-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstartjoin.c
179 lines (148 loc) · 6.4 KB
/
startjoin.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#include "starfishnet.h"
#include "node_table.h"
#include "logging.h"
#include "routing_tree.h"
#include "discovery.h"
#include "config.h"
#include "dmem.h"
#include <string.h>
#include <assert.h>
//start a new StarfishNet network as coordinator
int8_t SN_Start(const SN_Network_descriptor_t *network) {
int8_t ret;
SN_InfoPrintf("enter\n");
if(network == NULL || network->network_config == NULL) {
SN_ErrPrintf("network and network->config must be non-NULL\n");
return -SN_ERR_NULL;
}
//Fill NIB
SN_InfoPrintf("filling NIB...\n");
starfishnet_config.tree_branching_factor = network->network_config->routing_tree_branching_factor;
starfishnet_config.tree_position = 0;
starfishnet_config.enable_routing = 1;
starfishnet_config.leaf_blocks = network->network_config->leaf_blocks;
starfishnet_config.parent_address = SN_COORDINATOR_ADDRESS;
memcpy(&starfishnet_config.parent_public_key, &starfishnet_config.device_root_key.public_key, sizeof(starfishnet_config.parent_public_key));
ret = SN_Tree_init();
if(ret != SN_OK) {
SN_ErrPrintf("error in routing tree configuration: %d\n", -ret);
return ret;
}
SN_InfoPrintf("setting channel...\n");
if(NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, network->radio_channel) != RADIO_RESULT_OK) {
SN_ErrPrintf("tried to set channel to %d; radio said no\n", network->radio_channel);
return -SN_ERR_RADIO;
}
SN_InfoPrintf("setting short address...\n");
if(NETSTACK_RADIO.set_value(RADIO_PARAM_16BIT_ADDR, SN_COORDINATOR_ADDRESS) != RADIO_RESULT_OK) {
SN_ErrPrintf("tried to set short address to %d; radio said no\n", SN_COORDINATOR_ADDRESS);
return -SN_ERR_RADIO;
}
starfishnet_config.short_address = SN_COORDINATOR_ADDRESS;
SN_InfoPrintf("setting PAN ID...\n");
if(NETSTACK_RADIO.set_value(RADIO_PARAM_PAN_ID, network->pan_id) != RADIO_RESULT_OK) {
SN_ErrPrintf("tried to set PAN ID to %d; radio said no\n", network->pan_id);
return -SN_ERR_RADIO;
}
starfishnet_config.pan_id = network->pan_id;
SN_InfoPrintf("updating beacon payload\n");
SN_Beacon_update();
return SN_OK;
}
static int8_t add_parent_to_node_table() {
int8_t ret;
SN_Table_entry_t* parent_table_entry;
SN_InfoPrintf("adding parent (0x%04x) to node table\n", starfishnet_config.parent_address);
ALLOCATE_COND(parent_table_entry, {
SN_InfoPrintf("failed to add parent to node table due to lack of memory\n");
return -SN_ERR_RESOURCES;
});
memset(parent_table_entry, 0, sizeof(*parent_table_entry));
parent_table_entry->short_address = starfishnet_config.parent_address;
parent_table_entry->details_known = 1;
memcpy(&parent_table_entry->public_key, &starfishnet_config.parent_public_key, sizeof(parent_table_entry->public_key));
ret = SN_Table_lookup(NULL, parent_table_entry);
if(ret == SN_OK) {
parent_table_entry->short_address = starfishnet_config.parent_address;
parent_table_entry->details_known = 1;
memcpy(&parent_table_entry->public_key, &starfishnet_config.parent_public_key, sizeof(parent_table_entry->public_key));
}
parent_table_entry->neighbor = 1;
SN_InfoPrintf("performing table insertion\n");
SN_Table_update(parent_table_entry);
ret = SN_Table_insert(parent_table_entry);
if(ret == -SN_ERR_UNEXPECTED) {
//it's ok if the entry already exists
ret = SN_OK;
}
FREE(parent_table_entry);
return ret;
}
/* Tune the radio to a StarfishNet network.
* Then, discover any other nearby nodes, and add them to the node table as neighbors.
* Finally, associate with our new parent and get an address.
*
* Note that if routing is disabled, we don't transmit beacons.
*/
int8_t SN_Join(const SN_Network_descriptor_t *network, bool disable_routing) {
int8_t ret;
SN_Endpoint_t *parent_address;
SN_InfoPrintf("enter\n");
//we're joining a new network, so assume we have no neighbors
SN_Table_clear_all_neighbors();
//Fill NIB
SN_InfoPrintf("filling NIB...\n");
starfishnet_config.tree_branching_factor = network->network_config->routing_tree_branching_factor;
starfishnet_config.tree_position = network->network_config->routing_tree_position + starfishnet_config.tree_branching_factor;
starfishnet_config.enable_routing = (uint8_t) (disable_routing ? 0 : 1);
starfishnet_config.leaf_blocks = network->network_config->leaf_blocks;
starfishnet_config.parent_address = network->network_config->router_address;
starfishnet_config.pan_id = network->pan_id;
memcpy(&starfishnet_config.parent_public_key, &network->network_config->router_public_key,
sizeof(starfishnet_config.parent_public_key));
//Do routing tree math and set up address allocation
SN_InfoPrintf("configuring the routing tree...\n");
ret = SN_Tree_init();
assert(SN_OK == RADIO_RESULT_OK);
//Tune to the right channel
if (ret == SN_OK) {
SN_InfoPrintf("setting radio channel to %d...\n", network->radio_channel);
ret = NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, network->radio_channel);
if (ret != RADIO_RESULT_OK) {
ret = -SN_ERR_RADIO;
}
}
//Set our PAN ID
if (ret == SN_OK) {
SN_InfoPrintf("setting PAN ID to 0x%04x...\n", starfishnet_config.pan_id);
ret = NETSTACK_RADIO.set_value(RADIO_PARAM_PAN_ID, starfishnet_config.pan_id);
if (ret != RADIO_RESULT_OK) {
ret = -SN_ERR_RADIO;
}
}
//add parent to node table
if (ret == SN_OK) {
ret = add_parent_to_node_table();
}
//start neighbor discovery
/*if (ret == SN_OK) {
ret = SN_Discover_neighbors();
}*/
if (ret != SN_OK) {
return ret;
}
//start security association with our parent (implicitly requesting an address)
ALLOCATE_COND(parent_address, {
SN_InfoPrintf("cannot send association message due to lack of memory\n");
return -SN_ERR_RESOURCES;
});
memset(parent_address, 0, sizeof(*parent_address));
parent_address->type = SN_ENDPOINT_SHORT_ADDRESS;
parent_address->short_address = starfishnet_config.parent_address;
SN_InfoPrintf("sending associate request to 0x%04x\n", parent_address->short_address);
ret = SN_Associate(parent_address);
FREE(parent_address);
//And we're done
SN_InfoPrintf("exit\n");
return ret;
}