blob: ad72f6361c055c249adad1512c70994bb48cf29a [file] [log] [blame]
/*
*
* Copyright (c) 2022 Project CHIP Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "em_bus.h"
#include "em_cmu.h"
#include "em_gpio.h"
#include "em_ldma.h"
#include "em_usart.h"
#include "sl_status.h"
#include "FreeRTOS.h"
#include "event_groups.h"
#include "task.h"
#include "wfx_host_events.h"
#include "rsi_driver.h"
#include "rsi_wlan_non_rom.h"
#include "rsi_common_apis.h"
#include "rsi_data_types.h"
#include "rsi_nwk.h"
#include "rsi_socket.h"
#include "rsi_utils.h"
#include "rsi_wlan.h"
#include "rsi_wlan_apis.h"
#include "rsi_wlan_config.h"
//#include "rsi_wlan_non_rom.h"
#include "rsi_bootup_config.h"
#include "rsi_error.h"
#include "dhcp_client.h"
#include "wfx_host_events.h"
#include "wfx_rsi.h"
/* Rsi driver Task will use as its stack */
StackType_t driverRsiTaskStack[WFX_RSI_WLAN_TASK_SZ] = { 0 };
/* Structure that will hold the TCB of the wfxRsi Task being created. */
StaticTask_t driverRsiTaskBuffer;
/* Declare a variable to hold the data associated with the created event group. */
StaticEventGroup_t rsiDriverEventGroup;
bool hasNotifiedIPV6 = false;
#if (CHIP_DEVICE_CONFIG_ENABLE_IPV4)
bool hasNotifiedIPV4 = false;
#endif /* CHIP_DEVICE_CONFIG_ENABLE_IPV4 */
bool hasNotifiedWifiConnectivity = false;
/*
* This file implements the interface to the RSI SAPIs
*/
static uint8_t wfx_rsi_drv_buf[WFX_RSI_BUF_SZ];
wfx_wifi_scan_ext_t * temp_reset;
uint8_t security;
/******************************************************************
* @fn int32_t wfx_rsi_get_ap_info(wfx_wifi_scan_result_t *ap)
* @brief
* Getting the AP details
* @param[in] ap: access point
* @return
* status
*********************************************************************/
int32_t wfx_rsi_get_ap_info(wfx_wifi_scan_result_t * ap)
{
int32_t status;
uint8_t rssi;
ap->security = security;
ap->chan = wfx_rsi.ap_chan;
memcpy(&ap->bssid[0], &wfx_rsi.ap_mac.octet[0], BSSID_MAX_STR_LEN);
status = rsi_wlan_get(RSI_RSSI, &rssi, sizeof(rssi));
if (status == RSI_SUCCESS)
{
ap->rssi = (-1) * rssi;
}
return status;
}
/******************************************************************
* @fn int32_t wfx_rsi_get_ap_ext(wfx_wifi_scan_ext_t *extra_info)
* @brief
* Getting the AP extra details
* @param[in] extra info: access point extra information
* @return
* status
*********************************************************************/
int32_t wfx_rsi_get_ap_ext(wfx_wifi_scan_ext_t * extra_info)
{
int32_t status;
uint8_t buff[RSI_RESPONSE_MAX_SIZE] = { 0 };
status = rsi_wlan_get(RSI_WLAN_EXT_STATS, buff, sizeof(buff));
if (status != RSI_SUCCESS)
{
WFX_RSI_LOG("\r\n Failed, Error Code : 0x%lX\r\n", status);
}
else
{
rsi_wlan_ext_stats_t * test = (rsi_wlan_ext_stats_t *) buff;
extra_info->beacon_lost_count = test->beacon_lost_count - temp_reset->beacon_lost_count;
extra_info->beacon_rx_count = test->beacon_rx_count - temp_reset->beacon_rx_count;
extra_info->mcast_rx_count = test->mcast_rx_count - temp_reset->mcast_rx_count;
extra_info->mcast_tx_count = test->mcast_tx_count - temp_reset->mcast_tx_count;
extra_info->ucast_rx_count = test->ucast_rx_count - temp_reset->ucast_rx_count;
extra_info->ucast_tx_count = test->ucast_tx_count - temp_reset->ucast_tx_count;
extra_info->overrun_count = test->overrun_count - temp_reset->overrun_count;
}
return status;
}
/******************************************************************
* @fn int32_t wfx_rsi_reset_count()
* @brief
* Getting the driver reset count
* @param[in] None
* @return
* status
*********************************************************************/
int32_t wfx_rsi_reset_count()
{
int32_t status;
uint8_t buff[RSI_RESPONSE_MAX_SIZE] = { 0 };
status = rsi_wlan_get(RSI_WLAN_EXT_STATS, buff, sizeof(buff));
if (status != RSI_SUCCESS)
{
WFX_RSI_LOG("\r\n Failed, Error Code : 0x%lX\r\n", status);
}
else
{
rsi_wlan_ext_stats_t * test = (rsi_wlan_ext_stats_t *) buff;
temp_reset->beacon_lost_count = test->beacon_lost_count;
temp_reset->beacon_rx_count = test->beacon_rx_count;
temp_reset->mcast_rx_count = test->mcast_rx_count;
temp_reset->mcast_tx_count = test->mcast_tx_count;
temp_reset->ucast_rx_count = test->ucast_rx_count;
temp_reset->ucast_tx_count = test->ucast_tx_count;
temp_reset->overrun_count = test->overrun_count;
}
return status;
}
/******************************************************************
* @fn wfx_rsi_disconnect()
* @brief
* Getting the driver disconnect status
* @param[in] None
* @return
* status
*********************************************************************/
int32_t wfx_rsi_disconnect()
{
int32_t status = rsi_wlan_disconnect();
return status;
}
/******************************************************************
* @fn wfx_rsi_join_cb(uint16_t status, const uint8_t *buf, const uint16_t len)
* @brief
* called when driver join with cb
* @param[in] status:
* @param[in] buf:
* @param[in] len:
* @return
* None
*********************************************************************/
static void wfx_rsi_join_cb(uint16_t status, const uint8_t * buf, const uint16_t len)
{
WFX_RSI_LOG("%s: status: %02x", __func__, status);
wfx_rsi.dev_state &= ~WFX_RSI_ST_STA_CONNECTING;
temp_reset = (wfx_wifi_scan_ext_t *) malloc(sizeof(wfx_wifi_scan_ext_t));
memset(temp_reset, 0, sizeof(wfx_wifi_scan_ext_t));
if (status != RSI_SUCCESS)
{
/*
* We should enable retry.. (Need config variable for this)
*/
WFX_RSI_LOG("%s: failed. retry: %d", __func__, wfx_rsi.join_retries);
#if (WFX_RSI_CONFIG_MAX_JOIN != 0)
if (++wfx_rsi.join_retries < WFX_RSI_CONFIG_MAX_JOIN)
#endif
{
xEventGroupSetBits(wfx_rsi.events, WFX_EVT_STA_START_JOIN);
}
}
else
{
/*
* Join was complete - Do the DHCP
*/
WFX_RSI_LOG("%s: join completed.", __func__);
#ifdef RS911X_SOCKETS
xEventGroupSetBits(wfx_rsi.events, WFX_EVT_STA_DO_DHCP);
#else
xEventGroupSetBits(wfx_rsi.events, WFX_EVT_STA_CONN);
#endif
}
}
/******************************************************************
* @fn wfx_rsi_join_fail_cb(uint16_t status, uint8_t *buf, uint32_t len)
* @brief
* called when driver fail to join with cb
* @param[in] status:
* @param[in] buf:
* @param[in] len:
* @return
* None
*********************************************************************/
static void wfx_rsi_join_fail_cb(uint16_t status, uint8_t * buf, uint32_t len)
{
WFX_RSI_LOG("%s: error: failed status: %02x on try %d", __func__, status, wfx_rsi.join_retries);
wfx_rsi.join_retries += 1;
wfx_rsi.dev_state &= ~WFX_RSI_ST_STA_CONNECTING;
xEventGroupSetBits(wfx_rsi.events, WFX_EVT_STA_START_JOIN);
}
#ifdef RS911X_SOCKETS
/******************************************************************
* @fn wfx_rsi_ipchange_cb(uint16_t status, uint8_t *buf, uint32_t len)
* @brief
* DHCP should end up here
* @param[in] status:
* @param[in] buf:
* @param[in] len:
* @return
* None
*********************************************************************/
static void wfx_rsi_ipchange_cb(uint16_t status, uint8_t * buf, uint32_t len)
{
WFX_RSI_LOG("%s: status: %02x", __func__, status);
if (status != RSI_SUCCESS)
{
/* Restart DHCP? */
xEventGroupSetBits(wfx_rsi.events, WFX_EVT_STA_DO_DHCP);
}
else
{
wfx_rsi.dev_state |= WFX_RSI_ST_STA_DHCP_DONE;
xEventGroupSetBits(wfx_rsi.events, WFX_EVT_STA_DHCP_DONE);
}
}
#else
/*************************************************************************************
* @fn wfx_rsi_wlan_pkt_cb(uint16_t status, uint8_t *buf, uint32_t len)
* @brief
* Got RAW WLAN data pkt
* @param[in] status:
* @param[in] buf:
* @param[in] len:
* @return
* None
*****************************************************************************************/
static void wfx_rsi_wlan_pkt_cb(uint16_t status, uint8_t * buf, uint32_t len)
{
// WFX_RSI_LOG("%s: status=%d, len=%d", __func__, status, len);
if (status != RSI_SUCCESS)
{
return;
}
wfx_host_received_sta_frame_cb(buf, len);
}
#endif /* !Socket support */
/*************************************************************************************
* @fn static int32_t wfx_rsi_init(void)
* @brief
* driver initialization
* @param[in] None
* @return
* None
*****************************************************************************************/
static int32_t wfx_rsi_init(void)
{
int32_t status;
uint8_t buf[RSI_RESPONSE_HOLD_BUFF_SIZE];
extern void rsi_hal_board_init(void);
WFX_RSI_LOG("%s: starting(HEAP_SZ = %d)", __func__, SL_HEAP_SIZE);
//! Driver initialization
status = rsi_driver_init(wfx_rsi_drv_buf, WFX_RSI_BUF_SZ);
if ((status < RSI_DRIVER_STATUS) || (status > WFX_RSI_BUF_SZ))
{
WFX_RSI_LOG("%s: error: RSI drv init failed with status: %02x", __func__, status);
return status;
}
WFX_RSI_LOG("%s: rsi_device_init", __func__);
/* ! Redpine module intialisation */
if ((status = rsi_device_init(LOAD_NWP_FW)) != RSI_SUCCESS)
{
WFX_RSI_LOG("%s: error: rsi_device_init failed with status: %02x", __func__, status);
return status;
}
WFX_RSI_LOG("%s: start wireless drv task", __func__);
/*
* Create the driver task
*/
wfx_rsi.drv_task = xTaskCreateStatic((TaskFunction_t) rsi_wireless_driver_task, "rsi_drv", WFX_RSI_WLAN_TASK_SZ, NULL,
WLAN_TASK_PRIORITY, driverRsiTaskStack, &driverRsiTaskBuffer);
if (NULL == wfx_rsi.drv_task)
{
WFX_RSI_LOG("%s: error: rsi_wireless_driver_task failed", __func__);
return RSI_ERROR_INVALID_PARAM;
}
/* Initialize WiSeConnect or Module features. */
WFX_RSI_LOG("%s: rsi_wireless_init", __func__);
if ((status = rsi_wireless_init(OPER_MODE_0, COEX_MODE_0)) != RSI_SUCCESS)
{
WFX_RSI_LOG("%s: error: rsi_wireless_init failed with status: %02x", __func__, status);
return status;
}
WFX_RSI_LOG("%s: get FW version..", __func__);
/*
* Get the MAC and other info to let the user know about it.
*/
if (rsi_wlan_get(RSI_FW_VERSION, buf, sizeof(buf)) != RSI_SUCCESS)
{
WFX_RSI_LOG("%s: error: rsi_wlan_get(RSI_FW_VERSION) failed with status: %02x", __func__, status);
return status;
}
buf[sizeof(buf) - 1] = 0;
WFX_RSI_LOG("%s: RSI firmware version: %s", __func__, buf);
//! Send feature frame
if ((status = rsi_send_feature_frame()) != RSI_SUCCESS)
{
WFX_RSI_LOG("%s: error: rsi_send_feature_frame failed with status: %02x", __func__, status);
return status;
}
WFX_RSI_LOG("%s: sent rsi_send_feature_frame", __func__);
/* initializes wlan radio parameters and WLAN supplicant parameters.
*/
(void) rsi_wlan_radio_init(); /* Required so we can get MAC address */
if ((status = rsi_wlan_get(RSI_MAC_ADDRESS, &wfx_rsi.sta_mac.octet[0], RESP_BUFF_SIZE)) != RSI_SUCCESS)
{
WFX_RSI_LOG("%s: error: rsi_wlan_get failed with status: %02x", __func__, status);
return status;
}
WFX_RSI_LOG("%s: WLAN: MAC %02x:%02x:%02x %02x:%02x:%02x", __func__, wfx_rsi.sta_mac.octet[0], wfx_rsi.sta_mac.octet[1],
wfx_rsi.sta_mac.octet[2], wfx_rsi.sta_mac.octet[3], wfx_rsi.sta_mac.octet[4], wfx_rsi.sta_mac.octet[5]);
wfx_rsi.events = xEventGroupCreateStatic(&rsiDriverEventGroup);
/*
* Register callbacks - We are only interested in the connectivity CBs
*/
if ((status = rsi_wlan_register_callbacks(RSI_JOIN_FAIL_CB, wfx_rsi_join_fail_cb)) != RSI_SUCCESS)
{
WFX_RSI_LOG("%s: RSI callback register join failed with status: %02x", __func__, status);
return status;
}
#ifdef RS911X_SOCKETS
(void) rsi_wlan_register_callbacks(RSI_IP_CHANGE_NOTIFY_CB, wfx_rsi_ipchange_cb);
#else
if ((status = rsi_wlan_register_callbacks(RSI_WLAN_DATA_RECEIVE_NOTIFY_CB, wfx_rsi_wlan_pkt_cb)) != RSI_SUCCESS)
{
WFX_RSI_LOG("%s: RSI callback register data-notify failed with status: %02x", __func__, status);
return status;
}
#endif
wfx_rsi.dev_state |= WFX_RSI_ST_DEV_READY;
WFX_RSI_LOG("%s: RSI: OK", __func__);
return RSI_SUCCESS;
}
/*************************************************************************************
* @fn void wfx_show_err(char *msg)
* @brief
* driver shows error message
* @param[in] msg
* @return
* None
*****************************************************************************************/
void wfx_show_err(char * msg)
{
WFX_RSI_LOG("%s: message: %d", __func__, msg);
}
/***************************************************************************************
* @fn static void wfx_rsi_save_ap_info()
* @brief
* Saving the details of the AP
* @param[in] None
* @return
* None
*******************************************************************************************/
static void wfx_rsi_save_ap_info()
{
int32_t status;
rsi_rsp_scan_t rsp;
status =
rsi_wlan_scan_with_bitmap_options((int8_t *) &wfx_rsi.sec.ssid[0], AP_CHANNEL_NO_0, &rsp, sizeof(rsp), SCAN_BITMAP_OPTN_1);
if (status)
{
/*
* Scan is done - failed
*/
}
else
{
wfx_rsi.sec.security = rsp.scan_info->security_mode;
wfx_rsi.ap_chan = rsp.scan_info->rf_channel;
memcpy(&wfx_rsi.ap_mac.octet[0], &rsp.scan_info->bssid[0], BSSID_MAX_STR_LEN);
}
if ((wfx_rsi.sec.security == RSI_WPA) || (wfx_rsi.sec.security == RSI_WPA2))
{
// saving the security before changing into mixed mode
security = wfx_rsi.sec.security;
wfx_rsi.sec.security = RSI_WPA_WPA2_MIXED;
}
if (wfx_rsi.sec.security == SME_WPA3)
{
// returning 3 for WPA3 when DGWIFI read security-type is called
security = WPA3_SECURITY;
wfx_rsi.sec.security = RSI_WPA3;
}
WFX_RSI_LOG("%s: WLAN: connecting to %s==%s, sec=%d, status=%02x", __func__, &wfx_rsi.sec.ssid[0], &wfx_rsi.sec.passkey[0],
wfx_rsi.sec.security, status);
}
/********************************************************************************************
* @fn static void wfx_rsi_do_join(void)
* @brief
* Start an async Join command
* @return
* None
**********************************************************************************************/
static void wfx_rsi_do_join(void)
{
int32_t status;
if (wfx_rsi.dev_state & (WFX_RSI_ST_STA_CONNECTING | WFX_RSI_ST_STA_CONNECTED))
{
WFX_RSI_LOG("%s: not joining - already in progress", __func__);
}
else
{
WFX_RSI_LOG("%s: WLAN: connecting to %s==%s, sec=%d", __func__, &wfx_rsi.sec.ssid[0], &wfx_rsi.sec.passkey[0],
wfx_rsi.sec.security);
/*
* Join the network
*/
/* TODO - make the WFX_SECURITY_xxx - same as RSI_xxx
* Right now it's done by hand - we need something better
*/
wfx_rsi.dev_state |= WFX_RSI_ST_STA_CONNECTING;
/* Try to connect Wifi with given Credentials
* untill there is a success or maximum number of tries allowed
*/
while (++wfx_rsi.join_retries < WFX_RSI_CONFIG_MAX_JOIN)
{
/* Call rsi connect call with given ssid and password
* And check there is a success
*/
if ((status = rsi_wlan_connect_async((int8_t *) &wfx_rsi.sec.ssid[0], (rsi_security_mode_t) wfx_rsi.sec.security,
&wfx_rsi.sec.passkey[0], wfx_rsi_join_cb)) != RSI_SUCCESS)
{
wfx_rsi.dev_state &= ~WFX_RSI_ST_STA_CONNECTING;
WFX_RSI_LOG("%s: rsi_wlan_connect_async failed with status: %02x on try %d", __func__, status,
wfx_rsi.join_retries);
vTaskDelay(4000);
/* TODO - Start a timer.. to retry */
}
else
{
break; // exit while loop
}
}
if (wfx_rsi.join_retries == MAX_JOIN_RETRIES_COUNT)
{
WFX_RSI_LOG("Connect failed after %d tries", wfx_rsi.join_retries);
}
else
{
WFX_RSI_LOG("%s: starting JOIN to %s after %d tries\n", __func__, (char *) &wfx_rsi.sec.ssid[0], wfx_rsi.join_retries);
}
}
}
/*********************************************************************************
* @fn void wfx_rsi_task(void *arg)
* @brief
* The main WLAN task - started by wfx_wifi_start () that interfaces with RSI.
* The rest of RSI stuff come in call-backs.
* The initialization has been already done.
* @param[in] arg:
* @return
* None
**********************************************************************************/
/* ARGSUSED */
void wfx_rsi_task(void * arg)
{
EventBits_t flags;
#ifndef RS911X_SOCKETS
TickType_t last_dhcp_poll, now;
struct netif * sta_netif;
#endif
(void) arg;
uint32_t rsi_status = wfx_rsi_init();
if (rsi_status != RSI_SUCCESS)
{
WFX_RSI_LOG("%s: error: wfx_rsi_init with status: %02x", __func__, rsi_status);
return;
}
#ifndef RS911X_SOCKETS
wfx_lwip_start();
last_dhcp_poll = xTaskGetTickCount();
sta_netif = wfx_get_netif(SL_WFX_STA_INTERFACE);
#endif
wfx_started_notify();
WFX_RSI_LOG("%s: starting event wait", __func__);
for (;;)
{
/*
* This is the main job of this task.
* Wait for commands from the ConnectivityManager
* Make state changes (based on call backs)
*/
flags = xEventGroupWaitBits(wfx_rsi.events,
WFX_EVT_STA_CONN | WFX_EVT_STA_DISCONN | WFX_EVT_STA_START_JOIN
#ifdef RS911X_SOCKETS
| WFX_EVT_STA_DO_DHCP | WFX_EVT_STA_DHCP_DONE
#endif /* RS911X_SOCKETS */
#ifdef SL_WFX_CONFIG_SOFTAP
| WFX_EVT_AP_START | WFX_EVT_AP_STOP
#endif /* SL_WFX_CONFIG_SOFTAP */
#ifdef SL_WFX_CONFIG_SCAN
| WFX_EVT_SCAN
#endif /* SL_WFX_CONFIG_SCAN */
| 0,
pdTRUE, /* Clear the bits */
pdFALSE, /* Wait for any bit */
pdMS_TO_TICKS(250)); /* 250 mSec */
if (flags)
{
WFX_RSI_LOG("%s: wait event encountered: %x", __func__, flags);
}
#ifdef RS911X_SOCKETS
if (flags & WFX_EVT_STA_DO_DHCP)
{
/*
* Do DHCP -
*/
if ((status = rsi_config_ipaddress(RSI_IP_VERSION_4, RSI_DHCP | RSI_DHCP_UNICAST_OFFER, NULL, NULL, NULL,
&wfx_rsi.ip4_addr[0], IP_CONF_RSP_BUFF_LENGTH_4, STATION)) != RSI_SUCCESS)
{
/* We should try this again.. (perhaps sleep) */
/* TODO - Figure out what to do here */
}
}
#else /* !RS911X_SOCKET - using LWIP */
/*
* Let's handle DHCP polling here
*/
if (wfx_rsi.dev_state & WFX_RSI_ST_STA_CONNECTED)
{
if ((now = xTaskGetTickCount()) > (last_dhcp_poll + pdMS_TO_TICKS(250)))
{
#if (CHIP_DEVICE_CONFIG_ENABLE_IPV4)
uint8_t dhcp_state = dhcpclient_poll(sta_netif);
if (dhcp_state == DHCP_ADDRESS_ASSIGNED && !hasNotifiedIPV4)
{
wfx_dhcp_got_ipv4((uint32_t) sta_netif->ip_addr.u_addr.ip4.addr);
hasNotifiedIPV4 = true;
if (!hasNotifiedWifiConnectivity)
{
wfx_connected_notify(CONNECTION_STATUS_SUCCESS, &wfx_rsi.ap_mac);
hasNotifiedWifiConnectivity = true;
}
}
else if (dhcp_state == DHCP_OFF)
{
wfx_ip_changed_notify(IP_STATUS_FAIL);
hasNotifiedIPV4 = false;
}
#endif /* CHIP_DEVICE_CONFIG_ENABLE_IPV4 */
/* Checks if the assigned IPv6 address is preferred by evaluating
* the first block of IPv6 address ( block 0)
*/
if ((ip6_addr_ispreferred(netif_ip6_addr_state(sta_netif, 0))) && !hasNotifiedIPV6)
{
wfx_ipv6_notify(GET_IPV6_SUCCESS);
hasNotifiedIPV6 = true;
if (!hasNotifiedWifiConnectivity)
{
wfx_connected_notify(CONNECTION_STATUS_SUCCESS, &wfx_rsi.ap_mac);
hasNotifiedWifiConnectivity = true;
}
}
last_dhcp_poll = now;
}
}
#endif /* RS911X_SOCKETS */
if (flags & WFX_EVT_STA_START_JOIN)
{
// saving the AP related info
wfx_rsi_save_ap_info();
// Joining to the network
wfx_rsi_do_join();
}
if (flags & WFX_EVT_STA_CONN)
{
/*
* Initiate the Join command (assuming we have been provisioned)
*/
WFX_RSI_LOG("%s: starting LwIP STA", __func__);
wfx_rsi.dev_state |= WFX_RSI_ST_STA_CONNECTED;
#ifndef RS911X_SOCKETS
hasNotifiedWifiConnectivity = false;
#if (CHIP_DEVICE_CONFIG_ENABLE_IPV4)
hasNotifiedIPV4 = false;
#endif // CHIP_DEVICE_CONFIG_ENABLE_IPV4
hasNotifiedIPV6 = false;
wfx_lwip_set_sta_link_up();
#endif /* !RS911X_SOCKETS */
/* We need to get AP Mac - TODO */
// Uncomment once the hook into MATTER is moved to IP connectivty instead
// of AP connectivity. wfx_connected_notify(0, &wfx_rsi.ap_mac); // This
// is independant of IP connectivity.
}
if (flags & WFX_EVT_STA_DISCONN)
{
wfx_rsi.dev_state &=
~(WFX_RSI_ST_STA_READY | WFX_RSI_ST_STA_CONNECTING | WFX_RSI_ST_STA_CONNECTED | WFX_RSI_ST_STA_DHCP_DONE);
WFX_RSI_LOG("%s: disconnect notify", __func__);
/* TODO: Implement disconnect notify */
#ifndef RS911X_SOCKETS
wfx_lwip_set_sta_link_down(); // Internally dhcpclient_poll(netif) ->
// wfx_ip_changed_notify(0) for IPV4
#if (CHIP_DEVICE_CONFIG_ENABLE_IPV4)
wfx_ip_changed_notify(IP_STATUS_FAIL);
hasNotifiedIPV4 = false;
#endif /* CHIP_DEVICE_CONFIG_ENABLE_IPV4 */
wfx_ipv6_notify(GET_IPV6_FAIL);
hasNotifiedIPV6 = false;
hasNotifiedWifiConnectivity = false;
#endif /* !RS911X_SOCKETS */
}
#ifdef SL_WFX_CONFIG_SCAN
if (flags & WFX_EVT_SCAN)
{
if (!(wfx_rsi.dev_state & WFX_RSI_ST_SCANSTARTED))
{
WFX_RSI_LOG("%s: start SSID scan", __func__);
int x;
wfx_wifi_scan_result_t ap;
rsi_scan_info_t * scan;
int32_t status;
uint8_t bgscan_results[BG_SCAN_RES_SIZE] = { 0 };
status = rsi_wlan_bgscan_profile(1, (rsi_rsp_scan_t *) bgscan_results, BG_SCAN_RES_SIZE);
WFX_RSI_LOG("%s: status: %02x size = %d", __func__, status, BG_SCAN_RES_SIZE);
rsi_rsp_scan_t * rsp = (rsi_rsp_scan_t *) bgscan_results;
if (status)
{
/*
* Scan is done - failed
*/
}
else
for (x = 0; x < rsp->scan_count[0]; x++)
{
scan = &rsp->scan_info[x];
strcpy(&ap.ssid[0], (char *) &scan->ssid[0]);
if (wfx_rsi.scan_ssid)
{
WFX_RSI_LOG("Inside scan_ssid");
WFX_RSI_LOG("SCAN SSID: %s , ap scan: %s", wfx_rsi.scan_ssid, ap.ssid);
if (strcmp(wfx_rsi.scan_ssid, ap.ssid) == CMP_SUCCESS)
{
WFX_RSI_LOG("Inside ap details");
ap.security = scan->security_mode;
ap.rssi = (-1) * scan->rssi_val;
memcpy(&ap.bssid[0], &scan->bssid[0], BSSID_MAX_STR_LEN);
(*wfx_rsi.scan_cb)(&ap);
}
}
else
{
WFX_RSI_LOG("Inside else");
ap.security = scan->security_mode;
ap.rssi = (-1) * scan->rssi_val;
memcpy(&ap.bssid[0], &scan->bssid[0], BSSID_MAX_STR_LEN);
(*wfx_rsi.scan_cb)(&ap);
}
}
wfx_rsi.dev_state &= ~WFX_RSI_ST_SCANSTARTED;
/* Terminate with end of scan which is no ap sent back */
(*wfx_rsi.scan_cb)((wfx_wifi_scan_result_t *) 0);
wfx_rsi.scan_cb = (void (*)(wfx_wifi_scan_result_t *)) 0;
if (wfx_rsi.scan_ssid)
{
vPortFree(wfx_rsi.scan_ssid);
wfx_rsi.scan_ssid = (char *) 0;
}
}
}
#endif /* SL_WFX_CONFIG_SCAN */
#ifdef SL_WFX_CONFIG_SOFTAP
/* TODO */
if (flags & WFX_EVT_AP_START)
{
}
if (flags & WFX_EVT_AP_STOP)
{
}
#endif /* SL_WFX_CONFIG_SOFTAP */
}
}
#if CHIP_DEVICE_CONFIG_ENABLE_IPV4
/********************************************************************************************
* @fn void wfx_dhcp_got_ipv4(uint32_t ip)
* @brief
* Acquire the new ip address
* @param[in] ip: internet protocol
* @return
* None
**********************************************************************************************/
void wfx_dhcp_got_ipv4(uint32_t ip)
{
/*
* Acquire the new IP address
*/
wfx_rsi.ip4_addr[0] = (ip) &HEX_VALUE_FF;
wfx_rsi.ip4_addr[1] = (ip >> 8) & HEX_VALUE_FF;
wfx_rsi.ip4_addr[2] = (ip >> 16) & HEX_VALUE_FF;
wfx_rsi.ip4_addr[3] = (ip >> 24) & HEX_VALUE_FF;
WFX_RSI_LOG("%s: DHCP OK: IP=%d.%d.%d.%d", __func__, wfx_rsi.ip4_addr[0], wfx_rsi.ip4_addr[1], wfx_rsi.ip4_addr[2],
wfx_rsi.ip4_addr[3]);
/* Notify the Connectivity Manager - via the app */
wfx_ip_changed_notify(IP_STATUS_SUCCESS);
wfx_rsi.dev_state |= WFX_RSI_ST_STA_READY;
}
#endif /* CHIP_DEVICE_CONFIG_ENABLE_IPV4 */
/*
* WARNING - Taken from RSI and broken up
* This is my own RSI stuff for not copying code and allocating an extra
* level of indirection - when using LWIP buffers
* see also: int32_t rsi_wlan_send_data_xx(uint8_t *buffer, uint32_t length)
*/
/********************************************************************************************
* @fn void *wfx_rsi_alloc_pkt()
* @brief
* Allocate packet to send data
* @param[in] None
* @return
* None
**********************************************************************************************/
void * wfx_rsi_alloc_pkt()
{
rsi_pkt_t * pkt;
// Allocate packet to send data
if ((pkt = rsi_pkt_alloc(&rsi_driver_cb->wlan_cb->wlan_tx_pool)) == NULL)
{
return (void *) 0;
}
return (void *) pkt;
}
/********************************************************************************************
* @fn void wfx_rsi_pkt_add_data(void *p, uint8_t *buf, uint16_t len, uint16_t off)
* @brief
* add the data into packet
* @param[in] p:
* @param[in] buf:
* @param[in] len:
* @param[in] off:
* @return
* None
**********************************************************************************************/
void wfx_rsi_pkt_add_data(void * p, uint8_t * buf, uint16_t len, uint16_t off)
{
rsi_pkt_t * pkt;
pkt = (rsi_pkt_t *) p;
memcpy(((char *) pkt->data) + off, buf, len);
}
/********************************************************************************************
* @fn int32_t wfx_rsi_send_data(void *p, uint16_t len)
* @brief
* Driver send a data
* @param[in] p:
* @param[in] len:
* @return
* None
**********************************************************************************************/
int32_t wfx_rsi_send_data(void * p, uint16_t len)
{
int32_t status;
register uint8_t * host_desc;
rsi_pkt_t * pkt;
pkt = (rsi_pkt_t *) p;
host_desc = pkt->desc;
memset(host_desc, 0, RSI_HOST_DESC_LENGTH);
rsi_uint16_to_2bytes(host_desc, (len & 0xFFF));
// Fill packet type
host_desc[1] |= (RSI_WLAN_DATA_Q << 4);
host_desc[2] |= 0x01;
rsi_enqueue_pkt(&rsi_driver_cb->wlan_tx_q, pkt);
#ifndef RSI_SEND_SEM_BITMAP
rsi_driver_cb_non_rom->send_wait_bitmap |= BIT(0);
#endif
// Set TX packet pending event
rsi_set_event(RSI_TX_EVENT);
if (rsi_wait_on_wlan_semaphore(&rsi_driver_cb_non_rom->send_data_sem, RSI_SEND_DATA_RESPONSE_WAIT_TIME) != RSI_ERROR_NONE)
{
return RSI_ERROR_RESPONSE_TIMEOUT;
}
status = rsi_wlan_get_status();
return status;
}
struct wfx_rsi wfx_rsi;