mesh: Correctly generate NetKey list 30/222930/1
authorInga Stotland <inga.stotland@intel.com>
Thu, 9 Jan 2020 21:54:32 +0000 (13:54 -0800)
committerAbhay Agarwal <ay.agarwal@samsung.com>
Mon, 20 Jan 2020 05:29:50 +0000 (10:59 +0530)
When responding with NetKey List Status, packed NetKey indices into
3 octets per pair. If number of NetKeys is odd, append the last key
index as a 2-octet value.

Change-Id: I56d98a5203d4a72f1b419d0f4758227594537808
Signed-off-by: Abhay Agarwal <ay.agarwal@samsung.com>
mesh/net.c

index 1208762..49be155 100644 (file)
@@ -1063,26 +1063,46 @@ bool mesh_net_get_key(struct mesh_net *net, bool new_key, uint16_t idx,
 bool mesh_net_key_list_get(struct mesh_net *net, uint8_t *buf, uint16_t *size)
 {
        const struct l_queue_entry *entry;
-       uint16_t n, buf_size;
+       uint16_t num_keys, req_size, buf_size;
+       struct mesh_subnet *subnet;
 
        if (!net || !buf || !size)
                return false;
 
        buf_size = *size;
-       if (buf_size < l_queue_length(net->subnets) * 2)
+
+       num_keys = l_queue_length(net->subnets);
+       req_size = (num_keys / 2) * 3 + (num_keys % 2) * 2;
+
+       if (buf_size < req_size)
                return false;
 
-       n = 0;
-       entry = l_queue_get_entries(net->subnets);
+       *size = req_size;
+
+       /* Pack NetKey indices in 3 octets */
+       for (entry = l_queue_get_entries(net->subnets); num_keys > 1;) {
+               uint32_t idx_pair;
 
-       for (; entry; entry = entry->next) {
-               struct mesh_subnet *subnet = entry->data;
+               subnet = entry->data;
+               idx_pair = subnet->idx;
+               idx_pair <<= 12;
+
+               subnet = entry->next->data;
+               idx_pair += subnet->idx;
+
+               l_put_le32(idx_pair, buf);
+               buf += 3;
+
+               num_keys -= 2;
+               entry = entry->next->next;
+       }
 
+       /* If odd number of NetKeys, fill in the end of the buffer */
+       if (num_keys % 2) {
+               subnet = entry->data;
                l_put_le16(subnet->idx, buf);
-               n += 2;
        }
 
-       *size = n;
        return true;
 }