Update revision to use TI's mqtt and Freertos.

Dependencies:   mbed client server

Fork of cc3100_Test_mqtt_CM3 by David Fletcher

Embed: (wiki syntax)

« Back to documentation index

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