Skip to content

Commit bcbf2ff

Browse files
committed
Z/IP Gateway Watchdog (Reopen for review) (#4)
* FIX ZGW-3422: zipgateway got stuck in RD_probe_cc_version.c + Fixed zipgw stuck if controller send VERSION_COMMAND_CLASS_GET in the inclusion phase without receiving VERSION_COMMAND_CLASS_REPORT from the end-node + Put the NULL checking of pCmd first; added extra NULL checking for ep & ep->node Fixes: #ZGW-3422 Signed-off-by: silabs-tuD <tu.dao@silabs.com> Reviewed-on: SiliconLabs#34 * ZGW-3422: Z/IP got stuck after sending VERSION_COMMAND_CLASS_GET without receving report from the end-node (#1) * ZGW-3422: Fix: Z/IP GW got stuck without receiving VERSION_COMMAND_CLASS_REPORT from the end-node * Put the NULL checking of pCmd first; added extra NULL checking for ep & ep->node * Fix/zgw 3422 getting stuck on command class version (#2) + Fixed errors on ctest with the Null Check of pCmd * Z/IP Gateway Watchdog Implement the watchdog feature for Z/IP Gateway working as below: - Create a “soft_reset_timer” with 2-minnute timeout. - During 2 mins, if Z/IP GW only receive TRANSMIT_COMPLETE_FAIL status, it will try to resend the previous failed serial-API command to the controller. - After timeout (2 mins), Z/IP GW will call ZW_SoftReset() to reset the controller and wait for 10 seconds to ensure the reset process is successful. - Z/IP GW will also send a soft_reset report back to ZWare. Fixes: #ZGW-3433 Signed-off-by: silabs-tuD <tu.dao@silabs.com> Authored-by: hanguyen3_silabs <Ha.Nguyen3@silabs.com> Reviewed-by: silabs-tuD <tu.dao@silabs.com> Origin: SiliconLabs#35 * Resolve comments on PR --------- Signed-off-by: silabs-tuD <tu.dao@silabs.com>
1 parent 3b3ef4b commit bcbf2ff

8 files changed

Lines changed: 319 additions & 64 deletions

File tree

contiki/platform/linux/parse_config.c

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,9 +433,38 @@ void ConfigInit()
433433

434434
cfg.single_classic_temp_association = 0;
435435
}
436+
437+
/* Parse TimeResendSerial config */
438+
endptr = NULL;
439+
int time_resend_serial;
440+
/* Convert time resend serial into string */
441+
s = config_get_val("TimeResendSerial", NULL);
442+
if (s != NULL) {
443+
LOG_PRINTF("TimeResendSerial: %s\n", s);
444+
/* Convert the time reset serial into integer */
445+
time_resend_serial = strtol(s, &endptr, 0);
446+
/* Invalid if further characters are found after number or it's not numeric at all */
447+
if (*endptr != '\0' || endptr == s) {
448+
WRN_PRINTF("Failed to convert time_resend_serial to integer! Set to minimum value\n");
449+
/* Set to minimum value: 20 */
450+
time_resend_serial = 20;
451+
}
452+
else {
453+
/* Filtering the time resend serial within a proper range [20 to 80] */
454+
time_resend_serial = (time_resend_serial > 80) ? 80
455+
: (time_resend_serial < 20) ? 20
456+
: time_resend_serial;
457+
}
458+
cfg.time_resend_serial = time_resend_serial;
459+
}
460+
else {
461+
/* Default value if not set in config file */
462+
cfg.time_resend_serial = 50;
463+
}
464+
DBG_PRINTF("cfg.time_resend_serial: %d\n", cfg.time_resend_serial);
436465
}
437466

438-
/*We wan't command line to override config file.*/
467+
/*We want command line to override config file.*/
439468
parse_prog_args();
440469
}
441470

files/zipgateway.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,4 @@ ZWRFRegion=0x00
3636
#Measured0dBmPower=
3737
#ZipDeviceID=AABBCCDDEEFF
3838
#MaxLRTxPowerLevel=
39+
TimeResendSerial=50

