Skip to content

Commit 11de56d

Browse files
author
Mika Tervonen
committed
Added info API for Wi-SUN border router
Added API to get generic BBR status Added API to get routing table from Border router Added RPL interface to get routing table from instance
1 parent 87a4f69 commit 11de56d

File tree

7 files changed

+205
-1
lines changed

7 files changed

+205
-1
lines changed

nanostack/ws_bbr_api.h

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,34 @@
3030

3131
#include "ns_types.h"
3232

33+
/**
34+
* \brief Struct ws_statistics Border router dynamic information.
35+
*/
36+
typedef struct bbr_information {
37+
/** Timestamp of the the device. Can be used as version number*/
38+
uint64_t timestamp;
39+
/** Border router dodag id */
40+
uint8_t dodag_id[16];
41+
/** Address prefix given to devices in network set to 0 if not available*/
42+
uint8_t prefix[8];
43+
/** Amount of devices in the network. */
44+
uint16_t devices_in_network;
45+
/** Border router instance identifier defined in RPL */
46+
uint8_t instance_id;
47+
/** RPL version number */
48+
uint8_t version;
49+
} bbr_information_t;
50+
51+
/**
52+
* \brief Struct route_info is parent child relation structure.
53+
*/
54+
typedef struct bbr_route_info {
55+
/** IID of target device public IPv6 address can be formed by combining prefix + IID*/
56+
uint8_t target[8];
57+
/** IID of parent*/
58+
uint8_t parent[8];
59+
} bbr_route_info_t;
60+
3361
/**
3462
* Start backbone border router service.
3563
*
@@ -83,6 +111,49 @@ int ws_bbr_configure(int8_t interface_id, uint16_t options);
83111
*/
84112
void ws_bbr_stop(int8_t interface_id);
85113

