Fix the svace issues
[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         int i;
526
527         if (BLUETOOTH_ERROR_NONE == result) {
528
529                 if (evt->appkeylist_count) {
530                         builder = g_variant_builder_new(G_VARIANT_TYPE("aq"));
531                         for (i = 0; i < evt->appkeylist_count; i++)
532                                 g_variant_builder_add(builder, "q", *evt->appkey_list[i]);
533
534                         param = g_variant_new("(isqiui(aq))", result, evt->net_uuid,
535                                         evt->primary_unicast, evt->elem_index, evt->model,
536                                         evt->appkeylist_count, builder);
537
538                         g_variant_builder_unref(builder);
539                 }
540
541                 /* Send event */
542                 _bt_send_event(BT_MESH_EVENT,
543                                 BLUETOOTH_EVENT_MESH_MODEL_APPKEY_LIST,
544                                 param);
545
546                 if (evt->appkeylist_count) {
547                         /* Free List data */
548                         for (int i = 0; i < evt->appkeylist_count; i++)
549                                 g_free(evt->appkey_list[i]);
550                         g_free(evt->appkey_list);
551                 }
552         }
553 }
554
555 static void __bt_mesh_send_model_configure_appkey_event(int result,
556                 bluetooth_mesh_model_configure_t *evt)
557 {
558         GVariant *out_var = NULL, *param = NULL;
559         GArray *info = NULL;
560
561         if (BLUETOOTH_ERROR_NONE == result) {
562                 /* Send event */
563                 info = g_array_new(FALSE, FALSE, sizeof(gchar));
564                 g_array_append_vals(info, evt, sizeof(bluetooth_mesh_model_configure_t));
565
566                 out_var = g_variant_new_from_data((const GVariantType *)"ay",
567                                 info->data, info->len,
568                                 TRUE, NULL, NULL);
569
570                 param = g_variant_new("(iv)", result, out_var);
571                 _bt_send_event(BT_MESH_EVENT,
572                                 BLUETOOTH_EVENT_MESH_NODE_MODEL_APPKEY_BIND,
573                                 param);
574         }
575 }
576
577 static void __bt_mesh_send_node_ttl_configuration_event(int result,
578                 bluetooth_mesh_node_ttl_info_t *ttl_evt)
579 {
580         GVariant *out_var = NULL, *param = NULL;
581         GArray *info = NULL;
582
583         if (BLUETOOTH_ERROR_NONE == result) {
584                 /* Send event */
585                 info = g_array_new(FALSE, FALSE, sizeof(gchar));
586                 g_array_append_vals(info, ttl_evt,
587                         sizeof(bluetooth_mesh_node_ttl_info_t));
588
589                 out_var = g_variant_new_from_data((const GVariantType *)"ay",
590                                 info->data, info->len,
591                                 TRUE, NULL, NULL);
592
593                 param = g_variant_new("(iv)", result, out_var);
594                 _bt_send_event(BT_MESH_EVENT,
595                                 BLUETOOTH_EVENT_MESH_NODE_TTL_CONFIGURED,
596                                 param);
597         }
598 }
599
600 static void __bt_mesh_send_node_key_configuration_event(int result,
601                 bluetooth_mesh_key_configure_t *key_evt)
602 {
603         GVariant *out_var = NULL, *param = NULL;
604         GArray *info = NULL;
605
606         if (BLUETOOTH_ERROR_NONE == result) {
607                 /* Send event */
608                 info = g_array_new(FALSE, FALSE, sizeof(gchar));
609                 g_array_append_vals(info, key_evt,
610                         sizeof(bluetooth_mesh_key_configure_t));
611
612                 out_var = g_variant_new_from_data((const GVariantType *)"ay",
613                                 info->data, info->len,
614                                 TRUE, NULL, NULL);
615
616                 param = g_variant_new("(iv)", result, out_var);
617                 _bt_send_event(BT_MESH_EVENT,
618                                 BLUETOOTH_EVENT_MESH_NODE_KEY_CONFIGURED,
619                                 param);
620         }
621 }
622
623 static void __bt_mesh_send_node_get_vendor_features_event(int result,
624                 bluetooth_mesh_node_features_t *features_evt)
625 {
626         GVariant *out_var = NULL, *param = NULL;
627         GArray *info = NULL;
628
629         if (BLUETOOTH_ERROR_NONE == result) {
630                 /* Send event */
631                 info = g_array_new(FALSE, FALSE, sizeof(gchar));
632                 g_array_append_vals(info, features_evt,
633                                 sizeof(bluetooth_mesh_node_features_t));
634
635                 out_var = g_variant_new_from_data((const GVariantType *)"ay",
636                                 info->data, info->len,
637                                 TRUE, NULL, NULL);
638
639                 param = g_variant_new("(iv)", result, out_var);
640                 _bt_send_event(BT_MESH_EVENT,
641                                 BLUETOOTH_EVENT_MESH_NODE_VENDOR_FEATURES,
642                                 param);
643         }
644 }
645
646 static void __bt_mesh_send_node_browsed_event(int result,
647                 bluetooth_mesh_node_discover_t *browse_evt)
648 {
649         GVariant *out_var = NULL, *param = NULL;
650         GArray *info = NULL;
651
652         if (BLUETOOTH_ERROR_NONE == result) {
653                 /* Send event */
654                 info = g_array_new(FALSE, FALSE, sizeof(gchar));
655                 g_array_append_vals(info, browse_evt,
656                                 sizeof(bluetooth_mesh_node_discover_t));
657
658                 out_var = g_variant_new_from_data((const GVariantType *)"ay",
659                                 info->data, info->len,
660                                 TRUE, NULL, NULL);
661
662                 param = g_variant_new("(iv)", result, out_var);
663                 _bt_send_event(BT_MESH_EVENT,
664                                 BLUETOOTH_EVENT_MESH_NODE_BROWSED,
665                                 param);
666         }
667 }
668
669 static void __bt_mesh_handle_pending_dev_config_request_info(int result,
670                 int service_function, void *param, unsigned int size)
671 {
672         GSList *l;
673         GArray *out_param;
674         invocation_info_t *req_info = NULL;
675
676         for (l = _bt_get_invocation_list(); l != NULL; ) {
677                 req_info = l->data;
678                 l = g_slist_next(l);
679                 if (req_info == NULL ||
680                                 req_info->service_function != service_function)
681                         continue;
682
683                 switch (service_function) {
684                 case BT_MESH_NODE_GET_VENDOR_FEATURES: {
685                         bluetooth_mesh_node_features_t *event;
686                         bluetooth_mesh_node_features_t *req;
687
688                         event = (bluetooth_mesh_node_features_t*) param;
689                         req = (bluetooth_mesh_node_features_t*)req_info->user_data;
690
691                         BT_DBG("Request Sender: [%s]", req_info->sender);
692                         /* Match Network and Remote Node unicast*/
693                         if (!g_strcmp0(event->net_uuid, req->net_uuid) && event->unicast == req->unicast) {
694                                 event->unicast = req->unicast;
695                                 event->elem_count = req->elem_count;
696
697                                 /* Send Event */
698                                 __bt_mesh_send_node_get_vendor_features_event(result, event);
699
700                                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
701                                 g_array_append_vals(out_param, event, sizeof(bluetooth_mesh_node_features_t));
702
703                                 /* Return DBUS Invocation*/
704                                 _bt_service_method_return(req_info->context, out_param, result);
705                                 _bt_free_info_from_invocation_list(req_info);
706                                 g_array_free(out_param, TRUE);
707                         }
708                         break;
709                 }
710                 case BT_MESH_NODE_BROWSE: {
711                         bluetooth_mesh_node_discover_t *node;
712                         event_mesh_devkey_message_t *event;
713                         uint16_t remote_addr;
714                         uint8_t elem_count;
715                         uint8_t dev_uuid[16];
716                         char net_uuid[BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1];
717
718                         event = (event_mesh_devkey_message_t*) param;
719                         node = (bluetooth_mesh_node_discover_t*)req_info->user_data;
720                         BT_INFO("Mesh: Request Node UUID [%s]", node->dev_uuid);
721                         BT_INFO("Mesh: Request Network UUID [%s]", node->net_uuid);
722
723                         _bt_mesh_util_convert_hex_to_string((uint8_t *) event->net_uuid.uuid, 16, net_uuid,
724                                         BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
725
726                         _bt_mesh_util_convert_string_to_hex(node->dev_uuid, strlen(node->dev_uuid), dev_uuid, 16);
727
728                         /* Get Unicast from pending request's Dev UUID and match with event */
729                         if (_bt_mesh_node_get_unicast_from_dev_uuid(event->net_uuid.uuid, dev_uuid, &remote_addr)) {
730
731                                 BT_DBG("Request Sender: [%s]", req_info->sender);
732                                 /* Match Network and Remote Node unicast*/
733                                 if (!g_strcmp0(node->net_uuid, net_uuid) && remote_addr == event->source) {
734                                         _bt_mesh_node_get_element_count(event->net_uuid.uuid, remote_addr, &elem_count);
735                                         node->unicast = event->source;
736                                         node->count = elem_count;
737                                         /* Send Event */
738                                         __bt_mesh_send_node_browsed_event(result, node);
739
740                                         out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
741                                         g_array_append_vals(out_param, node, sizeof(bluetooth_mesh_node_discover_t));
742
743                                         /* Return DBUS Invocation*/
744                                         _bt_service_method_return(req_info->context, out_param, result);
745                                         _bt_free_info_from_invocation_list(req_info);
746                                         g_array_free(out_param, TRUE);
747
748                                 }
749                         }
750                         break;
751                 }
752                 case BT_MESH_NODE_CONFIGURE_KEY: {
753                         bluetooth_mesh_key_configure_t *event;
754                         bluetooth_mesh_key_configure_t *req;
755
756                         event = (bluetooth_mesh_key_configure_t*) param;
757                         req = (bluetooth_mesh_key_configure_t*)req_info->user_data;
758
759                         if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
760                                 req->primary_unicast == event->primary_unicast &&
761                                 req->is_netkey == event->is_netkey) {
762                                 /* Send Event */
763                                 __bt_mesh_send_node_key_configuration_event(result, event);
764
765                                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
766                                 g_array_append_vals(out_param, event, sizeof(bluetooth_mesh_key_configure_t));
767
768                                 /* Return DBUS Invocation*/
769                                 _bt_service_method_return(req_info->context, out_param, result);
770                                 _bt_free_info_from_invocation_list(req_info);
771                                 g_array_free(out_param, TRUE);
772                         }
773                         break;
774                 }
775                 case BT_MESH_NODE_TTL_EXECUTE: {
776                         bluetooth_mesh_node_ttl_info_t *event;
777                         bluetooth_mesh_node_ttl_info_t *req;
778
779                         event = (bluetooth_mesh_node_ttl_info_t*) param;
780                         req = (bluetooth_mesh_node_ttl_info_t*)req_info->user_data;
781                         req->ttl = event->ttl;
782
783                         if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
784                                 req->unicast == event->unicast) {
785                                 /* Send Event */
786                                 __bt_mesh_send_node_ttl_configuration_event(result, req);
787
788                                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
789                                 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_node_ttl_info_t));
790
791                                 /* Return DBUS Invocation*/
792                                 _bt_service_method_return(req_info->context, out_param, result);
793                                 _bt_free_info_from_invocation_list(req_info);
794                                 g_array_free(out_param, TRUE);
795                         }
796                         break;
797                 }
798                 case BT_MESH_MODEL_CONFIGURE_APPKEY: {
799                         bluetooth_mesh_model_configure_t *event;
800                         bluetooth_mesh_model_configure_t *req;
801
802                         event = (bluetooth_mesh_model_configure_t*) param;
803                         req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
804
805                         if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
806                                 req->primary_unicast == event->primary_unicast) {
807                                 /* Send Event */
808                                 __bt_mesh_send_model_configure_appkey_event(result, req);
809
810                                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
811                                 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_model_configure_t));
812
813                                 /* Return DBUS Invocation*/
814                                 _bt_service_method_return(req_info->context, out_param, result);
815                                 _bt_free_info_from_invocation_list(req_info);
816                                 g_array_free(out_param, TRUE);
817                         }
818
819                         break;
820                 }
821                 case BT_MESH_MODEL_GET_APPKEY_LIST: {
822                         bluetooth_mesh_model_configure_t *event;
823                         bluetooth_mesh_model_configure_t *req;
824
825                         event = (bluetooth_mesh_model_configure_t*) param;
826                         req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
827
828                         if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
829                                 req->primary_unicast == event->primary_unicast) {
830                                 /* Send Event */
831                                 __bt_mesh_send_model_get_appkey_list_event(result, event);
832
833                                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
834                                 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_model_configure_t));
835
836                                 /* Return DBUS Invocation*/
837                                 _bt_service_method_return(req_info->context, out_param, result);
838                                 _bt_free_info_from_invocation_list(req_info);
839                                 g_array_free(out_param, TRUE);
840                         }
841                         break;
842                 }
843                 case BT_MESH_MODEL_GET_SUBSCRIPTION_LIST: {
844                         bluetooth_mesh_model_configure_t *event;
845                         bluetooth_mesh_model_configure_t *req;
846
847                         event = (bluetooth_mesh_model_configure_t*) param;
848                         req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
849
850                         if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
851                                 req->primary_unicast == event->primary_unicast) {
852                                 /* Send Event */
853                                 __bt_mesh_send_model_get_subscription_list_event(result, event);
854
855                                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
856                                 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_model_configure_t));
857
858                                 /* Return DBUS Invocation*/
859                                 _bt_service_method_return(req_info->context, out_param, result);
860                                 _bt_free_info_from_invocation_list(req_info);
861                                 g_array_free(out_param, TRUE);
862                         }
863                         break;
864                 }
865                 case BT_MESH_MODEL_CONFIG_GROUP_SUB: {
866                         bluetooth_mesh_model_configure_t *event;
867                         bluetooth_mesh_model_configure_t *req;
868
869                         event = (bluetooth_mesh_model_configure_t*) param;
870                         req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
871
872                         if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
873                                 req->primary_unicast == event->primary_unicast) {
874
875                                 req->sub_addr = event->sub_addr;
876                                 /* Send Event */
877                                 __bt_mesh_send_model_subscription_configure_event(
878                                         BLUETOOTH_EVENT_MESH_MODEL_SUBSCRIPTION_CONFGURED,
879                                                 result, req);
880
881                                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
882                                 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_model_configure_t));
883
884                                 /* Return DBUS Invocation*/
885                                 _bt_service_method_return(req_info->context, out_param, result);
886                                 _bt_free_info_from_invocation_list(req_info);
887                                 g_array_free(out_param, TRUE);
888                         }
889                         break;
890                 }
891                 case BT_MESH_MODEL_CONFIG_VIRTUAL_GROUP_SUB: {
892                         bluetooth_mesh_model_configure_t *event;
893                         bluetooth_mesh_model_configure_t *req;
894
895                         event = (bluetooth_mesh_model_configure_t*) param;
896                         req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
897
898                         if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
899                                 req->primary_unicast == event->primary_unicast) {
900                                 /* Send Event */
901                                 __bt_mesh_send_model_subscription_configure_event( \
902                                         BLUETOOTH_EVENT_MESH_MODEL_VIRTUAL_SUBSCRIPTION_CONFGURED, \
903                                                 result, req);
904
905                                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
906                                 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_model_configure_t));
907
908                                 /* Return DBUS Invocation*/
909                                 _bt_service_method_return(req_info->context, out_param, result);
910                                 _bt_free_info_from_invocation_list(req_info);
911                                 g_array_free(out_param, TRUE);
912
913                         }
914                         break;
915                 }
916                 case BT_MESH_MODEL_GET_PUBLICATION: {
917                         bluetooth_mesh_model_configure_t *event;
918                         bluetooth_mesh_model_configure_t *req;
919
920                         event = (bluetooth_mesh_model_configure_t*) param;
921                         req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
922
923                         if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
924                                         req->primary_unicast == event->primary_unicast) {
925                                 /* Send Event */
926                                 __bt_mesh_send_model_publication_status_event( \
927                                                 BLUETOOTH_EVENT_MESH_MODEL_PUBLICATION_STATUS, \
928                                                 result, event);
929
930                                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
931                                 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_model_configure_t));
932
933                                 /* Return DBUS Invocation*/
934                                 _bt_service_method_return(req_info->context, out_param, result);
935                                 _bt_free_info_from_invocation_list(req_info);
936                                 g_array_free(out_param, TRUE);
937                         }
938                         break;
939                 }
940                 case BT_MESH_MODEL_SET_PUBLICATION: {
941                         bluetooth_mesh_model_configure_t *event;
942                         bluetooth_mesh_model_configure_t *req;
943
944                         event = (bluetooth_mesh_model_configure_t*) param;
945                         req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
946
947                         if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
948                                 req->primary_unicast == event->primary_unicast) {
949                                 /* Send Event */
950                                 __bt_mesh_send_model_publication_status_event( \
951                                         BLUETOOTH_EVENT_MESH_MODEL_PUBLICATION_STATUS, \
952                                                 result, req);
953
954                                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
955                                 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_model_configure_t));
956
957                                 /* Return DBUS Invocation*/
958                                 _bt_service_method_return(req_info->context, out_param, result);
959                                 _bt_free_info_from_invocation_list(req_info);
960                                 g_array_free(out_param, TRUE);
961                         }
962                         break;
963                 }
964                 default:
965                         BT_DBG("Unknown function(%d)", service_function);
966                         break;
967                 }
968         }
969 }
970
971 const char *__mesh_status_to_string(uint8_t err)
972 {
973         switch (err) {
974         case MESH_STATUS_SUCCESS: return "Success";
975         case MESH_STATUS_INVALID_ADDRESS: return "Invalid Address";
976         case MESH_STATUS_INVALID_MODEL: return "Invalid Model";
977         case MESH_STATUS_INVALID_APPKEY: return "Invalid AppKey";
978         case MESH_STATUS_INVALID_NETKEY: return "Invalid NetKey";
979         case MESH_STATUS_INSUFF_RESOURCES: return "Insufficient Resources";
980         case MESH_STATUS_IDX_ALREADY_STORED: return "Key Idx Already Stored";
981         case MESH_STATUS_INVALID_PUB_PARAM: return "Invalid Publish Parameters";
982         case MESH_STATUS_NOT_SUB_MOD: return "Not a Subscribe Model";
983         case MESH_STATUS_STORAGE_FAIL: return "Storage Failure";
984         case MESH_STATUS_FEATURE_NO_SUPPORT: return "Feature Not Supported";
985         case MESH_STATUS_CANNOT_UPDATE: return "Cannot Update";
986         case MESH_STATUS_CANNOT_REMOVE: return "Cannot Remove";
987         case MESH_STATUS_CANNOT_BIND: return "Cannot bind";
988         case MESH_STATUS_UNABLE_CHANGE_STATE: return "Unable to change state";
989         case MESH_STATUS_CANNOT_SET: return "Cannot set";
990         case MESH_STATUS_UNSPECIFIED_ERROR: return "Unspecified error";
991         case MESH_STATUS_INVALID_BINDING: return "Invalid Binding";
992
993         default: return "Unknown";
994         }
995 }
996
997 static void __mesh_handle_model_subscription_event(int result,
998                 bluetooth_mesh_model_configure_t *param,
999                         const struct mesh_config_cmd *cmd)
1000 {
1001         switch (cmd->opcode) {
1002         /* Fall through */
1003         case MESH_OPCODE_CONFIG_MODEL_SUB_ADD:
1004         case MESH_OPCODE_CONFIG_MODEL_SUB_DELETE:
1005         case MESH_OPCODE_CONFIG_MODEL_SUB_OVERWRITE:
1006         case MESH_OPCODE_CONFIG_MODEL_SUB_DELETE_ALL:
1007                 /* Model Bind/UnBind Event */
1008         __bt_mesh_handle_pending_dev_config_request_info(result,
1009                         BT_MESH_MODEL_CONFIG_GROUP_SUB, &param,
1010                                 sizeof(bluetooth_mesh_model_configure_t));
1011                 break;
1012         case MESH_OPCODE_CONFIG_MODEL_SUB_VIRT_ADD:
1013         case MESH_OPCODE_CONFIG_MODEL_SUB_VIRT_DELETE:
1014         case MESH_OPCODE_CONFIG_MODEL_SUB_VIRT_OVERWRITE:
1015         __bt_mesh_handle_pending_dev_config_request_info(result,
1016                         BT_MESH_MODEL_CONFIG_VIRTUAL_GROUP_SUB, &param,
1017                                 sizeof(bluetooth_mesh_model_configure_t));
1018                 break;
1019         default:
1020                 break;
1021         }
1022 }
1023
1024 void _bt_mesh_config_client_devkey_msg_handler(
1025                 event_mesh_devkey_message_t *event)
1026 {
1027         uint32_t opcode;
1028         const struct mesh_config_cmd *cmd;
1029         uint16_t data_len = event->data_len;
1030         uint8_t *data = event->data;
1031         int result = BLUETOOTH_ERROR_NONE;
1032         uint16_t app_idx;
1033         uint16_t addr;
1034         uint16_t net_idx;
1035         uint16_t elem_addr;
1036         uint16_t ele_addr;
1037         uint32_t mod_id;
1038         int n;
1039         struct mesh_pending_request *req;
1040
1041         if (_bt_mesh_util_opcode_get(data, data_len, &opcode, &n)) {
1042                 BT_INFO("Mesh: Opcode of response data [0x%2.2x], actual data len [%d]", opcode, n);
1043                 data_len -= n;
1044                 data += n;
1045         } else
1046                 return;
1047
1048         BT_INFO("Mesh: Received %s (len %u) opcode [0x%2.2x]",
1049                 __mesh_get_opcode_string(opcode), data_len, opcode);
1050
1051         req = __bt_mesh_get_request_by_response(event->source,
1052                 event->net_uuid.uuid, (opcode & ~MESH_OPCODE_UNRELIABLE));
1053         if (req) {
1054                 BT_INFO("Mesh: Got Config Request");
1055                 cmd = req->cmd;
1056                 __mesh_request_remove(req);
1057                 l_queue_remove(pending_requests, req);
1058         } else
1059                 cmd = NULL;
1060
1061
1062         switch (opcode & ~MESH_OPCODE_UNRELIABLE) {
1063                 default:
1064                         return;
1065         case MESH_OPCODE_CONFIG_MODEL_PUB_STATUS: {
1066                 if (data_len != 12 && data_len != 14)
1067                         break;
1068                 bluetooth_mesh_model_configure_t param;
1069                 memset(&param, 0x00, sizeof(bluetooth_mesh_model_configure_t));
1070
1071                 _bt_mesh_util_convert_hex_to_string((uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1072                                 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1073
1074                 BT_INFO("\nNode %4.4x Model Publication status %s\n",
1075                                 event->source, __mesh_status_to_string(data[0]));
1076
1077                 if (data[0] != MESH_STATUS_SUCCESS)
1078                         break;
1079
1080                 /* Extract Element Address */
1081                 ele_addr = l_get_le16(data + 1);
1082
1083                 /* Extract Model ID */
1084                 if (data_len == 14) {
1085                         /* vendor Model */
1086                         mod_id = l_get_le16(data + 10 + 2);
1087                         mod_id = l_get_le16(data) << 16 | mod_id;
1088                 } else {
1089                         /* BT SIG Model */
1090                         mod_id = l_get_le16(data + 10);
1091                         mod_id = MESH_VENDOR_ID_MASK | mod_id;
1092                 }
1093
1094                 param.primary_unicast = event->source;
1095                 param.elem_index = ele_addr - event->source;
1096                 /* Extract Publish Address */
1097                 param.pub_addr = l_get_le16(data + 3);
1098
1099                 /* Extract Appkey Index */
1100                 param.appkey_idx =  l_get_le16(data + 5);
1101
1102                 /* Extract TTL */
1103                 param.ttl = data[6];
1104
1105                 /* Extract Period */
1106                 param.period = data[7];
1107                 if (!cmd)
1108                         break;
1109
1110                 if (cmd->opcode == MESH_OPCODE_CONFIG_MODEL_PUB_GET)
1111                         __bt_mesh_handle_pending_dev_config_request_info(result,
1112                                 BT_MESH_MODEL_GET_PUBLICATION, &param,
1113                                 sizeof(bluetooth_mesh_model_configure_t));
1114                 else
1115                         __bt_mesh_handle_pending_dev_config_request_info(result,
1116                                 BT_MESH_MODEL_SET_PUBLICATION, &param,
1117                                 sizeof(bluetooth_mesh_model_configure_t));
1118                 break;
1119         }
1120         case MESH_OPCODE_CONFIG_MODEL_SUB_STATUS: {
1121                 if (data_len != 7 && data_len != 9)
1122                         break;
1123                 bluetooth_mesh_model_configure_t param;
1124                 memset(&param, 0x00, sizeof(bluetooth_mesh_model_configure_t));
1125
1126                 _bt_mesh_util_convert_hex_to_string(
1127                         (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1128                                 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1129
1130                 BT_INFO("\nNode %4.4x Subscription status %s\n",
1131                                 event->source, __mesh_status_to_string(data[0]));
1132
1133                 ele_addr = l_get_le16(data + 1);
1134                 addr = l_get_le16(data + 3);
1135                 BT_INFO("Element Addr\t%4.4x\n", ele_addr);
1136
1137                 if (data_len == 9) {
1138                         /* vendor Model */
1139                         mod_id = l_get_le16(data + 5 + 2);
1140                         mod_id = l_get_le16(data) << 16 | mod_id;
1141                 } else {
1142                         /* BT SIG Model */
1143                         mod_id = l_get_le16(data + 5);
1144                         mod_id = MESH_VENDOR_ID_MASK | mod_id;
1145                 }
1146
1147                 param.primary_unicast = event->source;
1148                 param.elem_index = ele_addr - event->source;
1149                 /* Subscription address, unassigned address in case of Delete All command */
1150                 param.sub_addr = addr;
1151                 param.model = mod_id;
1152                 BT_INFO("Subscr Addr\t%4.4x\n", addr);
1153
1154                 if (cmd)
1155                         __mesh_handle_model_subscription_event(result, &param, cmd);
1156
1157                 break;
1158         }
1159         case MESH_OPCODE_CONFIG_DEFAULT_TTL_STATUS: {
1160                 if (data_len != 1)
1161                         break;
1162                 bluetooth_mesh_node_ttl_info_t param;
1163                 memset(&param, 0x00, sizeof(bluetooth_mesh_node_ttl_info_t));
1164
1165                 BT_INFO("Node %4.4x Default TTL %d", event->source, data[0]);
1166                  _bt_mesh_util_convert_hex_to_string(
1167                         (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1168                                 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1169                 param.unicast = event->source;
1170                 param.ttl = data[0];
1171
1172                 if (!_bt_mesh_network_save_remote_node_ttl(event->net_uuid.uuid,
1173                                 event->source,  data[0])) {
1174                         result = BLUETOOTH_ERROR_INTERNAL;
1175                         BT_INFO("Failed to save node TTL");
1176                 }
1177
1178                 /* Remote Node TTL event */
1179                 __bt_mesh_handle_pending_dev_config_request_info(result,
1180                         BT_MESH_NODE_TTL_EXECUTE, &param,
1181                                 sizeof(bluetooth_mesh_node_ttl_info_t));
1182                 break;
1183         }
1184         case MESH_OPCODE_MODEL_APP_STATUS: {
1185                 if (data_len != 7 && data_len != 9)
1186                         break;
1187                 bluetooth_mesh_model_configure_t param;
1188                 memset(&param, 0x00, sizeof(bluetooth_mesh_model_configure_t));
1189
1190                  _bt_mesh_util_convert_hex_to_string(
1191                         (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1192                                 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1193                 BT_INFO("Node %4.4x: Model App status %s\n", event->source,
1194                         __mesh_status_to_string(data[0]));
1195                 elem_addr = l_get_le16(data + 1);
1196                 app_idx = l_get_le16(data + 3);
1197
1198                 BT_INFO("Element Addr\t%4.4x", elem_addr);
1199                 if (data_len == 9) {
1200                         /* vendor Model */
1201                         mod_id = l_get_le16(data + 5 + 2);
1202                         mod_id = l_get_le16(data) << 16 | mod_id;
1203                 } else {
1204                         /* BT SIG Model */
1205                         mod_id = l_get_le16(data + 5);
1206                         mod_id = MESH_VENDOR_ID_MASK | mod_id;
1207                 }
1208
1209                 param.primary_unicast = event->source;
1210                 param.elem_index = elem_addr - event->source;
1211                 param.appkey_idx = app_idx;
1212                 param.model = mod_id;
1213                 BT_INFO("AppIdx\t\t%u (0x%3.3x)\n ", app_idx, app_idx);
1214
1215                 /* Model Bind/UnBind Event */
1216                 __bt_mesh_handle_pending_dev_config_request_info(result,
1217                         BT_MESH_MODEL_CONFIGURE_APPKEY, &param,
1218                                 sizeof(bluetooth_mesh_model_configure_t));
1219                 break;
1220         }
1221         case MESH_OPCODE_MODEL_APP_LIST: {
1222                 if (data_len < 5)
1223                         break;
1224                 GArray *garray;
1225                 int total = 0;
1226                 bluetooth_mesh_model_configure_t param;
1227                 memset(&param, 0x00, sizeof(bluetooth_mesh_model_configure_t));
1228
1229                 _bt_mesh_util_convert_hex_to_string(
1230                         (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1231                                 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1232
1233                 garray = g_array_new(FALSE, FALSE, sizeof(gchar));
1234
1235                 BT_INFO("\nNode %4.4x Model AppIdx status %s\n",
1236                                 event->source, __mesh_status_to_string(data[0]));
1237
1238                 BT_INFO("Element Addr\t%4.4x\n", l_get_le16(data + 1));
1239                 BT_INFO("Model ID\t%4.4x\n", l_get_le16(data + 3));
1240
1241                 elem_addr = l_get_le16(data + 1);
1242                 /* BT SIG Model */
1243                 mod_id = l_get_le16(data + 3);
1244                 mod_id = MESH_VENDOR_ID_MASK | mod_id;
1245
1246                 param.primary_unicast = event->source;
1247                 param.elem_index = elem_addr - event->source;
1248                 param.model = mod_id;
1249
1250                 data += 5;
1251                 data_len -= 5;
1252
1253                 while (data_len >= 3) {
1254                         app_idx = l_get_le16(data) & 0xfff;
1255                         g_array_append_vals(garray, &app_idx, sizeof(uint16_t));
1256                         BT_INFO("\t%u (0x%3.3x)\n", app_idx, app_idx);
1257
1258                         app_idx = l_get_le16(data + 1) >> 4;
1259                         g_array_append_vals(garray, &app_idx, sizeof(uint16_t));
1260                         BT_INFO("\t%u (0x%3.3x)\n", app_idx, app_idx);
1261                         data += 3;
1262                         data_len -= 3;
1263                 }
1264
1265                 if (data_len == 2) {
1266                         app_idx = l_get_le16(data) & 0xfff;
1267                         g_array_append_vals(garray, &app_idx, sizeof(uint16_t));
1268                         BT_INFO("\t %u (0x%3.3x)\n", app_idx, app_idx);
1269                 }
1270                 total = garray->len / sizeof(uint16_t);
1271                 param.appkey_list = (uint16_t **)g_malloc0(sizeof(uint16_t*) * garray->len);
1272                 param.appkeylist_count = total;
1273                 for (int i = 0; i < total; i++) {
1274                         param.appkey_list[i] = g_malloc(sizeof(uint16_t));
1275                         *param.appkey_list[i] = g_array_index(garray, uint16_t, i);
1276                 }
1277                 g_array_free(garray, TRUE);
1278
1279                 __bt_mesh_handle_pending_dev_config_request_info(result,
1280                         BT_MESH_MODEL_GET_APPKEY_LIST, &param,
1281                                 sizeof(bluetooth_mesh_model_configure_t));
1282                 break;
1283         }
1284         case MESH_OPCODE_CONFIG_MODEL_SUB_LIST: {
1285                 if (data_len < 5)
1286                         break;
1287                 int total = 0;
1288                 int i = 0;
1289                 bluetooth_mesh_model_configure_t param;
1290                 memset(&param, 0x00, sizeof(bluetooth_mesh_model_configure_t));
1291
1292                 _bt_mesh_util_convert_hex_to_string((uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1293                                 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1294
1295                 BT_INFO("\nNode %4.4x BT SIG Model Subscription List status %s\n",
1296                                 event->source, __mesh_status_to_string(data[0]));
1297
1298                 BT_INFO("Element Addr\t%4.4x\n", l_get_le16(data + 1));
1299                 elem_addr = l_get_le16(data + 1);
1300
1301                 /* BT SIG Model */
1302                 mod_id = l_get_le16(data + 3);
1303                 mod_id = MESH_VENDOR_ID_MASK | mod_id;
1304                 BT_INFO("Model ID\t%4.4x\n", mod_id);
1305
1306                 param.primary_unicast = event->source;
1307                 param.elem_index = elem_addr - event->source;
1308                 param.model = mod_id;
1309
1310                 total = data_len -  5;
1311                 param.sublist_count = total;
1312                 if (total) {
1313                         param.sub_list = (uint16_t **)g_malloc0(sizeof(uint16_t*) * total);
1314
1315                         i = 5;
1316                         for (; i < data_len; i += 2) {
1317                                 BT_INFO("Subscription Addr \t\t%4.4x\n ", l_get_le16(data + i));
1318                                 param.sub_list[i] = g_malloc(sizeof(uint16_t));
1319                                 *param.sub_list[i] = l_get_le16(data + i);
1320                         }
1321                 }
1322                 __bt_mesh_handle_pending_dev_config_request_info(result,
1323                         BT_MESH_MODEL_GET_SUBSCRIPTION_LIST, &param,
1324                                 sizeof(bluetooth_mesh_model_configure_t));
1325                 break;
1326         }
1327         case MESH_OPCODE_CONFIG_VEND_MODEL_SUB_LIST: {
1328                 if (data_len < 7)
1329                         break;
1330                 int total = 0;
1331                 int i = 0;
1332                 bluetooth_mesh_model_configure_t param;
1333                 memset(&param, 0x00, sizeof(bluetooth_mesh_model_configure_t));
1334
1335                 _bt_mesh_util_convert_hex_to_string(
1336                         (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1337                                 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1338
1339                 BT_INFO("\nNode %4.4x BT SIG Model Subscription List status %s\n",
1340                                 event->source, __mesh_status_to_string(data[0]));
1341
1342                 BT_INFO("Element Addr\t%4.4x\n", l_get_le16(data + 1));
1343                 elem_addr = l_get_le16(data + 1);
1344
1345                 /* VENDOR Model */
1346                 mod_id = l_get_le16(data + 5);
1347                 mod_id = l_get_le16(data + 3) << 16 | mod_id;
1348
1349                 BT_INFO("Model ID\t%4.4x\n", mod_id);
1350
1351                 param.primary_unicast = event->source;
1352                 param.elem_index = elem_addr - event->source;
1353                 param.model = mod_id;
1354
1355                 total = data_len -  7;
1356                 param.sublist_count = total;
1357                 if (total) {
1358                         param.sub_list = (uint16_t **)g_malloc0(sizeof(uint16_t*) * total);
1359
1360                         i = 7;
1361                         for (; i < data_len; i += 2) {
1362                                 BT_INFO("Subscription Addr \t\t%4.4x\n ", l_get_le16(data + i));
1363                                 param.sub_list[i] = g_malloc(sizeof(uint16_t));
1364                                 *param.sub_list[i] = l_get_le16(data + i);
1365                         }
1366                 }
1367                 __bt_mesh_handle_pending_dev_config_request_info(result,
1368                         BT_MESH_MODEL_GET_SUBSCRIPTION_LIST, &param,
1369                                 sizeof(bluetooth_mesh_model_configure_t));
1370                 break;
1371         }
1372         case MESH_OPCODE_DEV_COMP_STATUS: {
1373                 if (data_len < MESH_MINIMUM_COMPOSITION_LEN)
1374                         break;
1375                 bluetooth_mesh_node_features_t features;
1376                 memset(&features, 0x00, sizeof(bluetooth_mesh_node_features_t));
1377                 BT_INFO("Mesh: Got Response for Device Composition Data");
1378                 __bt_mesh_print_device_composition_data(data, data_len);
1379
1380                 if (!_bt_mesh_network_save_remote_node_composition(
1381                         event->net_uuid.uuid, event->source, data, data_len)) {
1382                         result = BLUETOOTH_ERROR_INTERNAL;
1383                         BT_INFO("Failed to save node composition!");
1384                 }
1385                 /* Browse Remote Node event */
1386                 __bt_mesh_handle_pending_dev_config_request_info(result,
1387                         BT_MESH_NODE_BROWSE, event, sizeof(event_mesh_devkey_message_t));
1388
1389                 /* Vendor Features Discover event */
1390                 _bt_mesh_util_convert_hex_to_string(
1391                         (uint8_t *) event->net_uuid.uuid, 16, features.net_uuid,
1392                                 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1393                 features.unicast = event->source;
1394                 _bt_mesh_node_get_vendor_features(event->net_uuid.uuid,
1395                         event->source, &features);
1396
1397                 __bt_mesh_handle_pending_dev_config_request_info(result,
1398                         BT_MESH_NODE_GET_VENDOR_FEATURES, &features,
1399                                 sizeof(bluetooth_mesh_node_features_t));
1400                 break;
1401         }
1402         case MESH_OPCODE_NETKEY_STATUS: {
1403                 if (data_len != 3)
1404                         break;
1405
1406                 bluetooth_mesh_key_configure_t param;
1407                 memset(&param, 0x00, sizeof(bluetooth_mesh_key_configure_t));
1408
1409                 BT_INFO("Mesh: Node %4.4x NetKey status %s",
1410                         event->source,  __mesh_status_to_string(data[0]));
1411                 net_idx = l_get_le16(data + 1) & 0xfff;
1412
1413                 BT_INFO("\tNetKey %u (0x%3.3x)", net_idx, net_idx);
1414
1415                 if (data[0] != 0)
1416                         break;
1417
1418                 if (!cmd)
1419                         break;
1420
1421                 _bt_mesh_util_convert_hex_to_string(
1422                         (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1423                                 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1424                 param.primary_unicast = event->source;
1425                 param.netkey_idx = net_idx;
1426                 param.is_netkey = true;
1427
1428                 if (cmd->opcode == MESH_OPCODE_NETKEY_ADD) {
1429                         BT_INFO("Mesh: Resp recvd: MESH_OPCODE_NETKEY_ADD");
1430                         if (!_bt_mesh_network_save_remote_node_netkey(
1431                                         event->net_uuid.uuid, event->source, net_idx)) {
1432                                 result = BLUETOOTH_ERROR_INTERNAL;
1433                                 BT_INFO("Failed to save node Netkey!");
1434                         }
1435                         param.op = BLUETOOTH_MESH_NODE_KEY_ADD;
1436                 } else if (cmd->opcode == MESH_OPCODE_NETKEY_DELETE) {
1437                         if (!_bt_mesh_network_delete_remote_node_netkey(
1438                                         event->net_uuid.uuid, event->source, net_idx)) {
1439                                 result = BLUETOOTH_ERROR_INTERNAL;
1440                                 BT_INFO("Failed to delete node Netkey!");
1441                         }
1442                         param.op = BLUETOOTH_MESH_NODE_KEY_DELETE;
1443                 } else if (cmd->opcode == MESH_OPCODE_NETKEY_UPDATE) {
1444                         BT_INFO("Mesh: Resp recvd: MESH_OPCODE_NETKEY_UPDATE");
1445                         param.op = BLUETOOTH_MESH_NODE_KEY_UPDATE;
1446                 }
1447                 /* Node Net Key Configure event */
1448                 __bt_mesh_handle_pending_dev_config_request_info(result,
1449                         BT_MESH_NODE_CONFIGURE_KEY,
1450                                 &param, sizeof(bluetooth_mesh_key_configure_t));
1451                 break;
1452         }
1453         case MESH_OPCODE_APPKEY_STATUS: {
1454                 if (data_len != 4)
1455                         break;
1456
1457                 bluetooth_mesh_key_configure_t param;
1458                 memset(&param, 0x00, sizeof(bluetooth_mesh_key_configure_t));
1459
1460                 BT_INFO("Mesh: Node %4.4x AppKey status %s\n", event->source,
1461                                 __mesh_status_to_string(data[0]));
1462                 net_idx = l_get_le16(data + 1) & 0xfff;
1463                 app_idx = l_get_le16(data + 2) >> 4;
1464
1465                 BT_INFO("NetKey\t%u (0x%3.3x)\n", net_idx, net_idx);
1466                 BT_INFO("AppKey\t%u (0x%3.3x)\n", app_idx, app_idx);
1467
1468                 if (data[0] != MESH_STATUS_SUCCESS)
1469                         break;
1470
1471                 if (!cmd)
1472                         break;
1473
1474                 _bt_mesh_util_convert_hex_to_string(
1475                         (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1476                                 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1477
1478                 param.primary_unicast = event->source;
1479                 param.netkey_idx = net_idx;
1480                 param.appkey_idx = app_idx;
1481                 param.is_netkey = false;
1482
1483                 if (cmd->opcode == MESH_OPCODE_APPKEY_ADD) {
1484                         BT_INFO("Mesh: Resp recvd: MESH_OPCODE_APPKEY_ADD");
1485                         if (!_bt_mesh_network_save_remote_node_appkey(
1486                                 event->net_uuid.uuid, event->source,
1487                                         net_idx, app_idx)) {
1488                                 result = BLUETOOTH_ERROR_INTERNAL;
1489                                 BT_INFO("Failed to save node Appkey!");
1490                         }
1491                         param.op = BLUETOOTH_MESH_NODE_KEY_ADD;
1492                 } else if (cmd->opcode == MESH_OPCODE_APPKEY_DELETE) {
1493                         BT_INFO("Mesh: Resp recvd: MESH_OPCODE_APPKEY_DELETE");
1494                         if (!_bt_mesh_network_delete_remote_node_appkey(
1495                                 event->net_uuid.uuid, event->source,
1496                                         net_idx, app_idx)) {
1497                                 result = BLUETOOTH_ERROR_INTERNAL;
1498                                 BT_INFO("Failed to delete node Appkey!");
1499                         }
1500                         param.op = BLUETOOTH_MESH_NODE_KEY_DELETE;
1501                 } else if (cmd->opcode == MESH_OPCODE_APPKEY_UPDATE) {
1502                         BT_INFO("Mesh: Resp recvd: MESH_OPCODE_APPKEY_UPDATE");
1503                         param.op = BLUETOOTH_MESH_NODE_KEY_UPDATE;
1504                 }
1505
1506                 /* Node App Key Configure event */
1507                 __bt_mesh_handle_pending_dev_config_request_info(result,
1508                         BT_MESH_NODE_CONFIGURE_KEY,
1509                                 &param, sizeof(bluetooth_mesh_key_configure_t));
1510                 break;
1511         }
1512         }
1513 }
1514
1515 static gboolean __bt_mesh_vendor_feature_event_handler(gpointer data)
1516 {
1517         bluetooth_mesh_node_features_t *result = (bluetooth_mesh_node_features_t*) data;
1518         __bt_mesh_handle_pending_dev_config_request_info(
1519                 BLUETOOTH_ERROR_NONE,
1520                         BT_MESH_NODE_GET_VENDOR_FEATURES,
1521                                 result, sizeof(bluetooth_mesh_node_features_t));
1522         g_free(result);
1523         return FALSE;
1524 }
1525
1526 int _bt_mesh_node_discover_vendor_features(const char *app_cred, const char *sender,
1527                 bluetooth_mesh_node_features_t *req)
1528 {
1529         int ret = OAL_STATUS_SUCCESS;
1530         uint16_t dest;
1531         uint16_t netkey_idx;
1532         uint16_t data_len;
1533         oal_uuid_t net_uuid;
1534         uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
1535
1536         _bt_mesh_util_convert_string_to_hex(req->net_uuid,
1537                         strlen(req->net_uuid), net_uuid.uuid, 16);
1538         /* Check if Node's vendor features are already svaed or not */
1539         if (_bt_mesh_node_get_vendor_features(net_uuid.uuid, req->unicast, req)) {
1540                 /* Schedule event ot Application */
1541                 bluetooth_mesh_node_features_t *event = \
1542                         g_memdup(req, sizeof(bluetooth_mesh_node_features_t));
1543                 g_idle_add(__bt_mesh_vendor_feature_event_handler, (gpointer) event);
1544                 return BLUETOOTH_ERROR_NONE;
1545         }
1546
1547         /* If Scanning is going on */
1548         if (_bt_mesh_is_provisioning() ||
1549                         _bt_mesh_is_scanning()) {
1550                 BT_ERR("Device is buzy..");
1551                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1552         }
1553
1554         _bt_mesh_util_convert_string_to_hex(req->net_uuid,
1555                         strlen(req->net_uuid), net_uuid.uuid, 16);
1556
1557         dest = req->unicast;
1558
1559         /* Check pending request */
1560         if (_bt_mesh_check_pending_request(MESH_OPCODE_DEV_COMP_GET,
1561                                 dest, net_uuid.uuid)) {
1562                 BT_ERR("Device is buzy..");
1563                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1564         }
1565
1566         /* Get Subnet index of the rmeote node for TX encryption */
1567         netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, dest);
1568         if (netkey_idx == MESH_NET_IDX_INVALID)
1569                 return BLUETOOTH_ERROR_INTERNAL;
1570
1571         data_len = _bt_mesh_util_opcode_set(MESH_OPCODE_DEV_COMP_GET,
1572                         buffer);
1573
1574         /* By default, use page 0 */
1575         buffer[data_len++] = 0;
1576         ret = mesh_conf_send_message(&net_uuid, dest, true,
1577                         netkey_idx, buffer, data_len);
1578
1579         if (ret != OAL_STATUS_SUCCESS) {
1580                 BT_ERR("ret: %d", ret);
1581                 return BLUETOOTH_ERROR_INTERNAL;
1582         }
1583
1584         /* Queue the request with timeout */
1585         __bt_mesh_add_request(MESH_OPCODE_DEV_COMP_GET,
1586                         dest, net_uuid.uuid, NULL);
1587         return BLUETOOTH_ERROR_NONE;
1588 }
1589
1590 int _bt_mesh_browse_remote_node(const char *app_cred,
1591         const char *sender,
1592                 bluetooth_mesh_node_discover_t *req)
1593 {
1594         int ret = OAL_STATUS_SUCCESS;
1595         uint16_t dest;
1596         uint16_t netkey_idx;
1597         uint16_t data_len;
1598         oal_uuid_t net_uuid;
1599         oal_uuid_t dev_uuid;
1600         uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
1601
1602         /* If Scanning is going on */
1603         if (_bt_mesh_is_provisioning() ||
1604                         _bt_mesh_is_scanning()) {
1605                 BT_ERR("Device is buzy..");
1606                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1607         }
1608
1609         _bt_mesh_util_convert_string_to_hex(req->net_uuid,
1610                 strlen(req->net_uuid), net_uuid.uuid, 16);
1611         _bt_mesh_util_convert_string_to_hex(req->dev_uuid,
1612                 strlen(req->dev_uuid), dev_uuid.uuid, 16);
1613
1614         BT_INFO("Mesh: Browse Node UUID [%s]", req->dev_uuid);
1615
1616         /* Get Remote Node unicast address from Dev UUID */
1617         if (!_bt_mesh_node_get_unicast_from_dev_uuid(net_uuid.uuid,
1618                         dev_uuid.uuid, &dest))
1619                 return BLUETOOTH_ERROR_INTERNAL;
1620
1621         /* Check pending request */
1622         if (_bt_mesh_check_pending_request(MESH_OPCODE_DEV_COMP_GET,
1623                         dest, net_uuid.uuid)) {
1624                 BT_ERR("Device is buzy..");
1625                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1626         }
1627
1628         /* Get Subnet index of the rmeote node for TX encryption */
1629         netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, dest);
1630         if (netkey_idx == MESH_NET_IDX_INVALID)
1631                 return BLUETOOTH_ERROR_INTERNAL;
1632
1633         data_len = _bt_mesh_util_opcode_set(MESH_OPCODE_DEV_COMP_GET, buffer);
1634
1635         /* By default, use page 0 */
1636         buffer[data_len++] = 0;
1637         ret = mesh_conf_send_message(&net_uuid, dest, true,
1638                         netkey_idx, buffer, data_len);
1639
1640         if (ret != OAL_STATUS_SUCCESS) {
1641                 BT_ERR("ret: %d", ret);
1642                 return BLUETOOTH_ERROR_INTERNAL;
1643         }
1644
1645         /* Queue the request with timeout */
1646         __bt_mesh_add_request(MESH_OPCODE_DEV_COMP_GET,
1647                         dest, net_uuid.uuid, NULL);
1648         return BLUETOOTH_ERROR_NONE;
1649 }
1650
1651 int _bt_mesh_model_configure_group_subscription(const char *app_cred,
1652                 const char *sender, bluetooth_mesh_model_configure_t *req)
1653 {
1654         int ret = OAL_STATUS_SUCCESS;
1655         uint16_t netkey_idx;
1656         oal_uuid_t net_uuid;
1657         uint16_t data_len;
1658         uint32_t opcode = 0;
1659         uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
1660
1661         /* If Scanning is going on */
1662         if (_bt_mesh_is_provisioning() ||
1663                         _bt_mesh_is_scanning()) {
1664                 BT_ERR("Device is buzy..");
1665                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1666         }
1667
1668         if (req->op != BLUETOOTH_MESH_MODEL_SUB_DELETE_ALL) {
1669                 /* Subscriptio address sanity check */
1670                 if ((!MESH_IS_GROUP(req->sub_addr) ||
1671                         MESH_IS_ALL_NODES(req->sub_addr)) ||
1672                                 MESH_IS_VIRTUAL(req->sub_addr)) {
1673                         BT_ERR("Mesh: Bad subscription address %x\n",
1674                                 req->sub_addr);
1675                         return BLUETOOTH_ERROR_INVALID_PARAM;
1676                 }
1677         }
1678
1679         /* Get Subnet index of the remote node for TX encryption */
1680         netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid,
1681                                 req->primary_unicast);
1682         if (netkey_idx == MESH_NET_IDX_INVALID)
1683                 return BLUETOOTH_ERROR_INTERNAL;
1684
1685         _bt_mesh_util_convert_string_to_hex(req->net_uuid,
1686                 strlen(req->net_uuid), net_uuid.uuid, 16);
1687
1688         if (req->op == BLUETOOTH_MESH_MODEL_SUB_ADD)
1689                 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_ADD;
1690         else if (req->op == BLUETOOTH_MESH_MODEL_SUB_DELETE)
1691                 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_DELETE;
1692         else if (req->op == BLUETOOTH_MESH_MODEL_SUB_DELETE_ALL)
1693                 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_DELETE_ALL;
1694         else if (req->op == BLUETOOTH_MESH_MODEL_SUB_OVERWRITE)
1695                 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_OVERWRITE;
1696
1697         /* Check pending request */
1698         if (_bt_mesh_check_pending_request(opcode,
1699                                 req->primary_unicast, net_uuid.uuid)) {
1700                 BT_ERR("Device is buzy..");
1701                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1702         }
1703
1704         data_len = _bt_mesh_util_opcode_set(opcode, buffer);
1705
1706         /* Element Address */
1707         l_put_le16((req->primary_unicast + req->elem_index),
1708                         buffer + data_len);
1709         data_len += 2;
1710
1711         /* Subscription address */
1712         if (req->op != BLUETOOTH_MESH_MODEL_SUB_DELETE_ALL) {
1713                 l_put_le16(req->sub_addr, buffer + data_len);
1714                 data_len += 2;
1715         }
1716
1717         /* Insert Model ID */
1718          if (req->model >= 0xFFFF0000) {
1719                 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
1720                 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
1721                 data_len += 2;
1722         } else {
1723                 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
1724                 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
1725                 data_len += 2;
1726                 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
1727                 data_len += 2;
1728         }
1729
1730         ret = mesh_conf_send_message(&net_uuid, req->primary_unicast, true,
1731                         netkey_idx, buffer, data_len);
1732
1733         if (ret != OAL_STATUS_SUCCESS) {
1734                 BT_ERR("ret: %d", ret);
1735                 return BLUETOOTH_ERROR_INTERNAL;
1736         }
1737
1738         /* Queue the request with timeout */
1739         __bt_mesh_add_request(opcode, req->primary_unicast,
1740                 net_uuid.uuid,
1741                         g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
1742
1743         return BLUETOOTH_ERROR_NONE;
1744 }
1745
1746 int _bt_mesh_model_configure_virtual_group_subscription(
1747                 const char *app_cred, const char *sender,
1748                         bluetooth_mesh_model_configure_t *req)
1749 {
1750         int ret = OAL_STATUS_SUCCESS;
1751         uint16_t netkey_idx;
1752         oal_uuid_t net_uuid;
1753         uint16_t data_len;
1754         uint32_t opcode = 0;
1755         uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
1756
1757         /* If Scanning is going on */
1758         if (_bt_mesh_is_provisioning() ||
1759                         _bt_mesh_is_scanning()) {
1760                 BT_ERR("Device is buzy..");
1761                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1762         }
1763
1764         _bt_mesh_util_convert_string_to_hex(req->net_uuid,
1765                 strlen(req->net_uuid), net_uuid.uuid, 16);
1766
1767         if (req->op != BLUETOOTH_MESH_MODEL_SUB_DELETE_ALL) {
1768                 /* Subscription address sanity check */
1769                 if ((MESH_IS_GROUP(req->sub_addr) ||
1770                         MESH_IS_ALL_NODES(req->sub_addr)) ||
1771                                 !(MESH_IS_VIRTUAL(req->sub_addr))) {
1772                         BT_ERR("Mesh: Bad Virtual subscription address %x\n",
1773                                 req->sub_addr);
1774                         return BLUETOOTH_ERROR_INVALID_PARAM;
1775                 }
1776         }
1777
1778         /* Get Subnet index of the remote node for TX encryption */
1779         netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid,
1780                                 req->primary_unicast);
1781         if (netkey_idx == MESH_NET_IDX_INVALID)
1782                 return BLUETOOTH_ERROR_INTERNAL;
1783
1784         if (req->op == BLUETOOTH_MESH_MODEL_SUB_ADD)
1785                 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_ADD;
1786         else if (req->op == BLUETOOTH_MESH_MODEL_SUB_DELETE)
1787                 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_DELETE;
1788         else if (req->op == BLUETOOTH_MESH_MODEL_SUB_DELETE_ALL)
1789                 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_DELETE_ALL;
1790         else if (req->op == BLUETOOTH_MESH_MODEL_SUB_OVERWRITE)
1791                 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_OVERWRITE;
1792
1793         /* Check pending request */
1794         if (_bt_mesh_check_pending_request(opcode,
1795                                 req->primary_unicast, net_uuid.uuid)) {
1796                 BT_ERR("Device is buzy..");
1797                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1798         }
1799
1800         data_len = _bt_mesh_util_opcode_set(opcode, buffer);
1801
1802         /* Element Address */
1803         l_put_le16((req->primary_unicast + req->elem_index), buffer + data_len);
1804         data_len += 2;
1805
1806         /* Subscription address */
1807         if (req->op != BLUETOOTH_MESH_MODEL_SUB_DELETE_ALL) {
1808                 uint8_t label_uuid[16];
1809                 if (!_bt_mesh_network_get_label_uuid_from_sub_addr(
1810                         net_uuid.uuid, req->sub_addr, label_uuid)) {
1811                         BT_ERR("Mesh: Virtual Group Label UUID Not found");
1812                         return BLUETOOTH_ERROR_INVALID_PARAM;
1813                 }
1814                 memcpy(buffer + data_len, label_uuid, 16);
1815                 data_len += 16;
1816         }
1817
1818         /* Insert Model ID */
1819          if (req->model >= 0xFFFF0000) {
1820                 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
1821                 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
1822                 data_len += 2;
1823         } else {
1824                 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
1825                 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
1826                 data_len += 2;
1827                 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
1828                 data_len += 2;
1829         }
1830
1831         ret = mesh_conf_send_message(&net_uuid,
1832                         req->primary_unicast, true,
1833                                 netkey_idx, buffer, data_len);
1834
1835         if (ret != OAL_STATUS_SUCCESS) {
1836                 BT_ERR("ret: %d", ret);
1837                 return BLUETOOTH_ERROR_INTERNAL;
1838         }
1839
1840         /* Queue the request with timeout */
1841         __bt_mesh_add_request(opcode, req->primary_unicast,
1842                 net_uuid.uuid,
1843                         g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
1844
1845         return BLUETOOTH_ERROR_NONE;
1846 }
1847
1848 int _bt_mesh_model_get_publication(const char *app_cred, const char *sender,
1849                 bluetooth_mesh_model_configure_t *req)
1850 {
1851         int ret = OAL_STATUS_SUCCESS;
1852         uint16_t netkey_idx;
1853         oal_uuid_t net_uuid;
1854         uint16_t data_len;
1855         uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
1856
1857         /* If Scanning is going on */
1858         if (_bt_mesh_is_provisioning() ||
1859                         _bt_mesh_is_scanning()) {
1860                 BT_ERR("Device is buzy..");
1861                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1862         }
1863
1864         _bt_mesh_util_convert_string_to_hex(req->net_uuid,
1865                 strlen(req->net_uuid), net_uuid.uuid, 16);
1866
1867         /* Check pending request */
1868         if (_bt_mesh_check_pending_request(MESH_OPCODE_CONFIG_MODEL_PUB_GET,
1869                                 req->primary_unicast, net_uuid.uuid)) {
1870                 BT_ERR("Device is buzy..");
1871                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1872         }
1873
1874         /* Get Subnet index of the remote node for TX encryption */
1875         netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, req->primary_unicast);
1876         if (netkey_idx == MESH_NET_IDX_INVALID)
1877                 return BLUETOOTH_ERROR_INTERNAL;
1878
1879         /* Set Opcode */
1880         data_len = _bt_mesh_util_opcode_set(MESH_OPCODE_CONFIG_MODEL_PUB_GET, buffer);
1881
1882         /* Element Address */
1883         l_put_le16((req->primary_unicast + req->elem_index), buffer + data_len);
1884         data_len += 2;
1885
1886         /* Insert Model ID */
1887         if (req->model >= 0xFFFF0000) {
1888                 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
1889                 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
1890                 data_len += 2;
1891         } else {
1892                 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
1893                 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
1894                 data_len += 2;
1895                 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
1896                 data_len += 2;
1897         }
1898
1899         ret = mesh_conf_send_message(&net_uuid, req->primary_unicast, true, netkey_idx, buffer, data_len);
1900
1901         if (ret != OAL_STATUS_SUCCESS) {
1902                 BT_ERR("ret: %d", ret);
1903                 return BLUETOOTH_ERROR_INTERNAL;
1904         }
1905
1906         /* Queue the request with timeout */
1907         __bt_mesh_add_request(MESH_OPCODE_CONFIG_MODEL_PUB_GET, req->primary_unicast, net_uuid.uuid,
1908                         g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
1909
1910         return BLUETOOTH_ERROR_NONE;
1911 }
1912
1913 int _bt_mesh_model_set_publication(const char *app_cred, const char *sender,
1914                 bluetooth_mesh_model_configure_t *req)
1915 {
1916         int ret = OAL_STATUS_SUCCESS;
1917         uint16_t netkey_idx;
1918         oal_uuid_t net_uuid;
1919         uint16_t data_len;
1920         uint32_t opcode = 0;
1921         uint8_t label_uuid[16];
1922         uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
1923
1924         /* If Scanning is going on */
1925         if (_bt_mesh_is_provisioning() ||
1926                         _bt_mesh_is_scanning()) {
1927                 BT_ERR("Device is buzy..");
1928                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1929         }
1930
1931         _bt_mesh_util_convert_string_to_hex(req->net_uuid, strlen(req->net_uuid), net_uuid.uuid, 16);
1932
1933         if (req->pub_addr == MESH_ALL_NODES_ADDRESS)
1934                 BT_INFO("Mesh: Setting Publication to ALL Node Address");
1935
1936         if (!MESH_IS_GROUP(req->pub_addr) && !MESH_IS_VIRTUAL(req->pub_addr) &&
1937                         req->pub_addr != MESH_UNASSIGNED_ADDRESS) {
1938                 BT_ERR("Mesh: Bad Publication address %x\n", req->pub_addr);
1939                 return BLUETOOTH_ERROR_INVALID_PARAM;
1940         }
1941
1942         if (req->pub_addr != MESH_UNASSIGNED_ADDRESS) {
1943                 if (MESH_IS_VIRTUAL(req->pub_addr)) {
1944                         if(!_bt_mesh_network_get_label_uuid_from_sub_addr(
1945                                         net_uuid.uuid, req->pub_addr, label_uuid))
1946                                 return BLUETOOTH_ERROR_INVALID_PARAM;
1947                         opcode = MESH_OPCODE_CONFIG_MODEL_PUB_VIRT_SET;
1948
1949                 } else if (MESH_IS_GROUP(req->pub_addr))
1950                         opcode = MESH_OPCODE_CONFIG_MODEL_PUB_SET;
1951         }
1952
1953         /* Check pending request */
1954         if (_bt_mesh_check_pending_request(opcode,
1955                                 req->primary_unicast, net_uuid.uuid)) {
1956                 BT_ERR("Device is buzy..");
1957                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1958         }
1959
1960         /* Get Subnet index of the remote node for TX encryption */
1961         netkey_idx = _bt_mesh_node_get_subnet_idx(
1962                                 net_uuid.uuid, req->primary_unicast);
1963         if (netkey_idx == MESH_NET_IDX_INVALID)
1964                 return BLUETOOTH_ERROR_INTERNAL;
1965
1966         /* Set opcode */
1967         data_len = _bt_mesh_util_opcode_set(opcode, buffer);
1968
1969         /* Element Address */
1970         l_put_le16((req->primary_unicast + req->elem_index), buffer + data_len);
1971         data_len += 2;
1972
1973         /* Fill Publication Address */
1974         if (MESH_IS_VIRTUAL(req->pub_addr)) {
1975                 memcpy(buffer + data_len, label_uuid, 16);
1976                 data_len += 16;
1977         } else {
1978                 l_put_le16(req->pub_addr, buffer + data_len);
1979                 data_len += 2;
1980         }
1981
1982         /* AppKey index + credential (set to 0) */
1983         l_put_le16(req->appkey_idx, buffer + data_len);
1984         data_len += 2;
1985
1986         /* Fill TTL */
1987         buffer[data_len++] = req->ttl;
1988         /* Publish period  step count and step resolution */
1989         buffer[data_len++] = req->period;
1990         /* Publish retransmit count & interval steps */
1991         buffer[data_len++] = req->retransmit;
1992
1993         /* Insert Model ID */
1994         if (req->model >= 0xFFFF0000) {
1995                 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
1996                 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
1997                 data_len += 2;
1998         } else {
1999                 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
2000                 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
2001                 data_len += 2;
2002                 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2003                 data_len += 2;
2004         }
2005
2006         ret = mesh_conf_send_message(&net_uuid,
2007                         req->primary_unicast, true,
2008                                 netkey_idx, buffer, data_len);
2009
2010         if (ret != OAL_STATUS_SUCCESS) {
2011                 BT_ERR("ret: %d", ret);
2012                 return BLUETOOTH_ERROR_INTERNAL;
2013         }
2014
2015         /* Queue the request with timeout */
2016         __bt_mesh_add_request(opcode, req->primary_unicast, net_uuid.uuid,
2017                         g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
2018
2019         return BLUETOOTH_ERROR_NONE;
2020 }
2021
2022 int _bt_mesh_node_model_get_subscription_list(const char *app_cred, const char *sender,
2023                 bluetooth_mesh_model_configure_t *req)
2024 {
2025         int ret = OAL_STATUS_SUCCESS;
2026         uint16_t netkey_idx;
2027         oal_uuid_t net_uuid;
2028         uint16_t data_len;
2029         uint32_t opcode = 0;
2030         uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
2031
2032         /* If Scanning is going on */
2033         if (_bt_mesh_is_provisioning() ||
2034                         _bt_mesh_is_scanning()) {
2035                 BT_ERR("Device is buzy..");
2036                 return BLUETOOTH_ERROR_DEVICE_BUSY;
2037         }
2038
2039         _bt_mesh_util_convert_string_to_hex(req->net_uuid, strlen(req->net_uuid), net_uuid.uuid, 16);
2040
2041         /* Insert Model ID */
2042         if (req->model >= 0xFFFF0000)
2043                 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
2044                 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_GET;
2045         else
2046                 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
2047                 opcode = MESH_OPCODE_CONFIG_VEND_MODEL_SUB_GET;
2048
2049         /* Check pending request */
2050         if (_bt_mesh_check_pending_request(opcode,
2051                                 req->primary_unicast, net_uuid.uuid)) {
2052                 BT_ERR("Device is buzy..");
2053                 return BLUETOOTH_ERROR_DEVICE_BUSY;
2054         }
2055         /* Get Subnet index of the remote node for TX encryption */
2056         netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, req->primary_unicast);
2057         if (netkey_idx == MESH_NET_IDX_INVALID)
2058                 return BLUETOOTH_ERROR_INTERNAL;
2059
2060         data_len = _bt_mesh_util_opcode_set(opcode, buffer);
2061         /* Element Address */
2062         l_put_le16((req->primary_unicast + req->elem_index), buffer + data_len);
2063         data_len += 2;
2064
2065
2066         /* Insert Model ID */
2067         if (opcode == MESH_OPCODE_CONFIG_MODEL_SUB_GET) {
2068                 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
2069                 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2070                 data_len += 2;
2071         } else {
2072                 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
2073                 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
2074                 data_len += 2;
2075                 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2076                 data_len += 2;
2077         }
2078
2079         ret = mesh_conf_send_message(&net_uuid,
2080                 req->primary_unicast, true, netkey_idx, buffer, data_len);
2081
2082         if (ret != OAL_STATUS_SUCCESS) {
2083                 BT_ERR("ret: %d", ret);
2084                 return BLUETOOTH_ERROR_INTERNAL;
2085         }
2086
2087         /* Queue the request with timeout */
2088         __bt_mesh_add_request(opcode, req->primary_unicast, net_uuid.uuid,
2089                         g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
2090
2091         return BLUETOOTH_ERROR_NONE;
2092 }
2093
2094 int _bt_mesh_node_model_get_appkey_list(const char *app_cred, const char *sender,
2095                 bluetooth_mesh_model_configure_t *req)
2096 {
2097         int ret = OAL_STATUS_SUCCESS;
2098         uint16_t netkey_idx;
2099         oal_uuid_t net_uuid;
2100         uint16_t data_len;
2101         uint32_t opcode = 0;
2102         uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
2103
2104         /* If Scanning is going on */
2105         if (_bt_mesh_is_provisioning() ||
2106                         _bt_mesh_is_scanning()) {
2107                 BT_ERR("Device is buzy..");
2108                 return BLUETOOTH_ERROR_DEVICE_BUSY;
2109         }
2110
2111         _bt_mesh_util_convert_string_to_hex(req->net_uuid,
2112                 strlen(req->net_uuid), net_uuid.uuid, 16);
2113
2114         /* Insert Model ID */
2115         if (req->model >= 0xFFFF0000)
2116                 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
2117                 opcode = MESH_OPCODE_MODEL_APP_GET;
2118         else
2119                 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
2120                 opcode = MESH_OPCODE_VENDOR_MODEL_APP_GET;
2121
2122         /* Check pending request */
2123         if (_bt_mesh_check_pending_request(opcode,
2124                                 req->primary_unicast, net_uuid.uuid)) {
2125                 BT_ERR("Device is buzy..");
2126                 return BLUETOOTH_ERROR_DEVICE_BUSY;
2127         }
2128         /* Get Subnet index of the remote node for TX encryption */
2129         netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, req->primary_unicast);
2130         if (netkey_idx == MESH_NET_IDX_INVALID)
2131                 return BLUETOOTH_ERROR_INTERNAL;
2132
2133         data_len = _bt_mesh_util_opcode_set(opcode, buffer);
2134         /* Element Address */
2135         l_put_le16((req->primary_unicast + req->elem_index), buffer + data_len);
2136         data_len += 2;
2137
2138
2139         /* Insert Model ID */
2140         if (opcode == MESH_OPCODE_MODEL_APP_GET) {
2141                 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
2142                 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2143                 data_len += 2;
2144         } else {
2145                 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
2146                 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
2147                 data_len += 2;
2148                 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2149                 data_len += 2;
2150         }
2151
2152         ret = mesh_conf_send_message(&net_uuid, req->primary_unicast, true, netkey_idx, buffer, data_len);
2153
2154         if (ret != OAL_STATUS_SUCCESS) {
2155                 BT_ERR("ret: %d", ret);
2156                 return BLUETOOTH_ERROR_INTERNAL;
2157         }
2158
2159         /* Queue the request with timeout */
2160         __bt_mesh_add_request(opcode, req->primary_unicast, net_uuid.uuid,
2161                         g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
2162
2163         return BLUETOOTH_ERROR_NONE;
2164 }
2165
2166 int _bt_mesh_node_model_appkey_execute(const char *app_cred, const char *sender,
2167                 bluetooth_mesh_model_configure_t *req)
2168 {
2169         int ret = OAL_STATUS_SUCCESS;
2170         uint16_t netkey_idx;
2171         oal_uuid_t net_uuid;
2172         uint16_t data_len;
2173         uint32_t opcode = 0;
2174         uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
2175
2176         /* If Scanning is going on */
2177         if (_bt_mesh_is_provisioning() ||
2178                         _bt_mesh_is_scanning()) {
2179                 BT_ERR("Device is buzy..");
2180                 return BLUETOOTH_ERROR_DEVICE_BUSY;
2181         }
2182
2183         _bt_mesh_util_convert_string_to_hex(req->net_uuid, strlen(req->net_uuid), net_uuid.uuid, 16);
2184
2185         /* Check pending request */
2186         if (_bt_mesh_check_pending_request(req->is_bind ? MESH_OPCODE_MODEL_APP_BIND : MESH_OPCODE_MODEL_APP_UNBIND,
2187                                 req->primary_unicast, net_uuid.uuid)) {
2188                 BT_ERR("Device is buzy..");
2189                 return BLUETOOTH_ERROR_DEVICE_BUSY;
2190         }
2191         /* Get Subnet index of the remote node for TX encryption */
2192         netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, req->primary_unicast);
2193         if (netkey_idx == MESH_NET_IDX_INVALID)
2194                 return BLUETOOTH_ERROR_INTERNAL;
2195
2196         if (req->is_bind)
2197                 opcode = MESH_OPCODE_MODEL_APP_BIND;
2198         else
2199                 opcode = MESH_OPCODE_MODEL_APP_UNBIND;
2200
2201         data_len = _bt_mesh_util_opcode_set(opcode, buffer);
2202         /* Element Address */
2203         l_put_le16((req->primary_unicast + req->elem_index), buffer + data_len);
2204         data_len += 2;
2205
2206         /* AppKey Index  */
2207         l_put_le16(req->appkey_idx, buffer + data_len);
2208         data_len += 2;
2209
2210         /* Insert Model ID */
2211         if (req->model >= 0xFFFF0000) {
2212                 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
2213                 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2214                 data_len += 2;
2215         } else {
2216                 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
2217                 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
2218                 data_len += 2;
2219                 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2220                 data_len += 2;
2221         }
2222
2223         ret = mesh_conf_send_message(&net_uuid, req->primary_unicast, true, netkey_idx, buffer, data_len);
2224
2225         if (ret != OAL_STATUS_SUCCESS) {
2226                 BT_ERR("ret: %d", ret);
2227                 return BLUETOOTH_ERROR_INTERNAL;
2228         }
2229
2230         /* Queue the request with timeout */
2231         __bt_mesh_add_request(opcode, req->primary_unicast, net_uuid.uuid,
2232                         g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
2233
2234         return BLUETOOTH_ERROR_NONE;
2235 }
2236
2237 int _bt_mesh_ttl_execute_remote_node(const char *app_cred, const char *sender,
2238                 bluetooth_mesh_node_ttl_info_t *req)
2239 {
2240         int ret = OAL_STATUS_SUCCESS;
2241         uint16_t netkey_idx;
2242         uint16_t data_len;
2243         oal_uuid_t net_uuid;
2244         uint32_t opcode = 0;
2245         uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
2246
2247         /* If Scanning is going on */
2248         if (_bt_mesh_is_provisioning() ||
2249                         _bt_mesh_is_scanning()) {
2250                 BT_ERR("Device is buzy..");
2251                 return BLUETOOTH_ERROR_DEVICE_BUSY;
2252         }
2253
2254         _bt_mesh_util_convert_string_to_hex(req->net_uuid, strlen(req->net_uuid), net_uuid.uuid, 16);
2255
2256         /* Check pending request */
2257         if (_bt_mesh_check_pending_request(req->is_set ? MESH_OPCODE_CONFIG_DEFAULT_TTL_SET : MESH_OPCODE_CONFIG_DEFAULT_TTL_GET,
2258                                 req->unicast, net_uuid.uuid)) {
2259                 BT_ERR("Device is buzy..");
2260                 return BLUETOOTH_ERROR_DEVICE_BUSY;
2261         }
2262
2263         /* Get Subnet index of the rmeote node for TX encryption */
2264         netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, req->unicast);
2265         if (netkey_idx == MESH_NET_IDX_INVALID)
2266                 return BLUETOOTH_ERROR_INTERNAL;
2267
2268         if (req->is_set) {
2269                 opcode = MESH_OPCODE_CONFIG_DEFAULT_TTL_SET;
2270                 data_len = _bt_mesh_util_opcode_set(MESH_OPCODE_CONFIG_DEFAULT_TTL_SET, buffer);
2271                 buffer[data_len++] = req->ttl;
2272         } else {
2273                 opcode = MESH_OPCODE_CONFIG_DEFAULT_TTL_GET;
2274                 data_len = _bt_mesh_util_opcode_set(MESH_OPCODE_CONFIG_DEFAULT_TTL_GET, buffer);
2275         }
2276
2277         ret = mesh_conf_send_message(&net_uuid, req->unicast, true, netkey_idx, buffer, data_len);
2278
2279         if (ret != OAL_STATUS_SUCCESS) {
2280                 BT_ERR("ret: %d", ret);
2281                 return BLUETOOTH_ERROR_INTERNAL;
2282         }
2283
2284         /* Queue the request with timeout */
2285         __bt_mesh_add_request(opcode, req->unicast, net_uuid.uuid,
2286                         g_memdup(req, sizeof(bluetooth_mesh_node_ttl_info_t)));
2287         return BLUETOOTH_ERROR_NONE;
2288 }
2289
2290 static bool __bt_mesh_check_pending_key_cmd(uint16_t dest, bool is_netkey,
2291                 bluetooth_mesh_node_key_conf_e op,  uint8_t net_uuid[], uint32_t *opcode)
2292 {
2293         const struct mesh_config_cmd *cmd;
2294
2295         if (is_netkey) {
2296                 switch(op) {
2297                 case BLUETOOTH_MESH_NODE_KEY_ADD:
2298                         cmd = __mesh_get_command(MESH_OPCODE_NETKEY_ADD);
2299                         if (!cmd)
2300                                 return false;
2301                         if (__bt_mesh_get_request_by_response(dest, net_uuid, cmd->response)) {
2302                                 BT_ERR("Mesh:Another Key Configuration command is pending\n");
2303                                 return true;
2304                         }
2305                         *opcode = MESH_OPCODE_NETKEY_ADD;
2306                         return false;
2307                 case BLUETOOTH_MESH_NODE_KEY_DELETE:
2308                         cmd = __mesh_get_command(MESH_OPCODE_NETKEY_DELETE);
2309                         if (!cmd)
2310                                 return false;
2311                         if (__bt_mesh_get_request_by_response(dest, net_uuid, cmd->response)) {
2312                                 BT_ERR("Mesh:Another Key Configuration command is pending\n");
2313                                 return true;
2314                         }
2315                         *opcode = MESH_OPCODE_NETKEY_DELETE;
2316                         return false;
2317                 case BLUETOOTH_MESH_NODE_KEY_UPDATE:
2318                         cmd = __mesh_get_command(MESH_OPCODE_NETKEY_UPDATE);
2319                         if (!cmd)
2320                                 return false;
2321                         if (__bt_mesh_get_request_by_response(dest, net_uuid, cmd->response)) {
2322                                 BT_ERR("Mesh:Another Key Configuration command is pending\n");
2323                                 return true;
2324                         }
2325                         *opcode = MESH_OPCODE_NETKEY_UPDATE;
2326                         return false;
2327                 }
2328         } else {
2329                 switch(op) {
2330                 case BLUETOOTH_MESH_NODE_KEY_ADD:
2331                         cmd = __mesh_get_command(MESH_OPCODE_APPKEY_ADD);
2332                         if (!cmd)
2333                                 return false;
2334                         if (__bt_mesh_get_request_by_response(dest, net_uuid, cmd->response)) {
2335                                 BT_ERR("Mesh:Another Key Configuration command is pending\n");
2336                                 return true;
2337                         }
2338                         *opcode = MESH_OPCODE_APPKEY_ADD;
2339                         return false;
2340                 case BLUETOOTH_MESH_NODE_KEY_DELETE:
2341                         cmd = __mesh_get_command(MESH_OPCODE_APPKEY_DELETE);
2342                         if (!cmd)
2343                                 return false;
2344                         if (__bt_mesh_get_request_by_response(dest, net_uuid, cmd->response)) {
2345                                 BT_ERR("Mesh:Another Key Configuration command is pending\n");
2346                                 return true;
2347                         }
2348                         *opcode = MESH_OPCODE_APPKEY_DELETE;
2349                         return false;
2350                 case BLUETOOTH_MESH_NODE_KEY_UPDATE:
2351                         cmd = __mesh_get_command(MESH_OPCODE_APPKEY_UPDATE);
2352                         if (!cmd)
2353                                 return false;
2354                         if (__bt_mesh_get_request_by_response(dest, net_uuid, cmd->response)) {
2355                                 BT_ERR("Mesh:Another Key Configuration command is pending\n");
2356                                 return true;
2357                         }
2358                         *opcode = MESH_OPCODE_APPKEY_UPDATE;
2359                         return false;
2360                 }
2361         }
2362         return false;
2363 }
2364
2365 int _bt_mesh_node_configure_key(const char *app_cred, const char *sender,
2366                 bluetooth_mesh_key_configure_t *req)
2367 {
2368         int ret = OAL_STATUS_SUCCESS;
2369         uint16_t netkey_idx;
2370         uint16_t bound_netkey_idx = 0x0000;
2371         oal_uuid_t net_uuid;
2372         uint32_t opcode = 0;
2373         bool update;
2374         uint16_t data_len;
2375         uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
2376
2377         /* If Scanning is going on */
2378         if (_bt_mesh_is_provisioning() ||
2379                         _bt_mesh_is_scanning()) {
2380                 BT_ERR("Device is buzy..");
2381                 return BLUETOOTH_ERROR_DEVICE_BUSY;
2382         }
2383
2384         _bt_mesh_util_convert_string_to_hex(req->net_uuid, strlen(req->net_uuid), net_uuid.uuid, 16);
2385
2386         if (req->is_netkey && !_bt_mesh_keys_subnet_exists(net_uuid.uuid, req->netkey_idx)) {
2387                 BT_ERR("Local Subnet not found..");
2388                 return BLUETOOTH_ERROR_INVALID_PARAM;
2389         }
2390
2391         /* For Appkey Configuration, check for available bound netkey */
2392         if (!req->is_netkey) {
2393                 bound_netkey_idx = _bt_mesh_keys_get_bound_key(net_uuid.uuid, req->appkey_idx);
2394                 if (bound_netkey_idx == MESH_NET_IDX_INVALID) {
2395                         BT_ERR("Local AppKey not found..");
2396                         return BLUETOOTH_ERROR_INVALID_PARAM;
2397                 }
2398         }
2399
2400         /* Check pending request */
2401         if (__bt_mesh_check_pending_key_cmd(req->primary_unicast,
2402                                 req->is_netkey, req->op, net_uuid.uuid, &opcode)) {
2403                 BT_ERR("Device is buzy..");
2404                 return BLUETOOTH_ERROR_DEVICE_BUSY;
2405         }
2406
2407         /* Get Subnet index of the rmeote node for TX encryption */
2408         netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, req->primary_unicast);
2409         if (netkey_idx == MESH_NET_IDX_INVALID)
2410                 return BLUETOOTH_ERROR_INTERNAL;
2411
2412         /* Handle Key (App/Net) Delete Commands: Configuration Message  */
2413         if (opcode == MESH_OPCODE_NETKEY_DELETE || opcode == MESH_OPCODE_APPKEY_DELETE) {
2414                 data_len = _bt_mesh_util_opcode_set(opcode, buffer);
2415                 if (req->is_netkey) {
2416                         l_put_le16(req->netkey_idx, buffer + data_len);
2417                         data_len += 2;
2418                 } else {
2419                         buffer[data_len] = bound_netkey_idx;
2420                         buffer[data_len + 1] = ((bound_netkey_idx >> 8) & 0xf) | ((req->appkey_idx << 4) & 0xf0);
2421                         buffer[data_len + 2] = req->appkey_idx >> 4;
2422
2423                         data_len += 3;
2424                 }
2425                 ret = mesh_conf_send_message(&net_uuid, req->primary_unicast, true, netkey_idx, buffer, data_len);
2426         } else {
2427                 /* Handle Key (App/Net) Update & Add Commands: Key Config message  */
2428                 update = (opcode == MESH_OPCODE_NETKEY_UPDATE || opcode == MESH_OPCODE_APPKEY_UPDATE);
2429                 ret = mesh_conf_send_key_message(&net_uuid, req->primary_unicast, req->is_netkey,
2430                                 update, req->is_netkey? req->netkey_idx: req->appkey_idx, netkey_idx);
2431         }
2432         if (ret != OAL_STATUS_SUCCESS) {
2433                 BT_ERR("ret: %d", ret);
2434                 return BLUETOOTH_ERROR_INTERNAL;
2435         }
2436
2437         /* Queue the request with timeout */
2438         __bt_mesh_add_request(opcode, req->primary_unicast,  net_uuid.uuid,
2439                 g_memdup(req, sizeof(bluetooth_mesh_key_configure_t)));
2440         return BLUETOOTH_ERROR_NONE;
2441 }