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