TI's CC3100 host driver and demo. Experimental and a work in progress.

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*
00002  * main.c - sample application to switch to AP mode and ping client
00003  *
00004  * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
00005  *
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *    Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  *
00014  *    Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in the
00016  *    documentation and/or other materials provided with the
00017  *    distribution.
00018  *
00019  *    Neither the name of Texas Instruments Incorporated nor the names of
00020  *    its contributors may be used to endorse or promote products derived
00021  *    from this software without specific prior written permission.
00022  *
00023  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00024  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00025  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00026  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00027  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00028  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00029  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00030  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00031  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00032  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00033  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034  *
00035  */
00036 
00037 /*
00038  * Application Name     -   Getting started with Wi-Fi Access-Point mode
00039  * Application Overview -   This sample application demonstrates how
00040  *                          to configure CC3100 in Access-Point mode. Any
00041  *                          WLAN station in its range can connect/communicate
00042  *                          to/with it as per the standard networking protocols.
00043  *                          On a successful connection, the device ping's the
00044  *                          connected station.
00045  * Application Details  -   http://processors.wiki.ti.com/index.php/CC31xx_Getting_Started_with_WLAN_AP
00046  *                          doc\examples\getting_started_with_wlan_ap.pdf
00047  */
00048 
00049 #include "mbed.h"
00050 #include "cc3100_simplelink.h"
00051 #include "cc3100_sl_common.h"
00052 #include "BoardInit.h"
00053 
00054 #if (THIS_BOARD == MBED_BOARD_LPC1768) 
00055 Serial pc(USBTX, USBRX);//lpc1768
00056 #elif (THIS_BOARD == ST_MBED_NUCLEOF411)
00057 Serial pc(SERIAL_TX, SERIAL_RX);//nucleoF411
00058 #elif (THIS_BOARD == EA_MBED_LPC4088)
00059 Serial pc(USBTX, USBRX);
00060 #elif (THIS_BOARD == ST_MBED_NUCLEOF103)
00061 Serial pc(SERIAL_TX, SERIAL_RX);
00062 #else
00063 
00064 #endif
00065 
00066 //using namespace mbed_cc3100;
00067  
00068 #define APPLICATION_VERSION "1.1.0"
00069 
00070 #define SL_STOP_TIMEOUT        0xFF
00071 
00072 /* Use bit 32: Lower bits of status variable are used for NWP events
00073  *      1 in a 'status_variable', the device has completed the ping operation
00074  *      0 in a 'status_variable', the device has not completed the ping operation
00075  */
00076 //#define STATUS_BIT_PING_DONE  31
00077 
00078 #define CONFIG_IP       SL_IPV4_VAL(192,168,0,1)    /* Static IP to be configured */
00079 #define CONFIG_MASK     SL_IPV4_VAL(255,255,255,0)  /* Subnet Mask for the station */
00080 #define CONFIG_GATEWAY  SL_IPV4_VAL(192,168,0,1)    /* Default Gateway address */
00081 #define CONFIG_DNS      SL_IPV4_VAL(192,168,0,1)    /* DNS Server Address */
00082 
00083 #define DHCP_START_IP    SL_IPV4_VAL(192,168,0,100) /* DHCP start IP address */
00084 #define DHCP_END_IP      SL_IPV4_VAL(192,168,0,200) /* DHCP End IP address */
00085 
00086 #define IP_LEASE_TIME        3600
00087 
00088 #define PING_INTERVAL        1000
00089 #define PING_SIZE            20
00090 #define PING_REQUEST_TIMEOUT 3000
00091 #define PING_ATTEMPT         3
00092 
00093 /* Application specific status/error codes */
00094 typedef enum{
00095     LAN_CONNECTION_FAILED = -0x7D0,        /* Choosing this number to avoid overlap with host-driver's error codes */
00096     INTERNET_CONNECTION_FAILED = LAN_CONNECTION_FAILED - 1,
00097     DEVICE_NOT_IN_STATION_MODE = INTERNET_CONNECTION_FAILED - 1,
00098 
00099     STATUS_CODE_MAX = -0xBB8
00100 }e_AppStatusCodes;
00101 /*
00102 #define IS_PING_DONE(status_variable)           GET_STATUS_BIT(status_variable, \
00103                                                                STATUS_BIT_PING_DONE)
00104 */
00105 /*
00106  * GLOBAL VARIABLES -- Start
00107  */
00108 
00109 //extern unsigned int  g_GatewayIP = 0;
00110 //extern unsigned int  g_StationIP = 0;
00111 unsigned int  g_PingPacketsRecv = 0;
00112 
00113 /*
00114  * GLOBAL VARIABLES -- End
00115  */
00116 
00117 
00118 /*
00119  * STATIC FUNCTION DEFINITIONS -- Start
00120  */
00121 static signed int configureSimpleLinkToDefaultState();
00122 static signed int initializeAppVariables();
00123 static void displayBanner();
00124 
00125 /*
00126  * STATIC FUNCTION DEFINITIONS -- End
00127  */
00128 
00129 /*
00130  * ASYNCHRONOUS EVENT HANDLERS -- Start
00131  */
00132 
00133 /*!
00134     \brief This function handles ping report events
00135 
00136     \param[in]      pPingReport holds the ping report statistics
00137 
00138     \return         None
00139 
00140     \note
00141 
00142     \warning
00143 */
00144 
00145 static void SimpleLinkPingReport(SlPingReport_t *pPingReport)
00146 {
00147     SET_STATUS_BIT(g_Status, STATUS_BIT_PING_DONE);
00148 
00149     if(pPingReport == NULL)
00150 
00151         printf(" [PING REPORT] NULL Pointer Error\r\n");
00152 
00153     g_PingPacketsRecv = pPingReport->PacketsReceived;
00154 }
00155 
00156 /*
00157  * ASYNCHRONOUS EVENT HANDLERS -- End
00158  */
00159 
00160 
00161 /*
00162  * Application's entry point
00163  */
00164 int main()
00165 {
00166     pc.baud(115200);
00167     
00168     SlPingStartCommand_t PingParams = {0};
00169     SlPingReport_t Report = {0};
00170     SlNetCfgIpV4Args_t ipV4 = {0};
00171     SlNetAppDhcpServerBasicOpt_t dhcpParams = {0};
00172 
00173     unsigned char SecType = 0;
00174     signed int mode = ROLE_STA;
00175     signed int retVal = -1;
00176 
00177     retVal = initializeAppVariables();
00178     ASSERT_ON_ERROR(retVal);
00179 
00180     displayBanner();
00181 
00182     CLR_STATUS_BIT(g_Status, STATUS_BIT_PING_DONE);
00183     g_PingPacketsRecv = 0;
00184 
00185     /*
00186      * Following function configures the device to default state by cleaning
00187      * the persistent settings stored in NVMEM (viz. connection profiles &
00188      * policies, power policy etc)
00189      *
00190      * Applications may choose to skip this step if the developer is sure
00191      * that the device is in its default state at start of application
00192      *
00193      * Note that all profiles and persistent settings that were done on the
00194      * device will be lost
00195      */
00196     retVal = configureSimpleLinkToDefaultState();
00197 
00198     if(retVal < 0)
00199     {
00200         if (DEVICE_NOT_IN_STATION_MODE == retVal)
00201             printf(" Failed to configure the device in its default state \n\r");
00202 
00203         LOOP_FOREVER();
00204     }
00205 
00206     printf(" Device is configured in default state \n\r");
00207 
00208     /*
00209      * Assumption is that the device is configured in station mode already
00210      * and it is in its default state
00211      */
00212     mode = sl_Start(0, 0, 0);
00213     if (ROLE_AP == mode)
00214     {
00215         /* If the device is in AP mode, we need to wait for this event before doing anything */
00216         while(!IS_IP_ACQUIRED(g_Status)) { _SlNonOsMainLoopTask(); }
00217     }
00218     else
00219     {
00220         /* Configure CC3100 to start in AP mode */
00221         retVal = sl_WlanSetMode(ROLE_AP);
00222         if(retVal < 0)
00223             LOOP_FOREVER();
00224 
00225         retVal = sl_Stop(SL_STOP_TIMEOUT);
00226         if(retVal < 0)
00227             LOOP_FOREVER();
00228 
00229         CLR_STATUS_BIT(g_Status, STATUS_BIT_IP_ACQUIRED);
00230 
00231         mode = sl_Start(0, 0, 0);
00232         if (ROLE_AP == mode)
00233         {
00234             /* If the device is in AP mode, we need to wait for this event before doing anything */
00235             while(!IS_IP_ACQUIRED(g_Status)) { _SlNonOsMainLoopTask(); }
00236         }
00237         else
00238         {
00239             printf(" Device couldn't be configured in AP mode \n\r");
00240             LOOP_FOREVER();
00241         }
00242     }
00243     
00244     printf(" Ready to configue SSID\r\n");
00245 
00246     /* Configure the SSID of the CC3100 */
00247     retVal = sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_SSID,
00248             pal_Strlen(SSID_AP_MODE), (unsigned char *)SSID_AP_MODE);
00249     if(retVal < 0)
00250         LOOP_FOREVER();
00251 
00252     SecType = SEC_TYPE_AP_MODE;
00253     /* Configure the Security parameter the AP mode */
00254     retVal = sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_SECURITY_TYPE, 1,
00255             (unsigned char *)&SecType);
00256     if(retVal < 0)
00257         LOOP_FOREVER();
00258 
00259     retVal = sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_PASSWORD, pal_Strlen(PASSWORD_AP_MODE),
00260             (unsigned char *)PASSWORD_AP_MODE);
00261     if(retVal < 0)
00262         LOOP_FOREVER();
00263 
00264     ipV4.ipV4 = CONFIG_IP;
00265     ipV4.ipV4Mask = CONFIG_MASK;
00266     ipV4.ipV4Gateway = CONFIG_GATEWAY;
00267     ipV4.ipV4DnsServer = CONFIG_DNS;
00268 
00269     /* Configure the Static IP */
00270     retVal = sl_NetCfgSet(SL_IPV4_AP_P2P_GO_STATIC_ENABLE,1,sizeof(SlNetCfgIpV4Args_t),
00271             (unsigned char *)&ipV4);
00272     if(retVal < 0)
00273         LOOP_FOREVER();
00274 
00275     dhcpParams.lease_time      = IP_LEASE_TIME;
00276     dhcpParams.ipv4_addr_start =  DHCP_START_IP;
00277     dhcpParams.ipv4_addr_last  =  DHCP_END_IP;
00278 
00279     retVal = sl_NetAppSet(SL_NET_APP_DHCP_SERVER_ID, NETAPP_SET_DHCP_SRV_BASIC_OPT,
00280             sizeof(SlNetAppDhcpServerBasicOpt_t), (unsigned char*)&dhcpParams);
00281     if(retVal < 0)
00282         LOOP_FOREVER();
00283 
00284     /* Restart the CC3100 */
00285     retVal = sl_Stop(SL_STOP_TIMEOUT);
00286     if(retVal < 0)
00287         LOOP_FOREVER();
00288 
00289     g_Status = 0;
00290 
00291     mode = sl_Start(0, 0, 0);
00292     if (ROLE_AP == mode)
00293     {
00294         /* If the device is in AP mode, we need to wait for this event before doing anything */
00295         while(!IS_IP_ACQUIRED(g_Status)) { _SlNonOsMainLoopTask(); }
00296     }
00297     else
00298     {
00299         printf(" Device couldn't come in AP mode \n\r");
00300         LOOP_FOREVER();
00301     }
00302     
00303     printf(" Device started as Access Point\n\r");
00304 
00305     /* Wait */
00306     printf(" Waiting for clients to connect...!\n\r");
00307     while((!IS_IP_LEASED(g_Status)) || (!IS_STA_CONNECTED(g_Status))) { _SlNonOsMainLoopTask(); }
00308     printf(" Client connected to the device \n\r");
00309     printf(" Pinging...! \n\r");
00310 
00311     /* Set the ping parameters */
00312     PingParams.PingIntervalTime = PING_INTERVAL;
00313     PingParams.PingSize = PING_SIZE;
00314     PingParams.PingRequestTimeout = PING_REQUEST_TIMEOUT;
00315     PingParams.TotalNumberOfAttempts = PING_ATTEMPT;
00316     PingParams.Flags = 0;
00317     PingParams.Ip = g_StationIP; /* Fill the station IP address connected to CC3100 */
00318 
00319     /* Ping client connected to CC3100 */
00320     retVal = sl_NetAppPingStart((SlPingStartCommand_t*)&PingParams, SL_AF_INET,
00321                        (SlPingReport_t*)&Report, SimpleLinkPingReport);
00322     if(retVal < 0)
00323         LOOP_FOREVER();
00324 
00325     /* Wait */
00326     while(!IS_PING_DONE(g_Status)) { _SlNonOsMainLoopTask(); }
00327 
00328     if (0 == g_PingPacketsRecv)
00329     {
00330         printf(" A STATION couldn't connect to the device \n\r");
00331         ASSERT_ON_ERROR(LAN_CONNECTION_FAILED);
00332     }
00333 
00334     printf(" Device and the station are successfully connected \n\r");
00335     return SUCCESS;
00336 }
00337 
00338 
00339 /*! 
00340     \brief This function configure the SimpleLink device in its default state. It:
00341            - Sets the mode to STATION
00342            - Configures connection policy to Auto and AutoSmartConfig
00343            - Deletes all the stored profiles
00344            - Enables DHCP
00345            - Disables Scan policy
00346            - Sets Tx power to maximum
00347            - Sets power policy to normal
00348            - Unregisters mDNS services
00349            - Remove all filters
00350 
00351     \param[in]      none
00352 
00353     \return         On success, zero is returned. On error, negative is returned
00354 */
00355 static signed int configureSimpleLinkToDefaultState()
00356 {
00357     SlVersionFull   ver = {0};
00358     _WlanRxFilterOperationCommandBuff_t   RxFilterIdMask = {0};
00359     unsigned char           val = 1;
00360     unsigned char           configOpt = 0;
00361     unsigned char           configLen = 0;
00362     unsigned char           power = 0;
00363 
00364     signed int          retVal = -1;
00365     signed int          mode = -1;
00366 
00367     mode = sl_Start(0, 0, 0);
00368     ASSERT_ON_ERROR(mode);
00369 
00370     /* If the device is not in station-mode, try configuring it in station-mode */
00371     if (ROLE_STA != mode)
00372     {
00373         if (ROLE_AP == mode)
00374         {
00375             /* If the device is in AP mode, we need to wait for this event before doing anything */
00376             while(!IS_IP_ACQUIRED(g_Status)) { _SlNonOsMainLoopTask(); }
00377         }
00378 
00379         /* Switch to STA role and restart */
00380         retVal = sl_WlanSetMode(ROLE_STA);
00381         ASSERT_ON_ERROR(retVal);
00382 
00383         retVal = sl_Stop(SL_STOP_TIMEOUT);
00384         ASSERT_ON_ERROR(retVal);
00385         
00386         retVal = sl_Start(0, 0, 0);
00387         ASSERT_ON_ERROR(retVal);
00388 
00389         /* Check if the device is in station again */
00390         if (ROLE_STA != retVal)
00391         {
00392             /* We don't want to proceed if the device is not coming up in station-mode */
00393             ASSERT_ON_ERROR(DEVICE_NOT_IN_STATION_MODE);
00394         }
00395     }
00396 
00397     /* Get the device's version-information */
00398     configOpt = SL_DEVICE_GENERAL_VERSION;
00399     configLen = sizeof(ver);
00400     retVal = sl_DevGet(SL_DEVICE_GENERAL_CONFIGURATION, &configOpt, &configLen, (unsigned char *)(&ver));
00401     ASSERT_ON_ERROR(retVal);
00402 
00403     /* Set connection policy to Auto + SmartConfig (Device's default connection policy) */
00404     retVal = sl_WlanPolicySet(SL_POLICY_CONNECTION, SL_CONNECTION_POLICY(1, 0, 0, 0, 1), NULL, 0);
00405     ASSERT_ON_ERROR(retVal);
00406 
00407     /* Remove all profiles */
00408     retVal = sl_WlanProfileDel(0xFF);
00409     ASSERT_ON_ERROR(retVal);
00410 
00411     /*
00412      * Device in station-mode. Disconnect previous connection if any
00413      * The function returns 0 if 'Disconnected done', negative number if already disconnected
00414      * Wait for 'disconnection' event if 0 is returned, Ignore other return-codes
00415      */
00416     retVal = sl_WlanDisconnect();
00417     if(0 == retVal)
00418     {
00419         /* Wait */
00420         while(IS_CONNECTED(g_Status)) { _SlNonOsMainLoopTask(); }
00421     }
00422 
00423     /* Enable DHCP client*/
00424     retVal = sl_NetCfgSet(SL_IPV4_STA_P2P_CL_DHCP_ENABLE,1,1,&val);
00425     ASSERT_ON_ERROR(retVal);
00426 
00427     /* Disable scan */
00428     configOpt = SL_SCAN_POLICY(0);
00429     retVal = sl_WlanPolicySet(SL_POLICY_SCAN , configOpt, NULL, 0);
00430     ASSERT_ON_ERROR(retVal);
00431 
00432     /* Set Tx power level for station mode
00433        Number between 0-15, as dB offset from maximum power - 0 will set maximum power */
00434     power = 0;
00435     retVal = sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID, WLAN_GENERAL_PARAM_OPT_STA_TX_POWER, 1, (unsigned char *)&power);
00436     ASSERT_ON_ERROR(retVal);
00437 
00438     /* Set PM policy to normal */
00439     retVal = sl_WlanPolicySet(SL_POLICY_PM , SL_NORMAL_POLICY, NULL, 0);
00440     ASSERT_ON_ERROR(retVal);
00441 
00442     /* Unregister mDNS services */
00443     retVal = sl_NetAppMDNSUnRegisterService(0, 0);
00444     ASSERT_ON_ERROR(retVal);
00445 
00446     /* Remove  all 64 filters (8*8) */
00447     pal_Memset(RxFilterIdMask.FilterIdMask, 0xFF, 8);
00448     retVal = sl_WlanRxFilterSet(SL_REMOVE_RX_FILTER, (unsigned char *)&RxFilterIdMask,
00449                        sizeof(_WlanRxFilterOperationCommandBuff_t ));
00450     ASSERT_ON_ERROR(retVal);
00451 
00452     retVal = sl_Stop(SL_STOP_TIMEOUT);
00453     ASSERT_ON_ERROR(retVal);
00454 
00455     retVal = initializeAppVariables();
00456     ASSERT_ON_ERROR(retVal);
00457 
00458     return retVal; /* Success */
00459 }
00460 
00461 /*!
00462     \brief This function initializes the application variables
00463 
00464     \param[in]  None
00465 
00466     \return     0 on success, negative error-code on error
00467 */
00468 static signed int initializeAppVariables()
00469 {
00470     //g_Status = 0;
00471     //g_PingPacketsRecv = 0;
00472     //g_StationIP = 0;
00473 
00474     return SUCCESS;
00475 }
00476 
00477 /*!
00478     \brief This function displays the application's banner
00479 
00480     \param      None
00481 
00482     \return     None
00483 */
00484 static void displayBanner()
00485 {
00486     printf("\n\r\n\r");
00487     printf(" Getting started with WLAN access-point application - Version ");
00488     printf("%s",APPLICATION_VERSION);
00489     printf("\n\r*******************************************************************\n\r");
00490 }
00491