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 BT_INFO("Mesh: Number of pending requests [%u] Remove the req",
273 l_queue_length(pending_requests));
274 l_queue_remove(pending_requests, req);
275 __mesh_request_remove(req);
278 static void __bt_mesh_add_request(uint32_t opcode, uint16_t dest,
279 uint8_t net_uuid[], void *data)
281 struct mesh_pending_request *req;
282 const struct mesh_config_cmd *cmd;
285 cmd = __mesh_get_command(opcode);
288 _bt_mesh_util_convert_hex_to_string((uint8_t *) net_uuid, 16, uuid_str,
289 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
290 BT_INFO("Mesh: Net UUID[%s]",uuid_str);
292 BT_INFO("Mesh: Adding command opcode [0x%2.2x] response [0x%2.2x]",
293 cmd->opcode, cmd->response);
294 req = l_new(struct mesh_pending_request, 1);
298 memcpy(req->net_uuid, net_uuid, 16);
299 req->timer = l_timeout_create(MESH_DEFAULT_RESPONSE_TIMEOUT,
300 __bt_mesh_wait_response_timeout, req, NULL);
302 if (!pending_requests)
303 pending_requests = l_queue_new();
304 l_queue_push_tail(pending_requests, req);
305 BT_INFO("Mesh: Number of pending requests [%u]", l_queue_length(pending_requests));
308 static struct mesh_pending_request *__bt_mesh_get_request_by_response(
309 uint16_t addr, uint8_t net_uuid[],
312 const struct l_queue_entry *entry;
316 BT_INFO("Mesh: Number of pending requests [%u]", l_queue_length(pending_requests));
317 entry = l_queue_get_entries(pending_requests);
319 for (; entry; entry = entry->next) {
320 struct mesh_pending_request *req = entry->data;
323 BT_INFO("Mesh: Req addr [0x%2.2x] req opcode [0x%2.2x] res [0x%2.2x]", req->addr, req->cmd->opcode, req->cmd->response);
324 BT_INFO("Mesh: Current req addr [0x%2.2x] res [0x%2.2x]", addr, response);
325 _bt_mesh_util_convert_hex_to_string((uint8_t *) net_uuid, 16, uuid_str,
326 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
327 BT_INFO("Mesh: Net UUID[%s]",uuid_str);
329 _bt_mesh_util_convert_hex_to_string((uint8_t *) req->net_uuid, 16, uuid_str1,
330 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
331 BT_INFO("Mesh: Net UUID1[%s]",uuid_str1);
332 if (!memcmp(net_uuid, req->net_uuid, 16) &&
334 req->cmd->response == response)
341 bool _bt_mesh_check_pending_request(uint32_t opcode,
342 uint16_t dest, uint8_t net_uuid[])
344 const struct mesh_config_cmd *cmd;
345 cmd = __mesh_get_command(opcode);
350 if (__bt_mesh_get_request_by_response(dest,
351 net_uuid, cmd->response)) {
352 BT_ERR("Mesh:Another command is pending\n");
358 static uint32_t __bt_mesh_print_model_identifier(uint8_t *data,
359 bool vendor, const char *offset)
364 mod_id = l_get_le16(data);
365 BT_INFO("%sModel ID\t%4.4x\n", offset, mod_id);
366 mod_id = MESH_VENDOR_ID_MASK | mod_id;
368 mod_id = l_get_le16(data + 2);
369 BT_INFO("%sModel ID\t%4.4x %4.4x\n", offset,
370 l_get_le16(data), mod_id);
371 mod_id = l_get_le16(data) << 16 | mod_id;
377 static void __bt_mesh_print_device_composition_data(
378 uint8_t *data, uint16_t len)
383 BT_INFO("Mesh: Received composion:\n");
385 /* skip page -- We only support Page Zero */
389 BT_INFO("\tCID: %4.4x", l_get_le16(&data[0]));
390 BT_INFO("\tPID: %4.4x", l_get_le16(&data[2]));
391 BT_INFO("\tVID: %4.4x", l_get_le16(&data[4]));
392 BT_INFO("\tCRPL: %4.4x", l_get_le16(&data[6]));
394 features = l_get_le16(&data[8]);
398 BT_INFO("\tFeature support:\n");
399 BT_INFO("\t\trelay: %s\n", (features & MESH_FEATURE_RELAY) ?
401 BT_INFO("\t\tproxy: %s\n", (features & MESH_FEATURE_PROXY) ?
403 BT_INFO("\t\tfriend: %s\n", (features & MESH_FEATURE_FRIEND) ?
405 BT_INFO("\t\tlpn: %s\n", (features & MESH_FEATURE_LPN) ?
410 BT_INFO("\t Element %d:\n", i);
411 BT_INFO("\t\tlocation: %4.4x\n", l_get_le16(data));
420 BT_INFO("\t\tSIG defined models:\n");
422 while (len >= 2 && m--) {
423 __bt_mesh_print_model_identifier(data, false, "\t\t ");
429 BT_INFO("\t\t Vendor defined models:\n");
431 while (len >= 4 && v--) {
432 __bt_mesh_print_model_identifier(data, true, "\t\t ");
441 static void __bt_mesh_send_model_publication_status_event(
442 int event, int result,
443 bluetooth_mesh_model_configure_t *evt)
445 GVariant *out_var = NULL, *param = NULL;
448 if (BLUETOOTH_ERROR_NONE == result) {
450 info = g_array_new(FALSE, FALSE, sizeof(gchar));
451 g_array_append_vals(info, evt,
452 sizeof(bluetooth_mesh_model_configure_t));
454 out_var = g_variant_new_from_data((const GVariantType *)"ay",
455 info->data, info->len,
458 param = g_variant_new("(iv)", result, out_var);
459 _bt_send_event(BT_MESH_EVENT, event,
464 static void __bt_mesh_send_model_subscription_configure_event(
465 int event, int result,
466 bluetooth_mesh_model_configure_t *evt)
468 GVariant *out_var = NULL, *param = NULL;
471 if (BLUETOOTH_ERROR_NONE == result) {
473 info = g_array_new(FALSE, FALSE, sizeof(gchar));
474 g_array_append_vals(info, evt,
475 sizeof(bluetooth_mesh_model_configure_t));
477 out_var = g_variant_new_from_data((const GVariantType *)"ay",
478 info->data, info->len,
481 param = g_variant_new("(iv)", result, out_var);
482 _bt_send_event(BT_MESH_EVENT, event,
487 static void __bt_mesh_send_model_get_subscription_list_event(
488 int result, bluetooth_mesh_model_configure_t *evt)
490 GVariant *param = NULL;
491 GVariantBuilder *builder = NULL;
494 if (BLUETOOTH_ERROR_NONE == result) {
495 if (evt->sublist_count) {
496 builder = g_variant_builder_new(G_VARIANT_TYPE("aq"));
497 for (i = 0; i < evt->sublist_count; i++)
498 g_variant_builder_add(builder, "q", *evt->sub_list[i]);
500 param = g_variant_new("(isqiui(aq))", result, evt->net_uuid,
501 evt->primary_unicast, evt->elem_index, evt->model,
502 evt->sublist_count, builder);
504 g_variant_builder_unref(builder);
507 _bt_send_event(BT_MESH_EVENT,
508 BLUETOOTH_EVENT_MESH_MODEL_SUBSCRIPTION_LIST,
511 if (evt->sublist_count) {
513 for (int i = 0; i < evt->sublist_count; i++)
514 g_free(evt->sub_list[i]);
515 g_free(evt->sub_list);
520 static void __bt_mesh_send_model_get_appkey_list_event(int result,
521 bluetooth_mesh_model_configure_t *evt)
523 GVariant *param = NULL;
524 GVariantBuilder *builder = NULL;
527 if (BLUETOOTH_ERROR_NONE == result) {
529 if (evt->appkeylist_count) {
530 builder = g_variant_builder_new(G_VARIANT_TYPE("aq"));
531 for (i = 0; i < evt->appkeylist_count; i++)
532 g_variant_builder_add(builder, "q", *evt->appkey_list[i]);
534 param = g_variant_new("(isqiui(aq))", result, evt->net_uuid,
535 evt->primary_unicast, evt->elem_index, evt->model,
536 evt->appkeylist_count, builder);
538 g_variant_builder_unref(builder);
542 _bt_send_event(BT_MESH_EVENT,
543 BLUETOOTH_EVENT_MESH_MODEL_APPKEY_LIST,
546 if (evt->appkeylist_count) {
548 for (int i = 0; i < evt->appkeylist_count; i++)
549 g_free(evt->appkey_list[i]);
550 g_free(evt->appkey_list);
555 static void __bt_mesh_send_model_configure_appkey_event(int result,
556 bluetooth_mesh_model_configure_t *evt)
558 GVariant *out_var = NULL, *param = NULL;
561 if (BLUETOOTH_ERROR_NONE == result) {
563 info = g_array_new(FALSE, FALSE, sizeof(gchar));
564 g_array_append_vals(info, evt, sizeof(bluetooth_mesh_model_configure_t));
566 out_var = g_variant_new_from_data((const GVariantType *)"ay",
567 info->data, info->len,
570 param = g_variant_new("(iv)", result, out_var);
571 _bt_send_event(BT_MESH_EVENT,
572 BLUETOOTH_EVENT_MESH_NODE_MODEL_APPKEY_BIND,
577 static void __bt_mesh_send_node_ttl_configuration_event(int result,
578 bluetooth_mesh_node_ttl_info_t *ttl_evt)
580 GVariant *out_var = NULL, *param = NULL;
583 if (BLUETOOTH_ERROR_NONE == result) {
585 info = g_array_new(FALSE, FALSE, sizeof(gchar));
586 g_array_append_vals(info, ttl_evt,
587 sizeof(bluetooth_mesh_node_ttl_info_t));
589 out_var = g_variant_new_from_data((const GVariantType *)"ay",
590 info->data, info->len,
593 param = g_variant_new("(iv)", result, out_var);
594 _bt_send_event(BT_MESH_EVENT,
595 BLUETOOTH_EVENT_MESH_NODE_TTL_CONFIGURED,
600 static void __bt_mesh_send_node_key_configuration_event(int result,
601 bluetooth_mesh_key_configure_t *key_evt)
603 GVariant *out_var = NULL, *param = NULL;
606 if (BLUETOOTH_ERROR_NONE == result) {
608 info = g_array_new(FALSE, FALSE, sizeof(gchar));
609 g_array_append_vals(info, key_evt,
610 sizeof(bluetooth_mesh_key_configure_t));
612 out_var = g_variant_new_from_data((const GVariantType *)"ay",
613 info->data, info->len,
616 param = g_variant_new("(iv)", result, out_var);
617 _bt_send_event(BT_MESH_EVENT,
618 BLUETOOTH_EVENT_MESH_NODE_KEY_CONFIGURED,
623 static void __bt_mesh_send_node_get_vendor_features_event(int result,
624 bluetooth_mesh_node_features_t *features_evt)
626 GVariant *out_var = NULL, *param = NULL;
629 if (BLUETOOTH_ERROR_NONE == result) {
631 info = g_array_new(FALSE, FALSE, sizeof(gchar));
632 g_array_append_vals(info, features_evt,
633 sizeof(bluetooth_mesh_node_features_t));
635 out_var = g_variant_new_from_data((const GVariantType *)"ay",
636 info->data, info->len,
639 param = g_variant_new("(iv)", result, out_var);
640 _bt_send_event(BT_MESH_EVENT,
641 BLUETOOTH_EVENT_MESH_NODE_VENDOR_FEATURES,
646 static void __bt_mesh_send_node_browsed_event(int result,
647 bluetooth_mesh_node_discover_t *browse_evt)
649 GVariant *out_var = NULL, *param = NULL;
652 if (BLUETOOTH_ERROR_NONE == result) {
654 info = g_array_new(FALSE, FALSE, sizeof(gchar));
655 g_array_append_vals(info, browse_evt,
656 sizeof(bluetooth_mesh_node_discover_t));
658 out_var = g_variant_new_from_data((const GVariantType *)"ay",
659 info->data, info->len,
662 param = g_variant_new("(iv)", result, out_var);
663 _bt_send_event(BT_MESH_EVENT,
664 BLUETOOTH_EVENT_MESH_NODE_BROWSED,
669 static void __bt_mesh_handle_pending_dev_config_request_info(int result,
670 int service_function, void *param, unsigned int size)
674 invocation_info_t *req_info = NULL;
676 for (l = _bt_get_invocation_list(); l != NULL; ) {
679 if (req_info == NULL ||
680 req_info->service_function != service_function)
683 switch (service_function) {
684 case BT_MESH_NODE_GET_VENDOR_FEATURES: {
685 bluetooth_mesh_node_features_t *event;
686 bluetooth_mesh_node_features_t *req;
688 event = (bluetooth_mesh_node_features_t*) param;
689 req = (bluetooth_mesh_node_features_t*)req_info->user_data;
691 BT_DBG("Request Sender: [%s]", req_info->sender);
692 /* Match Network and Remote Node unicast*/
693 if (!g_strcmp0(event->net_uuid, req->net_uuid) && event->unicast == req->unicast) {
694 event->unicast = req->unicast;
695 event->elem_count = req->elem_count;
698 __bt_mesh_send_node_get_vendor_features_event(result, event);
700 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
701 g_array_append_vals(out_param, event, sizeof(bluetooth_mesh_node_features_t));
703 /* Return DBUS Invocation*/
704 _bt_service_method_return(req_info->context, out_param, result);
705 _bt_free_info_from_invocation_list(req_info);
706 g_array_free(out_param, TRUE);
710 case BT_MESH_NODE_BROWSE: {
711 bluetooth_mesh_node_discover_t *node;
712 event_mesh_devkey_message_t *event;
713 uint16_t remote_addr;
715 uint8_t dev_uuid[16];
716 char net_uuid[BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1];
718 event = (event_mesh_devkey_message_t*) param;
719 node = (bluetooth_mesh_node_discover_t*)req_info->user_data;
720 BT_INFO("Mesh: Request Node UUID [%s]", node->dev_uuid);
721 BT_INFO("Mesh: Request Network UUID [%s]", node->net_uuid);
723 _bt_mesh_util_convert_hex_to_string((uint8_t *) event->net_uuid.uuid, 16, net_uuid,
724 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
726 _bt_mesh_util_convert_string_to_hex(node->dev_uuid, strlen(node->dev_uuid), dev_uuid, 16);
728 /* Get Unicast from pending request's Dev UUID and match with event */
729 if (_bt_mesh_node_get_unicast_from_dev_uuid(event->net_uuid.uuid, dev_uuid, &remote_addr)) {
731 BT_DBG("Request Sender: [%s]", req_info->sender);
732 /* Match Network and Remote Node unicast*/
733 if (!g_strcmp0(node->net_uuid, net_uuid) && remote_addr == event->source) {
734 _bt_mesh_node_get_element_count(event->net_uuid.uuid, remote_addr, &elem_count);
735 node->unicast = event->source;
736 node->count = elem_count;
738 __bt_mesh_send_node_browsed_event(result, node);
740 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
741 g_array_append_vals(out_param, node, sizeof(bluetooth_mesh_node_discover_t));
743 /* Return DBUS Invocation*/
744 _bt_service_method_return(req_info->context, out_param, result);
745 _bt_free_info_from_invocation_list(req_info);
746 g_array_free(out_param, TRUE);
752 case BT_MESH_NODE_CONFIGURE_KEY: {
753 bluetooth_mesh_key_configure_t *event;
754 bluetooth_mesh_key_configure_t *req;
756 event = (bluetooth_mesh_key_configure_t*) param;
757 req = (bluetooth_mesh_key_configure_t*)req_info->user_data;
759 if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
760 req->primary_unicast == event->primary_unicast &&
761 req->is_netkey == event->is_netkey) {
763 __bt_mesh_send_node_key_configuration_event(result, event);
765 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
766 g_array_append_vals(out_param, event, sizeof(bluetooth_mesh_key_configure_t));
768 /* Return DBUS Invocation*/
769 _bt_service_method_return(req_info->context, out_param, result);
770 _bt_free_info_from_invocation_list(req_info);
771 g_array_free(out_param, TRUE);
775 case BT_MESH_NODE_TTL_EXECUTE: {
776 bluetooth_mesh_node_ttl_info_t *event;
777 bluetooth_mesh_node_ttl_info_t *req;
779 event = (bluetooth_mesh_node_ttl_info_t*) param;
780 req = (bluetooth_mesh_node_ttl_info_t*)req_info->user_data;
781 req->ttl = event->ttl;
783 if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
784 req->unicast == event->unicast) {
786 __bt_mesh_send_node_ttl_configuration_event(result, req);
788 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
789 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_node_ttl_info_t));
791 /* Return DBUS Invocation*/
792 _bt_service_method_return(req_info->context, out_param, result);
793 _bt_free_info_from_invocation_list(req_info);
794 g_array_free(out_param, TRUE);
798 case BT_MESH_MODEL_CONFIGURE_APPKEY: {
799 bluetooth_mesh_model_configure_t *event;
800 bluetooth_mesh_model_configure_t *req;
802 event = (bluetooth_mesh_model_configure_t*) param;
803 req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
805 if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
806 req->primary_unicast == event->primary_unicast) {
808 __bt_mesh_send_model_configure_appkey_event(result, req);
810 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
811 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_model_configure_t));
813 /* Return DBUS Invocation*/
814 _bt_service_method_return(req_info->context, out_param, result);
815 _bt_free_info_from_invocation_list(req_info);
816 g_array_free(out_param, TRUE);
821 case BT_MESH_MODEL_GET_APPKEY_LIST: {
822 bluetooth_mesh_model_configure_t *event;
823 bluetooth_mesh_model_configure_t *req;
825 event = (bluetooth_mesh_model_configure_t*) param;
826 req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
828 if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
829 req->primary_unicast == event->primary_unicast) {
831 __bt_mesh_send_model_get_appkey_list_event(result, event);
833 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
834 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_model_configure_t));
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);
843 case BT_MESH_MODEL_GET_SUBSCRIPTION_LIST: {
844 bluetooth_mesh_model_configure_t *event;
845 bluetooth_mesh_model_configure_t *req;
847 event = (bluetooth_mesh_model_configure_t*) param;
848 req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
850 if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
851 req->primary_unicast == event->primary_unicast) {
853 __bt_mesh_send_model_get_subscription_list_event(result, event);
855 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
856 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_model_configure_t));
858 /* Return DBUS Invocation*/
859 _bt_service_method_return(req_info->context, out_param, result);
860 _bt_free_info_from_invocation_list(req_info);
861 g_array_free(out_param, TRUE);
865 case BT_MESH_MODEL_CONFIG_GROUP_SUB: {
866 bluetooth_mesh_model_configure_t *event;
867 bluetooth_mesh_model_configure_t *req;
869 event = (bluetooth_mesh_model_configure_t*) param;
870 req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
872 if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
873 req->primary_unicast == event->primary_unicast) {
875 req->sub_addr = event->sub_addr;
877 __bt_mesh_send_model_subscription_configure_event(
878 BLUETOOTH_EVENT_MESH_MODEL_SUBSCRIPTION_CONFGURED,
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_array_free(out_param, TRUE);
891 case BT_MESH_MODEL_CONFIG_VIRTUAL_GROUP_SUB: {
892 bluetooth_mesh_model_configure_t *event;
893 bluetooth_mesh_model_configure_t *req;
895 event = (bluetooth_mesh_model_configure_t*) param;
896 req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
898 if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
899 req->primary_unicast == event->primary_unicast) {
901 __bt_mesh_send_model_subscription_configure_event( \
902 BLUETOOTH_EVENT_MESH_MODEL_VIRTUAL_SUBSCRIPTION_CONFGURED, \
905 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
906 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_model_configure_t));
908 /* Return DBUS Invocation*/
909 _bt_service_method_return(req_info->context, out_param, result);
910 _bt_free_info_from_invocation_list(req_info);
911 g_array_free(out_param, TRUE);
916 case BT_MESH_MODEL_GET_PUBLICATION: {
917 bluetooth_mesh_model_configure_t *event;
918 bluetooth_mesh_model_configure_t *req;
920 event = (bluetooth_mesh_model_configure_t*) param;
921 req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
923 if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
924 req->primary_unicast == event->primary_unicast) {
926 __bt_mesh_send_model_publication_status_event( \
927 BLUETOOTH_EVENT_MESH_MODEL_PUBLICATION_STATUS, \
930 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
931 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_model_configure_t));
933 /* Return DBUS Invocation*/
934 _bt_service_method_return(req_info->context, out_param, result);
935 _bt_free_info_from_invocation_list(req_info);
936 g_array_free(out_param, TRUE);
940 case BT_MESH_MODEL_SET_PUBLICATION: {
941 bluetooth_mesh_model_configure_t *event;
942 bluetooth_mesh_model_configure_t *req;
944 event = (bluetooth_mesh_model_configure_t*) param;
945 req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
947 if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
948 req->primary_unicast == event->primary_unicast) {
950 __bt_mesh_send_model_publication_status_event( \
951 BLUETOOTH_EVENT_MESH_MODEL_PUBLICATION_STATUS, \
954 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
955 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_model_configure_t));
957 /* Return DBUS Invocation*/
958 _bt_service_method_return(req_info->context, out_param, result);
959 _bt_free_info_from_invocation_list(req_info);
960 g_array_free(out_param, TRUE);
965 BT_DBG("Unknown function(%d)", service_function);
971 const char *__mesh_status_to_string(uint8_t err)
974 case MESH_STATUS_SUCCESS: return "Success";
975 case MESH_STATUS_INVALID_ADDRESS: return "Invalid Address";
976 case MESH_STATUS_INVALID_MODEL: return "Invalid Model";
977 case MESH_STATUS_INVALID_APPKEY: return "Invalid AppKey";
978 case MESH_STATUS_INVALID_NETKEY: return "Invalid NetKey";
979 case MESH_STATUS_INSUFF_RESOURCES: return "Insufficient Resources";
980 case MESH_STATUS_IDX_ALREADY_STORED: return "Key Idx Already Stored";
981 case MESH_STATUS_INVALID_PUB_PARAM: return "Invalid Publish Parameters";
982 case MESH_STATUS_NOT_SUB_MOD: return "Not a Subscribe Model";
983 case MESH_STATUS_STORAGE_FAIL: return "Storage Failure";
984 case MESH_STATUS_FEATURE_NO_SUPPORT: return "Feature Not Supported";
985 case MESH_STATUS_CANNOT_UPDATE: return "Cannot Update";
986 case MESH_STATUS_CANNOT_REMOVE: return "Cannot Remove";
987 case MESH_STATUS_CANNOT_BIND: return "Cannot bind";
988 case MESH_STATUS_UNABLE_CHANGE_STATE: return "Unable to change state";
989 case MESH_STATUS_CANNOT_SET: return "Cannot set";
990 case MESH_STATUS_UNSPECIFIED_ERROR: return "Unspecified error";
991 case MESH_STATUS_INVALID_BINDING: return "Invalid Binding";
993 default: return "Unknown";
997 static void __mesh_handle_model_subscription_event(int result,
998 bluetooth_mesh_model_configure_t *param,
999 const struct mesh_config_cmd *cmd)
1001 switch (cmd->opcode) {
1003 case MESH_OPCODE_CONFIG_MODEL_SUB_ADD:
1004 case MESH_OPCODE_CONFIG_MODEL_SUB_DELETE:
1005 case MESH_OPCODE_CONFIG_MODEL_SUB_OVERWRITE:
1006 case MESH_OPCODE_CONFIG_MODEL_SUB_DELETE_ALL:
1007 /* Model Bind/UnBind Event */
1008 __bt_mesh_handle_pending_dev_config_request_info(result,
1009 BT_MESH_MODEL_CONFIG_GROUP_SUB, ¶m,
1010 sizeof(bluetooth_mesh_model_configure_t));
1012 case MESH_OPCODE_CONFIG_MODEL_SUB_VIRT_ADD:
1013 case MESH_OPCODE_CONFIG_MODEL_SUB_VIRT_DELETE:
1014 case MESH_OPCODE_CONFIG_MODEL_SUB_VIRT_OVERWRITE:
1015 __bt_mesh_handle_pending_dev_config_request_info(result,
1016 BT_MESH_MODEL_CONFIG_VIRTUAL_GROUP_SUB, ¶m,
1017 sizeof(bluetooth_mesh_model_configure_t));
1024 void _bt_mesh_config_client_devkey_msg_handler(
1025 event_mesh_devkey_message_t *event)
1028 const struct mesh_config_cmd *cmd;
1029 uint16_t data_len = event->data_len;
1030 uint8_t *data = event->data;
1031 int result = BLUETOOTH_ERROR_NONE;
1039 struct mesh_pending_request *req;
1041 if (_bt_mesh_util_opcode_get(data, data_len, &opcode, &n)) {
1042 BT_INFO("Mesh: Opcode of response data [0x%2.2x], actual data len [%d]", opcode, n);
1048 BT_INFO("Mesh: Received %s (len %u) opcode [0x%2.2x]",
1049 __mesh_get_opcode_string(opcode), data_len, opcode);
1051 req = __bt_mesh_get_request_by_response(event->source,
1052 event->net_uuid.uuid, (opcode & ~MESH_OPCODE_UNRELIABLE));
1054 BT_INFO("Mesh: Got Config Request");
1056 __mesh_request_remove(req);
1057 l_queue_remove(pending_requests, req);
1062 switch (opcode & ~MESH_OPCODE_UNRELIABLE) {
1065 case MESH_OPCODE_CONFIG_MODEL_PUB_STATUS: {
1066 if (data_len != 12 && data_len != 14)
1068 bluetooth_mesh_model_configure_t param;
1069 memset(¶m, 0x00, sizeof(bluetooth_mesh_model_configure_t));
1071 _bt_mesh_util_convert_hex_to_string((uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1072 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1074 BT_INFO("\nNode %4.4x Model Publication status %s\n",
1075 event->source, __mesh_status_to_string(data[0]));
1077 if (data[0] != MESH_STATUS_SUCCESS)
1080 /* Extract Element Address */
1081 ele_addr = l_get_le16(data + 1);
1083 /* Extract Model ID */
1084 if (data_len == 14) {
1086 mod_id = l_get_le16(data + 10 + 2);
1087 mod_id = l_get_le16(data) << 16 | mod_id;
1090 mod_id = l_get_le16(data + 10);
1091 mod_id = MESH_VENDOR_ID_MASK | mod_id;
1094 param.primary_unicast = event->source;
1095 param.elem_index = ele_addr - event->source;
1096 /* Extract Publish Address */
1097 param.pub_addr = l_get_le16(data + 3);
1099 /* Extract Appkey Index */
1100 param.appkey_idx = l_get_le16(data + 5);
1103 param.ttl = data[6];
1105 /* Extract Period */
1106 param.period = data[7];
1110 if (cmd->opcode == MESH_OPCODE_CONFIG_MODEL_PUB_GET)
1111 __bt_mesh_handle_pending_dev_config_request_info(result,
1112 BT_MESH_MODEL_GET_PUBLICATION, ¶m,
1113 sizeof(bluetooth_mesh_model_configure_t));
1115 __bt_mesh_handle_pending_dev_config_request_info(result,
1116 BT_MESH_MODEL_SET_PUBLICATION, ¶m,
1117 sizeof(bluetooth_mesh_model_configure_t));
1120 case MESH_OPCODE_CONFIG_MODEL_SUB_STATUS: {
1121 if (data_len != 7 && data_len != 9)
1123 bluetooth_mesh_model_configure_t param;
1124 memset(¶m, 0x00, sizeof(bluetooth_mesh_model_configure_t));
1126 _bt_mesh_util_convert_hex_to_string(
1127 (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1128 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1130 BT_INFO("\nNode %4.4x Subscription status %s\n",
1131 event->source, __mesh_status_to_string(data[0]));
1133 ele_addr = l_get_le16(data + 1);
1134 addr = l_get_le16(data + 3);
1135 BT_INFO("Element Addr\t%4.4x\n", ele_addr);
1137 if (data_len == 9) {
1139 mod_id = l_get_le16(data + 5 + 2);
1140 mod_id = l_get_le16(data) << 16 | mod_id;
1143 mod_id = l_get_le16(data + 5);
1144 mod_id = MESH_VENDOR_ID_MASK | mod_id;
1147 param.primary_unicast = event->source;
1148 param.elem_index = ele_addr - event->source;
1149 /* Subscription address, unassigned address in case of Delete All command */
1150 param.sub_addr = addr;
1151 param.model = mod_id;
1152 BT_INFO("Subscr Addr\t%4.4x\n", addr);
1155 __mesh_handle_model_subscription_event(result, ¶m, cmd);
1159 case MESH_OPCODE_CONFIG_DEFAULT_TTL_STATUS: {
1162 bluetooth_mesh_node_ttl_info_t param;
1163 memset(¶m, 0x00, sizeof(bluetooth_mesh_node_ttl_info_t));
1165 BT_INFO("Node %4.4x Default TTL %d", event->source, data[0]);
1166 _bt_mesh_util_convert_hex_to_string(
1167 (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1168 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1169 param.unicast = event->source;
1170 param.ttl = data[0];
1172 if (!_bt_mesh_network_save_remote_node_ttl(event->net_uuid.uuid,
1173 event->source, data[0])) {
1174 result = BLUETOOTH_ERROR_INTERNAL;
1175 BT_INFO("Failed to save node TTL");
1178 /* Remote Node TTL event */
1179 __bt_mesh_handle_pending_dev_config_request_info(result,
1180 BT_MESH_NODE_TTL_EXECUTE, ¶m,
1181 sizeof(bluetooth_mesh_node_ttl_info_t));
1184 case MESH_OPCODE_MODEL_APP_STATUS: {
1185 if (data_len != 7 && data_len != 9)
1187 bluetooth_mesh_model_configure_t param;
1188 memset(¶m, 0x00, sizeof(bluetooth_mesh_model_configure_t));
1190 _bt_mesh_util_convert_hex_to_string(
1191 (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1192 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1193 BT_INFO("Node %4.4x: Model App status %s\n", event->source,
1194 __mesh_status_to_string(data[0]));
1195 elem_addr = l_get_le16(data + 1);
1196 app_idx = l_get_le16(data + 3);
1198 BT_INFO("Element Addr\t%4.4x", elem_addr);
1199 if (data_len == 9) {
1201 mod_id = l_get_le16(data + 5 + 2);
1202 mod_id = l_get_le16(data) << 16 | mod_id;
1205 mod_id = l_get_le16(data + 5);
1206 mod_id = MESH_VENDOR_ID_MASK | mod_id;
1209 param.primary_unicast = event->source;
1210 param.elem_index = elem_addr - event->source;
1211 param.appkey_idx = app_idx;
1212 param.model = mod_id;
1213 BT_INFO("AppIdx\t\t%u (0x%3.3x)\n ", app_idx, app_idx);
1215 /* Model Bind/UnBind Event */
1216 __bt_mesh_handle_pending_dev_config_request_info(result,
1217 BT_MESH_MODEL_CONFIGURE_APPKEY, ¶m,
1218 sizeof(bluetooth_mesh_model_configure_t));
1221 case MESH_OPCODE_MODEL_APP_LIST: {
1226 bluetooth_mesh_model_configure_t param;
1227 memset(¶m, 0x00, sizeof(bluetooth_mesh_model_configure_t));
1229 _bt_mesh_util_convert_hex_to_string(
1230 (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1231 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1233 garray = g_array_new(FALSE, FALSE, sizeof(gchar));
1235 BT_INFO("\nNode %4.4x Model AppIdx status %s\n",
1236 event->source, __mesh_status_to_string(data[0]));
1238 BT_INFO("Element Addr\t%4.4x\n", l_get_le16(data + 1));
1239 BT_INFO("Model ID\t%4.4x\n", l_get_le16(data + 3));
1241 elem_addr = l_get_le16(data + 1);
1243 mod_id = l_get_le16(data + 3);
1244 mod_id = MESH_VENDOR_ID_MASK | mod_id;
1246 param.primary_unicast = event->source;
1247 param.elem_index = elem_addr - event->source;
1248 param.model = mod_id;
1253 while (data_len >= 3) {
1254 app_idx = l_get_le16(data) & 0xfff;
1255 g_array_append_vals(garray, &app_idx, sizeof(uint16_t));
1256 BT_INFO("\t%u (0x%3.3x)\n", app_idx, app_idx);
1258 app_idx = l_get_le16(data + 1) >> 4;
1259 g_array_append_vals(garray, &app_idx, sizeof(uint16_t));
1260 BT_INFO("\t%u (0x%3.3x)\n", app_idx, app_idx);
1265 if (data_len == 2) {
1266 app_idx = l_get_le16(data) & 0xfff;
1267 g_array_append_vals(garray, &app_idx, sizeof(uint16_t));
1268 BT_INFO("\t %u (0x%3.3x)\n", app_idx, app_idx);
1270 total = garray->len / sizeof(uint16_t);
1271 param.appkey_list = (uint16_t **)g_malloc0(sizeof(uint16_t*) * garray->len);
1272 param.appkeylist_count = total;
1273 for (int i = 0; i < total; i++) {
1274 param.appkey_list[i] = g_malloc(sizeof(uint16_t));
1275 *param.appkey_list[i] = g_array_index(garray, uint16_t, i);
1277 g_array_free(garray, TRUE);
1279 __bt_mesh_handle_pending_dev_config_request_info(result,
1280 BT_MESH_MODEL_GET_APPKEY_LIST, ¶m,
1281 sizeof(bluetooth_mesh_model_configure_t));
1284 case MESH_OPCODE_CONFIG_MODEL_SUB_LIST: {
1289 bluetooth_mesh_model_configure_t param;
1290 memset(¶m, 0x00, sizeof(bluetooth_mesh_model_configure_t));
1292 _bt_mesh_util_convert_hex_to_string((uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1293 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1295 BT_INFO("\nNode %4.4x BT SIG Model Subscription List status %s\n",
1296 event->source, __mesh_status_to_string(data[0]));
1298 BT_INFO("Element Addr\t%4.4x\n", l_get_le16(data + 1));
1299 elem_addr = l_get_le16(data + 1);
1302 mod_id = l_get_le16(data + 3);
1303 mod_id = MESH_VENDOR_ID_MASK | mod_id;
1304 BT_INFO("Model ID\t%4.4x\n", mod_id);
1306 param.primary_unicast = event->source;
1307 param.elem_index = elem_addr - event->source;
1308 param.model = mod_id;
1310 total = data_len - 5;
1311 param.sublist_count = total;
1313 param.sub_list = (uint16_t **)g_malloc0(sizeof(uint16_t*) * total);
1316 for (; i < data_len; i += 2) {
1317 BT_INFO("Subscription Addr \t\t%4.4x\n ", l_get_le16(data + i));
1318 param.sub_list[i] = g_malloc(sizeof(uint16_t));
1319 *param.sub_list[i] = l_get_le16(data + i);
1322 __bt_mesh_handle_pending_dev_config_request_info(result,
1323 BT_MESH_MODEL_GET_SUBSCRIPTION_LIST, ¶m,
1324 sizeof(bluetooth_mesh_model_configure_t));
1327 case MESH_OPCODE_CONFIG_VEND_MODEL_SUB_LIST: {
1332 bluetooth_mesh_model_configure_t param;
1333 memset(¶m, 0x00, sizeof(bluetooth_mesh_model_configure_t));
1335 _bt_mesh_util_convert_hex_to_string(
1336 (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1337 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1339 BT_INFO("\nNode %4.4x BT SIG Model Subscription List status %s\n",
1340 event->source, __mesh_status_to_string(data[0]));
1342 BT_INFO("Element Addr\t%4.4x\n", l_get_le16(data + 1));
1343 elem_addr = l_get_le16(data + 1);
1346 mod_id = l_get_le16(data + 5);
1347 mod_id = l_get_le16(data + 3) << 16 | mod_id;
1349 BT_INFO("Model ID\t%4.4x\n", mod_id);
1351 param.primary_unicast = event->source;
1352 param.elem_index = elem_addr - event->source;
1353 param.model = mod_id;
1355 total = data_len - 7;
1356 param.sublist_count = total;
1358 param.sub_list = (uint16_t **)g_malloc0(sizeof(uint16_t*) * total);
1361 for (; i < data_len; i += 2) {
1362 BT_INFO("Subscription Addr \t\t%4.4x\n ", l_get_le16(data + i));
1363 param.sub_list[i] = g_malloc(sizeof(uint16_t));
1364 *param.sub_list[i] = l_get_le16(data + i);
1367 __bt_mesh_handle_pending_dev_config_request_info(result,
1368 BT_MESH_MODEL_GET_SUBSCRIPTION_LIST, ¶m,
1369 sizeof(bluetooth_mesh_model_configure_t));
1372 case MESH_OPCODE_DEV_COMP_STATUS: {
1373 if (data_len < MESH_MINIMUM_COMPOSITION_LEN)
1375 bluetooth_mesh_node_features_t features;
1376 memset(&features, 0x00, sizeof(bluetooth_mesh_node_features_t));
1377 BT_INFO("Mesh: Got Response for Device Composition Data");
1378 __bt_mesh_print_device_composition_data(data, data_len);
1380 if (!_bt_mesh_network_save_remote_node_composition(
1381 event->net_uuid.uuid, event->source, data, data_len)) {
1382 result = BLUETOOTH_ERROR_INTERNAL;
1383 BT_INFO("Failed to save node composition!");
1385 /* Browse Remote Node event */
1386 __bt_mesh_handle_pending_dev_config_request_info(result,
1387 BT_MESH_NODE_BROWSE, event, sizeof(event_mesh_devkey_message_t));
1389 /* Vendor Features Discover event */
1390 _bt_mesh_util_convert_hex_to_string(
1391 (uint8_t *) event->net_uuid.uuid, 16, features.net_uuid,
1392 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1393 features.unicast = event->source;
1394 _bt_mesh_node_get_vendor_features(event->net_uuid.uuid,
1395 event->source, &features);
1397 __bt_mesh_handle_pending_dev_config_request_info(result,
1398 BT_MESH_NODE_GET_VENDOR_FEATURES, &features,
1399 sizeof(bluetooth_mesh_node_features_t));
1402 case MESH_OPCODE_NETKEY_STATUS: {
1406 bluetooth_mesh_key_configure_t param;
1407 memset(¶m, 0x00, sizeof(bluetooth_mesh_key_configure_t));
1409 BT_INFO("Mesh: Node %4.4x NetKey status %s",
1410 event->source, __mesh_status_to_string(data[0]));
1411 net_idx = l_get_le16(data + 1) & 0xfff;
1413 BT_INFO("\tNetKey %u (0x%3.3x)", net_idx, net_idx);
1421 _bt_mesh_util_convert_hex_to_string(
1422 (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1423 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1424 param.primary_unicast = event->source;
1425 param.netkey_idx = net_idx;
1426 param.is_netkey = true;
1428 if (cmd->opcode == MESH_OPCODE_NETKEY_ADD) {
1429 BT_INFO("Mesh: Resp recvd: MESH_OPCODE_NETKEY_ADD");
1430 if (!_bt_mesh_network_save_remote_node_netkey(
1431 event->net_uuid.uuid, event->source, net_idx)) {
1432 result = BLUETOOTH_ERROR_INTERNAL;
1433 BT_INFO("Failed to save node Netkey!");
1435 param.op = BLUETOOTH_MESH_NODE_KEY_ADD;
1436 } else if (cmd->opcode == MESH_OPCODE_NETKEY_DELETE) {
1437 if (!_bt_mesh_network_delete_remote_node_netkey(
1438 event->net_uuid.uuid, event->source, net_idx)) {
1439 result = BLUETOOTH_ERROR_INTERNAL;
1440 BT_INFO("Failed to delete node Netkey!");
1442 param.op = BLUETOOTH_MESH_NODE_KEY_DELETE;
1443 } else if (cmd->opcode == MESH_OPCODE_NETKEY_UPDATE) {
1444 BT_INFO("Mesh: Resp recvd: MESH_OPCODE_NETKEY_UPDATE");
1445 param.op = BLUETOOTH_MESH_NODE_KEY_UPDATE;
1447 /* Node Net Key Configure event */
1448 __bt_mesh_handle_pending_dev_config_request_info(result,
1449 BT_MESH_NODE_CONFIGURE_KEY,
1450 ¶m, sizeof(bluetooth_mesh_key_configure_t));
1453 case MESH_OPCODE_APPKEY_STATUS: {
1457 bluetooth_mesh_key_configure_t param;
1458 memset(¶m, 0x00, sizeof(bluetooth_mesh_key_configure_t));
1460 BT_INFO("Mesh: Node %4.4x AppKey status %s\n", event->source,
1461 __mesh_status_to_string(data[0]));
1462 net_idx = l_get_le16(data + 1) & 0xfff;
1463 app_idx = l_get_le16(data + 2) >> 4;
1465 BT_INFO("NetKey\t%u (0x%3.3x)\n", net_idx, net_idx);
1466 BT_INFO("AppKey\t%u (0x%3.3x)\n", app_idx, app_idx);
1468 if (data[0] != MESH_STATUS_SUCCESS)
1474 _bt_mesh_util_convert_hex_to_string(
1475 (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1476 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1478 param.primary_unicast = event->source;
1479 param.netkey_idx = net_idx;
1480 param.appkey_idx = app_idx;
1481 param.is_netkey = false;
1483 if (cmd->opcode == MESH_OPCODE_APPKEY_ADD) {
1484 BT_INFO("Mesh: Resp recvd: MESH_OPCODE_APPKEY_ADD");
1485 if (!_bt_mesh_network_save_remote_node_appkey(
1486 event->net_uuid.uuid, event->source,
1487 net_idx, app_idx)) {
1488 result = BLUETOOTH_ERROR_INTERNAL;
1489 BT_INFO("Failed to save node Appkey!");
1491 param.op = BLUETOOTH_MESH_NODE_KEY_ADD;
1492 } else if (cmd->opcode == MESH_OPCODE_APPKEY_DELETE) {
1493 BT_INFO("Mesh: Resp recvd: MESH_OPCODE_APPKEY_DELETE");
1494 if (!_bt_mesh_network_delete_remote_node_appkey(
1495 event->net_uuid.uuid, event->source,
1496 net_idx, app_idx)) {
1497 result = BLUETOOTH_ERROR_INTERNAL;
1498 BT_INFO("Failed to delete node Appkey!");
1500 param.op = BLUETOOTH_MESH_NODE_KEY_DELETE;
1501 } else if (cmd->opcode == MESH_OPCODE_APPKEY_UPDATE) {
1502 BT_INFO("Mesh: Resp recvd: MESH_OPCODE_APPKEY_UPDATE");
1503 param.op = BLUETOOTH_MESH_NODE_KEY_UPDATE;
1506 /* Node App Key Configure event */
1507 __bt_mesh_handle_pending_dev_config_request_info(result,
1508 BT_MESH_NODE_CONFIGURE_KEY,
1509 ¶m, sizeof(bluetooth_mesh_key_configure_t));
1515 static gboolean __bt_mesh_vendor_feature_event_handler(gpointer data)
1517 bluetooth_mesh_node_features_t *result = (bluetooth_mesh_node_features_t*) data;
1518 __bt_mesh_handle_pending_dev_config_request_info(
1519 BLUETOOTH_ERROR_NONE,
1520 BT_MESH_NODE_GET_VENDOR_FEATURES,
1521 result, sizeof(bluetooth_mesh_node_features_t));
1526 int _bt_mesh_node_discover_vendor_features(const char *app_cred, const char *sender,
1527 bluetooth_mesh_node_features_t *req)
1529 int ret = OAL_STATUS_SUCCESS;
1531 uint16_t netkey_idx;
1533 oal_uuid_t net_uuid;
1534 uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
1536 _bt_mesh_util_convert_string_to_hex(req->net_uuid,
1537 strlen(req->net_uuid), net_uuid.uuid, 16);
1538 /* Check if Node's vendor features are already svaed or not */
1539 if (_bt_mesh_node_get_vendor_features(net_uuid.uuid, req->unicast, req)) {
1540 /* Schedule event ot Application */
1541 bluetooth_mesh_node_features_t *event = \
1542 g_memdup(req, sizeof(bluetooth_mesh_node_features_t));
1543 g_idle_add(__bt_mesh_vendor_feature_event_handler, (gpointer) event);
1544 return BLUETOOTH_ERROR_NONE;
1547 /* If Scanning is going on */
1548 if (_bt_mesh_is_provisioning() ||
1549 _bt_mesh_is_scanning()) {
1550 BT_ERR("Device is buzy..");
1551 return BLUETOOTH_ERROR_DEVICE_BUSY;
1554 _bt_mesh_util_convert_string_to_hex(req->net_uuid,
1555 strlen(req->net_uuid), net_uuid.uuid, 16);
1557 dest = req->unicast;
1559 /* Check pending request */
1560 if (_bt_mesh_check_pending_request(MESH_OPCODE_DEV_COMP_GET,
1561 dest, net_uuid.uuid)) {
1562 BT_ERR("Device is buzy..");
1563 return BLUETOOTH_ERROR_DEVICE_BUSY;
1566 /* Get Subnet index of the rmeote node for TX encryption */
1567 netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, dest);
1568 if (netkey_idx == MESH_NET_IDX_INVALID)
1569 return BLUETOOTH_ERROR_INTERNAL;
1571 data_len = _bt_mesh_util_opcode_set(MESH_OPCODE_DEV_COMP_GET,
1574 /* By default, use page 0 */
1575 buffer[data_len++] = 0;
1576 ret = mesh_conf_send_message(&net_uuid, dest, true,
1577 netkey_idx, buffer, data_len);
1579 if (ret != OAL_STATUS_SUCCESS) {
1580 BT_ERR("ret: %d", ret);
1581 return BLUETOOTH_ERROR_INTERNAL;
1584 /* Queue the request with timeout */
1585 __bt_mesh_add_request(MESH_OPCODE_DEV_COMP_GET,
1586 dest, net_uuid.uuid, NULL);
1587 return BLUETOOTH_ERROR_NONE;
1590 int _bt_mesh_browse_remote_node(const char *app_cred,
1592 bluetooth_mesh_node_discover_t *req)
1594 int ret = OAL_STATUS_SUCCESS;
1596 uint16_t netkey_idx;
1598 oal_uuid_t net_uuid;
1599 oal_uuid_t dev_uuid;
1600 uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
1602 /* If Scanning is going on */
1603 if (_bt_mesh_is_provisioning() ||
1604 _bt_mesh_is_scanning()) {
1605 BT_ERR("Device is buzy..");
1606 return BLUETOOTH_ERROR_DEVICE_BUSY;
1609 _bt_mesh_util_convert_string_to_hex(req->net_uuid,
1610 strlen(req->net_uuid), net_uuid.uuid, 16);
1611 _bt_mesh_util_convert_string_to_hex(req->dev_uuid,
1612 strlen(req->dev_uuid), dev_uuid.uuid, 16);
1614 BT_INFO("Mesh: Browse Node UUID [%s]", req->dev_uuid);
1616 /* Get Remote Node unicast address from Dev UUID */
1617 if (!_bt_mesh_node_get_unicast_from_dev_uuid(net_uuid.uuid,
1618 dev_uuid.uuid, &dest))
1619 return BLUETOOTH_ERROR_INTERNAL;
1621 /* Check pending request */
1622 if (_bt_mesh_check_pending_request(MESH_OPCODE_DEV_COMP_GET,
1623 dest, net_uuid.uuid)) {
1624 BT_ERR("Device is buzy..");
1625 return BLUETOOTH_ERROR_DEVICE_BUSY;
1628 /* Get Subnet index of the rmeote node for TX encryption */
1629 netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, dest);
1630 if (netkey_idx == MESH_NET_IDX_INVALID)
1631 return BLUETOOTH_ERROR_INTERNAL;
1633 data_len = _bt_mesh_util_opcode_set(MESH_OPCODE_DEV_COMP_GET, buffer);
1635 /* By default, use page 0 */
1636 buffer[data_len++] = 0;
1637 ret = mesh_conf_send_message(&net_uuid, dest, true,
1638 netkey_idx, buffer, data_len);
1640 if (ret != OAL_STATUS_SUCCESS) {
1641 BT_ERR("ret: %d", ret);
1642 return BLUETOOTH_ERROR_INTERNAL;
1645 /* Queue the request with timeout */
1646 __bt_mesh_add_request(MESH_OPCODE_DEV_COMP_GET,
1647 dest, net_uuid.uuid, NULL);
1648 return BLUETOOTH_ERROR_NONE;
1651 int _bt_mesh_model_configure_group_subscription(const char *app_cred,
1652 const char *sender, bluetooth_mesh_model_configure_t *req)
1654 int ret = OAL_STATUS_SUCCESS;
1655 uint16_t netkey_idx;
1656 oal_uuid_t net_uuid;
1658 uint32_t opcode = 0;
1659 uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
1661 /* If Scanning is going on */
1662 if (_bt_mesh_is_provisioning() ||
1663 _bt_mesh_is_scanning()) {
1664 BT_ERR("Device is buzy..");
1665 return BLUETOOTH_ERROR_DEVICE_BUSY;
1668 if (req->op != BLUETOOTH_MESH_MODEL_SUB_DELETE_ALL) {
1669 /* Subscriptio address sanity check */
1670 if ((!MESH_IS_GROUP(req->sub_addr) ||
1671 MESH_IS_ALL_NODES(req->sub_addr)) ||
1672 MESH_IS_VIRTUAL(req->sub_addr)) {
1673 BT_ERR("Mesh: Bad subscription address %x\n",
1675 return BLUETOOTH_ERROR_INVALID_PARAM;
1679 /* Get Subnet index of the remote node for TX encryption */
1680 netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid,
1681 req->primary_unicast);
1682 if (netkey_idx == MESH_NET_IDX_INVALID)
1683 return BLUETOOTH_ERROR_INTERNAL;
1685 _bt_mesh_util_convert_string_to_hex(req->net_uuid,
1686 strlen(req->net_uuid), net_uuid.uuid, 16);
1688 if (req->op == BLUETOOTH_MESH_MODEL_SUB_ADD)
1689 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_ADD;
1690 else if (req->op == BLUETOOTH_MESH_MODEL_SUB_DELETE)
1691 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_DELETE;
1692 else if (req->op == BLUETOOTH_MESH_MODEL_SUB_DELETE_ALL)
1693 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_DELETE_ALL;
1694 else if (req->op == BLUETOOTH_MESH_MODEL_SUB_OVERWRITE)
1695 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_OVERWRITE;
1697 /* Check pending request */
1698 if (_bt_mesh_check_pending_request(opcode,
1699 req->primary_unicast, net_uuid.uuid)) {
1700 BT_ERR("Device is buzy..");
1701 return BLUETOOTH_ERROR_DEVICE_BUSY;
1704 data_len = _bt_mesh_util_opcode_set(opcode, buffer);
1706 /* Element Address */
1707 l_put_le16((req->primary_unicast + req->elem_index),
1711 /* Subscription address */
1712 if (req->op != BLUETOOTH_MESH_MODEL_SUB_DELETE_ALL) {
1713 l_put_le16(req->sub_addr, buffer + data_len);
1717 /* Insert Model ID */
1718 if (req->model >= 0xFFFF0000) {
1719 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
1720 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
1723 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
1724 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
1726 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
1730 ret = mesh_conf_send_message(&net_uuid, req->primary_unicast, true,
1731 netkey_idx, buffer, data_len);
1733 if (ret != OAL_STATUS_SUCCESS) {
1734 BT_ERR("ret: %d", ret);
1735 return BLUETOOTH_ERROR_INTERNAL;
1738 /* Queue the request with timeout */
1739 __bt_mesh_add_request(opcode, req->primary_unicast,
1741 g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
1743 return BLUETOOTH_ERROR_NONE;
1746 int _bt_mesh_model_configure_virtual_group_subscription(
1747 const char *app_cred, const char *sender,
1748 bluetooth_mesh_model_configure_t *req)
1750 int ret = OAL_STATUS_SUCCESS;
1751 uint16_t netkey_idx;
1752 oal_uuid_t net_uuid;
1754 uint32_t opcode = 0;
1755 uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
1757 /* If Scanning is going on */
1758 if (_bt_mesh_is_provisioning() ||
1759 _bt_mesh_is_scanning()) {
1760 BT_ERR("Device is buzy..");
1761 return BLUETOOTH_ERROR_DEVICE_BUSY;
1764 _bt_mesh_util_convert_string_to_hex(req->net_uuid,
1765 strlen(req->net_uuid), net_uuid.uuid, 16);
1767 if (req->op != BLUETOOTH_MESH_MODEL_SUB_DELETE_ALL) {
1768 /* Subscription address sanity check */
1769 if ((MESH_IS_GROUP(req->sub_addr) ||
1770 MESH_IS_ALL_NODES(req->sub_addr)) ||
1771 !(MESH_IS_VIRTUAL(req->sub_addr))) {
1772 BT_ERR("Mesh: Bad Virtual subscription address %x\n",
1774 return BLUETOOTH_ERROR_INVALID_PARAM;
1778 /* Get Subnet index of the remote node for TX encryption */
1779 netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid,
1780 req->primary_unicast);
1781 if (netkey_idx == MESH_NET_IDX_INVALID)
1782 return BLUETOOTH_ERROR_INTERNAL;
1784 if (req->op == BLUETOOTH_MESH_MODEL_SUB_ADD)
1785 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_ADD;
1786 else if (req->op == BLUETOOTH_MESH_MODEL_SUB_DELETE)
1787 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_DELETE;
1788 else if (req->op == BLUETOOTH_MESH_MODEL_SUB_DELETE_ALL)
1789 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_DELETE_ALL;
1790 else if (req->op == BLUETOOTH_MESH_MODEL_SUB_OVERWRITE)
1791 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_OVERWRITE;
1793 /* Check pending request */
1794 if (_bt_mesh_check_pending_request(opcode,
1795 req->primary_unicast, net_uuid.uuid)) {
1796 BT_ERR("Device is buzy..");
1797 return BLUETOOTH_ERROR_DEVICE_BUSY;
1800 data_len = _bt_mesh_util_opcode_set(opcode, buffer);
1802 /* Element Address */
1803 l_put_le16((req->primary_unicast + req->elem_index), buffer + data_len);
1806 /* Subscription address */
1807 if (req->op != BLUETOOTH_MESH_MODEL_SUB_DELETE_ALL) {
1808 uint8_t label_uuid[16];
1809 if (!_bt_mesh_network_get_label_uuid_from_sub_addr(
1810 net_uuid.uuid, req->sub_addr, label_uuid)) {
1811 BT_ERR("Mesh: Virtual Group Label UUID Not found");
1812 return BLUETOOTH_ERROR_INVALID_PARAM;
1814 memcpy(buffer + data_len, label_uuid, 16);
1818 /* Insert Model ID */
1819 if (req->model >= 0xFFFF0000) {
1820 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
1821 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
1824 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
1825 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
1827 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
1831 ret = mesh_conf_send_message(&net_uuid,
1832 req->primary_unicast, true,
1833 netkey_idx, buffer, data_len);
1835 if (ret != OAL_STATUS_SUCCESS) {
1836 BT_ERR("ret: %d", ret);
1837 return BLUETOOTH_ERROR_INTERNAL;
1840 /* Queue the request with timeout */
1841 __bt_mesh_add_request(opcode, req->primary_unicast,
1843 g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
1845 return BLUETOOTH_ERROR_NONE;
1848 int _bt_mesh_model_get_publication(const char *app_cred, const char *sender,
1849 bluetooth_mesh_model_configure_t *req)
1851 int ret = OAL_STATUS_SUCCESS;
1852 uint16_t netkey_idx;
1853 oal_uuid_t net_uuid;
1855 uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
1857 /* If Scanning is going on */
1858 if (_bt_mesh_is_provisioning() ||
1859 _bt_mesh_is_scanning()) {
1860 BT_ERR("Device is buzy..");
1861 return BLUETOOTH_ERROR_DEVICE_BUSY;
1864 _bt_mesh_util_convert_string_to_hex(req->net_uuid,
1865 strlen(req->net_uuid), net_uuid.uuid, 16);
1867 /* Check pending request */
1868 if (_bt_mesh_check_pending_request(MESH_OPCODE_CONFIG_MODEL_PUB_GET,
1869 req->primary_unicast, net_uuid.uuid)) {
1870 BT_ERR("Device is buzy..");
1871 return BLUETOOTH_ERROR_DEVICE_BUSY;
1874 /* Get Subnet index of the remote node for TX encryption */
1875 netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, req->primary_unicast);
1876 if (netkey_idx == MESH_NET_IDX_INVALID)
1877 return BLUETOOTH_ERROR_INTERNAL;
1880 data_len = _bt_mesh_util_opcode_set(MESH_OPCODE_CONFIG_MODEL_PUB_GET, buffer);
1882 /* Element Address */
1883 l_put_le16((req->primary_unicast + req->elem_index), buffer + data_len);
1886 /* Insert Model ID */
1887 if (req->model >= 0xFFFF0000) {
1888 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
1889 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
1892 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
1893 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
1895 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
1899 ret = mesh_conf_send_message(&net_uuid, req->primary_unicast, true, netkey_idx, buffer, data_len);
1901 if (ret != OAL_STATUS_SUCCESS) {
1902 BT_ERR("ret: %d", ret);
1903 return BLUETOOTH_ERROR_INTERNAL;
1906 /* Queue the request with timeout */
1907 __bt_mesh_add_request(MESH_OPCODE_CONFIG_MODEL_PUB_GET, req->primary_unicast, net_uuid.uuid,
1908 g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
1910 return BLUETOOTH_ERROR_NONE;
1913 int _bt_mesh_model_set_publication(const char *app_cred, const char *sender,
1914 bluetooth_mesh_model_configure_t *req)
1916 int ret = OAL_STATUS_SUCCESS;
1917 uint16_t netkey_idx;
1918 oal_uuid_t net_uuid;
1920 uint32_t opcode = 0;
1921 uint8_t label_uuid[16];
1922 uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
1924 /* If Scanning is going on */
1925 if (_bt_mesh_is_provisioning() ||
1926 _bt_mesh_is_scanning()) {
1927 BT_ERR("Device is buzy..");
1928 return BLUETOOTH_ERROR_DEVICE_BUSY;
1931 _bt_mesh_util_convert_string_to_hex(req->net_uuid, strlen(req->net_uuid), net_uuid.uuid, 16);
1933 if (req->pub_addr == MESH_ALL_NODES_ADDRESS)
1934 BT_INFO("Mesh: Setting Publication to ALL Node Address");
1936 if (!MESH_IS_GROUP(req->pub_addr) && !MESH_IS_VIRTUAL(req->pub_addr) &&
1937 req->pub_addr != MESH_UNASSIGNED_ADDRESS) {
1938 BT_ERR("Mesh: Bad Publication address %x\n", req->pub_addr);
1939 return BLUETOOTH_ERROR_INVALID_PARAM;
1942 if (req->pub_addr != MESH_UNASSIGNED_ADDRESS) {
1943 if (MESH_IS_VIRTUAL(req->pub_addr)) {
1944 if(!_bt_mesh_network_get_label_uuid_from_sub_addr(
1945 net_uuid.uuid, req->pub_addr, label_uuid))
1946 return BLUETOOTH_ERROR_INVALID_PARAM;
1947 opcode = MESH_OPCODE_CONFIG_MODEL_PUB_VIRT_SET;
1949 } else if (MESH_IS_GROUP(req->pub_addr))
1950 opcode = MESH_OPCODE_CONFIG_MODEL_PUB_SET;
1953 /* Check pending request */
1954 if (_bt_mesh_check_pending_request(opcode,
1955 req->primary_unicast, net_uuid.uuid)) {
1956 BT_ERR("Device is buzy..");
1957 return BLUETOOTH_ERROR_DEVICE_BUSY;
1960 /* Get Subnet index of the remote node for TX encryption */
1961 netkey_idx = _bt_mesh_node_get_subnet_idx(
1962 net_uuid.uuid, req->primary_unicast);
1963 if (netkey_idx == MESH_NET_IDX_INVALID)
1964 return BLUETOOTH_ERROR_INTERNAL;
1967 data_len = _bt_mesh_util_opcode_set(opcode, buffer);
1969 /* Element Address */
1970 l_put_le16((req->primary_unicast + req->elem_index), buffer + data_len);
1973 /* Fill Publication Address */
1974 if (MESH_IS_VIRTUAL(req->pub_addr)) {
1975 memcpy(buffer + data_len, label_uuid, 16);
1978 l_put_le16(req->pub_addr, buffer + data_len);
1982 /* AppKey index + credential (set to 0) */
1983 l_put_le16(req->appkey_idx, buffer + data_len);
1987 buffer[data_len++] = req->ttl;
1988 /* Publish period step count and step resolution */
1989 buffer[data_len++] = req->period;
1990 /* Publish retransmit count & interval steps */
1991 buffer[data_len++] = req->retransmit;
1993 /* Insert Model ID */
1994 if (req->model >= 0xFFFF0000) {
1995 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
1996 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
1999 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
2000 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
2002 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2006 ret = mesh_conf_send_message(&net_uuid,
2007 req->primary_unicast, true,
2008 netkey_idx, buffer, data_len);
2010 if (ret != OAL_STATUS_SUCCESS) {
2011 BT_ERR("ret: %d", ret);
2012 return BLUETOOTH_ERROR_INTERNAL;
2015 /* Queue the request with timeout */
2016 __bt_mesh_add_request(opcode, req->primary_unicast, net_uuid.uuid,
2017 g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
2019 return BLUETOOTH_ERROR_NONE;
2022 int _bt_mesh_node_model_get_subscription_list(const char *app_cred, const char *sender,
2023 bluetooth_mesh_model_configure_t *req)
2025 int ret = OAL_STATUS_SUCCESS;
2026 uint16_t netkey_idx;
2027 oal_uuid_t net_uuid;
2029 uint32_t opcode = 0;
2030 uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
2032 /* If Scanning is going on */
2033 if (_bt_mesh_is_provisioning() ||
2034 _bt_mesh_is_scanning()) {
2035 BT_ERR("Device is buzy..");
2036 return BLUETOOTH_ERROR_DEVICE_BUSY;
2039 _bt_mesh_util_convert_string_to_hex(req->net_uuid, strlen(req->net_uuid), net_uuid.uuid, 16);
2041 /* Insert Model ID */
2042 if (req->model >= 0xFFFF0000)
2043 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
2044 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_GET;
2046 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
2047 opcode = MESH_OPCODE_CONFIG_VEND_MODEL_SUB_GET;
2049 /* Check pending request */
2050 if (_bt_mesh_check_pending_request(opcode,
2051 req->primary_unicast, net_uuid.uuid)) {
2052 BT_ERR("Device is buzy..");
2053 return BLUETOOTH_ERROR_DEVICE_BUSY;
2055 /* Get Subnet index of the remote node for TX encryption */
2056 netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, req->primary_unicast);
2057 if (netkey_idx == MESH_NET_IDX_INVALID)
2058 return BLUETOOTH_ERROR_INTERNAL;
2060 data_len = _bt_mesh_util_opcode_set(opcode, buffer);
2061 /* Element Address */
2062 l_put_le16((req->primary_unicast + req->elem_index), buffer + data_len);
2066 /* Insert Model ID */
2067 if (opcode == MESH_OPCODE_CONFIG_MODEL_SUB_GET) {
2068 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
2069 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2072 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
2073 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
2075 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2079 ret = mesh_conf_send_message(&net_uuid,
2080 req->primary_unicast, true, netkey_idx, buffer, data_len);
2082 if (ret != OAL_STATUS_SUCCESS) {
2083 BT_ERR("ret: %d", ret);
2084 return BLUETOOTH_ERROR_INTERNAL;
2087 /* Queue the request with timeout */
2088 __bt_mesh_add_request(opcode, req->primary_unicast, net_uuid.uuid,
2089 g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
2091 return BLUETOOTH_ERROR_NONE;
2094 int _bt_mesh_node_model_get_appkey_list(const char *app_cred, const char *sender,
2095 bluetooth_mesh_model_configure_t *req)
2097 int ret = OAL_STATUS_SUCCESS;
2098 uint16_t netkey_idx;
2099 oal_uuid_t net_uuid;
2101 uint32_t opcode = 0;
2102 uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
2104 /* If Scanning is going on */
2105 if (_bt_mesh_is_provisioning() ||
2106 _bt_mesh_is_scanning()) {
2107 BT_ERR("Device is buzy..");
2108 return BLUETOOTH_ERROR_DEVICE_BUSY;
2111 _bt_mesh_util_convert_string_to_hex(req->net_uuid,
2112 strlen(req->net_uuid), net_uuid.uuid, 16);
2114 /* Insert Model ID */
2115 if (req->model >= 0xFFFF0000)
2116 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
2117 opcode = MESH_OPCODE_MODEL_APP_GET;
2119 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
2120 opcode = MESH_OPCODE_VENDOR_MODEL_APP_GET;
2122 /* Check pending request */
2123 if (_bt_mesh_check_pending_request(opcode,
2124 req->primary_unicast, net_uuid.uuid)) {
2125 BT_ERR("Device is buzy..");
2126 return BLUETOOTH_ERROR_DEVICE_BUSY;
2128 /* Get Subnet index of the remote node for TX encryption */
2129 netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, req->primary_unicast);
2130 if (netkey_idx == MESH_NET_IDX_INVALID)
2131 return BLUETOOTH_ERROR_INTERNAL;
2133 data_len = _bt_mesh_util_opcode_set(opcode, buffer);
2134 /* Element Address */
2135 l_put_le16((req->primary_unicast + req->elem_index), buffer + data_len);
2139 /* Insert Model ID */
2140 if (opcode == MESH_OPCODE_MODEL_APP_GET) {
2141 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
2142 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2145 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
2146 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
2148 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2152 ret = mesh_conf_send_message(&net_uuid, req->primary_unicast, true, netkey_idx, buffer, data_len);
2154 if (ret != OAL_STATUS_SUCCESS) {
2155 BT_ERR("ret: %d", ret);
2156 return BLUETOOTH_ERROR_INTERNAL;
2159 /* Queue the request with timeout */
2160 __bt_mesh_add_request(opcode, req->primary_unicast, net_uuid.uuid,
2161 g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
2163 return BLUETOOTH_ERROR_NONE;
2166 int _bt_mesh_node_model_appkey_execute(const char *app_cred, const char *sender,
2167 bluetooth_mesh_model_configure_t *req)
2169 int ret = OAL_STATUS_SUCCESS;
2170 uint16_t netkey_idx;
2171 oal_uuid_t net_uuid;
2173 uint32_t opcode = 0;
2174 uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
2176 /* If Scanning is going on */
2177 if (_bt_mesh_is_provisioning() ||
2178 _bt_mesh_is_scanning()) {
2179 BT_ERR("Device is buzy..");
2180 return BLUETOOTH_ERROR_DEVICE_BUSY;
2183 _bt_mesh_util_convert_string_to_hex(req->net_uuid, strlen(req->net_uuid), net_uuid.uuid, 16);
2185 /* Check pending request */
2186 if (_bt_mesh_check_pending_request(req->is_bind ? MESH_OPCODE_MODEL_APP_BIND : MESH_OPCODE_MODEL_APP_UNBIND,
2187 req->primary_unicast, net_uuid.uuid)) {
2188 BT_ERR("Device is buzy..");
2189 return BLUETOOTH_ERROR_DEVICE_BUSY;
2191 /* Get Subnet index of the remote node for TX encryption */
2192 netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, req->primary_unicast);
2193 if (netkey_idx == MESH_NET_IDX_INVALID)
2194 return BLUETOOTH_ERROR_INTERNAL;
2197 opcode = MESH_OPCODE_MODEL_APP_BIND;
2199 opcode = MESH_OPCODE_MODEL_APP_UNBIND;
2201 data_len = _bt_mesh_util_opcode_set(opcode, buffer);
2202 /* Element Address */
2203 l_put_le16((req->primary_unicast + req->elem_index), buffer + data_len);
2207 l_put_le16(req->appkey_idx, buffer + data_len);
2210 /* Insert Model ID */
2211 if (req->model >= 0xFFFF0000) {
2212 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
2213 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2216 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
2217 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
2219 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2223 ret = mesh_conf_send_message(&net_uuid, req->primary_unicast, true, netkey_idx, buffer, data_len);
2225 if (ret != OAL_STATUS_SUCCESS) {
2226 BT_ERR("ret: %d", ret);
2227 return BLUETOOTH_ERROR_INTERNAL;
2230 /* Queue the request with timeout */
2231 __bt_mesh_add_request(opcode, req->primary_unicast, net_uuid.uuid,
2232 g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
2234 return BLUETOOTH_ERROR_NONE;
2237 int _bt_mesh_ttl_execute_remote_node(const char *app_cred, const char *sender,
2238 bluetooth_mesh_node_ttl_info_t *req)
2240 int ret = OAL_STATUS_SUCCESS;
2241 uint16_t netkey_idx;
2243 oal_uuid_t net_uuid;
2244 uint32_t opcode = 0;
2245 uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
2247 /* If Scanning is going on */
2248 if (_bt_mesh_is_provisioning() ||
2249 _bt_mesh_is_scanning()) {
2250 BT_ERR("Device is buzy..");
2251 return BLUETOOTH_ERROR_DEVICE_BUSY;
2254 _bt_mesh_util_convert_string_to_hex(req->net_uuid, strlen(req->net_uuid), net_uuid.uuid, 16);
2256 /* Check pending request */
2257 if (_bt_mesh_check_pending_request(req->is_set ? MESH_OPCODE_CONFIG_DEFAULT_TTL_SET : MESH_OPCODE_CONFIG_DEFAULT_TTL_GET,
2258 req->unicast, net_uuid.uuid)) {
2259 BT_ERR("Device is buzy..");
2260 return BLUETOOTH_ERROR_DEVICE_BUSY;
2263 /* Get Subnet index of the rmeote node for TX encryption */
2264 netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, req->unicast);
2265 if (netkey_idx == MESH_NET_IDX_INVALID)
2266 return BLUETOOTH_ERROR_INTERNAL;
2269 opcode = MESH_OPCODE_CONFIG_DEFAULT_TTL_SET;
2270 data_len = _bt_mesh_util_opcode_set(MESH_OPCODE_CONFIG_DEFAULT_TTL_SET, buffer);
2271 buffer[data_len++] = req->ttl;
2273 opcode = MESH_OPCODE_CONFIG_DEFAULT_TTL_GET;
2274 data_len = _bt_mesh_util_opcode_set(MESH_OPCODE_CONFIG_DEFAULT_TTL_GET, buffer);
2277 ret = mesh_conf_send_message(&net_uuid, req->unicast, true, netkey_idx, buffer, data_len);
2279 if (ret != OAL_STATUS_SUCCESS) {
2280 BT_ERR("ret: %d", ret);
2281 return BLUETOOTH_ERROR_INTERNAL;
2284 /* Queue the request with timeout */
2285 __bt_mesh_add_request(opcode, req->unicast, net_uuid.uuid,
2286 g_memdup(req, sizeof(bluetooth_mesh_node_ttl_info_t)));
2287 return BLUETOOTH_ERROR_NONE;
2290 static bool __bt_mesh_check_pending_key_cmd(uint16_t dest, bool is_netkey,
2291 bluetooth_mesh_node_key_conf_e op, uint8_t net_uuid[], uint32_t *opcode)
2293 const struct mesh_config_cmd *cmd;
2297 case BLUETOOTH_MESH_NODE_KEY_ADD:
2298 cmd = __mesh_get_command(MESH_OPCODE_NETKEY_ADD);
2301 if (__bt_mesh_get_request_by_response(dest, net_uuid, cmd->response)) {
2302 BT_ERR("Mesh:Another Key Configuration command is pending\n");
2305 *opcode = MESH_OPCODE_NETKEY_ADD;
2307 case BLUETOOTH_MESH_NODE_KEY_DELETE:
2308 cmd = __mesh_get_command(MESH_OPCODE_NETKEY_DELETE);
2311 if (__bt_mesh_get_request_by_response(dest, net_uuid, cmd->response)) {
2312 BT_ERR("Mesh:Another Key Configuration command is pending\n");
2315 *opcode = MESH_OPCODE_NETKEY_DELETE;
2317 case BLUETOOTH_MESH_NODE_KEY_UPDATE:
2318 cmd = __mesh_get_command(MESH_OPCODE_NETKEY_UPDATE);
2321 if (__bt_mesh_get_request_by_response(dest, net_uuid, cmd->response)) {
2322 BT_ERR("Mesh:Another Key Configuration command is pending\n");
2325 *opcode = MESH_OPCODE_NETKEY_UPDATE;
2330 case BLUETOOTH_MESH_NODE_KEY_ADD:
2331 cmd = __mesh_get_command(MESH_OPCODE_APPKEY_ADD);
2334 if (__bt_mesh_get_request_by_response(dest, net_uuid, cmd->response)) {
2335 BT_ERR("Mesh:Another Key Configuration command is pending\n");
2338 *opcode = MESH_OPCODE_APPKEY_ADD;
2340 case BLUETOOTH_MESH_NODE_KEY_DELETE:
2341 cmd = __mesh_get_command(MESH_OPCODE_APPKEY_DELETE);
2344 if (__bt_mesh_get_request_by_response(dest, net_uuid, cmd->response)) {
2345 BT_ERR("Mesh:Another Key Configuration command is pending\n");
2348 *opcode = MESH_OPCODE_APPKEY_DELETE;
2350 case BLUETOOTH_MESH_NODE_KEY_UPDATE:
2351 cmd = __mesh_get_command(MESH_OPCODE_APPKEY_UPDATE);
2354 if (__bt_mesh_get_request_by_response(dest, net_uuid, cmd->response)) {
2355 BT_ERR("Mesh:Another Key Configuration command is pending\n");
2358 *opcode = MESH_OPCODE_APPKEY_UPDATE;
2365 int _bt_mesh_node_configure_key(const char *app_cred, const char *sender,
2366 bluetooth_mesh_key_configure_t *req)
2368 int ret = OAL_STATUS_SUCCESS;
2369 uint16_t netkey_idx;
2370 uint16_t bound_netkey_idx = 0x0000;
2371 oal_uuid_t net_uuid;
2372 uint32_t opcode = 0;
2375 uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
2377 /* If Scanning is going on */
2378 if (_bt_mesh_is_provisioning() ||
2379 _bt_mesh_is_scanning()) {
2380 BT_ERR("Device is buzy..");
2381 return BLUETOOTH_ERROR_DEVICE_BUSY;
2384 _bt_mesh_util_convert_string_to_hex(req->net_uuid, strlen(req->net_uuid), net_uuid.uuid, 16);
2386 if (req->is_netkey && !_bt_mesh_keys_subnet_exists(net_uuid.uuid, req->netkey_idx)) {
2387 BT_ERR("Local Subnet not found..");
2388 return BLUETOOTH_ERROR_INVALID_PARAM;
2391 /* For Appkey Configuration, check for available bound netkey */
2392 if (!req->is_netkey) {
2393 bound_netkey_idx = _bt_mesh_keys_get_bound_key(net_uuid.uuid, req->appkey_idx);
2394 if (bound_netkey_idx == MESH_NET_IDX_INVALID) {
2395 BT_ERR("Local AppKey not found..");
2396 return BLUETOOTH_ERROR_INVALID_PARAM;
2400 /* Check pending request */
2401 if (__bt_mesh_check_pending_key_cmd(req->primary_unicast,
2402 req->is_netkey, req->op, net_uuid.uuid, &opcode)) {
2403 BT_ERR("Device is buzy..");
2404 return BLUETOOTH_ERROR_DEVICE_BUSY;
2407 /* Get Subnet index of the rmeote node for TX encryption */
2408 netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, req->primary_unicast);
2409 if (netkey_idx == MESH_NET_IDX_INVALID)
2410 return BLUETOOTH_ERROR_INTERNAL;
2412 /* Handle Key (App/Net) Delete Commands: Configuration Message */
2413 if (opcode == MESH_OPCODE_NETKEY_DELETE || opcode == MESH_OPCODE_APPKEY_DELETE) {
2414 data_len = _bt_mesh_util_opcode_set(opcode, buffer);
2415 if (req->is_netkey) {
2416 l_put_le16(req->netkey_idx, buffer + data_len);
2419 buffer[data_len] = bound_netkey_idx;
2420 buffer[data_len + 1] = ((bound_netkey_idx >> 8) & 0xf) | ((req->appkey_idx << 4) & 0xf0);
2421 buffer[data_len + 2] = req->appkey_idx >> 4;
2425 ret = mesh_conf_send_message(&net_uuid, req->primary_unicast, true, netkey_idx, buffer, data_len);
2427 /* Handle Key (App/Net) Update & Add Commands: Key Config message */
2428 update = (opcode == MESH_OPCODE_NETKEY_UPDATE || opcode == MESH_OPCODE_APPKEY_UPDATE);
2429 ret = mesh_conf_send_key_message(&net_uuid, req->primary_unicast, req->is_netkey,
2430 update, req->is_netkey? req->netkey_idx: req->appkey_idx, netkey_idx);
2432 if (ret != OAL_STATUS_SUCCESS) {
2433 BT_ERR("ret: %d", ret);
2434 return BLUETOOTH_ERROR_INTERNAL;
2437 /* Queue the request with timeout */
2438 __bt_mesh_add_request(opcode, req->primary_unicast, net_uuid.uuid,
2439 g_memdup(req, sizeof(bluetooth_mesh_key_configure_t)));
2440 return BLUETOOTH_ERROR_NONE;