Update revision to use TI's mqtt and Freertos.

Dependencies:   mbed client server

Fork of cc3100_Test_mqtt_CM3 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 #include "cli_uart.h"
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 button1_irq, PinName button2_irq, PinName cc3100_irq, PinName cc3100_nHIB, PinName cc3100_cs, SPI cc3100_spi)
00063     : _spi(button1_irq, button2_irq, cc3100_irq, cc3100_nHIB, cc3100_cs, cc3100_spi, _driver),
00064       _driver(_spi, _nonos, _netapp, _flowcont), _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 
00150     SlVersionFull   ver = {0};
00151     _WlanRxFilterOperationCommandBuff_t   RxFilterIdMask = {0};
00152 
00153     uint8_t           val = 1;
00154     uint8_t           configOpt = 0;
00155     uint8_t           configLen = 0;
00156     uint8_t           power = 0;
00157 
00158     int32_t          retVal = -1;
00159     int32_t          role = -1;
00160 
00161     role = sl_Start(0, 0, 0);
00162     ASSERT_ON_ERROR(role);
00163 
00164     /* If the device is not in station-mode, try configuring it in station-mode */
00165     if (ROLE_STA != role) {
00166         if (ROLE_AP == role) {
00167             /* If the device is in AP mode, we need to wait for this event before doing anything */
00168             while(!IS_IP_ACQUIRED(g_Status,STATUS_BIT_IP_ACQUIRED)) {
00169                 _nonos._SlNonOsMainLoopTask();
00170             }
00171         }
00172         
00173         /* Switch to STA role and restart */
00174         retVal = _wlan.sl_WlanSetMode(ROLE_STA);
00175         ASSERT_ON_ERROR(retVal);
00176         
00177         retVal = sl_Stop(SL_STOP_TIMEOUT);
00178         ASSERT_ON_ERROR(retVal);
00179 
00180         retVal = sl_Start(0, 0, 0);
00181         ASSERT_ON_ERROR(retVal);
00182 
00183         /* Check if the device is in station again */
00184         if (ROLE_STA != retVal) {
00185             /* We don't want to proceed if the device is not coming up in station-mode */
00186             ASSERT_ON_ERROR(DEVICE_NOT_IN_STATION_MODE);
00187         }
00188     }
00189     
00190     /* Get the device's version-information */
00191     configOpt = SL_DEVICE_GENERAL_VERSION;
00192     configLen = sizeof(ver);
00193     retVal = sl_DevGet(SL_DEVICE_GENERAL_CONFIGURATION, &configOpt, &configLen, (uint8_t *)(&ver));
00194     ASSERT_ON_ERROR(retVal);
00195     
00196     /* Set connection policy to Auto + SmartConfig (Device's default connection policy) */
00197     retVal = _wlan.sl_WlanPolicySet(SL_POLICY_CONNECTION, SL_CONNECTION_POLICY(1, 0, 0, 0, 1), NULL, 0);
00198     ASSERT_ON_ERROR(retVal);
00199     
00200     /* Remove all profiles */
00201     retVal = _wlan.sl_WlanProfileDel(0xFF);
00202     ASSERT_ON_ERROR(retVal);
00203 
00204     /*
00205      * Device in station-mode. Disconnect previous connection if any
00206      * The function returns 0 if 'Disconnected done', negative number if already disconnected
00207      * Wait for 'disconnection' event if 0 is returned, Ignore other return-codes
00208      */
00209     retVal = _wlan.sl_WlanDisconnect();
00210     if(0 == retVal) {
00211         /* Wait */
00212         while(IS_CONNECTED(g_Status,STATUS_BIT_CONNECTION)) {
00213             _nonos._SlNonOsMainLoopTask();
00214         }
00215     }
00216     
00217     /* Enable DHCP client*/
00218     retVal = _netcfg.sl_NetCfgSet(SL_IPV4_STA_P2P_CL_DHCP_ENABLE,1,1,&val);
00219     ASSERT_ON_ERROR(retVal);
00220     
00221     /* Disable scan */
00222     configOpt = SL_SCAN_POLICY(0);
00223     retVal = _wlan.sl_WlanPolicySet(SL_POLICY_SCAN , configOpt, NULL, 0);
00224     ASSERT_ON_ERROR(retVal);
00225     
00226     /* Set Tx power level for station mode
00227        Number between 0-15, as dB offset from maximum power - 0 will set maximum power */
00228     power = 0;
00229     retVal = _wlan.sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID, WLAN_GENERAL_PARAM_OPT_STA_TX_POWER, 1, (uint8_t *)&power);
00230     ASSERT_ON_ERROR(retVal);
00231 
00232     /* Set PM policy to normal */
00233     retVal = _wlan.sl_WlanPolicySet(SL_POLICY_PM , SL_NORMAL_POLICY, NULL, 0);
00234     ASSERT_ON_ERROR(retVal);
00235 
00236     /* Unregister mDNS services */
00237     retVal = _netapp.sl_NetAppMDNSUnRegisterService(0, 0);
00238     ASSERT_ON_ERROR(retVal);
00239 
00240     /* Remove  all 64 filters (8*8) */
00241     memset(RxFilterIdMask.FilterIdMask, 0xFF, 8);
00242 
00243     retVal = _wlan_filters.sl_WlanRxFilterSet(SL_REMOVE_RX_FILTER, (uint8_t *)&RxFilterIdMask,
00244              sizeof(_WlanRxFilterOperationCommandBuff_t ));
00245     ASSERT_ON_ERROR(retVal);
00246 
00247     retVal = sl_Stop(SL_STOP_TIMEOUT);
00248     ASSERT_ON_ERROR(retVal);
00249 
00250     retVal = initializeAppVariables();
00251     ASSERT_ON_ERROR(retVal);
00252 
00253     return retVal; /* Success */
00254 }
00255 
00256 /*!
00257     \brief Create UDP socket to communicate with server.
00258 
00259     \param[in]      none
00260 
00261     \return         Socket descriptor for success otherwise negative
00262 
00263     \warning
00264 */
00265 int32_t cc3100::createUDPConnection()
00266 {
00267     int32_t sd = 0;
00268 
00269     sd = _socket.sl_Socket(SL_AF_INET, SL_SOCK_DGRAM, IPPROTO_UDP);
00270     if( sd < 0 )
00271     {
00272         Uart_Write((uint8_t*)"Error creating socket\n\r\n\r");
00273     }
00274 
00275     return sd;
00276 }   
00277 
00278 /*!
00279     \brief Create connection with server.
00280 
00281     This function opens a socket and create the endpoint communication with server
00282 
00283     \param[in]      DestinationIP - IP address of the server
00284 
00285     \return         socket id for success and negative for error
00286 */
00287 int32_t cc3100::createConnection(uint32_t DestinationIP)
00288 {
00289     SlSockAddrIn_t  Addr = {0};
00290     int32_t           Status = 0;
00291     int32_t           AddrSize = 0;
00292     int32_t           SockID = 0;
00293 
00294     Addr.sin_family = SL_AF_INET;
00295     Addr.sin_port = _socket.sl_Htons(80);
00296     Addr.sin_addr.s_addr = _socket.sl_Htonl(DestinationIP);
00297 
00298     AddrSize = sizeof(SlSockAddrIn_t);
00299 
00300     SockID = _socket.sl_Socket(SL_AF_INET,SL_SOCK_STREAM, 0);
00301     ASSERT_ON_ERROR(SockID);
00302 
00303     Status = _socket.sl_Connect(SockID, ( SlSockAddr_t *)&Addr, AddrSize);
00304     if (Status < 0)
00305     {
00306         _socket.sl_Close(SockID);
00307         ASSERT_ON_ERROR(Status);
00308     }
00309 
00310     return SockID;
00311 }
00312 
00313 /*!
00314     \brief Convert hex to decimal base
00315 
00316     \param[in]      ptr - pointer to string containing number in hex
00317 
00318     \return         number in decimal base
00319 
00320 */
00321 int32_t cc3100::hexToi(unsigned char *ptr)
00322 {
00323     uint32_t result = 0;
00324     uint32_t len = 0;
00325 
00326     int32_t  idx = -1;
00327 
00328     len = strlen((const char*) ptr);
00329 
00330     /* convert characters to upper case */
00331     for(idx = 0; ptr[idx] != '\0'; ++idx)
00332     {
00333         if( (ptr[idx] >= 'a') &&
00334             (ptr[idx] <= 'f') )
00335         {
00336             ptr[idx] -= 32;         /* Change case - ASCII 'a' = 97, 'A' = 65 => 97-65 = 32 */
00337         }
00338     }
00339 
00340     for(idx = 0; ptr[idx] != '\0'; ++idx)
00341     {
00342         if(ptr[idx] >= '0' && ptr[idx] <= '9')
00343         {
00344             /* Converting '0' to '9' to their decimal value */
00345             result += (ptr[idx] - '0') * (1 << (4 * (len - 1 - idx)));
00346         }
00347         else if(ptr[idx] >= 'A' && ptr[idx] <= 'F')
00348         {
00349             /* Converting hex 'A' to 'F' to their decimal value */
00350             result += (ptr[idx] - 55) * (1 << (4 * (len -1 - idx))); /* .i.e. 'A' - 55 = 10, 'F' - 55 = 15 */
00351         }
00352         else
00353         {
00354             ASSERT_ON_ERROR(INVALID_HEX_STRING);
00355         }
00356     }
00357 
00358     return result;
00359 }
00360 
00361 /*!
00362     \brief Calculate the file chunk size
00363 
00364     \param[in]      len - pointer to length of the data in the buffer
00365     \param[in]      p_Buff - pointer to pointer of buffer containing data
00366     \param[out]     chunk_size - pointer to variable containing chunk size
00367 
00368     \return         0 for success, -ve for error
00369 
00370 */
00371 int32_t cc3100::getChunkSize(int32_t *len, uint8_t **p_Buff, uint32_t *chunk_size)
00372 {
00373     int32_t   idx = -1;
00374     unsigned char   lenBuff[10];
00375 
00376     idx = 0;
00377     memset(lenBuff, 0, sizeof(lenBuff));
00378     while(*len >= 0 && **p_Buff != 13) /* check for <CR> */
00379     {
00380         if(0 == *len)
00381         {
00382             memset(g_buff, 0, sizeof(g_buff));
00383             *len = _socket.sl_Recv(g_SockID, &g_buff[0], MAX_BUFF_SIZE, 0);
00384             if(*len <= 0)
00385                 ASSERT_ON_ERROR(TCP_RECV_ERROR);
00386 
00387             *p_Buff = g_buff;
00388         }
00389 
00390         lenBuff[idx] = **p_Buff;
00391         idx++;
00392         (*p_Buff)++;
00393         (*len)--;
00394     }
00395 
00396     (*p_Buff) += 2; /* skip <CR><LF> */
00397     (*len) -= 2;
00398     *chunk_size = hexToi(lenBuff);
00399 
00400     return SUCCESS;
00401 }
00402 
00403 /*!
00404     \brief Obtain the file from the server
00405 
00406     This function requests the file from the server and save it on serial flash.
00407     To request a different file for different user needs to modify the
00408     PREFIX_BUFFER and POST_BUFFER macros.
00409 
00410     \param[in]      None
00411 
00412     \return         0 for success and negative for error
00413 
00414 */
00415 /*
00416 int32_t cc3100::getFile()
00417 {
00418     uint32_t Token = 0;
00419     uint32_t recv_size = 0;
00420     uint8_t *pBuff = 0;
00421     uint8_t eof_detected = 0;
00422     uint8_t isChunked = 0;
00423 
00424     int32_t transfer_len = -1;
00425     int32_t retVal = -1;
00426     int32_t fileHandle = -1;
00427 
00428     memset(g_buff, 0, sizeof(g_buff));
00429 
00430     //Puts together the HTTP GET string.
00431     strcpy((char*)g_buff, PREFIX_BUFFER);
00432     strcat((char*)g_buff, POST_BUFFER);
00433 
00434     //Send the HTTP GET string to the opened TCP/IP socket.
00435     transfer_len = _socket.sl_Send(g_SockID, g_buff, strlen((const char*)g_buff), 0);
00436 
00437     if (transfer_len < 0)
00438     {
00439         // error 
00440         printf(" Socket Send Error\r\n");
00441         ASSERT_ON_ERROR(TCP_SEND_ERROR);
00442     }
00443 
00444     memset(g_buff, 0, sizeof(g_buff));
00445 
00446     //get the reply from the server in buffer.
00447     transfer_len = _socket.sl_Recv(g_SockID, &g_buff[0], MAX_BUFF_SIZE, 0);
00448 
00449     if(transfer_len <= 0)
00450         ASSERT_ON_ERROR(TCP_RECV_ERROR);
00451 
00452     // Check for 404 return code 
00453     if(strstr((const char*)g_buff, HTTP_FILE_NOT_FOUND) != 0)
00454     {
00455         printf(" File not found, check the file and try again\r\n");
00456         ASSERT_ON_ERROR(FILE_NOT_FOUND_ERROR);
00457     }
00458 
00459     // if not "200 OK" return error 
00460     if(strstr((const char*)g_buff, HTTP_STATUS_OK) == 0)
00461     {
00462         printf(" Error during downloading the file\r\n");
00463         ASSERT_ON_ERROR(INVALID_SERVER_RESPONSE);
00464     }
00465 
00466     // check if content length is transferred with headers 
00467     pBuff = (uint8_t *)strstr((const char*)g_buff, HTTP_CONTENT_LENGTH);
00468     if(pBuff != 0)
00469     {
00470         // not supported 
00471         printf(" Server response format is not supported\r\n");
00472         ASSERT_ON_ERROR(FORMAT_NOT_SUPPORTED);
00473     }
00474 
00475     // Check if data is chunked 
00476     pBuff = (uint8_t *)strstr((const char*)g_buff, HTTP_TRANSFER_ENCODING);
00477     if(pBuff != 0)
00478     {
00479         pBuff += strlen(HTTP_TRANSFER_ENCODING);
00480         while(*pBuff == SPACE)
00481             pBuff++;
00482 
00483         if(memcmp(pBuff, HTTP_ENCODING_CHUNKED, strlen(HTTP_ENCODING_CHUNKED)) == 0)
00484         {
00485             recv_size = 0;
00486             isChunked = 1;
00487         }
00488     }
00489     else
00490     {
00491         // Check if connection will be closed by after sending data
00492          // In this method the content length is not received and end of
00493          // connection marks the end of data 
00494         pBuff = (uint8_t *)strstr((const char*)g_buff, HTTP_CONNECTION);
00495         if(pBuff != 0)
00496         {
00497             pBuff += strlen(HTTP_CONNECTION);
00498             while(*pBuff == SPACE)
00499                 pBuff++;
00500 
00501             if(memcmp(pBuff, HTTP_ENCODING_CHUNKED, strlen(HTTP_CONNECTION_CLOSE)) == 0)
00502             {
00503                 // not supported 
00504                 printf(" Server response format is not supported\r\n");
00505                 ASSERT_ON_ERROR(FORMAT_NOT_SUPPORTED);
00506             }
00507         }
00508     }
00509 
00510     // "\r\n\r\n" marks the end of headers 
00511     pBuff = (uint8_t *)strstr((const char*)g_buff, HTTP_END_OF_HEADER);
00512     if(pBuff == 0)
00513     {
00514         printf(" Invalid response\r\n");
00515         ASSERT_ON_ERROR(INVALID_SERVER_RESPONSE);
00516     }
00517     // Increment by 4 to skip "\r\n\r\n" 
00518     pBuff += 4;
00519 
00520     // Adjust buffer data length for header size 
00521     transfer_len -= (pBuff - g_buff);
00522 
00523     // If data in chunked format, calculate the chunk size 
00524     if(isChunked == 1)
00525     {
00526         retVal = getChunkSize(&transfer_len, &pBuff, &recv_size);
00527         if(retVal < 0)
00528         {
00529             // Error 
00530             printf(" Problem with connection to server\r\n");
00531             return retVal;
00532         }
00533     }
00534 
00535     // Open file to save the downloaded file 
00536     retVal = _fs.sl_FsOpen((uint8_t *)FILE_NAME,
00537                        FS_MODE_OPEN_WRITE, &Token, &fileHandle);
00538     if(retVal < 0)
00539     {
00540         // File Doesn't exit create a new of 45 KB file 
00541         retVal = _fs.sl_FsOpen((uint8_t *)FILE_NAME,
00542                            _fs.FS_MODE_OPEN_CREATE(SIZE_45K,_FS_FILE_OPEN_FLAG_COMMIT|_FS_FILE_PUBLIC_WRITE),
00543                            &Token, &fileHandle);
00544         if(retVal < 0)
00545         {
00546             printf(" Error during opening the file\r\n");
00547             return retVal;
00548         }
00549     }
00550 
00551     while (0 < transfer_len)
00552     {
00553         // For chunked data recv_size contains the chunk size to be received
00554          // while the transfer_len contains the data in the buffer 
00555         if(recv_size <= transfer_len)
00556         {
00557             // write the recv_size 
00558             retVal = _fs.sl_FsWrite(fileHandle, g_BytesReceived,
00559                     (uint8_t *)pBuff, recv_size);
00560             if(retVal < recv_size)
00561             {
00562                 // Close file without saving 
00563                 retVal = _fs.sl_FsClose(fileHandle, 0, (unsigned char*)"A", 1);
00564                 printf(" Error during writing the file\r\n");
00565                 return FILE_WRITE_ERROR;
00566             }
00567             transfer_len -= recv_size;
00568             g_BytesReceived +=recv_size;
00569             pBuff += recv_size;
00570             recv_size = 0;
00571 
00572             if(isChunked == 1)
00573             {
00574                 // if data in chunked format calculate next chunk size 
00575                 pBuff += 2; // 2 bytes for <CR> <LF> 
00576                 transfer_len -= 2;
00577 
00578                 if(getChunkSize(&transfer_len, &pBuff, &recv_size) < 0)
00579                 {
00580                     // Error 
00581                     break;
00582                 }
00583 
00584                 // if next chunk size is zero we have received the complete file 
00585                 if(recv_size == 0)
00586                 {
00587                     eof_detected = 1;
00588                     break;
00589                 }
00590 
00591                 if(recv_size < transfer_len)
00592                 {
00593                     // Code will enter this section if the new chunk size is less then
00594                      // then the transfer size. This will the last chunk of file received
00595                      
00596                     retVal = _fs.sl_FsWrite(fileHandle, g_BytesReceived,
00597                             (uint8_t *)pBuff, recv_size);
00598                     if(retVal < recv_size)
00599                     {
00600                         // Close file without saving 
00601                         retVal = _fs.sl_FsClose(fileHandle, 0, (unsigned char*)"A", 1);
00602                         printf(" Error during writing the file\r\n");
00603                         return FILE_WRITE_ERROR;
00604                     }
00605                     transfer_len -= recv_size;
00606                     g_BytesReceived +=recv_size;
00607                     pBuff += recv_size;
00608                     recv_size = 0;
00609 
00610                     pBuff += 2; // 2bytes for <CR> <LF> 
00611                     transfer_len -= 2;
00612 
00613                     // Calculate the next chunk size, should be zero 
00614                     if(getChunkSize(&transfer_len, &pBuff, &recv_size) < 0)
00615                     {
00616                         // Error 
00617                         break;
00618                     }
00619 
00620                     // if next chunk size is non zero error 
00621                     if(recv_size != 0)
00622                     {
00623                         // Error 
00624                         break;
00625                     }
00626                     eof_detected = 1;
00627                     break;
00628                 }
00629                 else
00630                 {
00631                     // write data on the file 
00632                     retVal = _fs.sl_FsWrite(fileHandle, g_BytesReceived,
00633                             (uint8_t *)pBuff, transfer_len);
00634                     if(retVal < transfer_len)
00635                     {
00636                         // Close file without saving 
00637                         retVal = _fs.sl_FsClose(fileHandle, 0, (unsigned char*)"A", 1);
00638                         printf(" Error during writing the file\r\n");
00639                         ASSERT_ON_ERROR(FILE_WRITE_ERROR);
00640                     }
00641                     recv_size -= transfer_len;
00642                     g_BytesReceived +=transfer_len;
00643                 }
00644             }
00645             // complete file received exit 
00646             if(recv_size == 0)
00647             {
00648                 eof_detected = 1;
00649                 break;
00650             }
00651         }
00652         else
00653         {
00654             // write data on the file 
00655             retVal = _fs.sl_FsWrite(fileHandle, g_BytesReceived,
00656                                  (uint8_t *)pBuff, transfer_len);
00657             if (retVal < 0)
00658             {
00659                 // Close file without saving 
00660                 retVal = _fs.sl_FsClose(fileHandle, 0, (unsigned char*)"A", 1);
00661                 printf(" Error during writing the file\r\n");
00662                 ASSERT_ON_ERROR(FILE_WRITE_ERROR);
00663             }
00664             g_BytesReceived +=transfer_len;
00665             recv_size -= transfer_len;
00666         }
00667 
00668         memset(g_buff, 0, sizeof(g_buff));
00669 
00670         transfer_len = _socket.sl_Recv(g_SockID, &g_buff[0], MAX_BUFF_SIZE, 0);
00671         if(transfer_len <= 0)
00672             ASSERT_ON_ERROR(TCP_RECV_ERROR);
00673 
00674         pBuff = g_buff;
00675     }
00676 
00677     // If user file has checksum which can be used to verify the temporary
00678      // file then file should be verified
00679      // In case of invalid file (FILE_NAME) should be closed without saving to
00680      // recover the previous version of file 
00681     if(0 > transfer_len || eof_detected == 0)
00682     {
00683         // Close file without saving 
00684         retVal = _fs.sl_FsClose(fileHandle, 0, (unsigned char*)"A", 1);
00685         printf(" Error While File Download\r\n");
00686         ASSERT_ON_ERROR(INVALID_FILE);
00687     }
00688     else
00689     {
00690         // Save and close file 
00691         retVal = _fs.sl_FsClose(fileHandle, 0, 0, 0);
00692         ASSERT_ON_ERROR(retVal);
00693     }
00694 
00695     return SUCCESS;;
00696 }
00697 */
00698 
00699 /*!
00700     \brief Connecting to a WLAN Access point
00701 
00702     This function connects to the required AP (SSID_NAME).
00703     The function will return once we are connected and have acquired IP address
00704 
00705     \param[in]  None
00706 
00707     \return     0 on success, negative error-code on error
00708 
00709     \note
00710 
00711     \warning    If the WLAN connection fails or we don't acquire an IP address,
00712                 We will be stuck in this function forever.
00713 */
00714 int32_t cc3100::establishConnectionWithAP()
00715 {
00716     
00717     SlSecParams_t secParams = {0};
00718     int32_t retVal = 0;
00719 
00720     secParams.Key = (signed char *)PASSKEY;
00721     secParams.KeyLen = strlen(PASSKEY);
00722     secParams.Type = SEC_TYPE;
00723 
00724     retVal = _wlan.sl_WlanConnect((signed char *)SSID_NAME, strlen(SSID_NAME), 0, &secParams, 0);
00725     ASSERT_ON_ERROR(retVal);
00726     
00727     /* Wait */
00728     while((!IS_CONNECTED(g_Status,STATUS_BIT_CONNECTION)) || (!IS_IP_ACQUIRED(g_Status,STATUS_BIT_IP_ACQUIRED))) { _nonos._SlNonOsMainLoopTask(); }
00729 
00730     return SUCCESS;
00731 }
00732 
00733 /*!
00734     \brief This function checks the LAN connection by pinging the AP's gateway
00735 
00736     \param[in]  None
00737 
00738     \return     0 on success, negative error-code on error
00739 */
00740 int32_t cc3100::checkLanConnection()
00741 {
00742     SlPingStartCommand_t pingParams = {0};
00743     SlPingReport_t pingReport = {0};
00744 
00745     int32_t retVal = -1;
00746 
00747     CLR_STATUS_BIT(g_Status, STATUS_BIT_PING_DONE);
00748     g_PingPacketsRecv = 0;
00749 
00750     /* Set the ping parameters */
00751     pingParams.PingIntervalTime = PING_INTERVAL;
00752     pingParams.PingSize = PING_PKT_SIZE;
00753     pingParams.PingRequestTimeout = PING_TIMEOUT;
00754     pingParams.TotalNumberOfAttempts = PING_ATTEMPTS;
00755     pingParams.Flags = 0;
00756     pingParams.Ip = g_GatewayIP;
00757 
00758     /* Check for LAN connection */
00759     retVal = _netapp.sl_NetAppPingStart( (SlPingStartCommand_t*)&pingParams, SL_AF_INET,
00760                                  (SlPingReport_t*)&pingReport, SimpleLinkPingReport);
00761     ASSERT_ON_ERROR(retVal);
00762 
00763     /* Wait */
00764     while(!IS_PING_DONE(g_Status,STATUS_BIT_PING_DONE)) { _nonos._SlNonOsMainLoopTask(); }
00765 
00766     if(0 == g_PingPacketsRecv)
00767     {
00768         /* Problem with LAN connection */
00769         ASSERT_ON_ERROR(LAN_CONNECTION_FAILED);
00770     }
00771 
00772     /* LAN connection is successful */
00773     return SUCCESS;
00774 }
00775 
00776 /*!
00777     \brief This function checks the internet connection by pinging
00778            the external-host (HOST_NAME)
00779 
00780     \param[in]  None
00781 
00782     \return     0 on success, negative error-code on error
00783 */
00784 int32_t cc3100::checkInternetConnection()
00785 {
00786     SlPingStartCommand_t pingParams = {0};
00787     SlPingReport_t pingReport = {0};
00788 
00789     uint32_t ipAddr = 0;
00790 
00791     int32_t retVal = -1;
00792 
00793     CLR_STATUS_BIT(g_Status, STATUS_BIT_PING_DONE);
00794     g_PingPacketsRecv = 0;
00795 
00796     /* Set the ping parameters */
00797     pingParams.PingIntervalTime = PING_INTERVAL;
00798     pingParams.PingSize = PING_PKT_SIZE;
00799     pingParams.PingRequestTimeout = PING_TIMEOUT;
00800     pingParams.TotalNumberOfAttempts = PING_ATTEMPTS;
00801     pingParams.Flags = 0;
00802     pingParams.Ip = g_GatewayIP;
00803 
00804     /* Check for Internet connection */
00805     retVal = _netapp.sl_NetAppDnsGetHostByName((unsigned char *)HOST_NAME, strlen(HOST_NAME), &ipAddr, SL_AF_INET);
00806     ASSERT_ON_ERROR(retVal);
00807 
00808     /* Replace the ping address to match HOST_NAME's IP address */
00809     pingParams.Ip = ipAddr;
00810 
00811     /* Try to ping HOST_NAME */
00812     retVal = _netapp.sl_NetAppPingStart( (SlPingStartCommand_t*)&pingParams, SL_AF_INET,
00813                                  (SlPingReport_t*)&pingReport, SimpleLinkPingReport);
00814     ASSERT_ON_ERROR(retVal);
00815 
00816     /* Wait */
00817     while(!IS_PING_DONE(g_Status,STATUS_BIT_PING_DONE)) { _nonos._SlNonOsMainLoopTask(); }
00818 
00819     if (0 == g_PingPacketsRecv)
00820     {
00821         /* Problem with internet connection*/
00822         ASSERT_ON_ERROR(INTERNET_CONNECTION_FAILED);
00823     }
00824 
00825     /* Internet connection is successful */
00826     return SUCCESS;
00827 }
00828 
00829 const int8_t StartResponseLUT[8] = 
00830 {
00831     ROLE_UNKNOWN_ERR,
00832     ROLE_STA,
00833     ROLE_STA_ERR,
00834     ROLE_AP,
00835     ROLE_AP_ERR,
00836     ROLE_P2P,
00837     ROLE_P2P_ERR,
00838     ROLE_UNKNOWN_ERR    
00839 };
00840     
00841 /*****************************************************************************/
00842 /* Internal functions                                                        */
00843 /*****************************************************************************/
00844 
00845 int16_t cc3100::_sl_GetStartResponseConvert(uint32_t Status)
00846 {
00847     return (int16_t)StartResponseLUT[Status & 0x7];
00848     
00849 }
00850 
00851 /*****************************************************************************/
00852 /* API Functions                                                             */
00853 /*****************************************************************************/
00854 
00855 bool cc3100::IS_PING_DONE(uint32_t status_variable,const uint32_t bit){
00856     
00857         g_Status = status_variable;
00858         
00859         if(0 != (g_Status & ((uint32_t)1L<<(bit)))){
00860             return TRUE;
00861         }else{
00862             return FALSE;
00863         }
00864 }
00865         
00866 bool cc3100::IS_CONNECTED(uint32_t status_variable,const uint32_t bit){
00867     
00868         g_Status = status_variable;
00869         
00870         if(0 != (g_Status & ((uint32_t)1L<<(bit)))){
00871             return TRUE;
00872         }else{
00873             return FALSE;
00874         }
00875 }
00876         
00877 bool cc3100::IS_STA_CONNECTED(uint32_t status_variable,const uint32_t bit){
00878     
00879         g_Status = status_variable;
00880         
00881         if(0 != (g_Status & ((uint32_t)1L<<(bit)))){
00882             return TRUE;
00883         }else{
00884             return FALSE;
00885         }
00886 } 
00887        
00888 bool cc3100::IS_IP_ACQUIRED(uint32_t status_variable,const uint32_t bit){
00889     
00890         g_Status = status_variable;
00891         
00892         if(0 != (g_Status & ((uint32_t)1L<<(bit)))){
00893             return TRUE;
00894         }else{
00895             return FALSE;
00896         }
00897 }
00898         
00899 bool cc3100::IS_IP_LEASED(uint32_t status_variable,const uint32_t bit){
00900     
00901         g_Status = status_variable;
00902         
00903         if(0 != (g_Status & ((uint32_t)1L<<(bit)))){
00904             return TRUE;
00905         }else{
00906             return FALSE;
00907         }
00908 }
00909         
00910 bool cc3100::IS_CONNECTION_FAILED(uint32_t status_variable,const uint32_t bit){
00911         
00912         g_Status = status_variable;
00913         
00914         if(0 != (g_Status & ((uint32_t)1L<<(bit)))){
00915             return TRUE;
00916         }else{
00917             return FALSE;
00918         }
00919 }
00920         
00921 bool cc3100::IS_P2P_NEG_REQ_RECEIVED(uint32_t status_variable,const uint32_t bit){
00922     
00923         g_Status = status_variable;
00924         
00925         if(0 != (g_Status & ((uint32_t)1L<<(bit)))){
00926             return TRUE;
00927         }else{
00928             return FALSE;
00929         }
00930 }
00931         
00932 bool cc3100::IS_SMARTCONFIG_DONE(uint32_t status_variable,const uint32_t bit){
00933     
00934         g_Status = status_variable;
00935         
00936         if(0 != (g_Status & ((uint32_t)1L<<(bit)))){
00937             return TRUE;
00938         }else{
00939             return FALSE;
00940         }
00941 }
00942         
00943 bool cc3100::IS_SMARTCONFIG_STOPPED(uint32_t status_variable,const uint32_t bit){
00944     
00945         g_Status = status_variable;
00946         
00947         if(0 != (g_Status & ((uint32_t)1L<<(bit)))){            
00948             return TRUE;
00949         }else{
00950             return FALSE;           
00951         }        
00952 }
00953 
00954 void cc3100::CLR_STATUS_BIT(uint32_t status_variable, const uint32_t bit){
00955         
00956         g_Status = status_variable;
00957         g_Status &= ~((uint32_t)1L<<(bit));
00958         
00959 }
00960 
00961 void cc3100::SET_STATUS_BIT(uint32_t status_variable, const uint32_t bit){
00962 
00963         g_Status = status_variable;
00964         g_Status |= ((uint32_t)1L<<(bit));
00965         
00966 }
00967         
00968 /*****************************************************************************/
00969 /* sl_Task                                                                   */
00970 /*****************************************************************************/
00971 #if _SL_INCLUDE_FUNC(sl_Task)
00972 void cc3100::sl_Task(void)
00973 {
00974 #ifdef _SlTaskEntry
00975 //    _nonos._SlNonOsMainLoopTask;
00976     _SlTaskEntry();
00977     
00978 #endif
00979 }
00980 #endif
00981 
00982 /*****************************************************************************/
00983 /* sl_Start                                                                  */
00984 /*****************************************************************************/
00985 #if _SL_INCLUDE_FUNC(sl_Start)
00986 int16_t cc3100::sl_Start(const void* pIfHdl, int8_t*  pDevName, const P_INIT_CALLBACK pInitCallBack)
00987 {
00988     
00989     int16_t ObjIdx = MAX_CONCURRENT_ACTIONS;
00990     InitComplete_t  AsyncRsp;
00991 
00992     /* Perform any preprocessing before enable networking services */
00993     sl_DeviceEnablePreamble();//stub only
00994     
00995     /* ControlBlock init */
00996     _driver._SlDrvDriverCBInit();
00997     
00998     /* open the interface: usually SPI or UART */
00999     if (NULL == pIfHdl) 
01000     {
01001         g_pCB->FD = _spi.spi_Open((int8_t *)pDevName, 0);
01002     } 
01003     else 
01004     {
01005         g_pCB->FD = (_SlFd_t)pIfHdl;
01006     }
01007        
01008     ObjIdx = _driver._SlDrvProtectAsyncRespSetting((uint8_t *)&AsyncRsp, START_STOP_ID, SL_MAX_SOCKETS);
01009     
01010     if (MAX_CONCURRENT_ACTIONS == ObjIdx) 
01011     {
01012         Uart_Write((uint8_t*)"SL_POOL_IS_EMPTY\r\n");
01013         return SL_POOL_IS_EMPTY;
01014     }
01015     
01016     if( g_pCB->FD >= (_SlFd_t)0) {
01017         _spi.CC3100_disable();
01018         
01019         g_pCB->pInitCallback = pInitCallBack;
01020             
01021         _spi.CC3100_enable();
01022 
01023         if (NULL == pInitCallBack) {            
01024             _driver._SlDrvSyncObjWaitForever(&g_pCB->ObjPool[ObjIdx].SyncObj);      
01025             /*release Pool Object*/           
01026             _driver._SlDrvReleasePoolObj(g_pCB->FunctionParams.AsyncExt.ActionIndex);                       
01027             return _sl_GetStartResponseConvert(AsyncRsp.Status);
01028         }
01029         else
01030         {
01031             return SL_RET_CODE_OK;    
01032         }
01033     }
01034     
01035     return SL_BAD_INTERFACE;
01036 
01037 
01038 }
01039 #endif
01040 
01041 /***************************************************************************
01042 _sl_HandleAsync_InitComplete - handles init complete signalling to
01043 a waiting object
01044 ****************************************************************************/
01045 void cc3100::_sl_HandleAsync_InitComplete(void *pVoidBuf)
01046 {
01047 
01048     InitComplete_t *pMsgArgs = (InitComplete_t *)_SL_RESP_ARGS_START(pVoidBuf);
01049 
01050     _driver._SlDrvProtectionObjLockWaitForever();
01051 
01052     if(g_pCB->pInitCallback) {
01053         g_pCB->pInitCallback(_sl_GetStartResponseConvert(pMsgArgs->Status));
01054     } else {
01055         memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(InitComplete_t));        
01056         _driver._SlDrvSyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj);
01057     }
01058     _driver._SlDrvProtectionObjUnLock();
01059 
01060     if(g_pCB->pInitCallback) {
01061         _driver._SlDrvReleasePoolObj(g_pCB->FunctionParams.AsyncExt.ActionIndex);
01062     }
01063 
01064 }
01065 
01066 /*****************************************************************************
01067 sl_stop
01068 ******************************************************************************/
01069 typedef union {
01070     _DevStopCommand_t  Cmd;
01071     _BasicResponse_t   Rsp;
01072 } _SlStopMsg_u;
01073 
01074 const _SlCmdCtrl_t _SlStopCmdCtrl = {
01075     SL_OPCODE_DEVICE_STOP_COMMAND,
01076     sizeof(_DevStopCommand_t),
01077     sizeof(_BasicResponse_t)
01078 };
01079 
01080 #if _SL_INCLUDE_FUNC(sl_Stop)
01081 int16_t cc3100::sl_Stop(const uint16_t timeout)
01082 {
01083     
01084     int16_t RetVal=0;
01085     _SlStopMsg_u      Msg;
01086     _BasicResponse_t  AsyncRsp;
01087     int8_t ObjIdx = MAX_CONCURRENT_ACTIONS;
01088     /* if timeout is 0 the shutdown is forced immediately */
01089     if( 0 == timeout ) {
01090         _spi.registerInterruptHandler(NULL, NULL);
01091         _spi.CC3100_disable();
01092         RetVal = _spi.spi_Close(g_pCB->FD);
01093 
01094     } else {
01095         /* let the device make the shutdown using the defined timeout */
01096         Msg.Cmd.Timeout = timeout;        
01097         ObjIdx = _driver._SlDrvProtectAsyncRespSetting((uint8_t *)&AsyncRsp, START_STOP_ID, SL_MAX_SOCKETS);
01098         
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       _spi.registerInterruptHandler(NULL, NULL);
01115       _spi.CC3100_disable();
01116       _spi.spi_Close(g_pCB->FD);
01117      
01118     }
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