Skip to content

Commit 61f520f

Browse files
author
Mika Tervonen
committed
Added api to configure network size parameters
Modifies the timing configuration of Wi-SUN discovery and RPL configuration Created automatic RPL configuration that identifies the size of the network and then adjusts the RPL parameter in border router Added three different network size parameters that are used for Discovery Updated the default RPL parameter to newest specification Added support for RPL to modify configuration in runtime
1 parent 4d26258 commit 61f520f

File tree

11 files changed

+207
-49
lines changed

11 files changed

+207
-49
lines changed

nanostack/ws_management_api.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ extern "C" {
7575
#define CHANNEL_SPACING_100 0x03 // 100 khz
7676
#define CHANNEL_SPACING_250 0x04 // 250 khz
7777

78+
#define NETWORK_SIZE_AUTOMATIC 0x00
79+
#define NETWORK_SIZE_SMALL 0x01
80+
#define NETWORK_SIZE_LARGE 0x10
81+
7882

7983
/** Temporary API change flag. this will be removed when new version of API is implemented on applications
8084
*
@@ -126,6 +130,27 @@ int ws_management_regulatory_domain_set(
126130
uint8_t operating_class,
127131
uint8_t operating_mode);
128132

133+
/**
134+
* Set timing parameters related to network size.
135+
*
136+
* timing parameters follows the specification example from Wi-SUN specification
137+
*
138+
* Default value: automatic
139+
* small network size: hundreds of devices
140+
* Large network size: thousands of devices
141+
* automatic: when discovering the network network size is learned
142+
* from advertisements and timings adjusted accordingly
143+
*
144+
* \param interface_id Network interface ID.
145+
* \param network_size define from NETWORK_SIZE_*.
146+
*
147+
* \return 0, Init OK.
148+
* \return <0 Init fail.
149+
*/
150+
int ws_management_network_size_set(
151+
int8_t interface_id,
152+
uint8_t network_size);
153+
129154
/**
130155
* Set channel mask for FHSS operation.
131156
*

source/6LoWPAN/ws/ws_bbr_api.c

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "RPL/rpl_data.h"
3232
#include "Common_Protocols/icmpv6.h"
3333
#include "Common_Protocols/icmpv6_radv.h"
34+
#include "ws_management_api.h"
3435
#include "net_rpl.h"
3536
#include "Service_Libs/nd_proxy/nd_proxy.h"
3637
#include "6LoWPAN/ws/ws_bbr_api_internal.h"
@@ -55,32 +56,55 @@ static uint8_t static_dodag_id[16] = {0};
5556
static uint8_t global_dodag_id[16] = {0};
5657
static uint32_t bbr_delay_timer = 20; // initial delay.
5758

59+
static rpl_dodag_conf_t rpl_conf = {
60+
// Lifetime values
61+
.default_lifetime = 120,
62+
.lifetime_unit = 60,
63+
.objective_code_point = 1, // MRHOF algorithm used
64+
.authentication = 0,
65+
.path_control_size = 5,
66+
.dag_max_rank_increase = 2048,
67+
.min_hop_rank_increase = 256,
68+
// DIO configuration
69+
.dio_interval_min = WS_RPL_DIO_IMIN,
70+
.dio_interval_doublings = WS_RPL_DIO_DOUBLING,
71+
.dio_redundancy_constant = WS_RPL_DIO_REDUNDANCY
72+
};
73+
74+
void ws_bbr_rpl_config(uint8_t imin, uint8_t doubling, uint8_t redundancy)
75+
{
76+
if (imin == 0 || doubling == 0) {
77+
// use default values
78+
imin = WS_RPL_DIO_IMIN;
79+
doubling = WS_RPL_DIO_DOUBLING;
80+
redundancy = WS_RPL_DIO_REDUNDANCY;
81+
}
82+
if (rpl_conf.dio_interval_min == imin &&
83+
rpl_conf.dio_interval_doublings == doubling &&
84+
rpl_conf.dio_redundancy_constant == redundancy) {
85+
// Same values no update needed
86+
return;
87+
}
88+
rpl_conf.dio_interval_min = imin;
89+
rpl_conf.dio_interval_doublings = doubling;
90+
rpl_conf.dio_redundancy_constant = redundancy;
91+
if (protocol_6lowpan_rpl_root_dodag) {
92+
rpl_control_update_dodag_config(protocol_6lowpan_rpl_root_dodag, &rpl_conf);
93+
rpl_control_increment_dodag_version(protocol_6lowpan_rpl_root_dodag);
94+
}
95+
}
96+
5897
static void ws_bbr_rpl_root_start(uint8_t *dodag_id)
5998
{
6099
tr_info("RPL root start");
61-
rpl_dodag_conf_t new_conf = {
62-
// Lifetime values
63-
.default_lifetime = 120,
64-
.lifetime_unit = 60,
65-
.objective_code_point = 1, // MRHOF algorithm used
66-
.authentication = 0,
67-
.path_control_size = 5,
68-
.dag_max_rank_increase = 2048,
69-
.min_hop_rank_increase = 256,
70-
// DIO configuration
71-
.dio_interval_min = WS_RPL_DIO_IMIN,
72-
.dio_interval_doublings = WS_RPL_DIO_DOUBLING,
73-
.dio_redundancy_constant = WS_RPL_DIO_REDUNDANCY
74-
};
75-
76100
rpl_data_init_root();
77101

78102
if (protocol_6lowpan_rpl_root_dodag) {
79103
rpl_control_delete_dodag_root(protocol_6lowpan_rpl_domain, protocol_6lowpan_rpl_root_dodag);
80104
protocol_6lowpan_rpl_root_dodag = NULL;
81105
}
82106

83-
protocol_6lowpan_rpl_root_dodag = rpl_control_create_dodag_root(protocol_6lowpan_rpl_domain, RPL_INSTANCE_ID, dodag_id, &new_conf, new_conf.min_hop_rank_increase, RPL_GROUNDED | RPL_MODE_NON_STORING | RPL_DODAG_PREF(0));
107+
protocol_6lowpan_rpl_root_dodag = rpl_control_create_dodag_root(protocol_6lowpan_rpl_domain, RPL_INSTANCE_ID, dodag_id, &rpl_conf, rpl_conf.min_hop_rank_increase, RPL_GROUNDED | RPL_MODE_NON_STORING | RPL_DODAG_PREF(0));
84108
if (!protocol_6lowpan_rpl_root_dodag) {
85109
tr_err("RPL dodag init failed");
86110
return;
@@ -372,6 +396,9 @@ void ws_bbr_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds
372396
// Inconsistent for border router to make information distribute faster
373397
ws_bootstrap_configuration_trickle_reset(cur);
374398

399+
if (cur->ws_info->network_size_config == NETWORK_SIZE_AUTOMATIC) {
400+
ws_common_network_size_configure(cur, cur->ws_info->pan_information.pan_size);
401+
}
375402
// We update the RPL version in same time to allow nodes to reselect parent
376403
// As configuration is made so that devices cant move downward in dodag this allows it
377404
// TODO think the correct rate for this

source/6LoWPAN/ws/ws_bbr_api_internal.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,15 @@ void ws_bbr_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds
2727

2828
uint16_t ws_bbr_pan_size(protocol_interface_info_entry_t *cur);
2929

30+
void ws_bbr_rpl_config(uint8_t imin, uint8_t doubling, uint8_t redundancy);
31+
32+
3033

3134
#else
3235

3336
#define ws_bbr_seconds_timer( cur, seconds)
3437
#define ws_bbr_pan_size(cur)
38+
#define ws_bbr_rpl_config( imin, doubling, redundancy);
3539

3640
#endif //HAVE_WS
3741

source/6LoWPAN/ws/ws_bootstrap.c

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
#include "platform/topo_trace.h"
6161
#include "libDHCPv6/libDHCPv6.h"
6262
#include "DHCPv6_client/dhcpv6_client_api.h"
63+
#include "ws_management_api.h"
6364
#include "net_rpl.h"
6465
#include "mac_api.h"
6566
#include "6LoWPAN/ws/ws_pae_controller.h"
@@ -71,15 +72,6 @@
7172

7273
#ifdef HAVE_WS
7374

74-
#define TRICKLE_IMIN_60_SECS (60 * 10) //
75-
76-
static const trickle_params_t trickle_params_pan_discovery = {
77-
.Imin = TRICKLE_IMIN_60_SECS, /* 60 second; ticks are 1s */
78-
.Imax = TRICKLE_IMIN_60_SECS << 4, /* 960 seconds 16 min*/
79-
.k = 1, /* 1 */
80-
.TimerExpirations = TRICKLE_EXPIRATIONS_INFINITE
81-
};
82-
8375
static void ws_bootstrap_event_handler(arm_event_s *event);
8476
static void ws_bootstrap_state_change(protocol_interface_info_entry_t *cur, icmp_state_t nwk_bootstrap_state);
8577
//static bool ws_bootstrap_state_active(struct protocol_interface_info_entry *cur);
@@ -757,9 +749,15 @@ static void ws_bootstrap_pan_advertisement_analyse_active(struct protocol_interf
757749
if (pan_information->routing_cost <= cur->ws_info->pan_information.routing_cost) {
758750
trickle_consistent_heard(&cur->ws_info->trickle_pan_advertisement);
759751
} else {
760-
trickle_inconsistent_heard(&cur->ws_info->trickle_pan_advertisement, &trickle_params_pan_discovery);
752+
trickle_inconsistent_heard(&cur->ws_info->trickle_pan_advertisement, &cur->ws_info->trickle_params_pan_discovery);
761753
}
762754

755+
// automatic network size adjustment
756+
if (cur->ws_info->network_size_config == NETWORK_SIZE_AUTOMATIC &&
757+
cur->bootsrap_mode != ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER &&
758+
cur->ws_info->pan_information.pan_size != pan_information->pan_size) {
759+
ws_common_network_size_configure(cur, pan_information->pan_size);
760+
}
763761
}
764762

