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;
528 if (BLUETOOTH_ERROR_NONE == result) {
529 builder = g_variant_builder_new(G_VARIANT_TYPE("aq"));
530 BT_INFO("Mesh: Total AppKeys bound to model [%d]",
531 evt->appkeylist_count);
532 BT_INFO("Mesh: Network [%s]", evt->net_uuid);
533 for (i = 0; i < evt->appkeylist_count; i++)
534 g_variant_builder_add(builder, "q", *evt->appkey_list[i]);
535 net_uuid = g_strdup(evt->net_uuid);
536 param = g_variant_new("(isqiui(aq))", result, net_uuid,
537 evt->primary_unicast, evt->elem_index, evt->model,
538 evt->appkeylist_count, builder);
540 g_variant_builder_unref(builder);
543 _bt_send_event(BT_MESH_EVENT,
544 BLUETOOTH_EVENT_MESH_MODEL_APPKEY_LIST,
547 if (evt->appkeylist_count) {
548 for (int i = 0; i < evt->appkeylist_count; i++)
549 g_free(evt->appkey_list[i]);
551 g_free(evt->appkey_list);
558 static void __bt_mesh_send_model_configure_appkey_event(int result,
559 bluetooth_mesh_model_configure_t *evt)
561 GVariant *out_var = NULL, *param = NULL;
564 if (BLUETOOTH_ERROR_NONE == result) {
566 info = g_array_new(FALSE, FALSE, sizeof(gchar));
567 g_array_append_vals(info, evt, sizeof(bluetooth_mesh_model_configure_t));
569 out_var = g_variant_new_from_data((const GVariantType *)"ay",
570 info->data, info->len,
573 param = g_variant_new("(iv)", result, out_var);
574 _bt_send_event(BT_MESH_EVENT,
575 BLUETOOTH_EVENT_MESH_MODEL_APPKEY_BIND,
580 static void __bt_mesh_send_node_ttl_configuration_event(int result,
581 bluetooth_mesh_node_ttl_info_t *ttl_evt)
583 GVariant *out_var = NULL, *param = NULL;
586 if (BLUETOOTH_ERROR_NONE == result) {
588 info = g_array_new(FALSE, FALSE, sizeof(gchar));
589 g_array_append_vals(info, ttl_evt,
590 sizeof(bluetooth_mesh_node_ttl_info_t));
592 out_var = g_variant_new_from_data((const GVariantType *)"ay",
593 info->data, info->len,
596 param = g_variant_new("(iv)", result, out_var);
597 _bt_send_event(BT_MESH_EVENT,
598 BLUETOOTH_EVENT_MESH_NODE_TTL_CONFIGURED,
603 static void __bt_mesh_send_node_key_configuration_event(int result,
604 bluetooth_mesh_key_configure_t *key_evt)
606 GVariant *out_var = NULL, *param = NULL;
609 if (BLUETOOTH_ERROR_NONE == result) {
611 info = g_array_new(FALSE, FALSE, sizeof(gchar));
612 g_array_append_vals(info, key_evt,
613 sizeof(bluetooth_mesh_key_configure_t));
615 out_var = g_variant_new_from_data((const GVariantType *)"ay",
616 info->data, info->len,
619 param = g_variant_new("(iv)", result, out_var);
620 _bt_send_event(BT_MESH_EVENT,
621 BLUETOOTH_EVENT_MESH_NODE_KEY_CONFIGURED,
626 static void __bt_mesh_send_node_get_vendor_features_event(int result,
627 bluetooth_mesh_node_features_t *features_evt)
629 GVariant *out_var = NULL, *param = NULL;
632 if (BLUETOOTH_ERROR_NONE == result) {
634 info = g_array_new(FALSE, FALSE, sizeof(gchar));
635 g_array_append_vals(info, features_evt,
636 sizeof(bluetooth_mesh_node_features_t));
638 out_var = g_variant_new_from_data((const GVariantType *)"ay",
639 info->data, info->len,
642 param = g_variant_new("(iv)", result, out_var);
643 _bt_send_event(BT_MESH_EVENT,
644 BLUETOOTH_EVENT_MESH_NODE_VENDOR_FEATURES,
649 static void __bt_mesh_send_node_browsed_event(int result,
650 bluetooth_mesh_node_discover_t *browse_evt)
652 GVariant *out_var = NULL, *param = NULL;
655 if (BLUETOOTH_ERROR_NONE == result) {
657 info = g_array_new(FALSE, FALSE, sizeof(gchar));
658 g_array_append_vals(info, browse_evt,
659 sizeof(bluetooth_mesh_node_discover_t));
661 out_var = g_variant_new_from_data((const GVariantType *)"ay",
662 info->data, info->len,
665 param = g_variant_new("(iv)", result, out_var);
666 _bt_send_event(BT_MESH_EVENT,
667 BLUETOOTH_EVENT_MESH_NODE_BROWSED,
672 static void __bt_mesh_handle_pending_dev_config_request_info(int result,
673 int service_function, void *param, unsigned int size)
677 invocation_info_t *req_info = NULL;
679 for (l = _bt_get_invocation_list(); l != NULL; ) {
682 if (req_info == NULL ||
683 req_info->service_function != service_function)
686 switch (service_function) {
687 case BT_MESH_NODE_GET_VENDOR_FEATURES: {
688 bluetooth_mesh_node_features_t *event;
689 bluetooth_mesh_node_features_t *req;
691 event = (bluetooth_mesh_node_features_t*) param;
692 req = (bluetooth_mesh_node_features_t*)req_info->user_data;
694 BT_DBG("Request Sender: [%s]", req_info->sender);
695 /* Match Network and Remote Node unicast*/
696 if (!g_strcmp0(event->net_uuid, req->net_uuid) && event->unicast == req->unicast) {
697 event->unicast = req->unicast;
698 event->elem_count = req->elem_count;
701 __bt_mesh_send_node_get_vendor_features_event(result, event);
703 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
704 g_array_append_vals(out_param, event, sizeof(bluetooth_mesh_node_features_t));
706 /* Return DBUS Invocation*/
707 _bt_service_method_return(req_info->context, out_param, result);
708 _bt_free_info_from_invocation_list(req_info);
709 g_array_free(out_param, TRUE);
713 case BT_MESH_NODE_BROWSE: {
714 bluetooth_mesh_node_discover_t *node;
715 event_mesh_devkey_message_t *event;
716 uint16_t remote_addr;
718 uint8_t dev_uuid[16];
719 char net_uuid[BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1];
721 event = (event_mesh_devkey_message_t*) param;
722 node = (bluetooth_mesh_node_discover_t*)req_info->user_data;
723 BT_INFO("Mesh: Request Node UUID [%s]", node->dev_uuid);
724 BT_INFO("Mesh: Request Network UUID [%s]", node->net_uuid);
726 _bt_mesh_util_convert_hex_to_string((uint8_t *) event->net_uuid.uuid, 16, net_uuid,
727 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
729 _bt_mesh_util_convert_string_to_hex(node->dev_uuid, strlen(node->dev_uuid), dev_uuid, 16);
731 /* Get Unicast from pending request's Dev UUID and match with event */
732 if (_bt_mesh_node_get_unicast_from_dev_uuid(event->net_uuid.uuid, dev_uuid, &remote_addr)) {
734 BT_DBG("Request Sender: [%s]", req_info->sender);
735 /* Match Network and Remote Node unicast*/
736 if (!g_strcmp0(node->net_uuid, net_uuid) && remote_addr == event->source) {
737 _bt_mesh_node_get_element_count(event->net_uuid.uuid, remote_addr, &elem_count);
738 node->unicast = event->source;
739 node->count = elem_count;
741 __bt_mesh_send_node_browsed_event(result, node);
743 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
744 g_array_append_vals(out_param, node, sizeof(bluetooth_mesh_node_discover_t));
746 /* Return DBUS Invocation*/
747 _bt_service_method_return(req_info->context, out_param, result);
748 _bt_free_info_from_invocation_list(req_info);
749 g_array_free(out_param, TRUE);
755 case BT_MESH_NODE_CONFIGURE_KEY: {
756 bluetooth_mesh_key_configure_t *event;
757 bluetooth_mesh_key_configure_t *req;
759 event = (bluetooth_mesh_key_configure_t*) param;
760 req = (bluetooth_mesh_key_configure_t*)req_info->user_data;
762 if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
763 req->primary_unicast == event->primary_unicast &&
764 req->is_netkey == event->is_netkey) {
766 __bt_mesh_send_node_key_configuration_event(result, event);
768 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
769 g_array_append_vals(out_param, event, sizeof(bluetooth_mesh_key_configure_t));
771 /* Return DBUS Invocation*/
772 _bt_service_method_return(req_info->context, out_param, result);
773 _bt_free_info_from_invocation_list(req_info);
774 g_array_free(out_param, TRUE);
778 case BT_MESH_NODE_TTL_EXECUTE: {
779 bluetooth_mesh_node_ttl_info_t *event;
780 bluetooth_mesh_node_ttl_info_t *req;
782 event = (bluetooth_mesh_node_ttl_info_t*) param;
783 req = (bluetooth_mesh_node_ttl_info_t*)req_info->user_data;
784 req->ttl = event->ttl;
786 if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
787 req->unicast == event->unicast) {
789 __bt_mesh_send_node_ttl_configuration_event(result, req);
791 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
792 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_node_ttl_info_t));
794 /* Return DBUS Invocation*/
795 _bt_service_method_return(req_info->context, out_param, result);
796 _bt_free_info_from_invocation_list(req_info);
797 g_array_free(out_param, TRUE);
801 case BT_MESH_MODEL_CONFIGURE_APPKEY: {
802 bluetooth_mesh_model_configure_t *event;
803 bluetooth_mesh_model_configure_t *req;
805 event = (bluetooth_mesh_model_configure_t*) param;
806 req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
808 if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
809 req->primary_unicast == event->primary_unicast) {
811 __bt_mesh_send_model_configure_appkey_event(result, req);
813 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
814 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_model_configure_t));
816 /* Return DBUS Invocation*/
817 _bt_service_method_return(req_info->context, out_param, result);
818 _bt_free_info_from_invocation_list(req_info);
819 g_array_free(out_param, TRUE);
824 case BT_MESH_MODEL_GET_APPKEY_LIST: {
825 bluetooth_mesh_model_configure_t *event;
826 bluetooth_mesh_model_configure_t *req;
828 event = (bluetooth_mesh_model_configure_t*) param;
829 req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
831 if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
832 req->primary_unicast == event->primary_unicast) {
834 __bt_mesh_send_model_get_appkey_list_event(result, event);
836 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
837 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_model_configure_t));
839 /* Return DBUS Invocation*/
840 _bt_service_method_return(req_info->context, out_param, result);
841 _bt_free_info_from_invocation_list(req_info);
842 g_array_free(out_param, TRUE);
846 case BT_MESH_MODEL_GET_SUBSCRIPTION_LIST: {
847 bluetooth_mesh_model_configure_t *event;
848 bluetooth_mesh_model_configure_t *req;
850 event = (bluetooth_mesh_model_configure_t*) param;
851 req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
853 if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
854 req->primary_unicast == event->primary_unicast) {
856 __bt_mesh_send_model_get_subscription_list_event(result, event);
858 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
859 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_model_configure_t));
861 /* Return DBUS Invocation*/
862 _bt_service_method_return(req_info->context, out_param, result);
863 _bt_free_info_from_invocation_list(req_info);
864 g_array_free(out_param, TRUE);
868 case BT_MESH_MODEL_CONFIG_GROUP_SUB: {
869 bluetooth_mesh_model_configure_t *event;
870 bluetooth_mesh_model_configure_t *req;
872 event = (bluetooth_mesh_model_configure_t*) param;
873 req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
875 if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
876 req->primary_unicast == event->primary_unicast) {
878 req->sub_addr = event->sub_addr;
880 __bt_mesh_send_model_subscription_configure_event(
881 BLUETOOTH_EVENT_MESH_MODEL_SUBSCRIPTION_CONFGURED,
884 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
885 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_model_configure_t));
887 /* Return DBUS Invocation*/
888 _bt_service_method_return(req_info->context, out_param, result);
889 _bt_free_info_from_invocation_list(req_info);
890 g_array_free(out_param, TRUE);
894 case BT_MESH_MODEL_CONFIG_VIRTUAL_GROUP_SUB: {
895 bluetooth_mesh_model_configure_t *event;
896 bluetooth_mesh_model_configure_t *req;
898 event = (bluetooth_mesh_model_configure_t*) param;
899 req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
901 if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
902 req->primary_unicast == event->primary_unicast) {
904 __bt_mesh_send_model_subscription_configure_event( \
905 BLUETOOTH_EVENT_MESH_MODEL_VIRTUAL_SUBSCRIPTION_CONFGURED, \
908 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
909 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_model_configure_t));
911 /* Return DBUS Invocation*/
912 _bt_service_method_return(req_info->context, out_param, result);
913 _bt_free_info_from_invocation_list(req_info);
914 g_array_free(out_param, TRUE);
919 case BT_MESH_MODEL_GET_PUBLICATION: {
920 bluetooth_mesh_model_configure_t *event;
921 bluetooth_mesh_model_configure_t *req;
923 event = (bluetooth_mesh_model_configure_t*) param;
924 req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
926 if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
927 req->primary_unicast == event->primary_unicast) {
929 __bt_mesh_send_model_publication_status_event( \
930 BLUETOOTH_EVENT_MESH_MODEL_PUBLICATION_STATUS, \
933 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
934 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_model_configure_t));
936 /* Return DBUS Invocation*/
937 _bt_service_method_return(req_info->context, out_param, result);
938 _bt_free_info_from_invocation_list(req_info);
939 g_array_free(out_param, TRUE);
943 case BT_MESH_MODEL_SET_PUBLICATION: {
944 bluetooth_mesh_model_configure_t *event;
945 bluetooth_mesh_model_configure_t *req;
947 event = (bluetooth_mesh_model_configure_t*) param;
948 req = (bluetooth_mesh_model_configure_t*)req_info->user_data;
950 if (!g_strcmp0(req->net_uuid, event->net_uuid) &&
951 req->primary_unicast == event->primary_unicast) {
953 __bt_mesh_send_model_publication_status_event( \
954 BLUETOOTH_EVENT_MESH_MODEL_PUBLICATION_STATUS, \
957 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
958 g_array_append_vals(out_param, req, sizeof(bluetooth_mesh_model_configure_t));
960 /* Return DBUS Invocation*/
961 _bt_service_method_return(req_info->context, out_param, result);
962 _bt_free_info_from_invocation_list(req_info);
963 g_array_free(out_param, TRUE);
968 BT_DBG("Unknown function(%d)", service_function);
974 const char *__mesh_status_to_string(uint8_t err)
977 case MESH_STATUS_SUCCESS: return "Success";
978 case MESH_STATUS_INVALID_ADDRESS: return "Invalid Address";
979 case MESH_STATUS_INVALID_MODEL: return "Invalid Model";
980 case MESH_STATUS_INVALID_APPKEY: return "Invalid AppKey";
981 case MESH_STATUS_INVALID_NETKEY: return "Invalid NetKey";
982 case MESH_STATUS_INSUFF_RESOURCES: return "Insufficient Resources";
983 case MESH_STATUS_IDX_ALREADY_STORED: return "Key Idx Already Stored";
984 case MESH_STATUS_INVALID_PUB_PARAM: return "Invalid Publish Parameters";
985 case MESH_STATUS_NOT_SUB_MOD: return "Not a Subscribe Model";
986 case MESH_STATUS_STORAGE_FAIL: return "Storage Failure";
987 case MESH_STATUS_FEATURE_NO_SUPPORT: return "Feature Not Supported";
988 case MESH_STATUS_CANNOT_UPDATE: return "Cannot Update";
989 case MESH_STATUS_CANNOT_REMOVE: return "Cannot Remove";
990 case MESH_STATUS_CANNOT_BIND: return "Cannot bind";
991 case MESH_STATUS_UNABLE_CHANGE_STATE: return "Unable to change state";
992 case MESH_STATUS_CANNOT_SET: return "Cannot set";
993 case MESH_STATUS_UNSPECIFIED_ERROR: return "Unspecified error";
994 case MESH_STATUS_INVALID_BINDING: return "Invalid Binding";
996 default: return "Unknown";
1000 static void __mesh_handle_model_subscription_event(int result,
1001 bluetooth_mesh_model_configure_t *param,
1002 const struct mesh_config_cmd *cmd)
1004 switch (cmd->opcode) {
1006 case MESH_OPCODE_CONFIG_MODEL_SUB_ADD:
1007 case MESH_OPCODE_CONFIG_MODEL_SUB_DELETE:
1008 case MESH_OPCODE_CONFIG_MODEL_SUB_OVERWRITE:
1009 case MESH_OPCODE_CONFIG_MODEL_SUB_DELETE_ALL:
1010 /* Model Bind/UnBind Event */
1011 __bt_mesh_handle_pending_dev_config_request_info(result,
1012 BT_MESH_MODEL_CONFIG_GROUP_SUB, ¶m,
1013 sizeof(bluetooth_mesh_model_configure_t));
1015 case MESH_OPCODE_CONFIG_MODEL_SUB_VIRT_ADD:
1016 case MESH_OPCODE_CONFIG_MODEL_SUB_VIRT_DELETE:
1017 case MESH_OPCODE_CONFIG_MODEL_SUB_VIRT_OVERWRITE:
1018 __bt_mesh_handle_pending_dev_config_request_info(result,
1019 BT_MESH_MODEL_CONFIG_VIRTUAL_GROUP_SUB, ¶m,
1020 sizeof(bluetooth_mesh_model_configure_t));
1027 void _bt_mesh_config_client_devkey_msg_handler(
1028 event_mesh_devkey_message_t *event)
1031 const struct mesh_config_cmd *cmd;
1032 uint16_t data_len = event->data_len;
1033 uint8_t *data = event->data;
1034 int result = BLUETOOTH_ERROR_NONE;
1042 struct mesh_pending_request *req;
1044 if (_bt_mesh_util_opcode_get(data, data_len, &opcode, &n)) {
1045 BT_INFO("Mesh: Opcode of response data [0x%2.2x], actual data len [%d]", opcode, n);
1051 BT_INFO("Mesh: Received %s (len %u) opcode [0x%2.2x]",
1052 __mesh_get_opcode_string(opcode), data_len, opcode);
1054 req = __bt_mesh_get_request_by_response(event->source,
1055 event->net_uuid.uuid, (opcode & ~MESH_OPCODE_UNRELIABLE));
1057 BT_INFO("Mesh: Got Config Request");
1059 __mesh_request_remove(req);
1060 l_queue_remove(pending_requests, req);
1065 switch (opcode & ~MESH_OPCODE_UNRELIABLE) {
1068 case MESH_OPCODE_CONFIG_MODEL_PUB_STATUS: {
1069 if (data_len != 12 && data_len != 14)
1071 bluetooth_mesh_model_configure_t param;
1072 memset(¶m, 0x00, sizeof(bluetooth_mesh_model_configure_t));
1074 _bt_mesh_util_convert_hex_to_string((uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1075 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1077 BT_INFO("\nNode %4.4x Model Publication status %s\n",
1078 event->source, __mesh_status_to_string(data[0]));
1080 if (data[0] != MESH_STATUS_SUCCESS)
1083 /* Extract Element Address */
1084 ele_addr = l_get_le16(data + 1);
1086 /* Extract Model ID */
1087 if (data_len == 14) {
1089 mod_id = l_get_le16(data + 10 + 2);
1090 mod_id = l_get_le16(data) << 16 | mod_id;
1093 mod_id = l_get_le16(data + 10);
1094 mod_id = MESH_VENDOR_ID_MASK | mod_id;
1097 param.primary_unicast = event->source;
1098 param.elem_index = ele_addr - event->source;
1099 /* Extract Publish Address */
1100 param.pub_addr = l_get_le16(data + 3);
1102 /* Extract Appkey Index */
1103 param.appkey_idx = l_get_le16(data + 5);
1106 param.ttl = data[6];
1108 /* Extract Period */
1109 param.period = data[7];
1113 if (cmd->opcode == MESH_OPCODE_CONFIG_MODEL_PUB_GET)
1114 __bt_mesh_handle_pending_dev_config_request_info(result,
1115 BT_MESH_MODEL_GET_PUBLICATION, ¶m,
1116 sizeof(bluetooth_mesh_model_configure_t));
1118 __bt_mesh_handle_pending_dev_config_request_info(result,
1119 BT_MESH_MODEL_SET_PUBLICATION, ¶m,
1120 sizeof(bluetooth_mesh_model_configure_t));
1123 case MESH_OPCODE_CONFIG_MODEL_SUB_STATUS: {
1124 if (data_len != 7 && data_len != 9)
1126 bluetooth_mesh_model_configure_t param;
1127 memset(¶m, 0x00, sizeof(bluetooth_mesh_model_configure_t));
1129 _bt_mesh_util_convert_hex_to_string(
1130 (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1131 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1133 BT_INFO("\nNode %4.4x Subscription status %s\n",
1134 event->source, __mesh_status_to_string(data[0]));
1136 ele_addr = l_get_le16(data + 1);
1137 addr = l_get_le16(data + 3);
1138 BT_INFO("Element Addr\t%4.4x\n", ele_addr);
1140 if (data_len == 9) {
1142 mod_id = l_get_le16(data + 5 + 2);
1143 mod_id = l_get_le16(data) << 16 | mod_id;
1146 mod_id = l_get_le16(data + 5);
1147 mod_id = MESH_VENDOR_ID_MASK | mod_id;
1150 param.primary_unicast = event->source;
1151 param.elem_index = ele_addr - event->source;
1152 /* Subscription address, unassigned address in case of Delete All command */
1153 param.sub_addr = addr;
1154 param.model = mod_id;
1155 BT_INFO("Subscr Addr\t%4.4x\n", addr);
1158 __mesh_handle_model_subscription_event(result, ¶m, cmd);
1162 case MESH_OPCODE_CONFIG_DEFAULT_TTL_STATUS: {
1165 bluetooth_mesh_node_ttl_info_t param;
1166 memset(¶m, 0x00, sizeof(bluetooth_mesh_node_ttl_info_t));
1168 BT_INFO("Node %4.4x Default TTL %d", event->source, data[0]);
1169 _bt_mesh_util_convert_hex_to_string(
1170 (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1171 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1172 param.unicast = event->source;
1173 param.ttl = data[0];
1175 if (!_bt_mesh_network_save_remote_node_ttl(event->net_uuid.uuid,
1176 event->source, data[0])) {
1177 result = BLUETOOTH_ERROR_INTERNAL;
1178 BT_INFO("Failed to save node TTL");
1181 /* Remote Node TTL event */
1182 __bt_mesh_handle_pending_dev_config_request_info(result,
1183 BT_MESH_NODE_TTL_EXECUTE, ¶m,
1184 sizeof(bluetooth_mesh_node_ttl_info_t));
1187 case MESH_OPCODE_MODEL_APP_STATUS: {
1188 if (data_len != 7 && data_len != 9)
1190 bluetooth_mesh_model_configure_t param;
1191 memset(¶m, 0x00, sizeof(bluetooth_mesh_model_configure_t));
1193 _bt_mesh_util_convert_hex_to_string(
1194 (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1195 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1196 BT_INFO("Node %4.4x: Model App status %s\n", event->source,
1197 __mesh_status_to_string(data[0]));
1199 if (data[0] != MESH_STATUS_SUCCESS)
1200 result = BLUETOOTH_ERROR_INTERNAL;
1202 elem_addr = l_get_le16(data + 1);
1203 app_idx = l_get_le16(data + 3);
1205 BT_INFO("Element Addr\t%4.4x", elem_addr);
1206 if (data_len == 9) {
1208 mod_id = l_get_le16(data + 5 + 2);
1209 mod_id = l_get_le16(data) << 16 | mod_id;
1212 mod_id = l_get_le16(data + 5);
1213 mod_id = MESH_VENDOR_ID_MASK | mod_id;
1216 param.primary_unicast = event->source;
1217 param.elem_index = elem_addr - event->source;
1218 param.appkey_idx = app_idx;
1219 param.model = mod_id;
1220 BT_INFO("AppIdx\t\t%u (0x%3.3x)\n ", app_idx, app_idx);
1222 /* Model Bind/UnBind Event */
1223 __bt_mesh_handle_pending_dev_config_request_info(result,
1224 BT_MESH_MODEL_CONFIGURE_APPKEY, ¶m,
1225 sizeof(bluetooth_mesh_model_configure_t));
1228 case MESH_OPCODE_MODEL_APP_LIST: {
1233 bluetooth_mesh_model_configure_t param;
1234 memset(¶m, 0x00, sizeof(bluetooth_mesh_model_configure_t));
1236 _bt_mesh_util_convert_hex_to_string(
1237 (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1238 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1240 garray = g_array_new(FALSE, FALSE, sizeof(gchar));
1242 BT_INFO("\nNode %4.4x Model AppIdx status %s\n",
1243 event->source, __mesh_status_to_string(data[0]));
1245 BT_INFO("Element Addr\t%4.4x\n", l_get_le16(data + 1));
1246 BT_INFO("Model ID\t%4.4x\n", l_get_le16(data + 3));
1248 elem_addr = l_get_le16(data + 1);
1250 mod_id = l_get_le16(data + 3);
1251 mod_id = MESH_VENDOR_ID_MASK | mod_id;
1253 param.primary_unicast = event->source;
1254 param.elem_index = elem_addr - event->source;
1255 param.model = mod_id;
1260 while (data_len >= 3) {
1261 app_idx = l_get_le16(data) & 0xfff;
1262 g_array_append_vals(garray, &app_idx, sizeof(uint16_t));
1263 BT_INFO("\t%u (0x%3.3x)\n", app_idx, app_idx);
1265 app_idx = l_get_le16(data + 1) >> 4;
1266 g_array_append_vals(garray, &app_idx, sizeof(uint16_t));
1267 BT_INFO("\t%u (0x%3.3x)\n", app_idx, app_idx);
1272 if (data_len == 2) {
1273 app_idx = l_get_le16(data) & 0xfff;
1274 g_array_append_vals(garray, &app_idx, sizeof(uint16_t));
1275 BT_INFO("\t %u (0x%3.3x)\n", app_idx, app_idx);
1277 total = garray->len / sizeof(uint16_t);
1278 param.appkey_list = (uint16_t **)g_malloc0(sizeof(uint16_t*) * garray->len);
1279 param.appkeylist_count = total;
1280 for (int i = 0; i < total; i++) {
1281 param.appkey_list[i] = g_malloc(sizeof(uint16_t));
1282 *param.appkey_list[i] = g_array_index(garray, uint16_t, i);
1284 g_array_free(garray, TRUE);
1286 __bt_mesh_handle_pending_dev_config_request_info(result,
1287 BT_MESH_MODEL_GET_APPKEY_LIST, ¶m,
1288 sizeof(bluetooth_mesh_model_configure_t));
1291 case MESH_OPCODE_CONFIG_MODEL_SUB_LIST: {
1296 bluetooth_mesh_model_configure_t param;
1297 memset(¶m, 0x00, sizeof(bluetooth_mesh_model_configure_t));
1299 _bt_mesh_util_convert_hex_to_string((uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1300 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1302 BT_INFO("\nNode %4.4x BT SIG Model Subscription List status %s\n",
1303 event->source, __mesh_status_to_string(data[0]));
1305 BT_INFO("Element Addr\t%4.4x\n", l_get_le16(data + 1));
1306 elem_addr = l_get_le16(data + 1);
1309 mod_id = l_get_le16(data + 3);
1310 mod_id = MESH_VENDOR_ID_MASK | mod_id;
1311 BT_INFO("Model ID\t%4.4x\n", mod_id);
1313 param.primary_unicast = event->source;
1314 param.elem_index = elem_addr - event->source;
1315 param.model = mod_id;
1317 total = data_len - 5;
1318 param.sublist_count = total;
1320 param.sub_list = (uint16_t **)g_malloc0(sizeof(uint16_t*) * total);
1323 for (; i < data_len; i += 2) {
1324 BT_INFO("Subscription Addr \t\t%4.4x\n ", l_get_le16(data + i));
1325 param.sub_list[i] = g_malloc(sizeof(uint16_t));
1326 *param.sub_list[i] = l_get_le16(data + i);
1329 __bt_mesh_handle_pending_dev_config_request_info(result,
1330 BT_MESH_MODEL_GET_SUBSCRIPTION_LIST, ¶m,
1331 sizeof(bluetooth_mesh_model_configure_t));
1334 case MESH_OPCODE_CONFIG_VEND_MODEL_SUB_LIST: {
1339 bluetooth_mesh_model_configure_t param;
1340 memset(¶m, 0x00, sizeof(bluetooth_mesh_model_configure_t));
1342 _bt_mesh_util_convert_hex_to_string(
1343 (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1344 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1346 BT_INFO("\nNode %4.4x BT SIG Model Subscription List status %s\n",
1347 event->source, __mesh_status_to_string(data[0]));
1349 BT_INFO("Element Addr\t%4.4x\n", l_get_le16(data + 1));
1350 elem_addr = l_get_le16(data + 1);
1353 mod_id = l_get_le16(data + 5);
1354 mod_id = l_get_le16(data + 3) << 16 | mod_id;
1356 BT_INFO("Model ID\t%4.4x\n", mod_id);
1358 param.primary_unicast = event->source;
1359 param.elem_index = elem_addr - event->source;
1360 param.model = mod_id;
1362 total = data_len - 7;
1363 param.sublist_count = total;
1365 param.sub_list = (uint16_t **)g_malloc0(sizeof(uint16_t*) * total);
1368 for (; i < data_len; i += 2) {
1369 BT_INFO("Subscription Addr \t\t%4.4x\n ", l_get_le16(data + i));
1370 param.sub_list[i] = g_malloc(sizeof(uint16_t));
1371 *param.sub_list[i] = l_get_le16(data + i);
1374 __bt_mesh_handle_pending_dev_config_request_info(result,
1375 BT_MESH_MODEL_GET_SUBSCRIPTION_LIST, ¶m,
1376 sizeof(bluetooth_mesh_model_configure_t));
1379 case MESH_OPCODE_DEV_COMP_STATUS: {
1380 if (data_len < MESH_MINIMUM_COMPOSITION_LEN)
1382 bluetooth_mesh_node_features_t features;
1383 memset(&features, 0x00, sizeof(bluetooth_mesh_node_features_t));
1384 BT_INFO("Mesh: Got Response for Device Composition Data");
1385 __bt_mesh_print_device_composition_data(data, data_len);
1387 if (!_bt_mesh_network_save_remote_node_composition(
1388 event->net_uuid.uuid, event->source, data, data_len)) {
1389 result = BLUETOOTH_ERROR_INTERNAL;
1390 BT_INFO("Failed to save node composition!");
1392 /* Browse Remote Node event */
1393 __bt_mesh_handle_pending_dev_config_request_info(result,
1394 BT_MESH_NODE_BROWSE, event, sizeof(event_mesh_devkey_message_t));
1396 /* Vendor Features Discover event */
1397 _bt_mesh_util_convert_hex_to_string(
1398 (uint8_t *) event->net_uuid.uuid, 16, features.net_uuid,
1399 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1400 features.unicast = event->source;
1401 _bt_mesh_node_get_vendor_features(event->net_uuid.uuid,
1402 event->source, &features);
1404 __bt_mesh_handle_pending_dev_config_request_info(result,
1405 BT_MESH_NODE_GET_VENDOR_FEATURES, &features,
1406 sizeof(bluetooth_mesh_node_features_t));
1409 case MESH_OPCODE_NETKEY_STATUS: {
1413 bluetooth_mesh_key_configure_t param;
1414 memset(¶m, 0x00, sizeof(bluetooth_mesh_key_configure_t));
1416 BT_INFO("Mesh: Node %4.4x NetKey status %s",
1417 event->source, __mesh_status_to_string(data[0]));
1418 net_idx = l_get_le16(data + 1) & 0xfff;
1420 BT_INFO("\tNetKey %u (0x%3.3x)", net_idx, net_idx);
1423 result = BLUETOOTH_ERROR_INTERNAL;
1428 _bt_mesh_util_convert_hex_to_string(
1429 (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1430 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1431 param.primary_unicast = event->source;
1432 param.netkey_idx = net_idx;
1433 param.is_netkey = true;
1435 BT_INFO("Mesh: Resp recvd from node unicast [0x%4.4x]", event->source);
1436 if (cmd->opcode == MESH_OPCODE_NETKEY_ADD) {
1437 BT_INFO("Mesh: Resp recvd: MESH_OPCODE_NETKEY_ADD");
1438 if (result == BLUETOOTH_ERROR_NONE) {
1439 if (!_bt_mesh_network_save_remote_node_netkey(
1440 event->net_uuid.uuid, event->source, net_idx)) {
1441 result = BLUETOOTH_ERROR_INTERNAL;
1442 BT_INFO("Failed to save node Netkey!");
1445 param.op = BLUETOOTH_MESH_NODE_KEY_ADD;
1446 } else if (cmd->opcode == MESH_OPCODE_NETKEY_DELETE) {
1447 BT_INFO("Mesh: Resp recvd: MESH_OPCODE_NETKEY_DELETE");
1448 if (result == BLUETOOTH_ERROR_NONE) {
1449 if (!_bt_mesh_network_delete_remote_node_netkey(
1450 event->net_uuid.uuid, event->source, net_idx)) {
1451 result = BLUETOOTH_ERROR_INTERNAL;
1452 BT_INFO("Failed to delete node Netkey!");
1455 param.op = BLUETOOTH_MESH_NODE_KEY_DELETE;
1456 } else if (cmd->opcode == MESH_OPCODE_NETKEY_UPDATE) {
1457 BT_INFO("Mesh: Resp recvd: MESH_OPCODE_NETKEY_UPDATE");
1458 param.op = BLUETOOTH_MESH_NODE_KEY_UPDATE;
1460 /* Node Net Key Configure event */
1461 __bt_mesh_handle_pending_dev_config_request_info(result,
1462 BT_MESH_NODE_CONFIGURE_KEY,
1463 ¶m, sizeof(bluetooth_mesh_key_configure_t));
1466 case MESH_OPCODE_APPKEY_STATUS: {
1470 bluetooth_mesh_key_configure_t param;
1471 memset(¶m, 0x00, sizeof(bluetooth_mesh_key_configure_t));
1473 BT_INFO("Mesh: Node %4.4x AppKey status %s\n", event->source,
1474 __mesh_status_to_string(data[0]));
1475 net_idx = l_get_le16(data + 1) & 0xfff;
1476 app_idx = l_get_le16(data + 2) >> 4;
1478 BT_INFO("NetKey\t%u (0x%3.3x)\n", net_idx, net_idx);
1479 BT_INFO("AppKey\t%u (0x%3.3x)\n", app_idx, app_idx);
1481 if (data[0] != MESH_STATUS_SUCCESS)
1482 result = BLUETOOTH_ERROR_INTERNAL;
1487 _bt_mesh_util_convert_hex_to_string(
1488 (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
1489 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1491 param.primary_unicast = event->source;
1492 param.netkey_idx = net_idx;
1493 param.appkey_idx = app_idx;
1494 param.is_netkey = false;
1496 if (cmd->opcode == MESH_OPCODE_APPKEY_ADD) {
1497 BT_INFO("Mesh: Resp recvd: MESH_OPCODE_APPKEY_ADD");
1498 if (result == BLUETOOTH_ERROR_NONE) {
1499 if (!_bt_mesh_network_save_remote_node_appkey(
1500 event->net_uuid.uuid, event->source,
1501 net_idx, app_idx)) {
1502 result = BLUETOOTH_ERROR_INTERNAL;
1503 BT_INFO("Failed to save node Appkey!");
1506 param.op = BLUETOOTH_MESH_NODE_KEY_ADD;
1507 } else if (cmd->opcode == MESH_OPCODE_APPKEY_DELETE) {
1508 BT_INFO("Mesh: Resp recvd: MESH_OPCODE_APPKEY_DELETE");
1509 if (result == BLUETOOTH_ERROR_NONE) {
1510 if (!_bt_mesh_network_delete_remote_node_appkey(
1511 event->net_uuid.uuid, event->source,
1512 net_idx, app_idx)) {
1513 result = BLUETOOTH_ERROR_INTERNAL;
1514 BT_INFO("Failed to delete node Appkey!");
1517 param.op = BLUETOOTH_MESH_NODE_KEY_DELETE;
1518 } else if (cmd->opcode == MESH_OPCODE_APPKEY_UPDATE) {
1519 BT_INFO("Mesh: Resp recvd: MESH_OPCODE_APPKEY_UPDATE");
1520 param.op = BLUETOOTH_MESH_NODE_KEY_UPDATE;
1523 /* Node App Key Configure event */
1524 __bt_mesh_handle_pending_dev_config_request_info(result,
1525 BT_MESH_NODE_CONFIGURE_KEY,
1526 ¶m, sizeof(bluetooth_mesh_key_configure_t));
1532 static gboolean __bt_mesh_vendor_feature_event_handler(gpointer data)
1534 bluetooth_mesh_node_features_t *result = (bluetooth_mesh_node_features_t*) data;
1535 __bt_mesh_handle_pending_dev_config_request_info(
1536 BLUETOOTH_ERROR_NONE,
1537 BT_MESH_NODE_GET_VENDOR_FEATURES,
1538 result, sizeof(bluetooth_mesh_node_features_t));
1543 int _bt_mesh_node_discover_vendor_features(const char *app_cred, const char *sender,
1544 bluetooth_mesh_node_features_t *req)
1546 int ret = OAL_STATUS_SUCCESS;
1548 uint16_t netkey_idx;
1550 oal_uuid_t net_uuid;
1551 uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
1553 _bt_mesh_util_convert_string_to_hex(req->net_uuid,
1554 strlen(req->net_uuid), net_uuid.uuid, 16);
1555 /* Check if Node's vendor features are already svaed or not */
1556 if (_bt_mesh_node_get_vendor_features(net_uuid.uuid, req->unicast, req)) {
1557 /* Schedule event ot Application */
1558 bluetooth_mesh_node_features_t *event = \
1559 g_memdup(req, sizeof(bluetooth_mesh_node_features_t));
1560 g_idle_add(__bt_mesh_vendor_feature_event_handler, (gpointer) event);
1561 return BLUETOOTH_ERROR_NONE;
1564 /* If Scanning is going on */
1565 if (_bt_mesh_is_provisioning() ||
1566 _bt_mesh_is_scanning()) {
1567 BT_ERR("Device is buzy..");
1568 return BLUETOOTH_ERROR_DEVICE_BUSY;
1571 _bt_mesh_util_convert_string_to_hex(req->net_uuid,
1572 strlen(req->net_uuid), net_uuid.uuid, 16);
1574 dest = req->unicast;
1576 /* Check pending request */
1577 if (_bt_mesh_check_pending_request(MESH_OPCODE_DEV_COMP_GET,
1578 dest, net_uuid.uuid)) {
1579 BT_ERR("Device is buzy..");
1580 return BLUETOOTH_ERROR_DEVICE_BUSY;
1583 /* Get Subnet index of the rmeote node for TX encryption */
1584 netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, dest);
1585 if (netkey_idx == MESH_NET_IDX_INVALID)
1586 return BLUETOOTH_ERROR_INTERNAL;
1588 data_len = _bt_mesh_util_opcode_set(MESH_OPCODE_DEV_COMP_GET,
1591 /* By default, use page 0 */
1592 buffer[data_len++] = 0;
1593 ret = mesh_conf_send_message(&net_uuid, dest, true,
1594 netkey_idx, buffer, data_len);
1596 if (ret != OAL_STATUS_SUCCESS) {
1597 BT_ERR("ret: %d", ret);
1598 return BLUETOOTH_ERROR_INTERNAL;
1601 /* Queue the request with timeout */
1602 __bt_mesh_add_request(MESH_OPCODE_DEV_COMP_GET,
1603 dest, net_uuid.uuid, NULL);
1604 return BLUETOOTH_ERROR_NONE;
1607 int _bt_mesh_browse_remote_node(const char *app_cred,
1609 bluetooth_mesh_node_discover_t *req)
1611 int ret = OAL_STATUS_SUCCESS;
1613 uint16_t netkey_idx;
1615 oal_uuid_t net_uuid;
1616 oal_uuid_t dev_uuid;
1617 uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
1619 /* If Scanning is going on */
1620 if (_bt_mesh_is_provisioning() ||
1621 _bt_mesh_is_scanning()) {
1622 BT_ERR("Device is buzy..");
1623 return BLUETOOTH_ERROR_DEVICE_BUSY;
1626 _bt_mesh_util_convert_string_to_hex(req->net_uuid,
1627 strlen(req->net_uuid), net_uuid.uuid, 16);
1628 _bt_mesh_util_convert_string_to_hex(req->dev_uuid,
1629 strlen(req->dev_uuid), dev_uuid.uuid, 16);
1631 BT_INFO("Mesh: Browse Node UUID [%s]", req->dev_uuid);
1633 /* Get Remote Node unicast address from Dev UUID */
1634 if (!_bt_mesh_node_get_unicast_from_dev_uuid(net_uuid.uuid,
1635 dev_uuid.uuid, &dest))
1636 return BLUETOOTH_ERROR_INTERNAL;
1638 /* Check pending request */
1639 if (_bt_mesh_check_pending_request(MESH_OPCODE_DEV_COMP_GET,
1640 dest, net_uuid.uuid)) {
1641 BT_ERR("Device is buzy..");
1642 return BLUETOOTH_ERROR_DEVICE_BUSY;
1645 /* Get Subnet index of the rmeote node for TX encryption */
1646 netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, dest);
1647 if (netkey_idx == MESH_NET_IDX_INVALID)
1648 return BLUETOOTH_ERROR_INTERNAL;
1650 data_len = _bt_mesh_util_opcode_set(MESH_OPCODE_DEV_COMP_GET, buffer);
1652 /* By default, use page 0 */
1653 buffer[data_len++] = 0;
1654 ret = mesh_conf_send_message(&net_uuid, dest, true,
1655 netkey_idx, buffer, data_len);
1657 if (ret != OAL_STATUS_SUCCESS) {
1658 BT_ERR("ret: %d", ret);
1659 return BLUETOOTH_ERROR_INTERNAL;
1662 /* Queue the request with timeout */
1663 __bt_mesh_add_request(MESH_OPCODE_DEV_COMP_GET,
1664 dest, net_uuid.uuid, NULL);
1665 return BLUETOOTH_ERROR_NONE;
1668 int _bt_mesh_model_configure_group_subscription(const char *app_cred,
1669 const char *sender, bluetooth_mesh_model_configure_t *req)
1671 int ret = OAL_STATUS_SUCCESS;
1672 uint16_t netkey_idx;
1673 oal_uuid_t net_uuid;
1675 uint32_t opcode = 0;
1676 uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
1678 /* If Scanning is going on */
1679 if (_bt_mesh_is_provisioning() ||
1680 _bt_mesh_is_scanning()) {
1681 BT_ERR("Device is buzy..");
1682 return BLUETOOTH_ERROR_DEVICE_BUSY;
1685 if (req->op != BLUETOOTH_MESH_MODEL_SUB_DELETE_ALL) {
1686 /* Subscriptio address sanity check */
1687 if ((!MESH_IS_GROUP(req->sub_addr) ||
1688 MESH_IS_ALL_NODES(req->sub_addr)) ||
1689 MESH_IS_VIRTUAL(req->sub_addr)) {
1690 BT_ERR("Mesh: Bad subscription address %x\n",
1692 return BLUETOOTH_ERROR_INVALID_PARAM;
1696 /* Get Subnet index of the remote node for TX encryption */
1697 netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid,
1698 req->primary_unicast);
1699 if (netkey_idx == MESH_NET_IDX_INVALID)
1700 return BLUETOOTH_ERROR_INTERNAL;
1702 _bt_mesh_util_convert_string_to_hex(req->net_uuid,
1703 strlen(req->net_uuid), net_uuid.uuid, 16);
1705 if (req->op == BLUETOOTH_MESH_MODEL_SUB_ADD)
1706 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_ADD;
1707 else if (req->op == BLUETOOTH_MESH_MODEL_SUB_DELETE)
1708 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_DELETE;
1709 else if (req->op == BLUETOOTH_MESH_MODEL_SUB_DELETE_ALL)
1710 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_DELETE_ALL;
1711 else if (req->op == BLUETOOTH_MESH_MODEL_SUB_OVERWRITE)
1712 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_OVERWRITE;
1714 /* Check pending request */
1715 if (_bt_mesh_check_pending_request(opcode,
1716 req->primary_unicast, net_uuid.uuid)) {
1717 BT_ERR("Device is buzy..");
1718 return BLUETOOTH_ERROR_DEVICE_BUSY;
1721 data_len = _bt_mesh_util_opcode_set(opcode, buffer);
1723 /* Element Address */
1724 l_put_le16((req->primary_unicast + req->elem_index),
1728 /* Subscription address */
1729 if (req->op != BLUETOOTH_MESH_MODEL_SUB_DELETE_ALL) {
1730 l_put_le16(req->sub_addr, buffer + data_len);
1734 /* Insert Model ID */
1735 if (req->model >= 0xFFFF0000) {
1736 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
1737 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
1740 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
1741 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
1743 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
1747 ret = mesh_conf_send_message(&net_uuid, req->primary_unicast, true,
1748 netkey_idx, buffer, data_len);
1750 if (ret != OAL_STATUS_SUCCESS) {
1751 BT_ERR("ret: %d", ret);
1752 return BLUETOOTH_ERROR_INTERNAL;
1755 /* Queue the request with timeout */
1756 __bt_mesh_add_request(opcode, req->primary_unicast,
1758 g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
1760 return BLUETOOTH_ERROR_NONE;
1763 int _bt_mesh_model_configure_virtual_group_subscription(
1764 const char *app_cred, const char *sender,
1765 bluetooth_mesh_model_configure_t *req)
1767 int ret = OAL_STATUS_SUCCESS;
1768 uint16_t netkey_idx;
1769 oal_uuid_t net_uuid;
1771 uint32_t opcode = 0;
1772 uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
1774 /* If Scanning is going on */
1775 if (_bt_mesh_is_provisioning() ||
1776 _bt_mesh_is_scanning()) {
1777 BT_ERR("Device is buzy..");
1778 return BLUETOOTH_ERROR_DEVICE_BUSY;
1781 _bt_mesh_util_convert_string_to_hex(req->net_uuid,
1782 strlen(req->net_uuid), net_uuid.uuid, 16);
1784 if (req->op != BLUETOOTH_MESH_MODEL_SUB_DELETE_ALL) {
1785 /* Subscription address sanity check */
1786 if ((MESH_IS_GROUP(req->sub_addr) ||
1787 MESH_IS_ALL_NODES(req->sub_addr)) ||
1788 !(MESH_IS_VIRTUAL(req->sub_addr))) {
1789 BT_ERR("Mesh: Bad Virtual subscription address %x\n",
1791 return BLUETOOTH_ERROR_INVALID_PARAM;
1795 /* Get Subnet index of the remote node for TX encryption */
1796 netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid,
1797 req->primary_unicast);
1798 if (netkey_idx == MESH_NET_IDX_INVALID)
1799 return BLUETOOTH_ERROR_INTERNAL;
1801 if (req->op == BLUETOOTH_MESH_MODEL_SUB_ADD)
1802 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_ADD;
1803 else if (req->op == BLUETOOTH_MESH_MODEL_SUB_DELETE)
1804 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_DELETE;
1805 else if (req->op == BLUETOOTH_MESH_MODEL_SUB_DELETE_ALL)
1806 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_DELETE_ALL;
1807 else if (req->op == BLUETOOTH_MESH_MODEL_SUB_OVERWRITE)
1808 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_OVERWRITE;
1810 /* Check pending request */
1811 if (_bt_mesh_check_pending_request(opcode,
1812 req->primary_unicast, net_uuid.uuid)) {
1813 BT_ERR("Device is buzy..");
1814 return BLUETOOTH_ERROR_DEVICE_BUSY;
1817 data_len = _bt_mesh_util_opcode_set(opcode, buffer);
1819 /* Element Address */
1820 l_put_le16((req->primary_unicast + req->elem_index), buffer + data_len);
1823 /* Subscription address */
1824 if (req->op != BLUETOOTH_MESH_MODEL_SUB_DELETE_ALL) {
1825 uint8_t label_uuid[16];
1826 if (!_bt_mesh_network_get_label_uuid_from_sub_addr(
1827 net_uuid.uuid, req->sub_addr, label_uuid)) {
1828 BT_ERR("Mesh: Virtual Group Label UUID Not found");
1829 return BLUETOOTH_ERROR_INVALID_PARAM;
1831 memcpy(buffer + data_len, label_uuid, 16);
1835 /* Insert Model ID */
1836 if (req->model >= 0xFFFF0000) {
1837 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
1838 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
1841 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
1842 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
1844 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
1848 ret = mesh_conf_send_message(&net_uuid,
1849 req->primary_unicast, true,
1850 netkey_idx, buffer, data_len);
1852 if (ret != OAL_STATUS_SUCCESS) {
1853 BT_ERR("ret: %d", ret);
1854 return BLUETOOTH_ERROR_INTERNAL;
1857 /* Queue the request with timeout */
1858 __bt_mesh_add_request(opcode, req->primary_unicast,
1860 g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
1862 return BLUETOOTH_ERROR_NONE;
1865 int _bt_mesh_model_get_publication(const char *app_cred, const char *sender,
1866 bluetooth_mesh_model_configure_t *req)
1868 int ret = OAL_STATUS_SUCCESS;
1869 uint16_t netkey_idx;
1870 oal_uuid_t net_uuid;
1872 uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
1874 /* If Scanning is going on */
1875 if (_bt_mesh_is_provisioning() ||
1876 _bt_mesh_is_scanning()) {
1877 BT_ERR("Device is buzy..");
1878 return BLUETOOTH_ERROR_DEVICE_BUSY;
1881 _bt_mesh_util_convert_string_to_hex(req->net_uuid,
1882 strlen(req->net_uuid), net_uuid.uuid, 16);
1884 /* Check pending request */
1885 if (_bt_mesh_check_pending_request(MESH_OPCODE_CONFIG_MODEL_PUB_GET,
1886 req->primary_unicast, net_uuid.uuid)) {
1887 BT_ERR("Device is buzy..");
1888 return BLUETOOTH_ERROR_DEVICE_BUSY;
1891 /* Get Subnet index of the remote node for TX encryption */
1892 netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, req->primary_unicast);
1893 if (netkey_idx == MESH_NET_IDX_INVALID)
1894 return BLUETOOTH_ERROR_INTERNAL;
1897 data_len = _bt_mesh_util_opcode_set(MESH_OPCODE_CONFIG_MODEL_PUB_GET, buffer);
1899 /* Element Address */
1900 l_put_le16((req->primary_unicast + req->elem_index), buffer + data_len);
1903 /* Insert Model ID */
1904 if (req->model >= 0xFFFF0000) {
1905 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
1906 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
1909 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
1910 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
1912 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
1916 ret = mesh_conf_send_message(&net_uuid, req->primary_unicast, true, netkey_idx, buffer, data_len);
1918 if (ret != OAL_STATUS_SUCCESS) {
1919 BT_ERR("ret: %d", ret);
1920 return BLUETOOTH_ERROR_INTERNAL;
1923 /* Queue the request with timeout */
1924 __bt_mesh_add_request(MESH_OPCODE_CONFIG_MODEL_PUB_GET, req->primary_unicast, net_uuid.uuid,
1925 g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
1927 return BLUETOOTH_ERROR_NONE;
1930 int _bt_mesh_model_set_publication(const char *app_cred, const char *sender,
1931 bluetooth_mesh_model_configure_t *req)
1933 int ret = OAL_STATUS_SUCCESS;
1934 uint16_t netkey_idx;
1935 oal_uuid_t net_uuid;
1937 uint32_t opcode = 0;
1938 uint8_t label_uuid[16];
1939 uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
1941 /* If Scanning is going on */
1942 if (_bt_mesh_is_provisioning() ||
1943 _bt_mesh_is_scanning()) {
1944 BT_ERR("Device is buzy..");
1945 return BLUETOOTH_ERROR_DEVICE_BUSY;
1948 _bt_mesh_util_convert_string_to_hex(req->net_uuid, strlen(req->net_uuid), net_uuid.uuid, 16);
1950 if (req->pub_addr == MESH_ALL_NODES_ADDRESS)
1951 BT_INFO("Mesh: Setting Publication to ALL Node Address");
1953 if (!MESH_IS_GROUP(req->pub_addr) && !MESH_IS_VIRTUAL(req->pub_addr) &&
1954 req->pub_addr != MESH_UNASSIGNED_ADDRESS) {
1955 BT_ERR("Mesh: Bad Publication address %x\n", req->pub_addr);
1956 return BLUETOOTH_ERROR_INVALID_PARAM;
1959 if (req->pub_addr != MESH_UNASSIGNED_ADDRESS) {
1960 if (MESH_IS_VIRTUAL(req->pub_addr)) {
1961 if(!_bt_mesh_network_get_label_uuid_from_sub_addr(
1962 net_uuid.uuid, req->pub_addr, label_uuid))
1963 return BLUETOOTH_ERROR_INVALID_PARAM;
1964 opcode = MESH_OPCODE_CONFIG_MODEL_PUB_VIRT_SET;
1966 } else if (MESH_IS_GROUP(req->pub_addr))
1967 opcode = MESH_OPCODE_CONFIG_MODEL_PUB_SET;
1970 /* Check pending request */
1971 if (_bt_mesh_check_pending_request(opcode,
1972 req->primary_unicast, net_uuid.uuid)) {
1973 BT_ERR("Device is buzy..");
1974 return BLUETOOTH_ERROR_DEVICE_BUSY;
1977 /* Get Subnet index of the remote node for TX encryption */
1978 netkey_idx = _bt_mesh_node_get_subnet_idx(
1979 net_uuid.uuid, req->primary_unicast);
1980 if (netkey_idx == MESH_NET_IDX_INVALID)
1981 return BLUETOOTH_ERROR_INTERNAL;
1984 data_len = _bt_mesh_util_opcode_set(opcode, buffer);
1986 /* Element Address */
1987 l_put_le16((req->primary_unicast + req->elem_index), buffer + data_len);
1990 /* Fill Publication Address */
1991 if (MESH_IS_VIRTUAL(req->pub_addr)) {
1992 memcpy(buffer + data_len, label_uuid, 16);
1995 l_put_le16(req->pub_addr, buffer + data_len);
1999 /* AppKey index + credential (set to 0) */
2000 l_put_le16(req->appkey_idx, buffer + data_len);
2004 buffer[data_len++] = req->ttl;
2005 /* Publish period step count and step resolution */
2006 buffer[data_len++] = req->period;
2007 /* Publish retransmit count & interval steps */
2008 buffer[data_len++] = req->retransmit;
2010 /* Insert Model ID */
2011 if (req->model >= 0xFFFF0000) {
2012 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
2013 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2016 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
2017 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
2019 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2023 ret = mesh_conf_send_message(&net_uuid,
2024 req->primary_unicast, true,
2025 netkey_idx, buffer, data_len);
2027 if (ret != OAL_STATUS_SUCCESS) {
2028 BT_ERR("ret: %d", ret);
2029 return BLUETOOTH_ERROR_INTERNAL;
2032 /* Queue the request with timeout */
2033 __bt_mesh_add_request(opcode, req->primary_unicast, net_uuid.uuid,
2034 g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
2036 return BLUETOOTH_ERROR_NONE;
2039 int _bt_mesh_node_model_get_subscription_list(const char *app_cred, const char *sender,
2040 bluetooth_mesh_model_configure_t *req)
2042 int ret = OAL_STATUS_SUCCESS;
2043 uint16_t netkey_idx;
2044 oal_uuid_t net_uuid;
2046 uint32_t opcode = 0;
2047 uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
2049 /* If Scanning is going on */
2050 if (_bt_mesh_is_provisioning() ||
2051 _bt_mesh_is_scanning()) {
2052 BT_ERR("Device is buzy..");
2053 return BLUETOOTH_ERROR_DEVICE_BUSY;
2056 _bt_mesh_util_convert_string_to_hex(req->net_uuid, strlen(req->net_uuid), net_uuid.uuid, 16);
2058 /* Insert Model ID */
2059 if (req->model >= 0xFFFF0000)
2060 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
2061 opcode = MESH_OPCODE_CONFIG_MODEL_SUB_GET;
2063 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
2064 opcode = MESH_OPCODE_CONFIG_VEND_MODEL_SUB_GET;
2066 /* Check pending request */
2067 if (_bt_mesh_check_pending_request(opcode,
2068 req->primary_unicast, net_uuid.uuid)) {
2069 BT_ERR("Device is buzy..");
2070 return BLUETOOTH_ERROR_DEVICE_BUSY;
2072 /* Get Subnet index of the remote node for TX encryption */
2073 netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, req->primary_unicast);
2074 if (netkey_idx == MESH_NET_IDX_INVALID)
2075 return BLUETOOTH_ERROR_INTERNAL;
2077 data_len = _bt_mesh_util_opcode_set(opcode, buffer);
2078 /* Element Address */
2079 l_put_le16((req->primary_unicast + req->elem_index), buffer + data_len);
2083 /* Insert Model ID */
2084 if (opcode == MESH_OPCODE_CONFIG_MODEL_SUB_GET) {
2085 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
2086 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2089 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
2090 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
2092 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2096 ret = mesh_conf_send_message(&net_uuid,
2097 req->primary_unicast, true, netkey_idx, buffer, data_len);
2099 if (ret != OAL_STATUS_SUCCESS) {
2100 BT_ERR("ret: %d", ret);
2101 return BLUETOOTH_ERROR_INTERNAL;
2104 /* Queue the request with timeout */
2105 __bt_mesh_add_request(opcode, req->primary_unicast, net_uuid.uuid,
2106 g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
2108 return BLUETOOTH_ERROR_NONE;
2111 int _bt_mesh_node_model_get_appkey_list(const char *app_cred, const char *sender,
2112 bluetooth_mesh_model_configure_t *req)
2114 int ret = OAL_STATUS_SUCCESS;
2115 uint16_t netkey_idx;
2116 oal_uuid_t net_uuid;
2118 uint32_t opcode = 0;
2119 uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
2121 /* If Scanning is going on */
2122 if (_bt_mesh_is_provisioning() ||
2123 _bt_mesh_is_scanning()) {
2124 BT_ERR("Device is buzy..");
2125 return BLUETOOTH_ERROR_DEVICE_BUSY;
2128 _bt_mesh_util_convert_string_to_hex(req->net_uuid,
2129 strlen(req->net_uuid), net_uuid.uuid, 16);
2131 /* Insert Model ID */
2132 if (req->model >= 0xFFFF0000)
2133 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
2134 opcode = MESH_OPCODE_MODEL_APP_GET;
2136 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
2137 opcode = MESH_OPCODE_VENDOR_MODEL_APP_GET;
2139 /* Check pending request */
2140 if (_bt_mesh_check_pending_request(opcode,
2141 req->primary_unicast, net_uuid.uuid)) {
2142 BT_ERR("Device is buzy..");
2143 return BLUETOOTH_ERROR_DEVICE_BUSY;
2145 /* Get Subnet index of the remote node for TX encryption */
2146 netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, req->primary_unicast);
2147 if (netkey_idx == MESH_NET_IDX_INVALID)
2148 return BLUETOOTH_ERROR_INTERNAL;
2150 data_len = _bt_mesh_util_opcode_set(opcode, buffer);
2151 /* Element Address */
2152 l_put_le16((req->primary_unicast + req->elem_index), buffer + data_len);
2156 /* Insert Model ID */
2157 if (opcode == MESH_OPCODE_MODEL_APP_GET) {
2158 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
2159 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2162 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
2163 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
2165 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2169 ret = mesh_conf_send_message(&net_uuid, req->primary_unicast, true, netkey_idx, buffer, data_len);
2171 if (ret != OAL_STATUS_SUCCESS) {
2172 BT_ERR("ret: %d", ret);
2173 return BLUETOOTH_ERROR_INTERNAL;
2176 /* Queue the request with timeout */
2177 __bt_mesh_add_request(opcode, req->primary_unicast, net_uuid.uuid,
2178 g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
2180 return BLUETOOTH_ERROR_NONE;
2183 int _bt_mesh_node_model_appkey_execute(const char *app_cred, const char *sender,
2184 bluetooth_mesh_model_configure_t *req)
2186 int ret = OAL_STATUS_SUCCESS;
2187 uint16_t netkey_idx;
2188 oal_uuid_t net_uuid;
2190 uint32_t opcode = 0;
2191 uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
2193 /* If Scanning is going on */
2194 if (_bt_mesh_is_provisioning() ||
2195 _bt_mesh_is_scanning()) {
2196 BT_ERR("Device is buzy..");
2197 return BLUETOOTH_ERROR_DEVICE_BUSY;
2200 _bt_mesh_util_convert_string_to_hex(req->net_uuid, strlen(req->net_uuid), net_uuid.uuid, 16);
2202 /* Check pending request */
2203 if (_bt_mesh_check_pending_request(req->is_bind ? MESH_OPCODE_MODEL_APP_BIND : MESH_OPCODE_MODEL_APP_UNBIND,
2204 req->primary_unicast, net_uuid.uuid)) {
2205 BT_ERR("Device is buzy..");
2206 return BLUETOOTH_ERROR_DEVICE_BUSY;
2208 /* Get Subnet index of the remote node for TX encryption */
2209 netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, req->primary_unicast);
2210 if (netkey_idx == MESH_NET_IDX_INVALID)
2211 return BLUETOOTH_ERROR_INTERNAL;
2214 opcode = MESH_OPCODE_MODEL_APP_BIND;
2216 opcode = MESH_OPCODE_MODEL_APP_UNBIND;
2218 data_len = _bt_mesh_util_opcode_set(opcode, buffer);
2219 /* Element Address */
2220 l_put_le16((req->primary_unicast + req->elem_index), buffer + data_len);
2224 l_put_le16(req->appkey_idx, buffer + data_len);
2227 /* Insert Model ID */
2228 if (req->model >= 0xFFFF0000) {
2229 /* 1st 2 octet Company ID is 0xFFFF means, it is BT SIG Model*/
2230 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2233 /* Vendor Model, 1st 2 octetes: Company ID, next 2 octets: Vendor Model ID */
2234 l_put_le16(req->model & 0xFFFF0000, buffer + data_len);
2236 l_put_le16(req->model & 0x0000FFFF, buffer + data_len);
2240 ret = mesh_conf_send_message(&net_uuid, req->primary_unicast, true, netkey_idx, buffer, data_len);
2242 if (ret != OAL_STATUS_SUCCESS) {
2243 BT_ERR("ret: %d", ret);
2244 return BLUETOOTH_ERROR_INTERNAL;
2247 /* Queue the request with timeout */
2248 __bt_mesh_add_request(opcode, req->primary_unicast, net_uuid.uuid,
2249 g_memdup(req, sizeof(bluetooth_mesh_model_configure_t)));
2251 return BLUETOOTH_ERROR_NONE;
2254 int _bt_mesh_ttl_execute_remote_node(const char *app_cred, const char *sender,
2255 bluetooth_mesh_node_ttl_info_t *req)
2257 int ret = OAL_STATUS_SUCCESS;
2258 uint16_t netkey_idx;
2260 oal_uuid_t net_uuid;
2261 uint32_t opcode = 0;
2262 uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
2264 /* If Scanning is going on */
2265 if (_bt_mesh_is_provisioning() ||
2266 _bt_mesh_is_scanning()) {
2267 BT_ERR("Device is buzy..");
2268 return BLUETOOTH_ERROR_DEVICE_BUSY;
2271 _bt_mesh_util_convert_string_to_hex(req->net_uuid, strlen(req->net_uuid), net_uuid.uuid, 16);
2273 /* Check pending request */
2274 if (_bt_mesh_check_pending_request(req->is_set ? MESH_OPCODE_CONFIG_DEFAULT_TTL_SET : MESH_OPCODE_CONFIG_DEFAULT_TTL_GET,
2275 req->unicast, net_uuid.uuid)) {
2276 BT_ERR("Device is buzy..");
2277 return BLUETOOTH_ERROR_DEVICE_BUSY;
2280 /* Get Subnet index of the rmeote node for TX encryption */
2281 netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, req->unicast);
2282 if (netkey_idx == MESH_NET_IDX_INVALID)
2283 return BLUETOOTH_ERROR_INTERNAL;
2286 opcode = MESH_OPCODE_CONFIG_DEFAULT_TTL_SET;
2287 data_len = _bt_mesh_util_opcode_set(MESH_OPCODE_CONFIG_DEFAULT_TTL_SET, buffer);
2288 buffer[data_len++] = req->ttl;
2290 opcode = MESH_OPCODE_CONFIG_DEFAULT_TTL_GET;
2291 data_len = _bt_mesh_util_opcode_set(MESH_OPCODE_CONFIG_DEFAULT_TTL_GET, buffer);
2294 ret = mesh_conf_send_message(&net_uuid, req->unicast, true, netkey_idx, buffer, data_len);
2296 if (ret != OAL_STATUS_SUCCESS) {
2297 BT_ERR("ret: %d", ret);
2298 return BLUETOOTH_ERROR_INTERNAL;
2301 /* Queue the request with timeout */
2302 __bt_mesh_add_request(opcode, req->unicast, net_uuid.uuid,
2303 g_memdup(req, sizeof(bluetooth_mesh_node_ttl_info_t)));
2304 return BLUETOOTH_ERROR_NONE;
2307 static bool __bt_mesh_check_pending_key_cmd(uint16_t dest, bool is_netkey,
2308 bluetooth_mesh_node_key_conf_e op, uint8_t net_uuid[], uint32_t *opcode)
2310 const struct mesh_config_cmd *cmd;
2314 case BLUETOOTH_MESH_NODE_KEY_ADD:
2315 cmd = __mesh_get_command(MESH_OPCODE_NETKEY_ADD);
2318 if (__bt_mesh_get_request_by_response(dest, net_uuid, cmd->response)) {
2319 BT_ERR("Mesh:Another Key Configuration command is pending\n");
2322 *opcode = MESH_OPCODE_NETKEY_ADD;
2324 case BLUETOOTH_MESH_NODE_KEY_DELETE:
2325 cmd = __mesh_get_command(MESH_OPCODE_NETKEY_DELETE);
2328 if (__bt_mesh_get_request_by_response(dest, net_uuid, cmd->response)) {
2329 BT_ERR("Mesh:Another Key Configuration command is pending\n");
2332 *opcode = MESH_OPCODE_NETKEY_DELETE;
2334 case BLUETOOTH_MESH_NODE_KEY_UPDATE:
2335 cmd = __mesh_get_command(MESH_OPCODE_NETKEY_UPDATE);
2338 if (__bt_mesh_get_request_by_response(dest, net_uuid, cmd->response)) {
2339 BT_ERR("Mesh:Another Key Configuration command is pending\n");
2342 *opcode = MESH_OPCODE_NETKEY_UPDATE;
2347 case BLUETOOTH_MESH_NODE_KEY_ADD:
2348 cmd = __mesh_get_command(MESH_OPCODE_APPKEY_ADD);
2351 if (__bt_mesh_get_request_by_response(dest, net_uuid, cmd->response)) {
2352 BT_ERR("Mesh:Another Key Configuration command is pending\n");
2355 *opcode = MESH_OPCODE_APPKEY_ADD;
2357 case BLUETOOTH_MESH_NODE_KEY_DELETE:
2358 cmd = __mesh_get_command(MESH_OPCODE_APPKEY_DELETE);
2361 if (__bt_mesh_get_request_by_response(dest, net_uuid, cmd->response)) {
2362 BT_ERR("Mesh:Another Key Configuration command is pending\n");
2365 *opcode = MESH_OPCODE_APPKEY_DELETE;
2367 case BLUETOOTH_MESH_NODE_KEY_UPDATE:
2368 cmd = __mesh_get_command(MESH_OPCODE_APPKEY_UPDATE);
2371 if (__bt_mesh_get_request_by_response(dest, net_uuid, cmd->response)) {
2372 BT_ERR("Mesh:Another Key Configuration command is pending\n");
2375 *opcode = MESH_OPCODE_APPKEY_UPDATE;
2382 int _bt_mesh_node_configure_key(const char *app_cred, const char *sender,
2383 bluetooth_mesh_key_configure_t *req)
2385 int ret = OAL_STATUS_SUCCESS;
2386 uint16_t netkey_idx;
2387 uint16_t bound_netkey_idx = 0x0000;
2388 oal_uuid_t net_uuid;
2389 uint32_t opcode = 0;
2392 uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
2394 /* If Scanning is going on */
2395 if (_bt_mesh_is_provisioning() ||
2396 _bt_mesh_is_scanning()) {
2397 BT_ERR("Device is buzy..");
2398 return BLUETOOTH_ERROR_DEVICE_BUSY;
2401 _bt_mesh_util_convert_string_to_hex(req->net_uuid, strlen(req->net_uuid), net_uuid.uuid, 16);
2403 if (req->is_netkey && !_bt_mesh_keys_subnet_exists(net_uuid.uuid, req->netkey_idx)) {
2404 BT_ERR("Local Subnet not found..");
2405 return BLUETOOTH_ERROR_INVALID_PARAM;
2408 /* For Appkey Configuration, check for available bound netkey */
2409 if (!req->is_netkey) {
2410 bound_netkey_idx = _bt_mesh_keys_get_bound_key(net_uuid.uuid, req->appkey_idx);
2411 if (bound_netkey_idx == MESH_NET_IDX_INVALID) {
2412 BT_ERR("Local AppKey not found..");
2413 return BLUETOOTH_ERROR_INVALID_PARAM;
2417 /* Check pending request */
2418 if (__bt_mesh_check_pending_key_cmd(req->primary_unicast,
2419 req->is_netkey, req->op, net_uuid.uuid, &opcode)) {
2420 BT_ERR("Device is buzy..");
2421 return BLUETOOTH_ERROR_DEVICE_BUSY;
2424 /* Get Subnet index of the rmeote node for TX encryption */
2425 netkey_idx = _bt_mesh_node_get_subnet_idx(net_uuid.uuid, req->primary_unicast);
2426 if (netkey_idx == MESH_NET_IDX_INVALID)
2427 return BLUETOOTH_ERROR_INTERNAL;
2429 /* Handle Key (App/Net) Delete Commands: Configuration Message */
2430 if (opcode == MESH_OPCODE_NETKEY_DELETE || opcode == MESH_OPCODE_APPKEY_DELETE) {
2431 data_len = _bt_mesh_util_opcode_set(opcode, buffer);
2432 if (req->is_netkey) {
2433 l_put_le16(req->netkey_idx, buffer + data_len);
2436 buffer[data_len] = bound_netkey_idx;
2437 buffer[data_len + 1] = ((bound_netkey_idx >> 8) & 0xf) | ((req->appkey_idx << 4) & 0xf0);
2438 buffer[data_len + 2] = req->appkey_idx >> 4;
2442 ret = mesh_conf_send_message(&net_uuid, req->primary_unicast, true, netkey_idx, buffer, data_len);
2444 /* Handle Key (App/Net) Update & Add Commands: Key Config message */
2445 update = (opcode == MESH_OPCODE_NETKEY_UPDATE || opcode == MESH_OPCODE_APPKEY_UPDATE);
2446 ret = mesh_conf_send_key_message(&net_uuid, req->primary_unicast, req->is_netkey,
2447 update, req->is_netkey? req->netkey_idx: req->appkey_idx, netkey_idx);
2449 if (ret != OAL_STATUS_SUCCESS) {
2450 BT_ERR("ret: %d", ret);
2451 return BLUETOOTH_ERROR_INTERNAL;
2454 /* Queue the request with timeout */
2455 __bt_mesh_add_request(opcode, req->primary_unicast, net_uuid.uuid,
2456 g_memdup(req, sizeof(bluetooth_mesh_key_configure_t)));
2457 return BLUETOOTH_ERROR_NONE;