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