Skip to content

Commit

Permalink
Merge pull request ARMmbed#1763 from ARMmbed/mle_fixs
Browse files Browse the repository at this point in the history
Fix broken MLE neigbor list write operation.
  • Loading branch information
juhhei01 committed Aug 1, 2018
2 parents 833e740 + 944f9ca commit 87cc2c9
Showing 1 changed file with 54 additions and 47 deletions.
101 changes: 54 additions & 47 deletions source/6LoWPAN/Bootstraps/Generic/protocol_6lowpan_bootstrap.c
Expand Up @@ -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) {
Expand Down

0 comments on commit 87cc2c9

Please sign in to comment.