SZSPTP 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 #include "ptp.h"
98 #if DEBUG!=1
99 #include "uart.h"
100 #endif
101 
102 /*
103  * ======== Constants ========
104  */
105 
106 /*
107  * ======== Macros ========
108  */
109 
114 #define NWK_NEIGHBORHEARTBEATTIMEOUT 9
115 
116 #define NWK_START_TIMEOUT 10
117 
118 #define NWK_FLAGIDX_SINK 0x01
119 #define NWK_FLAGIDX_NSINK 0xFE
120 #define NWK_FLAGIDX_BOUND 0x02
121 #define NWK_FLAGIDX_NBOUND 0xFD
122 #define NWK_FLAGIDX_SENDFAIL 0x04
123 #define NWK_FLAGIDX_NSENDFAIL 0xFB
124 #define NWK_FLAGIDX_FAILJOIN 0x08
125 #define NWK_FLAGIDX_NFAILJOIN 0xF7
126 
127 /*
128  * ======== Types ========
129  */
130 
131 // network state
135 typedef enum nwk_state {
136  NWK_S_INIT,
137  NWK_S_SUSPENDED,
138  NWK_S_CONFIGSTART,
139  NWK_S_CONFIGSTARTWAIT,
140  NWK_S_SETDEVICETYPE,
141  NWK_S_RESETWAIT,
142  NWK_S_CONFIGURE,
143  NWK_S_REGISTER,
144  NWK_S_START,
145  NWK_S_STARTWAIT,
146  NWK_S_POSTSTARTCONFIGURE,
147  NWK_S_GETINFO,
148  NWK_S_CHECKFORBIND,
149  NWK_S_RUNNING
150 } nwk_state;
151 
152 /*
153  * ======== Global Variables ========
154  */
155 
160 
161 /*
162  * ======== Local Variables ========
163  */
164 
204 
211 
218 
225 
230 
234 UInt16 nwk_address;
235 
240 
245 
250 
255 
256 // 0 - allow bind
257 // 1 - bound to another device
258 UInt8 nwk_flags;
259 
260 /*
261  * ======== Local Functions ========
262  */
263 
264 UInt8 nwk_sendHeartBeat();
265 
266 /*
267  * ================
268  */
269 
277 void nwk_init() {
278  UInt8 portIndex;
279 
281  nwk_currentState = NWK_S_INIT;
282  nwk_returnState = NWK_S_INIT;
283  nwk_lastParam = 0;
286  nwk_address = 0xFFFF;
287  nwk_ieeeAddress = 0;
288  nwk_dataHandle = 0;
289  nwk_freezeDetect = 255;
290  nwk_runCounter = 0;
291  nwk_flags = 0;
292 
293  portIndex = NWK_NEIGHBORMAX;
294  while (portIndex) {
295  portIndex--;
296  nwk_neighbors[portIndex].foreignAddress = 0xFFFF;
297  nwk_neighbors[portIndex].foreignPort = 0;
298  nwk_neighbors[portIndex].timeOut = 0;
299  };
300 }
301 
311 UInt16 nwk_process() {
312  UInt8 portIndex;
313 
314  switch (nwk_currentState) {
315  case NWK_S_INIT:
316  // Reset bind state
317  nwk_flags &= NWK_FLAGIDX_NBOUND & NWK_FLAGIDX_NSINK;
318  return 1000;
319  case NWK_S_SUSPENDED:
320  break;
321  case NWK_S_CONFIGSTART:
322  if (nwk_configureWrite()) {
323  // configure finished, nwk_configureWriteRsp will set next state on success.
324  return 10;
325  }
326  // Configuration not finished, execute again in 10ms
327  return 10;
328  case NWK_S_CONFIGSTARTWAIT:
329  // nwk_resetResume sets next state
330  return 50;
331  case NWK_S_SETDEVICETYPE:
332  // Reset bind state
333  nwk_flags &= NWK_FLAGIDX_NBOUND;
334  if (nwk_configureWrite()) {
335  // configure finished, nwk_configureWriteRsp will set next state on success.
336  return 50;
337  }
338  // Configuration not finished, execute again in 10ms
339  return 10;
340  case NWK_S_RESETWAIT:
341  // nwk_resetResume sets next state
342  return 50;
343  case NWK_S_CONFIGURE:
344  if (nwk_configureWrite()) {
345  // configure finished, nwk_configureWriteRsp will set next state on success.
346  return 10;
347  }
348  // Configuration not finished, execute again in 10ms
349  return 10;
350  case NWK_S_REGISTER:
351  // Registering application
352  if (nwk_register()) {
353  // nwk_registerRsp sets next state.
354  // if nwk_registerRsp is not called in 10ms, nwk_register will be called again.
355  return 10;
356  }
357  // Failed to send command, try again in 10ms
358  return 10;
359  case NWK_S_START:
360  // Reset bind state
361  nwk_flags &= NWK_FLAGIDX_NBOUND;
362  if (nwk_start()) {
363  // Set led indicator to starting network
364  led_redConfigure(1, 300);
365  // nwk_startRsp sets next state
366  nwk_freezeDetect = NWK_START_TIMEOUT; // give ~5s to network start, see NWK_S_STARTWAIT block.
367  return 500;
368  }
369  // Failed to send command, try again in 10ms
370  return 10;
371  case NWK_S_STARTWAIT:
373  if (!nwk_freezeDetect) {
374  nwk_freezeDetect = NWK_START_TIMEOUT;
375  nwk_flags ^= NWK_FLAGIDX_FAILJOIN;
376  if (nwk_flags & NWK_FLAGIDX_FAILJOIN) {
377  // try again, next time, if not EndDevice, try as router
379  } else {
382  } else
384  }
385  }
386  return 500;
387  case NWK_S_POSTSTARTCONFIGURE:
388  if (nwk_configureWrite()) {
389  // configure finished, nwk_configureWriteRsp will set next state on success.
390  return 10;
391  }
392  // Configuration not finished, execute again in 10ms
393  return 10;
394  case NWK_S_GETINFO:
395  if (nwk_getDeviceInfo()) {
396  // nwk_getDeviceInfoRsp sets next state
397  return 10;
398  }
399  // request next info in 5ms.
400  return 5;
401  case NWK_S_CHECKFORBIND:
402  // Check if device was a sink before CC2480 reset
403  if (nwk_flags & NWK_FLAGIDX_SINK)
404  if (!nwk_allow_bind(0xFF))
405  return 10;
406 
407  nwk_freezeDetect = 6 + ((((char *) &nwk_ieeeAddress)[0] & 0x0F) << 1);
408  nwk_currentState = NWK_S_RUNNING;
409  return 10;
410  case NWK_S_RUNNING:
411 
412  if (nwk_freezeDetect) {
413  switch (nwk_runCounter & 0x03) { // each of these tasks runs once per 4s (alternate):
414  case 0x00:
415  if (!nwk_sendHeartBeat())
416  return 5;
417  break;
418  case 0x01:
419  if (!(nwk_flags & (NWK_FLAGIDX_SINK | NWK_FLAGIDX_BOUND))) // not sink nor bound
420  if (!nwk_bind_device(1, NWK_CMDIDRPT, 0))
421  return 5;
422  break;
423  default:
424  break;
425  }
426 
427  portIndex = NWK_NEIGHBORMAX;
428  while (portIndex) {
429  portIndex--;
430  if (nwk_neighbors[portIndex].foreignAddress != 0xFFFF)
431  if (nwk_neighbors[portIndex].timeOut)
432  nwk_neighbors[portIndex].timeOut--;
433  else {
434  nwk_neighbors[portIndex].foreignAddress = 0xFFFF;
435  nwk_neighbors[portIndex].foreignPort = 0;
436  }
437  }
439  } else {
440  ccai_resetFull();
441  }
442 
443  nwk_runCounter++;
444  return 1000;
445  default:
446  nwk_currentState = NWK_S_INIT;
447  return 1;
448  }
449  return 500;
450 }
451 
459 void nwk_suspend() {
461  // states that must be set to an earlier one
462  nwk_lastParam = 0;
464  nwk_currentState = NWK_S_SUSPENDED;
465 }
466 
475 UInt8 nwk_wakeUp() {
476  switch (nwk_currentState) {
477  case NWK_S_CONFIGSTARTWAIT:
478  case NWK_S_RESETWAIT:
479  // device is in normal reset, it is not a simple wake-up
480  return 0;
481  case NWK_S_SUSPENDED: // Network is suspended, return to previous state.
483  nwk_lastParam = 0;
485  default: // If default, CC2480 was reset by its watch-dog
486  // check the need of an earlier state
487  switch (nwk_currentState) {
488  case NWK_S_REGISTER:
489  case NWK_S_START:
490  case NWK_S_POSTSTARTCONFIGURE:
492  nwk_lastParam = 0;
493  nwk_currentState = NWK_S_CONFIGURE;
494  break;
495  case NWK_S_STARTWAIT:
496  default:
497  nwk_currentState = NWK_S_START; // This is to call nwk_start again
498  break;
499  }
500  // Set led indicator to no network
501  led_redConfigure(5, 300);
502  break;
503  }
504  return 1;
505 }
506 
518  nwk_currentDevType = newType;
519  nwk_lastParam = 0;
521  nwk_currentState = NWK_S_CONFIGSTART;
522  // Set led indicator to no network
523  led_redConfigure(5, 0);
524 }
525 
536  if (nwk_currentState == NWK_S_RUNNING)
537  return nwk_currentDevType;
538  else
539  return NWK_DEVTYPE_NONE;
540 }
541 
550  nwk_lastParam = 0;
552  if (nwk_currentState == NWK_S_CONFIGSTARTWAIT)
553  nwk_currentState = NWK_S_SETDEVICETYPE;
554  else
555  nwk_currentState = NWK_S_CONFIGURE;
556  // Set led indicator to no network
557  led_redConfigure(5, 300);
558 }
559 
573  UInt8 v8;
574 
575  // Only write one configuration each time after the last one had success.
576  // On fail, nwk_lastParam is set to last one successful and written again.
577  switch (nwk_currentState) {
578  case NWK_S_CONFIGSTART:
579  switch (nwk_lastParamSuccess) {
580  case 0:
584  1, &v8))
585  nwk_lastParam = 1;
586  break;
587  case 1:
588  // configure finished, nwk_configureWriteRsp sets next state
589  return 1;
590  default: // If can't find last successful written configuration, restarting configuring
591  nwk_lastParam = 0;
593  break;
594  }
595  case NWK_S_SETDEVICETYPE:
596  switch (nwk_lastParamSuccess) {
597  case 0:
598  switch (nwk_currentDevType) {
601  break;
602  case NWK_DEVTYPE_ROUTER:
604  break;
607  break;
608  default:
610  break;
611  }
613  &v8))
614  nwk_lastParam = 1;
615  break;
616  case 1:
617  // configure finished, nwk_configureWriteRsp sets next state
618  return 1;
619  default: // If can't find last successful written configuration, restarting configuring
620  nwk_lastParam = 0;
622  break;
623  }
624  break;
625  case NWK_S_CONFIGURE:
627  switch (nwk_lastParamSuccess) {
628  case 0:
629  // swra175a.pdf - 6.2.3.1 ZCD_NV_STARTUP_OPTION and ZASA cc2480.h
632  } else {
633  // CCAI_CFGD_BIT_STARTOPT_AUTO_START: undocumented on swra175a.pdf
634  // got from ZASA cc2480.h file. See declaration at cc2480.h
636  //& CCAI_CFGD_BIT_STARTOPT_AUTO_START;
637  }
640  nwk_lastParam = 1;
641  break;
642  case 1:
643  // swra175a.pdf - 6.2.4.1 ZCD_NV_PANID
645  NWK_CFG_PANID))
646  nwk_lastParam = 2;
647  break;
648  case 2:
649  // swra175a.pdf - 6.2.4.2 ZCD_NV_CHANLIST
652  nwk_lastParam = 3;
653  break;
654  case 3:
655  // swra175a.pdf - 6.2.4.3 ZCD_NV_PRECFGKEY
657  16, NWK_CFG_PRECFGKEY))
658  nwk_lastParam = 4;
659  break;
660  case 4:
661  // swra175a.pdf - 6.2.4.4 ZCD_NV_PRECFGKEYS_ENABLE
665  nwk_lastParam = 5;
666  break;
667  case 5:
668  // swra175a.pdf - 6.2.4.5 ZCD_NV_SECURITY_MODE
672  nwk_lastParam = 6;
673  break;
674  case 6:
675  // swra175a.pdf - 6.2.4.6 ZCD_NV_BCAST_RETRIES
679  nwk_lastParam = 7;
680  break;
681  case 7:
682  // swra175a.pdf - 6.2.4.7 ZCD_NV_PASSIVE_ACK_TIMEOUT
686  nwk_lastParam = 8;
687  break;
688  case 8:
689  // swra175a.pdf - 6.2.4.8 ZCD_NV_BCAST_DELIVERY_TIME
693  nwk_lastParam = 9;
694  break;
695  case 9:
696  // swra175a.pdf - 6.2.4.9 ZCD_NV_ROUTE_EXPIRY_TIME
700  nwk_lastParam = 10;
701  break;
702  case 10:
703  // configure finished, nwk_configureWriteRsp sets next state
704  return 1;
705  default: // If can't find last successful written configuration, restarting configuring
706  nwk_lastParam = 0;
708  break;
709  }
710  break;
711  case NWK_S_POSTSTARTCONFIGURE:
713  switch (nwk_lastParamSuccess) {
714  case 0:
715  // swra175a.pdf - 6.2.3.1 ZCD_NV_STARTUP_OPTION
717  v8 = 0;
718  } else {
720  }
723  nwk_lastParam = 1;
724  break;
725  case 1:
726  // configure finished, nwk_configureWriteRsp sets next state
727  return 1;
728  default: // If can't find last successful written configuration, restarting configuring
729  nwk_lastParam = 0;
731  break;
732  }
733  break;
734  default:
735  break;
736  }
737  return 0;
738 }
739 
749 void nwk_configureWriteRsp(UInt8 status) {
750  switch (status) {
751  case CCAI_STA_ZSUCCESS:
753  break;
754  default:
755  // Device failed to configure
756  // In this program, the configuration will be sent again.
757  // This could result in an infinite loop if the state that prevents the configuration do
758  // not change, if it is the case, additional processing may be needed.
760  break;
761  }
762  // Test for end of each configuration group:
763  switch (nwk_currentState) {
764  case NWK_S_CONFIGSTART:
765  if (nwk_lastParamSuccess == 1) {
766  nwk_lastParam = 0;
768  nwk_currentState = NWK_S_CONFIGSTARTWAIT;
769  ccai_resetLight();
770  }
771  case NWK_S_SETDEVICETYPE:
772  if (nwk_lastParamSuccess == 1) {
773  nwk_lastParam = 0;
775  nwk_currentState = NWK_S_RESETWAIT;
776  ccai_resetLight();
777  }
778  case NWK_S_CONFIGURE:
779  if (nwk_lastParamSuccess == 10) {
780  nwk_lastParam = 0;
782  nwk_currentState = NWK_S_REGISTER;
783  }
784  break;
785  case NWK_S_POSTSTARTCONFIGURE:
786  if (nwk_lastParamSuccess == 1) {
787  nwk_lastParam = 0;
789  nwk_currentState = NWK_S_GETINFO;
790  }
791  break;
792  default:
793  break;
794  }
795 }
796 
807 UInt8 nwk_register() {
812 }
813 
823 void nwk_registerRsp(UInt8 status) {
824  if (status == CCAI_STA_ZSUCCESS) {
825  // Application is registered, start network
826  nwk_currentState = NWK_S_START;
827  }
828 }
829 
839 UInt8 nwk_start() {
840  return ccai_s_zb_start_request();
841 }
842 
850 void nwk_startRsp() {
851  // CC2480 is sending 0x66 0x00 instead of 0x66 0x03 after 0x26 0x03 and
852  // instead of 0x66 0x02 after 0x26 0x02
853  // so ignore the response if network state is NWK_S_RUNNING or NWK_S_CHECKFORBIND.
854  if ((nwk_currentState != NWK_S_RUNNING)
855  && (nwk_currentState != NWK_S_CHECKFORBIND))
856  nwk_currentState = NWK_S_STARTWAIT;
857 }
858 
868 void nwk_startConfirm(UInt8 status) {
869  if (status == CCAI_STA_ZSUCCESS) {
870  // Network is up
871  nwk_currentState = NWK_S_POSTSTARTCONFIGURE;
872  }
873 }
874 
890 UInt8 nwk_allow_bind(UInt8 timeout) {
891  return ccai_s_zb_allow_bind(timeout);
892 }
893 
902  // CC2480 is sending 6600, not 6602, so this code will not run.
903 }
904 
913 void nwk_allow_bindConfirm(char *pBuf) {
914  // another device bound to this one
915 #if DEBUG!=1
916  // If debug, all received data is forward to serial by SPI, else forward here.
917  uart_forwardCmd(pBuf);
918 #endif
919 }
920 
932 UInt8 nwk_bind_device(UInt8 create, UInt16 commandId, uint64_t destination) {
933  return ccai_s_zb_bind_device(create, commandId, destination);
934 }
935 
942 
943 }
944 
950 void nwk_bind_deviceConfirm(char *pBuf) {
951  if ((pBuf[3] == NWK_CMDIDRPT) && (pBuf[4] == 0)) { // (UInt16) pBuf[3] == NWK_CMDIDRPT
952 #if DEBUG!=1
953  // If debug, all received data is forward to serial by SPI, else forward here.
954  uart_forwardCmd(pBuf);
955 #endif
956  if (pBuf[5] == CCAI_STA_ZSUCCESS)
957  nwk_flags |= NWK_FLAGIDX_BOUND;
958  else
959  nwk_flags &= NWK_FLAGIDX_NBOUND;
960  }
961 }
962 
976  // swra175a.pdf - 6.3.12 ZB_GET_DEVICE_INFO
977  // read one information each time after last value read have success
979  // The nwk_lastParam and nwk_lastParamSuccess used to be set to CCAI_INFO_XXX, but this
980  // relies on no configuration Id being 0 (zero), but CCAI_INFO_STATE = 0, so
981  // nwk_lastParamSuccessit was changed to sequential numbers.
982 
983  switch (nwk_lastParamSuccess) {
984  case 0:
986  nwk_lastParam = 1;
987  break;
988  case 1:
990  nwk_lastParam = 2;
991  break;
992  case 2:
994  nwk_lastParam = 3;
995  break;
996  case 3:
998  nwk_lastParam = 4;
999  break;
1000  case 4:
1002  nwk_lastParam = 5;
1003  break;
1004  case 5:
1006  nwk_lastParam = 6;
1007  break;
1008  case 6:
1010  nwk_lastParam = 7;
1011  break;
1012  case 7:
1014  nwk_lastParam = 8;
1015  break;
1016  case 8:
1017  // all parameters have been requested
1018  return 1;
1019  default: // If can't find last successful information, restart reading
1020  nwk_lastParam = 0;
1022  break;
1023  }
1024  }
1025  return 0;
1026 }
1027 
1038 void nwk_getDeviceInfoRsp(UInt8 param, void *pValue) {
1039  // Not all information is useful, and there isn't a lot of gratuitous RAM, so only needed
1040  // information is stored.
1041  switch (param) {
1042  case CCAI_INFO_STATE:
1043  break;
1044  case CCAI_INFO_IEEEADDRESS:
1045  nwk_ieeeAddress = *((uint64_t *) pValue);
1046  break;
1048  nwk_address = *((UInt16 *) pValue);
1049  break;
1051  break;
1053  break;
1054  case CCAI_INFO_ZBCHANNEL:
1055  break;
1056  case CCAI_INFO_ZBPANID:
1057  break;
1059  // Last parameter, pass network to next state
1060  // Configure led indicator
1061  switch (nwk_currentDevType) {
1063  led_redConfigure(2, 600);
1064  break;
1065  case NWK_DEVTYPE_ROUTER:
1066  led_redConfigure(1, 800);
1067  break;
1068  case NWK_DEVTYPE_ENDDEVICE:
1069  led_redConfigure(1, 2800);
1070  break;
1071  default:
1072  // Error, no valid device type selected, reset MSP430
1073  WDTCTL = 0;
1074  break;
1075  }
1076  break;
1077  default:
1078  break;
1079  }
1081  if (nwk_lastParamSuccess == 8) {
1082  nwk_lastParam = 0;
1084  nwk_currentState = NWK_S_CHECKFORBIND;
1085  // PTP: end PTP initialization or reset it if network just reconfigured
1086  ptp_initEnd();
1087  }
1088 
1089 }
1090 
1107 UInt8 nwk_setPermitJoin(UInt8 timeout) {
1108  if (nwk_currentState != NWK_S_RUNNING) {
1109  return 0;
1110  }
1111  return ccai_s_zb_permit_joining_request(0xFFFC, timeout);
1112 }
1113 
1122  // no action needed
1123 }
1124 
1134 UInt8 nwk_allowJoin() {
1135  return nwk_setPermitJoin(0xFF);
1136 }
1137 
1146  return nwk_setPermitJoin(0x00);
1147 }
1148 
1156 UInt8 nwk_isClient() {
1159  && (nwk_currentState == NWK_S_RUNNING);
1160 }
1161 
1170 UInt8 nwk_isSink() {
1171  return nwk_flags & NWK_FLAGIDX_SINK;
1172 }
1173 
1182 UInt8 nwk_isBound() {
1183  return nwk_flags & NWK_FLAGIDX_BOUND;
1184 }
1185 
1186 
1198 void nwk_setSink(UInt8 sink) {
1199  if (sink) {
1200  if (nwk_allow_bind(0xFF))
1201  nwk_flags |= NWK_FLAGIDX_SINK;
1202  } else {
1203  if (nwk_allow_bind(0))
1204  nwk_flags &= NWK_FLAGIDX_NSINK;
1205  }
1206 }
1207 
1218  return nwk_address;
1219 }
1220 
1231  return nwk_ieeeAddress;
1232 }
1233 
1245 uint64_t * nwk_getPIeeeAddress() {
1246  return &nwk_ieeeAddress;
1247 }
1248 
1264 UInt8 nwk_startFrame(UInt16 destination, UInt16 cmdId, UInt8 radius, UInt8 len) {
1265  if (nwk_currentState != NWK_S_RUNNING) {
1266  return 0;
1267  }
1268  return ccai_s_zb_send_data_request_begin(destination, cmdId, nwk_dataHandle,
1269  NWK_DEFACK, radius, len);
1270 }
1271 
1285 UInt8 nwk_snd(UInt8 len, void *pBuf) {
1286  return ccai_s_zb_send_data_request_payload(len, pBuf);
1287 }
1288 
1300 void nwk_endFrame(UInt8 forwardToSerial) {
1301  ccai_s_zb_send_data_request_end(forwardToSerial);
1302  nwk_dataHandle++;
1303 }
1304 
1317 UInt8 nwk_sndUInt8(UInt8 v) {
1318  return nwk_snd(1, &v);
1319 }
1320 
1333 UInt8 nwk_sndUInt16(UInt16 v) {
1334  return nwk_snd(2, &v);
1335 }
1336 
1349 UInt8 nwk_sndUInt32(UInt32 *p) {
1350  return nwk_snd(4, p);
1351 }
1352 
1366 UInt8 nwk_sndUInt48(uint64_t *p) {
1367  return nwk_snd(6, p);
1368 }
1369 
1380 UInt8 nwk_sndUInt64(uint64_t *p) {
1381  return nwk_snd(8, p);
1382 }
1383 
1394 UInt8 nwk_sndInt64(int64_t *p) {
1395  return nwk_snd(8, p);
1396 }
1397 
1407 void nwk_send_dataConfirm(UInt8 dataHandle, UInt8 status) {
1408  if (status == CCAI_STA_ZAPSNOBOUNDDEVICE) // ZApsNoBoundDevice
1409  nwk_flags &= NWK_FLAGIDX_NBOUND;
1410  if (status == CCAI_STA_ZFAILURE) {
1411  if (nwk_flags & NWK_FLAGIDX_SENDFAIL) {
1412  nwk_flags &= NWK_FLAGIDX_NSENDFAIL & NWK_FLAGIDX_NBOUND;
1413  } else {
1414  nwk_flags |= NWK_FLAGIDX_SENDFAIL;
1415  }
1416  } else {
1417  if (nwk_flags & NWK_FLAGIDX_BOUND) {
1418  nwk_flags &= NWK_FLAGIDX_NSENDFAIL;
1419  }
1420  }
1421 }
1422 
1430 void nwk_rcv(char *pBuf) {
1431  UInt16 src;
1432  UInt16 cmd;
1433  UInt16 len;
1434  UInt8 portNumber;
1435  UInt8 i;
1436 
1437  nwk_freezeDetect = 4 + ((char *) &nwk_ieeeAddress)[0];
1438 
1439  src = pBuf[3] | (pBuf[4] << 8);
1440  cmd = pBuf[5] | (pBuf[6] << 8);
1441  len = pBuf[7] | (pBuf[8] << 8);
1442 
1443  switch (cmd) {
1444  case NWK_CMDIDHEARTBEAT:
1445  // heart beat
1446  portNumber = nwk_getNeighborPort(src);
1447  if (portNumber) {
1448  nwk_neighbors[portNumber - 1u].timeOut =
1450  } else {
1451  portNumber = nwk_registerNeighbor(src);
1452  }
1453  if (portNumber) {
1454  // verify if neighbor know this device, if so, register the port reported by the neighbor
1455  pBuf += 9;
1456  i = 0;
1457  while (i < len) {
1458  if (nwk_address == (pBuf[i] | (pBuf[i + 1u] << 8))) {
1459  nwk_neighbors[portNumber - 1u].foreignPort = pBuf[i + 2u];
1460  // no need to continue scan, device was found:
1461  i = len;
1462  } else
1463  i += 3;
1464  }
1465  } else {
1466  // neighbor is unknown and not enough resources to record a new one.
1467  }
1468  case NWK_CMDIDRPT:
1469  // report
1470 #if DEBUG!=1
1471  // If debug, all received data is forward to serial by SPI, else forward here if device is in sink mode.
1472  if (nwk_isSink())
1473  uart_forwardCmd(pBuf);
1474 #endif
1475  break;
1476  case NWK_CMDIDPTP:
1477  // PTP
1478 #if DEBUG!=1
1479  // If debug, all received data is forward to serial by SPI, else forward here.
1480  uart_forwardCmd(pBuf);
1481 #endif
1482  // only process PTP messages from known neighbors from the right port or packet is to all ports.
1483  portNumber = nwk_getNeighborPort(src);
1484  if (portNumber
1485  && ((nwk_getNeighborForeignPort(portNumber) == pBuf[9 + 28])
1486  || ((pBuf[9 + 28] | (pBuf[9 + 29] << 8)) == 0xFFFF))) {
1487  ptp_rcvmessage(&(pBuf[9]), portNumber, len);
1488  }
1489  break;
1490  default:
1491  break;
1492  }
1493 }
1494 
1503  UInt8 size;
1504  UInt8 portIndex;
1505 
1506  size = 0;
1507  portIndex = NWK_NEIGHBORMAX;
1508  while (portIndex) {
1509  portIndex--;
1510  if (nwk_neighbors[portIndex].foreignAddress != 0xFFFF) {
1511  size += 3;
1512  }
1513  };
1514 
1515  if (nwk_startFrame(0xFFFF, NWK_CMDIDHEARTBEAT, 1, size)) {
1516  portIndex = NWK_NEIGHBORMAX;
1517  while (portIndex) {
1518  portIndex--;
1519  if (nwk_neighbors[portIndex].foreignAddress != 0xFFFF) {
1520  nwk_sndUInt16(nwk_neighbors[portIndex].foreignAddress);
1521  nwk_sndUInt8(portIndex + 1);
1522  }
1523  };
1524  nwk_endFrame(FALSE);
1525  return 1;
1526  }
1527  return 0;
1528 }
1529 
1539 UInt8 nwk_getNeighborPort(UInt16 a) {
1540  UInt8 portIndex;
1541 
1542  portIndex = NWK_NEIGHBORMAX;
1543  while (portIndex) {
1544  portIndex--;
1545  if (nwk_neighbors[portIndex].foreignAddress == a) {
1546  return portIndex + 1;
1547  }
1548  };
1549  return 0;
1550 }
1551 
1562 UInt8 nwk_getNeighborForeignPort(UInt8 portNumber) {
1563  if ((!portNumber) || (portNumber > NWK_NEIGHBORMAX))
1564  return 0;
1565  portNumber--; // portIndex from here
1566  return nwk_neighbors[portNumber].foreignPort;
1567 }
1568 
1578 UInt16 nwk_getNeighborAddress(UInt8 portNumber) {
1579  if ((!portNumber) || (portNumber > NWK_NEIGHBORMAX))
1580  return 0xFFFF;
1581  portNumber--; // portIndex from here
1582  return nwk_neighbors[portNumber].foreignAddress;
1583 
1584 }
1585 
1595 UInt8 nwk_registerNeighbor(UInt16 a) {
1596  UInt8 portIndex;
1597 
1598  portIndex = NWK_NEIGHBORMAX;
1599  while (portIndex) {
1600  portIndex--;
1601  if (nwk_neighbors[portIndex].foreignAddress == 0xFFFF) {
1602  nwk_neighbors[portIndex].foreignAddress = a;
1603  nwk_neighbors[portIndex].foreignPort = 0;
1604  nwk_neighbors[portIndex].timeOut = NWK_NEIGHBORHEARTBEATTIMEOUT;
1605  return portIndex + 1;
1606  }
1607  };
1608  return 0;
1609 }
UInt8 nwk_isSink()
Is sink.
Definition: nwk.c:1170
Coordinator.
Definition: nwk.h:223
Network functions interface.
uint64_t * nwk_getPIeeeAddress()
Get pointer to the IEEE address.
Definition: nwk.c:1245
void nwk_allow_bindConfirm(char *pBuf)
Allow bind confirmation.
Definition: nwk.c:913
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:244
UInt8 nwk_sndInt64(int64_t *p)
Send signed 64 bits integer.
Definition: nwk.c:1394
#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:807
UInt16 nwk_address
Short address of the device.
Definition: nwk.c:234
UInt8 nwk_start()
Start network request.
Definition: nwk.c:839
UInt8 nwk_sndUInt64(uint64_t *p)
Send unsigned 64 bits integer.
Definition: nwk.c:1380
UInt8 nwk_sendHeartBeat()
Send heart beat.
Definition: nwk.c:1502
UInt8 nwk_setPermitJoin(UInt8 timeout)
Permit join request.
Definition: nwk.c:1107
void nwk_allow_bindRsp()
Allow bind response.
Definition: nwk.c:901
UInt8 nwk_getNeighborForeignPort(UInt8 portNumber)
Get neighbor foreign port.
Definition: nwk.c:1562
None, invalid in a network.
Definition: nwk.h:226
#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:823
UInt8 nwk_wakeUp()
Network wake up.
Definition: nwk.c:475
void nwk_suspend()
network suspend
Definition: nwk.c:459
void nwk_setPermitJoinRsp()
Permit join response.
Definition: nwk.c:1121
void nwk_configureWriteRsp(UInt8 status)
Response to a configuration write.
Definition: nwk.c:749
#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:1366
void nwk_setSink(UInt8 sink)
Set sink.
Definition: nwk.c:1198
Router.
Definition: nwk.h:224
#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
void ptp_initEnd()
PTP initialization completion.
Definition: ptp.c:128
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:1156
void nwk_bind_deviceRsp()
Bind device response.
Definition: nwk.c:941
#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:114
#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:1217
#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:159
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:1349
UInt8 nwk_isBound()
Is bound.
Definition: nwk.c:1182
void ccai_resetFull()
Full reset.
Definition: cc2480ai.c:616
UInt8 nwk_lastParamSuccess
Last successful parameter.
Definition: nwk.c:224
#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:203
#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:1333
PTP interface.
#define NWK_CMDIDPTP
Command id for PTP messages.
Definition: nwk.h:169
#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:850
#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:249
void nwk_setDeviceType(nwk_devType newType)
Set device type.
Definition: nwk.c:517
UInt8 nwk_sndUInt8(UInt8 v)
Send unsigned 8 bits integer.
Definition: nwk.c:1317
UInt8 nwk_disallowJoin()
Disallow join.
Definition: nwk.c:1145
UInt8 nwk_getDeviceInfo()
Get device information request.
Definition: nwk.c:975
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:277
void nwk_resetResume()
Resume from CC2480 reset.
Definition: nwk.c:549
UInt8 uart_forwardCmd(char *pBuf)
Forward command.
Definition: uart.c:741
#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:239
#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:213
void led_redConfigure(UInt8 n, UInt16 offDelay)
Configures red led.
Definition: led.c:201
UInt16 nwk_process()
Network process.
Definition: nwk.c:311
#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:229
#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:535
#define CCAI_STA_ZSUCCESS
ZSuccess.
Definition: cc2480ai.h:514
void nwk_rcv(char *pBuf)
Network receive.
Definition: nwk.c:1430
#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:1407
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:1134
void nwk_getDeviceInfoRsp(UInt8 param, void *pValue)
Get device information response.
Definition: nwk.c:1038
uint64_t nwk_getIeeeAddress()
Get IEEE address.
Definition: nwk.c:1230
Neighbor data.
Definition: nwk.h:234
UInt8 nwk_bind_device(UInt8 create, UInt16 commandId, uint64_t destination)
Bind device request.
Definition: nwk.c:932
#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:1264
#define CCAI_INFO_IEEEADDRESS
Request IEEE address of the device.
Definition: cc2480ai.h:476
End device.
Definition: nwk.h:225
#define NWK_DEFACK
Default ACK request. On transmitted packets, 1 to request ACK, 0 to don't.
Definition: nwk.h:195
#define NWK_CFG_APPENDPOINT
The endpoint of the device.
Definition: nwk.h:101
UInt8 nwk_runCounter
Children information.
Definition: nwk.c:254
UInt8 nwk_snd(UInt8 len, void *pBuf)
Send data.
Definition: nwk.c:1285
#define NWK_DEVTYPE_DEFALUT
The default device type on network initialization.
Definition: nwk.h:208
nwk_state
States for the network.
Definition: nwk.c:135
UInt8 nwk_configureWrite()
Write configuration.
Definition: nwk.c:572
nwk_state nwk_returnState
State on suspend.
Definition: nwk.c:210
#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 ptp_rcvmessage(ptp_octet *pBuf, ptp_uinteger8 portNumber, ptp_uinteger16 size)
Receive message.
Definition: ptp.c:257
void nwk_bind_deviceConfirm(char *pBuf)
Bind device confirmation.
Definition: nwk.c:950
#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:217
#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:890
#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:1539
void nwk_endFrame(UInt8 forwardToSerial)
End frame.
Definition: nwk.c:1300
nwk_devType
Device types.
Definition: nwk.h:222
UInt8 nwk_registerNeighbor(UInt16 a)
Register neighbor.
Definition: nwk.c:1595
UInt16 nwk_getNeighborAddress(UInt8 portNumber)
Get neighbor address.
Definition: nwk.c:1578
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:868
#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