SZS ez430-RF2480 1.0

ZigBee Sensor Network with synchronized time and time-stamped measurements.
nwk.c
Go to the documentation of this file.
1 /*
2  * nwk.c
3  *
4  * Date: 19/06/2014
5  * Author: Fernando Biazi Nascimento
6  * Copyright © 2014 Fernando Biazi Nascimento. All rights reserved.
7  *
8  * License of use and copy on file license.txt
9  *
10  */
11 
20 /*
21  * From "CC2480 Target Board Schematics_1_4.pdf":
22  *
23  * Reference connections:
24  * MSP430 in master mode
25  *
26  * (MSP430 pin number; pin name; config) <-> BUS name <-> (CC2480 pin number; pin name)
27  *
28  * (MSP430 26 P3.7: GPIO ) -> RESET_N -> (CC2480 10 RESETn)
29  *
30  * (MSP430 15 P4.0: GPIO ) -> CFG0 -> (CC2480 11 CFG0) - 1=32KHz crystal installed; 0=not
31  * (MSP430 16 P4.1: GPIO ) -> CFG1 -> (CC2480 12 CFG1) - 1=SPI; 0=UART
32  *
33  * (MSP430 03 P2.6: GPIO ) <- SRDY <- (CC2480 05 SRDY)
34  * (MSP430 25 P3.6: GPIO ) -> MRDY -> (CC2480 06 MRDY)
35  *
36  * (MSP430 09 P3.0: UCB0STE ) -> SS/CT -> (CC2480 15 SS/CT) - disabled in 3-pin SPI
37  * UCxSTE chooses between master active/inactive
38  *
39  * (MSP430 10 P3.1: UCB0SIMO) -> SI -> (CC2480 14 SI/TX)
40  * (MSP430 11 P3.2: UCB0SOMI) <- SO <- (CC2480 13 SO/RX)
41  * (MSP430 12 P3.3: UCB0CLK ) -> C/RT -> (CC2480 16 C/RT)
42  *
43  * (MSP430 17 P4.2: GPIO ) -> P_4.2 -> (CC2480 45 NC)
44  * (MSP430 18 P4.3: GPIO ) -> P_4.3 -> (CC2480 46 NC)
45  *
46  *
47  * From "swra175a.pdf":
48  *
49  * Frame format:
50  * ---------+------------------
51  * Bytes | 1 | 2 | 0-253 |
52  * +--------+---------+-------+
53  * Information | Length | Command | Data |
54  * ---------+------------------
55  *
56  * -------------------+-------
57  * Byte | Cmd0 | Cmd1 |
58  * -------+-----------+------+
59  * Bits | 7-5 | 4-0 | 7-0 |
60  * +------+-----------+------+
61  * Information | Type | Subsystem | ID |
62  * -------+-------------------
63  *
64  * Type
65  * 0: 0x00 POLL. Used to retrieve data, length, subsystem and id are set to 0;
66  * 1: 0x20 SREQ. Synchronous request;
67  * 2: 0x40 AREQ. Asynchronous request;
68  * 3: 0x60 SRSP. Synchronous response;
69  * 4-7: Reserved.
70  *
71  * Subsystem
72  * 0: Reserved
73  * 1: SYS interface
74  * 2: Reserved
75  * 3: Reserved
76  * 4: AF interface
77  * 5: ZDO interface
78  * 6: Simple API interface
79  * 7-32: Reserved
80  *
81  * ID
82  * Command ID, maps to a particular interface message. 0-255
83  *
84  */
85 
86 /*
87  * ======== Standard MSP430 includes ========
88  */
89 #include <msp430.h>
90 
91 /*
92  * ======== Includes ========
93  */
94 #include "nwk.h"
95 #include "cc2480ai.h"
96 #include "led.h"
97 #if DEBUG!=1
98 #include "uart.h"
99 #endif
100 
101 /*
102  * ======== Constants ========
103  */
104 
105 /*
106  * ======== Macros ========
107  */
108 
113 #define NWK_NEIGHBORHEARTBEATTIMEOUT 9
114 
115 #define NWK_START_TIMEOUT 10
116 
117 #define NWK_FLAGIDX_SINK 0x01
118 #define NWK_FLAGIDX_NSINK 0xFE
119 #define NWK_FLAGIDX_BOUND 0x02
120 #define NWK_FLAGIDX_NBOUND 0xFD
121 #define NWK_FLAGIDX_SENDFAIL 0x04
122 #define NWK_FLAGIDX_NSENDFAIL 0xFB
123 #define NWK_FLAGIDX_FAILJOIN 0x08
124 #define NWK_FLAGIDX_NFAILJOIN 0xF7
125 
126 /*
127  * ======== Types ========
128  */
129 
130 // network state
134 typedef enum nwk_state {
135  NWK_S_INIT,
136  NWK_S_SUSPENDED,
137  NWK_S_CONFIGSTART,
138  NWK_S_CONFIGSTARTWAIT,
139  NWK_S_SETDEVICETYPE,
140  NWK_S_RESETWAIT,
141  NWK_S_CONFIGURE,
142  NWK_S_REGISTER,
143  NWK_S_START,
144  NWK_S_STARTWAIT,
145  NWK_S_POSTSTARTCONFIGURE,
146  NWK_S_GETINFO,
147  NWK_S_CHECKFORBIND,
148  NWK_S_RUNNING
149 } nwk_state;
150 
151 /*
152  * ======== Global Variables ========
153  */
154 
159 
160 /*
161  * ======== Local Variables ========
162  */
163 
203 
210 
217 
224 
229 
233 UInt16 nwk_address;
234 
239 
244 
249 
254 
255 // 0 - allow bind
256 // 1 - bound to another device
257 UInt8 nwk_flags;
258 
259 /*
260  * ======== Local Functions ========
261  */
262 
263 UInt8 nwk_sendHeartBeat();
264 
265 /*
266  * ================
267  */
268 
276 void nwk_init() {
277  UInt8 portIndex;
278 
280  nwk_currentState = NWK_S_INIT;
281  nwk_returnState = NWK_S_INIT;
282  nwk_lastParam = 0;
285  nwk_address = 0xFFFF;
286  nwk_ieeeAddress = 0;
287  nwk_dataHandle = 0;
288  nwk_freezeDetect = 255;
289  nwk_runCounter = 0;
290  nwk_flags = 0;
291 
292  portIndex = NWK_NEIGHBORMAX;
293  while (portIndex) {
294  portIndex--;
295  nwk_neighbors[portIndex].foreignAddress = 0xFFFF;
296  nwk_neighbors[portIndex].foreignPort = 0;
297  nwk_neighbors[portIndex].timeOut = 0;
298  };
299 }
300 
310 UInt16 nwk_process() {
311  UInt8 portIndex;
312 
313  switch (nwk_currentState) {
314  case NWK_S_INIT:
315  // Reset bind state
316  nwk_flags &= NWK_FLAGIDX_NBOUND & NWK_FLAGIDX_NSINK;
317  return 1000;
318  case NWK_S_SUSPENDED:
319  break;
320  case NWK_S_CONFIGSTART:
321  if (nwk_configureWrite()) {
322  // configure finished, nwk_configureWriteRsp will set next state on success.
323  return 10;
324  }
325  // Configuration not finished, execute again in 10ms
326  return 10;
327  case NWK_S_CONFIGSTARTWAIT:
328  // nwk_resetResume sets next state
329  return 50;
330  case NWK_S_SETDEVICETYPE:
331  // Reset bind state
332  nwk_flags &= NWK_FLAGIDX_NBOUND;
333  if (nwk_configureWrite()) {
334  // configure finished, nwk_configureWriteRsp will set next state on success.
335  return 50;
336  }
337  // Configuration not finished, execute again in 10ms
338  return 10;
339  case NWK_S_RESETWAIT:
340  // nwk_resetResume sets next state
341  return 50;
342  case NWK_S_CONFIGURE:
343  if (nwk_configureWrite()) {
344  // configure finished, nwk_configureWriteRsp will set next state on success.
345  return 10;
346  }
347  // Configuration not finished, execute again in 10ms
348  return 10;
349  case NWK_S_REGISTER:
350  // Registering application
351  if (nwk_register()) {
352  // nwk_registerRsp sets next state.
353  // if nwk_registerRsp is not called in 10ms, nwk_register will be called again.
354  return 10;
355  }
356  // Failed to send command, try again in 10ms
357  return 10;
358  case NWK_S_START:
359  // Reset bind state
360  nwk_flags &= NWK_FLAGIDX_NBOUND;
361  if (nwk_start()) {
362  // Set led indicator to starting network
363  led_redConfigure(1, 300);
364  // nwk_startRsp sets next state
365  nwk_freezeDetect = NWK_START_TIMEOUT; // give ~5s to network start, see NWK_S_STARTWAIT block.
366  return 500;
367  }
368  // Failed to send command, try again in 10ms
369  return 10;
370  case NWK_S_STARTWAIT:
372  if (!nwk_freezeDetect) {
373  nwk_freezeDetect = NWK_START_TIMEOUT;
374  nwk_flags ^= NWK_FLAGIDX_FAILJOIN;
375  if (nwk_flags & NWK_FLAGIDX_FAILJOIN) {
376  // try again, next time, if not EndDevice, try as router
378  } else {
381  } else
383  }
384  }
385  return 500;
386  case NWK_S_POSTSTARTCONFIGURE:
387  if (nwk_configureWrite()) {
388  // configure finished, nwk_configureWriteRsp will set next state on success.
389  return 10;
390  }
391  // Configuration not finished, execute again in 10ms
392  return 10;
393  case NWK_S_GETINFO:
394  if (nwk_getDeviceInfo()) {
395  // nwk_getDeviceInfoRsp sets next state
396  return 10;
397  }
398  // request next info in 5ms.
399  return 5;
400  case NWK_S_CHECKFORBIND:
401  // Check if device was a sink before CC2480 reset
402  if (nwk_flags & NWK_FLAGIDX_SINK)
403  if (!nwk_allow_bind(0xFF))
404  return 10;
405 
406  nwk_freezeDetect = 6 + ((((char *) &nwk_ieeeAddress)[0] & 0x0F) << 1);
407  nwk_currentState = NWK_S_RUNNING;
408  return 10;
409  case NWK_S_RUNNING:
410 
411  if (nwk_freezeDetect) {
412  switch (nwk_runCounter & 0x03) { // each of these tasks runs once per 4s (alternate):
413  case 0x00:
414  if (!nwk_sendHeartBeat())
415  return 5;
416  break;
417  case 0x01:
418  if (!(nwk_flags & (NWK_FLAGIDX_SINK | NWK_FLAGIDX_BOUND))) // not sink nor bound
419  if (!nwk_bind_device(1, NWK_CMDIDRPT, 0))
420  return 5;
421  break;
422  default:
423  break;
424  }
425 
426  portIndex = NWK_NEIGHBORMAX;
427  while (portIndex) {
428  portIndex--;
429  if (nwk_neighbors[portIndex].foreignAddress != 0xFFFF)
430  if (nwk_neighbors[portIndex].timeOut)
431  nwk_neighbors[portIndex].timeOut--;
432  else {
433  nwk_neighbors[portIndex].foreignAddress = 0xFFFF;
434  nwk_neighbors[portIndex].foreignPort = 0;
435  }
436  }
438  } else {
439  ccai_resetFull();
440  }
441 
442  nwk_runCounter++;
443  return 1000;
444  default:
445  nwk_currentState = NWK_S_INIT;
446  return 1;
447  }
448  return 500;
449 }
450 
458 void nwk_suspend() {
460  // states that must be set to an earlier one
461  nwk_lastParam = 0;
463  nwk_currentState = NWK_S_SUSPENDED;
464 }
465 
474 UInt8 nwk_wakeUp() {
475  switch (nwk_currentState) {
476  case NWK_S_CONFIGSTARTWAIT:
477  case NWK_S_RESETWAIT:
478  // device is in normal reset, it is not a simple wake-up
479  return 0;
480  case NWK_S_SUSPENDED: // Network is suspended, return to previous state.
482  nwk_lastParam = 0;
484  default: // If default, CC2480 was reset by its watch-dog
485  // check the need of an earlier state
486  switch (nwk_currentState) {
487  case NWK_S_REGISTER:
488  case NWK_S_START:
489  case NWK_S_POSTSTARTCONFIGURE:
491  nwk_lastParam = 0;
492  nwk_currentState = NWK_S_CONFIGURE;
493  break;
494  case NWK_S_STARTWAIT:
495  default:
496  nwk_currentState = NWK_S_START; // This is to call nwk_start again
497  break;
498  }
499  // Set led indicator to no network
500  led_redConfigure(5, 300);
501  break;
502  }
503  return 1;
504 }
505 
517  nwk_currentDevType = newType;
518  nwk_lastParam = 0;
520  nwk_currentState = NWK_S_CONFIGSTART;
521  // Set led indicator to no network
522  led_redConfigure(5, 0);
523 }
524 
535  if (nwk_currentState == NWK_S_RUNNING)
536  return nwk_currentDevType;
537  else
538  return NWK_DEVTYPE_NONE;
539 }
540 
549  nwk_lastParam = 0;
551  if (nwk_currentState == NWK_S_CONFIGSTARTWAIT)
552  nwk_currentState = NWK_S_SETDEVICETYPE;
553  else
554  nwk_currentState = NWK_S_CONFIGURE;
555  // Set led indicator to no network
556  led_redConfigure(5, 300);
557 }
558 
572  UInt8 v8;
573 
574  // Only write one configuration each time after the last one had success.
575  // On fail, nwk_lastParam is set to last one successful and written again.
576  switch (nwk_currentState) {
577  case NWK_S_CONFIGSTART:
578  switch (nwk_lastParamSuccess) {
579  case 0:
583  1, &v8))
584  nwk_lastParam = 1;
585  break;
586  case 1:
587  // configure finished, nwk_configureWriteRsp sets next state
588  return 1;
589  default: // If can't find last successful written configuration, restarting configuring
590  nwk_lastParam = 0;
592  break;
593  }
594  case NWK_S_SETDEVICETYPE:
595  switch (nwk_lastParamSuccess) {
596  case 0:
597  switch (nwk_currentDevType) {
600  break;
601  case NWK_DEVTYPE_ROUTER:
603  break;
606  break;
607  default:
609  break;
610  }
612  &v8))
613  nwk_lastParam = 1;
614  break;
615  case 1:
616  // configure finished, nwk_configureWriteRsp sets next state
617  return 1;
618  default: // If can't find last successful written configuration, restarting configuring
619  nwk_lastParam = 0;
621  break;
622  }
623  break;
624  case NWK_S_CONFIGURE:
626  switch (nwk_lastParamSuccess) {
627  case 0:
628  // swra175a.pdf - 6.2.3.1 ZCD_NV_STARTUP_OPTION and ZASA cc2480.h
631  } else {
632  // CCAI_CFGD_BIT_STARTOPT_AUTO_START: undocumented on swra175a.pdf
633  // got from ZASA cc2480.h file. See declaration at cc2480.h
635  //& CCAI_CFGD_BIT_STARTOPT_AUTO_START;
636  }
639  nwk_lastParam = 1;
640  break;
641  case 1:
642  // swra175a.pdf - 6.2.4.1 ZCD_NV_PANID
644  NWK_CFG_PANID))
645  nwk_lastParam = 2;
646  break;
647  case 2:
648  // swra175a.pdf - 6.2.4.2 ZCD_NV_CHANLIST
651  nwk_lastParam = 3;
652  break;
653  case 3:
654  // swra175a.pdf - 6.2.4.3 ZCD_NV_PRECFGKEY
656  16, NWK_CFG_PRECFGKEY))
657  nwk_lastParam = 4;
658  break;
659  case 4:
660  // swra175a.pdf - 6.2.4.4 ZCD_NV_PRECFGKEYS_ENABLE
664  nwk_lastParam = 5;
665  break;
666  case 5:
667  // swra175a.pdf - 6.2.4.5 ZCD_NV_SECURITY_MODE
671  nwk_lastParam = 6;
672  break;
673  case 6:
674  // swra175a.pdf - 6.2.4.6 ZCD_NV_BCAST_RETRIES
678  nwk_lastParam = 7;
679  break;
680  case 7:
681  // swra175a.pdf - 6.2.4.7 ZCD_NV_PASSIVE_ACK_TIMEOUT
685  nwk_lastParam = 8;
686  break;
687  case 8:
688  // swra175a.pdf - 6.2.4.8 ZCD_NV_BCAST_DELIVERY_TIME
692  nwk_lastParam = 9;
693  break;
694  case 9:
695  // swra175a.pdf - 6.2.4.9 ZCD_NV_ROUTE_EXPIRY_TIME
699  nwk_lastParam = 10;
700  break;
701  case 10:
702  // configure finished, nwk_configureWriteRsp sets next state
703  return 1;
704  default: // If can't find last successful written configuration, restarting configuring
705  nwk_lastParam = 0;
707  break;
708  }
709  break;
710  case NWK_S_POSTSTARTCONFIGURE:
712  switch (nwk_lastParamSuccess) {
713  case 0:
714  // swra175a.pdf - 6.2.3.1 ZCD_NV_STARTUP_OPTION
716  v8 = 0;
717  } else {
719  }
722  nwk_lastParam = 1;
723  break;
724  case 1:
725  // configure finished, nwk_configureWriteRsp sets next state
726  return 1;
727  default: // If can't find last successful written configuration, restarting configuring
728  nwk_lastParam = 0;
730  break;
731  }
732  break;
733  default:
734  break;
735  }
736  return 0;
737 }
738 
748 void nwk_configureWriteRsp(UInt8 status) {
749  switch (status) {
750  case CCAI_STA_ZSUCCESS:
752  break;
753  default:
754  // Device failed to configure
755  // In this program, the configuration will be sent again.
756  // This could result in an infinite loop if the state that prevents the configuration do
757  // not change, if it is the case, additional processing may be needed.
759  break;
760  }
761  // Test for end of each configuration group:
762  switch (nwk_currentState) {
763  case NWK_S_CONFIGSTART:
764  if (nwk_lastParamSuccess == 1) {
765  nwk_lastParam = 0;
767  nwk_currentState = NWK_S_CONFIGSTARTWAIT;
768  ccai_resetLight();
769  }
770  case NWK_S_SETDEVICETYPE:
771  if (nwk_lastParamSuccess == 1) {
772  nwk_lastParam = 0;
774  nwk_currentState = NWK_S_RESETWAIT;
775  ccai_resetLight();
776  }
777  case NWK_S_CONFIGURE:
778  if (nwk_lastParamSuccess == 10) {
779  nwk_lastParam = 0;
781  nwk_currentState = NWK_S_REGISTER;
782  }
783  break;
784  case NWK_S_POSTSTARTCONFIGURE:
785  if (nwk_lastParamSuccess == 1) {
786  nwk_lastParam = 0;
788  nwk_currentState = NWK_S_GETINFO;
789  }
790  break;
791  default:
792  break;
793  }
794 }
795 
806 UInt8 nwk_register() {
811 }
812 
822 void nwk_registerRsp(UInt8 status) {
823  if (status == CCAI_STA_ZSUCCESS) {
824  // Application is registered, start network
825  nwk_currentState = NWK_S_START;
826  }
827 }
828 
838 UInt8 nwk_start() {
839  return ccai_s_zb_start_request();
840 }
841 
849 void nwk_startRsp() {
850  // CC2480 is sending 0x66 0x00 instead of 0x66 0x03 after 0x26 0x03 and
851  // instead of 0x66 0x02 after 0x26 0x02
852  // so ignore the response if network state is NWK_S_RUNNING or NWK_S_CHECKFORBIND.
853  if ((nwk_currentState != NWK_S_RUNNING)
854  && (nwk_currentState != NWK_S_CHECKFORBIND))
855  nwk_currentState = NWK_S_STARTWAIT;
856 }
857 
867 void nwk_startConfirm(UInt8 status) {
868  if (status == CCAI_STA_ZSUCCESS) {
869  // Network is up
870  nwk_currentState = NWK_S_POSTSTARTCONFIGURE;
871  }
872 }
873 
889 UInt8 nwk_allow_bind(UInt8 timeout) {
890  return ccai_s_zb_allow_bind(timeout);
891 }
892 
901  // CC2480 is sending 6600, not 6602, so this code will not run.
902 }
903 
912 void nwk_allow_bindConfirm(char *pBuf) {
913  // another device bound to this one
914 #if DEBUG!=1
915  // If debug, all received data is forward to serial by SPI, else forward here.
916  uart_forwardCmd(pBuf);
917 #endif
918 }
919 
931 UInt8 nwk_bind_device(UInt8 create, UInt16 commandId, uint64_t destination) {
932  return ccai_s_zb_bind_device(create, commandId, destination);
933 }
934 
941 
942 }
943 
949 void nwk_bind_deviceConfirm(char *pBuf) {
950  if ((pBuf[3] == NWK_CMDIDRPT) && (pBuf[4] == 0)) { // (UInt16) pBuf[3] == NWK_CMDIDRPT
951 #if DEBUG!=1
952  // If debug, all received data is forward to serial by SPI, else forward here.
953  uart_forwardCmd(pBuf);
954 #endif
955  if (pBuf[5] == CCAI_STA_ZSUCCESS)
956  nwk_flags |= NWK_FLAGIDX_BOUND;
957  else
958  nwk_flags &= NWK_FLAGIDX_NBOUND;
959  }
960 }
961 
975  // swra175a.pdf - 6.3.12 ZB_GET_DEVICE_INFO
976  // read one information each time after last value read have success
978  // The nwk_lastParam and nwk_lastParamSuccess used to be set to CCAI_INFO_XXX, but this
979  // relies on no configuration Id being 0 (zero), but CCAI_INFO_STATE = 0, so
980  // nwk_lastParamSuccessit was changed to sequential numbers.
981 
982  switch (nwk_lastParamSuccess) {
983  case 0:
985  nwk_lastParam = 1;
986  break;
987  case 1:
989  nwk_lastParam = 2;
990  break;
991  case 2:
993  nwk_lastParam = 3;
994  break;
995  case 3:
997  nwk_lastParam = 4;
998  break;
999  case 4:
1001  nwk_lastParam = 5;
1002  break;
1003  case 5:
1005  nwk_lastParam = 6;
1006  break;
1007  case 6:
1009  nwk_lastParam = 7;
1010  break;
1011  case 7:
1013  nwk_lastParam = 8;
1014  break;
1015  case 8:
1016  // all parameters have been requested
1017  return 1;
1018  default: // If can't find last successful information, restart reading
1019  nwk_lastParam = 0;
1021  break;
1022  }
1023  }
1024  return 0;
1025 }
1026 
1037 void nwk_getDeviceInfoRsp(UInt8 param, void *pValue) {
1038  // Not all information is useful, and there isn't a lot of gratuitous RAM, so only needed
1039  // information is stored.
1040  switch (param) {
1041  case CCAI_INFO_STATE:
1042  break;
1043  case CCAI_INFO_IEEEADDRESS:
1044  nwk_ieeeAddress = *((uint64_t *) pValue);
1045  break;
1047  nwk_address = *((UInt16 *) pValue);
1048  break;
1050  break;
1052  break;
1053  case CCAI_INFO_ZBCHANNEL:
1054  break;
1055  case CCAI_INFO_ZBPANID:
1056  break;
1058  // Last parameter, pass network to next state
1059  // Configure led indicator
1060  switch (nwk_currentDevType) {
1062  led_redConfigure(2, 600);
1063  break;
1064  case NWK_DEVTYPE_ROUTER:
1065  led_redConfigure(1, 800);
1066  break;
1067  case NWK_DEVTYPE_ENDDEVICE:
1068  led_redConfigure(1, 2800);
1069  break;
1070  default:
1071  // Error, no valid device type selected, reset MSP430
1072  WDTCTL = 0;
1073  break;
1074  }
1075  break;
1076  default:
1077  break;
1078  }
1080  if (nwk_lastParamSuccess == 8) {
1081  nwk_lastParam = 0;
1083  nwk_currentState = NWK_S_CHECKFORBIND;
1084  }
1085 
1086 }
1087 
1104 UInt8 nwk_setPermitJoin(UInt8 timeout) {
1105  if (nwk_currentState != NWK_S_RUNNING) {
1106  return 0;
1107  }
1108  return ccai_s_zb_permit_joining_request(0xFFFC, timeout);
1109 }
1110 
1119  // no action needed
1120 }
1121 
1131 UInt8 nwk_allowJoin() {
1132  return nwk_setPermitJoin(0xFF);
1133 }
1134 
1143  return nwk_setPermitJoin(0x00);
1144 }
1145 
1153 UInt8 nwk_isClient() {
1156  && (nwk_currentState == NWK_S_RUNNING);
1157 }
1158 
1167 UInt8 nwk_isSink() {
1168  return nwk_flags & NWK_FLAGIDX_SINK;
1169 }
1170 
1179 UInt8 nwk_isBound() {
1180  return nwk_flags & NWK_FLAGIDX_BOUND;
1181 }
1182 
1183 
1195 void nwk_setSink(UInt8 sink) {
1196  if (sink) {
1197  if (nwk_allow_bind(0xFF))
1198  nwk_flags |= NWK_FLAGIDX_SINK;
1199  } else {
1200  if (nwk_allow_bind(0))
1201  nwk_flags &= NWK_FLAGIDX_NSINK;
1202  }
1203 }
1204 
1215  return nwk_address;
1216 }
1217 
1228  return nwk_ieeeAddress;
1229 }
1230 
1242 uint64_t * nwk_getPIeeeAddress() {
1243  return &nwk_ieeeAddress;
1244 }
1245 
1261 UInt8 nwk_startFrame(UInt16 destination, UInt16 cmdId, UInt8 radius, UInt8 len) {
1262  if (nwk_currentState != NWK_S_RUNNING) {
1263  return 0;
1264  }
1265  return ccai_s_zb_send_data_request_begin(destination, cmdId, nwk_dataHandle,
1266  NWK_DEFACK, radius, len);
1267 }
1268 
1282 UInt8 nwk_snd(UInt8 len, void *pBuf) {
1283  return ccai_s_zb_send_data_request_payload(len, pBuf);
1284 }
1285 
1297 void nwk_endFrame(UInt8 forwardToSerial) {
1298  ccai_s_zb_send_data_request_end(forwardToSerial);
1299  nwk_dataHandle++;
1300 }
1301 
1314 UInt8 nwk_sndUInt8(UInt8 v) {
1315  return nwk_snd(1, &v);
1316 }
1317 
1330 UInt8 nwk_sndUInt16(UInt16 v) {
1331  return nwk_snd(2, &v);
1332 }
1333 
1346 UInt8 nwk_sndUInt32(UInt32 *p) {
1347  return nwk_snd(4, p);
1348 }
1349 
1363 UInt8 nwk_sndUInt48(uint64_t *p) {
1364  return nwk_snd(6, p);
1365 }
1366 
1377 UInt8 nwk_sndUInt64(uint64_t *p) {
1378  return nwk_snd(8, p);
1379 }
1380 
1391 UInt8 nwk_sndInt64(int64_t *p) {
1392  return nwk_snd(8, p);
1393 }
1394 
1404 void nwk_send_dataConfirm(UInt8 dataHandle, UInt8 status) {
1405  if (status == CCAI_STA_ZAPSNOBOUNDDEVICE) // ZApsNoBoundDevice
1406  nwk_flags &= NWK_FLAGIDX_NBOUND;
1407  if (status == CCAI_STA_ZFAILURE) {
1408  if (nwk_flags & NWK_FLAGIDX_SENDFAIL) {
1409  nwk_flags &= NWK_FLAGIDX_NSENDFAIL & NWK_FLAGIDX_NBOUND;
1410  } else {
1411  nwk_flags |= NWK_FLAGIDX_SENDFAIL;
1412  }
1413  } else {
1414  if (nwk_flags & NWK_FLAGIDX_BOUND) {
1415  nwk_flags &= NWK_FLAGIDX_NSENDFAIL;
1416  }
1417  }
1418 }
1419 
1427 void nwk_rcv(char *pBuf) {
1428  UInt16 src;
1429  UInt16 cmd;
1430  UInt16 len;
1431  UInt8 portNumber;
1432  UInt8 i;
1433 
1434  nwk_freezeDetect = 4 + ((char *) &nwk_ieeeAddress)[0];
1435 
1436  src = pBuf[3] | (pBuf[4] << 8);
1437  cmd = pBuf[5] | (pBuf[6] << 8);
1438  len = pBuf[7] | (pBuf[8] << 8);
1439 
1440  switch (cmd) {
1441  case NWK_CMDIDHEARTBEAT:
1442  // heart beat
1443  portNumber = nwk_getNeighborPort(src);
1444  if (portNumber) {
1445  nwk_neighbors[portNumber - 1u].timeOut =
1447  } else {
1448  portNumber = nwk_registerNeighbor(src);
1449  }
1450  if (portNumber) {
1451  // verify if neighbor know this device, if so, register the port reported by the neighbor
1452  pBuf += 9;
1453  i = 0;
1454  while (i < len) {
1455  if (nwk_address == (pBuf[i] | (pBuf[i + 1u] << 8))) {
1456  nwk_neighbors[portNumber - 1u].foreignPort = pBuf[i + 2u];
1457  // no need to continue scan, device was found:
1458  i = len;
1459  } else
1460  i += 3;
1461  }
1462  } else {
1463  // neighbor is unknown and not enough resources to record a new one.
1464  }
1465  case NWK_CMDIDRPT:
1466  // report
1467 #if DEBUG!=1
1468  // If debug, all received data is forward to serial by SPI, else forward here if device is in sink mode.
1469  if (nwk_isSink())
1470  uart_forwardCmd(pBuf);
1471 #endif
1472  break;
1473  default:
1474  break;
1475  }
1476 }
1477 
1486  UInt8 size;
1487  UInt8 portIndex;
1488 
1489  size = 0;
1490  portIndex = NWK_NEIGHBORMAX;
1491  while (portIndex) {
1492  portIndex--;
1493  if (nwk_neighbors[portIndex].foreignAddress != 0xFFFF) {
1494  size += 3;
1495  }
1496  };
1497 
1498  if (nwk_startFrame(0xFFFF, NWK_CMDIDHEARTBEAT, 1, size)) {
1499  portIndex = NWK_NEIGHBORMAX;
1500  while (portIndex) {
1501  portIndex--;
1502  if (nwk_neighbors[portIndex].foreignAddress != 0xFFFF) {
1503  nwk_sndUInt16(nwk_neighbors[portIndex].foreignAddress);
1504  nwk_sndUInt8(portIndex + 1);
1505  }
1506  };
1507  nwk_endFrame(FALSE);
1508  return 1;
1509  }
1510  return 0;
1511 }
1512 
1522 UInt8 nwk_getNeighborPort(UInt16 a) {
1523  UInt8 portIndex;
1524 
1525  portIndex = NWK_NEIGHBORMAX;
1526  while (portIndex) {
1527  portIndex--;
1528  if (nwk_neighbors[portIndex].foreignAddress == a) {
1529  return portIndex + 1;
1530  }
1531  };
1532  return 0;
1533 }
1534 
1545 UInt8 nwk_getNeighborForeignPort(UInt8 portNumber) {
1546  if ((!portNumber) || (portNumber > NWK_NEIGHBORMAX))
1547  return 0;
1548  portNumber--; // portIndex from here
1549  return nwk_neighbors[portNumber].foreignPort;
1550 }
1551 
1561 UInt16 nwk_getNeighborAddress(UInt8 portNumber) {
1562  if ((!portNumber) || (portNumber > NWK_NEIGHBORMAX))
1563  return 0xFFFF;
1564  portNumber--; // portIndex from here
1565  return nwk_neighbors[portNumber].foreignAddress;
1566 
1567 }
1568 
1578 UInt8 nwk_registerNeighbor(UInt16 a) {
1579  UInt8 portIndex;
1580 
1581  portIndex = NWK_NEIGHBORMAX;
1582  while (portIndex) {
1583  portIndex--;
1584  if (nwk_neighbors[portIndex].foreignAddress == 0xFFFF) {
1585  nwk_neighbors[portIndex].foreignAddress = a;
1586  nwk_neighbors[portIndex].foreignPort = 0;
1587  nwk_neighbors[portIndex].timeOut = NWK_NEIGHBORHEARTBEATTIMEOUT;
1588  return portIndex + 1;
1589  }
1590  };
1591  return 0;
1592 }
UInt8 nwk_isSink()
Is sink.
Definition: nwk.c:1167
Coordinator.
Definition: nwk.h:217
Network functions interface.
uint64_t * nwk_getPIeeeAddress()
Get pointer to the IEEE address.
Definition: nwk.c:1242
void nwk_allow_bindConfirm(char *pBuf)
Allow bind confirmation.
Definition: nwk.c:912
UInt8 ccai_s_zb_start_request()
Start request.
Definition: cc2480ai.c:1342
UART interface.
UInt8 nwk_dataHandle
Handle used to identify one packet.
Definition: nwk.c:243
UInt8 nwk_sndInt64(int64_t *p)
Send signed 64 bits integer.
Definition: nwk.c:1391
#define CCAI_CFGD_BIT_STARTOPT_AUTO_START
This is undocumented. This bit is present on ZASA cc2480.h file, but reserved on the description of s...
Definition: cc2480ai.h:342
#define CCAI_CFGD_ZCD_NV_STARTUP_OPTION
Device startup options.
Definition: cc2480ai.h:321
#define CCAI_CFGD_LOGICAL_TYPE_ROUTER
Set device type as a router.
Definition: cc2480ai.h:365
#define CCAI_INFO_ZBPANID
Request PAN id of the ZigBee network.
Definition: cc2480ai.h:496
UInt8 nwk_register()
Register application request.
Definition: nwk.c:806
UInt16 nwk_address
Short address of the device.
Definition: nwk.c:233
UInt8 nwk_start()
Start network request.
Definition: nwk.c:838
UInt8 nwk_sndUInt64(uint64_t *p)
Send unsigned 64 bits integer.
Definition: nwk.c:1377
UInt8 nwk_sendHeartBeat()
Send heart beat.
Definition: nwk.c:1485
UInt8 nwk_setPermitJoin(UInt8 timeout)
Permit join request.
Definition: nwk.c:1104
void nwk_allow_bindRsp()
Allow bind response.
Definition: nwk.c:900
UInt8 nwk_getNeighborForeignPort(UInt8 portNumber)
Get neighbor foreign port.
Definition: nwk.c:1545
None, invalid in a network.
Definition: nwk.h:220
#define CCAI_INFO_PARENTSHORTADDRESS
Request short address of the parent device.
Definition: cc2480ai.h:484
void nwk_registerRsp(UInt8 status)
Register application response.
Definition: nwk.c:822
UInt8 nwk_wakeUp()
Network wake up.
Definition: nwk.c:474
void nwk_suspend()
network suspend
Definition: nwk.c:458
void nwk_setPermitJoinRsp()
Permit join response.
Definition: nwk.c:1118
void nwk_configureWriteRsp(UInt8 status)
Response to a configuration write.
Definition: nwk.c:748
#define CCAI_CFGN_ZCD_NV_PRECFGKEY
Used to secure and un-secure packets when security is enabled.
Definition: cc2480ai.h:432
#define CCAI_CFGD_LOGICAL_TYPE_COORDINATOR
Set device type as a coordinator.
Definition: cc2480ai.h:361
UInt8 nwk_sndUInt48(uint64_t *p)
Send unsigned 48 bits integer.
Definition: nwk.c:1363
void nwk_setSink(UInt8 sink)
Set sink.
Definition: nwk.c:1195
Router.
Definition: nwk.h:218
#define CCAI_CFGD_BIT_STARTOPT_CLEAR_STATE
Clear network state.
Definition: cc2480ai.h:336
UInt8 ccai_s_zb_bind_device(UInt8 create, UInt16 commandId, uint64_t destination)
Bind device request.
Definition: cc2480ai.c:1421
#define NWK_CFG_APPPROFILEID
Profile id of application.
Definition: nwk.h:109
UInt8 ccai_s_zb_send_data_request_payload(UInt8 len, void *pBuf)
Append data to the payload of send data request.
Definition: cc2480ai.c:1588
UInt8 nwk_isClient()
Is client.
Definition: nwk.c:1153
void nwk_bind_deviceRsp()
Bind device response.
Definition: nwk.c:940
#define CCAI_CFGN_ZCD_NV_PRECFGKEYS_ENABLE
Configure if key is pre-configured (1) or sent when device joins (0).
Definition: cc2480ai.h:436
#define CCAI_CFGN_ZCD_NV_SECURITY_MODE
Turn security on or off.
Definition: cc2480ai.h:440
#define NWK_NEIGHBORHEARTBEATTIMEOUT
Timeout after a neighbor is considered disconnected.
Definition: nwk.c:113
#define CCAI_CFGN_ZCD_NV_CHANLIST
List of channels to operate on, each bit is a channel.
Definition: cc2480ai.h:428
#define CCAI_CFGN_ZCD_NV_BCAST_RETRIES
Maximum retransmissions when sending a broadcast packet.
Definition: cc2480ai.h:444
#define NWK_CFG_OUTPUTCMDLIST
Output command list.
Definition: nwk.h:149
UInt16 nwk_getShortAddress()
Get shotr address.
Definition: nwk.c:1214
#define CCAI_INFO_ZBCHANNEL
Request operation channel of the ZigBee network.
Definition: cc2480ai.h:492
nwk_neighbor nwk_neighbors[NWK_NEIGHBORMAX]
Neighbors information.
Definition: nwk.c:158
UInt8 ccai_s_zb_allow_bind(UInt8 timeout)
Allow bind request.
Definition: cc2480ai.c:1466
UInt8 nwk_sndUInt32(UInt32 *p)
Send unsigned 32 bits integer.
Definition: nwk.c:1346
UInt8 nwk_isBound()
Is bound.
Definition: nwk.c:1179
void ccai_resetFull()
Full reset.
Definition: cc2480ai.c:616
UInt8 nwk_lastParamSuccess
Last successful parameter.
Definition: nwk.c:223
#define NWK_CMDIDHEARTBEAT
Command id for child heartbeat.
Definition: nwk.h:157
UInt8 ccai_s_zb_get_device_info(UInt8 param)
Get device information request.
Definition: cc2480ai.c:1653
nwk_state nwk_currentState
Current state of the LEDs control.
Definition: nwk.c:202
#define NWK_CFG_INPUTCMDCOUNT
Number of input commands.
Definition: nwk.h:129
UInt8 nwk_sndUInt16(UInt16 v)
Send unsigned 16 bits integer.
Definition: nwk.c:1330
#define CCAI_STA_ZAPSNOBOUNDDEVICE
ZApsNoBoundDevice.
Definition: cc2480ai.h:614
#define NWK_CFG_DEVICEID
Application specific.
Definition: nwk.h:116
void nwk_startRsp()
Start network response.
Definition: nwk.c:849
#define CCAI_CFGN_ZCD_NV_PANID
Identifies the ZigBee network.
Definition: cc2480ai.h:424
UInt8 nwk_freezeDetect
Counter used to detect freezes.
Definition: nwk.c:248
void nwk_setDeviceType(nwk_devType newType)
Set device type.
Definition: nwk.c:516
UInt8 nwk_sndUInt8(UInt8 v)
Send unsigned 8 bits integer.
Definition: nwk.c:1314
UInt8 nwk_disallowJoin()
Disallow join.
Definition: nwk.c:1142
UInt8 nwk_getDeviceInfo()
Get device information request.
Definition: nwk.c:974
UInt8 ccai_s_zb_send_data_request_begin(UInt16 destination, UInt16 commandId, UInt8 handle, UInt8 ack, UInt8 radius, UInt8 len)
Begin request to send data.
Definition: cc2480ai.c:1557
#define NWK_CFG_OUTPUTCMDCOUNT
Number of output commands.
Definition: nwk.h:142
#define CCAI_STA_ZFAILURE
ZFailure.
Definition: cc2480ai.h:518
void nwk_init()
Network initialization.
Definition: nwk.c:276
void nwk_resetResume()
Resume from CC2480 reset.
Definition: nwk.c:548
UInt8 uart_forwardCmd(char *pBuf)
Forward command.
Definition: uart.c:740
#define NWK_CFG_ROUTE_EXPIRY_TIME
swra175a.pdf - 6.2.4.9 ZCD_NV_ROUTE_EXPIRY_TIME
Definition: nwk.h:83
void ccai_resetLight()
Reset.
Definition: cc2480ai.c:627
#define NWK_CMDIDRPT
Command id for report.
Definition: nwk.h:163
uint64_t nwk_ieeeAddress
Short address of the device.
Definition: nwk.c:238
#define CCAI_CFGN_ZCD_NV_ROUTE_EXPIRY_TIME
Time (s) after an idle route is marked as expired.
Definition: cc2480ai.h:456
#define NWK_CFG_PASSIVE_ACK_TIMEOUT
swra175a.pdf - 6.2.4.7 ZCD_NV_PASSIVE_ACK_TIMEOUT
Definition: nwk.h:75
#define NWK_NEIGHBORMAX
Max number of expected direct neighbors.
Definition: nwk.h:207
void led_redConfigure(UInt8 n, UInt16 offDelay)
Configures red led.
Definition: led.c:201
UInt16 nwk_process()
Network process.
Definition: nwk.c:310
#define NWK_CFG_BCAST_RETRIES
swra175a.pdf - 6.2.4.6 ZCD_NV_BCAST_RETRIES
Definition: nwk.h:71
#define NWK_CFG_BCAST_DELIVERY_TIME
swra175a.pdf - 6.2.4.8 ZCD_NV_BCAST_DELIVERY_TIME
Definition: nwk.h:79
nwk_devType nwk_currentDevType
Current device type.
Definition: nwk.c:228
#define CCAI_CFGN_ZCD_NV_BCAST_DELIVERY_TIME
Maximum time (units of 100ms) to a broadcast packet propagate through the entire network.
Definition: cc2480ai.h:452
#define NWK_CFG_CHANLIST
swra175a.pdf - 6.2.4.2 ZCD_NV_CHANLIST
Definition: nwk.h:55
#define CCAI_CFGD_LOGICAL_TYPE_ENDDEVICE
Set device type as an end-device.
Definition: cc2480ai.h:369
nwk_devType nwk_getDeviceType()
This function gets the device type.
Definition: nwk.c:534
#define CCAI_STA_ZSUCCESS
ZSuccess.
Definition: cc2480ai.h:514
void nwk_rcv(char *pBuf)
Network receive.
Definition: nwk.c:1427
#define CCAI_INFO_STATE
Request state of the device.
Definition: cc2480ai.h:472
void nwk_send_dataConfirm(UInt8 dataHandle, UInt8 status)
Send data confirmation.
Definition: nwk.c:1404
CC2480 interface.
UInt8 ccai_s_zb_app_register_request(UInt8 appEndPoint, UInt16 appProfileId, UInt16 DeviceId, UInt8 DeviceVersion, UInt8 inputCommandsNum, char *InputCommandsList, UInt8 OutputCommandsNum, char *OutputCommandsList)
Application register request.
Definition: cc2480ai.c:1301
#define NWK_CFG_PANID
swra175a.pdf - 6.2.4.1 ZCD_NV_PANID
Definition: nwk.h:51
UInt8 nwk_allowJoin()
Allow join.
Definition: nwk.c:1131
void nwk_getDeviceInfoRsp(UInt8 param, void *pValue)
Get device information response.
Definition: nwk.c:1037
uint64_t nwk_getIeeeAddress()
Get IEEE address.
Definition: nwk.c:1227
Neighbor data.
Definition: nwk.h:228
UInt8 nwk_bind_device(UInt8 create, UInt16 commandId, uint64_t destination)
Bind device request.
Definition: nwk.c:931
#define NWK_CFG_DEVICEVERSION
Application specific.
Definition: nwk.h:123
UInt8 nwk_startFrame(UInt16 destination, UInt16 cmdId, UInt8 radius, UInt8 len)
Start Frame.
Definition: nwk.c:1261
#define CCAI_INFO_IEEEADDRESS
Request IEEE address of the device.
Definition: cc2480ai.h:476
End device.
Definition: nwk.h:219
#define NWK_DEFACK
Default ACK request. On transmitted packets, 1 to request ACK, 0 to don't.
Definition: nwk.h:189
#define NWK_CFG_APPENDPOINT
The endpoint of the device.
Definition: nwk.h:101
UInt8 nwk_runCounter
Children information.
Definition: nwk.c:253
UInt8 nwk_snd(UInt8 len, void *pBuf)
Send data.
Definition: nwk.c:1282
#define NWK_DEVTYPE_DEFALUT
The default device type on network initialization.
Definition: nwk.h:202
nwk_state
States for the network.
Definition: nwk.c:134
UInt8 nwk_configureWrite()
Write configuration.
Definition: nwk.c:571
nwk_state nwk_returnState
State on suspend.
Definition: nwk.c:209
#define CCAI_INFO_PARENTIEEEADDRESS
Request IEEE address of the parent device.
Definition: cc2480ai.h:488
#define NWK_CFG_PRECFGKEY
swra175a.pdf - 6.2.4.3 ZCD_NV_PRECFGKEY
Definition: nwk.h:59
void nwk_bind_deviceConfirm(char *pBuf)
Bind device confirmation.
Definition: nwk.c:949
#define CCAI_CFGD_BIT_STARTOPT_CLEAR_CONFIG
Overwrite all configuration parameters except this one.
Definition: cc2480ai.h:332
Led interface.
UInt8 nwk_lastParam
Last parameter.
Definition: nwk.c:216
#define NWK_CFG_PRECFGKEYS_ENABLE
swra175a.pdf - 6.2.4.4 ZCD_NV_PRECFGKEYS_ENABLE
Definition: nwk.h:63
UInt8 ccai_s_zb_write_configuration(UInt8 configId, UInt8 len, void *pBuf)
Write configuration request.
Definition: cc2480ai.c:1256
#define NWK_CFG_INPUTCMDLIST
Input command list.
Definition: nwk.h:136
UInt8 nwk_allow_bind(UInt8 timeout)
Allow bind request.
Definition: nwk.c:889
#define CCAI_INFO_ZBEXTENDEDPANID
Request Extended PAN id of the ZigBee network.
Definition: cc2480ai.h:500
UInt8 nwk_getNeighborPort(UInt16 a)
Get neighbor port.
Definition: nwk.c:1522
void nwk_endFrame(UInt8 forwardToSerial)
End frame.
Definition: nwk.c:1297
nwk_devType
Device types.
Definition: nwk.h:216
UInt8 nwk_registerNeighbor(UInt16 a)
Register neighbor.
Definition: nwk.c:1578
UInt16 nwk_getNeighborAddress(UInt8 portNumber)
Get neighbor address.
Definition: nwk.c:1561
UInt8 ccai_s_zb_permit_joining_request(UInt16 destination, UInt8 timeOut)
Permit join change request.
Definition: cc2480ai.c:1386
#define CCAI_CFGN_ZCD_NV_PASSIVE_ACK_TIMEOUT
Time (units of 100ms) to wait before retransmitting a broadcast packet.
Definition: cc2480ai.h:448
#define CCAI_INFO_SHORTADDRESS
Request shor address of the device.
Definition: cc2480ai.h:480
#define CCAI_CFGD_ZCD_NV_LOGICAL_TYPE
Logical type of the device in the ZigBee network.
Definition: cc2480ai.h:350
void nwk_startConfirm(UInt8 status)
Start network confirmation.
Definition: nwk.c:867
#define NWK_CFG_SECURITY_MODE
swra175a.pdf - 6.2.4.5 ZCD_NV_SECURITY_MODE
Definition: nwk.h:67
void ccai_s_zb_send_data_request_end(UInt8 forwardToSerial)
Terminate the request to send data and send it to CC2480.
Definition: cc2480ai.c:1604