TI's CC3100 websocket camera demo with Arducam mini ov5642 and freertos. Should work with other M3's. Work in progress test demo.

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