114+
/**
115+
* Get border router information
116+
*
117+
* \param interface_id interface ID of the Wi-SUN network
118+
* \param info_ptr Structure given to stack where information is stored
119+
*
120+
* \return 0 on success
121+
* \return <0 in case of errors
122+
*
123+
*/
124+
int ws_bbr_info_get(int8_t interface_id, bbr_information_t *info_ptr);
125+
126+
/**
127+
* Routing table get
128+
*
129+
* Table is Parent child relation using the Global address IID of the devices
130+
* To get the full IPv6 address of the device.
131+
* IPv6 = Global Prefix + IID.
132+
*
133+
* Routing table is in the format: 18 bytes per entry
134+
* | Node IID 8 bytes | parent IID 8 bytes |
135+
* | 1122112211221122 | 1111111111111111 |
136+
* | 1133113311331133 | 1111111111111111 |
137+
* | 1144114411441144 | 1111111111111111 |
138+
* | 1155115511551155 | 1122112211221122 |
139+
* | 1166116611661166 | 1122112211221122 |
140+
* | 1177117711771177 | 1155115511551155 |
141+
* | 1188118811881188 | 1177117711771177 |
142+
*
143+
* Order is not assured only parent child link is given in random order
144+
*
145+
* Return value is device amount in network divided by 16 bytes per route entry
146+
*
147+
* \param interface_id interface ID of the Wi-SUN network
148+
* \param table_ptr Application allocated memory block where routing table is written.
149+
* \param table_len Length of the table allocated by application given as amount of entries.
150+
*
151+
* \return 0 - x on success indicates amount of bytes written to the table_ptr
152+
* \return <0 in case of errors
153+
*
154+
*/
155+
int ws_bbr_routing_table_get(int8_t interface_id, bbr_route_info_t *table_ptr, uint16_t table_len);
156+
86157
/**
87158
* Remove node's keys from border router
88159
*

source/6LoWPAN/ws/ws_bbr_api.c

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,79 @@ int ws_bbr_configure(int8_t interface_id, uint16_t options)
737737
return -1;
738738
#endif
739739
}
740+
int ws_bbr_info_get(int8_t interface_id, bbr_information_t *info_ptr)
741+
{
742+
#ifdef HAVE_WS_BORDER_ROUTER
743+
744+
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
745+
rpl_dodag_info_t dodag_info;
746+
747+
if (!info_ptr) {
748+
return -1;
749+
}
750+
if (!cur || !protocol_6lowpan_rpl_root_dodag) {
751+
tr_warn("bbr not started");
752+
return -1;
753+
}
754+
struct rpl_instance *instance = rpl_control_lookup_instance(protocol_6lowpan_rpl_domain, current_instance_id, current_dodag_id);
755+
if (!instance) {
756+
tr_warn("bbr instance not found");
757+
return -2;
758+
}
759+
// Zero the structure
760+
memset(info_ptr, 0, sizeof(bbr_information_t));
761+
762+
rpl_control_read_dodag_info(instance, &dodag_info);
763+
764+
memcpy(info_ptr->dodag_id, current_dodag_id, 16);
765+
memcpy(info_ptr->prefix, current_global_prefix, 8);
766+
767+
info_ptr->devices_in_network = ws_bbr_pan_size(cur);
768+
info_ptr->instance_id = current_instance_id;
769+
info_ptr->version = dodag_info.version_num;
770+
info_ptr->timestamp = protocol_core_monotonic_time; // TODO switch to second timer
771+
// consider DTSN included It can also be added for getting device information
772+
// Consider own device API to get DTSN, DHCP lifetime values
773+
return 0;
774+
775+
#else
776+
(void) interface_id;
777+
(void) info_ptr;
778+
779+
return -1;
780+
#endif
781+
}
782+
783+
int ws_bbr_routing_table_get(int8_t interface_id, bbr_route_info_t *table_ptr, uint16_t table_len)
784+
{
785+
#ifdef HAVE_WS_BORDER_ROUTER
786+
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
787+
int length;
788+
if (!cur || !protocol_6lowpan_rpl_root_dodag) {
789+
return -1;
790+
}
791+
792+
struct rpl_instance *instance = rpl_control_lookup_instance(protocol_6lowpan_rpl_domain, current_instance_id, current_dodag_id);
793+
if (!instance) {
794+
tr_warn("bbr instance not found");
795+
return -2;
796+
}
797+
memset(table_ptr, 0, table_len);
798+
799+
/* RPL structure must match the external structure so we dont need to make conversion.
800+
*
801+
*/
802+
length = rpl_control_route_table_get(instance, current_global_prefix, (rpl_route_info_t *)table_ptr, table_len);
803+
804+
return length;
805+
#else
806+
(void) interface_id;
807+
(void) table_ptr;
808+
(void) table_len;
809+
810+
return -1;
811+
#endif
812+
}
740813

741814
int ws_bbr_node_keys_remove(int8_t interface_id, uint8_t *eui64)
742815
{

source/RPL/rpl_control.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1886,6 +1886,11 @@ static void rpl_domain_print(const rpl_domain_t *domain, route_print_fn_t *print
18861886
}
18871887
}
18881888

