Merge "Mesh: Apply stabilization fixes in FRWK" into tizen
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / services / mesh / bt-service-mesh-config-client.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 <fcntl.h>
24 #include <dirent.h>
25 #include <errno.h>
26 #include <limits.h>
27 #include <stdio.h>
28 #include <unistd.h>
29 #include <sys/stat.h>
30 #include <ell/ell.h>
31
32 #include "bt-service-common.h"
33 #include "bt-service-core-adapter.h"
34 #include "bt-service-event-receiver.h"
35 #include "bt-request-handler.h"
36 #include "bluetooth-api.h"
37
38 #include "bluetooth-api.h"
39 #include "bluetooth-mesh-api.h"
40 #include "bt-internal-types.h"
41 #include "bt-service-util.h"
42 #include "bt-service-common.h"
43 #include "bt-service-core-adapter.h"
44 #include "bt-service-event-receiver.h"
45 #include "bt-request-handler.h"
46 #include "bluetooth-api.h"
47
48 #include "bluetooth-api.h"
49 #include "bluetooth-mesh-api.h"
50 #include "bt-internal-types.h"
51 #include "bt-service-util.h"
52 #include "bt-service-common.h"
53 #include "bt-service-event.h"
54
55 #include "bt-service-mesh-network.h"
56 #include "bt-service-mesh-cdb.h"
57 #include "bt-service-mesh-nodes.h"
58 #include "bt-service-mesh-keys.h"
59 #include "bt-service-mesh-util.h"
60
61 #include <oal-hardware.h>
62 #include <oal-manager.h>
63 #include <oal-event.h>
64 #include <oal-adapter-mgr.h>
65 #include <oal-device-mgr.h>
66 #include <oal-mesh.h>
67
68 #include "bt-internal-types.h"
69
70 #define MESH_CONFIG_BUFFER_MAX_LEN 100
71
72
73 static void __bt_mesh_send_node_browsed_event(int result,
74                 bluetooth_mesh_node_discover_t *browse_evt);
75 static void __bt_mesh_handle_pending_dev_config_request_info(int result,
76                 int service_function, void *param,
77                         unsigned int size);
78
79 struct mesh_config_cmd {
80         uint32_t opcode;
81         uint32_t response;
82         const char *descriptor;
83 };
84
85 static struct l_queue *pending_requests;
86
87 struct mesh_pending_request {
88         struct l_timeout *timer;
89         const struct mesh_config_cmd *cmd;
90         uint8_t net_uuid[16];
91         uint16_t addr;
92         void *data;
93 };
94
95 static struct mesh_config_cmd commands[] = {
96         { MESH_OPCODE_APPKEY_ADD, MESH_OPCODE_APPKEY_STATUS, "AppKeyAdd" },
97         { MESH_OPCODE_APPKEY_DELETE, MESH_OPCODE_APPKEY_STATUS, "AppKeyDelete" },
98         { MESH_OPCODE_APPKEY_GET, MESH_OPCODE_APPKEY_LIST, "AppKeyGet" },
99         { MESH_OPCODE_APPKEY_LIST, MESH_RESPONSE_NONE, "AppKeyList" },
100         { MESH_OPCODE_APPKEY_STATUS, MESH_RESPONSE_NONE, "AppKeyStatus" },
101         { MESH_OPCODE_APPKEY_UPDATE, MESH_OPCODE_APPKEY_STATUS, "AppKeyUpdate" },
102         { MESH_OPCODE_DEV_COMP_GET, MESH_OPCODE_DEV_COMP_STATUS, "DeviceCompositionGet" },
103         { MESH_OPCODE_DEV_COMP_STATUS, MESH_RESPONSE_NONE, "DeviceCompositionStatus" },
104         { MESH_OPCODE_CONFIG_BEACON_GET, MESH_OPCODE_CONFIG_BEACON_STATUS, "BeaconGet" },
105         { MESH_OPCODE_CONFIG_BEACON_SET, MESH_OPCODE_CONFIG_BEACON_STATUS, "BeaconSet" },
106         { MESH_OPCODE_CONFIG_BEACON_STATUS, MESH_RESPONSE_NONE, "BeaconStatus" },
107         { MESH_OPCODE_CONFIG_DEFAULT_TTL_GET, MESH_OPCODE_CONFIG_DEFAULT_TTL_STATUS,
108                 "DefaultTTLGet" },
109         { MESH_OPCODE_CONFIG_DEFAULT_TTL_SET, MESH_OPCODE_CONFIG_DEFAULT_TTL_STATUS,
110                 "DefaultTTLSet" },
111         { MESH_OPCODE_CONFIG_DEFAULT_TTL_STATUS, MESH_RESPONSE_NONE, "DefaultTTLStatus" },
112         { MESH_OPCODE_CONFIG_FRIEND_GET, MESH_OPCODE_CONFIG_FRIEND_STATUS, "FriendGet" },
113         { MESH_OPCODE_CONFIG_FRIEND_SET, MESH_OPCODE_CONFIG_FRIEND_STATUS, "FrienSet" },
114         { MESH_OPCODE_CONFIG_FRIEND_STATUS, MESH_RESPONSE_NONE, "FriendStatus" },
115         { MESH_OPCODE_CONFIG_PROXY_GET, MESH_OPCODE_CONFIG_PROXY_STATUS, "ProxyGet" },
116         { MESH_OPCODE_CONFIG_PROXY_SET, MESH_OPCODE_CONFIG_PROXY_STATUS, "ProxySet" },
117         { MESH_OPCODE_CONFIG_PROXY_STATUS, MESH_RESPONSE_NONE, "ProxyStatus" },
118         { MESH_OPCODE_CONFIG_KEY_REFRESH_PHASE_GET, MESH_OPCODE_CONFIG_KEY_REFRESH_PHASE_STATUS,
119                 "KeyRefreshPhaseGet" },
120         { MESH_OPCODE_CONFIG_KEY_REFRESH_PHASE_SET, MESH_OPCODE_CONFIG_KEY_REFRESH_PHASE_STATUS,
121                 "KeyRefreshPhaseSet" },
122         { MESH_OPCODE_CONFIG_KEY_REFRESH_PHASE_STATUS, MESH_RESPONSE_NONE,
123                 "KeyRefreshPhaseStatus" },
124         { MESH_OPCODE_CONFIG_MODEL_PUB_GET, MESH_OPCODE_CONFIG_MODEL_PUB_STATUS, "ModelPubGet" },
125         { MESH_OPCODE_CONFIG_MODEL_PUB_SET, MESH_OPCODE_CONFIG_MODEL_PUB_STATUS, "ModelPubSet" },
126         { MESH_OPCODE_CONFIG_MODEL_PUB_STATUS, MESH_RESPONSE_NONE, "ModelPubStatus" },
127         { MESH_OPCODE_CONFIG_MODEL_PUB_VIRT_SET, MESH_OPCODE_CONFIG_MODEL_PUB_STATUS,
128                 "ModelPubVirtualSet" },
129         { MESH_OPCODE_CONFIG_MODEL_SUB_ADD, MESH_OPCODE_CONFIG_MODEL_SUB_STATUS, "ModelSubAdd" },
130         { MESH_OPCODE_CONFIG_MODEL_SUB_DELETE, MESH_OPCODE_CONFIG_MODEL_SUB_STATUS,
131                 "ModelSubDelete" },
132         { MESH_OPCODE_CONFIG_MODEL_SUB_DELETE_ALL, MESH_OPCODE_CONFIG_MODEL_SUB_STATUS,
133                 "ModelSubDeleteAll" },
134         { MESH_OPCODE_CONFIG_MODEL_SUB_OVERWRITE, MESH_OPCODE_CONFIG_MODEL_SUB_STATUS,
135                 "ModelSubOverwrite" },
136         { MESH_OPCODE_CONFIG_MODEL_SUB_STATUS, MESH_RESPONSE_NONE, "ModelSubStatus" },
137         { MESH_OPCODE_CONFIG_MODEL_SUB_VIRT_ADD, MESH_OPCODE_CONFIG_MODEL_SUB_STATUS,
138                 "ModelSubVirtAdd" },
139         { MESH_OPCODE_CONFIG_MODEL_SUB_VIRT_DELETE, MESH_OPCODE_CONFIG_MODEL_SUB_STATUS,
140                 "ModelSubVirtDelete" },
141         { MESH_OPCODE_CONFIG_MODEL_SUB_VIRT_OVERWRITE, MESH_OPCODE_CONFIG_MODEL_SUB_STATUS,
142                 "ModelSubVirtOverwrite" },
143         { MESH_OPCODE_CONFIG_NETWORK_TRANSMIT_GET, MESH_OPCODE_CONFIG_NETWORK_TRANSMIT_STATUS,
144                 "NetworkTransmitGet" },
145         { MESH_OPCODE_CONFIG_NETWORK_TRANSMIT_SET, MESH_OPCODE_CONFIG_NETWORK_TRANSMIT_STATUS,
146                 "NetworkTransmitSet" },
147         { MESH_OPCODE_CONFIG_NETWORK_TRANSMIT_STATUS, MESH_RESPONSE_NONE,
148                 "NetworkTransmitStatus" },
149         { MESH_OPCODE_CONFIG_RELAY_GET, MESH_OPCODE_CONFIG_RELAY_STATUS, "RelayGet" },
150         { MESH_OPCODE_CONFIG_RELAY_SET, MESH_OPCODE_CONFIG_RELAY_STATUS, "RelaySet" },
151         { MESH_OPCODE_CONFIG_RELAY_STATUS, MESH_RESPONSE_NONE, "RelayStatus" },
152         { MESH_OPCODE_CONFIG_MODEL_SUB_GET, MESH_OPCODE_CONFIG_MODEL_SUB_LIST, "ModelSubGet" },
153         { MESH_OPCODE_CONFIG_MODEL_SUB_LIST, MESH_RESPONSE_NONE, "ModelSubList" },
154         { MESH_OPCODE_CONFIG_VEND_MODEL_SUB_GET, MESH_OPCODE_CONFIG_VEND_MODEL_SUB_LIST,
155                 "VendorModelSubGet" },
156         { MESH_OPCODE_CONFIG_VEND_MODEL_SUB_LIST, MESH_RESPONSE_NONE, "VendorModelSubList" },
157         { MESH_OPCODE_CONFIG_POLL_TIMEOUT_LIST, MESH_OPCODE_CONFIG_POLL_TIMEOUT_STATUS,
158                 "PollTimeoutList" },
159         { MESH_OPCODE_CONFIG_POLL_TIMEOUT_STATUS, MESH_RESPONSE_NONE, "PollTimeoutStatus" },
160         { MESH_OPCODE_CONFIG_HEARTBEAT_PUB_GET, MESH_OPCODE_CONFIG_HEARTBEAT_PUB_STATUS,
161                 "HeartbeatPubGet" },
162         { MESH_OPCODE_CONFIG_HEARTBEAT_PUB_SET, MESH_OPCODE_CONFIG_HEARTBEAT_PUB_STATUS,
163                 "HeartbeatPubSet" },
164         { MESH_OPCODE_CONFIG_HEARTBEAT_PUB_STATUS, MESH_RESPONSE_NONE, "HeartbeatPubStatus" },
165         { MESH_OPCODE_CONFIG_HEARTBEAT_SUB_GET, MESH_OPCODE_CONFIG_HEARTBEAT_SUB_STATUS,
166                 "HeartbeatSubGet" },
167         { MESH_OPCODE_CONFIG_HEARTBEAT_SUB_SET, MESH_OPCODE_CONFIG_HEARTBEAT_SUB_STATUS,
168                 "HeartbeatSubSet" },
169         { MESH_OPCODE_CONFIG_HEARTBEAT_SUB_STATUS, MESH_RESPONSE_NONE, "HeartbeatSubStatus" },
170         { MESH_OPCODE_MODEL_APP_BIND, MESH_OPCODE_MODEL_APP_STATUS, "ModelAppBind" },
171         { MESH_OPCODE_MODEL_APP_STATUS, MESH_RESPONSE_NONE, "ModelAppStatus" },
172         { MESH_OPCODE_MODEL_APP_UNBIND, MESH_OPCODE_MODEL_APP_STATUS, "ModelAppUnbind" },
173         { MESH_OPCODE_NETKEY_ADD, MESH_OPCODE_NETKEY_STATUS, "NetKeyAdd" },
174         { MESH_OPCODE_NETKEY_DELETE, MESH_OPCODE_NETKEY_STATUS, "NetKeyDelete" },
175         { MESH_OPCODE_NETKEY_GET, MESH_OPCODE_NETKEY_LIST, "NetKeyGet" },
176         { MESH_OPCODE_NETKEY_LIST, MESH_RESPONSE_NONE, "NetKeyList" },
177         { MESH_OPCODE_NETKEY_STATUS, MESH_RESPONSE_NONE, "NetKeyStatus" },
178         { MESH_OPCODE_NETKEY_UPDATE, MESH_OPCODE_NETKEY_STATUS, "NetKeyUpdate" },
179         { MESH_OPCODE_NODE_IDENTITY_GET, MESH_OPCODE_NODE_IDENTITY_STATUS, "NodeIdentityGet" },
180         { MESH_OPCODE_NODE_IDENTITY_SET, MESH_OPCODE_NODE_IDENTITY_STATUS, "NodeIdentitySet" },
181         { MESH_OPCODE_NODE_IDENTITY_STATUS, MESH_RESPONSE_NONE, "NodeIdentityStatus" },
182         { MESH_OPCODE_NODE_RESET, MESH_OPCODE_NODE_RESET_STATUS, "NodeReset" },
183         { MESH_OPCODE_NODE_RESET_STATUS, MESH_RESPONSE_NONE, "NodeResetStatus" },
184         { MESH_OPCODE_MODEL_APP_GET, MESH_OPCODE_MODEL_APP_LIST, "ModelAppGet" },
185         { MESH_OPCODE_MODEL_APP_LIST, MESH_RESPONSE_NONE, "ModelAppList" },
186         { MESH_OPCODE_VENDOR_MODEL_APP_GET, MESH_OPCODE_VENDOR_MODEL_APP_LIST, "VendorModelAppGet" },
187         { MESH_OPCODE_VENDOR_MODEL_APP_LIST, MESH_RESPONSE_NONE, "VendorModelAppList" }
188 };
189
190
191 static const struct mesh_config_cmd *__mesh_get_command(uint32_t opcode)
192 {
193         uint32_t n;
194
195         for (n = 0; n < L_ARRAY_SIZE(commands); n++) {
196                 if (opcode == commands[n].opcode)
197                         return &commands[n];
198         }
199
200         return NULL;
201 }
202
203 static const char *__mesh_get_opcode_string(uint32_t opcode)
204 {
205         const struct mesh_config_cmd *cmd;
206
207         cmd = __mesh_get_command(opcode);
208         if (!cmd)
209                 return "Unknown Command Received";
210
211         return cmd->descriptor;
212 }
213
214 static void __mesh_request_remove(void *a)
215 {
216         struct mesh_pending_request *req = a;
217
218         if (req->data)
219                 l_free(req->data);
220         l_timeout_remove(req->timer);
221         l_free(req);
222 }
223
224 static void __bt_mesh_wait_response_timeout(
225                 struct l_timeout *timeout, void *user_data)
226 {
227         struct mesh_pending_request *req = user_data;
228
229         BT_INFO("Mesh: No response for \"%s\" from %4.4x\n",
230                         req->cmd->descriptor, req->addr);
231
232         /* Node reset case: delete the remote even if there is no response */
233         /* TODO Reset the remote node, as no response is expected on reset command */
234
235
236         switch(req->cmd->opcode) {
237         case MESH_OPCODE_DEV_COMP_GET: {
238                 /* Send event with timeout */
239                 event_mesh_devkey_message_t *event = \
240                         g_malloc0(sizeof(event_mesh_devkey_message_t));
241                 memcpy(event->net_uuid.uuid, req->net_uuid, 16);
242                 event->source = req->addr;
243                  __bt_mesh_handle_pending_dev_config_request_info(
244                         BLUETOOTH_ERROR_TIMEOUT, BT_MESH_NODE_BROWSE,
245                                 event, sizeof(event_mesh_devkey_message_t));
246                 g_free(event);
247                 break;
248         }
249         case MESH_OPCODE_NETKEY_ADD:
250         case MESH_OPCODE_NETKEY_UPDATE:
251         case MESH_OPCODE_NETKEY_DELETE:
252         case MESH_OPCODE_APPKEY_ADD:
253         case MESH_OPCODE_APPKEY_UPDATE:
254         case MESH_OPCODE_APPKEY_DELETE:
255                 /* Send event with timeout */
256                  __bt_mesh_handle_pending_dev_config_request_info(
257                         BLUETOOTH_ERROR_TIMEOUT,
258                                 BT_MESH_NODE_CONFIGURE_KEY, req->data,
259                                         sizeof(bluetooth_mesh_key_configure_t));
260                 break;
261         case MESH_OPCODE_CONFIG_DEFAULT_TTL_GET:
262         case MESH_OPCODE_CONFIG_DEFAULT_TTL_SET:
263                 /* Send event with timeout */
264                  __bt_mesh_handle_pending_dev_config_request_info(
265                         BLUETOOTH_ERROR_TIMEOUT,
266                                 BT_MESH_NODE_TTL_EXECUTE, req->data,
267                                         sizeof(bluetooth_mesh_node_ttl_info_t));
268                 break;
269         default:
270                 break;
271         }
272         BT_INFO("Mesh: Number of pending requests [%u] Remove the req",
273                 l_queue_length(pending_requests));
274         l_queue_remove(pending_requests, req);
275         __mesh_request_remove(req);
276 }
277
278 static void __bt_mesh_add_request(uint32_t opcode, uint16_t dest,
279                         uint8_t net_uuid[], void *data)
280 {
281         struct mesh_pending_request *req;
282         const struct mesh_config_cmd *cmd;
283         char uuid_str[33];
284
285         cmd = __mesh_get_command(opcode);
286         if (!cmd)
287                 return;
288         _bt_mesh_util_convert_hex_to_string((uint8_t *) net_uuid, 16, uuid_str,
289                 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
290         BT_INFO("Mesh: Net UUID[%s]",uuid_str);
291
292         BT_INFO("Mesh: Adding command opcode [0x%2.2x] response [0x%2.2x]",
293                         cmd->opcode, cmd->response);
294         req = l_new(struct mesh_pending_request, 1);
295         req->cmd = cmd;
296         req->addr = dest;
297         req->data = data;
298         memcpy(req->net_uuid, net_uuid, 16);
299         req->timer = l_timeout_create(MESH_DEFAULT_RESPONSE_TIMEOUT,
300                         __bt_mesh_wait_response_timeout, req, NULL);
301
302         if (!pending_requests)
303                 pending_requests = l_queue_new();
304         l_queue_push_tail(pending_requests, req);
305         BT_INFO("Mesh: Number of pending requests [%u]", l_queue_length(pending_requests));
306 }
307
308 static struct mesh_pending_request *__bt_mesh_get_request_by_response(
309                 uint16_t addr, uint8_t net_uuid[],
310                         uint32_t response)
311 {
312         const struct l_queue_entry *entry;
313         char uuid_str[33];
314         char uuid_str1[33];
315
316         BT_INFO("Mesh: Number of pending requests [%u]", l_queue_length(pending_requests));
317         entry = l_queue_get_entries(pending_requests);
318
319         for (; entry; entry = entry->next) {
320                 struct mesh_pending_request *req = entry->data;
321
322                 /* Test */
323                 BT_INFO("Mesh: Req addr [0x%2.2x] req opcode [0x%2.2x] res [0x%2.2x]", req->addr, req->cmd->opcode, req->cmd->response);
324                 BT_INFO("Mesh: Current req addr [0x%2.2x] res [0x%2.2x]", addr, response);
325                 _bt_mesh_util_convert_hex_to_string((uint8_t *) net_uuid, 16, uuid_str,
326                                 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
327                 BT_INFO("Mesh: Net UUID[%s]",uuid_str);
328
329                 _bt_mesh_util_convert_hex_to_string((uint8_t *) req->net_uuid, 16, uuid_str1,
330                                 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
331                 BT_INFO("Mesh: Net UUID1[%s]",uuid_str1);
332                 if (!memcmp(net_uuid, req->net_uuid, 16) &&
333                                 req->addr == addr &&
334                                 req->cmd->response == response)
335                         return req;
336         }
337
338         return NULL;
339 }
340
341 bool _bt_mesh_check_pending_request(uint32_t opcode,
342                 uint16_t dest, uint8_t net_uuid[])
343 {
344         const struct mesh_config_cmd *cmd;
345         cmd = __mesh_get_command(opcode);
346
347         if (!cmd)
348                 return false;
349
350         if (__bt_mesh_get_request_by_response(dest,
351                                 net_uuid, cmd->response)) {
352                 BT_ERR("Mesh:Another command is pending\n");
353                 return true;
354         }
355         return false;
356 }
357
358 static uint32_t __bt_mesh_print_model_identifier(uint8_t *data,
359                 bool vendor, const char *offset)
360 {
361         uint32_t mod_id;
362
363         if (!vendor) {
364                 mod_id = l_get_le16(data);
365                 BT_INFO("%sModel ID\t%4.4x\n", offset, mod_id);
366                 mod_id = MESH_VENDOR_ID_MASK | mod_id;
367         } else {
368                 mod_id = l_get_le16(data + 2);
369                 BT_INFO("%sModel ID\t%4.4x %4.4x\n", offset,
370                                 l_get_le16(data), mod_id);
371                 mod_id = l_get_le16(data) << 16 | mod_id;
372         }
373
374         return mod_id;
375 }
376
377 static void __bt_mesh_print_device_composition_data(
378                 uint8_t *data, uint16_t len)
379 {
380         uint16_t features;
381         int i = 0;
382
383         BT_INFO("Mesh: Received composion:\n");
384
385         /* skip page -- We only support Page Zero */
386         data++;
387         len--;
388
389         BT_INFO("\tCID: %4.4x", l_get_le16(&data[0]));
390         BT_INFO("\tPID: %4.4x", l_get_le16(&data[2]));
391         BT_INFO("\tVID: %4.4x", l_get_le16(&data[4]));
392         BT_INFO("\tCRPL: %4.4x", l_get_le16(&data[6]));
393
394         features = l_get_le16(&data[8]);
395         data += 10;
396         len -= 10;
397
398         BT_INFO("\tFeature support:\n");
399         BT_INFO("\t\trelay: %s\n", (features & MESH_FEATURE_RELAY) ?
400                         "yes" : "no");
401         BT_INFO("\t\tproxy: %s\n", (features & MESH_FEATURE_PROXY) ?
402                         "yes" : "no");
403         BT_INFO("\t\tfriend: %s\n", (features & MESH_FEATURE_FRIEND) ?
404                         "yes" : "no");
405         BT_INFO("\t\tlpn: %s\n", (features & MESH_FEATURE_LPN) ?
406                         "yes" : "no");
407         while (len) {
408                 uint8_t m, v;
409
410                 BT_INFO("\t Element %d:\n", i);
411                 BT_INFO("\t\tlocation: %4.4x\n", l_get_le16(data));
412                 data += 2;
413                 len -= 2;
414
415                 m = *data++;
416                 v = *data++;
417                 len -= 2;
418
419                 if (m)
420                         BT_INFO("\t\tSIG defined models:\n");
421
422                 while (len >= 2 && m--) {
423                         __bt_mesh_print_model_identifier(data, false, "\t\t  ");
424                         data += 2;
425                         len -= 2;
426                 }
427
428                 if (v)
429                         BT_INFO("\t\t Vendor defined models:\n");
430
431                 while (len >= 4 && v--) {
432                         __bt_mesh_print_model_identifier(data, true, "\t\t  ");
433                         data += 4;
434                         len -= 4;
435                 }
436
437                 i++;
438         }
439 }
440
441 static void __bt_mesh_send_model_publication_status_event(
442                 int event, int result,
443                         bluetooth_mesh_model_configure_t *evt)
444 {
445         GVariant *out_var = NULL, *param = NULL;
446         GArray *info = NULL;
447
448         if (BLUETOOTH_ERROR_NONE == result) {
449                 /* Send event */
450                 info = g_array_new(FALSE, FALSE, sizeof(gchar));
451                 g_array_append_vals(info, evt,
452                                 sizeof(bluetooth_mesh_model_configure_t));
453
454                 out_var = g_variant_new_from_data((const GVariantType *)"ay",
455                                 info->data, info->len,
456                                 TRUE, NULL, NULL);
457
458                 param = g_variant_new("(iv)", result, out_var);
459                 _bt_send_event(BT_MESH_EVENT, event,
460                                 param);
461         }
462 }
463
464 static void __bt_mesh_send_model_subscription_configure_event(
465                 int event, int result,
466                         bluetooth_mesh_model_configure_t *evt)
467 {
468         GVariant *out_var = NULL, *param = NULL;
469         GArray *info = NULL;
470
471         if (BLUETOOTH_ERROR_NONE == result) {
472                 /* Send event */
473                 info = g_array_new(FALSE, FALSE, sizeof(gchar));
474                 g_array_append_vals(info, evt,
475                                 sizeof(bluetooth_mesh_model_configure_t));
476
477                 out_var = g_variant_new_from_data((const GVariantType *)"ay",
478                                 info->data, info->len,
479                                 TRUE, NULL, NULL);
480
481                 param = g_variant_new("(iv)", result, out_var);
482                 _bt_send_event(BT_MESH_EVENT, event,
483                                 param);
484         }
485 }
486
487 static void __bt_mesh_send_model_get_subscription_list_event(
488         int result, bluetooth_mesh_model_configure_t *evt)
489 {
490         GVariant  *param = NULL;
491         GVariantBuilder *builder = NULL;
492         int i;
493
494         if (BLUETOOTH_ERROR_NONE == result) {
495                 if (evt->sublist_count) {
496                         builder = g_variant_builder_new(G_VARIANT_TYPE("aq"));
497                         for (i = 0; i < evt->sublist_count; i++)
498                                 g_variant_builder_add(builder, "q", *evt->sub_list[i]);
499
500                         param = g_variant_new("(isqiui(aq))", result, evt->net_uuid,
501                                         evt->primary_unicast, evt->elem_index, evt->model,
502                                         evt->sublist_count, builder);
503
504                         g_variant_builder_unref(builder);
505                 }
506                 /* Send event */
507                 _bt_send_event(BT_MESH_EVENT,
508                                 BLUETOOTH_EVENT_MESH_MODEL_SUBSCRIPTION_LIST,
509                                 param);
510
511                 if (evt->sublist_count) {
512                         /* Free List data */
513                         for (int i = 0; i < evt->sublist_count; i++)
514                                 g_free(evt->sub_list[i]);
515                         g_free(evt->sub_list);
516                 }
517         }
518 }
519
520 static void __bt_mesh_send_model_get_appkey_list_event(int result,
521                 bluetooth_mesh_model_configure_t *evt)
522 {
523         GVariant  *param = NULL;
524         GVariantBuilder *builder = NULL;
525         char *net_uuid;
526         int i;
527
528         if (BLUETOOTH_ERROR_NONE == result) {
529                 builder = g_variant_builder_new(G_VARIANT_TYPE("aq"));
530                 BT_INFO("Mesh: Total AppKeys bound to model [%d]",
531                                 evt->appkeylist_count);
532                 BT_INFO("Mesh: Network [%s]", evt->net_uuid);
533                 for (i = 0; i < evt->appkeylist_count; i++)
534                         g_variant_builder_add(builder, "q", *evt->appkey_list[i]);
535                 net_uuid = g_strdup(evt->net_uuid);
536                 param = g_variant_new("(isqiui(aq))", result, net_uuid,
537                                 evt->primary_unicast, evt->elem_index, evt->model,
538                                 evt->appkeylist_count, builder);
539
540                 g_variant_builder_unref(builder);
541
542                 /* Send event */
543                 _bt_send_event(BT_MESH_EVENT,
544                                 BLUETOOTH_EVENT_MESH_MODEL_APPKEY_LIST,
545                                 param);
546
547                 if (evt->appkeylist_count) {
548                         for (int i = 0; i < evt->appkeylist_count; i++)
549                                 g_free(evt->appkey_list[i]);
550
551                         g_free(evt->appkey_list);
552                 }
553                 /* Free List data */
554                 g_free(net_uuid);
555         }
556 }
557
558 static void __bt_mesh_send_model_configure_appkey_event(int result,
559                 bluetooth_mesh_model_configure_t *evt)
560 {
561         GVariant *out_var = NULL, *param = NULL;
562         GArray *info = NULL;
563
564         if (BLUETOOTH_ERROR_NONE == result) {
565                 /* Send event */
566                 info = g_array_new(FALSE, FALSE, sizeof(gchar));
567                 g_array_append_vals(info, evt, sizeof(bluetooth_mesh_model_configure_t));
568
569                 out_var = g_variant_new_from_data((const GVariantType *)"ay",
570                                 info->data, info->len,
571                                 TRUE, NULL, NULL);
572
573                 param = g_variant_new("(iv)", result, out_var);
574                 _bt_send_event(BT_MESH_EVENT,
575                                 BLUETOOTH_EVENT_MESH_MODEL_APPKEY_BIND,
576                                 param);
577         }
578 }
579
580 static void __bt_mesh_send_node_ttl_configuration_event(int result,
581                 bluetooth_mesh_node_ttl_info_t *ttl_evt)
582 {
583         GVariant *out_var = NULL, *param = NULL;
584         GArray *info = NULL;
585
586         if (BLUETOOTH_ERROR_NONE == result) {
587                 /* Send event */
588                 info = g_array_new(FALSE, FALSE, sizeof(gchar));
589                 g_array_append_vals(info, ttl_evt,
590                         sizeof(bluetooth_mesh_node_ttl_info_t));
591
592                 out_var = g_variant_new_from_data((const GVariantType *)"ay",
593                                 info->data, info->len,
594                                 TRUE, NULL, NULL);
595
596                 param = g_variant_new("(iv)", result, out_var);
597                 _bt_send_event(BT_MESH_EVENT,
598                                 BLUETOOTH_EVENT_MESH_NODE_TTL_CONFIGURED,
599                                 param);
600         }
601 }
602
603 static void __bt_mesh_send_node_key_configuration_event(int result,
604                 bluetooth_mesh_key_configure_t *key_evt)
605 {
606         GVariant *out_var = NULL, *param = NULL;
607         GArray *info = NULL;
608
609         if (BLUETOOTH_ERROR_NONE == result) {
610                 /* Send event */
611                 info = g_array_new(FALSE, FALSE, sizeof(gchar));
612                 g_array_append_vals(info, key_evt,
613                         sizeof(bluetooth_mesh_key_configure_t));
614
615                 out_var = g_variant_new_from_data((const GVariantType *)"ay",
616                                 info->data, info->len,
617                                 TRUE, NULL, NULL);
618
619                 param = g_variant_new("(iv)", result, out_var);
620                 _bt_send_event(BT_MESH_EVENT,
621                                 BLUETOOTH_EVENT_MESH_NODE_KEY_CONFIGURED,
622                                 param);
623         }
624 }
625
626 static void __bt_mesh_send_node_get_vendor_features_event(int result,
627                 bluetooth_mesh_node_features_t *features_evt)
628 {
629         GVariant *out_var = NULL, *param = NULL;
630         GArray *info = NULL;
631
632         if (BLUETOOTH_ERROR_NONE == result) {
633                 /* Send event */
634                 info = g_array_new(FALSE, FALSE, sizeof(gchar));
635                 g_array_append_vals(info, features_evt,
636                                 sizeof(bluetooth_mesh_node_features_t));
637
638                 out_var = g_variant_new_from_data((const GVariantType *)"ay",
639                                 info->data, info->len,
640                                 TRUE, NULL, NULL);
641
642                 param = g_variant_new("(iv)", result, out_var);
643                 _bt_send_event(BT_MESH_EVENT,
644                                 BLUETOOTH_EVENT_MESH_NODE_VENDOR_FEATURES,
645                                 param);
646         }
647 }
648
649 static void __bt_mesh_send_node_browsed_event(int result,
650                 bluetooth_mesh_node_discover_t *browse_evt)
651 {
652         GVariant *out_var = NULL, *param = NULL;
653         GArray *info = NULL;
654
655         if (BLUETOOTH_ERROR_NONE == result) {
656                 /* Send event */
657                 info = g_array_new(FALSE, FALSE, sizeof(gchar));
658                 g_array_append_vals(info, browse_evt,
659                                 sizeof(bluetooth_mesh_node_discover_t));
660
661                 out_var = g_variant_new_from_data((const GVariantType *)"ay",
662                                 info->data, info->len,
663                                 TRUE, NULL, NULL);
664
665                 param = g_variant_new("(iv)", result, out_var);
666                 _bt_send_event(BT_MESH_EVENT,
667                                 BLUETOOTH_EVENT_MESH_NODE_BROWSED,
668                                 param);
669         }
670 }
671
672 static void __bt_mesh_handle_pending_dev_config_request_info(int result,
673                 int service_function, void *param, unsigned int size)
674 {
675         GSList *l;
676         GArray *out_param;
677         invocation_info_t *req_info = NULL;
678
679         for (l = _bt_get_invocation_list(); l != NULL; ) {
680                 req_info = l->data;
681                 l = g_slist_next(l);
682                 if (req_info == NULL ||
683                                 req_info->service_function != service_function)
684                         continue;
685
686                 switch (service_function) {
687                 case BT_MESH_NODE_GET_VENDOR_FEATURES: {
688                         bluetooth_mesh_node_features_t *event;
689                         bluetooth_mesh_node_features_t *req;
690
691                         event = (bluetooth_mesh_node_features_t*) param;
692                         req = (bluetooth_mesh_node_features_t*)req_info->user_data;
693
694                         BT_DBG("Request Sender: [%s]", req_info->sender);
695                         /* Match Network and Remote Node unicast*/
696                         if (!g_strcmp0(event->net_uuid, req->net_uuid) && event->unicast == req->unicast) {
697                                 event->unicast = req->unicast;
698                                 event->elem_count = req->elem_count;
699
700                                 /* Send Event */
701                                 __bt_mesh_send_node_get_vendor_features_event(result, event);
702
703                                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
704                                 g_array_append_vals(out_param, event, sizeof(bluetooth_mesh_node_features_t));
705
706                                 /* Return DBUS Invocation*/
707                                 _bt_service_method_return(req_info->context, out_param, result);
708                                 _bt_free_info_from_invocation_list(req_info);
709                                 g_array_free(out_param, TRUE);
710                         }
711                         break;
712                 }
713                 case BT_MESH_NODE_BROWSE: {
714                         bluetooth_mesh_node_discover_t *node;
715                         event_mesh_devkey_message_t *event;
716                         uint16_t remote_addr;
717                         uint8_t elem_count;
718                         uint8_t dev_uuid[16];
719                         char net_uuid[BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1];
720
721                         event = (event_mesh_devkey_message_t*) param;
722                         node = (bluetooth_mesh_node_discover_t*)req_info->user_data;
723                         BT_INFO("Mesh: Request Node UUID [%s]", node->dev_uuid);
724                         BT_INFO("Mesh: Request Network UUID [%s]", node->net_uuid);
725
726                         _bt_mesh_util_convert_hex_to_string((uint8_t *) event->net_uuid.uuid, 16, net_uuid,
727                                         BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
728
729                         _bt_mesh_util_convert_string_to_hex(node->dev_uuid, strlen(node->dev_uuid), dev_uuid, 16);
730
731                         /* Get Unicast from pending request's Dev UUID and match with event */
732                         if (_bt_mesh_node_get_unicast_from_dev_uuid(event->net_uuid.uuid, dev_uuid, &remote_addr)) {
733
734                                 BT_DBG("Request Sender: [%s]", req_info->sender);
735                                 /* Match Network and Remote Node unicast*/
736                                 if (!g_strcmp0(node->net_uuid, net_uuid) && remote_addr == event->source) {
737                                         _bt_mesh_node_get_element_count(event->net_uuid.uuid, remote_addr, &elem_count);
738                                         node->unicast = event->source;
739                                         node->count = elem_count;
740                                         /* Send Event */
741                                         __bt_mesh_send_node_browsed_event(result, node);
742
743                                         out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
744                                         g_array_append_vals(out_param, node, sizeof(bluetooth_mesh_node_discover_t));
745
746                                         /* Return DBUS Invocation*/
747                                         _bt_service_method_return(req_info->context, out_param, result);
748                                         _bt_free_info_from_invocation_list(req_info);
749                                         g_array_free(out_param, TRUE);
750
751                                 }
752                         }
753                         break;
754                 }
755                 case BT_MESH_NODE_CONFIGURE_KEY: {
756                         bluetooth_mesh_key_configure_t *event;
757                         bluetooth_mesh_key_configure_t *req;
758
759                         event = (bluetooth_mesh_key_configure_t*) param;
760                         req = (bluetooth_mesh_key_configure_t*)req_info->user_data;
761
762                         if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
763                                 req->primary_unicast == event->primary_unicast &&
764                                 req->is_netkey == event->is_netkey) {
765                                 /* Send Event */
766                                 __bt_mesh_send_node_key_configuration_event(result, event);
767
768                                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
769                                 g_array_append_vals(out_param, event, sizeof(bluetooth_mesh_key_configure_t));
770
771                                 /* Return DBUS Invocation*/
772                                 _bt_service_method_return(req_info->context, out_param, result);
773                                 _bt_free_info_from_invocation_list(req_info);
774                                 g_array_free(out_param, TRUE);
775                         }
776                         break;
777                 }
778                 case BT_MESH_NODE_TTL_EXECUTE: {
779                         bluetooth_mesh_node_ttl_info_t *event;
780                         bluetooth_mesh_node_ttl_info_t *req;
781
782                         event = (bluetooth_mesh_node_ttl_info_t*) param;
783                         req = (bluetooth_mesh_node_ttl_info_t*)req_info->user_data;
784                         req->ttl = event->ttl;
785
786                         if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
787                                 req->unicast == event->unicast) {
788                                 /* Send Event */
789                                 __bt_mesh_send_node_ttl_configuration_event(result, req);
790
791                                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
792                                 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_node_ttl_info_t));
793
794                                 /* Return DBUS Invocation*/
795                                 _bt_service_method_return(req_info->context, out_param, result);
796                                 _bt_free_info_from_invocation_list(req_info);
797                                 g_array_free(out_param, TRUE);
798                         }
799                         break;
800                 }
801                 case BT_MESH_MODEL_CONFIGURE_APPKEY: {
802                         bluetooth_mesh_model_configure_t *event;
803                         bluetooth_mesh_model_configure_t *req;
804
805                         event = (bluetooth_mesh_model_configure_t*) param;
806                         req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
807
808                         if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
809                                 req->primary_unicast == event->primary_unicast) {
810                                 /* Send Event */
811                                 __bt_mesh_send_model_configure_appkey_event(result, req);
812
813                                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
814                                 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_model_configure_t));
815
816                                 /* Return DBUS Invocation*/
817                                 _bt_service_method_return(req_info->context, out_param, result);
818                                 _bt_free_info_from_invocation_list(req_info);
819                                 g_array_free(out_param, TRUE);
820                         }
821
822                         break;
823                 }
824                 case BT_MESH_MODEL_GET_APPKEY_LIST: {
825                         bluetooth_mesh_model_configure_t *event;
826                         bluetooth_mesh_model_configure_t *req;
827
828                         event = (bluetooth_mesh_model_configure_t*) param;
829                         req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
830
831                         if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
832                                 req->primary_unicast == event->primary_unicast) {
833                                 /* Send Event */
834                                 __bt_mesh_send_model_get_appkey_list_event(result, event);
835
836                                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
837                                 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_model_configure_t));
838
839                                 /* Return DBUS Invocation*/
840                                 _bt_service_method_return(req_info->context, out_param, result);
841                                 _bt_free_info_from_invocation_list(req_info);
842                                 g_array_free(out_param, TRUE);
843                         }
844                         break;
845                 }
846                 case BT_MESH_MODEL_GET_SUBSCRIPTION_LIST: {
847                         bluetooth_mesh_model_configure_t *event;
848                         bluetooth_mesh_model_configure_t *req;
849
850                         event = (bluetooth_mesh_model_configure_t*) param;
851                         req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
852
853                         if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
854                                 req->primary_unicast == event->primary_unicast) {
855                                 /* Send Event */
856                                 __bt_mesh_send_model_get_subscription_list_event(result, event);
857
858                                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
859                                 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_model_configure_t));
860
861                                 /* Return DBUS Invocation*/
862                                 _bt_service_method_return(req_info->context, out_param, result);
863                                 _bt_free_info_from_invocation_list(req_info);
864                                 g_array_free(out_param, TRUE);
865                         }
866                         break;
867                 }
868                 case BT_MESH_MODEL_CONFIG_GROUP_SUB: {
869                         bluetooth_mesh_model_configure_t *event;
870                         bluetooth_mesh_model_configure_t *req;
871
872                         event = (bluetooth_mesh_model_configure_t*) param;
873                         req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
874
875                         if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
876                                 req->primary_unicast == event->primary_unicast) {
877
878                                 req->sub_addr = event->sub_addr;
879                                 /* Send Event */
880                                 __bt_mesh_send_model_subscription_configure_event(
881                                         BLUETOOTH_EVENT_MESH_MODEL_SUBSCRIPTION_CONFGURED,
882                                                 result, req);
883
884                                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
885                                 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_model_configure_t));
886
887                                 /* Return DBUS Invocation*/
888                                 _bt_service_method_return(req_info->context, out_param, result);
889                                 _bt_free_info_from_invocation_list(req_info);
890                                 g_array_free(out_param, TRUE);
891                         }
892                         break;
893                 }
894                 case BT_MESH_MODEL_CONFIG_VIRTUAL_GROUP_SUB: {
895                         bluetooth_mesh_model_configure_t *event;
896                         bluetooth_mesh_model_configure_t *req;
897
898                         event = (bluetooth_mesh_model_configure_t*) param;
899                         req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
900
901                         if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
902                                 req->primary_unicast == event->primary_unicast) {
903                                 /* Send Event */
904                                 __bt_mesh_send_model_subscription_configure_event( \
905                                         BLUETOOTH_EVENT_MESH_MODEL_VIRTUAL_SUBSCRIPTION_CONFGURED, \
906                                                 result, req);
907
908                                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
909                                 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_model_configure_t));
910
911                                 /* Return DBUS Invocation*/
912                                 _bt_service_method_return(req_info->context, out_param, result);
913                                 _bt_free_info_from_invocation_list(req_info);
914                                 g_array_free(out_param, TRUE);
915
916                         }
917                         break;
918                 }
919                 case BT_MESH_MODEL_GET_PUBLICATION: {
920                         bluetooth_mesh_model_configure_t *event;
921                         bluetooth_mesh_model_configure_t *req;
922
923                         event = (bluetooth_mesh_model_configure_t*) param;
924                         req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
925
926                         if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
927                                         req->primary_unicast == event->primary_unicast) {
928                                 /* Send Event */
929                                 __bt_mesh_send_model_publication_status_event( \
930                                                 BLUETOOTH_EVENT_MESH_MODEL_PUBLICATION_STATUS, \
931                                                 result, event);
932
933                                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
934                                 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_model_configure_t));
935
936                                 /* Return DBUS Invocation*/
937                                 _bt_service_method_return(req_info->context, out_param, result);
938                                 _bt_free_info_from_invocation_list(req_info);
939                                 g_array_free(out_param, TRUE);
940                         }
941                         break;
942                 }
943                 case BT_MESH_MODEL_SET_PUBLICATION: {
944                         bluetooth_mesh_model_configure_t *event;
945                         bluetooth_mesh_model_configure_t *req;
946
947                         event = (bluetooth_mesh_model_configure_t*) param;
948                         req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
949
950                         if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
951                                 req->primary_unicast == event->primary_unicast) {
952                                 /* Send Event */
953                                 __bt_mesh_send_model_publication_status_event( \
954                                         BLUETOOTH_EVENT_MESH_MODEL_PUBLICATION_STATUS, \
955                                                 result, req);
956
957                                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
958                                 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_model_configure_t));
959
960                                 /* Return DBUS Invocation*/
961                                 _bt_service_method_return(req_info->context, out_param, result);
962                                 _bt_free_info_from_invocation_list(req_info);
963                                 g_array_free(out_param, TRUE);
964                         }
965                         break;
966                 }
967                 default:
968                         BT_DBG("Unknown function(%d)", service_function);
969                         break;
970                 }
971         }
972 }
973
974 const char *__mesh_status_to_string(uint8_t err)
975 {
976         switch (err) {
977         case MESH_STATUS_SUCCESS: return "Success";
978         case MESH_STATUS_INVALID_ADDRESS: return "Invalid Address";
979         case MESH_STATUS_INVALID_MODEL: return "Invalid Model";
980         case MESH_STATUS_INVALID_APPKEY: return "Invalid AppKey";
981         case MESH_STATUS_INVALID_NETKEY: return "Invalid NetKey";
982         case MESH_STATUS_INSUFF_RESOURCES: return "Insufficient Resources";
983         case MESH_STATUS_IDX_ALREADY_STORED: return "Key Idx Already Stored";
984         case MESH_STATUS_INVALID_PUB_PARAM: return "Invalid Publish Parameters";
985         case MESH_STATUS_NOT_SUB_MOD: return "Not a Subscribe Model";
986         case MESH_STATUS_STORAGE_FAIL: return "Storage Failure";
987         case MESH_STATUS_FEATURE_NO_SUPPORT: return "Feature Not Supported";
988         case MESH_STATUS_CANNOT_UPDATE: return "Cannot Update";
989         case MESH_STATUS_CANNOT_REMOVE: return "Cannot Remove";
990         case MESH_STATUS_CANNOT_BIND: return "Cannot bind";
991         case MESH_STATUS_UNABLE_CHANGE_STATE: return "Unable to change state";
992         case MESH_STATUS_CANNOT_SET: return "Cannot set";
993         case MESH_STATUS_UNSPECIFIED_ERROR: return "Unspecified error";
994         case MESH_STATUS_INVALID_BINDING: return "Invalid Binding";
995
996         default: return "Unknown";
997         }
998 }
999
1000 static void __mesh_handle_model_subscription_event(int result,
1001                 bluetooth_mesh_model_configure_t *param,
1002                         const struct mesh_config_cmd *cmd)
1003 {
1004         switch (cmd->opcode) {
1005         /* Fall through */
1006         case MESH_OPCODE_CONFIG_MODEL_SUB_ADD:
1007         case MESH_OPCODE_CONFIG_MODEL_SUB_DELETE:
1008         case MESH_OPCODE_CONFIG_MODEL_SUB_OVERWRITE:
1009         case MESH_OPCODE_CONFIG_MODEL_SUB_DELETE_ALL:
1010                 /* Model Bind/UnBind Event */
1011         __bt_mesh_handle_pending_dev_config_request_info(result,
1012                         BT_MESH_MODEL_CONFIG_GROUP_SUB, &param,
1013                                 sizeof(bluetooth_mesh_model_configure_t));
1014                 break;
1015         case MESH_OPCODE_CONFIG_MODEL_SUB_VIRT_ADD:
1016         case MESH_OPCODE_CONFIG_MODEL_SUB_VIRT_DELETE:
1017         case MESH_OPCODE_CONFIG_MODEL_SUB_VIRT_OVERWRITE:
1018         __bt_mesh_handle_pending_dev_config_request_info(result,
1019                         BT_MESH_MODEL_CONFIG_VIRTUAL_GROUP_SUB, &param,
1020                                 sizeof(bluetooth_mesh_model_configure_t));
1021                 break;
1022         default:
1023                 break;
1024         }
1025 }
1026
1027 void _bt_mesh_config_client_devkey_msg_handler(
1028                 event_mesh_devkey_message_t *event)
1029 {
1030         uint32_t opcode;
1031         const struct mesh_config_cmd *cmd;
1032         uint16_t data_len = event->data_len;
1033         uint8_t *data = event->data;
1034         int result = BLUETOOTH_ERROR_NONE;
1035         uint16_t app_idx;
1036         uint16_t addr;
1037         uint16_t net_idx;
1038         uint16_t elem_addr;
1039         uint16_t ele_addr;
1040         uint32_t mod_id;
1041         int n;
1042         struct mesh_pending_request *req;
1043
1044         if (_bt_mesh_util_opcode_get(data, data_len, &opcode, &n)) {
1045                 BT_INFO("Mesh: Opcode of response data [0x%2.2x], actual data len [%d]", opcode, n);
1046                 data_len -= n;
1047                 data += n;
1048         } else
1049                 return;
1050
1051         BT_INFO("Mesh: Received %s (len %u) opcode [0x%2.2x]",
1052                 __mesh_get_opcode_string(opcode), data_len, opcode);
1053
1054         req = __bt_mesh_get_request_by_response(event->source,
1055                 event->net_uuid.uuid, (opcode & ~MESH_OPCODE_UNRELIABLE));
1056         if (req) {
1057                 BT_INFO("Mesh: Got Config Request");
1058                 cmd = req->cmd;
1059                 __mesh_request_remove(req);
1060                 l_queue_remove(pending_requests, req);
1061         } else
1062                 cmd = NULL;
1063
1064
1065         switch (opcode & ~MESH_OPCODE_UNRELIABLE) {
1066                 default:
1067                         return;
1068         case MESH_OPCODE_CONFIG_MODEL_PUB_STATUS: {
1069                 if (data_len != 12 && data_len != 14)
1070                         break;
1071                 bluetooth_mesh_model_configure_t param;
1072                 memset(&param, 0x00, sizeof(bluetooth_mesh_model_configure_t));
1073
1074                 _bt_mesh_util_convert_hex_to_string((uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1075                                 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1076
1077                 BT_INFO("\nNode %4.4x Model Publication status %s\n",
1078                                 event->source, __mesh_status_to_string(data[0]));
1079
1080                 if (data[0] != MESH_STATUS_SUCCESS)
1081                         break;
1082
1083                 /* Extract Element Address */
1084                 ele_addr = l_get_le16(data + 1);
1085
1086                 /* Extract Model ID */
1087                 if (data_len == 14) {
1088                         /* vendor Model */
1089                         mod_id = l_get_le16(data + 10 + 2);
1090                         mod_id = l_get_le16(data) << 16 | mod_id;
1091                 } else {
1092                         /* BT SIG Model */
1093                         mod_id = l_get_le16(data + 10);
1094                         mod_id = MESH_VENDOR_ID_MASK | mod_id;
1095                 }
1096
1097                 param.primary_unicast = event->source;
1098                 param.elem_index = ele_addr - event->source;
1099                 /* Extract Publish Address */
1100                 param.pub_addr = l_get_le16(data + 3);
1101
1102                 /* Extract Appkey Index */
1103                 param.appkey_idx =  l_get_le16(data + 5);
1104
1105                 /* Extract TTL */
1106                 param.ttl = data[6];
1107
1108                 /* Extract Period */
1109                 param.period = data[7];
1110                 if (!cmd)
1111                         break;
1112
1113                 if (cmd->opcode == MESH_OPCODE_CONFIG_MODEL_PUB_GET)
1114                         __bt_mesh_handle_pending_dev_config_request_info(result,
1115                                 BT_MESH_MODEL_GET_PUBLICATION, &param,
1116                                 sizeof(bluetooth_mesh_model_configure_t));
1117                 else
1118                         __bt_mesh_handle_pending_dev_config_request_info(result,
1119                                 BT_MESH_MODEL_SET_PUBLICATION, &param,
1120                                 sizeof(bluetooth_mesh_model_configure_t));
1121                 break;
1122         }
1123         case MESH_OPCODE_CONFIG_MODEL_SUB_STATUS: {
1124                 if (data_len != 7 && data_len != 9)
1125                         break;
1126                 bluetooth_mesh_model_configure_t param;
1127                 memset(&param, 0x00, sizeof(bluetooth_mesh_model_configure_t));
1128
1129                 _bt_mesh_util_convert_hex_to_string(
1130                         (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1131                                 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1132
1133                 BT_INFO("\nNode %4.4x Subscription status %s\n",
1134                                 event->source, __mesh_status_to_string(data[0]));
1135
1136                 ele_addr = l_get_le16(data + 1);
1137                 addr = l_get_le16(data + 3);
1138                 BT_INFO("Element Addr\t%4.4x\n", ele_addr);
1139
1140                 if (data_len == 9) {
1141                         /* vendor Model */
1142                         mod_id = l_get_le16(data + 5 + 2);
1143                         mod_id = l_get_le16(data) << 16 | mod_id;
1144                 } else {
1145                         /* BT SIG Model */
1146                         mod_id = l_get_le16(data + 5);
1147                         mod_id = MESH_VENDOR_ID_MASK | mod_id;
1148                 }
1149
1150                 param.primary_unicast = event->source;
1151                 param.elem_index = ele_addr - event->source;
1152                 /* Subscription address, unassigned address in case of Delete All command */
1153                 param.sub_addr = addr;
1154                 param.model = mod_id;
1155                 BT_INFO("Subscr Addr\t%4.4x\n", addr);
1156
1157                 if (cmd)
1158                         __mesh_handle_model_subscription_event(result, &param, cmd);
1159
1160                 break;
1161         }
1162         case MESH_OPCODE_CONFIG_DEFAULT_TTL_STATUS: {
1163                 if (data_len != 1)
1164                         break;
1165                 bluetooth_mesh_node_ttl_info_t param;
1166                 memset(&param, 0x00, sizeof(bluetooth_mesh_node_ttl_info_t));
1167
1168                 BT_INFO("Node %4.4x Default TTL %d", event->source, data[0]);
1169                  _bt_mesh_util_convert_hex_to_string(
1170                         (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1171                                 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1172                 param.unicast = event->source;
1173                 param.ttl = data[0];
1174
1175                 if (!_bt_mesh_network_save_remote_node_ttl(event->net_uuid.uuid,
1176                                 event->source,  data[0])) {
1177                         result = BLUETOOTH_ERROR_INTERNAL;
1178                         BT_INFO("Failed to save node TTL");
1179                 }
1180
1181                 /* Remote Node TTL event */
1182                 __bt_mesh_handle_pending_dev_config_request_info(result,
1183                         BT_MESH_NODE_TTL_EXECUTE, &param,
1184                                 sizeof(bluetooth_mesh_node_ttl_info_t));
1185                 break;
1186         }
1187         case MESH_OPCODE_MODEL_APP_STATUS: {
1188                 if (data_len != 7 && data_len != 9)
1189                         break;
1190                 bluetooth_mesh_model_configure_t param;
1191                 memset(&param, 0x00, sizeof(bluetooth_mesh_model_configure_t));
1192
1193                  _bt_mesh_util_convert_hex_to_string(
1194                         (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1195                                 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1196                 BT_INFO("Node %4.4x: Model App status %s\n", event->source,
1197                         __mesh_status_to_string(data[0]));
1198
1199                 if (data[0] != MESH_STATUS_SUCCESS)
1200                         result = BLUETOOTH_ERROR_INTERNAL;
1201
1202                 elem_addr = l_get_le16(data + 1);
1203                 app_idx = l_get_le16(data + 3);
1204
1205                 BT_INFO("Element Addr\t%4.4x", elem_addr);
1206                 if (data_len == 9) {
1207                         /* vendor Model */
1208                         mod_id = l_get_le16(data + 5 + 2);
1209                         mod_id = l_get_le16(data) << 16 | mod_id;
1210                 } else {
1211                         /* BT SIG Model */
1212                         mod_id = l_get_le16(data + 5);
1213                         mod_id = MESH_VENDOR_ID_MASK | mod_id;
1214                 }
1215
1216                 param.primary_unicast = event->source;
1217                 param.elem_index = elem_addr - event->source;
1218                 param.appkey_idx = app_idx;
1219                 param.model = mod_id;
1220                 BT_INFO("AppIdx\t\t%u (0x%3.3x)\n ", app_idx, app_idx);
1221
1222                 /* Model Bind/UnBind Event */
1223                 __bt_mesh_handle_pending_dev_config_request_info(result,
1224                         BT_MESH_MODEL_CONFIGURE_APPKEY, &param,
1225                                 sizeof(bluetooth_mesh_model_configure_t));
1226                 break;
1227         }
1228         case MESH_OPCODE_MODEL_APP_LIST: {
1229                 if (data_len < 5)
1230                         break;
1231                 GArray *garray;
1232                 int total = 0;
1233                 bluetooth_mesh_model_configure_t param;
1234                 memset(&param, 0x00, sizeof(bluetooth_mesh_model_configure_t));
1235
1236                 _bt_mesh_util_convert_hex_to_string(
1237                         (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1238                                 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1239
1240                 garray = g_array_new(FALSE, FALSE, sizeof(gchar));
1241
1242                 BT_INFO("\nNode %4.4x Model AppIdx status %s\n",
1243                                 event->source, __mesh_status_to_string(data[0]));
1244
1245                 BT_INFO("Element Addr\t%4.4x\n", l_get_le16(data + 1));
1246                 BT_INFO("Model ID\t%4.4x\n", l_get_le16(data + 3));
1247
1248                 elem_addr = l_get_le16(data + 1);
1249                 /* BT SIG Model */
1250                 mod_id = l_get_le16(data + 3);
1251                 mod_id = MESH_VENDOR_ID_MASK | mod_id;
1252
1253                 param.primary_unicast = event->source;
1254                 param.elem_index = elem_addr - event->source;
1255                 param.model = mod_id;
1256
1257                 data += 5;
1258                 data_len -= 5;
1259
1260                 while (data_len >= 3) {
1261                         app_idx = l_get_le16(data) & 0xfff;
1262                         g_array_append_vals(garray, &app_idx, sizeof(uint16_t));
1263                         BT_INFO("\t%u (0x%3.3x)\n", app_idx, app_idx);
1264
1265                         app_idx = l_get_le16(data + 1) >> 4;
1266                         g_array_append_vals(garray, &app_idx, sizeof(uint16_t));
1267                         BT_INFO("\t%u (0x%3.3x)\n", app_idx, app_idx);
1268                         data += 3;
1269                         data_len -= 3;
1270                 }
1271
1272                 if (data_len == 2) {
1273                         app_idx = l_get_le16(data) & 0xfff;
1274                         g_array_append_vals(garray, &app_idx, sizeof(uint16_t));
1275                         BT_INFO("\t %u (0x%3.3x)\n", app_idx, app_idx);
1276                 }
1277                 total = garray->len / sizeof(uint16_t);
1278                 param.appkey_list = (uint16_t **)g_malloc0(sizeof(uint16_t*) * garray->len);
1279                 param.appkeylist_count = total;
1280                 for (int i = 0; i < total; i++) {
1281                         param.appkey_list[i] = g_malloc(sizeof(uint16_t));
1282                         *param.appkey_list[i] = g_array_index(garray, uint16_t, i);
1283                 }
1284                 g_array_free(garray, TRUE);
1285
1286                 __bt_mesh_handle_pending_dev_config_request_info(result,
1287                         BT_MESH_MODEL_GET_APPKEY_LIST, &param,
1288                                 sizeof(bluetooth_mesh_model_configure_t));
1289                 break;
1290         }
1291         case MESH_OPCODE_CONFIG_MODEL_SUB_LIST: {
1292                 if (data_len < 5)
1293                         break;
1294                 int total = 0;
1295                 int i = 0;
1296                 bluetooth_mesh_model_configure_t param;
1297                 memset(&param, 0x00, sizeof(bluetooth_mesh_model_configure_t));
1298
1299                 _bt_mesh_util_convert_hex_to_string((uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1300                                 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1301
1302                 BT_INFO("\nNode %4.4x BT SIG Model Subscription List status %s\n",
1303                                 event->source, __mesh_status_to_string(data[0]));
1304
1305                 BT_INFO("Element Addr\t%4.4x\n", l_get_le16(data + 1));
1306                 elem_addr = l_get_le16(data + 1);
1307
1308                 /* BT SIG Model */
1309                 mod_id = l_get_le16(data + 3);
1310                 mod_id = MESH_VENDOR_ID_MASK | mod_id;
1311                 BT_INFO("Model ID\t%4.4x\n", mod_id);
1312
1313                 param.primary_unicast = event->source;
1314                 param.elem_index = elem_addr - event->source;
1315                 param.model = mod_id;
1316
1317                 total = data_len -  5;
1318                 param.sublist_count = total;
1319                 if (total) {
1320                         param.sub_list = (uint16_t **)g_malloc0(sizeof(uint16_t*) * total);
1321
1322                         i = 5;
1323                         for (; i < data_len; i += 2) {
1324                                 BT_INFO("Subscription Addr \t\t%4.4x\n ", l_get_le16(data + i));
1325                                 param.sub_list[i] = g_malloc(sizeof(uint16_t));
1326                                 *param.sub_list[i] = l_get_le16(data + i);
1327                         }
1328                 }
1329                 __bt_mesh_handle_pending_dev_config_request_info(result,
1330                         BT_MESH_MODEL_GET_SUBSCRIPTION_LIST, &param,
1331                                 sizeof(bluetooth_mesh_model_configure_t));
1332                 break;
1333         }
1334         case MESH_OPCODE_CONFIG_VEND_MODEL_SUB_LIST: {
1335                 if (data_len < 7)
1336                         break;
1337                 int total = 0;
1338                 int i = 0;
1339                 bluetooth_mesh_model_configure_t param;
1340                 memset(&param, 0x00, sizeof(bluetooth_mesh_model_configure_t));
1341
1342                 _bt_mesh_util_convert_hex_to_string(
1343                         (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1344                                 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1345
1346                 BT_INFO("\nNode %4.4x BT SIG Model Subscription List status %s\n",
1347                                 event->source, __mesh_status_to_string(data[0]));
1348
1349                 BT_INFO("Element Addr\t%4.4x\n", l_get_le16(data + 1));
1350                 elem_addr = l_get_le16(data + 1);
1351
1352                 /* VENDOR Model */
1353                 mod_id = l_get_le16(data + 5);
1354                 mod_id = l_get_le16(data + 3) << 16 | mod_id;
1355
1356                 BT_INFO("Model ID\t%4.4x\n", mod_id);
1357
1358                 param.primary_unicast = event->source;
1359                 param.elem_index = elem_addr - event->source;
1360                 param.model = mod_id;
1361
1362                 total = data_len -  7;
1363                 param.sublist_count = total;
1364                 if (total) {
1365                         param.sub_list = (uint16_t **)g_malloc0(sizeof(uint16_t*) * total);
1366
1367                         i = 7;
1368                         for (; i < data_len; i += 2) {
1369                                 BT_INFO("Subscription Addr \t\t%4.4x\n ", l_get_le16(data + i));
1370                                 param.sub_list[i] = g_malloc(sizeof(uint16_t));
1371                                 *param.sub_list[i] = l_get_le16(data + i);
1372                         }
1373                 }
1374                 __bt_mesh_handle_pending_dev_config_request_info(result,
1375                         BT_MESH_MODEL_GET_SUBSCRIPTION_LIST, &param,
1376                                 sizeof(bluetooth_mesh_model_configure_t));
1377                 break;
1378         }
1379         case MESH_OPCODE_DEV_COMP_STATUS: {
1380                 if (data_len < MESH_MINIMUM_COMPOSITION_LEN)
1381                         break;
1382                 bluetooth_mesh_node_features_t features;
1383                 memset(&features, 0x00, sizeof(bluetooth_mesh_node_features_t));
1384                 BT_INFO("Mesh: Got Response for Device Composition Data");
1385                 __bt_mesh_print_device_composition_data(data, data_len);
1386
1387                 if (!_bt_mesh_network_save_remote_node_composition(
1388                         event->net_uuid.uuid, event->source, data, data_len)) {
1389                         result = BLUETOOTH_ERROR_INTERNAL;
1390                         BT_INFO("Failed to save node composition!");
1391                 }
1392                 /* Browse Remote Node event */
1393                 __bt_mesh_handle_pending_dev_config_request_info(result,
1394                         BT_MESH_NODE_BROWSE, event, sizeof(event_mesh_devkey_message_t));
1395
1396                 /* Vendor Features Discover event */
1397                 _bt_mesh_util_convert_hex_to_string(
1398                         (uint8_t *) event->net_uuid.uuid, 16, features.net_uuid,
1399                                 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1400                 features.unicast = event->source;
1401                 _bt_mesh_node_get_vendor_features(event->net_uuid.uuid,
1402                         event->source, &features);
1403
1404                 __bt_mesh_handle_pending_dev_config_request_info(result,
1405                         BT_MESH_NODE_GET_VENDOR_FEATURES, &features,
1406                                 sizeof(bluetooth_mesh_node_features_t));
1407                 break;
1408         }
1409         case MESH_OPCODE_NETKEY_STATUS: {
1410                 if (data_len != 3)
1411                         break;
1412
1413                 bluetooth_mesh_key_configure_t param;
1414                 memset(&param, 0x00, sizeof(bluetooth_mesh_key_configure_t));
1415
1416                 BT_INFO("Mesh: Node %4.4x NetKey status %s",
1417                         event->source,  __mesh_status_to_string(data[0]));
1418                 net_idx = l_get_le16(data + 1) & 0xfff;
1419
1420                 BT_INFO("\tNetKey %u (0x%3.3x)", net_idx, net_idx);
1421
1422                 if (data[0] != 0)
1423                         result = BLUETOOTH_ERROR_INTERNAL;
1424
1425                 if (!cmd)
1426                         break;
1427
1428                 _bt_mesh_util_convert_hex_to_string(
1429                         (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1430                                 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1431                 param.primary_unicast = event->source;
1432                 param.netkey_idx = net_idx;
1433                 param.is_netkey = true;
1434
1435                 BT_INFO("Mesh: Resp recvd from node unicast [0x%4.4x]", event->source);
1436                 if (cmd->opcode == MESH_OPCODE_NETKEY_ADD) {
1437                         BT_INFO("Mesh: Resp recvd: MESH_OPCODE_NETKEY_ADD");
1438                         if (result == BLUETOOTH_ERROR_NONE) {
1439                                 if (!_bt_mesh_network_save_remote_node_netkey(
1440                                                         event->net_uuid.uuid, event->source, net_idx)) {
1441                                         result = BLUETOOTH_ERROR_INTERNAL;
1442                                         BT_INFO("Failed to save node Netkey!");
1443                                 }
1444                         }
1445                         param.op = BLUETOOTH_MESH_NODE_KEY_ADD;
1446                 } else if (cmd->opcode == MESH_OPCODE_NETKEY_DELETE) {
1447                         BT_INFO("Mesh: Resp recvd: MESH_OPCODE_NETKEY_DELETE");
1448                         if (result == BLUETOOTH_ERROR_NONE) {
1449                                 if (!_bt_mesh_network_delete_remote_node_netkey(
1450                                                         event->net_uuid.uuid, event->source, net_idx)) {
1451                                         result = BLUETOOTH_ERROR_INTERNAL;
1452                                         BT_INFO("Failed to delete node Netkey!");
1453                                 }
1454                         }
1455                         param.op = BLUETOOTH_MESH_NODE_KEY_DELETE;
1456                 } else if (cmd->opcode == MESH_OPCODE_NETKEY_UPDATE) {
1457                         BT_INFO("Mesh: Resp recvd: MESH_OPCODE_NETKEY_UPDATE");
1458                         param.op = BLUETOOTH_MESH_NODE_KEY_UPDATE;
1459                 }
1460                 /* Node Net Key Configure event */
1461                 __bt_mesh_handle_pending_dev_config_request_info(result,
1462                         BT_MESH_NODE_CONFIGURE_KEY,
1463                                 &param, sizeof(bluetooth_mesh_key_configure_t));
1464                 break;
1465         }
1466         case MESH_OPCODE_APPKEY_STATUS: {
1467                 if (data_len != 4)
1468                         break;
1469
1470                 bluetooth_mesh_key_configure_t param;
1471                 memset(&param, 0x00, sizeof(bluetooth_mesh_key_configure_t));
1472
1473                 BT_INFO("Mesh: Node %4.4x AppKey status %s\n", event->source,
1474                                 __mesh_status_to_string(data[0]));
1475                 net_idx = l_get_le16(data + 1) & 0xfff;
1476                 app_idx = l_get_le16(data + 2) >> 4;
1477
1478                 BT_INFO("NetKey\t%u (0x%3.3x)\n", net_idx, net_idx);
1479                 BT_INFO("AppKey\t%u (0x%3.3x)\n", app_idx, app_idx);
1480
1481                 if (data[0] != MESH_STATUS_SUCCESS)
1482                         result = BLUETOOTH_ERROR_INTERNAL;
1483
1484                 if (!cmd)
1485                         break;
1486
1487                 _bt_mesh_util_convert_hex_to_string(
1488                         (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1489                                 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1490
1491                 param.primary_unicast = event->source;
1492                 param.netkey_idx = net_idx;
1493                 param.appkey_idx = app_idx;
1494                 param.is_netkey = false;
1495
1496                 if (cmd->opcode == MESH_OPCODE_APPKEY_ADD) {
1497                         BT_INFO("Mesh: Resp recvd: MESH_OPCODE_APPKEY_ADD");
1498                         if (result == BLUETOOTH_ERROR_NONE) {
1499                                 if (!_bt_mesh_network_save_remote_node_appkey(
1500                                                 event->net_uuid.uuid, event->source,
1501                                                 net_idx, app_idx)) {
1502                                         result = BLUETOOTH_ERROR_INTERNAL;
1503                                         BT_INFO("Failed to save node Appkey!");
1504                                 }
1505                         }
1506                         param.op = BLUETOOTH_MESH_NODE_KEY_ADD;
1507                 } else if (cmd->opcode == MESH_OPCODE_APPKEY_DELETE) {
1508                         BT_INFO("Mesh: Resp recvd: MESH_OPCODE_APPKEY_DELETE");
1509                         if (result == BLUETOOTH_ERROR_NONE) {
1510                                 if (!_bt_mesh_network_delete_remote_node_appkey(
1511                                                 event->net_uuid.uuid, event->source,
1512                                                 net_idx, app_idx)) {
1513                                         result = BLUETOOTH_ERROR_INTERNAL;
1514                                         BT_INFO("Failed to delete node Appkey!");
1515                                 }
1516                         }
1517                         param.op = BLUETOOTH_MESH_NODE_KEY_DELETE;
1518                 } else if (cmd->opcode == MESH_OPCODE_APPKEY_UPDATE) {
1519                         BT_INFO("Mesh: Resp recvd: MESH_OPCODE_APPKEY_UPDATE");
1520                         param.op = BLUETOOTH_MESH_NODE_KEY_UPDATE;
1521                 }
1522
1523                 /* Node App Key Configure event */
1524                 __bt_mesh_handle_pending_dev_config_request_info(result,
1525                         BT_MESH_NODE_CONFIGURE_KEY,
1526                                 &param, sizeof(bluetooth_mesh_key_configure_t));
1527                 break;
1528         }
1529         }
1530 }
1531
1532 static gboolean __bt_mesh_vendor_feature_event_handler(gpointer data)
1533 {
1534         bluetooth_mesh_node_features_t *result = (bluetooth_mesh_node_features_t*) data;
1535         __bt_mesh_handle_pending_dev_config_request_info(
1536                 BLUETOOTH_ERROR_NONE,
1537                         BT_MESH_NODE_GET_VENDOR_FEATURES,
1538                                 result, sizeof(bluetooth_mesh_node_features_t));
1539         g_free(result);
1540         return FALSE;
1541 }
1542
1543 int _bt_mesh_node_discover_vendor_features(const char *app_cred, const char *sender,
1544                 bluetooth_mesh_node_features_t *req)
1545 {
1546         int ret = OAL_STATUS_SUCCESS;
1547         uint16_t dest;
1548         uint16_t netkey_idx;
1549         uint16_t data_len;
1550         oal_uuid_t net_uuid;
1551         uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
1552
1553         _bt_mesh_util_convert_string_to_hex(req->net_uuid,
1554                         strlen(req->net_uuid), net_uuid.uuid, 16);
1555         /* Check if Node's vendor features are already svaed or not */
1556         if (_bt_mesh_node_get_vendor_features(net_uuid.uuid, req->unicast, req)) {
1557                 /* Schedule event ot Application */
1558                 bluetooth_mesh_node_features_t *event = \
1559                         g_memdup(req, sizeof(bluetooth_mesh_node_features_t));
1560                 g_idle_add(__bt_mesh_vendor_feature_event_handler, (gpointer) event);
1561                 return BLUETOOTH_ERROR_NONE;
1562         }
1563
1564         /* If Scanning is going on */
1565         if (_bt_mesh_is_provisioning() ||
1566                         _bt_mesh_is_scanning()) {
1567                 BT_ERR("Device is buzy..");
1568                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1569         }
1570
1571         _bt_mesh_util_convert_string_to_hex(req->net_uuid,
1572                         strlen(req->net_uuid), net_uuid.uuid, 16);
1573
1574         dest = req->unicast;
1575
1576         /* Check pending request */
1577         if (_bt_mesh_check_pending_request(MESH_OPCODE_DEV_COMP_GET,
1578                                 dest, net_uuid.uuid)) {
1579                 BT_ERR("Device is buzy..");
1580                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1581         }
1582
1583         /* Get Subnet index of the rmeote node for TX encryption */
1584         netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, dest);
1585         if (netkey_idx == MESH_NET_IDX_INVALID)
1586                 return BLUETOOTH_ERROR_INTERNAL;
1587
1588         data_len = _bt_mesh_util_opcode_set(MESH_OPCODE_DEV_COMP_GET,
1589                         buffer);
1590
1591         /* By default, use page 0 */
1592         buffer[data_len++] = 0;
1593         ret = mesh_conf_send_message(&net_uuid, dest, true,
1594                         netkey_idx, buffer, data_len);
1595
1596         if (ret != OAL_STATUS_SUCCESS) {
1597                 BT_ERR("ret: %d", ret);
1598                 return BLUETOOTH_ERROR_INTERNAL;
1599         }
1600
1601         /* Queue the request with timeout */
1602         __bt_mesh_add_request(MESH_OPCODE_DEV_COMP_GET,
1603                         dest, net_uuid.uuid, NULL);
1604         return BLUETOOTH_ERROR_NONE;
1605 }
1606
1607 int _bt_mesh_browse_remote_node(const char *app_cred,
1608         const char *sender,
1609                 bluetooth_mesh_node_discover_t *req)
1610 {
1611         int ret = OAL_STATUS_SUCCESS;
1612         uint16_t dest;
1613         uint16_t netkey_idx;
1614         uint16_t data_len;
1615         oal_uuid_t net_uuid;
1616         oal_uuid_t dev_uuid;
1617         uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
1618
1619         /* If Scanning is going on */
1620         if (_bt_mesh_is_provisioning() ||
1621                         _bt_mesh_is_scanning()) {
1622                 BT_ERR("Device is buzy..");
1623                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1624         }
1625
1626         _bt_mesh_util_convert_string_to_hex(req->net_uuid,
1627                 strlen(req->net_uuid), net_uuid.uuid, 16);
1628         _bt_mesh_util_convert_string_to_hex(req->dev_uuid,
1629                 strlen(req->dev_uuid), dev_uuid.uuid, 16);
1630
1631         BT_INFO("Mesh: Browse Node UUID [%s]", req->dev_uuid);
1632
1633         /* Get Remote Node unicast address from Dev UUID */
1634         if (!_bt_mesh_node_get_unicast_from_dev_uuid(net_uuid.uuid,
1635                         dev_uuid.uuid, &dest))
1636                 return BLUETOOTH_ERROR_INTERNAL;
1637
1638         /* Check pending request */
1639         if (_bt_mesh_check_pending_request(MESH_OPCODE_DEV_COMP_GET,
1640                         dest, net_uuid.uuid)) {
1641                 BT_ERR("Device is buzy..");
1642                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1643         }
1644
1645         /* Get Subnet index of the rmeote node for TX encryption */
1646         netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, dest);
1647         if (netkey_idx == MESH_NET_IDX_INVALID)
1648                 return BLUETOOTH_ERROR_INTERNAL;
1649
1650         data_len = _bt_mesh_util_opcode_set(MESH_OPCODE_DEV_COMP_GET, buffer);
1651
1652         /* By default, use page 0 */
1653         buffer[data_len++] = 0;
1654         ret = mesh_conf_send_message(&net_uuid, dest, true,
1655                         netkey_idx, buffer, data_len);
1656
1657         if (ret != OAL_STATUS_SUCCESS) {
1658                 BT_ERR("ret: %d", ret);
1659                 return BLUETOOTH_ERROR_INTERNAL;
1660         }
1661
1662         /* Queue the request with timeout */
1663         __bt_mesh_add_request(MESH_OPCODE_DEV_COMP_GET,
1664                         dest, net_uuid.uuid, NULL);
1665         return BLUETOOTH_ERROR_NONE;
1666 }
1667
1668 int _bt_mesh_model_configure_group_subscription(const char *app_cred,
1669                 const char *sender, bluetooth_mesh_model_configure_t *req)
1670 {
1671         int ret = OAL_STATUS_SUCCESS;
1672         uint16_t netkey_idx;
1673         oal_uuid_t net_uuid;
1674         uint16_t data_len;
1675         uint32_t opcode = 0;
1676         uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
1677
1678         /* If Scanning is going on */
1679         if (_bt_mesh_is_provisioning() ||
1680                         _bt_mesh_is_scanning()) {
1681                 BT_ERR("Device is buzy..");
1682                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1683         }
1684
1685         if (req->op != BLUETOOTH_MESH_MODEL_SUB_DELETE_ALL) {
1686                 /* Subscriptio address sanity check */
1687                 if ((!MESH_IS_GROUP(req->sub_addr) ||
1688                         MESH_IS_ALL_NODES(req->sub_addr)) ||
1689                                 MESH_IS_VIRTUAL(req->sub_addr)) {
1690                         BT_ERR("Mesh: Bad subscription address %x\n",
1691                                 req->sub_addr);
1692                         return BLUETOOTH_ERROR_INVALID_PARAM;
1693                 }
1694         }
1695
1696         /* Get Subnet index of the remote node for TX encryption */
1697         netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid,
1698                                 req->primary_unicast);
1699         if (netkey_idx == MESH_NET_IDX_INVALID)
1700                 return BLUETOOTH_ERROR_INTERNAL;
1701
1702         _bt_mesh_util_convert_string_to_hex(req->net_uuid,
1703                 strlen(req->net_uuid), net_uuid.uuid, 16);
1704
1705         if (req->op == BLUETOOTH_MESH_MODEL_SUB_ADD)
1706                 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_ADD;
1707         else if (req->op == BLUETOOTH_MESH_MODEL_SUB_DELETE)
1708                 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_DELETE;
1709         else if (req->op == BLUETOOTH_MESH_MODEL_SUB_DELETE_ALL)
1710                 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_DELETE_ALL;
1711         else if (req->op == BLUETOOTH_MESH_MODEL_SUB_OVERWRITE)
1712                 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_OVERWRITE;
1713
1714         /* Check pending request */
1715         if (_bt_mesh_check_pending_request(opcode,
1716                                 req->primary_unicast, net_uuid.uuid)) {
1717                 BT_ERR("Device is buzy..");
1718                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1719         }
1720
1721         data_len = _bt_mesh_util_opcode_set(opcode, buffer);
1722
1723         /* Element Address */
1724         l_put_le16((req->primary_unicast + req->elem_index),
1725                         buffer + data_len);
1726         data_len += 2;
1727
1728         /* Subscription address */
1729         if (req->op != BLUETOOTH_MESH_MODEL_SUB_DELETE_ALL) {
1730                 l_put_le16(req->sub_addr, buffer + data_len);
1731                 data_len += 2;
1732         }
1733
1734         /* Insert Model ID */
1735          if (req->model >= 0xFFFF0000) {
1736                 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
1737                 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
1738                 data_len += 2;
1739         } else {
1740                 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
1741                 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
1742                 data_len += 2;
1743                 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
1744                 data_len += 2;
1745         }
1746
1747         ret = mesh_conf_send_message(&net_uuid, req->primary_unicast, true,
1748                         netkey_idx, buffer, data_len);
1749
1750         if (ret != OAL_STATUS_SUCCESS) {
1751                 BT_ERR("ret: %d", ret);
1752                 return BLUETOOTH_ERROR_INTERNAL;
1753         }
1754
1755         /* Queue the request with timeout */
1756         __bt_mesh_add_request(opcode, req->primary_unicast,
1757                 net_uuid.uuid,
1758                         g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
1759
1760         return BLUETOOTH_ERROR_NONE;
1761 }
1762
1763 int _bt_mesh_model_configure_virtual_group_subscription(
1764                 const char *app_cred, const char *sender,
1765                         bluetooth_mesh_model_configure_t *req)
1766 {
1767         int ret = OAL_STATUS_SUCCESS;
1768         uint16_t netkey_idx;
1769         oal_uuid_t net_uuid;
1770         uint16_t data_len;
1771         uint32_t opcode = 0;
1772         uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
1773
1774         /* If Scanning is going on */
1775         if (_bt_mesh_is_provisioning() ||
1776                         _bt_mesh_is_scanning()) {
1777                 BT_ERR("Device is buzy..");
1778                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1779         }
1780
1781         _bt_mesh_util_convert_string_to_hex(req->net_uuid,
1782                 strlen(req->net_uuid), net_uuid.uuid, 16);
1783
1784         if (req->op != BLUETOOTH_MESH_MODEL_SUB_DELETE_ALL) {
1785                 /* Subscription address sanity check */
1786                 if ((MESH_IS_GROUP(req->sub_addr) ||
1787                         MESH_IS_ALL_NODES(req->sub_addr)) ||
1788                                 !(MESH_IS_VIRTUAL(req->sub_addr))) {
1789                         BT_ERR("Mesh: Bad Virtual subscription address %x\n",
1790                                 req->sub_addr);
1791                         return BLUETOOTH_ERROR_INVALID_PARAM;
1792                 }
1793         }
1794
1795         /* Get Subnet index of the remote node for TX encryption */
1796         netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid,
1797                                 req->primary_unicast);
1798         if (netkey_idx == MESH_NET_IDX_INVALID)
1799                 return BLUETOOTH_ERROR_INTERNAL;
1800
1801         if (req->op == BLUETOOTH_MESH_MODEL_SUB_ADD)
1802                 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_ADD;
1803         else if (req->op == BLUETOOTH_MESH_MODEL_SUB_DELETE)
1804                 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_DELETE;
1805         else if (req->op == BLUETOOTH_MESH_MODEL_SUB_DELETE_ALL)
1806                 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_DELETE_ALL;
1807         else if (req->op == BLUETOOTH_MESH_MODEL_SUB_OVERWRITE)
1808                 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_OVERWRITE;
1809
1810         /* Check pending request */
1811         if (_bt_mesh_check_pending_request(opcode,
1812                                 req->primary_unicast, net_uuid.uuid)) {
1813                 BT_ERR("Device is buzy..");
1814                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1815         }
1816
1817         data_len = _bt_mesh_util_opcode_set(opcode, buffer);
1818
1819         /* Element Address */
1820         l_put_le16((req->primary_unicast + req->elem_index), buffer + data_len);
1821         data_len += 2;
1822
1823         /* Subscription address */
1824         if (req->op != BLUETOOTH_MESH_MODEL_SUB_DELETE_ALL) {
1825                 uint8_t label_uuid[16];
1826                 if (!_bt_mesh_network_get_label_uuid_from_sub_addr(
1827                         net_uuid.uuid, req->sub_addr, label_uuid)) {
1828                         BT_ERR("Mesh: Virtual Group Label UUID Not found");
1829                         return BLUETOOTH_ERROR_INVALID_PARAM;
1830                 }
1831                 memcpy(buffer + data_len, label_uuid, 16);
1832                 data_len += 16;
1833         }
1834
1835         /* Insert Model ID */
1836          if (req->model >= 0xFFFF0000) {
1837                 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
1838                 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
1839                 data_len += 2;
1840         } else {
1841                 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
1842                 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
1843                 data_len += 2;
1844                 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
1845                 data_len += 2;
1846         }
1847
1848         ret = mesh_conf_send_message(&net_uuid,
1849                         req->primary_unicast, true,
1850                                 netkey_idx, buffer, data_len);
1851
1852         if (ret != OAL_STATUS_SUCCESS) {
1853                 BT_ERR("ret: %d", ret);
1854                 return BLUETOOTH_ERROR_INTERNAL;
1855         }
1856
1857         /* Queue the request with timeout */
1858         __bt_mesh_add_request(opcode, req->primary_unicast,
1859                 net_uuid.uuid,
1860                         g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
1861
1862         return BLUETOOTH_ERROR_NONE;
1863 }
1864
1865 int _bt_mesh_model_get_publication(const char *app_cred, const char *sender,
1866                 bluetooth_mesh_model_configure_t *req)
1867 {
1868         int ret = OAL_STATUS_SUCCESS;
1869         uint16_t netkey_idx;
1870         oal_uuid_t net_uuid;
1871         uint16_t data_len;
1872         uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
1873
1874         /* If Scanning is going on */
1875         if (_bt_mesh_is_provisioning() ||
1876                         _bt_mesh_is_scanning()) {
1877                 BT_ERR("Device is buzy..");
1878                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1879         }
1880
1881         _bt_mesh_util_convert_string_to_hex(req->net_uuid,
1882                 strlen(req->net_uuid), net_uuid.uuid, 16);
1883
1884         /* Check pending request */
1885         if (_bt_mesh_check_pending_request(MESH_OPCODE_CONFIG_MODEL_PUB_GET,
1886                                 req->primary_unicast, net_uuid.uuid)) {
1887                 BT_ERR("Device is buzy..");
1888                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1889         }
1890
1891         /* Get Subnet index of the remote node for TX encryption */
1892         netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, req->primary_unicast);
1893         if (netkey_idx == MESH_NET_IDX_INVALID)
1894                 return BLUETOOTH_ERROR_INTERNAL;
1895
1896         /* Set Opcode */
1897         data_len = _bt_mesh_util_opcode_set(MESH_OPCODE_CONFIG_MODEL_PUB_GET, buffer);
1898
1899         /* Element Address */
1900         l_put_le16((req->primary_unicast + req->elem_index), buffer + data_len);
1901         data_len += 2;
1902
1903         /* Insert Model ID */
1904         if (req->model >= 0xFFFF0000) {
1905                 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
1906                 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
1907                 data_len += 2;
1908         } else {
1909                 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
1910                 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
1911                 data_len += 2;
1912                 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
1913                 data_len += 2;
1914         }
1915
1916         ret = mesh_conf_send_message(&net_uuid, req->primary_unicast, true, netkey_idx, buffer, data_len);
1917
1918         if (ret != OAL_STATUS_SUCCESS) {
1919                 BT_ERR("ret: %d", ret);
1920                 return BLUETOOTH_ERROR_INTERNAL;
1921         }
1922
1923         /* Queue the request with timeout */
1924         __bt_mesh_add_request(MESH_OPCODE_CONFIG_MODEL_PUB_GET, req->primary_unicast, net_uuid.uuid,
1925                         g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
1926
1927         return BLUETOOTH_ERROR_NONE;
1928 }
1929
1930 int _bt_mesh_model_set_publication(const char *app_cred, const char *sender,
1931                 bluetooth_mesh_model_configure_t *req)
1932 {
1933         int ret = OAL_STATUS_SUCCESS;
1934         uint16_t netkey_idx;
1935         oal_uuid_t net_uuid;
1936         uint16_t data_len;
1937         uint32_t opcode = 0;
1938         uint8_t label_uuid[16];
1939         uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
1940
1941         /* If Scanning is going on */
1942         if (_bt_mesh_is_provisioning() ||
1943                         _bt_mesh_is_scanning()) {
1944                 BT_ERR("Device is buzy..");
1945                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1946         }
1947
1948         _bt_mesh_util_convert_string_to_hex(req->net_uuid, strlen(req->net_uuid), net_uuid.uuid, 16);
1949
1950         if (req->pub_addr == MESH_ALL_NODES_ADDRESS)
1951                 BT_INFO("Mesh: Setting Publication to ALL Node Address");
1952
1953         if (!MESH_IS_GROUP(req->pub_addr) && !MESH_IS_VIRTUAL(req->pub_addr) &&
1954                         req->pub_addr != MESH_UNASSIGNED_ADDRESS) {
1955                 BT_ERR("Mesh: Bad Publication address %x\n", req->pub_addr);
1956                 return BLUETOOTH_ERROR_INVALID_PARAM;
1957         }
1958
1959         if (req->pub_addr != MESH_UNASSIGNED_ADDRESS) {
1960                 if (MESH_IS_VIRTUAL(req->pub_addr)) {
1961                         if(!_bt_mesh_network_get_label_uuid_from_sub_addr(
1962                                         net_uuid.uuid, req->pub_addr, label_uuid))
1963                                 return BLUETOOTH_ERROR_INVALID_PARAM;
1964                         opcode = MESH_OPCODE_CONFIG_MODEL_PUB_VIRT_SET;
1965
1966                 } else if (MESH_IS_GROUP(req->pub_addr))
1967                         opcode = MESH_OPCODE_CONFIG_MODEL_PUB_SET;
1968         }
1969
1970         /* Check pending request */
1971         if (_bt_mesh_check_pending_request(opcode,
1972                                 req->primary_unicast, net_uuid.uuid)) {
1973                 BT_ERR("Device is buzy..");
1974                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1975         }
1976
1977         /* Get Subnet index of the remote node for TX encryption */
1978         netkey_idx = _bt_mesh_node_get_subnet_idx(
1979                                 net_uuid.uuid, req->primary_unicast);
1980         if (netkey_idx == MESH_NET_IDX_INVALID)
1981                 return BLUETOOTH_ERROR_INTERNAL;
1982
1983         /* Set opcode */
1984         data_len = _bt_mesh_util_opcode_set(opcode, buffer);
1985
1986         /* Element Address */
1987         l_put_le16((req->primary_unicast + req->elem_index), buffer + data_len);
1988         data_len += 2;
1989
1990         /* Fill Publication Address */
1991         if (MESH_IS_VIRTUAL(req->pub_addr)) {
1992                 memcpy(buffer + data_len, label_uuid, 16);
1993                 data_len += 16;
1994         } else {
1995                 l_put_le16(req->pub_addr, buffer + data_len);
1996                 data_len += 2;
1997         }
1998
1999         /* AppKey index + credential (set to 0) */
2000         l_put_le16(req->appkey_idx, buffer + data_len);
2001         data_len += 2;
2002
2003         /* Fill TTL */
2004         buffer[data_len++] = req->ttl;
2005         /* Publish period  step count and step resolution */
2006         buffer[data_len++] = req->period;
2007         /* Publish retransmit count & interval steps */
2008         buffer[data_len++] = req->retransmit;
2009
2010         /* Insert Model ID */
2011         if (req->model >= 0xFFFF0000) {
2012                 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
2013                 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2014                 data_len += 2;
2015         } else {
2016                 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
2017                 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
2018                 data_len += 2;
2019                 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2020                 data_len += 2;
2021         }
2022
2023         ret = mesh_conf_send_message(&net_uuid,
2024                         req->primary_unicast, true,
2025                                 netkey_idx, buffer, data_len);
2026
2027         if (ret != OAL_STATUS_SUCCESS) {
2028                 BT_ERR("ret: %d", ret);
2029                 return BLUETOOTH_ERROR_INTERNAL;
2030         }
2031
2032         /* Queue the request with timeout */
2033         __bt_mesh_add_request(opcode, req->primary_unicast, net_uuid.uuid,
2034                         g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
2035
2036         return BLUETOOTH_ERROR_NONE;
2037 }
2038
2039 int _bt_mesh_node_model_get_subscription_list(const char *app_cred, const char *sender,
2040                 bluetooth_mesh_model_configure_t *req)
2041 {
2042         int ret = OAL_STATUS_SUCCESS;
2043         uint16_t netkey_idx;
2044         oal_uuid_t net_uuid;
2045         uint16_t data_len;
2046         uint32_t opcode = 0;
2047         uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
2048
2049         /* If Scanning is going on */
2050         if (_bt_mesh_is_provisioning() ||
2051                         _bt_mesh_is_scanning()) {
2052                 BT_ERR("Device is buzy..");
2053                 return BLUETOOTH_ERROR_DEVICE_BUSY;
2054         }
2055
2056         _bt_mesh_util_convert_string_to_hex(req->net_uuid, strlen(req->net_uuid), net_uuid.uuid, 16);
2057
2058         /* Insert Model ID */
2059         if (req->model >= 0xFFFF0000)
2060                 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
2061                 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_GET;
2062         else
2063                 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
2064                 opcode = MESH_OPCODE_CONFIG_VEND_MODEL_SUB_GET;
2065
2066         /* Check pending request */
2067         if (_bt_mesh_check_pending_request(opcode,
2068                                 req->primary_unicast, net_uuid.uuid)) {
2069                 BT_ERR("Device is buzy..");
2070                 return BLUETOOTH_ERROR_DEVICE_BUSY;
2071         }
2072         /* Get Subnet index of the remote node for TX encryption */
2073         netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, req->primary_unicast);
2074         if (netkey_idx == MESH_NET_IDX_INVALID)
2075                 return BLUETOOTH_ERROR_INTERNAL;
2076
2077         data_len = _bt_mesh_util_opcode_set(opcode, buffer);
2078         /* Element Address */
2079         l_put_le16((req->primary_unicast + req->elem_index), buffer + data_len);
2080         data_len += 2;
2081
2082
2083         /* Insert Model ID */
2084         if (opcode == MESH_OPCODE_CONFIG_MODEL_SUB_GET) {
2085                 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
2086                 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2087                 data_len += 2;
2088         } else {
2089                 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
2090                 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
2091                 data_len += 2;
2092                 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2093                 data_len += 2;
2094         }
2095
2096         ret = mesh_conf_send_message(&net_uuid,
2097                 req->primary_unicast, true, netkey_idx, buffer, data_len);
2098
2099         if (ret != OAL_STATUS_SUCCESS) {
2100                 BT_ERR("ret: %d", ret);
2101                 return BLUETOOTH_ERROR_INTERNAL;
2102         }
2103
2104         /* Queue the request with timeout */
2105         __bt_mesh_add_request(opcode, req->primary_unicast, net_uuid.uuid,
2106                         g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
2107
2108         return BLUETOOTH_ERROR_NONE;
2109 }
2110
2111 int _bt_mesh_node_model_get_appkey_list(const char *app_cred, const char *sender,
2112                 bluetooth_mesh_model_configure_t *req)
2113 {
2114         int ret = OAL_STATUS_SUCCESS;
2115         uint16_t netkey_idx;
2116         oal_uuid_t net_uuid;
2117         uint16_t data_len;
2118         uint32_t opcode = 0;
2119         uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
2120
2121         /* If Scanning is going on */
2122         if (_bt_mesh_is_provisioning() ||
2123                         _bt_mesh_is_scanning()) {
2124                 BT_ERR("Device is buzy..");
2125                 return BLUETOOTH_ERROR_DEVICE_BUSY;
2126         }
2127
2128         _bt_mesh_util_convert_string_to_hex(req->net_uuid,
2129                 strlen(req->net_uuid), net_uuid.uuid, 16);
2130
2131         /* Insert Model ID */
2132         if (req->model >= 0xFFFF0000)
2133                 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
2134                 opcode = MESH_OPCODE_MODEL_APP_GET;
2135         else
2136                 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
2137                 opcode = MESH_OPCODE_VENDOR_MODEL_APP_GET;
2138
2139         /* Check pending request */
2140         if (_bt_mesh_check_pending_request(opcode,
2141                                 req->primary_unicast, net_uuid.uuid)) {
2142                 BT_ERR("Device is buzy..");
2143                 return BLUETOOTH_ERROR_DEVICE_BUSY;
2144         }
2145         /* Get Subnet index of the remote node for TX encryption */
2146         netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, req->primary_unicast);
2147         if (netkey_idx == MESH_NET_IDX_INVALID)
2148                 return BLUETOOTH_ERROR_INTERNAL;
2149
2150         data_len = _bt_mesh_util_opcode_set(opcode, buffer);
2151         /* Element Address */
2152         l_put_le16((req->primary_unicast + req->elem_index), buffer + data_len);
2153         data_len += 2;
2154
2155
2156         /* Insert Model ID */
2157         if (opcode == MESH_OPCODE_MODEL_APP_GET) {
2158                 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
2159                 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2160                 data_len += 2;
2161         } else {
2162                 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
2163                 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
2164                 data_len += 2;
2165                 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2166                 data_len += 2;
2167         }
2168
2169         ret = mesh_conf_send_message(&net_uuid, req->primary_unicast, true, netkey_idx, buffer, data_len);
2170
2171         if (ret != OAL_STATUS_SUCCESS) {
2172                 BT_ERR("ret: %d", ret);
2173                 return BLUETOOTH_ERROR_INTERNAL;
2174         }
2175
2176         /* Queue the request with timeout */
2177         __bt_mesh_add_request(opcode, req->primary_unicast, net_uuid.uuid,
2178                         g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
2179
2180         return BLUETOOTH_ERROR_NONE;
2181 }
2182
2183 int _bt_mesh_node_model_appkey_execute(const char *app_cred, const char *sender,
2184                 bluetooth_mesh_model_configure_t *req)
2185 {
2186         int ret = OAL_STATUS_SUCCESS;
2187         uint16_t netkey_idx;
2188         oal_uuid_t net_uuid;
2189         uint16_t data_len;
2190         uint32_t opcode = 0;
2191         uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
2192
2193         /* If Scanning is going on */
2194         if (_bt_mesh_is_provisioning() ||
2195                         _bt_mesh_is_scanning()) {
2196                 BT_ERR("Device is buzy..");
2197                 return BLUETOOTH_ERROR_DEVICE_BUSY;
2198         }
2199
2200         _bt_mesh_util_convert_string_to_hex(req->net_uuid, strlen(req->net_uuid), net_uuid.uuid, 16);
2201
2202         /* Check pending request */
2203         if (_bt_mesh_check_pending_request(req->is_bind ? MESH_OPCODE_MODEL_APP_BIND : MESH_OPCODE_MODEL_APP_UNBIND,
2204                                 req->primary_unicast, net_uuid.uuid)) {
2205                 BT_ERR("Device is buzy..");
2206                 return BLUETOOTH_ERROR_DEVICE_BUSY;
2207         }
2208         /* Get Subnet index of the remote node for TX encryption */
2209         netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, req->primary_unicast);
2210         if (netkey_idx == MESH_NET_IDX_INVALID)
2211                 return BLUETOOTH_ERROR_INTERNAL;
2212
2213         if (req->is_bind)
2214                 opcode = MESH_OPCODE_MODEL_APP_BIND;
2215         else
2216                 opcode = MESH_OPCODE_MODEL_APP_UNBIND;
2217
2218         data_len = _bt_mesh_util_opcode_set(opcode, buffer);
2219         /* Element Address */
2220         l_put_le16((req->primary_unicast + req->elem_index), buffer + data_len);
2221         data_len += 2;
2222
2223         /* AppKey Index  */
2224         l_put_le16(req->appkey_idx, buffer + data_len);
2225         data_len += 2;
2226
2227         /* Insert Model ID */
2228         if (req->model >= 0xFFFF0000) {
2229                 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
2230                 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2231                 data_len += 2;
2232         } else {
2233                 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
2234                 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
2235                 data_len += 2;
2236                 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2237                 data_len += 2;
2238         }
2239
2240         ret = mesh_conf_send_message(&net_uuid, req->primary_unicast, true, netkey_idx, buffer, data_len);
2241
2242         if (ret != OAL_STATUS_SUCCESS) {
2243                 BT_ERR("ret: %d", ret);
2244                 return BLUETOOTH_ERROR_INTERNAL;
2245         }
2246
2247         /* Queue the request with timeout */
2248         __bt_mesh_add_request(opcode, req->primary_unicast, net_uuid.uuid,
2249                         g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
2250
2251         return BLUETOOTH_ERROR_NONE;
2252 }
2253
2254 int _bt_mesh_ttl_execute_remote_node(const char *app_cred, const char *sender,
2255                 bluetooth_mesh_node_ttl_info_t *req)
2256 {
2257         int ret = OAL_STATUS_SUCCESS;
2258         uint16_t netkey_idx;
2259         uint16_t data_len;
2260         oal_uuid_t net_uuid;
2261         uint32_t opcode = 0;
2262         uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
2263
2264         /* If Scanning is going on */
2265         if (_bt_mesh_is_provisioning() ||
2266                         _bt_mesh_is_scanning()) {
2267                 BT_ERR("Device is buzy..");
2268                 return BLUETOOTH_ERROR_DEVICE_BUSY;
2269         }
2270
2271         _bt_mesh_util_convert_string_to_hex(req->net_uuid, strlen(req->net_uuid), net_uuid.uuid, 16);
2272
2273         /* Check pending request */
2274         if (_bt_mesh_check_pending_request(req->is_set ? MESH_OPCODE_CONFIG_DEFAULT_TTL_SET : MESH_OPCODE_CONFIG_DEFAULT_TTL_GET,
2275                                 req->unicast, net_uuid.uuid)) {
2276                 BT_ERR("Device is buzy..");
2277                 return BLUETOOTH_ERROR_DEVICE_BUSY;
2278         }
2279
2280         /* Get Subnet index of the rmeote node for TX encryption */
2281         netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, req->unicast);
2282         if (netkey_idx == MESH_NET_IDX_INVALID)
2283                 return BLUETOOTH_ERROR_INTERNAL;
2284
2285         if (req->is_set) {
2286                 opcode = MESH_OPCODE_CONFIG_DEFAULT_TTL_SET;
2287                 data_len = _bt_mesh_util_opcode_set(MESH_OPCODE_CONFIG_DEFAULT_TTL_SET, buffer);
2288                 buffer[data_len++] = req->ttl;
2289         } else {
2290                 opcode = MESH_OPCODE_CONFIG_DEFAULT_TTL_GET;
2291                 data_len = _bt_mesh_util_opcode_set(MESH_OPCODE_CONFIG_DEFAULT_TTL_GET, buffer);
2292         }
2293
2294         ret = mesh_conf_send_message(&net_uuid, req->unicast, true, netkey_idx, buffer, data_len);
2295
2296         if (ret != OAL_STATUS_SUCCESS) {
2297                 BT_ERR("ret: %d", ret);
2298                 return BLUETOOTH_ERROR_INTERNAL;
2299         }
2300
2301         /* Queue the request with timeout */
2302         __bt_mesh_add_request(opcode, req->unicast, net_uuid.uuid,
2303                         g_memdup(req, sizeof(bluetooth_mesh_node_ttl_info_t)));
2304         return BLUETOOTH_ERROR_NONE;
2305 }
2306
2307 static bool __bt_mesh_check_pending_key_cmd(uint16_t dest, bool is_netkey,
2308                 bluetooth_mesh_node_key_conf_e op,  uint8_t net_uuid[], uint32_t *opcode)
2309 {
2310         const struct mesh_config_cmd *cmd;
2311
2312         if (is_netkey) {
2313                 switch(op) {
2314                 case BLUETOOTH_MESH_NODE_KEY_ADD:
2315                         cmd = __mesh_get_command(MESH_OPCODE_NETKEY_ADD);
2316                         if (!cmd)
2317                                 return false;
2318                         if (__bt_mesh_get_request_by_response(dest, net_uuid, cmd->response)) {
2319                                 BT_ERR("Mesh:Another Key Configuration command is pending\n");
2320                                 return true;
2321                         }
2322                         *opcode = MESH_OPCODE_NETKEY_ADD;
2323                         return false;
2324                 case BLUETOOTH_MESH_NODE_KEY_DELETE:
2325                         cmd = __mesh_get_command(MESH_OPCODE_NETKEY_DELETE);
2326                         if (!cmd)
2327                                 return false;
2328                         if (__bt_mesh_get_request_by_response(dest, net_uuid, cmd->response)) {
2329                                 BT_ERR("Mesh:Another Key Configuration command is pending\n");
2330                                 return true;
2331                         }
2332                         *opcode = MESH_OPCODE_NETKEY_DELETE;
2333                         return false;
2334                 case BLUETOOTH_MESH_NODE_KEY_UPDATE:
2335                         cmd = __mesh_get_command(MESH_OPCODE_NETKEY_UPDATE);
2336                         if (!cmd)
2337                                 return false;
2338                         if (__bt_mesh_get_request_by_response(dest, net_uuid, cmd->response)) {
2339                                 BT_ERR("Mesh:Another Key Configuration command is pending\n");
2340                                 return true;
2341                         }
2342                         *opcode = MESH_OPCODE_NETKEY_UPDATE;
2343                         return false;
2344                 }
2345         } else {
2346                 switch(op) {
2347                 case BLUETOOTH_MESH_NODE_KEY_ADD:
2348                         cmd = __mesh_get_command(MESH_OPCODE_APPKEY_ADD);
2349                         if (!cmd)
2350                                 return false;
2351                         if (__bt_mesh_get_request_by_response(dest, net_uuid, cmd->response)) {
2352                                 BT_ERR("Mesh:Another Key Configuration command is pending\n");
2353                                 return true;
2354                         }
2355                         *opcode = MESH_OPCODE_APPKEY_ADD;
2356                         return false;
2357                 case BLUETOOTH_MESH_NODE_KEY_DELETE:
2358                         cmd = __mesh_get_command(MESH_OPCODE_APPKEY_DELETE);
2359                         if (!cmd)
2360                                 return false;
2361                         if (__bt_mesh_get_request_by_response(dest, net_uuid, cmd->response)) {
2362                                 BT_ERR("Mesh:Another Key Configuration command is pending\n");
2363                                 return true;
2364                         }
2365                         *opcode = MESH_OPCODE_APPKEY_DELETE;
2366                         return false;
2367                 case BLUETOOTH_MESH_NODE_KEY_UPDATE:
2368                         cmd = __mesh_get_command(MESH_OPCODE_APPKEY_UPDATE);
2369                         if (!cmd)
2370                                 return false;
2371                         if (__bt_mesh_get_request_by_response(dest, net_uuid, cmd->response)) {
2372                                 BT_ERR("Mesh:Another Key Configuration command is pending\n");
2373                                 return true;
2374                         }
2375                         *opcode = MESH_OPCODE_APPKEY_UPDATE;
2376                         return false;
2377                 }
2378         }
2379         return false;
2380 }
2381
2382 int _bt_mesh_node_configure_key(const char *app_cred, const char *sender,
2383                 bluetooth_mesh_key_configure_t *req)
2384 {
2385         int ret = OAL_STATUS_SUCCESS;
2386         uint16_t netkey_idx;
2387         uint16_t bound_netkey_idx = 0x0000;
2388         oal_uuid_t net_uuid;
2389         uint32_t opcode = 0;
2390         bool update;
2391         uint16_t data_len;
2392         uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
2393
2394         /* If Scanning is going on */
2395         if (_bt_mesh_is_provisioning() ||
2396                         _bt_mesh_is_scanning()) {
2397                 BT_ERR("Device is buzy..");
2398                 return BLUETOOTH_ERROR_DEVICE_BUSY;
2399         }
2400
2401         _bt_mesh_util_convert_string_to_hex(req->net_uuid, strlen(req->net_uuid), net_uuid.uuid, 16);
2402
2403         if (req->is_netkey && !_bt_mesh_keys_subnet_exists(net_uuid.uuid, req->netkey_idx)) {
2404                 BT_ERR("Local Subnet not found..");
2405                 return BLUETOOTH_ERROR_INVALID_PARAM;
2406         }
2407
2408         /* For Appkey Configuration, check for available bound netkey */
2409         if (!req->is_netkey) {
2410                 bound_netkey_idx = _bt_mesh_keys_get_bound_key(net_uuid.uuid, req->appkey_idx);
2411                 if (bound_netkey_idx == MESH_NET_IDX_INVALID) {
2412                         BT_ERR("Local AppKey not found..");
2413                         return BLUETOOTH_ERROR_INVALID_PARAM;
2414                 }
2415         }
2416
2417         /* Check pending request */
2418         if (__bt_mesh_check_pending_key_cmd(req->primary_unicast,
2419                                 req->is_netkey, req->op, net_uuid.uuid, &opcode)) {
2420                 BT_ERR("Device is buzy..");
2421                 return BLUETOOTH_ERROR_DEVICE_BUSY;
2422         }
2423
2424         /* Get Subnet index of the rmeote node for TX encryption */
2425         netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, req->primary_unicast);
2426         if (netkey_idx == MESH_NET_IDX_INVALID)
2427                 return BLUETOOTH_ERROR_INTERNAL;
2428
2429         /* Handle Key (App/Net) Delete Commands: Configuration Message  */
2430         if (opcode == MESH_OPCODE_NETKEY_DELETE || opcode == MESH_OPCODE_APPKEY_DELETE) {
2431                 data_len = _bt_mesh_util_opcode_set(opcode, buffer);
2432                 if (req->is_netkey) {
2433                         l_put_le16(req->netkey_idx, buffer + data_len);
2434                         data_len += 2;
2435                 } else {
2436                         buffer[data_len] = bound_netkey_idx;
2437                         buffer[data_len + 1] = ((bound_netkey_idx >> 8) & 0xf) | ((req->appkey_idx << 4) & 0xf0);
2438                         buffer[data_len + 2] = req->appkey_idx >> 4;
2439
2440                         data_len += 3;
2441                 }
2442                 ret = mesh_conf_send_message(&net_uuid, req->primary_unicast, true, netkey_idx, buffer, data_len);
2443         } else {
2444                 /* Handle Key (App/Net) Update & Add Commands: Key Config message  */
2445                 update = (opcode == MESH_OPCODE_NETKEY_UPDATE || opcode == MESH_OPCODE_APPKEY_UPDATE);
2446                 ret = mesh_conf_send_key_message(&net_uuid, req->primary_unicast, req->is_netkey,
2447                                 update, req->is_netkey? req->netkey_idx: req->appkey_idx, netkey_idx);
2448         }
2449         if (ret != OAL_STATUS_SUCCESS) {
2450                 BT_ERR("ret: %d", ret);
2451                 return BLUETOOTH_ERROR_INTERNAL;
2452         }
2453
2454         /* Queue the request with timeout */
2455         __bt_mesh_add_request(opcode, req->primary_unicast,  net_uuid.uuid,
2456                 g_memdup(req, sizeof(bluetooth_mesh_key_configure_t)));
2457         return BLUETOOTH_ERROR_NONE;
2458 }