cc3100_Socket_Wifi_Server with Ethernet Interface not working

Dependencies:   EthernetInterface mbed-rtos mbed

Fork of cc3100_Test_Demo by David Fletcher

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     \brief Create connection with server.
00277 
00278     This function opens a socket and create the endpoint communication with server
00279 
00280     \param[in]      DestinationIP - IP address of the server
00281 
00282     \return         socket id for success and negative for error
00283 */
00284 int32_t cc3100::createConnection(uint32_t DestinationIP)
00285 {
00286     SlSockAddrIn_t  Addr = {0};
00287     int32_t           Status = 0;
00288     int32_t           AddrSize = 0;
00289     int32_t           SockID = 0;
00290 
00291     Addr.sin_family = SL_AF_INET;
00292     Addr.sin_port = _socket.sl_Htons(80);
00293     Addr.sin_addr.s_addr = _socket.sl_Htonl(DestinationIP);
00294 
00295     AddrSize = sizeof(SlSockAddrIn_t);
00296 
00297     SockID = _socket.sl_Socket(SL_AF_INET,SL_SOCK_STREAM, 0);
00298     ASSERT_ON_ERROR(SockID);
00299 
00300     Status = _socket.sl_Connect(SockID, ( SlSockAddr_t *)&Addr, AddrSize);
00301     if (Status < 0)
00302     {
00303         _socket.sl_Close(SockID);
00304         ASSERT_ON_ERROR(Status);
00305     }
00306 
00307     return SockID;
00308 }
00309 
00310 /*!
00311     \brief Convert hex to decimal base
00312 
00313     \param[in]      ptr - pointer to string containing number in hex
00314 
00315     \return         number in decimal base
00316 
00317 */
00318 int32_t cc3100::hexToi(unsigned char *ptr)
00319 {
00320     uint32_t result = 0;
00321     uint32_t len = 0;
00322 
00323     int32_t  idx = -1;
00324 
00325     len = strlen((const char*) ptr);
00326 
00327     /* convert characters to upper case */
00328     for(idx = 0; ptr[idx] != '\0'; ++idx)
00329     {
00330         if( (ptr[idx] >= 'a') &&
00331             (ptr[idx] <= 'f') )
00332         {
00333             ptr[idx] -= 32;         /* Change case - ASCII 'a' = 97, 'A' = 65 => 97-65 = 32 */
00334         }
00335     }
00336 
00337     for(idx = 0; ptr[idx] != '\0'; ++idx)
00338     {
00339         if(ptr[idx] >= '0' && ptr[idx] <= '9')
00340         {
00341             /* Converting '0' to '9' to their decimal value */
00342             result += (ptr[idx] - '0') * (1 << (4 * (len - 1 - idx)));
00343         }
00344         else if(ptr[idx] >= 'A' && ptr[idx] <= 'F')
00345         {
00346             /* Converting hex 'A' to 'F' to their decimal value */
00347             result += (ptr[idx] - 55) * (1 << (4 * (len -1 - idx))); /* .i.e. 'A' - 55 = 10, 'F' - 55 = 15 */
00348         }
00349         else
00350         {
00351             ASSERT_ON_ERROR(INVALID_HEX_STRING);
00352         }
00353     }
00354 
00355     return result;
00356 }
00357 
00358 /*!
00359     \brief Calculate the file chunk size
00360 
00361     \param[in]      len - pointer to length of the data in the buffer
00362     \param[in]      p_Buff - pointer to pointer of buffer containing data
00363     \param[out]     chunk_size - pointer to variable containing chunk size
00364 
00365     \return         0 for success, -ve for error
00366 
00367 */
00368 int32_t cc3100::getChunkSize(int32_t *len, uint8_t **p_Buff, uint32_t *chunk_size)
00369 {
00370     int32_t   idx = -1;
00371     unsigned char   lenBuff[10];
00372 
00373     idx = 0;
00374     memset(lenBuff, 0, sizeof(lenBuff));
00375     while(*len >= 0 && **p_Buff != 13) /* check for <CR> */
00376     {
00377         if(0 == *len)
00378         {
00379             memset(g_buff, 0, sizeof(g_buff));
00380             *len = _socket.sl_Recv(g_SockID, &g_buff[0], MAX_BUFF_SIZE, 0);
00381             if(*len <= 0)
00382                 ASSERT_ON_ERROR(TCP_RECV_ERROR);
00383 
00384             *p_Buff = g_buff;
00385         }
00386 
00387         lenBuff[idx] = **p_Buff;
00388         idx++;
00389         (*p_Buff)++;
00390         (*len)--;
00391     }
00392 
00393     (*p_Buff) += 2; /* skip <CR><LF> */
00394     (*len) -= 2;
00395     *chunk_size = hexToi(lenBuff);
00396 
00397     return SUCCESS;
00398 }
00399 
00400 /*!
00401     \brief Obtain the file from the server
00402 
00403     This function requests the file from the server and save it on serial flash.
00404     To request a different file for different user needs to modify the
00405     PREFIX_BUFFER and POST_BUFFER macros.
00406 
00407     \param[in]      None
00408 
00409     \return         0 for success and negative for error
00410 
00411 */
00412 /*
00413 int32_t cc3100::getFile()
00414 {
00415     uint32_t Token = 0;
00416     uint32_t recv_size = 0;
00417     uint8_t *pBuff = 0;
00418     uint8_t eof_detected = 0;
00419     uint8_t isChunked = 0;
00420 
00421     int32_t transfer_len = -1;
00422     int32_t retVal = -1;
00423     int32_t fileHandle = -1;
00424 
00425     memset(g_buff, 0, sizeof(g_buff));
00426 
00427     //Puts together the HTTP GET string.
00428     strcpy((char*)g_buff, PREFIX_BUFFER);
00429     strcat((char*)g_buff, POST_BUFFER);
00430 
00431     //Send the HTTP GET string to the opened TCP/IP socket.
00432     transfer_len = _socket.sl_Send(g_SockID, g_buff, strlen((const char*)g_buff), 0);
00433 
00434     if (transfer_len < 0)
00435     {
00436         // error 
00437         printf(" Socket Send Error\r\n");
00438         ASSERT_ON_ERROR(TCP_SEND_ERROR);
00439     }
00440 
00441     memset(g_buff, 0, sizeof(g_buff));
00442 
00443     //get the reply from the server in buffer.
00444     transfer_len = _socket.sl_Recv(g_SockID, &g_buff[0], MAX_BUFF_SIZE, 0);
00445 
00446     if(transfer_len <= 0)
00447         ASSERT_ON_ERROR(TCP_RECV_ERROR);
00448 
00449     // Check for 404 return code 
00450     if(strstr((const char*)g_buff, HTTP_FILE_NOT_FOUND) != 0)
00451     {
00452         printf(" File not found, check the file and try again\r\n");
00453         ASSERT_ON_ERROR(FILE_NOT_FOUND_ERROR);
00454     }
00455 
00456     // if not "200 OK" return error 
00457     if(strstr((const char*)g_buff, HTTP_STATUS_OK) == 0)
00458     {
00459         printf(" Error during downloading the file\r\n");
00460         ASSERT_ON_ERROR(INVALID_SERVER_RESPONSE);
00461     }
00462 
00463     // check if content length is transferred with headers 
00464     pBuff = (uint8_t *)strstr((const char*)g_buff, HTTP_CONTENT_LENGTH);
00465     if(pBuff != 0)
00466     {
00467         // not supported 
00468         printf(" Server response format is not supported\r\n");
00469         ASSERT_ON_ERROR(FORMAT_NOT_SUPPORTED);
00470     }
00471 
00472     // Check if data is chunked 
00473     pBuff = (uint8_t *)strstr((const char*)g_buff, HTTP_TRANSFER_ENCODING);
00474     if(pBuff != 0)
00475     {
00476         pBuff += strlen(HTTP_TRANSFER_ENCODING);
00477         while(*pBuff == SPACE)
00478             pBuff++;
00479 
00480         if(memcmp(pBuff, HTTP_ENCODING_CHUNKED, strlen(HTTP_ENCODING_CHUNKED)) == 0)
00481         {
00482             recv_size = 0;
00483             isChunked = 1;
00484         }
00485     }
00486     else
00487     {
00488         // Check if connection will be closed by after sending data
00489          // In this method the content length is not received and end of
00490          // connection marks the end of data 
00491         pBuff = (uint8_t *)strstr((const char*)g_buff, HTTP_CONNECTION);
00492         if(pBuff != 0)
00493         {
00494             pBuff += strlen(HTTP_CONNECTION);
00495             while(*pBuff == SPACE)
00496                 pBuff++;
00497 
00498             if(memcmp(pBuff, HTTP_ENCODING_CHUNKED, strlen(HTTP_CONNECTION_CLOSE)) == 0)
00499             {
00500                 // not supported 
00501                 printf(" Server response format is not supported\r\n");
00502                 ASSERT_ON_ERROR(FORMAT_NOT_SUPPORTED);
00503             }
00504         }
00505     }
00506 
00507     // "\r\n\r\n" marks the end of headers 
00508     pBuff = (uint8_t *)strstr((const char*)g_buff, HTTP_END_OF_HEADER);
00509     if(pBuff == 0)
00510     {
00511         printf(" Invalid response\r\n");
00512         ASSERT_ON_ERROR(INVALID_SERVER_RESPONSE);
00513     }
00514     // Increment by 4 to skip "\r\n\r\n" 
00515     pBuff += 4;
00516 
00517     // Adjust buffer data length for header size 
00518     transfer_len -= (pBuff - g_buff);
00519 
00520     // If data in chunked format, calculate the chunk size 
00521     if(isChunked == 1)
00522     {
00523         retVal = getChunkSize(&transfer_len, &pBuff, &recv_size);
00524         if(retVal < 0)
00525         {
00526             // Error 
00527             printf(" Problem with connection to server\r\n");
00528             return retVal;
00529         }
00530     }
00531 
00532     // Open file to save the downloaded file 
00533     retVal = _fs.sl_FsOpen((uint8_t *)FILE_NAME,
00534                        FS_MODE_OPEN_WRITE, &Token, &fileHandle);
00535     if(retVal < 0)
00536     {
00537         // File Doesn't exit create a new of 45 KB file 
00538         retVal = _fs.sl_FsOpen((uint8_t *)FILE_NAME,
00539                            _fs.FS_MODE_OPEN_CREATE(SIZE_45K,_FS_FILE_OPEN_FLAG_COMMIT|_FS_FILE_PUBLIC_WRITE),
00540                            &Token, &fileHandle);
00541         if(retVal < 0)
00542         {
00543             printf(" Error during opening the file\r\n");
00544             return retVal;
00545         }
00546     }
00547 
00548     while (0 < transfer_len)
00549     {
00550         // For chunked data recv_size contains the chunk size to be received
00551          // while the transfer_len contains the data in the buffer 
00552         if(recv_size <= transfer_len)
00553         {
00554             // write the recv_size 
00555             retVal = _fs.sl_FsWrite(fileHandle, g_BytesReceived,
00556                     (uint8_t *)pBuff, recv_size);
00557             if(retVal < recv_size)
00558             {
00559                 // Close file without saving 
00560                 retVal = _fs.sl_FsClose(fileHandle, 0, (unsigned char*)"A", 1);
00561                 printf(" Error during writing the file\r\n");
00562                 return FILE_WRITE_ERROR;
00563             }
00564             transfer_len -= recv_size;
00565             g_BytesReceived +=recv_size;
00566             pBuff += recv_size;
00567             recv_size = 0;
00568 
00569             if(isChunked == 1)
00570             {
00571                 // if data in chunked format calculate next chunk size 
00572                 pBuff += 2; // 2 bytes for <CR> <LF> 
00573                 transfer_len -= 2;
00574 
00575                 if(getChunkSize(&transfer_len, &pBuff, &recv_size) < 0)
00576                 {
00577                     // Error 
00578                     break;
00579                 }
00580 
00581                 // if next chunk size is zero we have received the complete file 
00582                 if(recv_size == 0)
00583                 {
00584                     eof_detected = 1;
00585                     break;
00586                 }
00587 
00588                 if(recv_size < transfer_len)
00589                 {
00590                     // Code will enter this section if the new chunk size is less then
00591                      // then the transfer size. This will the last chunk of file received
00592                      
00593                     retVal = _fs.sl_FsWrite(fileHandle, g_BytesReceived,
00594                             (uint8_t *)pBuff, recv_size);
00595                     if(retVal < recv_size)
00596                     {
00597                         // Close file without saving 
00598                         retVal = _fs.sl_FsClose(fileHandle, 0, (unsigned char*)"A", 1);
00599                         printf(" Error during writing the file\r\n");
00600                         return FILE_WRITE_ERROR;
00601                     }
00602                     transfer_len -= recv_size;
00603                     g_BytesReceived +=recv_size;
00604                     pBuff += recv_size;
00605                     recv_size = 0;
00606 
00607                     pBuff += 2; // 2bytes for <CR> <LF> 
00608                     transfer_len -= 2;
00609 
00610                     // Calculate the next chunk size, should be zero 
00611                     if(getChunkSize(&transfer_len, &pBuff, &recv_size) < 0)
00612                     {
00613                         // Error 
00614                         break;
00615                     }
00616 
00617                     // if next chunk size is non zero error 
00618                     if(recv_size != 0)
00619                     {
00620                         // Error 
00621                         break;
00622                     }
00623                     eof_detected = 1;
00624                     break;
00625                 }
00626                 else
00627                 {
00628                     // write data on the file 
00629                     retVal = _fs.sl_FsWrite(fileHandle, g_BytesReceived,
00630                             (uint8_t *)pBuff, transfer_len);
00631                     if(retVal < transfer_len)
00632                     {
00633                         // Close file without saving 
00634                         retVal = _fs.sl_FsClose(fileHandle, 0, (unsigned char*)"A", 1);
00635                         printf(" Error during writing the file\r\n");
00636                         ASSERT_ON_ERROR(FILE_WRITE_ERROR);
00637                     }
00638                     recv_size -= transfer_len;
00639                     g_BytesReceived +=transfer_len;
00640                 }
00641             }
00642             // complete file received exit 
00643             if(recv_size == 0)
00644             {
00645                 eof_detected = 1;
00646                 break;
00647             }
00648         }
00649         else
00650         {
00651             // write data on the file 
00652             retVal = _fs.sl_FsWrite(fileHandle, g_BytesReceived,
00653                                  (uint8_t *)pBuff, transfer_len);
00654             if (retVal < 0)
00655             {
00656                 // Close file without saving 
00657                 retVal = _fs.sl_FsClose(fileHandle, 0, (unsigned char*)"A", 1);
00658                 printf(" Error during writing the file\r\n");
00659                 ASSERT_ON_ERROR(FILE_WRITE_ERROR);
00660             }
00661             g_BytesReceived +=transfer_len;
00662             recv_size -= transfer_len;
00663         }
00664 
00665         memset(g_buff, 0, sizeof(g_buff));
00666 
00667         transfer_len = _socket.sl_Recv(g_SockID, &g_buff[0], MAX_BUFF_SIZE, 0);
00668         if(transfer_len <= 0)
00669             ASSERT_ON_ERROR(TCP_RECV_ERROR);
00670 
00671         pBuff = g_buff;
00672     }
00673 
00674     // If user file has checksum which can be used to verify the temporary
00675      // file then file should be verified
00676      // In case of invalid file (FILE_NAME) should be closed without saving to
00677      // recover the previous version of file 
00678     if(0 > transfer_len || eof_detected == 0)
00679     {
00680         // Close file without saving 
00681         retVal = _fs.sl_FsClose(fileHandle, 0, (unsigned char*)"A", 1);
00682         printf(" Error While File Download\r\n");
00683         ASSERT_ON_ERROR(INVALID_FILE);
00684     }
00685     else
00686     {
00687         // Save and close file 
00688         retVal = _fs.sl_FsClose(fileHandle, 0, 0, 0);
00689         ASSERT_ON_ERROR(retVal);
00690     }
00691 
00692     return SUCCESS;;
00693 }
00694 */
00695 
00696 /*!
00697     \brief Connecting to a WLAN Access point
00698 
00699     This function connects to the required AP (SSID_NAME).
00700     The function will return once we are connected and have acquired IP address
00701 
00702     \param[in]  None
00703 
00704     \return     0 on success, negative error-code on error
00705 
00706     \note
00707 
00708     \warning    If the WLAN connection fails or we don't acquire an IP address,
00709                 We will be stuck in this function forever.
00710 */
00711 int32_t cc3100::establishConnectionWithAP()
00712 {
00713     
00714     SlSecParams_t secParams = {0};
00715     int32_t retVal = 0;
00716 
00717     secParams.Key = (signed char *)PASSKEY;
00718     secParams.KeyLen = strlen(PASSKEY);
00719     secParams.Type = SEC_TYPE;
00720 
00721     retVal = _wlan.sl_WlanConnect((signed char *)SSID_NAME, strlen(SSID_NAME), 0, &secParams, 0);
00722     ASSERT_ON_ERROR(retVal);
00723     
00724     /* Wait */
00725     while((!IS_CONNECTED(g_Status,STATUS_BIT_CONNECTION)) || (!IS_IP_ACQUIRED(g_Status,STATUS_BIT_IP_ACQUIRED))) { _nonos._SlNonOsMainLoopTask(); }
00726 
00727     return SUCCESS;
00728 }
00729 
00730 /*!
00731     \brief This function checks the LAN connection by pinging the AP's gateway
00732 
00733     \param[in]  None
00734 
00735     \return     0 on success, negative error-code on error
00736 */
00737 int32_t cc3100::checkLanConnection()
00738 {
00739     SlPingStartCommand_t pingParams = {0};
00740     SlPingReport_t pingReport = {0};
00741 
00742     int32_t retVal = -1;
00743 
00744     CLR_STATUS_BIT(g_Status, STATUS_BIT_PING_DONE);
00745     g_PingPacketsRecv = 0;
00746 
00747     /* Set the ping parameters */
00748     pingParams.PingIntervalTime = PING_INTERVAL;
00749     pingParams.PingSize = PING_PKT_SIZE;
00750     pingParams.PingRequestTimeout = PING_TIMEOUT;
00751     pingParams.TotalNumberOfAttempts = PING_ATTEMPTS;
00752     pingParams.Flags = 0;
00753     pingParams.Ip = g_GatewayIP;
00754 
00755     /* Check for LAN connection */
00756     retVal = _netapp.sl_NetAppPingStart( (SlPingStartCommand_t*)&pingParams, SL_AF_INET,
00757                                  (SlPingReport_t*)&pingReport, SimpleLinkPingReport);
00758     ASSERT_ON_ERROR(retVal);
00759 
00760     /* Wait */
00761     while(!IS_PING_DONE(g_Status,STATUS_BIT_PING_DONE)) { _nonos._SlNonOsMainLoopTask(); }
00762 
00763     if(0 == g_PingPacketsRecv)
00764     {
00765         /* Problem with LAN connection */
00766         ASSERT_ON_ERROR(LAN_CONNECTION_FAILED);
00767     }
00768 
00769     /* LAN connection is successful */
00770     return SUCCESS;
00771 }
00772 
00773 /*!
00774     \brief This function checks the internet connection by pinging
00775            the external-host (HOST_NAME)
00776 
00777     \param[in]  None
00778 
00779     \return     0 on success, negative error-code on error
00780 */
00781 int32_t cc3100::checkInternetConnection()
00782 {
00783     SlPingStartCommand_t pingParams = {0};
00784     SlPingReport_t pingReport = {0};
00785 
00786     uint32_t ipAddr = 0;
00787 
00788     int32_t retVal = -1;
00789 
00790     CLR_STATUS_BIT(g_Status, STATUS_BIT_PING_DONE);
00791     g_PingPacketsRecv = 0;
00792 
00793     /* Set the ping parameters */
00794     pingParams.PingIntervalTime = PING_INTERVAL;
00795     pingParams.PingSize = PING_PKT_SIZE;
00796     pingParams.PingRequestTimeout = PING_TIMEOUT;
00797     pingParams.TotalNumberOfAttempts = PING_ATTEMPTS;
00798     pingParams.Flags = 0;
00799     pingParams.Ip = g_GatewayIP;
00800 
00801     /* Check for Internet connection */
00802     retVal = _netapp.sl_NetAppDnsGetHostByName((unsigned char *)HOST_NAME, strlen(HOST_NAME), &ipAddr, SL_AF_INET);
00803     ASSERT_ON_ERROR(retVal);
00804 
00805     /* Replace the ping address to match HOST_NAME's IP address */
00806     pingParams.Ip = ipAddr;
00807 
00808     /* Try to ping HOST_NAME */
00809     retVal = _netapp.sl_NetAppPingStart( (SlPingStartCommand_t*)&pingParams, SL_AF_INET,
00810                                  (SlPingReport_t*)&pingReport, SimpleLinkPingReport);
00811     ASSERT_ON_ERROR(retVal);
00812 
00813     /* Wait */
00814     while(!IS_PING_DONE(g_Status,STATUS_BIT_PING_DONE)) { _nonos._SlNonOsMainLoopTask(); }
00815 
00816     if (0 == g_PingPacketsRecv)
00817     {
00818         /* Problem with internet connection*/
00819         ASSERT_ON_ERROR(INTERNET_CONNECTION_FAILED);
00820     }
00821 
00822     /* Internet connection is successful */
00823     return SUCCESS;
00824 }
00825 
00826 const int8_t StartResponseLUT[8] = 
00827 {
00828     ROLE_UNKNOWN_ERR,
00829     ROLE_STA,
00830     ROLE_STA_ERR,
00831     ROLE_AP,
00832     ROLE_AP_ERR,
00833     ROLE_P2P,
00834     ROLE_P2P_ERR,
00835     ROLE_UNKNOWN_ERR    
00836 };
00837     
00838 /*****************************************************************************/
00839 /* Internal functions                                                        */
00840 /*****************************************************************************/
00841 
00842 int16_t cc3100::_sl_GetStartResponseConvert(uint32_t Status)
00843 {
00844     return (int16_t)StartResponseLUT[Status & 0x7];
00845     
00846 }
00847 
00848 /*****************************************************************************/
00849 /* API Functions                                                             */
00850 /*****************************************************************************/
00851 
00852 bool cc3100::IS_PING_DONE(uint32_t status_variable,const uint32_t bit){
00853     
00854         g_Status = status_variable;
00855         
00856         if(0 != (g_Status & ((uint32_t)1L<<(bit)))){
00857             return TRUE;
00858         }else{
00859             return FALSE;
00860         }
00861 }
00862         
00863 bool cc3100::IS_CONNECTED(uint32_t status_variable,const uint32_t bit){
00864     
00865         g_Status = status_variable;
00866         
00867         if(0 != (g_Status & ((uint32_t)1L<<(bit)))){
00868             return TRUE;
00869         }else{
00870             return FALSE;
00871         }
00872 }
00873         
00874 bool cc3100::IS_STA_CONNECTED(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_IP_ACQUIRED(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_IP_LEASED(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_CONNECTION_FAILED(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_P2P_NEG_REQ_RECEIVED(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_SMARTCONFIG_DONE(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_SMARTCONFIG_STOPPED(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 void cc3100::CLR_STATUS_BIT(uint32_t status_variable, const uint32_t bit){
00952         
00953         g_Status = status_variable;
00954         g_Status &= ~((uint32_t)1L<<(bit));
00955         
00956 }
00957 
00958 void cc3100::SET_STATUS_BIT(uint32_t status_variable, const uint32_t bit){
00959 
00960         g_Status = status_variable;
00961         g_Status |= ((uint32_t)1L<<(bit));
00962         
00963 }
00964         
00965 /*****************************************************************************/
00966 /* sl_Task                                                                   */
00967 /*****************************************************************************/
00968 #if _SL_INCLUDE_FUNC(sl_Task)
00969 void cc3100::sl_Task(void)
00970 {
00971 #ifdef _SlTaskEntry
00972     _nonos._SlNonOsMainLoopTask;
00973     
00974 #endif
00975 }
00976 #endif
00977 
00978 /*****************************************************************************/
00979 /* sl_Start                                                                  */
00980 /*****************************************************************************/
00981 #if _SL_INCLUDE_FUNC(sl_Start)
00982 int16_t cc3100::sl_Start(const void* pIfHdl, int8_t*  pDevName, const P_INIT_CALLBACK pInitCallBack)
00983 {
00984     int16_t ObjIdx = MAX_CONCURRENT_ACTIONS;
00985     InitComplete_t  AsyncRsp;
00986 
00987     /* Perform any preprocessing before enable networking services */
00988     sl_DeviceEnablePreamble();//stub only
00989     
00990     /* ControlBlock init */
00991     _driver._SlDrvDriverCBInit();
00992     
00993     /* open the interface: usually SPI or UART */
00994     if (NULL == pIfHdl) 
00995     {
00996         g_pCB->FD = _spi.spi_Open((int8_t *)pDevName, 0);
00997     } 
00998     else 
00999     {
01000         g_pCB->FD = (_SlFd_t)pIfHdl;
01001     }
01002        
01003     ObjIdx = _driver._SlDrvProtectAsyncRespSetting((uint8_t *)&AsyncRsp, START_STOP_ID, SL_MAX_SOCKETS);
01004     
01005     if (MAX_CONCURRENT_ACTIONS == ObjIdx) 
01006     {
01007         printf("SL_POOL_IS_EMPTY\r\n");
01008         return SL_POOL_IS_EMPTY;
01009     }
01010 
01011     if( g_pCB->FD >= (_SlFd_t)0) {
01012         _spi.CC3100_disable();
01013         
01014         g_pCB->pInitCallback = pInitCallBack;
01015             
01016         _spi.CC3100_enable();
01017 
01018         if (NULL == pInitCallBack) {
01019             
01020             _driver._SlDrvSyncObjWaitForever(&g_pCB->ObjPool[ObjIdx].SyncObj);
01021             
01022             /*release Pool Object*/           
01023             _driver._SlDrvReleasePoolObj(g_pCB->FunctionParams.AsyncExt.ActionIndex);            
01024             return _sl_GetStartResponseConvert(AsyncRsp.Status);
01025         }
01026         else
01027         {
01028             return SL_RET_CODE_OK;    
01029         }
01030     }
01031     
01032     return SL_BAD_INTERFACE;
01033 
01034 
01035 }
01036 #endif
01037 
01038 /***************************************************************************
01039 _sl_HandleAsync_InitComplete - handles init complete signalling to
01040 a waiting object
01041 ****************************************************************************/
01042 void cc3100::_sl_HandleAsync_InitComplete(void *pVoidBuf)
01043 {
01044 
01045     InitComplete_t *pMsgArgs = (InitComplete_t *)_SL_RESP_ARGS_START(pVoidBuf);
01046 
01047     _driver._SlDrvProtectionObjLockWaitForever();
01048 
01049     if(g_pCB->pInitCallback) {
01050         g_pCB->pInitCallback(_sl_GetStartResponseConvert(pMsgArgs->Status));
01051     } else {
01052         memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(InitComplete_t));        
01053         _driver._SlDrvSyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj);
01054     }
01055     _driver._SlDrvProtectionObjUnLock();
01056 
01057     if(g_pCB->pInitCallback) {
01058         _driver._SlDrvReleasePoolObj(g_pCB->FunctionParams.AsyncExt.ActionIndex);
01059     }
01060 
01061 }
01062 
01063 /*****************************************************************************
01064 sl_stop
01065 ******************************************************************************/
01066 typedef union {
01067     _DevStopCommand_t  Cmd;
01068     _BasicResponse_t   Rsp;
01069 } _SlStopMsg_u;
01070 
01071 const _SlCmdCtrl_t _SlStopCmdCtrl = {
01072     SL_OPCODE_DEVICE_STOP_COMMAND,
01073     sizeof(_DevStopCommand_t),
01074     sizeof(_BasicResponse_t)
01075 };
01076 
01077 #if _SL_INCLUDE_FUNC(sl_Stop)
01078 int16_t cc3100::sl_Stop(const uint16_t timeout)
01079 {
01080     int16_t RetVal=0;
01081     _SlStopMsg_u      Msg;
01082     _BasicResponse_t  AsyncRsp;
01083     int8_t ObjIdx = MAX_CONCURRENT_ACTIONS;
01084     /* if timeout is 0 the shutdown is forced immediately */
01085     if( 0 == timeout ) {
01086         _spi.registerInterruptHandler(NULL, NULL);
01087         _spi.CC3100_disable();
01088         RetVal = _spi.spi_Close(g_pCB->FD);
01089 
01090     } else {
01091         /* let the device make the shutdown using the defined timeout */
01092         Msg.Cmd.Timeout = timeout;
01093         
01094         
01095         
01096         
01097         
01098         ObjIdx = _driver._SlDrvProtectAsyncRespSetting((uint8_t *)&AsyncRsp, START_STOP_ID, SL_MAX_SOCKETS);
01099       if (MAX_CONCURRENT_ACTIONS == ObjIdx)
01100       {
01101           return SL_POOL_IS_EMPTY;
01102       }
01103 
01104       VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlStopCmdCtrl, &Msg, NULL));
01105 
01106       if(SL_OS_RET_CODE_OK == (int16_t)Msg.Rsp.status)
01107       {
01108          _driver._SlDrvSyncObjWaitForever(&g_pCB->ObjPool[ObjIdx].SyncObj);
01109          Msg.Rsp.status = AsyncRsp.status;
01110          RetVal = Msg.Rsp.status;
01111       }
01112 
01113       _driver._SlDrvReleasePoolObj((uint8_t)ObjIdx);
01114 
01115       _spi.registerInterruptHandler(NULL, NULL);
01116       _spi.CC3100_disable();
01117       _spi.spi_Close(g_pCB->FD);
01118     }
01119     _driver._SlDrvDriverCBDeinit();
01120 
01121     return RetVal;
01122 }
01123 #endif
01124 
01125 
01126 /*****************************************************************************
01127 sl_EventMaskSet
01128 *****************************************************************************/
01129 typedef union {
01130     _DevMaskEventSetCommand_t       Cmd;
01131     _BasicResponse_t                Rsp;
01132 } _SlEventMaskSetMsg_u;
01133 
01134 #if _SL_INCLUDE_FUNC(sl_EventMaskSet)
01135 const _SlCmdCtrl_t _SlEventMaskSetCmdCtrl = {
01136     SL_OPCODE_DEVICE_EVENTMASKSET,
01137     sizeof(_DevMaskEventSetCommand_t),
01138     sizeof(_BasicResponse_t)
01139 };
01140 
01141 int16_t cc3100::sl_EventMaskSet(uint8_t EventClass , uint32_t Mask)
01142 {
01143     _SlEventMaskSetMsg_u Msg;
01144     Msg.Cmd.group = EventClass;
01145     Msg.Cmd.mask = Mask;
01146 
01147     VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlEventMaskSetCmdCtrl, &Msg, NULL));
01148 
01149     return (int16_t)Msg.Rsp.status;
01150 }
01151 #endif
01152 
01153 /******************************************************************************
01154 sl_EventMaskGet
01155 ******************************************************************************/
01156 typedef union {
01157     _DevMaskEventGetCommand_t       Cmd;
01158     _DevMaskEventGetResponse_t      Rsp;
01159 } _SlEventMaskGetMsg_u;
01160 
01161 #if _SL_INCLUDE_FUNC(sl_EventMaskGet)
01162 const _SlCmdCtrl_t _SlEventMaskGetCmdCtrl = {
01163     SL_OPCODE_DEVICE_EVENTMASKGET,
01164     sizeof(_DevMaskEventGetCommand_t),
01165     sizeof(_DevMaskEventGetResponse_t)
01166 };
01167 
01168 int16_t cc3100::sl_EventMaskGet(uint8_t EventClass, uint32_t *pMask)
01169 {
01170     _SlEventMaskGetMsg_u Msg;
01171 
01172     Msg.Cmd.group = EventClass;
01173 
01174     VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlEventMaskGetCmdCtrl, &Msg, NULL));
01175 
01176     *pMask = Msg.Rsp.mask;
01177     return SL_RET_CODE_OK;
01178 }
01179 #endif
01180 
01181 /******************************************************************************
01182 sl_DevGet
01183 ******************************************************************************/
01184 
01185 typedef union {
01186     _DeviceSetGet_t     Cmd;
01187     _DeviceSetGet_t     Rsp;
01188 } _SlDeviceMsgGet_u;
01189 
01190 #if _SL_INCLUDE_FUNC(sl_DevGet)
01191 const _SlCmdCtrl_t _SlDeviceGetCmdCtrl = {
01192     SL_OPCODE_DEVICE_DEVICEGET,
01193     sizeof(_DeviceSetGet_t),
01194     sizeof(_DeviceSetGet_t)
01195 };
01196 
01197 int32_t cc3100::sl_DevGet(uint8_t DeviceGetId, uint8_t *pOption,uint8_t *pConfigLen, uint8_t *pValues)
01198 {
01199     _SlDeviceMsgGet_u         Msg;
01200     _SlCmdExt_t               CmdExt;
01201     
01202     if (*pConfigLen == 0) {
01203         return SL_EZEROLEN;
01204     }
01205    
01206     if( pOption ) {
01207         _driver._SlDrvResetCmdExt(&CmdExt);
01208         CmdExt.RxPayloadLen = *pConfigLen;
01209         
01210         CmdExt.pRxPayload = (uint8_t *)pValues;
01211         
01212 
01213         Msg.Cmd.DeviceSetId = DeviceGetId;
01214 
01215         Msg.Cmd.Option   = (uint16_t)*pOption;
01216 
01217         VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlDeviceGetCmdCtrl, &Msg, &CmdExt));
01218         
01219         if( pOption ) {
01220             *pOption = (uint8_t)Msg.Rsp.Option;
01221         }
01222         
01223         if (CmdExt.RxPayloadLen < CmdExt.ActualRxPayloadLen) {
01224             *pConfigLen = (uint8_t)CmdExt.RxPayloadLen;
01225             return SL_ESMALLBUF;
01226         } else {
01227             *pConfigLen = (uint8_t)CmdExt.ActualRxPayloadLen;
01228         }
01229         
01230         return (int16_t)Msg.Rsp.Status;
01231     } else {
01232         return -1;
01233     }
01234 }
01235 #endif
01236 
01237 /******************************************************************************
01238 sl_DevSet
01239 ******************************************************************************/
01240 typedef union {
01241     _DeviceSetGet_t    Cmd;
01242     _BasicResponse_t   Rsp;
01243 } _SlDeviceMsgSet_u;
01244 
01245 #if _SL_INCLUDE_FUNC(sl_DevSet)
01246 const _SlCmdCtrl_t _SlDeviceSetCmdCtrl = {
01247     SL_OPCODE_DEVICE_DEVICESET,
01248     sizeof(_DeviceSetGet_t),
01249     sizeof(_BasicResponse_t)
01250 };
01251 
01252 int32_t cc3100::sl_DevSet(const uint8_t DeviceSetId, const uint8_t Option, const uint8_t ConfigLen, const uint8_t *pValues)
01253 {
01254     _SlDeviceMsgSet_u         Msg;
01255     _SlCmdExt_t               CmdExt;
01256     
01257     _driver._SlDrvResetCmdExt(&CmdExt);
01258     CmdExt.TxPayloadLen = (ConfigLen+3) & (~3);
01259     
01260     CmdExt.pTxPayload = (uint8_t *)pValues;
01261     
01262 
01263 
01264     Msg.Cmd.DeviceSetId    = DeviceSetId;
01265     Msg.Cmd.ConfigLen   = ConfigLen;
01266     Msg.Cmd.Option   = Option;
01267 
01268     VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlDeviceSetCmdCtrl, &Msg, &CmdExt));
01269 
01270     return (int16_t)Msg.Rsp.status;
01271 }
01272 #endif
01273 
01274 /******************************************************************************
01275 sl_UartSetMode
01276 ******************************************************************************/
01277 #ifdef SL_IF_TYPE_UART
01278 typedef union {
01279     _DevUartSetModeCommand_t      Cmd;
01280     _DevUartSetModeResponse_t     Rsp;
01281 } _SlUartSetModeMsg_u;
01282 
01283 #if _SL_INCLUDE_FUNC(sl_UartSetMode)
01284 const _SlCmdCtrl_t _SlUartSetModeCmdCtrl = {
01285     SL_OPCODE_DEVICE_SETUARTMODECOMMAND,
01286     sizeof(_DevUartSetModeCommand_t),
01287     sizeof(_DevUartSetModeResponse_t)
01288 };
01289 
01290 int16_t cc3100::sl_UartSetMode(const SlUartIfParams_t* pUartParams)
01291 {
01292     _SlUartSetModeMsg_u Msg;
01293     uint32_t magicCode = 0xFFFFFFFF;
01294 
01295     Msg.Cmd.BaudRate = pUartParams->BaudRate;
01296     Msg.Cmd.FlowControlEnable = pUartParams->FlowControlEnable;
01297 
01298 
01299     VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlUartSetModeCmdCtrl, &Msg, NULL));
01300 
01301     /* cmd response OK, we can continue with the handshake */
01302     if (SL_RET_CODE_OK == Msg.Rsp.status) {
01303         sl_IfMaskIntHdlr();
01304 
01305         /* Close the comm port */
01306         sl_IfClose(g_pCB->FD);
01307 
01308         /* Re-open the comm port */
01309         sl_IfOpen((void * )pUartParams, UART_IF_OPEN_FLAG_RE_OPEN);
01310         sl_IfUnMaskIntHdlr();
01311 
01312         /* send the magic code and wait for the response */
01313         sl_IfWrite(g_pCB->FD, (uint8_t* )&magicCode, 4);
01314 
01315         magicCode = UART_SET_MODE_MAGIC_CODE;
01316         sl_IfWrite(g_pCB->FD, (uint8_t* )&magicCode, 4);
01317 
01318         /* clear magic code */
01319         magicCode = 0;
01320 
01321         /* wait (blocking) till the magic code to be returned from device */
01322         sl_IfRead(g_pCB->FD, (uint8_t* )&magicCode, 4);
01323 
01324         /* check for the received magic code matching */
01325         if (UART_SET_MODE_MAGIC_CODE != magicCode) {
01326             _SL_ASSERT(0);
01327         }
01328     }
01329 
01330     return (int16_t)Msg.Rsp.status;
01331 }
01332 #endif
01333 #endif
01334 
01335 }//namespace
01336 
01337