src/ZIP_Router.c

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ ApplicationCommandHandlerZIP(ts_param_t *p, ZW_APPLICATION_TX_BUFFER *pCmd,
381381
if (cmdLength == 0)
382382
return;
383383

384-
LOG_PRINTF("ApplicationCommandHandler %d->%d [%s] \n",
384+
LOG_PRINTF("ApplicationCommandHandlerZIP %d->%d [%s] \n",
385385
(int )p->snode,(int)p->dnode, print_frame((const char *)pCmd, cmdLength));
386386

387387

@@ -634,17 +634,18 @@ ApplicationCommandHandlerSerial(BYTE rxStatus, nodeid_t destNode, nodeid_t sourc
634634
static u8_t
635635
zwave_send(uip_lladdr_t *addr)
636636
{
637+
LOG_PRINTF("zwave_send()\n");
637638
nodeid_t nodeid = 0;
638639
/* Is Unicast? */
639640
if (addr)
640641
{
641-
/* DBG_PRINTF(" %02x:%02x:%02x:%02x:%02x:%02x length %i",
642+
DBG_PRINTF(" %02x:%02x:%02x:%02x:%02x:%02x length %i",
642643
pan_lladdr.addr[0],
643644
pan_lladdr.addr[1],
644645
pan_lladdr.addr[2],
645646
pan_lladdr.addr[3],
646647
pan_lladdr.addr[4],
647-
pan_lladdr.addr[5],uip_len);*/
648+
pan_lladdr.addr[5],uip_len);
648649

649650
if(memcmp(addr->addr, tun_lladdr.addr, 6) == 0) /* Is L2 address in portal */
650651
{
@@ -662,7 +663,7 @@ zwave_send(uip_lladdr_t *addr)
662663
{
663664
if (landev_send)
664665
{
665-
//DBG_PRINTF("Send to lan\n");
666+
DBG_PRINTF("Send to lan\n");
666667
landev_send(addr);
667668
}
668669
}
@@ -675,6 +676,7 @@ zwave_send(uip_lladdr_t *addr)
675676
if (!(UIP_IP_BUF ->proto == UIP_PROTO_ICMP6
676677
&& UIP_ICMP_BUF ->type == ICMP6_RPL))
677678
{
679+
DBG_PRINTF("Do not send RPL messages to LAN | landev_send: %p\n", landev_send);
678680
if (landev_send)
679681
/* Multicast, send to all interfaces */
680682
landev_send(addr);
@@ -1348,7 +1350,7 @@ PROCESS_THREAD(zip_process, ev, data)
13481350

13491351
while(1)
13501352
{
1351-
//DBG_PRINTF("Event ***************** %x ********************\n",ev);
1353+
DBG_PRINTF("Event ***************** %x ********************\n",ev);
13521354
#ifndef __ASIX_C51__
13531355
if(ev == serial_line_event_message)
13541356
{
@@ -1667,18 +1669,22 @@ PROCESS_THREAD(zip_process, ev, data)
16671669

16681670
/* Check if we are waiting for backup */
16691671
zip_router_check_backup(data);
1670-
} else if (ev == ZIP_EVENT_NODE_PROBED)
1672+
}
1673+
else if (ev == ZIP_EVENT_NODE_PROBED)
16711674
{
1675+
LOG_PRINTF("ZIP_EVENT_NODE_PROBED\n");
16721676
/* Tell NMS that the node probe has completed. */
16731677
NetworkManagement_node_probed(data);
1674-
} else if (ev == ZIP_EVENT_ALL_IPV4_ASSIGNED
1678+
}
1679+
else if (ev == ZIP_EVENT_ALL_IPV4_ASSIGNED
16751680
|| ev == ZIP_EVENT_NODE_DHCP_TIMEOUT)
16761681
{
16771682
/* FIXME: We trigger the script here. But what if few nodes do not get DHCP lease. THen
16781683
we dont get this event. Find a correct place where GW gets the IP address or?
16791684
*/
16801685
if (ev == ZIP_EVENT_ALL_IPV4_ASSIGNED)
16811686
{
1687+
LOG_PRINTF("ZIP_EVENT_ALL_IPV4_ASSIGNED\n");
16821688
char ip[IPV6_STR_LEN] = {0};
16831689
char *execve_args[2] = {0};
16841690
pid_t pid = 0;
@@ -1746,7 +1752,9 @@ PROCESS_THREAD(zip_process, ev, data)
17461752
/* Tell NM to poll for its requirements. This will set
17471753
* NETWORK_UPDATE_FLAG_VIRTUAL and maybe other flags. */
17481754
NetworkManagement_NetworkUpdateStatusUpdate(0);
1749-
} else if(ev == ZIP_EVENT_NETWORK_MANAGEMENT_DONE) {
1755+
}
1756+
else if(ev == ZIP_EVENT_NETWORK_MANAGEMENT_DONE) {
1757+
LOG_PRINTF("ZIP_EVENT_NETWORK_MANAGEMENT_DONE\n");
17501758
/* Always send node list report when GW just starts */
17511759
if (zgw_initing == TRUE) {
17521760
set_should_send_nodelist();
@@ -1764,28 +1772,35 @@ PROCESS_THREAD(zip_process, ev, data)
17641772
* now. */
17651773
zgw_component_done(ZGW_NM, data);
17661774
}
1767-
} else if(ev == ZIP_EVENT_NM_VIRT_NODE_REMOVE_DONE) {
1775+
}
1776+
else if(ev == ZIP_EVENT_NM_VIRT_NODE_REMOVE_DONE) {
17681777
DBG_PRINTF(" ZIP_EVENT_NM_VIRT_NODE_REMOVE_DONE triggered\n");
17691778
NetworkManagement_VirtualNodes_removed();
1770-
} else if (ev == ZIP_EVENT_BACKUP_REQUEST) {
1779+
}
1780+
else if (ev == ZIP_EVENT_BACKUP_REQUEST) {
1781+
LOG_PRINTF("ZIP_EVENT_BACKUP_REQUEST\n");
17711782
if (ZGW_COMPONENT_ACTIVE(ZGW_BU)) {
17721783
WRN_PRINTF("Backup already requested once.\n");
17731784
}
17741785
zgw_component_start(ZGW_BU);
17751786
zip_router_check_backup(data);
1776-
} else if (ev == ZIP_EVENT_COMPONENT_DONE) {
1777-
if (ZGW_COMPONENT_ACTIVE(ZGW_BU)) {
1778-
if (data == (void*)extend_middleware_probe_timeout) {
1779-
DBG_PRINTF("NetworkManagement done after middleware probe timeout.\n");
1780-
} else {
1781-
DBG_PRINTF("Component done with data: %p\n", data);
1782-
}
1783-
}
1784-
zip_router_check_backup(data);
1785-
} else if (ev == PROCESS_EVENT_TIMER) {
1786-
if (data == (void*)&zgw_bu_timer) {
1787-
zip_router_check_backup(data);
1788-
}
1787+
}
1788+
else if (ev == ZIP_EVENT_COMPONENT_DONE) {
1789+
LOG_PRINTF("ZIP_EVENT_COMPONENT_DONE\n");
1790+
if (ZGW_COMPONENT_ACTIVE(ZGW_BU)) {
1791+
if (data == (void*)extend_middleware_probe_timeout) {
1792+
DBG_PRINTF("NetworkManagement done after middleware probe timeout.\n");
1793+
} else {
1794+
DBG_PRINTF("Component done with data: %p\n", data);
1795+
}
1796+
}
1797+
zip_router_check_backup(data);
1798+
}
1799+
else if (ev == PROCESS_EVENT_TIMER) {
1800+
LOG_PRINTF("PROCESS_EVENT_TIMER\n");
1801+
if (data == (void*)&zgw_bu_timer) {
1802+
zip_router_check_backup(data);
1803+
}
17891804
}
17901805

17911806
PROCESS_WAIT_EVENT()

src/ZW_classcmd_ex.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,4 +1214,10 @@ typedef struct _ZW_EXTENDED_NODE_ADD_STATUS_1BYTE_FRAME_
12141214
#define EXTENDED_STATISTICS_REPORT 0X0C
12151215
#define COMMAND_CLASS_NO_OPERATION_LR 0x04
12161216

1217+
1218+
// Soft Reset Status
1219+
#define COMMAND_ZIP_SOFT_RESET_REPORT 0x04
1220+
#define STATUS_SOFT_RESET_OK 0x0
1221+
#define STATUS_SOFT_RESET_FAIL 0xFF
1222+
12171223
#endif /* ZW_CLASSCMD_EX_H_ */

0 commit comments

Comments
 (0)