Updated TI Linux Sensor To Cloud to the latest TI 15.4-Stack v2.4, now with CC13x2...
[apps/tidep0084.git] / example / collector / collector.c
1 /******************************************************************************
3  @file collector.c
5  @brief TIMAC 2.0 Collector Example Application
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 /******************************************************************************
48  Includes
49  *****************************************************************************/
50 #include <string.h>
51 #include <stdint.h>
52 #include <stdio.h>
54 #include "util.h"
55 #include "api_mac.h"
56 #include "cllc.h"
57 #include "csf.h"
58 #include "smsgs.h"
59 #include "collector.h"
61 #include "log.h"
63 #include "oad_protocol.h"
64 #include "oad_storage.h"
65 #include "oad_image_header.h"
67 /******************************************************************************
68  Constants and definitions
69  *****************************************************************************/
71 #if !defined(CONFIG_AUTO_START)
72 #if defined(AUTO_START)
73 #define CONFIG_AUTO_START 1
74 #else
75 #define CONFIG_AUTO_START 0
76 #endif
77 #endif
79 /* Beacon order for non beacon network */
80 #define NON_BEACON_ORDER      15
82 /* Default MSDU Handle rollover */
83 #define MSDU_HANDLE_MAX 0x3F
85 /* App marker in MSDU handle */
86 #define APP_MARKER_MSDU_HANDLE 0x80
88 /* App Config request marker for the MSDU handle */
89 #define APP_CONFIG_MSDU_HANDLE 0x40
91 /* App Broadcast Cmd Msg marker for the MSDU Handle */
92 #define APP_BROADCAST_MSDU_HANDLE 0x20
93 /* Default configuration frame control */
94 #define CONFIG_FRAME_CONTROL (0xFFFF)
96 /* Delay for config request retry in busy network */
97 #define CONFIG_DELAY 2000
98 #define CONFIG_RESPONSE_DELAY 3*CONFIG_DELAY
99 /* Tracking timeouts */
100 #define TRACKING_CNF_DELAY_TIME 2000 /* in milliseconds */
101 #define TRACKING_TIMEOUT_TIME (CONFIG_POLLING_INTERVAL * 3) /*in milliseconds*/
102 /* Initial delay before broadcast transmissions are started in FH mode */
103 #define BROADCAST_CMD_START_TIME 60000
105 /* Number of superframe periods to hold a indirect packet at collector for
106 Sensor to poll and get the frame*/
107 #define BCN_MODE_INDIRECT_PERSISTENT_TIME 3
109 #if ((CONFIG_PHY_ID >= APIMAC_MRFSK_STD_PHY_ID_BEGIN) && (CONFIG_PHY_ID <= APIMAC_MRFSK_GENERIC_PHY_ID_BEGIN))
111 /* MAC Indirect Persistent Timeout */
112 #define INDIRECT_PERSISTENT_TIME ((5 * 1000 * CONFIG_POLLING_INTERVAL / 2)/ \
113                                   (BASE_SUPER_FRAME_DURATION * \
114                                    SYMBOL_DURATION_50_kbps))
116 #elif ((CONFIG_PHY_ID >= APIMAC_GENERIC_US_915_PHY_132) && (CONFIG_PHY_ID <= APIMAC_GENERIC_ETSI_863_PHY_133))
118 /* MAC Indirect Persistent Timeout */
119 #define INDIRECT_PERSISTENT_TIME ((5 * 1000 * CONFIG_POLLING_INTERVAL / 2)/ \
120                                   (BASE_SUPER_FRAME_DURATION * \
121                                    SYMBOL_DURATION_200_kbps))
123 #elif (CONFIG_PHY_ID == APIMAC_PHY_ID_NONE)
125 /* MAC Indirect Persistent Timeout */
126 #define INDIRECT_PERSISTENT_TIME ((5 * 1000 * CONFIG_POLLING_INTERVAL / 2)/ \
127                                   (BASE_SUPER_FRAME_DURATION * \
128                                    SYMBOL_DURATION_250_kbps))
130 #else
131 /* MAC Indirect Persistent Timeout */
132 #define INDIRECT_PERSISTENT_TIME ((5 * 1000 * CONFIG_POLLING_INTERVAL / 2)/ \
133                                   (BASE_SUPER_FRAME_DURATION * \
134                                     SYMBOL_DURATION_LRM))
135 #endif
137 /* Assoc Table (CLLC) status settings */
138 #define ASSOC_CONFIG_SENT       0x0100    /* Config Req sent */
139 #define ASSOC_CONFIG_RSP        0x0200    /* Config Rsp received */
140 #define ASSOC_CONFIG_MASK       0x0300    /* Config mask */
141 #define ASSOC_TRACKING_SENT     0x1000    /* Tracking Req sent */
142 #define ASSOC_TRACKING_RSP      0x2000    /* Tracking Rsp received */
143 #define ASSOC_TRACKING_RETRY    0x4000    /* Tracking Req retried */
144 #define ASSOC_TRACKING_ERROR    0x8000    /* Tracking Req error */
145 #define ASSOC_TRACKING_MASK     0xF000    /* Tracking mask  */
147 #define MAX_OAD_FILES           10
149 #ifdef TIRTOS_IN_ROM
150 #define IMG_HDR_ADDR            0x04F0
151 #else
152 #define IMG_HDR_ADDR            0x0000
153 #endif
155 typedef struct
157     uint8_t oad_file_id;
158     char oad_file[256];
159 }oadFile_t;
161 /******************************************************************************
162  Global variables
163  *****************************************************************************/
165 /* Task pending events */
166 uint16_t Collector_events = 0;
168 /*! Collector statistics */
169 Collector_statistics_t Collector_statistics;
171 /******************************************************************************
172  Local variables
173  *****************************************************************************/
175 static void *sem;
177 /*! true if the device was restarted */
178 static bool restarted = false;
180 /*! CLLC State */
181 static Cllc_states_t cllcState = Cllc_states_initWaiting;
183 /*! Device's PAN ID */
184 static uint16_t devicePanId = 0xFFFF;
186 /*! Device's Outgoing MSDU Handle values */
187 static uint8_t deviceTxMsduHandle = 0;
189 static bool fhEnabled = false;
191 static oadFile_t oad_file_list[MAX_OAD_FILES] = {{0}};
192 static uint16_t oadBNumBlocks;
194 /******************************************************************************
195  Local function prototypes
196  *****************************************************************************/
197 static void initializeClocks(void);
198 static void cllcStartedCB(Llc_netInfo_t *pStartedInfo);
199 static ApiMac_assocStatus_t cllcDeviceJoiningCB(
200                 ApiMac_deviceDescriptor_t *pDevInfo,
201                 ApiMac_capabilityInfo_t *pCapInfo);
202 static void cllcStateChangedCB(Cllc_states_t state);
203 static void dataCnfCB(ApiMac_mcpsDataCnf_t *pDataCnf);
204 static void dataIndCB(ApiMac_mcpsDataInd_t *pDataInd);
205 static void disassocIndCB(ApiMac_mlmeDisassociateInd_t *pDisassocInd);
206 static void disassocCnfCB(ApiMac_mlmeDisassociateCnf_t *pDisassocCnf);
207 static void processStartEvent(void);
208 static void processConfigResponse(ApiMac_mcpsDataInd_t *pDataInd);
209 static void processTrackingResponse(ApiMac_mcpsDataInd_t *pDataInd);
210 static void processToggleLedResponse(ApiMac_mcpsDataInd_t *pDataInd);
211 static void processSensorData(ApiMac_mcpsDataInd_t *pDataInd);
212 static void processOadData(ApiMac_mcpsDataInd_t *pDataInd);
213 static Cllc_associated_devices_t *findDevice(ApiMac_sAddr_t *pAddr);
214 static Cllc_associated_devices_t *findDeviceStatusBit(uint16_t mask, uint16_t statusBit);
215 static uint8_t getMsduHandle(Smsgs_cmdIds_t msgType);
216 static bool sendMsg(Smsgs_cmdIds_t type, uint16_t dstShortAddr, bool rxOnIdle,
217                     uint16_t len,
218                     uint8_t *pData);
219 static void generateConfigRequests(void);
220 static void generateTrackingRequests(void);
221 static void generateBroadcastCmd(void);
222 static void sendTrackingRequest(Cllc_associated_devices_t *pDev);
223 static void commStatusIndCB(ApiMac_mlmeCommStatusInd_t *pCommStatusInd);
224 static void pollIndCB(ApiMac_mlmePollInd_t *pPollInd);
225 static void processDataRetry(ApiMac_sAddr_t *pAddr);
226 static void processConfigRetry(void);
228 static void oadFwVersionRspCb(void* pSrcAddr, char *fwVersionStr);
229 static void oadImgIdentifyRspCb(void* pSrcAddr, uint8_t status);
230 static void oadBlockReqCb(void* pSrcAddr, uint8_t imgId, uint16_t blockNum, uint16_t multiBlockSize);
232 static void* oadRadioAccessAllocMsg(uint32_t size);
233 static OADProtocol_Status_t oadRadioAccessPacketSend(void* pDstAddr, uint8_t *pMsg, uint32_t msgLen);
235 /******************************************************************************
236  Callback tables
237  *****************************************************************************/
239 /*! API MAC Callback table */
240 ApiMac_callbacks_t Collector_macCallbacks =
241     {
242       /*! Associate Indicated callback */
243       NULL,
244       /*! Associate Confirmation callback */
245       NULL,
246       /*! Disassociate Indication callback */
247       disassocIndCB,
248       /*! Disassociate Confirmation callback */
249       disassocCnfCB,
250       /*! Beacon Notify Indication callback */
251       NULL,
252       /*! Orphan Indication callback */
253       NULL,
254       /*! Scan Confirmation callback */
255       NULL,
256       /*! Start Confirmation callback */
257       NULL,
258       /*! Sync Loss Indication callback */
259       NULL,
260       /*! Poll Confirm callback */
261       NULL,
262       /*! Comm Status Indication callback */
263       commStatusIndCB,
264       /*! Poll Indication Callback */
265       pollIndCB,
266       /*! Data Confirmation callback */
267       dataCnfCB,
268       /*! Data Indication callback */
269       dataIndCB,
270       /*! Purge Confirm callback */
271       NULL,
272       /*! WiSUN Async Indication callback */
273       NULL,
274       /*! WiSUN Async Confirmation callback */
275       NULL,
276       /*! Unprocessed message callback */
277       NULL
278     };
280 static Cllc_callbacks_t cllcCallbacks =
281     {
282       /*! Coordinator Started Indication callback */
283       cllcStartedCB,
284       /*! Device joining callback */
285       cllcDeviceJoiningCB,
286       /*! The state has changed callback */
287       cllcStateChangedCB
288     };
290 static OADProtocol_RadioAccessFxns_t  oadRadioAccessFxns =
291     {
292       oadRadioAccessAllocMsg,
293       oadRadioAccessPacketSend
294     };
296 static OADProtocol_MsgCBs_t oadMsgCallbacks =
297     {
298       /*! Incoming FW Req */
299       NULL,
300       /*! Incoming FW Version Rsp */
301       oadFwVersionRspCb,
302       /*! Incoming Image Identify Req */
303       NULL,
304       /*! Incoming Image Identify Rsp */
305       oadImgIdentifyRspCb,
306       /*! Incoming OAD Block Req */
307       oadBlockReqCb,
308       /*! Incoming OAD Block Rsp */
309       NULL
310     };
312 /******************************************************************************
313  Public Functions
314  *****************************************************************************/
316 /*!
317  Initialize this application.
319  Public function defined in collector.h
320  */
321 void Collector_init(void)
323     OADProtocol_Params_t OADProtocol_params;
325     /* Initialize the collector's statistics */
326     memset(&Collector_statistics, 0, sizeof(Collector_statistics_t));
328     /* Initialize the MAC */
329     sem = ApiMac_init(CONFIG_FH_ENABLE);
331     /* Initialize the Coordinator Logical Link Controller */
332     Cllc_init(&Collector_macCallbacks, &cllcCallbacks);
334     /* Register the MAC Callbacks */
335     ApiMac_registerCallbacks(&Collector_macCallbacks);
337     /* Initialize the platform specific functions */
338     Csf_init(sem);
340     ApiMac_mlmeSetReqUint8(ApiMac_attribute_phyCurrentDescriptorId,
341                            (uint8_t)CONFIG_PHY_ID);
343     ApiMac_mlmeSetReqUint8(ApiMac_attribute_channelPage,
344                            (uint8_t)CONFIG_CHANNEL_PAGE);
346     /* Set the indirect persistent timeout */
347     if(CONFIG_MAC_BEACON_ORDER != NON_BEACON_ORDER)
348     {
349         ApiMac_mlmeSetReqUint16(ApiMac_attribute_transactionPersistenceTime,
350             BCN_MODE_INDIRECT_PERSISTENT_TIME);
351     }
352     else
353     {
354         ApiMac_mlmeSetReqUint16(ApiMac_attribute_transactionPersistenceTime,
355             INDIRECT_PERSISTENT_TIME);
356     }
357     ApiMac_mlmeSetReqUint8(ApiMac_attribute_phyTransmitPowerSigned,
358                            (uint8_t)CONFIG_TRANSMIT_POWER);
359     /* Set Min BE */
360     ApiMac_mlmeSetReqUint8(ApiMac_attribute_backoffExponent,
361                               (uint8_t)CONFIG_MIN_BE);
362     /* Set Max BE */
363     ApiMac_mlmeSetReqUint8(ApiMac_attribute_maxBackoffExponent,
364                               (uint8_t)CONFIG_MAX_BE);
365     /* Set MAC MAX CSMA Backoffs */
366     ApiMac_mlmeSetReqUint8(ApiMac_attribute_maxCsmaBackoffs,
367                               (uint8_t)CONFIG_MAC_MAX_CSMA_BACKOFFS);
368     /* Set MAC MAX Frame Retries */
369     ApiMac_mlmeSetReqUint8(ApiMac_attribute_maxFrameRetries,
370                               (uint8_t)CONFIG_MAX_RETRIES);
371 #ifdef FCS_TYPE16
372     /* Set the fcs type */
373     ApiMac_mlmeSetReqBool(ApiMac_attribute_fcsType,
374                           (bool)1);
375 #endif
377     /* Initialize the app clocks */
378     initializeClocks();
379     if(CONFIG_FH_ENABLE && (FH_BROADCAST_DWELL_TIME > 0))
380     {
381         /* Start broadcast frame transmissions in FH mode if broadcast dwell time
382          * is greater than zero */
383         Csf_setBroadcastClock(BROADCAST_CMD_START_TIME);
384     }
386     if(CONFIG_AUTO_START)
387     {
388         /* Start the device */
389         Util_setEvent(&Collector_events, COLLECTOR_START_EVT);
390     }
392     OADProtocol_Params_init(&OADProtocol_params);
393     OADProtocol_params.pRadioAccessFxns = &oadRadioAccessFxns;
394     OADProtocol_params.pProtocolMsgCallbacks = &oadMsgCallbacks;
396     OADProtocol_open(&OADProtocol_params);
400 /*!
401  Application task processing.
403  Public function defined in collector.h
404  */
405 void Collector_process(void)
407     /* Start the collector device in the network */
408     if(Collector_events & COLLECTOR_START_EVT)
409     {
410         if(cllcState == Cllc_states_initWaiting)
411         {
412             processStartEvent();
413         }
415         /* Clear the event */
416         Util_clearEvent(&Collector_events, COLLECTOR_START_EVT);
417     }
419     /* Is it time to send the next tracking message? */
420     if(Collector_events & COLLECTOR_TRACKING_TIMEOUT_EVT)
421     {
422         /* Process Tracking Event */
423         generateTrackingRequests();
425         /* Clear the event */
426         Util_clearEvent(&Collector_events, COLLECTOR_TRACKING_TIMEOUT_EVT);
427     }
429     /*
430      The generate a config request for all associated devices that need one
431      */
432     if(Collector_events & COLLECTOR_CONFIG_EVT)
433     {
434         generateConfigRequests();
436         /* Clear the event */
437         Util_clearEvent(&Collector_events, COLLECTOR_CONFIG_EVT);
438     }
440     /*
441      Collector generate a broadcast command message for FH mode
442      */
443     if(Collector_events & COLLECTOR_BROADCAST_TIMEOUT_EVT)
444     {
445         /* Clear the event */
446         Util_clearEvent(&Collector_events, COLLECTOR_BROADCAST_TIMEOUT_EVT);
447         if(FH_BROADCAST_INTERVAL > 0 && (!CERTIFICATION_TEST_MODE))
448         {
449             generateBroadcastCmd();
450             /* set clock for next broadcast command */
451             Csf_setBroadcastClock(FH_BROADCAST_INTERVAL);
452         }
453     }
455     /* Process LLC Events */
456     Cllc_process();
458     /* Allow the Specific functions to process */
459     Csf_processEvents();
461     /*
462      Don't process ApiMac messages until all of the collector events
463      are processed.
464      */
465     if(Collector_events == 0)
466     {
467         /* Wait for response message or events */
468         ApiMac_processIncoming();
469     }
472 /*!
473  Build and send the configuration message to a device.
475  Public function defined in collector.h
476  */
477 Collector_status_t Collector_sendConfigRequest(ApiMac_sAddr_t *pDstAddr,
478                                                uint16_t frameControl,
479                                                uint32_t reportingInterval,
480                                                uint32_t pollingInterval)
482     Collector_status_t status = Collector_status_invalid_state;
484     /* Are we in the right state? */
485     if(cllcState >= Cllc_states_started)
486     {
487         Llc_deviceListItem_t item;
489         /* Is the device a known device? */
490         if(Csf_getDevice(pDstAddr, &item))
491         {
492             uint8_t buffer[SMSGS_CONFIG_REQUEST_MSG_LENGTH];
493             uint8_t *pBuf = buffer;
495             /* Build the message */
496             *pBuf++ = (uint8_t)Smsgs_cmdIds_configReq;
497             *pBuf++ = Util_loUint16(frameControl);
498             *pBuf++ = Util_hiUint16(frameControl);
499             *pBuf++ = Util_breakUint32(reportingInterval, 0);
500             *pBuf++ = Util_breakUint32(reportingInterval, 1);
501             *pBuf++ = Util_breakUint32(reportingInterval, 2);
502             *pBuf++ = Util_breakUint32(reportingInterval, 3);
503             *pBuf++ = Util_breakUint32(pollingInterval, 0);
504             *pBuf++ = Util_breakUint32(pollingInterval, 1);
505             *pBuf++ = Util_breakUint32(pollingInterval, 2);
506             *pBuf = Util_breakUint32(pollingInterval, 3);
508             if((sendMsg(Smsgs_cmdIds_configReq, item.devInfo.shortAddress,
509                         item.capInfo.rxOnWhenIdle,
510                         (SMSGS_CONFIG_REQUEST_MSG_LENGTH),
511                          buffer)) == true)
512             {
513                 status = Collector_status_success;
514                 Collector_statistics.configRequestAttempts++;
515                 /* set timer for retry in case response is not received */
516                 Csf_setConfigClock(CONFIG_DELAY);
517             }
518             else
519             {
520                 processConfigRetry();
521             }
522         }
523     }
525     return (status);
528 /*!
529  Update the collector statistics
531  Public function defined in collector.h
532  */
533 void Collector_updateStats( void )
535     /* update the stats from the MAC */
536     ApiMac_mlmeGetReqUint32(ApiMac_attribute_diagRxSecureFail,
537                             &Collector_statistics.rxDecryptFailures);
539     ApiMac_mlmeGetReqUint32(ApiMac_attribute_diagTxSecureFail,
540                             &Collector_statistics.txEncryptFailures);
543 /*!
544  Build and send the toggle led message to a device.
546  Public function defined in collector.h
547  */
548 Collector_status_t Collector_sendToggleLedRequest(ApiMac_sAddr_t *pDstAddr)
550     Collector_status_t status = Collector_status_invalid_state;
552     /* Are we in the right state? */
553     if(cllcState >= Cllc_states_started)
554     {
555         Llc_deviceListItem_t item;
557         /* Is the device a known device? */
558         if(Csf_getDevice(pDstAddr, &item))
559         {
560             uint8_t buffer[SMSGS_TOGGLE_LED_REQUEST_MSG_LEN];
562             /* Build the message */
563             buffer[0] = (uint8_t)Smsgs_cmdIds_toggleLedReq;
565             sendMsg(Smsgs_cmdIds_toggleLedReq, item.devInfo.shortAddress,
566                     item.capInfo.rxOnWhenIdle,
567                     SMSGS_TOGGLE_LED_REQUEST_MSG_LEN,
568                     buffer);
570             status = Collector_status_success;
571         }
572         else
573         {
574             status = Collector_status_deviceNotFound;
575         }
576     }
578     return(status);
581 /*!
582  updates the FW list.
584  Public function defined in collector.h
585  */
586 uint32_t Collector_updateFwList(char *new_oad_file)
588     uint32_t oad_file_idx;
589     uint32_t oad_file_id;
590     bool found = false;
592     LOG_printf( LOG_DBG_COLLECTOR, "Collector_updateFwList: new oad file: %s\n",
593                           new_oad_file);
595     /* Does OAD file exist */
596     for(oad_file_idx = 0; oad_file_idx < MAX_OAD_FILES; oad_file_idx++)
597     {
598         if(strcmp(new_oad_file, oad_file_list[oad_file_idx].oad_file) == 0)
599         {
600             LOG_printf( LOG_DBG_COLLECTOR, "Collector_updateFwList: found ID: %d\n",
601                           oad_file_list[oad_file_idx].oad_file_id);
602             oad_file_id = oad_file_list[oad_file_idx].oad_file_id;
603             found = true;
604             break;
605         }
606     }
608     if(!found)
609     {
610         static uint32_t latest_oad_file_idx = 0;
611         static uint32_t latest_oad_file_id = 0;
613         oad_file_id = latest_oad_file_id;
615         oad_file_list[latest_oad_file_idx].oad_file_id = oad_file_id;
616         strncpy(oad_file_list[latest_oad_file_idx].oad_file, new_oad_file, 256);
618         LOG_printf( LOG_DBG_COLLECTOR, "Collector_updateFwList: Added %s, ID %d\n",
619               oad_file_list[latest_oad_file_idx].oad_file,
620               oad_file_list[latest_oad_file_idx].oad_file_id);
622         latest_oad_file_id++;
623         latest_oad_file_idx++;
624         if(latest_oad_file_idx == MAX_OAD_FILES)
625         {
626             latest_oad_file_idx = 0;
627         }
628     }
630     return oad_file_id;
634 /*!
635  Send OAD version request message.
637  Public function defined in collector.h
638  */
639 Collector_status_t Collector_sendFwVersionRequest(ApiMac_sAddr_t *pDstAddr)
641     Collector_status_t status = Collector_status_invalid_state;
643     if(OADProtocol_sendFwVersionReq((void*) pDstAddr) == OADProtocol_Status_Success)
644     {
645         status = Collector_status_success;
646     }
648     return status;
651 /*!
652  Send OAD version request message.
654  Public function defined in collector.h
655  */
656 Collector_status_t Collector_startFwUpdate(ApiMac_sAddr_t *pDstAddr, uint32_t oad_file_id)
658     Collector_status_t status = Collector_status_invalid_state;
659     uint8_t imgInfoData[OADProtocol_AGAMA_IMAGE_HDR_LEN];
660     uint32_t oad_file_idx;
661     FILE *oadFile;
663     for(oad_file_idx = 0; oad_file_idx < MAX_OAD_FILES; oad_file_idx++)
664     {
665         if(oad_file_list[oad_file_idx].oad_file_id == oad_file_id)
666         {
667           LOG_printf( LOG_DBG_COLLECTOR, "Collector_startFwUpdate: opening file: %s\n",
668                           oad_file_list[oad_file_idx].oad_file);
670           oadFile = fopen(oad_file_list[oad_file_idx].oad_file, "r");
671           break;
672         }
673     }
675     if(oadFile)
676     {
677         LOG_printf( LOG_DBG_COLLECTOR, "Collector_startFwUpdate: opened file....\n");
679         fseek(oadFile, IMG_HDR_ADDR, SEEK_SET);
681         if(fread(imgInfoData, 1, OADProtocol_AGAMA_IMAGE_HDR_LEN, oadFile) == OADProtocol_AGAMA_IMAGE_HDR_LEN)
682         {
683             //check if it is a unified OAD binary
684             OADStorage_imgIdentifyPld_t imgIdPld;
685             
687             imgHdr_t* pImgHdr = (imgHdr_t*) imgInfoData;
689             if((strncmp((const char*) pImgHdr->fixedHdr.imgID, CC26X2_OAD_IMG_ID_VAL, 8) == 0)
690                                 || (strncmp((const char*) pImgHdr->fixedHdr.imgID, CC13X2_OAD_IMG_ID_VAL, 8) == 0))
691             {
692                 LOG_printf( LOG_DBG_COLLECTOR, "Collector_startFwUpdate: unified OAD image\n");
693                                 
694                 //copy image indentify payload
695                 memcpy(imgIdPld.imgID, pImgHdr->fixedHdr.imgID, 8);
696                 imgIdPld.bimVer = pImgHdr->fixedHdr.bimVer;
697                 imgIdPld.metaVer = pImgHdr->fixedHdr.metaVer;
698                 imgIdPld.imgCpStat = pImgHdr->fixedHdr.imgCpStat;
699                 imgIdPld.crcStat = pImgHdr->fixedHdr.crcStat;
700                 imgIdPld.imgType = pImgHdr->fixedHdr.imgType;
701                 imgIdPld.imgNo = pImgHdr->fixedHdr.imgNo;
702                 imgIdPld.len = pImgHdr->fixedHdr.len;
703                 memcpy(imgIdPld.softVer, pImgHdr->fixedHdr.softVer, 4);
705                 LOG_printf( LOG_DBG_COLLECTOR, "Collector_startFwUpdate: sending ImgIdentifyReq, Img Len %x\n", pImgHdr->fixedHdr.len);
706                 
707                                 oadBNumBlocks = pImgHdr->fixedHdr.len / OAD_BLOCK_SIZE;
709                 if(pImgHdr->fixedHdr.len % OAD_BLOCK_SIZE)
710                 {
711                     //there are some remaining bytes in an additional block
712                     oadBNumBlocks++;
713                 }
715                 if(OADProtocol_sendImgIdentifyReq((void*) pDstAddr, oad_file_id, (uint8_t*) &imgIdPld) == OADProtocol_Status_Success)
716                 {
717                     status = Collector_status_success;
718                 }
719             }
720             else
721             {
722                                 uint32_t oadImgLen = ((imgInfoData[6]) | (imgInfoData[7] << 8));
723                                 
724                 LOG_printf( LOG_DBG_COLLECTOR, "Collector_startFwUpdate: Not a unified OAD image\n");
725                 LOG_printf( LOG_DBG_COLLECTOR, "Collector_startFwUpdate: sending ImgIdentifyReq, Img Len %x\n", oadImgLen);
727                 oadBNumBlocks =  oadImgLen / (OAD_BLOCK_SIZE / 4);
729                 if(oadImgLen % OAD_BLOCK_SIZE)
730                 {
731                     //there are some remaining bytes in an additional block
732                     oadBNumBlocks++;
733                 }
735                 if(oadImgLen % OAD_BLOCK_SIZE)
736                 {
737                     //there are some remaining bytes in an additional block
738                     oadBNumBlocks++;
739                 }
741                 if(OADProtocol_sendImgIdentifyReq((void*) pDstAddr, oad_file_id, imgInfoData) == OADProtocol_Status_Success)
742                 {
743                     status = Collector_status_success;
744                 }
745             }
746         }
748         fclose(oadFile);
749     }
750     else
751     {
752         LOG_printf( LOG_DBG_COLLECTOR, "Collector_startFwUpdate: could not open file: %s\n",
753                         oad_file_list[oad_file_idx].oad_file);
754         status = Collector_status_invalid_file;
755     }
757     return status;
760 /*!
761  Find if a device is present.
763  Public function defined in collector.h
764  */
765 Collector_status_t Collector_findDevice(ApiMac_sAddr_t *pAddr)
767     Collector_status_t status = Collector_status_deviceNotFound;
769     if(findDevice(pAddr))
770     {
771         status = Collector_status_success;
772     }
774     return status;
777 /******************************************************************************
778  Local Functions
779  *****************************************************************************/
781 /*!
782  * @brief       Initialize the clocks.
783  */
784 static void initializeClocks(void)
786     /* Initialize the tracking clock */
787     Csf_initializeTrackingClock();
788     Csf_initializeConfigClock();
789     Csf_initializeBroadcastClock();
792 /*!
793  * @brief      CLLC Started callback.
794  *
795  * @param      pStartedInfo - pointer to network information
796  */
797 static void cllcStartedCB(Llc_netInfo_t *pStartedInfo)
799     devicePanId = pStartedInfo->devInfo.panID;
800     if(pStartedInfo->fh == true)
801     {
802         fhEnabled = true;
803     }
805     /* updated the user */
806     Csf_networkUpdate(restarted, pStartedInfo);
808     /* Start the tracking clock */
809     Csf_setTrackingClock(TRACKING_DELAY_TIME);
812 /*!
813  * @brief      Device Joining callback from the CLLC module (ref.
814  *             Cllc_deviceJoiningFp_t in cllc.h).  This function basically
815  *             gives permission that the device can join with the return
816  *             value.
817  *
818  * @param      pDevInfo - device information
819  * @param      capInfo - device's capability information
820  *
821  * @return     ApiMac_assocStatus_t
822  */
823 static ApiMac_assocStatus_t cllcDeviceJoiningCB(
824                 ApiMac_deviceDescriptor_t *pDevInfo,
825                 ApiMac_capabilityInfo_t *pCapInfo)
827     ApiMac_assocStatus_t status;
829     /* Make sure the device is in our PAN */
830     if(pDevInfo->panID == devicePanId)
831     {
832         /* Update the user that a device is joining */
833         status = Csf_deviceUpdate(pDevInfo, pCapInfo);
834         if(status==ApiMac_assocStatus_success)
835         {
836 #ifdef FEATURE_MAC_SECURITY
837             /* Add device to security device table */
838             Cllc_addSecDevice(pDevInfo->panID,
839                               pDevInfo->shortAddress,
840                               &pDevInfo->extAddress, 0);
841 #endif /* FEATURE_MAC_SECURITY */
843             Util_setEvent(&Collector_events, COLLECTOR_CONFIG_EVT);
844         }
845     }
846     else
847     {
848         status = ApiMac_assocStatus_panAccessDenied;
849     }
850     return (status);
853 /*!
854  * @brief     CLLC State Changed callback.
855  *
856  * @param     state - CLLC new state
857  */
858 static void cllcStateChangedCB(Cllc_states_t state)
860     /* Save the state */
861     cllcState = state;
863     /* Notify the user interface */
864     Csf_stateChangeUpdate(cllcState);
867 /*!
868  * @brief      MAC Data Confirm callback.
869  *
870  * @param      pDataCnf - pointer to the data confirm information
871  */
872 static void dataCnfCB(ApiMac_mcpsDataCnf_t *pDataCnf)
874     /* Record statistics */
875     if(pDataCnf->status == ApiMac_status_channelAccessFailure)
876     {
877         Collector_statistics.channelAccessFailures++;
878     }
879     else if(pDataCnf->status == ApiMac_status_noAck)
880     {
881         Collector_statistics.ackFailures++;
882     }
883     else if(pDataCnf->status == ApiMac_status_transactionExpired)
884     {
885         Collector_statistics.txTransactionExpired++;
886     }
887     else if(pDataCnf->status == ApiMac_status_transactionOverflow)
888     {
889         Collector_statistics.txTransactionOverflow++;
890     }
891     else if(pDataCnf->status == ApiMac_status_success)
892     {
893         Csf_updateFrameCounter(NULL, pDataCnf->frameCntr);
894     }
895     else if(pDataCnf->status != ApiMac_status_success)
896     {
897         Collector_statistics.otherTxFailures++;
898     }
900     /* Make sure the message came from the app */
901     if(pDataCnf->msduHandle & APP_MARKER_MSDU_HANDLE)
902     {
903         /* What message type was the original request? */
904         if(pDataCnf->msduHandle & APP_CONFIG_MSDU_HANDLE)
905         {
906             /* Config Request */
907             Cllc_associated_devices_t *pDev;
908             pDev = findDeviceStatusBit(ASSOC_CONFIG_MASK, ASSOC_CONFIG_SENT);
909             if(pDev != NULL)
910             {
911                 if(pDataCnf->status != ApiMac_status_success)
912                 {
913                     /* Try to send again */
914                     pDev->status &= ~ASSOC_CONFIG_SENT;
915                     Csf_setConfigClock(CONFIG_DELAY);
916                 }
917                 else
918                 {
919                     pDev->status |= ASSOC_CONFIG_SENT;
920                     pDev->status |= ASSOC_CONFIG_RSP;
921                     pDev->status |= CLLC_ASSOC_STATUS_ALIVE;
922                     Csf_setConfigClock(CONFIG_RESPONSE_DELAY);
923                 }
924             }
926             /* Update stats */
927             if(pDataCnf->status == ApiMac_status_success)
928             {
929                 Collector_statistics.configReqRequestSent++;
930             }
931         }
932         else if(pDataCnf->msduHandle & APP_BROADCAST_MSDU_HANDLE)
933         {
934             if(pDataCnf->status == ApiMac_status_success)
935             {
936                 Collector_statistics.broadcastMsgSentCnt++;
937             }
938         }
939         else
940         {
941             /* Tracking Request */
942             Cllc_associated_devices_t *pDev;
943             pDev = findDeviceStatusBit(ASSOC_TRACKING_SENT,
944                                        ASSOC_TRACKING_SENT);
945             if(pDev != NULL)
946             {
947                 if(pDataCnf->status == ApiMac_status_success)
948                 {
949                     /* Make sure the retry is clear */
950                     pDev->status &= ~ASSOC_TRACKING_RETRY;
951                 }
952                 else
953                 {
954                     if(pDev->status & ASSOC_TRACKING_RETRY)
955                     {
956                         /* We already tried to resend */
957                         pDev->status &= ~ASSOC_TRACKING_RETRY;
958                         pDev->status |= ASSOC_TRACKING_ERROR;
959                     }
960                     else
961                     {
962                         /* Go ahead and retry */
963                         pDev->status |= ASSOC_TRACKING_RETRY;
964                     }
966                     pDev->status &= ~ASSOC_TRACKING_SENT;
968                     /* Try to send again or another */
969                     Csf_setTrackingClock(TRACKING_CNF_DELAY_TIME);
970                 }
971             }
973             /* Update stats */
974             if(pDataCnf->status == ApiMac_status_success)
975             {
976                 Collector_statistics.trackingReqRequestSent++;
977             }
978         }
979     }
982 /*!
983  * @brief      MAC Data Indication callback.
984  *
985  * @param      pDataInd - pointer to the data indication information
986  */
987 static void dataIndCB(ApiMac_mcpsDataInd_t *pDataInd)
989     int i;
991     if((pDataInd != NULL) && (pDataInd->msdu.p != NULL)
992        && (pDataInd->msdu.len > 0))
993     {
994       Smsgs_cmdIds_t cmdId = (Smsgs_cmdIds_t)*(pDataInd->msdu.p);
996 #ifdef FEATURE_MAC_SECURITY
997         if(Cllc_securityCheck(&(pDataInd->sec)) == false)
998         {
999             /* Reject the message */
1000             return;
1001         }
1002 #endif /* FEATURE_MAC_SECURITY */
1004         if(pDataInd->srcAddr.addrMode == ApiMac_addrType_extended)
1005         {
1006             uint16_t shortAddr = Csf_getDeviceShort(
1007                             &pDataInd->srcAddr.addr.extAddr);
1008             if(shortAddr != CSF_INVALID_SHORT_ADDR)
1009             {
1010                 /* Switch to the short address for internal tracking */
1011                 pDataInd->srcAddr.addrMode = ApiMac_addrType_short;
1012                 pDataInd->srcAddr.addr.shortAddr = shortAddr;
1014                 LOG_printf(LOG_DBG_COLLECTOR_RAW,"Sensor MSG Short: 0x%04x\
1015                     Extended: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n Data Len: %d Data: ",
1016                     shortAddr,
1017                     pDataInd->srcAddr.addr.extAddr[7],
1018                     pDataInd->srcAddr.addr.extAddr[6],
1019                     pDataInd->srcAddr.addr.extAddr[5],
1020                     pDataInd->srcAddr.addr.extAddr[4],
1021                     pDataInd->srcAddr.addr.extAddr[3],
1022                     pDataInd->srcAddr.addr.extAddr[2],
1023                     pDataInd->srcAddr.addr.extAddr[1],
1024                     pDataInd->srcAddr.addr.extAddr[0], pDataInd->msdu.len);
1026                 for (i = 0; i < pDataInd->msdu.len; i++)
1027                 {
1028                   LOG_printf(LOG_DBG_COLLECTOR_RAW, "%02X ", pDataInd->msdu.p[i]);
1029                 }
1030                 LOG_printf(LOG_DBG_COLLECTOR_RAW, "\n");
1031             }
1032             else
1033             {
1034                 /* Can't accept the message - ignore it */
1035                 return;
1036             }
1037         }
1038         /* Log using short address */
1039         else {
1040             LOG_printf(LOG_DBG_COLLECTOR_RAW,"Sensor MSG Short: 0x%04x Data Len: %d Data: ",
1041              pDataInd->srcAddr.addr.shortAddr, pDataInd->msdu.len);
1043             for (i = 0; i < pDataInd->msdu.len; i++)
1044             {
1045               LOG_printf(LOG_DBG_COLLECTOR_RAW, "%02X ", pDataInd->msdu.p[i]);
1046             }
1047             LOG_printf(LOG_DBG_COLLECTOR_RAW, "\n");
1048         }
1050         switch(cmdId)
1051         {
1052             case Smsgs_cmdIds_configRsp:
1053 #ifndef PROCESS_JS
1054                 processConfigResponse(pDataInd);
1055 #else
1056                 Collector_statistics.configResponseReceived++;
1057                 Cllc_associated_devices_t *pDev = findDevice(&pDataInd->srcAddr);
1058                 if (pDev != NULL)
1059                 {
1060                     /* Clear the sent flag and set the response flag */
1061                     pDev->status &= ~ASSOC_CONFIG_SENT;
1062                     pDev->status |= ASSOC_CONFIG_RSP;
1063                 }
1064                 Util_setEvent(&Collector_events, COLLECTOR_CONFIG_EVT);
1065                 Csf_deviceRawDataUpdate(pDataInd);
1066 #endif
1067                 break;
1069             case Smsgs_cmdIds_trackingRsp:
1070                 processTrackingResponse(pDataInd);
1071                 break;
1073             case Smsgs_cmdIds_toggleLedRsp:
1074                 processToggleLedResponse(pDataInd);
1075                 break;
1077             case Smsgs_cmdIds_sensorData:
1078 #ifndef PROCESS_JS
1079                 processSensorData(pDataInd);
1080 #else
1081                 Collector_statistics.sensorMessagesReceived++;
1082                 processDataRetry(&(pDataInd->srcAddr));
1083                 Csf_deviceRawDataUpdate(pDataInd);
1084 #endif
1085                 break;
1087             case Smsgs_cmdIds_rampdata:
1088                 Collector_statistics.sensorMessagesReceived++;
1089                 break;
1091             case Smsgs_cmdIds_oad:
1092                 processOadData(pDataInd);
1093                 break;
1095             default:
1096                 /* Should not receive other messages */
1097 #ifdef PROCESS_JS
1098                 Csf_deviceRawDataUpdate(pDataInd);
1099 #endif
1100                 break;
1101         }
1102     }
1105 /*!
1106  * @brief      Process the start event
1107  */
1108 static void processStartEvent(void)
1110     Llc_netInfo_t netInfo;
1111     uint32_t frameCounter = 0;
1113     Csf_getFrameCounter(NULL, &frameCounter);
1114     /* See if there is existing network information */
1115     if(Csf_getNetworkInformation(&netInfo))
1116     {
1117         uint16_t numDevices = 0;
1119 #ifdef FEATURE_MAC_SECURITY
1120         /* Initialize the MAC Security */
1121         Cllc_securityInit(frameCounter);
1122 #endif /* FEATURE_MAC_SECURITY */
1124         numDevices = Csf_getNumDeviceListEntries();
1125         /* Restore with the network and device information */
1126         Cllc_restoreNetwork(&netInfo, (uint8_t)numDevices, NULL);
1128         restarted = true;
1129     }
1130     else
1131     {
1132         restarted = false;
1134 #ifdef FEATURE_MAC_SECURITY
1135         /* Initialize the MAC Security */
1136         Cllc_securityInit(frameCounter);
1137 #endif /* FEATURE_MAC_SECURITY */
1139         /* Start a new netork */
1140         Cllc_startNetwork();
1141     }
1144 /*!
1145  * @brief      Process the Config Response message.
1146  *
1147  * @param      pDataInd - pointer to the data indication information
1148  */
1149 static void processConfigResponse(ApiMac_mcpsDataInd_t *pDataInd)
1151     /* Make sure the message is the correct size */
1152     if(pDataInd->msdu.len == SMSGS_CONFIG_RESPONSE_MSG_LENGTH)
1153     {
1154         Cllc_associated_devices_t *pDev;
1155         Smsgs_configRspMsg_t configRsp;
1156         uint8_t *pBuf = pDataInd->msdu.p;
1158         /* Parse the message */
1159         configRsp.cmdId = (Smsgs_cmdIds_t)*pBuf++;
1161         configRsp.status = (Smsgs_statusValues_t)Util_buildUint16(pBuf[0],
1162                                                                   pBuf[1]);
1163         pBuf += 2;
1165         configRsp.frameControl = Util_buildUint16(pBuf[0], pBuf[1]);
1166         pBuf += 2;
1168         configRsp.reportingInterval = Util_buildUint32(pBuf[0], pBuf[1],
1169                                                        pBuf[2],
1170                                                        pBuf[3]);
1171         pBuf += 4;
1173         configRsp.pollingInterval = Util_buildUint32(pBuf[0], pBuf[1], pBuf[2],
1174                                                      pBuf[3]);
1175         pDev = findDevice(&pDataInd->srcAddr);
1176         if(pDev != NULL)
1177         {
1178             /* Clear the sent flag and set the response flag */
1179             pDev->status &= ~ASSOC_CONFIG_SENT;
1180             pDev->status |= ASSOC_CONFIG_RSP;
1181         }
1182         /* Report the config response */
1183         Csf_deviceConfigUpdate(&pDataInd->srcAddr, pDataInd->rssi,
1184                                &configRsp);
1186         Util_setEvent(&Collector_events, COLLECTOR_CONFIG_EVT);
1188         Collector_statistics.configResponseReceived++;
1189     }
1192 /*!
1193  * @brief      Process the Tracking Response message.
1194  *
1195  * @param      pDataInd - pointer to the data indication information
1196  */
1197 static void processTrackingResponse(ApiMac_mcpsDataInd_t *pDataInd)
1199     /* Make sure the message is the correct size */
1200     if(pDataInd->msdu.len == SMSGS_TRACKING_RESPONSE_MSG_LENGTH)
1201     {
1202         Cllc_associated_devices_t *pDev;
1204         pDev = findDevice(&pDataInd->srcAddr);
1205         if(pDev != NULL)
1206         {
1207             if(pDev->status & ASSOC_TRACKING_SENT)
1208             {
1209                 pDev->status &= ~ASSOC_TRACKING_SENT;
1210                 pDev->status |= ASSOC_TRACKING_RSP;
1212                 /* Setup for next tracking */
1213                 Csf_setTrackingClock( TRACKING_DELAY_TIME);
1215                 /* Retry config request */
1216                 processConfigRetry();
1217             }
1218         }
1220         /* Update stats */
1221         Collector_statistics.trackingResponseReceived++;
1222     }
1225 /*!
1226  * @brief      Process the Toggle Led Response message.
1227  *
1228  * @param      pDataInd - pointer to the data indication information
1229  */
1230 static void processToggleLedResponse(ApiMac_mcpsDataInd_t *pDataInd)
1232     /* Make sure the message is the correct size */
1233     if(pDataInd->msdu.len == SMSGS_TOGGLE_LED_RESPONSE_MSG_LEN)
1234     {
1235         bool ledState;
1236         uint8_t *pBuf = pDataInd->msdu.p;
1238         /* Skip past the command ID */
1239         pBuf++;
1241         ledState = (bool)*pBuf;
1243         /* Notify the user */
1244         Csf_toggleResponseReceived(&pDataInd->srcAddr, ledState);
1245     }
1248 /*!
1249  * @brief      Process the Sensor Data message.
1250  *
1251  * @param      pDataInd - pointer to the data indication information
1252  */
1253 static void processSensorData(ApiMac_mcpsDataInd_t *pDataInd)
1255     Smsgs_sensorMsg_t sensorData;
1256     uint8_t *pBuf = pDataInd->msdu.p;
1258     memset(&sensorData, 0, sizeof(Smsgs_sensorMsg_t));
1260     /* Parse the message */
1261     sensorData.cmdId = (Smsgs_cmdIds_t)*pBuf++;
1263     memcpy(sensorData.extAddress, pBuf, SMGS_SENSOR_EXTADDR_LEN);
1264     pBuf += SMGS_SENSOR_EXTADDR_LEN;
1266     sensorData.frameControl = Util_buildUint16(pBuf[0], pBuf[1]);
1267     pBuf += 2;
1269     /* Parse data in order of frameControl mask, starting with LSB */
1270     if(sensorData.frameControl & Smsgs_dataFields_tempSensor)
1271     {
1272         sensorData.tempSensor.ambienceTemp = Util_buildUint16(pBuf[0], pBuf[1]);
1273         pBuf += 2;
1274         sensorData.tempSensor.objectTemp = Util_buildUint16(pBuf[0], pBuf[1]);
1275         pBuf += 2;
1276     }
1278     if(sensorData.frameControl & Smsgs_dataFields_lightSensor)
1279     {
1280         sensorData.lightSensor.rawData = Util_buildUint16(pBuf[0], pBuf[1]);
1281         pBuf += 2;
1282     }
1284     if(sensorData.frameControl & Smsgs_dataFields_humiditySensor)
1285     {
1286         sensorData.humiditySensor.temp = Util_buildUint16(pBuf[0], pBuf[1]);
1287         pBuf += 2;
1288         sensorData.humiditySensor.humidity = Util_buildUint16(pBuf[0], pBuf[1]);
1289         pBuf += 2;
1290     }
1292     if(sensorData.frameControl & Smsgs_dataFields_msgStats)
1293     {
1294         sensorData.msgStats.joinAttempts = Util_buildUint16(pBuf[0], pBuf[1]);
1295         pBuf += 2;
1296         sensorData.msgStats.joinFails = Util_buildUint16(pBuf[0], pBuf[1]);
1297         pBuf += 2;
1298         sensorData.msgStats.msgsAttempted = Util_buildUint16(pBuf[0], pBuf[1]);
1299         pBuf += 2;
1300         sensorData.msgStats.msgsSent = Util_buildUint16(pBuf[0], pBuf[1]);
1301         pBuf += 2;
1302         sensorData.msgStats.trackingRequests = Util_buildUint16(pBuf[0],
1303                                                                 pBuf[1]);
1304         pBuf += 2;
1305         sensorData.msgStats.trackingResponseAttempts = Util_buildUint16(
1306                         pBuf[0],
1307                         pBuf[1]);
1308         pBuf += 2;
1309         sensorData.msgStats.trackingResponseSent = Util_buildUint16(pBuf[0],
1310                                                                     pBuf[1]);
1311         pBuf += 2;
1312         sensorData.msgStats.configRequests = Util_buildUint16(pBuf[0],
1313                                                               pBuf[1]);
1314         pBuf += 2;
1315         sensorData.msgStats.configResponseAttempts = Util_buildUint16(
1316                         pBuf[0],
1317                         pBuf[1]);
1318         pBuf += 2;
1319         sensorData.msgStats.configResponseSent = Util_buildUint16(pBuf[0],
1320                                                                   pBuf[1]);
1321         pBuf += 2;
1322         sensorData.msgStats.channelAccessFailures = Util_buildUint16(pBuf[0],
1323                                                                      pBuf[1]);
1324         pBuf += 2;
1325         sensorData.msgStats.macAckFailures = Util_buildUint16(pBuf[0], pBuf[1]);
1326         pBuf += 2;
1327         sensorData.msgStats.otherDataRequestFailures = Util_buildUint16(
1328                         pBuf[0],
1329                         pBuf[1]);
1330         pBuf += 2;
1331         sensorData.msgStats.syncLossIndications = Util_buildUint16(pBuf[0],
1332                                                                    pBuf[1]);
1333         pBuf += 2;
1334         sensorData.msgStats.rxDecryptFailures = Util_buildUint16(pBuf[0],
1335                                                                  pBuf[1]);
1336         pBuf += 2;
1337         sensorData.msgStats.txEncryptFailures = Util_buildUint16(pBuf[0],
1338                                                                  pBuf[1]);
1339         pBuf += 2;
1340         sensorData.msgStats.resetCount = Util_buildUint16(pBuf[0],
1341                                                           pBuf[1]);
1342         pBuf += 2;
1343         sensorData.msgStats.lastResetReason = Util_buildUint16(pBuf[0],
1344                                                                pBuf[1]);
1345         pBuf += 2;
1346         sensorData.msgStats.joinTime = Util_buildUint16(pBuf[0],
1347                                                         pBuf[1]);
1348         pBuf += 2;
1349         sensorData.msgStats.interimDelay = Util_buildUint16(pBuf[0],
1350                                                             pBuf[1]);
1351         pBuf += 2;
1352         sensorData.msgStats.numBroadcastMsgRcvd = Util_buildUint16(pBuf[0],
1353                                                                    pBuf[1]);
1354         pBuf += 2;
1355         sensorData.msgStats.numBroadcastMsglost = Util_buildUint16(pBuf[0],
1356                                                                    pBuf[1]);
1357         pBuf += 2;
1358     }
1360     if(sensorData.frameControl & Smsgs_dataFields_configSettings)
1361     {
1362         sensorData.configSettings.reportingInterval = Util_buildUint32(pBuf[0],
1363                                                                        pBuf[1],
1364                                                                        pBuf[2],
1365                                                                        pBuf[3]);
1366         pBuf += 4;
1367         sensorData.configSettings.pollingInterval = Util_buildUint32(pBuf[0],
1368                                                                      pBuf[1],
1369                                                                      pBuf[2],
1370                                                                      pBuf[3]);
1371     }
1373     Collector_statistics.sensorMessagesReceived++;
1375     /* Report the sensor data */
1376     Csf_deviceSensorDataUpdate(&pDataInd->srcAddr, pDataInd->rssi,
1377                                &sensorData);
1379     processDataRetry(&(pDataInd->srcAddr));
1382 /*!
1383  * @brief      Process the OAD Data message.
1384  *
1385  * @param      pDataInd - pointer to the data indication information
1386  */
1387 static void processOadData(ApiMac_mcpsDataInd_t *pDataInd)
1389     //Index past the Smsgs_cmdId
1390     OADProtocol_ParseIncoming((void*) &(pDataInd->srcAddr), &(pDataInd->msdu.p[1]));
1392     Collector_statistics.sensorMessagesReceived++;
1395 /*!
1396  * @brief      Find the associated device table entry matching pAddr.
1397  *
1398  * @param      pAddr - pointer to device's address
1399  *
1400  * @return     pointer to the associated device table entry,
1401  *             NULL if not found.
1402  */
1403 static Cllc_associated_devices_t *findDevice(ApiMac_sAddr_t *pAddr)
1405     int x;
1406     Cllc_associated_devices_t *pItem = NULL;
1408     /* Check for invalid parameters */
1409     if((pAddr == NULL) || (pAddr->addrMode == ApiMac_addrType_none))
1410     {
1411         return (NULL);
1412     }
1414     for(x = 0; x < CONFIG_MAX_DEVICES; x++)
1415     {
1416         /* Make sure the entry is valid. */
1417         if(Cllc_associatedDevList[x].shortAddr != CSF_INVALID_SHORT_ADDR)
1418         {
1419             if(pAddr->addrMode == ApiMac_addrType_short)
1420             {
1421                 if(pAddr->addr.shortAddr == Cllc_associatedDevList[x].shortAddr)
1422                 {
1423                     pItem = &Cllc_associatedDevList[x];
1424                     break;
1425                 }
1426             }
1427         }
1428     }
1430     return (pItem);
1433 /*!
1434  * @brief      Find the associated device table entry matching status bit.
1435  *
1436  * @param      statusBit - what status bit to find
1437  *
1438  * @return     pointer to the associated device table entry,
1439  *             NULL if not found.
1440  */
1441 static Cllc_associated_devices_t *findDeviceStatusBit(uint16_t mask, uint16_t statusBit)
1443     int x;
1444     Cllc_associated_devices_t *pItem = NULL;
1446     for(x = 0; x < CONFIG_MAX_DEVICES; x++)
1447     {
1448         /* Make sure the entry is valid. */
1449         if(Cllc_associatedDevList[x].shortAddr != CSF_INVALID_SHORT_ADDR)
1450         {
1451             if((Cllc_associatedDevList[x].status & mask) == statusBit)
1452             {
1453                 pItem = &Cllc_associatedDevList[x];
1454                 break;
1455             }
1456         }
1457     }
1459     return (pItem);
1462 /*!
1463  * @brief      Get the next MSDU Handle
1464  *             <BR>
1465  *             The MSDU handle has 3 parts:<BR>
1466  *             - The MSBit(7), when set means the the application sent the message
1467  *             - Bit 6, when set means that the app message is a config request
1468  *             - Bits 0-5, used as a message counter that rolls over.
1469  *
1470  * @param      msgType - message command id needed
1471  *
1472  * @return     msdu Handle
1473  */
1474 static uint8_t getMsduHandle(Smsgs_cmdIds_t msgType)
1476     uint8_t msduHandle = deviceTxMsduHandle;
1478     /* Increment for the next msdu handle, or roll over */
1479     if(deviceTxMsduHandle >= MSDU_HANDLE_MAX)
1480     {
1481         deviceTxMsduHandle = 0;
1482     }
1483     else
1484     {
1485         deviceTxMsduHandle++;
1486     }
1488     /* Add the App specific bit */
1489     msduHandle |= APP_MARKER_MSDU_HANDLE;
1491     /* Add the message type bit */
1492     if(msgType == Smsgs_cmdIds_configReq)
1493     {
1494         msduHandle |= APP_CONFIG_MSDU_HANDLE;
1495     }
1496     else if(msgType == Smgs_cmdIds_broadcastCtrlMsg)
1497     {
1498         msduHandle |= APP_BROADCAST_MSDU_HANDLE;
1499     }
1501     return (msduHandle);
1504 /*!
1505  * @brief      Send MAC data request
1506  *
1507  * @param      type - message type
1508  * @param      dstShortAddr - destination short address
1509  * @param      rxOnIdle - true if not a sleepy device
1510  * @param      len - length of payload
1511  * @param      pData - pointer to the buffer
1512  *
1513  * @return  true if sent, false if not
1514  */
1515 static bool sendMsg(Smsgs_cmdIds_t type, uint16_t dstShortAddr, bool rxOnIdle,
1516                     uint16_t len,
1517                     uint8_t *pData)
1519     ApiMac_mcpsDataReq_t dataReq;
1521     /* Fill the data request field */
1522     memset(&dataReq, 0, sizeof(ApiMac_mcpsDataReq_t));
1524     dataReq.dstAddr.addrMode = ApiMac_addrType_short;
1525     dataReq.dstAddr.addr.shortAddr = dstShortAddr;
1526     dataReq.srcAddrMode = ApiMac_addrType_short;
1528     if(fhEnabled && rxOnIdle)
1529     {
1530         Llc_deviceListItem_t item;
1532         if(Csf_getDevice(&(dataReq.dstAddr), &item))
1533         {
1534             /* Switch to the long address */
1535             dataReq.dstAddr.addrMode = ApiMac_addrType_extended;
1536             memcpy(&dataReq.dstAddr.addr.extAddr, &item.devInfo.extAddress,
1537                    (APIMAC_SADDR_EXT_LEN));
1538             dataReq.srcAddrMode = ApiMac_addrType_extended;
1539         }
1540         else
1541         {
1542             /* Can't send the message */
1543             return (false);
1544         }
1545     }
1547     dataReq.dstPanId = devicePanId;
1549     dataReq.msduHandle = getMsduHandle(type);
1551     dataReq.txOptions.ack = true;
1552     if(rxOnIdle == false)
1553     {
1554         dataReq.txOptions.indirect = true;
1555     }
1557     dataReq.msdu.len = len;
1558     dataReq.msdu.p = pData;
1560 #ifdef FEATURE_MAC_SECURITY
1561     /* Fill in the appropriate security fields */
1562     Cllc_securityFill(&dataReq.sec);
1563 #endif /* FEATURE_MAC_SECURITY */
1565     /* Send the message */
1566     if(ApiMac_mcpsDataReq(&dataReq) != ApiMac_status_success)
1567     {
1568         /*  Transaction overflow occurred */
1569         return (false);
1570     }
1571     else
1572     {
1573         return (true);
1574     }
1577 /*!
1578  * @brief      Send MAC broadcast data request. Only supported in FH mode.
1579  *
1580  * @param      type - message type
1581  * @param      len - length of payload
1582  * @param      pData - pointer to the buffer
1583  */
1584 static void sendBroadcastMsg(Smsgs_cmdIds_t type, uint16_t len,
1585                     uint8_t *pData)
1587     ApiMac_mcpsDataReq_t dataReq;
1589     /* Only supported for FH mode */
1590     if(!fhEnabled)
1591     {
1592         return;
1593     }
1594     /* Fill the data request field */
1595     memset(&dataReq, 0, sizeof(ApiMac_mcpsDataReq_t));
1597     dataReq.dstAddr.addrMode = ApiMac_addrType_none;
1598     dataReq.srcAddrMode = ApiMac_addrType_short;
1600     dataReq.dstPanId = devicePanId;
1602     dataReq.msduHandle = getMsduHandle(type);
1604     dataReq.txOptions.ack = false;
1605     dataReq.txOptions.indirect = false;
1608     dataReq.msdu.len = len;
1609     dataReq.msdu.p = pData;
1611 #ifdef FEATURE_MAC_SECURITY
1612     /* Fill in the appropriate security fields */
1613     Cllc_securityFill(&dataReq.sec);
1614 #endif /* FEATURE_MAC_SECURITY */
1616     /* Send the message */
1617     ApiMac_mcpsDataReq(&dataReq);
1620 /*!
1621  * @brief      Generate Config Requests for all associate devices
1622  *             that need one.
1623  */
1624 static void generateConfigRequests(void)
1626     int x;
1628     if(CERTIFICATION_TEST_MODE)
1629     {
1630         /* In Certification mode only back to back uplink
1631          * data traffic shall be supported*/
1632         return;
1633     }
1635     /* Clear any timed out transactions */
1636     for(x = 0; x < CONFIG_MAX_DEVICES; x++)
1637     {
1638         if((Cllc_associatedDevList[x].shortAddr != CSF_INVALID_SHORT_ADDR)
1639            && (Cllc_associatedDevList[x].status & CLLC_ASSOC_STATUS_ALIVE))
1640         {
1641             if((Cllc_associatedDevList[x].status &
1642                (ASSOC_CONFIG_SENT | ASSOC_CONFIG_RSP))
1643                == (ASSOC_CONFIG_SENT | ASSOC_CONFIG_RSP))
1644             {
1645                 Cllc_associatedDevList[x].status &= ~(ASSOC_CONFIG_SENT
1646                                 | ASSOC_CONFIG_RSP);
1647             }
1648         }
1649     }
1651     /* Make sure we are only sending one config request at a time */
1652     if(findDeviceStatusBit(ASSOC_CONFIG_MASK, ASSOC_CONFIG_SENT) == NULL)
1653     {
1654         /* Run through all of the devices */
1655         for(x = 0; x < CONFIG_MAX_DEVICES; x++)
1656         {
1657             /* Make sure the entry is valid. */
1658             if((Cllc_associatedDevList[x].shortAddr != CSF_INVALID_SHORT_ADDR)
1659                && (Cllc_associatedDevList[x].status & CLLC_ASSOC_STATUS_ALIVE))
1660             {
1661                 uint16_t status = Cllc_associatedDevList[x].status;
1663                 /*
1664                  Has the device been sent or already received a config request?
1665                  */
1666                 if(((status & (ASSOC_CONFIG_SENT | ASSOC_CONFIG_RSP)) == 0))
1667                 {
1668                     ApiMac_sAddr_t dstAddr;
1669                     Collector_status_t stat;
1671                     /* Set up the destination address */
1672                     dstAddr.addrMode = ApiMac_addrType_short;
1673                     dstAddr.addr.shortAddr =
1674                         Cllc_associatedDevList[x].shortAddr;
1676                     /* Send the Config Request */
1677                     stat = Collector_sendConfigRequest(
1678                                     &dstAddr, (CONFIG_FRAME_CONTROL),
1679                                     (CONFIG_REPORTING_INTERVAL),
1680                                     (CONFIG_POLLING_INTERVAL));
1681                     if(stat == Collector_status_success)
1682                     {
1683                         /*
1684                          Mark as the message has been sent and expecting a response
1685                          */
1686                         Cllc_associatedDevList[x].status |= ASSOC_CONFIG_SENT;
1687                         Cllc_associatedDevList[x].status &= ~ASSOC_CONFIG_RSP;
1688                     }
1690                     /* Only do one at a time */
1691                     break;
1692                 }
1693             }
1694         }
1695     }
1699 /*!
1700  * @brief      Generate Config Requests for all associate devices
1701  *             that need one.
1702  */
1703 static void generateTrackingRequests(void)
1705     int x;
1707     /* Run through all of the devices, looking for previous activity */
1708     for(x = 0; x < CONFIG_MAX_DEVICES; x++)
1709     {
1710         if(CERTIFICATION_TEST_MODE)
1711         {
1712             /* In Certification mode only back to back uplink
1713              * data traffic shall be supported*/
1714             return;
1715         }
1716         /* Make sure the entry is valid. */
1717         if((Cllc_associatedDevList[x].shortAddr != CSF_INVALID_SHORT_ADDR)
1718              && (Cllc_associatedDevList[x].status & CLLC_ASSOC_STATUS_ALIVE))
1719         {
1720             uint16_t status = Cllc_associatedDevList[x].status;
1722             /*
1723              Has the device been sent a tracking request or received a
1724              tracking response?
1725              */
1726             if(status & ASSOC_TRACKING_RETRY)
1727             {
1728                 sendTrackingRequest(&Cllc_associatedDevList[x]);
1729                 return;
1730             }
1731             else if((status & (ASSOC_TRACKING_SENT | ASSOC_TRACKING_RSP
1732                                | ASSOC_TRACKING_ERROR)))
1733             {
1734                 Cllc_associated_devices_t *pDev = NULL;
1735                 int y;
1737                 if(status & (ASSOC_TRACKING_SENT | ASSOC_TRACKING_ERROR))
1738                 {
1739                     ApiMac_deviceDescriptor_t devInfo;
1740                     Llc_deviceListItem_t item;
1741                     ApiMac_sAddr_t devAddr;
1743                     /*
1744                      Timeout occured, notify the user that the tracking
1745                      failed.
1746                      */
1747                     memset(&devInfo, 0, sizeof(ApiMac_deviceDescriptor_t));
1749                     devAddr.addrMode = ApiMac_addrType_short;
1750                     devAddr.addr.shortAddr =
1751                         Cllc_associatedDevList[x].shortAddr;
1753                     if(Csf_getDevice(&devAddr, &item))
1754                     {
1755                         memcpy(&devInfo.extAddress,
1756                                &item.devInfo.extAddress,
1757                                sizeof(ApiMac_sAddrExt_t));
1758                     }
1759                     devInfo.shortAddress = Cllc_associatedDevList[x].shortAddr;
1760                     devInfo.panID = devicePanId;
1761                     Csf_deviceNotActiveUpdate(&devInfo,
1762                         ((status & ASSOC_TRACKING_SENT) ? true : false));
1764                     /* Not responding, so remove the alive marker */
1765                     Cllc_associatedDevList[x].status
1766                             &= ~(CLLC_ASSOC_STATUS_ALIVE
1767                                 | ASSOC_CONFIG_SENT | ASSOC_CONFIG_RSP);
1768                 }
1770                 /* Clear the tracking bits */
1771                 Cllc_associatedDevList[x].status  &= ~(ASSOC_TRACKING_ERROR
1772                                 | ASSOC_TRACKING_SENT | ASSOC_TRACKING_RSP);
1774                 /* Find the next valid device */
1775                 y = x;
1776                 while(pDev == NULL)
1777                 {
1778                     /* Check for rollover */
1779                     if(y == (CONFIG_MAX_DEVICES-1))
1780                     {
1781                         /* Move to the beginning */
1782                         y = 0;
1783                     }
1784                     else
1785                     {
1786                         /* Move the the next device */
1787                         y++;
1788                     }
1790                     if(y == x)
1791                     {
1792                         /* We've come back around */
1793                         break;
1794                     }
1796                     /*
1797                      Is the entry valid and active */
1798                     if((Cllc_associatedDevList[y].shortAddr
1799                                     != CSF_INVALID_SHORT_ADDR)
1800                          && (Cllc_associatedDevList[y].status
1801                                    & CLLC_ASSOC_STATUS_ALIVE))
1802                     {
1803                         pDev = &Cllc_associatedDevList[y];
1804                     }
1805                 }
1807                 if(pDev == NULL)
1808                 {
1809                     /* Another device wasn't found, send to same device */
1810                     pDev = &Cllc_associatedDevList[x];
1811                 }
1813                 sendTrackingRequest(pDev);
1815                 /* Only do one at a time */
1816                 return;
1817             }
1818         }
1819     }
1821     /* If no activity found, find the first active device */
1822     for(x = 0; x < CONFIG_MAX_DEVICES; x++)
1823     {
1824         /* Make sure the entry is valid. */
1825         if((Cllc_associatedDevList[x].shortAddr != CSF_INVALID_SHORT_ADDR)
1826               && (Cllc_associatedDevList[x].status & CLLC_ASSOC_STATUS_ALIVE))
1827         {
1828             sendTrackingRequest(&Cllc_associatedDevList[x]);
1829             break;
1830         }
1831     }
1833     if(x == CONFIG_MAX_DEVICES)
1834     {
1835         /* No device found, Setup delay for next tracking message */
1836         Csf_setTrackingClock(TRACKING_DELAY_TIME);
1837     }
1840 /*!
1841  * @brief      Generate Broadcast Cmd Request Message
1842  */
1843 static void generateBroadcastCmd(void)
1845     uint8_t buffer[SMSGS_BROADCAST_CMD_LENGTH];
1846     uint8_t *pBuf = buffer;
1848     /* Build the message */
1849     *pBuf++ = (uint8_t)Smgs_cmdIds_broadcastCtrlMsg;
1850     *pBuf++ = Util_loUint16(Collector_statistics.broadcastMsgSentCnt);
1851     *pBuf++ = Util_hiUint16(Collector_statistics.broadcastMsgSentCnt);
1853     sendBroadcastMsg(Smgs_cmdIds_broadcastCtrlMsg, SMSGS_BROADCAST_CMD_LENGTH,
1854                      buffer);
1857 /*!
1858  * @brief      Generate Tracking Requests for a device
1859  *
1860  * @param      pDev - pointer to the device's associate device table entry
1861  */
1862 static void sendTrackingRequest(Cllc_associated_devices_t *pDev)
1864     uint8_t cmdId = Smsgs_cmdIds_trackingReq;
1866     /* Send the Tracking Request */
1867    if((sendMsg(Smsgs_cmdIds_trackingReq, pDev->shortAddr,
1868             pDev->capInfo.rxOnWhenIdle,
1869             (SMSGS_TRACKING_REQUEST_MSG_LENGTH),
1870             &cmdId)) == true)
1871     {
1872         /* Mark as Tracking Request sent */
1873         pDev->status |= ASSOC_TRACKING_SENT;
1875         /* Setup Timeout for response */
1876         Csf_setTrackingClock(TRACKING_TIMEOUT_TIME);
1878         /* Update stats */
1879         Collector_statistics.trackingRequestAttempts++;
1880     }
1881     else
1882     {
1883         ApiMac_sAddr_t devAddr;
1884         devAddr.addrMode = ApiMac_addrType_short;
1885         devAddr.addr.shortAddr = pDev->shortAddr;
1886         processDataRetry(&devAddr);
1887     }
1890 /*!
1891  * @brief      Process the MAC Comm Status Indication Callback
1892  *
1893  * @param      pCommStatusInd - Comm Status indication
1894  */
1895 static void commStatusIndCB(ApiMac_mlmeCommStatusInd_t *pCommStatusInd)
1897     if(pCommStatusInd->reason == ApiMac_commStatusReason_assocRsp)
1898     {
1899         if(pCommStatusInd->status != ApiMac_status_success)
1900         {
1901             Cllc_associated_devices_t *pDev;
1903             pDev = findDevice(&pCommStatusInd->dstAddr);
1904             if(pDev)
1905             {
1906                 /* Mark as inactive and clear config and tracking states */
1907                 pDev->status = 0;
1908             }
1909         }
1910     }
1913 /*!
1914  * @brief      Process the MAC Poll Indication Callback
1915  *
1916  * @param      pPollInd - poll indication
1917  */
1918 static void pollIndCB(ApiMac_mlmePollInd_t *pPollInd)
1920     ApiMac_sAddr_t addr;
1922     addr.addrMode = ApiMac_addrType_short;
1923     if (pPollInd->srcAddr.addrMode == ApiMac_addrType_short)
1924     {
1925         addr.addr.shortAddr = pPollInd->srcAddr.addr.shortAddr;
1926     }
1927     else
1928     {
1929         addr.addr.shortAddr = Csf_getDeviceShort(
1930                         &pPollInd->srcAddr.addr.extAddr);
1931     }
1933     processDataRetry(&addr);
1936 /*!
1937  * @brief      Process the disassoc Indication Callback
1938  *
1939  * @param      disassocIndCB - disassoc indication
1940  */
1941 static void disassocIndCB(ApiMac_mlmeDisassociateInd_t *pDisassocInd)
1943     ApiMac_sAddr_t addr;
1945     addr.addrMode = ApiMac_addrType_extended;
1946     memcpy(&addr.addr.extAddr, &pDisassocInd->deviceAddress,
1947                    (APIMAC_SADDR_EXT_LEN));
1949     Csf_deviceDisassocUpdate(&addr);
1952 /*!
1953  * @brief      Process the disassoc cofirmation Callback
1954  *
1955  * @param      disassocCnfCB - disassoc cofirmation
1956  */
1957 static void disassocCnfCB(ApiMac_mlmeDisassociateCnf_t *pDisassocCnf)
1959     Csf_deviceDisassocUpdate(&pDisassocCnf->deviceAddress);
1962 /*!
1963  * @brief      Process retries for config and tracking messages
1964  *
1965  * @param      addr - MAC address structure */
1966 static void processDataRetry(ApiMac_sAddr_t *pAddr)
1968     if(pAddr->addr.shortAddr != CSF_INVALID_SHORT_ADDR)
1969     {
1970         Cllc_associated_devices_t *pItem;
1971         pItem = findDevice(pAddr);
1972         if(pItem)
1973         {
1974             /* Set device status to alive */
1975             pItem->status |= CLLC_ASSOC_STATUS_ALIVE;
1977             /* Check to see if we need to send it a config */
1978             if((pItem->status & (ASSOC_CONFIG_RSP | ASSOC_CONFIG_SENT)) == 0)
1979             {
1980                 processConfigRetry();
1981             }
1982             /* Check to see if we need to send it a tracking message */
1983             if((pItem->status & (ASSOC_TRACKING_SENT| ASSOC_TRACKING_RETRY)) == 0)
1984             {
1985                 /* Make sure we aren't already doing a tracking message */
1986                 if(((Collector_events & COLLECTOR_TRACKING_TIMEOUT_EVT) == 0)
1987                     && (Csf_isTrackingTimerActive() == false)
1988                     && (findDeviceStatusBit(ASSOC_TRACKING_MASK,
1989                                             ASSOC_TRACKING_SENT) == NULL))
1990                 {
1991                     /* Setup for next tracking */
1992                     Csf_setTrackingClock(TRACKING_DELAY_TIME);
1993                 }
1994             }
1995         }
1996     }
1999 /*!
2000  * @brief      Process retries for config messages
2001  */
2002 static void processConfigRetry(void)
2004     /* Retry config request if not already sent */
2005     if(((Collector_events & COLLECTOR_CONFIG_EVT) == 0)
2006         && (Csf_isConfigTimerActive() == false))
2007     {
2008         /* Set config event */
2009         Csf_setConfigClock(CONFIG_DELAY);
2010     }
2013 /*!
2014  * @brief      Process FW version response
2015  */
2016 static void oadFwVersionRspCb(void* pSrcAddr, char *fwVersionStr)
2018     LOG_printf( LOG_DBG_COLLECTOR, "oadFwVersionRspCb from %x\n", ((ApiMac_sAddr_t*)pSrcAddr)->addr.shortAddr);
2019     Csf_deviceSensorFwVerUpdate(((ApiMac_sAddr_t*)pSrcAddr)->addr.shortAddr, fwVersionStr);
2022 /*!
2023  * @brief      Process OAD image identify response
2024  */
2025 static void oadImgIdentifyRspCb(void* pSrcAddr, uint8_t status)
2030 static void oadBlockReqCb(void* pSrcAddr, uint8_t imgId, uint16_t blockNum, uint16_t multiBlockSize)
2032     uint8_t blockBuf[OAD_BLOCK_SIZE] = {0};
2033     int byteRead = 0;
2034     uint32_t oad_file_idx;
2035     FILE *oadFile = NULL;
2037     LOG_printf( LOG_DBG_COLLECTOR, "oadBlockReqCb[%d:%x] from %x\n", imgId, blockNum, ((ApiMac_sAddr_t*)pSrcAddr)->addr.shortAddr);
2039     Csf_deviceSensorOadUpdate( ((ApiMac_sAddr_t*)pSrcAddr)->addr.shortAddr, imgId, blockNum, oadBNumBlocks);
2041     for(oad_file_idx = 0; oad_file_idx < MAX_OAD_FILES; oad_file_idx++)
2042     {
2043         if(oad_file_list[oad_file_idx].oad_file_id == imgId)
2044         {
2045             LOG_printf( LOG_DBG_COLLECTOR, "oadBlockReqCb: openinging %d:%d:%s\n", oad_file_idx,
2046                                     oad_file_list[oad_file_idx].oad_file_id,
2047                                     oad_file_list[oad_file_idx].oad_file);
2049             oadFile = fopen(oad_file_list[oad_file_idx].oad_file, "r");
2051             break;
2052         }
2053     }
2055     if(oadFile != NULL)
2056     {
2057         fseek(oadFile, (blockNum * OAD_BLOCK_SIZE), SEEK_SET);
2058         byteRead = (int) fread(blockBuf, 1, OAD_BLOCK_SIZE, oadFile);
2060         LOG_printf( LOG_DBG_COLLECTOR, "oadBlockReqCb: read %d bytes from position %d of %p\n",
2061                                                     byteRead, (blockNum * OAD_BLOCK_SIZE), oadFile);
2063         if(byteRead == 0)
2064         {
2065             LOG_printf( LOG_ERROR, "oadBlockReqCb: Read 0 Bytes");
2066         }
2068         fclose(oadFile);
2070         OADProtocol_sendOadImgBlockRsp(pSrcAddr, imgId, blockNum, blockBuf);
2071     }
2072     else
2073     {
2074       LOG_printf( LOG_DBG_COLLECTOR, "imgId %d file not found\n", imgId);
2075     }
2078 /*!
2079  * @brief      Radio access function for OAD module to send messages
2080  */
2081 void* oadRadioAccessAllocMsg(uint32_t msgLen)
2083     uint8_t *msgBuffer;
2085     /* allocate buffer for CmdId + message */
2086     msgBuffer = malloc(msgLen + 1);
2088     return msgBuffer + 1;
2091 /*!
2092  * @brief      Radio access function for OAD module to send messages
2093  */
2094 static OADProtocol_Status_t oadRadioAccessPacketSend(void* pDstAddr, uint8_t *pMsg, uint32_t msgLen)
2096     OADProtocol_Status_t status = OADProtocol_Failed;
2097     uint8_t* pMsduPayload;
2098     Cllc_associated_devices_t* pDev;
2100     pDev  = findDevice(pDstAddr);
2102     if( (pDev) && (pMsg) )
2103     {
2104         /* Buffer should have been allocated with oadRadioAccessAllocMsg,
2105          * so 1 byte before the oad msg buffer was allocated for the Smsgs_cmdId
2106          */
2107         pMsduPayload = pMsg - 1;
2108         pMsduPayload[0] = Smsgs_cmdIds_oad;
2110         /* Send the Tracking Request */
2111        if((sendMsg(Smsgs_cmdIds_oad, ((ApiMac_sAddr_t*)pDstAddr)->addr.shortAddr,
2112                 pDev->capInfo.rxOnWhenIdle,
2113                 (msgLen + 1),
2114                 pMsduPayload)) == true)
2115        {
2116            status = OADProtocol_Status_Success;
2117        }
2118     }
2120     if( (pDev) && (pMsg) )
2121     {
2122         /* Free the memory allocated in oadRadioAccessAllocMsg. */
2123         free(pMsg - 1);
2124     }
2126     return status;
2129 /*!
2130  Build and send the buzzer ctrl message to a device.
2132  Public function defined in collector.h
2133  */
2134 Collector_status_t Collector_sendBuzzerCtrlRequest(ApiMac_sAddr_t *pDstAddr)
2136     Collector_status_t status = Collector_status_invalid_state;
2138     /* Are we in the right state? */
2139     if (cllcState >= Cllc_states_started)
2140     {
2141         Llc_deviceListItem_t item;
2143         /* Is the device a known device? */
2144         if (Csf_getDevice(pDstAddr, &item))
2145         {
2146             uint8_t buffer[SMSGS_BUZZER_CTRL_REQUEST_MSG_LEN];
2148             /* Build the message */
2149             buffer[0] = (uint8_t)Smsgs_cmdIds_buzzerCtrlReq;
2151             sendMsg(Smsgs_cmdIds_buzzerCtrlReq, item.devInfo.shortAddress,
2152                     item.capInfo.rxOnWhenIdle,
2153                     SMSGS_BUZZER_CTRL_REQUEST_MSG_LEN,
2154                     buffer);
2156             status = Collector_status_success;
2157         }
2158         else
2159         {
2160             status = Collector_status_deviceNotFound;
2161         }
2162     }
2164     return (status);
2166 /*
2167  *  ========================================
2168  *  Texas Instruments Micro Controller Style
2169  *  ========================================
2170  *  Local Variables:
2171  *  mode: c
2172  *  c-file-style: "bsd"
2173  *  tab-width: 4
2174  *  c-basic-offset: 4
2175  *  indent-tabs-mode: nil
2176  *  End:
2177  *  vim:set  filetype=c tabstop=4 shiftwidth=4 expandtab=true
2178  */