diff --git a/source/6LoWPAN/Bootstraps/Generic/protocol_6lowpan_bootstrap.c b/source/6LoWPAN/Bootstraps/Generic/protocol_6lowpan_bootstrap.c index f8bbd3919e8..7ab3ae6294c 100644 --- a/source/6LoWPAN/Bootstraps/Generic/protocol_6lowpan_bootstrap.c +++ b/source/6LoWPAN/Bootstraps/Generic/protocol_6lowpan_bootstrap.c @@ -389,80 +389,87 @@ static uint8_t mle_link_quality_tlv_parse(uint8_t *mac64, uint16_t short_address return 0; } +static bool neighbor_list_short_address_available(mac_neighbor_table_t *table_class) +{ + ns_list_foreach(mac_neighbor_table_entry_t, cur_entry, &table_class->neighbour_list) { + if (cur_entry->connected_device && cur_entry->mac16 == 0xffff) { + return false; + } + } + return true; +} + + static uint8_t *mle_table_set_neighbours(protocol_interface_info_entry_t *cur, uint8_t *ptr) { uint8_t *len_ptr = 0; - uint8_t short_temp[2] = {0xff,0xff}; uint8_t neigh_count = 0; uint8_t neigh_count_max = 0; uint8_t *link_flags_ptr; mac_neighbor_table_entry_t *first_entry_ptr = NULL; - bool loop_list = false; mac_neighbor_table_list_t * neigh_list = &cur->mac_parameters->mac_neighbor_table->neighbour_list; *ptr++ = MLE_TYPE_LINK_QUALITY; len_ptr = ptr++; *len_ptr = 1; - // defaults: complete, 2 bytes long link-layer address + link_flags_ptr = ptr++; - *link_flags_ptr = 0x81; - if (mac_neighbor_table_address_discover(mac_neighbor_info(cur), short_temp,ADDR_802_15_4_SHORT)) { - *link_flags_ptr |= 0x07; - neigh_count_max = mle_advert_neigh_cnt(cur, false); + //*link_flags_ptr = 0x81; + bool use_short_address_compression = neighbor_list_short_address_available(mac_neighbor_info(cur)); + if (use_short_address_compression) { + //complete, 2 bytes long link-layer address + *link_flags_ptr = 0x81; } else { - neigh_count_max = mle_advert_neigh_cnt(cur, true); + //complete, 8 bytes long link-layer address + *link_flags_ptr = 0x87; + } + neigh_count_max = mle_advert_neigh_cnt(cur, use_short_address_compression); bool clean_entries = false; - do { - ns_list_foreach(mac_neighbor_table_entry_t, cur_entry, neigh_list) - { - - loop_list = false; + ns_list_foreach(mac_neighbor_table_entry_t, cur_entry, neigh_list) + { - if ((cur_entry->connected_device) && (cur_entry->advertisment == false) && (cur_entry->mac16 < 0xfffe)) { + if ((cur_entry->connected_device) && (cur_entry->advertisment == false)) { - // If looping list, stops adding entries when at first sent entry again - if (first_entry_ptr == cur_entry) { - break; - } else if (first_entry_ptr == NULL) { - first_entry_ptr = cur_entry; - } + // If looping list, stops adding entries when at first sent entry again + if (first_entry_ptr == cur_entry) { + break; + } else if (first_entry_ptr == NULL) { + first_entry_ptr = cur_entry; + } - // Limits the number of entries that are sent - if (++neigh_count > neigh_count_max) { - *link_flags_ptr &= 0x7f; - break; - } + // Limits the number of entries that are sent + if (++neigh_count > neigh_count_max) { + *link_flags_ptr &= 0x7f; + break; + } - if (cur_entry->link_role == PRIORITY_PARENT_NEIGHBOUR) { - *ptr++ = MLE_NEIGHBOR_PRIORITY_LINK | MLE_NEIGHBOR_INCOMING_LINK | MLE_NEIGHBOR_OUTGOING_LINK; - } else { - *ptr++ = MLE_NEIGHBOR_INCOMING_LINK | MLE_NEIGHBOR_OUTGOING_LINK; - } + if (cur_entry->link_role == PRIORITY_PARENT_NEIGHBOUR) { + *ptr++ = MLE_NEIGHBOR_PRIORITY_LINK | MLE_NEIGHBOR_INCOMING_LINK | MLE_NEIGHBOR_OUTGOING_LINK; + } else { + *ptr++ = MLE_NEIGHBOR_INCOMING_LINK | MLE_NEIGHBOR_OUTGOING_LINK; + } - *ptr++ = etx_local_incoming_idr_read(cur->id, cur_entry->index) >> 3; + *ptr++ = etx_local_incoming_idr_read(cur->id, cur_entry->index) >> 3; - if ((*link_flags_ptr & 0x07) == 1) { - ptr = common_write_16_bit(cur_entry->mac16, ptr); - *len_ptr += 4; - } else { - memcpy(ptr, cur_entry->mac64, 8); - ptr += 8; - *len_ptr += 10; - } + if (use_short_address_compression) { + ptr = common_write_16_bit(cur_entry->mac16, ptr); + *len_ptr += 4; + } else { + memcpy(ptr, cur_entry->mac64, 8); + ptr += 8; + *len_ptr += 10; + } - // If end of the neighbor list, start adding entries from start again - if (cur_entry->link.next == 0) { - loop_list = true; - clean_entries = true; - } else { - cur_entry->advertisment = true; - } + // If end of the neighbor list, Mark a clean advertisment from the list + if (cur_entry->link.next == 0) { + clean_entries = true; } + cur_entry->advertisment = true; } - } while (loop_list); + } if (clean_entries) { ns_list_foreach(mac_neighbor_table_entry_t, temp, neigh_list) {