//***************************************************************************** // network_if.c // // Networking interface functions for CC3200 device // // Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ // // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the // distribution. // // Neither the name of Texas Instruments Incorporated nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // //***************************************************************************** #include #include // Simplelink includes #include "simplelink.h" // driverlib includes #include "hw_types.h" #include "timer.h" #include "rom.h" #include "rom_map.h" #include "utils.h" // free-rtos/TI-rtos include #ifdef SL_PLATFORM_MULTI_THREADED #include "osi.h" #endif // common interface includes #include "network_if.h" #ifndef NOTERM #include "uart_if.h" #endif #include "timer_if.h" #include "common.h" // Network App specific status/error codes which are used only in this file typedef enum{ // Choosing this number to avoid overlap w/ host-driver's error codes DEVICE_NOT_IN_STATION_MODE = -0x7F0, DEVICE_NOT_IN_AP_MODE = DEVICE_NOT_IN_STATION_MODE - 1, DEVICE_NOT_IN_P2P_MODE = DEVICE_NOT_IN_AP_MODE - 1, STATUS_CODE_MAX = -0xBB8 }e_NetAppStatusCodes; //***************************************************************************** // GLOBAL VARIABLES -- Start //***************************************************************************** volatile unsigned long g_ulStatus = 0; /* SimpleLink Status */ unsigned long g_ulStaIp = 0; /* Station IP address */ unsigned long g_ulGatewayIP = 0; /* Network Gateway IP address */ unsigned char g_ucConnectionSSID[SSID_LEN_MAX+1]; /* Connection SSID */ unsigned char g_ucConnectionBSSID[BSSID_LEN_MAX]; /* Connection BSSID */ volatile unsigned short g_usConnectIndex; /* Connection time delay index */ const char pcDigits[] = "0123456789"; /* variable used by itoa function */ //***************************************************************************** // GLOBAL VARIABLES -- End //***************************************************************************** #ifdef USE_FREERTOS //***************************************************************************** // FreeRTOS User Hook Functions enabled in FreeRTOSConfig.h //***************************************************************************** //***************************************************************************** // //! \brief Application defined hook (or callback) function - assert //! //! \param[in] pcFile - Pointer to the File Name //! \param[in] ulLine - Line Number //! //! \return none //! //***************************************************************************** void vAssertCalled( const char *pcFile, unsigned long ulLine ) { //Handle Assert here while(1) { } } //***************************************************************************** // //! \brief Application defined idle task hook //! //! \param none //! //! \return none //! //***************************************************************************** void vApplicationIdleHook( void) { //Handle Idle Hook for Profiling, Power Management etc } //***************************************************************************** // //! \brief Application defined malloc failed hook //! //! \param none //! //! \return none //! //***************************************************************************** void vApplicationMallocFailedHook() { //Handle Memory Allocation Errors while(1) { } } //***************************************************************************** // //! \brief Application defined stack overflow hook //! //! \param none //! //! \return none //! //***************************************************************************** void vApplicationStackOverflowHook( OsiTaskHandle *pxTask, signed char *pcTaskName) { //Handle FreeRTOS Stack Overflow while(1) { } } #endif //USE_FREERTOS //***************************************************************************** // SimpleLink Asynchronous Event Handlers -- Start //***************************************************************************** //***************************************************************************** // //! \brief The Function Handles WLAN Events //! //! \param[in] pSlWlanEvent - Pointer to WLAN Event Info //! //! \return None //! //***************************************************************************** void SimpleLinkWlanEventHandler(SlWlanEvent_t *pSlWlanEvent) { if(pSlWlanEvent == NULL) { return; } switch(((SlWlanEvent_t*)pSlWlanEvent)->Event) { case SL_WLAN_CONNECT_EVENT: { SET_STATUS_BIT(g_ulStatus, STATUS_BIT_CONNECTION); CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_CONNECTION_FAILED); // // Information about the connected AP (like name, MAC etc) will be // available in 'slWlanConnectAsyncResponse_t'-Applications // can use it if required // // slWlanConnectAsyncResponse_t *pEventData = NULL; // pEventData = &pSlWlanEvent->EventData.STAandP2PModeWlanConnected; // // Copy new connection SSID and BSSID to global parameters memcpy(g_ucConnectionSSID,pSlWlanEvent->EventData. STAandP2PModeWlanConnected.ssid_name, pSlWlanEvent->EventData.STAandP2PModeWlanConnected.ssid_len); memcpy(g_ucConnectionBSSID, pSlWlanEvent->EventData.STAandP2PModeWlanConnected.bssid, SL_BSSID_LENGTH); UART_PRINT("[WLAN EVENT] STA Connected to the AP: %s , BSSID: " "%x:%x:%x:%x:%x:%x\n\r", g_ucConnectionSSID, g_ucConnectionBSSID[0], g_ucConnectionBSSID[1], g_ucConnectionBSSID[2], g_ucConnectionBSSID[3], g_ucConnectionBSSID[4], g_ucConnectionBSSID[5]); } break; case SL_WLAN_DISCONNECT_EVENT: { slWlanConnectAsyncResponse_t* pEventData = NULL; CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_CONNECTION); CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_IP_AQUIRED); pEventData = &pSlWlanEvent->EventData.STAandP2PModeDisconnected; // If the user has initiated 'Disconnect' request, //'reason_code' is SL_WLAN_DISCONNECT_USER_INITIATED_DISCONNECTION if(SL_WLAN_DISCONNECT_USER_INITIATED_DISCONNECTION == pEventData->reason_code) { UART_PRINT("[WLAN EVENT]Device disconnected from the AP: %s, " "BSSID: %x:%x:%x:%x:%x:%x on application's request " "\n\r", g_ucConnectionSSID,g_ucConnectionBSSID[0], g_ucConnectionBSSID[1],g_ucConnectionBSSID[2], g_ucConnectionBSSID[3],g_ucConnectionBSSID[4], g_ucConnectionBSSID[5]); } else { UART_PRINT("[WLAN ERROR]Device disconnected from the AP AP: %s," " BSSID: %x:%x:%x:%x:%x:%x on an ERROR..!! \n\r", g_ucConnectionSSID,g_ucConnectionBSSID[0], g_ucConnectionBSSID[1],g_ucConnectionBSSID[2], g_ucConnectionBSSID[3],g_ucConnectionBSSID[4], g_ucConnectionBSSID[5]); } memset(g_ucConnectionSSID,0,sizeof(g_ucConnectionSSID)); memset(g_ucConnectionBSSID,0,sizeof(g_ucConnectionBSSID)); } break; case SL_WLAN_STA_CONNECTED_EVENT: { // when device is in AP mode and any client connects to device cc3xxx SET_STATUS_BIT(g_ulStatus, STATUS_BIT_CONNECTION); CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_CONNECTION_FAILED); // // Information about the connected client (like SSID, MAC etc) will // be available in 'slPeerInfoAsyncResponse_t' - Applications // can use it if required // // slPeerInfoAsyncResponse_t *pEventData = NULL; // pEventData = &pSlWlanEvent->EventData.APModeStaConnected; // } break; case SL_WLAN_STA_DISCONNECTED_EVENT: { // when client disconnects from device (AP) CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_CONNECTION); CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_IP_LEASED); // // Information about the connected client (like SSID, MAC etc) will // be available in 'slPeerInfoAsyncResponse_t' - Applications // can use it if required // // slPeerInfoAsyncResponse_t *pEventData = NULL; // pEventData = &pSlWlanEvent->EventData.APModestaDisconnected; // } break; case SL_WLAN_SMART_CONFIG_COMPLETE_EVENT: { SET_STATUS_BIT(g_ulStatus, STATUS_BIT_SMARTCONFIG_START); // // Information about the SmartConfig details (like Status, SSID, // Token etc) will be available in 'slSmartConfigStartAsyncResponse_t' // - Applications can use it if required // // slSmartConfigStartAsyncResponse_t *pEventData = NULL; // pEventData = &pSlWlanEvent->EventData.smartConfigStartResponse; // } break; case SL_WLAN_SMART_CONFIG_STOP_EVENT: { // SmartConfig operation finished CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_SMARTCONFIG_START); // // Information about the SmartConfig details (like Status, padding // etc) will be available in 'slSmartConfigStopAsyncResponse_t' - // Applications can use it if required // // slSmartConfigStopAsyncResponse_t *pEventData = NULL; // pEventData = &pSlWlanEvent->EventData.smartConfigStopResponse; // } break; case SL_WLAN_P2P_DEV_FOUND_EVENT: { SET_STATUS_BIT(g_ulStatus, STATUS_BIT_P2P_DEV_FOUND); // // Information about P2P config details (like Peer device name, own // SSID etc) will be available in 'slPeerInfoAsyncResponse_t' - // Applications can use it if required // // slPeerInfoAsyncResponse_t *pEventData = NULL; // pEventData = &pSlWlanEvent->EventData.P2PModeDevFound; // } break; case SL_WLAN_P2P_NEG_REQ_RECEIVED_EVENT: { SET_STATUS_BIT(g_ulStatus, STATUS_BIT_P2P_REQ_RECEIVED); // // Information about P2P Negotiation req details (like Peer device // name, own SSID etc) will be available in 'slPeerInfoAsyncResponse_t' // - Applications can use it if required // // slPeerInfoAsyncResponse_t *pEventData = NULL; // pEventData = &pSlWlanEvent->EventData.P2PModeNegReqReceived; // } break; case SL_WLAN_CONNECTION_FAILED_EVENT: { // If device gets any connection failed event SET_STATUS_BIT(g_ulStatus, STATUS_BIT_CONNECTION_FAILED); } break; default: { UART_PRINT("[WLAN EVENT] Unexpected event \n\r"); } break; } } //***************************************************************************** // //! \brief This function handles network events such as IP acquisition, IP //! leased, IP released etc. //! //! \param pNetAppEvent - Pointer indicating device acquired IP //! //! \return None //! //***************************************************************************** void SimpleLinkNetAppEventHandler(SlNetAppEvent_t *pNetAppEvent) { if(pNetAppEvent == NULL) { return; } switch(pNetAppEvent->Event) { case SL_NETAPP_IPV4_IPACQUIRED_EVENT: case SL_NETAPP_IPV6_IPACQUIRED_EVENT: { SET_STATUS_BIT(g_ulStatus, STATUS_BIT_IP_AQUIRED); UART_PRINT("[NETAPP EVENT] IP acquired by the device\n\r"); // // Information about the IPv4 & IPv6 details (like IP, gateway,dns // etc) will be available in 'SlIpV4AcquiredAsync_t / // SlIpV6AcquiredAsync_t' - Applications can use it if required // // For IPv4: // // SlIpV4AcquiredAsync_t *pEventData = NULL; // pEventData = &pNetAppEvent->EventData.ipAcquiredV4; // // For IPv6: // // SlIpV6AcquiredAsync_t *pEventData = NULL; // pEventData = &pNetAppEvent->EventData.ipAcquiredV6; // } break; case SL_NETAPP_IP_LEASED_EVENT: { SET_STATUS_BIT(g_ulStatus, STATUS_BIT_IP_LEASED); UART_PRINT("[NETAPP EVENT] IP leased to a client\n\r"); // // Information about the IP-Leased details(like IP-Leased,lease-time, // mac etc) will be available in 'SlIpLeasedAsync_t' - Applications // can use it if required // // SlIpLeasedAsync_t *pEventData = NULL; // pEventData = &pNetAppEvent->EventData.ipLeased; // SlIpLeasedAsync_t *pEventData = NULL; pEventData = &pNetAppEvent->EventData.ipLeased; g_ulStaIp = pEventData->ip_address; } break; case SL_NETAPP_IP_RELEASED_EVENT: { CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_IP_LEASED); UART_PRINT("[NETAPP EVENT] IP released from a client\n\r"); // // Information about the IP-Released details (like IP-address, mac // etc) will be available in 'SlIpReleasedAsync_t' - Applications // can use it if required // // SlIpReleasedAsync_t *pEventData = NULL; // pEventData = &pNetAppEvent->EventData.ipReleased; // } break; default: { UART_PRINT("[NETAPP EVENT] Unexpected event \n\r"); } break; } } //***************************************************************************** // //! \brief This function handles General Events //! //! \param[in] pDevEvent - Pointer to General Event Info //! //! \return None //! //***************************************************************************** void SimpleLinkGeneralEventHandler(SlDeviceEvent_t *pDevEvent) { if(pDevEvent == NULL) { return; } // // Most of the general errors are not FATAL are are to be handled // appropriately by the application // UART_PRINT("[GENERAL EVENT] - ID=[%d] Sender=[%d]\n\n", pDevEvent->EventData.deviceEvent.status, pDevEvent->EventData.deviceEvent.sender); } //***************************************************************************** // //! This function handles socket events indication //! //! \param[in] pSock - Pointer to Socket Event Info //! //! \return None //! //***************************************************************************** void SimpleLinkSockEventHandler(SlSockEvent_t *pSock) { if(pSock == NULL) { return; } // // This application doesn't work w/ socket - Events are not expected // switch( pSock->Event ) { case SL_SOCKET_TX_FAILED_EVENT: switch( pSock->socketAsyncEvent.SockTxFailData.status) { case SL_ECLOSE: UART_PRINT("[SOCK ERROR] - close socket (%d) operation " "failed to transmit all queued packets\n\n", pSock->socketAsyncEvent.SockTxFailData.sd); break; default: UART_PRINT("[SOCK ERROR] - TX FAILED : socket %d , reason " "(%d) \n\n", pSock->socketAsyncEvent.SockTxFailData.sd, pSock->socketAsyncEvent.SockTxFailData.status); break; } break; case SL_SOCKET_ASYNC_EVENT: switch(pSock->socketAsyncEvent.SockAsyncData.type) { case SSL_ACCEPT:/*accept failed due to ssl issue ( tcp pass)*/ UART_PRINT("[SOCK ERROR] - close socket (%d) operation" "accept failed due to ssl issue\n\r", pSock->socketAsyncEvent.SockAsyncData.sd); break; case RX_FRAGMENTATION_TOO_BIG: UART_PRINT("[SOCK ERROR] -close scoket (%d) operation" "connection less mode, rx packet fragmentation\n\r" "> 16K, packet is being released", pSock->socketAsyncEvent.SockAsyncData.sd); break; case OTHER_SIDE_CLOSE_SSL_DATA_NOT_ENCRYPTED: UART_PRINT("[SOCK ERROR] -close socket (%d) operation" "remote side down from secure to unsecure\n\r", pSock->socketAsyncEvent.SockAsyncData.sd); break; default: UART_PRINT("unknown sock async event: %d\n\r", pSock->socketAsyncEvent.SockAsyncData.type); } break; default: UART_PRINT("[SOCK EVENT] - Unexpected Event [%x0x]\n\n",pSock->Event); break; } } //***************************************************************************** // //! This function gets triggered when HTTP Server receives Application //! defined GET and POST HTTP Tokens. //! //! \param pHttpServerEvent Pointer indicating http server event //! \param pHttpServerResponse Pointer indicating http server response //! //! \return None //! //***************************************************************************** void SimpleLinkHttpServerCallback(SlHttpServerEvent_t *pSlHttpServerEvent, SlHttpServerResponse_t *pSlHttpServerResponse) { } //***************************************************************************** // SimpleLink Asynchronous Event Handlers -- End //***************************************************************************** //**************************************************************************** // //! \brief This function initializes the application variables //! //! \param[in] None //! //! \return 0 on success, negative error-code on error // //**************************************************************************** void InitializeAppVariables() { g_ulStatus = 0; g_ulStaIp = 0; g_ulGatewayIP = 0; memset(g_ucConnectionSSID,0,sizeof(g_ucConnectionSSID)); memset(g_ucConnectionBSSID,0,sizeof(g_ucConnectionBSSID)); } //***************************************************************************** //! \brief This function puts the device in its default state. It: //! - Set the mode to STATION //! - Configures connection policy to Auto and AutoSmartConfig //! - Deletes all the stored profiles //! - Enables DHCP //! - Disables Scan policy //! - Sets Tx power to maximum //! - Sets power policy to normal //! - Unregister mDNS services //! - Remove all filters //! //! \param none //! \return On success, zero is returned. On error, negative is returned //***************************************************************************** long ConfigureSimpleLinkToDefaultState() { SlVersionFull ver = {{0}}; _WlanRxFilterOperationCommandBuff_t RxFilterIdMask = {{0}}; unsigned char ucVal = 1; unsigned char ucConfigOpt = 0; unsigned char ucConfigLen = 0; unsigned char ucPower = 0; long lRetVal = -1; long lMode = -1; lMode = sl_Start(0, 0, 0); ASSERT_ON_ERROR(lMode); // If the device is not in station-mode, try configuring it in station-mode if (ROLE_STA != lMode) { if (ROLE_AP == lMode) { // If the device is in AP mode, we need to wait for this event // before doing anything while(!IS_IP_ACQUIRED(g_ulStatus)) { #ifndef SL_PLATFORM_MULTI_THREADED _SlNonOsMainLoopTask(); #else osi_Sleep(1); #endif } } // Switch to STA role and restart lRetVal = sl_WlanSetMode(ROLE_STA); ASSERT_ON_ERROR(lRetVal); lRetVal = sl_Stop(0xFF); ASSERT_ON_ERROR(lRetVal); lRetVal = sl_Start(0, 0, 0); ASSERT_ON_ERROR(lRetVal); // Check if the device is in station again if (ROLE_STA != lRetVal) { // We don't want to proceed if the device is not coming up in STA-mode ASSERT_ON_ERROR(DEVICE_NOT_IN_STATION_MODE); } } // Get the device's version-information ucConfigOpt = SL_DEVICE_GENERAL_VERSION; ucConfigLen = sizeof(ver); lRetVal = sl_DevGet(SL_DEVICE_GENERAL_CONFIGURATION, &ucConfigOpt, &ucConfigLen, (unsigned char *)(&ver)); ASSERT_ON_ERROR(lRetVal); UART_PRINT("Host Driver Version: %s\n\r",SL_DRIVER_VERSION); UART_PRINT("Build Version %d.%d.%d.%d.31.%d.%d.%d.%d.%d.%d.%d.%d\n\r", ver.NwpVersion[0],ver.NwpVersion[1],ver.NwpVersion[2],ver.NwpVersion[3], ver.ChipFwAndPhyVersion.FwVersion[0],ver.ChipFwAndPhyVersion.FwVersion[1], ver.ChipFwAndPhyVersion.FwVersion[2],ver.ChipFwAndPhyVersion.FwVersion[3], ver.ChipFwAndPhyVersion.PhyVersion[0],ver.ChipFwAndPhyVersion.PhyVersion[1], ver.ChipFwAndPhyVersion.PhyVersion[2],ver.ChipFwAndPhyVersion.PhyVersion[3]); // Set connection policy to Auto + SmartConfig // (Device's default connection policy) lRetVal = sl_WlanPolicySet(SL_POLICY_CONNECTION, SL_CONNECTION_POLICY(1, 0, 0, 0, 1), NULL, 0); ASSERT_ON_ERROR(lRetVal); // Remove all profiles lRetVal = sl_WlanProfileDel(0xFF); ASSERT_ON_ERROR(lRetVal); // // Device in station-mode. Disconnect previous connection if any // The function returns 0 if 'Disconnected done', negative number if already // disconnected Wait for 'disconnection' event if 0 is returned, Ignore // other return-codes // lRetVal = sl_WlanDisconnect(); if(0 == lRetVal) { // Wait while(IS_CONNECTED(g_ulStatus)) { #ifndef SL_PLATFORM_MULTI_THREADED _SlNonOsMainLoopTask(); #else osi_Sleep(1); #endif } } // Enable DHCP client lRetVal = sl_NetCfgSet(SL_IPV4_STA_P2P_CL_DHCP_ENABLE,1,1,&ucVal); ASSERT_ON_ERROR(lRetVal); // Disable scan ucConfigOpt = SL_SCAN_POLICY(0); lRetVal = sl_WlanPolicySet(SL_POLICY_SCAN , ucConfigOpt, NULL, 0); ASSERT_ON_ERROR(lRetVal); // Set Tx power level for station mode // Number between 0-15, as dB offset from max power - 0 will set max power ucPower = 0; lRetVal = sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID, WLAN_GENERAL_PARAM_OPT_STA_TX_POWER, 1, (unsigned char *)&ucPower); ASSERT_ON_ERROR(lRetVal); // Set PM policy to normal lRetVal = sl_WlanPolicySet(SL_POLICY_PM , SL_NORMAL_POLICY, NULL, 0); ASSERT_ON_ERROR(lRetVal); // Unregister mDNS services lRetVal = sl_NetAppMDNSUnRegisterService(0, 0); ASSERT_ON_ERROR(lRetVal); // Remove all 64 filters (8*8) memset(RxFilterIdMask.FilterIdMask, 0xFF, 8); lRetVal = sl_WlanRxFilterSet(SL_REMOVE_RX_FILTER, (_u8 *)&RxFilterIdMask, sizeof(_WlanRxFilterOperationCommandBuff_t)); ASSERT_ON_ERROR(lRetVal); lRetVal = sl_Stop(SL_STOP_TIMEOUT); ASSERT_ON_ERROR(lRetVal); InitializeAppVariables(); return lRetVal; // Success } //***************************************************************************** // //! Network_IF_InitDriver //! The function initializes a CC3200 device and triggers it to start operation //! //! \param uiMode (device mode in which device will be configured) //! //! \return 0 : sucess, -ve : failure // //***************************************************************************** long Network_IF_InitDriver(unsigned int uiMode) { long lRetVal = -1; // Reset CC3200 Network State Machine InitializeAppVariables(); // // Following function configure the device to default state by cleaning // the persistent settings stored in NVMEM (viz. connection profiles & // policies, power policy etc) // // Applications may choose to skip this step if the developer is sure // that the device is in its default state at start of application // // Note that all profiles and persistent settings that were done on the // device will be lost // lRetVal = ConfigureSimpleLinkToDefaultState(); if(lRetVal < 0) { if (DEVICE_NOT_IN_STATION_MODE == lRetVal) UART_PRINT("Failed to configure the device in its default state \n\r"); LOOP_FOREVER(); } UART_PRINT("Device is configured in default state \n\r"); // // Assumption is that the device is configured in station mode already // and it is in its default state // lRetVal = sl_Start(NULL,NULL,NULL); if (lRetVal < 0 || lRetVal != ROLE_STA) { UART_PRINT("Failed to start the device \n\r"); LOOP_FOREVER(); } UART_PRINT("Started SimpleLink Device: STA Mode\n\r"); if(uiMode == ROLE_AP) { UART_PRINT("Switching to AP mode on application request\n\r"); // Switch to AP role and restart lRetVal = sl_WlanSetMode(uiMode); ASSERT_ON_ERROR(lRetVal); lRetVal = sl_Stop(0xFF); lRetVal = sl_Start(0, 0, 0); ASSERT_ON_ERROR(lRetVal); // Check if the device is up in AP Mode if (ROLE_AP == lRetVal) { // If the device is in AP mode, we need to wait for this event // before doing anything while(!IS_IP_ACQUIRED(g_ulStatus)) { #ifndef SL_PLATFORM_MULTI_THREADED _SlNonOsMainLoopTask(); #else osi_Sleep(1); #endif } } else { // We don't want to proceed if the device is not coming up in AP-mode ASSERT_ON_ERROR(DEVICE_NOT_IN_AP_MODE); } UART_PRINT("Re-started SimpleLink Device: AP Mode\n\r"); } else if(uiMode == ROLE_P2P) { UART_PRINT("Switching to P2P mode on application request\n\r"); // Switch to AP role and restart lRetVal = sl_WlanSetMode(uiMode); ASSERT_ON_ERROR(lRetVal); lRetVal = sl_Stop(0xFF); lRetVal = sl_Start(0, 0, 0); ASSERT_ON_ERROR(lRetVal); // Check if the device is in station again if (ROLE_P2P != lRetVal) { // We don't want to proceed if the device is not coming up in P2P-mode ASSERT_ON_ERROR(DEVICE_NOT_IN_P2P_MODE); } UART_PRINT("Re-started SimpleLink Device: P2P Mode\n\r"); } else { // Device already started in STA-Mode } return 0; } //***************************************************************************** // //! Network_IF_DeInitDriver //! The function de-initializes a CC3200 device //! //! \param None //! //! \return On success, zero is returned. On error, other // //***************************************************************************** long Network_IF_DeInitDriver(void) { long lRetVal = -1; UART_PRINT("SL Disconnect...\n\r"); // // Disconnect from the AP // lRetVal = Network_IF_DisconnectFromAP(); // // Stop the simplelink host // sl_Stop(SL_STOP_TIMEOUT); // // Reset the state to uninitialized // Network_IF_ResetMCUStateMachine(); return lRetVal; } //***************************************************************************** // //! Network_IF_ConnectAP Connect to an Access Point using the specified SSID //! //! \param[in] pcSsid is a string of the AP's SSID //! \param[in] SecurityParams is Security parameter for AP //! //! \return On success, zero is returned. On error, -ve value is returned // //***************************************************************************** long Network_IF_ConnectAP(char *pcSsid, SlSecParams_t SecurityParams) { #ifndef NOTERM char acCmdStore[128]; unsigned short usConnTimeout; unsigned char ucRecvdAPDetails; #endif long lRetVal; unsigned long ulIP = 0; unsigned long ulSubMask = 0; unsigned long ulDefGateway = 0; unsigned long ulDns = 0; // // Disconnect from the AP // Network_IF_DisconnectFromAP(); // // This triggers the CC3200 to connect to specific AP // lRetVal = sl_WlanConnect((signed char *)pcSsid, strlen((const char *)pcSsid), NULL, &SecurityParams, NULL); ASSERT_ON_ERROR(lRetVal); // // Wait for ~10 sec to check if connection to desire AP succeeds // while(g_usConnectIndex < 15) { #ifndef SL_PLATFORM_MULTI_THREADED _SlNonOsMainLoopTask(); #else osi_Sleep(1); #endif MAP_UtilsDelay(8000000); if(IS_CONNECTED(g_ulStatus) && IS_IP_ACQUIRED(g_ulStatus)) { break; } g_usConnectIndex++; } #ifndef NOTERM // // Check and loop until AP connection successful, else ask new AP SSID name // while(!(IS_CONNECTED(g_ulStatus)) || !(IS_IP_ACQUIRED(g_ulStatus))) { // // Disconnect the previous attempt // Network_IF_DisconnectFromAP(); CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_CONNECTION); CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_IP_AQUIRED); UART_PRINT("Device could not connect to %s\n\r",pcSsid); do { ucRecvdAPDetails = 0; UART_PRINT("\n\r\n\rPlease enter the AP(open) SSID name # "); // // Get the AP name to connect over the UART // lRetVal = GetCmd(acCmdStore, sizeof(acCmdStore)); if(lRetVal > 0) { // remove start/end spaces if any lRetVal = TrimSpace(acCmdStore); // // Parse the AP name // strncpy(pcSsid, acCmdStore, lRetVal); if(pcSsid != NULL) { ucRecvdAPDetails = 1; pcSsid[lRetVal] = '\0'; } } }while(ucRecvdAPDetails == 0); // // Reset Security Parameters to OPEN security type // SecurityParams.Key = (signed char *)""; SecurityParams.KeyLen = 0; SecurityParams.Type = SL_SEC_TYPE_OPEN; UART_PRINT("\n\rTrying to connect to AP: %s ...\n\r",pcSsid); // // Get the current timer tick and setup the timeout accordingly // usConnTimeout = g_usConnectIndex + 15; // // This triggers the CC3200 to connect to specific AP // lRetVal = sl_WlanConnect((signed char *)pcSsid, strlen((const char *)pcSsid), NULL, &SecurityParams, NULL); ASSERT_ON_ERROR(lRetVal); // // Wait ~10 sec to check if connection to specifed AP succeeds // while(!(IS_CONNECTED(g_ulStatus)) || !(IS_IP_ACQUIRED(g_ulStatus))) { #ifndef SL_PLATFORM_MULTI_THREADED _SlNonOsMainLoopTask(); #else osi_Sleep(1); #endif MAP_UtilsDelay(8000000); if(g_usConnectIndex >= usConnTimeout) { break; } g_usConnectIndex++; } } #endif // // Put message on UART // UART_PRINT("\n\rDevice has connected to %s\n\r",pcSsid); // // Get IP address // lRetVal = Network_IF_IpConfigGet(&ulIP,&ulSubMask,&ulDefGateway,&ulDns); ASSERT_ON_ERROR(lRetVal); // // Send the information // UART_PRINT("Device IP Address is %d.%d.%d.%d \n\r\n\r", SL_IPV4_BYTE(ulIP, 3),SL_IPV4_BYTE(ulIP, 2), SL_IPV4_BYTE(ulIP, 1),SL_IPV4_BYTE(ulIP, 0)); return 0; } //***************************************************************************** // //! Disconnect Disconnects from an Access Point //! //! \param none //! //! \return 0 disconnected done, other already disconnected // //***************************************************************************** long Network_IF_DisconnectFromAP() { long lRetVal = 0; if (IS_CONNECTED(g_ulStatus)) { lRetVal = sl_WlanDisconnect(); if(0 == lRetVal) { // Wait while(IS_CONNECTED(g_ulStatus)) { #ifndef SL_PLATFORM_MULTI_THREADED _SlNonOsMainLoopTask(); #else osi_Sleep(1); #endif } return lRetVal; } else { return lRetVal; } } else { return lRetVal; } } //***************************************************************************** // //! Network_IF_IpConfigGet Get the IP Address of the device. //! //! \param pulIP IP Address of Device //! \param pulSubnetMask Subnetmask of Device //! \param pulDefaultGateway Default Gateway value //! \param pulDNSServer DNS Server //! //! \return On success, zero is returned. On error, -1 is returned // //***************************************************************************** long Network_IF_IpConfigGet(unsigned long *pulIP, unsigned long *pulSubnetMask, unsigned long *pulDefaultGateway, unsigned long *pulDNSServer) { unsigned char isDhcp; unsigned char len = sizeof(SlNetCfgIpV4Args_t); long lRetVal = -1; SlNetCfgIpV4Args_t ipV4 = {0}; lRetVal = sl_NetCfgGet(SL_IPV4_STA_P2P_CL_GET_INFO,&isDhcp,&len, (unsigned char *)&ipV4); ASSERT_ON_ERROR(lRetVal); *pulIP=ipV4.ipV4; *pulSubnetMask=ipV4.ipV4Mask; *pulDefaultGateway=ipV4.ipV4Gateway; *pulDefaultGateway=ipV4.ipV4DnsServer; return lRetVal; } //***************************************************************************** // //! Network_IF_GetHostIP //! //! \brief This function obtains the server IP address using a DNS lookup //! //! \param[in] pcHostName The server hostname //! \param[out] pDestinationIP This parameter is filled with host IP address. //! //! \return On success, +ve value is returned. On error, -ve value is returned //! // //***************************************************************************** long Network_IF_GetHostIP( char* pcHostName,unsigned long * pDestinationIP ) { long lStatus = 0; lStatus = sl_NetAppDnsGetHostByName((signed char *) pcHostName, strlen(pcHostName), pDestinationIP, SL_AF_INET); ASSERT_ON_ERROR(lStatus); UART_PRINT("Get Host IP succeeded.\n\rHost: %s IP: %d.%d.%d.%d \n\r\n\r", pcHostName, SL_IPV4_BYTE(*pDestinationIP,3), SL_IPV4_BYTE(*pDestinationIP,2), SL_IPV4_BYTE(*pDestinationIP,1), SL_IPV4_BYTE(*pDestinationIP,0)); return lStatus; } //***************************************************************************** // //! \brief Reset state from the state machine //! //! \param None //! //! \return none //! //***************************************************************************** void Network_IF_ResetMCUStateMachine() { g_ulStatus = 0; } //***************************************************************************** // //! \brief Return the current state bits //! //! \param None //! //! \return none //! // //***************************************************************************** unsigned long Network_IF_CurrentMCUState() { return g_ulStatus; } //***************************************************************************** // //! \brief sets a state from the state machine //! //! \param cStat Status of State Machine defined in e_StatusBits //! //! \return none //! //***************************************************************************** void Network_IF_SetMCUMachineState(char cStat) { SET_STATUS_BIT(g_ulStatus, cStat); } //***************************************************************************** // //! \brief Unsets a state from the state machine //! //! \param cStat Status of State Machine defined in e_StatusBits //! //! \return none //! //***************************************************************************** void Network_IF_UnsetMCUMachineState(char cStat) { CLR_STATUS_BIT(g_ulStatus, cStat); } //***************************************************************************** // //! itoa //! //! @brief Convert integer to ASCII in decimal base //! //! @param cNum is input integer number to convert //! @param cString is output string //! //! @return number of ASCII parameters //! //! // //***************************************************************************** unsigned short itoa(short cNum, char *cString) { char* ptr; short uTemp = cNum; unsigned short length; // value 0 is a special case if (cNum == 0) { length = 1; *cString = '0'; return length; } // Find out the length of the number, in decimal base length = 0; while (uTemp > 0) { uTemp /= 10; length++; } // Do the actual formatting, right to left uTemp = cNum; ptr = cString + length; while (uTemp > 0) { --ptr; *ptr = pcDigits[uTemp % 10]; uTemp /= 10; } return length; } //***************************************************************************** // // Close the Doxygen group. //! @} // //*****************************************************************************