TI's MQTT Demo with freertos CM4F

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers cc3100_driver.cpp Source File

cc3100_driver.cpp

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