Skip to content

Commit cab9849

Browse files
author
Tero Heinonen
authored
Send address registration to all PC parents (ARMmbed#1618)
Send non-ll address registration to path control parents.
1 parent 5417936 commit cab9849

File tree

10 files changed

+164
-59
lines changed

10 files changed

+164
-59
lines changed

source/6LoWPAN/ws/ws_bootstrap.c

Lines changed: 26 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ static void ws_bootstrap_state_change(protocol_interface_info_entry_t *cur, icmp
7777
static bool ws_bootstrap_state_active(struct protocol_interface_info_entry *cur);
7878
static bool ws_bootstrap_state_discovery(struct protocol_interface_info_entry *cur);
7979
static bool ws_bootstrap_state_wait_rpl(struct protocol_interface_info_entry *cur);
80-
80+
static int8_t ws_bootsrap_event_trig(ws_bootsrap_event_type_e event_type, int8_t interface_id, arm_library_event_priority_e priority, void *event_data);
8181
static mac_neighbor_table_entry_t * ws_bootstrap_add_neighbor(struct protocol_interface_info_entry *interface, const uint8_t *src64)
8282
{
8383
mac_neighbor_table_entry_t *neighbor = mac_neighbor_table_address_discover(interface->mac_parameters->mac_neighbor_table, src64, MAC_ADDR_MODE_64_BIT);
@@ -94,30 +94,6 @@ static mac_neighbor_table_entry_t * ws_bootstrap_add_neighbor(struct protocol_in
9494
}
9595

9696

97-
static void ws_bootstrap_address_registration_ns_send(struct protocol_interface_info_entry *interface, const struct if_address_entry *addr)
98-
{
99-
aro_t aro;
100-
buffer_t *buf;
101-
102-
tr_debug("Send ARO");
103-
104-
aro.status = ARO_SUCCESS;
105-
aro.present = true;
106-
aro.lifetime = addr->preferred_lifetime;
107-
memcpy(aro.eui64, interface->mac, 8);
108-
109-
/* Fill address to be registered */
110-
memcpy(&interface->if_6lowpan_dad_process.address, addr->address, 16);
111-
112-
ns_list_foreach(struct rpl_instance, instance, &interface->rpl_domain->instances) {
113-
const uint8_t *preferred_parent = rpl_control_preferred_parent_addr(instance, false);
114-
if (preferred_parent) {
115-
buf = icmpv6_build_ns(interface, preferred_parent, addr->address, true, false, &aro);
116-
protocol_push(buf);
117-
}
118-
}
119-
}
120-
12197

12298
static void ws_bootstrap_address_notification_cb(struct protocol_interface_info_entry *interface, const struct if_address_entry *addr, if_address_callback_t reason)
12399
{
@@ -127,12 +103,12 @@ static void ws_bootstrap_address_notification_cb(struct protocol_interface_info_
127103
}
128104

129105
if (reason == ADDR_CALLBACK_DAD_COMPLETE) {
130-
// When SLAAC address is created, send NS with ARO to parent
131-
ws_bootstrap_address_registration_ns_send(interface, addr);
106+
ws_bootsrap_event_trig(WS_ADDRESS_ADDED, interface->bootStrapId, ARM_LIB_LOW_PRIORITY_EVENT, (void *)addr);
132107
} else if (reason == ADDR_CALLBACK_DELETED) {
133108
// What to do?
134109
}
135110
}
111+
136112
static int ws_bootstrap_tasklet_init(protocol_interface_info_entry_t *cur)
137113
{
138114
if (cur->bootStrapId < 0) {
@@ -149,13 +125,14 @@ static int ws_bootstrap_tasklet_init(protocol_interface_info_entry_t *cur)
149125
return 0;
150126
}
151127

152-
static int8_t ws_bootsrap_event_trig(ws_bootsrap_event_type_e event_type, int8_t interface_id, arm_library_event_priority_e priority)
128+
static int8_t ws_bootsrap_event_trig(ws_bootsrap_event_type_e event_type, int8_t interface_id, arm_library_event_priority_e priority, void *event_data)
153129
{
154130
arm_event_s event = {
155131
.receiver = interface_id,
156132
.sender = 0,
157133
.event_type = event_type,
158134
.priority = priority,
135+
.data_ptr = event_data,
159136
};
160137
return eventOS_event_send(&event);
161138
}
@@ -912,23 +889,23 @@ static void ws_bootstrap_start_discovery(protocol_interface_info_entry_t *cur)
912889
* */
913890
void ws_bootstrap_event_discovery_start(protocol_interface_info_entry_t *cur)
914891
{
915-
ws_bootsrap_event_trig(WS_DISCOVERY_START, cur->bootStrapId, ARM_LIB_LOW_PRIORITY_EVENT);
892+
ws_bootsrap_event_trig(WS_DISCOVERY_START, cur->bootStrapId, ARM_LIB_LOW_PRIORITY_EVENT, NULL);
916893
}
917894
void ws_bootstrap_event_configuration_start(protocol_interface_info_entry_t *cur)
918895
{
919-
ws_bootsrap_event_trig(WS_CONFIGURATION_START, cur->bootStrapId, ARM_LIB_LOW_PRIORITY_EVENT);
896+
ws_bootsrap_event_trig(WS_CONFIGURATION_START, cur->bootStrapId, ARM_LIB_LOW_PRIORITY_EVENT, NULL);
920897
}
921898
void ws_bootstrap_event_authentication_start(protocol_interface_info_entry_t *cur)
922899
{
923-
ws_bootsrap_event_trig(WS_AUTHENTICATION_START, cur->bootStrapId, ARM_LIB_LOW_PRIORITY_EVENT);
900+
ws_bootsrap_event_trig(WS_AUTHENTICATION_START, cur->bootStrapId, ARM_LIB_LOW_PRIORITY_EVENT, NULL);
924901
}
925902
void ws_bootstrap_event_operation_start(protocol_interface_info_entry_t *cur)
926903
{
927-
ws_bootsrap_event_trig(WS_OPERATION_START, cur->bootStrapId, ARM_LIB_LOW_PRIORITY_EVENT);
904+
ws_bootsrap_event_trig(WS_OPERATION_START, cur->bootStrapId, ARM_LIB_LOW_PRIORITY_EVENT, NULL);
928905
}
929906
void ws_bootstrap_event_routing_ready(protocol_interface_info_entry_t *cur)
930907
{
931-
ws_bootsrap_event_trig(WS_ROUTING_READY, cur->bootStrapId, ARM_LIB_LOW_PRIORITY_EVENT);
908+
ws_bootsrap_event_trig(WS_ROUTING_READY, cur->bootStrapId, ARM_LIB_LOW_PRIORITY_EVENT, NULL);
932909
}
933910

934911

@@ -1010,6 +987,17 @@ static void ws_bootstrap_pan_config(protocol_interface_info_entry_t *cur)
1010987
ws_llc_asynch_request(cur, &async_req);
1011988
}
1012989

990+
static bool ws_bootstrap_address_registration_ongoing(protocol_interface_info_entry_t *cur)
991+
{
992+
ns_list_foreach(if_address_entry_t, addr, &cur->ip_addresses) {
993+
if (addr->addr_reg_pend != 0) {
994+
return true;
995+
}
996+
}
997+
998+
return false;
999+
}
1000+
10131001
static void ws_bootstrap_event_handler(arm_event_s *event)
10141002
{
10151003
ws_bootsrap_event_type_e event_type;
@@ -1085,6 +1073,11 @@ static void ws_bootstrap_event_handler(arm_event_s *event)
10851073
tr_info("Routing ready");
10861074
ws_bootstrap_state_change(cur, ER_BOOTSRAP_DONE);
10871075
break;
1076+
case WS_ADDRESS_ADDED:
1077+
if (!ws_bootstrap_address_registration_ongoing(cur)) {
1078+
rpl_control_register_address(cur, (if_address_entry_t *) event->data_ptr);
1079+
}
1080+
break;
10881081
default:
10891082
tr_err("Invalid event received");
10901083
break;

source/6LoWPAN/ws/ws_bootstrap.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,13 @@
2020

2121

2222
typedef enum {
23-
WS_INIT_EVENT = 0, /**< tasklet initializion event*/
24-
WS_DISCOVERY_START, /**< discovery start*/
25-
WS_CONFIGURATION_START, /**< configuration learn start*/
23+
WS_INIT_EVENT = 0, /**< tasklet initializion event*/
24+
WS_DISCOVERY_START, /**< discovery start*/
25+
WS_CONFIGURATION_START, /**< configuration learn start*/
2626
WS_AUTHENTICATION_START, /**< authentication start*/
27-
WS_OPERATION_START, /**< active operation start*/
28-
WS_ROUTING_READY /**< RPL routing connected to BR*/
27+
WS_OPERATION_START, /**< active operation start*/
28+
WS_ROUTING_READY, /**< RPL routing connected to BR*/
29+
WS_ADDRESS_ADDED /**< Address added to IF*/
2930
} ws_bootsrap_event_type_e;
3031

3132
#ifdef HAVE_WS

source/Common_Protocols/icmpv6.c

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
#include "ns_trace.h"
2121
#include "randLIB.h"
2222
#include "NWK_INTERFACE/Include/protocol.h"
23-
#ifdef HAVE_RPL
2423
#include "RPL/rpl_control.h"
24+
#ifdef HAVE_RPL
2525
#include "RPL/rpl_data.h"
2626
#endif
2727
#include "RPL/rpl_protocol.h"
@@ -1214,25 +1214,6 @@ uint8_t *icmpv6_write_mtu_option(uint32_t mtu, uint8_t *dptr)
12141214
return dptr;
12151215
}
12161216

1217-
static void icmpv6_ns_ack_cb(struct buffer *buf, uint8_t status)
1218-
{
1219-
(void) buf;
1220-
1221-
if (status == SOCKET_TX_DONE) {
1222-
tr_debug("NS ARO ack received %s", trace_ipv6(buf->interface->if_6lowpan_dad_process.address));
1223-
1224-
if_address_entry_t *addr_entry = addr_get_entry(buf->interface, buf->interface->if_6lowpan_dad_process.address);
1225-
if (!addr_entry) {
1226-
return;
1227-
}
1228-
/* State_timer is 1/10 s. Set renewal to 75-85% of lifetime */
1229-
addr_entry->state_timer = (addr_entry->preferred_lifetime * randLIB_get_random_in_range(75, 85) / 10);
1230-
} else {
1231-
// todo: What to do when address registration fails?
1232-
tr_debug("NS ARO send failed");
1233-
}
1234-
}
1235-
12361217
buffer_t *icmpv6_build_ns(protocol_interface_info_entry_t *cur, const uint8_t target_addr[16], const uint8_t *prompting_src_addr, bool unicast, bool unspecified_source, const aro_t *aro)
12371218
{
12381219
if (!cur || addr_is_ipv6_multicast(target_addr)) {
@@ -1308,7 +1289,7 @@ buffer_t *icmpv6_build_ns(protocol_interface_info_entry_t *cur, const uint8_t ta
13081289
/* If ARO Success sending is omitted, MAC ACK is used instead */
13091290
/* Setting callback for receiving ACK from adaptation layer */
13101291
if (aro && cur->ipv6_neighbour_cache.omit_aro_success) {
1311-
buf->ack_receive_cb = icmpv6_ns_ack_cb;
1292+
buf->ack_receive_cb = rpl_control_address_register_done;
13121293
}
13131294
}
13141295
buf->src_sa.addr_type = ADDR_IPV6;

source/Core/include/address.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ typedef struct if_address_entry {
9696
bool temporary:1; // RFC 4941 temporary address
9797
bool tentative:1; // Tentative address (Duplicate Address Detection running)
9898
bool group_added:1; // Solicited-Node group added
99+
uint8_t addr_reg_pend; // Bitmask for pending address registrations. Based on RPL path control bits
100+
uint8_t addr_reg_done; // Bitmask for address registration done. Based on RPL path control bits
99101
if_address_source_t source; //
100102
if_address_callback_fn *cb; // Address protocol callback function
101103
void *data; // Address protocol data

source/RPL/rpl_control.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,51 @@ void rpl_control_unpublish_address(rpl_domain_t *domain, const uint8_t addr[16])
182182
}
183183
}
184184

185+
static if_address_entry_t *rpl_instance_reg_addr_get(protocol_interface_info_entry_t *interface)
186+
{
187+
ns_list_foreach(if_address_entry_t, address, &interface->ip_addresses) {
188+
if (!address->addr_reg_done && !addr_is_ipv6_link_local(address->address)) {
189+
return address;
190+
}
191+
}
192+
193+
return NULL;
194+
}
195+
196+
/* Send address registration to either specified address, or to non-registered address */
197+
void rpl_control_register_address(protocol_interface_info_entry_t *interface, if_address_entry_t *addr)
198+
{
199+
if_address_entry_t *reg_addr = addr;
200+
201+
if (!reg_addr) {
202+
reg_addr = rpl_instance_reg_addr_get(interface);
203+
204+
if (!reg_addr) {
205+
return;
206+
}
207+
}
208+
ns_list_foreach(struct rpl_instance, instance, &interface->rpl_domain->instances) {
209+
rpl_instance_send_address_registration(interface, instance, addr);
210+
}
211+
}
212+
213+
void rpl_control_address_register_done(struct buffer *buf, uint8_t status)
214+
{
215+
ns_list_foreach(if_address_entry_t, addr, &buf->interface->ip_addresses) {
216+
217+
/* Optimize, ll addresses are not registered anyway.. */
218+
if (addr_is_ipv6_link_local(addr->address) || !addr->addr_reg_pend) {
219+
continue;
220+
}
221+
222+
ns_list_foreach(struct rpl_instance, instance, &buf->interface->rpl_domain->instances) {
223+
if (rpl_instance_address_registration_done(buf->interface, instance, addr, status)) {
224+
return;
225+
}
226+
}
227+
}
228+
}
229+
185230
/* Address changes need to trigger DAO target re-evaluation */
186231
static void rpl_control_addr_notifier(struct protocol_interface_info_entry *interface, const if_address_entry_t *addr, if_address_callback_t reason)
187232
{

source/RPL/rpl_control.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ void rpl_control_set_callback(rpl_domain_t *domain, rpl_domain_callback_t callba
143143
/* Target publishing */
144144
void rpl_control_publish_host_address(rpl_domain_t *domain, const uint8_t addr[16], uint32_t lifetime);
145145
void rpl_control_unpublish_address(rpl_domain_t *domain, const uint8_t addr[16]);
146+
void rpl_control_register_address(struct protocol_interface_info_entry *interface, if_address_entry_t *addr);
147+
void rpl_control_address_register_done(struct buffer *buf, uint8_t status);
146148

147149
/* Configure and return the routing lookup predicate for a specified RPL instance ID */
148150
ipv6_route_predicate_fn_t *rpl_control_get_route_predicate(rpl_domain_t *domain, uint8_t instance_id, const uint8_t src[16], const uint8_t dst[16]);
@@ -157,11 +159,14 @@ bool rpl_control_read_dodag_info(const struct rpl_instance *instance, struct rpl
157159
const rpl_dodag_conf_t *rpl_control_get_dodag_config(const struct rpl_instance *instance);
158160
const uint8_t *rpl_control_preferred_parent_addr(const struct rpl_instance *instance, bool global);
159161

162+
160163
#else /* HAVE_RPL */
161164

162165
#define rpl_control_fast_timer(ticks) ((void) 0)
163166
#define rpl_control_slow_timer(seconds) ((void) 0)
164167
#define rpl_control_remove_domain_from_interface(cur) ((void) 0)
168+
#define rpl_control_register_address(interface, addr) ((void) 0)
169+
#define rpl_control_address_register_done NULL
165170

166171
#endif /* HAVE_RPL */
167172

source/RPL/rpl_downward.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
#include "randLIB.h"
8989
#include "ip6string.h"
9090

91+
#include "Common_Protocols/icmpv6.h"
9192
#include "NWK_INTERFACE/Include/protocol.h"
9293
#include "ipv6_stack/ipv6_routing_table.h"
9394

@@ -580,6 +581,61 @@ static void rpl_downward_reset_assigning(rpl_instance_t *instance, uint8_t pcs_m
580581
}
581582

582583

584+
void rpl_instance_send_address_registration(protocol_interface_info_entry_t *interface, rpl_instance_t *instance, if_address_entry_t *addr)
585+
{
586+
aro_t aro;
587+
buffer_t *buf;
588+
589+
aro.status = ARO_SUCCESS;
590+
aro.present = true;
591+
aro.lifetime = addr->preferred_lifetime;
592+
memcpy(aro.eui64, interface->mac, 8);
593+
594+
// go through neighbour list, and send to all assigned parents.
595+
ns_list_foreach(rpl_neighbour_t, neighbour, &instance->candidate_neighbours) {
596+
if (neighbour->dao_path_control) {
597+
tr_debug("Send ARO %s to %s", trace_ipv6(addr->address), trace_ipv6(neighbour->ll_address));
598+
buf = icmpv6_build_ns(interface, neighbour->ll_address, addr->address, true, false, &aro);
599+
addr->addr_reg_pend |= neighbour->dao_path_control;
600+
protocol_push(buf);
601+
} else {
602+
tr_debug("Skip ARO to %s - no pc", trace_ipv6(neighbour->ll_address));
603+
}
604+
}
605+
}
606+
607+
bool rpl_instance_address_registration_done(protocol_interface_info_entry_t *interface, rpl_instance_t *instance, if_address_entry_t *addr, uint8_t status)
608+
{
609+
ns_list_foreach(rpl_neighbour_t, neighbour, &instance->candidate_neighbours) {
610+
// Check path control mask
611+
if (!(addr->addr_reg_pend & neighbour->dao_path_control)) {
612+
continue;
613+
}
614+
615+
tr_debug("Address %s register to %s", trace_ipv6(addr->address), trace_ipv6(neighbour->ll_address));
616+
617+
/* Clear pending flag */
618+
addr->addr_reg_pend &= ~neighbour->dao_path_control;
619+
620+
if (status == SOCKET_TX_DONE) {
621+
addr->addr_reg_done |= neighbour->dao_path_control;
622+
/* State_timer is 1/10 s. Set renewal to 75-85% of lifetime */
623+
addr->state_timer = (addr->preferred_lifetime * randLIB_get_random_in_range(75, 85) / 10);
624+
} else {
625+
tr_error("Address registration failed");
626+
}
627+
628+
/* If that was last one to reply, send next one. */
629+
if (!addr->addr_reg_pend) {
630+
rpl_control_register_address(interface, NULL);
631+
}
632+
633+
return true;
634+
}
635+
636+
return false;
637+
}
638+
583639
/* We are optimised for sending updates to existing targets to current parents;
584640
* we track the state of what information DAO parents have, and manage the
585641
* updates together with message coalescing and ack tracking.

source/RPL/rpl_downward.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ void rpl_instance_dao_request(struct rpl_instance *instance, struct rpl_neighbou
4141
void rpl_instance_dao_trigger(struct rpl_instance *instance, uint16_t delay);
4242
void rpl_instance_dao_acked(struct rpl_instance *instance, const uint8_t src[16], int8_t interface_id, uint8_t dao_sequence, uint8_t status);
4343

44+
void rpl_instance_send_address_registration(protocol_interface_info_entry_t *interface, rpl_instance_t *instance, if_address_entry_t *addr);
45+
bool rpl_instance_address_registration_done(protocol_interface_info_entry_t *interface, rpl_instance_t *instance, if_address_entry_t *addr, uint8_t status);
46+
4447
#ifdef HAVE_RPL_DAO_HANDLING
4548
bool rpl_instance_dao_received(struct rpl_instance *instance, const uint8_t src[16], int8_t interface_id, bool multicast, const uint8_t *opts, uint16_t opts_len, uint8_t *status_out);
4649
#endif

test/nanostack/unittest/stub/rpl_control_stub.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,3 +223,13 @@ void rpl_control_print(route_print_fn_t *print_fn)
223223
{
224224

225225
}
226+
227+
void rpl_control_register_address(struct protocol_interface_info_entry *interface, if_address_entry_t *addr)
228+
{
229+
230+
}
231+
232+
void rpl_control_address_register_done(struct buffer *buf, uint8_t status)
233+
{
234+
235+
}

test/nanostack/unittest/stub/rpl_downward_stub.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,4 +137,13 @@ void rpl_downward_print_instance(rpl_instance_t *instance, route_print_fn_t *pri
137137
{
138138
}
139139

140+
void rpl_instance_send_address_registration(protocol_interface_info_entry_t *interface, rpl_instance_t *instance, if_address_entry_t *addr)
141+
{
142+
}
143+
144+
bool rpl_instance_address_registration_done(protocol_interface_info_entry_t *interface, rpl_instance_t *instance, if_address_entry_t *addr, uint8_t status)
145+
{
146+
return true;
147+
}
148+
140149
#endif /* HAVE_RPL */

0 commit comments

Comments
 (0)