Updated TI Linux Sensor To Cloud to the latest TI 15.4-Stack v2.4, now with CC13x2...
[apps/tidep0084.git] / example / collector / csf_linux.c
1 /******************************************************************************
3  @file csf_linux.c [Linux version of csf.c]
5  @brief Collector Specific Functions
7  Group: WCS LPC
8  $Target Devices: Linux: AM335x, Embedded Devices: CC1310, CC1350, CC1352$
10  ******************************************************************************
11  $License: BSD3 2016 $
12   
13    Copyright (c) 2015, Texas Instruments Incorporated
14    All rights reserved.
15   
16    Redistribution and use in source and binary forms, with or without
17    modification, are permitted provided that the following conditions
18    are met:
19   
20    *  Redistributions of source code must retain the above copyright
21       notice, this list of conditions and the following disclaimer.
22   
23    *  Redistributions in binary form must reproduce the above copyright
24       notice, this list of conditions and the following disclaimer in the
25       documentation and/or other materials provided with the distribution.
26   
27    *  Neither the name of Texas Instruments Incorporated nor the names of
28       its contributors may be used to endorse or promote products derived
29       from this software without specific prior written permission.
30   
31    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
32    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
33    THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
34    PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
35    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
36    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
37    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
38    OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
39    WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
40    OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
41    EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42  ******************************************************************************
43  $Release Name: TI-15.4Stack Linux x64 SDK$
44  $Release Date: Sept 27, 2017 (2.04.00.13)$
45  *****************************************************************************/
47 #if (defined(_MSC_VER) || defined(__linux__))
48 #define IS_HLOS 1  /* compiler=non-embedded */
49 #else
50 #define IS_HLOS 0  /* compiler=embedded */
51 #endif
52 /******************************************************************************
53  Includes
54  *****************************************************************************/
56 #if IS_HLOS
57 #include <stdio.h>
58 #include <stdarg.h>
59 #include <string.h>
60 #include <stdlib.h>
61 #include <stdint.h>
62 #include <unistd.h>
63 #include "nvintf.h"
64 #include "nv_linux.h"
66 #include "log.h"
67 #include "mutex.h"
68 #include "ti_semaphore.h"
69 #include "timer.h"
71 #include "appsrv.h"
73 #include "util.h"
75 #include "common/util/board_lcd.h"
77 #else /* (HLOS) */
78 #include <xdc/std.h>
79 #include <xdc/runtime/Error.h>
80 #include <xdc/runtime/System.h>
81 #include <ti/sysbios/BIOS.h>
82 #include <ti/sysbios/knl/Clock.h>
83 #include <ti/sysbios/family/arm/m3/Hwi.h>
84 #include <ti/sysbios/knl/Semaphore.h>
85 #include <ti/drivers/Power.h>
86 #include <ti/drivers/PIN.h>
87 #include <string.h>
88 #include <inc/hw_ints.h>
89 #include <aon_event.h>
90 #include <ioc.h>
92 #include "board.h"
93 #include "timer.h"
94 #include "util.h"
95 #include "board_key.h"
96 #include "board_led.h"
98 #include "macconfig.h"
100 #include "nvoctp.h"
102 #include "icall.h"
104 #endif /* (HLOS) */
105 #include "config.h"
106 #include "api_mac.h"
107 #if IS_HLOS
108 #include "api_mac_linux.h"
109 #endif
110 #include "collector.h"
111 #include "cllc.h"
112 #include "csf.h"
114 #if defined(MT_CSF)
115 #include "mt_csf.h"
116 #endif
118 #if IS_HLOS
119 /* additional linux information */
120 #include "csf_linux.h"
121 #endif
123 /******************************************************************************
124  Constants and definitions
125  *****************************************************************************/
127 /* Initial timeout value for the tracking clock */
128 #define TRACKING_INIT_TIMEOUT_VALUE 100
130 /* NV Item ID - the device's network information */
131 #define CSF_NV_NETWORK_INFO_ID 0x0001
132 /* NV Item ID - the number of black list entries */
133 #define CSF_NV_BLACKLIST_ENTRIES_ID 0x0002
134 /* NV Item ID - the black list, use sub ID for each record in the list */
135 #define CSF_NV_BLACKLIST_ID 0x0003
136 /* NV Item ID - the number of device list entries */
137 #define CSF_NV_DEVICELIST_ENTRIES_ID 0x0004
138 /* NV Item ID - the device list, use sub ID for each record in the list */
139 #define CSF_NV_DEVICELIST_ID 0x0005
140 /* NV Item ID - this devices frame counter */
141 #define CSF_NV_FRAMECOUNTER_ID 0x0006
142 /* NV Item ID - reset reason */
143 #define CSF_NV_RESET_REASON_ID 0x0007
145 /* Maximum number of black list entries */
146 #define CSF_MAX_BLACKLIST_ENTRIES 10
148 /* Maximum number of device list entries */
149 #define CSF_MAX_DEVICELIST_ENTRIES CONFIG_MAX_DEVICES
151 /*
152  Maximum sub ID for a blacklist item, this is failsafe.  This is
153  not the maximum number of items in the list
154  */
155 #define CSF_MAX_BLACKLIST_IDS (2*CONFIG_MAX_DEVICES)
157 /*
158  Maximum sub ID for a device list item, this is failsafe.  This is
159  not the maximum number of items in the list
160  */
161 #define CSF_MAX_DEVICELIST_IDS (2*CONFIG_MAX_DEVICES)
163 /* timeout value for trickle timer initialization */
164 #define TRICKLE_TIMEOUT_VALUE       20
166 /* timeout value for join timer */
167 #define JOIN_TIMEOUT_VALUE       20
168 /* timeout value for config request delay */
169 #define CONFIG_TIMEOUT_VALUE 1000
171 /*
172  The increment value needed to save a frame counter. Example, setting this
173  constant to 100, means that the frame counter will be saved when the new
174  frame counter is 100 more than the last saved frame counter.  Also, when
175  the get frame counter function reads the value from NV it will add this value
176  to the read value.
177  */
178 #define FRAME_COUNTER_SAVE_WINDOW     25
180 /* Value returned from findDeviceListIndex() when not found */
181 #define DEVICE_INDEX_NOT_FOUND  -1
183 /*! NV driver item ID for reset reason */
184 #define NVID_RESET {NVINTF_SYSID_APP, CSF_NV_RESET_REASON_ID, 0}
186 #ifdef IS_HLOS
188 #define board_led_type_LED1 0
189 #define board_led_type_LED2 0
190 #define board_led_state_ON  0
191 #define Board_Led_toggle(led)(void)led;
192 #define Board_Led_control(led, action) \
193 (void)led; \
194 (void)action;
196 #include <termios.h>
198 #define KEY_PERMIT_JOIN 'o'
199 #define KEY_SELECT_DEVICE 's'
200 #define KEY_FW_VER_REQ 'v'
201 #define KEY_FW_UPDATE_REQ 'u'
202 #define KEY_GET_OAD_FILE 'f'
203 #define KEY_TOGGLE_REQ 't'
204 #define KEY_LIST_DEVICES 'l'
205 #define KEY_DISASSOCIATE_DEVICE 'd'
207 #define DEFUALT_OAD_FILE "../../firmware/oad/sensor_oad_cc13x0lp_app.bin"
208 #endif //IS_HLOS
210 /******************************************************************************
211  External variables
212  *****************************************************************************/
213 #if IS_HLOS
215 /* handle for tracking timeout */
216 static intptr_t trackingClkHandle;
217 /* handle for PA trickle timeout */
218 static intptr_t tricklePAClkHandle;
219 /* handle for PC timeout */
220 static intptr_t tricklePCClkHandle;
221 /* handle for join permit timeout */
222 static intptr_t joinClkHandle;
223 /* handle for config request delay */
224 static intptr_t configClkHandle;
225 /* handle for broadcast interval */
226 static intptr_t broadcastClkHandle;
228 extern intptr_t semaphore0;
229 /* Non-volatile function pointers */
230 NVINTF_nvFuncts_t nvFps;
232 #else
234 #ifdef NV_RESTORE
235 /*! MAC Configuration Parameters */
236 extern mac_Config_t Main_user1Cfg;
237 #endif
239 #endif //IS_HLOS
241 /******************************************************************************
242  Local variables
243  *****************************************************************************/
244 #if IS_HLOS
245 static intptr_t collectorSem;
246 #define Semaphore_post(S)  SEMAPHORE_put(S)
247 #else
248 /* The application's semaphore */
249 static ICall_Semaphore collectorSem;
251 /* Clock/timer resources */
252 static Clock_Struct trackingClkStruct;
253 static Clock_Handle trackingClkHandle;
255 static Clock_Struct broadcastClkStruct;
256 static Clock_Handle broadcastClkHandle;
258 /* Clock/timer resources for CLLC */
259 /* trickle timer */
260 STATIC Clock_Struct tricklePAClkStruct;
261 STATIC Clock_Handle tricklePAClkHandle;
262 STATIC Clock_Struct tricklePCClkStruct;
263 STATIC Clock_Handle tricklePCClkHandle;
265 /* timer for join permit */
266 STATIC Clock_Struct joinClkStruct;
267 STATIC Clock_Handle joinClkHandle;
269 /* timer for config request delay */
270 STATIC Clock_Struct configClkStruct;
271 STATIC Clock_Handle configClkHandle;
272 #endif /* (!IS_HLOS) */
274 /* NV Function Pointers */
275 static NVINTF_nvFuncts_t *pNV = NULL;
277 /* Permit join setting */
278 static bool permitJoining = false;
280 static bool started = false;
282 /* The last saved coordinator frame counter */
283 static uint32_t lastSavedCoordinatorFrameCounter = 0;
285 #if defined(MT_CSF)
286 /*! NV driver item ID for reset reason */
287 static const NVINTF_itemID_t nvResetId = NVID_RESET;
288 #endif
290 #ifndef IS_HEADLESS
291 enum {
292     DisplayLine_product = 0,
293     DisplayLine_nwk,
294     DisplayLine_sensorStart,
295     DisplayLine_sensorEnd = 6,
296     DisplayLine_info,
297     DisplayLine_cmd,
298 } DisplayLine;
299 #else
300 #endif //IS_HEADLESS
302 static uint32_t selected_oad_file_id = 0;
304 /******************************************************************************
305  Global variables
306  *****************************************************************************/
307 /* Key press parameters */
308 uint8_t Csf_keys;
310 /* pending Csf_events */
311 uint16_t Csf_events = 0;
313 /* Saved CLLC state */
314 Cllc_states_t savedCllcState = Cllc_states_initWaiting;
316 /******************************************************************************
317  Local function prototypes
318  *****************************************************************************/
319 #if IS_HLOS
321 static void processTackingTimeoutCallback_WRAPPER(intptr_t thandle, intptr_t cookie);
322 static void processPATrickleTimeoutCallback_WRAPPER(intptr_t thandle, intptr_t cookie);
323 static void processPCTrickleTimeoutCallback_WRAPPER(intptr_t thandle, intptr_t cookie);
324 static void processJoinTimeoutCallback_WRAPPER(intptr_t thandle, intptr_t cookie);
325 static void processConfigTimeoutCallback_WRAPPER(intptr_t thandle, intptr_t cookie);
326 static void processBroadcastTimeoutCallback_WRAPPER(intptr_t thandle, intptr_t cookie);
328 #ifndef IS_HEADLESS
329 char* getConsoleCmd(void);
330 void initConsoleCmd(void);
331 #endif //!IS_HEADLESS
333 #endif
335 static void processTackingTimeoutCallback(UArg a0);
336 static void processBroadcastTimeoutCallback(UArg a0);
337 static void processKeyChangeCallback(uint8_t keysPressed);
338 static void processPATrickleTimeoutCallback(UArg a0);
339 static void processPCTrickleTimeoutCallback(UArg a0);
340 static void processJoinTimeoutCallback(UArg a0);
341 static void processConfigTimeoutCallback(UArg a0);
342 static bool addDeviceListItem(Llc_deviceListItem_t *pItem);
343 static void updateDeviceListItem(Llc_deviceListItem_t *pItem);
344 static int findDeviceListIndex(ApiMac_sAddrExt_t *pAddr);
345 static int findUnusedDeviceListIndex(void);
346 static void saveNumDeviceListEntries(uint16_t numEntries);
347 static int findBlackListIndex(ApiMac_sAddr_t *pAddr);
348 static int findUnusedBlackListIndex(void);
349 static uint16_t getNumBlackListEntries(void);
350 static void saveNumBlackListEntries(uint16_t numEntries);
351 void removeBlackListItem(ApiMac_sAddr_t *pAddr);
352 static bool removeDevice(ApiMac_sAddr_t addr);
354 #if defined(TEST_REMOVE_DEVICE)
355 static void removeTheFirstDevice(void);
356 #endif
357 #if !IS_HLOS
358 /* not used in hlos version */
359 static uint16_t getTheFirstDevice(void);
360 #endif
362 /******************************************************************************
363  Public Functions
364  *****************************************************************************/
366 /*!
367  The application calls this function during initialization
369  Public function defined in csf.h
370  */
371 void Csf_init(void *sem)
373     char default_oad_file[256] = DEFUALT_OAD_FILE;
375     /* Set defualt FW image */
376     selected_oad_file_id = Collector_updateFwList(default_oad_file);
378     /* Initialize the LCD */
379     Board_LCD_open();
381 #ifndef IS_HEADLESS
382     Board_Lcd_printf(DisplayLine_product, "TI Collector");
384 #if !defined(AUTO_START)
385     Board_Lcd_printf(DisplayLine_nwk, "Nwk: Starting");
386 #endif /* AUTO_START */
388 #endif //!IS_HEADLESS
390 #if IS_HLOS
391     LOG_printf(LOG_APPSRV_MSG_CONTENT, "TI Collector");
392 #if !defined(AUTO_START)
393     LOG_printf(LOG_APPSRV_MSG_CONTENT, "Nwk: Starting\n");
394 #endif /* AUTO_START */
396 #ifndef IS_HEADLESS
397     initConsoleCmd();
398 #endif //!HEADLESS
400     /* Save off the semaphore */
401     collectorSem = (intptr_t)sem;
403     /* save the application semaphore here */
404     /* load the NV function pointers */
405     // printf("   >> Initialize the NV Function pointers \n");
406     NVOCTP_loadApiPtrs(&nvFps);
408     /* Suyash - the code is using pNV var. Using that for now. */
409     /* config nv pointer will be read from the mac_config_t... */
410     pNV = &nvFps;
412     /* Init NV */
413     nvFps.initNV(NULL);
415 #else
416    /* Save off the NV Function Pointers */
417 #ifdef NV_RESTORE
418     /* Save off the NV Function Pointers */
419     pNV = &Main_user1Cfg.nvFps;
420 #endif
422     /* Save off the semaphore */
423     collectorSem = sem;
425     /* Initialize keys */
426     if(Board_Key_initialize(processKeyChangeCallback) == KEY_RIGHT)
427     {
428         /* Right key is pressed on power up, clear all NV */
429         Csf_clearAllNVItems();
430     }
433 #ifndef IS_HEADLESS
434     /* Initialize the LCD */
435     Board_LCD_open();
437 #if !defined(AUTO_START)
438     Board_Lcd_printf(DisplayLine_nwk, "Nwk: Starting");
439 #endif /* AUTO_START */
440 #endif //!IS_HEADLESS
442     Board_Led_initialize();
445 #if defined(MT_CSF)
446     {
447         uint8_t resetReseason = 0;
449         if(pNV != NULL)
450         {
451             if(pNV->readItem != NULL)
452             {
453                 /* Attempt to retrieve reason for the reset */
454                 (void)pNV->readItem(nvResetId, 0, 1, &resetReseason);
455             }
457             if(pNV->deleteItem != NULL)
458             {
459                 /* Only use this reason once */
460                 (void)pNV->deleteItem(nvResetId);
461             }
462         }
464         /* Start up the MT message handler */
465         MTCSF_init(resetReseason);
467         /* Did we reset because of assert? */
468         if(resetReseason > 0)
469         {
470 #if IS_HEADLESS
471             Board_Lcd_printf(DisplayLine_nwk, "Nwk: Restarting");
472 #endif //!IS_HEADLESS
474             /* Tell the collector to restart */
475             Csf_events |= CSF_KEY_EVENT;
476             Csf_keys |= KEY_LEFT;
477         }
478     }
479 #endif
480 #endif //IS_HLOS
483 /*!
484  The application must call this function periodically to
485  process any Csf_events that this module needs to process.
487  Public function defined in csf.h
488  */
489 void Csf_processEvents(void)
492 #if (!defined(IS_HEADLESS) && defined(IS_HLOS))
494     char *cmdBuff;
495     static uint16_t selected_device = 0;
497     cmdBuff = getConsoleCmd();
499     if(cmdBuff)
500     {
501         Csf_keys = cmdBuff[0];
503         if(Csf_keys == KEY_PERMIT_JOIN)
504         {
505             uint32_t duration;
506             /* Toggle the permit joining */
507             if (permitJoining == true)
508             {
509                 permitJoining = false;
510                 duration = 0;
511                 Board_Lcd_printf(DisplayLine_info, "Info: PermitJoin-OFF");
512                 LOG_printf(LOG_APPSRV_MSG_CONTENT, "Info: PermitJoin-OFF\n");
513             }
514             else
515             {
516                 permitJoining = true;
517                 duration = 0xFFFFFFFF;
518                 Board_Lcd_printf(DisplayLine_info, "Info: PermitJoin-ON ");
519                 LOG_printf(LOG_APPSRV_MSG_CONTENT, "Info: PermitJoin-ON\n");
520             }
522             /* Set permit joining */
523             Cllc_setJoinPermit(duration);
524         }
526         if(Csf_keys == KEY_SELECT_DEVICE)
527         {
528             if(sscanf(cmdBuff, "s0x%hx", &selected_device) < 1)
529             {
530                 sscanf(cmdBuff, "s%hd", &selected_device);
531             }
533             Board_Lcd_printf(DisplayLine_info, "Info: Selected device 0x%04x", selected_device);
534             LOG_printf(LOG_APPSRV_MSG_CONTENT, "Info: Selected device 0x%04x\n", selected_device);
535         }
537         if(Csf_keys == KEY_FW_VER_REQ)
538         {
539             ApiMac_sAddr_t sAddr;
541             Board_Lcd_printf(DisplayLine_info, "Info: Sending 0x%04x FW version req", selected_device);
542             LOG_printf(LOG_APPSRV_MSG_CONTENT, "Info: Sending 0x%04x FW version req\n", selected_device);
544             sAddr.addr.shortAddr = selected_device;
545             sAddr.addrMode = ApiMac_addrType_short;
546             Collector_sendFwVersionRequest(&sAddr);
547         }
549         if(Csf_keys == KEY_FW_UPDATE_REQ)
550         {
551             ApiMac_sAddr_t sAddr;
552             Collector_status_t status;
554             Board_Lcd_printf(DisplayLine_info, "Info: Sending 0x%04x FW Update Req", selected_device);
555             LOG_printf(LOG_APPSRV_MSG_CONTENT, "Info: Sending 0x%04x FW Update Req\n", selected_device);
557             sAddr.addr.shortAddr = selected_device;
558             sAddr.addrMode = ApiMac_addrType_short;
559             status = Collector_startFwUpdate(&sAddr, selected_oad_file_id);
561             if(status == Collector_status_invalid_file)
562             {
563                 Board_Lcd_printf(DisplayLine_info, "Info: Update req file not found ID:%d", selected_oad_file_id);
564                 LOG_printf(LOG_APPSRV_MSG_CONTENT, "Info: Update req file not found ID:%d\n", selected_oad_file_id);
565             }
566             else if(status != Collector_status_success)
567             {
568                 Board_Lcd_printf(DisplayLine_info, "Info: Update req failed");
569                 LOG_printf(LOG_APPSRV_MSG_CONTENT, "Info: Update req failed\n");
570             }
571         }
573         if(Csf_keys == KEY_GET_OAD_FILE)
574         {
575             static char new_oad_file[256] = DEFUALT_OAD_FILE;
576             char temp_oad_file[256] = "";
578             sscanf(cmdBuff, "f %s", temp_oad_file);
580             if(strlen(temp_oad_file) > 0)
581             {
582                 // Verify file exists and we have read permissions
583                 if(access(temp_oad_file, F_OK | R_OK) != -1)
584                 {
585                     // If file exists, then copy to the static filename and call updateFwList
586                     strncpy(new_oad_file, temp_oad_file, strlen(temp_oad_file) + 1);
587                     selected_oad_file_id = Collector_updateFwList(new_oad_file);
589                     Board_Lcd_printf(DisplayLine_info, "Info: OAD file %s", new_oad_file);
590                     LOG_printf(LOG_APPSRV_MSG_CONTENT, "Info: OAD file %s\n", new_oad_file);
591                 }
592                 else
593                 {
594                     Board_Lcd_printf(DisplayLine_info, "Info: Can not read file %s", temp_oad_file);
595                     LOG_printf(LOG_APPSRV_MSG_CONTENT, "Info: Can not read file %s\n", temp_oad_file);
596                 }
597             }
598             else
599             {
600                 // User is asking what the current file is
601                 Board_Lcd_printf(DisplayLine_info, "Info: OAD file %s", new_oad_file);
602                 LOG_printf(LOG_APPSRV_MSG_CONTENT, "Info: OAD file %s\n", new_oad_file);
603             }
604         }
606         if(Csf_keys == KEY_TOGGLE_REQ)
607         {
608             ApiMac_sAddr_t sAddr;
609             Collector_status_t status;
611             Board_Lcd_printf(DisplayLine_info, "Info: Sending 0x%04x LED toggle req", selected_device);
612             LOG_printf(LOG_APPSRV_MSG_CONTENT, "Info: Sending 0x%04x LED toggle req\n", selected_device);
614             sAddr.addr.shortAddr = selected_device;
615             sAddr.addrMode = ApiMac_addrType_short;
616             status = Csf_sendToggleLedRequest(&sAddr);
618             if(status == Collector_status_deviceNotFound)
619             {
620                 Board_Lcd_printf(DisplayLine_info, "Info: Toggle Req device 0x%04x not found", selected_device);
621                 LOG_printf(LOG_APPSRV_MSG_CONTENT, "Info: Toggle Req device 0x%04x not found\n", selected_device);
622             }
623             else if(status != Collector_status_success)
624             {
625                 Board_Lcd_printf(DisplayLine_info, "Info: Update Req failed");
626                 LOG_printf(LOG_APPSRV_MSG_CONTENT, "Info: Update Req failed\n");
627             }
628         }
630         if(Csf_keys == KEY_LIST_DEVICES)
631         {
632             ApiMac_sAddr_t sAddr;
633             uint16_t devIdx;
634             ApiMac_sAddrExt_t pExtAddr;
636             for(devIdx = 1; devIdx < CONFIG_MAX_DEVICES; devIdx++)
637             {
638                 sAddr.addr.shortAddr = devIdx;
639                 sAddr.addrMode = ApiMac_addrType_short;
641                 if(Collector_findDevice(&sAddr) == Collector_status_success)
642                 {
643                     if(Csf_getDeviceExtended(devIdx, &pExtAddr)) {
644  
645                         Board_Lcd_printf(DisplayLine_info,
646                             "Short: 0x%04x Extended: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
647                             devIdx,
648                             pExtAddr[7],
649                             pExtAddr[6],
650                             pExtAddr[5],
651                             pExtAddr[4],
652                             pExtAddr[3],
653                             pExtAddr[2],
654                             pExtAddr[1],
655                             pExtAddr[0]);
657                         LOG_printf(LOG_DBG_COLLECTOR,"Short: 0x%04x Extended: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
658                             devIdx,
659                             pExtAddr[7],
660                             pExtAddr[6],
661                             pExtAddr[5],
662                             pExtAddr[4],
663                             pExtAddr[3],
664                             pExtAddr[2],
665                             pExtAddr[1],
666                             pExtAddr[0]);
667                     }
668                 }
669             }
670         }
672         if(Csf_keys == KEY_DISASSOCIATE_DEVICE)
673         {
674             ApiMac_sAddr_t sAddr;
676             Board_Lcd_printf(DisplayLine_info, "Info: Sending 0x%04x disassociation req", selected_device);
677             LOG_printf(LOG_APPSRV_MSG_CONTENT, "Info: Sending 0x%04x disassociation req\n", selected_device);
679             sAddr.addr.shortAddr = selected_device;
680             sAddr.addrMode = ApiMac_addrType_short;
682             if(!removeDevice(sAddr))
683             {
684                 Board_Lcd_printf(DisplayLine_info, "Info: disassociation req device 0x%04x not found", selected_device);
685                 LOG_printf(LOG_APPSRV_MSG_CONTENT, "Info: disassociation req device 0x%04x not found\n", selected_device);
686             }
687         }
689         /* Clear the key press indication */
690         Csf_keys = 0;
691     }
693     /* Clear the event */
694     Util_clearEvent(&Csf_events, CSF_KEY_EVENT);
696 #endif /* (!defined(IS_HEADLESS) && defined(IS_HLOS)) */
698 #if defined(MT_CSF)
699     MTCSF_displayStatistics();
700 #endif
703 #if (!defined(IS_HEADLESS) && defined(IS_HLOS))
704 void initConsoleCmd(void)
706     struct termios term_attr;
708     /* set the terminal to raw mode */
709     tcgetattr(fileno(stdin), &term_attr);
710     term_attr.c_lflag &= ~(ECHO|ICANON);
711     term_attr.c_cc[VTIME] = 0;
712     term_attr.c_cc[VMIN] = 0;
713     tcsetattr(fileno(stdin), TCSANOW, &term_attr);
717 char* getConsoleCmd(void)
719     static bool cmdComplete = false;
720     static char cmd[256] = {0};
721     static int ch;
722     static uint8_t cmdIdx = 0;
724     if(cmdComplete)
725     {
726         memset(cmd, 0, 256);
727         cmdIdx = 0;
728         cmdComplete = false;
729     }
731     /* read a character from the stdin stream without blocking */
732     /*   returns EOF (-1) if no character is available */
733     ch = getchar();
735     if(ch != -1)
736     {
737          /* Discard non-ascii characters except new lines */
738         if(ch == 0xa || (ch >= 0x20 && ch < 0x7F))
739         {
740             cmd[cmdIdx] = ch;
741         }
743         Board_Lcd_printf(DisplayLine_cmd, "cmd: %s", cmd);
744         /* cmdIdx will wrap around for the 256Byte buffer */
745         if(cmd[cmdIdx] == 0xa)
746         {
747             cmdComplete = true;
748         }
749         else
750         {
751             cmdIdx++;
752         }
753     }
755     if(cmdComplete)
756     {
757         Board_Lcd_printf(DisplayLine_cmd, "CMD: %s", cmd);
758         LOG_printf(LOG_APPSRV_MSG_CONTENT, "CMD: %s\n", cmd);
759         
760         return cmd;
761     }
762     else
763     {
764         return 0;
765     }
767 #endif //(!defined(HEADLESS) && defined(IS_HLOS))
769 /*!
770  The application calls this function to retrieve the stored
771  network information.
773  Public function defined in csf.h
774  */
775 bool Csf_getNetworkInformation(Llc_netInfo_t *pInfo)
777     if((pNV != NULL) && (pNV->readItem != NULL) && (pInfo != NULL))
778     {
779         NVINTF_itemID_t id;
781         /* Setup NV ID */
782         id.systemID = NVINTF_SYSID_APP;
783         id.itemID = CSF_NV_NETWORK_INFO_ID;
784         id.subID = 0;
786         /* Read Network Information from NV */
787         if(pNV->readItem(id, 0, sizeof(Llc_netInfo_t), pInfo) == NVINTF_SUCCESS)
788         {
789             return(true);
790         }
791     }
792     return(false);
795 /*!
796  The application calls this function to indicate that it has
797  started or restored the device in a network
799  Public function defined in csf.h
800  */
801 void Csf_networkUpdate(bool restored, Llc_netInfo_t *pNetworkInfo)
803     /* check for valid structure ponter, ignore if not */
804     if(pNetworkInfo != NULL)
805     {
806         if((pNV != NULL) && (pNV->writeItem != NULL))
807         {
808             NVINTF_itemID_t id;
810             /* Setup NV ID */
811             id.systemID = NVINTF_SYSID_APP;
812             id.itemID = CSF_NV_NETWORK_INFO_ID;
813             id.subID = 0;
815             /* Write the NV item */
816             pNV->writeItem(id, sizeof(Llc_netInfo_t), pNetworkInfo);
817         }
820 #if IS_HLOS
821         /* Send info to appClient */
822         if(pNetworkInfo != NULL)
823         {
824              appsrv_networkUpdate(restored, pNetworkInfo);
825         }
826 #endif //IS_HLOS
828         started = true;
830 #ifndef IS_HEADLESS
831         Board_Lcd_printf(DisplayLine_nwk, "Nwk: Started");
832 #endif //IS_HEADLESS
833         LOG_printf(LOG_APPSRV_MSG_CONTENT, "Nwk: Started");
835         if(pNetworkInfo->fh == false)
836         {
837 #ifndef IS_HEADLESS
838             Board_Lcd_printf(DisplayLine_info, "Info: Channel %d", pNetworkInfo->channel);
839 #endif //IS_HEADLESS
840             LOG_printf(LOG_APPSRV_MSG_CONTENT, "Info: Channel %d", pNetworkInfo->channel);
841         }
842         else
843         {
844 #ifndef IS_HEADLESS
845             Board_Lcd_printf(DisplayLine_info, "Info: Freq. Hopping");
846 #endif //IS_HEADLESS
847             LOG_printf(LOG_APPSRV_MSG_CONTENT, "Info: Freq. Hopping");
848         }
850         Board_Led_control(board_led_type_LED1, board_led_state_ON);
852 #if defined(MT_CSF)
853         MTCSF_networkUpdateIndCB();
854 #endif
855     }
858 /*!
859  The application calls this function to indicate that a device
860  has joined the network.
862  Public function defined in csf.h
863  */
864 ApiMac_assocStatus_t Csf_deviceUpdate(ApiMac_deviceDescriptor_t *pDevInfo,
865                                       ApiMac_capabilityInfo_t *pCapInfo)
867     ApiMac_assocStatus_t status = ApiMac_assocStatus_success;
868     ApiMac_sAddr_t shortAddr;
869     ApiMac_sAddr_t extAddr;
871     shortAddr.addrMode = ApiMac_addrType_short;
872     shortAddr.addr.shortAddr = pDevInfo->shortAddress;
874     extAddr.addrMode = ApiMac_addrType_extended;
875     memcpy(&extAddr.addr.extAddr, &pDevInfo->extAddress, APIMAC_SADDR_EXT_LEN);
877     /* Is the device in the black list? */
878     if((findBlackListIndex(&shortAddr) >= 0)
879        || (findBlackListIndex(&extAddr) >= 0))
880     {
881         /* Denied */
882         status = ApiMac_assocStatus_panAccessDenied;
884 #if IS_HLOS
885         LOG_printf(LOG_APPSRV_MSG_CONTENT,
886                    "Denied: 0x%04x\n",
887                    pDevInfo->shortAddress);
888 #endif //IS_HLOS
890 #ifndef IS_HEADLESS
891         Board_Lcd_printf(DisplayLine_info, "Info: Denied 0x%04x", pDevInfo->shortAddress);
892 #endif //IS_HEADLESS
893     }
894     else
895     {
896         /* Save the device information */
897         Llc_deviceListItem_t dev;
899         memcpy(&dev.devInfo, pDevInfo, sizeof(ApiMac_deviceDescriptor_t));
900         memcpy(&dev.capInfo, pCapInfo, sizeof(ApiMac_capabilityInfo_t));
901         dev.rxFrameCounter = 0;
903         if(addDeviceListItem(&dev) == false)
904         {
905 #ifdef NV_RESTORE
906             status = ApiMac_assocStatus_panAtCapacity;
908 #if IS_HLOS
909             LOG_printf(LOG_ERROR,"Failed: 0x%04x\n", pDevInfo->shortAddress);
910 #endif //IS_HLOS
912 #ifndef IS_HEADLESS
913             Board_Lcd_printf(DisplayLine_info, "Info: Join Failed 0x%04x", pDevInfo->shortAddress);
914 #endif //!IS_HEADLESS
916 #else /* NV_RESTORE */
917         status = ApiMac_assocStatus_success;
919 #if IS_HLOS
920         LOG_printf(LOG_DBG_COLLECTOR_RAW, "Joined: Short: 0x%04x Extended: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
921             pDevInfo->shortAddress,
922             extAddr.addr.extAddr[7],
923             extAddr.addr.extAddr[6],
924             extAddr.addr.extAddr[5],
925             extAddr.addr.extAddr[4],
926             extAddr.addr.extAddr[3],
927             extAddr.addr.extAddr[2],
928             extAddr.addr.extAddr[1],
929             extAddr.addr.extAddr[0]);
930 #endif //IS_HLOS
932 #ifndef IS_HEADLESS
933         Board_Lcd_printf(DisplayLine_info, "Info: Joined 0x%04x", pDevInfo->shortAddress);
934 #endif //!IS_HEADLESS
936 #endif /* NV_RESTORE */
937         }
938         else
939         {
940 #if IS_HLOS
941          /* Send update to the appClient */
942             LOG_printf(LOG_APPSRV_MSG_CONTENT,
943                        "sending device update info to appsrv\n");
944             appsrv_deviceUpdate(&dev);
946             LOG_printf(LOG_DBG_COLLECTOR_RAW, "Joined: Short: 0x%04x Extended: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
947                 pDevInfo->shortAddress,
948                 extAddr.addr.extAddr[7],
949                 extAddr.addr.extAddr[6],
950                 extAddr.addr.extAddr[5],
951                 extAddr.addr.extAddr[4],
952                 extAddr.addr.extAddr[3],
953                 extAddr.addr.extAddr[2],
954                 extAddr.addr.extAddr[1],
955                 extAddr.addr.extAddr[0]);
956 #endif //IS_HLOS
958 #ifndef IS_HEADLESS
959             Board_Lcd_printf(DisplayLine_info, "Info: Joined 0x%04x", pDevInfo->shortAddress);
960 #endif //!IS_HEADLESS
961         }
962     }
964 #if defined(MT_CSF)
965     MTCSF_deviceUpdateIndCB(pDevInfo, pCapInfo);
966 #endif
968     /* Return the status of the joining device */
969     return (status);
972 /*!
973  The application calls this function to indicate that a device
974  is no longer active in the network.
976  Public function defined in csf.h
977  */
978 void Csf_deviceNotActiveUpdate(ApiMac_deviceDescriptor_t *pDevInfo,
979 bool timeout)
982 #if IS_HLOS
983     /* send update to the appClient */
984     LOG_printf(LOG_APPSRV_MSG_CONTENT,
985                "!Responding: 0x%04x\n",
986                pDevInfo->shortAddress);
988     appsrv_deviceNotActiveUpdate(pDevInfo, timeout);
990     LOG_printf(LOG_DBG_COLLECTOR,
991                 "inactive: pan: 0x%04x short: 0x%04x ext: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
992                 pDevInfo->panID,
993                 pDevInfo->shortAddress,
994                 pDevInfo->extAddress[0],
995                 pDevInfo->extAddress[1],
996                 pDevInfo->extAddress[2],
997                 pDevInfo->extAddress[3],
998                 pDevInfo->extAddress[4],
999                 pDevInfo->extAddress[5],
1000                 pDevInfo->extAddress[6],
1001                 pDevInfo->extAddress[7]);
1002 #endif //IS_HLOS
1004 #ifndef IS_HEADLESS
1005     Board_Lcd_printf(DisplayLine_info, "Info: No response 0x%04x", pDevInfo->shortAddress);
1006 #endif //IS_HEADLESS
1008 #if defined(MT_CSF)
1009     MTCSF_deviceNotActiveIndCB(pDevInfo, timeout);
1010 #endif
1014 /*!
1015  The application calls this function to indicate that a device
1016  has responded to a Config Request.
1018  Public function defined in csf.h
1019  */
1020 void Csf_deviceConfigUpdate(ApiMac_sAddr_t *pSrcAddr, int8_t rssi,
1021                             Smsgs_configRspMsg_t *pMsg)
1023 #if IS_HLOS
1024     /* send update to the appClient */
1025     appsrv_deviceConfigUpdate(pSrcAddr,rssi,pMsg);
1026     LOG_printf(LOG_APPSRV_MSG_CONTENT, "ConfigRsp: 0x%04x\n", pSrcAddr->addr.shortAddr);
1027 #endif //IS_HLOS
1029 #ifndef IS_HEADLESS
1030     Board_Lcd_printf(DisplayLine_info, "Info: ConfigRsp 0x%04x", pSrcAddr->addr.shortAddr);
1031 #endif //IS_HEADLESS
1033 #if defined(MT_CSF)
1034     MTCSF_configResponseIndCB(pSrcAddr, rssi, pMsg);
1035 #endif
1039 /*!
1040  The application calls this function to indicate that a device
1041  has reported sensor data.
1043  Public function defined in csf.h
1044  */
1045 void Csf_deviceSensorDataUpdate(ApiMac_sAddr_t *pSrcAddr, int8_t rssi,
1046                                 Smsgs_sensorMsg_t *pMsg)
1048 #ifndef IS_HEADLESS
1049     uint16_t sensorData = pMsg->tempSensor.ambienceTemp;
1051     if((DisplayLine_sensorStart + (pSrcAddr->addr.shortAddr - 1)) < DisplayLine_sensorEnd)
1052     {
1053         Board_Lcd_printf(DisplayLine_sensorStart + (pSrcAddr->addr.shortAddr - 1), "Sensor 0x%04x: Temp %d, RSSI %d",
1054                         pSrcAddr->addr.shortAddr, sensorData, rssi);
1055     }
1056     else
1057     {
1058         Board_Lcd_printf(DisplayLine_sensorEnd, "Sensor 0x%04x: Temp %d, RSSI %d",
1059                         pSrcAddr->addr.shortAddr, sensorData, rssi);
1060     }
1061 #endif //!IS_HEADLESS
1063 #if IS_HLOS
1064     /* send data to the appClient */
1065     LOG_printf(LOG_APPSRV_MSG_CONTENT, "Sensor 0x%04x\n", pSrcAddr->addr.shortAddr);
1067     appsrv_deviceSensorDataUpdate(pSrcAddr, rssi, pMsg);
1068 #endif //IS_HLOS
1070     Board_Led_toggle(board_led_type_LED2);
1072 #if defined(MT_CSF)
1073     MTCSF_sensorUpdateIndCB(pSrcAddr, rssi, pMsg);
1074 #endif
1077 /*!
1078  The application calls this function to indicate that a device
1079  has disassociated.
1081  Public function defined in csf.h
1082  */
1083 void Csf_deviceDisassocUpdate( ApiMac_sAddr_t *pSrcAddr )
1085     if(pSrcAddr->addrMode == ApiMac_addrType_extended)
1086     {
1087 #ifndef IS_HEADLESS
1088         Board_Lcd_printf(DisplayLine_info, "Info: Disassociate ind from %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
1089                             pSrcAddr->addr.extAddr[7], pSrcAddr->addr.extAddr[6],
1090                             pSrcAddr->addr.extAddr[5], pSrcAddr->addr.extAddr[4],
1091                             pSrcAddr->addr.extAddr[3], pSrcAddr->addr.extAddr[2],
1092                             pSrcAddr->addr.extAddr[1], pSrcAddr->addr.extAddr[0]);
1093 #endif
1095 #if IS_HLOS
1096         LOG_printf(LOG_DBG_COLLECTOR,
1097                     "Info: Disassociate ind from %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
1098                      pSrcAddr->addr.extAddr[0],
1099                      pSrcAddr->addr.extAddr[1],
1100                      pSrcAddr->addr.extAddr[2],
1101                      pSrcAddr->addr.extAddr[3],
1102                      pSrcAddr->addr.extAddr[4],
1103                      pSrcAddr->addr.extAddr[5],
1104                      pSrcAddr->addr.extAddr[6],
1105                      pSrcAddr->addr.extAddr[7]);
1106 #endif
1107     }
1108     else // Use Short address
1109     {
1110 #ifndef IS_HEADLESS
1111         Board_Lcd_printf(DisplayLine_info, "Info: Disassociate ind from 0x%04x", pSrcAddr->addr.shortAddr);
1112 #endif //!IS_HEADLESS
1114 #if IS_HLOS
1115         LOG_printf(LOG_DBG_COLLECTOR, "Info: Disassociate ind from 0x%04x\n", pSrcAddr->addr.shortAddr);
1116 #endif
1117     }
1120 /*!
1121  The application calls this function to indicate that a device
1122  has reported its FW version.
1124  Public function defined in csf.h
1125  */
1126 void Csf_deviceSensorFwVerUpdate( uint16_t srcAddr, char *fwVerStr)
1128     Board_Led_toggle(board_led_type_LED2);
1130 #ifndef IS_HEADLESS
1131     if((DisplayLine_sensorStart + (srcAddr - 1)) < DisplayLine_sensorEnd)
1132     {
1133         Board_Lcd_printf(DisplayLine_sensorStart + (srcAddr - 1), "Sensor 0x%04x: FW Ver %s",
1134                         srcAddr, fwVerStr);
1135     }
1136     else
1137     {
1138         Board_Lcd_printf(DisplayLine_sensorEnd, "Sensor 0x%04x: FW Ver %s",
1139                         srcAddr, fwVerStr);
1140     }
1141 #endif //!IS_HEADLESS
1143 #if IS_HLOS
1144         LOG_printf(LOG_APPSRV_MSG_CONTENT, "Sensor 0x%04x: FW Ver %s\n",
1145                         srcAddr, fwVerStr);
1146 #endif
1149 /*!
1150  The application calls this function to indicate that a device
1151  has reported its FW version.
1153  Public function defined in csf.h
1154  */
1155 void Csf_deviceSensorOadUpdate( uint16_t srcAddr, uint16_t imgId, uint16_t blockNum, uint16_t NumBlocks)
1157     Board_Led_toggle(board_led_type_LED2);
1158 #ifndef IS_HEADLESS
1159     uint8_t displayLine = 0;
1161     if((DisplayLine_sensorStart + (srcAddr - 1)) < DisplayLine_sensorEnd)
1162     {
1163         displayLine = (DisplayLine_sensorStart + (srcAddr - 1));
1164     }
1165     else
1166     {
1167         displayLine = DisplayLine_sensorEnd;
1168     }
1169 #endif
1170     if((blockNum + 1) == NumBlocks)
1171     {
1172 #ifndef IS_HEADLESS
1174         Board_Lcd_printf(displayLine, "Sensor 0x%04x: OAD completed, booting new image...",
1175                         srcAddr);
1176 #endif
1178 #if IS_HLOS
1179         LOG_printf(LOG_APPSRV_MSG_CONTENT, "Sensor 0x%04x: OAD completed, booting new image...\n",
1180                         srcAddr);
1181 #endif
1182     }
1183     else
1184     {
1185 #ifndef IS_HEADLESS
1186         Board_Lcd_printf(displayLine, "Sensor 0x%04x: OAD image %d, block %d of %d",
1187                 srcAddr, imgId, blockNum + 1, NumBlocks);
1189 #endif
1191 #if IS_HLOS
1192         LOG_printf(LOG_APPSRV_MSG_CONTENT, "Sensor 0x%04x: OAD image %d, block %d of %d\n",
1193                 srcAddr, imgId, blockNum + 1, NumBlocks);
1194 #endif
1195     }
1198 /*!
1199  The application calls this function to indicate that a device
1200  set a Toggle LED Response message.
1202  Public function defined in csf.h
1203  */
1204 void Csf_toggleResponseReceived(ApiMac_sAddr_t *pSrcAddr, bool ledState)
1206 #if defined(MT_CSF)
1207     uint16_t shortAddr = 0xFFFF;
1209     Board_Lcd_printf(DisplayLine_info, "Info: Device 0x%04x LED toggle rsp received", selected_device);
1210 #if IS_HLOS
1211         LOG_printf(LOG_APPSRV_MSG_CONTENT, "Info: Device 0x%04x LED toggle rsp received\n", selected_device);
1212 #endif
1213     if(pSrcAddr)
1214     {
1215         if(pSrcAddr->addrMode == ApiMac_addrType_short)
1216         {
1217             shortAddr = pSrcAddr->addr.shortAddr;
1218         }
1219         else
1220         {
1221             /* Convert extended to short addr */
1222             shortAddr = Csf_getDeviceShort(&pSrcAddr->addr.extAddr);
1223         }
1224     }
1225     MTCSF_deviceToggleIndCB(shortAddr, ledState);
1226 #endif
1229 /*!
1230  The application calls this function to indicate that the
1231  Coordinator's state has changed.
1233  Public function defined in csf.h
1234  */
1235 void Csf_stateChangeUpdate(Cllc_states_t state)
1237 #if !defined(IS_HLOS)
1238     if(started == true)
1239     {
1240         if(state == Cllc_states_joiningAllowed)
1241         {
1242             /* Flash LED1 while allowing joining */
1243             Board_Led_control(board_led_type_LED1, board_led_state_BLINKING);
1244         }
1245         else if(state == Cllc_states_joiningNotAllowed)
1246         {
1247             /* Don't flash when not allowing joining */
1248             Board_Led_control(board_led_type_LED1, board_led_state_ON);
1249         }
1250     }
1251 #endif
1252     /* Save the state to be used later */
1253     savedCllcState = state;
1255 #if defined(MT_CSF)
1256     MTCSF_stateChangeIndCB(state);
1257 #endif
1258 #if IS_HLOS
1259     /* Send the update to appClient */
1260     LOG_printf(LOG_APPSRV_MSG_CONTENT,
1261                "stateChangeUpdate, newstate: (%d) %s\n",
1262                (int)(state), CSF_cllc_statename(state));
1263     appsrv_stateChangeUpdate(state);
1264 #endif //IS_HLOS
1267 /* Wrappers for Callbacks*/
1268 #if IS_HLOS
1270 static void processConfigTimeoutCallback_WRAPPER(intptr_t timer_handle,
1271                          intptr_t cookie)
1273     (void)timer_handle;
1274     (void)cookie;
1275     processConfigTimeoutCallback(0);
1278 static void processJoinTimeoutCallback_WRAPPER(intptr_t timer_handle,
1279                                                intptr_t cookie)
1281     (void)timer_handle;
1282     (void)cookie;
1283     processJoinTimeoutCallback(0);
1286 static void processPATrickleTimeoutCallback_WRAPPER(intptr_t timer_handle,
1287                                                     intptr_t cookie)
1289     (void)timer_handle;
1290     (void)cookie;
1291     processPATrickleTimeoutCallback(0);
1294 static void processPCTrickleTimeoutCallback_WRAPPER(intptr_t timer_handle,
1295                                                     intptr_t cookie)
1297     (void)timer_handle;
1298     (void)cookie;
1299     processPCTrickleTimeoutCallback(0);
1302 /* Wrap HLOS to embedded callback */
1303 static void processTackingTimeoutCallback_WRAPPER(intptr_t timer_handle,
1304                                                   intptr_t cookie)
1306     (void)timer_handle;
1307     (void)cookie;
1308     processTackingTimeoutCallback(0);
1311 /* Wrap HLOS to embedded callback */
1312 static void processBroadcastTimeoutCallback_WRAPPER(intptr_t timer_handle,
1313                                                   intptr_t cookie)
1315     (void)timer_handle;
1316     (void)cookie;
1317     processBroadcastTimeoutCallback(0);
1320 #endif
1322 /*!
1323  Initialize the tracking clock.
1325  Public function defined in csf.h
1326  */
1327 void Csf_initializeTrackingClock(void)
1329 #if IS_HLOS
1330     trackingClkHandle = TIMER_CB_create("trackingTimer",
1331         processTackingTimeoutCallback_WRAPPER,
1332         0,
1333         TRACKING_INIT_TIMEOUT_VALUE,
1334         false);
1335 #else
1336     /* Initialize the timers needed for this application */
1337     trackingClkHandle = Timer_construct(&trackingClkStruct,
1338                                         processTackingTimeoutCallback,
1339                                         TRACKING_INIT_TIMEOUT_VALUE,
1340                                         0,
1341                                         false,
1342                                         0);
1343 #endif
1346 /*!
1347  Initialize the broadcast cmd clock.
1349  Public function defined in csf.h
1350  */
1351 void Csf_initializeBroadcastClock(void)
1353 #if IS_HLOS
1354     broadcastClkHandle = TIMER_CB_create("broadcastTimer",
1355         processBroadcastTimeoutCallback_WRAPPER,
1356         0,
1357         TRACKING_INIT_TIMEOUT_VALUE,
1358         false);
1359 #else
1360     /* Initialize the timer needed for the broadcast clock */
1361     broadcastClkHandle = Timer_construct(&broadcastClkStruct,
1362                                         processBroadcastTimeoutCallback,
1363                                         TRACKING_INIT_TIMEOUT_VALUE,
1364                                         0,
1365                                         false,
1366                                         0);
1367 #endif
1370 /*!
1371  Initialize the trickle clock.
1373  Public function defined in csf.h
1374  */
1375 void Csf_initializeTrickleClock(void)
1377 #if IS_HLOS
1378     tricklePAClkHandle =
1379         TIMER_CB_create(
1380             "paTrickleTimer",
1381             processPATrickleTimeoutCallback_WRAPPER,
1382              0,
1383                 TRICKLE_TIMEOUT_VALUE,
1384                 false);
1386     tricklePCClkHandle =
1387         TIMER_CB_create(
1388             "pcTrickleTimer",
1389             processPCTrickleTimeoutCallback_WRAPPER,
1390              0,
1391             TRICKLE_TIMEOUT_VALUE,
1392         false);
1394 #else
1395     /* Initialize trickle timer */
1396     tricklePAClkHandle = Timer_construct(&tricklePAClkStruct,
1397                                          processPATrickleTimeoutCallback,
1398                                          TRICKLE_TIMEOUT_VALUE,
1399                                          0,
1400                                          false,
1401                                          0);
1403     tricklePCClkHandle = Timer_construct(&tricklePCClkStruct,
1404                                          processPCTrickleTimeoutCallback,
1405                                          TRICKLE_TIMEOUT_VALUE,
1406                                          0,
1407                                          false,
1408                                          0);
1409 #endif
1412 /*!
1413  Initialize the clock for join permit attribute.
1415  Public function defined in csf.h
1416  */
1417 void Csf_initializeJoinPermitClock(void)
1419 #if IS_HLOS
1420     /* Initialize join permit timer */
1421     joinClkHandle =
1422         TIMER_CB_create(
1423         "joinTimer",
1424         processJoinTimeoutCallback_WRAPPER,
1425         0,
1426         JOIN_TIMEOUT_VALUE,
1427         false);
1428 #else
1429     /* Initialize join permit timer */
1430     joinClkHandle = Timer_construct(&joinClkStruct,
1431                                     processJoinTimeoutCallback,
1432                                     JOIN_TIMEOUT_VALUE,
1433                                     0,
1434                                     false,
1435                                     0);
1436 #endif
1439 /*!
1440  Initialize the clock for config request delay
1442  Public function defined in csf.h
1443  */
1444 void Csf_initializeConfigClock(void)
1446 #if IS_HLOS
1447     configClkHandle =
1448         TIMER_CB_create(
1449             "configTimer",
1450             processConfigTimeoutCallback_WRAPPER,
1451             0,
1452             CONFIG_TIMEOUT_VALUE,
1453             false );
1454 #else
1455     /* Initialize join permit timer */
1456     configClkHandle = Timer_construct(&configClkStruct,
1457                                     processConfigTimeoutCallback,
1458                                     CONFIG_TIMEOUT_VALUE,
1459                                     0,
1460                                     false,
1461                                     0);
1462 #endif
1465 /*!
1466  Set the tracking clock.
1468  Public function defined in csf.h
1469  */
1470 void Csf_setTrackingClock(uint32_t trackingTime)
1472 #if IS_HLOS
1473     /* Stop the Tracking timer */
1475     TIMER_CB_destroy(trackingClkHandle);
1476     trackingClkHandle = 0;
1478     /* Setup timer */
1479     if(trackingTime != 0)
1480     {
1481         trackingClkHandle =
1482             TIMER_CB_create(
1483                 "trackingTimer",
1484                 processTackingTimeoutCallback_WRAPPER,
1485                 0,
1486                 trackingTime,
1487                 false);
1488     }
1489 #else
1490     /* Stop the Tracking timer */
1491     if(Timer_isActive(&trackingClkStruct) == true)
1492     {
1493         Timer_stop(&trackingClkStruct);
1494     }
1496     if(trackingTime)
1497     {
1498         /* Setup timer */
1499         Timer_setTimeout(trackingClkHandle, trackingTime);
1500         Timer_start(&trackingClkStruct);
1501     }
1502 #endif
1506 /*!
1507  Set the broadcast clock.
1509  Public function defined in csf.h
1510  */
1511 void Csf_setBroadcastClock(uint32_t broadcastTime)
1513 #if IS_HLOS
1514     /* Stop the Broadcast timer */
1515     TIMER_CB_destroy(broadcastClkHandle);
1516     broadcastClkHandle = 0;
1518     /* Setup timer */
1519     if(broadcastTime != 0)
1520     {
1521         broadcastClkHandle =
1522             TIMER_CB_create(
1523                 "broadcastTimer",
1524                 processBroadcastTimeoutCallback_WRAPPER,
1525                 0,
1526                 broadcastTime,
1527                 false);
1528     }
1529 #else
1530     /* Stop the Broadcast timer */
1531     if(Timer_isActive(&broadcastClkStruct) == true)
1532     {
1533         Timer_stop(&broadcastClkStruct);
1534     }
1536     if(broadcastTime)
1537     {
1538         /* Setup timer */
1539         Timer_setTimeout(broadcastClkHandle, broadcastTime);
1540         Timer_start(&broadcastClkStruct);
1541     }
1542 #endif
1546 /*!
1547  Set the trickle clock.
1549  Public function defined in csf.h
1550  */
1551 void Csf_setTrickleClock(uint32_t trickleTime, uint8_t frameType)
1553     uint16_t randomNum = 0;
1554     uint16_t randomTime = 0;
1556     if(trickleTime > 0)
1557     {
1558         randomNum = ((ApiMac_randomByte() << 8) + ApiMac_randomByte());
1559         randomTime = (trickleTime >> 1) +
1560                       (randomNum % (trickleTime >> 1));
1561     }
1563     if(frameType == ApiMac_wisunAsyncFrame_advertisement)
1564     {
1565 #if IS_HLOS
1566         /* ALWAYS stop (avoid race conditions) */
1567         TIMER_CB_destroy(tricklePAClkHandle);
1568         tricklePAClkHandle = 0;
1570     /* then create new, only if needed */
1571         if(trickleTime > 0)
1572         {
1573             /* Setup timer */
1574             tricklePAClkHandle = TIMER_CB_create(
1575                 "paTrickleTimer",
1576                     processPATrickleTimeoutCallback_WRAPPER,
1577                     0,
1578                     randomTime,
1579                     false);
1580         }
1581 #else
1582         /* Stop the PA trickle timer */
1583         if(Timer_isActive(&tricklePAClkStruct) == true)
1584         {
1585             Timer_stop(&tricklePAClkStruct);
1586         }
1588         if(trickleTime > 0)
1589         {
1590             /* Setup timer */
1591             Timer_setTimeout(tricklePAClkHandle, randomTime);
1592             Timer_start(&tricklePAClkStruct);
1593         }
1594 #endif
1595     }
1596     else if(frameType == ApiMac_wisunAsyncFrame_config)
1597     {
1598 #if IS_HLOS
1599         /* Always stop */
1600         TIMER_CB_destroy(tricklePCClkHandle);
1601         tricklePCClkHandle = 0;
1602     /* and recreate only if needed */
1603         if(trickleTime > 0)
1604         {
1605             /* Setup timer */
1606             tricklePCClkHandle =
1607                 TIMER_CB_create(
1608                 "pcTrickleTimer",
1609                 processPCTrickleTimeoutCallback_WRAPPER,
1610                 0,
1611                 trickleTime, false);
1612         }
1613 #else
1614         /* Stop the PC trickle timer */
1615         if(Timer_isActive(&tricklePCClkStruct) == true)
1616         {
1617             Timer_stop(&tricklePCClkStruct);
1618         }
1620         if(trickleTime > 0)
1621         {
1622             /* Setup timer */
1623             Timer_setTimeout(tricklePCClkHandle, randomTime);
1624             Timer_start(&tricklePCClkStruct);
1625         }
1626 #endif
1627     }
1630 /*!
1631  Set the clock join permit attribute.
1633  Public function defined in csf.h
1634  */
1635 void Csf_setJoinPermitClock(uint32_t joinDuration)
1637 #if IS_HLOS
1638     /* Always stop the join timer */
1639     TIMER_CB_destroy(joinClkHandle);
1640     joinClkHandle = 0;
1642     /* Setup timer */
1643     if(joinDuration != 0)
1644     {
1645         joinClkHandle =
1646             TIMER_CB_create("joinTimer",
1647                 processJoinTimeoutCallback_WRAPPER,
1648                 0,
1649                 joinDuration, false);
1650     }
1651 #else
1652     /* Stop the join timer */
1653     if(Timer_isActive(&joinClkStruct) == true)
1654     {
1655         Timer_stop(&joinClkStruct);
1656     }
1658     if(joinDuration != 0)
1659     {
1660         /* Setup timer */
1661         Timer_setTimeout(joinClkHandle, joinDuration);
1662         Timer_start(&joinClkStruct);
1663     }
1664 #endif
1667 /*!
1668  Set the clock config request delay.
1670  Public function defined in csf.h
1671  */
1672 void Csf_setConfigClock(uint32_t delay)
1674 #if IS_HLOS
1675     /* Always destroy */
1676     TIMER_CB_destroy( configClkHandle );
1677     configClkHandle = 0;
1678     /* and create if needed */
1679     if( delay != 0 ){
1680         configClkHandle =
1681             TIMER_CB_create( "configClk",
1682                              processConfigTimeoutCallback_WRAPPER,
1683                              0,
1684                              delay,
1685                              false );
1686     }
1687 #else
1688     /* Stop the join timer */
1689     if(Timer_isActive(&configClkStruct) == true)
1690     {
1691         Timer_stop(&configClkStruct);
1692     }
1694     if(delay != 0)
1695     {
1696         /* Setup timer */
1697         Timer_setTimeout(configClkHandle, delay);
1698         Timer_start(&configClkStruct);
1699     }
1700 #endif
1703 /*!
1704  Read the number of device list items stored
1706  Public function defined in csf.h
1707  */
1708 uint16_t Csf_getNumDeviceListEntries(void)
1710     uint16_t numEntries = 0;
1712     if(pNV != NULL)
1713     {
1714         NVINTF_itemID_t id;
1715         uint8_t stat;
1717         /* Setup NV ID for the number of entries in the device list */
1718         id.systemID = NVINTF_SYSID_APP;
1719         id.itemID = CSF_NV_DEVICELIST_ENTRIES_ID;
1720         id.subID = 0;
1722         /* Read the number of device list items from NV */
1723         stat = pNV->readItem(id, 0, sizeof(uint16_t), &numEntries);
1724         if(stat != NVINTF_SUCCESS)
1725         {
1726             numEntries = 0;
1727         }
1728     }
1729     return (numEntries);
1732 /*!
1733  Find the short address from a given extended address
1735  Public function defined in csf.h
1736  */
1737 uint16_t Csf_getDeviceShort(ApiMac_sAddrExt_t *pExtAddr)
1739     Llc_deviceListItem_t item;
1740     ApiMac_sAddr_t devAddr;
1741     uint16_t shortAddr = CSF_INVALID_SHORT_ADDR;
1743     devAddr.addrMode = ApiMac_addrType_extended;
1744     memcpy(&devAddr.addr.extAddr, pExtAddr, sizeof(ApiMac_sAddrExt_t));
1746     if(Csf_getDevice(&devAddr,&item))
1747     {
1748         shortAddr = item.devInfo.shortAddress;
1749     }
1751     return(shortAddr);
1754 /*!
1755  Find the extended address from a given short address
1757  Public function defined in csf.h
1758  */
1759 bool Csf_getDeviceExtended(uint16_t shortAddr, ApiMac_sAddrExt_t *pExtAddr)
1761     Llc_deviceListItem_t item;
1762     ApiMac_sAddr_t devAddr;
1763     bool ret = false;
1765     devAddr.addrMode = ApiMac_addrType_short;
1766     devAddr.addr.shortAddr = shortAddr;
1768     if(Csf_getDevice(&devAddr,&item))
1769     {
1770         /* Copy found extended address */
1771         memcpy(pExtAddr, &item.devInfo.extAddress, sizeof(ApiMac_sAddrExt_t));
1772         ret = true;
1773     }
1775     return(ret);
1778 /*!
1779  Find entry in device list
1781  Public function defined in csf.h
1782  */
1783 bool Csf_getDevice(ApiMac_sAddr_t *pDevAddr, Llc_deviceListItem_t *pItem)
1785     if((pNV != NULL) && (pItem != NULL))
1786     {
1787         uint16_t numEntries;
1789         numEntries = Csf_getNumDeviceListEntries();
1791         if(numEntries > 0)
1792         {
1793             NVINTF_itemID_t id;
1794             uint8_t stat;
1795             int subId = 0;
1796             int readItems = 0;
1798             /* Setup NV ID for the device list records */
1799             id.systemID = NVINTF_SYSID_APP;
1800             id.itemID = CSF_NV_DEVICELIST_ID;
1802             while((readItems < numEntries) && (subId
1803                                                < CSF_MAX_DEVICELIST_IDS))
1804             {
1805                 Llc_deviceListItem_t item;
1807                 id.subID = (uint16_t)subId;
1809                 /* Read Network Information from NV */
1810                 stat = pNV->readItem(id, 0, sizeof(Llc_deviceListItem_t),
1811                                      &item);
1812                 if(stat == NVINTF_SUCCESS)
1813                 {
1814                     if(((pDevAddr->addrMode == ApiMac_addrType_short)
1815                         && (pDevAddr->addr.shortAddr
1816                             == item.devInfo.shortAddress))
1817                        || ((pDevAddr->addrMode == ApiMac_addrType_extended)
1818                            && (memcmp(&pDevAddr->addr.extAddr,
1819                                       &item.devInfo.extAddress,
1820                                       (APIMAC_SADDR_EXT_LEN))
1821                                == 0)))
1822                     {
1823                         memcpy(pItem, &item, sizeof(Llc_deviceListItem_t));
1824                         return (true);
1825                     }
1826                     readItems++;
1827                 }
1828                 subId++;
1829             }
1830         }
1831     }
1833     return (false);
1836 /*!
1837  Find entry in device list
1839  Public function defined in csf.h
1840  */
1841 bool Csf_getDeviceItem(uint16_t devIndex, Llc_deviceListItem_t *pItem)
1843     if((pNV != NULL) && (pItem != NULL))
1844     {
1845         uint16_t numEntries;
1847         numEntries = Csf_getNumDeviceListEntries();
1849         if(numEntries > 0)
1850         {
1851             NVINTF_itemID_t id;
1852             uint8_t stat;
1853             int subId = 0;
1854             int readItems = 0;
1856             /* Setup NV ID for the device list records */
1857             id.systemID = NVINTF_SYSID_APP;
1858             id.itemID = CSF_NV_DEVICELIST_ID;
1860             while((readItems < numEntries) && (subId
1861                                                < CSF_MAX_DEVICELIST_IDS))
1862             {
1863                 Llc_deviceListItem_t item;
1865                 id.subID = (uint16_t)subId;
1867                 /* Read Network Information from NV */
1868                 stat = pNV->readItem(id, 0, sizeof(Llc_deviceListItem_t),
1869                                      &item);
1870                 if(stat == NVINTF_SUCCESS)
1871                 {
1872                     if(readItems == devIndex)
1873                     {
1874                         memcpy(pItem, &item, sizeof(Llc_deviceListItem_t));
1875                         return (true);
1876                     }
1877                     readItems++;
1878                 }
1879                 subId++;
1880             }
1881         }
1882     }
1884     return (false);
1887 /*!
1888  Csf implementation for memory allocation
1890  Public function defined in csf.h
1891  */
1892 void *Csf_malloc(uint16_t size)
1894 #if IS_HLOS
1895     return malloc(size);
1896 #else
1897     return ICall_malloc(size);
1898 #endif
1901 /*!
1902  Csf implementation for memory de-allocation
1904  Public function defined in csf.h
1905  */
1906 void Csf_free(void *ptr)
1908 #if IS_HLOS
1909     free(ptr);
1910 #else
1911     ICall_free(ptr);
1912 #endif
1915 /*!
1916  Update the Frame Counter
1918  Public function defined in csf.h
1919  */
1920 void Csf_updateFrameCounter(ApiMac_sAddr_t *pDevAddr, uint32_t frameCntr)
1922     if((pNV != NULL) && (pNV->writeItem != NULL))
1923     {
1924         if(pDevAddr == NULL)
1925         {
1926             /* Update this device's frame counter */
1927             if((frameCntr >=
1928                 (lastSavedCoordinatorFrameCounter + FRAME_COUNTER_SAVE_WINDOW)))
1929             {
1930                 NVINTF_itemID_t id;
1932                 /* Setup NV ID */
1933                 id.systemID = NVINTF_SYSID_APP;
1934                 id.itemID = CSF_NV_FRAMECOUNTER_ID;
1935                 id.subID = 0;
1937                 /* Write the NV item */
1938                 if(pNV->writeItem(id, sizeof(uint32_t), &frameCntr)
1939                                 == NVINTF_SUCCESS)
1940                 {
1941                     lastSavedCoordinatorFrameCounter = frameCntr;
1942                 }
1943             }
1944         }
1945         else
1946         {
1947             /* Child frame counter update */
1948             Llc_deviceListItem_t devItem;
1950             /* Is the device in our database? */
1951             if(Csf_getDevice(pDevAddr, &devItem))
1952             {
1953                 /*
1954                  Don't save every update, only save if the new frame
1955                  counter falls outside the save window.
1956                  */
1957                 if((devItem.rxFrameCounter + FRAME_COUNTER_SAVE_WINDOW)
1958                                 <= frameCntr)
1959                 {
1960                     /* Update the frame counter */
1961                     devItem.rxFrameCounter = frameCntr;
1962                     updateDeviceListItem(&devItem);
1963                 }
1964             }
1965         }
1966     }
1969 /*!
1970  Get the Frame Counter
1972  Public function defined in csf.h
1973  */
1974 bool Csf_getFrameCounter(ApiMac_sAddr_t *pDevAddr, uint32_t *pFrameCntr)
1976     /* Check for valid pointer */
1977     if(pFrameCntr != NULL)
1978     {
1979         /*
1980          A pDevAddr that is null means to get the frame counter for this device
1981          */
1982         if(pDevAddr == NULL)
1983         {
1984             if((pNV != NULL) && (pNV->readItem != NULL))
1985             {
1986                 NVINTF_itemID_t id;
1988                 /* Setup NV ID */
1989                 id.systemID = NVINTF_SYSID_APP;
1990                 id.itemID = CSF_NV_FRAMECOUNTER_ID;
1991                 id.subID = 0;
1993                 /* Read Network Information from NV */
1994                 if(pNV->readItem(id, 0, sizeof(uint32_t), pFrameCntr)
1995                                 == NVINTF_SUCCESS)
1996                 {
1997                     /* Set to the next window */
1998                     *pFrameCntr += FRAME_COUNTER_SAVE_WINDOW;
1999                     return(true);
2000                 }
2001                 else
2002                 {
2003                     /*
2004                      Wasn't found, so write 0, so the next time it will be
2005                      greater than 0
2006                      */
2007                     uint32_t fc = 0;
2009                     /* Setup NV ID */
2010                     id.systemID = NVINTF_SYSID_APP;
2011                     id.itemID = CSF_NV_FRAMECOUNTER_ID;
2012                     id.subID = 0;
2014                     /* Write the NV item */
2015                     pNV->writeItem(id, sizeof(uint32_t), &fc);
2016                 }
2017             }
2018         }
2020         *pFrameCntr = 0;
2021     }
2022     return (false);
2026 /*!
2027  Delete an entry from the device list
2029  Public function defined in csf.h
2030  */
2031 void Csf_removeDeviceListItem(ApiMac_sAddrExt_t *pAddr)
2033     if((pNV != NULL) && (pNV->deleteItem != NULL))
2034     {
2035         int index;
2037         /* Does the item exist? */
2038         index = findDeviceListIndex(pAddr);
2039         if(index != DEVICE_INDEX_NOT_FOUND)
2040         {
2041             uint8_t stat;
2042             NVINTF_itemID_t id;
2044             /* Setup NV ID for the device list record */
2045             id.systemID = NVINTF_SYSID_APP;
2046             id.itemID = CSF_NV_DEVICELIST_ID;
2047             id.subID = (uint16_t)index;
2049             stat = pNV->deleteItem(id);
2050             if(stat == NVINTF_SUCCESS)
2051             {
2052                 /* Update the number of entries */
2053                 uint16_t numEntries = Csf_getNumDeviceListEntries();
2054                 if(numEntries > 0)
2055                 {
2056                     numEntries--;
2057                     saveNumDeviceListEntries(numEntries);
2058                 }
2059             }
2060         }
2061     }
2064 /*!
2065  Assert Indication
2067  Public function defined in csf.h
2068  */
2069 void Csf_assertInd(uint8_t reason)
2071 #if IS_HLOS
2072     LOG_printf( LOG_ERROR, "Assert Reason: %d\n", (int)(reason) );
2073 #endif
2074 #if defined(MT_CSF)
2075     if((pNV != NULL) && (pNV->writeItem != NULL))
2076     {
2077         /* Attempt to save reason to read after reset */
2078         (void)pNV->writeItem(nvResetId, 1, &reason);
2079     }
2080 #endif
2083 /*!
2084  Clear all the NV Items
2086  Public function defined in csf.h
2087  */
2088 void Csf_clearAllNVItems(void)
2090     if((pNV != NULL) && (pNV->deleteItem != NULL))
2091     {
2092         NVINTF_itemID_t id;
2093         uint16_t entries;
2095         /* Clear Network Information */
2096         id.systemID = NVINTF_SYSID_APP;
2097         id.itemID = CSF_NV_NETWORK_INFO_ID;
2098         id.subID = 0;
2099         pNV->deleteItem(id);
2101         /* Clear the black list entries number */
2102         id.systemID = NVINTF_SYSID_APP;
2103         id.itemID = CSF_NV_BLACKLIST_ENTRIES_ID;
2104         id.subID = 0;
2105         pNV->deleteItem(id);
2107         /*
2108          Clear the black list entries.  Brute force through
2109          every possible subID, if it doesn't exist that's fine,
2110          it will fail in deleteItem.
2111          */
2112         id.systemID = NVINTF_SYSID_APP;
2113         id.itemID = CSF_NV_BLACKLIST_ID;
2114         for(entries = 0; entries < CSF_MAX_BLACKLIST_IDS; entries++)
2115         {
2116             id.subID = entries;
2117             pNV->deleteItem(id);
2118         }
2120         /* Clear the device list entries number */
2121         id.systemID = NVINTF_SYSID_APP;
2122         id.itemID = CSF_NV_DEVICELIST_ENTRIES_ID;
2123         id.subID = 0;
2124         pNV->deleteItem(id);
2126         /*
2127          Clear the device list entries.  Brute force through
2128          every possible subID, if it doesn't exist that's fine,
2129          it will fail in deleteItem.
2130          */
2131         id.systemID = NVINTF_SYSID_APP;
2132         id.itemID = CSF_NV_DEVICELIST_ID;
2133         for(entries = 0; entries < CSF_MAX_DEVICELIST_IDS; entries++)
2134         {
2135             id.subID = entries;
2136             pNV->deleteItem(id);
2137         }
2139         /* Clear the device tx frame counter */
2140         id.systemID = NVINTF_SYSID_APP;
2141         id.itemID = CSF_NV_FRAMECOUNTER_ID;
2142         id.subID = 0;
2143         pNV->deleteItem(id);
2144     }
2148 /*!
2149  Add an entry into the black list
2151  Public function defined in csf.h
2152  */
2153 bool Csf_addBlackListItem(ApiMac_sAddr_t *pAddr)
2155     bool retVal = false;
2157     if((pNV != NULL) && (pAddr != NULL)
2158        && (pAddr->addrMode != ApiMac_addrType_none))
2159     {
2160         if(findBlackListIndex(pAddr))
2161         {
2162             retVal = true;
2163         }
2164         else
2165         {
2166             uint8_t stat;
2167             NVINTF_itemID_t id;
2168             uint16_t numEntries = getNumBlackListEntries();
2170             /* Check the maximum size */
2171             if(numEntries < CSF_MAX_BLACKLIST_ENTRIES)
2172             {
2173                 /* Setup NV ID for the black list record */
2174                 id.systemID = NVINTF_SYSID_APP;
2175                 id.itemID = CSF_NV_BLACKLIST_ID;
2176                 id.subID = (uint16_t)findUnusedBlackListIndex();
2178                 /* write the black list record */
2179                 stat = pNV->writeItem(id, sizeof(ApiMac_sAddr_t), pAddr);
2180                 if(stat == NVINTF_SUCCESS)
2181                 {
2182                     /* Update the number of entries */
2183                     numEntries++;
2184                     saveNumBlackListEntries(numEntries);
2185                     retVal = true;
2186                 }
2187             }
2188         }
2189     }
2191     return (retVal);
2194 /*!
2195  Check if config timer is active
2197  Public function defined in csf.h
2198  */
2199 bool Csf_isConfigTimerActive(void)
2201     bool b;
2202 #if IS_HLOS
2203     int r;
2204     /*
2205      * If the timer is not valid (ie: handle=0)
2206      * the 'getRemain()' will return negative
2207      * which is the same as expired.
2208      */
2209     r = TIMER_CB_getRemain(configClkHandle);
2210     if( r < 0 ){
2211         b = false;
2212     } else {
2213         b = true;
2214     }
2215 #else
2216     b = (Timer_isActive(&configClkStruct));
2217 #endif
2218     return b;
2221 /*!
2222  Check if tracking timer is active
2224  Public function defined in csf.h
2225 */
2226 bool Csf_isTrackingTimerActive(void)
2228     bool b;
2229 #if IS_HLOS
2230     int r;
2231     r = TIMER_CB_getRemain(trackingClkHandle);
2232     if( r < 0 ){
2233         b = false;
2234     } else {
2235         b = true;
2236     }
2237 #else
2238     b = (Timer_isActive(&trackingClkStruct));
2239 #endif
2240     return b;
2243 /******************************************************************************
2244  Local Functions
2245  *****************************************************************************/
2247 /*!
2248  * @brief       Tracking timeout handler function.
2249  *
2250  * @param       a0 - ignored
2251  */
2252 static void processTackingTimeoutCallback(UArg a0)
2254     (void)a0; /* Parameter is not used */
2256     Util_setEvent(&Collector_events, COLLECTOR_TRACKING_TIMEOUT_EVT);
2258     /* Wake up the application thread when it waits for clock event */
2259     Semaphore_post(collectorSem);
2262 /*!
2263  * @brief       Broadcast timeout handler function.
2264  *
2265  * @param       a0 - ignored
2266  */
2267 static void processBroadcastTimeoutCallback(UArg a0)
2269     (void)a0; /* Parameter is not used */
2271     Util_setEvent(&Collector_events, COLLECTOR_BROADCAST_TIMEOUT_EVT);
2273     /* Wake up the application thread when it waits for clock event */
2274     Semaphore_post(collectorSem);
2277 /*!
2278  * @brief       Join permit timeout handler function.
2279  *
2280  * @param       a0 - ignored
2281  */
2282 static void processJoinTimeoutCallback(UArg a0)
2284     (void)a0; /* Parameter is not used */
2286     Util_setEvent(&Cllc_events, CLLC_JOIN_EVT);
2288     /* Wake up the application thread when it waits for clock event */
2289     Semaphore_post(collectorSem);
2292 /*!
2293  * @brief       Config delay timeout handler function.
2294  *
2295  * @param       a0 - ignored
2296  */
2297 static void processConfigTimeoutCallback(UArg a0)
2299     (void)a0; /* Parameter is not used */
2301     Util_setEvent(&Collector_events, COLLECTOR_CONFIG_EVT);
2303     /* Wake up the application thread when it waits for clock event */
2304     Semaphore_post(collectorSem);
2307 /*!
2308  * @brief       Trickle timeout handler function for PA .
2309  *
2310  * @param       a0 - ignored
2311  */
2312 static void processPATrickleTimeoutCallback(UArg a0)
2314     (void)a0; /* Parameter is not used */
2316     Util_setEvent(&Cllc_events, CLLC_PA_EVT);
2318     /* Wake up the application thread when it waits for clock event */
2319     Semaphore_post(collectorSem);
2322 /*!
2323  * @brief       Trickle timeout handler function for PC.
2324  *
2325  * @param       a0 - ignored
2326  */
2327 static void processPCTrickleTimeoutCallback(UArg a0)
2329     (void)a0; /* Parameter is not used */
2331     Util_setEvent(&Cllc_events, CLLC_PC_EVT);
2333     /* Wake up the application thread when it waits for clock event */
2334     Semaphore_post(collectorSem);
2337 /*!
2338  * @brief       Key event handler function
2339  *
2340  * @param       keysPressed - Csf_keys that are pressed
2341  */
2342 static void processKeyChangeCallback(uint8_t keysPressed)
2344     Csf_keys = keysPressed;
2346     Csf_events |= CSF_KEY_EVENT;
2348     /* Wake up the application thread when it waits for clock event */
2349     Semaphore_post(collectorSem);
2352 /*!
2353  * @brief       Add an entry into the device list
2354  *
2355  * @param       pItem - pointer to the device list entry
2356  *
2357  * @return      true if added or already existed, false if problem
2358  */
2359 static bool addDeviceListItem(Llc_deviceListItem_t *pItem)
2361     bool retVal = false;
2363     if((pNV != NULL) && (pItem != NULL))
2364     {
2365         if(findDeviceListIndex(&pItem->devInfo.extAddress)
2366                         != DEVICE_INDEX_NOT_FOUND)
2367         {
2368             retVal = true;
2369         }
2370         else
2371         {
2372             uint8_t stat;
2373             NVINTF_itemID_t id;
2374             uint16_t numEntries = Csf_getNumDeviceListEntries();
2376             /* Check the maximum size */
2377             if(numEntries < CSF_MAX_DEVICELIST_ENTRIES)
2378             {
2379                 /* Setup NV ID for the device list record */
2380                 id.systemID = NVINTF_SYSID_APP;
2381                 id.itemID = CSF_NV_DEVICELIST_ID;
2382                 id.subID = (uint16_t)findUnusedDeviceListIndex();
2384                 /* write the device list record */
2385                 stat = pNV->writeItem(id, sizeof(Llc_deviceListItem_t), pItem);
2386                 if(stat == NVINTF_SUCCESS)
2387                 {
2388                     /* Update the number of entries */
2389                     numEntries++;
2390                     saveNumDeviceListEntries(numEntries);
2391                     retVal = true;
2392                 }
2393             }
2394         }
2395     }
2397     return (retVal);
2400 /*!
2401  * @brief       Update an entry in the device list
2402  *
2403  * @param       pItem - pointer to the device list entry
2404  */
2405 static void updateDeviceListItem(Llc_deviceListItem_t *pItem)
2407     if((pNV != NULL) && (pItem != NULL))
2408     {
2409         int idx;
2411         idx = findDeviceListIndex(&pItem->devInfo.extAddress);
2412         if(idx != DEVICE_INDEX_NOT_FOUND)
2413         {
2414             NVINTF_itemID_t id;
2416             /* Setup NV ID for the device list record */
2417             id.systemID = NVINTF_SYSID_APP;
2418             id.itemID = CSF_NV_DEVICELIST_ID;
2419             id.subID = (uint16_t)idx;
2421             /* write the device list record */
2422             pNV->writeItem(id, sizeof(Llc_deviceListItem_t), pItem);
2423         }
2424     }
2427 /*!
2428  * @brief       Find entry in device list
2429  *
2430  * @param       pAddr - address to of device to find
2431  *
2432  * @return      sub index into the device list, -1 (DEVICE_INDEX_NOT_FOUND)
2433  *              if not found
2434  */
2435 static int findDeviceListIndex(ApiMac_sAddrExt_t *pAddr)
2437     if((pNV != NULL) && (pAddr != NULL))
2438     {
2439         uint16_t numEntries;
2441         numEntries = Csf_getNumDeviceListEntries();
2443         if(numEntries > 0)
2444         {
2445             NVINTF_itemID_t id;
2446             uint8_t stat;
2447             int subId = 0;
2448             int readItems = 0;
2450             /* Setup NV ID for the device list records */
2451             id.systemID = NVINTF_SYSID_APP;
2452             id.itemID = CSF_NV_DEVICELIST_ID;
2454             while((readItems < numEntries) && (subId
2455                                                < CSF_MAX_DEVICELIST_IDS))
2456             {
2457                 Llc_deviceListItem_t item;
2459                 id.subID = (uint16_t)subId;
2461                 /* Read Network Information from NV */
2462                 stat = pNV->readItem(id, 0, sizeof(Llc_deviceListItem_t),
2463                                      &item);
2464                 if(stat == NVINTF_SUCCESS)
2465                 {
2466                     /* Is the address the same */
2467                     if(memcmp(pAddr, &item.devInfo.extAddress,
2468                               (APIMAC_SADDR_EXT_LEN))
2469                        == 0)
2470                     {
2471                         return (subId);
2472                     }
2473                     readItems++;
2474                 }
2475                 subId++;
2476             }
2477         }
2478     }
2480     return (DEVICE_INDEX_NOT_FOUND);
2483 /*!
2484  * @brief       Find an unused device list index
2485  *
2486  * @return      index that is not in use
2487  */
2488 static int findUnusedDeviceListIndex(void)
2490     int subId = 0;
2492     if(pNV != NULL)
2493     {
2494         uint16_t numEntries;
2496         numEntries = Csf_getNumDeviceListEntries();
2498         if(numEntries > 0)
2499         {
2500             NVINTF_itemID_t id;
2502             int readItems = 0;
2503             /* Setup NV ID for the device list records */
2504             id.systemID = NVINTF_SYSID_APP;
2505             id.itemID = CSF_NV_DEVICELIST_ID;
2507             while((readItems < numEntries) && (subId
2508                                                < CSF_MAX_DEVICELIST_IDS))
2509             {
2510                 Llc_deviceListItem_t item;
2511                 uint8_t stat;
2513                 id.subID = (uint16_t)subId;
2515                 /* Read Network Information from NV */
2516                 stat = pNV->readItem(id, 0, sizeof(Llc_deviceListItem_t),
2517                                      &item);
2518                 if(stat == NVINTF_NOTFOUND)
2519                 {
2520                     /* Use this sub id */
2521                     break;
2522                 }
2523                 else if(stat == NVINTF_SUCCESS)
2524                 {
2525                     readItems++;
2526                 }
2527                 subId++;
2528             }
2529         }
2530     }
2532     return (subId);
2535 /*!
2536  * @brief       Read the number of device list items stored
2537  *
2538  * @param       numEntries - number of entries in the device list
2539  */
2540 static void saveNumDeviceListEntries(uint16_t numEntries)
2542     if(pNV != NULL)
2543     {
2544         NVINTF_itemID_t id;
2546         /* Setup NV ID for the number of entries in the device list */
2547         id.systemID = NVINTF_SYSID_APP;
2548         id.itemID = CSF_NV_DEVICELIST_ENTRIES_ID;
2549         id.subID = 0;
2551         /* Read the number of device list items from NV */
2552         pNV->writeItem(id, sizeof(uint16_t), &numEntries);
2553     }
2556 /*!
2557  * @brief       Find entry in black list
2558  *
2559  * @param       pAddr - address to add into the black list
2560  *
2561  * @return      sub index into the blacklist, -1 if not found
2562  */
2563 static int findBlackListIndex(ApiMac_sAddr_t *pAddr)
2565     if((pNV != NULL) && (pAddr != NULL)
2566        && (pAddr->addrMode != ApiMac_addrType_none))
2567     {
2568         uint16_t numEntries;
2570         numEntries = getNumBlackListEntries();
2572         if(numEntries > 0)
2573         {
2574             NVINTF_itemID_t id;
2575             uint8_t stat;
2576             int subId = 0;
2577             int readItems = 0;
2579             /* Setup NV ID for the black list records */
2580             id.systemID = NVINTF_SYSID_APP;
2581             id.itemID = CSF_NV_BLACKLIST_ID;
2583             while((readItems < numEntries) && (subId < CSF_MAX_BLACKLIST_IDS))
2584             {
2585                 ApiMac_sAddr_t item;
2587                 id.subID = (uint16_t)subId;
2589                 /* Read Network Information from NV */
2590                 stat = pNV->readItem(id, 0, sizeof(ApiMac_sAddr_t), &item);
2591                 if(stat == NVINTF_SUCCESS)
2592                 {
2593                     if(pAddr->addrMode == item.addrMode)
2594                     {
2595                         /* Is the address the same */
2596                         if(((pAddr->addrMode == ApiMac_addrType_short)
2597                             && (pAddr->addr.shortAddr == item.addr.shortAddr))
2598                            || ((pAddr->addrMode == ApiMac_addrType_extended)
2599                                && (memcmp(&pAddr->addr.extAddr,
2600                                           &item.addr.extAddr,
2601                                           APIMAC_SADDR_EXT_LEN)
2602                                    == 0)))
2603                         {
2604                             return (subId);
2605                         }
2606                     }
2607                     readItems++;
2608                 }
2609                 subId++;
2610             }
2611         }
2612     }
2614     return (-1);
2617 /*!
2618  * @brief       Find an unused blacklist index
2619  *
2620  * @return      index that is not in use
2621  */
2622 static int findUnusedBlackListIndex(void)
2624     int subId = 0;
2626     if(pNV != NULL)
2627     {
2628         uint16_t numEntries;
2630         numEntries = getNumBlackListEntries();
2632         if(numEntries > 0)
2633         {
2634             NVINTF_itemID_t id;
2636             int readItems = 0;
2637             /* Setup NV ID for the black list records */
2638             id.systemID = NVINTF_SYSID_APP;
2639             id.itemID = CSF_NV_BLACKLIST_ID;
2641             while((readItems < numEntries) && (subId < CSF_MAX_BLACKLIST_IDS))
2642             {
2643                 ApiMac_sAddr_t item;
2644                 uint8_t stat;
2646                 id.subID = (uint16_t)subId;
2648                 /* Read Network Information from NV */
2649                 stat = pNV->readItem(id, 0, sizeof(ApiMac_sAddr_t), &item);
2650                 if(stat == NVINTF_NOTFOUND)
2651                 {
2652                     /* Use this sub id */
2653                     break;
2654                 }
2655                 else if(stat == NVINTF_SUCCESS)
2656                 {
2657                     readItems++;
2658                 }
2659                 subId++;
2660             }
2661         }
2662     }
2664     return (subId);
2667 /*!
2668  * @brief       Read the number of black list items stored
2669  *
2670  * @return      number of entries in the black list
2671  */
2672 static uint16_t getNumBlackListEntries(void)
2674     uint16_t numEntries = 0;
2676     if(pNV != NULL)
2677     {
2678         NVINTF_itemID_t id;
2679         uint8_t stat;
2681         /* Setup NV ID for the number of entries in the black list */
2682         id.systemID = NVINTF_SYSID_APP;
2683         id.itemID = CSF_NV_BLACKLIST_ENTRIES_ID;
2684         id.subID = 0;
2686         /* Read the number of black list items from NV */
2687         stat = pNV->readItem(id, 0, sizeof(uint16_t), &numEntries);
2688         if(stat != NVINTF_SUCCESS)
2689         {
2690             numEntries = 0;
2691         }
2692     }
2693     return (numEntries);
2696 /*!
2697  * @brief       Read the number of black list items stored
2698  *
2699  * @param       numEntries - number of entries in the black list
2700  */
2701 static void saveNumBlackListEntries(uint16_t numEntries)
2703     if(pNV != NULL)
2704     {
2705         NVINTF_itemID_t id;
2707         /* Setup NV ID for the number of entries in the black list */
2708         id.systemID = NVINTF_SYSID_APP;
2709         id.itemID = CSF_NV_BLACKLIST_ENTRIES_ID;
2710         id.subID = 0;
2712         /* Read the number of black list items from NV */
2713         pNV->writeItem(id, sizeof(uint16_t), &numEntries);
2714     }
2717 /*!
2718  * @brief       Delete an address from the black list
2719  *
2720  * @param       pAddr - address to remove from black list.
2721  */
2722 void removeBlackListItem(ApiMac_sAddr_t *pAddr)
2724     if(pNV != NULL)
2725     {
2726         int index;
2728         /* Does the item exist? */
2729         index = findBlackListIndex(pAddr);
2730         if(index > 0)
2731         {
2732             uint8_t stat;
2733             NVINTF_itemID_t id;
2735             /* Setup NV ID for the black list record */
2736             id.systemID = NVINTF_SYSID_APP;
2737             id.itemID = CSF_NV_BLACKLIST_ID;
2738             id.subID = (uint16_t)index;
2740             stat = pNV->deleteItem(id);
2741             if(stat == NVINTF_SUCCESS)
2742             {
2743                 /* Update the number of entries */
2744                 uint16_t numEntries = getNumBlackListEntries();
2745                 if(numEntries > 0)
2746                 {
2747                     numEntries--;
2748                     saveNumBlackListEntries(numEntries);
2749                 }
2750             }
2751         }
2752     }
2755 /*!
2756  * @brief       This is an example function on how to remove a device
2757  *              from this network.
2758  *
2759  * @param       addr - device address
2760  *
2761  * @return      true if found, false if not
2762  */
2763 static bool removeDevice(ApiMac_sAddr_t addr)
2765     LOG_printf(LOG_ERROR, "removing device 0x%04x\n", addr.addr.shortAddr);
2767     LOG_printf(LOG_ERROR, "sending Disassociation request to device 0x%04x\n", addr.addr.shortAddr);
2769     /* Send a disassociate to the device */
2770     Cllc_sendDisassociationRequest(addr.addr.shortAddr,
2771                                      false);
2773     return 1;
2776 #if defined(TEST_REMOVE_DEVICE)
2777 /*!
2778  * @brief       This is an example function on how to remove a device
2779  *              from this network.
2780  */
2781 static void removeTheFirstDevice(void)
2783     if(pNV != NULL)
2784     {
2785         uint16_t numEntries;
2787         numEntries = Csf_getNumDeviceListEntries();
2789         if(numEntries > 0)
2790         {
2791             NVINTF_itemID_t id;
2792             uint16_t subId = 0;
2794             /* Setup NV ID for the device list records */
2795             id.systemID = NVINTF_SYSID_APP;
2796             id.itemID = CSF_NV_DEVICELIST_ID;
2798             while(subId < CSF_MAX_DEVICELIST_IDS)
2799             {
2800                 Llc_deviceListItem_t item;
2801                 uint8_t stat;
2803                 id.subID = (uint16_t)subId;
2805                 /* Read Network Information from NV */
2806                 stat = pNV->readItem(id, 0, sizeof(Llc_deviceListItem_t),
2807                                      &item);
2808                 if(stat == NVINTF_SUCCESS)
2809                 {
2810                     /* Found the first device in the list */
2811                     ApiMac_sAddr_t addr;
2813                     /* Send a disassociate to the device */
2814                     Cllc_sendDisassociationRequest(item.devInfo.shortAddress,
2815                                                    item.capInfo.rxOnWhenIdle);
2816                     /* Remove device from the NV list */
2817                     Cllc_removeDevice(&item.devInfo.extAddress);
2819                     /* Remove it from the Device list */
2820                     Csf_removeDeviceListItem(&item.devInfo.extAddress);
2822                     /* Add the device to the black list so it can't join again */
2823                     addr.addrMode = ApiMac_addrType_extended;
2824                     memcpy(&addr.addr.extAddr, &item.devInfo.extAddress,
2825                            (APIMAC_SADDR_EXT_LEN));
2826                     Csf_addBlackListItem(&addr);
2827                     break;
2828                 }
2829                 subId++;
2830             }
2831         }
2832     }
2834 #endif
2836 #if !IS_HLOS
2837 /*!
2838  * @brief       Retrieve the first device's short address
2839  *
2840  * @return      short address or 0xFFFF if not found
2841  */
2842 static uint16_t getTheFirstDevice(void)
2844     uint16_t found = CSF_INVALID_SHORT_ADDR;
2845     if(pNV != NULL)
2846     {
2847         uint16_t numEntries;
2849         numEntries = Csf_getNumDeviceListEntries();
2851         if(numEntries > 0)
2852         {
2853             NVINTF_itemID_t id;
2855             /* Setup NV ID for the device list records */
2856             id.systemID = NVINTF_SYSID_APP;
2857             id.itemID = CSF_NV_DEVICELIST_ID;
2858             id.subID = 0;
2860             while(id.subID < CSF_MAX_DEVICELIST_IDS)
2861             {
2862                 Llc_deviceListItem_t item;
2863                 uint8_t stat;
2865                 /* Read Network Information from NV */
2866                 stat = pNV->readItem(id, 0, sizeof(Llc_deviceListItem_t),
2867                                      &item);
2868                 if(stat == NVINTF_SUCCESS)
2869                 {
2870                     found = item.devInfo.shortAddress;
2871                     break;
2872                 }
2873                 id.subID++;
2874             }
2875         }
2876     }
2877     return(found);
2879 #endif
2881 /*!
2882  * @brief       Retrieve the first device's short address
2883  *
2884  * @return      short address or 0xFFFF if not found
2885  */
2886 void Csf_freeDeviceInformationList(size_t n, Csf_deviceInformation_t *p)
2888     (void)(n); /* not used */
2889     if(p)
2890     {
2891         free((void *)(p));
2892     }
2895 /*!
2896  The appSrv calls this function to get the list of connected
2897  devices
2899  Public function defined in csf_linux.h
2900  */
2901 int Csf_getDeviceInformationList(Csf_deviceInformation_t **ppDeviceInfo)
2903     Csf_deviceInformation_t *pThis;
2904     Llc_deviceListItem_t    tmp;
2905     uint16_t actual;
2906     uint16_t subId;
2907     int n;
2908     NVINTF_itemID_t id;
2910     /* get number of connected devices */
2911     n = Csf_getNumDeviceListEntries();
2912     /* initialize device list pointer */
2914     pThis = calloc(n+1, sizeof(*pThis));
2915     *ppDeviceInfo = pThis;
2916     if(pThis == NULL)
2917     {
2918         LOG_printf(LOG_ERROR, "No memory for device list\n");
2919         return 0;
2920     }
2922     /* Setup NV ID for the device list records */
2923     id.systemID = NVINTF_SYSID_APP;
2924     id.itemID = CSF_NV_DEVICELIST_ID;
2925     subId = 0;
2926     actual = 0;
2927     /* Read the Entries */
2928     while((subId < CSF_MAX_DEVICELIST_IDS) && (actual < n))
2929     {
2930         uint8_t stat;
2932         id.subID = subId;
2933         /* Read Device Information from NV */
2934         stat = pNV->readItem(id, 0,
2935                              sizeof(tmp),
2936                              &tmp);
2937         if(stat == NVINTF_SUCCESS)
2938         {
2939             pThis->devInfo = tmp.devInfo;
2940             pThis->capInfo = tmp.capInfo;
2941             actual++;
2942             pThis++;
2943         }
2944         subId++;
2945      }
2947     /* return actual number of devices connected */
2948     return actual;
2951 void CSF_LINUX_USE_THESE_FUNCTIONS(void);
2952 void CSF_LINUX_USE_THESE_FUNCTIONS(void)
2954     /* (void)started; */
2955 #if defined(TEST_REMOVE_DEVICE)
2956     (void)removeTheFirstDevice;
2957 #endif
2958     (void)removeBlackListItem;
2959     (void)processKeyChangeCallback;
2960     (void)permitJoining;
2963 const char *CSF_cllc_statename(Cllc_states_t s)
2965     const char *cp;
2966     switch(s)
2967     {
2968     default:
2969         cp = "unknown";
2970         break;
2971     case Cllc_states_initWaiting:
2972         cp = "initWaiting";
2973         break;
2974     case Cllc_states_startingCoordinator:
2975         cp = "startingCoordinator";
2976         break;
2977     case Cllc_states_initRestoringCoordinator:
2978         cp = "initRestoringCoordinator";
2979         break;
2980     case Cllc_states_started:
2981         cp = "started";
2982         break;
2983     case Cllc_states_restored:
2984         cp = "restored";
2985         break;
2986     case Cllc_states_joiningAllowed:
2987         cp = "joiningAllowed";
2988         break;
2989     case Cllc_states_joiningNotAllowed:
2990         cp = "joiningNotAllowed";
2991         break;
2992     }
2993     return cp;
2996 /*!
2997  The appsrv module calls this function to send config request
2998  to a device over the air
3000  Public function defined in csf_linux.h
3001  */
3002 extern uint8_t Csf_sendConfigRequest( ApiMac_sAddr_t *pDstAddr,
3003                 uint16_t frameControl,
3004                 uint32_t reportingInterval,
3005                 uint32_t pollingInterval)
3007     return Collector_sendConfigRequest( pDstAddr,
3008                 frameControl,
3009                 reportingInterval,
3010                 pollingInterval);
3013 /*!
3014  The appsrv module calls this function to send a led toggle request
3015  to a device over the air
3017  Public function defined in csf_linux.h
3018  */
3019 extern uint8_t Csf_sendToggleLedRequest(
3020                 ApiMac_sAddr_t *pDstAddr)
3022     return Collector_sendToggleLedRequest(pDstAddr);
3025 /*!
3026  The appsrv module calls this function to send a buzzer ctrl request
3027  to a device over the air
3029  Public function defined in csf_linux.h
3030  */
3031 extern uint8_t Csf_sendBuzzerCtrlRequest(
3032     ApiMac_sAddr_t *pDstAddr)
3034     return Collector_sendBuzzerCtrlRequest(pDstAddr);
3037 /*
3038  * Public function in csf_linux.h
3039  * Gateway front end uses this to get the current state.
3040  */
3041 Cllc_states_t Csf_getCllcState(void)
3043     return savedCllcState;
3046 #ifdef PROCESS_JS
3047 /*!
3048  The application calls this function to indicate that a device
3049  has reported raw data.
3051  Public function defined in csf.h
3052  */
3053 void Csf_deviceRawDataUpdate(ApiMac_mcpsDataInd_t *pDataInd)
3055 #if IS_HLOS
3056     /* send data to the appClient */
3057     appsrv_deviceRawDataUpdate(pDataInd);
3058 #endif /* IS_HLOS */
3060     Board_Led_toggle(board_led_type_LED2);
3062 #endif
3064 /*
3065  *  ========================================
3066  *  Texas Instruments Micro Controller Style
3067  *  ========================================
3068  *  Local Variables:
3069  *  mode: c
3070  *  c-file-style: "bsd"
3071  *  tab-width: 4
3072  *  c-basic-offset: 4
3073  *  indent-tabs-mode: nil
3074  *  End:
3075  *  vim:set  filetype=c tabstop=4 shiftwidth=4 expandtab=true
3076  */