1889+
uint16_t rpl_control_route_table_get(struct rpl_instance *instance, uint8_t *prefix, rpl_route_info_t *output_table, uint16_t output_table_len)
1890+
{
1891+
return rpl_downward_route_table_get(instance, prefix, output_table, output_table_len);
1892+
}
1893+
18891894
void rpl_control_print(route_print_fn_t *print_fn)
18901895
{
18911896
unsigned t = protocol_core_monotonic_time % 10;

source/RPL/rpl_control.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ typedef void rpl_prefix_callback_t(struct prefix_entry_t *prefix, void *handle,
4444

4545
typedef bool rpl_new_parent_callback_t(uint8_t *ll_parent_address, void *handle, struct rpl_instance *instance, uint16_t candidate_rank);
4646

47+
typedef struct rpl_route_info {
48+
uint8_t node[8]; /* IID of parent in parent child relation table */
49+
uint8_t parent[8]; /* IID of child in parent child relation table */
50+
} rpl_route_info_t;
4751

4852
typedef struct rpl_domain {
4953
NS_LIST_HEAD_INCOMPLETE(struct rpl_instance) instances;
@@ -186,6 +190,7 @@ ipv6_route_predicate_fn_t *rpl_control_get_route_predicate(rpl_domain_t *domain,
186190

187191
/* Diagnostic APIs */
188192
void rpl_control_print(route_print_fn_t *print_fn);
193+
uint16_t rpl_control_route_table_get(struct rpl_instance *instance, uint8_t *prefix, rpl_route_info_t *output_table, uint16_t output_table_len);
189194

190195
struct rpl_instance *rpl_control_enumerate_instances(rpl_domain_t *domain, struct rpl_instance *instance);
191196
struct rpl_instance *rpl_control_lookup_instance(rpl_domain_t *domain, uint8_t instance_id, const uint8_t *dodagid);

source/RPL/rpl_downward.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1754,6 +1754,52 @@ void rpl_downward_print_instance(rpl_instance_t *instance, route_print_fn_t *pri
17541754
}
17551755
}
17561756

1757+
uint16_t rpl_downward_route_table_get(rpl_instance_t *instance, uint8_t *prefix, rpl_route_info_t *output_table, uint16_t output_table_len)
1758+
{
1759+
uint16_t index = 0;
1760+
1761+
if (!prefix || !output_table || !output_table_len) {
1762+
return 0;
1763+
}
1764+
if (ns_list_is_empty(&instance->dao_targets)) {
1765+
return 0;
1766+
}
1767+
if (!rpl_instance_am_root(instance)) {
1768+
// Question should this be available also for non roots in storing mode
1769+
return 0;
1770+
}
1771+
1772+
#ifdef HAVE_RPL_ROOT
1773+
rpl_downward_compute_paths(instance);
1774+
1775+
ns_list_foreach(rpl_dao_target_t, target, &instance->dao_targets) {
1776+
if (memcmp(target->prefix, prefix, 8) != 0) {
1777+
continue;
1778+
}
1779+
1780+
if (target->root) {
1781+
/* Target has root structure
1782+
* We take the first transit only from table as simple topology is needed
1783+
*/
1784+
rpl_dao_root_transit_t *transit = ns_list_get_first(&target->info.root.transits);
1785+
if (transit) {
1786+
memcpy(output_table->node, &target->prefix[8], 8);
1787+
memcpy(output_table->parent, &transit->transit[8], 8);
1788+
1789+
index++;
1790+
if (index == output_table_len) {
1791+
//table is full
1792+
return index;
1793+
}
1794+
output_table++;
1795+
}
1796+
}
1797+
/* We dont put non roots to list so border router is not visible as a node in list*/
1798+
}
1799+
#endif
1800+
return index;
1801+
}
1802+
17571803
rpl_dao_target_t *rpl_instance_get_active_target_confirmation(rpl_instance_t *instance)
17581804
{
17591805
ns_list_foreach_safe(rpl_dao_target_t, n, &instance->dao_targets) {

source/RPL/rpl_downward.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ struct rpl_dao_root_transit;
2727
void rpl_downward_dao_slow_timer(struct rpl_instance *instance, uint16_t seconds);
2828
void rpl_downward_dao_timer(struct rpl_instance *instance, uint16_t ticks);
2929
void rpl_downward_print_instance(struct rpl_instance *instance, route_print_fn_t *print_fn);
30+
uint16_t rpl_downward_route_table_get(rpl_instance_t *instance, uint8_t *prefix, rpl_route_info_t *output_table, uint16_t output_table_len);
3031

3132
void rpl_downward_convert_dodag_preferences_to_dao_path_control(struct rpl_dodag *dodag);
3233
void rpl_downward_process_dao_parent_changes(struct rpl_instance *instance);

test/nanostack/unittest/stub/rpl_downward_stub.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,10 @@ void rpl_downward_dao_timer(rpl_instance_t *instance, uint16_t ticks)
139139
void rpl_downward_print_instance(rpl_instance_t *instance, route_print_fn_t *print_fn)
140140
{
141141
}
142-
142+
uint16_t rpl_downward_route_table_get(rpl_instance_t *instance, uint8_t *prefix, rpl_route_info_t *output_table, uint16_t output_table_len)
143+
{
144+
return 0;
145+
}
143146
void rpl_instance_send_address_registration(rpl_instance_t *instance, const uint8_t addr[16])
144147
{
145148
}

0 commit comments

Comments
 (0)