DeepCover Embedded Security in IoT: Public-key Secured Data Paths
Dependencies: MaximInterface
driver.c
00001 /* 00002 * driver.c - CC31xx/CC32xx Host Driver Implementation 00003 * 00004 * Copyright (C) 2015 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 "simplelink.h" 00041 #include "protocol.h" 00042 #include "driver.h" 00043 #include "flowcont.h" 00044 00045 /*****************************************************************************/ 00046 /* Macro declarations */ 00047 /*****************************************************************************/ 00048 00049 #define _SL_PENDING_RX_MSG(pDriverCB) (RxIrqCnt != (pDriverCB)->RxDoneCnt) 00050 00051 /* 2 LSB of the N2H_SYNC_PATTERN are for sequence number 00052 only in SPI interface 00053 support backward sync pattern */ 00054 #define N2H_SYNC_PATTERN_SEQ_NUM_BITS ((_u32)0x00000003) /* Bits 0..1 - use the 2 LBS for seq num */ 00055 #define N2H_SYNC_PATTERN_SEQ_NUM_EXISTS ((_u32)0x00000004) /* Bit 2 - sign that sequence number exists in the sync pattern */ 00056 #define N2H_SYNC_PATTERN_MASK ((_u32)0xFFFFFFF8) /* Bits 3..31 - constant SYNC PATTERN */ 00057 #define N2H_SYNC_SPI_BUGS_MASK ((_u32)0x7FFF7F7F) /* Bits 7,15,31 - ignore the SPI (8,16,32 bites bus) error bits */ 00058 #define BUF_SYNC_SPIM(pBuf) ((*(_u32 *)(pBuf)) & N2H_SYNC_SPI_BUGS_MASK) 00059 00060 #define N2H_SYNC_SPIM (N2H_SYNC_PATTERN & N2H_SYNC_SPI_BUGS_MASK) 00061 #define N2H_SYNC_SPIM_WITH_SEQ(TxSeqNum) ((N2H_SYNC_SPIM & N2H_SYNC_PATTERN_MASK) | N2H_SYNC_PATTERN_SEQ_NUM_EXISTS | ((TxSeqNum) & (N2H_SYNC_PATTERN_SEQ_NUM_BITS))) 00062 #define MATCH_WOUT_SEQ_NUM(pBuf) ( BUF_SYNC_SPIM(pBuf) == N2H_SYNC_SPIM ) 00063 #define MATCH_WITH_SEQ_NUM(pBuf, TxSeqNum) ( BUF_SYNC_SPIM(pBuf) == (N2H_SYNC_SPIM_WITH_SEQ(TxSeqNum)) ) 00064 #define N2H_SYNC_PATTERN_MATCH(pBuf, TxSeqNum) \ 00065 ( \ 00066 ( (*((_u32 *)pBuf) & N2H_SYNC_PATTERN_SEQ_NUM_EXISTS) && ( MATCH_WITH_SEQ_NUM(pBuf, TxSeqNum) ) ) || \ 00067 ( !(*((_u32 *)pBuf) & N2H_SYNC_PATTERN_SEQ_NUM_EXISTS) && ( MATCH_WOUT_SEQ_NUM(pBuf ) ) ) \ 00068 ) 00069 00070 #define OPCODE(_ptr) (((_SlResponseHeader_t *)(_ptr))->GenHeader.Opcode) 00071 #define RSP_PAYLOAD_LEN(_ptr) (((_SlResponseHeader_t *)(_ptr))->GenHeader.Len - _SL_RESP_SPEC_HDR_SIZE) 00072 #define SD(_ptr) (((_SocketAddrResponse_u *)(_ptr))->IpV4.sd) 00073 /* Actual size of Recv/Recvfrom response data */ 00074 #define ACT_DATA_SIZE(_ptr) (((_SocketAddrResponse_u *)(_ptr))->IpV4.statusOrLen) 00075 00076 00077 /* Internal function prototype declaration */ 00078 00079 00080 /* General Events handling*/ 00081 #if defined (EXT_LIB_REGISTERED_GENERAL_EVENTS) 00082 00083 typedef _SlEventPropogationStatus_e (*general_callback) (SlDeviceEvent_t *); 00084 00085 static const general_callback general_callbacks[] = 00086 { 00087 #ifdef SlExtLib1GeneralEventHandler 00088 SlExtLib1GeneralEventHandler, 00089 #endif 00090 00091 #ifdef SlExtLib2GeneralEventHandler 00092 SlExtLib2GeneralEventHandler, 00093 #endif 00094 00095 #ifdef SlExtLib3GeneralEventHandler 00096 SlExtLib3GeneralEventHandler, 00097 #endif 00098 00099 #ifdef SlExtLib4GeneralEventHandler 00100 SlExtLib4GeneralEventHandler, 00101 #endif 00102 00103 #ifdef SlExtLib5GeneralEventHandler 00104 SlExtLib5GeneralEventHandler, 00105 #endif 00106 }; 00107 00108 #undef _SlDrvHandleGeneralEvents 00109 00110 /******************************************************************** 00111 _SlDrvHandleGeneralEvents 00112 Iterates through all the general(device) event handlers which are 00113 registered by the external libs/user application. 00114 *********************************************************************/ 00115 void _SlDrvHandleGeneralEvents(SlDeviceEvent_t *slGeneralEvent) 00116 { 00117 _u8 i; 00118 00119 /* Iterate over all the extenal libs handlers */ 00120 for ( i = 0 ; i < sizeof(general_callbacks)/sizeof(general_callbacks[0]) ; i++ ) 00121 { 00122 if (EVENT_PROPAGATION_BLOCK == general_callbacks[i](slGeneralEvent) ) 00123 { 00124 /* exit immediately and do not call the user specific handler as well */ 00125 return; 00126 } 00127 } 00128 00129 /* At last call the Application specific handler if registered */ 00130 #ifdef sl_GeneralEvtHdlr 00131 sl_GeneralEvtHdlr(slGeneralEvent); 00132 #endif 00133 00134 } 00135 #endif 00136 00137 00138 00139 /* WLAN Events handling*/ 00140 00141 #if defined (EXT_LIB_REGISTERED_WLAN_EVENTS) 00142 00143 typedef _SlEventPropogationStatus_e (*wlan_callback) (SlWlanEvent_t *); 00144 00145 static wlan_callback wlan_callbacks[] = 00146 { 00147 #ifdef SlExtLib1WlanEventHandler 00148 SlExtLib1WlanEventHandler, 00149 #endif 00150 00151 #ifdef SlExtLib2WlanEventHandler 00152 SlExtLib2WlanEventHandler, 00153 #endif 00154 00155 #ifdef SlExtLib3WlanEventHandler 00156 SlExtLib3WlanEventHandler, 00157 #endif 00158 00159 #ifdef SlExtLib4WlanEventHandler 00160 SlExtLib4WlanEventHandler, 00161 #endif 00162 00163 #ifdef SlExtLib5WlanEventHandler 00164 SlExtLib5WlanEventHandler, 00165 #endif 00166 }; 00167 00168 #undef _SlDrvHandleWlanEvents 00169 00170 /*********************************************************** 00171 _SlDrvHandleWlanEvents 00172 Iterates through all the wlan event handlers which are 00173 registered by the external libs/user application. 00174 ************************************************************/ 00175 void _SlDrvHandleWlanEvents(SlWlanEvent_t *slWlanEvent) 00176 { 00177 _u8 i; 00178 00179 /* Iterate over all the extenal libs handlers */ 00180 for ( i = 0 ; i < sizeof(wlan_callbacks)/sizeof(wlan_callbacks[0]) ; i++ ) 00181 { 00182 if ( EVENT_PROPAGATION_BLOCK == wlan_callbacks[i](slWlanEvent) ) 00183 { 00184 /* exit immediately and do not call the user specific handler as well */ 00185 return; 00186 } 00187 } 00188 00189 /* At last call the Application specific handler if registered */ 00190 #ifdef sl_WlanEvtHdlr 00191 sl_WlanEvtHdlr(slWlanEvent); 00192 #endif 00193 00194 } 00195 #endif 00196 00197 00198 /* NetApp Events handling */ 00199 #if defined (EXT_LIB_REGISTERED_NETAPP_EVENTS) 00200 00201 typedef _SlEventPropogationStatus_e (*netApp_callback) (SlNetAppEvent_t *); 00202 00203 static const netApp_callback netApp_callbacks[] = 00204 { 00205 #ifdef SlExtLib1NetAppEventHandler 00206 SlExtLib1NetAppEventHandler, 00207 #endif 00208 00209 #ifdef SlExtLib2NetAppEventHandler 00210 SlExtLib2NetAppEventHandler, 00211 #endif 00212 00213 #ifdef SlExtLib3NetAppEventHandler 00214 SlExtLib3NetAppEventHandler, 00215 #endif 00216 00217 #ifdef SlExtLib4NetAppEventHandler 00218 SlExtLib4NetAppEventHandler, 00219 #endif 00220 00221 #ifdef SlExtLib5NetAppEventHandler 00222 SlExtLib5NetAppEventHandler, 00223 #endif 00224 }; 00225 00226 #undef _SlDrvHandleNetAppEvents 00227 00228 /************************************************************ 00229 _SlDrvHandleNetAppEvents 00230 Iterates through all the net app event handlers which are 00231 registered by the external libs/user application. 00232 ************************************************************/ 00233 void _SlDrvHandleNetAppEvents(SlNetAppEvent_t *slNetAppEvent) 00234 { 00235 _u8 i; 00236 00237 /* Iterate over all the extenal libs handlers */ 00238 for ( i = 0 ; i < sizeof(netApp_callbacks)/sizeof(netApp_callbacks[0]) ; i++ ) 00239 { 00240 if (EVENT_PROPAGATION_BLOCK == netApp_callbacks[i](slNetAppEvent) ) 00241 { 00242 /* exit immediately and do not call the user specific handler as well */ 00243 return; 00244 } 00245 } 00246 00247 /* At last call the Application specific handler if registered */ 00248 #ifdef sl_NetAppEvtHdlr 00249 sl_NetAppEvtHdlr(slNetAppEvent); 00250 #endif 00251 00252 } 00253 #endif 00254 00255 00256 /* Http Server Events handling */ 00257 #if defined (EXT_LIB_REGISTERED_HTTP_SERVER_EVENTS) 00258 00259 typedef _SlEventPropogationStatus_e (*httpServer_callback) (SlHttpServerEvent_t*, SlHttpServerResponse_t*); 00260 00261 static const httpServer_callback httpServer_callbacks[] = 00262 { 00263 #ifdef SlExtLib1HttpServerEventHandler 00264 SlExtLib1HttpServerEventHandler, 00265 #endif 00266 00267 #ifdef SlExtLib2HttpServerEventHandler 00268 SlExtLib2HttpServerEventHandler, 00269 #endif 00270 00271 #ifdef SlExtLib3HttpServerEventHandler 00272 SlExtLib3HttpServerEventHandler, 00273 #endif 00274 00275 #ifdef SlExtLib4HttpServerEventHandler 00276 SlExtLib4HttpServerEventHandler, 00277 #endif 00278 00279 #ifdef SlExtLib5HttpServerEventHandler 00280 SlExtLib5HttpServerEventHandler, 00281 #endif 00282 }; 00283 00284 #undef _SlDrvHandleHttpServerEvents 00285 00286 /******************************************************************* 00287 _SlDrvHandleHttpServerEvents 00288 Iterates through all the http server event handlers which are 00289 registered by the external libs/user application. 00290 ********************************************************************/ 00291 void _SlDrvHandleHttpServerEvents(SlHttpServerEvent_t *slHttpServerEvent, SlHttpServerResponse_t *slHttpServerResponse) 00292 { 00293 _u8 i; 00294 00295 /* Iterate over all the external libs handlers */ 00296 for ( i = 0 ; i < sizeof(httpServer_callbacks)/sizeof(httpServer_callbacks[0]) ; i++ ) 00297 { 00298 if ( EVENT_PROPAGATION_BLOCK == httpServer_callbacks[i](slHttpServerEvent, slHttpServerResponse) ) 00299 { 00300 /* exit immediately and do not call the user specific handler as well */ 00301 return; 00302 } 00303 } 00304 00305 /* At last call the Application specific handler if registered */ 00306 #ifdef sl_HttpServerCallback 00307 sl_HttpServerCallback(slHttpServerEvent, slHttpServerResponse); 00308 #endif 00309 00310 } 00311 #endif 00312 00313 00314 /* Socket Events */ 00315 #if defined (EXT_LIB_REGISTERED_SOCK_EVENTS) 00316 00317 typedef _SlEventPropogationStatus_e (*sock_callback) (SlSockEvent_t *); 00318 00319 static const sock_callback sock_callbacks[] = 00320 { 00321 #ifdef SlExtLib1SockEventHandler 00322 SlExtLib1SockEventHandler, 00323 #endif 00324 00325 #ifdef SlExtLib2SockEventHandler 00326 SlExtLib2SockEventHandler, 00327 #endif 00328 00329 #ifdef SlExtLib3SockEventHandler 00330 SlExtLib3SockEventHandler, 00331 #endif 00332 00333 #ifdef SlExtLib4SockEventHandler 00334 SlExtLib4SockEventHandler, 00335 #endif 00336 00337 #ifdef SlExtLib5SockEventHandler 00338 SlExtLib5SockEventHandler, 00339 #endif 00340 }; 00341 00342 /************************************************************* 00343 _SlDrvHandleSockEvents 00344 Iterates through all the socket event handlers which are 00345 registered by the external libs/user application. 00346 **************************************************************/ 00347 void _SlDrvHandleSockEvents(SlSockEvent_t *slSockEvent) 00348 { 00349 _u8 i; 00350 00351 /* Iterate over all the external libs handlers */ 00352 for ( i = 0 ; i < sizeof(sock_callbacks)/sizeof(sock_callbacks[0]) ; i++ ) 00353 { 00354 if ( EVENT_PROPAGATION_BLOCK == sock_callbacks[i](slSockEvent) ) 00355 { 00356 /* exit immediately and do not call the user specific handler as well */ 00357 return; 00358 } 00359 } 00360 00361 /* At last call the Application specific handler if registered */ 00362 #ifdef sl_SockEvtHdlr 00363 sl_SockEvtHdlr(slSockEvent); 00364 #endif 00365 00366 } 00367 00368 #endif 00369 00370 00371 #ifndef SL_MEMORY_MGMT_DYNAMIC 00372 typedef struct 00373 { 00374 _u32 Align; 00375 _SlDriverCb_t DriverCB; 00376 _u8 AsyncRespBuf[SL_ASYNC_MAX_MSG_LEN]; 00377 }_SlStatMem_t; 00378 00379 static _SlStatMem_t g_StatMem; 00380 #endif 00381 00382 _u8 _SlDrvProtectAsyncRespSetting(_u8 *pAsyncRsp, _SlActionID_e ActionID, _u8 SocketID) 00383 { 00384 _u8 ObjIdx; 00385 00386 00387 /* Use Obj to issue the command, if not available try later */ 00388 ObjIdx = (_u8)_SlDrvWaitForPoolObj(ActionID, SocketID); 00389 00390 if (MAX_CONCURRENT_ACTIONS != ObjIdx) 00391 { 00392 SL_DRV_PROTECTION_OBJ_LOCK_FOREVER(); 00393 g_pCB->ObjPool[ObjIdx].pRespArgs = pAsyncRsp; 00394 SL_DRV_PROTECTION_OBJ_UNLOCK(); 00395 } 00396 00397 return ObjIdx; 00398 } 00399 00400 00401 /*****************************************************************************/ 00402 /* Variables */ 00403 /*****************************************************************************/ 00404 static const _SlSyncPattern_t g_H2NSyncPattern = H2N_SYNC_PATTERN; 00405 00406 #ifndef SL_IF_TYPE_UART 00407 static const _SlSyncPattern_t g_H2NCnysPattern = H2N_CNYS_PATTERN; 00408 #endif 00409 00410 00411 _volatile _u8 RxIrqCnt; 00412 00413 #ifndef SL_TINY_EXT 00414 00415 _volatile _u8 g_bDeviceRestartIsRequired; 00416 00417 const _SlActionLookup_t _SlActionLookupTable[] = 00418 { 00419 {ACCEPT_ID, SL_OPCODE_SOCKET_ACCEPTASYNCRESPONSE, (_SlSpawnEntryFunc_t)_sl_HandleAsync_Accept}, 00420 {CONNECT_ID, SL_OPCODE_SOCKET_CONNECTASYNCRESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_Connect}, 00421 {SELECT_ID, SL_OPCODE_SOCKET_SELECTASYNCRESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_Select}, 00422 {GETHOSYBYNAME_ID, SL_OPCODE_NETAPP_DNSGETHOSTBYNAMEASYNCRESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_DnsGetHostByName}, 00423 {GETHOSYBYSERVICE_ID, SL_OPCODE_NETAPP_MDNSGETHOSTBYSERVICEASYNCRESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_DnsGetHostByService}, 00424 {PING_ID, SL_OPCODE_NETAPP_PINGREPORTREQUESTRESPONSE, (_SlSpawnEntryFunc_t)_sl_HandleAsync_PingResponse}, 00425 {START_STOP_ID, SL_OPCODE_DEVICE_STOP_ASYNC_RESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_Stop} 00426 }; 00427 #else 00428 const _SlActionLookup_t _SlActionLookupTable[] = 00429 { 00430 {CONNECT_ID, SL_OPCODE_SOCKET_CONNECTASYNCRESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_Connect}, 00431 {GETHOSYBYNAME_ID, SL_OPCODE_NETAPP_DNSGETHOSTBYNAMEASYNCRESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_DnsGetHostByName}, 00432 {START_STOP_ID, SL_OPCODE_DEVICE_STOP_ASYNC_RESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_Stop} 00433 }; 00434 #endif 00435 00436 00437 00438 typedef struct 00439 { 00440 _u16 opcode; 00441 _u8 event; 00442 } OpcodeKeyVal_t; 00443 00444 /* The table translates opcode to user's event type */ 00445 const OpcodeKeyVal_t OpcodeTranslateTable[] = 00446 { 00447 {SL_OPCODE_WLAN_SMART_CONFIG_START_ASYNC_RESPONSE, SL_WLAN_SMART_CONFIG_COMPLETE_EVENT}, 00448 {SL_OPCODE_WLAN_SMART_CONFIG_STOP_ASYNC_RESPONSE,SL_WLAN_SMART_CONFIG_STOP_EVENT}, 00449 {SL_OPCODE_WLAN_STA_CONNECTED, SL_WLAN_STA_CONNECTED_EVENT}, 00450 {SL_OPCODE_WLAN_STA_DISCONNECTED,SL_WLAN_STA_DISCONNECTED_EVENT}, 00451 {SL_OPCODE_WLAN_P2P_DEV_FOUND,SL_WLAN_P2P_DEV_FOUND_EVENT}, 00452 {SL_OPCODE_WLAN_P2P_NEG_REQ_RECEIVED, SL_WLAN_P2P_NEG_REQ_RECEIVED_EVENT}, 00453 {SL_OPCODE_WLAN_CONNECTION_FAILED, SL_WLAN_CONNECTION_FAILED_EVENT}, 00454 {SL_OPCODE_WLAN_WLANASYNCCONNECTEDRESPONSE, SL_WLAN_CONNECT_EVENT}, 00455 {SL_OPCODE_WLAN_WLANASYNCDISCONNECTEDRESPONSE, SL_WLAN_DISCONNECT_EVENT}, 00456 {SL_OPCODE_NETAPP_IPACQUIRED, SL_NETAPP_IPV4_IPACQUIRED_EVENT}, 00457 {SL_OPCODE_NETAPP_IPACQUIRED_V6, SL_NETAPP_IPV6_IPACQUIRED_EVENT}, 00458 {SL_OPCODE_NETAPP_IP_LEASED, SL_NETAPP_IP_LEASED_EVENT}, 00459 {SL_OPCODE_NETAPP_IP_RELEASED, SL_NETAPP_IP_RELEASED_EVENT}, 00460 {SL_OPCODE_SOCKET_TXFAILEDASYNCRESPONSE, SL_SOCKET_TX_FAILED_EVENT}, 00461 {SL_OPCODE_SOCKET_SOCKETASYNCEVENT, SL_SOCKET_ASYNC_EVENT} 00462 }; 00463 00464 00465 00466 _SlDriverCb_t* g_pCB = NULL; 00467 P_SL_DEV_PING_CALLBACK pPingCallBackFunc = NULL; 00468 00469 #ifndef SL_IF_TYPE_UART 00470 static _u8 gFirstCmdMode = 0; 00471 #endif 00472 00473 /*****************************************************************************/ 00474 /* Function prototypes */ 00475 /*****************************************************************************/ 00476 static _SlReturnVal_t _SlDrvMsgRead(void); 00477 static _SlReturnVal_t _SlDrvMsgWrite(_SlCmdCtrl_t *pCmdCtrl,_SlCmdExt_t *pCmdExt, _u8 *pTxRxDescBuff); 00478 static _SlReturnVal_t _SlDrvMsgReadCmdCtx(_u16 cmdOpcode); 00479 static _SlReturnVal_t _SlDrvClassifyRxMsg(_SlOpcode_t Opcode ); 00480 static _SlReturnVal_t _SlDrvRxHdrRead(_u8 *pBuf, _u8 *pAlignSize); 00481 static void _SlAsyncEventGenericHandler(_u8 bInCmdContext); 00482 static void _SlRemoveFromList(_u8* ListIndex, _u8 ItemIndex); 00483 static _SlReturnVal_t _SlFindAndSetActiveObj(_SlOpcode_t Opcode, _u8 Sd); 00484 static _SlReturnVal_t _SlDrvObjGlobalLockWaitForever(void); 00485 00486 /*****************************************************************************/ 00487 /* Internal functions */ 00488 /*****************************************************************************/ 00489 00490 00491 /***************************************************************************** 00492 _SlDrvDriverCBInit - init Driver Control Block 00493 *****************************************************************************/ 00494 00495 _SlReturnVal_t _SlDrvDriverCBInit(void) 00496 { 00497 _u8 Idx =0; 00498 00499 #ifdef SL_MEMORY_MGMT_DYNAMIC 00500 g_pCB = (_SlDriverCb_t*)sl_Malloc(sizeof(_SlDriverCb_t)); 00501 #else 00502 g_pCB = &(g_StatMem.DriverCB); 00503 #endif 00504 MALLOC_OK_CHECK(g_pCB); 00505 00506 #ifndef SL_PLATFORM_MULTI_THREADED 00507 { 00508 extern _SlNonOsCB_t g__SlNonOsCB; 00509 sl_Memset(&g__SlNonOsCB, 0, sizeof(g__SlNonOsCB)); 00510 } 00511 #endif 00512 00513 _SlDrvMemZero(g_pCB, (_u16)sizeof(_SlDriverCb_t)); 00514 RxIrqCnt = 0; 00515 OSI_RET_OK_CHECK( sl_SyncObjCreate(&g_pCB->CmdSyncObj, "CmdSyncObj") ); 00516 SL_DRV_SYNC_OBJ_CLEAR(&g_pCB->CmdSyncObj); 00517 00518 OSI_RET_OK_CHECK( sl_LockObjCreate(&g_pCB->GlobalLockObj, "GlobalLockObj") ); 00519 OSI_RET_OK_CHECK( sl_LockObjCreate(&g_pCB->ProtectionLockObj, "ProtectionLockObj") ); 00520 00521 /* Init Drv object */ 00522 _SlDrvMemZero(&g_pCB->ObjPool[0], (_u16)(MAX_CONCURRENT_ACTIONS*sizeof(_SlPoolObj_t))); 00523 00524 /* place all Obj in the free list*/ 00525 g_pCB->FreePoolIdx = 0; 00526 00527 for (Idx = 0 ; Idx < MAX_CONCURRENT_ACTIONS ; Idx++) 00528 { 00529 g_pCB->ObjPool[Idx].NextIndex = Idx + 1; 00530 g_pCB->ObjPool[Idx].AdditionalData = SL_MAX_SOCKETS; 00531 00532 OSI_RET_OK_CHECK( sl_SyncObjCreate(&g_pCB->ObjPool[Idx].SyncObj, "SyncObj")); 00533 SL_DRV_SYNC_OBJ_CLEAR(&g_pCB->ObjPool[Idx].SyncObj); 00534 } 00535 00536 g_pCB->ActivePoolIdx = MAX_CONCURRENT_ACTIONS; 00537 g_pCB->PendingPoolIdx = MAX_CONCURRENT_ACTIONS; 00538 00539 /* Flow control init */ 00540 g_pCB->FlowContCB.TxPoolCnt = FLOW_CONT_MIN; 00541 OSI_RET_OK_CHECK(sl_LockObjCreate(&g_pCB->FlowContCB.TxLockObj, "TxLockObj")); 00542 OSI_RET_OK_CHECK(sl_SyncObjCreate(&g_pCB->FlowContCB.TxSyncObj, "TxSyncObj")); 00543 00544 #ifndef SL_IF_TYPE_UART 00545 gFirstCmdMode = 0; 00546 #endif 00547 00548 return SL_OS_RET_CODE_OK; 00549 } 00550 00551 /***************************************************************************** 00552 _SlDrvDriverCBDeinit - De init Driver Control Block 00553 *****************************************************************************/ 00554 _SlReturnVal_t _SlDrvDriverCBDeinit(void) 00555 { 00556 _u8 Idx =0; 00557 00558 /* Flow control de-init */ 00559 g_pCB->FlowContCB.TxPoolCnt = 0; 00560 OSI_RET_OK_CHECK(sl_LockObjDelete(&g_pCB->FlowContCB.TxLockObj)); 00561 OSI_RET_OK_CHECK(sl_SyncObjDelete(&g_pCB->FlowContCB.TxSyncObj)); 00562 00563 OSI_RET_OK_CHECK( sl_SyncObjDelete(&g_pCB->CmdSyncObj) ); 00564 00565 #ifndef SL_TINY_EXT 00566 if (g_bDeviceRestartIsRequired == 0) 00567 #endif 00568 { 00569 OSI_RET_OK_CHECK( sl_LockObjDelete(&g_pCB->GlobalLockObj) ); 00570 } 00571 00572 OSI_RET_OK_CHECK( sl_LockObjDelete(&g_pCB->ProtectionLockObj) ); 00573 00574 #ifndef SL_TINY_EXT 00575 for (Idx = 0; Idx < MAX_CONCURRENT_ACTIONS; Idx++) 00576 #endif 00577 { 00578 OSI_RET_OK_CHECK( sl_SyncObjDelete(&g_pCB->ObjPool[Idx].SyncObj) ); 00579 } 00580 00581 g_pCB->FreePoolIdx = 0; 00582 g_pCB->PendingPoolIdx = MAX_CONCURRENT_ACTIONS; 00583 g_pCB->ActivePoolIdx = MAX_CONCURRENT_ACTIONS; 00584 00585 #ifdef SL_MEMORY_MGMT_DYNAMIC 00586 sl_Free(g_pCB); 00587 #else 00588 g_pCB = NULL; 00589 #endif 00590 00591 00592 g_pCB = NULL; 00593 return SL_OS_RET_CODE_OK; 00594 } 00595 00596 /***************************************************************************** 00597 _SlDrvRxIrqHandler - Interrupt handler 00598 *****************************************************************************/ 00599 _SlReturnVal_t _SlDrvRxIrqHandler(void *pValue) 00600 { 00601 (void)pValue; 00602 00603 sl_IfMaskIntHdlr(); 00604 00605 RxIrqCnt++; 00606 00607 if (TRUE == g_pCB->IsCmdRespWaited) 00608 { 00609 OSI_RET_OK_CHECK( sl_SyncObjSignalFromIRQ(&g_pCB->CmdSyncObj) ); 00610 } 00611 else 00612 { 00613 (void)sl_Spawn((_SlSpawnEntryFunc_t)_SlDrvMsgReadSpawnCtx, NULL, SL_SPAWN_FLAG_FROM_SL_IRQ_HANDLER); 00614 } 00615 return SL_OS_RET_CODE_OK; 00616 } 00617 00618 /***************************************************************************** 00619 _SlDrvCmdOp 00620 *****************************************************************************/ 00621 _SlReturnVal_t _SlDrvCmdOp( 00622 _SlCmdCtrl_t *pCmdCtrl , 00623 void *pTxRxDescBuff , 00624 _SlCmdExt_t *pCmdExt) 00625 { 00626 _SlReturnVal_t RetVal; 00627 00628 SL_DRV_LOCK_GLOBAL_LOCK_FOREVER(); 00629 00630 #ifndef SL_TINY_EXT 00631 /* In case the global was succesffully taken but error in progress 00632 it means it has been released as part of an error handling and we should abort immediately */ 00633 if (TRUE == g_bDeviceRestartIsRequired) 00634 { 00635 SL_DRV_LOCK_GLOBAL_UNLOCK(); 00636 return SL_API_ABORTED; 00637 } 00638 #endif 00639 00640 g_pCB->IsCmdRespWaited = TRUE; 00641 00642 SL_TRACE0(DBG_MSG, MSG_312, "_SlDrvCmdOp: call _SlDrvMsgWrite"); 00643 00644 00645 /* send the message */ 00646 RetVal = _SlDrvMsgWrite(pCmdCtrl, pCmdExt, pTxRxDescBuff); 00647 00648 if(SL_OS_RET_CODE_OK == RetVal) 00649 { 00650 00651 #ifndef SL_IF_TYPE_UART 00652 /* Waiting for SPI to stabilize after first command */ 00653 if( 0 == gFirstCmdMode ) 00654 { 00655 volatile _u32 CountVal = 0; 00656 gFirstCmdMode = 1; 00657 CountVal = CPU_FREQ_IN_MHZ*USEC_DELAY; 00658 while( CountVal-- ); 00659 } 00660 #endif 00661 /* wait for respond */ 00662 RetVal = _SlDrvMsgReadCmdCtx(pCmdCtrl->Opcode); /* will free global lock */ 00663 SL_TRACE0(DBG_MSG, MSG_314, "_SlDrvCmdOp: exited _SlDrvMsgReadCmdCtx"); 00664 } 00665 else 00666 { 00667 SL_DRV_LOCK_GLOBAL_UNLOCK(); 00668 } 00669 00670 return RetVal; 00671 } 00672 00673 00674 00675 /***************************************************************************** 00676 _SlDrvDataReadOp 00677 *****************************************************************************/ 00678 _SlReturnVal_t _SlDrvDataReadOp( 00679 _SlSd_t Sd, 00680 _SlCmdCtrl_t *pCmdCtrl , 00681 void *pTxRxDescBuff , 00682 _SlCmdExt_t *pCmdExt) 00683 { 00684 _SlReturnVal_t RetVal; 00685 _u8 ObjIdx = MAX_CONCURRENT_ACTIONS; 00686 _SlArgsData_t pArgsData; 00687 00688 /* Validate input arguments */ 00689 VERIFY_PROTOCOL(NULL != pCmdExt->pRxPayload); 00690 00691 /* If zero bytes is requested, return error. */ 00692 /* This allows us not to fill remote socket's IP address in return arguments */ 00693 VERIFY_PROTOCOL(0 != pCmdExt->RxPayloadLen); 00694 00695 /* Validate socket */ 00696 if((Sd & BSD_SOCKET_ID_MASK) >= SL_MAX_SOCKETS) 00697 { 00698 return SL_EBADF; 00699 } 00700 00701 /*Use Obj to issue the command, if not available try later*/ 00702 ObjIdx = (_u8)_SlDrvWaitForPoolObj(RECV_ID, Sd & BSD_SOCKET_ID_MASK); 00703 00704 if (MAX_CONCURRENT_ACTIONS == ObjIdx) 00705 { 00706 return SL_POOL_IS_EMPTY; 00707 } 00708 00709 SL_DRV_PROTECTION_OBJ_LOCK_FOREVER(); 00710 00711 pArgsData.pData = pCmdExt->pRxPayload; 00712 pArgsData.pArgs = (_u8 *)pTxRxDescBuff; 00713 g_pCB->ObjPool[ObjIdx].pRespArgs = (_u8 *)&pArgsData; 00714 00715 SL_DRV_PROTECTION_OBJ_UNLOCK(); 00716 00717 00718 /* Do Flow Control check/update for DataWrite operation */ 00719 SL_DRV_OBJ_LOCK_FOREVER(&g_pCB->FlowContCB.TxLockObj); 00720 00721 00722 /* Clear SyncObj for the case it was signalled before TxPoolCnt */ 00723 /* dropped below '1' (last Data buffer was taken) */ 00724 /* OSI_RET_OK_CHECK( sl_SyncObjClear(&g_pCB->FlowContCB.TxSyncObj) ); */ 00725 SL_DRV_SYNC_OBJ_CLEAR(&g_pCB->FlowContCB.TxSyncObj); 00726 00727 if(g_pCB->FlowContCB.TxPoolCnt <= FLOW_CONT_MIN) 00728 { 00729 00730 /* If TxPoolCnt was increased by other thread at this moment, 00731 TxSyncObj won't wait here */ 00732 SL_DRV_SYNC_OBJ_WAIT_FOREVER(&g_pCB->FlowContCB.TxSyncObj); 00733 00734 } 00735 00736 SL_DRV_LOCK_GLOBAL_LOCK_FOREVER(); 00737 00738 #ifndef SL_TINY_EXT 00739 /* In case the global was succesffully taken but error in progress 00740 it means it has been released as part of an error handling and we should abort immediately */ 00741 if (TRUE == g_bDeviceRestartIsRequired) 00742 { 00743 SL_DRV_LOCK_GLOBAL_UNLOCK(); 00744 return SL_API_ABORTED; 00745 } 00746 #endif 00747 00748 VERIFY_PROTOCOL(g_pCB->FlowContCB.TxPoolCnt > FLOW_CONT_MIN); 00749 g_pCB->FlowContCB.TxPoolCnt--; 00750 00751 SL_DRV_OBJ_UNLOCK(&g_pCB->FlowContCB.TxLockObj); 00752 00753 /* send the message */ 00754 RetVal = _SlDrvMsgWrite(pCmdCtrl, pCmdExt, (_u8 *)pTxRxDescBuff); 00755 00756 SL_DRV_LOCK_GLOBAL_UNLOCK(); 00757 00758 00759 if(SL_OS_RET_CODE_OK == RetVal) 00760 { 00761 #ifndef SL_TINY_EXT 00762 /* in case socket is non-blocking one, the async event should be received immediately */ 00763 if( g_pCB->SocketNonBlocking & (1<<(Sd & BSD_SOCKET_ID_MASK) )) 00764 { 00765 SlDriverAPIWithTimeout_e api = (pCmdCtrl->Opcode == SL_OPCODE_SOCKET_RECV) ? SL_DRIVER_API_SOCKET_RECV : SL_DRIVER_API_SOCKET_RECVFROM; 00766 00767 SL_DRV_SYNC_OBJ_WAIT_TIMEOUT(&g_pCB->ObjPool[ObjIdx].SyncObj, 00768 SL_DRIVER_TIMEOUT_SHORT, 00769 api 00770 ); 00771 } 00772 else 00773 #endif 00774 { 00775 /* Wait for response message. Will be signaled by _SlDrvMsgRead. */ 00776 SL_DRV_SYNC_OBJ_WAIT_FOREVER(&g_pCB->ObjPool[ObjIdx].SyncObj); 00777 } 00778 00779 } 00780 00781 _SlDrvReleasePoolObj(ObjIdx); 00782 return RetVal; 00783 } 00784 00785 /* ******************************************************************************/ 00786 /* _SlDrvDataWriteOp */ 00787 /* ******************************************************************************/ 00788 _SlReturnVal_t _SlDrvDataWriteOp( 00789 _SlSd_t Sd, 00790 _SlCmdCtrl_t *pCmdCtrl , 00791 void *pTxRxDescBuff , 00792 _SlCmdExt_t *pCmdExt) 00793 { 00794 _SlReturnVal_t RetVal = SL_EAGAIN; /* initiated as SL_EAGAIN for the non blocking mode */ 00795 while( 1 ) 00796 { 00797 /* Do Flow Control check/update for DataWrite operation */ 00798 SL_DRV_OBJ_LOCK_FOREVER(&g_pCB->FlowContCB.TxLockObj); 00799 00800 /* Clear SyncObj for the case it was signalled before TxPoolCnt */ 00801 /* dropped below '1' (last Data buffer was taken) */ 00802 /* OSI_RET_OK_CHECK( sl_SyncObjClear(&g_pCB->FlowContCB.TxSyncObj) ); */ 00803 SL_DRV_SYNC_OBJ_CLEAR(&g_pCB->FlowContCB.TxSyncObj); 00804 00805 /* we have indication that the last send has failed - socket is no longer valid for operations */ 00806 if(g_pCB->SocketTXFailure & (1<<(Sd & BSD_SOCKET_ID_MASK))) 00807 { 00808 SL_DRV_OBJ_UNLOCK(&g_pCB->FlowContCB.TxLockObj); 00809 return SL_SOC_ERROR; 00810 } 00811 if(g_pCB->FlowContCB.TxPoolCnt <= FLOW_CONT_MIN + 1) 00812 { 00813 /* we have indication that this socket is set as blocking and we try to */ 00814 /* unblock it - return an error */ 00815 if( g_pCB->SocketNonBlocking & (1<<(Sd & BSD_SOCKET_ID_MASK) )) 00816 { 00817 SL_DRV_OBJ_UNLOCK(&g_pCB->FlowContCB.TxLockObj); 00818 return RetVal; 00819 } 00820 /* If TxPoolCnt was increased by other thread at this moment, */ 00821 /* TxSyncObj won't wait here */ 00822 00823 SL_DRV_SYNC_OBJ_WAIT_FOREVER(&g_pCB->FlowContCB.TxSyncObj); 00824 } 00825 if(g_pCB->FlowContCB.TxPoolCnt > FLOW_CONT_MIN + 1 ) 00826 { 00827 break; 00828 } 00829 else 00830 { 00831 SL_DRV_OBJ_UNLOCK(&g_pCB->FlowContCB.TxLockObj); 00832 } 00833 } 00834 00835 SL_DRV_LOCK_GLOBAL_LOCK_FOREVER(); 00836 00837 #ifndef SL_TINY_EXT 00838 /* In case the global was succesffully taken but error in progress 00839 it means it has been released as part of an error handling and we should abort immediately */ 00840 if (TRUE == g_bDeviceRestartIsRequired) 00841 { 00842 SL_DRV_LOCK_GLOBAL_UNLOCK(); 00843 return SL_API_ABORTED; 00844 } 00845 #endif 00846 00847 00848 VERIFY_PROTOCOL(g_pCB->FlowContCB.TxPoolCnt > FLOW_CONT_MIN + 1 ); 00849 g_pCB->FlowContCB.TxPoolCnt--; 00850 00851 SL_DRV_OBJ_UNLOCK(&g_pCB->FlowContCB.TxLockObj); 00852 00853 /* send the message */ 00854 RetVal = _SlDrvMsgWrite(pCmdCtrl, pCmdExt, pTxRxDescBuff); 00855 00856 SL_DRV_LOCK_GLOBAL_UNLOCK(); 00857 00858 return RetVal; 00859 } 00860 00861 /* ******************************************************************************/ 00862 /* _SlDrvMsgWrite */ 00863 /* ******************************************************************************/ 00864 static _SlReturnVal_t _SlDrvMsgWrite(_SlCmdCtrl_t *pCmdCtrl,_SlCmdExt_t *pCmdExt, _u8 *pTxRxDescBuff) 00865 { 00866 _u8 sendRxPayload = FALSE; 00867 VERIFY_PROTOCOL(NULL != pCmdCtrl); 00868 00869 g_pCB->FunctionParams.pCmdCtrl = pCmdCtrl; 00870 g_pCB->FunctionParams.pTxRxDescBuff = pTxRxDescBuff; 00871 g_pCB->FunctionParams.pCmdExt = pCmdExt; 00872 00873 g_pCB->TempProtocolHeader.Opcode = pCmdCtrl->Opcode; 00874 g_pCB->TempProtocolHeader.Len = (_u16)(_SL_PROTOCOL_CALC_LEN(pCmdCtrl, pCmdExt)); 00875 00876 if (pCmdExt && pCmdExt->RxPayloadLen < 0 ) 00877 { 00878 pCmdExt->RxPayloadLen = pCmdExt->RxPayloadLen * (-1); /* change sign */ 00879 sendRxPayload = TRUE; 00880 g_pCB->TempProtocolHeader.Len = g_pCB->TempProtocolHeader.Len + pCmdExt->RxPayloadLen; 00881 } 00882 00883 #ifdef SL_START_WRITE_STAT 00884 sl_IfStartWriteSequence(g_pCB->FD); 00885 #endif 00886 00887 #ifdef SL_IF_TYPE_UART 00888 /* Write long sync pattern */ 00889 NWP_IF_WRITE_CHECK(g_pCB->FD, (_u8 *)&g_H2NSyncPattern.Long, 2*SYNC_PATTERN_LEN); 00890 #else 00891 /* Write short sync pattern */ 00892 NWP_IF_WRITE_CHECK(g_pCB->FD, (_u8 *)&g_H2NSyncPattern.Short, SYNC_PATTERN_LEN); 00893 #endif 00894 00895 /* Header */ 00896 NWP_IF_WRITE_CHECK(g_pCB->FD, (_u8 *)&g_pCB->TempProtocolHeader, _SL_CMD_HDR_SIZE); 00897 00898 /* Descriptors */ 00899 if (pTxRxDescBuff && pCmdCtrl->TxDescLen > 0) 00900 { 00901 NWP_IF_WRITE_CHECK(g_pCB->FD, pTxRxDescBuff, 00902 _SL_PROTOCOL_ALIGN_SIZE(pCmdCtrl->TxDescLen)); 00903 } 00904 00905 /* A special mode where Rx payload and Rx length are used as Tx as well */ 00906 /* This mode requires no Rx payload on the response and currently used by fs_Close and sl_Send on */ 00907 /* transceiver mode */ 00908 if (sendRxPayload == TRUE ) 00909 { 00910 NWP_IF_WRITE_CHECK(g_pCB->FD, pCmdExt->pRxPayload, 00911 _SL_PROTOCOL_ALIGN_SIZE(pCmdExt->RxPayloadLen)); 00912 } 00913 00914 /* Payload */ 00915 if (pCmdExt && pCmdExt->TxPayloadLen > 0) 00916 { 00917 /* If the message has payload, it is mandatory that the message's arguments are protocol aligned. */ 00918 /* Otherwise the aligning of arguments will create a gap between arguments and payload. */ 00919 VERIFY_PROTOCOL(_SL_IS_PROTOCOL_ALIGNED_SIZE(pCmdCtrl->TxDescLen)); 00920 00921 NWP_IF_WRITE_CHECK(g_pCB->FD, pCmdExt->pTxPayload, 00922 _SL_PROTOCOL_ALIGN_SIZE(pCmdExt->TxPayloadLen)); 00923 } 00924 00925 00926 _SL_DBG_CNT_INC(MsgCnt.Write); 00927 00928 #ifdef SL_START_WRITE_STAT 00929 sl_IfEndWriteSequence(g_pCB->FD); 00930 #endif 00931 00932 return SL_OS_RET_CODE_OK; 00933 } 00934 00935 /* ******************************************************************************/ 00936 /* _SlDrvMsgRead */ 00937 /* ******************************************************************************/ 00938 static _SlReturnVal_t _SlDrvMsgRead(void) 00939 { 00940 /* alignment for small memory models */ 00941 union 00942 { 00943 _u8 TempBuf[_SL_RESP_HDR_SIZE]; 00944 _u32 DummyBuf[2]; 00945 } uBuf; 00946 _u8 TailBuffer[4]; 00947 _u16 LengthToCopy; 00948 _u16 AlignedLengthRecv; 00949 _u8 AlignSize; 00950 _u8 *pAsyncBuf = NULL; 00951 _u16 OpCode; 00952 _u16 RespPayloadLen; 00953 _u8 sd = SL_MAX_SOCKETS; 00954 _SlRxMsgClass_e RxMsgClass; 00955 00956 00957 /* save params in global CB */ 00958 g_pCB->FunctionParams.AsyncExt.pAsyncBuf = NULL; 00959 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler= NULL; 00960 00961 #ifdef SL_TINY_EXT 00962 VERIFY_RET_OK(_SlDrvRxHdrRead((_u8*)(uBuf.TempBuf), &AlignSize)); 00963 #else 00964 if (_SlDrvRxHdrRead((_u8*)(uBuf.TempBuf), &AlignSize) == SL_API_ABORTED) 00965 { 00966 SL_DRV_LOCK_GLOBAL_UNLOCK(); 00967 00968 _SlDriverHandleError(SL_DEVICE_DRIVER_TIMEOUT_SYNC_PATTERN, 0, 0); 00969 return SL_API_ABORTED; 00970 } 00971 #endif 00972 OpCode = OPCODE(uBuf.TempBuf); 00973 RespPayloadLen = (_u16)(RSP_PAYLOAD_LEN(uBuf.TempBuf)); 00974 00975 00976 /* 'Init Compelete' message bears no valid FlowControl info */ 00977 if(SL_OPCODE_DEVICE_INITCOMPLETE != OpCode) 00978 { 00979 g_pCB->FlowContCB.TxPoolCnt = ((_SlResponseHeader_t *)uBuf.TempBuf)->TxPoolCnt; 00980 g_pCB->SocketNonBlocking = ((_SlResponseHeader_t *)uBuf.TempBuf)->SocketNonBlocking; 00981 g_pCB->SocketTXFailure = ((_SlResponseHeader_t *)uBuf.TempBuf)->SocketTXFailure; 00982 00983 if(g_pCB->FlowContCB.TxPoolCnt > FLOW_CONT_MIN) 00984 { 00985 SL_DRV_SYNC_OBJ_SIGNAL(&g_pCB->FlowContCB.TxSyncObj); 00986 } 00987 } 00988 00989 /* Find the RX messaage class and set its async event handler */ 00990 _SlDrvClassifyRxMsg(OpCode); 00991 00992 RxMsgClass = g_pCB->FunctionParams.AsyncExt.RxMsgClass; 00993 00994 00995 switch(RxMsgClass) 00996 { 00997 case ASYNC_EVT_CLASS: 00998 00999 VERIFY_PROTOCOL(NULL == pAsyncBuf); 01000 01001 #ifdef SL_MEMORY_MGMT_DYNAMIC 01002 g_pCB->FunctionParams.AsyncExt.pAsyncBuf = (_u8*)sl_Malloc(SL_ASYNC_MAX_MSG_LEN); 01003 #else 01004 g_pCB->FunctionParams.AsyncExt.pAsyncBuf = g_StatMem.AsyncRespBuf; 01005 #endif 01006 /* set the local pointer to the allocated one */ 01007 pAsyncBuf = g_pCB->FunctionParams.AsyncExt.pAsyncBuf; 01008 01009 /* clear the async buffer */ 01010 _SlDrvMemZero(pAsyncBuf, (_u16)SL_ASYNC_MAX_MSG_LEN); 01011 01012 MALLOC_OK_CHECK(pAsyncBuf); 01013 01014 sl_Memcpy(pAsyncBuf, uBuf.TempBuf, _SL_RESP_HDR_SIZE); 01015 if (_SL_PROTOCOL_ALIGN_SIZE(RespPayloadLen) <= SL_ASYNC_MAX_PAYLOAD_LEN) 01016 { 01017 AlignedLengthRecv = (_u16)_SL_PROTOCOL_ALIGN_SIZE(RespPayloadLen); 01018 } 01019 else 01020 { 01021 AlignedLengthRecv = (_u16)_SL_PROTOCOL_ALIGN_SIZE(SL_ASYNC_MAX_PAYLOAD_LEN); 01022 } 01023 if (RespPayloadLen > 0) 01024 { 01025 NWP_IF_READ_CHECK(g_pCB->FD, 01026 pAsyncBuf + _SL_RESP_HDR_SIZE, 01027 AlignedLengthRecv); 01028 } 01029 /* In case ASYNC RX buffer length is smaller then the received data length, dump the rest */ 01030 if ((_SL_PROTOCOL_ALIGN_SIZE(RespPayloadLen) > SL_ASYNC_MAX_PAYLOAD_LEN)) 01031 { 01032 AlignedLengthRecv = (_u16)(_SL_PROTOCOL_ALIGN_SIZE(RespPayloadLen) - SL_ASYNC_MAX_PAYLOAD_LEN); 01033 while (AlignedLengthRecv > 0) 01034 { 01035 NWP_IF_READ_CHECK(g_pCB->FD,TailBuffer,4); 01036 AlignedLengthRecv = AlignedLengthRecv - 4; 01037 } 01038 } 01039 01040 SL_DRV_PROTECTION_OBJ_LOCK_FOREVER(); 01041 01042 if ( 01043 #ifndef SL_TINY_EXT 01044 (SL_OPCODE_SOCKET_ACCEPTASYNCRESPONSE == OpCode) || 01045 (SL_OPCODE_SOCKET_ACCEPTASYNCRESPONSE_V6 == OpCode) || 01046 #endif 01047 (SL_OPCODE_SOCKET_CONNECTASYNCRESPONSE == OpCode) 01048 ) 01049 { 01050 /* go over the active list if exist to find obj waiting for this Async event */ 01051 sd = ((((_SocketResponse_t *)(pAsyncBuf + _SL_RESP_HDR_SIZE))->sd) & BSD_SOCKET_ID_MASK); 01052 } 01053 01054 (void)_SlFindAndSetActiveObj(OpCode, sd); 01055 01056 SL_DRV_PROTECTION_OBJ_UNLOCK(); 01057 01058 break; 01059 case RECV_RESP_CLASS: 01060 { 01061 _u8 ExpArgSize; /* Expected size of Recv/Recvfrom arguments */ 01062 01063 switch(OpCode) 01064 { 01065 case SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE: 01066 ExpArgSize = (_u8)RECVFROM_IPV4_ARGS_SIZE; 01067 break; 01068 #ifndef SL_TINY_EXT 01069 case SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE_V6: 01070 ExpArgSize = (_u8)RECVFROM_IPV6_ARGS_SIZE; 01071 break; 01072 #endif 01073 default: 01074 /* SL_OPCODE_SOCKET_RECVASYNCRESPONSE: */ 01075 ExpArgSize = (_u8)RECV_ARGS_SIZE; 01076 } 01077 01078 /* Read first 4 bytes of Recv/Recvfrom response to get SocketId and actual */ 01079 /* response data length */ 01080 NWP_IF_READ_CHECK(g_pCB->FD, &uBuf.TempBuf[4], RECV_ARGS_SIZE); 01081 01082 /* Validate Socket ID and Received Length value. */ 01083 VERIFY_PROTOCOL((SD(&uBuf.TempBuf[4])& BSD_SOCKET_ID_MASK) < SL_MAX_SOCKETS); 01084 01085 SL_DRV_PROTECTION_OBJ_LOCK_FOREVER(); 01086 01087 /* go over the active list if exist to find obj waiting for this Async event */ 01088 VERIFY_RET_OK(_SlFindAndSetActiveObj(OpCode,SD(&uBuf.TempBuf[4]) & BSD_SOCKET_ID_MASK)); 01089 01090 /* Verify data is waited on this socket. The pArgs should have been set by _SlDrvDataReadOp(). */ 01091 VERIFY_SOCKET_CB(NULL != ((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pData))->pArgs); 01092 01093 sl_Memcpy( ((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pArgs, &uBuf.TempBuf[4], RECV_ARGS_SIZE); 01094 01095 if(ExpArgSize > (_u8)RECV_ARGS_SIZE) 01096 { 01097 NWP_IF_READ_CHECK(g_pCB->FD, 01098 ((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pArgs + RECV_ARGS_SIZE, 01099 ExpArgSize - RECV_ARGS_SIZE); 01100 } 01101 01102 /* Here g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pData contains requested(expected) Recv/Recvfrom DataSize. */ 01103 /* Overwrite requested DataSize with actual one. */ 01104 /* If error is received, this information will be read from arguments. */ 01105 if(ACT_DATA_SIZE(&uBuf.TempBuf[4]) > 0) 01106 { 01107 VERIFY_SOCKET_CB(NULL != ((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pData); 01108 01109 /* Read 4 bytes aligned from interface */ 01110 /* therefore check the requested length and read only */ 01111 /* 4 bytes aligned data. The rest unaligned (if any) will be read */ 01112 /* and copied to a TailBuffer */ 01113 LengthToCopy = (_u16)(ACT_DATA_SIZE(&uBuf.TempBuf[4]) & (3)); 01114 AlignedLengthRecv = (_u16)(ACT_DATA_SIZE(&uBuf.TempBuf[4]) & (~3)); 01115 if( AlignedLengthRecv >= 4) 01116 { 01117 NWP_IF_READ_CHECK(g_pCB->FD,((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pData,AlignedLengthRecv ); 01118 } 01119 /* copy the unaligned part, if any */ 01120 if( LengthToCopy > 0) 01121 { 01122 NWP_IF_READ_CHECK(g_pCB->FD,TailBuffer,4); 01123 /* copy TailBuffer unaligned part (1/2/3 bytes) */ 01124 sl_Memcpy(((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pData + AlignedLengthRecv,TailBuffer,LengthToCopy); 01125 } 01126 } 01127 SL_DRV_SYNC_OBJ_SIGNAL(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj); 01128 SL_DRV_PROTECTION_OBJ_UNLOCK(); 01129 } 01130 break; 01131 01132 case CMD_RESP_CLASS: 01133 01134 /* Some commands pass a maximum arguments size. */ 01135 /* In this case Driver will send extra dummy patterns to NWP if */ 01136 /* the response message is smaller than maximum. */ 01137 /* When RxDescLen is not exact, using RxPayloadLen is forbidden! */ 01138 /* If such case cannot be avoided - parse message here to detect */ 01139 /* arguments/payload border. */ 01140 NWP_IF_READ_CHECK(g_pCB->FD, 01141 g_pCB->FunctionParams.pTxRxDescBuff, 01142 _SL_PROTOCOL_ALIGN_SIZE(g_pCB->FunctionParams.pCmdCtrl->RxDescLen)); 01143 01144 if((NULL != g_pCB->FunctionParams.pCmdExt) && (0 != g_pCB->FunctionParams.pCmdExt->RxPayloadLen)) 01145 { 01146 /* Actual size of command's response payload: <msg_payload_len> - <rsp_args_len> */ 01147 _i16 ActDataSize = (_i16)(RSP_PAYLOAD_LEN(uBuf.TempBuf) - g_pCB->FunctionParams.pCmdCtrl->RxDescLen); 01148 01149 g_pCB->FunctionParams.pCmdExt->ActualRxPayloadLen = ActDataSize; 01150 01151 /* Check that the space prepared by user for the response data is sufficient. */ 01152 if(ActDataSize <= 0) 01153 { 01154 g_pCB->FunctionParams.pCmdExt->RxPayloadLen = 0; 01155 } 01156 else 01157 { 01158 /* In case the user supplied Rx buffer length which is smaller then the received data length, copy according to user length */ 01159 if (ActDataSize > g_pCB->FunctionParams.pCmdExt->RxPayloadLen) 01160 { 01161 LengthToCopy = (_u16)(g_pCB->FunctionParams.pCmdExt->RxPayloadLen & (3)); 01162 AlignedLengthRecv = (_u16)(g_pCB->FunctionParams.pCmdExt->RxPayloadLen & (~3)); 01163 } 01164 else 01165 { 01166 LengthToCopy = (_u16)(ActDataSize & (3)); 01167 AlignedLengthRecv = (_u16)(ActDataSize & (~3)); 01168 } 01169 /* Read 4 bytes aligned from interface */ 01170 /* therefore check the requested length and read only */ 01171 /* 4 bytes aligned data. The rest unaligned (if any) will be read */ 01172 /* and copied to a TailBuffer */ 01173 01174 if( AlignedLengthRecv >= 4) 01175 { 01176 NWP_IF_READ_CHECK(g_pCB->FD, 01177 g_pCB->FunctionParams.pCmdExt->pRxPayload, 01178 AlignedLengthRecv ); 01179 01180 } 01181 /* copy the unaligned part, if any */ 01182 if( LengthToCopy > 0) 01183 { 01184 NWP_IF_READ_CHECK(g_pCB->FD,TailBuffer,4); 01185 /* copy TailBuffer unaligned part (1/2/3 bytes) */ 01186 sl_Memcpy(g_pCB->FunctionParams.pCmdExt->pRxPayload + AlignedLengthRecv, 01187 TailBuffer, 01188 LengthToCopy); 01189 ActDataSize = ActDataSize-4; 01190 } 01191 /* In case the user supplied Rx buffer length which is smaller then the received data length, dump the rest */ 01192 if (ActDataSize > g_pCB->FunctionParams.pCmdExt->RxPayloadLen) 01193 { 01194 /* calculate the rest of the data size to dump */ 01195 AlignedLengthRecv = (_u16)( (ActDataSize + 3 - g_pCB->FunctionParams.pCmdExt->RxPayloadLen) & (~3) ); 01196 while( AlignedLengthRecv > 0) 01197 { 01198 NWP_IF_READ_CHECK(g_pCB->FD,TailBuffer, 4 ); 01199 AlignedLengthRecv = AlignedLengthRecv - 4; 01200 } 01201 } 01202 } 01203 } 01204 break; 01205 01206 default: 01207 /* DUMMY_MSG_CLASS: Flow control message has no payload. */ 01208 break; 01209 } 01210 01211 if(AlignSize > 0) 01212 { 01213 NWP_IF_READ_CHECK(g_pCB->FD, uBuf.TempBuf, AlignSize); 01214 } 01215 01216 _SL_DBG_CNT_INC(MsgCnt.Read); 01217 01218 /* Unmask Interrupt call */ 01219 sl_IfUnMaskIntHdlr(); 01220 01221 return SL_OS_RET_CODE_OK; 01222 } 01223 01224 01225 /* ******************************************************************************/ 01226 /* _SlAsyncEventGenericHandler */ 01227 /* ******************************************************************************/ 01228 static void _SlAsyncEventGenericHandler(_u8 bInCmdContext) 01229 { 01230 _u32 SlAsyncEvent = 0; 01231 _u8 OpcodeFound = FALSE; 01232 _u8 i; 01233 01234 _u32* pEventLocation = NULL; /* This pointer will override the async buffer with the translated event type */ 01235 _SlResponseHeader_t *pHdr = (_SlResponseHeader_t *)g_pCB->FunctionParams.AsyncExt.pAsyncBuf; 01236 01237 01238 /* if no async event registered nothing to do..*/ 01239 if (g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler == NULL) 01240 return; 01241 01242 /* Iterate through all the opcode in the table */ 01243 for (i=0; i< (_u8)(sizeof(OpcodeTranslateTable) / sizeof(OpcodeKeyVal_t)); i++) 01244 { 01245 if (OpcodeTranslateTable[i].opcode == pHdr->GenHeader.Opcode) 01246 { 01247 SlAsyncEvent = OpcodeTranslateTable[i].event; 01248 OpcodeFound = TRUE; 01249 break; 01250 } 01251 } 01252 01253 /* No Async event found in the table */ 01254 if (OpcodeFound == FALSE) 01255 { 01256 if ((pHdr->GenHeader.Opcode & SL_OPCODE_SILO_MASK) == SL_OPCODE_SILO_DEVICE) 01257 { 01258 DeviceEventInfo_t deviceEvent; 01259 01260 deviceEvent.pAsyncMsgBuff = g_pCB->FunctionParams.AsyncExt.pAsyncBuf; 01261 deviceEvent.bInCmdContext = bInCmdContext; 01262 01263 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(&deviceEvent); 01264 } 01265 else 01266 { 01267 /* This case handles all the async events handlers of the DEVICE & SOCK Silos which are handled internally. 01268 For these cases we send the async even buffer as is */ 01269 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); 01270 } 01271 } 01272 else 01273 { 01274 /* calculate the event type location to be filled in the async buffer */ 01275 pEventLocation = (_u32*)(g_pCB->FunctionParams.AsyncExt.pAsyncBuf + sizeof (_SlResponseHeader_t) - sizeof(SlAsyncEvent) ); 01276 01277 /* Override the async buffer (before the data starts ) with our event type */ 01278 *pEventLocation = SlAsyncEvent; 01279 01280 /* call the event handler registered by the user with our async buffer which now holds 01281 the User's event type and its related data */ 01282 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(pEventLocation); 01283 } 01284 01285 01286 } 01287 01288 01289 /* ******************************************************************************/ 01290 /* _SlDrvMsgReadCmdCtx */ 01291 /* ******************************************************************************/ 01292 static _SlReturnVal_t _SlDrvMsgReadCmdCtx(_u16 cmdOpcode) 01293 { 01294 #ifndef SL_TINY_EXT 01295 _u16 CmdCmpltTimeout; 01296 01297 /* For any FS command, the timeout will be the long one as the commnad response holds the full response data */ 01298 CmdCmpltTimeout = (SL_OPCODE_SILO_NVMEM & cmdOpcode)? (_u16)(SL_DRIVER_TIMEOUT_LONG) : (_u16)SL_DRIVER_TIMEOUT_SHORT; 01299 #endif 01300 01301 /* after command response is received and isCmdRespWaited */ 01302 /* flag is set FALSE, it is necessary to read out all */ 01303 /* Async messages in Commands context, because ssiDma_IsrHandleSignalFromSlave */ 01304 /* could have dispatched some Async messages to g_NwpIf.CmdSyncObj */ 01305 /* after command response but before this response has been processed */ 01306 /* by spi_singleRead and isCmdRespWaited was set FALSE. */ 01307 while (TRUE == g_pCB->IsCmdRespWaited) 01308 { 01309 if(_SL_PENDING_RX_MSG(g_pCB)) 01310 { 01311 #ifdef SL_TINY_EXT 01312 VERIFY_RET_OK(_SlDrvMsgRead()); 01313 #else 01314 if (_SlDrvMsgRead() != SL_OS_RET_CODE_OK) 01315 { 01316 SL_DRV_LOCK_GLOBAL_UNLOCK(); 01317 return SL_API_ABORTED; 01318 } 01319 #endif 01320 g_pCB->RxDoneCnt++; 01321 01322 if (CMD_RESP_CLASS == g_pCB->FunctionParams.AsyncExt.RxMsgClass) 01323 { 01324 g_pCB->IsCmdRespWaited = FALSE; 01325 01326 /* In case CmdResp has been read without waiting on CmdSyncObj - that */ 01327 /* Sync object. That to prevent old signal to be processed. */ 01328 SL_DRV_SYNC_OBJ_CLEAR(&g_pCB->CmdSyncObj); 01329 } 01330 else if (ASYNC_EVT_CLASS == g_pCB->FunctionParams.AsyncExt.RxMsgClass) 01331 { 01332 /* If Async event has been read in CmdResp context, check whether */ 01333 /* there is a handler for this event. If there is, spawn specific */ 01334 /* handler. Otherwise free the event's buffer. */ 01335 /* This way there will be no "dry shots" from CmdResp context to */ 01336 /* temporary context, i.e less waste of CPU and faster buffer */ 01337 /* release. */ 01338 _SlAsyncEventGenericHandler(TRUE); 01339 01340 01341 #ifdef SL_MEMORY_MGMT_DYNAMIC 01342 sl_Free(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); 01343 #else 01344 g_pCB->FunctionParams.AsyncExt.pAsyncBuf = NULL; 01345 #endif 01346 } 01347 } 01348 else 01349 { 01350 #ifdef SL_TINY_EXT 01351 /* CmdSyncObj will be signaled by IRQ */ 01352 _SlDrvSyncObjWaitForever(&g_pCB->CmdSyncObj); 01353 #else 01354 01355 01356 if (sl_SyncObjWait(&g_pCB->CmdSyncObj, CmdCmpltTimeout)) 01357 { 01358 SL_DRV_LOCK_GLOBAL_UNLOCK(); 01359 _SlDriverHandleError(SL_DEVICE_DRIVER_TIMEOUT_CMD_COMPLETE, cmdOpcode, CmdCmpltTimeout); 01360 return SL_API_ABORTED; 01361 } 01362 #endif 01363 } 01364 } 01365 01366 /* If there are more pending Rx Msgs after CmdResp is received, */ 01367 /* that means that these are Async, Dummy or Read Data Msgs. */ 01368 /* Spawn _SlDrvMsgReadSpawnCtx to trigger reading these messages from */ 01369 /* Temporary context. */ 01370 /* sl_Spawn is activated, using a different context */ 01371 01372 SL_DRV_LOCK_GLOBAL_UNLOCK(); 01373 01374 if(_SL_PENDING_RX_MSG(g_pCB)) 01375 { 01376 (void)sl_Spawn((_SlSpawnEntryFunc_t)_SlDrvMsgReadSpawnCtx, NULL, 0); 01377 } 01378 01379 return SL_OS_RET_CODE_OK; 01380 } 01381 01382 /* ******************************************************************************/ 01383 /* _SlDrvMsgReadSpawnCtx */ 01384 /* ******************************************************************************/ 01385 _SlReturnVal_t _SlDrvMsgReadSpawnCtx(void *pValue) 01386 { 01387 #ifdef SL_POLLING_MODE_USED 01388 _i16 retCode = OSI_OK; 01389 /* for polling based systems */ 01390 do 01391 { 01392 retCode = sl_LockObjLock(&g_pCB->GlobalLockObj, 0); 01393 if ( OSI_OK != retCode ) 01394 { 01395 if (TRUE == g_pCB->IsCmdRespWaited) 01396 { 01397 SL_DRV_SYNC_OBJ_SIGNAL(&g_pCB->CmdSyncObj); 01398 return SL_RET_CODE_OK; 01399 } 01400 } 01401 01402 } 01403 while (OSI_OK != retCode); 01404 01405 #else 01406 SL_DRV_LOCK_GLOBAL_LOCK_FOREVER(); 01407 #endif 01408 01409 /* pValue paramater is currently not in use */ 01410 (void)pValue; 01411 01412 /* Messages might have been read by CmdResp context. Therefore after */ 01413 /* getting LockObj, check again where the Pending Rx Msg is still present. */ 01414 if(FALSE == (_SL_PENDING_RX_MSG(g_pCB))) 01415 { 01416 SL_DRV_LOCK_GLOBAL_UNLOCK(); 01417 01418 return SL_RET_CODE_OK; 01419 } 01420 01421 #ifdef SL_TINY_EXT 01422 VERIFY_RET_OK(_SlDrvMsgRead()); 01423 #else 01424 if (_SlDrvMsgRead() != SL_OS_RET_CODE_OK) 01425 { 01426 SL_DRV_LOCK_GLOBAL_UNLOCK(); 01427 return SL_API_ABORTED; 01428 } 01429 #endif 01430 01431 g_pCB->RxDoneCnt++; 01432 01433 switch(g_pCB->FunctionParams.AsyncExt.RxMsgClass) 01434 { 01435 case ASYNC_EVT_CLASS: 01436 /* If got here and protected by LockObj a message is waiting */ 01437 /* to be read */ 01438 VERIFY_PROTOCOL(NULL != g_pCB->FunctionParams.AsyncExt.pAsyncBuf); 01439 01440 _SlAsyncEventGenericHandler(FALSE); 01441 01442 #ifdef SL_MEMORY_MGMT_DYNAMIC 01443 sl_Free(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); 01444 #else 01445 g_pCB->FunctionParams.AsyncExt.pAsyncBuf = NULL; 01446 #endif 01447 break; 01448 case DUMMY_MSG_CLASS: 01449 case RECV_RESP_CLASS: 01450 /* These types are legal in this context. Do nothing */ 01451 break; 01452 case CMD_RESP_CLASS: 01453 /* Command response is illegal in this context. */ 01454 /* No 'break' here: Assert! */ 01455 default: 01456 VERIFY_PROTOCOL(0); 01457 } 01458 01459 SL_DRV_LOCK_GLOBAL_UNLOCK(); 01460 01461 return(SL_RET_CODE_OK); 01462 } 01463 01464 01465 01466 /* 01467 01468 #define SL_OPCODE_SILO_DEVICE ( 0x0 << SL_OPCODE_SILO_OFFSET ) 01469 #define SL_OPCODE_SILO_WLAN ( 0x1 << SL_OPCODE_SILO_OFFSET ) 01470 #define SL_OPCODE_SILO_SOCKET ( 0x2 << SL_OPCODE_SILO_OFFSET ) 01471 #define SL_OPCODE_SILO_NETAPP ( 0x3 << SL_OPCODE_SILO_OFFSET ) 01472 #define SL_OPCODE_SILO_NVMEM ( 0x4 << SL_OPCODE_SILO_OFFSET ) 01473 #define SL_OPCODE_SILO_NETCFG ( 0x5 << SL_OPCODE_SILO_OFFSET ) 01474 01475 01476 */ 01477 01478 /* The Lookup table below holds the event handlers to be called according to the incoming 01479 RX message SILO type */ 01480 static const _SlSpawnEntryFunc_t RxMsgClassLUT[] = { 01481 (_SlSpawnEntryFunc_t)_SlDrvDeviceEventHandler, /* SL_OPCODE_SILO_DEVICE */ 01482 #if defined(sl_WlanEvtHdlr) || defined(EXT_LIB_REGISTERED_WLAN_EVENTS) 01483 (_SlSpawnEntryFunc_t)_SlDrvHandleWlanEvents, /* SL_OPCODE_SILO_WLAN */ 01484 #else 01485 NULL, 01486 #endif 01487 #if defined (sl_SockEvtHdlr) || defined(EXT_LIB_REGISTERED_SOCK_EVENTS) 01488 (_SlSpawnEntryFunc_t)_SlDrvHandleSockEvents, /* SL_OPCODE_SILO_SOCKET */ 01489 #else 01490 NULL, 01491 #endif 01492 01493 #if defined(sl_NetAppEvtHdlr) || defined(EXT_LIB_REGISTERED_NETAPP_EVENTS) 01494 (_SlSpawnEntryFunc_t)_SlDrvHandleNetAppEvents, /* SL_OPCODE_SILO_NETAPP */ 01495 #else 01496 NULL, 01497 #endif 01498 NULL, /* SL_OPCODE_SILO_NVMEM */ 01499 NULL, /* SL_OPCODE_SILO_NETCFG */ 01500 NULL, 01501 NULL 01502 }; 01503 01504 01505 /* ******************************************************************************/ 01506 /* _SlDrvClassifyRxMsg */ 01507 /* ******************************************************************************/ 01508 static _SlReturnVal_t _SlDrvClassifyRxMsg( 01509 _SlOpcode_t Opcode) 01510 { 01511 _SlSpawnEntryFunc_t AsyncEvtHandler = NULL; 01512 _SlRxMsgClass_e RxMsgClass = CMD_RESP_CLASS; 01513 _u8 Silo; 01514 01515 01516 if (0 == (SL_OPCODE_SYNC & Opcode)) 01517 { /* Async event has received */ 01518 01519 if (SL_OPCODE_DEVICE_DEVICEASYNCDUMMY == Opcode) 01520 { 01521 RxMsgClass = DUMMY_MSG_CLASS; 01522 } 01523 else if ( (SL_OPCODE_SOCKET_RECVASYNCRESPONSE == Opcode) || (SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE == Opcode) 01524 #ifndef SL_TINY_EXT 01525 || (SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE_V6 == Opcode) 01526 #endif 01527 ) 01528 { 01529 RxMsgClass = RECV_RESP_CLASS; 01530 } 01531 else 01532 { 01533 /* This is Async Event class message */ 01534 RxMsgClass = ASYNC_EVT_CLASS; 01535 01536 /* Despite the fact that 4 bits are allocated in the SILO field, we actually have only 6 SILOs 01537 So we can use the 8 options of SILO in look up table */ 01538 Silo = (_u8)((Opcode >> SL_OPCODE_SILO_OFFSET) & 0x7); 01539 01540 VERIFY_PROTOCOL(Silo < (_u8)(sizeof(RxMsgClassLUT)/sizeof(_SlSpawnEntryFunc_t))); 01541 01542 /* Set the async event hander according to the LUT */ 01543 AsyncEvtHandler = RxMsgClassLUT[Silo]; 01544 01545 if ((SL_OPCODE_NETAPP_HTTPGETTOKENVALUE == Opcode) || (SL_OPCODE_NETAPP_HTTPPOSTTOKENVALUE == Opcode)) 01546 { 01547 AsyncEvtHandler = _SlDrvNetAppEventHandler; 01548 } 01549 #ifndef SL_TINY_EXT 01550 else if (SL_OPCODE_NETAPP_PINGREPORTREQUESTRESPONSE == Opcode) 01551 { 01552 AsyncEvtHandler = (_SlSpawnEntryFunc_t)_sl_HandleAsync_PingResponse; 01553 } 01554 #endif 01555 } 01556 } 01557 01558 g_pCB->FunctionParams.AsyncExt.RxMsgClass = RxMsgClass; 01559 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler = AsyncEvtHandler; 01560 01561 01562 return SL_RET_CODE_OK; 01563 } 01564 01565 01566 /* ******************************************************************************/ 01567 /* _SlDrvRxHdrRead */ 01568 /* ******************************************************************************/ 01569 static _SlReturnVal_t _SlDrvRxHdrRead(_u8 *pBuf, _u8 *pAlignSize) 01570 { 01571 _u32 SyncCnt = 0; 01572 _u8 ShiftIdx; 01573 _u8 TimeoutState = TIMEOUT_STATE_INIT_VAL; 01574 _u8 SearchSync = TRUE; 01575 01576 01577 #if (!defined (SL_TINY_EXT)) && (defined(sl_GetTimestamp)) 01578 _SlTimeoutParams_t TimeoutInfo={0}; 01579 #endif 01580 01581 #ifndef SL_IF_TYPE_UART 01582 /* 1. Write CNYS pattern to NWP when working in SPI mode only */ 01583 NWP_IF_WRITE_CHECK(g_pCB->FD, (_u8 *)&g_H2NCnysPattern.Short, SYNC_PATTERN_LEN); 01584 #endif 01585 01586 #if (!defined (SL_TINY)) && (defined(sl_GetTimestamp)) 01587 _SlDrvStartMeasureTimeout(&TimeoutInfo, SYNC_PATTERN_TIMEOUT_IN_MSEC); 01588 #endif 01589 01590 /* 2. Read 8 bytes (protocol aligned) - expected to be the sync pattern */ 01591 NWP_IF_READ_CHECK(g_pCB->FD, &pBuf[0], 8); 01592 _SL_DBG_SYNC_LOG(SyncCnt,pBuf); 01593 01594 /* read while first 4 bytes are different than last 4 bytes */ 01595 while ( *(_u32 *)&pBuf[0] == *(_u32 *)&pBuf[4]) 01596 { 01597 NWP_IF_READ_CHECK(g_pCB->FD, &pBuf[4], 4); 01598 } 01599 01600 01601 /* scan for the sync pattern till found or timeout elapsed (if configured) */ 01602 while (SearchSync && TimeoutState) 01603 { 01604 /* scan till we get the real sync pattern */ 01605 for (ShiftIdx =0; ShiftIdx <=4 ; ShiftIdx++) 01606 { 01607 /* sync pattern found so complete the read to 4 bytes aligned */ 01608 if (N2H_SYNC_PATTERN_MATCH(&pBuf[ShiftIdx], g_pCB->TxSeqNum)) 01609 { 01610 /* copy the bytes following the sync pattern to the buffer start */ 01611 *(_u32 *)&pBuf[0] = *(_u32 *)&pBuf[ShiftIdx + SYNC_PATTERN_LEN]; 01612 01613 /* read the rest of the byte */ 01614 NWP_IF_READ_CHECK(g_pCB->FD, &pBuf[SYNC_PATTERN_LEN - ShiftIdx], ShiftIdx); 01615 01616 /* here we except to get the opcode + length or false doubled sync..*/ 01617 SearchSync = FALSE; 01618 break; 01619 } 01620 01621 } 01622 01623 if (SearchSync == TRUE) 01624 { 01625 /* sync not found move top 4 bytes to bottom */ 01626 *(_u32 *)&pBuf[0] = *(_u32 *)&pBuf[4]; 01627 01628 /* read 4 more bytes to the buffer top */ 01629 NWP_IF_READ_CHECK(g_pCB->FD, &pBuf[4], 4); 01630 } 01631 01632 01633 #if (defined (sl_GetTimestamp)) && (!defined (SL_TINY)) 01634 01635 /* if we got here after first timeout detection, it means that we gave 01636 one more chance, and we can now exit the loop with timeout expiry */ 01637 if (TIMEOUT_ONE_MORE_SHOT == TimeoutState) 01638 { 01639 TimeoutState = TIMEOUT_STATE_EXPIRY; 01640 break; 01641 } 01642 01643 /* Timeout occured. do not break now as we want to give one more chance in case 01644 the timeout occured due to some external context switch */ 01645 if (_SlDrvIsTimeoutExpired(&TimeoutInfo)) 01646 { 01647 TimeoutState = TIMEOUT_ONE_MORE_SHOT; 01648 } 01649 01650 #endif 01651 01652 } /* end of while*/ 01653 01654 01655 #if (defined (sl_GetTimestamp)) && (!defined (SL_TINY)) 01656 if (TIMEOUT_STATE_EXPIRY == TimeoutState) 01657 { 01658 return SL_API_ABORTED; 01659 } 01660 #endif 01661 01662 01663 01664 /* 6. Scan for Double pattern. */ 01665 while ( N2H_SYNC_PATTERN_MATCH(pBuf, g_pCB->TxSeqNum) ) 01666 { 01667 _SL_DBG_CNT_INC(Work.DoubleSyncPattern); 01668 NWP_IF_READ_CHECK(g_pCB->FD, &pBuf[0], SYNC_PATTERN_LEN); 01669 } 01670 g_pCB->TxSeqNum++; 01671 01672 /* 7. Here we've read Generic Header (4 bytes opcode+length). 01673 * Now Read the Resp Specific header (4 more bytes). */ 01674 NWP_IF_READ_CHECK(g_pCB->FD, &pBuf[SYNC_PATTERN_LEN], _SL_RESP_SPEC_HDR_SIZE); 01675 01676 /* 8. Here we've read the entire Resp Header. */ 01677 /* Return number bytes needed to be sent after read for NWP Rx 4-byte alignment (protocol alignment) */ 01678 *pAlignSize = (_u8)((SyncCnt > 0) ? (SYNC_PATTERN_LEN - SyncCnt) : 0); 01679 01680 return SL_RET_CODE_OK; 01681 } 01682 01683 /* ***************************************************************************** */ 01684 /* _SlDrvBasicCmd */ 01685 /* ***************************************************************************** */ 01686 typedef union 01687 { 01688 _BasicResponse_t Rsp; 01689 }_SlBasicCmdMsg_u; 01690 01691 01692 #ifndef SL_TINY_EXT 01693 _i16 _SlDrvBasicCmd(_SlOpcode_t Opcode) 01694 { 01695 _SlBasicCmdMsg_u Msg; 01696 _SlCmdCtrl_t CmdCtrl; 01697 01698 _SlDrvMemZero(&Msg, (_u16)sizeof(_SlBasicCmdMsg_u)); 01699 01700 CmdCtrl.Opcode = Opcode; 01701 CmdCtrl.TxDescLen = 0; 01702 CmdCtrl.RxDescLen = (_SlArgSize_t)sizeof(_BasicResponse_t); 01703 01704 01705 VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&CmdCtrl, &Msg, NULL)); 01706 01707 return (_i16)Msg.Rsp.status; 01708 } 01709 01710 /***************************************************************************** 01711 _SlDrvCmdSend 01712 Send SL command without waiting for command response 01713 This function is unprotected and the caller should make 01714 sure global lock is active 01715 *****************************************************************************/ 01716 _SlReturnVal_t _SlDrvCmdSend( 01717 _SlCmdCtrl_t *pCmdCtrl , 01718 void *pTxRxDescBuff , 01719 _SlCmdExt_t *pCmdExt) 01720 { 01721 _SlReturnVal_t RetVal; 01722 _u8 IsCmdRespWaitedOriginalVal; 01723 01724 _SlFunctionParams_t originalFuncParms; 01725 01726 /* save the current RespWait flag before clearing it */ 01727 IsCmdRespWaitedOriginalVal = g_pCB->IsCmdRespWaited; 01728 01729 /* save the current command paramaters */ 01730 sl_Memcpy(&originalFuncParms, &g_pCB->FunctionParams, sizeof(_SlFunctionParams_t)); 01731 01732 g_pCB->IsCmdRespWaited = FALSE; 01733 01734 SL_TRACE0(DBG_MSG, MSG_312, "_SlDrvCmdSend: call _SlDrvMsgWrite"); 01735 01736 /* send the message */ 01737 RetVal = _SlDrvMsgWrite(pCmdCtrl, pCmdExt, pTxRxDescBuff); 01738 01739 /* restore the original RespWait flag */ 01740 g_pCB->IsCmdRespWaited = IsCmdRespWaitedOriginalVal; 01741 01742 /* restore the original command paramaters */ 01743 sl_Memcpy(&g_pCB->FunctionParams, &originalFuncParms, sizeof(_SlFunctionParams_t)); 01744 01745 return RetVal; 01746 01747 01748 } 01749 #endif 01750 01751 /* ***************************************************************************** */ 01752 /* _SlDrvWaitForPoolObj */ 01753 /* ***************************************************************************** */ 01754 _u8 _SlDrvWaitForPoolObj(_u8 ActionID, _u8 SocketID) 01755 { 01756 _u8 CurrObjIndex = MAX_CONCURRENT_ACTIONS; 01757 01758 /* Get free object */ 01759 SL_DRV_PROTECTION_OBJ_LOCK_FOREVER(); 01760 01761 if (MAX_CONCURRENT_ACTIONS > g_pCB->FreePoolIdx) 01762 { 01763 /* save the current obj index */ 01764 CurrObjIndex = g_pCB->FreePoolIdx; 01765 /* set the new free index */ 01766 #ifndef SL_TINY_EXT 01767 if (MAX_CONCURRENT_ACTIONS > g_pCB->ObjPool[CurrObjIndex].NextIndex) 01768 { 01769 g_pCB->FreePoolIdx = g_pCB->ObjPool[CurrObjIndex].NextIndex; 01770 } 01771 else 01772 #endif 01773 { 01774 /* No further free actions available */ 01775 g_pCB->FreePoolIdx = MAX_CONCURRENT_ACTIONS; 01776 } 01777 } 01778 else 01779 { 01780 SL_DRV_PROTECTION_OBJ_UNLOCK(); 01781 return CurrObjIndex; 01782 } 01783 g_pCB->ObjPool[CurrObjIndex].ActionID = (_u8)ActionID; 01784 if (SL_MAX_SOCKETS > SocketID) 01785 { 01786 g_pCB->ObjPool[CurrObjIndex].AdditionalData = SocketID; 01787 } 01788 #ifndef SL_TINY_EXT 01789 /*In case this action is socket related, SocketID bit will be on 01790 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 */ 01791 while ( ( (SL_MAX_SOCKETS > SocketID) && (g_pCB->ActiveActionsBitmap & (1<<SocketID)) ) || 01792 ( (g_pCB->ActiveActionsBitmap & (1<<ActionID)) && (SL_MAX_SOCKETS == SocketID) ) ) 01793 { 01794 /* action in progress - move to pending list */ 01795 g_pCB->ObjPool[CurrObjIndex].NextIndex = g_pCB->PendingPoolIdx; 01796 g_pCB->PendingPoolIdx = CurrObjIndex; 01797 SL_DRV_PROTECTION_OBJ_UNLOCK(); 01798 01799 /* wait for action to be free */ 01800 (void)_SlDrvSyncObjWaitForever(&g_pCB->ObjPool[CurrObjIndex].SyncObj); 01801 01802 /* set params and move to active (remove from pending list at _SlDrvReleasePoolObj) */ 01803 SL_DRV_PROTECTION_OBJ_LOCK_FOREVER(); 01804 } 01805 #endif 01806 /* mark as active. Set socket as active if action is on socket, otherwise mark action as active */ 01807 if (SL_MAX_SOCKETS > SocketID) 01808 { 01809 g_pCB->ActiveActionsBitmap |= (1<<SocketID); 01810 } 01811 else 01812 { 01813 g_pCB->ActiveActionsBitmap |= (1<<ActionID); 01814 } 01815 /* move to active list */ 01816 g_pCB->ObjPool[CurrObjIndex].NextIndex = g_pCB->ActivePoolIdx; 01817 g_pCB->ActivePoolIdx = CurrObjIndex; 01818 /* unlock */ 01819 SL_DRV_PROTECTION_OBJ_UNLOCK(); 01820 return CurrObjIndex; 01821 } 01822 01823 /* ******************************************************************************/ 01824 /* _SlDrvReleasePoolObj */ 01825 /* ******************************************************************************/ 01826 void _SlDrvReleasePoolObj(_u8 ObjIdx) 01827 { 01828 #ifndef SL_TINY_EXT 01829 _u8 PendingIndex; 01830 #endif 01831 01832 SL_DRV_PROTECTION_OBJ_LOCK_FOREVER(); 01833 01834 /* In Tiny mode, there is only one object pool so no pending actions are available */ 01835 #ifndef SL_TINY_EXT 01836 /* go over the pending list and release other pending action if needed */ 01837 PendingIndex = g_pCB->PendingPoolIdx; 01838 01839 while(MAX_CONCURRENT_ACTIONS > PendingIndex) 01840 { 01841 /* In case this action is socket related, SocketID is in use, otherwise will be set to SL_MAX_SOCKETS */ 01842 if ( (g_pCB->ObjPool[PendingIndex].ActionID == g_pCB->ObjPool[ObjIdx].ActionID) && 01843 ( (SL_MAX_SOCKETS == (g_pCB->ObjPool[PendingIndex].AdditionalData & BSD_SOCKET_ID_MASK)) || 01844 ((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) ))) ) 01845 { 01846 /* remove from pending list */ 01847 _SlRemoveFromList(&g_pCB->PendingPoolIdx, PendingIndex); 01848 SL_DRV_SYNC_OBJ_SIGNAL(&g_pCB->ObjPool[PendingIndex].SyncObj); 01849 break; 01850 } 01851 PendingIndex = g_pCB->ObjPool[PendingIndex].NextIndex; 01852 } 01853 #endif 01854 01855 if (SL_MAX_SOCKETS > (g_pCB->ObjPool[ObjIdx].AdditionalData & BSD_SOCKET_ID_MASK)) 01856 { 01857 /* unset socketID */ 01858 g_pCB->ActiveActionsBitmap &= ~(1<<(g_pCB->ObjPool[ObjIdx].AdditionalData & BSD_SOCKET_ID_MASK)); 01859 } 01860 else 01861 { 01862 /* unset actionID */ 01863 g_pCB->ActiveActionsBitmap &= ~(1<<g_pCB->ObjPool[ObjIdx].ActionID); 01864 } 01865 01866 /* delete old data */ 01867 g_pCB->ObjPool[ObjIdx].pRespArgs = NULL; 01868 g_pCB->ObjPool[ObjIdx].ActionID = 0; 01869 g_pCB->ObjPool[ObjIdx].AdditionalData = SL_MAX_SOCKETS; 01870 01871 /* remove from active list */ 01872 _SlRemoveFromList(&g_pCB->ActivePoolIdx, ObjIdx); 01873 /* move to free list */ 01874 g_pCB->ObjPool[ObjIdx].NextIndex = g_pCB->FreePoolIdx; 01875 g_pCB->FreePoolIdx = ObjIdx; 01876 SL_DRV_PROTECTION_OBJ_UNLOCK(); 01877 } 01878 01879 01880 /* ******************************************************************************/ 01881 /* _SlRemoveFromList */ 01882 /* ******************************************************************************/ 01883 static void _SlRemoveFromList(_u8 *ListIndex, _u8 ItemIndex) 01884 { 01885 #ifndef SL_TINY_EXT 01886 _u8 Idx; 01887 #endif 01888 01889 if (MAX_CONCURRENT_ACTIONS == g_pCB->ObjPool[*ListIndex].NextIndex) 01890 { 01891 *ListIndex = MAX_CONCURRENT_ACTIONS; 01892 } 01893 /* As MAX_CONCURRENT_ACTIONS is equal to 1 in Tiny mode */ 01894 #ifndef SL_TINY_EXT 01895 /* need to remove the first item in the list and therefore update the global which holds this index */ 01896 else if (*ListIndex == ItemIndex) 01897 { 01898 *ListIndex = g_pCB->ObjPool[ItemIndex].NextIndex; 01899 } 01900 else 01901 { 01902 Idx = *ListIndex; 01903 01904 while(MAX_CONCURRENT_ACTIONS > Idx) 01905 { 01906 /* remove from list */ 01907 if (g_pCB->ObjPool[Idx].NextIndex == ItemIndex) 01908 { 01909 g_pCB->ObjPool[Idx].NextIndex = g_pCB->ObjPool[ItemIndex].NextIndex; 01910 break; 01911 } 01912 01913 Idx = g_pCB->ObjPool[Idx].NextIndex; 01914 } 01915 } 01916 #endif 01917 } 01918 01919 01920 /* ******************************************************************************/ 01921 /* _SlFindAndSetActiveObj */ 01922 /* ******************************************************************************/ 01923 static _SlReturnVal_t _SlFindAndSetActiveObj(_SlOpcode_t Opcode, _u8 Sd) 01924 { 01925 _u8 ActiveIndex; 01926 01927 ActiveIndex = g_pCB->ActivePoolIdx; 01928 /* go over the active list if exist to find obj waiting for this Async event */ 01929 #ifndef SL_TINY_EXT 01930 while (MAX_CONCURRENT_ACTIONS > ActiveIndex) 01931 #else 01932 /* Only one Active action is availabe in tiny mode, so we can replace the loop with if condition */ 01933 if (MAX_CONCURRENT_ACTIONS > ActiveIndex) 01934 #endif 01935 { 01936 /* unset the Ipv4\IPv6 bit in the opcode if family bit was set */ 01937 if (g_pCB->ObjPool[ActiveIndex].AdditionalData & SL_NETAPP_FAMILY_MASK) 01938 { 01939 Opcode &= ~SL_OPCODE_IPV6; 01940 } 01941 01942 if ((g_pCB->ObjPool[ActiveIndex].ActionID == RECV_ID) && (Sd == g_pCB->ObjPool[ActiveIndex].AdditionalData) && 01943 ( (SL_OPCODE_SOCKET_RECVASYNCRESPONSE == Opcode) || (SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE == Opcode) 01944 #ifndef SL_TINY_EXT 01945 || (SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE_V6 == Opcode) 01946 #endif 01947 ) 01948 01949 ) 01950 { 01951 g_pCB->FunctionParams.AsyncExt.ActionIndex = ActiveIndex; 01952 return SL_RET_CODE_OK; 01953 } 01954 /* In case this action is socket related, SocketID is in use, otherwise will be set to SL_MAX_SOCKETS */ 01955 if ( (_SlActionLookupTable[ g_pCB->ObjPool[ActiveIndex].ActionID - MAX_SOCKET_ENUM_IDX].ActionAsyncOpcode == Opcode) && 01956 ( ((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)) ) ) 01957 { 01958 /* set handler */ 01959 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler = _SlActionLookupTable[ g_pCB->ObjPool[ActiveIndex].ActionID - MAX_SOCKET_ENUM_IDX].AsyncEventHandler; 01960 g_pCB->FunctionParams.AsyncExt.ActionIndex = ActiveIndex; 01961 return SL_RET_CODE_OK; 01962 } 01963 ActiveIndex = g_pCB->ObjPool[ActiveIndex].NextIndex; 01964 } 01965 01966 return SL_RET_CODE_SELF_ERROR; 01967 01968 } 01969 01970 01971 #if defined(sl_HttpServerCallback) || defined(EXT_LIB_REGISTERED_HTTP_SERVER_EVENTS) 01972 void _SlDrvDispatchHttpServerEvents(SlHttpServerEvent_t *slHttpServerEvent, SlHttpServerResponse_t *slHttpServerResponse) 01973 { 01974 _SlDrvHandleHttpServerEvents (slHttpServerEvent, slHttpServerResponse); 01975 } 01976 #endif 01977 01978 01979 /* Wrappers for the object functions */ 01980 01981 01982 _SlReturnVal_t _SlDrvSyncObjSignal(_SlSyncObj_t *pSyncObj) 01983 { 01984 OSI_RET_OK_CHECK(sl_SyncObjSignal(pSyncObj)); 01985 return SL_OS_RET_CODE_OK; 01986 } 01987 01988 _SlReturnVal_t _SlDrvObjLockWaitForever(_SlLockObj_t *pLockObj) 01989 { 01990 OSI_RET_OK_CHECK(sl_LockObjLock(pLockObj, SL_OS_WAIT_FOREVER)); 01991 return SL_OS_RET_CODE_OK; 01992 } 01993 01994 _SlReturnVal_t _SlDrvProtectionObjLockWaitForever(void) 01995 { 01996 OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); 01997 01998 return SL_OS_RET_CODE_OK; 01999 } 02000 02001 _SlReturnVal_t _SlDrvObjUnLock(_SlLockObj_t *pLockObj) 02002 { 02003 OSI_RET_OK_CHECK(sl_LockObjUnlock(pLockObj)); 02004 02005 return SL_OS_RET_CODE_OK; 02006 } 02007 02008 _SlReturnVal_t _SlDrvProtectionObjUnLock(void) 02009 { 02010 OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); 02011 return SL_OS_RET_CODE_OK; 02012 } 02013 02014 static _SlReturnVal_t _SlDrvObjGlobalLockWaitForever(void) 02015 { 02016 #ifndef SL_TINY_EXT 02017 if (g_bDeviceRestartIsRequired == TRUE) 02018 { 02019 return SL_API_ABORTED; 02020 } 02021 #endif 02022 return sl_LockObjLock(&g_pCB->GlobalLockObj, SL_OS_WAIT_FOREVER); 02023 } 02024 _SlReturnVal_t _SlDrvGlobalObjUnLock(void) 02025 { 02026 02027 OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->GlobalLockObj)); 02028 02029 return SL_OS_RET_CODE_OK; 02030 } 02031 02032 void _SlDrvMemZero(void* Addr, _u16 size) 02033 { 02034 sl_Memset(Addr, 0, size); 02035 } 02036 02037 02038 void _SlDrvResetCmdExt(_SlCmdExt_t* pCmdExt) 02039 { 02040 _SlDrvMemZero(pCmdExt, (_u16)sizeof (_SlCmdExt_t)); 02041 } 02042 02043 02044 #ifdef SL_TINY_EXT 02045 02046 _SlReturnVal_t _SlDrvSyncObjWaitForever(_SlSyncObj_t *pSyncObj) 02047 { 02048 return sl_SyncObjWait(pSyncObj, SL_OS_WAIT_FOREVER); 02049 } 02050 02051 #else 02052 _SlReturnVal_t _SlDrvSyncObjWaitForever(_SlSyncObj_t *pSyncObj) 02053 { 02054 (void)sl_SyncObjWait(pSyncObj, SL_OS_WAIT_FOREVER); 02055 02056 /* if the wait is finished and we detect that restart is required (we in the middle of error handling), 02057 than we should abort immediately from the current API command execution 02058 */ 02059 if (g_bDeviceRestartIsRequired == TRUE) 02060 { 02061 return SL_API_ABORTED; 02062 } 02063 02064 return SL_RET_CODE_OK; 02065 } 02066 02067 #endif 02068 02069 02070 #ifndef SL_TINY_EXT 02071 02072 02073 _SlReturnVal_t _SlDrvSyncObjWaitTimeout(_SlSyncObj_t *pSyncObj, _u32 timeoutVal, SlDriverAPIWithTimeout_e apiIdx) 02074 { 02075 _SlReturnVal_t ret = sl_SyncObjWait(pSyncObj, timeoutVal); 02076 02077 /* if timeout occured...*/ 02078 if (ret) 02079 { 02080 _SlDriverHandleError(SL_DEVICE_DRIVER_TIMEOUT_ASYNC_EVENT, apiIdx, timeoutVal); 02081 } 02082 else if (g_bDeviceRestartIsRequired == TRUE) 02083 { 02084 return SL_API_ABORTED; 02085 } 02086 02087 return SL_RET_CODE_OK; 02088 } 02089 02090 02091 void _SlDriverHandleError(SlDeviceDriverError_e eError, _u32 info1, _u32 info2) 02092 { 02093 _u8 i; 02094 SlDeviceEvent_t devHandler; 02095 02096 if (TRUE == g_bDeviceRestartIsRequired) 02097 { 02098 return; 02099 } 02100 02101 /* set the restart flag */ 02102 g_bDeviceRestartIsRequired = TRUE; 02103 02104 /* Upon the deletion of the mutex, all thread waiting on this 02105 mutex will return immediately with an error (i.e. MUTEX_DELETED status) */ 02106 (void)sl_LockObjDelete(&g_pCB->GlobalLockObj); 02107 02108 /* signal all waiting sync objects */ 02109 for (i=0; i< MAX_CONCURRENT_ACTIONS; i++) 02110 { 02111 SL_DRV_SYNC_OBJ_SIGNAL(&g_pCB->ObjPool[i].SyncObj); 02112 } 02113 02114 /* prepare the event and notify the user app/ext libraries */ 02115 devHandler.Event = eError; 02116 02117 switch (eError) 02118 { 02119 case SL_DEVICE_ABORT_ERROR_EVENT: 02120 { 02121 devHandler.EventData.deviceReport.AbortType = (_u32)info1; 02122 devHandler.EventData.deviceReport.AbortData = (_u32)info2; 02123 } 02124 break; 02125 02126 /* For asyn event timeout type error: 02127 * Info1 - Holds the SL API index (2 bytes) 02128 */ 02129 case SL_DEVICE_DRIVER_TIMEOUT_ASYNC_EVENT: 02130 02131 /* For cmd complete timeout type error: 02132 * Info1 - Holds the cmd opcode (2 bytes) 02133 */ 02134 case SL_DEVICE_DRIVER_TIMEOUT_CMD_COMPLETE: 02135 { 02136 devHandler.EventData.deviceDriverReport.info = info1; 02137 } 02138 break; 02139 02140 default: 02141 devHandler.EventData.deviceDriverReport.info = info1; 02142 break; 02143 } 02144 02145 /* call the registered handlers */ 02146 _SlDrvHandleGeneralEvents(&devHandler); 02147 02148 } 02149 02150 02151 #if (defined(sl_GetTimestamp)) 02152 02153 void _SlDrvStartMeasureTimeout(_SlTimeoutParams_t *pTimeoutInfo, _u32 TimeoutInMsec) 02154 { 02155 pTimeoutInfo->Total10MSecUnits = TimeoutInMsec / 10; 02156 pTimeoutInfo->TSPrev = sl_GetTimestamp(); 02157 } 02158 02159 _u8 _SlDrvIsTimeoutExpired(_SlTimeoutParams_t *pTimeoutInfo) 02160 { 02161 _u32 TSCount; 02162 02163 pTimeoutInfo->TSCurr = sl_GetTimestamp(); 02164 02165 if (pTimeoutInfo->TSCurr >= pTimeoutInfo->TSPrev) 02166 { 02167 pTimeoutInfo->DeltaTicks = pTimeoutInfo->TSCurr - pTimeoutInfo->TSPrev; 02168 } 02169 else 02170 { 02171 pTimeoutInfo->DeltaTicks = (SL_TIMESTAMP_MAX_VALUE - pTimeoutInfo->TSPrev) + pTimeoutInfo->TSCurr; 02172 } 02173 02174 TSCount = pTimeoutInfo->DeltaTicksReminder + pTimeoutInfo->DeltaTicks; 02175 02176 02177 if (TSCount > SL_TIMESTAMP_TICKS_IN_10_MILLISECONDS) 02178 { 02179 pTimeoutInfo->Total10MSecUnits -= (TSCount / SL_TIMESTAMP_TICKS_IN_10_MILLISECONDS); 02180 pTimeoutInfo->DeltaTicksReminder = TSCount % SL_TIMESTAMP_TICKS_IN_10_MILLISECONDS; 02181 02182 if (pTimeoutInfo->Total10MSecUnits > 0) 02183 { 02184 pTimeoutInfo->TSPrev = pTimeoutInfo->TSCurr; 02185 } 02186 else 02187 { 02188 return TRUE; 02189 } 02190 } 02191 02192 return FALSE; 02193 } 02194 02195 #endif 02196 02197 #endif
Generated on Tue Jul 12 2022 12:06:48 by 1.7.2