TI's CC3100. A test demo with very little testing done!

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