diff options
| author | danicampora | 2015-02-06 15:35:48 +0100 |
|---|---|---|
| committer | Damien George | 2015-02-06 22:10:11 +0000 |
| commit | 8785645a952c03315dbf93667b5f7c7eec49762f (patch) | |
| tree | 267e2d572d87e92bfc0bfabf83859231152a2162 /cc3200/simplelink/source | |
| parent | 97f14606f528180d1482cffbe3571163a1dd9273 (diff) | |
cc3200: Add cc3200 port of MicroPython.
The port currently implements support for GPIO, RTC, ExtInt and the WiFi
subsystem. A small file system is available in the serial flash. A
bootloader which makes OTA updates possible, is also part of this initial
implementation.
Diffstat (limited to 'cc3200/simplelink/source')
| -rw-r--r-- | cc3200/simplelink/source/device.c | 535 | ||||
| -rw-r--r-- | cc3200/simplelink/source/driver.c | 1520 | ||||
| -rw-r--r-- | cc3200/simplelink/source/driver.h | 220 | ||||
| -rw-r--r-- | cc3200/simplelink/source/flowcont.c | 71 | ||||
| -rw-r--r-- | cc3200/simplelink/source/flowcont.h | 61 | ||||
| -rw-r--r-- | cc3200/simplelink/source/fs.c | 415 | ||||
| -rw-r--r-- | cc3200/simplelink/source/netapp.c | 1285 | ||||
| -rw-r--r-- | cc3200/simplelink/source/netcfg.c | 142 | ||||
| -rw-r--r-- | cc3200/simplelink/source/nonos.c | 153 | ||||
| -rw-r--r-- | cc3200/simplelink/source/nonos.h | 325 | ||||
| -rw-r--r-- | cc3200/simplelink/source/objInclusion.h | 325 | ||||
| -rw-r--r-- | cc3200/simplelink/source/protocol.h | 1176 | ||||
| -rw-r--r-- | cc3200/simplelink/source/socket.c | 1123 | ||||
| -rw-r--r-- | cc3200/simplelink/source/spawn.c | 197 | ||||
| -rw-r--r-- | cc3200/simplelink/source/spawn.h | 63 | ||||
| -rw-r--r-- | cc3200/simplelink/source/wlan.c | 993 |
16 files changed, 8604 insertions, 0 deletions
diff --git a/cc3200/simplelink/source/device.c b/cc3200/simplelink/source/device.c new file mode 100644 index 000000000..a77e8335e --- /dev/null +++ b/cc3200/simplelink/source/device.c @@ -0,0 +1,535 @@ +/* +* device.c - CC31xx/CC32xx Host Driver Implementation +* +* Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the +* distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +*/ + + + +/*****************************************************************************/ +/* Include files */ +/*****************************************************************************/ +#include "simplelink.h" +#include "protocol.h" +#include "flowcont.h" +#include "driver.h" + + +/*****************************************************************************/ +/* Internal functions */ +/*****************************************************************************/ + +_i16 _sl_GetStartResponseConvert(_u32 Status) +{ + switch(Status) + { + case INIT_STA_OK: + return ROLE_STA; + case INIT_STA_ERR: + return ROLE_STA_ERR; + case INIT_AP_OK: + return ROLE_AP; + case INIT_AP_ERR: + return ROLE_AP_ERR; + case INIT_P2P_OK: + return ROLE_P2P; + case INIT_P2P_ERR: + return ROLE_P2P_ERR; + default: + return (_i16)Status; + } +} + +/*****************************************************************************/ +/* API Functions */ +/*****************************************************************************/ + + + +/*****************************************************************************/ +/* sl_Task */ +/*****************************************************************************/ +#if _SL_INCLUDE_FUNC(sl_Task) +void sl_Task(void) +{ +#ifdef _SlTaskEntry + _SlTaskEntry(); +#endif +} +#endif + +/*****************************************************************************/ +/* sl_Start */ +/*****************************************************************************/ +#if _SL_INCLUDE_FUNC(sl_Start) +_i16 sl_Start(const void* pIfHdl, _i8* pDevName, const P_INIT_CALLBACK pInitCallBack) +{ + _i16 ObjIdx = MAX_CONCURRENT_ACTIONS; + InitComplete_t AsyncRsp; + + /* Perform any preprocessing before enable networking services */ + sl_DeviceEnablePreamble(); + + /* ControlBlock init */ + _SlDrvDriverCBInit(); + + /* open the interface: usually SPI or UART */ + if (NULL == pIfHdl) + { + g_pCB->FD = sl_IfOpen((void *)pDevName, 0); + } + else + { + g_pCB->FD = (_SlFd_t)pIfHdl; + } + /* Use Obj to issue the command, if not available try later */ + ObjIdx = _SlDrvWaitForPoolObj(START_STOP_ID,SL_MAX_SOCKETS); + if (MAX_CONCURRENT_ACTIONS == ObjIdx) + { + return SL_POOL_IS_EMPTY; + } + OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); + g_pCB->ObjPool[ObjIdx].pRespArgs = (_u8 *)&AsyncRsp; + OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); + + if( g_pCB->FD >= 0) + { + sl_DeviceDisable(); + + sl_IfRegIntHdlr((SL_P_EVENT_HANDLER)_SlDrvRxIrqHandler, NULL); + + if(NULL != pInitCallBack) + { + g_pCB->pInitCallback = pInitCallBack; + } + sl_DeviceEnable(); + + if (NULL == pInitCallBack) + { + OSI_RET_OK_CHECK(sl_SyncObjWait(&g_pCB->ObjPool[ObjIdx].SyncObj, SL_OS_WAIT_FOREVER)); + /*release Pool Object*/ + _SlDrvReleasePoolObj(g_pCB->FunctionParams.AsyncExt.ActionIndex); + return _sl_GetStartResponseConvert(AsyncRsp.Status); + } + } + + return (_i16)g_pCB->FD; + +} +#endif + +/*************************************************************************** +_sl_HandleAsync_InitComplete - handles init complete signalling to +a waiting object +****************************************************************************/ +void _sl_HandleAsync_InitComplete(void *pVoidBuf) +{ + InitComplete_t *pMsgArgs = (InitComplete_t *)_SL_RESP_ARGS_START(pVoidBuf); + + OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); + + if(g_pCB->pInitCallback) + { + g_pCB->pInitCallback(_sl_GetStartResponseConvert(pMsgArgs->Status)); + } + else + { + sl_Memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(InitComplete_t)); + OSI_RET_OK_CHECK(sl_SyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj)); + } + OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); + + if(g_pCB->pInitCallback) + { + _SlDrvReleasePoolObj(g_pCB->FunctionParams.AsyncExt.ActionIndex); + } + +} + +/*************************************************************************** +_sl_HandleAsync_Stop - handles stop signalling to +a waiting object +****************************************************************************/ +void _sl_HandleAsync_Stop(void *pVoidBuf) +{ + _BasicResponse_t *pMsgArgs = (_BasicResponse_t *)_SL_RESP_ARGS_START(pVoidBuf); + + VERIFY_SOCKET_CB(NULL != g_pCB->StopCB.pAsyncRsp); + + OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); + + sl_Memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(_BasicResponse_t)); + OSI_RET_OK_CHECK(sl_SyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj)); + OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); + return; +} + + +/***************************************************************************** +sl_stop +******************************************************************************/ +typedef union +{ + _DevStopCommand_t Cmd; + _BasicResponse_t Rsp; +}_SlStopMsg_u; + +const _SlCmdCtrl_t _SlStopCmdCtrl = +{ + SL_OPCODE_DEVICE_STOP_COMMAND, + sizeof(_DevStopCommand_t), + sizeof(_BasicResponse_t) +}; + +#if _SL_INCLUDE_FUNC(sl_Stop) +_i16 sl_Stop(_u16 timeout) +{ + _i16 RetVal=0; + _SlStopMsg_u Msg; + _BasicResponse_t AsyncRsp; + _i16 ObjIdx = MAX_CONCURRENT_ACTIONS; + /* if timeout is 0 the shutdown is forced immediately */ + if( 0 == timeout ) + { + sl_IfRegIntHdlr(NULL, NULL); + sl_DeviceDisable(); + RetVal = sl_IfClose(g_pCB->FD); + + } + else + { + /* let the device make the shutdown using the defined timeout */ + Msg.Cmd.Timeout = timeout; + /* Use Obj to issue the command, if not available try later */ + ObjIdx = _SlDrvWaitForPoolObj(START_STOP_ID,SL_MAX_SOCKETS); + if (MAX_CONCURRENT_ACTIONS == ObjIdx) + { + return SL_POOL_IS_EMPTY; + } + OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); + + g_pCB->ObjPool[ObjIdx].pRespArgs = (_u8 *)&AsyncRsp; + + OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlStopCmdCtrl, &Msg, NULL)); + + if(SL_OS_RET_CODE_OK == (_i16)Msg.Rsp.status) + { + OSI_RET_OK_CHECK(sl_SyncObjWait(&g_pCB->ObjPool[ObjIdx].SyncObj, SL_OS_WAIT_FOREVER)); + Msg.Rsp.status = AsyncRsp.status; + RetVal = Msg.Rsp.status; + } + + _SlDrvReleasePoolObj((_u8)ObjIdx); + + sl_IfRegIntHdlr(NULL, NULL); + sl_DeviceDisable(); + sl_IfClose(g_pCB->FD); + } + _SlDrvDriverCBDeinit(); + + return RetVal; +} +#endif + + +/***************************************************************************** +sl_EventMaskSet +*****************************************************************************/ +typedef union +{ + _DevMaskEventSetCommand_t Cmd; + _BasicResponse_t Rsp; +}_SlEventMaskSetMsg_u; + +const _SlCmdCtrl_t _SlEventMaskSetCmdCtrl = +{ + SL_OPCODE_DEVICE_EVENTMASKSET, + sizeof(_DevMaskEventSetCommand_t), + sizeof(_BasicResponse_t) +}; + +#if _SL_INCLUDE_FUNC(sl_EventMaskSet) +_i16 sl_EventMaskSet(_u8 EventClass , _u32 Mask) +{ + _SlEventMaskSetMsg_u Msg; + + Msg.Cmd.group = EventClass; + Msg.Cmd.mask = Mask; + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlEventMaskSetCmdCtrl, &Msg, NULL)); + + return (_i16)Msg.Rsp.status; +} +#endif + +/****************************************************************************** +sl_EventMaskGet +******************************************************************************/ +typedef union +{ + _DevMaskEventGetCommand_t Cmd; + _DevMaskEventGetResponse_t Rsp; +}_SlEventMaskGetMsg_u; + +const _SlCmdCtrl_t _SlEventMaskGetCmdCtrl = +{ + SL_OPCODE_DEVICE_EVENTMASKGET, + sizeof(_DevMaskEventGetCommand_t), + sizeof(_DevMaskEventGetResponse_t) +}; + +#if _SL_INCLUDE_FUNC(sl_EventMaskGet) +_i16 sl_EventMaskGet(_u8 EventClass, _u32 *pMask) +{ + _SlEventMaskGetMsg_u Msg; + + Msg.Cmd.group = EventClass; + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlEventMaskGetCmdCtrl, &Msg, NULL)); + + *pMask = Msg.Rsp.mask; + return SL_RET_CODE_OK; +} +#endif + + + +/****************************************************************************** +sl_DevGet +******************************************************************************/ + +typedef union +{ + _DeviceSetGet_t Cmd; + _DeviceSetGet_t Rsp; +}_SlDeviceMsgGet_u; + +const _SlCmdCtrl_t _SlDeviceGetCmdCtrl = +{ + SL_OPCODE_DEVICE_DEVICEGET, + sizeof(_DeviceSetGet_t), + sizeof(_DeviceSetGet_t) +}; + +#if _SL_INCLUDE_FUNC(sl_DevGet) +_i32 sl_DevGet(_u8 DeviceGetId, _u8 *pOption,_u8 *pConfigLen, _u8 *pValues) +{ + _SlDeviceMsgGet_u Msg; + _SlCmdExt_t CmdExt; + + if (*pConfigLen == 0) + { + return SL_EZEROLEN; + } + + if( pOption ) + { + CmdExt.TxPayloadLen = 0; + CmdExt.RxPayloadLen = *pConfigLen; + CmdExt.pTxPayload = NULL; + CmdExt.pRxPayload = (_u8 *)pValues; + CmdExt.ActualRxPayloadLen = 0; + + Msg.Cmd.DeviceSetId = DeviceGetId; + + Msg.Cmd.Option = (_u16)*pOption; + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlDeviceGetCmdCtrl, &Msg, &CmdExt)); + + if( pOption ) + { + *pOption = (_u8)Msg.Rsp.Option; + } + + if (CmdExt.RxPayloadLen < CmdExt.ActualRxPayloadLen) + { + *pConfigLen = (_u8)CmdExt.RxPayloadLen; + return SL_ESMALLBUF; + } + else + { + *pConfigLen = (_u8)CmdExt.ActualRxPayloadLen; + } + + return (_i16)Msg.Rsp.Status; + } + else + { + return -1; + } +} +#endif + +/****************************************************************************** +sl_DevSet +******************************************************************************/ +typedef union +{ + _DeviceSetGet_t Cmd; + _BasicResponse_t Rsp; +}_SlDeviceMsgSet_u; + +const _SlCmdCtrl_t _SlDeviceSetCmdCtrl = +{ + SL_OPCODE_DEVICE_DEVICESET, + sizeof(_DeviceSetGet_t), + sizeof(_BasicResponse_t) +}; + +#if _SL_INCLUDE_FUNC(sl_DevSet) +_i32 sl_DevSet(_u8 DeviceSetId ,_u8 Option,_u8 ConfigLen, _u8 *pValues) +{ + _SlDeviceMsgSet_u Msg; + _SlCmdExt_t CmdExt; + + CmdExt.TxPayloadLen = (ConfigLen+3) & (~3); + CmdExt.RxPayloadLen = 0; + CmdExt.pTxPayload = (_u8 *)pValues; + CmdExt.pRxPayload = NULL; + + + Msg.Cmd.DeviceSetId = DeviceSetId; + Msg.Cmd.ConfigLen = ConfigLen; + Msg.Cmd.Option = Option; + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlDeviceSetCmdCtrl, &Msg, &CmdExt)); + + return (_i16)Msg.Rsp.status; +} +#endif + + +/****************************************************************************** +_SlDrvDeviceEventHandler - handles internally device async events +******************************************************************************/ +void _SlDrvDeviceEventHandler(void *pArgs) +{ + _SlResponseHeader_t *pHdr = (_SlResponseHeader_t *)pArgs; + + switch(pHdr->GenHeader.Opcode) + { + case SL_OPCODE_DEVICE_INITCOMPLETE: + _sl_HandleAsync_InitComplete(pHdr); + break; + case SL_OPCODE_DEVICE_STOP_ASYNC_RESPONSE: + _sl_HandleAsync_Stop(pHdr); + break; + case SL_OPCODE_DEVICE_DEVICEASYNCFATALERROR: +#ifdef sl_GeneralEvtHdlr + { + _BasicResponse_t *pMsgArgs = (_BasicResponse_t *)_SL_RESP_ARGS_START(pHdr); + SlDeviceEvent_t devHandler; + devHandler.Event = SL_DEVICE_FATAL_ERROR_EVENT; + devHandler.EventData.deviceEvent.status = pMsgArgs->status & 0xFF; + devHandler.EventData.deviceEvent.sender = (SlErrorSender_e)((pMsgArgs->status >> 8) & 0xFF); + sl_GeneralEvtHdlr(&devHandler); + } +#endif + break; + default: + SL_ERROR_TRACE1(MSG_306, "ASSERT: _SlDrvDeviceEventHandler : invalid opcode = 0x%x", pHdr->GenHeader.Opcode); + VERIFY_PROTOCOL(0); + } +} + + +/****************************************************************************** +sl_UartSetMode +******************************************************************************/ +#ifdef SL_IF_TYPE_UART +typedef union +{ + _DevUartSetModeCommand_t Cmd; + _DevUartSetModeResponse_t Rsp; +}_SlUartSetModeMsg_u; + +const _SlCmdCtrl_t _SlUartSetModeCmdCtrl = +{ + SL_OPCODE_DEVICE_SETUARTMODECOMMAND, + sizeof(_DevUartSetModeCommand_t), + sizeof(_DevUartSetModeResponse_t) +}; + + +#if _SL_INCLUDE_FUNC(sl_UartSetMode) +_i16 sl_UartSetMode(const SlUartIfParams_t* pUartParams) +{ + _SlUartSetModeMsg_u Msg; + _u32 magicCode = 0xFFFFFFFF; + + Msg.Cmd.BaudRate = pUartParams->BaudRate; + Msg.Cmd.FlowControlEnable = pUartParams->FlowControlEnable; + + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlUartSetModeCmdCtrl, &Msg, NULL)); + + /* cmd response OK, we can continue with the handshake */ + if (SL_RET_CODE_OK == Msg.Rsp.status) + { + sl_IfMaskIntHdlr(); + + /* Close the comm port */ + sl_IfClose(g_pCB->FD); + + /* Re-open the comm port */ + sl_IfOpen((void * )pUartParams, UART_IF_OPEN_FLAG_RE_OPEN); + + sl_IfUnMaskIntHdlr(); + + /* send the magic code and wait for the response */ + sl_IfWrite(g_pCB->FD, (_u8* )&magicCode, 4); + + magicCode = UART_SET_MODE_MAGIC_CODE; + sl_IfWrite(g_pCB->FD, (_u8* )&magicCode, 4); + + /* clear magic code */ + magicCode = 0; + + /* wait (blocking) till the magic code to be returned from device */ + sl_IfRead(g_pCB->FD, (_u8* )&magicCode, 4); + + /* check for the received magic code matching */ + if (UART_SET_MODE_MAGIC_CODE != magicCode) + { + _SL_ASSERT(0); + } + } + + return (_i16)Msg.Rsp.status; +} +#endif +#endif + + diff --git a/cc3200/simplelink/source/driver.c b/cc3200/simplelink/source/driver.c new file mode 100644 index 000000000..fe6bf5252 --- /dev/null +++ b/cc3200/simplelink/source/driver.c @@ -0,0 +1,1520 @@ +/* +* driver.c - CC31xx/CC32xx Host Driver Implementation +* +* Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the +* distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +*/ + +/*****************************************************************************/ +/* Include files */ +/*****************************************************************************/ +#include "simplelink.h" +#include "protocol.h" +#include "driver.h" +#include "flowcont.h" + +/*****************************************************************************/ +/* Macro declarations */ +/*****************************************************************************/ + +#define _SL_PENDING_RX_MSG(pDriverCB) ((pDriverCB)->RxIrqCnt != (pDriverCB)->RxDoneCnt) + +/* 2 LSB of the N2H_SYNC_PATTERN are for sequence number +only in SPI interface +support backward sync pattern */ +#define N2H_SYNC_PATTERN_SEQ_NUM_BITS ((_u32)0x00000003) /* Bits 0..1 - use the 2 LBS for seq num */ +#define N2H_SYNC_PATTERN_SEQ_NUM_EXISTS ((_u32)0x00000004) /* Bit 2 - sign that sequence number exists in the sync pattern */ +#define N2H_SYNC_PATTERN_MASK ((_u32)0xFFFFFFF8) /* Bits 3..31 - constant SYNC PATTERN */ +#define N2H_SYNC_SPI_BUGS_MASK ((_u32)0x7FFF7F7F) /* Bits 7,15,31 - ignore the SPI (8,16,32 bites bus) error bits */ +#define BUF_SYNC_SPIM(pBuf) ((*(_u32 *)(pBuf)) & N2H_SYNC_SPI_BUGS_MASK) +#define N2H_SYNC_SPIM (N2H_SYNC_PATTERN & N2H_SYNC_SPI_BUGS_MASK) +#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))) +#define MATCH_WOUT_SEQ_NUM(pBuf) ( BUF_SYNC_SPIM(pBuf) == N2H_SYNC_SPIM ) +#define MATCH_WITH_SEQ_NUM(pBuf, TxSeqNum) ( BUF_SYNC_SPIM(pBuf) == (N2H_SYNC_SPIM_WITH_SEQ(TxSeqNum)) ) +#define N2H_SYNC_PATTERN_MATCH(pBuf, TxSeqNum) \ + ( \ + ( (*((_u32 *)pBuf) & N2H_SYNC_PATTERN_SEQ_NUM_EXISTS) && ( MATCH_WITH_SEQ_NUM(pBuf, TxSeqNum) ) ) || \ + ( !(*((_u32 *)pBuf) & N2H_SYNC_PATTERN_SEQ_NUM_EXISTS) && ( MATCH_WOUT_SEQ_NUM(pBuf ) ) ) \ + ) + +#define OPCODE(_ptr) (((_SlResponseHeader_t *)(_ptr))->GenHeader.Opcode) +#define RSP_PAYLOAD_LEN(_ptr) (((_SlResponseHeader_t *)(_ptr))->GenHeader.Len - _SL_RESP_SPEC_HDR_SIZE) +#define SD(_ptr) (((_SocketAddrResponse_u *)(_ptr))->IpV4.sd) +/* Actual size of Recv/Recvfrom response data */ +#define ACT_DATA_SIZE(_ptr) (((_SocketAddrResponse_u *)(_ptr))->IpV4.statusOrLen) + +#if (SL_MEMORY_MGMT == SL_MEMORY_MGMT_STATIC) +typedef struct +{ + _u32 Align; + _SlDriverCb_t DriverCB; + _u8 AsyncRespBuf[SL_ASYNC_MAX_MSG_LEN]; +}_SlStatMem_t; + +_SlStatMem_t g_StatMem; +#endif + +/*****************************************************************************/ +/* Variables */ +/*****************************************************************************/ +const _SlSyncPattern_t g_H2NSyncPattern = H2N_SYNC_PATTERN; +const _SlSyncPattern_t g_H2NCnysPattern = H2N_CNYS_PATTERN; +const _SlActionLookup_t _SlActionLookupTable[7] = +{ + {ACCEPT_ID, SL_OPCODE_SOCKET_ACCEPTASYNCRESPONSE, (_SlSpawnEntryFunc_t)_sl_HandleAsync_Accept}, + {CONNECT_ID, SL_OPCODE_SOCKET_CONNECTASYNCRESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_Connect}, + {SELECT_ID, SL_OPCODE_SOCKET_SELECTASYNCRESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_Select}, + {GETHOSYBYNAME_ID, SL_OPCODE_NETAPP_DNSGETHOSTBYNAMEASYNCRESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_DnsGetHostByName}, + {GETHOSYBYSERVICE_ID, SL_OPCODE_NETAPP_MDNSGETHOSTBYSERVICEASYNCRESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_DnsGetHostByService}, + {PING_ID, SL_OPCODE_NETAPP_PINGREPORTREQUESTRESPONSE, (_SlSpawnEntryFunc_t)_sl_HandleAsync_PingResponse}, + {START_STOP_ID, SL_OPCODE_DEVICE_STOP_ASYNC_RESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_Stop} + +}; + +_SlDriverCb_t* g_pCB = NULL; +P_SL_DEV_PING_CALLBACK pPingCallBackFunc = NULL; +_u8 gFirstCmdMode = 0; + +/*****************************************************************************/ +/* Function prototypes */ +/*****************************************************************************/ +_SlReturnVal_t _SlDrvMsgRead(void); +_SlReturnVal_t _SlDrvMsgWrite(void); +_SlReturnVal_t _SlDrvMsgReadCmdCtx(void); +_SlReturnVal_t _SlDrvMsgReadSpawnCtx(void *pValue); +void _SlDrvClassifyRxMsg(_SlOpcode_t Opcode ); +_SlReturnVal_t _SlDrvRxHdrRead(_u8 *pBuf, _u8 *pAlignSize); +void _SlDrvShiftDWord(_u8 *pBuf); +void _SlDrvDriverCBInit(void); +void _SlAsyncEventGenericHandler(void); +_i16 _SlDrvWaitForPoolObj(_u32 ActionID, _u8 SocketID); +void _SlDrvReleasePoolObj(_u8 pObj); +void _SlDrvObjInit(void); +void _SlDrvObjDeInit(void); +void _SlRemoveFromList(_u8* ListIndex, _u8 ItemIndex); +_SlReturnVal_t _SlFindAndSetActiveObj(_SlOpcode_t Opcode, _u8 Sd); + + +/*****************************************************************************/ +/* Internal functions */ +/*****************************************************************************/ + + + +/***************************************************************************** +_SlDrvDriverCBInit - init Driver Control Block +*****************************************************************************/ +void _SlDrvDriverCBInit(void) +{ + _u8 Idx; + +#if (SL_MEMORY_MGMT == SL_MEMORY_MGMT_STATIC) + g_pCB = &(g_StatMem.DriverCB); +#else + g_pCB = sl_Malloc(sizeof(_SlDriverCb_t)); +#endif + MALLOC_OK_CHECK(g_pCB); + + sl_Memset((g_pCB), 0, sizeof(_SlDriverCb_t)); + + OSI_RET_OK_CHECK( sl_SyncObjCreate(&g_pCB->CmdSyncObj, "CmdSyncObj") ); + sl_SyncObjClear(&g_pCB->CmdSyncObj); + + OSI_RET_OK_CHECK( sl_LockObjCreate(&g_pCB->GlobalLockObj, "GlobalLockObj") ); + + OSI_RET_OK_CHECK( sl_LockObjCreate(&g_pCB->ProtectionLockObj, "ProtectionLockObj") ); + + _SlDrvObjInit(); + + for (Idx = 0; Idx < MAX_CONCURRENT_ACTIONS; Idx++) + { + OSI_RET_OK_CHECK( sl_SyncObjCreate(&g_pCB->ObjPool[Idx].SyncObj, "SyncObj") ); + sl_SyncObjClear(&g_pCB->ObjPool[Idx].SyncObj); + } + _SlDrvFlowContInit(); + gFirstCmdMode = 0; +} + +/***************************************************************************** +_SlDrvDriverCBDeinit - De init Driver Control Block +*****************************************************************************/ +void _SlDrvDriverCBDeinit() +{ + _u8 Idx; + + _SlDrvFlowContDeinit(); + + OSI_RET_OK_CHECK( sl_SyncObjDelete(&g_pCB->CmdSyncObj) ); + + OSI_RET_OK_CHECK( sl_LockObjDelete(&g_pCB->GlobalLockObj) ); + + OSI_RET_OK_CHECK( sl_LockObjDelete(&g_pCB->ProtectionLockObj) ); + for (Idx = 0; Idx < MAX_CONCURRENT_ACTIONS; Idx++) + { + OSI_RET_OK_CHECK( sl_SyncObjDelete(&g_pCB->ObjPool[Idx].SyncObj) ); + } + + _SlDrvObjDeInit(); + +#if (SL_MEMORY_MGMT == SL_MEMORY_MGMT_STATIC) + g_pCB = NULL; +#else + sl_Free(g_pCB); +#endif + + g_pCB = NULL; +} + +/***************************************************************************** +_SlDrvRxIrqHandler - Interrupt handler +*****************************************************************************/ +void _SlDrvRxIrqHandler(void *pValue) +{ + sl_IfMaskIntHdlr(); + + g_pCB->RxIrqCnt++; + + if (TRUE == g_pCB->IsCmdRespWaited) + { + OSI_RET_OK_CHECK( sl_SyncObjSignalFromIRQ(&g_pCB->CmdSyncObj) ); + } + else + { + sl_Spawn((_SlSpawnEntryFunc_t)_SlDrvMsgReadSpawnCtx, NULL, 0); + } +} + +/***************************************************************************** +_SlDrvCmdOp +*****************************************************************************/ +_SlReturnVal_t _SlDrvCmdOp( + _SlCmdCtrl_t *pCmdCtrl , + void *pTxRxDescBuff , + _SlCmdExt_t *pCmdExt) +{ + _SlReturnVal_t RetVal; + + OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->GlobalLockObj, SL_OS_WAIT_FOREVER)); + g_pCB->IsCmdRespWaited = TRUE; + + SL_TRACE0(DBG_MSG, MSG_312, "_SlDrvCmdOp: call _SlDrvMsgWrite"); + /* send the message */ + g_pCB->FunctionParams.pCmdCtrl = pCmdCtrl; + g_pCB->FunctionParams.pTxRxDescBuff = pTxRxDescBuff; + g_pCB->FunctionParams.pCmdExt = pCmdExt; + + RetVal = _SlDrvMsgWrite(); + + if(SL_OS_RET_CODE_OK == RetVal) + { + +#ifndef SL_IF_TYPE_UART + /* Waiting for SPI to stabilize after first command */ + if( 0 == gFirstCmdMode ) + { + volatile _u32 CountVal = 0; + gFirstCmdMode = 1; + CountVal = CPU_FREQ_IN_MHZ*USEC_DELAY; + while( CountVal-- ); + } +#endif + /* wait for respond */ + RetVal = _SlDrvMsgReadCmdCtx(); /* will free global lock */ + SL_TRACE0(DBG_MSG, MSG_314, "_SlDrvCmdOp: exited _SlDrvMsgReadCmdCtx"); + + } + else + { + OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->GlobalLockObj)); + } + + return RetVal; +} + +/***************************************************************************** +_SlDrvCmdSend +Send SL command without waiting for command response +This function is unprotected and the caller should make +sure global lock is active +*****************************************************************************/ +_SlReturnVal_t _SlDrvCmdSend( + _SlCmdCtrl_t *pCmdCtrl , + void *pTxRxDescBuff , + _SlCmdExt_t *pCmdExt) +{ + _SlReturnVal_t RetVal; + + g_pCB->IsCmdRespWaited = FALSE; + + SL_TRACE0(DBG_MSG, MSG_312, "_SlDrvCmdSend: call _SlDrvMsgWrite"); + /* send the message */ + g_pCB->FunctionParams.pCmdCtrl = pCmdCtrl; + g_pCB->FunctionParams.pTxRxDescBuff = pTxRxDescBuff; + g_pCB->FunctionParams.pCmdExt = pCmdExt; + + RetVal = _SlDrvMsgWrite(); + + return RetVal; +} + +/***************************************************************************** +_SlDrvDataReadOp +*****************************************************************************/ +_SlReturnVal_t _SlDrvDataReadOp( + _SlSd_t Sd, + _SlCmdCtrl_t *pCmdCtrl , + void *pTxRxDescBuff , + _SlCmdExt_t *pCmdExt) +{ + _SlReturnVal_t RetVal; + _u8 ObjIdx = MAX_CONCURRENT_ACTIONS; + _SlArgsData_t pArgsData; + + /* Validate input arguments */ + VERIFY_PROTOCOL(NULL != pCmdExt->pRxPayload); + + /* If zero bytes is requested, return error. */ + /* This allows us not to fill remote socket's IP address in return arguments */ + VERIFY_PROTOCOL(0 != pCmdExt->RxPayloadLen); + + /* Validate socket */ + if((Sd & BSD_SOCKET_ID_MASK) >= SL_MAX_SOCKETS) + { + return SL_EBADF; + } + + /*Use Obj to issue the command, if not available try later*/ + ObjIdx = (_u8)_SlDrvWaitForPoolObj(RECV_ID, Sd & BSD_SOCKET_ID_MASK); + + if (MAX_CONCURRENT_ACTIONS == ObjIdx) + { + return SL_POOL_IS_EMPTY; + } + + OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); + + pArgsData.pData = pCmdExt->pRxPayload; + pArgsData.pArgs = (_u8 *)pTxRxDescBuff; + g_pCB->ObjPool[ObjIdx].pRespArgs = (_u8 *)&pArgsData; + OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); + + + /* Do Flow Control check/update for DataWrite operation */ + OSI_RET_OK_CHECK( sl_LockObjLock(&g_pCB->FlowContCB.TxLockObj, SL_OS_WAIT_FOREVER) ); + + /* Clear SyncObj for the case it was signalled before TxPoolCnt */ + /* dropped below '1' (last Data buffer was taken) */ + /* OSI_RET_OK_CHECK( sl_SyncObjClear(&g_pCB->FlowContCB.TxSyncObj) ); */ + sl_SyncObjClear(&g_pCB->FlowContCB.TxSyncObj); + + if(g_pCB->FlowContCB.TxPoolCnt <= FLOW_CONT_MIN) + { + + /* If TxPoolCnt was increased by other thread at this moment, + TxSyncObj won't wait here */ + OSI_RET_OK_CHECK( sl_SyncObjWait(&g_pCB->FlowContCB.TxSyncObj, SL_OS_WAIT_FOREVER) ); + } + + OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->GlobalLockObj, SL_OS_WAIT_FOREVER)); + + VERIFY_PROTOCOL(g_pCB->FlowContCB.TxPoolCnt > FLOW_CONT_MIN); + g_pCB->FlowContCB.TxPoolCnt--; + + OSI_RET_OK_CHECK( sl_LockObjUnlock(&g_pCB->FlowContCB.TxLockObj) ); + + /* send the message */ + g_pCB->TempProtocolHeader.Opcode = pCmdCtrl->Opcode; + g_pCB->TempProtocolHeader.Len = _SL_PROTOCOL_CALC_LEN(pCmdCtrl,pCmdExt); + g_pCB->FunctionParams.pCmdCtrl = pCmdCtrl; + g_pCB->FunctionParams.pTxRxDescBuff = (_u8 *)pTxRxDescBuff; + g_pCB->FunctionParams.pCmdExt = pCmdExt; + RetVal = _SlDrvMsgWrite(); + + OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->GlobalLockObj)); + + if(SL_OS_RET_CODE_OK == RetVal) + { + /* Wait for response message. Will be signalled by _SlDrvMsgRead. */ + OSI_RET_OK_CHECK(sl_SyncObjWait(&g_pCB->ObjPool[ObjIdx].SyncObj, SL_OS_WAIT_FOREVER)); + } + + _SlDrvReleasePoolObj(ObjIdx); + return RetVal; +} + +/* ******************************************************************************/ +/* _SlDrvDataWriteOp */ +/* ******************************************************************************/ +_SlReturnVal_t _SlDrvDataWriteOp( + _SlSd_t Sd, + _SlCmdCtrl_t *pCmdCtrl , + void *pTxRxDescBuff , + _SlCmdExt_t *pCmdExt) +{ + _SlReturnVal_t RetVal = SL_EAGAIN; /* initiated as SL_EAGAIN for the non blocking mode */ + while( 1 ) + { + /* Do Flow Control check/update for DataWrite operation */ + OSI_RET_OK_CHECK( sl_LockObjLock(&g_pCB->FlowContCB.TxLockObj, SL_OS_WAIT_FOREVER) ); + + /* Clear SyncObj for the case it was signalled before TxPoolCnt */ + /* dropped below '1' (last Data buffer was taken) */ + /* OSI_RET_OK_CHECK( sl_SyncObjClear(&g_pCB->FlowContCB.TxSyncObj) ); */ + sl_SyncObjClear(&g_pCB->FlowContCB.TxSyncObj); + + /* we have indication that the last send has failed - socket is no longer valid for operations */ + if(g_pCB->SocketTXFailure & (1<<(Sd & BSD_SOCKET_ID_MASK))) + { + OSI_RET_OK_CHECK( sl_LockObjUnlock(&g_pCB->FlowContCB.TxLockObj) ); + return SL_SOC_ERROR; + } + if(g_pCB->FlowContCB.TxPoolCnt <= FLOW_CONT_MIN + 1) + { + /* we have indication that this socket is set as blocking and we try to */ + /* unblock it - return an error */ + if( g_pCB->SocketNonBlocking >> (Sd & BSD_SOCKET_ID_MASK) ) + { + OSI_RET_OK_CHECK( sl_LockObjUnlock(&g_pCB->FlowContCB.TxLockObj) ); + return RetVal; + } + /* If TxPoolCnt was increased by other thread at this moment, */ + /* TxSyncObj won't wait here */ + OSI_RET_OK_CHECK( sl_SyncObjWait(&g_pCB->FlowContCB.TxSyncObj, SL_OS_WAIT_FOREVER) ); + } + if(g_pCB->FlowContCB.TxPoolCnt > FLOW_CONT_MIN + 1 ) + { + break; + } + else + { + OSI_RET_OK_CHECK( sl_LockObjUnlock(&g_pCB->FlowContCB.TxLockObj) ); + } + } + OSI_RET_OK_CHECK( sl_LockObjLock(&g_pCB->GlobalLockObj, SL_OS_WAIT_FOREVER) ); + + VERIFY_PROTOCOL(g_pCB->FlowContCB.TxPoolCnt > FLOW_CONT_MIN + 1 ); + g_pCB->FlowContCB.TxPoolCnt--; + + OSI_RET_OK_CHECK( sl_LockObjUnlock(&g_pCB->FlowContCB.TxLockObj) ); + + /* send the message */ + g_pCB->TempProtocolHeader.Opcode = pCmdCtrl->Opcode; + g_pCB->TempProtocolHeader.Len = _SL_PROTOCOL_CALC_LEN(pCmdCtrl,pCmdExt); + + g_pCB->FunctionParams.pCmdCtrl = pCmdCtrl; + g_pCB->FunctionParams.pTxRxDescBuff = pTxRxDescBuff; + g_pCB->FunctionParams.pCmdExt = pCmdExt; + RetVal = _SlDrvMsgWrite(); + + OSI_RET_OK_CHECK( sl_LockObjUnlock(&g_pCB->GlobalLockObj) ); + + return RetVal; +} + +/* ******************************************************************************/ +/* _SlDrvMsgWrite */ +/* ******************************************************************************/ +_SlReturnVal_t _SlDrvMsgWrite(void) +{ + VERIFY_PROTOCOL(NULL != g_pCB->FunctionParams.pCmdCtrl); + + g_pCB->TempProtocolHeader.Opcode = g_pCB->FunctionParams.pCmdCtrl->Opcode; + g_pCB->TempProtocolHeader.Len = _SL_PROTOCOL_CALC_LEN(g_pCB->FunctionParams.pCmdCtrl, + g_pCB->FunctionParams.pCmdExt); + /* */ + if (g_pCB->RelayFlagsViaRxPayload == TRUE) + { + g_pCB->TempProtocolHeader.Len = g_pCB->TempProtocolHeader.Len + g_pCB->FunctionParams.pCmdExt->RxPayloadLen; + } + +#ifdef SL_START_WRITE_STAT + sl_IfStartWriteSequence(g_pCB->FD); +#endif + +#ifdef SL_IF_TYPE_UART + /* Write long sync pattern */ + NWP_IF_WRITE_CHECK(g_pCB->FD, (_u8 *)&g_H2NSyncPattern.Long, 2*SYNC_PATTERN_LEN); +#else + /* Write short sync pattern */ + NWP_IF_WRITE_CHECK(g_pCB->FD, (_u8 *)&g_H2NSyncPattern.Short, SYNC_PATTERN_LEN); +#endif + + /* Header */ + NWP_IF_WRITE_CHECK(g_pCB->FD, (_u8 *)&g_pCB->TempProtocolHeader, _SL_CMD_HDR_SIZE); + + /* Descriptors */ + if (g_pCB->FunctionParams.pTxRxDescBuff && g_pCB->FunctionParams.pCmdCtrl->TxDescLen > 0) + { + NWP_IF_WRITE_CHECK(g_pCB->FD, g_pCB->FunctionParams.pTxRxDescBuff, + _SL_PROTOCOL_ALIGN_SIZE(g_pCB->FunctionParams.pCmdCtrl->TxDescLen)); + } + + /* A special mode where Rx payload and Rx length are used as Tx as well */ + /* This mode requires no Rx payload on the response and currently used by fs_Close and sl_Send on */ + /* transceiver mode */ + if (g_pCB->RelayFlagsViaRxPayload == TRUE ) + { + g_pCB->RelayFlagsViaRxPayload = FALSE; + NWP_IF_WRITE_CHECK(g_pCB->FD, g_pCB->FunctionParams.pCmdExt->pRxPayload, + _SL_PROTOCOL_ALIGN_SIZE(g_pCB->FunctionParams.pCmdExt->RxPayloadLen)); + } + + /* Payload */ + if (g_pCB->FunctionParams.pCmdExt && g_pCB->FunctionParams.pCmdExt->TxPayloadLen > 0) + { + /* If the message has payload, it is mandatory that the message's arguments are protocol aligned. */ + /* Otherwise the aligning of arguments will create a gap between arguments and payload. */ + VERIFY_PROTOCOL(_SL_IS_PROTOCOL_ALIGNED_SIZE(g_pCB->FunctionParams.pCmdCtrl->TxDescLen)); + + NWP_IF_WRITE_CHECK(g_pCB->FD, g_pCB->FunctionParams.pCmdExt->pTxPayload, + _SL_PROTOCOL_ALIGN_SIZE(g_pCB->FunctionParams.pCmdExt->TxPayloadLen)); + } + + + _SL_DBG_CNT_INC(MsgCnt.Write); + +#ifdef SL_START_WRITE_STAT + sl_IfEndWriteSequence(g_pCB->FD); +#endif + + return SL_OS_RET_CODE_OK; +} + +/* ******************************************************************************/ +/* _SlDrvMsgRead */ +/* ******************************************************************************/ +_SlReturnVal_t _SlDrvMsgRead(void) +{ + /* alignment for small memory models */ + union + { + _u8 TempBuf[_SL_RESP_HDR_SIZE]; + _u32 DummyBuf[2]; + } uBuf; + _u8 TailBuffer[4]; + _u16 LengthToCopy; + _u16 AlignedLengthRecv; + _u8 AlignSize; + + VERIFY_RET_OK(_SlDrvRxHdrRead((_u8*)(uBuf.TempBuf), &AlignSize)); + + /* 'Init Compelete' message bears no valid FlowControl info */ + if(SL_OPCODE_DEVICE_INITCOMPLETE != OPCODE(uBuf.TempBuf)) + { + g_pCB->FlowContCB.TxPoolCnt = ((_SlResponseHeader_t *)uBuf.TempBuf)->TxPoolCnt; + g_pCB->SocketNonBlocking = ((_SlResponseHeader_t *)uBuf.TempBuf)->SocketNonBlocking; + g_pCB->SocketTXFailure = ((_SlResponseHeader_t *)uBuf.TempBuf)->SocketTXFailure; + + if(g_pCB->FlowContCB.TxPoolCnt > FLOW_CONT_MIN) + { + OSI_RET_OK_CHECK(sl_SyncObjSignal(&g_pCB->FlowContCB.TxSyncObj)); + } + } + + _SlDrvClassifyRxMsg(OPCODE(uBuf.TempBuf)); + + switch(g_pCB->FunctionParams.AsyncExt.RxMsgClass) + { + case ASYNC_EVT_CLASS: + + VERIFY_PROTOCOL(NULL == g_pCB->FunctionParams.AsyncExt.pAsyncBuf); + +#if (SL_MEMORY_MGMT == SL_MEMORY_MGMT_STATIC) + g_pCB->FunctionParams.AsyncExt.pAsyncBuf = g_StatMem.AsyncRespBuf; +#else + g_pCB->FunctionParams.AsyncExt.pAsyncBuf = sl_Malloc(SL_ASYNC_MAX_MSG_LEN); +#endif + MALLOC_OK_CHECK(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); + + sl_Memcpy(g_pCB->FunctionParams.AsyncExt.pAsyncBuf, uBuf.TempBuf, _SL_RESP_HDR_SIZE); + + /* This is an Async message. Read the rest of it. */ + if (_SL_PROTOCOL_ALIGN_SIZE(RSP_PAYLOAD_LEN(uBuf.TempBuf)) <= SL_ASYNC_MAX_PAYLOAD_LEN) + { + AlignedLengthRecv = _SL_PROTOCOL_ALIGN_SIZE(RSP_PAYLOAD_LEN(uBuf.TempBuf)); + } + else + { + AlignedLengthRecv = _SL_PROTOCOL_ALIGN_SIZE(SL_ASYNC_MAX_PAYLOAD_LEN); + } + + if (RSP_PAYLOAD_LEN(uBuf.TempBuf) > 0) + { + NWP_IF_READ_CHECK(g_pCB->FD, + g_pCB->FunctionParams.AsyncExt.pAsyncBuf + _SL_RESP_HDR_SIZE, + AlignedLengthRecv); + } + /* In case ASYNC RX buffer length is smaller then the received data length, dump the rest */ + if ((_SL_PROTOCOL_ALIGN_SIZE(RSP_PAYLOAD_LEN(uBuf.TempBuf)) > SL_ASYNC_MAX_PAYLOAD_LEN)) + { + AlignedLengthRecv = _SL_PROTOCOL_ALIGN_SIZE(RSP_PAYLOAD_LEN(uBuf.TempBuf)) - SL_ASYNC_MAX_PAYLOAD_LEN; + while (AlignedLengthRecv > 0) + { + NWP_IF_READ_CHECK(g_pCB->FD,TailBuffer,4); + AlignedLengthRecv = AlignedLengthRecv - 4; + } + } + OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); + + if ((SL_OPCODE_SOCKET_ACCEPTASYNCRESPONSE == OPCODE(uBuf.TempBuf)) || (SL_OPCODE_SOCKET_ACCEPTASYNCRESPONSE_V6 == OPCODE(uBuf.TempBuf)) || (SL_OPCODE_SOCKET_CONNECTASYNCRESPONSE == OPCODE(uBuf.TempBuf))) + { + /* go over the active list if exist to find obj waiting for this Async event */ + _SlFindAndSetActiveObj(OPCODE(uBuf.TempBuf),(((_SocketResponse_t *)(g_pCB->FunctionParams.AsyncExt.pAsyncBuf + _SL_RESP_HDR_SIZE))->sd) & BSD_SOCKET_ID_MASK); + } + else + { + _SlFindAndSetActiveObj(OPCODE(uBuf.TempBuf),SL_MAX_SOCKETS); + } + OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); + + break; + + case RECV_RESP_CLASS: + { + _u8 ExpArgSize; /* Expected size of Recv/Recvfrom arguments */ + + switch(OPCODE(uBuf.TempBuf)) + { + case SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE: + ExpArgSize = RECVFROM_IPV4_ARGS_SIZE; + break; + case SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE_V6: + ExpArgSize = RECVFROM_IPV6_ARGS_SIZE; + break; + default: + /* SL_OPCODE_SOCKET_RECVASYNCRESPONSE: */ + ExpArgSize = RECV_ARGS_SIZE; + } + + /* Read first 4 bytes of Recv/Recvfrom response to get SocketId and actual */ + /* response data length */ + NWP_IF_READ_CHECK(g_pCB->FD, &uBuf.TempBuf[4], RECV_ARGS_SIZE); + + /* Validate Socket ID and Received Length value. */ + VERIFY_PROTOCOL((SD(&uBuf.TempBuf[4])& BSD_SOCKET_ID_MASK) < SL_MAX_SOCKETS); + + OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); + + /* go over the active list if exist to find obj waiting for this Async event */ + VERIFY_RET_OK(_SlFindAndSetActiveObj(OPCODE(uBuf.TempBuf),SD(&uBuf.TempBuf[4]) & BSD_SOCKET_ID_MASK)); + + /* Verify data is waited on this socket. The pArgs should have been set by _SlDrvDataReadOp(). */ + VERIFY_SOCKET_CB(NULL != ((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pData))->pArgs); + + sl_Memcpy( ((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pArgs, &uBuf.TempBuf[4], RECV_ARGS_SIZE); + + if(ExpArgSize > RECV_ARGS_SIZE) + { + NWP_IF_READ_CHECK(g_pCB->FD, + ((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pArgs + RECV_ARGS_SIZE, + ExpArgSize - RECV_ARGS_SIZE); + } + + /* Here g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pData contains requested(expected) Recv/Recvfrom DataSize. */ + /* Overwrite requested DataSize with actual one. */ + /* If error is received, this information will be read from arguments. */ + if(ACT_DATA_SIZE(&uBuf.TempBuf[4]) > 0) + { + VERIFY_SOCKET_CB(NULL != ((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pData); + + /* Read 4 bytes aligned from interface */ + /* therefore check the requested length and read only */ + /* 4 bytes aligned data. The rest unaligned (if any) will be read */ + /* and copied to a TailBuffer */ + LengthToCopy = ACT_DATA_SIZE(&uBuf.TempBuf[4]) & (3); + AlignedLengthRecv = ACT_DATA_SIZE(&uBuf.TempBuf[4]) & (~3); + if( AlignedLengthRecv >= 4) + { + NWP_IF_READ_CHECK(g_pCB->FD,((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pData,AlignedLengthRecv ); + } + /* copy the unaligned part, if any */ + if( LengthToCopy > 0) + { + NWP_IF_READ_CHECK(g_pCB->FD,TailBuffer,4); + /* copy TailBuffer unaligned part (1/2/3 bytes) */ + sl_Memcpy(((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pData + AlignedLengthRecv,TailBuffer,LengthToCopy); + } + } + OSI_RET_OK_CHECK(sl_SyncObjSignal(&(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj))); + OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); + } + break; + + case CMD_RESP_CLASS: + + /* Some commands pass a maximum arguments size. */ + /* In this case Driver will send extra dummy patterns to NWP if */ + /* the response message is smaller than maximum. */ + /* When RxDescLen is not exact, using RxPayloadLen is forbidden! */ + /* If such case cannot be avoided - parse message here to detect */ + /* arguments/payload border. */ + NWP_IF_READ_CHECK(g_pCB->FD, + g_pCB->FunctionParams.pTxRxDescBuff, + _SL_PROTOCOL_ALIGN_SIZE(g_pCB->FunctionParams.pCmdCtrl->RxDescLen)); + + if((NULL != g_pCB->FunctionParams.pCmdExt) && (0 != g_pCB->FunctionParams.pCmdExt->RxPayloadLen)) + { + /* Actual size of command's response payload: <msg_payload_len> - <rsp_args_len> */ + _i16 ActDataSize = RSP_PAYLOAD_LEN(uBuf.TempBuf) - g_pCB->FunctionParams.pCmdCtrl->RxDescLen; + + g_pCB->FunctionParams.pCmdExt->ActualRxPayloadLen = ActDataSize; + + /* Check that the space prepared by user for the response data is sufficient. */ + if(ActDataSize <= 0) + { + g_pCB->FunctionParams.pCmdExt->RxPayloadLen = 0; + } + else + { + /* In case the user supplied Rx buffer length which is smaller then the received data length, copy according to user length */ + if (ActDataSize > g_pCB->FunctionParams.pCmdExt->RxPayloadLen) + { + LengthToCopy = g_pCB->FunctionParams.pCmdExt->RxPayloadLen & (3); + AlignedLengthRecv = g_pCB->FunctionParams.pCmdExt->RxPayloadLen & (~3); + } + else + { + LengthToCopy = ActDataSize & (3); + AlignedLengthRecv = ActDataSize & (~3); + } + /* Read 4 bytes aligned from interface */ + /* therefore check the requested length and read only */ + /* 4 bytes aligned data. The rest unaligned (if any) will be read */ + /* and copied to a TailBuffer */ + + if( AlignedLengthRecv >= 4) + { + NWP_IF_READ_CHECK(g_pCB->FD, + g_pCB->FunctionParams.pCmdExt->pRxPayload, + AlignedLengthRecv ); + + } + /* copy the unaligned part, if any */ + if( LengthToCopy > 0) + { + NWP_IF_READ_CHECK(g_pCB->FD,TailBuffer,4); + /* copy TailBuffer unaligned part (1/2/3 bytes) */ + sl_Memcpy(g_pCB->FunctionParams.pCmdExt->pRxPayload + AlignedLengthRecv, + TailBuffer, + LengthToCopy); + ActDataSize = ActDataSize-4; + } + /* In case the user supplied Rx buffer length which is smaller then the received data length, dump the rest */ + if (ActDataSize > g_pCB->FunctionParams.pCmdExt->RxPayloadLen) + { + /* calculate the rest of the data size to dump */ + AlignedLengthRecv = ActDataSize - (g_pCB->FunctionParams.pCmdExt->RxPayloadLen & (~3)); + while( AlignedLengthRecv > 0) + { + NWP_IF_READ_CHECK(g_pCB->FD,TailBuffer, 4 ); + AlignedLengthRecv = AlignedLengthRecv - 4; + } + } + } + } + break; + + default: + /* DUMMY_MSG_CLASS: Flow control message has no payload. */ + break; + } + + if(AlignSize > 0) + { + NWP_IF_READ_CHECK(g_pCB->FD, uBuf.TempBuf, AlignSize); + } + + _SL_DBG_CNT_INC(MsgCnt.Read); + + /* Unmask Interrupt call */ + sl_IfUnMaskIntHdlr(); + + return SL_OS_RET_CODE_OK; +} + +/* ******************************************************************************/ +/* _SlAsyncEventGenericHandler */ +/* ******************************************************************************/ +void _SlAsyncEventGenericHandler(void) +{ + _SlResponseHeader_t *pHdr = (_SlResponseHeader_t *)g_pCB->FunctionParams.AsyncExt.pAsyncBuf; + SlWlanEvent_t wlanEvent; + SlNetAppEvent_t netAppEvent; + SlSockEvent_t sockAppEvent; + + if (NULL != g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler) + { + switch(pHdr->GenHeader.Opcode) + { + case SL_OPCODE_WLAN_P2P_DEV_FOUND: + { + slPeerInfoAsyncResponse_t* pResp = (slPeerInfoAsyncResponse_t*)_SL_RESP_ARGS_START(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); + wlanEvent.Event = SL_WLAN_P2P_DEV_FOUND_EVENT; + sl_Memcpy(wlanEvent.EventData.P2PModeDevFound.mac,pResp->mac, 6); + sl_Memcpy(wlanEvent.EventData.P2PModeDevFound.go_peer_device_name,pResp->go_peer_device_name,pResp->go_peer_device_name_len); + wlanEvent.EventData.P2PModeDevFound.go_peer_device_name_len = pResp->go_peer_device_name_len; + g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(&wlanEvent); + break; + } + + case SL_OPCODE_WLAN_P2P_NEG_REQ_RECEIVED: + { + slPeerInfoAsyncResponse_t* pResp = (slPeerInfoAsyncResponse_t*)_SL_RESP_ARGS_START(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); + + wlanEvent.Event = SL_WLAN_P2P_NEG_REQ_RECEIVED_EVENT; + sl_Memcpy(wlanEvent.EventData.P2PModeNegReqReceived.mac,pResp->mac, 6); + sl_Memcpy(wlanEvent.EventData.P2PModeNegReqReceived.go_peer_device_name,pResp->go_peer_device_name,pResp->go_peer_device_name_len); + wlanEvent.EventData.P2PModeNegReqReceived.go_peer_device_name_len = pResp->go_peer_device_name_len; + wlanEvent.EventData.P2PModeNegReqReceived.wps_dev_password_id = pResp->wps_dev_password_id; + g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(&wlanEvent); + break; + } + case SL_OPCODE_WLAN_CONNECTION_FAILED: + { + slWlanConnFailureAsyncResponse_t * pResp = (slWlanConnFailureAsyncResponse_t*)_SL_RESP_ARGS_START(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); + + wlanEvent.Event = SL_WLAN_CONNECTION_FAILED_EVENT; + wlanEvent.EventData.P2PModewlanConnectionFailure.status = pResp->status; + + g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(&wlanEvent); + break; + } + + case SL_OPCODE_WLAN_WLANASYNCCONNECTEDRESPONSE: + { + slWlanConnectAsyncResponse_t *pWlanResp = (slWlanConnectAsyncResponse_t*)_SL_RESP_ARGS_START(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); + sl_Memset(&wlanEvent.EventData.STAandP2PModeWlanConnected,0,sizeof(slWlanConnectAsyncResponse_t)); + wlanEvent.Event = SL_WLAN_CONNECT_EVENT; + wlanEvent.EventData.STAandP2PModeWlanConnected.connection_type = pWlanResp->connection_type; + sl_Memcpy(wlanEvent.EventData.STAandP2PModeWlanConnected.bssid, pWlanResp->bssid, 6); + sl_Memcpy(wlanEvent.EventData.STAandP2PModeWlanConnected.go_peer_device_name,pWlanResp->go_peer_device_name,pWlanResp->go_peer_device_name_len); + sl_Memcpy(wlanEvent.EventData.STAandP2PModeWlanConnected.ssid_name, pWlanResp->ssid_name, pWlanResp->ssid_len); + wlanEvent.EventData.STAandP2PModeWlanConnected.ssid_len = pWlanResp->ssid_len; + wlanEvent.EventData.STAandP2PModeWlanConnected.go_peer_device_name_len = pWlanResp->go_peer_device_name_len; + + g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(&wlanEvent); + break; + } + case SL_OPCODE_WLAN_WLANASYNCDISCONNECTEDRESPONSE: + { + slWlanConnectAsyncResponse_t *pWlanResp = (slWlanConnectAsyncResponse_t*)_SL_RESP_ARGS_START(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); + sl_Memset(&wlanEvent.EventData.STAandP2PModeDisconnected,0,sizeof(slWlanConnectAsyncResponse_t)); + wlanEvent.Event = SL_WLAN_DISCONNECT_EVENT; + wlanEvent.EventData.STAandP2PModeDisconnected.connection_type = pWlanResp->connection_type; + sl_Memcpy(wlanEvent.EventData.STAandP2PModeDisconnected.bssid, pWlanResp->bssid, 6); + sl_Memcpy(wlanEvent.EventData.STAandP2PModeDisconnected.go_peer_device_name,pWlanResp->go_peer_device_name,pWlanResp->go_peer_device_name_len); + sl_Memcpy(wlanEvent.EventData.STAandP2PModeDisconnected.ssid_name, pWlanResp->ssid_name, pWlanResp->ssid_len); + wlanEvent.EventData.STAandP2PModeDisconnected.ssid_len = pWlanResp->ssid_len; + wlanEvent.EventData.STAandP2PModeDisconnected.reason_code = pWlanResp->reason_code; + wlanEvent.EventData.STAandP2PModeDisconnected.go_peer_device_name_len = pWlanResp->go_peer_device_name_len; + g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(&wlanEvent); + break; + } + case SL_OPCODE_NETAPP_IPACQUIRED: + { + SlIpV4AcquiredAsync_t *pIpV4 = (SlIpV4AcquiredAsync_t*)_SL_RESP_ARGS_START(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); + netAppEvent.Event = SL_NETAPP_IPV4_IPACQUIRED_EVENT; + netAppEvent.EventData.ipAcquiredV4.ip = pIpV4->ip; + netAppEvent.EventData.ipAcquiredV4.gateway = pIpV4->gateway; + netAppEvent.EventData.ipAcquiredV4.dns = pIpV4->dns; + g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(&netAppEvent); + } + break; + case SL_OPCODE_NETAPP_IPACQUIRED_V6: + { + SlIpV6AcquiredAsync_t *pIpV6 = (SlIpV6AcquiredAsync_t*)_SL_RESP_ARGS_START(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); + netAppEvent.Event = SL_NETAPP_IPV6_IPACQUIRED_EVENT; + sl_Memcpy((void *)&netAppEvent.EventData.ipAcquiredV6.ip[0],(void *)&pIpV6->ip[0],sizeof(pIpV6->ip[0])*4); + g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(&netAppEvent); + } + break; + + case SL_OPCODE_NETAPP_IP_LEASED: + { + SlIpLeasedAsync_t *pIpV4 = (SlIpLeasedAsync_t*)_SL_RESP_ARGS_START(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); + netAppEvent.Event = SL_NETAPP_IP_LEASED_EVENT; + netAppEvent.EventData.ipLeased.ip_address = pIpV4->ip_address; + netAppEvent.EventData.ipLeased.lease_time = pIpV4->lease_time; + sl_Memcpy(netAppEvent.EventData.ipLeased.mac, pIpV4->mac, 6); + + g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(&netAppEvent); + } + break; + + case SL_OPCODE_NETAPP_IP_RELEASED: + { + SlIpReleasedAsync_t *pIpV4 = (SlIpReleasedAsync_t *)_SL_RESP_ARGS_START(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); + netAppEvent.Event = SL_NETAPP_IP_RELEASED_EVENT; + netAppEvent.EventData.ipReleased.ip_address = pIpV4->ip_address; + netAppEvent.EventData.ipReleased.reason = pIpV4->reason; + sl_Memcpy(netAppEvent.EventData.ipReleased.mac, pIpV4->mac, 6); + + g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(&netAppEvent); + } + break; + + case SL_OPCODE_SOCKET_TXFAILEDASYNCRESPONSE: + { + SlSockEventData_t *txfailparams = (SlSockEventData_t*)_SL_RESP_ARGS_START(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); + sockAppEvent.Event = SL_SOCKET_TX_FAILED_EVENT; + sl_Memcpy((void *)&sockAppEvent.EventData,(void *)txfailparams,sizeof(SlSockEventData_t)); + g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(&sockAppEvent); + } + break; + + case SL_OPCODE_SOCKET_SOCKETASYNCEVENT: + { + SlSockEventData_t *socketAsyncEvent = (SlSockEventData_t*)_SL_RESP_ARGS_START(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); + sockAppEvent.Event = SL_SOCKET_ASYNC_EVENT; + sockAppEvent.EventData.socketAsyncEvent.sd = socketAsyncEvent->socketAsyncEvent.sd; + sockAppEvent.EventData.socketAsyncEvent.type = socketAsyncEvent->socketAsyncEvent.type; /* one of the possible types of socket */ + sockAppEvent.EventData.socketAsyncEvent.val = socketAsyncEvent->socketAsyncEvent.val; + g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(&sockAppEvent); + } + break; + + case SL_OPCODE_WLAN_SMART_CONFIG_START_ASYNC_RESPONSE: + { + slSmartConfigStartAsyncResponse_t *pResp = (slSmartConfigStartAsyncResponse_t*)_SL_RESP_ARGS_START(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); + + wlanEvent.Event = SL_WLAN_SMART_CONFIG_COMPLETE_EVENT; + wlanEvent.EventData.smartConfigStartResponse.status = pResp->status; + wlanEvent.EventData.smartConfigStartResponse.ssid_len = pResp->ssid_len; + wlanEvent.EventData.smartConfigStartResponse.private_token_len = pResp->private_token_len; + + sl_Memset(wlanEvent.EventData.smartConfigStartResponse.ssid, 0x00, sizeof(wlanEvent.EventData.smartConfigStartResponse.ssid)); + sl_Memcpy(wlanEvent.EventData.smartConfigStartResponse.ssid, pResp->ssid, pResp->ssid_len); + /* if private data exist */ + if (pResp->private_token_len) + { + sl_Memset(wlanEvent.EventData.smartConfigStartResponse.private_token, 0x00, sizeof(wlanEvent.EventData.smartConfigStartResponse.private_token)); + sl_Memcpy(wlanEvent.EventData.smartConfigStartResponse.private_token, pResp->private_token, pResp->private_token_len); + } + + g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(&wlanEvent); + } + break; + + case SL_OPCODE_WLAN_SMART_CONFIG_STOP_ASYNC_RESPONSE: + { + slSmartConfigStopAsyncResponse_t *pResp = (slSmartConfigStopAsyncResponse_t*)_SL_RESP_ARGS_START(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); + + wlanEvent.Event = SL_WLAN_SMART_CONFIG_STOP_EVENT; + wlanEvent.EventData.smartConfigStopResponse.status = pResp->status; + + g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(&wlanEvent); + } + break; + + case SL_OPCODE_WLAN_STA_CONNECTED: + { + slPeerInfoAsyncResponse_t* pResp = (slPeerInfoAsyncResponse_t*)_SL_RESP_ARGS_START(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); + sl_Memset(&wlanEvent.EventData.APModeStaConnected,0,sizeof(slPeerInfoAsyncResponse_t)); + wlanEvent.Event = SL_WLAN_STA_CONNECTED_EVENT; + sl_Memcpy(wlanEvent.EventData.APModeStaConnected.mac,pResp->mac, 6); + sl_Memcpy(wlanEvent.EventData.APModeStaConnected.go_peer_device_name,pResp->go_peer_device_name,pResp->go_peer_device_name_len); + wlanEvent.EventData.APModeStaConnected.go_peer_device_name_len = pResp->go_peer_device_name_len; + + sl_Memcpy(wlanEvent.EventData.APModeStaConnected.own_ssid,pResp->own_ssid,pResp->own_ssid_len); + wlanEvent.EventData.APModeStaConnected.own_ssid_len = pResp->own_ssid_len; + g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(&wlanEvent); + } + break; + + case SL_OPCODE_WLAN_STA_DISCONNECTED: + { + slPeerInfoAsyncResponse_t* pResp = (slPeerInfoAsyncResponse_t*)_SL_RESP_ARGS_START(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); + sl_Memset(&wlanEvent.EventData.APModestaDisconnected,0,sizeof(slPeerInfoAsyncResponse_t)); + wlanEvent.Event = SL_WLAN_STA_DISCONNECTED_EVENT; + sl_Memcpy(wlanEvent.EventData.APModestaDisconnected.mac,pResp->mac, 6); + sl_Memcpy(wlanEvent.EventData.APModestaDisconnected.go_peer_device_name,pResp->go_peer_device_name,pResp->go_peer_device_name_len); + wlanEvent.EventData.APModestaDisconnected.go_peer_device_name_len = pResp->go_peer_device_name_len; + g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(&wlanEvent); + } + break; + + case SL_OPCODE_NETAPP_PINGREPORTREQUESTRESPONSE: + { + _sl_HandleAsync_PingResponse((void *)g_pCB->FunctionParams.AsyncExt.pAsyncBuf); + } + break; + + + default: + g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); + break; + } + } +} + + +/* ******************************************************************************/ +/* _SlDrvMsgReadCmdCtx */ +/* ******************************************************************************/ +_SlReturnVal_t _SlDrvMsgReadCmdCtx(void) +{ + + /* after command response is received and isCmdRespWaited */ + /* flag is set FALSE, it is necessary to read out all */ + /* Async messages in Commands context, because ssiDma_IsrHandleSignalFromSlave */ + /* could have dispatched some Async messages to g_NwpIf.CmdSyncObj */ + /* after command response but before this response has been processed */ + /* by spi_singleRead and isCmdRespWaited was set FALSE. */ + while (TRUE == g_pCB->IsCmdRespWaited) + { + if(_SL_PENDING_RX_MSG(g_pCB)) + { + g_pCB->FunctionParams.AsyncExt.pAsyncBuf = NULL;/* buffer must be allocated by _SlDrvMsgRead */ + g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler= NULL; + g_pCB->FunctionParams.AsyncExt.RxMsgClass = (_SlRxMsgClass_e)(-1);/* init to illegal value and verify it's overwritten with the valid one */ + + VERIFY_RET_OK(_SlDrvMsgRead()); + g_pCB->RxDoneCnt++; + + if (CMD_RESP_CLASS == g_pCB->FunctionParams.AsyncExt.RxMsgClass) + { + g_pCB->IsCmdRespWaited = FALSE; + + /* In case CmdResp has been read without waiting on CmdSyncObj - that */ + /* Sync object. That to prevent old signal to be processed. */ + sl_SyncObjClear(&g_pCB->CmdSyncObj); + } + else if (ASYNC_EVT_CLASS == g_pCB->FunctionParams.AsyncExt.RxMsgClass) + { + /* If Async event has been read in CmdResp context, check whether */ + /* there is a handler for this event. If there is, spawn specific */ + /* handler. Otherwise free the event's buffer. */ + /* This way there will be no "dry shots" from CmdResp context to */ + /* temporary context, i.e less waste of CPU and faster buffer */ + /* release. */ + _SlAsyncEventGenericHandler(); + +#if (SL_MEMORY_MGMT == SL_MEMORY_MGMT_STATIC) + g_pCB->FunctionParams.AsyncExt.pAsyncBuf = NULL; +#else + sl_Free(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); +#endif + } + } + else + { + /* CmdSyncObj will be signaled by IRQ */ + OSI_RET_OK_CHECK(sl_SyncObjWait(&g_pCB->CmdSyncObj, SL_OS_WAIT_FOREVER)); + } + } + + /* If there are more pending Rx Msgs after CmdResp is received, */ + /* that means that these are Async, Dummy or Read Data Msgs. */ + /* Spawn _SlDrvMsgReadSpawnCtx to trigger reading these messages from */ + /* Temporary context. */ + /* sl_Spawn is activated, using a different context */ + OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->GlobalLockObj)); + if(_SL_PENDING_RX_MSG(g_pCB)) + { + sl_Spawn((_SlSpawnEntryFunc_t)_SlDrvMsgReadSpawnCtx, NULL, 0); + } + + return SL_OS_RET_CODE_OK; +} + +/* ******************************************************************************/ +/* _SlDrvMsgReadSpawnCtx */ +/* ******************************************************************************/ +_SlReturnVal_t _SlDrvMsgReadSpawnCtx(void *pValue) +{ +#ifdef SL_POLLING_MODE_USED + _i16 retCode = OSI_OK; + /* for polling based systems */ + do + { + retCode = sl_LockObjLock(&g_pCB->GlobalLockObj, 0); + if ( OSI_OK != retCode ) + { + if (TRUE == g_pCB->IsCmdRespWaited) + { + OSI_RET_OK_CHECK( sl_SyncObjSignal(&g_pCB->CmdSyncObj) ); + return SL_RET_CODE_OK; + } + } + + } + while (OSI_OK != retCode); + +#else + OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->GlobalLockObj, SL_OS_WAIT_FOREVER) ); +#endif + + g_pCB->FunctionParams.AsyncExt.pAsyncBuf = NULL;/* buffer must be allocated by _SlDrvMsgRead */ + g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler= NULL; + g_pCB->FunctionParams.AsyncExt.RxMsgClass = CMD_RESP_CLASS;/* init to illegal value and verify it's overwritten with the valid one */ + + /* Messages might have been read by CmdResp context. Therefore after */ + /* getting LockObj, check again where the Pending Rx Msg is still present. */ + if(FALSE == (_SL_PENDING_RX_MSG(g_pCB))) + { + OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->GlobalLockObj)); + return SL_RET_CODE_OK; + } + + VERIFY_RET_OK(_SlDrvMsgRead()); + + g_pCB->RxDoneCnt++; + + switch(g_pCB->FunctionParams.AsyncExt.RxMsgClass) + { + case ASYNC_EVT_CLASS: + /* If got here and protected by LockObj a message is waiting */ + /* to be read */ + VERIFY_PROTOCOL(NULL != g_pCB->FunctionParams.AsyncExt.pAsyncBuf); + + _SlAsyncEventGenericHandler(); + +#if (SL_MEMORY_MGMT == SL_MEMORY_MGMT_STATIC) + g_pCB->FunctionParams.AsyncExt.pAsyncBuf = NULL; +#else + sl_Free(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); +#endif + break; + case DUMMY_MSG_CLASS: + case RECV_RESP_CLASS: + /* These types are legal in this context. Do nothing */ + break; + case CMD_RESP_CLASS: + /* Command response is illegal in this context. */ + /* No 'break' here: Assert! */ + default: + VERIFY_PROTOCOL(0); + } + + OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->GlobalLockObj)); + + return(SL_RET_CODE_OK); +} + +/* ******************************************************************************/ +/* _SlDrvClassifyRxMsg */ +/* ******************************************************************************/ +void _SlDrvClassifyRxMsg( + _SlOpcode_t Opcode) +{ + + g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler = NULL; + + /* Async event has received */ + if (0 == (SL_OPCODE_SYNC & Opcode)) + { + if (SL_OPCODE_DEVICE_DEVICEASYNCDUMMY == Opcode) + { + g_pCB->FunctionParams.AsyncExt.RxMsgClass = DUMMY_MSG_CLASS; + } + else if ( (SL_OPCODE_SOCKET_RECVASYNCRESPONSE == Opcode) || (SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE == Opcode) || (SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE_V6 == Opcode) ) + { + g_pCB->FunctionParams.AsyncExt.RxMsgClass = RECV_RESP_CLASS; + } + else + { + g_pCB->FunctionParams.AsyncExt.RxMsgClass = ASYNC_EVT_CLASS; + + /* set silo handler */ + if (SL_OPCODE_SILO_DEVICE == (Opcode & SL_OPCODE_SILO_MASK)) + { + g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler = _SlDrvDeviceEventHandler; + } + else if (SL_OPCODE_SILO_WLAN == (Opcode & SL_OPCODE_SILO_MASK)) + { +#ifdef sl_WlanEvtHdlr + g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler = (_SlSpawnEntryFunc_t)sl_WlanEvtHdlr; +#endif + } + else if (SL_OPCODE_SILO_SOCKET == (Opcode & SL_OPCODE_SILO_MASK)) + { + +#ifdef sl_SockEvtHdlr + g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler = (_SlSpawnEntryFunc_t)sl_SockEvtHdlr; +#endif + } + else if (SL_OPCODE_SILO_NETAPP == (Opcode & SL_OPCODE_SILO_MASK)) + { + + if ((SL_OPCODE_NETAPP_HTTPGETTOKENVALUE == Opcode) || (SL_OPCODE_NETAPP_HTTPPOSTTOKENVALUE == Opcode)) + { + g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler = _SlDrvNetAppEventHandler; + } +#ifdef sl_NetAppEvtHdlr + else + { + g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler = (_SlSpawnEntryFunc_t)sl_NetAppEvtHdlr; + } +#endif + } + /* else if (SL_OPCODE_SILO_NVMEM == (Opcode & SL_OPCODE_SILO_MASK)) */ + /* { */ + /* } */ + /* else if (SL_OPCODE_SILO_NETCFG == (Opcode & SL_OPCODE_SILO_MASK)) */ + /* { */ + /* } */ + else + { + SL_ERROR_TRACE1(MSG_311, "ASSERT: _SlDrvClassifyRxMsg : invalid opcode = 0x%x", Opcode); + } + } + } + else + { + /* These may be Command responses only */ + g_pCB->FunctionParams.AsyncExt.RxMsgClass = CMD_RESP_CLASS; + } + +} + +/* ******************************************************************************/ +/* _SlDrvShiftDWord */ +/* ******************************************************************************/ +void _SlDrvShiftDWord(_u8 *pBuf) +{ + _u8 ShiftIdx; + for(ShiftIdx = 0; ShiftIdx< 7; ShiftIdx++) + { + pBuf[ShiftIdx] = pBuf[ShiftIdx+1]; + } + pBuf[7] = 0; +} + +/* ******************************************************************************/ +/* _SlDrvRxHdrRead */ +/* ******************************************************************************/ +_SlReturnVal_t _SlDrvRxHdrRead(_u8 *pBuf, _u8 *pAlignSize) +{ + _u32 SyncCnt = 0; + +#ifndef SL_IF_TYPE_UART + /* 1. Write CNYS pattern to NWP when working in SPI mode only */ + NWP_IF_WRITE_CHECK(g_pCB->FD, (_u8 *)&g_H2NCnysPattern.Short, SYNC_PATTERN_LEN); +#endif + + /* 2. Read 4 bytes (protocol aligned) */ + NWP_IF_READ_CHECK(g_pCB->FD, &pBuf[0], 4); + _SL_DBG_SYNC_LOG(SyncCnt,pBuf); + + /* Wait for SYNC_PATTERN_LEN from the device */ + while ( ! N2H_SYNC_PATTERN_MATCH(pBuf, g_pCB->TxSeqNum) ) + { + /* 3. Debug limit of scan */ + VERIFY_PROTOCOL(SyncCnt < SL_SYNC_SCAN_THRESHOLD); + + /* 4. Read next 4 bytes to Low 4 bytes of buffer */ + if(0 == (SyncCnt % (_u32)SYNC_PATTERN_LEN)) + { + NWP_IF_READ_CHECK(g_pCB->FD, &pBuf[4], 4); + _SL_DBG_SYNC_LOG(SyncCnt,pBuf); + } + + /* 5. Shift Buffer Up for checking if the sync is shifted */ + _SlDrvShiftDWord(pBuf); + + SyncCnt++; + } + + /* 5. Sync pattern found. If needed, complete number of read bytes to multiple of 4 (protocol align) */ + SyncCnt %= SYNC_PATTERN_LEN; + + if(SyncCnt > 0) + { + *(_u32 *)&pBuf[0] = *(_u32 *)&pBuf[4]; + NWP_IF_READ_CHECK(g_pCB->FD, &pBuf[SYNC_PATTERN_LEN - SyncCnt], (_u16)SyncCnt); + } + else + { + NWP_IF_READ_CHECK(g_pCB->FD, &pBuf[0], 4); + } + + /* 6. Scan for Double pattern. */ + while ( N2H_SYNC_PATTERN_MATCH(pBuf, g_pCB->TxSeqNum) ) + { + _SL_DBG_CNT_INC(Work.DoubleSyncPattern); + NWP_IF_READ_CHECK(g_pCB->FD, &pBuf[0], SYNC_PATTERN_LEN); + } + g_pCB->TxSeqNum++; + + /* 7. Here we've read Generic Header (4 bytes). Read the Resp Specific header (4 more bytes). */ + NWP_IF_READ_CHECK(g_pCB->FD, &pBuf[SYNC_PATTERN_LEN], _SL_RESP_SPEC_HDR_SIZE); + + /* 8. Here we've read the entire Resp Header. */ + /* Return number bytes needed to be sent after read for NWP Rx 4-byte alignment (protocol alignment) */ + *pAlignSize = (_u8)((SyncCnt > 0) ? (SYNC_PATTERN_LEN - SyncCnt) : 0); + + return SL_RET_CODE_OK; +} + +/* ***************************************************************************** */ +/* _SlDrvBasicCmd */ +/* ***************************************************************************** */ +typedef union +{ + _BasicResponse_t Rsp; +}_SlBasicCmdMsg_u; + +_i16 _SlDrvBasicCmd(_SlOpcode_t Opcode) +{ + _SlBasicCmdMsg_u Msg = {{0, 0}}; + _SlCmdCtrl_t CmdCtrl; + + CmdCtrl.Opcode = Opcode; + CmdCtrl.TxDescLen = 0; + CmdCtrl.RxDescLen = sizeof(_BasicResponse_t); + + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&CmdCtrl, &Msg, NULL)); + + return (_i16)Msg.Rsp.status; +} + +/* ***************************************************************************** */ +/* _SlDrvWaitForPoolObj */ +/* ***************************************************************************** */ +_i16 _SlDrvWaitForPoolObj(_u32 ActionID, _u8 SocketID) +{ + _u8 CurrObjIndex = MAX_CONCURRENT_ACTIONS; + + OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); + + /* Get free object */ + if (MAX_CONCURRENT_ACTIONS > g_pCB->FreePoolIdx) + { + /* save the current obj index */ + CurrObjIndex = g_pCB->FreePoolIdx; + /* set the new free index */ + if (MAX_CONCURRENT_ACTIONS > g_pCB->ObjPool[CurrObjIndex].NextIndex) + { + g_pCB->FreePoolIdx = g_pCB->ObjPool[CurrObjIndex].NextIndex; + } + else + { + /* No further free actions available */ + g_pCB->FreePoolIdx = MAX_CONCURRENT_ACTIONS; + } + } + else + { + OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); + return CurrObjIndex; + } + g_pCB->ObjPool[CurrObjIndex].ActionID = (_u8)ActionID; + if (SL_MAX_SOCKETS > SocketID) + { + g_pCB->ObjPool[CurrObjIndex].AdditionalData = SocketID; + } + /*In case this action is socket related, SocketID bit will be on + 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 */ + while ( ( (SL_MAX_SOCKETS > SocketID) && (g_pCB->ActiveActionsBitmap & (1<<SocketID)) ) || ( (g_pCB->ActiveActionsBitmap & (1<<ActionID)) && (SL_MAX_SOCKETS == SocketID) ) ) + { + //action in progress - move to pending list + g_pCB->ObjPool[CurrObjIndex].NextIndex = g_pCB->PendingPoolIdx; + g_pCB->PendingPoolIdx = CurrObjIndex; + OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); + //wait for action to be free + OSI_RET_OK_CHECK(sl_SyncObjWait(&g_pCB->ObjPool[CurrObjIndex].SyncObj, SL_OS_WAIT_FOREVER)); + //set params and move to active (remove from pending list at _SlDrvReleasePoolObj) + OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); + } + /*mark as active. Set socket as active if action is on socket, otherwise mark action as active*/ + if (SL_MAX_SOCKETS > SocketID) + { + g_pCB->ActiveActionsBitmap |= (1<<SocketID); + } + else + { + g_pCB->ActiveActionsBitmap |= (1<<ActionID); + } + /* move to active list */ + g_pCB->ObjPool[CurrObjIndex].NextIndex = g_pCB->ActivePoolIdx; + g_pCB->ActivePoolIdx = CurrObjIndex; + /* unlock */ + OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); + return CurrObjIndex; +} + +/* ******************************************************************************/ +/* _SlDrvReleasePoolObj */ +/* ******************************************************************************/ +void _SlDrvReleasePoolObj(_u8 ObjIdx) +{ + _u8 PendingIndex; + + OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); + + /* go over the pending list and release other pending action if needed */ + PendingIndex = g_pCB->PendingPoolIdx; + while(MAX_CONCURRENT_ACTIONS > PendingIndex) + { + /* In case this action is socket related, SocketID is in use, otherwise will be set to SL_MAX_SOCKETS */ + if ( (g_pCB->ObjPool[PendingIndex].ActionID == g_pCB->ObjPool[ObjIdx].ActionID) && + ( (SL_MAX_SOCKETS == (g_pCB->ObjPool[PendingIndex].AdditionalData & BSD_SOCKET_ID_MASK)) || + ((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) ))) ) + { + /* remove from pending list */ + _SlRemoveFromList(&g_pCB->PendingPoolIdx, PendingIndex); + OSI_RET_OK_CHECK(sl_SyncObjSignal(&(g_pCB->ObjPool[PendingIndex].SyncObj))); + break; + } + PendingIndex = g_pCB->ObjPool[PendingIndex].NextIndex; + } + + if (SL_MAX_SOCKETS > (g_pCB->ObjPool[ObjIdx].AdditionalData & BSD_SOCKET_ID_MASK)) + { + /* unset socketID */ + g_pCB->ActiveActionsBitmap &= ~(1<<(g_pCB->ObjPool[ObjIdx].AdditionalData & BSD_SOCKET_ID_MASK)); + } + else + { + /* unset actionID */ + g_pCB->ActiveActionsBitmap &= ~(1<<g_pCB->ObjPool[ObjIdx].ActionID); + } + + /* delete old data */ + g_pCB->ObjPool[ObjIdx].pRespArgs = NULL; + g_pCB->ObjPool[ObjIdx].ActionID = 0; + g_pCB->ObjPool[ObjIdx].AdditionalData = SL_MAX_SOCKETS; + + /* remove from active list */ + _SlRemoveFromList(&g_pCB->ActivePoolIdx, ObjIdx); + /* move to free list */ + g_pCB->ObjPool[ObjIdx].NextIndex = g_pCB->FreePoolIdx; + g_pCB->FreePoolIdx = ObjIdx; + + OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); +} + + + +/* ******************************************************************************/ +/* _SlDrvObjInit */ +/* ******************************************************************************/ +void _SlDrvObjInit(void) +{ + _u8 Idx; + + sl_Memset(&g_pCB->ObjPool[0],0,MAX_CONCURRENT_ACTIONS*sizeof(_SlPoolObj_t)); + /* place all Obj in the free list */ + g_pCB->FreePoolIdx = 0; + for (Idx = 0 ; Idx < MAX_CONCURRENT_ACTIONS ; Idx++) + { + g_pCB->ObjPool[Idx].NextIndex = Idx + 1; + g_pCB->ObjPool[Idx].AdditionalData = SL_MAX_SOCKETS; + } + + g_pCB->ActivePoolIdx = MAX_CONCURRENT_ACTIONS; + g_pCB->PendingPoolIdx = MAX_CONCURRENT_ACTIONS; + +} + +/* ******************************************************************************/ +/* _SlDrvObjDeInit */ +/* ******************************************************************************/ +void _SlDrvObjDeInit(void) +{ + g_pCB->FreePoolIdx = 0; + g_pCB->PendingPoolIdx = MAX_CONCURRENT_ACTIONS; + g_pCB->ActivePoolIdx = MAX_CONCURRENT_ACTIONS; + +} + +/* ******************************************************************************/ +/* _SlRemoveFromList */ +/* ******************************************************************************/ +void _SlRemoveFromList(_u8 *ListIndex, _u8 ItemIndex) +{ + _u8 Idx; + /* only one item in the list */ + if (MAX_CONCURRENT_ACTIONS == g_pCB->ObjPool[*ListIndex].NextIndex) + { + *ListIndex = MAX_CONCURRENT_ACTIONS; + } + /* need to remove the first item in the list and therefore update the global which holds this index */ + else if (*ListIndex == ItemIndex) + { + *ListIndex = g_pCB->ObjPool[ItemIndex].NextIndex; + } + else + { + Idx = *ListIndex; + while(MAX_CONCURRENT_ACTIONS > Idx) + { + /* remove from list */ + if (g_pCB->ObjPool[Idx].NextIndex == ItemIndex) + { + g_pCB->ObjPool[Idx].NextIndex = g_pCB->ObjPool[ItemIndex].NextIndex; + break; + } + Idx = g_pCB->ObjPool[Idx].NextIndex; + } + } +} + + +/* ******************************************************************************/ +/* _SlFindAndSetActiveObj */ +/* ******************************************************************************/ +_SlReturnVal_t _SlFindAndSetActiveObj(_SlOpcode_t Opcode, _u8 Sd) +{ + _u8 ActiveIndex; + + ActiveIndex = g_pCB->ActivePoolIdx; + /* go over the active list if exist to find obj waiting for this Async event */ + while (MAX_CONCURRENT_ACTIONS > ActiveIndex) + { + /* unset the Ipv4\IPv6 bit in the opcode if family bit was set */ + if (g_pCB->ObjPool[ActiveIndex].AdditionalData & SL_NETAPP_FAMILY_MASK) + { + Opcode &= ~SL_OPCODE_IPV6; + } + + if ((g_pCB->ObjPool[ActiveIndex].ActionID == RECV_ID) && (Sd == g_pCB->ObjPool[ActiveIndex].AdditionalData) && + ( (SL_OPCODE_SOCKET_RECVASYNCRESPONSE == Opcode) || (SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE == Opcode) || (SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE_V6 == Opcode) ) ) + { + g_pCB->FunctionParams.AsyncExt.ActionIndex = ActiveIndex; + return SL_RET_CODE_OK; + } + /* In case this action is socket related, SocketID is in use, otherwise will be set to SL_MAX_SOCKETS */ + if ( (_SlActionLookupTable[ g_pCB->ObjPool[ActiveIndex].ActionID - MAX_SOCKET_ENUM_IDX].ActionAsyncOpcode == Opcode) && + ( ((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)) ) ) + { + /* set handler */ + g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler = _SlActionLookupTable[ g_pCB->ObjPool[ActiveIndex].ActionID - MAX_SOCKET_ENUM_IDX].AsyncEventHandler; + g_pCB->FunctionParams.AsyncExt.ActionIndex = ActiveIndex; + return SL_RET_CODE_OK; + } + ActiveIndex = g_pCB->ObjPool[ActiveIndex].NextIndex; + } + + return SL_RET_CODE_SELF_ERROR; +} diff --git a/cc3200/simplelink/source/driver.h b/cc3200/simplelink/source/driver.h new file mode 100644 index 000000000..9aa3b729a --- /dev/null +++ b/cc3200/simplelink/source/driver.h @@ -0,0 +1,220 @@ +/* + * driver.h - CC31xx/CC32xx Host Driver Implementation + * + * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + +#ifndef __DRIVER_INT_H__ +#define __DRIVER_INT_H__ + + +/*****************************************************************************/ +/* Macro declarations */ +/*****************************************************************************/ + +#ifndef CPU_FREQ_IN_MHZ + #define CPU_FREQ_IN_MHZ (200) +#endif +#define USEC_DELAY (50) + +/*****************************************************************************/ +/* Structure/Enum declarations */ +/*****************************************************************************/ + +typedef struct +{ + _SlOpcode_t Opcode; + _SlArgSize_t TxDescLen; + _SlArgSize_t RxDescLen; +}_SlCmdCtrl_t; + +typedef struct +{ + _u16 TxPayloadLen; + _u16 RxPayloadLen; + _u16 ActualRxPayloadLen; + _u8 *pTxPayload; + _u8 *pRxPayload; +}_SlCmdExt_t; + + +typedef struct _SlArgsData_t +{ + _u8 *pArgs; + _u8 *pData; +} _SlArgsData_t; + + +typedef struct _SlPoolObj_t +{ + _SlSyncObj_t SyncObj; + _u8 *pRespArgs; + _u8 ActionID; + _u8 AdditionalData; /* use for socketID and one bit which indicate supprt IPV6 or not (1=support, 0 otherwise) */ + _u8 NextIndex; + +} _SlPoolObj_t; + + +typedef enum +{ + SOCKET_0, + SOCKET_1, + SOCKET_2, + SOCKET_3, + SOCKET_4, + SOCKET_5, + SOCKET_6, + SOCKET_7, + MAX_SOCKET_ENUM_IDX, + ACCEPT_ID = MAX_SOCKET_ENUM_IDX, + CONNECT_ID, + SELECT_ID, + GETHOSYBYNAME_ID, + GETHOSYBYSERVICE_ID, + PING_ID, + START_STOP_ID, + RECV_ID +}_SlActionID_e; + +typedef struct _SlActionLookup_t +{ + _u8 ActionID; + _u16 ActionAsyncOpcode; + _SlSpawnEntryFunc_t AsyncEventHandler; + +} _SlActionLookup_t; + + +typedef struct +{ + _u8 TxPoolCnt; + _SlLockObj_t TxLockObj; + _SlSyncObj_t TxSyncObj; +}_SlFlowContCB_t; + +typedef enum +{ + RECV_RESP_CLASS, + CMD_RESP_CLASS, + ASYNC_EVT_CLASS, + DUMMY_MSG_CLASS +}_SlRxMsgClass_e; + +typedef struct +{ + _u8 *pAsyncBuf; /* place to write pointer to buffer with CmdResp's Header + Arguments */ + _u8 ActionIndex; + _SlSpawnEntryFunc_t AsyncEvtHandler; /* place to write pointer to AsyncEvent handler (calc-ed by Opcode) */ + _SlRxMsgClass_e RxMsgClass; /* type of Rx message */ +} AsyncExt_t; + +typedef _u8 _SlSd_t; + +typedef struct +{ + _SlCmdCtrl_t *pCmdCtrl; + _u8 *pTxRxDescBuff; + _SlCmdExt_t *pCmdExt; + AsyncExt_t AsyncExt; +}_SlFunctionParams_t; + + +typedef struct +{ + _SlFd_t FD; + _SlLockObj_t GlobalLockObj; + _SlCommandHeader_t TempProtocolHeader; + P_INIT_CALLBACK pInitCallback; + + _SlPoolObj_t ObjPool[MAX_CONCURRENT_ACTIONS]; + _u8 FreePoolIdx; + _u8 PendingPoolIdx; + _u8 ActivePoolIdx; + _u32 ActiveActionsBitmap; + _SlLockObj_t ProtectionLockObj; + + _SlSyncObj_t CmdSyncObj; + _u8 IsCmdRespWaited; + + _SlFlowContCB_t FlowContCB; + + _u8 TxSeqNum; + _volatile _u8 RxIrqCnt; + _u8 RxDoneCnt; + _u8 SocketNonBlocking; + _u8 SocketTXFailure; + _u8 RelayFlagsViaRxPayload; + /* for stack reduction the parameters are globals */ + _SlFunctionParams_t FunctionParams; + +}_SlDriverCb_t; + + + +extern _SlDriverCb_t* g_pCB; +extern P_SL_DEV_PING_CALLBACK pPingCallBackFunc; + +/*****************************************************************************/ +/* Function prototypes */ +/*****************************************************************************/ +extern void _SlDrvDriverCBInit(void); +extern void _SlDrvDriverCBDeinit(void); +extern void _SlDrvRxIrqHandler(void *pValue); +extern _SlReturnVal_t _SlDrvCmdOp(_SlCmdCtrl_t *pCmdCtrl , void* pTxRxDescBuff , _SlCmdExt_t* pCmdExt); +extern _SlReturnVal_t _SlDrvCmdSend(_SlCmdCtrl_t *pCmdCtrl , void* pTxRxDescBuff , _SlCmdExt_t* pCmdExt); +extern _SlReturnVal_t _SlDrvDataReadOp(_SlSd_t Sd, _SlCmdCtrl_t *pCmdCtrl , void* pTxRxDescBuff , _SlCmdExt_t* pCmdExt); +extern _SlReturnVal_t _SlDrvDataWriteOp(_SlSd_t Sd, _SlCmdCtrl_t *pCmdCtrl , void* pTxRxDescBuff , _SlCmdExt_t* pCmdExt); +extern _i16 _SlDrvBasicCmd(_SlOpcode_t Opcode); + +extern void _sl_HandleAsync_InitComplete(void *pVoidBuf); +extern void _sl_HandleAsync_Connect(void *pVoidBuf); +extern void _sl_HandleAsync_Accept(void *pVoidBuf); +extern void _sl_HandleAsync_Select(void *pVoidBuf); +extern void _sl_HandleAsync_DnsGetHostByName(void *pVoidBuf); +extern void _sl_HandleAsync_DnsGetHostByService(void *pVoidBuf); +extern void _sl_HandleAsync_DnsGetHostByAddr(void *pVoidBuf); +extern void _sl_HandleAsync_PingResponse(void *pVoidBuf); +extern void _SlDrvNetAppEventHandler(void *pArgs); +extern void _SlDrvDeviceEventHandler(void *pArgs); +extern void _sl_HandleAsync_Stop(void *pVoidBuf); +extern _i16 _SlDrvWaitForPoolObj(_u32 ActionID, _u8 SocketID); +extern void _SlDrvReleasePoolObj(_u8 pObj); +extern void _SlDrvObjInit(void); + +#define _SL_PROTOCOL_ALIGN_SIZE(msgLen) (((msgLen)+3) & (~3)) +#define _SL_IS_PROTOCOL_ALIGNED_SIZE(msgLen) (!((msgLen) & 3)) +#define _SL_PROTOCOL_CALC_LEN(pCmdCtrl,pCmdExt) ((pCmdExt) ? \ + (_SL_PROTOCOL_ALIGN_SIZE(pCmdCtrl->TxDescLen) + _SL_PROTOCOL_ALIGN_SIZE(pCmdExt->TxPayloadLen)) : \ + (_SL_PROTOCOL_ALIGN_SIZE(pCmdCtrl->TxDescLen))) +#endif /* __DRIVER_INT_H__ */ diff --git a/cc3200/simplelink/source/flowcont.c b/cc3200/simplelink/source/flowcont.c new file mode 100644 index 000000000..889241ea2 --- /dev/null +++ b/cc3200/simplelink/source/flowcont.c @@ -0,0 +1,71 @@ +/* + * flowcont.c - CC31xx/CC32xx Host Driver Implementation + * + * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + + + +/*****************************************************************************/ +/* Include files */ +/*****************************************************************************/ +#include "simplelink.h" +#include "protocol.h" +#include "driver.h" +#include "flowcont.h" + + +/*****************************************************************************/ +/* _SlDrvFlowContInit */ +/*****************************************************************************/ +void _SlDrvFlowContInit(void) +{ + g_pCB->FlowContCB.TxPoolCnt = FLOW_CONT_MIN; + + OSI_RET_OK_CHECK(sl_LockObjCreate(&g_pCB->FlowContCB.TxLockObj, "TxLockObj")); + + OSI_RET_OK_CHECK(sl_SyncObjCreate(&g_pCB->FlowContCB.TxSyncObj, "TxSyncObj")); +} + +/*****************************************************************************/ +/* _SlDrvFlowContDeinit */ +/*****************************************************************************/ +void _SlDrvFlowContDeinit(void) +{ + g_pCB->FlowContCB.TxPoolCnt = 0; + + OSI_RET_OK_CHECK(sl_LockObjDelete(&g_pCB->FlowContCB.TxLockObj)); + + OSI_RET_OK_CHECK(sl_SyncObjDelete(&g_pCB->FlowContCB.TxSyncObj)); +} + diff --git a/cc3200/simplelink/source/flowcont.h b/cc3200/simplelink/source/flowcont.h new file mode 100644 index 000000000..3dcc130d8 --- /dev/null +++ b/cc3200/simplelink/source/flowcont.h @@ -0,0 +1,61 @@ +/* + * flowcont.h - CC31xx/CC32xx Host Driver Implementation + * + * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + +#ifndef __FLOWCONT_H__ +#define __FLOWCONT_H__ + + +#ifdef __cplusplus +extern "C" { +#endif + +/*****************************************************************************/ +/* Macro declarations */ +/*****************************************************************************/ +#define FLOW_CONT_MIN 1 + +/*****************************************************************************/ +/* Function prototypes */ +/*****************************************************************************/ +extern void _SlDrvFlowContInit(void); +extern void _SlDrvFlowContDeinit(void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __FLOWCONT_H__ */ + diff --git a/cc3200/simplelink/source/fs.c b/cc3200/simplelink/source/fs.c new file mode 100644 index 000000000..cc44e262e --- /dev/null +++ b/cc3200/simplelink/source/fs.c @@ -0,0 +1,415 @@ +/* + * fs.c - CC31xx/CC32xx Host Driver Implementation + * + * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + + + +/*****************************************************************************/ +/* Include files */ +/*****************************************************************************/ +#include "simplelink.h" +#include "protocol.h" +#include "driver.h" + +/*****************************************************************************/ +/* Macro declarations */ +/*****************************************************************************/ +#define sl_min(a,b) (((a) < (b)) ? (a) : (b)) +#define MAX_NVMEM_CHUNK_SIZE 1460 + +/*****************************************************************************/ +/* Internal functions */ +/*****************************************************************************/ + + +/*****************************************************************************/ +/* _sl_Strlen */ +/*****************************************************************************/ +_u16 _sl_Strlen(const _u8 *buffer) +{ + _u16 len = 0; + if( buffer != NULL ) + { + while(*buffer++) len++; + } + return len; +} + +/*****************************************************************************/ +/* _sl_GetCreateFsMode */ +/*****************************************************************************/ +_u32 _sl_GetCreateFsMode(_u32 maxSizeInBytes,_u32 accessFlags) +{ + _u32 granIdx = 0; + _u32 granNum = 0; + _u32 granTable[_FS_MAX_MODE_SIZE_GRAN] = {256,1024,4096,16384,65536}; + for(granIdx= _FS_MODE_SIZE_GRAN_256B ;granIdx< _FS_MAX_MODE_SIZE_GRAN;granIdx++) + { + if( granTable[granIdx]*255 >= maxSizeInBytes ) + break; + } + granNum = maxSizeInBytes/granTable[granIdx]; + if( maxSizeInBytes % granTable[granIdx] != 0 ) + granNum++; + + return _FS_MODE(_FS_MODE_OPEN_WRITE_CREATE_IF_NOT_EXIST, granIdx, granNum, accessFlags); +} + + +/*****************************************************************************/ +/* API functions */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* sl_FsOpen */ +/*****************************************************************************/ +typedef union +{ + _FsOpenCommand_t Cmd; + _FsOpenResponse_t Rsp; +}_SlFsOpenMsg_u; + +const _SlCmdCtrl_t _SlFsOpenCmdCtrl = +{ + SL_OPCODE_NVMEM_FILEOPEN, + sizeof(_FsOpenCommand_t), + sizeof(_FsOpenResponse_t) +}; + +#if _SL_INCLUDE_FUNC(sl_FsOpen) +_i32 sl_FsOpen(_u8 *pFileName,_u32 AccessModeAndMaxSize, _u32 *pToken,_i32 *pFileHandle) +{ + _SlReturnVal_t RetVal; + _SlFsOpenMsg_u Msg; + _SlCmdExt_t CmdExt; + + CmdExt.TxPayloadLen = (_sl_Strlen(pFileName)+4) & (~3); // add 4: 1 for NULL and the 3 for align + CmdExt.RxPayloadLen = 0; + CmdExt.pTxPayload = pFileName; + CmdExt.pRxPayload = NULL; + + Msg.Cmd.Mode = AccessModeAndMaxSize; + + if(pToken != NULL) + { + Msg.Cmd.Token = *pToken; + } + else + { + Msg.Cmd.Token = 0; + } + + RetVal = _SlDrvCmdOp((_SlCmdCtrl_t *)&_SlFsOpenCmdCtrl, &Msg, &CmdExt); + *pFileHandle = Msg.Rsp.FileHandle; + if (pToken != NULL) + { + *pToken = Msg.Rsp.Token; + } + + /* in case of an error, return the erros file handler as an error code */ + if( *pFileHandle < 0 ) + { + return *pFileHandle; + } + return (_i32)RetVal; +} +#endif + +/*****************************************************************************/ +/* sl_FsClose */ +/*****************************************************************************/ +typedef union +{ + _FsCloseCommand_t Cmd; + _BasicResponse_t Rsp; +}_SlFsCloseMsg_u; + +const _SlCmdCtrl_t _SlFsCloseCmdCtrl = +{ + SL_OPCODE_NVMEM_FILECLOSE, + sizeof(_FsCloseCommand_t), + sizeof(_FsCloseResponse_t) +}; + +#if _SL_INCLUDE_FUNC(sl_FsClose) +_i16 sl_FsClose(_i32 FileHdl, _u8* pCeritificateFileName,_u8* pSignature ,_u32 SignatureLen) +{ + _SlFsCloseMsg_u Msg = {.Cmd = {0, 0, 0}, .Rsp = {0, 0}}; + _SlCmdExt_t ExtCtrl; + + Msg.Cmd.FileHandle = FileHdl; + if( pCeritificateFileName != NULL ) + { + Msg.Cmd.CertificFileNameLength = (_sl_Strlen(pCeritificateFileName)+4) & (~3); /* add 4: 1 for NULL and the 3 for align */ + } + Msg.Cmd.SignatureLen = SignatureLen; + + ExtCtrl.TxPayloadLen = ((SignatureLen+3) & (~3)); /* align */ + ExtCtrl.pTxPayload = pSignature; + ExtCtrl.RxPayloadLen = (_u16)Msg.Cmd.CertificFileNameLength; + ExtCtrl.pRxPayload = pCeritificateFileName; /* Add signature */ + + if(ExtCtrl.pRxPayload != NULL && ExtCtrl.RxPayloadLen != 0) + { + g_pCB->RelayFlagsViaRxPayload = TRUE; + } + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlFsCloseCmdCtrl, &Msg, &ExtCtrl)); + + return (_i16)((_i16)Msg.Rsp.status); +} +#endif + + +/*****************************************************************************/ +/* sl_FsRead */ +/*****************************************************************************/ +typedef union +{ + _FsReadCommand_t Cmd; + _FsReadResponse_t Rsp; +}_SlFsReadMsg_u; + +const _SlCmdCtrl_t _SlFsReadCmdCtrl = +{ + SL_OPCODE_NVMEM_FILEREADCOMMAND, + sizeof(_FsReadCommand_t), + sizeof(_FsReadResponse_t) +}; + + +#if _SL_INCLUDE_FUNC(sl_FsRead) +_i32 sl_FsRead(_i32 FileHdl, _u32 Offset, _u8* pData, _u32 Len) +{ + _SlFsReadMsg_u Msg; + _SlCmdExt_t ExtCtrl; + _u16 ChunkLen; + _SlReturnVal_t RetVal =0; + _i32 RetCount = 0; + + ExtCtrl.TxPayloadLen = 0; + ExtCtrl.pTxPayload = NULL; + + ChunkLen = (_u16)sl_min(MAX_NVMEM_CHUNK_SIZE,Len); + ExtCtrl.RxPayloadLen = ChunkLen; + ExtCtrl.pRxPayload = (_u8 *)(pData); + Msg.Cmd.Offset = Offset; + Msg.Cmd.Len = ChunkLen; + Msg.Cmd.FileHandle = FileHdl; + do + { + RetVal = _SlDrvCmdOp((_SlCmdCtrl_t *)&_SlFsReadCmdCtrl, &Msg, &ExtCtrl); + if(SL_OS_RET_CODE_OK == RetVal) + { + if( Msg.Rsp.status < 0) + { + if( RetCount > 0) + { + return RetCount; + } + else + { + return Msg.Rsp.status; + } + } + RetCount += (_i32)Msg.Rsp.status; + Len -= ChunkLen; + Offset += ChunkLen; + Msg.Cmd.Offset = Offset; + ExtCtrl.pRxPayload += ChunkLen; + ChunkLen = (_u16)sl_min(MAX_NVMEM_CHUNK_SIZE,Len); + ExtCtrl.RxPayloadLen = ChunkLen; + Msg.Cmd.Len = ChunkLen; + Msg.Cmd.FileHandle = FileHdl; + } + else + { + return RetVal; + } + }while(ChunkLen > 0); + + return (_i32)RetCount; +} +#endif + +/*****************************************************************************/ +/* sl_FsWrite */ +/*****************************************************************************/ +typedef union +{ + _FsWriteCommand_t Cmd; + _FsWriteResponse_t Rsp; +}_SlFsWriteMsg_u; + +const _SlCmdCtrl_t _SlFsWriteCmdCtrl = +{ + SL_OPCODE_NVMEM_FILEWRITECOMMAND, + sizeof(_FsWriteCommand_t), + sizeof(_FsWriteResponse_t) +}; + + +#if _SL_INCLUDE_FUNC(sl_FsWrite) +_i32 sl_FsWrite(_i32 FileHdl, _u32 Offset, _u8* pData, _u32 Len) +{ + _SlFsWriteMsg_u Msg; + _SlCmdExt_t ExtCtrl; + _u16 ChunkLen; + _SlReturnVal_t RetVal; + _i32 RetCount = 0; + + ExtCtrl.RxPayloadLen = 0; + ExtCtrl.pRxPayload = NULL; + + ChunkLen = (_u16)sl_min(MAX_NVMEM_CHUNK_SIZE,Len); + ExtCtrl.TxPayloadLen = ChunkLen; + ExtCtrl.pTxPayload = (_u8 *)(pData); + Msg.Cmd.Offset = Offset; + Msg.Cmd.Len = ChunkLen; + Msg.Cmd.FileHandle = FileHdl; + + do + { + + RetVal = _SlDrvCmdOp((_SlCmdCtrl_t *)&_SlFsWriteCmdCtrl, &Msg, &ExtCtrl); + if(SL_OS_RET_CODE_OK == RetVal) + { + if( Msg.Rsp.status < 0) + { + if( RetCount > 0) + { + return RetCount; + } + else + { + return Msg.Rsp.status; + } + } + + RetCount += (_i32)Msg.Rsp.status; + Len -= ChunkLen; + Offset += ChunkLen; + Msg.Cmd.Offset = Offset; + ExtCtrl.pTxPayload += ChunkLen; + ChunkLen = (_u16)sl_min(MAX_NVMEM_CHUNK_SIZE,Len); + ExtCtrl.TxPayloadLen = ChunkLen; + Msg.Cmd.Len = ChunkLen; + Msg.Cmd.FileHandle = FileHdl; + } + else + { + return RetVal; + } + }while(ChunkLen > 0); + + return (_i32)RetCount; +} +#endif + +/*****************************************************************************/ +/* sl_FsGetInfo */ +/*****************************************************************************/ +typedef union +{ + _FsGetInfoCommand_t Cmd; + _FsGetInfoResponse_t Rsp; +}_SlFsGetInfoMsg_u; + +const _SlCmdCtrl_t _SlFsGetInfoCmdCtrl = +{ + SL_OPCODE_NVMEM_FILEGETINFOCOMMAND, + sizeof(_FsGetInfoCommand_t), + sizeof(_FsGetInfoResponse_t) +}; + +#if _SL_INCLUDE_FUNC(sl_FsGetInfo) +_i16 sl_FsGetInfo(_u8 *pFileName,_u32 Token,SlFsFileInfo_t* pFsFileInfo) +{ + _SlFsGetInfoMsg_u Msg; + _SlCmdExt_t CmdExt; + + CmdExt.TxPayloadLen = (_sl_Strlen(pFileName)+4) & (~3); /* add 4: 1 for NULL and the 3 for align */ + CmdExt.RxPayloadLen = 0; + CmdExt.pTxPayload = pFileName; + CmdExt.pRxPayload = NULL; + Msg.Cmd.Token = Token; + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlFsGetInfoCmdCtrl, &Msg, &CmdExt)); + + pFsFileInfo->flags = Msg.Rsp.flags; + pFsFileInfo->FileLen = Msg.Rsp.FileLen; + pFsFileInfo->AllocatedLen = Msg.Rsp.AllocatedLen; + pFsFileInfo->Token[0] = Msg.Rsp.Token[0]; + pFsFileInfo->Token[1] = Msg.Rsp.Token[1]; + pFsFileInfo->Token[2] = Msg.Rsp.Token[2]; + pFsFileInfo->Token[3] = Msg.Rsp.Token[3]; + return (_i16)((_i16)Msg.Rsp.Status); +} +#endif + +/*****************************************************************************/ +/* sl_FsDel */ +/*****************************************************************************/ +typedef union +{ + _FsDeleteCommand_t Cmd; + _FsDeleteResponse_t Rsp; +}_SlFsDeleteMsg_u; + +const _SlCmdCtrl_t _SlFsDeleteCmdCtrl = +{ + SL_OPCODE_NVMEM_FILEDELCOMMAND, + sizeof(_FsDeleteCommand_t), + sizeof(_FsDeleteResponse_t) +}; + +#if _SL_INCLUDE_FUNC(sl_FsDel) +_i16 sl_FsDel(_u8 *pFileName,_u32 Token) +{ + _SlFsDeleteMsg_u Msg; + _SlCmdExt_t CmdExt; + + CmdExt.TxPayloadLen = (_sl_Strlen(pFileName)+4) & (~3); /* add 4: 1 for NULL and the 3 for align */ + CmdExt.RxPayloadLen = 0; + CmdExt.pTxPayload = pFileName; + CmdExt.pRxPayload = NULL; + Msg.Cmd.Token = Token; + + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlFsDeleteCmdCtrl, &Msg, &CmdExt)); + + return (_i16)((_i16)Msg.Rsp.status); +} +#endif diff --git a/cc3200/simplelink/source/netapp.c b/cc3200/simplelink/source/netapp.c new file mode 100644 index 000000000..32315e093 --- /dev/null +++ b/cc3200/simplelink/source/netapp.c @@ -0,0 +1,1285 @@ +/* + * netapp.c - CC31xx/CC32xx Host Driver Implementation + * + * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + + + +/*****************************************************************************/ +/* Include files */ +/*****************************************************************************/ +#include "simplelink.h" +#include "protocol.h" +#include "driver.h" + +/*****************************************************************************/ +/* Macro declarations */ +/*****************************************************************************/ +#define NETAPP_MDNS_OPTIONS_ADD_SERVICE_BIT ((_u32)0x1 << 31) + +#ifdef SL_TINY +#define NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH 63 +#else +#define NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH 255 +#endif + + +/*****************************************************************************/ +/* Functions prototypes */ +/*****************************************************************************/ +void _sl_HandleAsync_DnsGetHostByName(void *pVoidBuf); +void _sl_HandleAsync_DnsGetHostByService(void *pVoidBuf); +void _sl_HandleAsync_PingResponse(void *pVoidBuf); +void CopyPingResultsToReport(_PingReportResponse_t *pResults,SlPingReport_t *pReport); +_u16 sl_NetAppSendTokenValue(slHttpServerData_t * Token); +_i16 sl_NetAppMDNSRegisterUnregisterService(const _i8* pServiceName, + _u8 ServiceNameLen, + const _i8* pText, + _u8 TextLen, + _u16 Port, + _u32 TTL, + _u32 Options); + + +/*****************************************************************************/ +/* API functions */ +/*****************************************************************************/ + +/***************************************************************************** + sl_NetAppStart +*****************************************************************************/ +typedef union +{ + _NetAppStartStopCommand_t Cmd; + _NetAppStartStopResponse_t Rsp; +}_SlNetAppStartStopMsg_u; + +const _SlCmdCtrl_t _SlNetAppStartCtrl = +{ + SL_OPCODE_NETAPP_START_COMMAND, + sizeof(_NetAppStartStopCommand_t), + sizeof(_NetAppStartStopResponse_t) +}; + +const _SlCmdCtrl_t _SlNetAppStopCtrl = +{ + SL_OPCODE_NETAPP_STOP_COMMAND, + sizeof(_NetAppStartStopCommand_t), + sizeof(_NetAppStartStopResponse_t) +}; + +#if _SL_INCLUDE_FUNC(sl_NetAppStart) +_i16 sl_NetAppStart(_u32 AppBitMap) +{ + _SlNetAppStartStopMsg_u Msg; + Msg.Cmd.appId = AppBitMap; + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlNetAppStartCtrl, &Msg, NULL)); + + return Msg.Rsp.status; +} +#endif + +/***************************************************************************** + sl_NetAppStop +*****************************************************************************/ +#if _SL_INCLUDE_FUNC(sl_NetAppStop) +_i16 sl_NetAppStop(_u32 AppBitMap) +{ + _SlNetAppStartStopMsg_u Msg; + Msg.Cmd.appId = AppBitMap; + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlNetAppStopCtrl, &Msg, NULL)); + + return Msg.Rsp.status; +} +#endif + + +/******************************************************************************/ +/* sl_NetAppGetServiceList */ +/******************************************************************************/ +typedef struct +{ + _u8 IndexOffest; + _u8 MaxServiceCount; + _u8 Flags; + _i8 Padding; +}NetappGetServiceListCMD_t; + +typedef union +{ + NetappGetServiceListCMD_t Cmd; + _BasicResponse_t Rsp; +}_SlNetappGetServiceListMsg_u; + +const _SlCmdCtrl_t _SlGetServiceListeCtrl = +{ + SL_OPCODE_NETAPP_NETAPP_MDNS_LOOKUP_SERVICE, + sizeof(NetappGetServiceListCMD_t), + sizeof(_BasicResponse_t) +}; + + +#if _SL_INCLUDE_FUNC(sl_NetAppGetServiceList) +_i16 sl_NetAppGetServiceList(_u8 IndexOffest, + _u8 MaxServiceCount, + _u8 Flags, + _i8 *pBuffer, + _u32 RxBufferLength + ) +{ + + _i32 retVal= 0; + _SlNetappGetServiceListMsg_u Msg; + _SlCmdExt_t CmdExt; + _u16 ServiceSize = 0; + _u16 BufferSize = 0; + + /* + Calculate RX pBuffer size + WARNING: + if this size is BufferSize than 1480 error should be returned because there + is no place in the RX packet. + */ + switch(Flags) + { + case SL_NET_APP_FULL_SERVICE_WITH_TEXT_IPV4_TYPE: + ServiceSize = sizeof(SlNetAppGetFullServiceWithTextIpv4List_t); + break; + + case SL_NET_APP_FULL_SERVICE_IPV4_TYPE: + ServiceSize = sizeof(SlNetAppGetFullServiceIpv4List_t); + break; + + case SL_NET_APP_SHORT_SERVICE_IPV4_TYPE: + ServiceSize = sizeof(SlNetAppGetShortServiceIpv4List_t); + break; + + default: + ServiceSize = sizeof(_BasicResponse_t); + break; + } + + + + BufferSize = MaxServiceCount * ServiceSize; + + /*Check the size of the requested services is smaller than size of the user buffer. + If not an error is returned in order to avoid overwriting memory. */ + if(RxBufferLength <= BufferSize) + { + return SL_ERROR_NETAPP_RX_BUFFER_LENGTH_ERROR; + } + + CmdExt.TxPayloadLen = 0; + CmdExt.RxPayloadLen = BufferSize; + CmdExt.pTxPayload = NULL; + CmdExt.pRxPayload = (_u8 *)pBuffer; + + Msg.Cmd.IndexOffest = IndexOffest; + Msg.Cmd.MaxServiceCount = MaxServiceCount; + Msg.Cmd.Flags = Flags; + Msg.Cmd.Padding = 0; + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlGetServiceListeCtrl, &Msg, &CmdExt)); + retVal = Msg.Rsp.status; + + return (_i16)retVal; +} + +#endif + +/*****************************************************************************/ +/* sl_mDNSRegisterService */ +/*****************************************************************************/ +/* + * The below struct depicts the constant parameters of the command/API RegisterService. + * + 1. ServiceLen - The length of the service should be smaller than NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH. + 2. TextLen - The length of the text should be smaller than NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH. + 3. port - The port on this target host. + 4. TTL - The TTL of the service + 5. Options - bitwise parameters: + bit 0 - is unique (means if the service needs to be unique) + bit 31 - for internal use if the service should be added or deleted (set means ADD). + bit 1-30 for future. + + NOTE: + + 1. There are another variable parameter is this API which is the service name and the text. + 2. According to now there is no warning and Async event to user on if the service is a unique. +* + */ + + +typedef struct +{ + _u8 ServiceNameLen; + _u8 TextLen; + _u16 Port; + _u32 TTL; + _u32 Options; +}NetappMdnsSetService_t; + +typedef union +{ + NetappMdnsSetService_t Cmd; + _BasicResponse_t Rsp; +}_SlNetappMdnsRegisterServiceMsg_u; + +const _SlCmdCtrl_t _SlRegisterServiceCtrl = +{ + SL_OPCODE_NETAPP_MDNSREGISTERSERVICE, + sizeof(NetappMdnsSetService_t), + sizeof(_BasicResponse_t) +}; + + +/****************************************************************************** + + sl_NetAppMDNSRegisterService + + CALLER user from its host + + + DESCRIPTION: + Add/delete service + The function manipulates the command that register the service and call + to the NWP in order to add/delete the service to/from the mDNS package and to/from the DB. + + This register service is a service offered by the application. + This unregister service is a service offered by the application before. + + The service name should be full service name according to RFC + of the DNS-SD - means the value in name field in SRV answer. + + Example for service name: + 1. PC1._ipp._tcp.local + 2. PC2_server._ftp._tcp.local + + If the option is_unique is set, mDNS probes the service name to make sure + it is unique before starting to announce the service on the network. + Instance is the instance portion of the service name. + + + + + PARAMETERS: + + The command is from constant parameters and variables parameters. + + Constant parameters are: + + ServiceLen - The length of the service. + TextLen - The length of the service should be smaller than 64. + port - The port on this target host. + TTL - The TTL of the service + Options - bitwise parameters: + bit 0 - is unique (means if the service needs to be unique) + bit 31 - for internal use if the service should be added or deleted (set means ADD). + bit 1-30 for future. + + The variables parameters are: + + Service name(full service name) - The service name. + Example for service name: + 1. PC1._ipp._tcp.local + 2. PC2_server._ftp._tcp.local + + Text - The description of the service. + should be as mentioned in the RFC + (according to type of the service IPP,FTP...) + + NOTE - pay attention + + 1. Temporary - there is an allocation on stack of internal buffer. + Its size is NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH. + It means that the sum of the text length and service name length cannot be bigger than + NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH. + If it is - An error is returned. + + 2. According to now from certain constraints the variables parameters are set in the + attribute part (contain constant parameters) + + + + RETURNS: Status - the immediate response of the command status. + 0 means success. + + + +******************************************************************************/ +#if _SL_INCLUDE_FUNC(sl_NetAppMDNSRegisterUnregisterService) + +_i16 sl_NetAppMDNSRegisterUnregisterService( const _i8* pServiceName, + _u8 ServiceNameLen, + const _i8* pText, + _u8 TextLen, + _u16 Port, + _u32 TTL, + _u32 Options) + +{ + _SlNetappMdnsRegisterServiceMsg_u Msg; + _SlCmdExt_t CmdExt ; + _i8 ServiceNameAndTextBuffer[NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH]; + _i8 *TextPtr; + + /* + + NOTE - pay attention + + 1. Temporary - there is an allocation on stack of internal buffer. + Its size is NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH. + It means that the sum of the text length and service name length cannot be bigger than + NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH. + If it is - An error is returned. + + 2. According to now from certain constraints the variables parameters are set in the + attribute part (contain constant parameters) + + + */ + + /*build the attribute part of the command. + It contains the constant parameters of the command*/ + + Msg.Cmd.ServiceNameLen = ServiceNameLen; + Msg.Cmd.Options = Options; + Msg.Cmd.Port = Port; + Msg.Cmd.TextLen = TextLen; + Msg.Cmd.TTL = TTL; + + /*Build the payload part of the command + Copy the service name and text to one buffer. + NOTE - pay attention + The size of the service length + the text length should be smaller than 255, + Until the simplelink drive supports to variable length through SPI command. */ + if(TextLen + ServiceNameLen > (NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH - 1 )) /*-1 is for giving a place to set null termination at the end of the text*/ + { + return -1; + } + + sl_Memset(ServiceNameAndTextBuffer,0,NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH); + + + /*Copy the service name*/ + sl_Memcpy(ServiceNameAndTextBuffer, + pServiceName, + ServiceNameLen); + + if(TextLen > 0 ) + { + + TextPtr = &ServiceNameAndTextBuffer[ServiceNameLen]; + /*Copy the text just after the service name*/ + sl_Memcpy(TextPtr, + pText, + TextLen); + + + } + + CmdExt.TxPayloadLen = (TextLen + ServiceNameLen); + CmdExt.RxPayloadLen = 0; + CmdExt.pTxPayload = (_u8 *)ServiceNameAndTextBuffer; + CmdExt.pRxPayload = NULL; + + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlRegisterServiceCtrl, &Msg, &CmdExt)); + + return (_i16)Msg.Rsp.status; + + +} +#endif + +/**********************************************************************************************/ +#if _SL_INCLUDE_FUNC(sl_NetAppMDNSRegisterService) + +_i16 sl_NetAppMDNSRegisterService( const _i8* pServiceName, + _u8 ServiceNameLen, + const _i8* pText, + _u8 TextLen, + _u16 Port, + _u32 TTL, + _u32 Options) + +{ + + /* + + NOTE - pay attention + + 1. Temporary - there is an allocation on stack of internal buffer. + Its size is NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH. + It means that the sum of the text length and service name length cannot be bigger than + NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH. + If it is - An error is returned. + + 2. According to now from certain constraints the variables parameters are set in the + attribute part (contain constant parameters) + + */ + + /*Set the add service bit in the options parameter. + In order not use different opcodes for the register service and unregister service + bit 31 in option is taken for this purpose. if it is set it means in NWP that the service should be added + if it is cleared it means that the service should be deleted and there is only meaning to pServiceName + and ServiceNameLen values. */ + Options |= NETAPP_MDNS_OPTIONS_ADD_SERVICE_BIT; + + return sl_NetAppMDNSRegisterUnregisterService( pServiceName, + ServiceNameLen, + pText, + TextLen, + Port, + TTL, + Options); + + +} +#endif +/**********************************************************************************************/ + + + +/**********************************************************************************************/ +#if _SL_INCLUDE_FUNC(sl_NetAppMDNSUnRegisterService) + +_i16 sl_NetAppMDNSUnRegisterService( const _i8* pServiceName, + _u8 ServiceNameLen) + + +{ + _u32 Options = 0; + + /* + + NOTE - pay attention + + The size of the service length should be smaller than 255, + Until the simplelink drive supports to variable length through SPI command. + + + */ + + /*Clear the add service bit in the options parameter. + In order not use different opcodes for the register service and unregister service + bit 31 in option is taken for this purpose. if it is set it means in NWP that the service should be added + if it is cleared it means that the service should be deleted and there is only meaning to pServiceName + and ServiceNameLen values.*/ + + Options &= (~NETAPP_MDNS_OPTIONS_ADD_SERVICE_BIT); + + return sl_NetAppMDNSRegisterUnregisterService( pServiceName, + ServiceNameLen, + NULL, + 0, + 0, + 0, + Options); + + +} +#endif +/**********************************************************************************************/ + + + +/*****************************************************************************/ +/* sl_DnsGetHostByService */ +/*****************************************************************************/ +/* + * The below struct depicts the constant parameters of the command/API sl_DnsGetHostByService. + * + 1. ServiceLen - The length of the service should be smaller than 255. + 2. AddrLen - TIPv4 or IPv6 (SL_AF_INET , SL_AF_INET6). +* + */ + +typedef struct +{ + _u8 ServiceLen; + _u8 AddrLen; + _u16 Padding; +}_GetHostByServiceCommand_t; + + + +/* + * The below structure depict the constant parameters that are returned in the Async event answer + * according to command/API sl_DnsGetHostByService for IPv4 and IPv6. + * + 1Status - The status of the response. + 2.Address - Contains the IP address of the service. + 3.Port - Contains the port of the service. + 4.TextLen - Contains the max length of the text that the user wants to get. + it means that if the test of service is bigger that its value than + the text is cut to inout_TextLen value. + Output: Contain the length of the text that is returned. Can be full text or part + of the text (see above). + +* + */ +typedef struct +{ + _u16 Status; + _u16 TextLen; + _u32 Port; + _u32 Address; +}_GetHostByServiceIPv4AsyncResponse_t; + + +typedef struct +{ + _u16 Status; + _u16 TextLen; + _u32 Port; + _u32 Address[4]; +}_GetHostByServiceIPv6AsyncResponse_t; + + +typedef union +{ + _GetHostByServiceIPv4AsyncResponse_t IpV4; + _GetHostByServiceIPv6AsyncResponse_t IpV6; +}_GetHostByServiceAsyncResponseAttribute_u; + +/* + * The below struct contains pointers to the output parameters that the user gives + * + */ +typedef struct +{ + _i16 Status; + _u32 *out_pAddr; + _u32 *out_pPort; + _u16 *inout_TextLen; // in: max len , out: actual len + _i8 *out_pText; +}_GetHostByServiceAsyncResponse_t; + + +typedef union +{ + _GetHostByServiceCommand_t Cmd; + _BasicResponse_t Rsp; +}_SlGetHostByServiceMsg_u; + +const _SlCmdCtrl_t _SlGetHostByServiceCtrl = +{ + SL_OPCODE_NETAPP_MDNSGETHOSTBYSERVICE, + sizeof(_GetHostByServiceCommand_t), + sizeof(_BasicResponse_t) +}; + + + +/******************************************************************************/ + +#if _SL_INCLUDE_FUNC(sl_NetAppDnsGetHostByService) +_i32 sl_NetAppDnsGetHostByService(_i8 *pServiceName, /* string containing all (or only part): name + subtype + service */ + _u8 ServiceLen, + _u8 Family, /* 4-IPv4 , 16-IPv6 */ + _u32 pAddr[], + _u32 *pPort, + _u16 *pTextLen, /* in: max len , out: actual len */ + _i8 *pText + ) +{ + _SlGetHostByServiceMsg_u Msg; + _SlCmdExt_t CmdExt ; + _GetHostByServiceAsyncResponse_t AsyncRsp; + _u8 ObjIdx = MAX_CONCURRENT_ACTIONS; + +/* + Note: + 1. The return's attributes are belonged to first service that is found. + It can be other services with the same service name will response to + the query. The results of these responses are saved in the peer cache of the NWP, and + should be read by another API. + + 2. Text length can be 120 bytes only - not more + It is because of constraints in the NWP on the buffer that is allocated for the Async event. + + 3.The API waits to Async event by blocking. It means that the API is finished only after an Async event + is sent by the NWP. + + 4.No rolling option!!! - only PTR type is sent. + + +*/ + /*build the attribute part of the command. + It contains the constant parameters of the command */ + + Msg.Cmd.ServiceLen = ServiceLen; + Msg.Cmd.AddrLen = Family; + + /*Build the payload part of the command + Copy the service name and text to one buffer.*/ + CmdExt.TxPayloadLen = ServiceLen; + CmdExt.RxPayloadLen = 0; + CmdExt.pTxPayload = (_u8 *)pServiceName; + CmdExt.pRxPayload = NULL; + + /*set pointers to the output parameters (the returned parameters). + This pointers are belonged to local struct that is set to global Async response parameter. + It is done in order not to run more than one sl_DnsGetHostByService at the same time. + The API should be run only if global parameter is pointed to NULL. */ + AsyncRsp.out_pText = pText; + AsyncRsp.inout_TextLen = (_u16* )pTextLen; + AsyncRsp.out_pPort = pPort; + AsyncRsp.out_pAddr = (_u32 *)pAddr; + + + /*Use Obj to issue the command, if not available try later */ + ObjIdx = (_u8)_SlDrvWaitForPoolObj(GETHOSYBYSERVICE_ID,SL_MAX_SOCKETS); + + if (MAX_CONCURRENT_ACTIONS == ObjIdx) + { + return SL_POOL_IS_EMPTY; + } + + OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); + + g_pCB->ObjPool[ObjIdx].pRespArgs = (void *)&AsyncRsp; + + OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); + /* set bit to indicate IPv6 address is expected */ + if (SL_AF_INET6 == Family) + { + g_pCB->ObjPool[ObjIdx].AdditionalData |= SL_NETAPP_FAMILY_MASK; + } + /* Send the command */ + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlGetHostByServiceCtrl, &Msg, &CmdExt)); + + + + /* If the immediate reponse is O.K. than wait for aSYNC event response. */ + if(SL_RET_CODE_OK == Msg.Rsp.status) + { + OSI_RET_OK_CHECK(sl_SyncObjWait(&g_pCB->ObjPool[ObjIdx].SyncObj, SL_OS_WAIT_FOREVER)); + + /* If we are - it means that Async event was sent. + The results are copied in the Async handle return functions */ + + Msg.Rsp.status = AsyncRsp.Status; + } + + _SlDrvReleasePoolObj(ObjIdx); + return Msg.Rsp.status; +} +#endif +/******************************************************************************/ + +/****************************************************************************** + _sl_HandleAsync_DnsGetHostByService + + CALLER NWP - Async event on sl_DnsGetHostByService with IPv4 Family + + + DESCRIPTION: + + Async event on sl_DnsGetHostByService command with IPv4 Family. + Return service attributes like IP address, port and text according to service name. + The user sets a service name Full/Part (see example below), and should get the: + 1. IP of the service + 2. The port of service. + 3. The text of service. + + Hence it can make a connection to the specific service and use it. + It is similar to get host by name method. + + It is done by a single shot query with PTR type on the service name. + + + + Note: + 1. The return's attributes are belonged to first service that is found. + It can be other services with the same service name will response to + the query. The results of these responses are saved in the peer cache of the NWP, and + should be read by another API. + + + PARAMETERS: + + pVoidBuf - is point to opcode of the event. + it contains the outputs that are given to the user + + outputs description: + + 1.out_pAddr[] - output: Contain the IP address of the service. + 2.out_pPort - output: Contain the port of the service. + 3.inout_TextLen - Input: Contain the max length of the text that the user wants to get. + it means that if the test of service is bigger that its value than + the text is cut to inout_TextLen value. + Output: Contain the length of the text that is returned. Can be full text or part + of the text (see above). + + 4.out_pText - Contain the text of the service (full or part see above- inout_TextLen description). + + * + + + RETURNS: success or fail. + + + + + +******************************************************************************/ +void _sl_HandleAsync_DnsGetHostByService(void *pVoidBuf) +{ + + _GetHostByServiceAsyncResponse_t* Res; + _u16 TextLen; + _u16 UserTextLen; + + + /*pVoidBuf - is point to opcode of the event.*/ + + /*set pMsgArgs to point to the attribute of the event.*/ + _GetHostByServiceIPv4AsyncResponse_t *pMsgArgs = (_GetHostByServiceIPv4AsyncResponse_t *)_SL_RESP_ARGS_START(pVoidBuf); + + VERIFY_SOCKET_CB(NULL != g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs); + + /*IPv6*/ + if(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].AdditionalData & SL_NETAPP_FAMILY_MASK) + { + return; + } + /*IPv4*/ + else + { + /************************************************************************************************* + + 1. Copy the attribute part of the evnt to the attribute part of the response + sl_Memcpy(g_pCB->GetHostByServiceCB.pAsyncRsp, pMsgArgs, sizeof(_GetHostByServiceIPv4AsyncResponse_t)); + + set to TextLen the text length of the service.*/ + TextLen = pMsgArgs->TextLen; + + /*Res pointed to mDNS global object struct */ + Res = (_GetHostByServiceAsyncResponse_t*)g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs; + + + + /*It is 4 bytes so we avoid from memcpy*/ + Res->out_pAddr[0] = pMsgArgs->Address; + Res->out_pPort[0] = pMsgArgs->Port; + Res->Status = pMsgArgs->Status; + + /*set to TextLen the text length of the user (input fromthe user).*/ + UserTextLen = Res->inout_TextLen[0]; + + /*Cut the service text if the user requested for smaller text.*/ + UserTextLen = (TextLen <= UserTextLen) ? TextLen : UserTextLen; + Res->inout_TextLen[0] = UserTextLen ; + + /************************************************************************************************** + + 2. Copy the payload part of the evnt (the text) to the payload part of the response + the lenght of the copy is according to the text length in the attribute part. */ + + + sl_Memcpy(Res->out_pText , + (_i8 *)(& pMsgArgs[1]) , /* & pMsgArgs[1] -> 1st byte after the fixed header = 1st byte of variable text.*/ + UserTextLen ); + + + /**************************************************************************************************/ + + OSI_RET_OK_CHECK(sl_SyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj)); + return; + } +} + + + +/*****************************************************************************/ +/* _sl_HandleAsync_DnsGetHostByAddr */ +/*****************************************************************************/ +void _sl_HandleAsync_DnsGetHostByAddr(void *pVoidBuf) +{ + SL_TRACE0(DBG_MSG, MSG_303, "STUB: _sl_HandleAsync_DnsGetHostByAddr not implemented yet!"); + return; +} + +/*****************************************************************************/ +/* sl_DnsGetHostByName */ +/*****************************************************************************/ +typedef union +{ + _GetHostByNameIPv4AsyncResponse_t IpV4; + _GetHostByNameIPv6AsyncResponse_t IpV6; +}_GetHostByNameAsyncResponse_u; + +typedef union +{ + _GetHostByNameCommand_t Cmd; + _BasicResponse_t Rsp; +}_SlGetHostByNameMsg_u; + +const _SlCmdCtrl_t _SlGetHostByNameCtrl = +{ + SL_OPCODE_NETAPP_DNSGETHOSTBYNAME, + sizeof(_GetHostByNameCommand_t), + sizeof(_BasicResponse_t) +}; +#if _SL_INCLUDE_FUNC(sl_NetAppDnsGetHostByName) +_i16 sl_NetAppDnsGetHostByName(_i8 * hostname, _u16 usNameLen, _u32* out_ip_addr,_u8 family) +{ + _SlGetHostByNameMsg_u Msg; + _SlCmdExt_t ExtCtrl; + _GetHostByNameAsyncResponse_u AsyncRsp; + _u8 ObjIdx = MAX_CONCURRENT_ACTIONS; + + ExtCtrl.TxPayloadLen = usNameLen; + ExtCtrl.RxPayloadLen = 0; + ExtCtrl.pTxPayload = (_u8 *)hostname; + ExtCtrl.pRxPayload = 0; + + Msg.Cmd.Len = usNameLen; + Msg.Cmd.family = family; + + /*Use Obj to issue the command, if not available try later */ + ObjIdx = (_u8)_SlDrvWaitForPoolObj(GETHOSYBYNAME_ID,SL_MAX_SOCKETS); + if (MAX_CONCURRENT_ACTIONS == ObjIdx) + { + return SL_POOL_IS_EMPTY; + } + OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); + + g_pCB->ObjPool[ObjIdx].pRespArgs = (_u8 *)&AsyncRsp; + /*set bit to indicate IPv6 address is expected */ + if (SL_AF_INET6 == family) + { + g_pCB->ObjPool[ObjIdx].AdditionalData |= SL_NETAPP_FAMILY_MASK; + } + + OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlGetHostByNameCtrl, &Msg, &ExtCtrl)); + + if(SL_RET_CODE_OK == Msg.Rsp.status) + { + OSI_RET_OK_CHECK(sl_SyncObjWait(&g_pCB->ObjPool[ObjIdx].SyncObj, SL_OS_WAIT_FOREVER)); + Msg.Rsp.status = AsyncRsp.IpV4.status; + + if(SL_OS_RET_CODE_OK == (_i16)Msg.Rsp.status) + { + sl_Memcpy((_i8 *)out_ip_addr, + (_i8 *)&AsyncRsp.IpV4.ip0, + (SL_AF_INET == family) ? SL_IPV4_ADDRESS_SIZE : SL_IPV6_ADDRESS_SIZE); + } + } + _SlDrvReleasePoolObj(ObjIdx); + return Msg.Rsp.status; +} +#endif +/******************************************************************************/ +/* _sl_HandleAsync_DnsGetHostByName */ +/******************************************************************************/ +void _sl_HandleAsync_DnsGetHostByName(void *pVoidBuf) +{ + _GetHostByNameIPv4AsyncResponse_t *pMsgArgs = (_GetHostByNameIPv4AsyncResponse_t *)_SL_RESP_ARGS_START(pVoidBuf); + + OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); + + VERIFY_SOCKET_CB(NULL != g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs); + + /*IPv6 */ + if(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].AdditionalData & SL_NETAPP_FAMILY_MASK) + { + sl_Memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(_GetHostByNameIPv6AsyncResponse_t)); + } + /*IPv4 */ + else + { + sl_Memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(_GetHostByNameIPv4AsyncResponse_t)); + } + OSI_RET_OK_CHECK(sl_SyncObjSignal(&(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj))); + + OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); + return; +} + + +void CopyPingResultsToReport(_PingReportResponse_t *pResults,SlPingReport_t *pReport) +{ + pReport->PacketsSent = pResults->numSendsPings; + pReport->PacketsReceived = pResults->numSuccsessPings; + pReport->MinRoundTime = pResults->rttMin; + pReport->MaxRoundTime = pResults->rttMax; + pReport->AvgRoundTime = pResults->rttAvg; + pReport->TestTime = pResults->testTime; +} + + +/*****************************************************************************/ +/* _sl_HandleAsync_PingResponse */ +/*****************************************************************************/ +void _sl_HandleAsync_PingResponse(void *pVoidBuf) +{ + _PingReportResponse_t *pMsgArgs = (_PingReportResponse_t *)_SL_RESP_ARGS_START(pVoidBuf); + SlPingReport_t pingReport; + + if(pPingCallBackFunc) + { + CopyPingResultsToReport(pMsgArgs,&pingReport); + pPingCallBackFunc(&pingReport); + } + else + { + + OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); + VERIFY_SOCKET_CB(NULL != g_pCB->PingCB.PingAsync.pAsyncRsp); + + if (NULL != g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs) + { + sl_Memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(_PingReportResponse_t)); + OSI_RET_OK_CHECK(sl_SyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj)); + } + OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); + } + return; +} + + +/*****************************************************************************/ +/* sl_PingStart */ +/*****************************************************************************/ +typedef union +{ + _PingStartCommand_t Cmd; + _PingReportResponse_t Rsp; +}_SlPingStartMsg_u; + + +typedef enum +{ + CMD_PING_TEST_RUNNING = 0, + CMD_PING_TEST_STOPPED +}_SlPingStatus_e; + + +#if _SL_INCLUDE_FUNC(sl_NetAppPingStart) +_i16 sl_NetAppPingStart(SlPingStartCommand_t* pPingParams,_u8 family,SlPingReport_t *pReport,const P_SL_DEV_PING_CALLBACK pPingCallback) +{ + _SlCmdCtrl_t CmdCtrl = {0, sizeof(_PingStartCommand_t), sizeof(_BasicResponse_t)}; + _SlPingStartMsg_u Msg; + _PingReportResponse_t PingRsp; + _u8 ObjIdx = MAX_CONCURRENT_ACTIONS; + + if( 0 == pPingParams->Ip ) // stop any ongoing ping + { + return _SlDrvBasicCmd(SL_OPCODE_NETAPP_PINGSTOP); + } + + if(SL_AF_INET == family) + { + CmdCtrl.Opcode = SL_OPCODE_NETAPP_PINGSTART; + sl_Memcpy(&Msg.Cmd.ip0, &pPingParams->Ip, SL_IPV4_ADDRESS_SIZE); + } + else + { + CmdCtrl.Opcode = SL_OPCODE_NETAPP_PINGSTART_V6; + sl_Memcpy(&Msg.Cmd.ip0, &pPingParams->Ip, SL_IPV6_ADDRESS_SIZE); + } + + Msg.Cmd.pingIntervalTime = pPingParams->PingIntervalTime; + Msg.Cmd.PingSize = pPingParams->PingSize; + Msg.Cmd.pingRequestTimeout = pPingParams->PingRequestTimeout; + Msg.Cmd.totalNumberOfAttempts = pPingParams->TotalNumberOfAttempts; + Msg.Cmd.flags = pPingParams->Flags; + + if( pPingCallback ) + { + pPingCallBackFunc = pPingCallback; + } + else + { + /*Use Obj to issue the command, if not available try later */ + ObjIdx = (_u8)_SlDrvWaitForPoolObj(PING_ID,SL_MAX_SOCKETS); + if (MAX_CONCURRENT_ACTIONS == ObjIdx) + { + return SL_POOL_IS_EMPTY; + } + OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); + /* async response handler for non callback mode */ + g_pCB->ObjPool[ObjIdx].pRespArgs = (_u8 *)&PingRsp; + pPingCallBackFunc = NULL; + OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); + } + + + VERIFY_RET_OK(_SlDrvCmdOp(&CmdCtrl, &Msg, NULL)); + /*send the command*/ + if(CMD_PING_TEST_RUNNING == (_i16)Msg.Rsp.status || CMD_PING_TEST_STOPPED == (_i16)Msg.Rsp.status ) + { + /* block waiting for results if no callback function is used */ + if( NULL == pPingCallback ) + { + OSI_RET_OK_CHECK(sl_SyncObjWait(&g_pCB->ObjPool[ObjIdx].SyncObj, SL_OS_WAIT_FOREVER)); + if( SL_OS_RET_CODE_OK == (_i16)PingRsp.status ) + { + CopyPingResultsToReport(&PingRsp,pReport); + } + _SlDrvReleasePoolObj(ObjIdx); + } + } + else + { /* ping failure, no async response */ + if( NULL == pPingCallback ) + { + _SlDrvReleasePoolObj(ObjIdx); + } + } + + return Msg.Rsp.status; +} +#endif + +/*****************************************************************************/ +/* sl_NetAppSet */ +/*****************************************************************************/ +typedef union +{ + _NetAppSetGet_t Cmd; + _BasicResponse_t Rsp; +}_SlNetAppMsgSet_u; + +const _SlCmdCtrl_t _SlNetAppSetCmdCtrl = +{ + SL_OPCODE_NETAPP_NETAPPSET, + sizeof(_NetAppSetGet_t), + sizeof(_BasicResponse_t) +}; + +#if _SL_INCLUDE_FUNC(sl_NetAppSet) +_i32 sl_NetAppSet(_u8 AppId ,_u8 Option,_u8 OptionLen, _u8 *pOptionValue) +{ + _SlNetAppMsgSet_u Msg; + _SlCmdExt_t CmdExt; + + CmdExt.TxPayloadLen = (OptionLen+3) & (~3); + CmdExt.RxPayloadLen = 0; + CmdExt.pTxPayload = (_u8 *)pOptionValue; + CmdExt.pRxPayload = NULL; + + + Msg.Cmd.AppId = AppId; + Msg.Cmd.ConfigLen = OptionLen; + Msg.Cmd.ConfigOpt = Option; + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlNetAppSetCmdCtrl, &Msg, &CmdExt)); + + return (_i16)Msg.Rsp.status; +} +#endif + +/*****************************************************************************/ +/* sl_NetAppSendTokenValue */ +/*****************************************************************************/ +typedef union +{ + sl_NetAppHttpServerSendToken_t Cmd; + _BasicResponse_t Rsp; +}_SlNetAppMsgSendTokenValue_u; + +const _SlCmdCtrl_t _SlNetAppSendTokenValueCmdCtrl = +{ + SL_OPCODE_NETAPP_HTTPSENDTOKENVALUE, + sizeof(sl_NetAppHttpServerSendToken_t), + sizeof(_BasicResponse_t) +}; + +_u16 sl_NetAppSendTokenValue(slHttpServerData_t * Token_value) +{ + _SlNetAppMsgSendTokenValue_u Msg; + _SlCmdExt_t CmdExt; + + CmdExt.TxPayloadLen = (Token_value->value_len+3) & (~3); + CmdExt.RxPayloadLen = 0; + CmdExt.pTxPayload = (_u8 *) Token_value->token_value; + CmdExt.pRxPayload = NULL; + + Msg.Cmd.token_value_len = Token_value->value_len; + Msg.Cmd.token_name_len = Token_value->name_len; + sl_Memcpy(&Msg.Cmd.token_name[0], Token_value->token_name, Token_value->name_len); + + + VERIFY_RET_OK(_SlDrvCmdSend((_SlCmdCtrl_t *)&_SlNetAppSendTokenValueCmdCtrl, &Msg, &CmdExt)); + + return Msg.Rsp.status; +} + +/*****************************************************************************/ +/* sl_NetAppGet */ +/*****************************************************************************/ +typedef union +{ + _NetAppSetGet_t Cmd; + _NetAppSetGet_t Rsp; +}_SlNetAppMsgGet_u; + +const _SlCmdCtrl_t _SlNetAppGetCmdCtrl = +{ + SL_OPCODE_NETAPP_NETAPPGET, + sizeof(_NetAppSetGet_t), + sizeof(_NetAppSetGet_t) +}; + +#if _SL_INCLUDE_FUNC(sl_NetAppGet) +_i32 sl_NetAppGet(_u8 AppId, _u8 Option,_u8 *pOptionLen, _u8 *pOptionValue) +{ + _SlNetAppMsgGet_u Msg; + _SlCmdExt_t CmdExt; + + if (*pOptionLen == 0) + { + return SL_EZEROLEN; + } + CmdExt.TxPayloadLen = 0; + CmdExt.RxPayloadLen = *pOptionLen; + CmdExt.pTxPayload = NULL; + CmdExt.pRxPayload = (_u8 *)pOptionValue; + CmdExt.ActualRxPayloadLen = 0; + + Msg.Cmd.AppId = AppId; + Msg.Cmd.ConfigOpt = Option; + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlNetAppGetCmdCtrl, &Msg, &CmdExt)); + + + if (CmdExt.RxPayloadLen < CmdExt.ActualRxPayloadLen) + { + *pOptionLen = (_u8)CmdExt.RxPayloadLen; + return SL_ESMALLBUF; + } + else + { + *pOptionLen = (_u8)CmdExt.ActualRxPayloadLen; + } + + return (_i16)Msg.Rsp.Status; +} +#endif + + +/*****************************************************************************/ +/* _SlDrvNetAppEventHandler */ +/*****************************************************************************/ +void _SlDrvNetAppEventHandler(void *pArgs) +{ + _SlResponseHeader_t *pHdr = (_SlResponseHeader_t *)pArgs; +#ifdef sl_HttpServerCallback + SlHttpServerEvent_t httpServerEvent; + SlHttpServerResponse_t httpServerResponse; +#endif + switch(pHdr->GenHeader.Opcode) + { + case SL_OPCODE_NETAPP_DNSGETHOSTBYNAMEASYNCRESPONSE: + case SL_OPCODE_NETAPP_DNSGETHOSTBYNAMEASYNCRESPONSE_V6: + _sl_HandleAsync_DnsGetHostByName(pArgs); + break; + case SL_OPCODE_NETAPP_MDNSGETHOSTBYSERVICEASYNCRESPONSE: + case SL_OPCODE_NETAPP_MDNSGETHOSTBYSERVICEASYNCRESPONSE_V6: + _sl_HandleAsync_DnsGetHostByService(pArgs); + break; + case SL_OPCODE_NETAPP_PINGREPORTREQUESTRESPONSE: + _sl_HandleAsync_PingResponse(pArgs); + break; + case SL_OPCODE_NETAPP_HTTPGETTOKENVALUE: + { +#ifdef sl_HttpServerCallback + _u8 *pTokenName; + slHttpServerData_t Token_value; + sl_NetAppHttpServerGetToken_t *httpGetToken = (sl_NetAppHttpServerGetToken_t *)_SL_RESP_ARGS_START(pHdr); + pTokenName = (_u8 *)((sl_NetAppHttpServerGetToken_t *)httpGetToken + 1); + + httpServerResponse.Response = SL_NETAPP_HTTPSETTOKENVALUE; + httpServerResponse.ResponseData.token_value.len = MAX_TOKEN_VALUE_LEN; + httpServerResponse.ResponseData.token_value.data = (_u8 *)_SL_RESP_ARGS_START(pHdr) + MAX_TOKEN_NAME_LEN; //Reuse the async buffer for getting the token value response from the user + + httpServerEvent.Event = SL_NETAPP_HTTPGETTOKENVALUE_EVENT; + httpServerEvent.EventData.httpTokenName.len = httpGetToken->token_name_len; + httpServerEvent.EventData.httpTokenName.data = pTokenName; + + Token_value.token_name = pTokenName; + + sl_HttpServerCallback (&httpServerEvent, &httpServerResponse); + + Token_value.value_len = httpServerResponse.ResponseData.token_value.len; + Token_value.name_len = httpServerEvent.EventData.httpTokenName.len; + + Token_value.token_value = httpServerResponse.ResponseData.token_value.data; + + + sl_NetAppSendTokenValue(&Token_value); +#endif + } + break; + + case SL_OPCODE_NETAPP_HTTPPOSTTOKENVALUE: + { +#ifdef sl_HttpServerCallback + _u8 *pPostParams; + + sl_NetAppHttpServerPostToken_t *httpPostTokenArgs = (sl_NetAppHttpServerPostToken_t *)_SL_RESP_ARGS_START(pHdr); + pPostParams = (_u8 *)((sl_NetAppHttpServerPostToken_t *)httpPostTokenArgs + 1); + + httpServerEvent.Event = SL_NETAPP_HTTPPOSTTOKENVALUE_EVENT; + + httpServerEvent.EventData.httpPostData.action.len = httpPostTokenArgs->post_action_len; + httpServerEvent.EventData.httpPostData.action.data = pPostParams; + pPostParams+=httpPostTokenArgs->post_action_len; + + httpServerEvent.EventData.httpPostData.token_name.len = httpPostTokenArgs->token_name_len; + httpServerEvent.EventData.httpPostData.token_name.data = pPostParams; + pPostParams+=httpPostTokenArgs->token_name_len; + + httpServerEvent.EventData.httpPostData.token_value.len = httpPostTokenArgs->token_value_len; + httpServerEvent.EventData.httpPostData.token_value.data = pPostParams; + + httpServerResponse.Response = SL_NETAPP_RESPONSE_NONE; + + + sl_HttpServerCallback (&httpServerEvent, &httpServerResponse); +#endif + } + break; + default: + SL_ERROR_TRACE1(MSG_305, "ASSERT: _SlDrvNetAppEventHandler : invalid opcode = 0x%x", pHdr->GenHeader.Opcode); + VERIFY_PROTOCOL(0); + } +} diff --git a/cc3200/simplelink/source/netcfg.c b/cc3200/simplelink/source/netcfg.c new file mode 100644 index 000000000..36d1e1fa9 --- /dev/null +++ b/cc3200/simplelink/source/netcfg.c @@ -0,0 +1,142 @@ +/* +* netcfg.c - CC31xx/CC32xx Host Driver Implementation +* +* Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the +* distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +*/ + + + +/*****************************************************************************/ +/* Include files */ +/*****************************************************************************/ +#include "simplelink.h" +#include "protocol.h" +#include "driver.h" + +/*****************************************************************************/ +/* sl_NetCfgSet */ +/*****************************************************************************/ +typedef union +{ + _NetCfgSetGet_t Cmd; + _BasicResponse_t Rsp; +}_SlNetCfgMsgSet_u; + +const _SlCmdCtrl_t _SlNetCfgSetCmdCtrl = +{ + SL_OPCODE_DEVICE_NETCFG_SET_COMMAND, + sizeof(_NetCfgSetGet_t), + sizeof(_BasicResponse_t) +}; + +#if _SL_INCLUDE_FUNC(sl_NetCfgSet) +_i32 sl_NetCfgSet(_u8 ConfigId ,_u8 ConfigOpt,_u8 ConfigLen, _u8 *pValues) +{ + _SlNetCfgMsgSet_u Msg; + _SlCmdExt_t CmdExt; + + CmdExt.TxPayloadLen = (ConfigLen+3) & (~3); + CmdExt.RxPayloadLen = 0; + CmdExt.pTxPayload = (_u8 *)pValues; + CmdExt.pRxPayload = NULL; + + + Msg.Cmd.ConfigId = ConfigId; + Msg.Cmd.ConfigLen = ConfigLen; + Msg.Cmd.ConfigOpt = ConfigOpt; + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlNetCfgSetCmdCtrl, &Msg, &CmdExt)); + + return (_i16)Msg.Rsp.status; +} +#endif + + +/*****************************************************************************/ +/* sl_NetCfgGet */ +/*****************************************************************************/ +typedef union +{ + _NetCfgSetGet_t Cmd; + _NetCfgSetGet_t Rsp; +}_SlNetCfgMsgGet_u; + +const _SlCmdCtrl_t _SlNetCfgGetCmdCtrl = +{ + SL_OPCODE_DEVICE_NETCFG_GET_COMMAND, + sizeof(_NetCfgSetGet_t), + sizeof(_NetCfgSetGet_t) +}; + +#if _SL_INCLUDE_FUNC(sl_NetCfgGet) +_i32 sl_NetCfgGet(_u8 ConfigId, _u8 *pConfigOpt,_u8 *pConfigLen, _u8 *pValues) +{ + _SlNetCfgMsgGet_u Msg; + _SlCmdExt_t CmdExt; + + if (*pConfigLen == 0) + { + return SL_EZEROLEN; + } + CmdExt.TxPayloadLen = 0; + CmdExt.RxPayloadLen = *pConfigLen; + CmdExt.pTxPayload = NULL; + CmdExt.pRxPayload = (_u8 *)pValues; + CmdExt.ActualRxPayloadLen = 0; + Msg.Cmd.ConfigLen = *pConfigLen; + Msg.Cmd.ConfigId = ConfigId; + + if( pConfigOpt ) + { + Msg.Cmd.ConfigOpt = (_u16)*pConfigOpt; + } + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlNetCfgGetCmdCtrl, &Msg, &CmdExt)); + + if( pConfigOpt ) + { + *pConfigOpt = (_u8)Msg.Rsp.ConfigOpt; + } + if (CmdExt.RxPayloadLen < CmdExt.ActualRxPayloadLen) + { + *pConfigLen = (_u8)CmdExt.RxPayloadLen; + return SL_ESMALLBUF; + } + else + { + *pConfigLen = (_u8)CmdExt.ActualRxPayloadLen; + } + + return (_i16)Msg.Rsp.Status; +} +#endif + diff --git a/cc3200/simplelink/source/nonos.c b/cc3200/simplelink/source/nonos.c new file mode 100644 index 000000000..9e7d1772e --- /dev/null +++ b/cc3200/simplelink/source/nonos.c @@ -0,0 +1,153 @@ +/* +* nonos.c - CC31xx/CC32xx Host Driver Implementation +* +* Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the +* distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +*/ + + + +/*****************************************************************************/ +/* Include files */ +/*****************************************************************************/ +#include "simplelink.h" +#include "protocol.h" +#include "driver.h" + +#ifndef SL_PLATFORM_MULTI_THREADED + +#include "nonos.h" + +#define NONOS_MAX_SPAWN_ENTRIES 5 + +typedef struct +{ + _SlSpawnEntryFunc_t pEntry; + void* pValue; +}_SlNonOsSpawnEntry_t; + +typedef struct +{ + _SlNonOsSpawnEntry_t SpawnEntries[NONOS_MAX_SPAWN_ENTRIES]; +}_SlNonOsCB_t; + +_SlNonOsCB_t g__SlNonOsCB; + + +_SlNonOsRetVal_t _SlNonOsSemSet(_SlNonOsSemObj_t* pSemObj , _SlNonOsSemObj_t Value) +{ + *pSemObj = Value; + return NONOS_RET_OK; +} + +_SlNonOsRetVal_t _SlNonOsSemGet(_SlNonOsSemObj_t* pSyncObj, _SlNonOsSemObj_t WaitValue, _SlNonOsSemObj_t SetValue, _SlNonOsTime_t Timeout) +{ + while (Timeout>0) + { + if (WaitValue == *pSyncObj) + { + *pSyncObj = SetValue; + break; + } + if (Timeout != NONOS_WAIT_FOREVER) + { + Timeout--; + } + _SlNonOsMainLoopTask(); +#ifdef _SlSyncWaitLoopCallback + if( __NON_OS_SYNC_OBJ_SIGNAL_VALUE == WaitValue ) + { + if (WaitValue == *pSyncObj) + { + *pSyncObj = SetValue; + break; + } + _SlSyncWaitLoopCallback(); + } +#endif + } + + if (0 == Timeout) + { + return NONOS_RET_ERR; + } + else + { + return NONOS_RET_OK; + } +} + + +_SlNonOsRetVal_t _SlNonOsSpawn(_SlSpawnEntryFunc_t pEntry , void* pValue , _u32 flags) +{ + _i16 i; + + for (i=0 ; i<NONOS_MAX_SPAWN_ENTRIES ; i++) + { + _SlNonOsSpawnEntry_t* pE = &g__SlNonOsCB.SpawnEntries[i]; + + if (NULL == pE->pEntry) + { + pE->pValue = pValue; + pE->pEntry = pEntry; + break; + } + } + + return NONOS_RET_OK; +} + + +_SlNonOsRetVal_t _SlNonOsMainLoopTask(void) +{ + _i16 i; + + for (i=0 ; i<NONOS_MAX_SPAWN_ENTRIES ; i++) + { + _SlNonOsSpawnEntry_t* pE = &g__SlNonOsCB.SpawnEntries[i]; + _SlSpawnEntryFunc_t pF = pE->pEntry; + + if (NULL != pF) + { + if((g_pCB)->RxIrqCnt != (g_pCB)->RxDoneCnt) + { + pF(0);/*(pValue);*/ + } + pE->pEntry = NULL; + pE->pValue = NULL; + } + } + + return NONOS_RET_OK; +} + +#endif /*(SL_PLATFORM != SL_PLATFORM_NON_OS)*/ diff --git a/cc3200/simplelink/source/nonos.h b/cc3200/simplelink/source/nonos.h new file mode 100644 index 000000000..a888a90cf --- /dev/null +++ b/cc3200/simplelink/source/nonos.h @@ -0,0 +1,325 @@ +/* + * nonos.h - CC31xx/CC32xx Host Driver Implementation + * + * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + +#ifndef __NONOS_H__ +#define __NONOS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifndef SL_PLATFORM_MULTI_THREADED + +/* This function call the user defined function, if defined, from the sync wait loop */ +/* The use case of this function is to allow nonos system to call a user function to put the device into sleep */ +/* The wake up should be activated after getting an interrupt from the device to Host */ +/* The user function must return without blocking to prevent a delay on the event handling */ +/* +#define _SlSyncWaitLoopCallback UserSleepFunction +*/ + + + +#define NONOS_WAIT_FOREVER 0xFF +#define NONOS_NO_WAIT 0x01 + +#define NONOS_RET_OK (0) +#define NONOS_RET_ERR (0xFF) +#define OSI_OK NONOS_RET_OK + +#define __NON_OS_SYNC_OBJ_CLEAR_VALUE 0x11 +#define __NON_OS_SYNC_OBJ_SIGNAL_VALUE 0x22 +#define __NON_OS_LOCK_OBJ_UNLOCK_VALUE 0x33 +#define __NON_OS_LOCK_OBJ_LOCK_VALUE 0x44 + +/*! + \brief type definition for the return values of this adaptation layer +*/ +typedef _i8 _SlNonOsRetVal_t; + +/*! + \brief type definition for a time value +*/ +typedef _u8 _SlNonOsTime_t; + +/*! + \brief type definition for a sync object container + + Sync object is object used to synchronize between two threads or thread and interrupt handler. + One thread is waiting on the object and the other thread send a signal, which then + release the waiting thread. + The signal must be able to be sent from interrupt context. + This object is generally implemented by binary semaphore or events. +*/ +typedef _u8 _SlNonOsSemObj_t; + + +#define _SlTime_t _SlNonOsTime_t + +#define _SlSyncObj_t _SlNonOsSemObj_t + +#define _SlLockObj_t _SlNonOsSemObj_t + +#define SL_OS_WAIT_FOREVER NONOS_WAIT_FOREVER + +#define SL_OS_RET_CODE_OK NONOS_RET_OK + +#define SL_OS_NO_WAIT NONOS_NO_WAIT + + + + + +/*! + \brief This function creates a sync object + + The sync object is used for synchronization between different thread or ISR and + a thread. + + \param pSyncObj - pointer to the sync object control block + + \return upon successful creation the function return 0 + Otherwise, a negative value indicating the error code shall be returned + \note + \warning +*/ +#define _SlNonOsSyncObjCreate(pSyncObj) _SlNonOsSemSet(pSyncObj,__NON_OS_SYNC_OBJ_CLEAR_VALUE) + +/*! + \brief This function deletes a sync object + + \param pSyncObj - pointer to the sync object control block + + \return upon successful deletion the function should return 0 + Otherwise, a negative value indicating the error code shall be returned + \note + \warning +*/ +#define _SlNonOsSyncObjDelete(pSyncObj) _SlNonOsSemSet(pSyncObj,0) + +/*! + \brief This function generates a sync signal for the object. + + All suspended threads waiting on this sync object are resumed + + \param pSyncObj - pointer to the sync object control block + + \return upon successful signaling the function should return 0 + Otherwise, a negative value indicating the error code shall be returned + \note the function could be called from ISR context + \warning +*/ +#define _SlNonOsSyncObjSignal(pSyncObj) _SlNonOsSemSet(pSyncObj,__NON_OS_SYNC_OBJ_SIGNAL_VALUE) + +/*! + \brief This function waits for a sync signal of the specific sync object + + \param pSyncObj - pointer to the sync object control block + \param Timeout - numeric value specifies the maximum number of mSec to + stay suspended while waiting for the sync signal + Currently, the simple link driver uses only two values: + - NONOS_WAIT_FOREVER + - NONOS_NO_WAIT + + \return upon successful reception of the signal within the timeout window return 0 + Otherwise, a negative value indicating the error code shall be returned + \note + \warning +*/ +#define _SlNonOsSyncObjWait(pSyncObj , Timeout) _SlNonOsSemGet(pSyncObj,__NON_OS_SYNC_OBJ_SIGNAL_VALUE,__NON_OS_SYNC_OBJ_CLEAR_VALUE,Timeout) + +/*! + \brief This function clears a sync object + + \param pSyncObj - pointer to the sync object control block + + \return upon successful clearing the function should return 0 + Otherwise, a negative value indicating the error code shall be returned + \note + \warning +*/ +#define _SlNonOsSyncObjClear(pSyncObj) _SlNonOsSemSet(pSyncObj,__NON_OS_SYNC_OBJ_CLEAR_VALUE) + +/*! + \brief This function creates a locking object. + + The locking object is used for protecting a shared resources between different + threads. + + \param pLockObj - pointer to the locking object control block + + \return upon successful creation the function should return 0 + Otherwise, a negative value indicating the error code shall be returned + \note + \warning +*/ +#define _SlNonOsLockObjCreate(pLockObj) _SlNonOsSemSet(pLockObj,__NON_OS_LOCK_OBJ_UNLOCK_VALUE) + +/*! + \brief This function deletes a locking object. + + \param pLockObj - pointer to the locking object control block + + \return upon successful deletion the function should return 0 + Otherwise, a negative value indicating the error code shall be returned + \note + \warning +*/ +#define _SlNonOsLockObjDelete(pLockObj) _SlNonOsSemSet(pLockObj,0) + +/*! + \brief This function locks a locking object. + + All other threads that call this function before this thread calls + the _SlNonOsLockObjUnlock would be suspended + + \param pLockObj - pointer to the locking object control block + \param Timeout - numeric value specifies the maximum number of mSec to + stay suspended while waiting for the locking object + Currently, the simple link driver uses only two values: + - NONOS_WAIT_FOREVER + - NONOS_NO_WAIT + + + \return upon successful reception of the locking object the function should return 0 + Otherwise, a negative value indicating the error code shall be returned + \note + \warning +*/ +#define _SlNonOsLockObjLock(pLockObj , Timeout) _SlNonOsSemGet(pLockObj,__NON_OS_LOCK_OBJ_UNLOCK_VALUE,__NON_OS_LOCK_OBJ_LOCK_VALUE,Timeout) + +/*! + \brief This function unlock a locking object. + + \param pLockObj - pointer to the locking object control block + + \return upon successful unlocking the function should return 0 + Otherwise, a negative value indicating the error code shall be returned + \note + \warning +*/ +#define _SlNonOsLockObjUnlock(pLockObj) _SlNonOsSemSet(pLockObj,__NON_OS_LOCK_OBJ_UNLOCK_VALUE) + + +/*! + \brief This function call the pEntry callback from a different context + + \param pEntry - pointer to the entry callback function + + \param pValue - pointer to any type of memory structure that would be + passed to pEntry callback from the execution thread. + + \param flags - execution flags - reserved for future usage + + \return upon successful registration of the spawn the function return 0 + (the function is not blocked till the end of the execution of the function + and could be returned before the execution is actually completed) + Otherwise, a negative value indicating the error code shall be returned + \note + \warning +*/ +_SlNonOsRetVal_t _SlNonOsSpawn(_SlSpawnEntryFunc_t pEntry , void* pValue , _u32 flags); + + +/*! + \brief This function must be called from the main loop in non-os paltforms + + \param None + + \return 0 - No more activities + 1 - Activity still in progress + \note + \warning +*/ +_SlNonOsRetVal_t _SlNonOsMainLoopTask(void); + +extern _SlNonOsRetVal_t _SlNonOsSemGet(_SlNonOsSemObj_t* pSyncObj, _SlNonOsSemObj_t WaitValue, _SlNonOsSemObj_t SetValue, _SlNonOsTime_t Timeout); +extern _SlNonOsRetVal_t _SlNonOsSemSet(_SlNonOsSemObj_t* pSemObj , _SlNonOsSemObj_t Value); +extern _SlNonOsRetVal_t _SlNonOsSpawn(_SlSpawnEntryFunc_t pEntry , void* pValue , _u32 flags); + +#if (defined(_SlSyncWaitLoopCallback)) +extern void _SlSyncWaitLoopCallback(void); +#endif + + +/***************************************************************************** + + Overwrite SimpleLink driver OS adaptation functions + + + *****************************************************************************/ + +#undef sl_SyncObjCreate +#define sl_SyncObjCreate(pSyncObj,pName) _SlNonOsSemSet(pSyncObj,__NON_OS_SYNC_OBJ_CLEAR_VALUE) + +#undef sl_SyncObjDelete +#define sl_SyncObjDelete(pSyncObj) _SlNonOsSemSet(pSyncObj,0) + +#undef sl_SyncObjSignal +#define sl_SyncObjSignal(pSyncObj) _SlNonOsSemSet(pSyncObj,__NON_OS_SYNC_OBJ_SIGNAL_VALUE) + +#undef sl_SyncObjSignalFromIRQ +#define sl_SyncObjSignalFromIRQ(pSyncObj) _SlNonOsSemSet(pSyncObj,__NON_OS_SYNC_OBJ_SIGNAL_VALUE) + +#undef sl_SyncObjWait +#define sl_SyncObjWait(pSyncObj,Timeout) _SlNonOsSemGet(pSyncObj,__NON_OS_SYNC_OBJ_SIGNAL_VALUE,__NON_OS_SYNC_OBJ_CLEAR_VALUE,Timeout) + +#undef sl_LockObjCreate +#define sl_LockObjCreate(pLockObj,pName) _SlNonOsSemSet(pLockObj,__NON_OS_LOCK_OBJ_UNLOCK_VALUE) + +#undef sl_LockObjDelete +#define sl_LockObjDelete(pLockObj) _SlNonOsSemSet(pLockObj,0) + +#undef sl_LockObjLock +#define sl_LockObjLock(pLockObj,Timeout) _SlNonOsSemGet(pLockObj,__NON_OS_LOCK_OBJ_UNLOCK_VALUE,__NON_OS_LOCK_OBJ_LOCK_VALUE,Timeout) + +#undef sl_LockObjUnlock +#define sl_LockObjUnlock(pLockObj) _SlNonOsSemSet(pLockObj,__NON_OS_LOCK_OBJ_UNLOCK_VALUE) + +#undef sl_Spawn +#define sl_Spawn(pEntry,pValue,flags) _SlNonOsSpawn(pEntry,pValue,flags) + +#undef _SlTaskEntry +#define _SlTaskEntry _SlNonOsMainLoopTask + +#endif /* !SL_PLATFORM_MULTI_THREADED */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/cc3200/simplelink/source/objInclusion.h b/cc3200/simplelink/source/objInclusion.h new file mode 100644 index 000000000..c63672405 --- /dev/null +++ b/cc3200/simplelink/source/objInclusion.h @@ -0,0 +1,325 @@ +/* + * objInclusion.h - CC31xx/CC32xx Host Driver Implementation + * + * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + +#include <simplelink.h> + +#ifndef OBJINCLUSION_H_ +#define OBJINCLUSION_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************** + + For future use + +*******************************************************************************/ + +#define __inln /* if inline functions requiered: #define __inln inline */ + +#define SL_DEVICE /* Device silo is currently always mandatory */ + + + +/****************************************************************************** + + Qualifiers for package customizations + +*******************************************************************************/ + +#if defined (SL_DEVICE) +#define __dev 1 +#else +#define __dev 0 +#endif + +#if defined (SL_DEVICE) && defined (SL_INC_EXT_API) +#define __dev__ext 1 +#else +#define __dev__ext 0 +#endif + + +#if (!defined (SL_PLATFORM_MULTI_THREADED)) || (!defined (SL_PLATFORM_EXTERNAL_SPAWN)) +#define __int__spwn 1 +#else +#define __int__spwn 0 +#endif + +#if defined (SL_INC_NET_APP_PKG) +#define __nap 1 +#else +#define __nap 0 +#endif + +#if defined (SL_INC_NET_APP_PKG) && defined (SL_INC_SOCK_CLIENT_SIDE_API) +#define __nap__clt 1 +#else +#define __nap__clt 0 +#endif + +#if defined (SL_INC_NET_APP_PKG) && defined (SL_INC_EXT_API) +#define __nap__ext 1 +#else +#define __nap__ext 0 +#endif + +#if defined (SL_INC_NET_CFG_PKG) +#define __ncg 1 +#else +#define __ncg 0 +#endif + +#if defined (SL_INC_NET_CFG_PKG) && defined (SL_INC_EXT_API) +#define __ncg__ext 1 +#else +#define __ncg__ext 0 +#endif + +#if defined (SL_INC_NVMEM_PKG) +#define __nvm 1 +#else +#define __nvm 0 +#endif + +#if defined (SL_INC_SOCKET_PKG) +#define __sck 1 +#else +#define __sck 0 +#endif + +#if defined (SL_INC_SOCKET_PKG) && defined (SL_INC_EXT_API) +#define __sck__ext 1 +#else +#define __sck__ext 0 +#endif + +#if defined (SL_INC_SOCKET_PKG) && defined (SL_INC_SOCK_SERVER_SIDE_API) +#define __sck__srv 1 +#else +#define __sck__srv 0 +#endif + +#if defined (SL_INC_SOCKET_PKG) && defined (SL_INC_SOCK_CLIENT_SIDE_API) +#define __sck__clt 1 +#else +#define __sck__clt 0 +#endif + +#if defined (SL_INC_SOCKET_PKG) && defined (SL_INC_SOCK_RECV_API) +#define __sck__rcv 1 +#else +#define __sck__rcv 0 +#endif + +#if defined (SL_INC_SOCKET_PKG) && defined (SL_INC_SOCK_SEND_API) +#define __sck__snd 1 +#else +#define __sck__snd 0 +#endif + +#if defined (SL_INC_WLAN_PKG) +#define __wln 1 +#else +#define __wln 0 +#endif + +#if defined (SL_INC_WLAN_PKG) && defined (SL_INC_EXT_API) +#define __wln__ext 1 +#else +#define __wln__ext 0 +#endif + +/* The return 1 is the function need to be included in the output */ +#define _SL_INCLUDE_FUNC(Name) (_SL_INC_##Name) + +/* Driver */ +#define _SL_INC_sl_NetAppStart __nap + +#define _SL_INC_sl_NetAppStop __nap + +#define _SL_INC_sl_NetAppDnsGetHostByName __nap__clt + + +#define _SL_INC_sl_NetAppDnsGetHostByService __nap__clt +#define _SL_INC_sl_NetAppMDNSRegisterService __nap__clt +#define _SL_INC_sl_NetAppMDNSUnRegisterService __nap__clt +#define _SL_INC_sl_NetAppMDNSRegisterUnregisterService __nap__clt +#define _SL_INC_sl_NetAppGetServiceList __nap__clt + + +#define _SL_INC_sl_DnsGetHostByAddr __nap__ext + +#define _SL_INC_sl_NetAppPingStart __nap + +#define _SL_INC_sl_NetAppPingReport __nap + +/* FS */ +#define _SL_INC_sl_FsOpen __nvm + +#define _SL_INC_sl_FsClose __nvm + +#define _SL_INC_sl_FsRead __nvm + +#define _SL_INC_sl_FsWrite __nvm + +#define _SL_INC_sl_FsGetInfo __nvm + +#define _SL_INC_sl_FsDel __nvm + +/* netcfg */ +#define _SL_INC_sl_MacAdrrSet __ncg + +#define _SL_INC_sl_MacAdrrGet __ncg + +#define _SL_INC_sl_NetCfgGet __ncg + +#define _SL_INC_sl_NetCfgSet __ncg + +#define _SL_INC_sl_NetAppSet __nap + +#define _SL_INC_sl_NetAppGet __nap + +/* socket */ +#define _SL_INC_sl_Socket __sck + +#define _SL_INC_sl_Close __sck__ext + +#define _SL_INC_sl_Accept __sck__srv + +#define _SL_INC_sl_Bind __sck + +#define _SL_INC_sl_Listen __sck__srv + +#define _SL_INC_sl_Connect __sck__clt + +#define _SL_INC_sl_Select __sck + +#define _SL_INC_sl_SetSockOpt __sck + +#define _SL_INC_sl_GetSockOpt __sck__ext + +#define _SL_INC_sl_Recv __sck__rcv + +#define _SL_INC_sl_RecvFrom __sck__rcv + +#define _SL_INC_sl_Write __sck__snd + +#define _SL_INC_sl_Send __sck__snd + +#define _SL_INC_sl_SendTo __sck__snd + +#define _SL_INC_sl_Htonl __sck + +#define _SL_INC_sl_Htons __sck + +/* wlan */ +#define _SL_INC_sl_WlanConnect __wln__ext + +#define _SL_INC_sl_WlanDisconnect __wln__ext + +#define _SL_INC_sl_WlanProfileAdd __wln__ext + +#define _SL_INC_sl_WlanProfileGet __wln__ext + +#define _SL_INC_sl_WlanProfileDel __wln__ext + +#define _SL_INC_sl_WlanPolicySet __wln__ext + +#define _SL_INC_sl_WlanPolicyGet __wln__ext + +#define _SL_INC_sl_WlanGetNetworkList __wln__ext + +#define _SL_INC_sl_WlanRxFilterAdd __wln__ext + +#define _SL_INC_sl_WlanRxFilterSet __wln__ext + +#define _SL_INC_sl_WlanRxFilterGet __wln__ext + +#define _SL_INC_sl_SmartConfigStart __wln + +#define _SL_INC_sl_SmartConfigOptSet __wln__ext + + +#define _SL_INC_sl_WlanSmartConfigStart __wln + +#define _SL_INC_sl_WlanSmartConfigStop __wln + +#define _SL_INC_sl_WlanSetMode __wln + +#define _SL_INC_sl_WlanSet __wln + +#define _SL_INC_sl_WlanGet __wln + +#define _SL_INC_sl_SmartConfigOptSet __wln__ext + +#define _SL_INC_sl_SmartConfigOptGet __wln__ext + +#define _SL_INC_sl_WlanRxStatStart __wln__ext + +#define _SL_INC_sl_WlanRxStatStop __wln__ext + +#define _SL_INC_sl_WlanRxStatGet __wln__ext + + +/* device */ +#define _SL_INC_sl_Task __int__spwn + +#define _SL_INC_sl_Start __dev + +#define _SL_INC_sl_Stop __dev + +#define _SL_INC_sl_StatusGet __dev + +#ifdef SL_IF_TYPE_UART +#define _SL_INC_sl_UartSetMode __dev +#endif + +#define _SL_INC_sl_EventMaskGet __dev__ext + +#define _SL_INC_sl_EventMaskSet __dev__ext + +#define _SL_INC_sl_DevGet __dev__ext + +#define _SL_INC_sl_DevSet __dev__ext + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /*OBJINCLUSION_H_ */ diff --git a/cc3200/simplelink/source/protocol.h b/cc3200/simplelink/source/protocol.h new file mode 100644 index 000000000..f83ad4c3d --- /dev/null +++ b/cc3200/simplelink/source/protocol.h @@ -0,0 +1,1176 @@ +/* + * protocol.h - CC31xx/CC32xx Host Driver Implementation + * + * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + +/*******************************************************************************\ +* +* FILE NAME: protocol.h +* +* DESCRIPTION: Constant and data structure definitions and function +* prototypes for the SL protocol module, which implements +* processing of SimpleLink Commands. +* +* AUTHOR: +* +\*******************************************************************************/ + +#ifndef _SL_PROTOCOL_TYPES_H_ +#define _SL_PROTOCOL_TYPES_H_ + +/**************************************************************************** +** +** User I/F pools definitions +** +****************************************************************************/ + +/**************************************************************************** +** +** Definitions for SimpleLink Commands +** +****************************************************************************/ + + +/* pattern for LE 8/16/32 or BE*/ +#define H2N_SYNC_PATTERN {0xBBDDEEFF,0x4321,0x34,0x12} +#define H2N_CNYS_PATTERN {0xBBDDEEFF,0x8765,0x78,0x56} + +#define H2N_DUMMY_PATTERN (_u32)0xFFFFFFFF +#define N2H_SYNC_PATTERN (_u32)0xABCDDCBA +#define SYNC_PATTERN_LEN (_u32)sizeof(_u32) +#define UART_SET_MODE_MAGIC_CODE (_u32)0xAA55AA55 +#define SPI_16BITS_BUG(pattern) (_u32)((_u32)pattern & (_u32)0xFFFF7FFF) +#define SPI_8BITS_BUG(pattern) (_u32)((_u32)pattern & (_u32)0xFFFFFF7F) + + + +typedef struct +{ + _u16 Opcode; + _u16 Len; +}_SlGenericHeader_t; + + +typedef struct +{ + _u32 Long; + _u16 Short; + _u8 Byte1; + _u8 Byte2; +}_SlSyncPattern_t; + +typedef _SlGenericHeader_t _SlCommandHeader_t; + +typedef struct +{ + _SlGenericHeader_t GenHeader; + _u8 TxPoolCnt; + _u8 DevStatus; + _u8 SocketTXFailure; + _u8 SocketNonBlocking; +}_SlResponseHeader_t; + +#define _SL_RESP_SPEC_HDR_SIZE (sizeof(_SlResponseHeader_t) - sizeof(_SlGenericHeader_t)) +#define _SL_RESP_HDR_SIZE sizeof(_SlResponseHeader_t) +#define _SL_CMD_HDR_SIZE sizeof(_SlCommandHeader_t) + +#define _SL_RESP_ARGS_START(_pMsg) (((_SlResponseHeader_t *)(_pMsg)) + 1) + +/* Used only in NWP! */ +typedef struct +{ + _SlCommandHeader_t sl_hdr; + _u8 func_args_start; +} T_SCMD; + + +#define WLAN_CONN_STATUS_BIT 0x01 +#define EVENTS_Q_STATUS_BIT 0x02 +#define PENDING_RCV_CMD_BIT 0x04 +#define FW_BUSY_PACKETS_BIT 0x08 + +#define INIT_STA_OK 0x11111111 +#define INIT_STA_ERR 0x22222222 +#define INIT_AP_OK 0x33333333 +#define INIT_AP_ERR 0x44444444 +#define INIT_P2P_OK 0x55555555 +#define INIT_P2P_ERR 0x66666666 + +/**************************************************************************** +** OPCODES +****************************************************************************/ +#define SL_IPV4_IPV6_OFFSET ( 9 ) +#define SL_OPCODE_IPV4 ( 0x0 << SL_IPV4_IPV6_OFFSET ) +#define SL_OPCODE_IPV6 ( 0x1 << SL_IPV4_IPV6_OFFSET ) + +#define SL_SYNC_ASYNC_OFFSET ( 10 ) +#define SL_OPCODE_SYNC (0x1 << SL_SYNC_ASYNC_OFFSET ) +#define SL_OPCODE_SILO_OFFSET ( 11 ) +#define SL_OPCODE_SILO_MASK ( 0xF << SL_OPCODE_SILO_OFFSET ) +#define SL_OPCODE_SILO_DEVICE ( 0x0 << SL_OPCODE_SILO_OFFSET ) +#define SL_OPCODE_SILO_WLAN ( 0x1 << SL_OPCODE_SILO_OFFSET ) +#define SL_OPCODE_SILO_SOCKET ( 0x2 << SL_OPCODE_SILO_OFFSET ) +#define SL_OPCODE_SILO_NETAPP ( 0x3 << SL_OPCODE_SILO_OFFSET ) +#define SL_OPCODE_SILO_NVMEM ( 0x4 << SL_OPCODE_SILO_OFFSET ) +#define SL_OPCODE_SILO_NETCFG ( 0x5 << SL_OPCODE_SILO_OFFSET ) + +#define SL_FAMILY_SHIFT (0x4) +#define SL_FLAGS_MASK (0xF) + +#define SL_OPCODE_DEVICE_INITCOMPLETE 0x0008 +#define SL_OPCODE_DEVICE_STOP_COMMAND 0x8473 +#define SL_OPCODE_DEVICE_STOP_RESPONSE 0x0473 +#define SL_OPCODE_DEVICE_STOP_ASYNC_RESPONSE 0x0073 +#define SL_OPCODE_DEVICE_DEVICEASYNCDUMMY 0x0063 + +#define SL_OPCODE_DEVICE_VERSIONREADCOMMAND 0x8470 +#define SL_OPCODE_DEVICE_VERSIONREADRESPONSE 0x0470 +#define SL_OPCODE_DEVICE_DEVICEASYNCFATALERROR 0x0078 +#define SL_OPCODE_WLAN_WLANCONNECTCOMMAND 0x8C80 +#define SL_OPCODE_WLAN_WLANCONNECTRESPONSE 0x0C80 +#define SL_OPCODE_WLAN_WLANASYNCCONNECTEDRESPONSE 0x0880 +#define SL_OPCODE_WLAN_P2P_DEV_FOUND 0x0830 +#define SL_OPCODE_WLAN_CONNECTION_FAILED 0x0831 +#define SL_OPCODE_WLAN_P2P_NEG_REQ_RECEIVED 0x0832 + +#define SL_OPCODE_WLAN_WLANDISCONNECTCOMMAND 0x8C81 +#define SL_OPCODE_WLAN_WLANDISCONNECTRESPONSE 0x0C81 +#define SL_OPCODE_WLAN_WLANASYNCDISCONNECTEDRESPONSE 0x0881 +#define SL_OPCODE_WLAN_WLANCONNECTEAPCOMMAND 0x8C82 +#define SL_OPCODE_WLAN_WLANCONNECTEAPCRESPONSE 0x0C82 +#define SL_OPCODE_WLAN_PROFILEADDCOMMAND 0x8C83 +#define SL_OPCODE_WLAN_PROFILEADDRESPONSE 0x0C83 +#define SL_OPCODE_WLAN_PROFILEGETCOMMAND 0x8C84 +#define SL_OPCODE_WLAN_PROFILEGETRESPONSE 0x0C84 +#define SL_OPCODE_WLAN_PROFILEDELCOMMAND 0x8C85 +#define SL_OPCODE_WLAN_PROFILEDELRESPONSE 0x0C85 +#define SL_OPCODE_WLAN_POLICYSETCOMMAND 0x8C86 +#define SL_OPCODE_WLAN_POLICYSETRESPONSE 0x0C86 +#define SL_OPCODE_WLAN_POLICYGETCOMMAND 0x8C87 +#define SL_OPCODE_WLAN_POLICYGETRESPONSE 0x0C87 +#define SL_OPCODE_WLAN_FILTERADD 0x8C88 +#define SL_OPCODE_WLAN_FILTERADDRESPONSE 0x0C88 +#define SL_OPCODE_WLAN_FILTERGET 0x8C89 +#define SL_OPCODE_WLAN_FILTERGETRESPONSE 0x0C89 +#define SL_OPCODE_WLAN_FILTERDELETE 0x8C8A +#define SL_OPCODE_WLAN_FILTERDELETERESPOSNE 0x0C8A +#define SL_OPCODE_WLAN_WLANGETSTATUSCOMMAND 0x8C8F +#define SL_OPCODE_WLAN_WLANGETSTATUSRESPONSE 0x0C8F +#define SL_OPCODE_WLAN_STARTTXCONTINUESCOMMAND 0x8CAA +#define SL_OPCODE_WLAN_STARTTXCONTINUESRESPONSE 0x0CAA +#define SL_OPCODE_WLAN_STOPTXCONTINUESCOMMAND 0x8CAB +#define SL_OPCODE_WLAN_STOPTXCONTINUESRESPONSE 0x0CAB +#define SL_OPCODE_WLAN_STARTRXSTATCOMMAND 0x8CAC +#define SL_OPCODE_WLAN_STARTRXSTATRESPONSE 0x0CAC +#define SL_OPCODE_WLAN_STOPRXSTATCOMMAND 0x8CAD +#define SL_OPCODE_WLAN_STOPRXSTATRESPONSE 0x0CAD +#define SL_OPCODE_WLAN_GETRXSTATCOMMAND 0x8CAF +#define SL_OPCODE_WLAN_GETRXSTATRESPONSE 0x0CAF +#define SL_OPCODE_WLAN_POLICYSETCOMMANDNEW 0x8CB0 +#define SL_OPCODE_WLAN_POLICYSETRESPONSENEW 0x0CB0 +#define SL_OPCODE_WLAN_POLICYGETCOMMANDNEW 0x8CB1 +#define SL_OPCODE_WLAN_POLICYGETRESPONSENEW 0x0CB1 + +#define SL_OPCODE_WLAN_SMART_CONFIG_START_COMMAND 0x8CB2 +#define SL_OPCODE_WLAN_SMART_CONFIG_START_RESPONSE 0x0CB2 +#define SL_OPCODE_WLAN_SMART_CONFIG_START_ASYNC_RESPONSE 0x08B2 +#define SL_OPCODE_WLAN_SMART_CONFIG_STOP_COMMAND 0x8CB3 +#define SL_OPCODE_WLAN_SMART_CONFIG_STOP_RESPONSE 0x0CB3 +#define SL_OPCODE_WLAN_SMART_CONFIG_STOP_ASYNC_RESPONSE 0x08B3 +#define SL_OPCODE_WLAN_SET_MODE 0x8CB4 +#define SL_OPCODE_WLAN_SET_MODE_RESPONSE 0x0CB4 +#define SL_OPCODE_WLAN_CFG_SET 0x8CB5 +#define SL_OPCODE_WLAN_CFG_SET_RESPONSE 0x0CB5 +#define SL_OPCODE_WLAN_CFG_GET 0x8CB6 +#define SL_OPCODE_WLAN_CFG_GET_RESPONSE 0x0CB6 +#define SL_OPCODE_WLAN_STA_CONNECTED 0x082E +#define SL_OPCODE_WLAN_STA_DISCONNECTED 0x082F +#define SL_OPCODE_WLAN_EAP_PROFILEADDCOMMAND 0x8C67 +#define SL_OPCODE_WLAN_EAP_PROFILEADDCOMMAND_RESPONSE 0x0C67 + +#define SL_OPCODE_SOCKET_SOCKET 0x9401 +#define SL_OPCODE_SOCKET_SOCKETRESPONSE 0x1401 +#define SL_OPCODE_SOCKET_CLOSE 0x9402 +#define SL_OPCODE_SOCKET_CLOSERESPONSE 0x1402 +#define SL_OPCODE_SOCKET_ACCEPT 0x9403 +#define SL_OPCODE_SOCKET_ACCEPTRESPONSE 0x1403 +#define SL_OPCODE_SOCKET_ACCEPTASYNCRESPONSE 0x1003 +#define SL_OPCODE_SOCKET_ACCEPTASYNCRESPONSE_V6 0x1203 +#define SL_OPCODE_SOCKET_BIND 0x9404 +#define SL_OPCODE_SOCKET_BIND_V6 0x9604 +#define SL_OPCODE_SOCKET_BINDRESPONSE 0x1404 +#define SL_OPCODE_SOCKET_LISTEN 0x9405 +#define SL_OPCODE_SOCKET_LISTENRESPONSE 0x1405 +#define SL_OPCODE_SOCKET_CONNECT 0x9406 +#define SL_OPCODE_SOCKET_CONNECT_V6 0x9606 +#define SL_OPCODE_SOCKET_CONNECTRESPONSE 0x1406 +#define SL_OPCODE_SOCKET_CONNECTASYNCRESPONSE 0x1006 +#define SL_OPCODE_SOCKET_SELECT 0x9407 +#define SL_OPCODE_SOCKET_SELECTRESPONSE 0x1407 +#define SL_OPCODE_SOCKET_SELECTASYNCRESPONSE 0x1007 +#define SL_OPCODE_SOCKET_SETSOCKOPT 0x9408 +#define SL_OPCODE_SOCKET_SETSOCKOPTRESPONSE 0x1408 +#define SL_OPCODE_SOCKET_GETSOCKOPT 0x9409 +#define SL_OPCODE_SOCKET_GETSOCKOPTRESPONSE 0x1409 +#define SL_OPCODE_SOCKET_RECV 0x940A +#define SL_OPCODE_SOCKET_RECVASYNCRESPONSE 0x100A +#define SL_OPCODE_SOCKET_RECVFROM 0x940B +#define SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE 0x100B +#define SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE_V6 0x120B +#define SL_OPCODE_SOCKET_SEND 0x940C +#define SL_OPCODE_SOCKET_SENDTO 0x940D +#define SL_OPCODE_SOCKET_SENDTO_V6 0x960D +#define SL_OPCODE_SOCKET_TXFAILEDASYNCRESPONSE 0x100E +#define SL_OPCODE_SOCKET_SOCKETASYNCEVENT 0x100F +#define SL_OPCODE_NETAPP_START_COMMAND 0x9C0A +#define SL_OPCODE_NETAPP_START_RESPONSE 0x1C0A +#define SL_OPCODE_NETAPP_NETAPPSTARTRESPONSE 0x1C0A +#define SL_OPCODE_NETAPP_STOP_COMMAND 0x9C61 +#define SL_OPCODE_NETAPP_STOP_RESPONSE 0x1C61 +#define SL_OPCODE_NETAPP_NETAPPSET 0x9C0B +#define SL_OPCODE_NETAPP_NETAPPSETRESPONSE 0x1C0B +#define SL_OPCODE_NETAPP_NETAPPGET 0x9C27 +#define SL_OPCODE_NETAPP_NETAPPGETRESPONSE 0x1C27 +#define SL_OPCODE_NETAPP_DNSGETHOSTBYNAME 0x9C20 +#define SL_OPCODE_NETAPP_DNSGETHOSTBYNAMERESPONSE 0x1C20 +#define SL_OPCODE_NETAPP_DNSGETHOSTBYNAMEASYNCRESPONSE 0x1820 +#define SL_OPCODE_NETAPP_DNSGETHOSTBYNAMEASYNCRESPONSE_V6 0x1A20 +#define SL_OPCODE_NETAPP_NETAPP_MDNS_LOOKUP_SERVICE 0x9C71 +#define SL_OPCODE_NETAPP_NETAPP_MDNS_LOOKUP_SERVICE_RESPONSE 0x1C72 +#define SL_OPCODE_NETAPP_MDNSREGISTERSERVICE 0x9C34 +#define SL_OPCODE_NETAPP_MDNSREGISTERSERVICERESPONSE 0x1C34 +#define SL_OPCODE_NETAPP_MDNSGETHOSTBYSERVICE 0x9C35 +#define SL_OPCODE_NETAPP_MDNSGETHOSTBYSERVICERESPONSE 0x1C35 +#define SL_OPCODE_NETAPP_MDNSGETHOSTBYSERVICEASYNCRESPONSE 0x1835 +#define SL_OPCODE_NETAPP_MDNSGETHOSTBYSERVICEASYNCRESPONSE_V6 0x1A35 +#define SL_OPCODE_NETAPP_DNSGETHOSTBYADDR 0x9C26 +#define SL_OPCODE_NETAPP_DNSGETHOSTBYADDR_V6 0x9E26 +#define SL_OPCODE_NETAPP_DNSGETHOSTBYADDRRESPONSE 0x1C26 +#define SL_OPCODE_NETAPP_DNSGETHOSTBYADDRASYNCRESPONSE 0x1826 +#define SL_OPCODE_NETAPP_PINGSTART 0x9C21 +#define SL_OPCODE_NETAPP_PINGSTART_V6 0x9E21 +#define SL_OPCODE_NETAPP_PINGSTARTRESPONSE 0x1C21 +#define SL_OPCODE_NETAPP_PINGREPORTREQUEST 0x9C22 +#define SL_OPCODE_NETAPP_PINGREPORTREQUESTRESPONSE 0x1822 +#define SL_OPCODE_NETAPP_PINGSTOP 0x9C23 +#define SL_OPCODE_NETAPP_PINGSTOPRESPONSE 0x1C23 +#define SL_OPCODE_NETAPP_ARPFLUSH 0x9C24 +#define SL_OPCODE_NETAPP_ARPFLUSHRESPONSE 0x1C24 +#define SL_OPCODE_NETAPP_IPACQUIRED 0x1825 +#define SL_OPCODE_NETAPP_IPV4_LOST 0x1832 +#define SL_OPCODE_NETAPP_DHCP_IPV4_ACQUIRE_TIMEOUT 0x1833 +#define SL_OPCODE_NETAPP_IPACQUIRED_V6 0x1A25 +#define SL_OPCODE_NETAPP_IPERFSTARTCOMMAND 0x9C28 +#define SL_OPCODE_NETAPP_IPERFSTARTRESPONSE 0x1C28 +#define SL_OPCODE_NETAPP_IPERFSTOPCOMMAND 0x9C29 +#define SL_OPCODE_NETAPP_IPERFSTOPRESPONSE 0x1C29 +#define SL_OPCODE_NETAPP_CTESTSTARTCOMMAND 0x9C2A +#define SL_OPCODE_NETAPP_CTESTSTARTRESPONSE 0x1C2A +#define SL_OPCODE_NETAPP_CTESTASYNCRESPONSE 0x182A +#define SL_OPCODE_NETAPP_CTESTSTOPCOMMAND 0x9C2B +#define SL_OPCODE_NETAPP_CTESTSTOPRESPONSE 0x1C2B +#define SL_OPCODE_NETAPP_IP_LEASED 0x182C +#define SL_OPCODE_NETAPP_IP_RELEASED 0x182D +#define SL_OPCODE_NETAPP_HTTPGETTOKENVALUE 0x182E +#define SL_OPCODE_NETAPP_HTTPSENDTOKENVALUE 0x9C2F +#define SL_OPCODE_NETAPP_HTTPPOSTTOKENVALUE 0x1830 +#define SL_OPCODE_NVMEM_FILEOPEN 0xA43C +#define SL_OPCODE_NVMEM_FILEOPENRESPONSE 0x243C +#define SL_OPCODE_NVMEM_FILECLOSE 0xA43D +#define SL_OPCODE_NVMEM_FILECLOSERESPONSE 0x243D +#define SL_OPCODE_NVMEM_FILEREADCOMMAND 0xA440 +#define SL_OPCODE_NVMEM_FILEREADRESPONSE 0x2440 +#define SL_OPCODE_NVMEM_FILEWRITECOMMAND 0xA441 +#define SL_OPCODE_NVMEM_FILEWRITERESPONSE 0x2441 +#define SL_OPCODE_NVMEM_FILEGETINFOCOMMAND 0xA442 +#define SL_OPCODE_NVMEM_FILEGETINFORESPONSE 0x2442 +#define SL_OPCODE_NVMEM_FILEDELCOMMAND 0xA443 +#define SL_OPCODE_NVMEM_FILEDELRESPONSE 0x2443 +#define SL_OPCODE_NVMEM_NVMEMFORMATCOMMAND 0xA444 +#define SL_OPCODE_NVMEM_NVMEMFORMATRESPONSE 0x2444 + +#define SL_OPCODE_DEVICE_SETDEBUGLEVELCOMMAND 0x846A +#define SL_OPCODE_DEVICE_SETDEBUGLEVELRESPONSE 0x046A + +#define SL_OPCODE_DEVICE_NETCFG_SET_COMMAND 0x8432 +#define SL_OPCODE_DEVICE_NETCFG_SET_RESPONSE 0x0432 +#define SL_OPCODE_DEVICE_NETCFG_GET_COMMAND 0x8433 +#define SL_OPCODE_DEVICE_NETCFG_GET_RESPONSE 0x0433 +/* */ +#define SL_OPCODE_DEVICE_SETUARTMODECOMMAND 0x846B +#define SL_OPCODE_DEVICE_SETUARTMODERESPONSE 0x046B +#define SL_OPCODE_DEVICE_SSISIZESETCOMMAND 0x846B +#define SL_OPCODE_DEVICE_SSISIZESETRESPONSE 0x046B + +/* */ +#define SL_OPCODE_DEVICE_EVENTMASKSET 0x8464 +#define SL_OPCODE_DEVICE_EVENTMASKSETRESPONSE 0x0464 +#define SL_OPCODE_DEVICE_EVENTMASKGET 0x8465 +#define SL_OPCODE_DEVICE_EVENTMASKGETRESPONSE 0x0465 + +#define SL_OPCODE_DEVICE_DEVICEGET 0x8466 +#define SL_OPCODE_DEVICE_DEVICEGETRESPONSE 0x0466 +#define SL_OPCODE_DEVICE_DEVICESET 0x84B7 +#define SL_OPCODE_DEVICE_DEVICESETRESPONSE 0x04B7 + +#define SL_OPCODE_WLAN_SCANRESULTSGETCOMMAND 0x8C8C +#define SL_OPCODE_WLAN_SCANRESULTSGETRESPONSE 0x0C8C +#define SL_OPCODE_WLAN_SMARTCONFIGOPTSET 0x8C8D +#define SL_OPCODE_WLAN_SMARTCONFIGOPTSETRESPONSE 0x0C8D +#define SL_OPCODE_WLAN_SMARTCONFIGOPTGET 0x8C8E +#define SL_OPCODE_WLAN_SMARTCONFIGOPTGETRESPONSE 0x0C8E + +#define SL_OPCODE_FREE_BSD_RECV_BUFFER 0xCCCB +#define SL_OPCODE_FREE_NON_BSD_READ_BUFFER 0xCCCD + + +/* Rx Filters opcodes */ +#define SL_OPCODE_WLAN_WLANRXFILTERADDCOMMAND 0x8C6C +#define SL_OPCODE_WLAN_WLANRXFILTERADDRESPONSE 0x0C6C +#define SL_OPCODE_WLAN_WLANRXFILTERSETCOMMAND 0x8C6D +#define SL_OPCODE_WLAN_WLANRXFILTERSETRESPONSE 0x0C6D +#define SL_OPCODE_WLAN_WLANRXFILTERGETSTATISTICSINFOCOMMAND 0x8C6E +#define SL_OPCODE_WLAN_WLANRXFILTERGETSTATISTICSINFORESPONSE 0x0C6E +#define SL_OPCODE_WLAN_WLANRXFILTERGETCOMMAND 0x8C6F +#define SL_OPCODE_WLAN_WLANRXFILTERGETRESPONSE 0x0C6F +#define SL_OPCODE_WLAN_WLANRXFILTERGETINFO 0x8C70 +#define SL_OPCODE_WLAN_WLANRXFILTERGETINFORESPONSE 0x0C70 + + +/******************************************************************************************/ +/* Device structs */ +/******************************************************************************************/ +typedef _u32 InitStatus_t; + + +typedef struct +{ + _i32 Status; +}InitComplete_t; + +typedef struct +{ + _i16 status; + _u16 padding; + +}_BasicResponse_t; + +typedef struct +{ + _u16 Timeout; + _u16 padding; +}_DevStopCommand_t; + +typedef struct +{ + _u32 group; + _u32 mask; +}_DevMaskEventSetCommand_t; + +typedef _BasicResponse_t _DevMaskEventSetResponse_t; + + +typedef struct +{ + _u32 group; +}_DevMaskEventGetCommand_t; + + +typedef struct +{ + _u32 group; + _u32 mask; +}_DevMaskEventGetResponse_t; + + +typedef struct +{ + _u32 group; +}_DevStatusGetCommand_t; + + +typedef struct +{ + _u32 group; + _u32 status; +}_DevStatusGetResponse_t; + +typedef struct +{ + _u32 ChipId; + _u32 FwVersion[4]; + _u8 PhyVersion[4]; +}_Device_VersionReadResponsePart_t; + +typedef struct +{ + _Device_VersionReadResponsePart_t part; + _u32 NwpVersion[4]; + _u16 RomVersion; + _u16 Padding; +}_Device_VersionReadResponseFull_t; + + +typedef struct +{ + _u32 BaudRate; + _u8 FlowControlEnable; +}_DevUartSetModeCommand_t; + +typedef _BasicResponse_t _DevUartSetModeResponse_t; + +/******************************************************/ + +typedef struct +{ + _u8 SsiSizeInBytes; + _u8 Padding[3]; +}_StellarisSsiSizeSet_t; + +/*****************************************************************************************/ +/* WLAN structs */ +/*****************************************************************************************/ +#define MAXIMAL_PASSWORD_LENGTH (64) + +typedef struct{ + _u8 SecType; + _u8 SsidLen; + _u8 Bssid[6]; + _u8 PasswordLen; +}_WlanConnectCommon_t; + +#define SSID_STRING(pCmd) (_i8 *)((_WlanConnectCommon_t *)(pCmd) + 1) +#define PASSWORD_STRING(pCmd) (SSID_STRING(pCmd) + ((_WlanConnectCommon_t *)(pCmd))->SsidLen) + +typedef struct{ + _WlanConnectCommon_t Common; + _u8 UserLen; + _u8 AnonUserLen; + _u8 CertIndex; + _u32 EapBitmask; +}_WlanConnectEapCommand_t; + +#define EAP_SSID_STRING(pCmd) (_i8 *)((_WlanConnectEapCommand_t *)(pCmd) + 1) +#define EAP_PASSWORD_STRING(pCmd) (EAP_SSID_STRING(pCmd) + ((_WlanConnectEapCommand_t *)(pCmd))->Common.SsidLen) +#define EAP_USER_STRING(pCmd) (EAP_PASSWORD_STRING(pCmd) + ((_WlanConnectEapCommand_t *)(pCmd))->Common.PasswordLen) +#define EAP_ANON_USER_STRING(pCmd) (EAP_USER_STRING(pCmd) + ((_WlanConnectEapCommand_t *)(pCmd))->UserLen) + + +typedef struct +{ + _u8 PolicyType; + _u8 Padding; + _u8 PolicyOption; + _u8 PolicyOptionLen; +}_WlanPoliciySetGet_t; + + +typedef struct{ + _u32 minDwellTime; + _u32 maxDwellTime; + _u32 numProbeResponse; + _u32 G_Channels_mask; + _i32 rssiThershold; + _i32 snrThershold; + _i32 defaultTXPower; + _u16 intervalList[16]; +}_WlanScanParamSetCommand_t; + + +typedef struct{ + _i8 SecType; + _u8 SsidLen; + _u8 Priority; + _u8 Bssid[6]; + _u8 PasswordLen; + _u8 WepKeyId; +}_WlanAddGetProfile_t; + + +typedef struct{ + _WlanAddGetProfile_t Common; + _u8 UserLen; + _u8 AnonUserLen; + _u8 CertIndex; + _u16 padding; + _u32 EapBitmask; +}_WlanAddGetEapProfile_t; + + + + +#define PROFILE_SSID_STRING(pCmd) ((_i8 *)((_WlanAddGetProfile_t *)(pCmd) + 1)) +#define PROFILE_PASSWORD_STRING(pCmd) (PROFILE_SSID_STRING(pCmd) + ((_WlanAddGetProfile_t *)(pCmd))->SsidLen) + +#define EAP_PROFILE_SSID_STRING(pCmd) (_i8 *)((_WlanAddGetEapProfile_t *)(pCmd) + 1) +#define EAP_PROFILE_PASSWORD_STRING(pCmd) (EAP_PROFILE_SSID_STRING(pCmd) + ((_WlanAddGetEapProfile_t *)(pCmd))->Common.SsidLen) +#define EAP_PROFILE_USER_STRING(pCmd) (EAP_PROFILE_PASSWORD_STRING(pCmd) + ((_WlanAddGetEapProfile_t *)(pCmd))->Common.PasswordLen) +#define EAP_PROFILE_ANON_USER_STRING(pCmd) (EAP_PROFILE_USER_STRING(pCmd) + ((_WlanAddGetEapProfile_t *)(pCmd))->UserLen) + + + +typedef struct +{ + _u8 index; + _u8 padding[3]; +}_WlanProfileDelGetCommand_t; + +typedef _BasicResponse_t _WlanGetNetworkListResponse_t; + +typedef struct +{ + _u8 index; + _u8 count; + _i8 padding[2]; +}_WlanGetNetworkListCommand_t; + + + + +typedef struct +{ + _u32 groupIdBitmask; + _u8 cipher; + _u8 publicKeyLen; + _u8 group1KeyLen; + _u8 group2KeyLen; +}_WlanSmartConfigStartCommand_t; + +#define SMART_CONFIG_START_PUBLIC_KEY_STRING(pCmd) ((_i8 *)((_WlanSmartConfigStartCommand_t *)(pCmd) + 1)) +#define SMART_CONFIG_START_GROUP1_KEY_STRING(pCmd) ((_i8 *) (SMART_CONFIG_START_PUBLIC_KEY_STRING(pCmd) + ((_WlanSmartConfigStartCommand_t *)(pCmd))->publicKeyLen)) +#define SMART_CONFIG_START_GROUP2_KEY_STRING(pCmd) ((_i8 *) (SMART_CONFIG_START_GROUP1_KEY_STRING(pCmd) + ((_WlanSmartConfigStartCommand_t *)(pCmd))->group1KeyLen)) + + + +typedef struct +{ + _u8 mode; + _u8 padding[3]; +}_WlanSetMode_t; + + + + +typedef struct +{ + _u16 Status; + _u16 ConfigId; + _u16 ConfigOpt; + _u16 ConfigLen; +}_WlanCfgSetGet_t; + + +/* ******************************************************************************/ +/* RX filters - Start */ +/* ******************************************************************************/ +/* -- 80 bytes */ +typedef struct _WlanRxFilterAddCommand_t +{ + /* -- 1 byte */ + SlrxFilterRuleType_t RuleType; + /* -- 1 byte */ + SlrxFilterFlags_t FilterFlags; + /* -- 1 byte */ + SlrxFilterID_t FilterId; + /* -- 1 byte */ + _u8 Padding; + /* -- 56 byte */ + SlrxFilterRule_t Rule; + /* -- 12 byte ( 3 padding ) */ + SlrxFilterTrigger_t Trigger; + /* -- 8 byte */ + SlrxFilterAction_t Action; +}_WlanRxFilterAddCommand_t; + + + +/* -- 4 bytes */ +typedef struct l_WlanRxFilterAddCommandReponse_t +{ + /* -- 1 byte */ + SlrxFilterID_t FilterId; + /* -- 1 Byte */ + _u8 Status; + /* -- 2 byte */ + _u8 Padding[2]; + +}_WlanRxFilterAddCommandReponse_t; + + + +/* + * \struct _WlanRxFilterSetCommand_t + */ +typedef struct _WlanRxFilterSetCommand_t +{ + _u16 InputBufferLength; + /* 1 byte */ + SLrxFilterOperation_t RxFilterOperation; + _u8 Padding[1]; +}_WlanRxFilterSetCommand_t; + +/** + * \struct _WlanRxFilterSetCommandReponse_t + */ +typedef struct _WlanRxFilterSetCommandReponse_t +{ + /* 1 byte */ + _u8 Status; + /* 3 bytes */ + _u8 Padding[3]; + +}_WlanRxFilterSetCommandReponse_t; + +/** + * \struct _WlanRxFilterGetCommand_t + */ +typedef struct _WlanRxFilterGetCommand_t +{ + _u16 OutputBufferLength; + /* 1 byte */ + SLrxFilterOperation_t RxFilterOperation; + _u8 Padding[1]; +}_WlanRxFilterGetCommand_t; + +/** + * \struct _WlanRxFilterGetCommandReponse_t + */ +typedef struct _WlanRxFilterGetCommandReponse_t +{ + /* 1 byte */ + _u8 Status; + /* 1 bytes */ + _u8 Padding; + /* 2 byte */ + _u16 OutputBufferLength; + +}_WlanRxFilterGetCommandReponse_t; + + + +/* ******************************************************************************/ +/* RX filters -- End */ +/* ******************************************************************************/ + +typedef struct +{ + _u16 status; + _u8 WlanRole; /* 0 = station, 2 = AP */ + _u8 Ipv6Enabled; + _u8 Ipv6DhcpEnabled; + + _u32 ipV6Global[4]; + _u32 ipV6Local[4]; + _u32 ipV6DnsServer[4]; + _u8 Ipv6DhcpState; + +}_NetappIpV6configRetArgs_t; + + +typedef struct +{ + _u8 ipV4[4]; + _u8 ipV4Mask[4]; + _u8 ipV4Gateway[4]; + _u8 ipV4DnsServer[4]; + _u8 ipV4Start[4]; + _u8 ipV4End[4]; +}_NetCfgIpV4AP_Args_t; + + + +typedef struct +{ + _u16 status; + _u8 MacAddr[6]; +} _MAC_Address_SetGet_t; + + +typedef struct +{ + _u16 Status; + _u16 ConfigId; + _u16 ConfigOpt; + _u16 ConfigLen; +}_NetCfgSetGet_t; + +typedef struct +{ + _u16 Status; + _u16 DeviceSetId; + _u16 Option; + _u16 ConfigLen; +}_DeviceSetGet_t; + + + + +/******************************************************************************************/ +/* Socket structs */ +/******************************************************************************************/ + +typedef struct +{ + _u8 Domain; + _u8 Type; + _u8 Protocol; + _u8 Padding; +}_SocketCommand_t; + + +typedef struct +{ + _i16 statusOrLen; + _u8 sd; + _u8 padding; +}_SocketResponse_t; + +typedef struct +{ + _u8 sd; + _u8 family; + _u8 padding1; + _u8 padding2; +}_AcceptCommand_t; + + +typedef struct +{ + _i16 statusOrLen; + _u8 sd; + _u8 family; + _u16 port; + _u16 paddingOrAddr; + _u32 address; +}_SocketAddrAsyncIPv4Response_t; + +typedef struct +{ + _i16 statusOrLen; + _u8 sd; + _u8 family; + _u16 port; + _u8 address[6]; +}_SocketAddrAsyncIPv6EUI48Response_t; +typedef struct +{ + _i16 statusOrLen; + _u8 sd; + _u8 family; + _u16 port; + _u16 paddingOrAddr; + _u32 address[4]; +}_SocketAddrAsyncIPv6Response_t; + + +typedef struct +{ + _i16 lenOrPadding; + _u8 sd; + _u8 FamilyAndFlags; + _u16 port; + _u16 paddingOrAddr; + _u32 address; +}_SocketAddrIPv4Command_t; + +typedef struct +{ + _i16 lenOrPadding; + _u8 sd; + _u8 FamilyAndFlags; + _u16 port; + _u8 address[6]; +}_SocketAddrIPv6EUI48Command_t; +typedef struct +{ + _i16 lenOrPadding; + _u8 sd; + _u8 FamilyAndFlags; + _u16 port; + _u16 paddingOrAddr; + _u32 address[4]; +}_SocketAddrIPv6Command_t; + +typedef union { + _SocketAddrIPv4Command_t IpV4; + _SocketAddrIPv6EUI48Command_t IpV6EUI48; +#ifdef SL_SUPPORT_IPV6 + _SocketAddrIPv6Command_t IpV6; +#endif +} _SocketAddrCommand_u; + +typedef union { + _SocketAddrAsyncIPv4Response_t IpV4; + _SocketAddrAsyncIPv6EUI48Response_t IpV6EUI48; +#ifdef SL_SUPPORT_IPV6 + _SocketAddrAsyncIPv6Response_t IpV6; +#endif +} _SocketAddrResponse_u; + +typedef struct +{ + _u8 sd; + _u8 backlog; + _u8 padding1; + _u8 padding2; +}_ListenCommand_t; + +typedef struct +{ + _u8 sd; + _u8 padding0; + _u8 padding1; + _u8 padding2; +}_CloseCommand_t; + + +typedef struct +{ + _u8 nfds; + _u8 readFdsCount; + _u8 writeFdsCount; + _u8 padding; + _u16 readFds; + _u16 writeFds; + _u16 tv_usec; + _u16 tv_sec; +}_SelectCommand_t; + + +typedef struct +{ + _u16 status; + _u8 readFdsCount; + _u8 writeFdsCount; + _u16 readFds; + _u16 writeFds; +}_SelectAsyncResponse_t; + +typedef struct +{ + _u8 sd; + _u8 level; + _u8 optionName; + _u8 optionLen; +}_setSockOptCommand_t; + +typedef struct +{ + _u8 sd; + _u8 level; + _u8 optionName; + _u8 optionLen; +}_getSockOptCommand_t; + +typedef struct +{ + _i16 status; + _u8 sd; + _u8 optionLen; +}_getSockOptResponse_t; + + +typedef struct +{ + _u16 StatusOrLen; + _u8 sd; + _u8 FamilyAndFlags; +}_sendRecvCommand_t; + +/***************************************************************************************** +* NETAPP structs +******************************************************************************************/ + + +typedef _BasicResponse_t _NetAppStartStopResponse_t; + +typedef struct +{ + _u32 appId; +}_NetAppStartStopCommand_t; + +typedef struct +{ + _u16 Status; + _u16 AppId; + _u16 ConfigOpt; + _u16 ConfigLen; +}_NetAppSetGet_t; +typedef struct +{ + _u16 port_number; +} _NetAppHttpServerGetSet_port_num_t; + +typedef struct +{ + _u8 auth_enable; +}_NetAppHttpServerGetSet_auth_enable_t; + +typedef struct _sl_NetAppHttpServerGetToken_t +{ + _u8 token_name_len; + _u8 padd1; + _u16 padd2; +}sl_NetAppHttpServerGetToken_t; + +typedef struct _sl_NetAppHttpServerSendToken_t +{ + _u8 token_value_len; + _u8 token_name_len; + _u8 token_name[MAX_TOKEN_NAME_LEN]; + _u16 padd; +}sl_NetAppHttpServerSendToken_t; + +typedef struct _sl_NetAppHttpServerPostToken_t +{ + _u8 post_action_len; + _u8 token_name_len; + _u8 token_value_len; + _u8 padding; +}sl_NetAppHttpServerPostToken_t; + + +typedef struct +{ + _u16 Len; + _u8 family; + _u8 padding; +}_GetHostByNameCommand_t; + +typedef struct +{ + _u16 status; + _u16 padding; + _u32 ip0; + _u32 ip1; + _u32 ip2; + _u32 ip3; +}_GetHostByNameIPv6AsyncResponse_t; + +typedef struct +{ + _u16 status; + _u8 padding1; + _u8 padding2; + _u32 ip0; +}_GetHostByNameIPv4AsyncResponse_t; + + + + +typedef enum +{ + CTST_BSD_UDP_TX, + CTST_BSD_UDP_RX, + CTST_BSD_TCP_TX, + CTST_BSD_TCP_RX, + CTST_BSD_TCP_SERVER_BI_DIR, + CTST_BSD_TCP_CLIENT_BI_DIR, + CTST_BSD_UDP_BI_DIR, + CTST_BSD_RAW_TX, + CTST_BSD_RAW_RX, + CTST_BSD_RAW_BI_DIR, + CTST_BSD_SECURED_TCP_TX, + CTST_BSD_SECURED_TCP_RX, + CTST_BSD_SECURED_TCP_SERVER_BI_DIR, + CTST_BSD_SECURED_TCP_CLIENT_BI_DIR + }CommTest_e; + +typedef struct _sl_protocol_CtestStartCommand_t +{ + _u32 Test; + _u16 DestPort; + _u16 SrcPort; + _u32 DestAddr[4]; + _u32 PayloadSize; + _u32 timeout; + _u32 csEnabled; + _u32 secure; + _u32 rawProtocol; + _u8 reserved1[4]; +}_CtestStartCommand_t; + +typedef struct +{ + _u8 test; + _u8 socket; + _i16 status; + _u32 startTime; + _u32 endTime; + _u16 txKbitsSec; + _u16 rxKbitsSec; + _u32 outOfOrderPackets; + _u32 missedPackets; +}_CtestAsyncResponse_t; + +typedef struct +{ + _u32 pingIntervalTime; + _u16 PingSize; + _u16 pingRequestTimeout; + _u32 totalNumberOfAttempts; + _u32 flags; + _u32 ip0; + _u32 ip1OrPaadding; + _u32 ip2OrPaadding; + _u32 ip3OrPaadding; +}_PingStartCommand_t; + +typedef struct +{ + _u16 status; + _u16 rttMin; + _u16 rttMax; + _u16 rttAvg; + _u32 numSuccsessPings; + _u32 numSendsPings; + _u32 testTime; +}_PingReportResponse_t; + + +typedef struct +{ + _u32 ip; + _u32 gateway; + _u32 dns; +}_IpV4AcquiredAsync_t; + + +typedef enum +{ + ACQUIRED_IPV6_LOCAL = 1, + ACQUIRED_IPV6_GLOBAL +}IpV6AcquiredType_e; + + +typedef struct +{ + _u32 type; + _u32 ip[4]; + _u32 gateway[4]; + _u32 dns[4]; +}_IpV6AcquiredAsync_t; + + +typedef union +{ + _SocketCommand_t EventMask; + _sendRecvCommand_t DeviceInit; +}_device_commands_t; + +/***************************************************************************************** +* FS structs +******************************************************************************************/ + +typedef struct +{ + _u32 FileHandle; + _u32 Offset; + _u16 Len; + _u16 Padding; +}_FsReadCommand_t; + +typedef struct +{ + _u32 Mode; + _u32 Token; +}_FsOpenCommand_t; + +typedef struct +{ + _u32 FileHandle; + _u32 Token; +}_FsOpenResponse_t; + + +typedef struct +{ + _u32 FileHandle; + _u32 CertificFileNameLength; + _u32 SignatureLen; +}_FsCloseCommand_t; + + +typedef _BasicResponse_t _FsReadResponse_t; +typedef _BasicResponse_t _FsDeleteResponse_t; +typedef _BasicResponse_t _FsCloseResponse_t; + +typedef struct +{ + _u16 Status; + _u16 flags; + _u32 FileLen; + _u32 AllocatedLen; + _u32 Token[4]; +}_FsGetInfoResponse_t; + +typedef struct +{ + _u8 DeviceID; + _u8 Padding[3]; +}_FsFormatCommand_t; + +typedef _BasicResponse_t _FsFormatResponse_t; + +typedef struct +{ + _u32 Token; +}_FsDeleteCommand_t; + +typedef _FsDeleteCommand_t _FsGetInfoCommand_t; + +typedef struct +{ + _u32 FileHandle; + _u32 Offset; + _u16 Len; + _u16 Padding; +}_FsWriteCommand_t; + +typedef _BasicResponse_t _FsWriteResponse_t; + + + +/* Set Max Async Payload length depending on flavor (Tiny, Small, etc.) */ +#define SL_ASYNC_MAX_PAYLOAD_LEN 160 /* size must be aligned to 4 */ +#define SL_ASYNC_MAX_MSG_LEN (_SL_RESP_HDR_SIZE + SL_ASYNC_MAX_PAYLOAD_LEN) + +#define RECV_ARGS_SIZE (sizeof(_SocketResponse_t)) +#define RECVFROM_IPV4_ARGS_SIZE (sizeof(_SocketAddrAsyncIPv4Response_t)) +#define RECVFROM_IPV6_ARGS_SIZE (sizeof(_SocketAddrAsyncIPv6Response_t)) + +#define SL_IPV4_ADDRESS_SIZE (sizeof(_u32)) +#define SL_IPV6_ADDRESS_SIZE (4 * sizeof(_u32)) + +#endif /* _SL_PROTOCOL_TYPES_H_ */ diff --git a/cc3200/simplelink/source/socket.c b/cc3200/simplelink/source/socket.c new file mode 100644 index 000000000..34dd4a8b4 --- /dev/null +++ b/cc3200/simplelink/source/socket.c @@ -0,0 +1,1123 @@ +/* + * socket.c - CC31xx/CC32xx Host Driver Implementation + * + * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + + + + +/*****************************************************************************/ +/* Include files */ +/*****************************************************************************/ +#include "simplelink.h" +#include "protocol.h" +#include "driver.h" + + +/*******************************************************************************/ +/* Functions prototypes */ +/*******************************************************************************/ +void _sl_BuildAddress(const SlSockAddr_t *addr, _i16 addrlen, _SocketAddrCommand_u *pCmd); +void _sl_ParseAddress(_SocketAddrResponse_u *pRsp, SlSockAddr_t *addr, SlSocklen_t *addrlen); +void _sl_HandleAsync_Connect(void *pVoidBuf); +void _sl_HandleAsync_Accept(void *pVoidBuf); +void _sl_HandleAsync_Select(void *pVoidBuf); +_u16 _sl_TruncatePayloadByProtocol(const _i16 pSd,const _u16 length); + +/*******************************************************************************/ +/* Functions */ +/*******************************************************************************/ + +/* ******************************************************************************/ +/* _sl_BuildAddress */ +/* ******************************************************************************/ +void _sl_BuildAddress(const SlSockAddr_t *addr, _i16 addrlen, _SocketAddrCommand_u *pCmd) +{ + + /* Note: parsing of family and port in the generic way for all IPV4, IPV6 and EUI48 */ + /* is possible as _i32 as these parameters are in the same offset and size for these */ + /* three families. */ + pCmd->IpV4.FamilyAndFlags = (addr->sa_family << 4) & 0xF0; + pCmd->IpV4.port = ((SlSockAddrIn_t *)addr)->sin_port; + + if(SL_AF_INET == addr->sa_family) + { + pCmd->IpV4.address = ((SlSockAddrIn_t *)addr)->sin_addr.s_addr; + } + else if (SL_AF_INET6_EUI_48 == addr->sa_family ) + { + sl_Memcpy( pCmd->IpV6EUI48.address,((SlSockAddrIn6_t *)addr)->sin6_addr._S6_un._S6_u8, 6); + } +#ifdef SL_SUPPORT_IPV6 + else + { + sl_Memcpy(pCmd->IpV6.address, ((sockaddr_in6 *)addr)->sin6_addr._S6_un._S6_u32, 16 ); + } +#endif +} + +/* ******************************************************************************/ +/* _sl_TruncatePayloadByProtocol */ +/* ******************************************************************************/ +_u16 _sl_TruncatePayloadByProtocol(const _i16 sd,const _u16 length) +{ + _u16 maxLength; + + switch(sd & SL_SOCKET_PAYLOAD_TYPE_MASK) + { + case SL_SOCKET_PAYLOAD_TYPE_UDP_IPV4: + maxLength = 1472; + break; + + case SL_SOCKET_PAYLOAD_TYPE_TCP_IPV4: + maxLength = 1460; + break; + + case SL_SOCKET_PAYLOAD_TYPE_UDP_IPV6: + maxLength = 1452; + break; + + case SL_SOCKET_PAYLOAD_TYPE_TCP_IPV6: + maxLength = 1440; + break; + case SL_SOCKET_PAYLOAD_TYPE_TCP_IPV4_SECURE: + case SL_SOCKET_PAYLOAD_TYPE_UDP_IPV4_SECURE: + maxLength = 1402; + break; + case SL_SOCKET_PAYLOAD_TYPE_UDP_IPV6_SECURE: + case SL_SOCKET_PAYLOAD_TYPE_TCP_IPV6_SECURE: + maxLength = 1396; + break; + case SL_SOCKET_PAYLOAD_TYPE_RAW_TRANCEIVER: + maxLength = 1476; + break; + case SL_SOCKET_PAYLOAD_TYPE_RAW_PACKET: + maxLength = 1514; + break; + case SL_SOCKET_PAYLOAD_TYPE_RAW_IP4: + maxLength = 1480; + break; + default: + maxLength = 1440; + break; + } + + if( length > maxLength ) + { + return maxLength; + } + else + { + return length; + } +} + +/*******************************************************************************/ +/* _sl_ParseAddress */ +/*******************************************************************************/ +void _sl_ParseAddress(_SocketAddrResponse_u *pRsp, SlSockAddr_t *addr, SlSocklen_t *addrlen) +{ + /* Note: parsing of family and port in the generic way for all IPV4, IPV6 and EUI48 */ + /* is possible as long as these parameters are in the same offset and size for these */ + /* three families. */ + addr->sa_family = pRsp->IpV4.family; + ((SlSockAddrIn_t *)addr)->sin_port = pRsp->IpV4.port; + + *addrlen = (SL_AF_INET == addr->sa_family) ? sizeof(SlSockAddrIn_t) : sizeof(SlSockAddrIn6_t); + + if(SL_AF_INET == addr->sa_family) + { + ((SlSockAddrIn_t *)addr)->sin_addr.s_addr = pRsp->IpV4.address; + } + else if (SL_AF_INET6_EUI_48 == addr->sa_family ) + { + sl_Memcpy(((SlSockAddrIn6_t *)addr)->sin6_addr._S6_un._S6_u8, pRsp->IpV6EUI48.address, 6); + } +#ifdef SL_SUPPORT_IPV6 + else + { + sl_Memcpy(((sockaddr_in6 *)addr)->sin6_addr._S6_un._S6_u32, pRsp->IpV6.address, 16); + } +#endif +} + +/*******************************************************************************/ +/* sl_Socket */ +/*******************************************************************************/ +typedef union +{ + _u32 Dummy; + _SocketCommand_t Cmd; + _SocketResponse_t Rsp; +}_SlSockSocketMsg_u; + +const _SlCmdCtrl_t _SlSockSocketCmdCtrl = +{ + SL_OPCODE_SOCKET_SOCKET, + sizeof(_SocketCommand_t), + sizeof(_SocketResponse_t) +}; + +#if _SL_INCLUDE_FUNC(sl_Socket) +_i16 sl_Socket(_i16 Domain, _i16 Type, _i16 Protocol) +{ + _SlSockSocketMsg_u Msg; + + Msg.Cmd.Domain = (_u8)Domain; + Msg.Cmd.Type = (_u8)Type; + Msg.Cmd.Protocol = (_u8)Protocol; + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlSockSocketCmdCtrl, &Msg, NULL)); + + if( Msg.Rsp.statusOrLen < 0 ) + { + return( Msg.Rsp.statusOrLen ); + } + else + { + return (_i16)((_u8)Msg.Rsp.sd); +} +} +#endif + +/*******************************************************************************/ +/* sl_Close */ +/*******************************************************************************/ +typedef union +{ + _CloseCommand_t Cmd; + _SocketResponse_t Rsp; +}_SlSockCloseMsg_u; + +const _SlCmdCtrl_t _SlSockCloseCmdCtrl = +{ + SL_OPCODE_SOCKET_CLOSE, + sizeof(_CloseCommand_t), + sizeof(_SocketResponse_t) +}; + +#if _SL_INCLUDE_FUNC(sl_Close) +_i16 sl_Close(_i16 sd) +{ + _SlSockCloseMsg_u Msg; + + Msg.Cmd.sd = (_u8)sd; + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlSockCloseCmdCtrl, &Msg, NULL)); + + return Msg.Rsp.statusOrLen; +} +#endif + +/*******************************************************************************/ +/* sl_Bind */ +/*******************************************************************************/ +typedef union +{ + _SocketAddrCommand_u Cmd; + _SocketResponse_t Rsp; +}_SlSockBindMsg_u; + +#if _SL_INCLUDE_FUNC(sl_Bind) +_i16 sl_Bind(_i16 sd, const SlSockAddr_t *addr, _i16 addrlen) +{ + _SlSockBindMsg_u Msg; + _SlCmdCtrl_t CmdCtrl = {0, 0, sizeof(_SocketResponse_t)}; + + switch(addr->sa_family) + { + case SL_AF_INET : + CmdCtrl.Opcode = SL_OPCODE_SOCKET_BIND; + CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv4Command_t); + break; + case SL_AF_INET6_EUI_48: + CmdCtrl.Opcode = SL_OPCODE_SOCKET_BIND_V6; + CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv6EUI48Command_t); + break; +#ifdef SL_SUPPORT_IPV6 + case AF_INET6: + CmdCtrl.Opcode = SL_OPCODE_SOCKET_BIND_V6; + CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv6Command_t); + break; +#endif + case SL_AF_RF : + default: + return SL_RET_CODE_INVALID_INPUT; + } + + Msg.Cmd.IpV4.lenOrPadding = 0; + Msg.Cmd.IpV4.sd = (_u8)sd; + + _sl_BuildAddress(addr, addrlen, &Msg.Cmd); + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&CmdCtrl, &Msg, NULL)); + + return Msg.Rsp.statusOrLen; +} +#endif + +/*******************************************************************************/ +/* sl_Sendto */ +/*******************************************************************************/ +typedef union +{ + _SocketAddrCommand_u Cmd; + /* no response for 'sendto' commands*/ +}_SlSendtoMsg_u; + +#if _SL_INCLUDE_FUNC(sl_SendTo) +_i16 sl_SendTo(_i16 sd, const void *pBuf, _i16 Len, _i16 flags, const SlSockAddr_t *to, SlSocklen_t tolen) +{ + _SlSendtoMsg_u Msg; + _SlCmdCtrl_t CmdCtrl = {0, 0, 0}; + _SlCmdExt_t CmdExt; + _u16 ChunkLen; + _i16 RetVal; + + CmdExt.TxPayloadLen = (_u16)Len; + CmdExt.RxPayloadLen = 0; + CmdExt.pTxPayload = (_u8 *)pBuf; + CmdExt.pRxPayload = NULL; + + + switch(to->sa_family) + { + case SL_AF_INET: + CmdCtrl.Opcode = SL_OPCODE_SOCKET_SENDTO; + CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv4Command_t); + break; + case SL_AF_INET6_EUI_48: + CmdCtrl.Opcode = SL_OPCODE_SOCKET_BIND_V6; + CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv6EUI48Command_t); + break; +#ifdef SL_SUPPORT_IPV6 + case AF_INET6: + CmdCtrl.Opcode = SL_OPCODE_SOCKET_SENDTO_V6; + CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv6Command_t); + break; +#endif + case SL_AF_RF: + default: + return SL_RET_CODE_INVALID_INPUT; + } + + ChunkLen = _sl_TruncatePayloadByProtocol(sd,Len); + Msg.Cmd.IpV4.lenOrPadding = ChunkLen; + CmdExt.TxPayloadLen = ChunkLen; + + Msg.Cmd.IpV4.sd = (_u8)sd; + + _sl_BuildAddress(to, tolen, &Msg.Cmd); + + Msg.Cmd.IpV4.FamilyAndFlags |= flags & 0x0F; + + do + { + RetVal = _SlDrvDataWriteOp((_SlSd_t)sd, &CmdCtrl, &Msg, &CmdExt); + + if(SL_OS_RET_CODE_OK == RetVal) + { + CmdExt.pTxPayload += ChunkLen; + ChunkLen = (_u16)((_u8 *)pBuf + Len - CmdExt.pTxPayload); + ChunkLen = _sl_TruncatePayloadByProtocol(sd,ChunkLen); + CmdExt.TxPayloadLen = ChunkLen; + Msg.Cmd.IpV4.lenOrPadding = ChunkLen; + } + else + { + return RetVal; + } + }while(ChunkLen > 0); + + return (_i16)Len; +} +#endif + +/*******************************************************************************/ +/* sl_Recvfrom */ +/*******************************************************************************/ +typedef union +{ + _sendRecvCommand_t Cmd; + _SocketAddrResponse_u Rsp; +}_SlRecvfromMsg_u; + +const _SlCmdCtrl_t _SlRecvfomCmdCtrl = +{ + SL_OPCODE_SOCKET_RECVFROM, + sizeof(_sendRecvCommand_t), + sizeof(_SocketAddrResponse_u) +}; + +#if _SL_INCLUDE_FUNC(sl_RecvFrom) +_i16 sl_RecvFrom(_i16 sd, void *buf, _i16 Len, _i16 flags, SlSockAddr_t *from, SlSocklen_t *fromlen) +{ + _SlRecvfromMsg_u Msg; + _SlCmdExt_t CmdExt; + _i16 RetVal; + + CmdExt.TxPayloadLen = 0; + CmdExt.RxPayloadLen = Len; + CmdExt.pTxPayload = NULL; + CmdExt.pRxPayload = (_u8 *)buf; + + + Msg.Cmd.sd = (_u8)sd; + Msg.Cmd.StatusOrLen = Len; + /* no size truncation in recv path */ + CmdExt.RxPayloadLen = Msg.Cmd.StatusOrLen; + + if(sizeof(SlSockAddrIn_t) == *fromlen) + { + Msg.Cmd.FamilyAndFlags = SL_AF_INET; + } + else if (sizeof(SlSockAddrIn6_t) == *fromlen) + { + Msg.Cmd.FamilyAndFlags = SL_AF_INET6; + } + else + { + return SL_RET_CODE_INVALID_INPUT; + } + + Msg.Cmd.FamilyAndFlags = (Msg.Cmd.FamilyAndFlags << 4) & 0xF0; + Msg.Cmd.FamilyAndFlags |= flags & 0x0F; + + RetVal = _SlDrvDataReadOp((_SlSd_t)sd, (_SlCmdCtrl_t *)&_SlRecvfomCmdCtrl, &Msg, &CmdExt); + if( RetVal != SL_OS_RET_CODE_OK ) + { + return RetVal; + } + + RetVal = Msg.Rsp.IpV4.statusOrLen; + + if(RetVal >= 0) + { + VERIFY_PROTOCOL(sd == Msg.Rsp.IpV4.sd); +#if 0 + _sl_ParseAddress(&Msg.Rsp, from, fromlen); +#else + from->sa_family = Msg.Rsp.IpV4.family; + if(SL_AF_INET == from->sa_family) + { + ((SlSockAddrIn_t *)from)->sin_port = Msg.Rsp.IpV4.port; + ((SlSockAddrIn_t *)from)->sin_addr.s_addr = Msg.Rsp.IpV4.address; + *fromlen = sizeof(SlSockAddrIn_t); + } + else if (SL_AF_INET6_EUI_48 == from->sa_family ) + { + ((SlSockAddrIn6_t *)from)->sin6_port = Msg.Rsp.IpV6EUI48.port; + sl_Memcpy(((SlSockAddrIn6_t *)from)->sin6_addr._S6_un._S6_u8, Msg.Rsp.IpV6EUI48.address, 6); + } +#ifdef SL_SUPPORT_IPV6 + else if(AF_INET6 == from->sa_family) + { + VERIFY_PROTOCOL(*fromlen >= sizeof(sockaddr_in6)); + + ((sockaddr_in6 *)from)->sin6_port = Msg.Rsp.IpV6.port; + sl_Memcpy(((sockaddr_in6 *)from)->sin6_addr._S6_un._S6_u32, Msg.Rsp.IpV6.address, 16); + *fromlen = sizeof(sockaddr_in6); + } +#endif +#endif + } + + return (_i16)RetVal; +} +#endif + +/*******************************************************************************/ +/* sl_Connect */ +/*******************************************************************************/ +typedef union +{ + _SocketAddrCommand_u Cmd; + _SocketResponse_t Rsp; +}_SlSockConnectMsg_u; + +#if _SL_INCLUDE_FUNC(sl_Connect) +_i16 sl_Connect(_i16 sd, const SlSockAddr_t *addr, _i16 addrlen) +{ + _SlSockConnectMsg_u Msg; + _SlReturnVal_t RetVal; + _SlCmdCtrl_t CmdCtrl = {0, 0, sizeof(_SocketResponse_t)}; + _SocketResponse_t AsyncRsp; + _u8 ObjIdx = MAX_CONCURRENT_ACTIONS; + + + switch(addr->sa_family) + { + case SL_AF_INET : + CmdCtrl.Opcode = SL_OPCODE_SOCKET_CONNECT; + CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv4Command_t); + break; + case SL_AF_INET6_EUI_48: + CmdCtrl.Opcode = SL_OPCODE_SOCKET_CONNECT_V6; + CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv6EUI48Command_t); + break; +#ifdef SL_SUPPORT_IPV6 + case AF_INET6: + CmdCtrl.Opcode = SL_OPCODE_SOCKET_CONNECT_V6; + CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv6Command_t); + break; +#endif + case SL_AF_RF : + default: + return SL_RET_CODE_INVALID_INPUT; + } + + Msg.Cmd.IpV4.lenOrPadding = 0; + Msg.Cmd.IpV4.sd = (_u8)sd; + + _sl_BuildAddress(addr, addrlen, &Msg.Cmd); + + /* Use Obj to issue the command, if not available try later */ + ObjIdx = (_u8)_SlDrvWaitForPoolObj(CONNECT_ID, (_u8)(sd & BSD_SOCKET_ID_MASK)); + + if (MAX_CONCURRENT_ACTIONS == ObjIdx) + { + return SL_POOL_IS_EMPTY; + } + OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); + + g_pCB->ObjPool[ObjIdx].pRespArgs = (_u8 *)&AsyncRsp; + + OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); + + /* send the command */ + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&CmdCtrl, &Msg, NULL)); + VERIFY_PROTOCOL(Msg.Rsp.sd == sd) + + RetVal = Msg.Rsp.statusOrLen; + + if(SL_RET_CODE_OK == RetVal) + { + /* wait for async and get Data Read parameters */ + OSI_RET_OK_CHECK(sl_SyncObjWait(&g_pCB->ObjPool[ObjIdx].SyncObj, SL_OS_WAIT_FOREVER)); + + VERIFY_PROTOCOL(AsyncRsp.sd == sd); + + RetVal = AsyncRsp.statusOrLen; + } + _SlDrvReleasePoolObj(ObjIdx); + return RetVal; +} +#endif + +/*******************************************************************************/ +/* _sl_HandleAsync_Connect */ +/*******************************************************************************/ +void _sl_HandleAsync_Connect(void *pVoidBuf) +{ + _SocketResponse_t *pMsgArgs = (_SocketResponse_t *)_SL_RESP_ARGS_START(pVoidBuf); + + OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); + + VERIFY_PROTOCOL((pMsgArgs->sd & BSD_SOCKET_ID_MASK) <= SL_MAX_SOCKETS); + VERIFY_SOCKET_CB(NULL != g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs); + + ((_SocketResponse_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->sd = pMsgArgs->sd; + ((_SocketResponse_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->statusOrLen = pMsgArgs->statusOrLen; + + OSI_RET_OK_CHECK(sl_SyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj)); + OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); + return; +} + +/*******************************************************************************/ +/* sl_Send */ +/*******************************************************************************/ +typedef union +{ + _sendRecvCommand_t Cmd; + /* no response for 'sendto' commands*/ +}_SlSendMsg_u; + +const _SlCmdCtrl_t _SlSendCmdCtrl = +{ + SL_OPCODE_SOCKET_SEND, + sizeof(_sendRecvCommand_t), + 0 +}; + +#if _SL_INCLUDE_FUNC(sl_Send) +_i16 sl_Send(_i16 sd, const void *pBuf, _i16 Len, _i16 flags) +{ + _SlSendMsg_u Msg; + _SlCmdExt_t CmdExt; + _u16 ChunkLen; + _i16 RetVal; + _u32 tempVal; + _u8 runSingleChunk = FALSE; + + CmdExt.TxPayloadLen = Len; + CmdExt.RxPayloadLen = 0; + CmdExt.pTxPayload = (_u8 *)pBuf; + + /* Only for RAW transceiver type socket, relay the flags parameter in the 2 bytes (4 byte aligned) before the actual payload */ + if ((sd & SL_SOCKET_PAYLOAD_TYPE_MASK) == SL_SOCKET_PAYLOAD_TYPE_RAW_TRANCEIVER) + { + tempVal = flags; + CmdExt.pRxPayload = (_u8 *)&tempVal; + CmdExt.RxPayloadLen = 4; + g_pCB->RelayFlagsViaRxPayload = TRUE; + runSingleChunk = TRUE; + } + else + { + CmdExt.pRxPayload = NULL; + } + + ChunkLen = _sl_TruncatePayloadByProtocol(sd,Len); + CmdExt.TxPayloadLen = ChunkLen; + + Msg.Cmd.StatusOrLen = ChunkLen; + Msg.Cmd.sd = (_u8)sd; + Msg.Cmd.FamilyAndFlags |= flags & 0x0F; + + do + { + RetVal = _SlDrvDataWriteOp((_u8)sd, (_SlCmdCtrl_t *)&_SlSendCmdCtrl, &Msg, &CmdExt); + if(SL_OS_RET_CODE_OK == RetVal) + { + CmdExt.pTxPayload += ChunkLen; + ChunkLen = (_u8 *)pBuf + Len - CmdExt.pTxPayload; + ChunkLen = _sl_TruncatePayloadByProtocol(sd,ChunkLen); + CmdExt.TxPayloadLen = ChunkLen; + Msg.Cmd.StatusOrLen = ChunkLen; + } + else + { + return RetVal; + } + }while((ChunkLen > 0) && (runSingleChunk==FALSE)); + + return (_i16)Len; +} +#endif + +/*******************************************************************************/ +/* sl_Listen */ +/*******************************************************************************/ +typedef union +{ + _ListenCommand_t Cmd; + _BasicResponse_t Rsp; +}_SlListenMsg_u; + +const _SlCmdCtrl_t _SlListenCmdCtrl = +{ + SL_OPCODE_SOCKET_LISTEN, + sizeof(_ListenCommand_t), + sizeof(_BasicResponse_t), +}; + +#if _SL_INCLUDE_FUNC(sl_Listen) +_i16 sl_Listen(_i16 sd, _i16 backlog) +{ + _SlListenMsg_u Msg; + + Msg.Cmd.sd = (_u8)sd; + Msg.Cmd.backlog = (_u8)backlog; + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlListenCmdCtrl, &Msg, NULL)); + + return (_i16)Msg.Rsp.status; +} +#endif + +/*******************************************************************************/ +/* sl_Accept */ +/*******************************************************************************/ +typedef union +{ + _AcceptCommand_t Cmd; + _SocketResponse_t Rsp; +}_SlSockAcceptMsg_u; + +const _SlCmdCtrl_t _SlAcceptCmdCtrl = +{ + SL_OPCODE_SOCKET_ACCEPT, + sizeof(_AcceptCommand_t), + sizeof(_BasicResponse_t), +}; + +#if _SL_INCLUDE_FUNC(sl_Accept) +_i16 sl_Accept(_i16 sd, SlSockAddr_t *addr, SlSocklen_t *addrlen) +{ + _SlSockAcceptMsg_u Msg; + _SlReturnVal_t RetVal; + _SocketAddrResponse_u AsyncRsp; + + _u8 ObjIdx = MAX_CONCURRENT_ACTIONS; + + + Msg.Cmd.sd = (_u8)sd; + Msg.Cmd.family = (sizeof(SlSockAddrIn_t) == *addrlen) ? SL_AF_INET : SL_AF_INET6; + + /* Use Obj to issue the command, if not available try later */ + ObjIdx = (_u8)_SlDrvWaitForPoolObj(ACCEPT_ID, (_u8)(sd & BSD_SOCKET_ID_MASK)); + + if (MAX_CONCURRENT_ACTIONS == ObjIdx) + { + return SL_POOL_IS_EMPTY; + } + + OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); + + g_pCB->ObjPool[ObjIdx].pRespArgs = (_u8 *)&AsyncRsp; + + OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); + /* send the command */ + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlAcceptCmdCtrl, &Msg, NULL)); + VERIFY_PROTOCOL(Msg.Rsp.sd == sd); + + RetVal = Msg.Rsp.statusOrLen; + + if(SL_OS_RET_CODE_OK == RetVal) + { + /* wait for async and get Data Read parameters */ + OSI_RET_OK_CHECK(sl_SyncObjWait(&g_pCB->ObjPool[ObjIdx].SyncObj, SL_OS_WAIT_FOREVER)); + + VERIFY_PROTOCOL(AsyncRsp.IpV4.sd == sd); + + RetVal = AsyncRsp.IpV4.statusOrLen; + if( (NULL != addr) && (NULL != addrlen) ) + { +#if 0 /* Kept for backup */ + _sl_ParseAddress(&AsyncRsp, addr, addrlen); +#else + addr->sa_family = AsyncRsp.IpV4.family; + + if(SL_AF_INET == addr->sa_family) + { + if( *addrlen == sizeof( SlSockAddrIn_t ) ) + { + ((SlSockAddrIn_t *)addr)->sin_port = AsyncRsp.IpV4.port; + ((SlSockAddrIn_t *)addr)->sin_addr.s_addr = AsyncRsp.IpV4.address; + } + else + { + *addrlen = 0; + } + } + else if (SL_AF_INET6_EUI_48 == addr->sa_family ) + { + if( *addrlen == sizeof( SlSockAddrIn6_t ) ) + { + ((SlSockAddrIn6_t *)addr)->sin6_port = AsyncRsp.IpV6EUI48.port ; + /* will be called from here and from _sl_BuildAddress*/ + sl_Memcpy(((SlSockAddrIn6_t *)addr)->sin6_addr._S6_un._S6_u8, AsyncRsp.IpV6EUI48.address, 6); + } + else + { + *addrlen = 0; + } + } +#ifdef SL_SUPPORT_IPV6 + else + { + if( *addrlen == sizeof( sockaddr_in6 ) ) + { + ((sockaddr_in6 *)addr)->sin6_port = AsyncRsp.IpV6.port ; + sl_Memcpy(((sockaddr_in6 *)addr)->sin6_addr._S6_un._S6_u32, AsyncRsp.IpV6.address, 16); + } + else + { + *addrlen = 0; + } + } +#endif +#endif + } + } + + _SlDrvReleasePoolObj(ObjIdx); + return (_i16)RetVal; +} +#endif + + +/*******************************************************************************/ +/* sl_Htonl */ +/*******************************************************************************/ +_u32 sl_Htonl( _u32 val ) +{ + _u32 i = 1; + _i8 *p = (_i8 *)&i; + if (p[0] == 1) /* little endian */ + { + p[0] = ((_i8* )&val)[3]; + p[1] = ((_i8* )&val)[2]; + p[2] = ((_i8* )&val)[1]; + p[3] = ((_i8* )&val)[0]; + return i; + } + else /* big endian */ + { + return val; + } +} + +/*******************************************************************************/ +/* sl_Htonl */ +/*******************************************************************************/ +_u16 sl_Htons( _u16 val ) +{ + _i16 i = 1; + _i8 *p = (_i8 *)&i; + if (p[0] == 1) /* little endian */ + { + p[0] = ((_i8* )&val)[1]; + p[1] = ((_i8* )&val)[0]; + return i; + } + else /* big endian */ + { + return val; + } +} + +/*******************************************************************************/ +/* _sl_HandleAsync_Accept */ +/*******************************************************************************/ +void _sl_HandleAsync_Accept(void *pVoidBuf) +{ + _SocketAddrResponse_u *pMsgArgs = (_SocketAddrResponse_u *)_SL_RESP_ARGS_START(pVoidBuf); + + OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); + + VERIFY_PROTOCOL(( pMsgArgs->IpV4.sd & BSD_SOCKET_ID_MASK) <= SL_MAX_SOCKETS); + VERIFY_SOCKET_CB(NULL != g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs); + + sl_Memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs,sizeof(_SocketAddrResponse_u)); + OSI_RET_OK_CHECK(sl_SyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj)); + + OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); + return; +} + +/*******************************************************************************/ +/* sl_Recv */ +/*******************************************************************************/ +typedef union +{ + _sendRecvCommand_t Cmd; + _SocketResponse_t Rsp; +}_SlRecvMsg_u; + +const _SlCmdCtrl_t _SlRecvCmdCtrl = +{ + SL_OPCODE_SOCKET_RECV, + sizeof(_sendRecvCommand_t), + sizeof(_SocketResponse_t) +}; + +#if _SL_INCLUDE_FUNC(sl_Recv) +_i16 sl_Recv(_i16 sd, void *pBuf, _i16 Len, _i16 flags) +{ + _SlRecvMsg_u Msg; + _SlCmdExt_t CmdExt; + _SlReturnVal_t status; + + CmdExt.TxPayloadLen = 0; + CmdExt.RxPayloadLen = Len; + CmdExt.pTxPayload = NULL; + CmdExt.pRxPayload = (_u8 *)pBuf; + + Msg.Cmd.sd = (_u8)sd; + Msg.Cmd.StatusOrLen = Len; + + /* no size truncation in recv path */ + CmdExt.RxPayloadLen = Msg.Cmd.StatusOrLen; + + Msg.Cmd.FamilyAndFlags = flags & 0x0F; + + status = _SlDrvDataReadOp((_SlSd_t)sd, (_SlCmdCtrl_t *)&_SlRecvCmdCtrl, &Msg, &CmdExt); + if( status != SL_OS_RET_CODE_OK ) + { + return status; + } + + /* if the Device side sends less than expected it is not the Driver's role */ + /* the returned value could be smaller than the requested size */ + return (_i16)Msg.Rsp.statusOrLen; +} +#endif + +/*******************************************************************************/ +/* sl_SetSockOpt */ +/*******************************************************************************/ +typedef union +{ + _setSockOptCommand_t Cmd; + _SocketResponse_t Rsp; +}_SlSetSockOptMsg_u; + +const _SlCmdCtrl_t _SlSetSockOptCmdCtrl = +{ + SL_OPCODE_SOCKET_SETSOCKOPT, + sizeof(_setSockOptCommand_t), + sizeof(_SocketResponse_t) +}; + +#if _SL_INCLUDE_FUNC(sl_SetSockOpt) +_i16 sl_SetSockOpt(_i16 sd, _i16 level, _i16 optname, const void *optval, SlSocklen_t optlen) +{ + _SlSetSockOptMsg_u Msg; + _SlCmdExt_t CmdExt; + + CmdExt.TxPayloadLen = optlen; + CmdExt.RxPayloadLen = 0; + CmdExt.pTxPayload = (_u8 *)optval; + CmdExt.pRxPayload = NULL; + + Msg.Cmd.sd = (_u8)sd; + Msg.Cmd.level = (_u8)level; + Msg.Cmd.optionLen = (_u8)optlen; + Msg.Cmd.optionName = (_u8)optname; + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlSetSockOptCmdCtrl, &Msg, &CmdExt)); + + return (_i16)Msg.Rsp.statusOrLen; +} +#endif + +/*******************************************************************************/ +/* sl_GetSockOpt */ +/*******************************************************************************/ +typedef union +{ + _getSockOptCommand_t Cmd; + _getSockOptResponse_t Rsp; +}_SlGetSockOptMsg_u; + +const _SlCmdCtrl_t _SlGetSockOptCmdCtrl = +{ + SL_OPCODE_SOCKET_GETSOCKOPT, + sizeof(_getSockOptCommand_t), + sizeof(_getSockOptResponse_t) +}; + +#if _SL_INCLUDE_FUNC(sl_GetSockOpt) +_i16 sl_GetSockOpt(_i16 sd, _i16 level, _i16 optname, void *optval, SlSocklen_t *optlen) +{ + _SlGetSockOptMsg_u Msg; + _SlCmdExt_t CmdExt; + + if (*optlen == 0) + { + return SL_EZEROLEN; + } + CmdExt.TxPayloadLen = 0; + CmdExt.RxPayloadLen = *optlen; + CmdExt.pTxPayload = NULL; + CmdExt.pRxPayload = optval; + CmdExt.ActualRxPayloadLen = 0; + + Msg.Cmd.sd = (_u8)sd; + Msg.Cmd.level = (_u8)level; + Msg.Cmd.optionLen = (_u8)(*optlen); + Msg.Cmd.optionName = (_u8)optname; + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlGetSockOptCmdCtrl, &Msg, &CmdExt)); + + if (CmdExt.RxPayloadLen < CmdExt.ActualRxPayloadLen) + { + *optlen = Msg.Rsp.optionLen; + return SL_ESMALLBUF; + } + else + { + *optlen = (_u8)CmdExt.ActualRxPayloadLen; + } + return (_i16)Msg.Rsp.status; +} +#endif + +/*******************************************************************************/ +/* sl_Select */ +/* ******************************************************************************/ +typedef union +{ + _SelectCommand_t Cmd; + _BasicResponse_t Rsp; +}_SlSelectMsg_u; + +const _SlCmdCtrl_t _SlSelectCmdCtrl = +{ + SL_OPCODE_SOCKET_SELECT, + sizeof(_SelectCommand_t), + sizeof(_BasicResponse_t) +}; + +#if _SL_INCLUDE_FUNC(sl_Select) +_i16 sl_Select(_i16 nfds, SlFdSet_t *readsds, SlFdSet_t *writesds, SlFdSet_t *exceptsds, struct SlTimeval_t *timeout) +{ + _SlSelectMsg_u Msg; + _SelectAsyncResponse_t AsyncRsp; + _u8 ObjIdx = MAX_CONCURRENT_ACTIONS; + + Msg.Cmd.nfds = (_u8)nfds; + Msg.Cmd.readFdsCount = 0; + Msg.Cmd.writeFdsCount = 0; + + Msg.Cmd.readFds = 0; + Msg.Cmd.writeFds = 0; + + if( readsds ) + { + Msg.Cmd.readFds = (_u16)readsds->fd_array[0]; + } + if( writesds ) + { + Msg.Cmd.writeFds = (_u16)writesds->fd_array[0]; + } + if( NULL == timeout ) + { + Msg.Cmd.tv_sec = 0xffff; + Msg.Cmd.tv_usec = 0xffff; + } + else + { + if( 0xffff <= timeout->tv_sec ) + { + Msg.Cmd.tv_sec = 0xffff; + } + else + { + Msg.Cmd.tv_sec = (_u16)timeout->tv_sec; + } + timeout->tv_usec = timeout->tv_usec >> 10; /* convert to milliseconds */ + if( 0xffff <= timeout->tv_usec ) + { + Msg.Cmd.tv_usec = 0xffff; + } + else + { + Msg.Cmd.tv_usec = (_u16)timeout->tv_usec; + } + } + + /* Use Obj to issue the command, if not available try later */ + ObjIdx = (_u8)_SlDrvWaitForPoolObj(SELECT_ID, SL_MAX_SOCKETS); + + if (MAX_CONCURRENT_ACTIONS == ObjIdx) + { + return SL_POOL_IS_EMPTY; + } + OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); + + g_pCB->ObjPool[ObjIdx].pRespArgs = (_u8 *)&AsyncRsp; + + OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); + /* send the command */ + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlSelectCmdCtrl, &Msg, NULL)); + + if(SL_OS_RET_CODE_OK == (_i16)Msg.Rsp.status) + { + OSI_RET_OK_CHECK(sl_SyncObjWait(&g_pCB->ObjPool[ObjIdx].SyncObj, SL_OS_WAIT_FOREVER)); + Msg.Rsp.status = AsyncRsp.status; + + if( ((_i16)Msg.Rsp.status) >= 0 ) + { + if( readsds ) + { + readsds->fd_array[0] = AsyncRsp.readFds; + } + if( writesds ) + { + writesds->fd_array[0] = AsyncRsp.writeFds; + } + } + } + + _SlDrvReleasePoolObj(ObjIdx); + return (_i16)Msg.Rsp.status; +} + +/* Select helper functions */ +/*******************************************************************************/ +/* SL_FD_SET */ +/* ******************************************************************************/ +void SL_FD_SET(_i16 fd, SlFdSet_t *fdset) +{ + fdset->fd_array[0] |= (1<< (fd & BSD_SOCKET_ID_MASK)); +} +/*******************************************************************************/ +/* SL_FD_CLR */ +/*******************************************************************************/ +void SL_FD_CLR(_i16 fd, SlFdSet_t *fdset) +{ + fdset->fd_array[0] &= ~(1<< (fd & BSD_SOCKET_ID_MASK)); +} +/*******************************************************************************/ +/* SL_FD_ISSET */ +/*******************************************************************************/ +_i16 SL_FD_ISSET(_i16 fd, SlFdSet_t *fdset) +{ + if( fdset->fd_array[0] & (1<< (fd & BSD_SOCKET_ID_MASK)) ) + { + return 1; + } + return 0; +} +/*******************************************************************************/ +/* SL_FD_ZERO */ +/*******************************************************************************/ +void SL_FD_ZERO(SlFdSet_t *fdset) +{ + fdset->fd_array[0] = 0; +} + +#endif + +/*******************************************************************************/ +/* _sl_HandleAsync_Select */ +/*******************************************************************************/ +void _sl_HandleAsync_Select(void *pVoidBuf) +{ + _SelectAsyncResponse_t *pMsgArgs = (_SelectAsyncResponse_t *)_SL_RESP_ARGS_START(pVoidBuf); + + OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); + + VERIFY_SOCKET_CB(NULL != g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs); + + sl_Memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(_SelectAsyncResponse_t)); + OSI_RET_OK_CHECK(sl_SyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj)); + + OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); + return; +} + diff --git a/cc3200/simplelink/source/spawn.c b/cc3200/simplelink/source/spawn.c new file mode 100644 index 000000000..fdf1930ca --- /dev/null +++ b/cc3200/simplelink/source/spawn.c @@ -0,0 +1,197 @@ +/* + * spawn.c - CC31xx/CC32xx Host Driver Implementation + * + * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + + + +/*****************************************************************************/ +/* Include files */ +/*****************************************************************************/ +#include "simplelink.h" + + +#if (defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN)) + +#define _SL_MAX_INTERNAL_SPAWN_ENTRIES 10 + +typedef struct _SlInternalSpawnEntry_t +{ + _SlSpawnEntryFunc_t pEntry; + void* pValue; + struct _SlInternalSpawnEntry_t* pNext; +}_SlInternalSpawnEntry_t; + +typedef struct +{ + _SlInternalSpawnEntry_t SpawnEntries[_SL_MAX_INTERNAL_SPAWN_ENTRIES]; + _SlInternalSpawnEntry_t* pFree; + _SlInternalSpawnEntry_t* pWaitForExe; + _SlInternalSpawnEntry_t* pLastInWaitList; + _SlSyncObj_t SyncObj; + _SlLockObj_t LockObj; +}_SlInternalSpawnCB_t; + +_SlInternalSpawnCB_t g_SlInternalSpawnCB; + + +void _SlInternalSpawnTaskEntry() +{ + _i16 i; + _SlInternalSpawnEntry_t* pEntry; + _u8 LastEntry; + + /* create and lock the locking object. lock in order to avoid race condition + on the first creation */ + sl_LockObjCreate(&g_SlInternalSpawnCB.LockObj,"SlSpawnProtect"); + sl_LockObjLock(&g_SlInternalSpawnCB.LockObj,SL_OS_NO_WAIT); + + /* create and clear the sync object */ + sl_SyncObjCreate(&g_SlInternalSpawnCB.SyncObj,"SlSpawnSync"); + sl_SyncObjWait(&g_SlInternalSpawnCB.SyncObj,SL_OS_NO_WAIT); + + g_SlInternalSpawnCB.pFree = &g_SlInternalSpawnCB.SpawnEntries[0]; + g_SlInternalSpawnCB.pWaitForExe = NULL; + g_SlInternalSpawnCB.pLastInWaitList = NULL; + + /* create the link list between the entries */ + for (i=0 ; i<_SL_MAX_INTERNAL_SPAWN_ENTRIES - 1 ; i++) + { + g_SlInternalSpawnCB.SpawnEntries[i].pNext = &g_SlInternalSpawnCB.SpawnEntries[i+1]; + g_SlInternalSpawnCB.SpawnEntries[i].pEntry = NULL; + } + g_SlInternalSpawnCB.SpawnEntries[i].pNext = NULL; + + sl_LockObjUnlock(&g_SlInternalSpawnCB.LockObj); + + + /* here we ready to execute entries */ + + while (TRUE) + { + sl_SyncObjWait(&g_SlInternalSpawnCB.SyncObj,SL_OS_WAIT_FOREVER); + /* go over all entries that already waiting for execution */ + LastEntry = FALSE; + do + { + /* get entry to execute */ + sl_LockObjLock(&g_SlInternalSpawnCB.LockObj,SL_OS_WAIT_FOREVER); + + pEntry = g_SlInternalSpawnCB.pWaitForExe; + if ( NULL == pEntry ) + { + sl_LockObjUnlock(&g_SlInternalSpawnCB.LockObj); + break; + } + g_SlInternalSpawnCB.pWaitForExe = pEntry->pNext; + if (pEntry == g_SlInternalSpawnCB.pLastInWaitList) + { + g_SlInternalSpawnCB.pLastInWaitList = NULL; + LastEntry = TRUE; + } + + sl_LockObjUnlock(&g_SlInternalSpawnCB.LockObj); + + + /* pEntry could be null in case that the sync was already set by some + of the entries during execution of earlier entry */ + if (NULL != pEntry) + { + pEntry->pEntry(pEntry->pValue); + /* free the entry */ + sl_LockObjLock(&g_SlInternalSpawnCB.LockObj,SL_OS_WAIT_FOREVER); + + pEntry->pNext = g_SlInternalSpawnCB.pFree; + g_SlInternalSpawnCB.pFree = pEntry; + + + if (NULL != g_SlInternalSpawnCB.pWaitForExe) + { + /* new entry received meanwhile */ + LastEntry = FALSE; + } + + sl_LockObjUnlock(&g_SlInternalSpawnCB.LockObj); + + } + + }while (!LastEntry); + } +} + + +_i16 _SlInternalSpawn(_SlSpawnEntryFunc_t pEntry , void* pValue , _u32 flags) +{ + _i16 Res = 0; + _SlInternalSpawnEntry_t* pSpawnEntry; + + if (NULL == pEntry) + { + Res = -1; + } + else + { + sl_LockObjLock(&g_SlInternalSpawnCB.LockObj,SL_OS_WAIT_FOREVER); + + pSpawnEntry = g_SlInternalSpawnCB.pFree; + g_SlInternalSpawnCB.pFree = pSpawnEntry->pNext; + + pSpawnEntry->pEntry = pEntry; + pSpawnEntry->pValue = pValue; + pSpawnEntry->pNext = NULL; + + if (NULL == g_SlInternalSpawnCB.pWaitForExe) + { + g_SlInternalSpawnCB.pWaitForExe = pSpawnEntry; + g_SlInternalSpawnCB.pLastInWaitList = pSpawnEntry; + } + else + { + g_SlInternalSpawnCB.pLastInWaitList->pNext = pSpawnEntry; + g_SlInternalSpawnCB.pLastInWaitList = pSpawnEntry; + } + + sl_LockObjUnlock(&g_SlInternalSpawnCB.LockObj); + /* this sync is called after releasing the lock object to avoid unnecessary context switches */ + sl_SyncObjSignal(&g_SlInternalSpawnCB.SyncObj); + } + + return Res; +} + + + + + +#endif diff --git a/cc3200/simplelink/source/spawn.h b/cc3200/simplelink/source/spawn.h new file mode 100644 index 000000000..82c112d2e --- /dev/null +++ b/cc3200/simplelink/source/spawn.h @@ -0,0 +1,63 @@ +/* + * spawn.h - CC31xx/CC32xx Host Driver Implementation + * + * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + +#ifndef __NONOS_H__ +#define __NONOS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#if (defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN)) + +extern void _SlInternalSpawnTaskEntry(); +extern _i16 _SlInternalSpawn(_SlSpawnEntryFunc_t pEntry , void* pValue , _u32 flags); + +#undef sl_Spawn +#define sl_Spawn(pEntry,pValue,flags) _SlInternalSpawn(pEntry,pValue,flags) + +#undef _SlTaskEntry +#define _SlTaskEntry _SlInternalSpawnTaskEntry + + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/cc3200/simplelink/source/wlan.c b/cc3200/simplelink/source/wlan.c new file mode 100644 index 000000000..648a624e1 --- /dev/null +++ b/cc3200/simplelink/source/wlan.c @@ -0,0 +1,993 @@ +/* +* wlan.c - CC31xx/CC32xx Host Driver Implementation +* +* Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the +* distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +*/ + + + +/*****************************************************************************/ +/* Include files */ +/*****************************************************************************/ +#include <string.h> +#include "simplelink.h" +#include "protocol.h" +#include "driver.h" + +/*****************************************************************************/ +/* Macro declarations */ +/*****************************************************************************/ +#define MAX_SSID_LEN (32) +#define MAX_KEY_LEN (63) +#define MAX_USER_LEN (32) +#define MAX_ANON_USER_LEN (32) +#define MAX_SMART_CONFIG_KEY (16) + + +/***************************************************************************** +sl_WlanConnect +*****************************************************************************/ +typedef struct +{ + _WlanConnectEapCommand_t Args; + _i8 Strings[MAX_SSID_LEN + MAX_KEY_LEN + MAX_USER_LEN + MAX_ANON_USER_LEN]; +}_WlanConnectCmd_t; + +typedef union +{ + _WlanConnectCmd_t Cmd; + _BasicResponse_t Rsp; +}_SlWlanConnectMsg_u; + + +#if _SL_INCLUDE_FUNC(sl_WlanConnect) +_i16 sl_WlanConnect(_i8* pName, _i16 NameLen, _u8 *pMacAddr, SlSecParams_t* pSecParams , SlSecParamsExt_t* pSecExtParams) +{ + _SlWlanConnectMsg_u Msg; + _SlCmdCtrl_t CmdCtrl; + + // Clear the above structures + memset (&Msg, 0, sizeof(Msg)); + memset (&CmdCtrl, 0, sizeof(CmdCtrl)); + + CmdCtrl.TxDescLen = 0;/* init */ + CmdCtrl.RxDescLen = sizeof(_BasicResponse_t); + + /* verify SSID length */ + VERIFY_PROTOCOL(NameLen <= MAX_SSID_LEN); + /* update SSID length */ + Msg.Cmd.Args.Common.SsidLen = (_u8)NameLen; + + /* Profile with no security */ + /* Enterprise security profile */ + if (NULL != pSecExtParams) + { + /* Update command opcode */ + CmdCtrl.Opcode = SL_OPCODE_WLAN_WLANCONNECTEAPCOMMAND; + CmdCtrl.TxDescLen += sizeof(_WlanConnectEapCommand_t); + /* copy SSID */ + sl_Memcpy(EAP_SSID_STRING(&Msg), pName, NameLen); + CmdCtrl.TxDescLen += NameLen; + /* Copy password if supplied */ + if ((NULL != pSecParams) && (pSecParams->KeyLen > 0)) + { + /* update security type */ + Msg.Cmd.Args.Common.SecType = pSecParams->Type; + /* verify key length */ + if (pSecParams->KeyLen > MAX_KEY_LEN) + { + return SL_INVALPARAM; + } + /* update key length */ + Msg.Cmd.Args.Common.PasswordLen = pSecParams->KeyLen; + ARG_CHECK_PTR(pSecParams->Key); + /* copy key */ + sl_Memcpy(EAP_PASSWORD_STRING(&Msg), pSecParams->Key, pSecParams->KeyLen); + CmdCtrl.TxDescLen += pSecParams->KeyLen; + } + else + { + Msg.Cmd.Args.Common.PasswordLen = 0; + } + + ARG_CHECK_PTR(pSecExtParams); + /* Update Eap bitmask */ + Msg.Cmd.Args.EapBitmask = pSecExtParams->EapMethod; + /* Update Certificate file ID index - currently not supported */ + Msg.Cmd.Args.CertIndex = pSecExtParams->CertIndex; + /* verify user length */ + if (pSecExtParams->UserLen > MAX_USER_LEN) + { + return SL_INVALPARAM; + } + Msg.Cmd.Args.UserLen = pSecExtParams->UserLen; + /* copy user name (identity) */ + if(pSecExtParams->UserLen > 0) + { + sl_Memcpy(EAP_USER_STRING(&Msg), pSecExtParams->User, pSecExtParams->UserLen); + CmdCtrl.TxDescLen += pSecExtParams->UserLen; + } + /* verify Anonymous user length */ + if (pSecExtParams->AnonUserLen > MAX_ANON_USER_LEN) + { + return SL_INVALPARAM; + } + Msg.Cmd.Args.AnonUserLen = pSecExtParams->AnonUserLen; + /* copy Anonymous user */ + if(pSecExtParams->AnonUserLen > 0) + { + sl_Memcpy(EAP_ANON_USER_STRING(&Msg), pSecExtParams->AnonUser, pSecExtParams->AnonUserLen); + CmdCtrl.TxDescLen += pSecExtParams->AnonUserLen; + } + + } + + /* Regular or open security profile */ + else + { + /* Update command opcode */ + CmdCtrl.Opcode = SL_OPCODE_WLAN_WLANCONNECTCOMMAND; + CmdCtrl.TxDescLen += sizeof(_WlanConnectCommon_t); + /* copy SSID */ + sl_Memcpy(SSID_STRING(&Msg), pName, NameLen); + CmdCtrl.TxDescLen += NameLen; + /* Copy password if supplied */ + if( NULL != pSecParams ) + { + /* update security type */ + Msg.Cmd.Args.Common.SecType = pSecParams->Type; + /* verify key length is valid */ + if (pSecParams->KeyLen > MAX_KEY_LEN) + { + return SL_INVALPARAM; + } + /* update key length */ + Msg.Cmd.Args.Common.PasswordLen = pSecParams->KeyLen; + CmdCtrl.TxDescLen += pSecParams->KeyLen; + /* copy key (could be no key in case of WPS pin) */ + if( NULL != pSecParams->Key ) + { + sl_Memcpy(PASSWORD_STRING(&Msg), pSecParams->Key, pSecParams->KeyLen); + } + } + /* Profile with no security */ + else + { + Msg.Cmd.Args.Common.PasswordLen = 0; + Msg.Cmd.Args.Common.SecType = SL_SEC_TYPE_OPEN; + } + } + /* If BSSID is not null, copy to buffer, otherwise set to 0 */ + if(NULL != pMacAddr) + { + sl_Memcpy(Msg.Cmd.Args.Common.Bssid, pMacAddr, sizeof(Msg.Cmd.Args.Common.Bssid)); + } + else + { + sl_Memset(Msg.Cmd.Args.Common.Bssid, 0, sizeof(Msg.Cmd.Args.Common.Bssid)); + } + + + VERIFY_RET_OK ( _SlDrvCmdOp(&CmdCtrl, &Msg, NULL)); + + return (_i16)Msg.Rsp.status; +} +#endif + +/*******************************************************************************/ +/* sl_Disconnect */ +/* ******************************************************************************/ +#if _SL_INCLUDE_FUNC(sl_WlanDisconnect) +_i16 sl_WlanDisconnect(void) +{ + return _SlDrvBasicCmd(SL_OPCODE_WLAN_WLANDISCONNECTCOMMAND); +} +#endif + +/******************************************************************************/ +/* sl_PolicySet */ +/******************************************************************************/ +typedef union +{ + _WlanPoliciySetGet_t Cmd; + _BasicResponse_t Rsp; +}_SlPolicyMsg_u; + +const _SlCmdCtrl_t _SlPolicySetCmdCtrl = +{ + SL_OPCODE_WLAN_POLICYSETCOMMAND, + sizeof(_WlanPoliciySetGet_t), + sizeof(_BasicResponse_t) +}; + +#if _SL_INCLUDE_FUNC(sl_WlanPolicySet) +_i16 sl_WlanPolicySet(_u8 Type , const _u8 Policy, _u8 *pVal,_u8 ValLen) +{ + _SlPolicyMsg_u Msg; + _SlCmdExt_t CmdExt; + + CmdExt.TxPayloadLen = ValLen; + CmdExt.RxPayloadLen = 0; + CmdExt.pTxPayload = (_u8 *)pVal; + CmdExt.pRxPayload = NULL; + + + Msg.Cmd.PolicyType = Type; + Msg.Cmd.PolicyOption = Policy; + Msg.Cmd.PolicyOptionLen = ValLen; + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlPolicySetCmdCtrl, &Msg, &CmdExt)); + + return (_i16)Msg.Rsp.status; +} +#endif + + +/******************************************************************************/ +/* sl_PolicyGet */ +/******************************************************************************/ +typedef union +{ + _WlanPoliciySetGet_t Cmd; + _WlanPoliciySetGet_t Rsp; +}_SlPolicyGetMsg_u; + +const _SlCmdCtrl_t _SlPolicyGetCmdCtrl = +{ + SL_OPCODE_WLAN_POLICYGETCOMMAND, + sizeof(_WlanPoliciySetGet_t), + sizeof(_WlanPoliciySetGet_t) +}; + +#if _SL_INCLUDE_FUNC(sl_WlanPolicyGet) +_i16 sl_WlanPolicyGet(_u8 Type , _u8 Policy,_u8 *pVal,_u8 *pValLen) +{ + _SlPolicyGetMsg_u Msg; + _SlCmdExt_t CmdExt; + + if (*pValLen == 0) + { + return SL_EZEROLEN; + } + CmdExt.TxPayloadLen = 0; + CmdExt.RxPayloadLen = *pValLen; + CmdExt.pTxPayload = NULL; + CmdExt.pRxPayload = pVal; + CmdExt.ActualRxPayloadLen = 0; + + + Msg.Cmd.PolicyType = Type; + Msg.Cmd.PolicyOption = Policy; + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlPolicyGetCmdCtrl, &Msg, &CmdExt)); + + + if (CmdExt.RxPayloadLen < CmdExt.ActualRxPayloadLen) + { + *pValLen = Msg.Rsp.PolicyOptionLen; + return SL_ESMALLBUF; + } + else + { + /* no pointer valus, fill the results into _i8 */ + *pValLen = (_u8)CmdExt.ActualRxPayloadLen; + if( 0 == CmdExt.ActualRxPayloadLen ) + { + *pValLen = 1; + pVal[0] = Msg.Rsp.PolicyOption; + } + } + return (_i16)SL_OS_RET_CODE_OK; +} +#endif + + +/*******************************************************************************/ +/* sl_ProfileAdd */ +/*******************************************************************************/ +typedef struct +{ + _WlanAddGetEapProfile_t Args; + _i8 Strings[MAX_SSID_LEN + MAX_KEY_LEN + MAX_USER_LEN + MAX_ANON_USER_LEN]; +}_SlProfileParams_t; + +typedef union +{ + _SlProfileParams_t Cmd; + _BasicResponse_t Rsp; +}_SlProfileAddMsg_u; + + + +#if _SL_INCLUDE_FUNC(sl_WlanProfileAdd) +_i16 sl_WlanProfileAdd(_i8* pName, _i16 NameLen, _u8 *pMacAddr, SlSecParams_t* pSecParams , SlSecParamsExt_t* pSecExtParams, _u32 Priority, _u32 Options) +{ + _SlProfileAddMsg_u Msg; + _SlCmdCtrl_t CmdCtrl = {0}; + CmdCtrl.TxDescLen = 0;/* init */ + CmdCtrl.RxDescLen = sizeof(_BasicResponse_t); + + /* update priority */ + Msg.Cmd.Args.Common.Priority = (_u8)Priority; + /* verify SSID length */ + VERIFY_PROTOCOL(NameLen <= MAX_SSID_LEN); + /* update SSID length */ + Msg.Cmd.Args.Common.SsidLen = (_u8)NameLen; + + + /* Enterprise security profile */ + if (NULL != pSecExtParams) + { + /* Update command opcode */ + CmdCtrl.Opcode = SL_OPCODE_WLAN_EAP_PROFILEADDCOMMAND; + CmdCtrl.TxDescLen += sizeof(_WlanAddGetEapProfile_t); + + /* copy SSID */ + sl_Memcpy(EAP_PROFILE_SSID_STRING(&Msg), pName, NameLen); + CmdCtrl.TxDescLen += NameLen; + + /* Copy password if supplied */ + if ((NULL != pSecParams) && (pSecParams->KeyLen > 0)) + { + /* update security type */ + Msg.Cmd.Args.Common.SecType = pSecParams->Type; + + if( SL_SEC_TYPE_WEP == Msg.Cmd.Args.Common.SecType ) + { + Msg.Cmd.Args.Common.WepKeyId = 0; + } + + /* verify key length */ + if (pSecParams->KeyLen > MAX_KEY_LEN) + { + return SL_INVALPARAM; + } + VERIFY_PROTOCOL(pSecParams->KeyLen <= MAX_KEY_LEN); + /* update key length */ + Msg.Cmd.Args.Common.PasswordLen = pSecParams->KeyLen; + CmdCtrl.TxDescLen += pSecParams->KeyLen; + ARG_CHECK_PTR(pSecParams->Key); + /* copy key */ + sl_Memcpy(EAP_PROFILE_PASSWORD_STRING(&Msg), pSecParams->Key, pSecParams->KeyLen); + } + else + { + Msg.Cmd.Args.Common.PasswordLen = 0; + } + + ARG_CHECK_PTR(pSecExtParams); + /* Update Eap bitmask */ + Msg.Cmd.Args.EapBitmask = pSecExtParams->EapMethod; + /* Update Certificate file ID index - currently not supported */ + Msg.Cmd.Args.CertIndex = pSecExtParams->CertIndex; + /* verify user length */ + if (pSecExtParams->UserLen > MAX_USER_LEN) + { + return SL_INVALPARAM; + } + Msg.Cmd.Args.UserLen = pSecExtParams->UserLen; + /* copy user name (identity) */ + if(pSecExtParams->UserLen > 0) + { + sl_Memcpy(EAP_PROFILE_USER_STRING(&Msg), pSecExtParams->User, pSecExtParams->UserLen); + CmdCtrl.TxDescLen += pSecExtParams->UserLen; + } + + /* verify Anonymous user length (for tunneled) */ + if (pSecExtParams->AnonUserLen > MAX_ANON_USER_LEN) + { + return SL_INVALPARAM; + } + Msg.Cmd.Args.AnonUserLen = pSecExtParams->AnonUserLen; + + /* copy Anonymous user */ + if(pSecExtParams->AnonUserLen > 0) + { + sl_Memcpy(EAP_PROFILE_ANON_USER_STRING(&Msg), pSecExtParams->AnonUser, pSecExtParams->AnonUserLen); + CmdCtrl.TxDescLen += pSecExtParams->AnonUserLen; + } + + } + /* Regular or open security profile */ + else + { + /* Update command opcode */ + CmdCtrl.Opcode = SL_OPCODE_WLAN_PROFILEADDCOMMAND; + /* update commnad length */ + CmdCtrl.TxDescLen += sizeof(_WlanAddGetProfile_t); + + if (NULL != pName) + { + /* copy SSID */ + sl_Memcpy(PROFILE_SSID_STRING(&Msg), pName, NameLen); + CmdCtrl.TxDescLen += NameLen; + } + + /* Copy password if supplied */ + if( NULL != pSecParams ) + { + /* update security type */ + Msg.Cmd.Args.Common.SecType = pSecParams->Type; + + if( SL_SEC_TYPE_WEP == Msg.Cmd.Args.Common.SecType ) + { + Msg.Cmd.Args.Common.WepKeyId = 0; + } + + /* verify key length */ + if (pSecParams->KeyLen > MAX_KEY_LEN) + { + return SL_INVALPARAM; + } + /* update key length */ + Msg.Cmd.Args.Common.PasswordLen = pSecParams->KeyLen; + CmdCtrl.TxDescLen += pSecParams->KeyLen; + /* copy key (could be no key in case of WPS pin) */ + if( NULL != pSecParams->Key ) + { + sl_Memcpy(PROFILE_PASSWORD_STRING(&Msg), pSecParams->Key, pSecParams->KeyLen); + } + } + else + { + Msg.Cmd.Args.Common.SecType = SL_SEC_TYPE_OPEN; + Msg.Cmd.Args.Common.PasswordLen = 0; + } + + } + + + /* If BSSID is not null, copy to buffer, otherwise set to 0 */ + if(NULL != pMacAddr) + { + sl_Memcpy(Msg.Cmd.Args.Common.Bssid, pMacAddr, sizeof(Msg.Cmd.Args.Common.Bssid)); + } + else + { + sl_Memset(Msg.Cmd.Args.Common.Bssid, 0, sizeof(Msg.Cmd.Args.Common.Bssid)); + } + + VERIFY_RET_OK(_SlDrvCmdOp(&CmdCtrl, &Msg, NULL)); + + return (_i16)Msg.Rsp.status; +} +#endif +/*******************************************************************************/ +/* sl_ProfileGet */ +/*******************************************************************************/ +typedef union +{ + _WlanProfileDelGetCommand_t Cmd; + _SlProfileParams_t Rsp; +}_SlProfileGetMsg_u; + +const _SlCmdCtrl_t _SlProfileGetCmdCtrl = +{ + SL_OPCODE_WLAN_PROFILEGETCOMMAND, + sizeof(_WlanProfileDelGetCommand_t), + sizeof(_SlProfileParams_t) +}; + +#if _SL_INCLUDE_FUNC(sl_WlanProfileGet) +_i16 sl_WlanProfileGet(_i16 Index,_i8* pName, _i16 *pNameLen, _u8 *pMacAddr, SlSecParams_t* pSecParams, SlGetSecParamsExt_t* pEntParams, _u32 *pPriority) +{ + _SlProfileGetMsg_u Msg; + Msg.Cmd.index = (_u8)Index; + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlProfileGetCmdCtrl, &Msg, NULL)); + + pSecParams->Type = Msg.Rsp.Args.Common.SecType; + /* since password is not transferred in getprofile, password length should always be zero */ + pSecParams->KeyLen = Msg.Rsp.Args.Common.PasswordLen; + if (NULL != pEntParams) + { + pEntParams->UserLen = Msg.Rsp.Args.UserLen; + /* copy user name */ + if (pEntParams->UserLen > 0) + { + sl_Memcpy(pEntParams->User, EAP_PROFILE_USER_STRING(&Msg), pEntParams->UserLen); + } + pEntParams->AnonUserLen = Msg.Rsp.Args.AnonUserLen; + /* copy anonymous user name */ + if (pEntParams->AnonUserLen > 0) + { + sl_Memcpy(pEntParams->AnonUser, EAP_PROFILE_ANON_USER_STRING(&Msg), pEntParams->AnonUserLen); + } + } + + *pNameLen = Msg.Rsp.Args.Common.SsidLen; + *pPriority = Msg.Rsp.Args.Common.Priority; + + if (NULL != Msg.Rsp.Args.Common.Bssid) + { + sl_Memcpy(pMacAddr, Msg.Rsp.Args.Common.Bssid, sizeof(Msg.Rsp.Args.Common.Bssid)); + } + + sl_Memcpy(pName, EAP_PROFILE_SSID_STRING(&Msg), *pNameLen); + + return (_i16)Msg.Rsp.Args.Common.SecType; + +} +#endif +/*******************************************************************************/ +/* sl_ProfileDel */ +/*******************************************************************************/ +typedef union +{ + _WlanProfileDelGetCommand_t Cmd; + _BasicResponse_t Rsp; +}_SlProfileDelMsg_u; + +const _SlCmdCtrl_t _SlProfileDelCmdCtrl = +{ + SL_OPCODE_WLAN_PROFILEDELCOMMAND, + sizeof(_WlanProfileDelGetCommand_t), + sizeof(_BasicResponse_t) +}; + +#if _SL_INCLUDE_FUNC(sl_WlanProfileDel) +_i16 sl_WlanProfileDel(_i16 Index) +{ + _SlProfileDelMsg_u Msg; + + Msg.Cmd.index = (_u8)Index; + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlProfileDelCmdCtrl, &Msg, NULL)); + + return (_i16)Msg.Rsp.status; +} +#endif + + +/******************************************************************************/ +/* sl_WlanGetNetworkList */ +/******************************************************************************/ +typedef union +{ + _WlanGetNetworkListCommand_t Cmd; + _WlanGetNetworkListResponse_t Rsp; +}_SlWlanGetNetworkListMsg_u; + +const _SlCmdCtrl_t _SlWlanGetNetworkListCtrl = +{ + SL_OPCODE_WLAN_SCANRESULTSGETCOMMAND, + sizeof(_WlanGetNetworkListCommand_t), + sizeof(_WlanGetNetworkListResponse_t) +}; + + +#if _SL_INCLUDE_FUNC(sl_WlanGetNetworkList) +_i16 sl_WlanGetNetworkList(_u8 Index, _u8 Count, Sl_WlanNetworkEntry_t *pEntries) +{ + _i16 retVal = 0; + _SlWlanGetNetworkListMsg_u Msg; + _SlCmdExt_t CmdExt; + + if (Count == 0) + { + return SL_EZEROLEN; + } + CmdExt.TxPayloadLen = 0; + CmdExt.RxPayloadLen = sizeof(Sl_WlanNetworkEntry_t)*(Count); + CmdExt.pTxPayload = NULL; + CmdExt.pRxPayload = (_u8 *)pEntries; + + Msg.Cmd.index = Index; + Msg.Cmd.count = Count; + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlWlanGetNetworkListCtrl, &Msg, &CmdExt)); + retVal = Msg.Rsp.status; + + return (_i16)retVal; +} +#endif + + + + + +/******************************************************************************/ +/* RX filters message command response structures */ +/******************************************************************************/ + +/* Set command */ +typedef union +{ + _WlanRxFilterAddCommand_t Cmd; + _WlanRxFilterAddCommandReponse_t Rsp; +}_SlrxFilterAddMsg_u; + +const _SlCmdCtrl_t _SlRxFilterAddtCmdCtrl = +{ + SL_OPCODE_WLAN_WLANRXFILTERADDCOMMAND, + sizeof(_WlanRxFilterAddCommand_t), + sizeof(_WlanRxFilterAddCommandReponse_t) +}; + + +/* Set command */ +typedef union _SlRxFilterSetMsg_u +{ + _WlanRxFilterSetCommand_t Cmd; + _WlanRxFilterSetCommandReponse_t Rsp; +}_SlRxFilterSetMsg_u; + + +const _SlCmdCtrl_t _SlRxFilterSetCmdCtrl = +{ + SL_OPCODE_WLAN_WLANRXFILTERSETCOMMAND, + sizeof(_WlanRxFilterSetCommand_t), + sizeof(_WlanRxFilterSetCommandReponse_t) +}; + +/* Get command */ +typedef union _SlRxFilterGetMsg_u +{ + _WlanRxFilterGetCommand_t Cmd; + _WlanRxFilterGetCommandReponse_t Rsp; +}_SlRxFilterGetMsg_u; + + +const _SlCmdCtrl_t _SlRxFilterGetCmdCtrl = +{ + SL_OPCODE_WLAN_WLANRXFILTERGETCOMMAND, + sizeof(_WlanRxFilterGetCommand_t), + sizeof(_WlanRxFilterGetCommandReponse_t) +}; + + +/*******************************************************************************/ +/* RX filters */ +/*******************************************************************************/ + +#if _SL_INCLUDE_FUNC(sl_WlanRxFilterAdd) +SlrxFilterID_t sl_WlanRxFilterAdd( SlrxFilterRuleType_t RuleType, + SlrxFilterFlags_t FilterFlags, + const SlrxFilterRule_t* const Rule, + const SlrxFilterTrigger_t* const Trigger, + const SlrxFilterAction_t* const Action, + SlrxFilterID_t* pFilterId) +{ + + + _SlrxFilterAddMsg_u Msg; + Msg.Cmd.RuleType = RuleType; + /* filterId is zero */ + Msg.Cmd.FilterId = 0; + Msg.Cmd.FilterFlags = FilterFlags; + sl_Memcpy( &(Msg.Cmd.Rule), Rule, sizeof(SlrxFilterRule_t) ); + sl_Memcpy( &(Msg.Cmd.Trigger), Trigger, sizeof(SlrxFilterTrigger_t) ); + sl_Memcpy( &(Msg.Cmd.Action), Action, sizeof(SlrxFilterAction_t) ); + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlRxFilterAddtCmdCtrl, &Msg, NULL) ); + *pFilterId = Msg.Rsp.FilterId; + return (_i16)Msg.Rsp.Status; + +} +#endif + + + +/*******************************************************************************/ +/* RX filters */ +/*******************************************************************************/ +#if _SL_INCLUDE_FUNC(sl_WlanRxFilterSet) +_i16 sl_WlanRxFilterSet(const SLrxFilterOperation_t RxFilterOperation, + const _u8* const pInputBuffer, + _u16 InputbufferLength) +{ + _SlRxFilterSetMsg_u Msg; + _SlCmdExt_t CmdExt; + + CmdExt.TxPayloadLen = InputbufferLength; + CmdExt.pTxPayload = (_u8 *)pInputBuffer; + CmdExt.RxPayloadLen = 0; + CmdExt.pRxPayload = (_u8 *)NULL; + + Msg.Cmd.RxFilterOperation = RxFilterOperation; + Msg.Cmd.InputBufferLength = InputbufferLength; + + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlRxFilterSetCmdCtrl, &Msg, &CmdExt) ); + + + return (_i16)Msg.Rsp.Status; +} +#endif + +/******************************************************************************/ +/* RX filters */ +/******************************************************************************/ +#if _SL_INCLUDE_FUNC(sl_WlanRxFilterGet) +_i16 sl_WlanRxFilterGet(const SLrxFilterOperation_t RxFilterOperation, + _u8* pOutputBuffer, + _u16 OutputbufferLength) +{ + _SlRxFilterGetMsg_u Msg; + _SlCmdExt_t CmdExt; + + if (OutputbufferLength == 0) + { + return SL_EZEROLEN; + } + CmdExt.TxPayloadLen = 0; + CmdExt.pTxPayload = NULL; + CmdExt.RxPayloadLen = OutputbufferLength; + CmdExt.pRxPayload = (_u8 *)pOutputBuffer; + CmdExt.ActualRxPayloadLen = 0; + + Msg.Cmd.RxFilterOperation = RxFilterOperation; + Msg.Cmd.OutputBufferLength = OutputbufferLength; + + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlRxFilterGetCmdCtrl, &Msg, &CmdExt) ); + + if (CmdExt.RxPayloadLen < CmdExt.ActualRxPayloadLen) + { + return SL_ESMALLBUF; + } + + return (_i16)Msg.Rsp.Status; +} +#endif + +/*******************************************************************************/ +/* sl_WlanRxStatStart */ +/*******************************************************************************/ +#if _SL_INCLUDE_FUNC(sl_WlanRxStatStart) +_i16 sl_WlanRxStatStart(void) +{ + return _SlDrvBasicCmd(SL_OPCODE_WLAN_STARTRXSTATCOMMAND); +} +#endif + +#if _SL_INCLUDE_FUNC(sl_WlanRxStatStop) +_i16 sl_WlanRxStatStop(void) +{ + return _SlDrvBasicCmd(SL_OPCODE_WLAN_STOPRXSTATCOMMAND); +} +#endif + +#if _SL_INCLUDE_FUNC(sl_WlanRxStatGet) +_i16 sl_WlanRxStatGet(SlGetRxStatResponse_t *pRxStat,_u32 Flags) +{ + _SlCmdCtrl_t CmdCtrl = {SL_OPCODE_WLAN_GETRXSTATCOMMAND, 0, sizeof(SlGetRxStatResponse_t)}; + sl_Memset(pRxStat,0,sizeof(SlGetRxStatResponse_t)); + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&CmdCtrl, pRxStat, NULL)); + + return 0; +} +#endif + + + +/******************************************************************************/ +/* sl_WlanSmartConfigStop */ +/******************************************************************************/ +#if _SL_INCLUDE_FUNC(sl_WlanSmartConfigStop) +_i16 sl_WlanSmartConfigStop(void) +{ + return _SlDrvBasicCmd(SL_OPCODE_WLAN_SMART_CONFIG_STOP_COMMAND); +} +#endif + + +/******************************************************************************/ +/* sl_WlanSmartConfigStart */ +/******************************************************************************/ + + +typedef struct +{ + _WlanSmartConfigStartCommand_t Args; + _i8 Strings[3 * MAX_SMART_CONFIG_KEY]; /* public key + groupId1 key + groupId2 key */ +}_SlSmartConfigStart_t; + +typedef union +{ + _SlSmartConfigStart_t Cmd; + _BasicResponse_t Rsp; +}_SlSmartConfigStartMsg_u; + +const _SlCmdCtrl_t _SlSmartConfigStartCmdCtrl = +{ + SL_OPCODE_WLAN_SMART_CONFIG_START_COMMAND, + sizeof(_SlSmartConfigStart_t), + sizeof(_BasicResponse_t) +}; + +#if _SL_INCLUDE_FUNC(sl_WlanSmartConfigStart) +_i16 sl_WlanSmartConfigStart( const _u32 groupIdBitmask, + const _u8 cipher, + const _u8 publicKeyLen, + const _u8 group1KeyLen, + const _u8 group2KeyLen, + const _u8* pPublicKey, + const _u8* pGroup1Key, + const _u8* pGroup2Key) +{ + _SlSmartConfigStartMsg_u Msg; + + Msg.Cmd.Args.groupIdBitmask = (_u8)groupIdBitmask; + Msg.Cmd.Args.cipher = (_u8)cipher; + Msg.Cmd.Args.publicKeyLen = (_u8)publicKeyLen; + Msg.Cmd.Args.group1KeyLen = (_u8)group1KeyLen; + Msg.Cmd.Args.group2KeyLen = (_u8)group2KeyLen; + + /* copy keys (if exist) after command (one after another) */ + sl_Memcpy(SMART_CONFIG_START_PUBLIC_KEY_STRING(&Msg), pPublicKey, publicKeyLen); + sl_Memcpy(SMART_CONFIG_START_GROUP1_KEY_STRING(&Msg), pGroup1Key, group1KeyLen); + sl_Memcpy(SMART_CONFIG_START_GROUP2_KEY_STRING(&Msg), pGroup2Key, group2KeyLen); + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlSmartConfigStartCmdCtrl , &Msg, NULL)); + + return (_i16)Msg.Rsp.status; + + +} +#endif + + +/*******************************************************************************/ +/* sl_WlanSetMode */ +/*******************************************************************************/ +typedef union +{ + _WlanSetMode_t Cmd; + _BasicResponse_t Rsp; +}_SlwlanSetModeMsg_u; + +const _SlCmdCtrl_t _SlWlanSetModeCmdCtrl = +{ + SL_OPCODE_WLAN_SET_MODE, + sizeof(_WlanSetMode_t), + sizeof(_BasicResponse_t) +}; + +/* possible values are: +WLAN_SET_STA_MODE = 1 +WLAN_SET_AP_MODE = 2 +WLAN_SET_P2P_MODE = 3 */ + +#if _SL_INCLUDE_FUNC(sl_WlanSetMode) +_i16 sl_WlanSetMode(const _u8 mode) +{ + _SlwlanSetModeMsg_u Msg; + + Msg.Cmd.mode = mode; + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlWlanSetModeCmdCtrl , &Msg, NULL)); + + return (_i16)Msg.Rsp.status; + +} +#endif + + + + +/*******************************************************************************/ +/* sl_WlanSet */ +/* ******************************************************************************/ +typedef union +{ + _WlanCfgSetGet_t Cmd; + _BasicResponse_t Rsp; +}_SlWlanCfgSetMsg_u; + +const _SlCmdCtrl_t _SlWlanCfgSetCmdCtrl = +{ + SL_OPCODE_WLAN_CFG_SET, + sizeof(_WlanCfgSetGet_t), + sizeof(_BasicResponse_t) +}; + + +#if _SL_INCLUDE_FUNC(sl_WlanSet) +_i16 sl_WlanSet(_u16 ConfigId ,_u16 ConfigOpt,_u16 ConfigLen, _u8 *pValues) +{ + _SlWlanCfgSetMsg_u Msg; + _SlCmdExt_t CmdExt; + + CmdExt.TxPayloadLen = (ConfigLen+3) & (~3); + CmdExt.RxPayloadLen = 0; + CmdExt.pTxPayload = (_u8 *)pValues; + CmdExt.pRxPayload = NULL; + + + Msg.Cmd.ConfigId = ConfigId; + Msg.Cmd.ConfigLen = ConfigLen; + Msg.Cmd.ConfigOpt = ConfigOpt; + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlWlanCfgSetCmdCtrl, &Msg, &CmdExt)); + + return (_i16)Msg.Rsp.status; +} +#endif + + +/******************************************************************************/ +/* sl_WlanGet */ +/******************************************************************************/ +typedef union +{ + _WlanCfgSetGet_t Cmd; + _WlanCfgSetGet_t Rsp; +}_SlWlanCfgMsgGet_u; + +const _SlCmdCtrl_t _SlWlanCfgGetCmdCtrl = +{ + SL_OPCODE_WLAN_CFG_GET, + sizeof(_WlanCfgSetGet_t), + sizeof(_WlanCfgSetGet_t) +}; + +#if _SL_INCLUDE_FUNC(sl_WlanGet) +_i16 sl_WlanGet(_u16 ConfigId, _u16 *pConfigOpt,_u16 *pConfigLen, _u8 *pValues) +{ + _SlWlanCfgMsgGet_u Msg; + _SlCmdExt_t CmdExt; + + if (*pConfigLen == 0) + { + return SL_EZEROLEN; + } + CmdExt.TxPayloadLen = 0; + CmdExt.RxPayloadLen = *pConfigLen; + CmdExt.pTxPayload = NULL; + CmdExt.pRxPayload = (_u8 *)pValues; + CmdExt.ActualRxPayloadLen = 0; + + Msg.Cmd.ConfigId = ConfigId; + if( pConfigOpt ) + { + Msg.Cmd.ConfigOpt = (_u16)*pConfigOpt; + } + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlWlanCfgGetCmdCtrl, &Msg, &CmdExt)); + + if( pConfigOpt ) + { + *pConfigOpt = (_u8)Msg.Rsp.ConfigOpt; + } + if (CmdExt.RxPayloadLen < CmdExt.ActualRxPayloadLen) + { + *pConfigLen = (_u8)CmdExt.RxPayloadLen; + return SL_ESMALLBUF; + } + else + { + *pConfigLen = (_u8)CmdExt.ActualRxPayloadLen; + } + + + return (_i16)Msg.Rsp.Status; +} +#endif |
