Mesh: Add OAL interface for Mesh message execution
[platform/core/connectivity/bluetooth-frwk.git] / bt-oal / oal-mesh.c
1 /*
2  * Open Adaptation Layer (OAL)
3  *
4  * Copyright (c) 2020 Samsung Electronics Co., Ltd.
5  *
6  * @author: Anupam Roy <anupam.r@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *              http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21 #include <dlog.h>
22 #include <bluetooth.h>
23 #include "bt_mesh.h"
24
25 #include "oal-event.h"
26 #include "oal-internal.h"
27 #include "oal-manager.h"
28 #include "oal-adapter-mgr.h"
29 #include "oal-utils.h"
30 #include "oal-mesh.h"
31 #include "oal-common.h"
32
33
34 static const bt_interface_t *blued_api;
35 static const btmesh_interface_t *mesh_api;
36
37 #define CHECK_OAL_MESH_ENABLED() \
38         do { \
39                 if (mesh_api == NULL) { \
40                         BT_ERR("Mesh Not Enabled"); \
41                         return OAL_STATUS_NOT_READY; \
42                 } \
43         } while (0)
44
45 /* Forward declaration: Callbacks from HAL */
46 static void mesh_network_attached_callback(bt_status_t status,
47                 bt_mesh_token_t *token, bt_uuid_t *uuid);
48 static void mesh_network_scan_status_callback(bt_mesh_scan_state_t scan_state,
49                 bt_status_t status, bt_uuid_t *net_uuid);
50 static void mesh_network_scan_result_callback(bt_status_t status,
51                 bt_uuid_t *net_uuid, bt_mesh_scan_result_t *result);
52 static void mesh_network_provisioning_status_callback(bt_status_t status,
53                 bt_uuid_t *net_uuid, bt_uuid_t *dev_uuid);
54 static void mesh_network_provisioning_finished_callback(bt_status_t status,
55                 int reason, bt_uuid_t *net_uuid,
56                         bt_uuid_t *dev_uuid, uint16_t unicast, uint8_t count);
57 static void mesh_network_provisioning_data_requested_callback(
58                 bt_uuid_t *net_uuid, uint8_t count);
59 static void mesh_network_authentication_requested_callback(bt_uuid_t *net_uuid,
60                 bt_hal_mesh_auth_variant_e auth_type, char auth_value[]);
61 static void mesh_network_netkey_execute_callback(bt_status_t status,
62                 bt_uuid_t *net_uuid, uint8_t key_event, uint16_t netkey_idx);
63 static void mesh_network_appkey_execute_callback(bt_status_t status,
64                 bt_uuid_t *net_uuid, uint8_t key_event, uint16_t netkey_idx, uint16_t appkey_idx);
65 static void mesh_network_appkey_execute_callback(bt_status_t status,
66                 bt_uuid_t *net_uuid, uint8_t key_event, uint16_t netkey_idx, uint16_t appkey_idx);
67 static void mesh_devkey_message_received_callback(bt_uuid_t *net_uuid,
68                 uint16_t source_addr, bool is_remote_devkey,
69                         uint16_t netkey_idx, uint16_t ata_len, uint8_t *data);
70 static void mesh_message_received_callback(bt_uuid_t *net_uuid,
71                 uint16_t source_addr, uint16_t dest_addr,
72                 uint16_t key_idx, uint16_t data_len, uint8_t *data);
73
74
75 static btmesh_callbacks_t sBluetoothMeshCallbacks = {
76         .size = sizeof(sBluetoothMeshCallbacks),
77         .network_attached_cb = mesh_network_attached_callback,
78         .scan_status_cb = mesh_network_scan_status_callback,
79         .scan_result_cb = mesh_network_scan_result_callback,
80         .provisioning_status_cb = mesh_network_provisioning_status_callback,
81         .provisioning_finished_cb = mesh_network_provisioning_finished_callback,
82         .provisioning_data_requested_cb = mesh_network_provisioning_data_requested_callback,
83         .authentication_requested_cb = mesh_network_authentication_requested_callback,
84         .netkey_execute_cb = mesh_network_netkey_execute_callback,
85         .appkey_execute_cb = mesh_network_appkey_execute_callback,
86         .devkey_msg_cb = mesh_devkey_message_received_callback,
87         .msg_cb = mesh_message_received_callback,
88 };
89
90 /* Mesh HAL event handlers */
91 static void mesh_network_attached_callback(bt_status_t status,
92                 bt_mesh_token_t *token, bt_uuid_t *uuid)
93 {
94         event_mesh_network_attached_t *event = g_new0(event_mesh_network_attached_t, 1);
95
96         event->status = convert_to_oal_status(status);
97         BT_INFO("Mesh Event: Network Attached, status: [%s]",
98                 status2string(status));
99
100         memcpy(event->token, token->token, sizeof(bt_mesh_token_t));
101         memcpy(event->uuid.uuid, uuid->uu, sizeof(bt_uuid_t));
102
103         send_event_bda_trace(OAL_EVENT_MESH_NETWORK_ATTACHED,
104                 event, sizeof(event_mesh_network_attached_t), NULL);
105 }
106
107 static void mesh_network_scan_status_callback(bt_mesh_scan_state_t scan_state,
108                 bt_status_t status, bt_uuid_t *net_uuid)
109 {
110         event_mesh_scan_status_t *event_data = g_new0(event_mesh_scan_status_t, 1);
111         oal_event_t event;
112
113         event_data->status = convert_to_oal_status(status);
114         BT_INFO("Mesh Event: Scan status: [%s] state [%d]",
115                 status2string(status), scan_state);
116
117         memcpy(event_data->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
118
119         event = (BT_MESH_SCAN_STARTED == scan_state) ? \
120                 OAL_EVENT_MESH_SCAN_STARTED : OAL_EVENT_MESH_SCAN_FINISHED;
121         send_event_bda_trace(event, event_data,
122                 sizeof(event_mesh_scan_status_t), NULL);
123 }
124
125 static void mesh_network_provisioning_status_callback(bt_status_t status,
126                 bt_uuid_t *net_uuid, bt_uuid_t *dev_uuid)
127 {
128         event_mesh_provisioning_status_t *event = g_new0(event_mesh_provisioning_status_t, 1);
129
130         event->status = convert_to_oal_status(status);
131         BT_INFO("Mesh Event: Provisioning status: [%s]",
132                 status2string(status));
133
134         memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
135         memcpy(event->dev_uuid.uuid, dev_uuid->uu, sizeof(bt_uuid_t));
136
137         if (event->status == OAL_STATUS_SUCCESS)
138                 send_event_bda_trace(OAL_EVENT_MESH_PROVISIONING_STARTED,
139                         event, sizeof(event_mesh_provisioning_status_t), NULL);
140         else
141                 send_event_bda_trace(OAL_EVENT_MESH_PROVISIONING_FAILED,
142                         event, sizeof(event_mesh_provisioning_status_t), NULL);
143 }
144
145 static void mesh_network_provisioning_finished_callback(bt_status_t status,
146                 int reason, bt_uuid_t *net_uuid,
147                         bt_uuid_t *dev_uuid, uint16_t unicast, uint8_t count)
148 {
149         event_mesh_provisioning_finished_t *event = \
150                 g_new0(event_mesh_provisioning_finished_t, 1);
151
152         event->status = convert_to_oal_status(status);
153         event->reason = reason;
154         BT_INFO("Mesh Event: Provisioning Completed Result: [%s]",
155                 status2string(status));
156
157         memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
158         memcpy(event->dev_uuid.uuid, dev_uuid->uu, sizeof(bt_uuid_t));
159         event->unicast = unicast;
160         event->count = count;
161
162         send_event_bda_trace(OAL_EVENT_MESH_PROVISIONING_FINISHED,
163                 event, sizeof(event_mesh_provisioning_finished_t), NULL);
164 }
165
166 static void mesh_network_provisioning_data_requested_callback(
167                 bt_uuid_t *net_uuid, uint8_t count)
168 {
169         event_mesh_provisioning_data_requested_t *event = \
170                 g_new0(event_mesh_provisioning_data_requested_t, 1);
171
172         BT_INFO("Mesh Event: Provisioning Data requested");
173
174         memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
175         event->count = count;
176
177         send_event_bda_trace(OAL_EVENT_MESH_PROVISIONING_DATA_REQUESTED,
178                 event, sizeof(event_mesh_provisioning_data_requested_t), NULL);
179 }
180
181 static void mesh_network_authentication_requested_callback(bt_uuid_t *net_uuid,
182                 bt_hal_mesh_auth_variant_e auth_type,
183                         char auth_value[])
184 {
185         event_mesh_authentication_requested_t *event = \
186                 g_new0(event_mesh_authentication_requested_t, 1);
187
188         BT_INFO("Mesh Event: Authentication requested");
189
190         memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
191         event->auth_type = auth_type;
192         g_strlcpy(event->auth_value, auth_value, sizeof(event->auth_value));
193
194         send_event_bda_trace(OAL_EVENT_MESH_AUTHENTICATION_REQUESTED,
195                 event, sizeof(event_mesh_provisioning_data_requested_t), NULL);
196 }
197
198 static void mesh_network_netkey_execute_callback(bt_status_t status,
199                 bt_uuid_t *net_uuid, uint8_t key_event, uint16_t index)
200 {
201         event_mesh_netkey_operation_t *event = \
202                 g_new0(event_mesh_netkey_operation_t, 1);
203
204         event->status = convert_to_oal_status(status);
205         BT_INFO("Mesh Event: NetKey Execute Event");
206
207         memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
208         event->op = (oal_mesh_key_op_e)key_event;
209         event->key_idx = index;
210
211         send_event_bda_trace(OAL_EVENT_MESH_NETKEY_EXECUTE_EVENT,
212                 event, sizeof(event_mesh_netkey_operation_t), NULL);
213 }
214
215 static void mesh_network_appkey_execute_callback(bt_status_t status,
216                 bt_uuid_t *net_uuid, uint8_t key_event,
217                         uint16_t net_idx, uint16_t app_idx)
218 {
219         event_mesh_appkey_operation_t *event = \
220                 g_new0(event_mesh_appkey_operation_t, 1);
221
222         event->status = convert_to_oal_status(status);
223         BT_INFO("Mesh Event: AppKey Execute Event");
224
225         memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
226         event->op = (oal_mesh_key_op_e)key_event;
227         event->net_idx = net_idx;
228         event->app_idx = app_idx;
229
230         send_event_bda_trace(OAL_EVENT_MESH_APPKEY_EXECUTE_EVENT,
231                 event, sizeof(event_mesh_appkey_operation_t), NULL);
232 }
233
234 static void mesh_network_scan_result_callback(bt_status_t status,
235                 bt_uuid_t *net_uuid, bt_mesh_scan_result_t *result)
236 {
237         event_mesh_scan_result_t *event = g_new0(event_mesh_scan_result_t, 1);
238
239         event->status = convert_to_oal_status(status);
240         BT_INFO("Mesh Event: Scan Result status: [%s]",
241                 status2string(status));
242
243         memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
244         memcpy(&event->result, result, sizeof(bt_mesh_scan_result_t));
245
246         send_event_bda_trace(OAL_EVENT_MESH_SCAN_RESULT,
247                 event, sizeof(event_mesh_scan_result_t), NULL);
248 }
249
250 static void mesh_devkey_message_received_callback(bt_uuid_t *net_uuid,
251                 uint16_t source_addr,
252                         bool is_remote_devkey, uint16_t netkey_idx,
253                                 uint16_t data_len, uint8_t *data)
254 {
255         event_mesh_devkey_message_t *event = g_new0(event_mesh_devkey_message_t, 1);
256
257         BT_INFO("Mesh Event: Dev Key Message Received");
258         event->source = source_addr;
259         event->remote = is_remote_devkey;
260         event->subnet = netkey_idx;
261         event->data_len = data_len;
262         memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
263         memcpy(event->data, data, data_len);
264
265         send_event_bda_trace(OAL_EVENT_MESH_DEVKEY_MESSAGE_RECEIVED, event,
266                 sizeof(event_mesh_devkey_message_t), NULL);
267 }
268
269 static void mesh_message_received_callback(bt_uuid_t *net_uuid,
270                 uint16_t source_addr, uint16_t dest_addr, uint16_t key_idx,
271                                 uint16_t data_len, uint8_t *data)
272 {
273         event_mesh_message_t *event = g_new0(event_mesh_message_t, 1);
274
275         BT_INFO("Mesh Event: Model Message Received");
276         event->source = source_addr;
277         event->dest = dest_addr;
278         event->key_idx = key_idx;
279         event->data_len = data_len;
280         memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
281         memcpy(event->data, data, data_len);
282
283         send_event_bda_trace(OAL_EVENT_MESH_MESSAGE_RECEIVED, event,
284                 sizeof(event_mesh_message_t), NULL);
285 }
286
287 oal_status_t mesh_enable(void)
288 {
289         int ret;
290         API_TRACE();
291
292         /* Get stack interface */
293         blued_api = (const bt_interface_t *) adapter_get_stack_interface();
294
295         if (blued_api == NULL) {
296                 BT_ERR("Stack is not initialized");
297                 return OAL_STATUS_NOT_READY;
298         }
299
300         if (mesh_api) {
301                 BT_WARN("MESH Interface is already initialized...");
302                 return OAL_STATUS_ALREADY_DONE;
303         }
304
305         mesh_api = (const btmesh_interface_t *)blued_api->get_profile_interface(BT_PROFILE_MESH_ID);
306         if (mesh_api == NULL) {
307                 BT_ERR("MESH interface failed");
308                 return OAL_STATUS_INTERNAL_ERROR;
309         }
310
311         if ((ret = mesh_api->init(&sBluetoothMeshCallbacks)) != BT_STATUS_SUCCESS) {
312                 BT_ERR("Error: Unable to initialise MESH :%s", status2string(ret));
313                 mesh_api->cleanup();
314                 mesh_api = NULL;
315                 return convert_to_oal_status(ret);
316         }
317
318         BT_INFO("MESH successfully initialized");
319         return OAL_STATUS_SUCCESS;
320 }
321
322 oal_status_t mesh_disable(void)
323 {
324         API_TRACE();
325         CHECK_OAL_MESH_ENABLED();
326
327         mesh_api->cleanup();
328
329         mesh_api = NULL;
330         return OAL_STATUS_SUCCESS;
331 }
332
333 oal_status_t mesh_register_node(oal_mesh_node_t *node,
334                 GSList *model_list, bool is_provisioner)
335 {
336         int ret = BT_STATUS_SUCCESS;
337         API_TRACE();
338         CHECK_OAL_MESH_ENABLED();
339
340         BT_INFO("Mesh: Send create network request to stack");
341         ret = mesh_api->create((bt_hal_mesh_node_t*)node, model_list, is_provisioner);
342         if (ret != BT_STATUS_SUCCESS) {
343                 BT_ERR("MESH: Create Network failed :failed: %s", status2string(ret));
344                 return convert_to_oal_status(ret);
345         }
346
347         BT_INFO("Mesh: Request sent to stack");
348         return OAL_STATUS_SUCCESS;
349 }
350
351 oal_status_t mesh_network_start_scan(oal_uuid_t* network_uuid,
352                 oal_mesh_scan_params_t *params)
353 {
354         int ret = BT_STATUS_SUCCESS;
355         API_TRACE();
356         CHECK_OAL_MESH_ENABLED();
357
358         ret = mesh_api->scan((bt_uuid_t*)network_uuid,
359                 (bt_hal_mesh_scan_param_t*)params);
360         if (ret != BT_STATUS_SUCCESS) {
361                 BT_ERR("MESH: Start Scan failed: %s", status2string(ret));
362                 return convert_to_oal_status(ret);
363         }
364
365         return OAL_STATUS_SUCCESS;
366 }
367
368 oal_status_t mesh_network_scan_cancel(oal_uuid_t* network_uuid)
369 {
370         int ret = BT_STATUS_SUCCESS;
371         API_TRACE();
372         CHECK_OAL_MESH_ENABLED();
373
374         ret = mesh_api->scan_cancel((bt_uuid_t*)network_uuid);
375         if (ret != BT_STATUS_SUCCESS) {
376                 BT_ERR("MESH: Scan Cancel failed: %s", status2string(ret));
377                 return convert_to_oal_status(ret);
378         }
379
380         return OAL_STATUS_SUCCESS;
381 }
382
383 oal_status_t mesh_network_set_provisioning_capabilities(
384                 oal_uuid_t *network_uuid,
385                          oal_mesh_capabilities_t *caps)
386 {
387         int ret = BT_STATUS_SUCCESS;
388         API_TRACE();
389         CHECK_OAL_MESH_ENABLED();
390
391         ret = mesh_api->capability((bt_uuid_t*)network_uuid,
392                 (bt_hal_mesh_prov_caps_t*)caps);
393         if (ret != BT_STATUS_SUCCESS) {
394                 BT_ERR("MESH: Set Provisioning capabilities :failed: %s",
395                         status2string(ret));
396                 return convert_to_oal_status(ret);
397         }
398
399         return OAL_STATUS_SUCCESS;
400 }
401
402 oal_status_t mesh_conf_send_message(oal_uuid_t *network_uuid,
403                 uint16_t dest, bool is_devkey_remote,
404                         uint16_t netkey_idx, uint8_t *buf, int len)
405 {
406         int ret = BT_STATUS_SUCCESS;
407         API_TRACE();
408         CHECK_OAL_MESH_ENABLED();
409
410         ret = mesh_api->config_send((bt_uuid_t*)network_uuid,
411                         dest, is_devkey_remote, netkey_idx, buf, len);
412         if (ret != BT_STATUS_SUCCESS) {
413                 BT_ERR("MESH: Configuration Message sending failed: %s",
414                         status2string(ret));
415                 return convert_to_oal_status(ret);
416         }
417
418         return OAL_STATUS_SUCCESS;
419 }
420
421 oal_status_t mesh_conf_send_key_message(oal_uuid_t *network_uuid,
422                 uint16_t dest, bool is_netkey,
423                         bool is_update, int key_idx, int netkey_idx)
424 {
425         int ret = BT_STATUS_SUCCESS;
426         API_TRACE();
427         CHECK_OAL_MESH_ENABLED();
428
429         ret = mesh_api->key_send((bt_uuid_t*)network_uuid, dest,
430                         is_netkey, is_update, key_idx, netkey_idx);
431         if (ret != BT_STATUS_SUCCESS) {
432                 BT_ERR("MESH: Key Configuration Message sending failed: %s",
433                         status2string(ret));
434                 return convert_to_oal_status(ret);
435         }
436
437         return OAL_STATUS_SUCCESS;
438 }
439
440 oal_status_t mesh_model_send_message(oal_uuid_t *network_uuid,
441                 uint16_t dest, uint16_t appkey_idx,
442                 uint8_t *buf, int len)
443 {
444         int ret = BT_STATUS_SUCCESS;
445         API_TRACE();
446         CHECK_OAL_MESH_ENABLED();
447
448         ret = mesh_api->msg_execute((bt_uuid_t*)network_uuid,
449                         dest, appkey_idx, buf, len);
450         if (ret != BT_STATUS_SUCCESS) {
451                 BT_ERR("MESH: Key Configuration Message sending failed: %s",
452                         status2string(ret));
453                 return convert_to_oal_status(ret);
454         }
455
456         return OAL_STATUS_SUCCESS;
457 }
458
459 oal_status_t mesh_network_provision_device(oal_uuid_t* network_uuid,
460                 oal_uuid_t *dev_uuid)
461 {
462         int ret = BT_STATUS_SUCCESS;
463         API_TRACE();
464         CHECK_OAL_MESH_ENABLED();
465
466         ret = mesh_api->provision((bt_uuid_t*)network_uuid, (bt_uuid_t *)dev_uuid);
467         if (ret != BT_STATUS_SUCCESS) {
468                 BT_ERR("MESH: Device Provisioning :failed: %s",
469                         status2string(ret));
470                 return convert_to_oal_status(ret);
471         }
472
473         return OAL_STATUS_SUCCESS;
474 }
475
476 oal_status_t mesh_network_send_provisioning_data(oal_uuid_t* network_uuid,
477                 uint16_t netkey_idx, uint16_t unicast)
478 {
479         int ret = BT_STATUS_SUCCESS;
480         API_TRACE();
481         CHECK_OAL_MESH_ENABLED();
482
483         ret = mesh_api->provision_data((bt_uuid_t*)network_uuid, netkey_idx, unicast);
484         if (ret != BT_STATUS_SUCCESS) {
485                 BT_ERR("MESH: Device Provisioning :failed: %s",
486                         status2string(ret));
487                 return convert_to_oal_status(ret);
488         }
489
490         return OAL_STATUS_SUCCESS;
491 }
492
493 oal_status_t mesh_network_subnet_execute(oal_uuid_t* network_uuid,
494                 oal_mesh_key_op_e operation, uint16_t net_index)
495 {
496         int ret = BT_STATUS_SUCCESS;
497         API_TRACE();
498         CHECK_OAL_MESH_ENABLED();
499
500         ret = mesh_api->subnet_execute((bt_uuid_t*)network_uuid,
501                 (bt_mesh_key_op_e)operation, net_index);
502         if (ret != BT_STATUS_SUCCESS) {
503                 BT_ERR("MESH: Create Subnet :failed: %s", status2string(ret));
504                 return convert_to_oal_status(ret);
505         }
506
507         return OAL_STATUS_SUCCESS;
508 }
509
510 oal_status_t mesh_network_appkey_execute(oal_uuid_t* network_uuid,
511                 oal_mesh_key_op_e operation,
512                         uint16_t net_index, uint16_t app_index)
513 {
514         int ret = BT_STATUS_SUCCESS;
515         API_TRACE();
516         CHECK_OAL_MESH_ENABLED();
517
518         ret = mesh_api->appkey_execute((bt_uuid_t*)network_uuid,
519                 (bt_mesh_key_op_e)operation,
520                         net_index, app_index);
521         if (ret != BT_STATUS_SUCCESS) {
522                 BT_ERR("MESH: Create Subnet :failed: %s",
523                         status2string(ret));
524                 return convert_to_oal_status(ret);
525         }
526
527         return OAL_STATUS_SUCCESS;
528 }
529
530 oal_status_t mesh_authentication_reply(
531                 oal_mesh_variant_authentication_e auth_type,
532                         const char* auth_value)
533 {
534         int ret = BT_STATUS_SUCCESS;
535         API_TRACE();
536         CHECK_OAL_MESH_ENABLED();
537
538         ret = mesh_api->auth_reply((bt_hal_mesh_auth_variant_e)auth_type,
539                         auth_value);
540         if (ret != BT_STATUS_SUCCESS) {
541                 BT_ERR("MESH: Device Provisioning :failed: %s",
542                         status2string(ret));
543                 return convert_to_oal_status(ret);
544         }
545
546         return OAL_STATUS_SUCCESS;
547 }