Mesh: Implement Network Destroy Request
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / services / mesh / bt-service-mesh-nodes.c
1 /*
2  * Bluetooth-frwk
3  *
4  * Copyright (c) 2020 Samsung Electronics Co., Ltd.
5  *
6  * @author: Anupam Roy <anupam.r@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *              http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21 #include <glib.h>
22 #include <dlog.h>
23 #include "bt-service-common.h"
24 #include "bt-service-core-adapter.h"
25 #include "bt-service-event-receiver.h"
26 #include "bt-request-handler.h"
27 #include "bluetooth-api.h"
28
29 #include "bluetooth-api.h"
30 #include "bluetooth-mesh-api.h"
31 #include "bt-internal-types.h"
32 #include "bt-service-util.h"
33 #include "bt-service-common.h"
34 #include "bt-service-event.h"
35
36 #include "bt-service-mesh-cdb.h"
37 #include "bt-service-mesh-keys.h"
38 #include "bt-service-mesh-util.h"
39
40 #include <ell/ell.h>
41
42 #include "bt-internal-types.h"
43
44 struct _bt_mesh_node_t {
45         uint16_t unicast;
46         struct l_queue *net_keys;
47         struct l_queue *app_keys;
48         struct l_queue **els;
49         uint8_t uuid[16];
50         uint8_t num_ele;
51 };
52
53 struct mesh_network_t {
54         uint8_t net_uuid[16];
55         struct l_queue *nodes;
56 };
57
58 static struct l_queue *networks;
59
60 struct mesh_key_index {
61         uint8_t uuid[16];
62         uint16_t idx;
63 };
64
65 static bool __mesh_match_bound_key(const void *a, const void *b)
66 {
67         uint16_t app_idx = L_PTR_TO_UINT(a);
68         const struct mesh_key_index *data = b;
69
70         uint16_t net_idx = L_PTR_TO_UINT(b);
71
72         return (net_idx == _bt_mesh_keys_get_bound_key(
73                                 (uint8_t*)data->uuid, app_idx));
74 }
75
76 static bool __mesh_match_node_dev_uuid(const void *a, const void *b)
77 {
78         const struct _bt_mesh_node_t *node = a;
79         uint8_t* dev_uuid = (uint8_t*)b;
80
81         if (memcmp(node->uuid, dev_uuid, 16) == 0) {
82                 BT_INFO("Mesh: Found Node with given Dev UUID");
83                 return true;
84         }
85
86         return false;
87 }
88
89 static bool __mesh_net_uuid_match(const void *a, const void *b)
90 {
91         const struct mesh_network_t *net = a;
92         uint8_t* uuid = (uint8_t*)b;
93
94         if (memcmp(net->net_uuid, uuid, 16) == 0) {
95                 BT_INFO("Mesh: Found network with given Net UUID");
96                 return true;
97         }
98
99         return false;
100 }
101
102 static bool __mesh_remove_node_entry(void *a, void *b)
103 {
104         uint8_t num_ele, i;
105         struct _bt_mesh_node_t *rmt = (struct _bt_mesh_node_t*) a;
106
107         num_ele = rmt->num_ele;
108
109         for (i = 0; i < num_ele; ++i)
110                 l_queue_destroy(rmt->els[i], NULL);
111
112         l_free(rmt->els);
113
114         l_queue_destroy(rmt->net_keys, l_free);
115         l_queue_destroy(rmt->app_keys, l_free);
116
117         l_free(rmt);
118         return true;
119 }
120
121 static bool __mesh_key_present(struct l_queue *keys, uint16_t app_idx)
122 {
123         const struct l_queue_entry *l;
124
125         for (l = l_queue_get_entries(keys); l; l = l->next) {
126                 uint16_t idx = L_PTR_TO_UINT(l->data);
127
128                 if (idx == app_idx)
129                         return true;
130         }
131
132         return false;
133 }
134
135 static int __mesh_compare_mod_id(const void *a, const void *b,
136                 void *user_data)
137 {
138         uint32_t id1 = L_PTR_TO_UINT(a);
139         uint32_t id2 = L_PTR_TO_UINT(b);
140
141         if (id1 >= MESH_VENDOR_ID_MASK)
142                 id1 &= ~MESH_VENDOR_ID_MASK;
143
144         if (id2 >= MESH_VENDOR_ID_MASK)
145                 id2 &= ~MESH_VENDOR_ID_MASK;
146
147         if (id1 < id2)
148                 return -1;
149
150         if (id1 > id2)
151                 return 1;
152
153         return 0;
154 }
155
156 static int __mesh_compare_unicast(const void *a, const void *b,
157                 void *user_data)
158 {
159         const struct _bt_mesh_node_t *a_rmt = a;
160         const struct _bt_mesh_node_t *b_rmt = b;
161
162         if (a_rmt->unicast < b_rmt->unicast)
163                 return -1;
164
165         if (a_rmt->unicast > b_rmt->unicast)
166                 return 1;
167
168         return 0;
169 }
170
171 static bool __mesh_match_node_addr(const void *a, const void *b)
172 {
173         const struct _bt_mesh_node_t *rmt = a;
174         uint16_t addr = L_PTR_TO_UINT(b);
175
176         if (addr >= rmt->unicast &&
177                         addr <= (rmt->unicast + rmt->num_ele - 1))
178                 return true;
179
180         return false;
181 }
182
183 void _bt_mesh_node_load_net(uint8_t net_uuid[])
184 {
185         struct mesh_network_t *network;
186         BT_INFO("Mesh:Nodes: Create new network");
187
188         if (l_queue_find(networks, __mesh_net_uuid_match, net_uuid))
189                 return;
190
191         if (!networks)
192                 networks = l_queue_new();
193
194         network = l_new(struct mesh_network_t, 1);
195         memcpy(network->net_uuid, net_uuid, 16);
196         network->nodes =  l_queue_new();
197         l_queue_push_tail(networks, network);
198 }
199
200 void _bt_mesh_node_unload_net(uint8_t net_uuid[])
201 {
202         struct mesh_network_t *network;
203         int numnodes;
204         BT_INFO("Mesh:Nodes: Unload network with all nodes");
205
206         network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
207         if (!network || !network->nodes)
208                 return;
209
210         /* Only remove the ndoe from the Local Network object:
211            DONT touch configuration file */
212         numnodes = l_queue_foreach_remove(network->nodes,
213                         __mesh_remove_node_entry, NULL);
214         BT_INFO("Mesh:Nodes: Unloadeded [%d] Nodes from the network", numnodes);
215         l_queue_remove(networks, network);
216         l_free(network);
217
218         BT_INFO("Mesh: After unloading, number of networks [%d]",
219                 l_queue_length(networks));
220 }
221
222 bool _bt_mesh_node_get_unicast_from_dev_uuid(uint8_t net_uuid[],
223                 const uint8_t dev_uuid[], uint16_t *unicast)
224 {
225         struct _bt_mesh_node_t *rmt;
226         struct mesh_network_t *network;
227
228         network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
229         if (!network)
230                 return false;
231
232         rmt = l_queue_find(network->nodes,
233                         __mesh_match_node_dev_uuid, dev_uuid);
234         if (!rmt)
235                 return false;
236
237         *unicast = rmt->unicast;
238         return true;
239 }
240
241 bool _bt_mesh_node_get_element_count(uint8_t net_uuid[],
242                 uint16_t unicast, uint8_t *count)
243 {
244         struct _bt_mesh_node_t *rmt;
245         struct mesh_network_t *network;
246
247         network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
248         if (!network)
249                 return false;
250
251         rmt = l_queue_find(network->nodes, __mesh_match_node_addr,
252                         L_UINT_TO_PTR(unicast));
253         if (!rmt)
254                 return false;
255
256         *count = rmt->num_ele;
257
258         return true;
259 }
260
261 bool _bt_mesh_node_add_node(uint8_t net_uuid[],
262         const uint8_t node_uuid[16], uint16_t unicast,
263                 uint8_t ele_cnt, uint16_t net_idx)
264 {
265         struct _bt_mesh_node_t *rmt;
266         struct mesh_network_t *network;
267
268         network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
269         if (!network)
270                 return false;
271
272         rmt = l_queue_find(network->nodes,
273                         __mesh_match_node_addr, L_UINT_TO_PTR(unicast));
274         if (rmt)
275                 return false;
276
277         rmt = l_new(struct _bt_mesh_node_t, 1);
278         memcpy(rmt->uuid, node_uuid, 16);
279         rmt->unicast = unicast;
280         rmt->num_ele = ele_cnt;
281         rmt->net_keys = l_queue_new();
282
283         l_queue_push_tail(rmt->net_keys, L_UINT_TO_PTR(net_idx));
284
285         rmt->els = l_new(struct l_queue *, ele_cnt);
286
287         if (!network->nodes)
288                 network->nodes = l_queue_new();
289
290         if (l_queue_insert(network->nodes, rmt, __mesh_compare_unicast, NULL))
291                 BT_INFO("Mesh: node added to Network");
292         else
293                 BT_INFO("Mesh: node could not be added to Network");
294         return true;
295 }
296
297 bool _bt_mesh_node_get_models(uint8_t net_uuid[],
298                 uint16_t unicast, uint8_t ele_idx,
299                         GArray **out)
300 {
301         struct _bt_mesh_node_t *rmt;
302         struct mesh_network_t *network;
303         const struct l_queue_entry *entry;
304
305         BT_INFO("Mesh: Get All Models in an element [0x%4.4x] Index [0x%x]",
306                         unicast, ele_idx);
307
308         network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
309         if (!network)
310                 return false;
311
312         rmt = l_queue_find(network->nodes,
313                         __mesh_match_node_addr, L_UINT_TO_PTR(unicast));
314         if (!rmt)
315                 return false;
316
317         if (!rmt->els[ele_idx])
318                 return false;
319
320         entry = l_queue_get_entries(rmt->els[ele_idx]);
321
322         BT_INFO("Mesh: Total Models in Element [%d]",
323                         l_queue_length(rmt->els[ele_idx]));
324         for (; entry; entry = entry->next) {
325                 uint32_t model = L_PTR_TO_UINT(entry->data);
326                 g_array_append_vals(*out, &model, sizeof(uint32_t));
327                 BT_INFO("Mesh: Appended Model ID [0x%4.4x]", model);
328         }
329         return true;
330 }
331
332 bool _bt_mesh_node_set_model(uint8_t net_uuid[],
333         uint16_t unicast, uint8_t ele_idx,
334                 uint32_t mod_id, bool vendor)
335 {
336         struct _bt_mesh_node_t *rmt;
337         struct mesh_network_t *network;
338
339         network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
340         if (!network)
341                 return false;
342
343         rmt = l_queue_find(network->nodes,
344                         __mesh_match_node_addr, L_UINT_TO_PTR(unicast));
345         if (!rmt)
346                 return false;
347
348         if (ele_idx >= rmt->num_ele)
349                 return false;
350
351         if (!rmt->els[ele_idx])
352                 rmt->els[ele_idx] = l_queue_new();
353
354         if (!vendor)
355                 mod_id = MESH_VENDOR_ID_MASK | mod_id;
356
357         BT_INFO("Mesh: Insert Model in Element Index [0x%x]", ele_idx);
358         BT_INFO("Mesh: Insert Model Id [0x%4.4x]", mod_id);
359         l_queue_insert(rmt->els[ele_idx], L_UINT_TO_PTR(mod_id),
360                         __mesh_compare_mod_id, NULL);
361
362         BT_INFO("Mesh: Current model count after update in element is [%d]",
363                         l_queue_length(rmt->els[ele_idx]));
364
365         return true;
366 }
367
368 bool _bt_mesh_node_del_net_key(_bt_mesh_cdb_t *cfg,
369         uint8_t net_uuid[], uint16_t addr,
370                 uint16_t net_idx)
371 {
372         struct _bt_mesh_node_t *rmt;
373         void *data;
374         struct mesh_network_t *network;
375         struct mesh_key_index *user_data;
376
377         network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
378         if (!network)
379                 return false;
380
381         rmt = l_queue_find(network->nodes,
382                         __mesh_match_node_addr, L_UINT_TO_PTR(addr));
383         if (!rmt)
384                 return false;
385
386         if (!l_queue_remove(rmt->net_keys, L_UINT_TO_PTR(net_idx)))
387                 return false;
388
389         user_data = g_malloc0(sizeof(struct mesh_key_index));
390         memcpy(user_data->uuid, net_uuid, 16);
391         user_data->idx = net_idx;
392
393         data = l_queue_remove_if(rmt->app_keys,
394                         __mesh_match_bound_key, user_data);
395         while (data) {
396                 uint16_t app_idx = (uint16_t) L_PTR_TO_UINT(data);
397
398                 _bt_mesh_conf_node_delete_application_key(cfg, rmt->unicast, app_idx);
399                 data = l_queue_remove_if(rmt->app_keys,
400                                 __mesh_match_bound_key, user_data);
401         }
402
403         g_free(user_data);
404         return true;
405 }
406
407 bool _bt_mesh_node_get_all_appkeys(uint8_t net_uuid[],
408                 uint16_t unicast, uint16_t netkey, GArray **out)
409 {
410         struct mesh_network_t *network;
411         const struct l_queue_entry *entry;
412         struct _bt_mesh_node_t *rmt;
413
414         network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
415         if (!network)
416                 return false;
417
418         rmt = l_queue_find(network->nodes,
419                 __mesh_match_node_addr, L_UINT_TO_PTR(unicast));
420         if (!rmt)
421                 return false;
422
423         entry = l_queue_get_entries(rmt->app_keys);
424
425         for (; entry; entry = entry->next) {
426                 uint16_t net_idx;
427                 uint16_t app_idx = L_PTR_TO_UINT(entry->data);
428                 net_idx = _bt_mesh_keys_get_bound_key(net_uuid, app_idx);
429                 if (net_idx == netkey)
430                         g_array_append_vals(*out, &app_idx, sizeof(uint16_t));
431         }
432         return true;
433 }
434
435 bool _bt_mesh_node_get_all_netkeys(uint8_t net_uuid[],
436                 uint16_t unicast, GArray **out)
437 {
438         struct mesh_network_t *network;
439         const struct l_queue_entry *entry;
440         struct _bt_mesh_node_t *rmt;
441
442         network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
443         if (!network)
444                 return false;
445
446         rmt = l_queue_find(network->nodes,
447                         __mesh_match_node_addr, L_UINT_TO_PTR(unicast));
448         if (!rmt)
449                 return false;
450
451         entry = l_queue_get_entries(rmt->net_keys);
452
453         for (; entry; entry = entry->next) {
454
455                 uint16_t net_idx = L_PTR_TO_UINT(entry->data);
456
457                 g_array_append_vals(*out, &net_idx, sizeof(uint16_t));
458         }
459         return true;
460 }
461
462 bool _bt_mesh_node_get_all(uint8_t net_uuid[], GArray **out)
463 {
464         struct mesh_network_t *network;
465         const struct l_queue_entry *entry;
466         bluetooth_mesh_node_info_t n;
467
468         network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
469         if (!network)
470                 return false;
471
472         entry = l_queue_get_entries(network->nodes);
473
474         for (; entry; entry = entry->next) {
475
476                 memset(&n, 0x00, sizeof(bluetooth_mesh_node_info_t));
477                 struct _bt_mesh_node_t *node = entry->data;
478
479                 n.primary_unicast = node->unicast;
480                 _bt_mesh_util_convert_hex_to_string(node->uuid, 16,
481                         n.dev_uuid, sizeof(n.dev_uuid));
482                 BT_INFO("Mesh: Dev UUID [%s]", n.dev_uuid);
483
484                 g_array_append_vals(*out, &n,
485                                 sizeof(bluetooth_mesh_node_info_t));
486         }
487         return true;
488 }
489
490 bool _bt_mesh_node_is_netkey_added_in_network(uint8_t net_uuid[],
491                 uint16_t net_idx)
492 {
493         struct mesh_network_t *network;
494         const struct l_queue_entry *entry;
495
496         network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
497         if (!network)
498                 return false;
499
500         entry = l_queue_get_entries(network->nodes);
501
502         for (; entry; entry = entry->next) {
503                 struct _bt_mesh_node_t *node = entry->data;
504
505                 if (__mesh_key_present(node->net_keys, net_idx))
506                         return true;
507         }
508         return false;
509 }
510
511 bool _bt_mesh_node_is_appkey_added_in_network(uint8_t net_uuid[],
512                 uint16_t app_idx)
513 {
514         struct mesh_network_t *network;
515         const struct l_queue_entry *entry;
516
517         network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
518         if (!network)
519                 return false;
520
521         entry = l_queue_get_entries(network->nodes);
522
523         for (; entry; entry = entry->next) {
524                 struct _bt_mesh_node_t *node = entry->data;
525
526                 if (__mesh_key_present(node->app_keys, app_idx))
527                         return true;
528         }
529         return false;
530 }
531
532 bool _bt_mesh_node_is_appkey_exists(uint8_t net_uuid[],
533                 uint16_t addr, uint16_t app_idx)
534 {
535         struct _bt_mesh_node_t *rmt;
536         struct mesh_network_t *network;
537
538         network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
539         if (!network)
540                 return false;
541
542         rmt = l_queue_find(network->nodes,
543                         __mesh_match_node_addr, L_UINT_TO_PTR(addr));
544         if (!rmt)
545                 return false;
546
547         if (__mesh_key_present(rmt->app_keys, app_idx))
548                 return true;
549
550         return false;
551 }
552
553 bool _bt_mesh_node_is_netkey_exists(uint8_t net_uuid[],
554                 uint16_t addr, uint16_t net_idx)
555 {
556         struct _bt_mesh_node_t *rmt;
557         struct mesh_network_t *network;
558
559         network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
560         if (!network)
561                 return false;
562
563         rmt = l_queue_find(network->nodes,
564                         __mesh_match_node_addr, L_UINT_TO_PTR(addr));
565         if (!rmt)
566                 return false;
567
568         if (__mesh_key_present(rmt->net_keys, net_idx))
569                 return true;
570
571         return false;
572 }
573
574 bool _bt_mesh_node_add_net_key(uint8_t net_uuid[],
575                 uint16_t addr, uint16_t net_idx)
576 {
577         struct _bt_mesh_node_t *rmt;
578         struct mesh_network_t *network;
579
580         network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
581         if (!network)
582                 return false;
583
584         rmt = l_queue_find(network->nodes,
585                         __mesh_match_node_addr, L_UINT_TO_PTR(addr));
586         if (!rmt)
587                 return false;
588
589         if (__mesh_key_present(rmt->net_keys, net_idx))
590                 return true;
591
592         l_queue_push_tail(rmt->net_keys, L_UINT_TO_PTR(net_idx));
593         return true;
594 }
595
596 bool _bt_mesh_node_add_app_key(uint8_t net_uuid[],
597                 uint16_t addr, uint16_t app_idx)
598 {
599         struct _bt_mesh_node_t *rmt;
600         struct mesh_network_t *network;
601
602         network = l_queue_find(networks,
603                         __mesh_net_uuid_match, net_uuid);
604         if (!network)
605                 return false;
606
607         rmt = l_queue_find(network->nodes,
608                         __mesh_match_node_addr, L_UINT_TO_PTR(addr));
609         if (!rmt)
610                 return false;
611
612         if (!rmt->app_keys)
613                 rmt->app_keys = l_queue_new();
614
615         if (__mesh_key_present(rmt->app_keys, app_idx))
616                 return false;
617
618         l_queue_push_tail(rmt->app_keys, L_UINT_TO_PTR(app_idx));
619         BT_INFO("Mesh: Total appkeys present in node [%d]",
620                         l_queue_length(rmt->app_keys));
621         return true;
622 }
623
624 bool _bt_mesh_node_del_app_key(uint8_t net_uuid[],
625                 uint16_t addr, uint16_t app_idx)
626 {
627         struct _bt_mesh_node_t *rmt;
628         struct mesh_network_t *network;
629
630         network = l_queue_find(networks,
631                         __mesh_net_uuid_match, net_uuid);
632         if (!network) {
633                 BT_INFO("Mesh: Could not find Network");
634                 return false;
635         }
636
637         rmt = l_queue_find(network->nodes,
638                         __mesh_match_node_addr, L_UINT_TO_PTR(addr));
639         if (!rmt) {
640                 BT_INFO("Mesh: Remote Node not found!");
641                 return false;
642         }
643
644         BT_INFO("Mesh: Total appkeys present in node [%d]",
645                         l_queue_length(rmt->app_keys));
646         BT_INFO("Mesh: To be deleted AppKey Idx [0x%2.2x]", app_idx);
647         return l_queue_remove(rmt->app_keys, L_UINT_TO_PTR(app_idx));
648 }
649
650 uint16_t _bt_mesh_node_get_subnet_idx(uint8_t net_uuid[],
651                 uint16_t addr)
652 {
653         struct _bt_mesh_node_t *rmt;
654         uint32_t net_idx;
655         struct mesh_network_t *network;
656
657         network = l_queue_find(networks,
658                         __mesh_net_uuid_match, net_uuid);
659         if (!network)
660                 return MESH_NET_IDX_INVALID;
661
662         rmt = l_queue_find(network->nodes,
663                         __mesh_match_node_addr, L_UINT_TO_PTR(addr));
664
665         if (!rmt || l_queue_isempty(rmt->net_keys))
666                 return MESH_NET_IDX_INVALID;
667
668         net_idx = L_PTR_TO_UINT(l_queue_peek_head(rmt->net_keys));
669
670         return (uint16_t) net_idx;
671 }
672
673 uint16_t _bt_mesh_node_get_next_unicast(uint8_t net_uuid[],
674                 uint16_t low, uint16_t high, uint8_t ele_cnt)
675 {
676         struct _bt_mesh_node_t *rmt;
677         const struct l_queue_entry *l;
678         uint16_t addr;
679         struct mesh_network_t *network;
680
681         network = l_queue_find(networks,
682                         __mesh_net_uuid_match, net_uuid);
683         if (!network) {
684                 BT_ERR("Mesh: Net UUID did not match");
685                 return 0;
686         }
687
688         /* Note: the address space includes both
689            low and high terminal values */
690         if (ele_cnt > (high - low + 1))
691                 return 0;
692
693         if (!network->nodes || l_queue_isempty(network->nodes))
694                 return low;
695
696         addr = low;
697         l = l_queue_get_entries(network->nodes);
698
699         /* Cycle through the sorted (by unicast) node list */
700         for (; l; l = l->next) {
701                 rmt = l->data;
702
703                 if (rmt->unicast >= (addr + ele_cnt))
704                         return addr;
705
706                 if ((rmt->unicast + rmt->num_ele) > addr)
707                         addr = rmt->unicast + rmt->num_ele;
708         }
709
710         if ((addr + ele_cnt - 1) <= high)
711                 return addr;
712
713         return 0;
714 }