summaryrefslogtreecommitdiffstatshomepage
path: root/drivers/cc3100/src
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2015-02-21 19:52:07 +0000
committerDamien George <damien.p.george@gmail.com>2015-02-21 19:52:07 +0000
commit49c2ad4fb417b8f0a9d815ff3295fb1af94965f7 (patch)
treec8509c73c23216f937a7aaad7b2257e1c5d6a7b5 /drivers/cc3100/src
parent36e2845e3616de8de96741e9608fbb65ccd8091d (diff)
downloadmicropython-49c2ad4fb417b8f0a9d815ff3295fb1af94965f7.tar.gz
micropython-49c2ad4fb417b8f0a9d815ff3295fb1af94965f7.zip
cc3200: Move CC3100 driver from cc3200/simplelink to drivers/cc3100.
This commit will not build, it exists just to track changes.
Diffstat (limited to 'drivers/cc3100/src')
-rw-r--r--drivers/cc3100/src/device.c535
-rw-r--r--drivers/cc3100/src/driver.c1520
-rw-r--r--drivers/cc3100/src/flowcont.c71
-rw-r--r--drivers/cc3100/src/fs.c415
-rw-r--r--drivers/cc3100/src/netapp.c1285
-rw-r--r--drivers/cc3100/src/netcfg.c142
-rw-r--r--drivers/cc3100/src/nonos.c153
-rw-r--r--drivers/cc3100/src/socket.c1123
-rw-r--r--drivers/cc3100/src/spawn.c197
-rw-r--r--drivers/cc3100/src/wlan.c993
10 files changed, 6434 insertions, 0 deletions
diff --git a/drivers/cc3100/src/device.c b/drivers/cc3100/src/device.c
new file mode 100644
index 0000000000..95907cf7f9
--- /dev/null
+++ b/drivers/cc3100/src/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/drivers/cc3100/src/driver.c b/drivers/cc3100/src/driver.c
new file mode 100644
index 0000000000..62d0aa8f45
--- /dev/null
+++ b/drivers/cc3100/src/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/drivers/cc3100/src/flowcont.c b/drivers/cc3100/src/flowcont.c
new file mode 100644
index 0000000000..889241ea2b
--- /dev/null
+++ b/drivers/cc3100/src/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/drivers/cc3100/src/fs.c b/drivers/cc3100/src/fs.c
new file mode 100644
index 0000000000..cc65e219e9
--- /dev/null
+++ b/drivers/cc3100/src/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/drivers/cc3100/src/netapp.c b/drivers/cc3100/src/netapp.c
new file mode 100644
index 0000000000..32315e093a
--- /dev/null
+++ b/drivers/cc3100/src/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/drivers/cc3100/src/netcfg.c b/drivers/cc3100/src/netcfg.c
new file mode 100644
index 0000000000..36d1e1fa97
--- /dev/null
+++ b/drivers/cc3100/src/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/drivers/cc3100/src/nonos.c b/drivers/cc3100/src/nonos.c
new file mode 100644
index 0000000000..9e7d1772e2
--- /dev/null
+++ b/drivers/cc3100/src/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/drivers/cc3100/src/socket.c b/drivers/cc3100/src/socket.c
new file mode 100644
index 0000000000..34dd4a8b43
--- /dev/null
+++ b/drivers/cc3100/src/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/drivers/cc3100/src/spawn.c b/drivers/cc3100/src/spawn.c
new file mode 100644
index 0000000000..fdf1930ca4
--- /dev/null
+++ b/drivers/cc3100/src/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/drivers/cc3100/src/wlan.c b/drivers/cc3100/src/wlan.c
new file mode 100644
index 0000000000..0cc825439f
--- /dev/null
+++ b/drivers/cc3100/src/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