zephyr/drivers/wifi/simplelink/simplelink_support.c
Gil Pitney 0633a1c294 drivers: wifi: simplelink: More fixes after logging update
Previously, '\n' in LOG_DBG statements were added to
improve readability, by ensuring IP address weren't printed
across typical console terminal line boundaries.

But with the logging updates, '\n' is no longer
getting automatically expanded to \r\n, and a new timestamp
is automatically added, throwing off attempts at alignment.

This patch finally just removes the '\n''s from the log messages,
and cuts a few longer messages into separate messages.

Signed-off-by: Gil Pitney <gil.pitney@linaro.org>
2018-10-11 15:51:57 +03:00

599 lines
16 KiB
C

/*
* Copyright (c) 2018, Texas Instruments Incorporated
*
* SPDX-License-Identifier: Apache-2.0
*
*/
#include <stdlib.h>
#include <string.h>
#include "simplelink_log.h"
LOG_MODULE_DECLARE(LOG_MODULE_NAME);
#include <zephyr.h>
#include <stdint.h>
#include <ti/drivers/net/wifi/simplelink.h>
#include <CC3220SF_LAUNCHXL.h>
#include "simplelink_support.h"
#define SET_STATUS_BIT(status, bit) {status |= (1 << (bit)); }
#define CLR_STATUS_BIT(status, bit) {status &= ~(1 << (bit)); }
#define GET_STATUS_BIT(status, bit) (0 != (status & (1 << (bit))))
#define SL_STOP_TIMEOUT (200)
#undef ASSERT_ON_ERROR
#define ASSERT_ON_ERROR(ret, e) __ASSERT(ret >= 0, e)
#define DEVICE_ERROR ("See \"DEVICE ERRORS CODES\" in SimpleLink errors.h")
#define WLAN_ERROR ("See \"WLAN ERRORS CODES\" in SimpleLink errors.h")
#define NETAPP_ERROR ("See \"NETAPP ERRORS CODES\" in SimpleLink errors.h")
#define CHANNEL_MASK_ALL (0x1FFF)
#define RSSI_TH_MAX (-95)
enum status_bits {
/* Network Processor is powered up */
STATUS_BIT_NWP_INIT = 0,
/* The device is connected to the AP */
STATUS_BIT_CONNECTION,
/* The device has leased IP to any connected client */
STATUS_BIT_IP_LEASED,
/* The device has acquired an IP */
STATUS_BIT_IP_ACQUIRED,
/* The device has acquired an IPv6 address */
STATUS_BIT_IPV6_ACQUIRED,
};
struct nwp_status {
/* Callback to notify net & wifi mgmt events from SL Event Handlers */
simplelink_wifi_cb_t cb;
/* Status Variables */
u32_t status; /* The state of the NWP */
u32_t role; /* The device's role (STA, P2P or AP) */
/* Scan results table: */
SlWlanNetworkEntry_t net_entries[CONFIG_WIFI_SIMPLELINK_SCAN_COUNT];
};
/* STA/AP mode state: shared with simplelink.c */
struct sl_connect_state sl_conn;
/* Network Coprocessor state, including role and connection state: */
static struct nwp_status nwp;
/* Configure the device to a default state, resetting previous parameters .*/
static s32_t configure_simplelink(void)
{
s32_t retval = -1;
s32_t mode = -1;
#if !defined(CONFIG_NET_IPV6)
u32_t if_bitmap = 0;
#endif
SlWlanScanParamCommand_t scan_default = { 0 };
SlWlanRxFilterOperationCommandBuff_t rx_filterid_mask = { { 0 } };
u8_t config_opt;
u8_t power;
/* Turn on NWP */
mode = sl_Start(0, 0, 0);
ASSERT_ON_ERROR(mode, DEVICE_ERROR);
if (mode != ROLE_STA) {
/* Set NWP role as STA */
mode = sl_WlanSetMode(ROLE_STA);
ASSERT_ON_ERROR(mode, WLAN_ERROR);
/* For changes to take affect, we restart the NWP */
retval = sl_Stop(SL_STOP_TIMEOUT);
ASSERT_ON_ERROR(retval, DEVICE_ERROR);
mode = sl_Start(0, 0, 0);
ASSERT_ON_ERROR(mode, DEVICE_ERROR);
}
if (mode != ROLE_STA) {
LOG_ERR("Failed to configure NWP to default state");
return -1;
}
/* Use Fast Connect Policy, to automatically connect to last AP: */
retval = sl_WlanPolicySet(SL_WLAN_POLICY_CONNECTION,
SL_WLAN_CONNECTION_POLICY(1, 1, 0, 0),
NULL, 0);
ASSERT_ON_ERROR(retval, WLAN_ERROR);
/* Disable Auto Provisioning*/
retval = sl_WlanProvisioning(SL_WLAN_PROVISIONING_CMD_STOP, 0xFF, 0,
NULL, 0x0);
ASSERT_ON_ERROR(retval, WLAN_ERROR);
/* Delete existing profiles */
retval = sl_WlanProfileDel(0xFF);
ASSERT_ON_ERROR(retval, WLAN_ERROR);
/* enable DHCP client */
retval = sl_NetCfgSet(SL_NETCFG_IPV4_STA_ADDR_MODE,
SL_NETCFG_ADDR_DHCP, 0, 0);
ASSERT_ON_ERROR(retval, NETAPP_ERROR);
#if !defined(CONFIG_NET_IPV6)
/* Disable ipv6 */
if_bitmap = !(SL_NETCFG_IF_IPV6_STA_LOCAL |
SL_NETCFG_IF_IPV6_STA_GLOBAL);
retval = sl_NetCfgSet(SL_NETCFG_IF, SL_NETCFG_IF_STATE,
sizeof(if_bitmap),
(const unsigned char *)&if_bitmap);
ASSERT_ON_ERROR(retval, NETAPP_ERROR);
#endif
/* Configure scan parameters to default */
scan_default.ChannelsMask = CHANNEL_MASK_ALL;
scan_default.RssiThershold = RSSI_TH_MAX;
retval = sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID,
SL_WLAN_GENERAL_PARAM_OPT_SCAN_PARAMS,
sizeof(scan_default), (u8_t *)&scan_default);
ASSERT_ON_ERROR(retval, WLAN_ERROR);
/* Disable scans: In other words, use "one-shot" scanning */
config_opt = SL_WLAN_SCAN_POLICY(0, 0);
retval = sl_WlanPolicySet(SL_WLAN_POLICY_SCAN, config_opt, NULL, 0);
ASSERT_ON_ERROR(retval, WLAN_ERROR);
/* Set TX power lvl to max */
power = 0;
retval = sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID,
SL_WLAN_GENERAL_PARAM_OPT_STA_TX_POWER, 1,
(u8_t *)&power);
ASSERT_ON_ERROR(retval, WLAN_ERROR);
/* Set NWP Power policy to 'normal' */
retval = sl_WlanPolicySet(SL_WLAN_POLICY_PM, SL_WLAN_NORMAL_POLICY,
NULL, 0);
ASSERT_ON_ERROR(retval, WLAN_ERROR);
/* Unregister mDNS services */
retval = sl_NetAppMDNSUnRegisterService(0, 0, 0);
ASSERT_ON_ERROR(retval, NETAPP_ERROR);
/* Remove all 64 RX filters (8*8) */
(void)memset(rx_filterid_mask.FilterBitmap, 0xFF, 8);
retval = sl_WlanSet(SL_WLAN_RX_FILTERS_ID, SL_WLAN_RX_FILTER_REMOVE,
sizeof(SlWlanRxFilterOperationCommandBuff_t),
(u8_t *)&rx_filterid_mask);
ASSERT_ON_ERROR(retval, WLAN_ERROR);
/* Set NWP role as STA */
retval = sl_WlanSetMode(ROLE_STA);
ASSERT_ON_ERROR(retval, WLAN_ERROR);
/* For changes to take affect, we restart the NWP */
retval = sl_Stop(0xFF);
ASSERT_ON_ERROR(retval, DEVICE_ERROR);
mode = sl_Start(0, 0, 0);
ASSERT_ON_ERROR(mode, DEVICE_ERROR);
if (mode != ROLE_STA) {
LOG_ERR("Failed to configure device to it's default state");
retval = -1;
} else {
nwp.role = ROLE_STA;
SET_STATUS_BIT(nwp.status, STATUS_BIT_NWP_INIT);
retval = 0;
}
return retval;
}
/**
* @brief SimpleLinkWlanEventHandler
*
* This handler gets called whenever a WLAN event is reported
* by the host driver / NWP.
*
* @note See the CC3120/CC3220 NWP programmer's guide (SWRU455)
* sections 4.3.4, 4.4.5 and 4.5.5.
*/
void SimpleLinkWlanEventHandler(SlWlanEvent_t *wlan_event)
{
SlWlanEventDisconnect_t *event_data = NULL;
if (!wlan_event) {
return;
}
switch (wlan_event->Id) {
case SL_WLAN_EVENT_CONNECT:
SET_STATUS_BIT(nwp.status, STATUS_BIT_CONNECTION);
/* Store new connection SSID and BSSID: */
memcpy(sl_conn.ssid, wlan_event->Data.Connect.SsidName,
wlan_event->Data.Connect.SsidLen);
memcpy(sl_conn.bssid, wlan_event->Data.Connect.Bssid,
BSSID_LEN_MAX);
LOG_INF("[WLAN EVENT] STA Connected to the AP: %s, "
"BSSID: %x:%x:%x:%x:%x:%x",
sl_conn.ssid, sl_conn.bssid[0],
sl_conn.bssid[1], sl_conn.bssid[2],
sl_conn.bssid[3], sl_conn.bssid[4],
sl_conn.bssid[5]);
/* Continue the notification callback chain... */
sl_conn.error = 0;
nwp.cb(SL_WLAN_EVENT_CONNECT, &sl_conn);
break;
case SL_WLAN_EVENT_DISCONNECT:
CLR_STATUS_BIT(nwp.status, STATUS_BIT_CONNECTION);
CLR_STATUS_BIT(nwp.status, STATUS_BIT_IP_ACQUIRED);
CLR_STATUS_BIT(nwp.status, STATUS_BIT_IPV6_ACQUIRED);
event_data = &wlan_event->Data.Disconnect;
/* If the user has initiated 'Disconnect' request,
* 'reason_code' is SL_WLAN_DISCONNECT_USER_INITIATED
*/
if (SL_WLAN_DISCONNECT_USER_INITIATED ==
event_data->ReasonCode) {
LOG_INF("[WLAN EVENT] "
"Device disconnected from the AP: %s",
event_data->SsidName);
LOG_INF("BSSID: %x:%x:%x:%x:%x:%x on application's"
" request", event_data->Bssid[0],
event_data->Bssid[1], event_data->Bssid[2],
event_data->Bssid[3], event_data->Bssid[4],
event_data->Bssid[5]);
sl_conn.error = 0;
} else {
LOG_ERR("[WLAN ERROR] "
"Device disconnected from the AP: %s",
event_data->SsidName);
LOG_ERR("BSSID: %x:%x:%x:%x:%x:%x on error: %d",
event_data->Bssid[0],
event_data->Bssid[1], event_data->Bssid[2],
event_data->Bssid[3], event_data->Bssid[4],
event_data->Bssid[5],
event_data->ReasonCode);
sl_conn.error = event_data->ReasonCode;
}
(void)memset(&(sl_conn.ssid), 0x0, sizeof(sl_conn.ssid));
(void)memset(&(sl_conn.bssid), 0x0, sizeof(sl_conn.bssid));
/* Continue the notification callback chain... */
nwp.cb(SL_WLAN_EVENT_DISCONNECT, &sl_conn);
break;
case SL_WLAN_EVENT_STA_ADDED:
memcpy(&(sl_conn.bssid), wlan_event->Data.STAAdded.Mac,
SL_WLAN_BSSID_LENGTH);
LOG_INF("[WLAN EVENT] STA was added to AP: "
"BSSID: %x:%x:%x:%x:%x:%x",
sl_conn.bssid[0], sl_conn.bssid[1],
sl_conn.bssid[2], sl_conn.bssid[3],
sl_conn.bssid[4], sl_conn.bssid[5]);
break;
case SL_WLAN_EVENT_STA_REMOVED:
memcpy(&(sl_conn.bssid), wlan_event->Data.STAAdded.Mac,
SL_WLAN_BSSID_LENGTH);
LOG_INF("[WLAN EVENT] STA was removed from AP: "
"BSSID: %x:%x:%x:%x:%x:%x",
sl_conn.bssid[0], sl_conn.bssid[1],
sl_conn.bssid[2], sl_conn.bssid[3],
sl_conn.bssid[4], sl_conn.bssid[5]);
(void)memset(&(sl_conn.bssid), 0x0, sizeof(sl_conn.bssid));
break;
default:
LOG_ERR("[WLAN EVENT] Unexpected event [0x%lx]",
wlan_event->Id);
break;
}
}
/**
* @brief SimpleLinkNetAppEventHandler
*
* This handler gets called whenever a Netapp event is reported
* by the host driver / NWP.
*
* @note See the CC3120/CC3220 NWP programmer's guide (SWRU455)
* section 5.7.
*/
void SimpleLinkNetAppEventHandler(SlNetAppEvent_t *netapp_event)
{
SlIpV4AcquiredAsync_t *event_data = NULL;
u32_t i;
if (!netapp_event) {
return;
}
switch (netapp_event->Id) {
case SL_DEVICE_EVENT_DROPPED_NETAPP_IPACQUIRED:
SET_STATUS_BIT(nwp.status, STATUS_BIT_IP_ACQUIRED);
/* Ip Acquired Event Data */
event_data = &netapp_event->Data.IpAcquiredV4;
sl_conn.ip_addr = event_data->Ip;
/* Gateway IP address */
sl_conn.gateway_ip = event_data->Gateway;
LOG_INF("[NETAPP EVENT] IP set to: IPv4=%d.%d.%d.%d, "
"Gateway=%d.%d.%d.%d",
SL_IPV4_BYTE(sl_conn.ip_addr, 3),
SL_IPV4_BYTE(sl_conn.ip_addr, 2),
SL_IPV4_BYTE(sl_conn.ip_addr, 1),
SL_IPV4_BYTE(sl_conn.ip_addr, 0),
SL_IPV4_BYTE(sl_conn.gateway_ip, 3),
SL_IPV4_BYTE(sl_conn.gateway_ip, 2),
SL_IPV4_BYTE(sl_conn.gateway_ip, 1),
SL_IPV4_BYTE(sl_conn.gateway_ip, 0));
nwp.cb(SIMPLELINK_WIFI_CB_IPACQUIRED, &sl_conn);
break;
case SL_DEVICE_EVENT_DROPPED_NETAPP_IPACQUIRED_V6:
SET_STATUS_BIT(nwp.status, STATUS_BIT_IPV6_ACQUIRED);
for (i = 0; i < 4; i++) {
sl_conn.ipv6_addr[i] =
netapp_event->Data.IpAcquiredV6.Ip[i];
}
if (LOG_LEVEL >= LOG_LEVEL_INF) {
char ipv6_addr[NET_IPV6_ADDR_LEN];
net_addr_ntop(AF_INET6, sl_conn.ipv6_addr,
ipv6_addr,
sizeof(ipv6_addr));
LOG_INF("[NETAPP EVENT] IP Acquired: IPv6= %s",
ipv6_addr);
}
break;
case SL_DEVICE_EVENT_DROPPED_NETAPP_IP_LEASED:
SET_STATUS_BIT(nwp.status, STATUS_BIT_IP_LEASED);
SET_STATUS_BIT(nwp.status, STATUS_BIT_IP_ACQUIRED);
sl_conn.sta_ip = netapp_event->Data.IpLeased.IpAddress;
LOG_INF("[NETAPP EVENT] IP Leased to Client: "
"IP=%d.%d.%d.%d",
SL_IPV4_BYTE(sl_conn.sta_ip, 3),
SL_IPV4_BYTE(sl_conn.sta_ip, 2),
SL_IPV4_BYTE(sl_conn.sta_ip, 1),
SL_IPV4_BYTE(sl_conn.sta_ip, 0));
break;
case SL_DEVICE_EVENT_DROPPED_NETAPP_IP_RELEASED:
LOG_INF("[NETAPP EVENT] IP is released.");
break;
default:
LOG_ERR("[NETAPP EVENT] Unexpected event [0x%lx]",
netapp_event->Id);
break;
}
}
/**
* @brief SimpleLinkGeneralEventHandler
*
* This handler gets called whenever a general error is reported
* by the NWP / Host driver. Since these errors are not fatal,
* the application can handle them.
*
* @note See the CC3120/CC3220 NWP programmer's guide (SWRU455)
* section 17.9.
*/
void SimpleLinkGeneralEventHandler(SlDeviceEvent_t *dev_event)
{
if (!dev_event) {
return;
}
LOG_INF("[GENERAL EVENT] - ID=[%d] Sender=[%d]",
dev_event->Data.Error.Code,
dev_event->Data.Error.Source);
}
/**
* @brief SimpleLinkFatalErrorEventHandler
*
* This handler gets called whenever a driver error occurs requiring
* restart of the device in order to recover.
*/
void SimpleLinkFatalErrorEventHandler(SlDeviceFatal_t *fatal_err_event)
{
switch (fatal_err_event->Id) {
case SL_DEVICE_EVENT_FATAL_DEVICE_ABORT:
LOG_ERR("[ERROR] - FATAL ERROR: "
"Abort NWP event detected: "
"AbortType=%ld, AbortData=0x%lx",
fatal_err_event->Data.DeviceAssert.Code,
fatal_err_event->Data.DeviceAssert.Value);
break;
case SL_DEVICE_EVENT_FATAL_DRIVER_ABORT:
LOG_ERR("[ERROR] - FATAL ERROR: Driver Abort detected.");
break;
case SL_DEVICE_EVENT_FATAL_NO_CMD_ACK:
LOG_ERR("[ERROR] - FATAL ERROR: No Cmd Ack detected "
"[cmd opcode = 0x%lx]",
fatal_err_event->Data.NoCmdAck.Code);
break;
case SL_DEVICE_EVENT_FATAL_SYNC_LOSS:
LOG_ERR("[ERROR] - FATAL ERROR: Sync loss detected");
break;
case SL_DEVICE_EVENT_FATAL_CMD_TIMEOUT:
LOG_ERR("[ERROR] - FATAL ERROR: "
"Async event timeout detected "
"[event opcode =0x%lx]",
fatal_err_event->Data.CmdTimeout.Code);
break;
default:
LOG_ERR("[ERROR] - FATAL ERROR: "
"Unspecified error detected");
break;
}
}
/* Unused, but must be defined to link. */
void SimpleLinkSockEventHandler(SlSockEvent_t *psock)
{
ARG_UNUSED(psock);
}
/* Unused, but must be defined to link. */
void SimpleLinkHttpServerEventHandler(SlNetAppHttpServerEvent_t *http_event,
SlNetAppHttpServerResponse_t *http_resp)
{
ARG_UNUSED(http_event);
ARG_UNUSED(http_resp);
}
/* Unused, but must be defined to link. */
void SimpleLinkNetAppRequestEventHandler(SlNetAppRequest_t *netapp_request,
SlNetAppResponse_t *netapp_response)
{
ARG_UNUSED(netapp_request);
ARG_UNUSED(netapp_response);
}
/* Unused, but must be defined to link. */
void SimpleLinkNetAppRequestMemFreeEventHandler(u8_t *buffer)
{
ARG_UNUSED(buffer);
}
/* Note: SimpleLink WiFi scan also can return the following:
* - BSSID
* - Whether network hidden or visible
* - Other types of security
*/
void _simplelink_get_scan_result(int index,
struct wifi_scan_result *scan_result)
{
SlWlanNetworkEntry_t *net_entry;
int sec_bmp;
__ASSERT_NO_MSG(index <= CONFIG_WIFI_SIMPLELINK_SCAN_COUNT);
net_entry = &nwp.net_entries[index];
(void)memset(scan_result, 0x0, sizeof(struct wifi_scan_result));
__ASSERT_NO_MSG(net_entry->SsidLen <= WIFI_SSID_MAX_LEN);
memcpy(scan_result->ssid, net_entry->Ssid, net_entry->SsidLen);
scan_result->ssid_length = net_entry->SsidLen;
scan_result->channel = net_entry->Channel;
/* Parse security bitmap: */
sec_bmp = net_entry->SecurityInfo;
if (SL_WLAN_SCAN_RESULT_SEC_TYPE_BITMAP(sec_bmp) & 0x6) {
scan_result->security = WIFI_SECURITY_TYPE_PSK;
} else {
scan_result->security = WIFI_SECURITY_TYPE_NONE;
}
scan_result->rssi = net_entry->Rssi;
}
int _simplelink_start_scan(void)
{
s32_t ret;
/* Clear the results buffer */
(void)memset(&nwp.net_entries, 0x0, sizeof(nwp.net_entries));
/* Attempt to get scan results from NWP
* Note: If scan policy isn't set, invoking 'sl_WlanGetNetworkList()'
* for the first time triggers 'one shot' scan.
*/
ret = sl_WlanGetNetworkList(0, CONFIG_WIFI_SIMPLELINK_SCAN_COUNT,
&nwp.net_entries[0]);
LOG_DBG("sl_WlanGetNetworkList: %d", ret);
return ret;
}
void _simplelink_get_mac(unsigned char *mac)
{
u16_t mac_len = SL_MAC_ADDR_LEN;
u16_t config_opt = 0;
sl_NetCfgGet(SL_NETCFG_MAC_ADDRESS_GET, &config_opt,
&mac_len, (u8_t *)mac);
}
int _simplelink_connect(struct wifi_connect_req_params *params)
{
SlWlanSecParams_t secParams = { 0 };
long lretval;
if (params->security == WIFI_SECURITY_TYPE_PSK) {
secParams.Key = (signed char *)params->psk;
secParams.KeyLen = params->psk_length;
/* This is only mapping handled for now: */
secParams.Type = SL_WLAN_SEC_TYPE_WPA_WPA2;
} else {
secParams.Key = (signed char *)NULL;
secParams.KeyLen = 0;
secParams.Type = SL_WLAN_SEC_TYPE_OPEN;
}
lretval = sl_WlanConnect((signed char *)params->ssid,
params->ssid_length, 0, &secParams, 0);
LOG_DBG("sl_WlanConnect: %ld", lretval);
return lretval;
}
int _simplelink_disconnect(void)
{
long lretval;
lretval = sl_WlanDisconnect();
LOG_DBG("sl_WlanDisconnect: %ld", lretval);
return lretval;
}
int _simplelink_init(simplelink_wifi_cb_t wifi_cb)
{
int retval;
__ASSERT(wifi_cb, "callback must be supplied");
/* Init the board: */
CC3220SF_LAUNCHXL_init();
/* Configure SimpleLink NWP: */
nwp.status = 0;
nwp.role = ROLE_RESERVED;
nwp.cb = wifi_cb;
(void)memset(&sl_conn, 0x0, sizeof(sl_conn));
retval = configure_simplelink();
__ASSERT(retval >= 0, "Unable to configure SimpleLink");
return retval;
}