TI's MQTT Demo with freertos CM4F

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