2222#include "net_interface.h"
2323#include "eventOS_event.h"
2424#include "randLIB.h"
25+ #include "common_functions.h"
2526#include "NWK_INTERFACE/Include/protocol.h"
2627#include "6LoWPAN/Bootstraps/protocol_6lowpan.h"
2728#include "6LoWPAN/Bootstraps/protocol_6lowpan_interface.h"
2829#include "6LoWPAN/MAC/mac_helper.h"
2930#include "6LoWPAN/MAC/mac_data_poll.h"
3031#include "6LoWPAN/MAC/mpx_api.h"
32+ #include "6LoWPAN/MAC/mac_ie_lib.h"
3133#include "6LoWPAN/ws/ws_common_defines.h"
3234#include "6LoWPAN/ws/ws_common.h"
3335#include "6LoWPAN/ws/ws_bootstrap.h"
@@ -216,6 +218,96 @@ void ws_bootstrap_configuration_reset(protocol_interface_info_entry_t *cur)
216218 return ;
217219}
218220
221+ static bool ws_bootstrap_network_name_matches (const struct mcps_data_ie_list * ie_ext , const char * network_name_ptr )
222+ {
223+ mac_nested_payload_IE_t nested_payload_ie ;
224+ nested_payload_ie .id = WP_PAYLOAD_IE_NETNAME_TYPE ;
225+ nested_payload_ie .type_long = true;
226+
227+ if (!network_name_ptr || !ie_ext ){
228+ return false;
229+ }
230+
231+ if (0 == mac_ie_nested_discover (ie_ext -> payloadIeList , ie_ext -> payloadIeListLength , & nested_payload_ie )) {
232+ tr_warn ("No network name IE" );
233+ return false;
234+ }
235+
236+ if (network_name_ptr == NULL || strncmp (network_name_ptr , (char * )nested_payload_ie .content_ptr , nested_payload_ie .length ) != 0 ) {
237+ return false;
238+ }
239+ return true;
240+ }
241+
242+ static bool ws_bootstrap_unicast_schedule_read (uint8_t * ptr , uint16_t length , ws_hoopping_schedule_t * uc_hopping )
243+ {
244+ mac_nested_payload_IE_t nested_payload_ie ;
245+ nested_payload_ie .id = WP_PAYLOAD_IE_US_TYPE ;
246+ nested_payload_ie .type_long = true;
247+
248+ if (0 == mac_ie_nested_discover (ptr , length , & nested_payload_ie )) {
249+ tr_warn ("No unicast schedule" );
250+ return false;
251+ }
252+ if (nested_payload_ie .length < 4 ) {
253+ tr_warn ("corrupetd schedule" );
254+ return false;
255+ }
256+ if (!uc_hopping ) {
257+ // all OK no data read
258+ return true;
259+ }
260+ uc_hopping -> fhss_uc_dwell_interval = nested_payload_ie .content_ptr [0 ];
261+ uc_hopping -> clock_drift = nested_payload_ie .content_ptr [1 ];
262+ uc_hopping -> timing_accurancy = nested_payload_ie .content_ptr [2 ];
263+ uc_hopping -> channel_plan = (nested_payload_ie .content_ptr [3 ] & 0x03 );
264+ uc_hopping -> channel_function = (nested_payload_ie .content_ptr [3 ] & 0x38 ) >> 3 ;
265+
266+ // TODO missing rest of the fields
267+
268+ return true;
269+ }
270+
271+ static bool ws_bootstrap_pan_information_read (uint8_t * ptr , uint16_t length , ws_pan_information_t * pan_information )
272+ {
273+ mac_nested_payload_IE_t nested_payload_ie ;
274+ nested_payload_ie .id = WP_PAYLOAD_IE_PAN_TYPE ;
275+ nested_payload_ie .type_long = true;
276+
277+ if (0 == mac_ie_nested_discover (ptr , length , & nested_payload_ie )) {
278+ tr_warn ("No PAN information" );
279+ return false;
280+ }
281+ if (nested_payload_ie .length < 5 ) {
282+ tr_warn ("corrupetd PAN information" );
283+ return false;
284+ }
285+ if (pan_information ) {
286+ pan_information -> pan_size = common_read_16_bit_inverse (nested_payload_ie .content_ptr );
287+ pan_information -> routing_cost = common_read_16_bit_inverse (nested_payload_ie .content_ptr + 2 );
288+ pan_information -> use_parent_bs = (nested_payload_ie .content_ptr [4 ] & 0x10 ) == 0x10 ;
289+ pan_information -> rpl_routing_method = (nested_payload_ie .content_ptr [4 ] & 0x20 ) == 0x20 ;
290+ pan_information -> version = (nested_payload_ie .content_ptr [4 ]& 0xe0 ) >> 5 ;
291+ }
292+
293+ return true;
294+ }
295+
296+ static bool ws_bootstrap_ufsi_read (uint8_t * ptr , uint16_t length , uint_fast24_t * ufsi )
297+ {
298+ mac_header_IE_t utt_ie ;
299+ utt_ie .id = MAC_HEADER_ASSIGNED_EXTERNAL_ORG_IE_ID ;
300+
301+ if (4 != mac_ie_header_sub_id_discover (ptr , length , & utt_ie , WH_IE_UTT_TYPE )) {
302+ // NO UTT header
303+ return false;
304+ }
305+ if (ufsi ) {
306+ * ufsi = common_read_24_bit_inverse (& utt_ie .content_ptr [1 ]);
307+ }
308+ return true;
309+ }
310+
219311static 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 )
220312{
221313
@@ -230,16 +322,57 @@ static void ws_bootstrap_pan_advertisement_analyse(struct protocol_interface_inf
230322 // Not from long address
231323 return ;
232324 }
233- //TODO Match network name
325+ if (!ws_bootstrap_network_name_matches (ie_ext , cur -> ws_info -> network_name )) {
326+ // Not in our network
327+ return ;
328+ }
234329
235330 // This parent is selected and used for authentication.
236331 if (memcmp (cur -> ws_info -> parent_info .addr , ADDR_UNSPECIFIED ,8 ) != 0 ) {
237332 //Decide which is better parent for authentication
238- if (cur -> ws_info -> parent_info .signal_dbm > data -> signal_dbm ) {
333+ if (cur -> ws_info -> parent_info .link_quality > data -> mpduLinkQuality ) {
239334 return ;
240335 }
241336 }
242- // TODO save unicast timing info
337+
338+ ws_pan_information_t pan_information ;
339+ ws_hoopping_schedule_t hopping_schedule = { 0 };
340+ uint_fast24_t ufsi ;
341+
342+ if (!ws_bootstrap_ufsi_read (ie_ext -> headerIeList , ie_ext -> headerIeListLength , & ufsi )) {
343+ // Corrupted
344+ tr_error ("No ufsi" );
345+ return ;
346+ }
347+ if (!ws_bootstrap_pan_information_read (ie_ext -> payloadIeList , ie_ext -> payloadIeListLength , & pan_information )) {
348+ // Corrupted
349+ tr_error ("No pan information" );
350+ return ;
351+ }
352+
353+ // TODO create own function to read just dwell time
354+ if (!ws_bootstrap_unicast_schedule_read (ie_ext -> payloadIeList , ie_ext -> payloadIeListLength , & hopping_schedule )) {
355+ // Corrupted
356+ tr_error ("No unicast schedule" );
357+ return ;
358+ }
359+ // Check pan flags so that it is valid
360+ if (!pan_information .rpl_routing_method ) {
361+ // NOT RPL routing
362+ tr_warn ("Not supported routing" );
363+ return ;
364+ }
365+
366+ // Parent valid store information
367+ cur -> ws_info -> parent_info .ufsi = ufsi ;
368+ // Saved from unicast IE
369+ cur -> ws_info -> parent_info .dwell_interval = hopping_schedule .fhss_uc_dwell_interval ;
370+
371+ // Saved from Pan information
372+ cur -> ws_info -> parent_info .pan_configuration = pan_information ;
373+
374+ // Saved from message
375+ cur -> ws_info -> parent_info .timestamp = data -> timestamp ;
243376 cur -> ws_info -> parent_info .pan_id = data -> SrcPANId ;
244377 cur -> ws_info -> parent_info .link_quality = data -> mpduLinkQuality ;
245378 cur -> ws_info -> parent_info .signal_dbm = data -> signal_dbm ;
@@ -252,16 +385,16 @@ static void ws_bootstrap_pan_advertisement_solicit_analyse(struct protocol_inter
252385{
253386
254387 (void )data ;
255- (void )ie_ext ;
256388 if (!ws_bootstrap_state_active (cur )) {
389+ // We are not active yet
390+ return ;
391+ }
392+ if (!ws_bootstrap_network_name_matches (ie_ext , cur -> ws_info -> network_name )) {
393+ // Not in our network
394+ tr_debug ("Network name not matching" );
257395 return ;
258396 }
259- //TODO Match network name
260- //TODO message is valid
261-
262397 trickle_inconsistent_heard (& cur -> ws_info -> trickle_pan_advertisement ,& trickle_params_pan_advertisement );
263-
264-
265398}
266399
267400static bool ws_bootstrap_network_found (protocol_interface_info_entry_t * cur )
@@ -415,6 +548,36 @@ static void ws_bootstrap_fhss_activate(protocol_interface_info_entry_t *cur)
415548 return ;
416549}
417550
551+ static void ws_bootstrap_network_information_learn (protocol_interface_info_entry_t * cur )
552+ {
553+ tr_debug ("learn network information from parent" );
554+
555+ // Start following network timing schedules
556+ cur -> ws_info -> hopping_schdule .fhss_uc_dwell_interval = cur -> ws_info -> parent_info .dwell_interval ;
557+ // Regulatory domain saving? cant change?
558+
559+ // Save network information
560+ cur -> ws_info -> network_pan_id = cur -> ws_info -> parent_info .pan_id ;
561+ cur -> ws_info -> pan_configuration = cur -> ws_info -> parent_info .pan_configuration ;
562+ cur -> ws_info -> pan_configuration .pan_version = 0 ; // This is learned from actual configuration
563+
564+ // TODO create parent neighbour table entry for unicast schedule to enable authentication
565+
566+ return ;
567+ }
568+ static void ws_bootstrap_network_configuration_learn (protocol_interface_info_entry_t * cur )
569+ {
570+ tr_debug ("learn network information from parent" );
571+
572+ // Save network information
573+ cur -> ws_info -> pan_configuration = cur -> ws_info -> parent_info .pan_configuration ;
574+
575+ // Timing information can be modified here
576+ ws_llc_set_pan_information_pointer (cur , & cur -> ws_info -> pan_configuration );
577+
578+ return ;
579+ }
580+
418581static void ws_bootstrap_ip_stack_activate (protocol_interface_info_entry_t * cur )
419582{
420583 tr_debug ("ip stack init" );
@@ -447,12 +610,18 @@ static void ws_bootstrap_rpl_activate(protocol_interface_info_entry_t *cur)
447610 rpl_control_transmit_dis (cur -> rpl_domain , cur , 0 , 0 , NULL , 0 , ADDR_LINK_LOCAL_ALL_ROUTERS );
448611 }
449612}
613+
450614static void ws_bootstrap_network_start (protocol_interface_info_entry_t * cur )
451615{
452616 //Set Network names, Pan information configure, hopping schedule & GTKHash
453617 ws_llc_set_network_name (cur , (uint8_t * )cur -> ws_info -> network_name , strlen (cur -> ws_info -> network_name ));
454618 ws_llc_set_pan_information_pointer (cur , & cur -> ws_info -> pan_configuration );
619+ }
455620
621+ static void ws_bootstrap_network_discovery_configure (protocol_interface_info_entry_t * cur )
622+ {
623+ //Set Network names, Pan information configure, hopping schedule & GTKHash
624+ ws_llc_set_network_name (cur , (uint8_t * )cur -> ws_info -> network_name , strlen (cur -> ws_info -> network_name ));
456625}
457626
458627
@@ -595,16 +764,26 @@ static void ws_bootstrap_event_handler(arm_event_s *event)
595764 if (cur -> bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER ) {
596765 tr_debug ("Border router start network" );
597766 cur -> ws_info -> network_pan_id = randLIB_get_random_in_range (0 ,0xfffd );
767+ cur -> ws_info -> pan_configuration .pan_size = 3 ;
768+ cur -> ws_info -> pan_configuration .pan_version = randLIB_get_random_in_range (0 ,0xffff );
769+ cur -> ws_info -> pan_configuration .routing_cost = 0 ;
770+ cur -> ws_info -> pan_configuration .rpl_routing_method = true;
771+ cur -> ws_info -> pan_configuration .use_parent_bs = true;
772+ cur -> ws_info -> pan_configuration .version = WS_FAN_VERSION_1_0 ;
598773 ws_bootstrap_fhss_activate (cur );
599774 ws_bootstrap_event_operation_start (cur );
600775 break ;
601776 }
777+ // Configure LLC for network discovery
778+ ws_bootstrap_network_discovery_configure (cur );
602779 ws_bootstrap_fhss_activate (cur );
603780 // Start network scan
604781 ws_bootstrap_start_discovery (cur );
605782 break ;
606783 case WS_CONFIGURATION_START :
607784 tr_info ("Configuration start" );
785+ // TODO temporary learn from parent
786+ ws_bootstrap_network_configuration_learn (cur );
608787 ws_bootstrap_event_authentication_start (cur );
609788 break ;
610789 case WS_AUTHENTICATION_START :
@@ -643,7 +822,7 @@ void ws_bootstrap_network_scan_process(protocol_interface_info_entry_t *cur)
643822 cur -> nwk_nd_re_scan_count ++ ;
644823 if (ws_bootstrap_network_found (cur )) {
645824 tr_info ("select network" );
646- cur -> ws_info -> network_pan_id = cur -> ws_info -> parent_info . pan_id ;
825+ ws_bootstrap_network_information_learn ( cur ) ;
647826 ws_bootstrap_fhss_activate (cur );
648827 ws_bootstrap_event_authentication_start (cur );
649828 return ;
@@ -716,7 +895,7 @@ void ws_bootstrap_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t s
716895 if (trickle_timer (& cur -> ws_info -> trickle_pan_config , & trickle_params_pan_configuration , seconds )) {
717896 // send PAN Configuration
718897 tr_info ("Send PAN configuration" );
719- ws_bootstrap_pan_config (cur );
898+ // ws_bootstrap_pan_config(cur);
720899 }
721900}
722901
0 commit comments