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