David Fletcher
/
cc3100_test
TI's CC3100 host driver and demo. Experimental and a work in progress.
Embed:
(wiki syntax)
Show/hide line numbers
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 #include "cc3100_flowcont.h" 00044 #include "cc3100_sl_common.h"//added 00045 00046 /*****************************************************************************/ 00047 /* Macro declarations */ 00048 /*****************************************************************************/ 00049 00050 #define _SL_PENDING_RX_MSG(pDriverCB) ((pDriverCB)->RxIrqCnt != (pDriverCB)->RxDoneCnt) 00051 00052 /* 2 LSB of the N2H_SYNC_PATTERN are for sequence number 00053 only in SPI interface 00054 support backward sync pattern */ 00055 #define N2H_SYNC_PATTERN_SEQ_NUM_BITS ((_u32)0x00000003) /* Bits 0..1 - use the 2 LBS for seq num */ 00056 #define N2H_SYNC_PATTERN_SEQ_NUM_EXISTS ((_u32)0x00000004) /* Bit 2 - sign that sequence number exists in the sync pattern */ 00057 #define N2H_SYNC_PATTERN_MASK ((_u32)0xFFFFFFF8) /* Bits 3..31 - constant SYNC PATTERN */ 00058 #define N2H_SYNC_SPI_BUGS_MASK ((_u32)0x7FFF7F7F) /* Bits 7,15,31 - ignore the SPI (8,16,32 bites bus) error bits */ 00059 #define BUF_SYNC_SPIM(pBuf) ((*(_u32 *)(pBuf)) & N2H_SYNC_SPI_BUGS_MASK) 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 #if (SL_MEMORY_MGMT == SL_MEMORY_MGMT_STATIC) 00077 typedef struct 00078 { 00079 _u32 Align; 00080 _SlDriverCb_t DriverCB; 00081 _u8 AsyncRespBuf[SL_ASYNC_MAX_MSG_LEN]; 00082 }_SlStatMem_t; 00083 00084 _SlStatMem_t g_StatMem; 00085 #endif 00086 00087 /*****************************************************************************/ 00088 /* Variables */ 00089 /*****************************************************************************/ 00090 //Vars taken from main 00091 extern _u32 g_Status = 0; 00092 extern _u32 g_GatewayIP = 0; 00093 extern _u32 g_StationIP = 0; 00094 00095 const _SlSyncPattern_t g_H2NSyncPattern = H2N_SYNC_PATTERN; 00096 const _SlSyncPattern_t g_H2NCnysPattern = H2N_CNYS_PATTERN; 00097 const _SlActionLookup_t _SlActionLookupTable[7] = 00098 { 00099 {ACCEPT_ID, SL_OPCODE_SOCKET_ACCEPTASYNCRESPONSE, (_SlSpawnEntryFunc_t)_sl_HandleAsync_Accept}, 00100 {CONNECT_ID, SL_OPCODE_SOCKET_CONNECTASYNCRESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_Connect}, 00101 {SELECT_ID, SL_OPCODE_SOCKET_SELECTASYNCRESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_Select}, 00102 {GETHOSYBYNAME_ID, SL_OPCODE_NETAPP_DNSGETHOSTBYNAMEASYNCRESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_DnsGetHostByName}, 00103 {GETHOSYBYSERVICE_ID, SL_OPCODE_NETAPP_MDNSGETHOSTBYSERVICEASYNCRESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_DnsGetHostByService}, 00104 {PING_ID, SL_OPCODE_NETAPP_PINGREPORTREQUESTRESPONSE, (_SlSpawnEntryFunc_t)_sl_HandleAsync_PingResponse}, 00105 {START_STOP_ID, SL_OPCODE_DEVICE_STOP_ASYNC_RESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_Stop} 00106 00107 }; 00108 00109 _SlDriverCb_t* g_pCB = NULL; 00110 P_SL_DEV_PING_CALLBACK pPingCallBackFunc = NULL; 00111 _u8 gFirstCmdMode = 0; 00112 00113 /*****************************************************************************/ 00114 /* Function prototypes */ 00115 /*****************************************************************************/ 00116 _SlReturnVal_t _SlDrvMsgRead(void); 00117 _SlReturnVal_t _SlDrvMsgWrite(void); 00118 _SlReturnVal_t _SlDrvMsgReadCmdCtx(void); 00119 _SlReturnVal_t _SlDrvMsgReadSpawnCtx(void *pValue); 00120 void _SlDrvClassifyRxMsg(_SlOpcode_t Opcode ); 00121 _SlReturnVal_t _SlDrvRxHdrRead(_u8 *pBuf, _u8 *pAlignSize); 00122 void _SlDrvShiftDWord(_u8 *pBuf); 00123 void _SlDrvDriverCBInit(void); 00124 void _SlAsyncEventGenericHandler(void); 00125 _i16 _SlDrvWaitForPoolObj(_u32 ActionID, _u8 SocketID); 00126 void _SlDrvReleasePoolObj(_u8 pObj); 00127 void _SlDrvObjInit(void); 00128 void _SlDrvObjDeInit(void); 00129 void _SlRemoveFromList(_u8* ListIndex, _u8 ItemIndex); 00130 _SlReturnVal_t _SlFindAndSetActiveObj(_SlOpcode_t Opcode, _u8 Sd); 00131 00132 00133 /*****************************************************************************/ 00134 /* Internal functions */ 00135 /*****************************************************************************/ 00136 00137 00138 00139 /***************************************************************************** 00140 _SlDrvDriverCBInit - init Driver Control Block 00141 *****************************************************************************/ 00142 void _SlDrvDriverCBInit(void) 00143 { 00144 _u8 Idx; 00145 00146 #if (SL_MEMORY_MGMT == SL_MEMORY_MGMT_STATIC) 00147 g_pCB = &(g_StatMem.DriverCB); 00148 #else 00149 g_pCB = sl_Malloc(sizeof(_SlDriverCb_t)); 00150 #endif 00151 MALLOC_OK_CHECK(g_pCB); 00152 00153 sl_Memset((g_pCB), 0, sizeof(_SlDriverCb_t)); 00154 00155 OSI_RET_OK_CHECK( sl_SyncObjCreate(&g_pCB->CmdSyncObj, "CmdSyncObj") ); 00156 sl_SyncObjClear(&g_pCB->CmdSyncObj); 00157 00158 OSI_RET_OK_CHECK( sl_LockObjCreate(&g_pCB->GlobalLockObj, "GlobalLockObj") ); 00159 00160 OSI_RET_OK_CHECK( sl_LockObjCreate(&g_pCB->ProtectionLockObj, "ProtectionLockObj") ); 00161 00162 _SlDrvObjInit(); 00163 00164 for (Idx = 0; Idx < MAX_CONCURRENT_ACTIONS; Idx++) 00165 { 00166 OSI_RET_OK_CHECK( sl_SyncObjCreate(&g_pCB->ObjPool[Idx].SyncObj, "SyncObj") ); 00167 sl_SyncObjClear(&g_pCB->ObjPool[Idx].SyncObj); 00168 } 00169 _SlDrvFlowContInit(); 00170 gFirstCmdMode = 0; 00171 } 00172 00173 /***************************************************************************** 00174 _SlDrvDriverCBDeinit - De init Driver Control Block 00175 *****************************************************************************/ 00176 void _SlDrvDriverCBDeinit() 00177 { 00178 _u8 Idx; 00179 00180 _SlDrvFlowContDeinit(); 00181 00182 OSI_RET_OK_CHECK( sl_SyncObjDelete(&g_pCB->CmdSyncObj) ); 00183 00184 OSI_RET_OK_CHECK( sl_LockObjDelete(&g_pCB->GlobalLockObj) ); 00185 00186 OSI_RET_OK_CHECK( sl_LockObjDelete(&g_pCB->ProtectionLockObj) ); 00187 for (Idx = 0; Idx < MAX_CONCURRENT_ACTIONS; Idx++) 00188 { 00189 OSI_RET_OK_CHECK( sl_SyncObjDelete(&g_pCB->ObjPool[Idx].SyncObj) ); 00190 } 00191 00192 _SlDrvObjDeInit(); 00193 00194 #if (SL_MEMORY_MGMT == SL_MEMORY_MGMT_STATIC) 00195 g_pCB = NULL; 00196 #else 00197 sl_Free(g_pCB); 00198 #endif 00199 00200 g_pCB = NULL; 00201 } 00202 00203 /***************************************************************************** 00204 _SlDrvRxIrqHandler - Interrupt handler 00205 *****************************************************************************/ 00206 void _SlDrvRxIrqHandler(void *pValue) 00207 { 00208 sl_IfMaskIntHdlr(); 00209 00210 g_pCB->RxIrqCnt++; 00211 00212 if (TRUE == g_pCB->IsCmdRespWaited) 00213 { 00214 OSI_RET_OK_CHECK( sl_SyncObjSignalFromIRQ(&g_pCB->CmdSyncObj) ); 00215 } 00216 else 00217 { 00218 sl_Spawn((_SlSpawnEntryFunc_t)_SlDrvMsgReadSpawnCtx, NULL, 0); 00219 } 00220 } 00221 00222 /***************************************************************************** 00223 _SlDrvCmdOp 00224 *****************************************************************************/ 00225 _SlReturnVal_t _SlDrvCmdOp( 00226 _SlCmdCtrl_t *pCmdCtrl , 00227 void *pTxRxDescBuff , 00228 _SlCmdExt_t *pCmdExt) 00229 { 00230 _SlReturnVal_t RetVal; 00231 00232 OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->GlobalLockObj, SL_OS_WAIT_FOREVER)); 00233 g_pCB->IsCmdRespWaited = TRUE; 00234 00235 SL_TRACE0(DBG_MSG, MSG_312, "_SlDrvCmdOp: call _SlDrvMsgWrite"); 00236 /* send the message */ 00237 g_pCB->FunctionParams.pCmdCtrl = pCmdCtrl; 00238 g_pCB->FunctionParams.pTxRxDescBuff = (unsigned char*)pTxRxDescBuff;//(unsigned char*) added 00239 g_pCB->FunctionParams.pCmdExt = pCmdExt; 00240 00241 RetVal = _SlDrvMsgWrite(); 00242 00243 if(SL_OS_RET_CODE_OK == RetVal) 00244 { 00245 00246 #ifndef SL_IF_TYPE_UART 00247 /* Waiting for SPI to stabilize after first command */ 00248 if( 0 == gFirstCmdMode ) 00249 { 00250 volatile _u32 CountVal = 0; 00251 gFirstCmdMode = 1; 00252 CountVal = CPU_FREQ_IN_MHZ*USEC_DELAY; 00253 while( CountVal-- ); 00254 } 00255 #endif 00256 /* wait for respond */ 00257 RetVal = _SlDrvMsgReadCmdCtx(); /* will free global lock */ 00258 SL_TRACE0(DBG_MSG, MSG_314, "_SlDrvCmdOp: exited _SlDrvMsgReadCmdCtx"); 00259 00260 } 00261 else 00262 { 00263 OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->GlobalLockObj)); 00264 } 00265 00266 return RetVal; 00267 } 00268 00269 /***************************************************************************** 00270 _SlDrvCmdSend 00271 Send SL command without waiting for command response 00272 This function is unprotected and the caller should make 00273 sure global lock is active 00274 *****************************************************************************/ 00275 _SlReturnVal_t _SlDrvCmdSend( 00276 _SlCmdCtrl_t *pCmdCtrl , 00277 void *pTxRxDescBuff , 00278 _SlCmdExt_t *pCmdExt) 00279 { 00280 _SlReturnVal_t RetVal; 00281 00282 g_pCB->IsCmdRespWaited = FALSE; 00283 00284 SL_TRACE0(DBG_MSG, MSG_312, "_SlDrvCmdSend: call _SlDrvMsgWrite"); 00285 /* send the message */ 00286 g_pCB->FunctionParams.pCmdCtrl = pCmdCtrl; 00287 g_pCB->FunctionParams.pTxRxDescBuff = (unsigned char*)pTxRxDescBuff;//(unsigned char*) added 00288 g_pCB->FunctionParams.pCmdExt = pCmdExt; 00289 00290 RetVal = _SlDrvMsgWrite(); 00291 00292 return RetVal; 00293 } 00294 00295 /***************************************************************************** 00296 _SlDrvDataReadOp 00297 *****************************************************************************/ 00298 _SlReturnVal_t _SlDrvDataReadOp( 00299 _SlSd_t Sd, 00300 _SlCmdCtrl_t *pCmdCtrl , 00301 void *pTxRxDescBuff , 00302 _SlCmdExt_t *pCmdExt) 00303 { 00304 _SlReturnVal_t RetVal; 00305 _u8 ObjIdx = MAX_CONCURRENT_ACTIONS; 00306 _SlArgsData_t pArgsData; 00307 00308 /* Validate input arguments */ 00309 VERIFY_PROTOCOL(NULL != pCmdExt->pRxPayload); 00310 00311 /* If zero bytes is requested, return error. */ 00312 /* This allows us not to fill remote socket's IP address in return arguments */ 00313 VERIFY_PROTOCOL(0 != pCmdExt->RxPayloadLen); 00314 00315 /* Validate socket */ 00316 if((Sd & BSD_SOCKET_ID_MASK) >= SL_MAX_SOCKETS) 00317 { 00318 return SL_EBADF; 00319 } 00320 00321 /*Use Obj to issue the command, if not available try later*/ 00322 ObjIdx = (_u8)_SlDrvWaitForPoolObj(RECV_ID, Sd & BSD_SOCKET_ID_MASK); 00323 00324 if (MAX_CONCURRENT_ACTIONS == ObjIdx) 00325 { 00326 return SL_POOL_IS_EMPTY; 00327 } 00328 00329 OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); 00330 00331 pArgsData.pData = pCmdExt->pRxPayload; 00332 pArgsData.pArgs = (_u8 *)pTxRxDescBuff; 00333 g_pCB->ObjPool[ObjIdx].pRespArgs = (_u8 *)&pArgsData; 00334 OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); 00335 00336 00337 /* Do Flow Control check/update for DataWrite operation */ 00338 OSI_RET_OK_CHECK( sl_LockObjLock(&g_pCB->FlowContCB.TxLockObj, SL_OS_WAIT_FOREVER) ); 00339 00340 /* Clear SyncObj for the case it was signalled before TxPoolCnt */ 00341 /* dropped below '1' (last Data buffer was taken) */ 00342 /* OSI_RET_OK_CHECK( sl_SyncObjClear(&g_pCB->FlowContCB.TxSyncObj) ); */ 00343 sl_SyncObjClear(&g_pCB->FlowContCB.TxSyncObj); 00344 00345 if(g_pCB->FlowContCB.TxPoolCnt <= FLOW_CONT_MIN) 00346 { 00347 00348 /* If TxPoolCnt was increased by other thread at this moment, 00349 TxSyncObj won't wait here */ 00350 OSI_RET_OK_CHECK( sl_SyncObjWait(&g_pCB->FlowContCB.TxSyncObj, SL_OS_WAIT_FOREVER) ); 00351 } 00352 00353 OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->GlobalLockObj, SL_OS_WAIT_FOREVER)); 00354 00355 VERIFY_PROTOCOL(g_pCB->FlowContCB.TxPoolCnt > FLOW_CONT_MIN); 00356 g_pCB->FlowContCB.TxPoolCnt--; 00357 00358 OSI_RET_OK_CHECK( sl_LockObjUnlock(&g_pCB->FlowContCB.TxLockObj) ); 00359 00360 /* send the message */ 00361 g_pCB->TempProtocolHeader.Opcode = pCmdCtrl->Opcode; 00362 g_pCB->TempProtocolHeader.Len = _SL_PROTOCOL_CALC_LEN(pCmdCtrl,pCmdExt); 00363 g_pCB->FunctionParams.pCmdCtrl = pCmdCtrl; 00364 g_pCB->FunctionParams.pTxRxDescBuff = (_u8 *)pTxRxDescBuff; 00365 g_pCB->FunctionParams.pCmdExt = pCmdExt; 00366 RetVal = _SlDrvMsgWrite(); 00367 00368 OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->GlobalLockObj)); 00369 00370 if(SL_OS_RET_CODE_OK == RetVal) 00371 { 00372 /* Wait for response message. Will be signalled by _SlDrvMsgRead. */ 00373 OSI_RET_OK_CHECK(sl_SyncObjWait(&g_pCB->ObjPool[ObjIdx].SyncObj, SL_OS_WAIT_FOREVER)); 00374 } 00375 00376 _SlDrvReleasePoolObj(ObjIdx); 00377 return RetVal; 00378 } 00379 00380 /* ******************************************************************************/ 00381 /* _SlDrvDataWriteOp */ 00382 /* ******************************************************************************/ 00383 _SlReturnVal_t _SlDrvDataWriteOp( 00384 _SlSd_t Sd, 00385 _SlCmdCtrl_t *pCmdCtrl , 00386 void *pTxRxDescBuff , 00387 _SlCmdExt_t *pCmdExt) 00388 { 00389 _SlReturnVal_t RetVal = SL_EAGAIN; /* initiated as SL_EAGAIN for the non blocking mode */ 00390 while( 1 ) 00391 { 00392 /* Do Flow Control check/update for DataWrite operation */ 00393 OSI_RET_OK_CHECK( sl_LockObjLock(&g_pCB->FlowContCB.TxLockObj, SL_OS_WAIT_FOREVER) ); 00394 00395 /* Clear SyncObj for the case it was signalled before TxPoolCnt */ 00396 /* dropped below '1' (last Data buffer was taken) */ 00397 /* OSI_RET_OK_CHECK( sl_SyncObjClear(&g_pCB->FlowContCB.TxSyncObj) ); */ 00398 sl_SyncObjClear(&g_pCB->FlowContCB.TxSyncObj); 00399 00400 /* we have indication that the last send has failed - socket is no longer valid for operations */ 00401 if(g_pCB->SocketTXFailure & (1<<(Sd & BSD_SOCKET_ID_MASK))) 00402 { 00403 OSI_RET_OK_CHECK( sl_LockObjUnlock(&g_pCB->FlowContCB.TxLockObj) ); 00404 return SL_SOC_ERROR; 00405 } 00406 if(g_pCB->FlowContCB.TxPoolCnt <= FLOW_CONT_MIN + 1) 00407 { 00408 /* we have indication that this socket is set as blocking and we try to */ 00409 /* unblock it - return an error */ 00410 if( g_pCB->SocketNonBlocking >> (Sd & BSD_SOCKET_ID_MASK) ) 00411 { 00412 OSI_RET_OK_CHECK( sl_LockObjUnlock(&g_pCB->FlowContCB.TxLockObj) ); 00413 return RetVal; 00414 } 00415 /* If TxPoolCnt was increased by other thread at this moment, */ 00416 /* TxSyncObj won't wait here */ 00417 OSI_RET_OK_CHECK( sl_SyncObjWait(&g_pCB->FlowContCB.TxSyncObj, SL_OS_WAIT_FOREVER) ); 00418 } 00419 if(g_pCB->FlowContCB.TxPoolCnt > FLOW_CONT_MIN + 1 ) 00420 { 00421 break; 00422 } 00423 else 00424 { 00425 OSI_RET_OK_CHECK( sl_LockObjUnlock(&g_pCB->FlowContCB.TxLockObj) ); 00426 } 00427 } 00428 OSI_RET_OK_CHECK( sl_LockObjLock(&g_pCB->GlobalLockObj, SL_OS_WAIT_FOREVER) ); 00429 00430 VERIFY_PROTOCOL(g_pCB->FlowContCB.TxPoolCnt > FLOW_CONT_MIN + 1 ); 00431 g_pCB->FlowContCB.TxPoolCnt--; 00432 00433 OSI_RET_OK_CHECK( sl_LockObjUnlock(&g_pCB->FlowContCB.TxLockObj) ); 00434 00435 /* send the message */ 00436 g_pCB->TempProtocolHeader.Opcode = pCmdCtrl->Opcode; 00437 g_pCB->TempProtocolHeader.Len = _SL_PROTOCOL_CALC_LEN(pCmdCtrl,pCmdExt); 00438 00439 g_pCB->FunctionParams.pCmdCtrl = pCmdCtrl; 00440 g_pCB->FunctionParams.pTxRxDescBuff = (unsigned char*)pTxRxDescBuff;//(unsigned char*) added 00441 g_pCB->FunctionParams.pCmdExt = pCmdExt; 00442 RetVal = _SlDrvMsgWrite(); 00443 00444 OSI_RET_OK_CHECK( sl_LockObjUnlock(&g_pCB->GlobalLockObj) ); 00445 00446 return RetVal; 00447 } 00448 00449 /* ******************************************************************************/ 00450 /* _SlDrvMsgWrite */ 00451 /* ******************************************************************************/ 00452 _SlReturnVal_t _SlDrvMsgWrite(void) 00453 { 00454 VERIFY_PROTOCOL(NULL != g_pCB->FunctionParams.pCmdCtrl); 00455 00456 g_pCB->TempProtocolHeader.Opcode = g_pCB->FunctionParams.pCmdCtrl->Opcode; 00457 g_pCB->TempProtocolHeader.Len = _SL_PROTOCOL_CALC_LEN(g_pCB->FunctionParams.pCmdCtrl, 00458 g_pCB->FunctionParams.pCmdExt); 00459 /* */ 00460 if (g_pCB->RelayFlagsViaRxPayload == TRUE) 00461 { 00462 g_pCB->TempProtocolHeader.Len = g_pCB->TempProtocolHeader.Len + g_pCB->FunctionParams.pCmdExt->RxPayloadLen; 00463 } 00464 00465 #ifdef SL_START_WRITE_STAT 00466 sl_IfStartWriteSequence(g_pCB->FD); 00467 #endif 00468 00469 #ifdef SL_IF_TYPE_UART 00470 /* Write long sync pattern */ 00471 NWP_IF_WRITE_CHECK(g_pCB->FD, (_u8 *)&g_H2NSyncPattern.Long, 2*SYNC_PATTERN_LEN); 00472 #else 00473 /* Write short sync pattern */ 00474 NWP_IF_WRITE_CHECK(g_pCB->FD, (_u8 *)&g_H2NSyncPattern.Short, SYNC_PATTERN_LEN); 00475 #endif 00476 00477 /* Header */ 00478 NWP_IF_WRITE_CHECK(g_pCB->FD, (_u8 *)&g_pCB->TempProtocolHeader, _SL_CMD_HDR_SIZE); 00479 00480 /* Descriptors */ 00481 if (g_pCB->FunctionParams.pTxRxDescBuff && g_pCB->FunctionParams.pCmdCtrl->TxDescLen > 0) 00482 { 00483 NWP_IF_WRITE_CHECK(g_pCB->FD, g_pCB->FunctionParams.pTxRxDescBuff, 00484 _SL_PROTOCOL_ALIGN_SIZE(g_pCB->FunctionParams.pCmdCtrl->TxDescLen)); 00485 } 00486 00487 /* A special mode where Rx payload and Rx length are used as Tx as well */ 00488 /* This mode requires no Rx payload on the response and currently used by fs_Close and sl_Send on */ 00489 /* transceiver mode */ 00490 if (g_pCB->RelayFlagsViaRxPayload == TRUE ) 00491 { 00492 g_pCB->RelayFlagsViaRxPayload = FALSE; 00493 NWP_IF_WRITE_CHECK(g_pCB->FD, g_pCB->FunctionParams.pCmdExt->pRxPayload, 00494 _SL_PROTOCOL_ALIGN_SIZE(g_pCB->FunctionParams.pCmdExt->RxPayloadLen)); 00495 } 00496 00497 /* Payload */ 00498 if (g_pCB->FunctionParams.pCmdExt && g_pCB->FunctionParams.pCmdExt->TxPayloadLen > 0) 00499 { 00500 /* If the message has payload, it is mandatory that the message's arguments are protocol aligned. */ 00501 /* Otherwise the aligning of arguments will create a gap between arguments and payload. */ 00502 VERIFY_PROTOCOL(_SL_IS_PROTOCOL_ALIGNED_SIZE(g_pCB->FunctionParams.pCmdCtrl->TxDescLen)); 00503 00504 NWP_IF_WRITE_CHECK(g_pCB->FD, g_pCB->FunctionParams.pCmdExt->pTxPayload, 00505 _SL_PROTOCOL_ALIGN_SIZE(g_pCB->FunctionParams.pCmdExt->TxPayloadLen)); 00506 } 00507 00508 00509 _SL_DBG_CNT_INC(MsgCnt.Write); 00510 00511 #ifdef SL_START_WRITE_STAT 00512 sl_IfEndWriteSequence(g_pCB->FD); 00513 #endif 00514 00515 return SL_OS_RET_CODE_OK; 00516 } 00517 00518 /* ******************************************************************************/ 00519 /* _SlDrvMsgRead */ 00520 /* ******************************************************************************/ 00521 _SlReturnVal_t _SlDrvMsgRead(void) 00522 { 00523 /* alignment for small memory models */ 00524 union 00525 { 00526 _u8 TempBuf[_SL_RESP_HDR_SIZE]; 00527 _u32 DummyBuf[2]; 00528 } uBuf; 00529 _u8 TailBuffer[4]; 00530 _u16 LengthToCopy; 00531 _u16 AlignedLengthRecv; 00532 _u8 AlignSize; 00533 00534 VERIFY_RET_OK(_SlDrvRxHdrRead((_u8*)(uBuf.TempBuf), &AlignSize)); 00535 00536 /* 'Init Compelete' message bears no valid FlowControl info */ 00537 if(SL_OPCODE_DEVICE_INITCOMPLETE != OPCODE(uBuf.TempBuf)) 00538 { 00539 g_pCB->FlowContCB.TxPoolCnt = ((_SlResponseHeader_t *)uBuf.TempBuf)->TxPoolCnt; 00540 g_pCB->SocketNonBlocking = ((_SlResponseHeader_t *)uBuf.TempBuf)->SocketNonBlocking; 00541 g_pCB->SocketTXFailure = ((_SlResponseHeader_t *)uBuf.TempBuf)->SocketTXFailure; 00542 00543 if(g_pCB->FlowContCB.TxPoolCnt > FLOW_CONT_MIN) 00544 { 00545 OSI_RET_OK_CHECK(sl_SyncObjSignal(&g_pCB->FlowContCB.TxSyncObj)); 00546 } 00547 } 00548 00549 _SlDrvClassifyRxMsg(OPCODE(uBuf.TempBuf)); 00550 00551 switch(g_pCB->FunctionParams.AsyncExt.RxMsgClass) 00552 { 00553 case ASYNC_EVT_CLASS: 00554 00555 VERIFY_PROTOCOL(NULL == g_pCB->FunctionParams.AsyncExt.pAsyncBuf); 00556 00557 #if (SL_MEMORY_MGMT == SL_MEMORY_MGMT_STATIC) 00558 g_pCB->FunctionParams.AsyncExt.pAsyncBuf = g_StatMem.AsyncRespBuf; 00559 #else 00560 g_pCB->FunctionParams.AsyncExt.pAsyncBuf = sl_Malloc(SL_ASYNC_MAX_MSG_LEN); 00561 #endif 00562 MALLOC_OK_CHECK(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); 00563 00564 sl_Memcpy(g_pCB->FunctionParams.AsyncExt.pAsyncBuf, uBuf.TempBuf, _SL_RESP_HDR_SIZE); 00565 00566 /* This is an Async message. Read the rest of it. */ 00567 if (_SL_PROTOCOL_ALIGN_SIZE(RSP_PAYLOAD_LEN(uBuf.TempBuf)) <= SL_ASYNC_MAX_PAYLOAD_LEN) 00568 { 00569 AlignedLengthRecv = _SL_PROTOCOL_ALIGN_SIZE(RSP_PAYLOAD_LEN(uBuf.TempBuf)); 00570 } 00571 else 00572 { 00573 AlignedLengthRecv = _SL_PROTOCOL_ALIGN_SIZE(SL_ASYNC_MAX_PAYLOAD_LEN); 00574 } 00575 00576 if (RSP_PAYLOAD_LEN(uBuf.TempBuf) > 0) 00577 { 00578 NWP_IF_READ_CHECK(g_pCB->FD, 00579 g_pCB->FunctionParams.AsyncExt.pAsyncBuf + _SL_RESP_HDR_SIZE, 00580 AlignedLengthRecv); 00581 } 00582 /* In case ASYNC RX buffer length is smaller then the received data length, dump the rest */ 00583 if ((_SL_PROTOCOL_ALIGN_SIZE(RSP_PAYLOAD_LEN(uBuf.TempBuf)) > SL_ASYNC_MAX_PAYLOAD_LEN)) 00584 { 00585 AlignedLengthRecv = _SL_PROTOCOL_ALIGN_SIZE(RSP_PAYLOAD_LEN(uBuf.TempBuf)) - SL_ASYNC_MAX_PAYLOAD_LEN; 00586 while (AlignedLengthRecv > 0) 00587 { 00588 NWP_IF_READ_CHECK(g_pCB->FD,TailBuffer,4); 00589 AlignedLengthRecv = AlignedLengthRecv - 4; 00590 } 00591 } 00592 OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); 00593 00594 if ((SL_OPCODE_SOCKET_ACCEPTASYNCRESPONSE == OPCODE(uBuf.TempBuf)) || (SL_OPCODE_SOCKET_ACCEPTASYNCRESPONSE_V6 == OPCODE(uBuf.TempBuf)) || (SL_OPCODE_SOCKET_CONNECTASYNCRESPONSE == OPCODE(uBuf.TempBuf))) 00595 { 00596 /* go over the active list if exist to find obj waiting for this Async event */ 00597 _SlFindAndSetActiveObj(OPCODE(uBuf.TempBuf),(((_SocketResponse_t *)(g_pCB->FunctionParams.AsyncExt.pAsyncBuf + _SL_RESP_HDR_SIZE))->sd) & BSD_SOCKET_ID_MASK); 00598 } 00599 else 00600 { 00601 _SlFindAndSetActiveObj(OPCODE(uBuf.TempBuf),SL_MAX_SOCKETS); 00602 } 00603 OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); 00604 00605 break; 00606 00607 case RECV_RESP_CLASS: 00608 { 00609 _u8 ExpArgSize; /* Expected size of Recv/Recvfrom arguments */ 00610 00611 switch(OPCODE(uBuf.TempBuf)) 00612 { 00613 case SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE: 00614 ExpArgSize = RECVFROM_IPV4_ARGS_SIZE; 00615 break; 00616 case SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE_V6: 00617 ExpArgSize = RECVFROM_IPV6_ARGS_SIZE; 00618 break; 00619 default: 00620 /* SL_OPCODE_SOCKET_RECVASYNCRESPONSE: */ 00621 ExpArgSize = RECV_ARGS_SIZE; 00622 } 00623 00624 /* Read first 4 bytes of Recv/Recvfrom response to get SocketId and actual */ 00625 /* response data length */ 00626 NWP_IF_READ_CHECK(g_pCB->FD, &uBuf.TempBuf[4], RECV_ARGS_SIZE); 00627 00628 /* Validate Socket ID and Received Length value. */ 00629 VERIFY_PROTOCOL((SD(&uBuf.TempBuf[4])& BSD_SOCKET_ID_MASK) < SL_MAX_SOCKETS); 00630 00631 OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); 00632 00633 /* go over the active list if exist to find obj waiting for this Async event */ 00634 VERIFY_RET_OK(_SlFindAndSetActiveObj(OPCODE(uBuf.TempBuf),SD(&uBuf.TempBuf[4]) & BSD_SOCKET_ID_MASK)); 00635 00636 /* Verify data is waited on this socket. The pArgs should have been set by _SlDrvDataReadOp(). */ 00637 VERIFY_SOCKET_CB(NULL != ((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pData))->pArgs); 00638 00639 sl_Memcpy( ((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pArgs, &uBuf.TempBuf[4], RECV_ARGS_SIZE); 00640 00641 if(ExpArgSize > RECV_ARGS_SIZE) 00642 { 00643 NWP_IF_READ_CHECK(g_pCB->FD, 00644 ((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pArgs + RECV_ARGS_SIZE, 00645 ExpArgSize - RECV_ARGS_SIZE); 00646 } 00647 00648 /* Here g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pData contains requested(expected) Recv/Recvfrom DataSize. */ 00649 /* Overwrite requested DataSize with actual one. */ 00650 /* If error is received, this information will be read from arguments. */ 00651 if(ACT_DATA_SIZE(&uBuf.TempBuf[4]) > 0) 00652 { 00653 VERIFY_SOCKET_CB(NULL != ((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pData); 00654 00655 /* Read 4 bytes aligned from interface */ 00656 /* therefore check the requested length and read only */ 00657 /* 4 bytes aligned data. The rest unaligned (if any) will be read */ 00658 /* and copied to a TailBuffer */ 00659 LengthToCopy = ACT_DATA_SIZE(&uBuf.TempBuf[4]) & (3); 00660 AlignedLengthRecv = ACT_DATA_SIZE(&uBuf.TempBuf[4]) & (~3); 00661 if( AlignedLengthRecv >= 4) 00662 { 00663 NWP_IF_READ_CHECK(g_pCB->FD,((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pData,AlignedLengthRecv ); 00664 } 00665 /* copy the unaligned part, if any */ 00666 if( LengthToCopy > 0) 00667 { 00668 NWP_IF_READ_CHECK(g_pCB->FD,TailBuffer,4); 00669 /* copy TailBuffer unaligned part (1/2/3 bytes) */ 00670 sl_Memcpy(((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pData + AlignedLengthRecv,TailBuffer,LengthToCopy); 00671 } 00672 } 00673 OSI_RET_OK_CHECK(sl_SyncObjSignal(&(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj))); 00674 OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); 00675 } 00676 break; 00677 00678 case CMD_RESP_CLASS: 00679 00680 /* Some commands pass a maximum arguments size. */ 00681 /* In this case Driver will send extra dummy patterns to NWP if */ 00682 /* the response message is smaller than maximum. */ 00683 /* When RxDescLen is not exact, using RxPayloadLen is forbidden! */ 00684 /* If such case cannot be avoided - parse message here to detect */ 00685 /* arguments/payload border. */ 00686 NWP_IF_READ_CHECK(g_pCB->FD, 00687 g_pCB->FunctionParams.pTxRxDescBuff, 00688 _SL_PROTOCOL_ALIGN_SIZE(g_pCB->FunctionParams.pCmdCtrl->RxDescLen)); 00689 00690 if((NULL != g_pCB->FunctionParams.pCmdExt) && (0 != g_pCB->FunctionParams.pCmdExt->RxPayloadLen)) 00691 { 00692 /* Actual size of command's response payload: <msg_payload_len> - <rsp_args_len> */ 00693 _i16 ActDataSize = RSP_PAYLOAD_LEN(uBuf.TempBuf) - g_pCB->FunctionParams.pCmdCtrl->RxDescLen; 00694 00695 g_pCB->FunctionParams.pCmdExt->ActualRxPayloadLen = ActDataSize; 00696 00697 /* Check that the space prepared by user for the response data is sufficient. */ 00698 if(ActDataSize <= 0) 00699 { 00700 g_pCB->FunctionParams.pCmdExt->RxPayloadLen = 0; 00701 } 00702 else 00703 { 00704 /* In case the user supplied Rx buffer length which is smaller then the received data length, copy according to user length */ 00705 if (ActDataSize > g_pCB->FunctionParams.pCmdExt->RxPayloadLen) 00706 { 00707 LengthToCopy = g_pCB->FunctionParams.pCmdExt->RxPayloadLen & (3); 00708 AlignedLengthRecv = g_pCB->FunctionParams.pCmdExt->RxPayloadLen & (~3); 00709 } 00710 else 00711 { 00712 LengthToCopy = ActDataSize & (3); 00713 AlignedLengthRecv = ActDataSize & (~3); 00714 } 00715 /* Read 4 bytes aligned from interface */ 00716 /* therefore check the requested length and read only */ 00717 /* 4 bytes aligned data. The rest unaligned (if any) will be read */ 00718 /* and copied to a TailBuffer */ 00719 00720 if( AlignedLengthRecv >= 4) 00721 { 00722 NWP_IF_READ_CHECK(g_pCB->FD, 00723 g_pCB->FunctionParams.pCmdExt->pRxPayload, 00724 AlignedLengthRecv ); 00725 00726 } 00727 /* copy the unaligned part, if any */ 00728 if( LengthToCopy > 0) 00729 { 00730 NWP_IF_READ_CHECK(g_pCB->FD,TailBuffer,4); 00731 /* copy TailBuffer unaligned part (1/2/3 bytes) */ 00732 sl_Memcpy(g_pCB->FunctionParams.pCmdExt->pRxPayload + AlignedLengthRecv, 00733 TailBuffer, 00734 LengthToCopy); 00735 ActDataSize = ActDataSize-4; 00736 } 00737 /* In case the user supplied Rx buffer length which is smaller then the received data length, dump the rest */ 00738 if (ActDataSize > g_pCB->FunctionParams.pCmdExt->RxPayloadLen) 00739 { 00740 /* calculate the rest of the data size to dump */ 00741 AlignedLengthRecv = ActDataSize - (g_pCB->FunctionParams.pCmdExt->RxPayloadLen & (~3)); 00742 while( AlignedLengthRecv > 0) 00743 { 00744 NWP_IF_READ_CHECK(g_pCB->FD,TailBuffer, 4 ); 00745 AlignedLengthRecv = AlignedLengthRecv - 4; 00746 } 00747 } 00748 } 00749 } 00750 break; 00751 00752 default: 00753 /* DUMMY_MSG_CLASS: Flow control message has no payload. */ 00754 break; 00755 } 00756 00757 if(AlignSize > 0) 00758 { 00759 NWP_IF_READ_CHECK(g_pCB->FD, uBuf.TempBuf, AlignSize); 00760 } 00761 00762 _SL_DBG_CNT_INC(MsgCnt.Read); 00763 00764 /* Unmask Interrupt call */ 00765 sl_IfUnMaskIntHdlr(); 00766 00767 return SL_OS_RET_CODE_OK; 00768 } 00769 00770 /* ******************************************************************************/ 00771 /* _SlAsyncEventGenericHandler */ 00772 /* ******************************************************************************/ 00773 void _SlAsyncEventGenericHandler(void) 00774 { 00775 _SlResponseHeader_t *pHdr = (_SlResponseHeader_t *)g_pCB->FunctionParams.AsyncExt.pAsyncBuf; 00776 SlWlanEvent_t wlanEvent; 00777 SlNetAppEvent_t netAppEvent; 00778 SlSockEvent_t sockAppEvent; 00779 00780 if (NULL != g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler) 00781 { 00782 switch(pHdr->GenHeader.Opcode) 00783 { 00784 case SL_OPCODE_WLAN_P2P_DEV_FOUND: 00785 { 00786 slPeerInfoAsyncResponse_t* pResp = (slPeerInfoAsyncResponse_t*)_SL_RESP_ARGS_START(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); 00787 wlanEvent.Event = SL_WLAN_P2P_DEV_FOUND_EVENT; 00788 sl_Memcpy(wlanEvent.EventData.P2PModeDevFound.mac,pResp->mac, 6); 00789 sl_Memcpy(wlanEvent.EventData.P2PModeDevFound.go_peer_device_name,pResp->go_peer_device_name,pResp->go_peer_device_name_len); 00790 wlanEvent.EventData.P2PModeDevFound.go_peer_device_name_len = pResp->go_peer_device_name_len; 00791 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(&wlanEvent); 00792 break; 00793 } 00794 00795 case SL_OPCODE_WLAN_P2P_NEG_REQ_RECEIVED: 00796 { 00797 slPeerInfoAsyncResponse_t* pResp = (slPeerInfoAsyncResponse_t*)_SL_RESP_ARGS_START(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); 00798 00799 wlanEvent.Event = SL_WLAN_P2P_NEG_REQ_RECEIVED_EVENT; 00800 sl_Memcpy(wlanEvent.EventData.P2PModeNegReqReceived.mac,pResp->mac, 6); 00801 sl_Memcpy(wlanEvent.EventData.P2PModeNegReqReceived.go_peer_device_name,pResp->go_peer_device_name,pResp->go_peer_device_name_len); 00802 wlanEvent.EventData.P2PModeNegReqReceived.go_peer_device_name_len = pResp->go_peer_device_name_len; 00803 wlanEvent.EventData.P2PModeNegReqReceived.wps_dev_password_id = pResp->wps_dev_password_id; 00804 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(&wlanEvent); 00805 break; 00806 } 00807 case SL_OPCODE_WLAN_CONNECTION_FAILED: 00808 { 00809 slWlanConnFailureAsyncResponse_t * pResp = (slWlanConnFailureAsyncResponse_t*)_SL_RESP_ARGS_START(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); 00810 00811 wlanEvent.Event = SL_WLAN_CONNECTION_FAILED_EVENT; 00812 wlanEvent.EventData.P2PModewlanConnectionFailure.status = pResp->status; 00813 00814 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(&wlanEvent); 00815 break; 00816 } 00817 00818 case SL_OPCODE_WLAN_WLANASYNCCONNECTEDRESPONSE: 00819 { 00820 slWlanConnectAsyncResponse_t *pWlanResp = (slWlanConnectAsyncResponse_t*)_SL_RESP_ARGS_START(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); 00821 sl_Memset(&wlanEvent.EventData.STAandP2PModeWlanConnected,0,sizeof(slWlanConnectAsyncResponse_t)); 00822 wlanEvent.Event = SL_WLAN_CONNECT_EVENT; 00823 wlanEvent.EventData.STAandP2PModeWlanConnected.connection_type = pWlanResp->connection_type; 00824 sl_Memcpy(wlanEvent.EventData.STAandP2PModeWlanConnected.bssid, pWlanResp->bssid, 6); 00825 sl_Memcpy(wlanEvent.EventData.STAandP2PModeWlanConnected.go_peer_device_name,pWlanResp->go_peer_device_name,pWlanResp->go_peer_device_name_len); 00826 sl_Memcpy(wlanEvent.EventData.STAandP2PModeWlanConnected.ssid_name, pWlanResp->ssid_name, pWlanResp->ssid_len); 00827 wlanEvent.EventData.STAandP2PModeWlanConnected.ssid_len = pWlanResp->ssid_len; 00828 wlanEvent.EventData.STAandP2PModeWlanConnected.go_peer_device_name_len = pWlanResp->go_peer_device_name_len; 00829 00830 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(&wlanEvent); 00831 break; 00832 } 00833 case SL_OPCODE_WLAN_WLANASYNCDISCONNECTEDRESPONSE: 00834 { 00835 slWlanConnectAsyncResponse_t *pWlanResp = (slWlanConnectAsyncResponse_t*)_SL_RESP_ARGS_START(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); 00836 sl_Memset(&wlanEvent.EventData.STAandP2PModeDisconnected,0,sizeof(slWlanConnectAsyncResponse_t)); 00837 wlanEvent.Event = SL_WLAN_DISCONNECT_EVENT; 00838 wlanEvent.EventData.STAandP2PModeDisconnected.connection_type = pWlanResp->connection_type; 00839 sl_Memcpy(wlanEvent.EventData.STAandP2PModeDisconnected.bssid, pWlanResp->bssid, 6); 00840 sl_Memcpy(wlanEvent.EventData.STAandP2PModeDisconnected.go_peer_device_name,pWlanResp->go_peer_device_name,pWlanResp->go_peer_device_name_len); 00841 sl_Memcpy(wlanEvent.EventData.STAandP2PModeDisconnected.ssid_name, pWlanResp->ssid_name, pWlanResp->ssid_len); 00842 wlanEvent.EventData.STAandP2PModeDisconnected.ssid_len = pWlanResp->ssid_len; 00843 wlanEvent.EventData.STAandP2PModeDisconnected.reason_code = pWlanResp->reason_code; 00844 wlanEvent.EventData.STAandP2PModeDisconnected.go_peer_device_name_len = pWlanResp->go_peer_device_name_len; 00845 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(&wlanEvent); 00846 break; 00847 } 00848 case SL_OPCODE_NETAPP_IPACQUIRED: 00849 { 00850 SlIpV4AcquiredAsync_t *pIpV4 = (SlIpV4AcquiredAsync_t*)_SL_RESP_ARGS_START(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); 00851 netAppEvent.Event = SL_NETAPP_IPV4_IPACQUIRED_EVENT; 00852 netAppEvent.EventData.ipAcquiredV4.ip = pIpV4->ip; 00853 netAppEvent.EventData.ipAcquiredV4.gateway = pIpV4->gateway; 00854 netAppEvent.EventData.ipAcquiredV4.dns = pIpV4->dns; 00855 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(&netAppEvent); 00856 } 00857 break; 00858 case SL_OPCODE_NETAPP_IPACQUIRED_V6: 00859 { 00860 SlIpV6AcquiredAsync_t *pIpV6 = (SlIpV6AcquiredAsync_t*)_SL_RESP_ARGS_START(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); 00861 netAppEvent.Event = SL_NETAPP_IPV6_IPACQUIRED_EVENT; 00862 sl_Memcpy((void *)&netAppEvent.EventData.ipAcquiredV6.ip[0],(void *)&pIpV6->ip[0],sizeof(pIpV6->ip[0])*4); 00863 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(&netAppEvent); 00864 } 00865 break; 00866 00867 case SL_OPCODE_NETAPP_IP_LEASED: 00868 { 00869 SlIpLeasedAsync_t *pIpV4 = (SlIpLeasedAsync_t*)_SL_RESP_ARGS_START(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); 00870 netAppEvent.Event = SL_NETAPP_IP_LEASED_EVENT; 00871 netAppEvent.EventData.ipLeased.ip_address = pIpV4->ip_address; 00872 netAppEvent.EventData.ipLeased.lease_time = pIpV4->lease_time; 00873 sl_Memcpy(netAppEvent.EventData.ipLeased.mac, pIpV4->mac, 6); 00874 00875 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(&netAppEvent); 00876 } 00877 break; 00878 00879 case SL_OPCODE_NETAPP_IP_RELEASED: 00880 { 00881 SlIpReleasedAsync_t *pIpV4 = (SlIpReleasedAsync_t *)_SL_RESP_ARGS_START(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); 00882 netAppEvent.Event = SL_NETAPP_IP_RELEASED_EVENT; 00883 netAppEvent.EventData.ipReleased.ip_address = pIpV4->ip_address; 00884 netAppEvent.EventData.ipReleased.reason = pIpV4->reason; 00885 sl_Memcpy(netAppEvent.EventData.ipReleased.mac, pIpV4->mac, 6); 00886 00887 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(&netAppEvent); 00888 } 00889 break; 00890 00891 case SL_OPCODE_SOCKET_TXFAILEDASYNCRESPONSE: 00892 { 00893 SlSockEventData_t *txfailparams = (SlSockEventData_t*)_SL_RESP_ARGS_START(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); 00894 sockAppEvent.Event = SL_SOCKET_TX_FAILED_EVENT; 00895 sl_Memcpy((void *)&sockAppEvent.EventData,(void *)txfailparams,sizeof(SlSockEventData_t)); 00896 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(&sockAppEvent); 00897 } 00898 break; 00899 00900 case SL_OPCODE_SOCKET_SOCKETASYNCEVENT: 00901 { 00902 SlSockEventData_t *socketAsyncEvent = (SlSockEventData_t*)_SL_RESP_ARGS_START(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); 00903 sockAppEvent.Event = SL_SOCKET_ASYNC_EVENT; 00904 sockAppEvent.EventData.socketAsyncEvent.sd = socketAsyncEvent->socketAsyncEvent.sd; 00905 sockAppEvent.EventData.socketAsyncEvent.type = socketAsyncEvent->socketAsyncEvent.type; /* one of the possible types of socket */ 00906 sockAppEvent.EventData.socketAsyncEvent.val = socketAsyncEvent->socketAsyncEvent.val; 00907 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(&sockAppEvent); 00908 } 00909 break; 00910 00911 case SL_OPCODE_WLAN_SMART_CONFIG_START_ASYNC_RESPONSE: 00912 { 00913 slSmartConfigStartAsyncResponse_t *pResp = (slSmartConfigStartAsyncResponse_t*)_SL_RESP_ARGS_START(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); 00914 00915 wlanEvent.Event = SL_WLAN_SMART_CONFIG_COMPLETE_EVENT; 00916 wlanEvent.EventData.smartConfigStartResponse.status = pResp->status; 00917 wlanEvent.EventData.smartConfigStartResponse.ssid_len = pResp->ssid_len; 00918 wlanEvent.EventData.smartConfigStartResponse.private_token_len = pResp->private_token_len; 00919 00920 sl_Memset(wlanEvent.EventData.smartConfigStartResponse.ssid, 0x00, sizeof(wlanEvent.EventData.smartConfigStartResponse.ssid)); 00921 sl_Memcpy(wlanEvent.EventData.smartConfigStartResponse.ssid, pResp->ssid, pResp->ssid_len); 00922 /* if private data exist */ 00923 if (pResp->private_token_len) 00924 { 00925 sl_Memset(wlanEvent.EventData.smartConfigStartResponse.private_token, 0x00, sizeof(wlanEvent.EventData.smartConfigStartResponse.private_token)); 00926 sl_Memcpy(wlanEvent.EventData.smartConfigStartResponse.private_token, pResp->private_token, pResp->private_token_len); 00927 } 00928 00929 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(&wlanEvent); 00930 } 00931 break; 00932 00933 case SL_OPCODE_WLAN_SMART_CONFIG_STOP_ASYNC_RESPONSE: 00934 { 00935 slSmartConfigStopAsyncResponse_t *pResp = (slSmartConfigStopAsyncResponse_t*)_SL_RESP_ARGS_START(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); 00936 00937 wlanEvent.Event = SL_WLAN_SMART_CONFIG_STOP_EVENT; 00938 wlanEvent.EventData.smartConfigStopResponse.status = pResp->status; 00939 00940 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(&wlanEvent); 00941 } 00942 break; 00943 00944 case SL_OPCODE_WLAN_STA_CONNECTED: 00945 { 00946 slPeerInfoAsyncResponse_t* pResp = (slPeerInfoAsyncResponse_t*)_SL_RESP_ARGS_START(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); 00947 sl_Memset(&wlanEvent.EventData.APModeStaConnected,0,sizeof(slPeerInfoAsyncResponse_t)); 00948 wlanEvent.Event = SL_WLAN_STA_CONNECTED_EVENT; 00949 sl_Memcpy(wlanEvent.EventData.APModeStaConnected.mac,pResp->mac, 6); 00950 sl_Memcpy(wlanEvent.EventData.APModeStaConnected.go_peer_device_name,pResp->go_peer_device_name,pResp->go_peer_device_name_len); 00951 wlanEvent.EventData.APModeStaConnected.go_peer_device_name_len = pResp->go_peer_device_name_len; 00952 00953 sl_Memcpy(wlanEvent.EventData.APModeStaConnected.own_ssid,pResp->own_ssid,pResp->own_ssid_len); 00954 wlanEvent.EventData.APModeStaConnected.own_ssid_len = pResp->own_ssid_len; 00955 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(&wlanEvent); 00956 } 00957 break; 00958 00959 case SL_OPCODE_WLAN_STA_DISCONNECTED: 00960 { 00961 slPeerInfoAsyncResponse_t* pResp = (slPeerInfoAsyncResponse_t*)_SL_RESP_ARGS_START(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); 00962 sl_Memset(&wlanEvent.EventData.APModestaDisconnected,0,sizeof(slPeerInfoAsyncResponse_t)); 00963 wlanEvent.Event = SL_WLAN_STA_DISCONNECTED_EVENT; 00964 sl_Memcpy(wlanEvent.EventData.APModestaDisconnected.mac,pResp->mac, 6); 00965 sl_Memcpy(wlanEvent.EventData.APModestaDisconnected.go_peer_device_name,pResp->go_peer_device_name,pResp->go_peer_device_name_len); 00966 wlanEvent.EventData.APModestaDisconnected.go_peer_device_name_len = pResp->go_peer_device_name_len; 00967 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(&wlanEvent); 00968 } 00969 break; 00970 00971 case SL_OPCODE_NETAPP_PINGREPORTREQUESTRESPONSE: 00972 { 00973 _sl_HandleAsync_PingResponse((void *)g_pCB->FunctionParams.AsyncExt.pAsyncBuf); 00974 } 00975 break; 00976 00977 00978 default: 00979 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); 00980 break; 00981 } 00982 } 00983 } 00984 00985 00986 /* ******************************************************************************/ 00987 /* _SlDrvMsgReadCmdCtx */ 00988 /* ******************************************************************************/ 00989 _SlReturnVal_t _SlDrvMsgReadCmdCtx(void) 00990 { 00991 00992 /* after command response is received and isCmdRespWaited */ 00993 /* flag is set FALSE, it is necessary to read out all */ 00994 /* Async messages in Commands context, because ssiDma_IsrHandleSignalFromSlave */ 00995 /* could have dispatched some Async messages to g_NwpIf.CmdSyncObj */ 00996 /* after command response but before this response has been processed */ 00997 /* by spi_singleRead and isCmdRespWaited was set FALSE. */ 00998 while (TRUE == g_pCB->IsCmdRespWaited) 00999 { 01000 if(_SL_PENDING_RX_MSG(g_pCB)) 01001 { 01002 g_pCB->FunctionParams.AsyncExt.pAsyncBuf = NULL;/* buffer must be allocated by _SlDrvMsgRead */ 01003 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler= NULL; 01004 g_pCB->FunctionParams.AsyncExt.RxMsgClass = (_SlRxMsgClass_e)(-1);/* init to illegal value and verify it's overwritten with the valid one */ 01005 01006 VERIFY_RET_OK(_SlDrvMsgRead()); 01007 g_pCB->RxDoneCnt++; 01008 01009 if (CMD_RESP_CLASS == g_pCB->FunctionParams.AsyncExt.RxMsgClass) 01010 { 01011 g_pCB->IsCmdRespWaited = FALSE; 01012 01013 /* In case CmdResp has been read without waiting on CmdSyncObj - that */ 01014 /* Sync object. That to prevent old signal to be processed. */ 01015 sl_SyncObjClear(&g_pCB->CmdSyncObj); 01016 } 01017 else if (ASYNC_EVT_CLASS == g_pCB->FunctionParams.AsyncExt.RxMsgClass) 01018 { 01019 /* If Async event has been read in CmdResp context, check whether */ 01020 /* there is a handler for this event. If there is, spawn specific */ 01021 /* handler. Otherwise free the event's buffer. */ 01022 /* This way there will be no "dry shots" from CmdResp context to */ 01023 /* temporary context, i.e less waste of CPU and faster buffer */ 01024 /* release. */ 01025 _SlAsyncEventGenericHandler(); 01026 01027 #if (SL_MEMORY_MGMT == SL_MEMORY_MGMT_STATIC) 01028 g_pCB->FunctionParams.AsyncExt.pAsyncBuf = NULL; 01029 #else 01030 sl_Free(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); 01031 #endif 01032 } 01033 } 01034 else 01035 { 01036 /* CmdSyncObj will be signaled by IRQ */ 01037 OSI_RET_OK_CHECK(sl_SyncObjWait(&g_pCB->CmdSyncObj, SL_OS_WAIT_FOREVER)); 01038 } 01039 } 01040 01041 /* If there are more pending Rx Msgs after CmdResp is received, */ 01042 /* that means that these are Async, Dummy or Read Data Msgs. */ 01043 /* Spawn _SlDrvMsgReadSpawnCtx to trigger reading these messages from */ 01044 /* Temporary context. */ 01045 /* sl_Spawn is activated, using a different context */ 01046 OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->GlobalLockObj)); 01047 if(_SL_PENDING_RX_MSG(g_pCB)) 01048 { 01049 sl_Spawn((_SlSpawnEntryFunc_t)_SlDrvMsgReadSpawnCtx, NULL, 0); 01050 } 01051 01052 return SL_OS_RET_CODE_OK; 01053 } 01054 01055 /* ******************************************************************************/ 01056 /* _SlDrvMsgReadSpawnCtx */ 01057 /* ******************************************************************************/ 01058 _SlReturnVal_t _SlDrvMsgReadSpawnCtx(void *pValue) 01059 { 01060 #ifdef SL_POLLING_MODE_USED 01061 _i16 retCode = OSI_OK; 01062 /* for polling based systems */ 01063 do 01064 { 01065 retCode = sl_LockObjLock(&g_pCB->GlobalLockObj, 0); 01066 if ( OSI_OK != retCode ) 01067 { 01068 if (TRUE == g_pCB->IsCmdRespWaited) 01069 { 01070 OSI_RET_OK_CHECK( sl_SyncObjSignal(&g_pCB->CmdSyncObj) ); 01071 return SL_RET_CODE_OK; 01072 } 01073 } 01074 01075 } 01076 while (OSI_OK != retCode); 01077 01078 #else 01079 OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->GlobalLockObj, SL_OS_WAIT_FOREVER) ); 01080 #endif 01081 01082 g_pCB->FunctionParams.AsyncExt.pAsyncBuf = NULL;/* buffer must be allocated by _SlDrvMsgRead */ 01083 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler= NULL; 01084 g_pCB->FunctionParams.AsyncExt.RxMsgClass = CMD_RESP_CLASS;/* init to illegal value and verify it's overwritten with the valid one */ 01085 01086 /* Messages might have been read by CmdResp context. Therefore after */ 01087 /* getting LockObj, check again where the Pending Rx Msg is still present. */ 01088 if(FALSE == (_SL_PENDING_RX_MSG(g_pCB))) 01089 { 01090 OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->GlobalLockObj)); 01091 return SL_RET_CODE_OK; 01092 } 01093 01094 VERIFY_RET_OK(_SlDrvMsgRead()); 01095 01096 g_pCB->RxDoneCnt++; 01097 01098 switch(g_pCB->FunctionParams.AsyncExt.RxMsgClass) 01099 { 01100 case ASYNC_EVT_CLASS: 01101 /* If got here and protected by LockObj a message is waiting */ 01102 /* to be read */ 01103 VERIFY_PROTOCOL(NULL != g_pCB->FunctionParams.AsyncExt.pAsyncBuf); 01104 01105 _SlAsyncEventGenericHandler(); 01106 01107 #if (SL_MEMORY_MGMT == SL_MEMORY_MGMT_STATIC) 01108 g_pCB->FunctionParams.AsyncExt.pAsyncBuf = NULL; 01109 #else 01110 sl_Free(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); 01111 #endif 01112 break; 01113 case DUMMY_MSG_CLASS: 01114 case RECV_RESP_CLASS: 01115 /* These types are legal in this context. Do nothing */ 01116 break; 01117 case CMD_RESP_CLASS: 01118 /* Command response is illegal in this context. */ 01119 /* No 'break' here: Assert! */ 01120 default: 01121 VERIFY_PROTOCOL(0); 01122 } 01123 01124 OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->GlobalLockObj)); 01125 01126 return(SL_RET_CODE_OK); 01127 } 01128 01129 /* ******************************************************************************/ 01130 /* _SlDrvClassifyRxMsg */ 01131 /* ******************************************************************************/ 01132 void _SlDrvClassifyRxMsg( 01133 _SlOpcode_t Opcode) 01134 { 01135 01136 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler = NULL; 01137 01138 /* Async event has received */ 01139 if (0 == (SL_OPCODE_SYNC & Opcode)) 01140 { 01141 if (SL_OPCODE_DEVICE_DEVICEASYNCDUMMY == Opcode) 01142 { 01143 g_pCB->FunctionParams.AsyncExt.RxMsgClass = DUMMY_MSG_CLASS; 01144 } 01145 else if ( (SL_OPCODE_SOCKET_RECVASYNCRESPONSE == Opcode) || (SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE == Opcode) || (SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE_V6 == Opcode) ) 01146 { 01147 g_pCB->FunctionParams.AsyncExt.RxMsgClass = RECV_RESP_CLASS; 01148 } 01149 else 01150 { 01151 g_pCB->FunctionParams.AsyncExt.RxMsgClass = ASYNC_EVT_CLASS; 01152 01153 /* set silo handler */ 01154 if (SL_OPCODE_SILO_DEVICE == (Opcode & SL_OPCODE_SILO_MASK)) 01155 { 01156 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler = _SlDrvDeviceEventHandler; 01157 } 01158 else if (SL_OPCODE_SILO_WLAN == (Opcode & SL_OPCODE_SILO_MASK)) 01159 { 01160 #ifdef sl_WlanEvtHdlr 01161 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler = (_SlSpawnEntryFunc_t)sl_WlanEvtHdlr; 01162 #endif 01163 } 01164 else if (SL_OPCODE_SILO_SOCKET == (Opcode & SL_OPCODE_SILO_MASK)) 01165 { 01166 01167 #ifdef sl_SockEvtHdlr 01168 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler = (_SlSpawnEntryFunc_t)sl_SockEvtHdlr; 01169 #endif 01170 } 01171 else if (SL_OPCODE_SILO_NETAPP == (Opcode & SL_OPCODE_SILO_MASK)) 01172 { 01173 01174 if ((SL_OPCODE_NETAPP_HTTPGETTOKENVALUE == Opcode) || (SL_OPCODE_NETAPP_HTTPPOSTTOKENVALUE == Opcode)) 01175 { 01176 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler = _SlDrvNetAppEventHandler; 01177 } 01178 #ifdef sl_NetAppEvtHdlr 01179 else 01180 { 01181 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler = (_SlSpawnEntryFunc_t)sl_NetAppEvtHdlr; 01182 } 01183 #endif 01184 } 01185 /* else if (SL_OPCODE_SILO_NVMEM == (Opcode & SL_OPCODE_SILO_MASK)) */ 01186 /* { */ 01187 /* } */ 01188 /* else if (SL_OPCODE_SILO_NETCFG == (Opcode & SL_OPCODE_SILO_MASK)) */ 01189 /* { */ 01190 /* } */ 01191 else 01192 { 01193 SL_ERROR_TRACE2(MSG_311, "ASSERT: _SlDrvClassifyRxMsg : invalid opcode = 0x%x = %1", Opcode, Opcode); 01194 } 01195 } 01196 } 01197 else 01198 { 01199 /* These may be Command responses only */ 01200 g_pCB->FunctionParams.AsyncExt.RxMsgClass = CMD_RESP_CLASS; 01201 } 01202 01203 } 01204 01205 /* ******************************************************************************/ 01206 /* _SlDrvShiftDWord */ 01207 /* ******************************************************************************/ 01208 void _SlDrvShiftDWord(_u8 *pBuf) 01209 { 01210 _u8 ShiftIdx; 01211 for(ShiftIdx = 0; ShiftIdx< 7; ShiftIdx++) 01212 { 01213 pBuf[ShiftIdx] = pBuf[ShiftIdx+1]; 01214 } 01215 pBuf[7] = 0; 01216 } 01217 01218 /* ******************************************************************************/ 01219 /* _SlDrvRxHdrRead */ 01220 /* ******************************************************************************/ 01221 _SlReturnVal_t _SlDrvRxHdrRead(_u8 *pBuf, _u8 *pAlignSize) 01222 { 01223 _u32 SyncCnt = 0; 01224 01225 #ifndef SL_IF_TYPE_UART 01226 /* 1. Write CNYS pattern to NWP when working in SPI mode only */ 01227 NWP_IF_WRITE_CHECK(g_pCB->FD, (_u8 *)&g_H2NCnysPattern.Short, SYNC_PATTERN_LEN); 01228 #endif 01229 01230 /* 2. Read 4 bytes (protocol aligned) */ 01231 NWP_IF_READ_CHECK(g_pCB->FD, &pBuf[0], 4); 01232 _SL_DBG_SYNC_LOG(SyncCnt,pBuf); 01233 01234 /* Wait for SYNC_PATTERN_LEN from the device */ 01235 while ( ! N2H_SYNC_PATTERN_MATCH(pBuf, g_pCB->TxSeqNum) ) 01236 { 01237 /* 3. Debug limit of scan */ 01238 VERIFY_PROTOCOL(SyncCnt < SL_SYNC_SCAN_THRESHOLD); 01239 01240 /* 4. Read next 4 bytes to Low 4 bytes of buffer */ 01241 if(0 == (SyncCnt % (_u32)SYNC_PATTERN_LEN)) 01242 { 01243 NWP_IF_READ_CHECK(g_pCB->FD, &pBuf[4], 4); 01244 _SL_DBG_SYNC_LOG(SyncCnt,pBuf); 01245 } 01246 01247 /* 5. Shift Buffer Up for checking if the sync is shifted */ 01248 _SlDrvShiftDWord(pBuf); 01249 01250 SyncCnt++; 01251 } 01252 01253 /* 5. Sync pattern found. If needed, complete number of read bytes to multiple of 4 (protocol align) */ 01254 SyncCnt %= SYNC_PATTERN_LEN; 01255 01256 if(SyncCnt > 0) 01257 { 01258 *(_u32 *)&pBuf[0] = *(_u32 *)&pBuf[4]; 01259 NWP_IF_READ_CHECK(g_pCB->FD, &pBuf[SYNC_PATTERN_LEN - SyncCnt], (_u16)SyncCnt); 01260 } 01261 else 01262 { 01263 NWP_IF_READ_CHECK(g_pCB->FD, &pBuf[0], 4); 01264 } 01265 01266 /* 6. Scan for Double pattern. */ 01267 while ( N2H_SYNC_PATTERN_MATCH(pBuf, g_pCB->TxSeqNum) ) 01268 { 01269 _SL_DBG_CNT_INC(Work.DoubleSyncPattern); 01270 NWP_IF_READ_CHECK(g_pCB->FD, &pBuf[0], SYNC_PATTERN_LEN); 01271 } 01272 g_pCB->TxSeqNum++; 01273 01274 /* 7. Here we've read Generic Header (4 bytes). Read the Resp Specific header (4 more bytes). */ 01275 NWP_IF_READ_CHECK(g_pCB->FD, &pBuf[SYNC_PATTERN_LEN], _SL_RESP_SPEC_HDR_SIZE); 01276 01277 /* 8. Here we've read the entire Resp Header. */ 01278 /* Return number bytes needed to be sent after read for NWP Rx 4-byte alignment (protocol alignment) */ 01279 *pAlignSize = (_u8)((SyncCnt > 0) ? (SYNC_PATTERN_LEN - SyncCnt) : 0); 01280 01281 return SL_RET_CODE_OK; 01282 } 01283 01284 /* ***************************************************************************** */ 01285 /* _SlDrvBasicCmd */ 01286 /* ***************************************************************************** */ 01287 typedef union 01288 { 01289 _BasicResponse_t Rsp; 01290 }_SlBasicCmdMsg_u; 01291 01292 _i16 _SlDrvBasicCmd(_SlOpcode_t Opcode) 01293 { 01294 _SlBasicCmdMsg_u Msg = {0}; 01295 _SlCmdCtrl_t CmdCtrl; 01296 01297 CmdCtrl.Opcode = Opcode; 01298 CmdCtrl.TxDescLen = 0; 01299 CmdCtrl.RxDescLen = sizeof(_BasicResponse_t); 01300 01301 01302 VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&CmdCtrl, &Msg, NULL)); 01303 01304 return (_i16)Msg.Rsp.status; 01305 } 01306 01307 /* ***************************************************************************** */ 01308 /* _SlDrvWaitForPoolObj */ 01309 /* ***************************************************************************** */ 01310 _i16 _SlDrvWaitForPoolObj(_u32 ActionID, _u8 SocketID) 01311 { 01312 _u8 CurrObjIndex = MAX_CONCURRENT_ACTIONS; 01313 01314 OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); 01315 01316 /* Get free object */ 01317 if (MAX_CONCURRENT_ACTIONS > g_pCB->FreePoolIdx) 01318 { 01319 /* save the current obj index */ 01320 CurrObjIndex = g_pCB->FreePoolIdx; 01321 /* set the new free index */ 01322 if (MAX_CONCURRENT_ACTIONS > g_pCB->ObjPool[CurrObjIndex].NextIndex) 01323 { 01324 g_pCB->FreePoolIdx = g_pCB->ObjPool[CurrObjIndex].NextIndex; 01325 } 01326 else 01327 { 01328 /* No further free actions available */ 01329 g_pCB->FreePoolIdx = MAX_CONCURRENT_ACTIONS; 01330 } 01331 } 01332 else 01333 { 01334 OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); 01335 return CurrObjIndex; 01336 } 01337 g_pCB->ObjPool[CurrObjIndex].ActionID = (_u8)ActionID; 01338 if (SL_MAX_SOCKETS > SocketID) 01339 { 01340 g_pCB->ObjPool[CurrObjIndex].AdditionalData = SocketID; 01341 } 01342 /*In case this action is socket related, SocketID bit will be on 01343 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 */ 01344 while ( ( (SL_MAX_SOCKETS > SocketID) && (g_pCB->ActiveActionsBitmap & (1<<SocketID)) ) || ( (g_pCB->ActiveActionsBitmap & (1<<ActionID)) && (SL_MAX_SOCKETS == SocketID) ) ) 01345 { 01346 //action in progress - move to pending list 01347 g_pCB->ObjPool[CurrObjIndex].NextIndex = g_pCB->PendingPoolIdx; 01348 g_pCB->PendingPoolIdx = CurrObjIndex; 01349 OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); 01350 //wait for action to be free 01351 OSI_RET_OK_CHECK(sl_SyncObjWait(&g_pCB->ObjPool[CurrObjIndex].SyncObj, SL_OS_WAIT_FOREVER)); 01352 //set params and move to active (remove from pending list at _SlDrvReleasePoolObj) 01353 OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); 01354 } 01355 /*mark as active. Set socket as active if action is on socket, otherwise mark action as active*/ 01356 if (SL_MAX_SOCKETS > SocketID) 01357 { 01358 g_pCB->ActiveActionsBitmap |= (1<<SocketID); 01359 } 01360 else 01361 { 01362 g_pCB->ActiveActionsBitmap |= (1<<ActionID); 01363 } 01364 /* move to active list */ 01365 g_pCB->ObjPool[CurrObjIndex].NextIndex = g_pCB->ActivePoolIdx; 01366 g_pCB->ActivePoolIdx = CurrObjIndex; 01367 /* unlock */ 01368 OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); 01369 return CurrObjIndex; 01370 } 01371 01372 /* ******************************************************************************/ 01373 /* _SlDrvReleasePoolObj */ 01374 /* ******************************************************************************/ 01375 void _SlDrvReleasePoolObj(_u8 ObjIdx) 01376 { 01377 _u8 PendingIndex; 01378 01379 OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); 01380 01381 /* go over the pending list and release other pending action if needed */ 01382 PendingIndex = g_pCB->PendingPoolIdx; 01383 while(MAX_CONCURRENT_ACTIONS > PendingIndex) 01384 { 01385 /* In case this action is socket related, SocketID is in use, otherwise will be set to SL_MAX_SOCKETS */ 01386 if ( (g_pCB->ObjPool[PendingIndex].ActionID == g_pCB->ObjPool[ObjIdx].ActionID) && 01387 ( (SL_MAX_SOCKETS == (g_pCB->ObjPool[PendingIndex].AdditionalData & BSD_SOCKET_ID_MASK)) || 01388 ((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) ))) ) 01389 { 01390 /* remove from pending list */ 01391 _SlRemoveFromList(&g_pCB->PendingPoolIdx, PendingIndex); 01392 OSI_RET_OK_CHECK(sl_SyncObjSignal(&(g_pCB->ObjPool[PendingIndex].SyncObj))); 01393 break; 01394 } 01395 PendingIndex = g_pCB->ObjPool[PendingIndex].NextIndex; 01396 } 01397 01398 if (SL_MAX_SOCKETS > (g_pCB->ObjPool[ObjIdx].AdditionalData & BSD_SOCKET_ID_MASK)) 01399 { 01400 /* unset socketID */ 01401 g_pCB->ActiveActionsBitmap &= ~(1<<(g_pCB->ObjPool[ObjIdx].AdditionalData & BSD_SOCKET_ID_MASK)); 01402 } 01403 else 01404 { 01405 /* unset actionID */ 01406 g_pCB->ActiveActionsBitmap &= ~(1<<g_pCB->ObjPool[ObjIdx].ActionID); 01407 } 01408 01409 /* delete old data */ 01410 g_pCB->ObjPool[ObjIdx].pRespArgs = NULL; 01411 g_pCB->ObjPool[ObjIdx].ActionID = 0; 01412 g_pCB->ObjPool[ObjIdx].AdditionalData = SL_MAX_SOCKETS; 01413 01414 /* remove from active list */ 01415 _SlRemoveFromList(&g_pCB->ActivePoolIdx, ObjIdx); 01416 /* move to free list */ 01417 g_pCB->ObjPool[ObjIdx].NextIndex = g_pCB->FreePoolIdx; 01418 g_pCB->FreePoolIdx = ObjIdx; 01419 01420 OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); 01421 } 01422 01423 01424 01425 /* ******************************************************************************/ 01426 /* _SlDrvObjInit */ 01427 /* ******************************************************************************/ 01428 void _SlDrvObjInit(void) 01429 { 01430 _u8 Idx; 01431 01432 sl_Memset(&g_pCB->ObjPool[0],0,MAX_CONCURRENT_ACTIONS*sizeof(_SlPoolObj_t)); 01433 /* place all Obj in the free list */ 01434 g_pCB->FreePoolIdx = 0; 01435 for (Idx = 0 ; Idx < MAX_CONCURRENT_ACTIONS ; Idx++) 01436 { 01437 g_pCB->ObjPool[Idx].NextIndex = Idx + 1; 01438 g_pCB->ObjPool[Idx].AdditionalData = SL_MAX_SOCKETS; 01439 } 01440 01441 g_pCB->ActivePoolIdx = MAX_CONCURRENT_ACTIONS; 01442 g_pCB->PendingPoolIdx = MAX_CONCURRENT_ACTIONS; 01443 01444 } 01445 01446 /* ******************************************************************************/ 01447 /* _SlDrvObjDeInit */ 01448 /* ******************************************************************************/ 01449 void _SlDrvObjDeInit(void) 01450 { 01451 g_pCB->FreePoolIdx = 0; 01452 g_pCB->PendingPoolIdx = MAX_CONCURRENT_ACTIONS; 01453 g_pCB->ActivePoolIdx = MAX_CONCURRENT_ACTIONS; 01454 01455 } 01456 01457 /* ******************************************************************************/ 01458 /* _SlRemoveFromList */ 01459 /* ******************************************************************************/ 01460 void _SlRemoveFromList(_u8 *ListIndex, _u8 ItemIndex) 01461 { 01462 _u8 Idx; 01463 /* only one item in the list */ 01464 if (MAX_CONCURRENT_ACTIONS == g_pCB->ObjPool[*ListIndex].NextIndex) 01465 { 01466 *ListIndex = MAX_CONCURRENT_ACTIONS; 01467 } 01468 /* need to remove the first item in the list and therefore update the global which holds this index */ 01469 else if (*ListIndex == ItemIndex) 01470 { 01471 *ListIndex = g_pCB->ObjPool[ItemIndex].NextIndex; 01472 } 01473 else 01474 { 01475 Idx = *ListIndex; 01476 while(MAX_CONCURRENT_ACTIONS > Idx) 01477 { 01478 /* remove from list */ 01479 if (g_pCB->ObjPool[Idx].NextIndex == ItemIndex) 01480 { 01481 g_pCB->ObjPool[Idx].NextIndex = g_pCB->ObjPool[ItemIndex].NextIndex; 01482 break; 01483 } 01484 Idx = g_pCB->ObjPool[Idx].NextIndex; 01485 } 01486 } 01487 } 01488 01489 01490 /* ******************************************************************************/ 01491 /* _SlFindAndSetActiveObj */ 01492 /* ******************************************************************************/ 01493 _SlReturnVal_t _SlFindAndSetActiveObj(_SlOpcode_t Opcode, _u8 Sd) 01494 { 01495 _u8 ActiveIndex; 01496 01497 ActiveIndex = g_pCB->ActivePoolIdx; 01498 /* go over the active list if exist to find obj waiting for this Async event */ 01499 while (MAX_CONCURRENT_ACTIONS > ActiveIndex) 01500 { 01501 /* unset the Ipv4\IPv6 bit in the opcode if family bit was set */ 01502 if (g_pCB->ObjPool[ActiveIndex].AdditionalData & SL_NETAPP_FAMILY_MASK) 01503 { 01504 Opcode &= ~SL_OPCODE_IPV6; 01505 } 01506 01507 if ((g_pCB->ObjPool[ActiveIndex].ActionID == RECV_ID) && (Sd == g_pCB->ObjPool[ActiveIndex].AdditionalData) && 01508 ( (SL_OPCODE_SOCKET_RECVASYNCRESPONSE == Opcode) || (SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE == Opcode) || (SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE_V6 == Opcode) ) ) 01509 { 01510 g_pCB->FunctionParams.AsyncExt.ActionIndex = ActiveIndex; 01511 return SL_RET_CODE_OK; 01512 } 01513 /* In case this action is socket related, SocketID is in use, otherwise will be set to SL_MAX_SOCKETS */ 01514 if ( (_SlActionLookupTable[ g_pCB->ObjPool[ActiveIndex].ActionID - MAX_SOCKET_ENUM_IDX].ActionAsyncOpcode == Opcode) && 01515 ( ((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)) ) ) 01516 { 01517 /* set handler */ 01518 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler = _SlActionLookupTable[ g_pCB->ObjPool[ActiveIndex].ActionID - MAX_SOCKET_ENUM_IDX].AsyncEventHandler; 01519 g_pCB->FunctionParams.AsyncExt.ActionIndex = ActiveIndex; 01520 return SL_RET_CODE_OK; 01521 } 01522 ActiveIndex = g_pCB->ObjPool[ActiveIndex].NextIndex; 01523 } 01524 01525 return SL_RET_CODE_SELF_ERROR; 01526 } 01527 01528 /*! 01529 \brief This function handles events for IP address acquisition via DHCP 01530 indication 01531 01532 \param[in] pNetAppEvent is the event passed to the handler 01533 01534 \return None 01535 01536 \note 01537 01538 \warning 01539 */ 01540 void SimpleLinkNetAppEventHandler(SlNetAppEvent_t *pNetAppEvent) 01541 { 01542 if(pNetAppEvent == NULL) 01543 // CLI_Write((_u8 *)" [NETAPP EVENT] NULL Pointer Error \n\r"); 01544 printf(" [NETAPP EVENT] NULL Pointer Error \n\r"); 01545 01546 switch(pNetAppEvent->Event) 01547 { 01548 case SL_NETAPP_IPV4_IPACQUIRED_EVENT: 01549 { 01550 SlIpV4AcquiredAsync_t *pEventData = NULL; 01551 01552 SET_STATUS_BIT(g_Status, STATUS_BIT_IP_ACQUIRED); 01553 01554 pEventData = &pNetAppEvent->EventData.ipAcquiredV4; 01555 g_GatewayIP = pEventData->gateway; 01556 } 01557 break; 01558 01559 case SL_NETAPP_IP_LEASED_EVENT: 01560 { 01561 g_StationIP = pNetAppEvent->EventData.ipLeased.ip_address; 01562 SET_STATUS_BIT(g_Status, STATUS_BIT_IP_LEASED); 01563 } 01564 break; 01565 01566 default: 01567 { 01568 // CLI_Write((_u8 *)" [NETAPP EVENT] Unexpected event \n\r"); 01569 printf(" [NETAPP EVENT] Unexpected event \n\r"); 01570 } 01571 break; 01572 } 01573 } 01574 01575 /*! 01576 \brief This function handles WLAN events 01577 01578 \param[in] pWlanEvent is the event passed to the handler 01579 01580 \return None 01581 01582 \note 01583 01584 \warning 01585 */ 01586 void SimpleLinkWlanEventHandler(SlWlanEvent_t *pWlanEvent) 01587 { 01588 if(pWlanEvent == NULL) 01589 // CLI_Write((_u8 *)" [WLAN EVENT] NULL Pointer Error \n\r"); 01590 printf(" [WLAN EVENT] NULL Pointer Error \n\r"); 01591 switch(pWlanEvent->Event) 01592 { 01593 case SL_WLAN_CONNECT_EVENT: 01594 { 01595 SET_STATUS_BIT(g_Status, STATUS_BIT_CONNECTION); 01596 01597 /* 01598 * Information about the connected AP (like name, MAC etc) will be 01599 * available in 'slWlanConnectAsyncResponse_t' - Applications 01600 * can use it if required 01601 * 01602 * slWlanConnectAsyncResponse_t *pEventData = NULL; 01603 * pEventData = &pWlanEvent->EventData.STAandP2PModeWlanConnected; 01604 * 01605 */ 01606 } 01607 break; 01608 01609 case SL_WLAN_DISCONNECT_EVENT: 01610 { 01611 slWlanConnectAsyncResponse_t* pEventData = NULL; 01612 01613 CLR_STATUS_BIT(g_Status, STATUS_BIT_CONNECTION); 01614 CLR_STATUS_BIT(g_Status, STATUS_BIT_IP_ACQUIRED); 01615 01616 pEventData = &pWlanEvent->EventData.STAandP2PModeDisconnected; 01617 01618 /* If the user has initiated 'Disconnect' request, 'reason_code' is SL_USER_INITIATED_DISCONNECTION */ 01619 if(SL_USER_INITIATED_DISCONNECTION == pEventData->reason_code) 01620 { 01621 // CLI_Write((_u8 *)" Device disconnected from the AP on application's request \n\r"); 01622 printf(" Device disconnected from the AP on application's request \n\r"); 01623 } 01624 else 01625 { 01626 // CLI_Write((_u8 *)" Device disconnected from the AP on an ERROR..!! \n\r"); 01627 printf(" Device disconnected from the AP on an ERROR..!! \n\r"); 01628 } 01629 } 01630 break; 01631 01632 case SL_WLAN_STA_CONNECTED_EVENT: 01633 { 01634 SET_STATUS_BIT(g_Status, STATUS_BIT_STA_CONNECTED); 01635 } 01636 break; 01637 01638 case SL_WLAN_STA_DISCONNECTED_EVENT: 01639 { 01640 CLR_STATUS_BIT(g_Status, STATUS_BIT_STA_CONNECTED); 01641 CLR_STATUS_BIT(g_Status, STATUS_BIT_IP_LEASED); 01642 } 01643 break; 01644 01645 default: 01646 { 01647 // CLI_Write((_u8 *)" [WLAN EVENT] Unexpected event \n\r"); 01648 printf(" [WLAN EVENT] Unexpected event \n\r"); 01649 } 01650 break; 01651 } 01652 } 01653 01654 /*! 01655 \brief This function handles socket events indication 01656 01657 \param[in] pSock is the event passed to the handler 01658 01659 \return None 01660 */ 01661 void SimpleLinkSockEventHandler(SlSockEvent_t *pSock) 01662 { 01663 /* 01664 * This application doesn't work with socket - Hence these 01665 * events are not handled here 01666 */ 01667 // CLI_Write((_u8 *)" [SOCK EVENT] Unexpected event \n\r"); 01668 printf(" [SOCK EVENT] Unexpected event \n\r"); 01669 } 01670
Generated on Tue Jul 12 2022 22:55:20 by 1.7.2