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