4 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
6 * @author: Anupam Roy <anupam.r@samsung.com>
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
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"
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"
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"
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"
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>
68 #include "bt-internal-types.h"
70 #define MESH_CONFIG_BUFFER_MAX_LEN 100
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,
79 struct mesh_config_cmd {
82 const char *descriptor;
85 static struct l_queue *pending_requests;
87 struct mesh_pending_request {
88 struct l_timeout *timer;
89 const struct mesh_config_cmd *cmd;
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,
109 { MESH_OPCODE_CONFIG_DEFAULT_TTL_SET, MESH_OPCODE_CONFIG_DEFAULT_TTL_STATUS,
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,
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,
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,
159 { MESH_OPCODE_CONFIG_POLL_TIMEOUT_STATUS, MESH_RESPONSE_NONE, "PollTimeoutStatus" },
160 { MESH_OPCODE_CONFIG_HEARTBEAT_PUB_GET, MESH_OPCODE_CONFIG_HEARTBEAT_PUB_STATUS,
162 { MESH_OPCODE_CONFIG_HEARTBEAT_PUB_SET, MESH_OPCODE_CONFIG_HEARTBEAT_PUB_STATUS,
164 { MESH_OPCODE_CONFIG_HEARTBEAT_PUB_STATUS, MESH_RESPONSE_NONE, "HeartbeatPubStatus" },
165 { MESH_OPCODE_CONFIG_HEARTBEAT_SUB_GET, MESH_OPCODE_CONFIG_HEARTBEAT_SUB_STATUS,
167 { MESH_OPCODE_CONFIG_HEARTBEAT_SUB_SET, MESH_OPCODE_CONFIG_HEARTBEAT_SUB_STATUS,
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" }
191 static const struct mesh_config_cmd *__mesh_get_command(uint32_t opcode)
195 for (n = 0; n < L_ARRAY_SIZE(commands); n++) {
196 if (opcode == commands[n].opcode)
203 static const char *__mesh_get_opcode_string(uint32_t opcode)
205 const struct mesh_config_cmd *cmd;
207 cmd = __mesh_get_command(opcode);
209 return "Unknown Command Received";
211 return cmd->descriptor;
214 static void __mesh_request_remove(void *a)
216 struct mesh_pending_request *req = a;
220 l_timeout_remove(req->timer);
224 static void __bt_mesh_wait_response_timeout(
225 struct l_timeout *timeout, void *user_data)
227 struct mesh_pending_request *req = user_data;
229 BT_INFO("Mesh: No response for \"%s\" from %4.4x\n",
230 req->cmd->descriptor, req->addr);
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 */
236 switch(req->cmd->opcode) {
237 case MESH_OPCODE_DEV_COMP_GET: {
238 /* Send event with timeout */
239 event_mesh_devkey_message_t *event = \
240 g_malloc0(sizeof(event_mesh_devkey_message_t));
241 memcpy(event->net_uuid.uuid, req->net_uuid, 16);
242 event->source = req->addr;
243 __bt_mesh_handle_pending_dev_config_request_info(
244 BLUETOOTH_ERROR_TIMEOUT, BT_MESH_NODE_BROWSE,
245 event, sizeof(event_mesh_devkey_message_t));
249 case MESH_OPCODE_NETKEY_ADD:
250 case MESH_OPCODE_NETKEY_UPDATE:
251 case MESH_OPCODE_NETKEY_DELETE:
252 case MESH_OPCODE_APPKEY_ADD:
253 case MESH_OPCODE_APPKEY_UPDATE:
254 case MESH_OPCODE_APPKEY_DELETE:
255 /* Send event with timeout */
256 __bt_mesh_handle_pending_dev_config_request_info(
257 BLUETOOTH_ERROR_TIMEOUT,
258 BT_MESH_NODE_CONFIGURE_KEY, req->data,
259 sizeof(bluetooth_mesh_key_configure_t));
261 case MESH_OPCODE_CONFIG_DEFAULT_TTL_GET:
262 case MESH_OPCODE_CONFIG_DEFAULT_TTL_SET:
263 /* Send event with timeout */
264 __bt_mesh_handle_pending_dev_config_request_info(
265 BLUETOOTH_ERROR_TIMEOUT,
266 BT_MESH_NODE_TTL_EXECUTE, req->data,
267 sizeof(bluetooth_mesh_node_ttl_info_t));
272 l_queue_remove(pending_requests, req);
273 __mesh_request_remove(req);
276 static void __bt_mesh_add_request(uint32_t opcode, uint16_t dest,
277 uint8_t net_uuid[], void *data)
279 struct mesh_pending_request *req;
280 const struct mesh_config_cmd *cmd;
282 cmd = __mesh_get_command(opcode);
286 req = l_new(struct mesh_pending_request, 1);
290 memcpy(req->net_uuid, net_uuid, 16);
291 req->timer = l_timeout_create(MESH_DEFAULT_RESPONSE_TIMEOUT,
292 __bt_mesh_wait_response_timeout, req, NULL);
293 l_queue_push_tail(pending_requests, req);
296 static struct mesh_pending_request *__bt_mesh_get_request_by_response(
297 uint16_t addr, uint8_t net_uuid[],
300 const struct l_queue_entry *entry;
302 entry = l_queue_get_entries(pending_requests);
304 for (; entry; entry = entry->next) {
305 struct mesh_pending_request *req = entry->data;
307 if (!memcmp(net_uuid, req->net_uuid, 16) &&
309 req->cmd->response == response)
316 bool _bt_mesh_check_pending_request(uint32_t opcode,
317 uint16_t dest, uint8_t net_uuid[])
319 const struct mesh_config_cmd *cmd;
320 cmd = __mesh_get_command(opcode);
325 if (__bt_mesh_get_request_by_response(dest,
326 net_uuid, cmd->response)) {
327 BT_ERR("Mesh:Another command is pending\n");
333 static uint32_t __bt_mesh_print_model_identifier(uint8_t *data,
334 bool vendor, const char *offset)
339 mod_id = l_get_le16(data);
340 BT_INFO("%sModel ID\t%4.4x\n", offset, mod_id);
341 mod_id = MESH_VENDOR_ID_MASK | mod_id;
343 mod_id = l_get_le16(data + 2);
344 BT_INFO("%sModel ID\t%4.4x %4.4x\n", offset,
345 l_get_le16(data), mod_id);
346 mod_id = l_get_le16(data) << 16 | mod_id;
352 static void __bt_mesh_print_device_composition_data(
353 uint8_t *data, uint16_t len)
358 BT_INFO("Mesh: Received composion:\n");
360 /* skip page -- We only support Page Zero */
364 BT_INFO("\tCID: %4.4x", l_get_le16(&data[0]));
365 BT_INFO("\tPID: %4.4x", l_get_le16(&data[2]));
366 BT_INFO("\tVID: %4.4x", l_get_le16(&data[4]));
367 BT_INFO("\tCRPL: %4.4x", l_get_le16(&data[6]));
369 features = l_get_le16(&data[8]);
373 BT_INFO("\tFeature support:\n");
374 BT_INFO("\t\trelay: %s\n", (features & MESH_FEATURE_RELAY) ?
376 BT_INFO("\t\tproxy: %s\n", (features & MESH_FEATURE_PROXY) ?
378 BT_INFO("\t\tfriend: %s\n", (features & MESH_FEATURE_FRIEND) ?
380 BT_INFO("\t\tlpn: %s\n", (features & MESH_FEATURE_LPN) ?
385 BT_INFO("\t Element %d:\n", i);
386 BT_INFO("\t\tlocation: %4.4x\n", l_get_le16(data));
395 BT_INFO("\t\tSIG defined models:\n");
397 while (len >= 2 && m--) {
398 __bt_mesh_print_model_identifier(data, false, "\t\t ");
404 BT_INFO("\t\t Vendor defined models:\n");
406 while (len >= 4 && v--) {
407 __bt_mesh_print_model_identifier(data, true, "\t\t ");
416 static void __bt_mesh_send_model_publication_status_event(
417 int event, int result,
418 bluetooth_mesh_model_configure_t *evt)
420 GVariant *out_var = NULL, *param = NULL;
423 if (BLUETOOTH_ERROR_NONE == result) {
425 info = g_array_new(FALSE, FALSE, sizeof(gchar));
426 g_array_append_vals(info, &evt,
427 sizeof(bluetooth_mesh_model_configure_t));
429 out_var = g_variant_new_from_data((const GVariantType *)"ay",
430 info->data, info->len,
433 param = g_variant_new("(iv)", result, out_var);
434 _bt_send_event(BT_MESH_EVENT, event,
439 static void __bt_mesh_send_model_subscription_configure_event(
440 int event, int result,
441 bluetooth_mesh_model_configure_t *evt)
443 GVariant *out_var = NULL, *param = NULL;
446 if (BLUETOOTH_ERROR_NONE == result) {
448 info = g_array_new(FALSE, FALSE, sizeof(gchar));
449 g_array_append_vals(info, &evt,
450 sizeof(bluetooth_mesh_model_configure_t));
452 out_var = g_variant_new_from_data((const GVariantType *)"ay",
453 info->data, info->len,
456 param = g_variant_new("(iv)", result, out_var);
457 _bt_send_event(BT_MESH_EVENT, event,
462 static void __bt_mesh_send_model_get_subscription_list_event(
463 int result, bluetooth_mesh_model_configure_t *evt)
465 GVariant *param = NULL;
466 GVariantBuilder *builder = NULL;
469 if (BLUETOOTH_ERROR_NONE == result) {
470 if (evt->sublist_count) {
471 builder = g_variant_builder_new(G_VARIANT_TYPE("aq"));
472 for (i = 0; i < evt->sublist_count; i++)
473 g_variant_builder_add(builder, "q", *evt->sub_list[i]);
475 param = g_variant_new("(isqiui(aq))", result, evt->net_uuid,
476 evt->primary_unicast, evt->elem_index, evt->model,
477 evt->sublist_count, builder);
479 g_variant_builder_unref(builder);
482 _bt_send_event(BT_MESH_EVENT,
483 BLUETOOTH_EVENT_MESH_MODEL_SUBSCRIPTION_LIST,
486 if (evt->sublist_count) {
488 for (int i = 0; i < evt->sublist_count; i++)
489 g_free(evt->sub_list[i]);
490 g_free(evt->sub_list);
495 static void __bt_mesh_send_model_get_appkey_list_event(int result,
496 bluetooth_mesh_model_configure_t *evt)
498 GVariant *param = NULL;
499 GVariantBuilder *builder = NULL;
502 if (BLUETOOTH_ERROR_NONE == result) {
504 if (evt->appkeylist_count) {
505 builder = g_variant_builder_new(G_VARIANT_TYPE("aq"));
506 for (i = 0; i < evt->appkeylist_count; i++)
507 g_variant_builder_add(builder, "q", *evt->appkey_list[i]);
509 param = g_variant_new("(isqiui(aq))", result, evt->net_uuid,
510 evt->primary_unicast, evt->elem_index, evt->model,
511 evt->appkeylist_count, builder);
513 g_variant_builder_unref(builder);
517 _bt_send_event(BT_MESH_EVENT,
518 BLUETOOTH_EVENT_MESH_MODEL_APPKEY_LIST,
521 if (evt->appkeylist_count) {
523 for (int i = 0; i < evt->appkeylist_count; i++)
524 g_free(evt->appkey_list[i]);
525 g_free(evt->appkey_list);
530 static void __bt_mesh_send_model_configure_appkey_event(int result,
531 bluetooth_mesh_model_configure_t *evt)
533 GVariant *out_var = NULL, *param = NULL;
536 if (BLUETOOTH_ERROR_NONE == result) {
538 info = g_array_new(FALSE, FALSE, sizeof(gchar));
539 g_array_append_vals(info, &evt, sizeof(bluetooth_mesh_model_configure_t));
541 out_var = g_variant_new_from_data((const GVariantType *)"ay",
542 info->data, info->len,
545 param = g_variant_new("(iv)", result, out_var);
546 _bt_send_event(BT_MESH_EVENT,
547 BLUETOOTH_EVENT_MESH_NODE_MODEL_APPKEY_BIND,
552 static void __bt_mesh_send_node_ttl_configuration_event(int result,
553 bluetooth_mesh_node_ttl_info_t *ttl_evt)
555 GVariant *out_var = NULL, *param = NULL;
558 if (BLUETOOTH_ERROR_NONE == result) {
560 info = g_array_new(FALSE, FALSE, sizeof(gchar));
561 g_array_append_vals(info, &ttl_evt,
562 sizeof(bluetooth_mesh_node_ttl_info_t));
564 out_var = g_variant_new_from_data((const GVariantType *)"ay",
565 info->data, info->len,
568 param = g_variant_new("(iv)", result, out_var);
569 _bt_send_event(BT_MESH_EVENT,
570 BLUETOOTH_EVENT_MESH_NODE_TTL_CONFIGURED,
575 static void __bt_mesh_send_node_key_configuration_event(int result,
576 bluetooth_mesh_key_configure_t *key_evt)
578 GVariant *out_var = NULL, *param = NULL;
581 if (BLUETOOTH_ERROR_NONE == result) {
583 info = g_array_new(FALSE, FALSE, sizeof(gchar));
584 g_array_append_vals(info, &key_evt,
585 sizeof(bluetooth_mesh_key_configure_t));
587 out_var = g_variant_new_from_data((const GVariantType *)"ay",
588 info->data, info->len,
591 param = g_variant_new("(iv)", result, out_var);
592 _bt_send_event(BT_MESH_EVENT,
593 BLUETOOTH_EVENT_MESH_NODE_KEY_CONFIGURED,
598 static void __bt_mesh_send_node_get_vendor_features_event(int result,
599 bluetooth_mesh_node_features_t *features_evt)
601 GVariant *out_var = NULL, *param = NULL;
604 if (BLUETOOTH_ERROR_NONE == result) {
606 info = g_array_new(FALSE, FALSE, sizeof(gchar));
607 g_array_append_vals(info, &features_evt,
608 sizeof(bluetooth_mesh_node_features_t));
610 out_var = g_variant_new_from_data((const GVariantType *)"ay",
611 info->data, info->len,
614 param = g_variant_new("(iv)", result, out_var);
615 _bt_send_event(BT_MESH_EVENT,
616 BLUETOOTH_EVENT_MESH_NODE_VENDOR_FEATURES,
621 static void __bt_mesh_send_node_browsed_event(int result,
622 bluetooth_mesh_node_discover_t *browse_evt)
624 GVariant *out_var = NULL, *param = NULL;
627 if (BLUETOOTH_ERROR_NONE == result) {
629 info = g_array_new(FALSE, FALSE, sizeof(gchar));
630 g_array_append_vals(info, &browse_evt,
631 sizeof(bluetooth_mesh_node_discover_t));
633 out_var = g_variant_new_from_data((const GVariantType *)"ay",
634 info->data, info->len,
637 param = g_variant_new("(iv)", result, out_var);
638 _bt_send_event(BT_MESH_EVENT,
639 BLUETOOTH_EVENT_MESH_NODE_BROWSED,
644 static void __bt_mesh_handle_pending_dev_config_request_info(int result,
645 int service_function, void *param, unsigned int size)
649 invocation_info_t *req_info = NULL;
651 for (l = _bt_get_invocation_list(); l != NULL; ) {
654 if (req_info == NULL ||
655 req_info->service_function != service_function)
658 switch (service_function) {
659 case BT_MESH_NODE_GET_VENDOR_FEATURES: {
660 bluetooth_mesh_node_features_t *event;
661 bluetooth_mesh_node_features_t *req;
663 event = (bluetooth_mesh_node_features_t*) param;
664 req = (bluetooth_mesh_node_features_t*)req_info->user_data;
666 BT_DBG("Request Sender: [%s]", req_info->sender);
667 /* Match Network and Remote Node unicast*/
668 if (!g_strcmp0(event->net_uuid, req->net_uuid) && event->unicast == req->unicast) {
669 event->unicast = req->unicast;
670 event->elem_count = req->elem_count;
672 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
673 g_array_append_vals(out_param, event, sizeof(bluetooth_mesh_node_features_t));
675 /* Return DBUS Invocation*/
676 _bt_service_method_return(req_info->context, out_param, result);
677 _bt_free_info_from_invocation_list(req_info);
678 g_free(req_info->user_data);
679 g_array_free(out_param, TRUE);
682 __bt_mesh_send_node_get_vendor_features_event(result, event);
686 case BT_MESH_NODE_BROWSE: {
687 bluetooth_mesh_node_discover_t *node;
688 event_mesh_devkey_message_t *event;
689 uint16_t remote_addr;
691 uint8_t dev_uuid[16];
692 char net_uuid[BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1];
694 event = (event_mesh_devkey_message_t*) param;
695 node = (bluetooth_mesh_node_discover_t*)req_info->user_data;
697 _bt_mesh_util_convert_hex_to_string((uint8_t *) event->net_uuid.uuid, 16, net_uuid,
698 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
700 _bt_mesh_util_convert_string_to_hex(node->dev_uuid, strlen(node->dev_uuid), dev_uuid, 16);
702 /* Get Unicast from pending request's Dev UUID and match with event */
703 if (_bt_mesh_node_get_unicast_from_dev_uuid(event->net_uuid.uuid, dev_uuid, &remote_addr)) {
705 BT_DBG("Request Sender: [%s]", req_info->sender);
706 /* Match Network and Remote Node unicast*/
707 if (!g_strcmp0(node->net_uuid, net_uuid) && remote_addr == event->source) {
708 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
709 g_array_append_vals(out_param, node, sizeof(bluetooth_mesh_node_discover_t));
711 _bt_mesh_node_get_element_count(event->net_uuid.uuid, remote_addr, &elem_count);
712 node->unicast = event->source;
713 node->count = elem_count;
715 /* Return DBUS Invocation*/
716 _bt_service_method_return(req_info->context, out_param, result);
717 _bt_free_info_from_invocation_list(req_info);
718 g_free(req_info->user_data);
719 g_array_free(out_param, TRUE);
722 __bt_mesh_send_node_browsed_event(result, node);
727 case BT_MESH_NODE_CONFIGURE_KEY: {
728 bluetooth_mesh_key_configure_t *event;
729 bluetooth_mesh_key_configure_t *req;
731 event = (bluetooth_mesh_key_configure_t*) param;
732 req = (bluetooth_mesh_key_configure_t*)req_info->user_data;
734 if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
735 req->primary_unicast == event->primary_unicast &&
736 req->is_netkey == event->is_netkey) {
737 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
738 g_array_append_vals(out_param, event, sizeof(bluetooth_mesh_key_configure_t));
740 /* Return DBUS Invocation*/
741 _bt_service_method_return(req_info->context, out_param, result);
742 _bt_free_info_from_invocation_list(req_info);
743 g_free(req_info->user_data);
744 g_array_free(out_param, TRUE);
747 __bt_mesh_send_node_key_configuration_event(result, event);
751 case BT_MESH_NODE_TTL_EXECUTE: {
752 bluetooth_mesh_node_ttl_info_t *event;
753 bluetooth_mesh_node_ttl_info_t *req;
755 event = (bluetooth_mesh_node_ttl_info_t*) param;
756 req = (bluetooth_mesh_node_ttl_info_t*)req_info->user_data;
757 req->ttl = event->ttl;
759 if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
760 req->unicast == event->unicast) {
761 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
762 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_node_ttl_info_t));
764 /* Return DBUS Invocation*/
765 _bt_service_method_return(req_info->context, out_param, result);
766 _bt_free_info_from_invocation_list(req_info);
767 g_free(req_info->user_data);
768 g_array_free(out_param, TRUE);
771 __bt_mesh_send_node_ttl_configuration_event(result, req);
775 case BT_MESH_MODEL_CONFIGURE_APPKEY: {
776 bluetooth_mesh_model_configure_t *event;
777 bluetooth_mesh_model_configure_t *req;
779 event = (bluetooth_mesh_model_configure_t*) param;
780 req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
782 if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
783 req->primary_unicast == event->primary_unicast) {
784 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
785 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_model_configure_t));
787 /* Return DBUS Invocation*/
788 _bt_service_method_return(req_info->context, out_param, result);
789 _bt_free_info_from_invocation_list(req_info);
790 g_free(req_info->user_data);
791 g_array_free(out_param, TRUE);
794 __bt_mesh_send_model_configure_appkey_event(result, req);
799 case BT_MESH_MODEL_GET_APPKEY_LIST: {
800 bluetooth_mesh_model_configure_t *event;
801 bluetooth_mesh_model_configure_t *req;
803 event = (bluetooth_mesh_model_configure_t*) param;
804 req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
806 if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
807 req->primary_unicast == event->primary_unicast) {
808 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
809 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_model_configure_t));
811 /* Return DBUS Invocation*/
812 _bt_service_method_return(req_info->context, out_param, result);
813 _bt_free_info_from_invocation_list(req_info);
814 g_free(req_info->user_data);
815 g_array_free(out_param, TRUE);
818 __bt_mesh_send_model_get_appkey_list_event(result, event);
822 case BT_MESH_MODEL_GET_SUBSCRIPTION_LIST: {
823 bluetooth_mesh_model_configure_t *event;
824 bluetooth_mesh_model_configure_t *req;
826 event = (bluetooth_mesh_model_configure_t*) param;
827 req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
829 if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
830 req->primary_unicast == event->primary_unicast) {
831 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
832 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_model_configure_t));
834 /* Return DBUS Invocation*/
835 _bt_service_method_return(req_info->context, out_param, result);
836 _bt_free_info_from_invocation_list(req_info);
837 g_free(req_info->user_data);
838 g_array_free(out_param, TRUE);
841 __bt_mesh_send_model_get_subscription_list_event(result, event);
845 case BT_MESH_MODEL_CONFIG_GROUP_SUB: {
846 bluetooth_mesh_model_configure_t *event;
847 bluetooth_mesh_model_configure_t *req;
849 event = (bluetooth_mesh_model_configure_t*) param;
850 req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
852 if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
853 req->primary_unicast == event->primary_unicast) {
855 req->sub_addr = event->sub_addr;
856 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
857 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_model_configure_t));
859 /* Return DBUS Invocation*/
860 _bt_service_method_return(req_info->context, out_param, result);
861 _bt_free_info_from_invocation_list(req_info);
862 g_free(req_info->user_data);
863 g_array_free(out_param, TRUE);
866 __bt_mesh_send_model_subscription_configure_event( \
867 BLUETOOTH_EVENT_MESH_MODEL_SUBSCRIPTION_CONFGURED, \
872 case BT_MESH_MODEL_CONFIG_VIRTUAL_GROUP_SUB: {
873 bluetooth_mesh_model_configure_t *event;
874 bluetooth_mesh_model_configure_t *req;
876 event = (bluetooth_mesh_model_configure_t*) param;
877 req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
879 if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
880 req->primary_unicast == event->primary_unicast) {
881 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
882 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_model_configure_t));
884 /* Return DBUS Invocation*/
885 _bt_service_method_return(req_info->context, out_param, result);
886 _bt_free_info_from_invocation_list(req_info);
887 g_free(req_info->user_data);
888 g_array_free(out_param, TRUE);
891 __bt_mesh_send_model_subscription_configure_event( \
892 BLUETOOTH_EVENT_MESH_MODEL_VIRTUAL_SUBSCRIPTION_CONFGURED, \
897 case BT_MESH_MODEL_GET_PUBLICATION: {
898 bluetooth_mesh_model_configure_t *event;
899 bluetooth_mesh_model_configure_t *req;
901 event = (bluetooth_mesh_model_configure_t*) param;
902 req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
904 if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
905 req->primary_unicast == event->primary_unicast) {
906 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
907 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_model_configure_t));
909 /* Return DBUS Invocation*/
910 _bt_service_method_return(req_info->context, out_param, result);
911 _bt_free_info_from_invocation_list(req_info);
912 g_free(req_info->user_data);
913 g_array_free(out_param, TRUE);
916 __bt_mesh_send_model_publication_status_event( \
917 BLUETOOTH_EVENT_MESH_MODEL_PUBLICATION_STATUS, \
922 case BT_MESH_MODEL_SET_PUBLICATION: {
923 bluetooth_mesh_model_configure_t *event;
924 bluetooth_mesh_model_configure_t *req;
926 event = (bluetooth_mesh_model_configure_t*) param;
927 req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
929 if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
930 req->primary_unicast == event->primary_unicast) {
931 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
932 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_model_configure_t));
934 /* Return DBUS Invocation*/
935 _bt_service_method_return(req_info->context, out_param, result);
936 _bt_free_info_from_invocation_list(req_info);
937 g_free(req_info->user_data);
938 g_array_free(out_param, TRUE);
941 __bt_mesh_send_model_publication_status_event( \
942 BLUETOOTH_EVENT_MESH_MODEL_PUBLICATION_STATUS, \
948 BT_DBG("Unknown function(%d)", service_function);
954 const char *__mesh_status_to_string(uint8_t err)
957 case MESH_STATUS_SUCCESS: return "Success";
958 case MESH_STATUS_INVALID_ADDRESS: return "Invalid Address";
959 case MESH_STATUS_INVALID_MODEL: return "Invalid Model";
960 case MESH_STATUS_INVALID_APPKEY: return "Invalid AppKey";
961 case MESH_STATUS_INVALID_NETKEY: return "Invalid NetKey";
962 case MESH_STATUS_INSUFF_RESOURCES: return "Insufficient Resources";
963 case MESH_STATUS_IDX_ALREADY_STORED: return "Key Idx Already Stored";
964 case MESH_STATUS_INVALID_PUB_PARAM: return "Invalid Publish Parameters";
965 case MESH_STATUS_NOT_SUB_MOD: return "Not a Subscribe Model";
966 case MESH_STATUS_STORAGE_FAIL: return "Storage Failure";
967 case MESH_STATUS_FEATURE_NO_SUPPORT: return "Feature Not Supported";
968 case MESH_STATUS_CANNOT_UPDATE: return "Cannot Update";
969 case MESH_STATUS_CANNOT_REMOVE: return "Cannot Remove";
970 case MESH_STATUS_CANNOT_BIND: return "Cannot bind";
971 case MESH_STATUS_UNABLE_CHANGE_STATE: return "Unable to change state";
972 case MESH_STATUS_CANNOT_SET: return "Cannot set";
973 case MESH_STATUS_UNSPECIFIED_ERROR: return "Unspecified error";
974 case MESH_STATUS_INVALID_BINDING: return "Invalid Binding";
976 default: return "Unknown";
980 static void __mesh_handle_model_subscription_event(int result,
981 bluetooth_mesh_model_configure_t *param,
982 const struct mesh_config_cmd *cmd)
984 switch (cmd->opcode) {
986 case MESH_OPCODE_CONFIG_MODEL_SUB_ADD:
987 case MESH_OPCODE_CONFIG_MODEL_SUB_DELETE:
988 case MESH_OPCODE_CONFIG_MODEL_SUB_OVERWRITE:
989 case MESH_OPCODE_CONFIG_MODEL_SUB_DELETE_ALL:
990 /* Model Bind/UnBind Event */
991 __bt_mesh_handle_pending_dev_config_request_info(result,
992 BT_MESH_MODEL_CONFIG_GROUP_SUB, ¶m,
993 sizeof(bluetooth_mesh_model_configure_t));
995 case MESH_OPCODE_CONFIG_MODEL_SUB_VIRT_ADD:
996 case MESH_OPCODE_CONFIG_MODEL_SUB_VIRT_DELETE:
997 case MESH_OPCODE_CONFIG_MODEL_SUB_VIRT_OVERWRITE:
998 __bt_mesh_handle_pending_dev_config_request_info(result,
999 BT_MESH_MODEL_CONFIG_VIRTUAL_GROUP_SUB, ¶m,
1000 sizeof(bluetooth_mesh_model_configure_t));
1007 void _bt_mesh_config_client_devkey_msg_handler(
1008 event_mesh_devkey_message_t *event)
1011 const struct mesh_config_cmd *cmd;
1012 uint16_t data_len = event->data_len;
1013 uint8_t *data = event->data;
1014 int result = BLUETOOTH_ERROR_NONE;
1022 struct mesh_pending_request *req;
1024 if (_bt_mesh_util_opcode_get(data, data_len, &opcode, &n)) {
1030 BT_INFO("Mesh: Received %s (len %u)",
1031 __mesh_get_opcode_string(opcode), data_len);
1033 req = __bt_mesh_get_request_by_response(event->source,
1034 event->net_uuid.uuid, (opcode & ~MESH_OPCODE_UNRELIABLE));
1037 __mesh_request_remove(req);
1038 l_queue_remove(pending_requests, req);
1043 switch (opcode & ~MESH_OPCODE_UNRELIABLE) {
1046 case MESH_OPCODE_CONFIG_MODEL_PUB_STATUS: {
1047 if (data_len != 12 && data_len != 14)
1049 bluetooth_mesh_model_configure_t param;
1050 memset(¶m, 0x00, sizeof(bluetooth_mesh_model_configure_t));
1052 _bt_mesh_util_convert_hex_to_string((uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1053 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1055 BT_INFO("\nNode %4.4x Model Publication status %s\n",
1056 event->source, __mesh_status_to_string(data[0]));
1058 if (data[0] != MESH_STATUS_SUCCESS)
1061 /* Extract Element Address */
1062 ele_addr = l_get_le16(data + 1);
1064 /* Extract Model ID */
1065 if (data_len == 14) {
1067 mod_id = l_get_le16(data + 10 + 2);
1068 mod_id = l_get_le16(data) << 16 | mod_id;
1071 mod_id = l_get_le16(data + 10);
1072 mod_id = MESH_VENDOR_ID_MASK | mod_id;
1075 param.primary_unicast = event->source;
1076 param.elem_index = ele_addr - event->source;
1077 /* Extract Publish Address */
1078 param.pub_addr = l_get_le16(data + 3);
1080 /* Extract Appkey Index */
1081 param.appkey_idx = l_get_le16(data + 5);
1084 param.ttl = data[6];
1086 /* Extract Period */
1087 param.period = data[7];
1089 if (cmd->opcode == MESH_OPCODE_CONFIG_MODEL_PUB_GET)
1090 __bt_mesh_handle_pending_dev_config_request_info(result,
1091 BT_MESH_MODEL_GET_PUBLICATION, ¶m,
1092 sizeof(bluetooth_mesh_model_configure_t));
1094 __bt_mesh_handle_pending_dev_config_request_info(result,
1095 BT_MESH_MODEL_SET_PUBLICATION, ¶m,
1096 sizeof(bluetooth_mesh_model_configure_t));
1099 case MESH_OPCODE_CONFIG_MODEL_SUB_STATUS: {
1100 if (data_len != 7 && data_len != 9)
1102 bluetooth_mesh_model_configure_t param;
1103 memset(¶m, 0x00, sizeof(bluetooth_mesh_model_configure_t));
1105 _bt_mesh_util_convert_hex_to_string(
1106 (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1107 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1109 BT_INFO("\nNode %4.4x Subscription status %s\n",
1110 event->source, __mesh_status_to_string(data[0]));
1112 ele_addr = l_get_le16(data + 1);
1113 addr = l_get_le16(data + 3);
1114 BT_INFO("Element Addr\t%4.4x\n", ele_addr);
1116 if (data_len == 9) {
1118 mod_id = l_get_le16(data + 5 + 2);
1119 mod_id = l_get_le16(data) << 16 | mod_id;
1122 mod_id = l_get_le16(data + 5);
1123 mod_id = MESH_VENDOR_ID_MASK | mod_id;
1126 param.primary_unicast = event->source;
1127 param.elem_index = ele_addr - event->source;
1128 /* Subscription address, unassigned address in case of Delete All command */
1129 param.sub_addr = addr;
1130 param.model = mod_id;
1131 BT_INFO("Subscr Addr\t%4.4x\n", addr);
1132 __mesh_handle_model_subscription_event(result, ¶m, cmd);
1135 case MESH_OPCODE_CONFIG_DEFAULT_TTL_STATUS: {
1138 bluetooth_mesh_node_ttl_info_t param;
1139 memset(¶m, 0x00, sizeof(bluetooth_mesh_node_ttl_info_t));
1141 BT_INFO("Node %4.4x Default TTL %d", event->source, data[0]);
1142 _bt_mesh_util_convert_hex_to_string(
1143 (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1144 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1145 param.unicast = event->source;
1146 param.ttl = data[0];
1148 if (!_bt_mesh_network_save_remote_node_ttl(event->net_uuid.uuid,
1149 event->source, data[0])) {
1150 result = BLUETOOTH_ERROR_INTERNAL;
1151 BT_INFO("Failed to save node TTL");
1154 /* Remote Node TTL event */
1155 __bt_mesh_handle_pending_dev_config_request_info(result,
1156 BT_MESH_NODE_TTL_EXECUTE, ¶m,
1157 sizeof(bluetooth_mesh_node_ttl_info_t));
1160 case MESH_OPCODE_MODEL_APP_STATUS: {
1161 if (data_len != 7 && data_len != 9)
1163 bluetooth_mesh_model_configure_t param;
1164 memset(¶m, 0x00, sizeof(bluetooth_mesh_model_configure_t));
1166 _bt_mesh_util_convert_hex_to_string(
1167 (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1168 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1169 BT_INFO("Node %4.4x: Model App status %s\n", event->source,
1170 __mesh_status_to_string(data[0]));
1171 elem_addr = l_get_le16(data + 1);
1172 app_idx = l_get_le16(data + 3);
1174 BT_INFO("Element Addr\t%4.4x", elem_addr);
1175 if (data_len == 9) {
1177 mod_id = l_get_le16(data + 5 + 2);
1178 mod_id = l_get_le16(data) << 16 | mod_id;
1181 mod_id = l_get_le16(data + 5);
1182 mod_id = MESH_VENDOR_ID_MASK | mod_id;
1185 param.primary_unicast = event->source;
1186 param.elem_index = elem_addr - event->source;
1187 param.appkey_idx = app_idx;
1188 param.model = mod_id;
1189 BT_INFO("AppIdx\t\t%u (0x%3.3x)\n ", app_idx, app_idx);
1191 /* Model Bind/UnBind Event */
1192 __bt_mesh_handle_pending_dev_config_request_info(result,
1193 BT_MESH_MODEL_CONFIGURE_APPKEY, ¶m,
1194 sizeof(bluetooth_mesh_model_configure_t));
1197 case MESH_OPCODE_MODEL_APP_LIST: {
1202 bluetooth_mesh_model_configure_t param;
1203 memset(¶m, 0x00, sizeof(bluetooth_mesh_model_configure_t));
1205 _bt_mesh_util_convert_hex_to_string(
1206 (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1207 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1209 garray = g_array_new(FALSE, FALSE, sizeof(gchar));
1211 BT_INFO("\nNode %4.4x Model AppIdx status %s\n",
1212 event->source, __mesh_status_to_string(data[0]));
1214 BT_INFO("Element Addr\t%4.4x\n", l_get_le16(data + 1));
1215 BT_INFO("Model ID\t%4.4x\n", l_get_le16(data + 3));
1217 elem_addr = l_get_le16(data + 1);
1219 mod_id = l_get_le16(data + 3);
1220 mod_id = MESH_VENDOR_ID_MASK | mod_id;
1222 param.primary_unicast = event->source;
1223 param.elem_index = elem_addr - event->source;
1224 param.model = mod_id;
1229 while (data_len >= 3) {
1230 app_idx = l_get_le16(data) & 0xfff;
1231 g_array_append_vals(garray, &app_idx, sizeof(uint16_t));
1232 BT_INFO("\t%u (0x%3.3x)\n", app_idx, app_idx);
1234 app_idx = l_get_le16(data + 1) >> 4;
1235 g_array_append_vals(garray, &app_idx, sizeof(uint16_t));
1236 BT_INFO("\t%u (0x%3.3x)\n", app_idx, app_idx);
1241 if (data_len == 2) {
1242 app_idx = l_get_le16(data) & 0xfff;
1243 g_array_append_vals(garray, &app_idx, sizeof(uint16_t));
1244 BT_INFO("\t %u (0x%3.3x)\n", app_idx, app_idx);
1246 total = garray->len / sizeof(uint16_t);
1247 param.appkey_list = (uint16_t **)g_malloc0(sizeof(uint16_t*) * garray->len);
1248 param.appkeylist_count = total;
1249 for (int i = 0; i < total; i++) {
1250 param.appkey_list[i] = g_malloc(sizeof(uint16_t));
1251 *param.appkey_list[i] = g_array_index(garray, uint16_t, i);
1253 g_array_free(garray, TRUE);
1255 __bt_mesh_handle_pending_dev_config_request_info(result,
1256 BT_MESH_MODEL_GET_APPKEY_LIST, ¶m,
1257 sizeof(bluetooth_mesh_model_configure_t));
1260 case MESH_OPCODE_CONFIG_MODEL_SUB_LIST: {
1265 bluetooth_mesh_model_configure_t param;
1266 memset(¶m, 0x00, sizeof(bluetooth_mesh_model_configure_t));
1268 _bt_mesh_util_convert_hex_to_string((uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1269 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1271 BT_INFO("\nNode %4.4x BT SIG Model Subscription List status %s\n",
1272 event->source, __mesh_status_to_string(data[0]));
1274 BT_INFO("Element Addr\t%4.4x\n", l_get_le16(data + 1));
1275 elem_addr = l_get_le16(data + 1);
1278 mod_id = l_get_le16(data + 3);
1279 mod_id = MESH_VENDOR_ID_MASK | mod_id;
1280 BT_INFO("Model ID\t%4.4x\n", mod_id);
1282 param.primary_unicast = event->source;
1283 param.elem_index = elem_addr - event->source;
1284 param.model = mod_id;
1286 total = data_len - 5;
1287 param.sublist_count = total;
1289 param.sub_list = (uint16_t **)g_malloc0(sizeof(uint16_t*) * total);
1292 for (; i < data_len; i += 2) {
1293 BT_INFO("Subscription Addr \t\t%4.4x\n ", l_get_le16(data + i));
1294 param.sub_list[i] = g_malloc(sizeof(uint16_t));
1295 *param.sub_list[i] = l_get_le16(data + i);
1298 __bt_mesh_handle_pending_dev_config_request_info(result,
1299 BT_MESH_MODEL_GET_SUBSCRIPTION_LIST, ¶m,
1300 sizeof(bluetooth_mesh_model_configure_t));
1303 case MESH_OPCODE_CONFIG_VEND_MODEL_SUB_LIST: {
1308 bluetooth_mesh_model_configure_t param;
1309 memset(¶m, 0x00, sizeof(bluetooth_mesh_model_configure_t));
1311 _bt_mesh_util_convert_hex_to_string(
1312 (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1313 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1315 BT_INFO("\nNode %4.4x BT SIG Model Subscription List status %s\n",
1316 event->source, __mesh_status_to_string(data[0]));
1318 BT_INFO("Element Addr\t%4.4x\n", l_get_le16(data + 1));
1319 elem_addr = l_get_le16(data + 1);
1322 mod_id = l_get_le16(data + 5);
1323 mod_id = l_get_le16(data + 3) << 16 | mod_id;
1325 BT_INFO("Model ID\t%4.4x\n", mod_id);
1327 param.primary_unicast = event->source;
1328 param.elem_index = elem_addr - event->source;
1329 param.model = mod_id;
1331 total = data_len - 7;
1332 param.sublist_count = total;
1334 param.sub_list = (uint16_t **)g_malloc0(sizeof(uint16_t*) * total);
1337 for (; i < data_len; i += 2) {
1338 BT_INFO("Subscription Addr \t\t%4.4x\n ", l_get_le16(data + i));
1339 param.sub_list[i] = g_malloc(sizeof(uint16_t));
1340 *param.sub_list[i] = l_get_le16(data + i);
1343 __bt_mesh_handle_pending_dev_config_request_info(result,
1344 BT_MESH_MODEL_GET_SUBSCRIPTION_LIST, ¶m,
1345 sizeof(bluetooth_mesh_model_configure_t));
1348 case MESH_OPCODE_DEV_COMP_STATUS: {
1349 if (data_len < MESH_MINIMUM_COMPOSITION_LEN)
1351 bluetooth_mesh_node_features_t features;
1352 memset(&features, 0x00, sizeof(bluetooth_mesh_node_features_t));
1354 __bt_mesh_print_device_composition_data(data, data_len);
1356 if (!_bt_mesh_network_save_remote_node_composition(
1357 event->net_uuid.uuid, event->source, data, data_len)) {
1358 result = BLUETOOTH_ERROR_INTERNAL;
1359 BT_INFO("Failed to save node composition!");
1361 /* Browse Remote Node event */
1362 __bt_mesh_handle_pending_dev_config_request_info(result,
1363 BT_MESH_NODE_BROWSE, event, sizeof(event_mesh_devkey_message_t));
1365 /* Vendor Features Discover event */
1366 _bt_mesh_util_convert_hex_to_string(
1367 (uint8_t *) event->net_uuid.uuid, 16, features.net_uuid,
1368 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1369 features.unicast = event->source;
1370 _bt_mesh_node_get_vendor_features(event->net_uuid.uuid,
1371 event->source, &features);
1373 __bt_mesh_handle_pending_dev_config_request_info(result,
1374 BT_MESH_NODE_GET_VENDOR_FEATURES, &features,
1375 sizeof(bluetooth_mesh_node_features_t));
1378 case MESH_OPCODE_NETKEY_STATUS: {
1382 bluetooth_mesh_key_configure_t param;
1383 memset(¶m, 0x00, sizeof(bluetooth_mesh_key_configure_t));
1385 BT_INFO("Mesh: Node %4.4x NetKey status %s",
1386 event->source, __mesh_status_to_string(data[0]));
1387 net_idx = l_get_le16(data + 1) & 0xfff;
1389 BT_INFO("\tNetKey %u (0x%3.3x)", net_idx, net_idx);
1397 _bt_mesh_util_convert_hex_to_string(
1398 (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1399 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1400 param.primary_unicast = event->source;
1401 param.netkey_idx = net_idx;
1402 param.is_netkey = true;
1404 if (cmd->opcode == MESH_OPCODE_NETKEY_ADD) {
1405 BT_INFO("Mesh: Resp recvd: MESH_OPCODE_NETKEY_ADD");
1406 if (_bt_mesh_network_save_remote_node_netkey(
1407 event->net_uuid.uuid, event->source, net_idx)) {
1408 result = BLUETOOTH_ERROR_INTERNAL;
1409 BT_INFO("Failed to save node Netkey!");
1411 param.op = BLUETOOTH_MESH_NODE_KEY_ADD;
1412 } else if (cmd->opcode == MESH_OPCODE_NETKEY_DELETE) {
1413 if (_bt_mesh_network_delete_remote_node_netkey(
1414 event->net_uuid.uuid, event->source, net_idx)) {
1415 result = BLUETOOTH_ERROR_INTERNAL;
1416 BT_INFO("Failed to delete node Netkey!");
1418 param.op = BLUETOOTH_MESH_NODE_KEY_DELETE;
1419 } else if (cmd->opcode == MESH_OPCODE_NETKEY_UPDATE) {
1420 BT_INFO("Mesh: Resp recvd: MESH_OPCODE_NETKEY_UPDATE");
1421 param.op = BLUETOOTH_MESH_NODE_KEY_UPDATE;
1423 /* Node Net Key Configure event */
1424 __bt_mesh_handle_pending_dev_config_request_info(result,
1425 BT_MESH_NODE_CONFIGURE_KEY,
1426 ¶m, sizeof(bluetooth_mesh_key_configure_t));
1429 case MESH_OPCODE_APPKEY_STATUS: {
1433 bluetooth_mesh_key_configure_t param;
1434 memset(¶m, 0x00, sizeof(bluetooth_mesh_key_configure_t));
1436 BT_INFO("Mesh: Node %4.4x AppKey status %s\n", event->source,
1437 __mesh_status_to_string(data[0]));
1438 net_idx = l_get_le16(data + 1) & 0xfff;
1439 app_idx = l_get_le16(data + 2) >> 4;
1441 BT_INFO("NetKey\t%u (0x%3.3x)\n", net_idx, net_idx);
1442 BT_INFO("AppKey\t%u (0x%3.3x)\n", app_idx, app_idx);
1444 if (data[0] != MESH_STATUS_SUCCESS)
1450 _bt_mesh_util_convert_hex_to_string(
1451 (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1452 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1454 param.primary_unicast = event->source;
1455 param.netkey_idx = net_idx;
1456 param.appkey_idx = app_idx;
1457 param.is_netkey = false;
1459 if (cmd->opcode == MESH_OPCODE_APPKEY_ADD) {
1460 BT_INFO("Mesh: Resp recvd: MESH_OPCODE_APPKEY_ADD");
1461 if (_bt_mesh_network_save_remote_node_appkey(
1462 event->net_uuid.uuid, event->source,
1463 net_idx, app_idx)) {
1464 result = BLUETOOTH_ERROR_INTERNAL;
1465 BT_INFO("Failed to save node Appkey!");
1467 param.op = BLUETOOTH_MESH_NODE_KEY_ADD;
1468 } else if (cmd->opcode == MESH_OPCODE_APPKEY_DELETE) {
1469 BT_INFO("Mesh: Resp recvd: MESH_OPCODE_APPKEY_DELETE");
1470 if (_bt_mesh_network_delete_remote_node_appkey(
1471 event->net_uuid.uuid, event->source,
1472 net_idx, app_idx)) {
1473 result = BLUETOOTH_ERROR_INTERNAL;
1474 BT_INFO("Failed to delete node Appkey!");
1476 param.op = BLUETOOTH_MESH_NODE_KEY_DELETE;
1477 } else if (cmd->opcode == MESH_OPCODE_APPKEY_UPDATE) {
1478 BT_INFO("Mesh: Resp recvd: MESH_OPCODE_APPKEY_UPDATE");
1479 param.op = BLUETOOTH_MESH_NODE_KEY_UPDATE;
1482 /* Node App Key Configure event */
1483 __bt_mesh_handle_pending_dev_config_request_info(result,
1484 BT_MESH_NODE_CONFIGURE_KEY,
1485 ¶m, sizeof(bluetooth_mesh_key_configure_t));
1491 static gboolean __bt_mesh_vendor_feature_event_handler(gpointer data)
1493 bluetooth_mesh_node_features_t *result = (bluetooth_mesh_node_features_t*) data;
1494 __bt_mesh_handle_pending_dev_config_request_info(
1495 BLUETOOTH_ERROR_NONE,
1496 BT_MESH_NODE_GET_VENDOR_FEATURES,
1497 result, sizeof(bluetooth_mesh_node_features_t));
1502 int _bt_mesh_node_discover_vendor_features(const char *app_cred, const char *sender,
1503 bluetooth_mesh_node_features_t *req)
1505 int ret = OAL_STATUS_SUCCESS;
1507 uint16_t netkey_idx;
1509 oal_uuid_t net_uuid;
1510 uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
1512 _bt_mesh_util_convert_string_to_hex(req->net_uuid,
1513 strlen(req->net_uuid), net_uuid.uuid, 16);
1514 /* Check if Node's vendor features are already svaed or not */
1515 if (_bt_mesh_node_get_vendor_features(net_uuid.uuid, req->unicast, req)) {
1516 /* Schedule event ot Application */
1517 bluetooth_mesh_node_features_t *event = \
1518 g_memdup(req, sizeof(bluetooth_mesh_node_features_t));
1519 g_idle_add(__bt_mesh_vendor_feature_event_handler, (gpointer) event);
1520 return BLUETOOTH_ERROR_NONE;
1523 /* If Scanning is going on */
1524 if (_bt_mesh_is_provisioning() ||
1525 _bt_mesh_is_scanning()) {
1526 BT_ERR("Device is buzy..");
1527 return BLUETOOTH_ERROR_DEVICE_BUSY;
1530 _bt_mesh_util_convert_string_to_hex(req->net_uuid,
1531 strlen(req->net_uuid), net_uuid.uuid, 16);
1533 dest = req->unicast;
1535 /* Check pending request */
1536 if (_bt_mesh_check_pending_request(MESH_OPCODE_DEV_COMP_GET,
1537 dest, net_uuid.uuid)) {
1538 BT_ERR("Device is buzy..");
1539 return BLUETOOTH_ERROR_DEVICE_BUSY;
1542 /* Get Subnet index of the rmeote node for TX encryption */
1543 netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, dest);
1544 if (netkey_idx == MESH_NET_IDX_INVALID)
1545 return BLUETOOTH_ERROR_INTERNAL;
1547 data_len = _bt_mesh_util_opcode_set(MESH_OPCODE_DEV_COMP_GET,
1550 /* By default, use page 0 */
1551 buffer[data_len++] = 0;
1552 ret = mesh_conf_send_message(&net_uuid, dest, true,
1553 netkey_idx, buffer, data_len);
1555 if (ret != OAL_STATUS_SUCCESS) {
1556 BT_ERR("ret: %d", ret);
1557 return BLUETOOTH_ERROR_INTERNAL;
1560 /* Queue the request with timeout */
1561 __bt_mesh_add_request(MESH_OPCODE_DEV_COMP_GET,
1562 dest, net_uuid.uuid, NULL);
1563 return BLUETOOTH_ERROR_NONE;
1566 int _bt_mesh_browse_remote_node(const char *app_cred,
1568 bluetooth_mesh_node_discover_t *req)
1570 int ret = OAL_STATUS_SUCCESS;
1572 uint16_t netkey_idx;
1574 oal_uuid_t net_uuid;
1575 oal_uuid_t dev_uuid;
1576 uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
1578 /* If Scanning is going on */
1579 if (_bt_mesh_is_provisioning() ||
1580 _bt_mesh_is_scanning()) {
1581 BT_ERR("Device is buzy..");
1582 return BLUETOOTH_ERROR_DEVICE_BUSY;
1585 _bt_mesh_util_convert_string_to_hex(req->net_uuid,
1586 strlen(req->net_uuid), net_uuid.uuid, 16);
1587 _bt_mesh_util_convert_string_to_hex(req->dev_uuid,
1588 strlen(req->dev_uuid), dev_uuid.uuid, 16);
1590 /* Get Remote Node unicast address from Dev UUID */
1591 if (!_bt_mesh_node_get_unicast_from_dev_uuid(net_uuid.uuid,
1592 dev_uuid.uuid, &dest))
1593 return BLUETOOTH_ERROR_INTERNAL;
1595 /* Check pending request */
1596 if (_bt_mesh_check_pending_request(MESH_OPCODE_DEV_COMP_GET,
1597 dest, net_uuid.uuid)) {
1598 BT_ERR("Device is buzy..");
1599 return BLUETOOTH_ERROR_DEVICE_BUSY;
1602 /* Get Subnet index of the rmeote node for TX encryption */
1603 netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, dest);
1604 if (netkey_idx == MESH_NET_IDX_INVALID)
1605 return BLUETOOTH_ERROR_INTERNAL;
1607 data_len = _bt_mesh_util_opcode_set(MESH_OPCODE_DEV_COMP_GET, buffer);
1609 /* By default, use page 0 */
1610 buffer[data_len++] = 0;
1611 ret = mesh_conf_send_message(&net_uuid, dest, true,
1612 netkey_idx, buffer, data_len);
1614 if (ret != OAL_STATUS_SUCCESS) {
1615 BT_ERR("ret: %d", ret);
1616 return BLUETOOTH_ERROR_INTERNAL;
1619 /* Queue the request with timeout */
1620 __bt_mesh_add_request(MESH_OPCODE_DEV_COMP_GET,
1621 dest, net_uuid.uuid, NULL);
1622 return BLUETOOTH_ERROR_NONE;
1625 int _bt_mesh_model_configure_group_subscription(const char *app_cred,
1626 const char *sender, bluetooth_mesh_model_configure_t *req)
1628 int ret = OAL_STATUS_SUCCESS;
1629 uint16_t netkey_idx;
1630 oal_uuid_t net_uuid;
1632 uint32_t opcode = 0;
1633 uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
1635 /* If Scanning is going on */
1636 if (_bt_mesh_is_provisioning() ||
1637 _bt_mesh_is_scanning()) {
1638 BT_ERR("Device is buzy..");
1639 return BLUETOOTH_ERROR_DEVICE_BUSY;
1642 if (req->op != BLUETOOTH_MESH_MODEL_SUB_DELETE_ALL) {
1643 /* Subscriptio address sanity check */
1644 if ((!MESH_IS_GROUP(req->sub_addr) ||
1645 MESH_IS_ALL_NODES(req->sub_addr)) ||
1646 MESH_IS_VIRTUAL(req->sub_addr)) {
1647 BT_ERR("Mesh: Bad subscription address %x\n",
1649 return BLUETOOTH_ERROR_INVALID_PARAM;
1653 /* Get Subnet index of the remote node for TX encryption */
1654 netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid,
1655 req->primary_unicast);
1656 if (netkey_idx == MESH_NET_IDX_INVALID)
1657 return BLUETOOTH_ERROR_INTERNAL;
1659 _bt_mesh_util_convert_string_to_hex(req->net_uuid,
1660 strlen(req->net_uuid), net_uuid.uuid, 16);
1662 if (req->op == BLUETOOTH_MESH_MODEL_SUB_ADD)
1663 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_ADD;
1664 else if (req->op == BLUETOOTH_MESH_MODEL_SUB_DELETE)
1665 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_DELETE;
1666 else if (req->op == BLUETOOTH_MESH_MODEL_SUB_DELETE_ALL)
1667 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_DELETE_ALL;
1668 else if (req->op == BLUETOOTH_MESH_MODEL_SUB_OVERWRITE)
1669 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_OVERWRITE;
1671 /* Check pending request */
1672 if (_bt_mesh_check_pending_request(opcode,
1673 req->primary_unicast, net_uuid.uuid)) {
1674 BT_ERR("Device is buzy..");
1675 return BLUETOOTH_ERROR_DEVICE_BUSY;
1678 data_len = _bt_mesh_util_opcode_set(opcode, buffer);
1680 /* Element Address */
1681 l_put_le16((req->primary_unicast + req->elem_index),
1685 /* Subscription address */
1686 if (req->op != BLUETOOTH_MESH_MODEL_SUB_DELETE_ALL) {
1687 l_put_le16(req->sub_addr, buffer + data_len);
1691 /* Insert Model ID */
1692 if (req->model >= 0xFFFF0000) {
1693 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
1694 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
1697 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
1698 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
1700 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
1704 ret = mesh_conf_send_message(&net_uuid, req->primary_unicast, true,
1705 netkey_idx, buffer, data_len);
1707 if (ret != OAL_STATUS_SUCCESS) {
1708 BT_ERR("ret: %d", ret);
1709 return BLUETOOTH_ERROR_INTERNAL;
1712 /* Queue the request with timeout */
1713 __bt_mesh_add_request(opcode, req->primary_unicast,
1715 g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
1717 return BLUETOOTH_ERROR_NONE;
1720 int _bt_mesh_model_configure_virtual_group_subscription(
1721 const char *app_cred, const char *sender,
1722 bluetooth_mesh_model_configure_t *req)
1724 int ret = OAL_STATUS_SUCCESS;
1725 uint16_t netkey_idx;
1726 oal_uuid_t net_uuid;
1728 uint32_t opcode = 0;
1729 uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
1731 /* If Scanning is going on */
1732 if (_bt_mesh_is_provisioning() ||
1733 _bt_mesh_is_scanning()) {
1734 BT_ERR("Device is buzy..");
1735 return BLUETOOTH_ERROR_DEVICE_BUSY;
1738 _bt_mesh_util_convert_string_to_hex(req->net_uuid,
1739 strlen(req->net_uuid), net_uuid.uuid, 16);
1741 if (req->op != BLUETOOTH_MESH_MODEL_SUB_DELETE_ALL) {
1742 /* Subscription address sanity check */
1743 if ((MESH_IS_GROUP(req->sub_addr) ||
1744 MESH_IS_ALL_NODES(req->sub_addr)) ||
1745 !(MESH_IS_VIRTUAL(req->sub_addr))) {
1746 BT_ERR("Mesh: Bad Virtual subscription address %x\n",
1748 return BLUETOOTH_ERROR_INVALID_PARAM;
1752 /* Get Subnet index of the remote node for TX encryption */
1753 netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid,
1754 req->primary_unicast);
1755 if (netkey_idx == MESH_NET_IDX_INVALID)
1756 return BLUETOOTH_ERROR_INTERNAL;
1758 if (req->op == BLUETOOTH_MESH_MODEL_SUB_ADD)
1759 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_ADD;
1760 else if (req->op == BLUETOOTH_MESH_MODEL_SUB_DELETE)
1761 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_DELETE;
1762 else if (req->op == BLUETOOTH_MESH_MODEL_SUB_DELETE_ALL)
1763 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_DELETE_ALL;
1764 else if (req->op == BLUETOOTH_MESH_MODEL_SUB_OVERWRITE)
1765 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_OVERWRITE;
1767 /* Check pending request */
1768 if (_bt_mesh_check_pending_request(opcode,
1769 req->primary_unicast, net_uuid.uuid)) {
1770 BT_ERR("Device is buzy..");
1771 return BLUETOOTH_ERROR_DEVICE_BUSY;
1774 data_len = _bt_mesh_util_opcode_set(opcode, buffer);
1776 /* Element Address */
1777 l_put_le16((req->primary_unicast + req->elem_index), buffer + data_len);
1780 /* Subscription address */
1781 if (req->op != BLUETOOTH_MESH_MODEL_SUB_DELETE_ALL) {
1782 uint8_t label_uuid[16];
1783 if (!_bt_mesh_network_get_label_uuid_from_sub_addr(
1784 net_uuid.uuid, req->sub_addr, label_uuid)) {
1785 BT_ERR("Mesh: Virtual Group Label UUID Not found");
1786 return BLUETOOTH_ERROR_INVALID_PARAM;
1788 memcpy(buffer + data_len, label_uuid, 16);
1792 /* Insert Model ID */
1793 if (req->model >= 0xFFFF0000) {
1794 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
1795 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
1798 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
1799 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
1801 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
1805 ret = mesh_conf_send_message(&net_uuid,
1806 req->primary_unicast, true,
1807 netkey_idx, buffer, data_len);
1809 if (ret != OAL_STATUS_SUCCESS) {
1810 BT_ERR("ret: %d", ret);
1811 return BLUETOOTH_ERROR_INTERNAL;
1814 /* Queue the request with timeout */
1815 __bt_mesh_add_request(opcode, req->primary_unicast,
1817 g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
1819 return BLUETOOTH_ERROR_NONE;
1822 int _bt_mesh_model_get_publication(const char *app_cred, const char *sender,
1823 bluetooth_mesh_model_configure_t *req)
1825 int ret = OAL_STATUS_SUCCESS;
1826 uint16_t netkey_idx;
1827 oal_uuid_t net_uuid;
1829 uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
1831 /* If Scanning is going on */
1832 if (_bt_mesh_is_provisioning() ||
1833 _bt_mesh_is_scanning()) {
1834 BT_ERR("Device is buzy..");
1835 return BLUETOOTH_ERROR_DEVICE_BUSY;
1838 _bt_mesh_util_convert_string_to_hex(req->net_uuid,
1839 strlen(req->net_uuid), net_uuid.uuid, 16);
1841 /* Check pending request */
1842 if (_bt_mesh_check_pending_request(MESH_OPCODE_CONFIG_MODEL_PUB_GET,
1843 req->primary_unicast, net_uuid.uuid)) {
1844 BT_ERR("Device is buzy..");
1845 return BLUETOOTH_ERROR_DEVICE_BUSY;
1848 /* Get Subnet index of the remote node for TX encryption */
1849 netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, req->primary_unicast);
1850 if (netkey_idx == MESH_NET_IDX_INVALID)
1851 return BLUETOOTH_ERROR_INTERNAL;
1854 data_len = _bt_mesh_util_opcode_set(MESH_OPCODE_CONFIG_MODEL_PUB_GET, buffer);
1856 /* Element Address */
1857 l_put_le16((req->primary_unicast + req->elem_index), buffer + data_len);
1860 /* Insert Model ID */
1861 if (req->model >= 0xFFFF0000) {
1862 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
1863 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
1866 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
1867 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
1869 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
1873 ret = mesh_conf_send_message(&net_uuid, req->primary_unicast, true, netkey_idx, buffer, data_len);
1875 if (ret != OAL_STATUS_SUCCESS) {
1876 BT_ERR("ret: %d", ret);
1877 return BLUETOOTH_ERROR_INTERNAL;
1880 /* Queue the request with timeout */
1881 __bt_mesh_add_request(MESH_OPCODE_CONFIG_MODEL_PUB_GET, req->primary_unicast, net_uuid.uuid,
1882 g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
1884 return BLUETOOTH_ERROR_NONE;
1887 int _bt_mesh_model_set_publication(const char *app_cred, const char *sender,
1888 bluetooth_mesh_model_configure_t *req)
1890 int ret = OAL_STATUS_SUCCESS;
1891 uint16_t netkey_idx;
1892 oal_uuid_t net_uuid;
1894 uint32_t opcode = 0;
1895 uint8_t label_uuid[16];
1896 uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
1898 /* If Scanning is going on */
1899 if (_bt_mesh_is_provisioning() ||
1900 _bt_mesh_is_scanning()) {
1901 BT_ERR("Device is buzy..");
1902 return BLUETOOTH_ERROR_DEVICE_BUSY;
1905 _bt_mesh_util_convert_string_to_hex(req->net_uuid, strlen(req->net_uuid), net_uuid.uuid, 16);
1907 if (req->pub_addr > MESH_ALL_NODES_ADDRESS)
1908 return BLUETOOTH_ERROR_INVALID_PARAM;
1911 if (!MESH_IS_GROUP(req->pub_addr) && !MESH_IS_VIRTUAL(req->pub_addr) &&
1912 req->pub_addr != MESH_UNASSIGNED_ADDRESS) {
1913 BT_ERR("Mesh: Bad Publication address %x\n", req->pub_addr);
1914 return BLUETOOTH_ERROR_INVALID_PARAM;
1917 if (req->pub_addr != MESH_UNASSIGNED_ADDRESS) {
1918 if (MESH_IS_VIRTUAL(req->pub_addr)) {
1919 if(!_bt_mesh_network_get_label_uuid_from_sub_addr(
1920 net_uuid.uuid, req->pub_addr, label_uuid))
1921 return BLUETOOTH_ERROR_INVALID_PARAM;
1922 opcode = MESH_OPCODE_CONFIG_MODEL_PUB_VIRT_SET;
1924 } else if (MESH_IS_GROUP(req->pub_addr))
1925 opcode = MESH_OPCODE_CONFIG_MODEL_PUB_SET;
1928 /* Check pending request */
1929 if (_bt_mesh_check_pending_request(opcode,
1930 req->primary_unicast, net_uuid.uuid)) {
1931 BT_ERR("Device is buzy..");
1932 return BLUETOOTH_ERROR_DEVICE_BUSY;
1935 /* Get Subnet index of the remote node for TX encryption */
1936 netkey_idx = _bt_mesh_node_get_subnet_idx(
1937 net_uuid.uuid, req->primary_unicast);
1938 if (netkey_idx == MESH_NET_IDX_INVALID)
1939 return BLUETOOTH_ERROR_INTERNAL;
1942 data_len = _bt_mesh_util_opcode_set(opcode, buffer);
1944 /* Element Address */
1945 l_put_le16((req->primary_unicast + req->elem_index), buffer + data_len);
1948 /* Fill Publication Address */
1949 if (MESH_IS_VIRTUAL(req->pub_addr)) {
1950 memcpy(buffer + data_len, label_uuid, 16);
1953 l_put_le16(req->pub_addr, buffer + data_len);
1957 /* AppKey index + credential (set to 0) */
1958 l_put_le16(req->appkey_idx, buffer + data_len);
1962 buffer[data_len++] = req->ttl;
1963 /* Publish period step count and step resolution */
1964 buffer[data_len++] = req->period;
1965 /* Publish retransmit count & interval steps */
1966 buffer[data_len++] = req->retransmit;
1968 /* Insert Model ID */
1969 if (req->model >= 0xFFFF0000) {
1970 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
1971 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
1974 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
1975 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
1977 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
1981 ret = mesh_conf_send_message(&net_uuid,
1982 req->primary_unicast, true,
1983 netkey_idx, buffer, data_len);
1985 if (ret != OAL_STATUS_SUCCESS) {
1986 BT_ERR("ret: %d", ret);
1987 return BLUETOOTH_ERROR_INTERNAL;
1990 /* Queue the request with timeout */
1991 __bt_mesh_add_request(opcode, req->primary_unicast, net_uuid.uuid,
1992 g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
1994 return BLUETOOTH_ERROR_NONE;
1997 int _bt_mesh_node_model_get_subscription_list(const char *app_cred, const char *sender,
1998 bluetooth_mesh_model_configure_t *req)
2000 int ret = OAL_STATUS_SUCCESS;
2001 uint16_t netkey_idx;
2002 oal_uuid_t net_uuid;
2004 uint32_t opcode = 0;
2005 uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
2007 /* If Scanning is going on */
2008 if (_bt_mesh_is_provisioning() ||
2009 _bt_mesh_is_scanning()) {
2010 BT_ERR("Device is buzy..");
2011 return BLUETOOTH_ERROR_DEVICE_BUSY;
2014 _bt_mesh_util_convert_string_to_hex(req->net_uuid, strlen(req->net_uuid), net_uuid.uuid, 16);
2016 /* Insert Model ID */
2017 if (req->model >= 0xFFFF0000)
2018 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
2019 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_GET;
2021 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
2022 opcode = MESH_OPCODE_CONFIG_VEND_MODEL_SUB_GET;
2024 /* Check pending request */
2025 if (_bt_mesh_check_pending_request(opcode,
2026 req->primary_unicast, net_uuid.uuid)) {
2027 BT_ERR("Device is buzy..");
2028 return BLUETOOTH_ERROR_DEVICE_BUSY;
2030 /* Get Subnet index of the remote node for TX encryption */
2031 netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, req->primary_unicast);
2032 if (netkey_idx == MESH_NET_IDX_INVALID)
2033 return BLUETOOTH_ERROR_INTERNAL;
2035 data_len = _bt_mesh_util_opcode_set(opcode, buffer);
2036 /* Element Address */
2037 l_put_le16((req->primary_unicast + req->elem_index), buffer + data_len);
2041 /* Insert Model ID */
2042 if (opcode == MESH_OPCODE_CONFIG_MODEL_SUB_GET) {
2043 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
2044 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2047 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
2048 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
2050 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2054 ret = mesh_conf_send_message(&net_uuid,
2055 req->primary_unicast, true, netkey_idx, buffer, data_len);
2057 if (ret != OAL_STATUS_SUCCESS) {
2058 BT_ERR("ret: %d", ret);
2059 return BLUETOOTH_ERROR_INTERNAL;
2062 /* Queue the request with timeout */
2063 __bt_mesh_add_request(opcode, req->primary_unicast, net_uuid.uuid,
2064 g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
2066 return BLUETOOTH_ERROR_NONE;
2069 int _bt_mesh_node_model_get_appkey_list(const char *app_cred, const char *sender,
2070 bluetooth_mesh_model_configure_t *req)
2072 int ret = OAL_STATUS_SUCCESS;
2073 uint16_t netkey_idx;
2074 oal_uuid_t net_uuid;
2076 uint32_t opcode = 0;
2077 uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
2079 /* If Scanning is going on */
2080 if (_bt_mesh_is_provisioning() ||
2081 _bt_mesh_is_scanning()) {
2082 BT_ERR("Device is buzy..");
2083 return BLUETOOTH_ERROR_DEVICE_BUSY;
2086 _bt_mesh_util_convert_string_to_hex(req->net_uuid,
2087 strlen(req->net_uuid), net_uuid.uuid, 16);
2089 /* Insert Model ID */
2090 if (req->model >= 0xFFFF0000)
2091 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
2092 opcode = MESH_OPCODE_MODEL_APP_GET;
2094 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
2095 opcode = MESH_OPCODE_VENDOR_MODEL_APP_GET;
2097 /* Check pending request */
2098 if (_bt_mesh_check_pending_request(opcode,
2099 req->primary_unicast, net_uuid.uuid)) {
2100 BT_ERR("Device is buzy..");
2101 return BLUETOOTH_ERROR_DEVICE_BUSY;
2103 /* Get Subnet index of the remote node for TX encryption */
2104 netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, req->primary_unicast);
2105 if (netkey_idx == MESH_NET_IDX_INVALID)
2106 return BLUETOOTH_ERROR_INTERNAL;
2108 data_len = _bt_mesh_util_opcode_set(opcode, buffer);
2109 /* Element Address */
2110 l_put_le16((req->primary_unicast + req->elem_index), buffer + data_len);
2114 /* Insert Model ID */
2115 if (opcode == MESH_OPCODE_MODEL_APP_GET) {
2116 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
2117 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2120 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
2121 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
2123 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2127 ret = mesh_conf_send_message(&net_uuid, req->primary_unicast, true, netkey_idx, buffer, data_len);
2129 if (ret != OAL_STATUS_SUCCESS) {
2130 BT_ERR("ret: %d", ret);
2131 return BLUETOOTH_ERROR_INTERNAL;
2134 /* Queue the request with timeout */
2135 __bt_mesh_add_request(opcode, req->primary_unicast, net_uuid.uuid,
2136 g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
2138 return BLUETOOTH_ERROR_NONE;
2141 int _bt_mesh_node_model_appkey_execute(const char *app_cred, const char *sender,
2142 bluetooth_mesh_model_configure_t *req)
2144 int ret = OAL_STATUS_SUCCESS;
2145 uint16_t netkey_idx;
2146 oal_uuid_t net_uuid;
2148 uint32_t opcode = 0;
2149 uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
2151 /* If Scanning is going on */
2152 if (_bt_mesh_is_provisioning() ||
2153 _bt_mesh_is_scanning()) {
2154 BT_ERR("Device is buzy..");
2155 return BLUETOOTH_ERROR_DEVICE_BUSY;
2158 _bt_mesh_util_convert_string_to_hex(req->net_uuid, strlen(req->net_uuid), net_uuid.uuid, 16);
2160 /* Check pending request */
2161 if (_bt_mesh_check_pending_request(req->is_bind ? MESH_OPCODE_MODEL_APP_BIND : MESH_OPCODE_MODEL_APP_UNBIND,
2162 req->primary_unicast, net_uuid.uuid)) {
2163 BT_ERR("Device is buzy..");
2164 return BLUETOOTH_ERROR_DEVICE_BUSY;
2166 /* Get Subnet index of the remote node for TX encryption */
2167 netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, req->primary_unicast);
2168 if (netkey_idx == MESH_NET_IDX_INVALID)
2169 return BLUETOOTH_ERROR_INTERNAL;
2172 opcode = MESH_OPCODE_MODEL_APP_BIND;
2174 opcode = MESH_OPCODE_MODEL_APP_UNBIND;
2176 data_len = _bt_mesh_util_opcode_set(opcode, buffer);
2177 /* Element Address */
2178 l_put_le16((req->primary_unicast + req->elem_index), buffer + data_len);
2182 l_put_le16(req->appkey_idx, buffer + data_len);
2185 /* Insert Model ID */
2186 if (req->model >= 0xFFFF0000) {
2187 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
2188 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2191 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
2192 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
2194 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2198 ret = mesh_conf_send_message(&net_uuid, req->primary_unicast, true, netkey_idx, buffer, data_len);
2200 if (ret != OAL_STATUS_SUCCESS) {
2201 BT_ERR("ret: %d", ret);
2202 return BLUETOOTH_ERROR_INTERNAL;
2205 /* Queue the request with timeout */
2206 __bt_mesh_add_request(opcode, req->primary_unicast, net_uuid.uuid,
2207 g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
2209 return BLUETOOTH_ERROR_NONE;
2212 int _bt_mesh_ttl_execute_remote_node(const char *app_cred, const char *sender,
2213 bluetooth_mesh_node_ttl_info_t *req)
2215 int ret = OAL_STATUS_SUCCESS;
2216 uint16_t netkey_idx;
2218 oal_uuid_t net_uuid;
2219 uint32_t opcode = 0;
2220 uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
2222 /* If Scanning is going on */
2223 if (_bt_mesh_is_provisioning() ||
2224 _bt_mesh_is_scanning()) {
2225 BT_ERR("Device is buzy..");
2226 return BLUETOOTH_ERROR_DEVICE_BUSY;
2229 _bt_mesh_util_convert_string_to_hex(req->net_uuid, strlen(req->net_uuid), net_uuid.uuid, 16);
2231 /* Check pending request */
2232 if (_bt_mesh_check_pending_request(req->is_set ? MESH_OPCODE_CONFIG_DEFAULT_TTL_SET : MESH_OPCODE_CONFIG_DEFAULT_TTL_GET,
2233 req->unicast, net_uuid.uuid)) {
2234 BT_ERR("Device is buzy..");
2235 return BLUETOOTH_ERROR_DEVICE_BUSY;
2238 /* Get Subnet index of the rmeote node for TX encryption */
2239 netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, req->unicast);
2240 if (netkey_idx == MESH_NET_IDX_INVALID)
2241 return BLUETOOTH_ERROR_INTERNAL;
2244 opcode = MESH_OPCODE_CONFIG_DEFAULT_TTL_SET;
2245 data_len = _bt_mesh_util_opcode_set(MESH_OPCODE_CONFIG_DEFAULT_TTL_SET, buffer);
2246 buffer[data_len++] = req->ttl;
2248 opcode = MESH_OPCODE_CONFIG_DEFAULT_TTL_GET;
2249 data_len = _bt_mesh_util_opcode_set(MESH_OPCODE_CONFIG_DEFAULT_TTL_GET, buffer);
2252 ret = mesh_conf_send_message(&net_uuid, req->unicast, true, netkey_idx, buffer, data_len);
2254 if (ret != OAL_STATUS_SUCCESS) {
2255 BT_ERR("ret: %d", ret);
2256 return BLUETOOTH_ERROR_INTERNAL;
2259 /* Queue the request with timeout */
2260 __bt_mesh_add_request(opcode, req->unicast, net_uuid.uuid,
2261 g_memdup(req, sizeof(bluetooth_mesh_node_ttl_info_t)));
2262 return BLUETOOTH_ERROR_NONE;
2265 static bool __bt_mesh_check_pending_key_cmd(uint16_t dest, bool is_netkey,
2266 bluetooth_mesh_node_key_conf_e op, uint8_t net_uuid[], uint32_t *opcode)
2268 const struct mesh_config_cmd *cmd;
2272 case BLUETOOTH_MESH_NODE_KEY_ADD:
2273 cmd = __mesh_get_command(MESH_OPCODE_NETKEY_ADD);
2276 if (__bt_mesh_get_request_by_response(dest, net_uuid, cmd->response)) {
2277 BT_ERR("Mesh:Another Key Configuration command is pending\n");
2280 *opcode = MESH_OPCODE_NETKEY_ADD;
2282 case BLUETOOTH_MESH_NODE_KEY_DELETE:
2283 cmd = __mesh_get_command(MESH_OPCODE_NETKEY_DELETE);
2286 if (__bt_mesh_get_request_by_response(dest, net_uuid, cmd->response)) {
2287 BT_ERR("Mesh:Another Key Configuration command is pending\n");
2290 *opcode = MESH_OPCODE_NETKEY_DELETE;
2292 case BLUETOOTH_MESH_NODE_KEY_UPDATE:
2293 cmd = __mesh_get_command(MESH_OPCODE_NETKEY_UPDATE);
2296 if (__bt_mesh_get_request_by_response(dest, net_uuid, cmd->response)) {
2297 BT_ERR("Mesh:Another Key Configuration command is pending\n");
2300 *opcode = MESH_OPCODE_NETKEY_UPDATE;
2305 case BLUETOOTH_MESH_NODE_KEY_ADD:
2306 cmd = __mesh_get_command(MESH_OPCODE_APPKEY_ADD);
2309 if (__bt_mesh_get_request_by_response(dest, net_uuid, cmd->response)) {
2310 BT_ERR("Mesh:Another Key Configuration command is pending\n");
2313 *opcode = MESH_OPCODE_APPKEY_ADD;
2315 case BLUETOOTH_MESH_NODE_KEY_DELETE:
2316 cmd = __mesh_get_command(MESH_OPCODE_APPKEY_DELETE);
2319 if (__bt_mesh_get_request_by_response(dest, net_uuid, cmd->response)) {
2320 BT_ERR("Mesh:Another Key Configuration command is pending\n");
2323 *opcode = MESH_OPCODE_APPKEY_DELETE;
2325 case BLUETOOTH_MESH_NODE_KEY_UPDATE:
2326 cmd = __mesh_get_command(MESH_OPCODE_APPKEY_UPDATE);
2329 if (__bt_mesh_get_request_by_response(dest, net_uuid, cmd->response)) {
2330 BT_ERR("Mesh:Another Key Configuration command is pending\n");
2333 *opcode = MESH_OPCODE_APPKEY_UPDATE;
2340 int _bt_mesh_node_configure_key(const char *app_cred, const char *sender,
2341 bluetooth_mesh_key_configure_t *req)
2343 int ret = OAL_STATUS_SUCCESS;
2344 uint16_t netkey_idx;
2345 uint16_t bound_netkey_idx = 0x0000;
2346 oal_uuid_t net_uuid;
2347 uint32_t opcode = 0;
2350 uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
2352 /* If Scanning is going on */
2353 if (_bt_mesh_is_provisioning() ||
2354 _bt_mesh_is_scanning()) {
2355 BT_ERR("Device is buzy..");
2356 return BLUETOOTH_ERROR_DEVICE_BUSY;
2359 _bt_mesh_util_convert_string_to_hex(req->net_uuid, strlen(req->net_uuid), net_uuid.uuid, 16);
2361 if (req->is_netkey && _bt_mesh_keys_subnet_exists(net_uuid.uuid, req->netkey_idx)) {
2362 BT_ERR("Local Subnet not found..");
2363 return BLUETOOTH_ERROR_INVALID_PARAM;
2366 /* For Appkey Configuration, check for available bound netkey */
2367 if (!req->is_netkey) {
2368 bound_netkey_idx = _bt_mesh_keys_get_bound_key(net_uuid.uuid, req->appkey_idx);
2369 if (bound_netkey_idx == MESH_NET_IDX_INVALID) {
2370 BT_ERR("Local AppKey not found..");
2371 return BLUETOOTH_ERROR_INVALID_PARAM;
2375 /* Check pending request */
2376 if (__bt_mesh_check_pending_key_cmd(req->primary_unicast,
2377 req->is_netkey, req->op, net_uuid.uuid, &opcode)) {
2378 BT_ERR("Device is buzy..");
2379 return BLUETOOTH_ERROR_DEVICE_BUSY;
2382 /* Get Subnet index of the rmeote node for TX encryption */
2383 netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, req->primary_unicast);
2384 if (netkey_idx == MESH_NET_IDX_INVALID)
2385 return BLUETOOTH_ERROR_INTERNAL;
2387 /* Handle Key (App/Net) Delete Commands: Configuration Message */
2388 if (opcode == MESH_OPCODE_NETKEY_DELETE || opcode == MESH_OPCODE_APPKEY_DELETE) {
2389 data_len = _bt_mesh_util_opcode_set(opcode, buffer);
2390 if (req->is_netkey) {
2391 l_put_le16(req->netkey_idx, buffer + data_len);
2394 buffer[data_len] = bound_netkey_idx;
2395 buffer[data_len + 1] = ((bound_netkey_idx >> 8) & 0xf) | ((req->appkey_idx << 4) & 0xf0);
2396 buffer[data_len + 2] = req->appkey_idx >> 4;
2400 ret = mesh_conf_send_message(&net_uuid, req->primary_unicast, true, netkey_idx, buffer, data_len);
2402 /* Handle Key (App/Net) Update & Add Commands: Key Config message */
2403 update = (opcode == MESH_OPCODE_NETKEY_UPDATE || opcode == MESH_OPCODE_APPKEY_UPDATE);
2404 ret = mesh_conf_send_key_message(&net_uuid, req->primary_unicast, req->is_netkey,
2405 update, req->is_netkey? req->netkey_idx: req->appkey_idx, netkey_idx);
2407 if (ret != OAL_STATUS_SUCCESS) {
2408 BT_ERR("ret: %d", ret);
2409 return BLUETOOTH_ERROR_INTERNAL;
2412 /* Queue the request with timeout */
2413 __bt_mesh_add_request(opcode, req->primary_unicast, net_uuid.uuid,
2414 g_memdup(req, sizeof(bluetooth_mesh_key_configure_t)));
2415 return BLUETOOTH_ERROR_NONE;