Port of TI's CC3100 Websock camera demo. Using FreeRTOS, mbedTLS, also parts of Arducam for cams ov5642 and 0v2640. Can also use MT9D111. Work in progress. Be warned some parts maybe a bit flacky. This is for Seeed Arch max only, for an M3, see the demo for CM3 using the 0v5642 aducam mini.

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers cc3100.cpp Source File

cc3100.cpp

00001 /*
00002 * device.c - CC31xx/CC32xx Host Driver Implementation
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 
00039 /*****************************************************************************/
00040 /* Include files                                                             */
00041 /*****************************************************************************/
00042 #include "cc3100_simplelink.h"
00043 #include "cc3100_protocol.h"
00044 #include "cc3100_sl_common.h"
00045 #include "cc3100.h"
00046 
00047 #include "fPtr_func.h"
00048 #include "cli_uart.h"
00049 #include "osi.h"
00050 #include "Led_config.h"
00051 
00052 namespace mbed_cc3100 { 
00053 
00054     uint32_t  g_PingPacketsRecv;
00055     uint32_t  g_GatewayIP;
00056     uint32_t  g_StationIP;
00057     uint32_t  g_DestinationIP;
00058     uint32_t  g_BytesReceived; // variable to store the file size 
00059     uint32_t  g_Status;
00060     uint8_t   g_buff[MAX_BUFF_SIZE+1];
00061     int32_t   g_SockID;
00062         
00063 
00064 //#ifndef SL_PLATFORM_MULTI_THREADED
00065 #if (!defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN))
00066 cc3100::cc3100(PinName button1_irq, PinName button2_irq, PinName cc3100_irq, PinName cc3100_nHIB, PinName cc3100_cs, SPI cc3100_spi)
00067     : _spi(button1_irq, button2_irq, cc3100_irq, cc3100_nHIB, cc3100_cs, cc3100_spi, _driver),
00068       _driver(_spi, _nonos, _netapp, _flowcont), _nonos(_driver), _wlan(_driver, _wlan_filters),
00069       _wlan_filters(_driver), _netapp(_driver, _nonos), _fs(_driver), _netcfg(_driver),
00070       _socket(_driver, _nonos), _flowcont(_driver, _nonos)       
00071 {
00072 
00073 }
00074 #else
00075 cc3100::cc3100(PinName button1_irq, PinName button2_irq, PinName cc3100_irq, PinName cc3100_nHIB, PinName cc3100_cs, SPI cc3100_spi)
00076     : _spi(button1_irq, button2_irq, cc3100_irq, cc3100_nHIB, cc3100_cs, cc3100_spi, _driver),
00077       _driver(_spi, _netapp, _flowcont), _wlan(_driver, _wlan_filters),
00078       _wlan_filters(_driver), _netapp(_driver), _fs(_driver), _netcfg(_driver),
00079       _socket(_driver), _flowcont(_driver)       
00080 {
00081 
00082 }
00083 #endif
00084 
00085 cc3100::~cc3100()
00086 {
00087 
00088 }
00089 
00090 /*!
00091     \brief This function initializes the application variables
00092 
00093     \param[in]  None
00094 
00095     \return     0 on success, negative error-code on error
00096 */
00097 int32_t cc3100::initializeAppVariables()
00098 {
00099     
00100     g_Status = 0;
00101     g_PingPacketsRecv = 0;
00102     g_StationIP = 0;
00103     g_GatewayIP = 0;
00104     g_DestinationIP = 0;
00105     g_BytesReceived = 0; /* variable to store the file size */
00106     g_SockID = 0;
00107     memset(g_buff, 0, sizeof(g_buff));
00108 
00109     return SUCCESS;
00110 }
00111     
00112 /*!
00113     \brief Disconnecting from a WLAN Access point
00114 
00115     This function disconnects from the connected AP
00116 
00117     \param[in]      None
00118 
00119     \return         none
00120 
00121     \note
00122 
00123     \warning        If the WLAN disconnection fails, we will be stuck in this function forever.
00124 */
00125 int32_t cc3100::disconnectFromAP()
00126 {
00127     int32_t retVal = -1;
00128 
00129     /*
00130      * The function returns 0 if 'Disconnected done', negative number if already disconnected
00131      * Wait for 'disconnection' event if 0 is returned, Ignore other return-codes
00132      */
00133     retVal = _wlan.sl_WlanDisconnect();
00134     if(0 == retVal)
00135     {
00136         /* Wait */
00137 //#ifndef SL_PLATFORM_MULTI_THREADED
00138 #if (!defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN))         
00139         while(IS_CONNECTED(g_Status,STATUS_BIT_CONNECTION)) { _nonos._SlNonOsMainLoopTask(); }
00140 #endif        
00141     }
00142 
00143     return SUCCESS;
00144 }
00145 
00146 int32_t cc3100::Network_AP_InitDriver(){
00147     
00148     SlPingStartCommand_t PingParams = {0};
00149     SlPingReport_t Report = {0};
00150 
00151     uint8_t SecType = 0;
00152     int32_t role = ROLE_STA;
00153     int32_t retVal = -1;
00154     
00155     /*
00156      * Assumption is that the device is configured in station mode already
00157      * and it is in its default state
00158      */
00159     role = sl_Start(0, 0, 0);
00160     if (ROLE_AP == role) {
00161         /* If the device is in AP mode, we need to wait for this event before doing anything */
00162 #if (!defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN))        
00163         while(!IS_IP_ACQUIRED(g_Status,STATUS_BIT_IP_ACQUIRED)) {
00164             _nonos._SlNonOsMainLoopTask();
00165         }
00166 #endif        
00167     } else {
00168         /* Configure CC3100 to start in AP mode */
00169         retVal = _wlan.sl_WlanSetMode(ROLE_AP);
00170         if(retVal < 0)
00171             LOOP_FOREVER();
00172             
00173         /* Configure the SSID of the CC3100 */
00174         retVal = _wlan.sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_SSID,
00175                 strlen(SSID_AP_MODE), (uint8_t *)SSID_AP_MODE);
00176         if(retVal < 0)
00177             LOOP_FOREVER();
00178 
00179         SecType = SEC_TYPE_AP_MODE;
00180         /* Configure the Security parameter the AP mode */
00181         retVal = _wlan.sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_SECURITY_TYPE, 1, (uint8_t *)&SecType);
00182         if(retVal < 0)
00183             LOOP_FOREVER();
00184 
00185         retVal = _wlan.sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_PASSWORD, strlen(PASSWORD_AP_MODE), (uint8_t *)PASSWORD_AP_MODE);
00186         if(retVal < 0)
00187             LOOP_FOREVER();    
00188 
00189         retVal = sl_Stop(SL_STOP_TIMEOUT);
00190         if(retVal < 0)
00191             LOOP_FOREVER();
00192 
00193         CLR_STATUS_BIT(g_Status, STATUS_BIT_IP_ACQUIRED);
00194 
00195         role = sl_Start(0, 0, 0);
00196         if (ROLE_AP == role) {
00197 #if (!defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN))            
00198             /* If the device is in AP mode, we need to wait for this event before doing anything */
00199             while(!IS_IP_ACQUIRED(g_Status,STATUS_BIT_IP_ACQUIRED)) {
00200                 _nonos._SlNonOsMainLoopTask();
00201             }
00202 #endif            
00203         } else {
00204             printf(" Device couldn't be configured in AP mode \n\r");
00205             LOOP_FOREVER();
00206         }
00207     }
00208     printf(" Device started as Access Point\r\n");  
00209     return 0;
00210 }   
00211 
00212 //*****************************************************************************
00213 //
00214 //! Network_IF_InitDriver
00215 //! The function initializes a CC3200 device and triggers it to start operation
00216 //!  
00217 //! \param  uiMode (device mode in which device will be configured)
00218 //!  
00219 //! \return 0 : sucess, -ve : failure
00220 //
00221 //*****************************************************************************
00222 int32_t cc3100::Network_IF_InitDriver(uint32_t uiMode)
00223 {
00224     int32_t lRetVal = -1;
00225     // Reset CC3200 Network State Machine
00226     initializeAppVariables();
00227     //
00228     // Following function configure the device to default state by cleaning
00229     // the persistent settings stored in NVMEM (viz. connection profiles &
00230     // policies, power policy etc)
00231     //
00232     // Applications may choose to skip this step if the developer is sure
00233     // that the device is in its default state at start of application
00234     //
00235     // Note that all profiles and persistent settings that were done on the
00236     // device will be lost
00237     //
00238     
00239     lRetVal = configureSimpleLinkToDefaultState();
00240     if(lRetVal < 0)
00241     {
00242         if (DEVICE_NOT_IN_STATION_MODE == lRetVal)
00243            Uart_Write((uint8_t*)"Failed to configure the device in its default state \n\r");
00244 
00245         LOOP_FOREVER();
00246     }
00247 
00248     Uart_Write((uint8_t*)"Device is configured in default state \n\r");
00249 
00250     //
00251     // Assumption is that the device is configured in station mode already
00252     // and it is in its default state
00253     //
00254 
00255     lRetVal = sl_Start(0, 0, 0);
00256 
00257     if (lRetVal < 0 || lRetVal != ROLE_STA)
00258     {
00259         Uart_Write((uint8_t*)"Failed to start the device \n\r");
00260         LOOP_FOREVER();
00261     }
00262 
00263     Uart_Write((uint8_t*)"Started SimpleLink Device: STA Mode\n\r");
00264 
00265     if(uiMode == ROLE_AP)
00266     {
00267         Uart_Write((uint8_t*)"Switching to AP mode on application request\n\r");
00268         // Switch to AP role and restart
00269         lRetVal = _wlan.sl_WlanSetMode(uiMode);        
00270         ASSERT_ON_ERROR(lRetVal);
00271 
00272         lRetVal = sl_Stop(0xFF);
00273 
00274         lRetVal = sl_Start(0, 0, 0);
00275         ASSERT_ON_ERROR(lRetVal);
00276 
00277         // Check if the device is up in AP Mode
00278         if (ROLE_AP == lRetVal)
00279         {
00280             // If the device is in AP mode, we need to wait for this event
00281             // before doing anything
00282             while(!IS_IP_ACQUIRED(g_Status,STATUS_BIT_IP_ACQUIRED))
00283             {
00284                     //Turn RED LED On
00285             GPIO_IF_LedOn(MCU_RED_LED_GPIO);
00286             osi_Sleep(50);
00287 
00288             //Turn RED LED Off
00289             GPIO_IF_LedOff(MCU_RED_LED_GPIO);
00290             osi_Sleep(50);
00291 
00292 //#ifndef SL_PLATFORM_MULTI_THREADED
00293 #if (!defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN))
00294               _nonos._SlNonOsMainLoopTask();
00295 #else
00296               osi_Sleep(1);
00297 #endif
00298             }
00299         }
00300         else
00301         {
00302             // We don't want to proceed if the device is not coming up in AP-mode
00303             ASSERT_ON_ERROR(DEVICE_NOT_IN_AP_MODE);
00304         }
00305 
00306         Uart_Write((uint8_t*)"Re-started SimpleLink Device: AP Mode\n\r");
00307     }
00308     else if(uiMode == ROLE_P2P)
00309     {
00310         Uart_Write((uint8_t*)"Switching to P2P mode on application request\n\r");
00311         // Switch to AP role and restart
00312         lRetVal = _wlan.sl_WlanSetMode(uiMode);
00313         ASSERT_ON_ERROR(lRetVal);
00314 
00315         lRetVal = sl_Stop(0xFF);
00316 
00317         lRetVal = sl_Start(0, 0, 0);
00318         ASSERT_ON_ERROR(lRetVal);
00319 
00320         // Check if the device is in station again
00321         if (ROLE_P2P != lRetVal)
00322         {
00323             // We don't want to proceed if the device is not coming up in P2P-mode
00324             ASSERT_ON_ERROR(DEVICE_NOT_IN_P2P_MODE);
00325         }
00326 
00327         Uart_Write((uint8_t*)"Re-started SimpleLink Device: P2P Mode\n\r");
00328     }
00329     else
00330     {
00331         // Device already started in STA-Mode
00332     }
00333     return 0;
00334 }     
00335 
00336 /*!
00337     \brief This function configure the SimpleLink device in its default state. It:
00338            - Sets the mode to STATION
00339            - Configures connection policy to Auto and AutoSmartConfig
00340            - Deletes all the stored profiles
00341            - Enables DHCP
00342            - Disables Scan policy
00343            - Sets Tx power to maximum
00344            - Sets power policy to normal
00345            - Unregisters mDNS services
00346            - Remove all filters
00347 
00348     \param[in]      none
00349 
00350     \return         On success, zero is returned. On error, negative is returned
00351 */
00352 int32_t cc3100::configureSimpleLinkToDefaultState()
00353 {
00354     SlVersionFull   ver = {0};
00355     _WlanRxFilterOperationCommandBuff_t   RxFilterIdMask = {0};
00356     
00357     uint8_t           val = 1;
00358     uint8_t           configOpt = 0;
00359     uint8_t           configLen = 0;
00360     uint8_t           power = 0;
00361 
00362     int32_t          retVal = -1;
00363     int32_t          role = -1;
00364 
00365     role = sl_Start(0, 0, 0);
00366     ASSERT_ON_ERROR(role);
00367 
00368     /* If the device is not in station-mode, try configuring it in station-mode */
00369     if (ROLE_STA != role) {
00370         if (ROLE_AP == role) {
00371             /* If the device is in AP mode, we need to wait for this event before doing anything */
00372 //#ifndef SL_PLATFORM_MULTI_THREADED
00373 #if (!defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN))            
00374             while(!IS_IP_ACQUIRED(g_Status,STATUS_BIT_IP_ACQUIRED)) {
00375                 _nonos._SlNonOsMainLoopTask();
00376             }
00377 #endif            
00378         }
00379        
00380         /* Switch to STA role and restart */
00381         retVal = _wlan.sl_WlanSetMode(ROLE_STA);
00382         ASSERT_ON_ERROR(retVal);
00383     
00384         retVal = sl_Stop(SL_STOP_TIMEOUT);
00385         ASSERT_ON_ERROR(retVal);
00386     
00387         retVal = sl_Start(0, 0, 0);
00388         ASSERT_ON_ERROR(retVal);
00389     
00390         /* Check if the device is in station again */
00391         if (ROLE_STA != retVal) {
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, (uint8_t *)(&ver));
00401     ASSERT_ON_ERROR(retVal);
00402     
00403     /* Set connection policy to Auto + SmartConfig (Device's default connection policy) */
00404     retVal = _wlan.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 = _wlan.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 = _wlan.sl_WlanDisconnect();
00417     if(0 == retVal) {
00418         /* Wait */
00419 //#ifndef SL_PLATFORM_MULTI_THREADED
00420 #if (!defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN))        
00421         while(IS_CONNECTED(g_Status,STATUS_BIT_CONNECTION)) {
00422             _nonos._SlNonOsMainLoopTask();
00423         }
00424 #endif        
00425     }
00426     
00427     /* Enable DHCP client*/
00428     retVal = _netcfg.sl_NetCfgSet(SL_IPV4_STA_P2P_CL_DHCP_ENABLE,1,1,&val);
00429     ASSERT_ON_ERROR(retVal);
00430     
00431     /* Disable scan */
00432     configOpt = SL_SCAN_POLICY(0);
00433     retVal = _wlan.sl_WlanPolicySet(SL_POLICY_SCAN , configOpt, NULL, 0);
00434     ASSERT_ON_ERROR(retVal);
00435     
00436     /* Set Tx power level for station mode
00437        Number between 0-15, as dB offset from maximum power - 0 will set maximum power */
00438     power = 0;
00439     retVal = _wlan.sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID, WLAN_GENERAL_PARAM_OPT_STA_TX_POWER, 1, (uint8_t *)&power);
00440     ASSERT_ON_ERROR(retVal);
00441 
00442     /* Set PM policy to normal */
00443     retVal = _wlan.sl_WlanPolicySet(SL_POLICY_PM , SL_NORMAL_POLICY, NULL, 0);
00444     ASSERT_ON_ERROR(retVal);
00445 
00446     /* Unregister mDNS services */
00447     retVal = _netapp.sl_NetAppMDNSUnRegisterService(0, 0);
00448     ASSERT_ON_ERROR(retVal);
00449 
00450     /* Remove  all 64 filters (8*8) */
00451     memset(RxFilterIdMask.FilterIdMask, 0xFF, 8);
00452 
00453     retVal = _wlan_filters.sl_WlanRxFilterSet(SL_REMOVE_RX_FILTER, (uint8_t *)&RxFilterIdMask,
00454              sizeof(_WlanRxFilterOperationCommandBuff_t ));
00455     ASSERT_ON_ERROR(retVal);
00456 
00457     retVal = sl_Stop(SL_STOP_TIMEOUT);
00458     ASSERT_ON_ERROR(retVal);
00459 
00460     retVal = initializeAppVariables();
00461     ASSERT_ON_ERROR(retVal);
00462 
00463     return retVal; /* Success */
00464 }
00465 
00466 /*!
00467     \brief Create UDP socket to communicate with server.
00468 
00469     \param[in]      none
00470 
00471     \return         Socket descriptor for success otherwise negative
00472 
00473     \warning
00474 */
00475 int32_t cc3100::createUDPConnection()
00476 {
00477     int32_t sd = 0;
00478 
00479     sd = _socket.sl_Socket(SL_AF_INET, SL_SOCK_DGRAM, IPPROTO_UDP);
00480     if( sd < 0 )
00481     {
00482         Uart_Write((uint8_t *)"Error creating socket\n\r\n\r");
00483     }
00484 
00485     return sd;
00486 }   
00487 
00488 /*!
00489     \brief Create connection with server.
00490 
00491     This function opens a socket and create the endpoint communication with server
00492 
00493     \param[in]      DestinationIP - IP address of the server
00494 
00495     \return         socket id for success and negative for error
00496 */
00497 int32_t cc3100::createConnection(uint32_t DestinationIP)
00498 {
00499     SlSockAddrIn_t  Addr = {0};
00500     int32_t           Status = 0;
00501     int32_t           AddrSize = 0;
00502     int32_t           SockID = 0;
00503 
00504     Addr.sin_family = SL_AF_INET;
00505     Addr.sin_port = _socket.sl_Htons(80);
00506     Addr.sin_addr.s_addr = _socket.sl_Htonl(DestinationIP);
00507 
00508     AddrSize = sizeof(SlSockAddrIn_t);
00509 
00510     SockID = _socket.sl_Socket(SL_AF_INET,SL_SOCK_STREAM, 0);
00511     ASSERT_ON_ERROR(SockID);
00512 
00513     Status = _socket.sl_Connect(SockID, ( SlSockAddr_t *)&Addr, AddrSize);
00514     if (Status < 0)
00515     {
00516         _socket.sl_Close(SockID);
00517         ASSERT_ON_ERROR(Status);
00518     }
00519 
00520     return SockID;
00521 }
00522 
00523 /*!
00524     \brief Convert hex to decimal base
00525 
00526     \param[in]      ptr - pointer to string containing number in hex
00527 
00528     \return         number in decimal base
00529 
00530 */
00531 int32_t cc3100::hexToi(unsigned char *ptr)
00532 {
00533     uint32_t result = 0;
00534     uint32_t len = 0;
00535 
00536     int32_t  idx = -1;
00537 
00538     len = strlen((const char*) ptr);
00539 
00540     /* convert characters to upper case */
00541     for(idx = 0; ptr[idx] != '\0'; ++idx)
00542     {
00543         if( (ptr[idx] >= 'a') &&
00544             (ptr[idx] <= 'f') )
00545         {
00546             ptr[idx] -= 32;         /* Change case - ASCII 'a' = 97, 'A' = 65 => 97-65 = 32 */
00547         }
00548     }
00549 
00550     for(idx = 0; ptr[idx] != '\0'; ++idx)
00551     {
00552         if(ptr[idx] >= '0' && ptr[idx] <= '9')
00553         {
00554             /* Converting '0' to '9' to their decimal value */
00555             result += (ptr[idx] - '0') * (1 << (4 * (len - 1 - idx)));
00556         }
00557         else if(ptr[idx] >= 'A' && ptr[idx] <= 'F')
00558         {
00559             /* Converting hex 'A' to 'F' to their decimal value */
00560             result += (ptr[idx] - 55) * (1 << (4 * (len -1 - idx))); /* .i.e. 'A' - 55 = 10, 'F' - 55 = 15 */
00561         }
00562         else
00563         {
00564             ASSERT_ON_ERROR(INVALID_HEX_STRING);
00565         }
00566     }
00567 
00568     return result;
00569 }
00570 
00571 /*!
00572     \brief Calculate the file chunk size
00573 
00574     \param[in]      len - pointer to length of the data in the buffer
00575     \param[in]      p_Buff - pointer to pointer of buffer containing data
00576     \param[out]     chunk_size - pointer to variable containing chunk size
00577 
00578     \return         0 for success, -ve for error
00579 
00580 */
00581 int32_t cc3100::getChunkSize(int32_t *len, uint8_t **p_Buff, uint32_t *chunk_size)
00582 {
00583     int32_t   idx = -1;
00584     unsigned char   lenBuff[10];
00585 
00586     idx = 0;
00587     memset(lenBuff, 0, sizeof(lenBuff));
00588     while(*len >= 0 && **p_Buff != 13) /* check for <CR> */
00589     {
00590         if(0 == *len)
00591         {
00592             memset(g_buff, 0, sizeof(g_buff));
00593             *len = _socket.sl_Recv(g_SockID, &g_buff[0], MAX_BUFF_SIZE, 0);
00594             if(*len <= 0)
00595                 ASSERT_ON_ERROR(TCP_RECV_ERROR);
00596 
00597             *p_Buff = g_buff;
00598         }
00599 
00600         lenBuff[idx] = **p_Buff;
00601         idx++;
00602         (*p_Buff)++;
00603         (*len)--;
00604     }
00605 
00606     (*p_Buff) += 2; /* skip <CR><LF> */
00607     (*len) -= 2;
00608     *chunk_size = hexToi(lenBuff);
00609 
00610     return SUCCESS;
00611 }
00612 
00613 /*!
00614     \brief Obtain the file from the server
00615 
00616     This function requests the file from the server and save it on serial flash.
00617     To request a different file for different user needs to modify the
00618     PREFIX_BUFFER and POST_BUFFER macros.
00619 
00620     \param[in]      None
00621 
00622     \return         0 for success and negative for error
00623 
00624 */
00625 /*
00626 int32_t cc3100::getFile()
00627 {
00628     uint32_t Token = 0;
00629     uint32_t recv_size = 0;
00630     uint8_t *pBuff = 0;
00631     uint8_t eof_detected = 0;
00632     uint8_t isChunked = 0;
00633 
00634     int32_t transfer_len = -1;
00635     int32_t retVal = -1;
00636     int32_t fileHandle = -1;
00637 
00638     memset(g_buff, 0, sizeof(g_buff));
00639 
00640     //Puts together the HTTP GET string.
00641     strcpy((char*)g_buff, PREFIX_BUFFER);
00642     strcat((char*)g_buff, POST_BUFFER);
00643 
00644     //Send the HTTP GET string to the opened TCP/IP socket.
00645     transfer_len = _socket.sl_Send(g_SockID, g_buff, strlen((const char*)g_buff), 0);
00646 
00647     if (transfer_len < 0)
00648     {
00649         // error 
00650         printf(" Socket Send Error\r\n");
00651         ASSERT_ON_ERROR(TCP_SEND_ERROR);
00652     }
00653 
00654     memset(g_buff, 0, sizeof(g_buff));
00655 
00656     //get the reply from the server in buffer.
00657     transfer_len = _socket.sl_Recv(g_SockID, &g_buff[0], MAX_BUFF_SIZE, 0);
00658 
00659     if(transfer_len <= 0)
00660         ASSERT_ON_ERROR(TCP_RECV_ERROR);
00661 
00662     // Check for 404 return code 
00663     if(strstr((const char*)g_buff, HTTP_FILE_NOT_FOUND) != 0)
00664     {
00665         printf(" File not found, check the file and try again\r\n");
00666         ASSERT_ON_ERROR(FILE_NOT_FOUND_ERROR);
00667     }
00668 
00669     // if not "200 OK" return error 
00670     if(strstr((const char*)g_buff, HTTP_STATUS_OK) == 0)
00671     {
00672         printf(" Error during downloading the file\r\n");
00673         ASSERT_ON_ERROR(INVALID_SERVER_RESPONSE);
00674     }
00675 
00676     // check if content length is transferred with headers 
00677     pBuff = (uint8_t *)strstr((const char*)g_buff, HTTP_CONTENT_LENGTH);
00678     if(pBuff != 0)
00679     {
00680         // not supported 
00681         printf(" Server response format is not supported\r\n");
00682         ASSERT_ON_ERROR(FORMAT_NOT_SUPPORTED);
00683     }
00684 
00685     // Check if data is chunked 
00686     pBuff = (uint8_t *)strstr((const char*)g_buff, HTTP_TRANSFER_ENCODING);
00687     if(pBuff != 0)
00688     {
00689         pBuff += strlen(HTTP_TRANSFER_ENCODING);
00690         while(*pBuff == SPACE)
00691             pBuff++;
00692 
00693         if(memcmp(pBuff, HTTP_ENCODING_CHUNKED, strlen(HTTP_ENCODING_CHUNKED)) == 0)
00694         {
00695             recv_size = 0;
00696             isChunked = 1;
00697         }
00698     }
00699     else
00700     {
00701         // Check if connection will be closed by after sending data
00702          // In this method the content length is not received and end of
00703          // connection marks the end of data 
00704         pBuff = (uint8_t *)strstr((const char*)g_buff, HTTP_CONNECTION);
00705         if(pBuff != 0)
00706         {
00707             pBuff += strlen(HTTP_CONNECTION);
00708             while(*pBuff == SPACE)
00709                 pBuff++;
00710 
00711             if(memcmp(pBuff, HTTP_ENCODING_CHUNKED, strlen(HTTP_CONNECTION_CLOSE)) == 0)
00712             {
00713                 // not supported 
00714                 printf(" Server response format is not supported\r\n");
00715                 ASSERT_ON_ERROR(FORMAT_NOT_SUPPORTED);
00716             }
00717         }
00718     }
00719 
00720     // "\r\n\r\n" marks the end of headers 
00721     pBuff = (uint8_t *)strstr((const char*)g_buff, HTTP_END_OF_HEADER);
00722     if(pBuff == 0)
00723     {
00724         printf(" Invalid response\r\n");
00725         ASSERT_ON_ERROR(INVALID_SERVER_RESPONSE);
00726     }
00727     // Increment by 4 to skip "\r\n\r\n" 
00728     pBuff += 4;
00729 
00730     // Adjust buffer data length for header size 
00731     transfer_len -= (pBuff - g_buff);
00732 
00733     // If data in chunked format, calculate the chunk size 
00734     if(isChunked == 1)
00735     {
00736         retVal = getChunkSize(&transfer_len, &pBuff, &recv_size);
00737         if(retVal < 0)
00738         {
00739             // Error 
00740             printf(" Problem with connection to server\r\n");
00741             return retVal;
00742         }
00743     }
00744 
00745     // Open file to save the downloaded file 
00746     retVal = _fs.sl_FsOpen((uint8_t *)FILE_NAME,
00747                        FS_MODE_OPEN_WRITE, &Token, &fileHandle);
00748     if(retVal < 0)
00749     {
00750         // File Doesn't exit create a new of 45 KB file 
00751         retVal = _fs.sl_FsOpen((uint8_t *)FILE_NAME,
00752                            _fs.FS_MODE_OPEN_CREATE(SIZE_45K,_FS_FILE_OPEN_FLAG_COMMIT|_FS_FILE_PUBLIC_WRITE),
00753                            &Token, &fileHandle);
00754         if(retVal < 0)
00755         {
00756             printf(" Error during opening the file\r\n");
00757             return retVal;
00758         }
00759     }
00760 
00761     while (0 < transfer_len)
00762     {
00763         // For chunked data recv_size contains the chunk size to be received
00764          // while the transfer_len contains the data in the buffer 
00765         if(recv_size <= transfer_len)
00766         {
00767             // write the recv_size 
00768             retVal = _fs.sl_FsWrite(fileHandle, g_BytesReceived,
00769                     (uint8_t *)pBuff, recv_size);
00770             if(retVal < recv_size)
00771             {
00772                 // Close file without saving 
00773                 retVal = _fs.sl_FsClose(fileHandle, 0, (unsigned char*)"A", 1);
00774                 printf(" Error during writing the file\r\n");
00775                 return FILE_WRITE_ERROR;
00776             }
00777             transfer_len -= recv_size;
00778             g_BytesReceived +=recv_size;
00779             pBuff += recv_size;
00780             recv_size = 0;
00781 
00782             if(isChunked == 1)
00783             {
00784                 // if data in chunked format calculate next chunk size 
00785                 pBuff += 2; // 2 bytes for <CR> <LF> 
00786                 transfer_len -= 2;
00787 
00788                 if(getChunkSize(&transfer_len, &pBuff, &recv_size) < 0)
00789                 {
00790                     // Error 
00791                     break;
00792                 }
00793 
00794                 // if next chunk size is zero we have received the complete file 
00795                 if(recv_size == 0)
00796                 {
00797                     eof_detected = 1;
00798                     break;
00799                 }
00800 
00801                 if(recv_size < transfer_len)
00802                 {
00803                     // Code will enter this section if the new chunk size is less then
00804                      // then the transfer size. This will the last chunk of file received
00805                      
00806                     retVal = _fs.sl_FsWrite(fileHandle, g_BytesReceived,
00807                             (uint8_t *)pBuff, recv_size);
00808                     if(retVal < recv_size)
00809                     {
00810                         // Close file without saving 
00811                         retVal = _fs.sl_FsClose(fileHandle, 0, (unsigned char*)"A", 1);
00812                         printf(" Error during writing the file\r\n");
00813                         return FILE_WRITE_ERROR;
00814                     }
00815                     transfer_len -= recv_size;
00816                     g_BytesReceived +=recv_size;
00817                     pBuff += recv_size;
00818                     recv_size = 0;
00819 
00820                     pBuff += 2; // 2bytes for <CR> <LF> 
00821                     transfer_len -= 2;
00822 
00823                     // Calculate the next chunk size, should be zero 
00824                     if(getChunkSize(&transfer_len, &pBuff, &recv_size) < 0)
00825                     {
00826                         // Error 
00827                         break;
00828                     }
00829 
00830                     // if next chunk size is non zero error 
00831                     if(recv_size != 0)
00832                     {
00833                         // Error 
00834                         break;
00835                     }
00836                     eof_detected = 1;
00837                     break;
00838                 }
00839                 else
00840                 {
00841                     // write data on the file 
00842                     retVal = _fs.sl_FsWrite(fileHandle, g_BytesReceived,
00843                             (uint8_t *)pBuff, transfer_len);
00844                     if(retVal < transfer_len)
00845                     {
00846                         // Close file without saving 
00847                         retVal = _fs.sl_FsClose(fileHandle, 0, (unsigned char*)"A", 1);
00848                         printf(" Error during writing the file\r\n");
00849                         ASSERT_ON_ERROR(FILE_WRITE_ERROR);
00850                     }
00851                     recv_size -= transfer_len;
00852                     g_BytesReceived +=transfer_len;
00853                 }
00854             }
00855             // complete file received exit 
00856             if(recv_size == 0)
00857             {
00858                 eof_detected = 1;
00859                 break;
00860             }
00861         }
00862         else
00863         {
00864             // write data on the file 
00865             retVal = _fs.sl_FsWrite(fileHandle, g_BytesReceived,
00866                                  (uint8_t *)pBuff, transfer_len);
00867             if (retVal < 0)
00868             {
00869                 // Close file without saving 
00870                 retVal = _fs.sl_FsClose(fileHandle, 0, (unsigned char*)"A", 1);
00871                 printf(" Error during writing the file\r\n");
00872                 ASSERT_ON_ERROR(FILE_WRITE_ERROR);
00873             }
00874             g_BytesReceived +=transfer_len;
00875             recv_size -= transfer_len;
00876         }
00877 
00878         memset(g_buff, 0, sizeof(g_buff));
00879 
00880         transfer_len = _socket.sl_Recv(g_SockID, &g_buff[0], MAX_BUFF_SIZE, 0);
00881         if(transfer_len <= 0)
00882             ASSERT_ON_ERROR(TCP_RECV_ERROR);
00883 
00884         pBuff = g_buff;
00885     }
00886 
00887     // If user file has checksum which can be used to verify the temporary
00888      // file then file should be verified
00889      // In case of invalid file (FILE_NAME) should be closed without saving to
00890      // recover the previous version of file 
00891     if(0 > transfer_len || eof_detected == 0)
00892     {
00893         // Close file without saving 
00894         retVal = _fs.sl_FsClose(fileHandle, 0, (unsigned char*)"A", 1);
00895         printf(" Error While File Download\r\n");
00896         ASSERT_ON_ERROR(INVALID_FILE);
00897     }
00898     else
00899     {
00900         // Save and close file 
00901         retVal = _fs.sl_FsClose(fileHandle, 0, 0, 0);
00902         ASSERT_ON_ERROR(retVal);
00903     }
00904 
00905     return SUCCESS;;
00906 }
00907 */
00908 
00909 /*!
00910     \brief Connecting to a WLAN Access point
00911 
00912     This function connects to the required AP (SSID_NAME).
00913     The function will return once we are connected and have acquired IP address
00914 
00915     \param[in]  None
00916 
00917     \return     0 on success, negative error-code on error
00918 
00919     \note
00920 
00921     \warning    If the WLAN connection fails or we don't acquire an IP address,
00922                 We will be stuck in this function forever.
00923 */
00924 int32_t cc3100::establishConnectionWithAP()
00925 {
00926     
00927     SlSecParams_t secParams = {0};
00928     int32_t retVal = 0;
00929 
00930     secParams.Key = (signed char *)PASSKEY;
00931     secParams.KeyLen = strlen(PASSKEY);
00932     secParams.Type = SEC_TYPE;
00933 
00934     retVal = _wlan.sl_WlanConnect((signed char *)SSID_NAME, strlen(SSID_NAME), 0, &secParams, 0);
00935     ASSERT_ON_ERROR(retVal);
00936     
00937     /* Wait */
00938 //#ifndef SL_PLATFORM_MULTI_THREADED 
00939 #if (!defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN))   
00940     while((!IS_CONNECTED(g_Status,STATUS_BIT_CONNECTION)) || (!IS_IP_ACQUIRED(g_Status,STATUS_BIT_IP_ACQUIRED))) { _nonos._SlNonOsMainLoopTask(); }
00941 #endif
00942     return SUCCESS;
00943 }
00944 
00945 /*!
00946     \brief This function checks the LAN connection by pinging the AP's gateway
00947 
00948     \param[in]  None
00949 
00950     \return     0 on success, negative error-code on error
00951 */
00952 int32_t cc3100::checkLanConnection()
00953 {
00954     SlPingStartCommand_t pingParams = {0};
00955     SlPingReport_t pingReport = {0};
00956 
00957     int32_t retVal = -1;
00958 
00959     CLR_STATUS_BIT(g_Status, STATUS_BIT_PING_DONE);
00960     g_PingPacketsRecv = 0;
00961 
00962     /* Set the ping parameters */
00963     pingParams.PingIntervalTime = PING_INTERVAL;
00964     pingParams.PingSize = PING_PKT_SIZE;
00965     pingParams.PingRequestTimeout = PING_TIMEOUT;
00966     pingParams.TotalNumberOfAttempts = PING_ATTEMPTS;
00967     pingParams.Flags = 0;
00968     pingParams.Ip = g_GatewayIP;
00969 
00970     /* Check for LAN connection */
00971     retVal = _netapp.sl_NetAppPingStart( (SlPingStartCommand_t*)&pingParams, SL_AF_INET,
00972                                  (SlPingReport_t*)&pingReport, SimpleLinkPingReport);
00973     ASSERT_ON_ERROR(retVal);
00974 
00975     /* Wait */
00976 //#ifndef SL_PLATFORM_MULTI_THREADED 
00977 #if (!defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN))   
00978     while(!IS_PING_DONE(g_Status,STATUS_BIT_PING_DONE)) { _nonos._SlNonOsMainLoopTask(); }
00979 #endif    
00980 
00981     if(0 == g_PingPacketsRecv)
00982     {
00983         /* Problem with LAN connection */
00984         ASSERT_ON_ERROR(LAN_CONNECTION_FAILED);
00985     }
00986 
00987     /* LAN connection is successful */
00988     return SUCCESS;
00989 }
00990 
00991 /*!
00992     \brief This function checks the internet connection by pinging
00993            the external-host (HOST_NAME)
00994 
00995     \param[in]  None
00996 
00997     \return     0 on success, negative error-code on error
00998 */
00999 int32_t cc3100::checkInternetConnection()
01000 {
01001     SlPingStartCommand_t pingParams = {0};
01002     SlPingReport_t pingReport = {0};
01003 
01004     uint32_t ipAddr = 0;
01005 
01006     int32_t retVal = -1;
01007 
01008     CLR_STATUS_BIT(g_Status, STATUS_BIT_PING_DONE);
01009     g_PingPacketsRecv = 0;
01010 
01011     /* Set the ping parameters */
01012     pingParams.PingIntervalTime = PING_INTERVAL;
01013     pingParams.PingSize = PING_PKT_SIZE;
01014     pingParams.PingRequestTimeout = PING_TIMEOUT;
01015     pingParams.TotalNumberOfAttempts = PING_ATTEMPTS;
01016     pingParams.Flags = 0;
01017     pingParams.Ip = g_GatewayIP;
01018 
01019     /* Check for Internet connection */
01020     retVal = _netapp.sl_NetAppDnsGetHostByName((unsigned char *)HOST_NAME, strlen(HOST_NAME), &ipAddr, SL_AF_INET);
01021     ASSERT_ON_ERROR(retVal);
01022 
01023     /* Replace the ping address to match HOST_NAME's IP address */
01024     pingParams.Ip = ipAddr;
01025 
01026     /* Try to ping HOST_NAME */
01027     retVal = _netapp.sl_NetAppPingStart( (SlPingStartCommand_t*)&pingParams, SL_AF_INET,
01028                                  (SlPingReport_t*)&pingReport, SimpleLinkPingReport);
01029     ASSERT_ON_ERROR(retVal);
01030 
01031     /* Wait */
01032 //#ifndef SL_PLATFORM_MULTI_THREADED
01033 #if (!defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN))    
01034     while(!IS_PING_DONE(g_Status,STATUS_BIT_PING_DONE)) { _nonos._SlNonOsMainLoopTask(); }
01035 #endif    
01036 
01037     if (0 == g_PingPacketsRecv)
01038     {
01039         /* Problem with internet connection*/
01040         ASSERT_ON_ERROR(INTERNET_CONNECTION_FAILED);
01041     }
01042 
01043     /* Internet connection is successful */
01044     return SUCCESS;
01045 }
01046 
01047 const int8_t StartResponseLUT[8] = 
01048 {
01049     ROLE_UNKNOWN_ERR,
01050     ROLE_STA,
01051     ROLE_STA_ERR,
01052     ROLE_AP,
01053     ROLE_AP_ERR,
01054     ROLE_P2P,
01055     ROLE_P2P_ERR,
01056     ROLE_UNKNOWN_ERR    
01057 };
01058     
01059 /*****************************************************************************/
01060 /* Internal functions                                                        */
01061 /*****************************************************************************/
01062 
01063 int16_t cc3100::_sl_GetStartResponseConvert(uint32_t Status)
01064 {
01065     return (int16_t)StartResponseLUT[Status & 0x7];
01066     
01067 }
01068 
01069 /*****************************************************************************/
01070 /* API Functions                                                             */
01071 /*****************************************************************************/
01072 
01073 bool cc3100::IS_PING_DONE(uint32_t status_variable,const uint32_t bit){
01074     
01075         g_Status = status_variable;
01076         
01077         if(0 != (g_Status & ((uint32_t)1L<<(bit)))){
01078             return TRUE;
01079         }else{
01080             return FALSE;
01081         }
01082 }
01083         
01084 bool cc3100::IS_CONNECTED(uint32_t status_variable,const uint32_t bit){
01085     
01086         g_Status = status_variable;
01087         
01088         if(0 != (g_Status & ((uint32_t)1L<<(bit)))){
01089             return TRUE;
01090         }else{
01091             return FALSE;
01092         }
01093 }
01094         
01095 bool cc3100::IS_STA_CONNECTED(uint32_t status_variable,const uint32_t bit){
01096     
01097         g_Status = status_variable;
01098         
01099         if(0 != (g_Status & ((uint32_t)1L<<(bit)))){
01100             return TRUE;
01101         }else{
01102             return FALSE;
01103         }
01104 } 
01105        
01106 bool cc3100::IS_IP_ACQUIRED(uint32_t status_variable,const uint32_t bit){
01107     
01108         g_Status = status_variable;
01109         
01110         if(0 != (g_Status & ((uint32_t)1L<<(bit)))){
01111             return TRUE;
01112         }else{
01113             return FALSE;
01114         }
01115 }
01116         
01117 bool cc3100::IS_IP_LEASED(uint32_t status_variable,const uint32_t bit){
01118     
01119         g_Status = status_variable;
01120         
01121         if(0 != (g_Status & ((uint32_t)1L<<(bit)))){
01122             return TRUE;
01123         }else{
01124             return FALSE;
01125         }
01126 }
01127         
01128 bool cc3100::IS_CONNECTION_FAILED(uint32_t status_variable,const uint32_t bit){
01129         
01130         g_Status = status_variable;
01131         
01132         if(0 != (g_Status & ((uint32_t)1L<<(bit)))){
01133             return TRUE;
01134         }else{
01135             return FALSE;
01136         }
01137 }
01138         
01139 bool cc3100::IS_P2P_NEG_REQ_RECEIVED(uint32_t status_variable,const uint32_t bit){
01140     
01141         g_Status = status_variable;
01142         
01143         if(0 != (g_Status & ((uint32_t)1L<<(bit)))){
01144             return TRUE;
01145         }else{
01146             return FALSE;
01147         }
01148 }
01149         
01150 bool cc3100::IS_SMARTCONFIG_DONE(uint32_t status_variable,const uint32_t bit){
01151     
01152         g_Status = status_variable;
01153         
01154         if(0 != (g_Status & ((uint32_t)1L<<(bit)))){
01155             return TRUE;
01156         }else{
01157             return FALSE;
01158         }
01159 }
01160         
01161 bool cc3100::IS_SMARTCONFIG_STOPPED(uint32_t status_variable,const uint32_t bit){
01162     
01163         g_Status = status_variable;
01164         
01165         if(0 != (g_Status & ((uint32_t)1L<<(bit)))){            
01166             return TRUE;
01167         }else{
01168             return FALSE;           
01169         }        
01170 }
01171 
01172 void cc3100::CLR_STATUS_BIT(uint32_t status_variable, const uint32_t bit){
01173         
01174         g_Status = status_variable;
01175         g_Status &= ~((uint32_t)1L<<(bit));
01176         
01177 }
01178 
01179 void cc3100::SET_STATUS_BIT(uint32_t status_variable, const uint32_t bit){
01180 
01181         g_Status = status_variable;
01182         g_Status |= ((uint32_t)1L<<(bit));
01183         
01184 }
01185 void cc3100::CLR_STATUS_BIT_ALL(uint32_t status_variable){
01186       
01187       g_Status = status_variable;
01188       g_Status = 0;
01189 }      
01190         
01191 /*****************************************************************************/
01192 /* sl_Task                                                                   */
01193 /*****************************************************************************/
01194 #if _SL_INCLUDE_FUNC(sl_Task)
01195 void cc3100::sl_Task(void)
01196 {
01197 #ifdef _SlTaskEntry
01198     _SlTaskEntry();
01199 #endif
01200 }
01201 #endif
01202 
01203 /*****************************************************************************/
01204 /* sl_Start                                                                  */
01205 /*****************************************************************************/
01206 #if _SL_INCLUDE_FUNC(sl_Start)
01207 int16_t cc3100::sl_Start(const void* pIfHdl, int8_t*  pDevName, const P_INIT_CALLBACK pInitCallBack)
01208 {
01209     int16_t ObjIdx = MAX_CONCURRENT_ACTIONS;
01210     InitComplete_t  AsyncRsp;
01211 
01212     /* Perform any preprocessing before enable networking services */
01213     sl_DeviceEnablePreamble();//stub only
01214     
01215     /* ControlBlock init */
01216     _driver._SlDrvDriverCBInit();
01217     
01218     /* open the interface: usually SPI or UART */
01219     if (NULL == pIfHdl) 
01220     {
01221         g_pCB->FD = _spi.spi_Open((int8_t *)pDevName, 0);
01222     } 
01223     else 
01224     {
01225         g_pCB->FD = (_SlFd_t)pIfHdl;
01226     }
01227      
01228     ObjIdx = _driver._SlDrvProtectAsyncRespSetting((uint8_t *)&AsyncRsp, START_STOP_ID, SL_MAX_SOCKETS);
01229     
01230     if (MAX_CONCURRENT_ACTIONS == ObjIdx) 
01231     {
01232         Uart_Write((uint8_t *)"SL_POOL_IS_EMPTY\r\n");
01233         return SL_POOL_IS_EMPTY;
01234     }
01235     
01236     if( g_pCB->FD >= (_SlFd_t)0) {
01237         _spi.CC3100_disable();
01238         
01239         g_pCB->pInitCallback = pInitCallBack;
01240             
01241         _spi.CC3100_enable();
01242         
01243         if (NULL == pInitCallBack) {            
01244             _driver._SlDrvSyncObjWaitForever(&g_pCB->ObjPool[ObjIdx].SyncObj);            
01245             /*release Pool Object*/           
01246             _driver._SlDrvReleasePoolObj(g_pCB->FunctionParams.AsyncExt.ActionIndex);                      
01247             return _sl_GetStartResponseConvert(AsyncRsp.Status);
01248         }
01249         else
01250         {
01251             return SL_RET_CODE_OK;    
01252         }
01253     }
01254     
01255     return SL_BAD_INTERFACE;
01256 
01257 
01258 }
01259 #endif
01260 
01261 /***************************************************************************
01262 _sl_HandleAsync_InitComplete - handles init complete signalling to
01263 a waiting object
01264 ****************************************************************************/
01265 void cc3100::_sl_HandleAsync_InitComplete(void *pVoidBuf)
01266 {
01267 
01268     InitComplete_t *pMsgArgs = (InitComplete_t *)_SL_RESP_ARGS_START(pVoidBuf);
01269 
01270     _driver._SlDrvProtectionObjLockWaitForever();
01271 
01272     if(g_pCB->pInitCallback) {
01273         g_pCB->pInitCallback(_sl_GetStartResponseConvert(pMsgArgs->Status));
01274     } else {
01275         memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(InitComplete_t));        
01276         _driver._SlDrvSyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj);
01277     }
01278     _driver._SlDrvProtectionObjUnLock();
01279 
01280     if(g_pCB->pInitCallback) {
01281         _driver._SlDrvReleasePoolObj(g_pCB->FunctionParams.AsyncExt.ActionIndex);
01282     }
01283 
01284 }
01285 
01286 /*****************************************************************************
01287 sl_stop
01288 ******************************************************************************/
01289 typedef union {
01290     _DevStopCommand_t  Cmd;
01291     _BasicResponse_t   Rsp;
01292 } _SlStopMsg_u;
01293 
01294 const _SlCmdCtrl_t _SlStopCmdCtrl = {
01295     SL_OPCODE_DEVICE_STOP_COMMAND,
01296     sizeof(_DevStopCommand_t),
01297     sizeof(_BasicResponse_t)
01298 };
01299 
01300 #if _SL_INCLUDE_FUNC(sl_Stop)
01301 int16_t cc3100::sl_Stop(const uint16_t timeout)
01302 {
01303     
01304     int16_t RetVal=0;
01305     _SlStopMsg_u      Msg;
01306     _BasicResponse_t  AsyncRsp;
01307     int8_t ObjIdx = MAX_CONCURRENT_ACTIONS;
01308     /* if timeout is 0 the shutdown is forced immediately */
01309     if( 0 == timeout ) {
01310         _spi.registerInterruptHandler(NULL, NULL);
01311         _spi.CC3100_disable();
01312         RetVal = _spi.spi_Close(g_pCB->FD);
01313 
01314     } else {
01315         /* let the device make the shutdown using the defined timeout */
01316         Msg.Cmd.Timeout = timeout;        
01317         ObjIdx = _driver._SlDrvProtectAsyncRespSetting((uint8_t *)&AsyncRsp, START_STOP_ID, SL_MAX_SOCKETS);
01318         
01319       if (MAX_CONCURRENT_ACTIONS == ObjIdx)
01320       {
01321           return SL_POOL_IS_EMPTY;
01322       }
01323 
01324       VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlStopCmdCtrl, &Msg, NULL));
01325 
01326       if(SL_OS_RET_CODE_OK == (int16_t)Msg.Rsp.status)
01327       {
01328          _driver._SlDrvSyncObjWaitForever(&g_pCB->ObjPool[ObjIdx].SyncObj);
01329          Msg.Rsp.status = AsyncRsp.status;
01330          RetVal = Msg.Rsp.status;
01331       }
01332       
01333       _driver._SlDrvReleasePoolObj((uint8_t)ObjIdx);
01334       _spi.registerInterruptHandler(NULL, NULL);
01335       _spi.CC3100_disable();
01336       _spi.spi_Close(g_pCB->FD);
01337      
01338     }
01339     
01340     _driver._SlDrvDriverCBDeinit();
01341 
01342     return RetVal;
01343 }
01344 #endif
01345 
01346 
01347 /*****************************************************************************
01348 sl_EventMaskSet
01349 *****************************************************************************/
01350 typedef union {
01351     _DevMaskEventSetCommand_t       Cmd;
01352     _BasicResponse_t                Rsp;
01353 } _SlEventMaskSetMsg_u;
01354 
01355 #if _SL_INCLUDE_FUNC(sl_EventMaskSet)
01356 const _SlCmdCtrl_t _SlEventMaskSetCmdCtrl = {
01357     SL_OPCODE_DEVICE_EVENTMASKSET,
01358     sizeof(_DevMaskEventSetCommand_t),
01359     sizeof(_BasicResponse_t)
01360 };
01361 
01362 int16_t cc3100::sl_EventMaskSet(uint8_t EventClass , uint32_t Mask)
01363 {
01364     _SlEventMaskSetMsg_u Msg;
01365     Msg.Cmd.group = EventClass;
01366     Msg.Cmd.mask = Mask;
01367 
01368     VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlEventMaskSetCmdCtrl, &Msg, NULL));
01369 
01370     return (int16_t)Msg.Rsp.status;
01371 }
01372 #endif
01373 
01374 /******************************************************************************
01375 sl_EventMaskGet
01376 ******************************************************************************/
01377 typedef union {
01378     _DevMaskEventGetCommand_t       Cmd;
01379     _DevMaskEventGetResponse_t      Rsp;
01380 } _SlEventMaskGetMsg_u;
01381 
01382 #if _SL_INCLUDE_FUNC(sl_EventMaskGet)
01383 const _SlCmdCtrl_t _SlEventMaskGetCmdCtrl = {
01384     SL_OPCODE_DEVICE_EVENTMASKGET,
01385     sizeof(_DevMaskEventGetCommand_t),
01386     sizeof(_DevMaskEventGetResponse_t)
01387 };
01388 
01389 int16_t cc3100::sl_EventMaskGet(uint8_t EventClass, uint32_t *pMask)
01390 {
01391     _SlEventMaskGetMsg_u Msg;
01392 
01393     Msg.Cmd.group = EventClass;
01394 
01395     VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlEventMaskGetCmdCtrl, &Msg, NULL));
01396 
01397     *pMask = Msg.Rsp.mask;
01398     return SL_RET_CODE_OK;
01399 }
01400 #endif
01401 
01402 /******************************************************************************
01403 sl_DevGet
01404 ******************************************************************************/
01405 
01406 typedef union {
01407     _DeviceSetGet_t     Cmd;
01408     _DeviceSetGet_t     Rsp;
01409 } _SlDeviceMsgGet_u;
01410 
01411 #if _SL_INCLUDE_FUNC(sl_DevGet)
01412 const _SlCmdCtrl_t _SlDeviceGetCmdCtrl = {
01413     SL_OPCODE_DEVICE_DEVICEGET,
01414     sizeof(_DeviceSetGet_t),
01415     sizeof(_DeviceSetGet_t)
01416 };
01417 
01418 int32_t cc3100::sl_DevGet(uint8_t DeviceGetId, uint8_t *pOption,uint8_t *pConfigLen, uint8_t *pValues)
01419 {
01420     _SlDeviceMsgGet_u         Msg;
01421     _SlCmdExt_t               CmdExt;
01422     
01423     if (*pConfigLen == 0) {
01424         return SL_EZEROLEN;
01425     }
01426    
01427     if( pOption ) {
01428         _driver._SlDrvResetCmdExt(&CmdExt);
01429         CmdExt.RxPayloadLen = *pConfigLen;
01430         
01431         CmdExt.pRxPayload = (uint8_t *)pValues;
01432         
01433 
01434         Msg.Cmd.DeviceSetId = DeviceGetId;
01435 
01436         Msg.Cmd.Option   = (uint16_t)*pOption;
01437 
01438         VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlDeviceGetCmdCtrl, &Msg, &CmdExt));
01439         
01440         if( pOption ) {
01441             *pOption = (uint8_t)Msg.Rsp.Option;
01442         }
01443         
01444         if (CmdExt.RxPayloadLen < CmdExt.ActualRxPayloadLen) {
01445             *pConfigLen = (uint8_t)CmdExt.RxPayloadLen;
01446             return SL_ESMALLBUF;
01447         } else {
01448             *pConfigLen = (uint8_t)CmdExt.ActualRxPayloadLen;
01449         }
01450         
01451         return (int16_t)Msg.Rsp.Status;
01452     } else {
01453         return -1;
01454     }
01455 }
01456 #endif
01457 
01458 /******************************************************************************
01459 sl_DevSet
01460 ******************************************************************************/
01461 typedef union {
01462     _DeviceSetGet_t    Cmd;
01463     _BasicResponse_t   Rsp;
01464 } _SlDeviceMsgSet_u;
01465 
01466 #if _SL_INCLUDE_FUNC(sl_DevSet)
01467 const _SlCmdCtrl_t _SlDeviceSetCmdCtrl = {
01468     SL_OPCODE_DEVICE_DEVICESET,
01469     sizeof(_DeviceSetGet_t),
01470     sizeof(_BasicResponse_t)
01471 };
01472 
01473 int32_t cc3100::sl_DevSet(const uint8_t DeviceSetId, const uint8_t Option, const uint8_t ConfigLen, const uint8_t *pValues)
01474 {
01475     _SlDeviceMsgSet_u         Msg;
01476     _SlCmdExt_t               CmdExt;
01477     
01478     _driver._SlDrvResetCmdExt(&CmdExt);
01479     CmdExt.TxPayloadLen = (ConfigLen+3) & (~3);
01480     
01481     CmdExt.pTxPayload = (uint8_t *)pValues;
01482     
01483 
01484 
01485     Msg.Cmd.DeviceSetId    = DeviceSetId;
01486     Msg.Cmd.ConfigLen   = ConfigLen;
01487     Msg.Cmd.Option   = Option;
01488 
01489     VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlDeviceSetCmdCtrl, &Msg, &CmdExt));
01490 
01491     return (int16_t)Msg.Rsp.status;
01492 }
01493 #endif
01494 
01495 /******************************************************************************
01496 sl_UartSetMode
01497 ******************************************************************************/
01498 #ifdef SL_IF_TYPE_UART
01499 typedef union {
01500     _DevUartSetModeCommand_t      Cmd;
01501     _DevUartSetModeResponse_t     Rsp;
01502 } _SlUartSetModeMsg_u;
01503 
01504 #if _SL_INCLUDE_FUNC(sl_UartSetMode)
01505 const _SlCmdCtrl_t _SlUartSetModeCmdCtrl = {
01506     SL_OPCODE_DEVICE_SETUARTMODECOMMAND,
01507     sizeof(_DevUartSetModeCommand_t),
01508     sizeof(_DevUartSetModeResponse_t)
01509 };
01510 
01511 int16_t cc3100::sl_UartSetMode(const SlUartIfParams_t* pUartParams)
01512 {
01513     _SlUartSetModeMsg_u Msg;
01514     uint32_t magicCode = 0xFFFFFFFF;
01515 
01516     Msg.Cmd.BaudRate = pUartParams->BaudRate;
01517     Msg.Cmd.FlowControlEnable = pUartParams->FlowControlEnable;
01518 
01519 
01520     VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlUartSetModeCmdCtrl, &Msg, NULL));
01521 
01522     /* cmd response OK, we can continue with the handshake */
01523     if (SL_RET_CODE_OK == Msg.Rsp.status) {
01524         sl_IfMaskIntHdlr();
01525 
01526         /* Close the comm port */
01527         sl_IfClose(g_pCB->FD);
01528 
01529         /* Re-open the comm port */
01530         sl_IfOpen((void * )pUartParams, UART_IF_OPEN_FLAG_RE_OPEN);
01531         sl_IfUnMaskIntHdlr();
01532 
01533         /* send the magic code and wait for the response */
01534         sl_IfWrite(g_pCB->FD, (uint8_t* )&magicCode, 4);
01535 
01536         magicCode = UART_SET_MODE_MAGIC_CODE;
01537         sl_IfWrite(g_pCB->FD, (uint8_t* )&magicCode, 4);
01538 
01539         /* clear magic code */
01540         magicCode = 0;
01541 
01542         /* wait (blocking) till the magic code to be returned from device */
01543         sl_IfRead(g_pCB->FD, (uint8_t* )&magicCode, 4);
01544 
01545         /* check for the received magic code matching */
01546         if (UART_SET_MODE_MAGIC_CODE != magicCode) {
01547             _SL_ASSERT(0);
01548         }
01549     }
01550 
01551     return (int16_t)Msg.Rsp.status;
01552 }
01553 #endif
01554 #endif
01555 
01556 }//namespace
01557 
01558