TI's CC3100 host driver and demo. Experimental and a work in progress.

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers cc3100_driver.cpp Source File

cc3100_driver.cpp

00001 /*
00002 * driver.c - CC31xx/CC32xx Host Driver Implementation
00003 *
00004 * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ 
00005 * 
00006 * 
00007 *  Redistribution and use in source and binary forms, with or without 
00008 *  modification, are permitted provided that the following conditions 
00009 *  are met:
00010 *
00011 *    Redistributions of source code must retain the above copyright 
00012 *    notice, this list of conditions and the following disclaimer.
00013 *
00014 *    Redistributions in binary form must reproduce the above copyright
00015 *    notice, this list of conditions and the following disclaimer in the 
00016 *    documentation and/or other materials provided with the   
00017 *    distribution.
00018 *
00019 *    Neither the name of Texas Instruments Incorporated nor the names of
00020 *    its contributors may be used to endorse or promote products derived
00021 *    from this software without specific prior written permission.
00022 *
00023 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
00024 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
00025 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00026 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
00027 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
00028 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
00029 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00030 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00031 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
00032 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
00033 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034 *
00035 */
00036 
00037 /*****************************************************************************/
00038 /* Include files                                                             */
00039 /*****************************************************************************/
00040 #include "cc3100_simplelink.h"
00041 //#include "cc3100_protocol.h"
00042 #include "cc3100_driver.h"
00043 #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