SimpleLink CC31xx/CC32xx Host Driver  Version 3.0.1.71
Simplifies the implementation of Internet connectivity
device.c
1 /*
2  * device.c - CC31xx/CC32xx Host Driver Implementation
3  *
4  * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/
5  *
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  *
14  * Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the
17  * distribution.
18  *
19  * Neither the name of Texas Instruments Incorporated nor the names of
20  * its contributors may be used to endorse or promote products derived
21  * from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  *
35  */
36 
37 /*****************************************************************************/
38 /* Include files */
39 /*****************************************************************************/
40 #include <ti/drivers/net/wifi/simplelink.h>
41 #include <ti/drivers/net/wifi/source/protocol.h>
42 #include <ti/drivers/net/wifi/source/driver.h>
43 #include <ti/drivers/net/wifi/source/flowcont.h>
44 
45 /*****************************************************************************/
46 /* Internal functions */
47 /*****************************************************************************/
48 
49 static _i16 _SlDeviceGetStartResponseConvert(_i32 Status);
50 void _SlDeviceHandleResetRequestInternally(void);
51 void _SlDeviceResetRequestInitCompletedCB(_u32 Status, SlDeviceInitInfo_t *DeviceInitInfo);
52 
53 #define RESET_REQUEST_STOP_TIMEOUT (300)
54 
55 #ifndef SL_IF_OPEN_FLAGS
56 #define SL_IF_OPEN_FLAGS (0x0)
57 #endif
58 
59 #ifndef SL_IF_UART_REOPEN_FLAGS
60 #define SL_IF_UART_REOPEN_FLAGS (0x1)
61 #endif
62 
63 typedef struct
64 {
65  const void *pIfHdl; /* Holds the last opened interface handle */
66  _i8 *pDevName; /* Holds the last opened interface parameters */
67  _u32 ResetRequestSessionNumber; /* Special session number to be verified upon every reset request during provisioning */
68 } _SlDeviceCb_t;
69 
70 _SlDeviceCb_t DeviceCB; /* the device control block */
71 
72 static const _i16 StartResponseLUT[16] =
73 {
74  ROLE_RESERVED,
75  ROLE_STA,
76  SL_ERROR_ROLE_STA_ERR,
77  ROLE_AP,
78  SL_ERROR_ROLE_AP_ERR,
79  ROLE_P2P,
80  SL_ERROR_ROLE_P2P_ERR,
81  SL_ERROR_CALIB_FAIL,
82  SL_ERROR_FS_CORRUPTED_ERR,
83  SL_ERROR_FS_ALERT_ERR,
84  SL_ERROR_RESTORE_IMAGE_COMPLETE,
85  SL_ERROR_INCOMPLETE_PROGRAMMING,
86  ROLE_TAG,
87  SL_ERROR_ROLE_TAG_ERR,
88  SL_ERROR_FIPS_ERR,
89  SL_ERROR_GENERAL_ERR
90 };
91 
92 static _i16 _SlDeviceGetStartResponseConvert(_i32 Status)
93 {
94  return StartResponseLUT[Status & 0xF];
95 }
96 
97 /*****************************************************************************/
98 /* API Functions */
99 /*****************************************************************************/
100 
101 /*****************************************************************************/
102 /* sl_Task */
103 /*****************************************************************************/
104 #if _SL_INCLUDE_FUNC(sl_Task)
105 void* sl_Task(void* pEntry)
106 {
107 #ifdef _SlTaskEntry
108  return (void*)_SlTaskEntry();
109 #else
110  return (void*)0;
111 #endif
112 }
113 #endif
114 
115 /*****************************************************************************/
116 /* sl_Start */
117 /*****************************************************************************/
118 #if _SL_INCLUDE_FUNC(sl_Start)
119 _i16 sl_Start(const void* pIfHdl, _i8* pDevName, const P_INIT_CALLBACK pInitCallBack)
120 {
121  _i16 ObjIdx = MAX_CONCURRENT_ACTIONS;
122  InitComplete_t AsyncRsp;
123  int ret = 0; // added for releasePoolObj
124 
125  _SlDrvMemZero(&AsyncRsp, sizeof(InitComplete_t));
126 
127  /* verify no error handling in progress. if in progress than
128  ignore the API execution and return immediately with an error */
129  VERIFY_NO_ERROR_HANDLING_IN_PROGRESS();
130  if (SL_IS_DEVICE_STARTED)
131  {
132  return SL_RET_CODE_DEV_ALREADY_STARTED;
133  }
134  /* Perform any preprocessing before enable networking services */
135 #ifdef sl_DeviceEnablePreamble
136  sl_DeviceEnablePreamble();
137 #endif
138 
139  /* ControlBlock init */
140  (void)_SlDrvDriverCBInit();
141 
142  /* open the interface: usually SPI or UART */
143  if (NULL == pIfHdl)
144  {
145  g_pCB->FD = sl_IfOpen((void *)pDevName, SL_IF_OPEN_FLAGS);
146  }
147  else
148  {
149  g_pCB->FD = (_SlFd_t)pIfHdl;
150  }
151 
152  ObjIdx = _SlDrvProtectAsyncRespSetting((_u8 *)&AsyncRsp, START_STOP_ID, SL_MAX_SOCKETS);
153 
154  if (ObjIdx < 0)
155  {
156  return ObjIdx;
157  }
158 
159  if( g_pCB->FD >= (_SlFd_t)0)
160  {
161  /* store the interface parameters for the internal call of the
162  sl_start to be called upon reset request handling */
163  DeviceCB.pIfHdl = pIfHdl;
164  DeviceCB.pDevName = pDevName;
165 
166  /* Mark that device is in progress! */
167  SL_SET_DEVICE_START_IN_PROGRESS;
168 
169  sl_DeviceDisable();
170 
171  sl_IfRegIntHdlr((SL_P_EVENT_HANDLER)_SlDrvRxIrqHandler, NULL);
172 
173  g_pCB->pInitCallback = pInitCallBack;
174  sl_DeviceEnable();
175 
176  if (NULL == pInitCallBack)
177  {
178  ret = _SlDrvWaitForInternalAsyncEvent(ObjIdx, INIT_COMPLETE_TIMEOUT, SL_OPCODE_DEVICE_INITCOMPLETE);
179 
180  SL_UNSET_DEVICE_START_IN_PROGRESS;
181 
182  SL_SET_DEVICE_STARTED;
183 
184  /* release Pool Object */
185  _SlDrvReleasePoolObj(g_pCB->FunctionParams.AsyncExt.ActionIndex);
186  if(ret < 0)
187  {
188  return ret;
189  }
190  else
191  {
192  return _SlDeviceGetStartResponseConvert(AsyncRsp.Status);
193  }
194  }
195  else
196  {
197  return SL_RET_CODE_OK;
198  }
199  }
200  return SL_BAD_INTERFACE;
201 }
202 #endif
203 
204 /***************************************************************************
205 _SlDeviceHandleAsync_InitComplete - handles init complete signalling to
206 a waiting object
207 ****************************************************************************/
208 _SlReturnVal_t _SlDeviceHandleAsync_InitComplete(void *pVoidBuf)
209 {
210  InitComplete_t *pMsgArgs = (InitComplete_t *)_SL_RESP_ARGS_START(pVoidBuf);
211  SlDeviceInitInfo_t DeviceInitInfo;
212 
213  SL_DRV_PROTECTION_OBJ_LOCK_FOREVER();
214 
215  if(g_pCB->pInitCallback)
216  {
217  DeviceInitInfo.ChipId = pMsgArgs->ChipId;
218  DeviceInitInfo.MoreData = pMsgArgs->MoreData;
219  g_pCB->pInitCallback(_SlDeviceGetStartResponseConvert(pMsgArgs->Status), &DeviceInitInfo);
220  }
221  else
222  {
223  sl_Memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(InitComplete_t));
224  SL_DRV_SYNC_OBJ_SIGNAL(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj);
225  }
226 
227  SL_DRV_PROTECTION_OBJ_UNLOCK();
228  if(g_pCB->pInitCallback)
229  {
230  SL_SET_DEVICE_STARTED;
231  SL_UNSET_DEVICE_START_IN_PROGRESS;
232  _SlDrvReleasePoolObj(g_pCB->FunctionParams.AsyncExt.ActionIndex);
233  }
234 
235  return SL_OS_RET_CODE_OK;
236  }
237 
238 
239 /***************************************************************************
240 _SlDeviceHandleAsync_Stop - handles stop signalling to
241 a waiting object
242 ****************************************************************************/
243 void _SlDeviceHandleAsync_Stop(void *pVoidBuf)
244 {
245  _BasicResponse_t *pMsgArgs = (_BasicResponse_t *)_SL_RESP_ARGS_START(pVoidBuf);
246 
247  VERIFY_SOCKET_CB(NULL != g_pCB->StopCB.pAsyncRsp);
248 
249  SL_DRV_PROTECTION_OBJ_LOCK_FOREVER();
250 
251  if (g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs != NULL)
252  {
253  sl_Memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(_BasicResponse_t));
254  SL_DRV_SYNC_OBJ_SIGNAL(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj);
255  }
256 
257  SL_DRV_PROTECTION_OBJ_UNLOCK();
258 
259  return;
260 }
261 
262 
263 /*****************************************************************************
264 sl_stop
265 ******************************************************************************/
266 typedef union
267 {
269  _BasicResponse_t Rsp;
270 }_SlStopMsg_u;
271 
272 static const _SlCmdCtrl_t _SlStopCmdCtrl =
273 {
274  SL_OPCODE_DEVICE_STOP_COMMAND,
275  (_SlArgSize_t)sizeof(SlDeviceStopCommand_t),
276  (_SlArgSize_t)sizeof(_BasicResponse_t)
277 };
278 
279 #if _SL_INCLUDE_FUNC(sl_Stop)
280 _i16 sl_Stop(const _u16 Timeout)
281 {
282  _i16 RetVal=0;
283  _SlStopMsg_u Msg;
284  _BasicResponse_t AsyncRsp;
285  _i16 ObjIdx = MAX_CONCURRENT_ACTIONS;
286  _u8 ReleasePoolObject = FALSE;
287  _u8 IsProvInProgress = FALSE;
288 
289  /* NOTE: don't check VERIFY_API_ALLOWED(), this command is not
290  * filtered in error handling and also not filtered in NWP lock state.
291  * If we are in the middle of assert handling than ignore stopping
292  * the device with timeout and force immediate shutdown as we would like
293  * to avoid any additional commands to the NWP */
294  if( (Timeout != 0) && (SL_IS_DEVICE_STARTED)
295  && (!SL_IS_RESTART_REQUIRED))
296  {
297  /* Clear the Async response structure */
298  _SlDrvMemZero(&AsyncRsp, sizeof(_BasicResponse_t));
299 
300  /* let the device make the shutdown using the defined timeout */
301  Msg.Cmd.Timeout = Timeout;
302 
303  IsProvInProgress = SL_IS_PROVISIONING_IN_PROGRESS;
304 
305  /* if provisioning in progress do not take pool object as we are not going to wait for it */
306  if (!IsProvInProgress)
307  {
308  ObjIdx = _SlDrvProtectAsyncRespSetting((_u8 *)&AsyncRsp, START_STOP_ID, SL_MAX_SOCKETS);
309  if (ObjIdx < 0)
310  {
311  return ObjIdx;
312  }
313 
314  ReleasePoolObject = TRUE;
315  }
316 
317  /* Set the stop-in-progress flag */
318  SL_SET_DEVICE_STOP_IN_PROGRESS;
319 
320  VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlStopCmdCtrl, &Msg, NULL));
321 
322  int ret_pool = 0; // for _SlDrvReleasePoolObj
323  /* Do not wait for stop async event if provisioning is in progress */
324  if((SL_OS_RET_CODE_OK == (_i16)Msg.Rsp.status) && (!(IsProvInProgress)))
325  {
326  /* Wait for sync object to be signaled */
327  ret_pool = _SlDrvWaitForInternalAsyncEvent(ObjIdx, STOP_DEVICE_TIMEOUT, SL_OPCODE_DEVICE_STOP_ASYNC_RESPONSE);
328 
329  Msg.Rsp.status = AsyncRsp.status;
330  RetVal = Msg.Rsp.status;
331  }
332 
333  /* Release pool object only if taken */
334  if (ReleasePoolObject == TRUE)
335  {
336  _SlDrvReleasePoolObj(ObjIdx);
337  if(ret_pool < 0)
338  {
339  return ret_pool;
340  }
341  }
342 
343  /* This macro wait for the NWP to raise a ready for shutdown indication.
344  * This function is unique for the CC32XX family, and expected to return
345  * in less than 600 mSec, which is the time takes for NWP to gracefully shutdown. */
346  WAIT_NWP_SHUTDOWN_READY;
347  }
348  else
349  {
350  if ((!SL_IS_DEVICE_STARTED)
351  && (!SL_IS_RESTART_REQUIRED))
352  {
353  sl_DeviceDisable();
354  return SL_RET_CODE_DEV_NOT_STARTED;
355  }
356  /* Set the stop-in-progress flag */
357  SL_SET_DEVICE_STOP_IN_PROGRESS;
358  }
359  /* Release (signal) all active and pending commands */
360  _SlDrvReleaseAllActivePendingPoolObj();
361 
362 #ifdef SL_PLATFORM_MULTI_THREADED
363  /* Do not continue until all sync object deleted (in relevant context) */
364  while (g_pCB->NumOfDeletedSyncObj < MAX_CONCURRENT_ACTIONS)
365  {
366  usleep(100000);
367  }
368 #endif
369 
370  /* Lock during stopping the interface only if reset is not required (if reset requires it
371  means GlobalLockObj is already deleted and interface operations cannot be performed) */
372  if (!SL_IS_RESTART_REQUIRED)
373  {
374  SL_DRV_OBJ_LOCK_FOREVER(&GlobalLockObj);
375  }
376  sl_IfRegIntHdlr(NULL, NULL);
377  sl_DeviceDisable();
378  RetVal = sl_IfClose(g_pCB->FD);
379 
380  (void)_SlDrvDriverCBDeinit();
381 
382  /* clear the stop-in-progress flag */
383  SL_UNSET_DEVICE_STOP_IN_PROGRESS;
384 
385  /* clear the device started flag */
386  SL_UNSET_DEVICE_STARTED;
387 
388  if (!SL_IS_RESTART_REQUIRED)
389  {
390  SL_DRV_OBJ_UNLOCK(&GlobalLockObj);
391  }
392  /* Clear the restart device flag */
393  SL_UNSET_RESTART_REQUIRED;
394 
395  return RetVal;
396 }
397 #endif
398 
399 
400 /*****************************************************************************
401 sl_DeviceEventMaskSet
402 *****************************************************************************/
403 typedef union
404 {
406  _BasicResponse_t Rsp;
407 }_SlEventMaskSetMsg_u;
408 
409 
410 #if _SL_INCLUDE_FUNC(sl_DeviceEventMaskSet)
411 
412 static const _SlCmdCtrl_t _SlEventMaskSetCmdCtrl =
413 {
414  SL_OPCODE_DEVICE_EVENTMASKSET,
415  (_SlArgSize_t)sizeof(SlDeviceMaskEventSetCommand_t),
416  (_SlArgSize_t)sizeof(_BasicResponse_t)
417 };
418 
419 
420 _i16 sl_DeviceEventMaskSet(const _u8 EventClass ,const _u32 Mask)
421 {
422  _SlEventMaskSetMsg_u Msg;
423 
424  /* verify that this api is allowed. if not allowed then
425  ignore the API execution and return immediately with an error */
426  VERIFY_API_ALLOWED(SL_OPCODE_SILO_DEVICE);
427 
428  Msg.Cmd.Group = EventClass;
429  Msg.Cmd.Mask = Mask;
430 
431  VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlEventMaskSetCmdCtrl, &Msg, NULL));
432 
433  return (_i16)Msg.Rsp.status;
434 }
435 #endif
436 
437 /******************************************************************************
438 sl_EventMaskGet
439 ******************************************************************************/
440 typedef union
441 {
444 }_SlEventMaskGetMsg_u;
445 
446 
447 
448 #if _SL_INCLUDE_FUNC(sl_DeviceEventMaskGet)
449 
450 static const _SlCmdCtrl_t _SlEventMaskGetCmdCtrl =
451 {
452  SL_OPCODE_DEVICE_EVENTMASKGET,
453  (_SlArgSize_t)sizeof(SlDeviceMaskEventGetCommand_t),
454  (_SlArgSize_t)sizeof(SlDeviceMaskEventGetResponse_t)
455 };
456 
457 
458 _i16 sl_DeviceEventMaskGet(const _u8 EventClass,_u32 *pMask)
459 {
460  _SlEventMaskGetMsg_u Msg;
461 
462  /* verify that this api is allowed. if not allowed then
463  ignore the API execution and return immediately with an error */
464  VERIFY_API_ALLOWED(SL_OPCODE_SILO_DEVICE);
465 
466  Msg.Cmd.Group = EventClass;
467 
468  VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlEventMaskGetCmdCtrl, &Msg, NULL));
469 
470  *pMask = Msg.Rsp.Mask;
471 
472  return SL_RET_CODE_OK;
473 }
474 #endif
475 
476 
477 
478 /******************************************************************************
479 sl_DeviceGet
480 ******************************************************************************/
481 
482 typedef union
483 {
484  SlDeviceSetGet_t Cmd;
485  SlDeviceSetGet_t Rsp;
486 }_SlDeviceMsgGet_u;
487 
488 
489 
490 #if _SL_INCLUDE_FUNC(sl_DeviceGet)
491 
492 static const _SlCmdCtrl_t _SlDeviceGetCmdCtrl =
493 {
494  SL_OPCODE_DEVICE_DEVICEGET,
495  (_SlArgSize_t)sizeof(SlDeviceSetGet_t),
496  (_SlArgSize_t)sizeof(SlDeviceSetGet_t)
497 };
498 
499 _i16 sl_DeviceGet(const _u8 DeviceGetId, _u8 *pOption,_u16 *pConfigLen, _u8 *pValues)
500 {
501  _SlDeviceMsgGet_u Msg;
502  _SlCmdExt_t CmdExt;
503 
504  /* verify that this api is allowed. if not allowed then
505  ignore the API execution and return immediately with an error */
506  VERIFY_API_ALLOWED(SL_OPCODE_SILO_DEVICE);
507 
508  if (*pConfigLen == 0)
509  {
510  return SL_EZEROLEN;
511  }
512 
513  if( pOption )
514  {
515 
516  _SlDrvResetCmdExt(&CmdExt);
517  CmdExt.RxPayloadLen = (_i16)*pConfigLen;
518  CmdExt.pRxPayload = (_u8 *)pValues;
519 
520  Msg.Cmd.DeviceSetId = DeviceGetId;
521 
522  Msg.Cmd.Option = (_u16)*pOption;
523 
524  VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlDeviceGetCmdCtrl, &Msg, &CmdExt));
525 
526  if( pOption )
527  {
528  *pOption = (_u8)Msg.Rsp.Option;
529  }
530 
531  if (CmdExt.RxPayloadLen < CmdExt.ActualRxPayloadLen)
532  {
533  *pConfigLen = (_u16)CmdExt.RxPayloadLen;
534 
535  return SL_ESMALLBUF;
536  }
537  else
538  {
539  *pConfigLen = (_u16)CmdExt.ActualRxPayloadLen;
540  }
541 
542  return (_i16)Msg.Rsp.Status;
543  }
544  else
545  {
546  return SL_RET_CODE_INVALID_INPUT;
547  }
548 }
549 #endif
550 
551 /******************************************************************************
552 sl_DeviceSet
553 ******************************************************************************/
554 typedef union
555 {
556  SlDeviceSetGet_t Cmd;
557  _BasicResponse_t Rsp;
558 }_SlDeviceMsgSet_u;
559 
560 
561 
562 #if _SL_INCLUDE_FUNC(sl_DeviceSet)
563 
564 static const _SlCmdCtrl_t _SlDeviceSetCmdCtrl =
565 {
566  SL_OPCODE_DEVICE_DEVICESET,
567  (_SlArgSize_t)sizeof(SlDeviceSetGet_t),
568  (_SlArgSize_t)sizeof(_BasicResponse_t)
569 };
570 
571 _i16 sl_DeviceSet(const _u8 DeviceSetId ,const _u8 Option,const _u16 ConfigLen,const _u8 *pValues)
572 {
573  _SlDeviceMsgSet_u Msg;
574  _SlCmdExt_t CmdExt;
575 
576  /* verify that this api is allowed. if not allowed then
577  ignore the API execution and return immediately with an error */
578  VERIFY_API_ALLOWED(SL_OPCODE_SILO_DEVICE);
579 
580  _SlDrvResetCmdExt(&CmdExt);
581 
582  CmdExt.TxPayload1Len = (ConfigLen+3) & (~3);
583  CmdExt.pTxPayload1 = (_u8 *)pValues;
584 
585  Msg.Cmd.DeviceSetId = DeviceSetId;
586  Msg.Cmd.ConfigLen = ConfigLen;
587  Msg.Cmd.Option = Option;
588 
589  VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlDeviceSetCmdCtrl, &Msg, &CmdExt));
590 
591  return (_i16)Msg.Rsp.status;
592 }
593 #endif
594 
595 
596 /******************************************************************************
597 _SlDeviceEventHandler - handles internally device async events
598 ******************************************************************************/
599 _SlReturnVal_t _SlDeviceEventHandler(void* pEventInfo)
600 {
601  DeviceEventInfo_t* pInfo = (DeviceEventInfo_t*)pEventInfo;
602  _SlResponseHeader_t* pHdr = (_SlResponseHeader_t *)pInfo->pAsyncMsgBuff;
603  _BasicResponse_t *pMsgArgs = (_BasicResponse_t *)_SL_RESP_ARGS_START(pHdr);
604  SlDeviceEvent_t DeviceEvent;
605 
606  _SlDrvMemZero(&DeviceEvent, sizeof(DeviceEvent));
607 
608  switch(pHdr->GenHeader.Opcode)
609  {
610  case SL_OPCODE_DEVICE_INITCOMPLETE:
611  _SlDeviceHandleAsync_InitComplete(pHdr);
612  break;
613  case SL_OPCODE_DEVICE_STOP_ASYNC_RESPONSE:
614  _SlDeviceHandleAsync_Stop(pHdr);
615  break;
616  case SL_OPCODE_DEVICE_RESET_REQUEST_ASYNC_EVENT:
617  {
618  SlDeviceResetRequestData_t *pResetRequestData = (SlDeviceResetRequestData_t*)pMsgArgs;
619 
620 #if defined(slcb_DeviceGeneralEvtHdlr) || defined (EXT_LIB_REGISTERED_GENERAL_EVENTS)
621  if (pResetRequestData->Caller == SL_DEVICE_RESET_REQUEST_CALLER_PROVISIONING_EXTERNAL_CONFIGURATION)
622  {
623  /* call the registered events handlers (application/external lib) */
624  DeviceEvent.Id = SL_DEVICE_EVENT_RESET_REQUEST;
625  DeviceEvent.Data.ResetRequest.Status = 0;
626  DeviceEvent.Data.ResetRequest.Caller = pResetRequestData->Caller;
627  _SlDrvHandleGeneralEvents(&DeviceEvent);
628  break;
629  }
630 #endif
631 
632  if (!_SlDrvIsApiInProgress() && SL_IS_PROVISIONING_IN_PROGRESS)
633  {
634  if (pResetRequestData->SessionNumber != DeviceCB.ResetRequestSessionNumber)
635  {
636  /* store the last session number */
637  DeviceCB.ResetRequestSessionNumber = pResetRequestData->SessionNumber;
638 
639  /* perform the reset request */
640  _SlDeviceHandleResetRequestInternally();
641  }
642  }
643  }
644  break;
645 
646  case SL_OPCODE_DEVICE_ABORT:
647  {
648  /* release global lock of cmd context */
649  if (pInfo->bInCmdContext == TRUE)
650  {
651  SL_DRV_LOCK_GLOBAL_UNLOCK(TRUE);
652  }
653 
654  _SlDrvHandleFatalError(SL_DEVICE_EVENT_FATAL_DEVICE_ABORT,
655  *((_u32*)pMsgArgs - 1), /* Abort type */
656  *((_u32*)pMsgArgs)); /* Abort data */
657  }
658  break;
659 
660  case SL_OPCODE_DEVICE_DEVICE_ASYNC_GENERAL_ERROR:
661  {
662 #if defined(slcb_DeviceGeneralEvtHdlr) || defined (EXT_LIB_REGISTERED_GENERAL_EVENTS)
663 
664  DeviceEvent.Id = SL_DEVICE_EVENT_ERROR;
665  DeviceEvent.Data.Error.Code = pMsgArgs->status;
666  DeviceEvent.Data.Error.Source = (SlDeviceSource_e)pMsgArgs->sender;
667  _SlDrvHandleGeneralEvents(&DeviceEvent);
668 #endif
669  }
670  break;
671 
672  case SL_OPCODE_DEVICE_FLOW_CTRL_ASYNC_EVENT:
673  _SlFlowContSet((void *)pHdr);
674  break;
675  default:
676  SL_ERROR_TRACE2(MSG_306, "ASSERT: _SlDeviceEventHandler : invalid opcode = 0x%x = %1", pHdr->GenHeader.Opcode, pHdr->GenHeader.Opcode);
677  }
678 
679  return SL_OS_RET_CODE_OK;
680 }
681 
682 
683 void _SlDeviceResetRequestInitCompletedCB(_u32 Status, SlDeviceInitInfo_t *DeviceInitInfo)
684 {
685  /* Do nothing...*/
686 }
687 
688 
689 void _SlDeviceHandleResetRequestInternally(void)
690 {
691  _u8 irqCountLast = RxIrqCnt;
692 #if (defined(slcb_GetTimestamp))
693  _SlTimeoutParams_t TimeoutInfo={0};
694 
695  _SlDrvStartMeasureTimeout(&TimeoutInfo, 2*RESET_REQUEST_STOP_TIMEOUT);
696 #endif
697 
698  /* Here we send stop command with timeout, but the API will not blocked
699  Till the stop complete event is received as we in the middle of async event handling */
700  sl_Stop(RESET_REQUEST_STOP_TIMEOUT);
701 
702  /* wait till the stop complete cmd & async
703  event messages are received (2 Irqs) */
704  do
705  {
706 #if (defined(slcb_GetTimestamp))
707  if (_SlDrvIsTimeoutExpired(&TimeoutInfo))
708  {
709  break;
710  }
711 #endif
712  }
713  while((RxIrqCnt - irqCountLast) < 2);
714 
715  /* start the device again */
716  sl_Start(DeviceCB.pIfHdl, DeviceCB.pDevName ,_SlDeviceResetRequestInitCompletedCB);
717 
718 }
719 
720 
721 
722 /******************************************************************************
723 sl_DeviceStat
724 ******************************************************************************/
725 
726 _i16 sl_DeviceStatStart(const _u32 Flags) // start collecting the statistics
727 {
728  SL_DRV_PROTECTION_OBJ_LOCK_FOREVER();
729  if(SL_IS_WLAN_RX_STAT_IN_PROGRESS)
730  {
731  SL_DRV_PROTECTION_OBJ_UNLOCK();
732  return SL_RET_CODE_WLAN_RX_STAT_IN_PROGRESS;
733  }
734  else
735  {
736  /* turn on flag indication for RX statistics is in progress
737  * to avoid parallel "starts" between
738  * Device statistics API and RX statistics API */
739  SL_SET_DEVICE_STAT_IN_PROGRESS;
740  SL_DRV_PROTECTION_OBJ_UNLOCK();
741  /* verify that this api is allowed. if not allowed then
742  ignore the API execution and return immediately with an error */
743  VERIFY_API_ALLOWED(SL_OPCODE_SILO_WLAN);
744  return _SlDrvBasicCmd(SL_OPCODE_WLAN_STARTRXSTATCOMMAND);
745  }
746 
747 }
748 
749 _i16 sl_DeviceStatGet(const _u16 ConfigId,_u16 length,void* buffer)
750 {
751  _i16 RetVal = 0;
752  SL_DRV_PROTECTION_OBJ_LOCK_FOREVER();
753  /* Device statistics and Rx statistics cannot run parallel */
754  if(SL_IS_WLAN_RX_STAT_IN_PROGRESS)
755  {
756  SL_DRV_PROTECTION_OBJ_UNLOCK();
757  return SL_RET_CODE_WLAN_RX_STAT_IN_PROGRESS;
758  }
759  else
760  {
761  SL_DRV_PROTECTION_OBJ_UNLOCK();
762  if(SL_DEVICE_STAT_WLAN_RX == ConfigId )
763  {
764  /* In this case we use SL_OPCODE_WLAN_GETRXSTATCOMMAND even though we are at "Device" module -
765  * duo to the fact we want keep this API to call the exact same deprecated API which called from Wlan */
766  _SlCmdCtrl_t CmdCtrl = {SL_OPCODE_WLAN_GETRXSTATCOMMAND, 0, (_SlArgSize_t)sizeof(SlDeviceGetStat_t)};
767 
768  /* verify that this api is allowed. if not allowed then
769  ignore the API execution and return immediately with an error */
770  VERIFY_API_ALLOWED(SL_OPCODE_SILO_WLAN);
771 
772  _SlDrvMemZero(buffer, (_u16)sizeof(SlDeviceGetStat_t));
773  VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&CmdCtrl, buffer, NULL));
774 
775  }
776  else
777  {
778  _u8 configOpt = ConfigId;
779  RetVal = sl_DeviceGet(SL_DEVICE_GENERAL,&configOpt,&length,(_u8* )buffer);
780  }
781 
782  return RetVal;
783  }
784 }
785 
786 _i16 sl_DeviceStatStop(const _u32 Flags) //stop collecting the statistics
787 {
788  SL_DRV_PROTECTION_OBJ_LOCK_FOREVER();
789  if(SL_IS_WLAN_RX_STAT_IN_PROGRESS)
790  {
791  SL_DRV_PROTECTION_OBJ_UNLOCK();
792  return SL_RET_CODE_WLAN_RX_STAT_IN_PROGRESS;
793  }
794  else
795  {
796  SL_UNSET_DEVICE_STAT_IN_PROGRESS;
797  SL_DRV_PROTECTION_OBJ_UNLOCK();
798  /* verify that this api is allowed. if not allowed then
799  ignore the API execution and return immediately with an error */
800  VERIFY_API_ALLOWED(SL_OPCODE_SILO_WLAN);
801 
802  return _SlDrvBasicCmd(SL_OPCODE_WLAN_STOPRXSTATCOMMAND);
803 
804  }
805 
806 }
807 /******************************************************************************
808 sl_DeviceUartSetMode
809 ******************************************************************************/
810 #ifdef SL_IF_TYPE_UART
811 typedef union
812 {
815 }_SlUartSetModeMsg_u;
816 
817 
818 #if _SL_INCLUDE_FUNC(sl_DeviceUartSetMode)
819 
820 
821 const _SlCmdCtrl_t _SlUartSetModeCmdCtrl =
822 {
823  SL_OPCODE_DEVICE_SETUARTMODECOMMAND,
824  (_SlArgSize_t)sizeof(SlDeviceUartSetModeCommand_t),
825  (_SlArgSize_t)sizeof(SlDeviceUartSetModeResponse_t)
826 };
827 
829 {
830  _SlUartSetModeMsg_u Msg;
831  _u32 magicCode = (_u32)0xFFFFFFFF;
832 
833  Msg.Cmd.BaudRate = pUartParams->BaudRate;
834  Msg.Cmd.FlowControlEnable = pUartParams->FlowControlEnable;
835 
836 
837  VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlUartSetModeCmdCtrl, &Msg, NULL));
838 
839  /* cmd response OK, we can continue with the handshake */
840  if (SL_RET_CODE_OK == Msg.Rsp.status)
841  {
842  sl_IfMaskIntHdlr();
843 
844  /* Close the comm port */
845  sl_IfClose(g_pCB->FD);
846 
847  /* Re-open the comm port */
848  sl_IfOpen((void * )pUartParams, SL_IF_UART_REOPEN_FLAGS);
849 
850  sl_IfUnMaskIntHdlr();
851 
852  /* send the magic code and wait for the response */
853  sl_IfWrite(g_pCB->FD, (_u8* )&magicCode, 4);
854 
855  magicCode = UART_SET_MODE_MAGIC_CODE;
856  sl_IfWrite(g_pCB->FD, (_u8* )&magicCode, 4);
857 
858  /* clear magic code */
859  magicCode = 0;
860 
861  /* wait (blocking) till the magic code to be returned from device */
862  sl_IfRead(g_pCB->FD, (_u8* )&magicCode, 4);
863 
864  /* check for the received magic code matching */
865  if (UART_SET_MODE_MAGIC_CODE != magicCode)
866  {
867  _SL_ASSERT(0);
868  }
869  }
870 
871  return (_i16)Msg.Rsp.status;
872 }
873 #endif
874 #endif
875 
_i16 sl_DeviceStatStop(const _u32 Flags)
Stop collecting Device statistic, (if previous called sl_DeviceStatStart)
Definition: device.c:786
_i16 sl_DeviceEventMaskSet(const _u8 EventClass, const _u32 Mask)
Set asynchronous event mask.
Definition: device.c:420
_i16 sl_DeviceGet(const _u8 DeviceGetId, _u8 *pOption, _u16 *pConfigLen, _u8 *pValues)
Internal function for getting device configurations.
Definition: device.c:499
void * sl_Task(void *pEntry)
The SimpleLink task entry.
Definition: device.c:105
_i16 sl_DeviceSet(const _u8 DeviceSetId, const _u8 Option, const _u16 ConfigLen, const _u8 *pValues)
Setting device configurations.
Definition: device.c:571
_i16 sl_Stop(const _u16 Timeout)
Stop the SimpleLink device.
Definition: device.c:280
_i16 sl_DeviceEventMaskGet(const _u8 EventClass, _u32 *pMask)
Get current event mask of the device.
Definition: device.c:458
_i16 sl_DeviceStatStart(const _u32 Flags)
Start collecting Device statistics (including RX statistics), for unlimited time. ...
Definition: device.c:726
_i16 sl_DeviceUartSetMode(const SlDeviceUartIfParams_t *pUartParams)
Setting the internal uart mode.
Definition: device.c:828
_i16 sl_Start(const void *pIfHdl, _i8 *pDevName, const P_INIT_CALLBACK pInitCallBack)
Start the SimpleLink device.
Definition: device.c:119
_i16 sl_DeviceStatGet(const _u16 ConfigId, _u16 length, void *buffer)
Getting DEVICE statistics.
Definition: device.c:749