wifi.c 5.3 KB
Newer Older
1 2
#include "wifi.h"

3
#include "mongoose.h"
4

5
#include <simplelink/cc_pal.h>
6 7 8 9 10
#include <simplelink/include/wlan.h>

#include <inc/hw_types.h>

#include <driverlib/gpio.h>
11 12
#include <driverlib/utils.h>

13
#include <example/common/gpio_if.h>
14
#include "cs_dbg.h"
15 16 17 18

void SimpleLinkWlanEventHandler(SlWlanEvent_t *e) {
  switch (e->Event) {
    case SL_WLAN_CONNECT_EVENT:
19
      LOG(LL_INFO, ("WiFi: connected, getting IP"));
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
      break;
    case SL_WLAN_STA_CONNECTED_EVENT:
      LOG(LL_INFO, ("WiFi: station connected"));
      break;
    case SL_WLAN_STA_DISCONNECTED_EVENT:
      LOG(LL_INFO, ("WiFi: station disconnected"));
      break;
    default:
      LOG(LL_INFO, ("WiFi: event %d", e->Event));
  }
}

void SimpleLinkNetAppEventHandler(SlNetAppEvent_t *e) {
  if (e->Event == SL_NETAPP_IPV4_IPACQUIRED_EVENT) {
    SlIpV4AcquiredAsync_t *ed = &e->EventData.ipAcquiredV4;
35
    LOG(LL_INFO, ("IP acquired: %lu.%lu.%lu.%lu", SL_IPV4_BYTE(ed->ip, 3),
36 37 38
                  SL_IPV4_BYTE(ed->ip, 2), SL_IPV4_BYTE(ed->ip, 1),
                  SL_IPV4_BYTE(ed->ip, 0)));
    GPIO_IF_LedToggle(MCU_RED_LED_GPIO);
39 40 41 42
  } else if (e->Event == SL_NETAPP_IP_LEASED_EVENT) {
    LOG(LL_INFO, ("IP leased"));
  } else {
    LOG(LL_INFO, ("NetApp event %d", e->Event));
43 44 45 46 47
  }
}

bool wifi_setup_ap(const char *ssid, const char *pass, int channel) {
  uint8_t v;
48 49 50
  if (sl_WlanSetMode(ROLE_AP) != 0) {
    return false;
  }
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
  if (sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_SSID, strlen(ssid),
                 (const uint8_t *) ssid) != 0) {
    return false;
  }
  v = strlen(pass) > 0 ? SL_SEC_TYPE_WPA : SL_SEC_TYPE_OPEN;
  if (sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_SECURITY_TYPE, 1, &v) != 0) {
    return false;
  }
  if (v == SL_SEC_TYPE_WPA &&
      sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_PASSWORD, strlen(pass),
                 (const uint8_t *) pass) != 0) {
    return false;
  }
  v = channel;
  if (sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_CHANNEL, 1, &v) != 0) {
    return false;
  }
68
  sl_NetAppStop(SL_NET_APP_DHCP_SERVER_ID);
69 70 71 72 73
  {
    SlNetCfgIpV4Args_t ipcfg;
    memset(&ipcfg, 0, sizeof(ipcfg));
    if (!inet_pton(AF_INET, "192.168.4.1", &ipcfg.ipV4) ||
        !inet_pton(AF_INET, "255.255.255.0", &ipcfg.ipV4Mask) ||
74 75 76 77 78
        /* This means "disable". 0.0.0.0 won't do. */
        !inet_pton(AF_INET, "255.255.255.255", &ipcfg.ipV4DnsServer) ||
        /* We'd like to disable gateway too, but DHCP server refuses to start.
           */
        !inet_pton(AF_INET, "192.168.4.1", &ipcfg.ipV4Gateway) ||
79 80 81 82 83
        sl_NetCfgSet(SL_IPV4_AP_P2P_GO_STATIC_ENABLE, IPCONFIG_MODE_ENABLE_IPV4,
                     sizeof(ipcfg), (uint8_t *) &ipcfg) != 0) {
      return false;
    }
  }
