Fix the coverity issues
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / services / mesh / bt-service-mesh-model.c
1 /*
2  * Bluetooth-frwk
3  *
4  * Copyright (c) 2020 Samsung Electronics Co., Ltd.
5  *
6  * @author: Abhay Agarwal <ay.agarwal@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *              http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21 #include <glib.h>
22 #include <dlog.h>
23 #include <fcntl.h>
24 #include <dirent.h>
25 #include <errno.h>
26 #include <limits.h>
27 #include <stdio.h>
28 #include <unistd.h>
29 #include <sys/stat.h>
30 #include <ell/ell.h>
31
32 #include "bt-service-common.h"
33 #include "bt-service-core-adapter.h"
34 #include "bt-service-event-receiver.h"
35 #include "bt-request-handler.h"
36 #include "bluetooth-api.h"
37
38 #include "bluetooth-api.h"
39 #include "bluetooth-mesh-api.h"
40 #include "bt-internal-types.h"
41 #include "bt-service-util.h"
42 #include "bt-service-common.h"
43 #include "bt-service-core-adapter.h"
44 #include "bt-service-event-receiver.h"
45 #include "bt-request-handler.h"
46 #include "bluetooth-api.h"
47 #include "bt-service-event.h"
48
49 #include "bt-service-mesh-network.h"
50 #include "bt-service-mesh-cdb.h"
51 #include "bt-service-mesh-nodes.h"
52 #include "bt-service-mesh-keys.h"
53 #include "bt-service-mesh-util.h"
54 #include "bt-service-mesh-config-client.h"
55
56 #include <oal-hardware.h>
57 #include <oal-manager.h>
58 #include <oal-event.h>
59 #include <oal-adapter-mgr.h>
60 #include <oal-device-mgr.h>
61 #include <oal-mesh.h>
62
63 #include "bt-internal-types.h"
64
65 #define MESH_CONFIG_BUFFER_MAX_LEN 100
66
67 static void __bt_mesh_handle_pending_msg_request_info(int result,
68                 int service_function, void *param,
69                         unsigned int size);
70
71 struct mesh_msg_cmd {
72         uint32_t opcode;
73         uint32_t response;
74         const char *descriptor;
75 };
76
77 static struct l_queue *pending_msg_requests;
78
79 struct mesh_pending_request {
80         struct l_timeout *timer;
81         const struct mesh_msg_cmd *cmd;
82         uint8_t net_uuid[16];
83         uint16_t addr;
84         void *data;
85 };
86
87 static struct mesh_msg_cmd commands[] = {
88         { MESH_OPCODE_GENERIC_ONOFF_GET, MESH_OPCODE_GENERIC_ONOFF_STATUS, "GenericOnoffGet" },
89         { MESH_OPCODE_GENERIC_ONOFF_SET, MESH_OPCODE_GENERIC_ONOFF_STATUS, "GenericOnoffSet" },
90         { MESH_OPCODE_GENERIC_ONOFF_SET_UNACK, MESH_RESPONSE_NONE, "GenericOnoffSetUnack" },
91         { MESH_OPCODE_GENERIC_ONOFF_STATUS, MESH_RESPONSE_NONE, "GenericOnoffStatus" },
92         { MESH_OPCODE_GENERIC_LEVEL_GET, MESH_OPCODE_GENERIC_LEVEL_STATUS, "GenericLevelGet" },
93         { MESH_OPCODE_GENERIC_LEVEL_SET, MESH_OPCODE_GENERIC_LEVEL_STATUS, "GenericLevelSet" },
94         { MESH_OPCODE_GENERIC_LEVEL_SET_UNACK, MESH_RESPONSE_NONE, "GenericLevelSetUnack" },
95         { MESH_OPCODE_GENERIC_LEVEL_STATUS, MESH_RESPONSE_NONE, "GenericLevelStatus" },
96         { MESH_OPCODE_GENERIC_DELTA_SET, MESH_RESPONSE_NONE, "GenericDeltaGet" },
97         { MESH_OPCODE_GENERIC_DELTA_SET_UNACK, MESH_RESPONSE_NONE, "GenericDeltaSetUnack" },
98         { MESH_OPCODE_GENERIC_MOVE_SET, MESH_RESPONSE_NONE, "GenericMoveSet" },
99         { MESH_OPCODE_GENERIC_MOVE_SET_UNACK, MESH_RESPONSE_NONE, "GenericMoveSetUnack" },
100         { MESH_OPCODE_GENERIC_DEFAULT_TRANSITION_TIME_GET, MESH_OPCODE_GENERIC_DEFAULT_TRANSITION_TIME_STATUS, "GenericTransitionTimeGet" },
101         { MESH_OPCODE_GENERIC_DEFAULT_TRANSITION_TIME_SET, MESH_OPCODE_GENERIC_DEFAULT_TRANSITION_TIME_STATUS, "GenericTransitionTimeSet" },
102         { MESH_OPCODE_GENERIC_DEFAULT_TRANSITION_TIME_SET_UNACK, MESH_RESPONSE_NONE, "GenericTransitionTimeSetUnack" },
103         { MESH_OPCODE_GENERIC_DEFAULT_TRANSITION_TIME_STATUS, MESH_RESPONSE_NONE, "GenericTransitionTimeStatus" },
104         { MESH_OPCODE_GENERIC_ONPOWERUP_GET, MESH_OPCODE_GENERIC_ONPOWERUP_STATUS, "GenericOnPowerUpGet" },
105         { MESH_OPCODE_GENERIC_ONPOWERUP_STATUS, MESH_RESPONSE_NONE, "GenericOnPowerUpStatus" },
106         { MESH_OPCODE_GENERIC_ONPOWERUP_SET, MESH_OPCODE_GENERIC_ONPOWERUP_STATUS, "GenericOnPowerUpSet" },
107         { MESH_OPCODE_GENERIC_ONPOWERUP_SET_UNACK, MESH_RESPONSE_NONE, "GenericOnPowerUpSetUnack" },
108         { MESH_OPCODE_GENERIC_POWER_LEVEL_GET, MESH_OPCODE_GENERIC_POWER_LEVEL_STATUS, "GenericPowerLevelGet" },
109         { MESH_OPCODE_GENERIC_POWER_LEVEL_SET, MESH_OPCODE_GENERIC_POWER_LEVEL_STATUS, "GenericPowerLevelSet" },
110         { MESH_OPCODE_GENERIC_POWER_LEVEL_SET_UNACK, MESH_RESPONSE_NONE, "GenericPowerLevelSetUnack" },
111         { MESH_OPCODE_GENERIC_POWER_LEVEL_STATUS, MESH_RESPONSE_NONE, "GenericPowerLevelStatus" },
112         { MESH_OPCODE_GENERIC_POWER_LAST_GET, MESH_OPCODE_GENERIC_POWER_LAST_STATUS, "GenericPowerLastGet" },
113         { MESH_OPCODE_GENERIC_POWER_LAST_STATUS, MESH_RESPONSE_NONE, "GenericPowerLastStatus" },
114         { MESH_OPCODE_GENERIC_POWER_DEFAULT_GET, MESH_OPCODE_GENERIC_POWER_DEFAULT_STATUS, "GenericPowerDefaultGet" },
115         { MESH_OPCODE_GENERIC_POWER_DEFAULT_STATUS, MESH_RESPONSE_NONE, "GenericPowerDefaultStatus" },
116         { MESH_OPCODE_GENERIC_POWER_RANGE_GET, MESH_OPCODE_GENERIC_POWER_RANGE_STATUS, "GenericPowerRangeGet" },
117         { MESH_OPCODE_GENERIC_POWER_RANGE_STATUS, MESH_RESPONSE_NONE, "GenericPowerRangeStatus" },
118         { MESH_OPCODE_GENERIC_POWER_DEFAULT_SET, MESH_OPCODE_GENERIC_POWER_DEFAULT_STATUS, "GenericPowerDefaultSet" },
119         { MESH_OPCODE_GENERIC_POWER_DEFAULT_SET_UNACK, MESH_RESPONSE_NONE, "GenericPowerDefaultSetUnack" },
120         { MESH_OPCODE_GENERIC_POWER_RANGE_SET, MESH_OPCODE_GENERIC_POWER_RANGE_STATUS, "GenericPowerRangeSet" },
121         { MESH_OPCODE_GENERIC_POWER_RANGE_SET_UNACK, MESH_RESPONSE_NONE, "GenericPowerRangeSetUnack" },
122         { MESH_OPCODE_GENERIC_BATTERY_GET, MESH_OPCODE_GENERIC_BATTERY_STATUS, "GenericBatteryGet" },
123         { MESH_OPCODE_GENERIC_BATTERY_STATUS, MESH_RESPONSE_NONE, "GenericBatteryStatus" },
124         { MESH_OPCODE_GENERIC_LOCATION_GLOBAL_GET, MESH_OPCODE_GENERIC_LOCATION_GLOBAL_STATUS, "GenericLocationGlobalGet" },
125         { MESH_OPCODE_GENERIC_LOCATION_GLOBAL_STATUS, MESH_RESPONSE_NONE, "GenericLocationGlobalStatus" },
126         { MESH_OPCODE_GENERIC_LOCATION_LOCAL_GET, MESH_OPCODE_GENERIC_LOCATION_LOCAL_STATUS, "GenericLocationLocalGet" },
127         { MESH_OPCODE_GENERIC_LOCATION_LOCAL_STATUS, MESH_RESPONSE_NONE, "GenericLocationLocalStatus" },
128         { MESH_OPCODE_GENERIC_LOCATION_GLOBAL_SET, MESH_OPCODE_GENERIC_LOCATION_GLOBAL_STATUS, "GenericLocationGlobalSet" },
129         { MESH_OPCODE_GENERIC_LOCATION_GLOBAL_SET_UNACK, MESH_RESPONSE_NONE, "GenericLocationGlobalSetUnack" },
130         { MESH_OPCODE_GENERIC_LOCATION_LOCAL_SET, MESH_OPCODE_GENERIC_LOCATION_LOCAL_STATUS, "GenericLocationLocalSet" },
131         { MESH_OPCODE_GENERIC_LOCATION_LOCAL_SET_UNACK, MESH_RESPONSE_NONE, "GenericLocationLocalSetUnack" },
132         { MESH_OPCODE_GENERIC_MANUFACTURER_PROPERTIES_GET, MESH_OPCODE_GENERIC_MANUFACTURER_PROPERTIES_STATUS, "GenericManufacturerPropertiesGet" },
133         { MESH_OPCODE_GENERIC_MANUFACTURER_PROPERTIES_STATUS, MESH_RESPONSE_NONE, "GenericManufacturerPropertiesStatus" },
134         { MESH_OPCODE_GENERIC_MANUFACTURER_PROPERTY_GET, MESH_OPCODE_GENERIC_MANUFACTURER_PROPERTY_STATUS, "GenericManufacturerPropertyGet" },
135         { MESH_OPCODE_GENERIC_MANUFACTURER_PROPERTY_SET_UNACK, MESH_RESPONSE_NONE, "GenericManufacturerPropertySetUnack" },
136         { MESH_OPCODE_GENERIC_MANUFACTURER_PROPERTY_STATUS, MESH_RESPONSE_NONE, "GenericManufacturerPropertyStatus" },
137         { MESH_OPCODE_GENERIC_ADMIN_PROPERTIES_GET, MESH_OPCODE_GENERIC_ADMIN_PROPERTIES_STATUS, "GenericAdminPropertiesGet" },
138         { MESH_OPCODE_GENERIC_ADMIN_PROPERTIES_STATUS, MESH_RESPONSE_NONE, "GenericAdminPropertiesStatus" },
139         { MESH_OPCODE_GENERIC_ADMIN_PROPERTY_GET, MESH_OPCODE_GENERIC_ADMIN_PROPERTY_STATUS, "GenericAdminPropertyGet" },
140         { MESH_OPCODE_GENERIC_ADMIN_PROPERTY_SET, MESH_OPCODE_GENERIC_ADMIN_PROPERTY_STATUS, "GenericAdminPropertySet" },
141         { MESH_OPCODE_GENERIC_ADMIN_PROPERTY_SET_UNACK, MESH_RESPONSE_NONE, "GenericAdminPropertySetUnack" },
142         { MESH_OPCODE_GENERIC_ADMIN_PROPERTY_STATUS, MESH_RESPONSE_NONE, "GenericAdminPropertyStatus" },
143         { MESH_OPCODE_GENERIC_USER_PROPERTIES_GET, MESH_OPCODE_GENERIC_USER_PROPERTIES_STATUS, "GenericUserPropertiesGet" },
144         { MESH_OPCODE_GENERIC_USER_PROPERTIES_STATUS, MESH_RESPONSE_NONE, "GenericUserPropertiesStatus" },
145         { MESH_OPCODE_GENERIC_USER_PROPERTY_GET, MESH_OPCODE_GENERIC_USER_PROPERTY_STATUS, "GenericUserPropertyGet" },
146         { MESH_OPCODE_GENERIC_USER_PROPERTY_SET, MESH_OPCODE_GENERIC_USER_PROPERTY_STATUS, "GenericUserPropertySet" },
147         { MESH_OPCODE_GENERIC_USER_PROPERTY_SET_UNACK, MESH_RESPONSE_NONE, "GenericUserPropertySetUnack" },
148         { MESH_OPCODE_GENERIC_USER_PROPERTY_STATUS, MESH_RESPONSE_NONE, "GenericUserPropertyStatus" },
149         { MESH_OPCODE_GENERIC_CLIENT_PROPERTIES_GET, MESH_OPCODE_GENERIC_CLIENT_PROPERTIES_STATUS, "GenericClientPropertiesGet" },
150         { MESH_OPCODE_GENERIC_CLIENT_PROPERTIES_STATUS, MESH_RESPONSE_NONE, "GenericClientPropertiesStatus" },
151 };
152
153
154 static const struct mesh_msg_cmd *__mesh_get_command(uint32_t opcode)
155 {
156         uint32_t n;
157
158         for (n = 0; n < L_ARRAY_SIZE(commands); n++) {
159                 if (opcode == commands[n].opcode)
160                         return &commands[n];
161         }
162
163         return NULL;
164 }
165
166 static const char *__mesh_get_opcode_string(uint32_t opcode)
167 {
168         const struct mesh_msg_cmd *cmd;
169
170         cmd = __mesh_get_command(opcode);
171         if (!cmd)
172                 return "Unknown Command Received";
173
174         return cmd->descriptor;
175 }
176
177 static void __mesh_request_remove(void *a)
178 {
179         struct mesh_pending_request *req = a;
180
181         if (req->data)
182                 l_free(req->data);
183         l_timeout_remove(req->timer);
184         l_free(req);
185 }
186
187 static void __bt_mesh_wait_response_timeout(
188                 struct l_timeout *timeout, void *user_data)
189 {
190         struct mesh_pending_request *req = user_data;
191
192         BT_INFO("Mesh: No response for \"%s\" from %4.4x\n",
193                         req->cmd->descriptor, req->addr);
194
195         switch (req->cmd->opcode) {
196         case MESH_OPCODE_GENERIC_ONOFF_GET:
197         case MESH_OPCODE_GENERIC_ONOFF_SET:
198         case MESH_OPCODE_GENERIC_LEVEL_GET:
199         case MESH_OPCODE_GENERIC_LEVEL_SET:
200         case MESH_OPCODE_GENERIC_DELTA_SET:
201         case MESH_OPCODE_GENERIC_MOVE_SET:
202         case MESH_OPCODE_GENERIC_DEFAULT_TRANSITION_TIME_GET:
203         case MESH_OPCODE_GENERIC_DEFAULT_TRANSITION_TIME_SET:
204         case MESH_OPCODE_GENERIC_ONPOWERUP_GET:
205         case MESH_OPCODE_GENERIC_ONPOWERUP_STATUS:
206         case MESH_OPCODE_GENERIC_ONPOWERUP_SET:
207         case MESH_OPCODE_GENERIC_POWER_LEVEL_GET:
208         case MESH_OPCODE_GENERIC_POWER_LEVEL_SET:
209         case MESH_OPCODE_GENERIC_POWER_LAST_GET:
210         case MESH_OPCODE_GENERIC_POWER_DEFAULT_GET:
211         case MESH_OPCODE_GENERIC_POWER_RANGE_GET:
212         case MESH_OPCODE_GENERIC_POWER_DEFAULT_SET:
213         case MESH_OPCODE_GENERIC_POWER_RANGE_SET:
214         case MESH_OPCODE_GENERIC_BATTERY_GET:
215         case MESH_OPCODE_GENERIC_LOCATION_GLOBAL_GET:
216         case MESH_OPCODE_GENERIC_LOCATION_LOCAL_GET:
217         case MESH_OPCODE_GENERIC_LOCATION_GLOBAL_SET:
218         case MESH_OPCODE_GENERIC_LOCATION_LOCAL_SET:
219         case MESH_OPCODE_GENERIC_MANUFACTURER_PROPERTIES_GET:
220         case MESH_OPCODE_GENERIC_MANUFACTURER_PROPERTY_GET:
221         case MESH_OPCODE_GENERIC_MANUFACTURER_PROPERTY_SET:
222         case MESH_OPCODE_GENERIC_ADMIN_PROPERTIES_GET:
223         case MESH_OPCODE_GENERIC_ADMIN_PROPERTY_GET:
224         case MESH_OPCODE_GENERIC_ADMIN_PROPERTY_SET:
225         case MESH_OPCODE_GENERIC_USER_PROPERTIES_GET:
226         case MESH_OPCODE_GENERIC_USER_PROPERTY_GET:
227         case MESH_OPCODE_GENERIC_USER_PROPERTY_SET:
228         case MESH_OPCODE_GENERIC_CLIENT_PROPERTIES_GET:
229                 /* Send event with timeout */
230                  __bt_mesh_handle_pending_msg_request_info(
231                         BLUETOOTH_ERROR_TIMEOUT,
232                                 BT_MESH_MODEL_EXECUTE_MSG, req->data,
233                                         sizeof(bluetooth_mesh_model_msg_t));
234                 break;
235         default:
236                 break;
237         }
238         BT_INFO("Mesh: Number of pending requests [%u] Remove the req",
239                 l_queue_length(pending_msg_requests));
240         l_queue_remove(pending_msg_requests, req);
241         __mesh_request_remove(req);
242 }
243
244 static void __bt_mesh_add_request(uint32_t opcode, uint16_t dest,
245                         uint8_t net_uuid[], void *data)
246 {
247         struct mesh_pending_request *req;
248         const struct mesh_msg_cmd *cmd;
249         char uuid_str[33];
250
251         cmd = __mesh_get_command(opcode);
252         if (!cmd)
253                 return;
254         _bt_mesh_util_convert_hex_to_string((uint8_t *) net_uuid, 16, uuid_str,
255                 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
256         BT_INFO("Mesh: Net UUID[%s]", uuid_str);
257
258         BT_INFO("Mesh: Adding command opcode [0x%2.2x] response [0x%2.2x]",
259                         cmd->opcode, cmd->response);
260         req = l_new(struct mesh_pending_request, 1);
261         req->cmd = cmd;
262         req->addr = dest;
263         req->data = data;
264         memcpy(req->net_uuid, net_uuid, 16);
265         req->timer = l_timeout_create(MESH_DEFAULT_RESPONSE_TIMEOUT,
266                         __bt_mesh_wait_response_timeout, req, NULL);
267
268         if (!pending_msg_requests)
269                 pending_msg_requests = l_queue_new();
270         l_queue_push_tail(pending_msg_requests, req);
271         BT_INFO("Mesh: Number of pending requests [%u]", l_queue_length(pending_msg_requests));
272 }
273
274 static struct mesh_pending_request *__bt_mesh_get_request_by_response(
275                 uint16_t addr, uint8_t net_uuid[],
276                         uint32_t response)
277 {
278         const struct l_queue_entry *entry;
279         char uuid_str[33];
280         char uuid_str1[33];
281
282         BT_INFO("Mesh: Number of pending requests [%u]", l_queue_length(pending_msg_requests));
283         entry = l_queue_get_entries(pending_msg_requests);
284
285         for (; entry; entry = entry->next) {
286                 struct mesh_pending_request *req = entry->data;
287
288                 BT_INFO("Mesh: Req addr [0x%4.4x] req opcode [0x%4.4x] res [0x%4.4x]", req->addr, req->cmd->opcode, req->cmd->response);
289                 BT_INFO("Mesh: Current req addr [0x%4.4x] res [0x%4.4x]", addr, response);
290                 _bt_mesh_util_convert_hex_to_string((uint8_t *) net_uuid, 16, uuid_str,
291                                 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
292                 BT_INFO("Mesh: Net UUID[%s]", uuid_str);
293
294                 _bt_mesh_util_convert_hex_to_string((uint8_t *) req->net_uuid, 16, uuid_str1,
295                                 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
296                 BT_INFO("Mesh: Net UUID1[%s]", uuid_str1);
297                 /* Do not compare addr - In case of group message address may not match */
298                 if (!memcmp(net_uuid, req->net_uuid, 16) &&
299                                 req->cmd->response == response)
300                         return req;
301         }
302
303         return NULL;
304 }
305
306 bool _bt_mesh_check_pending_msg_request(uint32_t opcode,
307                 uint16_t dest, uint8_t net_uuid[])
308 {
309         const struct mesh_msg_cmd *cmd;
310         cmd = __mesh_get_command(opcode);
311
312         if (!cmd)
313                 return false;
314
315         if (__bt_mesh_get_request_by_response(dest,
316                                 net_uuid, cmd->response)) {
317                 BT_ERR("Mesh:Another command is pending\n");
318                 return true;
319         }
320         return false;
321 }
322
323 static void __bt_mesh_send_model_msg_event(int result,
324                 bluetooth_mesh_model_msg_t *evt)
325 {
326         GVariant *out_var = NULL, *param = NULL;
327         GArray *info = NULL;
328
329         if (BLUETOOTH_ERROR_NONE == result) {
330                 /* Send event */
331                 info = g_array_new(FALSE, FALSE, sizeof(gchar));
332                 g_array_append_vals(info, evt,
333                                 sizeof(bluetooth_mesh_model_msg_t));
334
335                 out_var = g_variant_new_from_data((const GVariantType *)"ay",
336                                 info->data, info->len,
337                                 TRUE, NULL, NULL);
338
339                 param = g_variant_new("(iv)", result, out_var);
340                 _bt_send_event(BT_MESH_EVENT,
341                                 BLUETOOTH_EVENT_MESH_MODEL_MSG_EXECUTED,
342                                 param);
343         }
344 }
345
346 static void __bt_mesh_handle_pending_msg_request_info(int result,
347                 int service_function, void *param, unsigned int size)
348 {
349         GSList *l;
350         GArray *out_param;
351         invocation_info_t *req_info = NULL;
352
353         for (l = _bt_get_invocation_list(); l != NULL; ) {
354                 req_info = l->data;
355                 l = g_slist_next(l);
356                 if (req_info == NULL ||
357                                 req_info->service_function != service_function)
358                         continue;
359
360                 switch (service_function) {
361                 case BT_MESH_MODEL_EXECUTE_MSG: {
362                         bluetooth_mesh_model_msg_t *event;
363                         bluetooth_mesh_model_msg_t *req;
364
365                         event = (bluetooth_mesh_model_msg_t*) param;
366                         req = (bluetooth_mesh_model_msg_t*)req_info->user_data;
367
368                         BT_DBG("Request Sender: [%s]", req_info->sender);
369                         /* Match Network and Remote Node unicast*/
370                         if (!g_strcmp0(event->net_uuid, req->net_uuid)) {
371                                 event->elem_index = req->elem_index;
372
373                                 /* Send Event */
374                                 __bt_mesh_send_model_msg_event(result, event);
375
376                                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
377                                 g_array_append_vals(out_param, event, sizeof(bluetooth_mesh_model_msg_t));
378
379                                 /* Return DBUS Invocation*/
380                                 _bt_service_method_return(req_info->context, out_param, result);
381                                 _bt_free_info_from_invocation_list(req_info);
382                                 g_array_free(out_param, TRUE);
383                         }
384                         break;
385                         }
386                 default:
387                         BT_DBG("Unknown function(%d)", service_function);
388                         break;
389                 }
390         }
391 }
392
393 void _bt_mesh_msg_handler(event_mesh_message_t *event)
394 {
395         uint32_t opcode;
396         uint16_t data_len = event->data_len;
397         uint8_t *data = event->data;
398         int n;
399         struct mesh_pending_request *req;
400
401         int result = BLUETOOTH_ERROR_NONE;
402
403         if (_bt_mesh_util_opcode_get(data, data_len, &opcode, &n)) {
404                 BT_INFO("Mesh: Opcode of response data [0x%2.2x], actual data len [%d]", opcode, n);
405                 data_len -= n;
406                 data += n;
407         } else
408                 return;
409
410         for (int msg_idx = 0; msg_idx < data_len; msg_idx++)
411                 BT_INFO("Mesh: Message data[%d]: [%2.2X]", msg_idx, data[msg_idx]);
412
413         BT_INFO("Mesh: Received %s (len %u) opcode [0x%2.2x]",
414                 __mesh_get_opcode_string(opcode), data_len, opcode);
415
416         req = __bt_mesh_get_request_by_response(event->source,
417                 event->net_uuid.uuid, (opcode & ~MESH_OPCODE_UNRELIABLE));
418
419         if (req) {
420                 BT_INFO("Mesh: Got Request");
421                 l_queue_remove(pending_msg_requests, req);
422                 __mesh_request_remove(req);
423         }
424
425         bluetooth_mesh_model_msg_t param;
426         memset(&param, 0x00, sizeof(bluetooth_mesh_model_msg_t));
427
428         _bt_mesh_util_convert_hex_to_string(
429                 (uint8_t *) event->net_uuid.uuid, 16, param.net_uuid,
430                         BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
431
432         param.primary_unicast = event->source;
433         param.elem_index = 0;
434         param.appkey_idx = event->key_idx;
435         param.msg_len = data_len*2;
436         _bt_mesh_util_convert_hex_to_string(
437                 (uint8_t *) data, data_len, param.msg,
438                         param.msg_len + 1);
439
440         param.appkey_idx = event->key_idx;
441         param.opcode = opcode;
442         BT_INFO("Send response");
443
444         __bt_mesh_handle_pending_msg_request_info(result,
445                 BT_MESH_MODEL_EXECUTE_MSG, &param,
446                 sizeof(bluetooth_mesh_model_msg_t));
447
448 }
449
450 int _bt_mesh_model_execute_msg(const char *app_cred, const char *sender,
451         bluetooth_mesh_model_msg_t *req)
452 {
453         int ret = OAL_STATUS_SUCCESS;
454         uint16_t appkey_idx;
455         oal_uuid_t net_uuid;
456         uint16_t data_len;
457         uint16_t msg_hex_len = 0;
458         uint32_t opcode = 0;
459         uint8_t buffer[MESH_CONFIG_BUFFER_MAX_LEN];
460         uint8_t msg[BLUETOOTH_MESH_MODEL_MSG_LENGTH_MAX + 1];
461
462         /* If Scanning is going on */
463         if (_bt_mesh_is_provisioning() ||
464                         _bt_mesh_is_scanning()) {
465                 BT_ERR("Device is buzy..");
466                 return BLUETOOTH_ERROR_DEVICE_BUSY;
467         }
468
469         /* Check pending request */
470         opcode = req->opcode;
471         if (_bt_mesh_check_pending_msg_request(opcode, req->primary_unicast,
472                 net_uuid.uuid)) {
473                 BT_ERR("Device is buzy..");
474                 return BLUETOOTH_ERROR_DEVICE_BUSY;
475         }
476
477         _bt_mesh_util_convert_string_to_hex(req->net_uuid, strlen(req->net_uuid), net_uuid.uuid, 16);
478
479         appkey_idx = req->appkey_idx;
480
481         /* Update data buffer */
482         data_len = _bt_mesh_util_opcode_set(req->opcode, buffer);
483
484         BT_DBG("Mesh: Model string msg opcode: 0x%2.2X msg_len: %d",
485                 req->opcode, req->msg_len);
486         if (req->msg_len > 0) {
487                 /* Convert Mesh msg to hex*/
488                 BT_DBG("Mesh: Model string msg_len: %zd, msg: %s", strlen(req->msg), req->msg);
489                 msg_hex_len = req->msg_len/2;
490                 _bt_mesh_util_convert_string_to_hex(req->msg, strlen(req->msg), msg, msg_hex_len);
491
492                 for (int msg_idx = 0; msg_idx < msg_hex_len; msg_idx++)
493                         BT_DBG("Mesh: Model hex msg[%d]: msg: 0x%2.2X", msg_idx, msg[msg_idx]);
494
495                 /* Append model msg */
496                 if (msg_hex_len > 0) {
497                         memcpy(buffer + data_len, msg, msg_hex_len);
498                         data_len += msg_hex_len;
499                 }
500         }
501
502         ret = mesh_model_send_message(&net_uuid, req->primary_unicast, appkey_idx, buffer, data_len);
503
504         if (ret != OAL_STATUS_SUCCESS) {
505                 BT_ERR("ret: %d", ret);
506                 return BLUETOOTH_ERROR_INTERNAL;
507         }
508
509         /* Queue the request with timeout */
510         __bt_mesh_add_request(opcode, req->primary_unicast, net_uuid.uuid,
511                         g_memdup(req, sizeof(bluetooth_mesh_model_msg_t)));
512
513         return BLUETOOTH_ERROR_NONE;
514 }