765763
static void ws_bootstrap_pan_advertisement_analyse(struct protocol_interface_info_entry *cur, const struct mcps_data_ind_s *data, const struct mcps_data_ie_list *ie_ext, ws_utt_ie_t *ws_utt, ws_us_ie_t *ws_us)
@@ -846,7 +844,7 @@ static void ws_bootstrap_pan_advertisement_analyse(struct protocol_interface_inf
846844

847845
if (ws_neighbor_class_rssi_from_dbm_calculate(data->signal_dbm) < (CAND_PARENT_THRESHOLD + CAND_PARENT_HYSTERISIS)) {
848846
// First neighbor is too low we need to wait one extra trickle
849-
cur->bootsrap_state_machine_cnt += trickle_params_pan_discovery.Imin + randLIB_get_8bit() % 50;
847+
cur->bootsrap_state_machine_cnt += cur->ws_info->trickle_params_pan_discovery.Imin + randLIB_get_8bit() % 50;
850848
}
851849
}
852850

@@ -896,7 +894,7 @@ static void ws_bootstrap_pan_advertisement_solicit_analyse(struct protocol_inter
896894
* An inconsistent transmission is defined as:
897895
* A PAN Advertisement Solicit with NETNAME-IE matching that of the receiving node.
898896
*/
899-
trickle_inconsistent_heard(&cur->ws_info->trickle_pan_advertisement, &trickle_params_pan_discovery);
897+
trickle_inconsistent_heard(&cur->ws_info->trickle_pan_advertisement, &cur->ws_info->trickle_params_pan_discovery);
900898
/*
901899
* A consistent transmission is defined as
902900
* a PAN Advertisement Solicit with NETNAME-IE / Network Name matching that configured on the receiving node.
@@ -973,7 +971,7 @@ static void ws_bootstrap_pan_config_analyse(struct protocol_interface_info_entry
973971
trickle_consistent_heard(&cur->ws_info->trickle_pan_config);
974972
} else {
975973
tr_info("different pan version heard");
976-
trickle_inconsistent_heard(&cur->ws_info->trickle_pan_config, &trickle_params_pan_discovery);
974+
trickle_inconsistent_heard(&cur->ws_info->trickle_pan_config, &cur->ws_info->trickle_params_pan_discovery);
977975
if (common_serial_number_greater_16(cur->ws_info->pan_information.pan_version, pan_version)) {
978976
// older version heard ignoring the message
979977
return;
@@ -1061,7 +1059,7 @@ static void ws_bootstrap_pan_config_solicit_analyse(struct protocol_interface_in
10611059
* A PAN Configuration Solicit with a PAN-ID matching that of the receiving node and
10621060
* a NETNAME-IE / Network Name matching the network name configured on the receiving
10631061
*/
1064-
trickle_inconsistent_heard(&cur->ws_info->trickle_pan_config, &trickle_params_pan_discovery);
1062+
trickle_inconsistent_heard(&cur->ws_info->trickle_pan_config, &cur->ws_info->trickle_params_pan_discovery);
10651063
}
10661064
static bool ws_bootstrap_network_found(protocol_interface_info_entry_t *cur)
10671065
{
@@ -1751,11 +1749,11 @@ static void ws_bootstrap_network_discovery_configure(protocol_interface_info_ent
17511749
static void ws_bootstrap_advertise_start(protocol_interface_info_entry_t *cur)
17521750
{
17531751
cur->ws_info->trickle_pa_running = true;
1754-
trickle_start(&cur->ws_info->trickle_pan_advertisement, &trickle_params_pan_discovery);
1755-
trickle_inconsistent_heard(&cur->ws_info->trickle_pan_advertisement, &trickle_params_pan_discovery);
1752+
trickle_start(&cur->ws_info->trickle_pan_advertisement, &cur->ws_info->trickle_params_pan_discovery);
1753+
trickle_inconsistent_heard(&cur->ws_info->trickle_pan_advertisement, &cur->ws_info->trickle_params_pan_discovery);
17561754
cur->ws_info->trickle_pc_running = true;
1757-
trickle_start(&cur->ws_info->trickle_pan_config, &trickle_params_pan_discovery);
1758-
trickle_inconsistent_heard(&cur->ws_info->trickle_pan_config, &trickle_params_pan_discovery);
1755+
trickle_start(&cur->ws_info->trickle_pan_config, &cur->ws_info->trickle_params_pan_discovery);
1756+
trickle_inconsistent_heard(&cur->ws_info->trickle_pan_config, &cur->ws_info->trickle_params_pan_discovery);
17591757
}
17601758

17611759
// Start network scan
@@ -1782,11 +1780,11 @@ static void ws_bootstrap_start_discovery(protocol_interface_info_entry_t *cur)
17821780

17831781
// Reset advertisement solicit trickle to start discovering network
17841782
cur->ws_info->trickle_pas_running = true;
1785-
trickle_start(&cur->ws_info->trickle_pan_advertisement_solicit, &trickle_params_pan_discovery);
1786-
trickle_inconsistent_heard(&cur->ws_info->trickle_pan_advertisement_solicit, &trickle_params_pan_discovery);
1783+
trickle_start(&cur->ws_info->trickle_pan_advertisement_solicit, &cur->ws_info->trickle_params_pan_discovery);
1784+
trickle_inconsistent_heard(&cur->ws_info->trickle_pan_advertisement_solicit, &cur->ws_info->trickle_params_pan_discovery);
17871785

17881786
// Discovery statemachine is checkked after two trickle interval
1789-
cur->bootsrap_state_machine_cnt = 2 * trickle_params_pan_discovery.Imin + randLIB_get_8bit() % 50;
1787+
cur->bootsrap_state_machine_cnt = 2 * cur->ws_info->trickle_params_pan_discovery.Imin + randLIB_get_8bit() % 50;
17901788
}
17911789

17921790
// Start authentication
@@ -1842,8 +1840,8 @@ static void ws_bootstrap_start_configuration_learn(protocol_interface_info_entry
18421840
cur->ws_info->pas_requests = 0;
18431841
// Reset advertisement solicit trickle to start discovering network
18441842
cur->ws_info->trickle_pcs_running = true;
1845-
trickle_start(&cur->ws_info->trickle_pan_config_solicit, &trickle_params_pan_discovery);
1846-
trickle_inconsistent_heard(&cur->ws_info->trickle_pan_config_solicit, &trickle_params_pan_discovery);
1843+
trickle_start(&cur->ws_info->trickle_pan_config_solicit, &cur->ws_info->trickle_params_pan_discovery);
1844+
trickle_inconsistent_heard(&cur->ws_info->trickle_pan_config_solicit, &cur->ws_info->trickle_params_pan_discovery);
18471845
}
18481846
static void ws_bootstrap_rpl_scan_start(protocol_interface_info_entry_t *cur)
18491847
{
@@ -1880,7 +1878,7 @@ void ws_bootstrap_event_routing_ready(protocol_interface_info_entry_t *cur)
18801878
}
18811879
void ws_bootstrap_configuration_trickle_reset(protocol_interface_info_entry_t *cur)
18821880
{
1883-
trickle_inconsistent_heard(&cur->ws_info->trickle_pan_config, &trickle_params_pan_discovery);
1881+
trickle_inconsistent_heard(&cur->ws_info->trickle_pan_config, &cur->ws_info->trickle_params_pan_discovery);
18841882
}
18851883

18861884

@@ -2185,7 +2183,7 @@ void ws_bootstrap_network_scan_process(protocol_interface_info_entry_t *cur)
21852183

21862184
if (!ws_bootstrap_network_found(cur)) {
21872185
// Next check will be after one trickle
2188-
cur->bootsrap_state_machine_cnt += trickle_params_pan_discovery.Imin + randLIB_get_8bit() % 50;
2186+
cur->bootsrap_state_machine_cnt += cur->ws_info->trickle_params_pan_discovery.Imin + randLIB_get_8bit() % 50;
21892187
return;
21902188
}
21912189
tr_info("select network");
@@ -2312,13 +2310,13 @@ void ws_bootstrap_state_machine(protocol_interface_info_entry_t *cur)
23122310
void ws_bootstrap_trickle_timer(protocol_interface_info_entry_t *cur, uint16_t ticks)
23132311
{
23142312
if (cur->ws_info->trickle_pas_running &&
2315-
trickle_timer(&cur->ws_info->trickle_pan_advertisement_solicit, &trickle_params_pan_discovery, ticks)) {
2313+
trickle_timer(&cur->ws_info->trickle_pan_advertisement_solicit, &cur->ws_info->trickle_params_pan_discovery, ticks)) {
23162314
// send PAN advertisement solicit
23172315
tr_info("Send PAN advertisement Solicit");
23182316
ws_bootstrap_pan_advert_solicit(cur);
23192317
}
23202318
if (cur->ws_info->trickle_pcs_running &&
2321-
trickle_timer(&cur->ws_info->trickle_pan_config_solicit, &trickle_params_pan_discovery, ticks)) {
2319+
trickle_timer(&cur->ws_info->trickle_pan_config_solicit, &cur->ws_info->trickle_params_pan_discovery, ticks)) {
23222320
// send PAN Configuration solicit
23232321
if (cur->ws_info->pas_requests > PCS_MAX) {
23242322
// if MAX PCS sent restart discovery
@@ -2331,13 +2329,13 @@ void ws_bootstrap_trickle_timer(protocol_interface_info_entry_t *cur, uint16_t t
23312329
ws_bootstrap_pan_config_solicit(cur);
23322330
}
23332331
if (cur->ws_info->trickle_pa_running &&
2334-
trickle_timer(&cur->ws_info->trickle_pan_advertisement, &trickle_params_pan_discovery, ticks)) {
2332+
trickle_timer(&cur->ws_info->trickle_pan_advertisement, &cur->ws_info->trickle_params_pan_discovery, ticks)) {
23352333
// send PAN advertisement
23362334
tr_info("Send PAN advertisement");
23372335
ws_bootstrap_pan_advert(cur);
23382336
}
23392337
if (cur->ws_info->trickle_pc_running &&
2340-
trickle_timer(&cur->ws_info->trickle_pan_config, &trickle_params_pan_discovery, ticks)) {
2338+
trickle_timer(&cur->ws_info->trickle_pan_config, &cur->ws_info->trickle_params_pan_discovery, ticks)) {
23412339
// send PAN Configuration
23422340
tr_info("Send PAN configuration");
23432341
ws_bootstrap_pan_config(cur);

source/6LoWPAN/ws/ws_common.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,33 @@
3737

3838
int8_t DEVICE_MIN_SENS = -93;
3939

40+
#define TRICKLE_IMIN_60_SECS (60 * 10)
41+
#define TRICKLE_IMIN_30_SECS (30 * 10)
42+
#define TRICKLE_IMIN_15_SECS (15 * 10)
43+
44+
static const trickle_params_t trickle_params_pan_discovery_large = {
45+
.Imin = TRICKLE_IMIN_60_SECS, /* 60 second; ticks are 1s */
46+
.Imax = TRICKLE_IMIN_60_SECS << 4, /* 960 seconds 16 min*/
47+
.k = 1, /* 1 */
48+
.TimerExpirations = TRICKLE_EXPIRATIONS_INFINITE
49+
};
50+
51+
static const trickle_params_t trickle_params_pan_discovery_medium = {
52+
.Imin = TRICKLE_IMIN_30_SECS, /* 30 second; ticks are 1s */
53+
.Imax = TRICKLE_IMIN_30_SECS << 3, /* 240 seconds 4 min*/
54+
.k = 1, /* 1 */
55+
.TimerExpirations = TRICKLE_EXPIRATIONS_INFINITE
56+
};
57+
58+
static const trickle_params_t trickle_params_pan_discovery_small = {
59+
.Imin = TRICKLE_IMIN_15_SECS, /* 15 second; ticks are 1s */
60+
.Imax = TRICKLE_IMIN_15_SECS << 2, /* 60 seconds 1 min*/
61+
.k = 1, /* 1 */
62+
.TimerExpirations = TRICKLE_EXPIRATIONS_INFINITE
63+
};
64+
65+
66+
4067

4168
int8_t ws_generate_channel_list(uint32_t *channel_mask, uint16_t number_of_channels, uint8_t regulatory_domain)
4269
{
@@ -164,6 +191,7 @@ int8_t ws_common_allocate_and_init(protocol_interface_info_entry_t *cur)
164191
cur->ws_info->hopping_schdule.operating_mode = OPERATING_MODE_1a;
165192
cur->ws_info->hopping_schdule.operating_class = 1;
166193
ws_common_regulatory_domain_config(cur);
194+
ws_common_network_size_configure(cur, 10); // defaults to small network size
167195

168196
// Set defaults for the device. user can modify these.
169197
cur->ws_info->fhss_uc_fixed_channel = 0xffff;
@@ -179,6 +207,38 @@ int8_t ws_common_allocate_and_init(protocol_interface_info_entry_t *cur)
179207

180208
return 0;
181209
}
210+
void ws_common_network_size_configure(protocol_interface_info_entry_t *cur, uint16_t network_size)
211+
{
212+
// TODO Modify NUD timings based on network size
213+
// TODO Modify EAPOLL timings
214+
215+
if (network_size < 100) {
216+
// Configure the Wi-SUN discovery trickle parameters
217+
cur->ws_info->trickle_params_pan_discovery = trickle_params_pan_discovery_small;
218+
// default values are for Wi-SUN small network parameters
219+
// imin: 14 (16s)
220+
// doublings:3 (128s)
221+
// redundancy; 0 Disabled
222+
ws_bbr_rpl_config(0, 0, 0);// set the default values
223+
} else if (network_size < 300) {
224+
// Configure the Wi-SUN discovery trickle parameters
225+
cur->ws_info->trickle_params_pan_discovery = trickle_params_pan_discovery_medium;
226+
// Something in between
227+
// imin: 15 (32s)
228+
// doublings:3 (262s)
229+
// redundancy; 7
230+
ws_bbr_rpl_config(15, 3, 7);
231+
} else {
232+
// Configure the Wi-SUN discovery trickle parameters
233+
cur->ws_info->trickle_params_pan_discovery = trickle_params_pan_discovery_large;
234+
// Wi-SUN Large network parameters
235+
// imin: 19 (524s, 9 min)
236+
// doublings:1 (1048s, 17 min)
237+
// redundancy; 1 Really heavy redundancy
238+
ws_bbr_rpl_config(19, 1, 1);
239+
}
240+
return;
241+
}
182242

183243
void ws_common_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds)
184244
{

0 commit comments

Comments
 (0)