84 85 86 87 88 89 90 91 92 93 94
  {
    SlNetAppDhcpServerBasicOpt_t dhcpcfg;
    memset(&dhcpcfg, 0, sizeof(dhcpcfg));
    dhcpcfg.lease_time = 900;
    if (!inet_pton(AF_INET, "192.168.4.20", &dhcpcfg.ipv4_addr_start) ||
        !inet_pton(AF_INET, "192.168.4.200", &dhcpcfg.ipv4_addr_last) ||
        sl_NetAppSet(SL_NET_APP_DHCP_SERVER_ID, NETAPP_SET_DHCP_SRV_BASIC_OPT,
                     sizeof(dhcpcfg), (uint8_t *) &dhcpcfg) != 0) {
      return false;
    }
  }
95 96
  sl_Stop(0);
  sl_Start(NULL, NULL, NULL);
97 98 99 100
  if (sl_NetAppStart(SL_NET_APP_DHCP_SERVER_ID) != 0) {
    LOG(LL_ERROR, ("DHCP server failed to start"));
    return false;
  }
101
  LOG(LL_INFO, ("WiFi: AP %s configured, IP 192.168.4.1", ssid));
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
  return true;
}

bool wifi_setup_sta(const char *ssid, const char *pass) {
  SlSecParams_t sp;
  LOG(LL_INFO, ("WiFi: connecting to %s", ssid));
  if (sl_WlanSetMode(ROLE_STA) != 0) return false;
  sl_Stop(0);
  sl_Start(NULL, NULL, NULL);
  sl_WlanDisconnect();
  sp.Key = (_i8 *) pass;
  sp.KeyLen = strlen(pass);
  sp.Type = sp.KeyLen ? SL_SEC_TYPE_WPA : SL_SEC_TYPE_OPEN;
  if (sl_WlanConnect((const _i8 *) ssid, strlen(ssid), 0, &sp, 0) != 0) {
    return false;
  }
  return true;
}
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166

/*
 * In SDK 1.2.0 TI decided to stop resetting NWP before sl_Start, which in
 * practice means that sl_start will hang on subsequent runs after the first.
 *
 * See this post for details and suggested solution:
 * https://e2e.ti.com/support/wireless_connectivity/simplelink_wifi_cc31xx_cc32xx/f/968/p/499123/1806610#1806610
 *
 * However, since they don't provide OS_debug variant of simplelink.a and
 * adding another project dependency will complicate our demo even more,
 * we just take the required bit of code.
 *
 * This is a copy-paste of NwpPowerOnPreamble from cc_pal.c.
 */
void stop_nwp(void) {
#define MAX_RETRY_COUNT 1000
  unsigned int sl_stop_ind, apps_int_sts_raw, nwp_lpds_wake_cfg;
  unsigned int retry_count;
  /* Perform the sl_stop equivalent to ensure network services
     are turned off if active */
  HWREG(0x400F70B8) = 1; /* APPs to NWP interrupt */
  UtilsDelay(800000 / 5);

  retry_count = 0;
  nwp_lpds_wake_cfg = HWREG(0x4402D404);
  sl_stop_ind = HWREG(0x4402E16C);

  if ((nwp_lpds_wake_cfg != 0x20) && /* Check for NWP POR condition */
      !(sl_stop_ind & 0x2))          /* Check if sl_stop was executed */
  {
    /* Loop until APPs->NWP interrupt is cleared or timeout */
    while (retry_count < MAX_RETRY_COUNT) {
      apps_int_sts_raw = HWREG(0x400F70C0);
      if (apps_int_sts_raw & 0x1) {
        UtilsDelay(800000 / 5);
        retry_count++;
      } else {
        break;
      }
    }
  }
  HWREG(0x400F70B0) = 1; /* Clear APPs to NWP interrupt */
  UtilsDelay(800000 / 5);

  /* Stop the networking services */
  NwpPowerOff();
}