David Fletcher / Mbed 2 deprecated cc3100_Test_websock_Camera_CM4F

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers cc3100_driver.cpp Source File

cc3100_driver.cpp

00001 /*
00002 * driver.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 /* Include files                                                             */
00039 /*****************************************************************************/
00040 #include "cc3100_simplelink.h"
00041 #include "cc3100_protocol.h"
00042 #include "cc3100_driver.h"
00043 
00044 #include "fPtr_func.h"
00045 #include "cli_uart.h"
00046 
00047 #if (defined (SL_PLATFORM_MULTI_THREADED)) || (defined (SL_PLATFORM_EXTERNAL_SPAWN))
00048 #include "osi.h"
00049 #endif
00050 
00051 /*****************************************************************************/
00052 /* Macro declarations                                                        */
00053 /*****************************************************************************/
00054 
00055 namespace mbed_cc3100 {
00056 
00057 #ifndef SL_MEMORY_MGMT_DYNAMIC
00058 typedef struct {
00059     uint32_t      Align;
00060     _SlDriverCb_t DriverCB;
00061     uint8_t AsyncRespBuf[SL_ASYNC_MAX_MSG_LEN];
00062 } _SlStatMem_t;
00063 
00064 _SlStatMem_t g_StatMem;
00065 #endif
00066 
00067 
00068 _SlDriverCb_t* g_pCB = NULL;
00069 
00070 uint8_t gFirstCmdMode = 0;
00071 
00072 const _SlSyncPattern_t g_H2NSyncPattern = H2N_SYNC_PATTERN;
00073 const _SlSyncPattern_t g_H2NCnysPattern = H2N_CNYS_PATTERN;
00074 volatile uint8_t RxIrqCnt;
00075 
00076 #ifndef SL_TINY_EXT
00077 const _SlActionLookup_t _SlActionLookupTable[] = {
00078     {ACCEPT_ID, SL_OPCODE_SOCKET_ACCEPTASYNCRESPONSE, (_SlSpawnEntryFunc_t) &_sl_HandleAsync_Accept},
00079     {CONNECT_ID, SL_OPCODE_SOCKET_CONNECTASYNCRESPONSE,(_SlSpawnEntryFunc_t) &_sl_HandleAsync_Connect},
00080     {SELECT_ID, SL_OPCODE_SOCKET_SELECTASYNCRESPONSE,(_SlSpawnEntryFunc_t) &_sl_HandleAsync_Select},
00081     {GETHOSYBYNAME_ID, SL_OPCODE_NETAPP_DNSGETHOSTBYNAMEASYNCRESPONSE,(_SlSpawnEntryFunc_t) &_sl_HandleAsync_DnsGetHostByName},
00082     {GETHOSYBYSERVICE_ID, SL_OPCODE_NETAPP_MDNSGETHOSTBYSERVICEASYNCRESPONSE,(_SlSpawnEntryFunc_t) &_sl_HandleAsync_DnsGetHostByService},
00083     {PING_ID, SL_OPCODE_NETAPP_PINGREPORTREQUESTRESPONSE, (_SlSpawnEntryFunc_t) &_sl_HandleAsync_PingResponse},
00084     {START_STOP_ID, SL_OPCODE_DEVICE_STOP_ASYNC_RESPONSE,(_SlSpawnEntryFunc_t) &_sl_HandleAsync_Stop}
00085 
00086 };
00087 #else
00088 const _SlActionLookup_t _SlActionLookupTable[] = 
00089 {
00090     {CONNECT_ID, SL_OPCODE_SOCKET_CONNECTASYNCRESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_Connect},
00091     {GETHOSYBYNAME_ID, SL_OPCODE_NETAPP_DNSGETHOSTBYNAMEASYNCRESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_DnsGetHostByName},  
00092     {START_STOP_ID, SL_OPCODE_DEVICE_STOP_ASYNC_RESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_Stop}
00093 };
00094 #endif
00095 
00096 typedef struct
00097 {
00098     uint16_t opcode;
00099     uint8_t  event;
00100 } OpcodeKeyVal_t;
00101 
00102 /* The table translates opcode to user's event type */
00103 const OpcodeKeyVal_t OpcodeTranslateTable[] = 
00104 {
00105 {SL_OPCODE_WLAN_SMART_CONFIG_START_ASYNC_RESPONSE, SL_WLAN_SMART_CONFIG_COMPLETE_EVENT},
00106 {SL_OPCODE_WLAN_SMART_CONFIG_STOP_ASYNC_RESPONSE,SL_WLAN_SMART_CONFIG_STOP_EVENT},
00107 {SL_OPCODE_WLAN_STA_CONNECTED, SL_WLAN_STA_CONNECTED_EVENT},
00108 {SL_OPCODE_WLAN_STA_DISCONNECTED,SL_WLAN_STA_DISCONNECTED_EVENT},
00109 {SL_OPCODE_WLAN_P2P_DEV_FOUND,SL_WLAN_P2P_DEV_FOUND_EVENT},    
00110 {SL_OPCODE_WLAN_P2P_NEG_REQ_RECEIVED, SL_WLAN_P2P_NEG_REQ_RECEIVED_EVENT},
00111 {SL_OPCODE_WLAN_CONNECTION_FAILED, SL_WLAN_CONNECTION_FAILED_EVENT},
00112 {SL_OPCODE_WLAN_WLANASYNCCONNECTEDRESPONSE, SL_WLAN_CONNECT_EVENT},
00113 {SL_OPCODE_WLAN_WLANASYNCDISCONNECTEDRESPONSE, SL_WLAN_DISCONNECT_EVENT},
00114 {SL_OPCODE_NETAPP_IPACQUIRED, SL_NETAPP_IPV4_IPACQUIRED_EVENT},
00115 {SL_OPCODE_NETAPP_IPACQUIRED_V6, SL_NETAPP_IPV6_IPACQUIRED_EVENT},
00116 {SL_OPCODE_NETAPP_IP_LEASED, SL_NETAPP_IP_LEASED_EVENT},
00117 {SL_OPCODE_NETAPP_IP_RELEASED, SL_NETAPP_IP_RELEASED_EVENT},
00118 {SL_OPCODE_SOCKET_TXFAILEDASYNCRESPONSE, SL_SOCKET_TX_FAILED_EVENT},
00119 {SL_OPCODE_SOCKET_SOCKETASYNCEVENT, SL_SOCKET_ASYNC_EVENT}
00120 };
00121 
00122 /*
00123 
00124 #define SL_OPCODE_SILO_DEVICE                           ( 0x0 << SL_OPCODE_SILO_OFFSET )
00125 #define SL_OPCODE_SILO_WLAN                             ( 0x1 << SL_OPCODE_SILO_OFFSET )
00126 #define SL_OPCODE_SILO_SOCKET                           ( 0x2 << SL_OPCODE_SILO_OFFSET )
00127 #define SL_OPCODE_SILO_NETAPP                           ( 0x3 << SL_OPCODE_SILO_OFFSET )
00128 #define SL_OPCODE_SILO_NVMEM                            ( 0x4 << SL_OPCODE_SILO_OFFSET )
00129 #define SL_OPCODE_SILO_NETCFG                           ( 0x5 << SL_OPCODE_SILO_OFFSET )
00130 
00131 
00132 */
00133 
00134 /* The Lookup table below holds the event handlers to be called according to the incoming
00135     RX message SILO type */
00136 const _SlSpawnEntryFunc_t RxMsgClassLUT[] = {
00137     (_SlSpawnEntryFunc_t)_SlDrvDeviceEventHandler, /* SL_OPCODE_SILO_DEVICE */
00138 #if defined(sl_WlanEvtHdlr) || defined(EXT_LIB_REGISTERED_WLAN_EVENTS)
00139     (_SlSpawnEntryFunc_t)_SlDrvHandleWlanEvents,           /* SL_OPCODE_SILO_WLAN */
00140 #else
00141     NULL,
00142 #endif
00143 #if defined (sl_SockEvtHdlr) || defined(EXT_LIB_REGISTERED_SOCK_EVENTS)
00144     (_SlSpawnEntryFunc_t)_SlDrvHandleSockEvents,   /* SL_OPCODE_SILO_SOCKET */
00145 #else
00146     NULL,
00147 #endif
00148 
00149 #if defined(sl_NetAppEvtHdlr) || defined(EXT_LIB_REGISTERED_NETAPP_EVENTS)
00150     (_SlSpawnEntryFunc_t)_SlDrvHandleNetAppEvents, /* SL_OPCODE_SILO_NETAPP */
00151 #else
00152     NULL,  
00153 #endif
00154     NULL,                                          /* SL_OPCODE_SILO_NVMEM */
00155     NULL,                                          /* SL_OPCODE_SILO_NETCFG */
00156     NULL,
00157     NULL
00158 };
00159 
00160 //#ifndef SL_PLATFORM_MULTI_THREADED
00161 #if (!defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN))
00162 cc3100_driver::cc3100_driver(cc3100_spi &spi, cc3100_nonos &nonos, cc3100_netapp &netapp, cc3100_flowcont &flowcont)
00163     :  _spi(spi), _nonos(nonos), _netapp(netapp), _flowcont(flowcont)
00164 {
00165 }
00166 #else
00167 
00168 cc3100_driver::cc3100_driver(cc3100_spi &spi, cc3100_netapp &netapp, cc3100_flowcont &flowcont)
00169     :  _spi(spi), _netapp(netapp), _flowcont(flowcont)
00170 {
00171 }
00172 #endif
00173 
00174 cc3100_driver::~cc3100_driver()
00175 {
00176 
00177 }
00178 
00179 /*****************************************************************************/
00180 /* Variables                                                                 */
00181 /*****************************************************************************/
00182 
00183 /********************************************************************************/
00184 
00185 uint8_t cc3100_driver::_SlDrvProtectAsyncRespSetting(uint8_t *pAsyncRsp, uint8_t ActionID, uint8_t SocketID)
00186 {
00187     uint8_t ObjIdx;
00188 
00189 
00190     /* Use Obj to issue the command, if not available try later */
00191     ObjIdx = _SlDrvWaitForPoolObj(ActionID, SocketID);
00192 
00193     if (MAX_CONCURRENT_ACTIONS != ObjIdx)
00194     {
00195         _SlDrvProtectionObjLockWaitForever();
00196         g_pCB->ObjPool[ObjIdx].pRespArgs = pAsyncRsp;
00197         _SlDrvProtectionObjUnLock();
00198     }
00199 
00200     return ObjIdx;
00201 }
00202 
00203 
00204 /*****************************************************************************/
00205 /* Internal functions                                                        */
00206 /*****************************************************************************/
00207 bool cc3100_driver::_SL_PENDING_RX_MSG(pDriver* pDriverCB){
00208     
00209     if(RxIrqCnt != (pDriverCB)->RxDoneCnt){
00210         return TRUE;
00211     }else{
00212         return FALSE;
00213     }
00214 }
00215 
00216 /*****************************************************************************
00217 _SlDrvDriverCBInit - init Driver Control Block
00218 *****************************************************************************/
00219 void cc3100_driver::_SlDrvDriverCBInit(void)
00220 {
00221     
00222     uint8_t Idx = 0;
00223 
00224 #ifdef SL_MEMORY_MGMT_DYNAMIC
00225 
00226     g_pCB = sl_Malloc(sizeof(_SlDriverCb_t));
00227 #else
00228     g_pCB = &(g_StatMem.DriverCB);
00229 #endif
00230    
00231     MALLOC_OK_CHECK(g_pCB);
00232     _SlDrvMemZero(g_pCB, sizeof(_SlDriverCb_t));
00233     RxIrqCnt = 0;
00234 //#ifndef SL_PLATFORM_MULTI_THREADED
00235 #if (!defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN))
00236     OSI_RET_OK_CHECK( _nonos.sl_SyncObjCreate(&g_pCB->CmdSyncObj, "CmdSyncObj") );
00237     _nonos.sl_SyncObjClear(&g_pCB->CmdSyncObj);
00238     OSI_RET_OK_CHECK( _nonos.sl_LockObjCreate(&g_pCB->GlobalLockObj, "GlobalLockObj") );
00239     OSI_RET_OK_CHECK( _nonos.sl_LockObjCreate(&g_pCB->ProtectionLockObj, "ProtectionLockObj") );
00240 #else    
00241     OSI_RET_OK_CHECK( sl_SyncObjCreate(&g_pCB->CmdSyncObj, "CmdSyncObj") );
00242     sl_SyncObjClear(&g_pCB->CmdSyncObj);
00243     OSI_RET_OK_CHECK( sl_LockObjCreate(&g_pCB->GlobalLockObj, "GlobalLockObj") );
00244     OSI_RET_OK_CHECK( sl_LockObjCreate(&g_pCB->ProtectionLockObj, "ProtectionLockObj") );
00245 #endif    
00246     /* Init Drv object */
00247     _SlDrvMemZero(&g_pCB->ObjPool[0], MAX_CONCURRENT_ACTIONS*sizeof(_SlPoolObj_t));
00248 
00249     /* place all Obj in the free list*/
00250     g_pCB->FreePoolIdx = 0;
00251 
00252     for (Idx = 0 ; Idx < MAX_CONCURRENT_ACTIONS ; Idx++)
00253     {
00254         g_pCB->ObjPool[Idx].NextIndex = Idx + 1;
00255         g_pCB->ObjPool[Idx].AdditionalData = SL_MAX_SOCKETS;
00256 //#ifndef SL_PLATFORM_MULTI_THREADED
00257 #if (!defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN))
00258         OSI_RET_OK_CHECK( _nonos.sl_SyncObjCreate(&g_pCB->ObjPool[Idx].SyncObj, "SyncObj"));
00259         _nonos.sl_SyncObjClear(&g_pCB->ObjPool[Idx].SyncObj);
00260 #else
00261         OSI_RET_OK_CHECK( sl_SyncObjCreate(&g_pCB->ObjPool[Idx].SyncObj, "SyncObj"));
00262         sl_SyncObjClear(&g_pCB->ObjPool[Idx].SyncObj);
00263 #endif               
00264     }
00265 
00266      g_pCB->ActivePoolIdx = MAX_CONCURRENT_ACTIONS;
00267      g_pCB->PendingPoolIdx = MAX_CONCURRENT_ACTIONS;
00268 
00269     /* Flow control init */
00270     g_pCB->FlowContCB.TxPoolCnt = FLOW_CONT_MIN;
00271 //#ifndef SL_PLATFORM_MULTI_THREADED
00272 #if (!defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN))   
00273     OSI_RET_OK_CHECK(_nonos.sl_LockObjCreate(&g_pCB->FlowContCB.TxLockObj, "TxLockObj"));
00274     OSI_RET_OK_CHECK(_nonos.sl_SyncObjCreate(&g_pCB->FlowContCB.TxSyncObj, "TxSyncObj"));
00275 #else
00276     OSI_RET_OK_CHECK(sl_LockObjCreate(&g_pCB->FlowContCB.TxLockObj, "TxLockObj"));
00277     OSI_RET_OK_CHECK(sl_SyncObjCreate(&g_pCB->FlowContCB.TxSyncObj, "TxSyncObj"));
00278 #endif  
00279     gFirstCmdMode = 0;  
00280 }
00281 
00282 /*****************************************************************************
00283 _SlDrvDriverCBDeinit - De init Driver Control Block
00284 *****************************************************************************/
00285 void cc3100_driver::_SlDrvDriverCBDeinit()
00286 {
00287     uint8_t        Idx = 0;
00288     
00289     /* Flow control de-init */
00290     g_pCB->FlowContCB.TxPoolCnt = 0;
00291 //#ifndef SL_PLATFORM_MULTI_THREADED 
00292 #if (!defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN))   
00293     OSI_RET_OK_CHECK(_nonos.sl_LockObjDelete(&g_pCB->FlowContCB.TxLockObj));
00294     OSI_RET_OK_CHECK(_nonos.sl_SyncObjDelete(&g_pCB->FlowContCB.TxSyncObj));
00295     
00296     OSI_RET_OK_CHECK( _nonos.sl_SyncObjDelete(&g_pCB->CmdSyncObj) );
00297     OSI_RET_OK_CHECK( _nonos.sl_LockObjDelete(&g_pCB->GlobalLockObj) );
00298     OSI_RET_OK_CHECK( _nonos.sl_LockObjDelete(&g_pCB->ProtectionLockObj) );
00299 #else    
00300     OSI_RET_OK_CHECK(sl_LockObjDelete(&g_pCB->FlowContCB.TxLockObj));
00301     OSI_RET_OK_CHECK(sl_SyncObjDelete(&g_pCB->FlowContCB.TxSyncObj));
00302     
00303     OSI_RET_OK_CHECK( sl_SyncObjDelete(&g_pCB->CmdSyncObj) );
00304     OSI_RET_OK_CHECK( sl_LockObjDelete(&g_pCB->GlobalLockObj) );
00305     OSI_RET_OK_CHECK( sl_LockObjDelete(&g_pCB->ProtectionLockObj) );   
00306 #endif
00307     
00308 #ifndef SL_TINY_EXT
00309     for (Idx = 0; Idx < MAX_CONCURRENT_ACTIONS; Idx++)
00310 #endif
00311 
00312     g_pCB->FreePoolIdx = 0;
00313     g_pCB->PendingPoolIdx = MAX_CONCURRENT_ACTIONS;
00314     g_pCB->ActivePoolIdx = MAX_CONCURRENT_ACTIONS;
00315 
00316 #ifdef SL_MEMORY_MGMT_DYNAMIC
00317     sl_Free(g_pCB);
00318 #else
00319     g_pCB = NULL;
00320 #endif
00321 
00322     g_pCB = NULL;
00323 }
00324 
00325 /*****************************************************************************
00326 _SlDrvRxIrqHandler - Interrupt handler
00327 *****************************************************************************/
00328 
00329 void cc3100_driver::_SlDrvRxIrqHandler(void *pValue)
00330 {
00331     
00332     int32_t rv = 0;
00333     _spi.MaskIntHdlr();
00334     
00335     RxIrqCnt++;
00336     
00337     if (TRUE == g_pCB->IsCmdRespWaited) {
00338 //#ifndef SL_PLATFORM_MULTI_THREADED
00339 #if (!defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN))      
00340         OSI_RET_OK_CHECK( _nonos.sl_SyncObjSignalFromIRQ(&g_pCB->CmdSyncObj) );
00341 #else        
00342         OSI_RET_OK_CHECK( sl_SyncObjSignalFromIRQ(&g_pCB->CmdSyncObj) );
00343 #endif       
00344     } else {
00345 #if (defined (SL_PLATFORM_MULTI_THREADED)) || (defined (SL_PLATFORM_EXTERNAL_SPAWN))               
00346         rv = sl_Spawn((_SlSpawnEntryFunc_t)_SlDrvMsgReadSpawnCtx, NULL, 0);
00347 
00348         if(rv <0){
00349            Uart_Write((uint8_t*)"\n\r OSI_OPERATION_FAILED \n\r");
00350         }   
00351 #else        
00352         _nonos._SlNonOsSpawn((_SlSpawnEntryFunc_t)&_SlDrvMsgReadSpawnCtx, NULL, 0);
00353 #endif      
00354 //#ifndef SL_PLATFORM_MULTI_THREADED        
00355 //        _nonos._SlNonOsSpawn((_SlSpawnEntryFunc_t)&_SlDrvMsgReadSpawnCtx, NULL, 0);
00356 //#else
00357 //        sl_Spawn((_SlSpawnEntryFunc_t)&_SlDrvMsgReadSpawnCtx, NULL, 0);
00358 //#endif        
00359     }
00360 }
00361 
00362 /*****************************************************************************
00363 _SlDrvCmdOp
00364 *****************************************************************************/
00365 _SlReturnVal_t cc3100_driver::_SlDrvCmdOp(_SlCmdCtrl_t *pCmdCtrl,void* pTxRxDescBuff, _SlCmdExt_t *pCmdExt)
00366 {
00367     _SlReturnVal_t RetVal;
00368     
00369     _SlDrvObjLockWaitForever(&g_pCB->GlobalLockObj);
00370     g_pCB->IsCmdRespWaited = TRUE;
00371     SL_TRACE0(DBG_MSG, MSG_312, "_SlDrvCmdOp: call _SlDrvMsgWrite");
00372     
00373     /* send the message */
00374     RetVal = _SlDrvMsgWrite(pCmdCtrl, pCmdExt, (uint8_t*)pTxRxDescBuff);
00375     
00376     if(SL_OS_RET_CODE_OK == RetVal) {
00377 
00378 #ifndef SL_IF_TYPE_UART
00379         /* Waiting for SPI to stabilize after first command */
00380         if( 0 == gFirstCmdMode ) {           
00381             gFirstCmdMode = 1;
00382             wait_ms(2);
00383         }
00384 #endif
00385         
00386         /* wait for respond */
00387         RetVal = _SlDrvMsgReadCmdCtx(); /* will free global lock */
00388         SL_TRACE0(DBG_MSG, MSG_314, "_SlDrvCmdOp: exited _SlDrvMsgReadCmdCtx");
00389     } else 
00390     {
00391         _SlDrvObjUnLock(&g_pCB->GlobalLockObj);
00392     }
00393     return RetVal;
00394 }
00395 
00396 /*****************************************************************************
00397 _SlDrvDataReadOp
00398 *****************************************************************************/
00399 _SlReturnVal_t cc3100_driver::_SlDrvDataReadOp(_SlSd_t Sd, _SlCmdCtrl_t *pCmdCtrl, void* pTxRxDescBuff, _SlCmdExt_t *pCmdExt)
00400 {
00401     _SlReturnVal_t RetVal;
00402     uint8_t ObjIdx = MAX_CONCURRENT_ACTIONS;
00403     _SlArgsData_t pArgsData;
00404 
00405     /* Validate input arguments */
00406     VERIFY_PROTOCOL(NULL != pCmdExt->pRxPayload);
00407 
00408     /* If zero bytes is requested, return error. */
00409     /*  This allows us not to fill remote socket's IP address in return arguments */
00410     VERIFY_PROTOCOL(0 != pCmdExt->RxPayloadLen);
00411 
00412     /* Validate socket */
00413     if((Sd & BSD_SOCKET_ID_MASK) >= SL_MAX_SOCKETS) {
00414         return SL_EBADF;
00415     }
00416 
00417     /*Use Obj to issue the command, if not available try later*/
00418     ObjIdx = (uint8_t)_SlDrvWaitForPoolObj(RECV_ID, Sd & BSD_SOCKET_ID_MASK);
00419 
00420     if (MAX_CONCURRENT_ACTIONS == ObjIdx) {
00421         return SL_POOL_IS_EMPTY;
00422     }
00423     
00424     _SlDrvProtectionObjLockWaitForever();
00425     
00426     pArgsData.pData = pCmdExt->pRxPayload;
00427     pArgsData.pArgs =  (uint8_t *)pTxRxDescBuff;
00428     g_pCB->ObjPool[ObjIdx].pRespArgs =  (uint8_t *)&pArgsData;
00429     _SlDrvProtectionObjUnLock();
00430 
00431     /* Do Flow Control check/update for DataWrite operation */
00432     _SlDrvObjLockWaitForever(&g_pCB->FlowContCB.TxLockObj);
00433     
00434     /* Clear SyncObj for the case it was signalled before TxPoolCnt */
00435     /* dropped below '1' (last Data buffer was taken)  */
00436     /* OSI_RET_OK_CHECK( sl_SyncObjClear(&g_pCB->FlowContCB.TxSyncObj) ); */
00437 //#ifndef SL_PLATFORM_MULTI_THREADED
00438 #if (!defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN))       
00439     _nonos.sl_SyncObjClear(&g_pCB->FlowContCB.TxSyncObj);
00440 #else    
00441     sl_SyncObjClear(&g_pCB->FlowContCB.TxSyncObj);
00442 #endif
00443     if(g_pCB->FlowContCB.TxPoolCnt <= FLOW_CONT_MIN) {
00444 
00445         /* If TxPoolCnt was increased by other thread at this moment,
00446         TxSyncObj won't wait here */
00447     _SlDrvSyncObjWaitForever(&g_pCB->FlowContCB.TxSyncObj);
00448        
00449     }
00450 
00451     _SlDrvObjLockWaitForever(&g_pCB->GlobalLockObj);
00452 
00453     VERIFY_PROTOCOL(g_pCB->FlowContCB.TxPoolCnt > FLOW_CONT_MIN);
00454     g_pCB->FlowContCB.TxPoolCnt--;
00455 
00456     _SlDrvObjUnLock(&g_pCB->FlowContCB.TxLockObj);
00457 
00458     /* send the message */
00459     RetVal =  _SlDrvMsgWrite(pCmdCtrl, pCmdExt, (uint8_t *)pTxRxDescBuff);
00460 
00461     _SlDrvObjUnLock(&g_pCB->GlobalLockObj);
00462 
00463     if(SL_OS_RET_CODE_OK == RetVal) {
00464         /* Wait for response message. Will be signaled by _SlDrvMsgRead. */
00465         _SlDrvSyncObjWaitForever(&g_pCB->ObjPool[ObjIdx].SyncObj);
00466     }
00467 
00468     _SlDrvReleasePoolObj(ObjIdx);
00469     return RetVal;
00470 }
00471 
00472 /* ******************************************************************************/
00473 /*   _SlDrvDataWriteOp                                                          */
00474 /* ******************************************************************************/
00475 _SlReturnVal_t cc3100_driver::_SlDrvDataWriteOp(_SlSd_t Sd, _SlCmdCtrl_t *pCmdCtrl, void* pTxRxDescBuff, _SlCmdExt_t *pCmdExt)
00476 {
00477     _SlReturnVal_t  RetVal = SL_EAGAIN; /*  initiated as SL_EAGAIN for the non blocking mode */
00478     while( 1 ) {
00479         /*  Do Flow Control check/update for DataWrite operation */        
00480         _SlDrvObjLockWaitForever(&g_pCB->FlowContCB.TxLockObj);
00481 
00482         /*  Clear SyncObj for the case it was signalled before TxPoolCnt */
00483         /*  dropped below '1' (last Data buffer was taken) */
00484         /* OSI_RET_OK_CHECK( sl_SyncObjClear(&g_pCB->FlowContCB.TxSyncObj) ); */
00485 //#ifndef SL_PLATFORM_MULTI_THREADED
00486 #if (!defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN))               
00487         _nonos.sl_SyncObjClear(&g_pCB->FlowContCB.TxSyncObj);
00488 #else        
00489         sl_SyncObjClear(&g_pCB->FlowContCB.TxSyncObj);
00490 #endif               
00491         /*  we have indication that the last send has failed - socket is no longer valid for operations  */
00492         if(g_pCB->SocketTXFailure & (1<<(Sd & BSD_SOCKET_ID_MASK))) {
00493             _SlDrvObjUnLock(&g_pCB->FlowContCB.TxLockObj);
00494             return SL_SOC_ERROR;
00495         }
00496         
00497         if(g_pCB->FlowContCB.TxPoolCnt <= FLOW_CONT_MIN + 1) {
00498             /*  we have indication that this socket is set as blocking and we try to  */
00499             /*  unblock it - return an error */
00500             if( g_pCB->SocketNonBlocking & (1<< (Sd & BSD_SOCKET_ID_MASK)))
00501             {
00502             _SlDrvObjUnLock(&g_pCB->FlowContCB.TxLockObj);
00503                 return RetVal;
00504             }
00505             /*  If TxPoolCnt was increased by other thread at this moment, */
00506             /*  TxSyncObj won't wait here */
00507             _SlDrvSyncObjWaitForever(&g_pCB->FlowContCB.TxSyncObj);
00508         }
00509 
00510         if(g_pCB->FlowContCB.TxPoolCnt > FLOW_CONT_MIN + 1 ) {
00511             break;
00512         } 
00513         else 
00514         {
00515         _SlDrvObjUnLock(&g_pCB->FlowContCB.TxLockObj);
00516         }
00517     }
00518 
00519     _SlDrvObjLockWaitForever(&g_pCB->GlobalLockObj);
00520 
00521 
00522     VERIFY_PROTOCOL(g_pCB->FlowContCB.TxPoolCnt > FLOW_CONT_MIN + 1 );
00523     g_pCB->FlowContCB.TxPoolCnt--;
00524 
00525     _SlDrvObjUnLock(&g_pCB->FlowContCB.TxLockObj);
00526 
00527     /* send the message */
00528     RetVal =  _SlDrvMsgWrite(pCmdCtrl, pCmdExt, (uint8_t*)pTxRxDescBuff);
00529     
00530     _SlDrvObjUnLock(&g_pCB->GlobalLockObj);
00531 
00532     return RetVal;
00533 }
00534 
00535 /* ******************************************************************************/
00536 /*  _SlDrvMsgWrite */
00537 /* ******************************************************************************/
00538 _SlReturnVal_t cc3100_driver::_SlDrvMsgWrite(_SlCmdCtrl_t  *pCmdCtrl, _SlCmdExt_t  *pCmdExt, uint8_t *pTxRxDescBuff)
00539 {
00540     //printf("_SlDrvMsgWrite\r\n");
00541     uint8_t sendRxPayload = FALSE;
00542     VERIFY_PROTOCOL(NULL != pCmdCtrl);
00543 
00544     g_pCB->FunctionParams.pCmdCtrl = pCmdCtrl;
00545     g_pCB->FunctionParams.pTxRxDescBuff = pTxRxDescBuff;
00546     g_pCB->FunctionParams.pCmdExt = pCmdExt;
00547     
00548     g_pCB->TempProtocolHeader.Opcode   = pCmdCtrl->Opcode;
00549     g_pCB->TempProtocolHeader.Len   = _SL_PROTOCOL_CALC_LEN(pCmdCtrl, pCmdExt);
00550 
00551     if (pCmdExt && pCmdExt->RxPayloadLen < 0 && pCmdExt->TxPayloadLen)
00552     {
00553         pCmdExt->RxPayloadLen = pCmdExt->RxPayloadLen * (-1); /* change sign */
00554         sendRxPayload = TRUE;
00555         g_pCB->TempProtocolHeader.Len = g_pCB->TempProtocolHeader.Len + pCmdExt->RxPayloadLen;
00556     }
00557     
00558 #ifdef SL_START_WRITE_STAT
00559     sl_IfStartWriteSequence(g_pCB->FD);
00560 #endif
00561 
00562 #ifdef SL_IF_TYPE_UART
00563     /*  Write long sync pattern */
00564     NWP_IF_WRITE_CHECK(g_pCB->FD, (uint8_t *)&g_H2NSyncPattern.Long, 2*SYNC_PATTERN_LEN);
00565 #else
00566     /*  Write short sync pattern */
00567     NWP_IF_WRITE_CHECK(g_pCB->FD, (uint8_t *)&g_H2NSyncPattern.Short, SYNC_PATTERN_LEN);
00568 #endif
00569     /*  Header */
00570     NWP_IF_WRITE_CHECK(g_pCB->FD, (uint8_t *)&g_pCB->TempProtocolHeader, _SL_CMD_HDR_SIZE);
00571 
00572     /*  Descriptors */
00573     if (pTxRxDescBuff && pCmdCtrl->TxDescLen > 0)
00574     {
00575         NWP_IF_WRITE_CHECK(g_pCB->FD, pTxRxDescBuff, 
00576                            _SL_PROTOCOL_ALIGN_SIZE(pCmdCtrl->TxDescLen));
00577     }
00578 
00579     /*  A special mode where Rx payload and Rx length are used as Tx as well */
00580     /*  This mode requires no Rx payload on the response and currently used by fs_Close and sl_Send on */
00581     /*  transceiver mode */
00582     if (sendRxPayload == TRUE )
00583     {
00584         NWP_IF_WRITE_CHECK(g_pCB->FD, pCmdExt->pRxPayload, _SL_PROTOCOL_ALIGN_SIZE(pCmdExt->RxPayloadLen));
00585     }
00586 
00587     /*  Payload */
00588     if (pCmdExt && pCmdExt->TxPayloadLen > 0)
00589     {
00590         /*  If the message has payload, it is mandatory that the message's arguments are protocol aligned. */
00591         /*  Otherwise the aligning of arguments will create a gap between arguments and payload. */
00592         VERIFY_PROTOCOL(_SL_IS_PROTOCOL_ALIGNED_SIZE(pCmdCtrl->TxDescLen));
00593 
00594         NWP_IF_WRITE_CHECK(g_pCB->FD, pCmdExt->pTxPayload, _SL_PROTOCOL_ALIGN_SIZE(pCmdExt->TxPayloadLen));
00595     }
00596 
00597     _SL_DBG_CNT_INC(MsgCnt.Write);
00598 
00599 #ifdef SL_START_WRITE_STAT
00600     sl_IfEndWriteSequence(g_pCB->FD);
00601 #endif
00602 
00603     return SL_OS_RET_CODE_OK;
00604 }
00605 
00606 /* ******************************************************************************/
00607 /*  _SlDrvMsgRead  */
00608 /* ******************************************************************************/
00609 _SlReturnVal_t cc3100_driver::_SlDrvMsgRead(void)
00610 {
00611     /*  alignment for small memory models */
00612     union {
00613       uint8_t             TempBuf[_SL_RESP_HDR_SIZE];
00614       uint32_t            DummyBuf[2];
00615     } uBuf;
00616     uint8_t               TailBuffer[4];
00617     uint16_t              LengthToCopy;
00618     uint16_t              AlignedLengthRecv;
00619     uint8_t               AlignSize;
00620     uint8_t               *pAsyncBuf = NULL;
00621     uint16_t              OpCode;
00622     uint16_t              RespPayloadLen;
00623     uint8_t               sd = SL_MAX_SOCKETS;
00624     _SlRxMsgClass_e   RxMsgClass;
00625     
00626 
00627     /* save params in global CB */
00628     g_pCB->FunctionParams.AsyncExt.pAsyncBuf      = NULL;
00629     g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler= NULL;
00630 
00631     
00632     VERIFY_RET_OK(_SlDrvRxHdrRead((uint8_t*)(uBuf.TempBuf), &AlignSize));
00633     OpCode = OPCODE(uBuf.TempBuf);
00634     RespPayloadLen = RSP_PAYLOAD_LEN(uBuf.TempBuf);
00635 
00636 
00637     /* 'Init Compelete' message bears no valid FlowControl info */
00638     if(SL_OPCODE_DEVICE_INITCOMPLETE != OpCode) {
00639         g_pCB->FlowContCB.TxPoolCnt = ((_SlResponseHeader_t *)uBuf.TempBuf)->TxPoolCnt;
00640         g_pCB->SocketNonBlocking = ((_SlResponseHeader_t *)uBuf.TempBuf)->SocketNonBlocking;
00641         g_pCB->SocketTXFailure = ((_SlResponseHeader_t *)uBuf.TempBuf)->SocketTXFailure;
00642 
00643         if(g_pCB->FlowContCB.TxPoolCnt > FLOW_CONT_MIN) {
00644             _SlDrvSyncObjSignal(&g_pCB->FlowContCB.TxSyncObj);
00645         }
00646     }
00647    
00648     /* Find the RX messaage class and set its async event handler */
00649     _SlDrvClassifyRxMsg(OpCode);
00650     RxMsgClass = g_pCB->FunctionParams.AsyncExt.RxMsgClass;
00651 
00652 
00653     switch(RxMsgClass)
00654     {
00655     case ASYNC_EVT_CLASS:
00656 
00657             VERIFY_PROTOCOL(NULL == pAsyncBuf);
00658 
00659 #ifdef SL_MEMORY_MGMT_DYNAMIC
00660         g_pCB->FunctionParams.AsyncExt.pAsyncBuf = sl_Malloc(SL_ASYNC_MAX_MSG_LEN);
00661 #else
00662         g_pCB->FunctionParams.AsyncExt.pAsyncBuf = g_StatMem.AsyncRespBuf;
00663 #endif
00664             /* set the local pointer to the allocated one */
00665             pAsyncBuf = g_pCB->FunctionParams.AsyncExt.pAsyncBuf;
00666 
00667             /* clear the async buffer */
00668             _SlDrvMemZero(pAsyncBuf, SL_ASYNC_MAX_MSG_LEN);
00669             
00670             MALLOC_OK_CHECK(pAsyncBuf);
00671 
00672             memcpy(pAsyncBuf, uBuf.TempBuf, _SL_RESP_HDR_SIZE);
00673             if (_SL_PROTOCOL_ALIGN_SIZE(RespPayloadLen) <= SL_ASYNC_MAX_PAYLOAD_LEN)
00674             {
00675                 AlignedLengthRecv = _SL_PROTOCOL_ALIGN_SIZE(RespPayloadLen);
00676             }
00677             else
00678             {
00679                 AlignedLengthRecv = _SL_PROTOCOL_ALIGN_SIZE(SL_ASYNC_MAX_PAYLOAD_LEN);
00680             }
00681             if (RespPayloadLen > 0)
00682             {
00683                 NWP_IF_READ_CHECK(g_pCB->FD, pAsyncBuf + _SL_RESP_HDR_SIZE, AlignedLengthRecv);
00684             }
00685         /* In case ASYNC RX buffer length is smaller then the received data length, dump the rest */
00686             if ((_SL_PROTOCOL_ALIGN_SIZE(RespPayloadLen) > SL_ASYNC_MAX_PAYLOAD_LEN))
00687             {
00688                 AlignedLengthRecv = _SL_PROTOCOL_ALIGN_SIZE(RespPayloadLen) - SL_ASYNC_MAX_PAYLOAD_LEN;
00689                 while (AlignedLengthRecv > 0)
00690                 {
00691                 NWP_IF_READ_CHECK(g_pCB->FD,TailBuffer,4);
00692                 AlignedLengthRecv = AlignedLengthRecv - 4;
00693                 }
00694             }
00695             
00696             _SlDrvProtectionObjLockWaitForever();
00697           
00698             if (
00699 #ifndef SL_TINY_EXT               
00700                 (SL_OPCODE_SOCKET_ACCEPTASYNCRESPONSE == OpCode) || (SL_OPCODE_SOCKET_ACCEPTASYNCRESPONSE_V6 == OpCode) || 
00701 #endif                
00702                 (SL_OPCODE_SOCKET_CONNECTASYNCRESPONSE == OpCode)
00703                )
00704             {
00705                 /* go over the active list if exist to find obj waiting for this Async event */
00706                 sd = ((((_SocketResponse_t *)(pAsyncBuf + _SL_RESP_HDR_SIZE))->sd) & BSD_SOCKET_ID_MASK);
00707             }
00708             _SlFindAndSetActiveObj(OpCode, sd);
00709             _SlDrvProtectionObjUnLock();
00710 
00711             break;
00712     case RECV_RESP_CLASS:
00713         {
00714             uint8_t ExpArgSize; /*  Expected size of Recv/Recvfrom arguments */
00715 
00716             switch(OpCode)
00717             {
00718             case SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE:
00719                 ExpArgSize = RECVFROM_IPV4_ARGS_SIZE;
00720                 break;
00721 #ifndef SL_TINY_EXT                        
00722             case SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE_V6:
00723                 ExpArgSize = RECVFROM_IPV6_ARGS_SIZE;
00724                 break;
00725 #endif                        
00726             default:
00727                 /* SL_OPCODE_SOCKET_RECVASYNCRESPONSE: */
00728                 ExpArgSize = RECV_ARGS_SIZE;
00729             }              
00730 
00731             /*  Read first 4 bytes of Recv/Recvfrom response to get SocketId and actual  */
00732             /*  response data length */
00733             NWP_IF_READ_CHECK(g_pCB->FD, &uBuf.TempBuf[4], RECV_ARGS_SIZE);
00734 
00735             /*  Validate Socket ID and Received Length value.  */
00736             VERIFY_PROTOCOL((SD(&uBuf.TempBuf[4])& BSD_SOCKET_ID_MASK) < SL_MAX_SOCKETS);
00737 
00738             _SlDrvProtectionObjLockWaitForever();
00739 
00740             /* go over the active list if exist to find obj waiting for this Async event */
00741                 VERIFY_RET_OK(_SlFindAndSetActiveObj(OpCode,SD(&uBuf.TempBuf[4]) & BSD_SOCKET_ID_MASK));
00742 
00743             /*  Verify data is waited on this socket. The pArgs should have been set by _SlDrvDataReadOp(). */
00744             VERIFY_SOCKET_CB(NULL !=  ((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pData))->pArgs);    
00745 
00746             memcpy( ((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pArgs, &uBuf.TempBuf[4], RECV_ARGS_SIZE);
00747 
00748             if(ExpArgSize > RECV_ARGS_SIZE)
00749             {
00750                 NWP_IF_READ_CHECK(g_pCB->FD,
00751                     ((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pArgs + RECV_ARGS_SIZE,
00752                     ExpArgSize - RECV_ARGS_SIZE);
00753             }
00754 
00755             /*  Here g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pData contains requested(expected) Recv/Recvfrom DataSize. */
00756             /*  Overwrite requested DataSize with actual one. */
00757             /*  If error is received, this information will be read from arguments. */
00758             if(ACT_DATA_SIZE(&uBuf.TempBuf[4]) > 0)
00759             {       
00760                 VERIFY_SOCKET_CB(NULL != ((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pData);
00761 
00762                 /*  Read 4 bytes aligned from interface */
00763                 /*  therefore check the requested length and read only  */
00764                 /*  4 bytes aligned data. The rest unaligned (if any) will be read */
00765                 /*  and copied to a TailBuffer  */
00766                 LengthToCopy = ACT_DATA_SIZE(&uBuf.TempBuf[4]) & (3);
00767                 AlignedLengthRecv = ACT_DATA_SIZE(&uBuf.TempBuf[4]) & (~3);
00768                 if( AlignedLengthRecv >= 4)
00769                 {
00770                     NWP_IF_READ_CHECK(g_pCB->FD,((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pData,AlignedLengthRecv );                      
00771                 }
00772                 /*  copy the unaligned part, if any */
00773                 if( LengthToCopy > 0) 
00774                 {
00775                     NWP_IF_READ_CHECK(g_pCB->FD,TailBuffer,4);
00776                     /*  copy TailBuffer unaligned part (1/2/3 bytes) */
00777                     memcpy(((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pData + AlignedLengthRecv,TailBuffer,LengthToCopy);                    
00778                 }                  
00779             }
00780                  _SlDrvSyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj);
00781                  _SlDrvProtectionObjUnLock();
00782         }
00783         break;
00784 
00785         case CMD_RESP_CLASS:
00786 
00787             /*  Some commands pass a maximum arguments size. */
00788             /*  In this case Driver will send extra dummy patterns to NWP if */
00789             /*  the response message is smaller than maximum. */
00790             /*  When RxDescLen is not exact, using RxPayloadLen is forbidden! */
00791             /*  If such case cannot be avoided - parse message here to detect */
00792             /*  arguments/payload border. */
00793             NWP_IF_READ_CHECK(g_pCB->FD, g_pCB->FunctionParams.pTxRxDescBuff, _SL_PROTOCOL_ALIGN_SIZE(g_pCB->FunctionParams.pCmdCtrl->RxDescLen));
00794 
00795             if((NULL != g_pCB->FunctionParams.pCmdExt) && (0 != g_pCB->FunctionParams.pCmdExt->RxPayloadLen)) {
00796                 /*  Actual size of command's response payload: <msg_payload_len> - <rsp_args_len> */
00797                 int16_t    ActDataSize = RSP_PAYLOAD_LEN(uBuf.TempBuf) - g_pCB->FunctionParams.pCmdCtrl->RxDescLen;
00798 
00799                 g_pCB->FunctionParams.pCmdExt->ActualRxPayloadLen = ActDataSize;
00800 
00801                 /* Check that the space prepared by user for the response data is sufficient. */
00802                 if(ActDataSize <= 0) {
00803                     g_pCB->FunctionParams.pCmdExt->RxPayloadLen = 0;
00804                 } else {
00805                     /* In case the user supplied Rx buffer length which is smaller then the received data length, copy according to user length */
00806                     if (ActDataSize > g_pCB->FunctionParams.pCmdExt->RxPayloadLen) {
00807                         LengthToCopy = g_pCB->FunctionParams.pCmdExt->RxPayloadLen & (3);
00808                         AlignedLengthRecv = g_pCB->FunctionParams.pCmdExt->RxPayloadLen & (~3);
00809                     } else {
00810                         LengthToCopy = ActDataSize & (3);
00811                         AlignedLengthRecv = ActDataSize & (~3);
00812                     }
00813                     /*  Read 4 bytes aligned from interface */
00814                     /*  therefore check the requested length and read only  */
00815                     /*  4 bytes aligned data. The rest unaligned (if any) will be read */
00816                     /*  and copied to a TailBuffer  */
00817 
00818                     if( AlignedLengthRecv >= 4) {
00819                         NWP_IF_READ_CHECK(g_pCB->FD,
00820                                           g_pCB->FunctionParams.pCmdExt->pRxPayload,
00821                                           AlignedLengthRecv );
00822 
00823                     }
00824                     /*  copy the unaligned part, if any */
00825                     if( LengthToCopy > 0) {
00826                         NWP_IF_READ_CHECK(g_pCB->FD,TailBuffer,4);
00827                         /*  copy TailBuffer unaligned part (1/2/3 bytes) */
00828                         memcpy(g_pCB->FunctionParams.pCmdExt->pRxPayload + AlignedLengthRecv,
00829                                   TailBuffer,
00830                                   LengthToCopy);
00831                         ActDataSize = ActDataSize-4;
00832                     }
00833                     /* In case the user supplied Rx buffer length which is smaller then the received data length, dump the rest */
00834                     if (ActDataSize > g_pCB->FunctionParams.pCmdExt->RxPayloadLen) {
00835                         /* calculate the rest of the data size to dump */
00836                         AlignedLengthRecv = ActDataSize - (g_pCB->FunctionParams.pCmdExt->RxPayloadLen & (~3));
00837                         while( AlignedLengthRecv > 0) {
00838                             NWP_IF_READ_CHECK(g_pCB->FD,TailBuffer, 4 );
00839                             AlignedLengthRecv = AlignedLengthRecv - 4;
00840                         }
00841                     }
00842                 }
00843             }
00844             break;
00845 
00846         default:
00847             /*  DUMMY_MSG_CLASS: Flow control message has no payload. */
00848             break;
00849     }
00850 
00851     if(AlignSize > 0) {
00852         NWP_IF_READ_CHECK(g_pCB->FD, uBuf.TempBuf, AlignSize);
00853     }
00854 
00855     _SL_DBG_CNT_INC(MsgCnt.Read);
00856 
00857     /*  Unmask Interrupt call */
00858     _spi.UnMaskIntHdlr();
00859     
00860     return SL_OS_RET_CODE_OK;
00861 }
00862 
00863 /* ******************************************************************************/
00864 /*  _SlAsyncEventGenericHandler */
00865 /* ******************************************************************************/
00866 void cc3100_driver::_SlAsyncEventGenericHandler(void)
00867 {
00868     uint32_t SlAsyncEvent = 0;
00869     uint8_t  OpcodeFound = FALSE; 
00870     uint8_t  i;
00871     
00872     uint32_t* pEventLocation  = NULL; /* This pointer will override the async buffer with the translated event type */
00873     _SlResponseHeader_t  *pHdr       = (_SlResponseHeader_t *)g_pCB->FunctionParams.AsyncExt.pAsyncBuf;
00874 
00875 
00876     /* if no async event registered nothing to do..*/
00877     if (g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler == NULL)
00878         return;
00879 
00880     /* Iterate through all the opcode in the table */
00881     for (i=0; i< (sizeof(OpcodeTranslateTable) / sizeof(OpcodeKeyVal_t)); i++)
00882     {
00883         if (OpcodeTranslateTable[i].opcode == pHdr->GenHeader.Opcode)
00884         {
00885             SlAsyncEvent = OpcodeTranslateTable[i].event;
00886             OpcodeFound = TRUE;
00887             break;
00888         }
00889     }
00890 
00891     /* No Async event found in the table */
00892     if (OpcodeFound == FALSE)
00893     {
00894         /* This case handles all the async events handlers of the DEVICE & SOCK Silos which are handled internally.
00895                  For these cases we send the async even buffer as is */
00896         g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(g_pCB->FunctionParams.AsyncExt.pAsyncBuf);
00897     }
00898     else
00899     {
00900        /* calculate the event type location to be filled in the async buffer */
00901        pEventLocation = (uint32_t*)(g_pCB->FunctionParams.AsyncExt.pAsyncBuf + sizeof (_SlResponseHeader_t) - sizeof(SlAsyncEvent) );
00902 
00903        /* Override the async buffer (before the data starts ) with our event type  */
00904        *pEventLocation = SlAsyncEvent;
00905 
00906        /* call the event handler registered by the user with our async buffer which now holds
00907                 the User's event type and its related data */
00908        g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(pEventLocation);
00909     }
00910     
00911 }
00912 
00913 
00914 /* ******************************************************************************/
00915 /*  _SlDrvMsgReadCmdCtx  */
00916 /* ******************************************************************************/
00917 _SlReturnVal_t cc3100_driver::_SlDrvMsgReadCmdCtx(void)
00918 {
00919     /*  after command response is received and isCmdRespWaited */
00920     /*  flag is set FALSE, it is necessary to read out all */
00921     /*  Async messages in Commands context, because ssiDma_IsrHandleSignalFromSlave */
00922     /*  could have dispatched some Async messages to g_NwpIf.CmdSyncObj */
00923     /*  after command response but before this response has been processed */
00924     /*  by spi_singleRead and isCmdRespWaited was set FALSE. */
00925     
00926     while (TRUE == g_pCB->IsCmdRespWaited) {
00927         
00928         if(_SL_PENDING_RX_MSG(g_pCB)) {
00929                        
00930             VERIFY_RET_OK(_SlDrvMsgRead());
00931             g_pCB->RxDoneCnt++;
00932             
00933             if (CMD_RESP_CLASS == g_pCB->FunctionParams.AsyncExt.RxMsgClass) {
00934                 g_pCB->IsCmdRespWaited = FALSE;
00935 
00936                 /*  In case CmdResp has been read without  waiting on CmdSyncObj -  that */
00937                 /*  Sync object. That to prevent old signal to be processed. */
00938 //#ifndef SL_PLATFORM_MULTI_THREADED 
00939 #if (!defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN))              
00940                 _nonos.sl_SyncObjClear(&g_pCB->CmdSyncObj);
00941 #else                
00942                 sl_SyncObjClear(&g_pCB->CmdSyncObj);
00943 #endif                
00944             } else if (ASYNC_EVT_CLASS == g_pCB->FunctionParams.AsyncExt.RxMsgClass) {
00945                 /*  If Async event has been read in CmdResp context, check whether */
00946                 /*  there is a handler for this event. If there is, spawn specific */
00947                 /*  handler. Otherwise free the event's buffer. */
00948                 /*  This way there will be no "dry shots" from CmdResp context to */
00949                 /*  temporary context, i.e less waste of CPU and faster buffer */
00950                 /*  release. */
00951                 _SlAsyncEventGenericHandler();
00952                
00953 #ifdef SL_MEMORY_MGMT_DYNAMIC
00954                 sl_Free(g_pCB->FunctionParams.AsyncExt.pAsyncBuf);
00955 #else
00956                 g_pCB->FunctionParams.AsyncExt.pAsyncBuf = NULL;
00957 #endif
00958             }
00959         } else {
00960             /* CmdSyncObj will be signaled by IRQ */
00961             _SlDrvSyncObjWaitForever(&g_pCB->CmdSyncObj);
00962         }
00963     }
00964     
00965     /*  If there are more pending Rx Msgs after CmdResp is received, */
00966     /*  that means that these are Async, Dummy or Read Data Msgs. */
00967     /*  Spawn _SlDrvMsgReadSpawnCtx to trigger reading these messages from */
00968     /*  Temporary context. */
00969     /* sl_Spawn is activated, using a different context */
00970     _SlDrvObjUnLock(&g_pCB->GlobalLockObj);
00971     
00972     if(_SL_PENDING_RX_MSG(g_pCB)) {
00973 //#ifndef SL_PLATFORM_MULTI_THREADED 
00974 #if (!defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN))     
00975       _nonos._SlNonOsSpawn((_SlSpawnEntryFunc_t)&_SlDrvMsgReadSpawnCtx, NULL, 0);
00976 #else
00977       sl_Spawn((_SlSpawnEntryFunc_t)&_SlDrvMsgReadSpawnCtx, NULL, 0);
00978 #endif      
00979     }
00980     
00981     return SL_OS_RET_CODE_OK;
00982 }
00983 
00984 /* ******************************************************************************/
00985 /*  _SlDrvMsgReadSpawnCtx                                                       */
00986 /* ******************************************************************************/
00987 /*
00988 _SlReturnVal_t cc3100_driver::_SlDrvMsgReadSpawnCtx_(void *pValue)
00989 {
00990     
00991 #ifdef SL_POLLING_MODE_USED
00992     int16_t retCode = OSI_OK;
00993     //  for polling based systems 
00994     do {
00995         retCode = sl_LockObjLock(&g_pCB->GlobalLockObj, 0);
00996         if ( OSI_OK != retCode ) {
00997             if (TRUE == g_pCB->IsCmdRespWaited) {
00998                 _SlDrvSyncObjSignal(&g_pCB->CmdSyncObj);
00999                 return SL_RET_CODE_OK;
01000             }
01001         }
01002 
01003     } while (OSI_OK != retCode);
01004 
01005 #else
01006     _SlDrvObjLockWaitForever(&g_pCB->GlobalLockObj);
01007 #endif
01008 
01009     //  Messages might have been read by CmdResp context. Therefore after 
01010     //  getting LockObj, check again where the Pending Rx Msg is still present. 
01011     if(FALSE == (_SL_PENDING_RX_MSG(g_pCB))) {
01012         _SlDrvObjUnLock(&g_pCB->GlobalLockObj);
01013         return SL_RET_CODE_OK;
01014     }
01015 
01016     VERIFY_RET_OK(_SlDrvMsgRead());
01017 
01018     g_pCB->RxDoneCnt++;
01019 
01020     switch(g_pCB->FunctionParams.AsyncExt.RxMsgClass) {
01021         case ASYNC_EVT_CLASS:
01022             //  If got here and protected by LockObj a message is waiting  
01023             //  to be read 
01024             VERIFY_PROTOCOL(NULL != g_pCB->FunctionParams.AsyncExt.pAsyncBuf);
01025 
01026             _SlAsyncEventGenericHandler();
01027 
01028 #ifdef SL_MEMORY_MGMT_DYNAMIC
01029         sl_Free(g_pCB->FunctionParams.AsyncExt.pAsyncBuf);
01030 #else
01031         g_pCB->FunctionParams.AsyncExt.pAsyncBuf = NULL;
01032 #endif
01033             break;
01034         case DUMMY_MSG_CLASS:
01035         case RECV_RESP_CLASS:
01036             // These types are legal in this context. Do nothing 
01037             break;
01038         case CMD_RESP_CLASS:
01039             // Command response is illegal in this context. 
01040             // No 'break' here: Assert! 
01041         default:
01042             VERIFY_PROTOCOL(0);
01043     }
01044 
01045     _SlDrvObjUnLock(&g_pCB->GlobalLockObj);
01046 
01047     return(SL_RET_CODE_OK);
01048 }
01049 */
01050 /* ******************************************************************************/
01051 /*  _SlDrvClassifyRxMsg */
01052 /* ******************************************************************************/
01053 void cc3100_driver::_SlDrvClassifyRxMsg(_SlOpcode_t Opcode)
01054 {
01055     _SlSpawnEntryFunc_t AsyncEvtHandler = NULL;
01056     _SlRxMsgClass_e     RxMsgClass  = CMD_RESP_CLASS;
01057     uint8_t             Silo;
01058     
01059 
01060     if (0 == (SL_OPCODE_SYNC & Opcode))
01061     {   /* Async event has received */
01062         
01063         if (SL_OPCODE_DEVICE_DEVICEASYNCDUMMY == Opcode)
01064         { 
01065             RxMsgClass = DUMMY_MSG_CLASS;
01066         }
01067         else if ( (SL_OPCODE_SOCKET_RECVASYNCRESPONSE == Opcode) || (SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE == Opcode) 
01068 #ifndef SL_TINY_EXT                      
01069                     || (SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE_V6 == Opcode) 
01070 #endif                    
01071                  ) 
01072         {
01073             RxMsgClass = RECV_RESP_CLASS;
01074         }
01075         else
01076         {
01077             /* This is Async Event class message */
01078             RxMsgClass = ASYNC_EVT_CLASS;
01079         
01080             /* Despite the fact that 4 bits are allocated in the SILO field, we actually have only 6 SILOs
01081               So we can use the 8 options of SILO in look up table */
01082             Silo = ((Opcode >> SL_OPCODE_SILO_OFFSET) & 0x7);
01083 
01084             VERIFY_PROTOCOL(Silo < (sizeof(RxMsgClassLUT)/sizeof(_SlSpawnEntryFunc_t)));
01085 
01086             /* Set the async event hander according to the LUT */
01087             AsyncEvtHandler = RxMsgClassLUT[Silo];
01088             
01089             if ((SL_OPCODE_NETAPP_HTTPGETTOKENVALUE == Opcode) || (SL_OPCODE_NETAPP_HTTPPOSTTOKENVALUE == Opcode))
01090             {
01091                 AsyncEvtHandler = _SlDrvNetAppEventHandler;
01092             }
01093 #ifndef SL_TINY_EXT            
01094             else if (SL_OPCODE_NETAPP_PINGREPORTREQUESTRESPONSE == Opcode)
01095             {
01096                 AsyncEvtHandler = (_SlSpawnEntryFunc_t)_sl_HandleAsync_PingResponse;
01097             }
01098 #endif
01099         }
01100     }
01101 
01102     g_pCB->FunctionParams.AsyncExt.RxMsgClass = RxMsgClass; 
01103     g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler = AsyncEvtHandler;
01104 
01105 }
01106 
01107 /* ******************************************************************************/
01108 /*  _SlDrvRxHdrRead  */
01109 /* ******************************************************************************/
01110 _SlReturnVal_t  cc3100_driver::_SlDrvRxHdrRead(uint8_t *pBuf, uint8_t *pAlignSize)
01111 {
01112     uint32_t       SyncCnt  = 0;
01113     uint8_t        ShiftIdx;    
01114     
01115 #ifndef SL_IF_TYPE_UART
01116     /*  1. Write CNYS pattern to NWP when working in SPI mode only  */
01117     NWP_IF_WRITE_CHECK(g_pCB->FD, (uint8_t *)&g_H2NCnysPattern.Short, SYNC_PATTERN_LEN);
01118 #endif
01119   
01120     /*  2. Read 4 bytes (protocol aligned) */
01121     NWP_IF_READ_CHECK(g_pCB->FD, &pBuf[0], 4);
01122     _SL_DBG_SYNC_LOG(SyncCnt,pBuf);
01123  
01124     /* Wait for SYNC_PATTERN_LEN from the device */
01125     while ( ! N2H_SYNC_PATTERN_MATCH(pBuf, g_pCB->TxSeqNum) ) {
01126         /*  3. Debug limit of scan */
01127         if(SyncCnt >= SL_SYNC_SCAN_THRESHOLD){
01128             printf("SPI Sync pattern match fault\n\r");
01129         }
01130         VERIFY_PROTOCOL(SyncCnt < SL_SYNC_SCAN_THRESHOLD);
01131 
01132         /*  4. Read next 4 bytes to Low 4 bytes of buffer */
01133         if(0 == (SyncCnt % (uint32_t)SYNC_PATTERN_LEN)) {
01134             NWP_IF_READ_CHECK(g_pCB->FD, &pBuf[4], 4);
01135             _SL_DBG_SYNC_LOG(SyncCnt,pBuf);
01136         }
01137 
01138         /*  5. Shift Buffer Up for checking if the sync is shifted */
01139         for(ShiftIdx = 0; ShiftIdx< 7; ShiftIdx++)
01140         {
01141             pBuf[ShiftIdx] = pBuf[ShiftIdx+1];
01142         }             
01143         pBuf[7] = 0;
01144 
01145         SyncCnt++;
01146     }
01147 
01148     /*  5. Sync pattern found. If needed, complete number of read bytes to multiple of 4 (protocol align) */
01149     SyncCnt %= SYNC_PATTERN_LEN;
01150 
01151     if(SyncCnt > 0) {
01152         *(uint32_t *)&pBuf[0] = *(uint32_t *)&pBuf[4];
01153         NWP_IF_READ_CHECK(g_pCB->FD, &pBuf[SYNC_PATTERN_LEN - SyncCnt], (uint16_t)SyncCnt);
01154     } else {
01155         NWP_IF_READ_CHECK(g_pCB->FD, &pBuf[0], 4);
01156     }
01157 
01158     /*  6. Scan for Double pattern. */
01159     while ( N2H_SYNC_PATTERN_MATCH(pBuf, g_pCB->TxSeqNum) ) {
01160         _SL_DBG_CNT_INC(Work.DoubleSyncPattern);
01161         NWP_IF_READ_CHECK(g_pCB->FD, &pBuf[0], SYNC_PATTERN_LEN);
01162     }
01163     g_pCB->TxSeqNum++;
01164 
01165     /*  7. Here we've read Generic Header (4 bytes). Read the Resp Specific header (4 more bytes). */
01166     NWP_IF_READ_CHECK(g_pCB->FD, &pBuf[SYNC_PATTERN_LEN], _SL_RESP_SPEC_HDR_SIZE);
01167 
01168     /*  8. Here we've read the entire Resp Header. */
01169     /*     Return number bytes needed to be sent after read for NWP Rx 4-byte alignment (protocol alignment) */
01170     *pAlignSize = (uint8_t)((SyncCnt > 0) ? (SYNC_PATTERN_LEN - SyncCnt) : 0);
01171 
01172     return SL_RET_CODE_OK;
01173 }
01174 
01175 /* ***************************************************************************** */
01176 /*  _SlDrvBasicCmd */
01177 /* ***************************************************************************** */
01178 typedef union {
01179     _BasicResponse_t    Rsp;
01180 } _SlBasicCmdMsg_u;
01181 
01182 #ifndef SL_TINY_EXT
01183 int16_t cc3100_driver::_SlDrvBasicCmd(_SlOpcode_t Opcode)
01184 {
01185     _SlBasicCmdMsg_u       Msg = {0};
01186     _SlCmdCtrl_t           CmdCtrl;
01187 
01188     CmdCtrl.Opcode = Opcode;
01189     CmdCtrl.TxDescLen = 0;
01190     CmdCtrl.RxDescLen = sizeof(_BasicResponse_t);
01191 
01192 
01193     VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&CmdCtrl, &Msg, NULL));
01194 
01195     return (int16_t)Msg.Rsp.status;
01196 }
01197 
01198 /*****************************************************************************
01199   _SlDrvCmdSend 
01200   Send SL command without waiting for command response 
01201   This function is unprotected and the caller should make 
01202   sure global lock is active
01203 *****************************************************************************/
01204 _SlReturnVal_t cc3100_driver::_SlDrvCmdSend(_SlCmdCtrl_t *pCmdCtrl, void *pTxRxDescBuff, _SlCmdExt_t *pCmdExt)
01205 {
01206     _SlReturnVal_t RetVal;
01207     uint8_t        IsCmdRespWaitedOriginalVal;
01208 
01209     _SlFunctionParams_t originalFuncParms;
01210 
01211     /* save the current RespWait flag before clearing it */
01212     IsCmdRespWaitedOriginalVal = g_pCB->IsCmdRespWaited;
01213 
01214     /* save the current command parameters */
01215     memcpy(&originalFuncParms,  &g_pCB->FunctionParams, sizeof(_SlFunctionParams_t));
01216 
01217     g_pCB->IsCmdRespWaited = FALSE;
01218   
01219     SL_TRACE0(DBG_MSG, MSG_312, "_SlDrvCmdSend: call _SlDrvMsgWrite");
01220 
01221     /* send the message */
01222     RetVal = _SlDrvMsgWrite(pCmdCtrl, pCmdExt, (uint8_t*)pTxRxDescBuff);
01223 
01224     /* restore the original RespWait flag */
01225     g_pCB->IsCmdRespWaited = IsCmdRespWaitedOriginalVal;
01226 
01227     /* restore the original command parameters  */
01228     memcpy(&g_pCB->FunctionParams, &originalFuncParms, sizeof(_SlFunctionParams_t));
01229 
01230     return RetVal;
01231 
01232 
01233 }
01234 #endif
01235 
01236 /* ***************************************************************************** */
01237 /*  _SlDrvWaitForPoolObj */
01238 /* ***************************************************************************** */
01239 uint8_t cc3100_driver::_SlDrvWaitForPoolObj(uint8_t ActionID, uint8_t SocketID)
01240 {
01241     uint8_t CurrObjIndex = MAX_CONCURRENT_ACTIONS;
01242     
01243     /* Get free object  */
01244     _SlDrvProtectionObjLockWaitForever();
01245     if (MAX_CONCURRENT_ACTIONS > g_pCB->FreePoolIdx) {
01246         /* save the current obj index */
01247         CurrObjIndex = g_pCB->FreePoolIdx;
01248         /* set the new free index */
01249 #ifndef SL_TINY_EXT        
01250         if (MAX_CONCURRENT_ACTIONS > g_pCB->ObjPool[CurrObjIndex].NextIndex) {
01251             g_pCB->FreePoolIdx = g_pCB->ObjPool[CurrObjIndex].NextIndex;
01252         } 
01253         else
01254 #endif         
01255         {            
01256             /* No further free actions available */
01257             g_pCB->FreePoolIdx = MAX_CONCURRENT_ACTIONS;
01258         }
01259     } else {
01260         _SlDrvProtectionObjUnLock();
01261         return CurrObjIndex;
01262     }
01263     g_pCB->ObjPool[CurrObjIndex].ActionID = (uint8_t)ActionID;
01264     if (SL_MAX_SOCKETS > SocketID) {
01265         g_pCB->ObjPool[CurrObjIndex].AdditionalData = SocketID;
01266     }
01267 #ifndef SL_TINY_EXT    
01268     /*In case this action is socket related, SocketID bit will be on
01269     In case SocketID is set to SL_MAX_SOCKETS, the socket is not relevant to the action. In that case ActionID bit will be on */
01270         while ( ( (SL_MAX_SOCKETS > SocketID) && (g_pCB->ActiveActionsBitmap & (1<<SocketID)) ) || 
01271             ( (g_pCB->ActiveActionsBitmap & (1<<ActionID)) && (SL_MAX_SOCKETS == SocketID) ) )
01272     {
01273         /* action in progress - move to pending list */
01274         g_pCB->ObjPool[CurrObjIndex].NextIndex = g_pCB->PendingPoolIdx;
01275         g_pCB->PendingPoolIdx = CurrObjIndex;
01276         _SlDrvProtectionObjUnLock();
01277         
01278         /* wait for action to be free */
01279         _SlDrvSyncObjWaitForever(&g_pCB->ObjPool[CurrObjIndex].SyncObj);
01280         
01281         /* set params and move to active (remove from pending list at _SlDrvReleasePoolObj) */
01282         _SlDrvProtectionObjLockWaitForever();
01283     }
01284 #endif
01285     /* mark as active. Set socket as active if action is on socket, otherwise mark action as active */
01286     if (SL_MAX_SOCKETS > SocketID) {
01287         g_pCB->ActiveActionsBitmap |= (1<<SocketID);
01288     } else {
01289         g_pCB->ActiveActionsBitmap |= (1<<ActionID);
01290     }
01291     /* move to active list  */
01292     g_pCB->ObjPool[CurrObjIndex].NextIndex = g_pCB->ActivePoolIdx;
01293     g_pCB->ActivePoolIdx = CurrObjIndex;
01294     /* unlock */
01295     _SlDrvProtectionObjUnLock();
01296     return CurrObjIndex;
01297 }
01298 
01299 /* ******************************************************************************/
01300 /*  _SlDrvReleasePoolObj */
01301 /* ******************************************************************************/
01302 void cc3100_driver::_SlDrvReleasePoolObj(uint8_t ObjIdx)
01303 {
01304 #ifndef SL_TINY_EXT        
01305     uint8_t PendingIndex;
01306 #endif
01307 
01308      _SlDrvProtectionObjLockWaitForever();
01309 
01310       /* In Tiny mode, there is only one object pool so no pending actions are available */
01311 #ifndef SL_TINY_EXT
01312     /* go over the pending list and release other pending action if needed */
01313     PendingIndex = g_pCB->PendingPoolIdx;
01314         
01315     while(MAX_CONCURRENT_ACTIONS > PendingIndex)
01316     {
01317         /* In case this action is socket related, SocketID is in use, otherwise will be set to SL_MAX_SOCKETS */
01318         if ( (g_pCB->ObjPool[PendingIndex].ActionID == g_pCB->ObjPool[ObjIdx].ActionID) && 
01319             ( (SL_MAX_SOCKETS == (g_pCB->ObjPool[PendingIndex].AdditionalData & BSD_SOCKET_ID_MASK)) || 
01320             ((SL_MAX_SOCKETS > (g_pCB->ObjPool[ObjIdx].AdditionalData & BSD_SOCKET_ID_MASK)) && ( (g_pCB->ObjPool[PendingIndex].AdditionalData & BSD_SOCKET_ID_MASK) == (g_pCB->ObjPool[ObjIdx].AdditionalData & BSD_SOCKET_ID_MASK) ))) )
01321         {
01322             /* remove from pending list */
01323             _SlRemoveFromList(&g_pCB->PendingPoolIdx, PendingIndex);
01324              _SlDrvSyncObjSignal(&g_pCB->ObjPool[PendingIndex].SyncObj);
01325              break;
01326         }
01327         PendingIndex = g_pCB->ObjPool[PendingIndex].NextIndex;
01328     }
01329 #endif
01330 
01331         if (SL_MAX_SOCKETS > (g_pCB->ObjPool[ObjIdx].AdditionalData & BSD_SOCKET_ID_MASK))
01332         {
01333         /* unset socketID  */
01334             g_pCB->ActiveActionsBitmap &= ~(1<<(g_pCB->ObjPool[ObjIdx].AdditionalData & BSD_SOCKET_ID_MASK));
01335         }
01336         else
01337         {
01338         /* unset actionID  */
01339             g_pCB->ActiveActionsBitmap &= ~(1<<g_pCB->ObjPool[ObjIdx].ActionID);
01340         }
01341 
01342     /* delete old data */
01343     g_pCB->ObjPool[ObjIdx].pRespArgs = NULL;
01344     g_pCB->ObjPool[ObjIdx].ActionID = 0;
01345     g_pCB->ObjPool[ObjIdx].AdditionalData = SL_MAX_SOCKETS;
01346 
01347     /* remove from active list */
01348     _SlRemoveFromList(&g_pCB->ActivePoolIdx, ObjIdx);
01349     /* move to free list */
01350     g_pCB->ObjPool[ObjIdx].NextIndex = g_pCB->FreePoolIdx;
01351     g_pCB->FreePoolIdx = ObjIdx;
01352 
01353     _SlDrvProtectionObjUnLock();
01354 }
01355 
01356 /* ******************************************************************************/
01357 /* _SlRemoveFromList  */
01358 /* ******************************************************************************/
01359 void cc3100_driver::_SlRemoveFromList(uint8_t *ListIndex, uint8_t ItemIndex)
01360 {
01361  #ifndef SL_TINY_EXT  
01362     uint8_t Idx;
01363 #endif        
01364         
01365     if (MAX_CONCURRENT_ACTIONS == g_pCB->ObjPool[*ListIndex].NextIndex)
01366     {
01367         *ListIndex = MAX_CONCURRENT_ACTIONS;
01368     }
01369     /* As MAX_CONCURRENT_ACTIONS is equal to 1 in Tiny mode */
01370 #ifndef SL_TINY_EXT
01371     /* need to remove the first item in the list and therefore update the global which holds this index */
01372     else if (*ListIndex == ItemIndex)
01373     {
01374         *ListIndex = g_pCB->ObjPool[ItemIndex].NextIndex;
01375     }
01376     else
01377     {
01378               Idx = *ListIndex;
01379       
01380               while(MAX_CONCURRENT_ACTIONS > Idx)
01381               {
01382                   /* remove from list */
01383                   if (g_pCB->ObjPool[Idx].NextIndex == ItemIndex)
01384                   {
01385                           g_pCB->ObjPool[Idx].NextIndex = g_pCB->ObjPool[ItemIndex].NextIndex;
01386                           break;
01387                   }
01388 
01389                   Idx = g_pCB->ObjPool[Idx].NextIndex;
01390               }
01391     }
01392 #endif    
01393 }
01394 
01395 /* ******************************************************************************/
01396 /*  _SlFindAndSetActiveObj                                                     */
01397 /* ******************************************************************************/
01398 _SlReturnVal_t cc3100_driver::_SlFindAndSetActiveObj(_SlOpcode_t  Opcode, uint8_t Sd)
01399 {
01400     uint8_t ActiveIndex;
01401 
01402     ActiveIndex = g_pCB->ActivePoolIdx;
01403     /* go over the active list if exist to find obj waiting for this Async event */
01404     #ifndef SL_TINY_EXT    
01405         while (MAX_CONCURRENT_ACTIONS > ActiveIndex){
01406 #else
01407         /* Only one Active action is availabe in tiny mode, so we can replace the loop with if condition */
01408         if (MAX_CONCURRENT_ACTIONS > ActiveIndex)
01409 #endif
01410         /* unset the Ipv4\IPv6 bit in the opcode if family bit was set  */
01411         if (g_pCB->ObjPool[ActiveIndex].AdditionalData & SL_NETAPP_FAMILY_MASK) {
01412             Opcode &= ~SL_OPCODE_IPV6;
01413         }
01414 
01415         if ((g_pCB->ObjPool[ActiveIndex].ActionID == RECV_ID) && (Sd == g_pCB->ObjPool[ActiveIndex].AdditionalData) &&
01416                                         ( (SL_OPCODE_SOCKET_RECVASYNCRESPONSE == Opcode) || (SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE == Opcode)
01417 #ifndef SL_TINY_EXT
01418                         || (SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE_V6 == Opcode) 
01419 #endif
01420                           ) 
01421 
01422                )
01423         {       
01424             g_pCB->FunctionParams.AsyncExt.ActionIndex = ActiveIndex;
01425             return SL_RET_CODE_OK;
01426         }
01427         /* In case this action is socket related, SocketID is in use, otherwise will be set to SL_MAX_SOCKETS */
01428         if ( (_SlActionLookupTable[ g_pCB->ObjPool[ActiveIndex].ActionID - MAX_SOCKET_ENUM_IDX].ActionAsyncOpcode == Opcode) &&
01429                 ( ((Sd == (g_pCB->ObjPool[ActiveIndex].AdditionalData & BSD_SOCKET_ID_MASK) ) && (SL_MAX_SOCKETS > Sd)) || (SL_MAX_SOCKETS == (g_pCB->ObjPool[ActiveIndex].AdditionalData & BSD_SOCKET_ID_MASK)) ) ) {
01430             /* set handler */
01431             g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler = _SlActionLookupTable[ g_pCB->ObjPool[ActiveIndex].ActionID - MAX_SOCKET_ENUM_IDX].AsyncEventHandler;
01432             g_pCB->FunctionParams.AsyncExt.ActionIndex = ActiveIndex;
01433             return SL_RET_CODE_OK;
01434         }
01435         ActiveIndex = g_pCB->ObjPool[ActiveIndex].NextIndex;
01436     }
01437 
01438     return SL_RET_CODE_SELF_ERROR;
01439 
01440 }
01441 
01442 /* Wrappers for the object functions */
01443 
01444 void  cc3100_driver::_SlDrvSyncObjWaitForever(_SlSyncObj_t *pSyncObj)
01445 {
01446 //#ifndef SL_PLATFORM_MULTI_THREADED
01447 #if (!defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN))   
01448     OSI_RET_OK_CHECK(_nonos.sl_SyncObjWait(pSyncObj, SL_OS_WAIT_FOREVER));
01449 #else    
01450     OSI_RET_OK_CHECK(sl_SyncObjWait(pSyncObj, SL_OS_WAIT_FOREVER));
01451 #endif   
01452 }
01453 
01454 void  cc3100_driver::_SlDrvSyncObjSignal(_SlSyncObj_t *pSyncObj)
01455 {
01456 //#ifndef SL_PLATFORM_MULTI_THREADED 
01457 #if (!defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN))  
01458     OSI_RET_OK_CHECK(_nonos.sl_SyncObjSignal(pSyncObj));
01459 #else    
01460     OSI_RET_OK_CHECK(sl_SyncObjSignal(pSyncObj));
01461 #endif   
01462 }
01463 
01464 void cc3100_driver::_SlDrvObjLockWaitForever(_SlLockObj_t *pLockObj)
01465 {
01466 //#ifndef SL_PLATFORM_MULTI_THREADED
01467 #if (!defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN))  
01468     OSI_RET_OK_CHECK(_nonos.sl_LockObjLock(pLockObj, SL_OS_WAIT_FOREVER));
01469 #else    
01470     OSI_RET_OK_CHECK(sl_LockObjLock(pLockObj, SL_OS_WAIT_FOREVER));
01471 #endif    
01472 }
01473 
01474 void cc3100_driver::_SlDrvProtectionObjLockWaitForever()
01475 {
01476 //#ifndef SL_PLATFORM_MULTI_THREADED
01477 #if (!defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN))    
01478     OSI_RET_OK_CHECK(_nonos.sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER));
01479 #else
01480     OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER));
01481 #endif
01482 }
01483 
01484 void cc3100_driver::_SlDrvObjUnLock(_SlLockObj_t *pLockObj)
01485 {
01486 //#ifndef SL_PLATFORM_MULTI_THREADED
01487 #if (!defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN))    
01488     OSI_RET_OK_CHECK(_nonos.sl_LockObjUnlock(pLockObj));
01489 #else    
01490     OSI_RET_OK_CHECK(sl_LockObjUnlock(pLockObj));
01491 #endif
01492 }
01493 
01494 void cc3100_driver::_SlDrvProtectionObjUnLock()
01495 {
01496 //#ifndef SL_PLATFORM_MULTI_THREADED
01497 #if (!defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN))   
01498     OSI_RET_OK_CHECK(_nonos.sl_LockObjUnlock(&g_pCB->ProtectionLockObj));
01499 #else    
01500     OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj));
01501 #endif    
01502 }
01503 
01504 
01505 void cc3100_driver::_SlDrvMemZero(void* Addr, uint16_t size)
01506 {
01507     memset(Addr, 0, size);
01508 }
01509 
01510 
01511 void cc3100_driver::_SlDrvResetCmdExt(_SlCmdExt_t* pCmdExt)
01512 {
01513     _SlDrvMemZero(pCmdExt, sizeof (_SlCmdExt_t));
01514 }
01515 
01516 }//namespace mbed_cc3100
01517 
01518