cc3100_Socket_Wifi_Server with Ethernet Interface not working

Dependencies:   EthernetInterface mbed-rtos mbed

Fork of cc3100_Test_Demo by David Fletcher

Embed: (wiki syntax)

« Back to documentation index

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