Port of TI's CC3100 Websock camera demo. Using FreeRTOS, mbedTLS, also parts of Arducam for cams ov5642 and 0v2640. Can also use MT9D111. Work in progress. Be warned some parts maybe a bit flacky. This is for Seeed Arch max only, for an M3, see the demo for CM3 using the 0v5642 aducam mini.

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers cc3100_driver.cpp Source File

cc3100_driver.cpp

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