043ff5fb2fdb1e58b0cf3cdbef02474e8db01638
[platform/core/connectivity/bluetooth-frwk.git] / bt-oal / bluez_hal / src / bt-hal-bluetooth.c
1 /*
2  * BLUETOOTH HAL
3  *
4  * Copyright (c) 2015 -2016 Samsung Electronics Co., Ltd All Rights Reserved.
5  *
6  * Contact: 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
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <stdbool.h>
25 #include <string.h>
26 #include <dlog.h>
27
28 #include "bt-hal.h"
29 #include "bt-hal-log.h"
30 #include "bt-hal-msg.h"
31 #include "bt-hal-utils.h"
32
33 #include <bt-hal-adapter-dbus-handler.h>
34 #include <bt-hal-device-dbus-handler.h>
35
36 #define enum_prop_to_hal(prop, hal_prop, type) do { \
37         static type e; \
38         prop.val = &e; \
39         prop.len = sizeof(e); \
40         e = *((uint8_t *) (hal_prop->val)); \
41 } while (0)
42
43 static const bt_callbacks_t *bt_hal_cbacks = NULL;
44
45
46 /* Forward declarations */
47 static void __bt_adapter_props_to_hal(bt_property_t *send_props, struct hal_property *prop, uint8_t num_props, uint16_t len);
48 static void __bt_device_props_to_hal(bt_property_t *send_props,
49                 struct hal_property *prop, uint8_t num_props,
50                 uint16_t len);
51 static void __bt_hal_handle_adapter_state_changed(void *buf, uint16_t len);
52 static void __bt_hal_handle_adapter_property_changed(void *buf, uint16_t len);
53 static void __bt_hal_handle_stack_messages(int message, void *buf, uint16_t len);
54 static void __bt_hal_handle_adapter_discovery_state_changed(void *buf, uint16_t len);
55 static void __bt_hal_handle_device_found_event(void *buf, uint16_t len);
56
57 static bool interface_ready(void)
58 {
59         return bt_hal_cbacks != NULL;
60 }
61
62 static int init(bt_callbacks_t *callbacks)
63 {
64         int ret;
65         DBG("HAL library Initialization..");
66
67         if (interface_ready())
68                 return BT_STATUS_DONE;
69         else {
70                 bt_hal_cbacks = callbacks;
71                 DBG("Store HAL stack msg handler callback");
72                 _bt_hal_dbus_store_stack_msg_cb(__bt_hal_handle_stack_messages);
73                 ret = _bt_hal_initialize_event_receiver(__bt_hal_handle_stack_messages);
74
75                 if (ret == BT_STATUS_SUCCESS)
76                         return BT_STATUS_SUCCESS;
77                 else
78                         return BT_STATUS_FAIL;
79
80         }
81         return BT_STATUS_SUCCESS;
82 }
83
84 /* Enable Adapter */
85 static int enable(void)
86 {
87         return _bt_hal_dbus_enable_adapter();
88 }
89
90 /* Disable Adapter */
91 static int disable(void)
92 {
93         return _bt_hal_dbus_disable_adapter();
94 }
95
96 static void cleanup(void)
97 {
98         return;
99 }
100
101 static int get_adapter_properties(void)
102 {
103         return _bt_hal_dbus_get_adapter_properties();
104 }
105
106 static int get_adapter_property(bt_property_type_t type)
107 {
108         return _bt_hal_dbus_get_adapter_property(type);
109 }
110
111 static int set_adapter_property(const bt_property_t *property)
112 {
113         if (!property) {
114                 ERR("Invalid param");
115                 return BT_STATUS_PARM_INVALID;
116         }
117
118         return _bt_hal_dbus_set_adapter_property(property);
119 }
120
121 static int get_remote_device_properties(bt_bdaddr_t *remote_addr)
122 {
123         if (!remote_addr) {
124                 ERR("Invalid param");
125                 return BT_STATUS_PARM_INVALID;
126         }
127
128         return _bt_hal_dbus_get_remote_device_properties(remote_addr);
129 }
130
131 static int get_remote_device_property(bt_bdaddr_t *remote_addr,
132                 bt_property_type_t type)
133 {
134         return BT_STATUS_UNSUPPORTED;
135 }
136
137 static int set_remote_device_property(bt_bdaddr_t *remote_addr,
138                 const bt_property_t *property)
139 {
140         return _bt_hal_dbus_set_remote_device_property(remote_addr, property);
141 }
142
143 static int get_remote_service_record(bt_bdaddr_t *remote_addr, bt_uuid_t *uuid)
144 {
145         return BT_STATUS_UNSUPPORTED;
146
147 }
148
149 static int get_remote_services(bt_bdaddr_t *remote_addr)
150 {
151         return BT_STATUS_UNSUPPORTED;
152 }
153
154 static int start_discovery(void)
155 {
156         return _bt_hal_dbus_start_discovery();
157 }
158
159 static int cancel_discovery(void)
160 {
161         return _bt_hal_dbus_stop_discovery();
162 }
163
164 static int create_bond(const bt_bdaddr_t *bd_addr, int transport)
165 {
166         DBG("+");
167         return _bt_hal_device_create_bond(bd_addr);
168 }
169
170 static int cancel_bond(const bt_bdaddr_t *bd_addr)
171 {
172         return BT_STATUS_UNSUPPORTED;
173 }
174
175 static int remove_bond(const bt_bdaddr_t *bd_addr)
176 {
177         DBG("+");
178         return _bt_hal_device_remove_bond(bd_addr);
179 }
180
181 static int pin_reply(const bt_bdaddr_t *bd_addr, uint8_t accept,
182                 uint8_t pin_len, bt_pin_code_t *pin_code)
183 {
184         return BT_STATUS_UNSUPPORTED;
185 }
186
187 static int ssp_reply(const bt_bdaddr_t *bd_addr, bt_ssp_variant_t variant,
188                 uint8_t accept, uint32_t passkey)
189 {
190         return BT_STATUS_UNSUPPORTED;
191 }
192
193 static const void *get_profile_interface(const char *profile_id)
194 {
195         /*TODO: Profile interfaces to be included later*/
196         DBG("%s", profile_id);
197
198         if (!interface_ready())
199                 return NULL;
200
201         if (!strcmp(profile_id, BT_PROFILE_PAN_ID))
202                 return NULL;
203
204         if (!strcmp(profile_id, BT_PROFILE_ADVANCED_AUDIO_ID))
205                 return NULL;
206
207         if (!strcmp(profile_id, BT_PROFILE_AV_RC_ID))
208                 return NULL;
209
210         if (!strcmp(profile_id, BT_PROFILE_HANDSFREE_ID))
211                 return NULL;
212
213         if (!strcmp(profile_id, BT_PROFILE_GATT_ID))
214                 return NULL;
215
216         if (!strcmp(profile_id, BT_PROFILE_HEALTH_ID))
217                 return NULL;
218
219         if (!strcmp(profile_id, BT_PROFILE_AV_RC_CTRL_ID))
220                 return NULL;
221
222         if (!strcmp(profile_id, BT_PROFILE_HANDSFREE_CLIENT_ID))
223                 return NULL;
224
225         if (!strcmp(profile_id, BT_PROFILE_MAP_CLIENT_ID))
226                 return NULL;
227
228         if (!strcmp(profile_id, BT_PROFILE_ADVANCED_AUDIO_SINK_ID))
229                 return NULL;
230
231         return NULL;
232 }
233
234 static int dut_mode_configure(uint8_t enable)
235 {
236         return BT_STATUS_UNSUPPORTED;
237 }
238
239 static int dut_mode_send(uint16_t opcode, uint8_t *buf, uint8_t buf_len)
240 {
241         return BT_STATUS_UNSUPPORTED;
242 }
243
244 static int le_test_mode(uint16_t opcode, uint8_t *buf, uint8_t buf_len)
245 {
246         return BT_STATUS_UNSUPPORTED;
247 }
248
249 static int config_hci_snoop_log(uint8_t enable)
250 {
251         return BT_STATUS_UNSUPPORTED;
252 }
253
254 static int get_connection_state(const bt_bdaddr_t *bd_addr)
255 {
256         return BT_STATUS_UNSUPPORTED;
257 }
258
259 static int set_os_callouts(bt_os_callouts_t *callouts)
260 {
261         DBG("callouts: %p", callouts);
262
263         /* TODO: implement */
264
265         return BT_STATUS_UNSUPPORTED;
266 }
267
268 static int read_energy_info(void)
269 {
270         return BT_STATUS_UNSUPPORTED;
271 }
272
273 static const bt_interface_t bluetooth_if = {
274         .size = sizeof(bt_interface_t),
275         .init = init,
276         .enable = enable,
277         .disable = disable,
278         .cleanup = cleanup,
279         .get_adapter_properties = get_adapter_properties,
280         .get_adapter_property = get_adapter_property,
281         .set_adapter_property = set_adapter_property,
282         .get_remote_device_properties = get_remote_device_properties,
283         .get_remote_device_property = get_remote_device_property,
284         .set_remote_device_property = set_remote_device_property,
285         .get_remote_service_record = get_remote_service_record,
286         .get_remote_services = get_remote_services,
287         .start_discovery = start_discovery,
288         .cancel_discovery = cancel_discovery,
289         .create_bond = create_bond,
290         .remove_bond = remove_bond,
291         .cancel_bond = cancel_bond,
292         .pin_reply = pin_reply,
293         .ssp_reply = ssp_reply,
294         .get_profile_interface = get_profile_interface,
295         .dut_mode_configure = dut_mode_configure,
296         .dut_mode_send = dut_mode_send,
297         .le_test_mode = le_test_mode,
298         .config_hci_snoop_log = config_hci_snoop_log,
299         .get_connection_state = get_connection_state,
300         .set_os_callouts = set_os_callouts,
301         .read_energy_info = read_energy_info,
302 };
303
304 static const bt_interface_t *get_bluetooth_interface(void)
305 {
306         DBG("");
307         return &bluetooth_if;
308 }
309
310 static int close_bluetooth(struct hw_device_t *device)
311 {
312         DBG("");
313         cleanup();
314         free(device);
315         return 0;
316 }
317
318 static int open_bluetooth(const struct hw_module_t *module, char const *name,
319                 struct hw_device_t **device)
320 {
321         bluetooth_device_t *dev = malloc(sizeof(bluetooth_device_t));
322
323         DBG("");
324
325         memset(dev, 0, sizeof(bluetooth_device_t));
326         dev->common.tag = HARDWARE_DEVICE_TAG;
327         dev->common.version = 0;
328         dev->common.module = (struct hw_module_t *) module;
329         dev->common.close = close_bluetooth;
330         dev->get_bluetooth_interface = get_bluetooth_interface;
331
332         *device = (struct hw_device_t *) dev;
333
334         return 0;
335 }
336
337 static struct hw_module_methods_t bluetooth_module_methods = {
338         .open = open_bluetooth,
339 };
340
341 struct hw_module_t HAL_MODULE_INFO_SYM = {
342         .tag = HARDWARE_MODULE_TAG,
343         .version_major = 1,
344         .version_minor = 0,
345         .id = BT_HARDWARE_MODULE_ID,
346         .name = "Bluetooth stack",
347         .author = "Intel Corporation",
348         .methods = &bluetooth_module_methods
349 };
350
351 static void __bt_hal_handle_adapter_state_changed(void *buf, uint16_t len)
352 {
353         struct hal_ev_adapter_state_changed *ev = buf;
354
355         DBG("Adapter State: %d", ev->state);
356
357         if (bt_hal_cbacks->adapter_state_changed_cb)
358                 bt_hal_cbacks->adapter_state_changed_cb(ev->state);
359 }
360
361 static void __bt_adapter_props_to_hal(bt_property_t *send_props, struct hal_property *prop,
362                 uint8_t num_props, uint16_t len)
363 {
364         void *buf = prop;
365         uint8_t i;
366
367         for (i = 0; i < num_props; i++) {
368                 if (sizeof(*prop) + prop->len > len) {
369                         ERR("invalid adapter properties(%zu > %u), cant process further properties!!!",
370                                         sizeof(*prop) + prop->len, len);
371                         return;
372                 }
373
374                 send_props[i].type = prop->type;
375
376                 switch (prop->type) {
377                         /* TODO: Add Adapter Properties */
378                         default:
379                                 send_props[i].len = prop->len;
380                                 send_props[i].val = prop->val;
381                                 break;
382                 }
383
384                 DBG("prop[%d]: %s", i, btproperty2str(&send_props[i]));
385
386                 len -= sizeof(*prop) + prop->len;
387                 buf += sizeof(*prop) + prop->len;
388                 prop = buf;
389         }
390
391         if (!len)
392                 return;
393 }
394
395 static void __bt_device_props_to_hal(bt_property_t *send_props,
396                 struct hal_property *prop, uint8_t num_props,
397                 uint16_t len)
398 {
399         void *buf = prop;
400         uint8_t i;
401
402         DBG("+");
403
404         for (i = 0; i < num_props; i++) {
405
406                 if (sizeof(*prop) + prop->len > len) {
407                         ERR("invalid device properties (%zu > %u), cant process further properties!!!",
408                                         sizeof(*prop) + prop->len, len);
409                         return;
410                 }
411
412                 send_props[i].type = prop->type;
413
414                 DBG("HAL prop Type [%d]", prop->type);
415
416                 switch (prop->type) {
417                 case HAL_PROP_DEVICE_TYPE:
418                 {
419                         DBG("Device property:HAL_PROP_DEVICE_TYPE:");
420                         enum_prop_to_hal(send_props[i], prop,
421                                         bt_device_type_t);
422                         break;
423                 }
424                 case HAL_PROP_DEVICE_VERSION_INFO:
425                 {
426                         DBG("Device property: HAL_PROP_DEVICE_VERSION_INFO");
427                         static bt_remote_version_t e;
428                         const struct hal_prop_device_info *p;
429                         send_props[i].val = &e;
430                         send_props[i].len = sizeof(e);
431                                 p = (struct hal_prop_device_info *) prop->val;
432                                 e.manufacturer = p->manufacturer;
433                         e.sub_ver = p->sub_version;
434                         e.version = p->version;
435                         break;
436                 }
437                 case HAL_PROP_DEVICE_SERVICE_REC:
438                 {
439                         DBG("Device property: HAL_PROP_DEVICE_SERVICE_REC");
440                         static bt_service_record_t e;
441                         const struct hal_prop_device_service_rec *p;
442                         send_props[i].val = &e;
443                         send_props[i].len = sizeof(e);
444                                 p = (struct hal_prop_device_service_rec *) prop->val;
445                                         memset(&e, 0, sizeof(e));
446                         memcpy(&e.channel, &p->channel, sizeof(e.channel));
447                         memcpy(e.uuid.uu, p->uuid, sizeof(e.uuid.uu));
448                         memcpy(e.name, p->name, p->name_len);
449                         break;
450                 }
451                 default:
452                         send_props[i].len = prop->len;
453                         send_props[i].val = prop->val;
454                         break;
455                 }
456
457                 DBG("prop[%d]: %s", i, btproperty2str(&send_props[i]));
458                 len -= sizeof(*prop) + prop->len;
459                 buf += sizeof(*prop) + prop->len;
460                 prop = buf;
461
462         }
463
464         if (!len) {
465                 DBG("-");
466                 return;
467         }
468
469         ERR("invalid device properties (%u bytes left), ", len);
470 }
471
472 static void __bt_hal_handle_adapter_property_changed(void *buf, uint16_t len)
473 {
474         struct hal_ev_adapter_props_changed *ev = (struct hal_ev_adapter_props_changed *)buf;
475         bt_property_t props[ev->num_props];
476         DBG("+");
477
478         if (!bt_hal_cbacks->adapter_properties_cb)
479                 return;
480
481         len -= sizeof(*ev);
482         __bt_adapter_props_to_hal(props, ev->props, ev->num_props, len);
483
484         if (bt_hal_cbacks->adapter_properties_cb)
485                 bt_hal_cbacks->adapter_properties_cb(ev->status, ev->num_props, props);
486 }
487
488 static void __bt_hal_handle_adapter_discovery_state_changed(void *buf, uint16_t len)
489 {
490         struct hal_ev_discovery_state_changed *ev = (struct hal_ev_discovery_state_changed *)buf;
491
492         DBG("+");
493
494         if (bt_hal_cbacks->discovery_state_changed_cb)
495                 bt_hal_cbacks->discovery_state_changed_cb(ev->state);
496 }
497
498 static void __bt_hal_handle_device_found_event(void *buf, uint16_t len)
499 {
500         struct hal_ev_device_found *ev =  (struct hal_ev_device_found *) buf;
501         bt_property_t props[ev->num_props];
502         DBG("+");
503
504         if (!bt_hal_cbacks->device_found_cb)
505                 return;
506
507         len -= sizeof(*ev);
508         __bt_device_props_to_hal(props, ev->props, ev->num_props, len);
509
510         bt_hal_cbacks->device_found_cb(ev->num_props, props);
511 }
512
513 static void __bt_hal_handle_remote_device_properties_event(void *buf, uint16_t len)
514 {
515         struct hal_ev_remote_device_props *ev = (struct hal_ev_remote_device_props *) buf;
516         bt_bdaddr_t bd_addr;
517         bt_property_t props[ev->num_props];
518
519         DBG("+");
520
521         if (!bt_hal_cbacks->remote_device_properties_cb)
522                 return;
523
524         len -= sizeof(*ev);
525         __bt_device_props_to_hal(props, ev->props, ev->num_props, len);
526         memcpy(bd_addr.address, ev->bdaddr, 6);
527         bt_hal_cbacks->remote_device_properties_cb(
528                         ev->status, &bd_addr, ev->num_props, props);
529         DBG("-");
530 }
531
532 static void __bt_hal_handle_stack_messages(int message, void *buf, uint16_t len)
533 {
534         DBG("+");
535         switch(message) {
536                 case HAL_EV_ADAPTER_STATE_CHANGED:
537                         DBG("Event: HAL_EV_ADAPTER_STATE_CHANGED");
538                         __bt_hal_handle_adapter_state_changed(buf, len);
539                         break;
540                 case HAL_EV_ADAPTER_PROPS_CHANGED:
541                         DBG("Event: HAL_EV_ADAPTER_PROPS_CHANGED");
542                         __bt_hal_handle_adapter_property_changed(buf, len);
543                         break;
544                 case HAL_EV_DISCOVERY_STATE_CHANGED:
545                         DBG("Event: HAL_EV_DISCOVERY_STATE_CHANGED");
546                         __bt_hal_handle_adapter_discovery_state_changed(buf, len);
547                         break;
548                 case HAL_EV_DEVICE_FOUND:
549                         DBG("Event: HAL_EV_DEVICE_FOUND");
550                         __bt_hal_handle_device_found_event(buf, len);
551                         break;
552                 case HAL_EV_REMOTE_DEVICE_PROPS:
553                         DBG("Event: HAL_EV_REMOTE_DEVICE_PROPS");
554                         __bt_hal_handle_remote_device_properties_event(buf, len);
555                         break;
556                 default:
557                         DBG("Event Currently not handled!!");
558                         break;
559         }
560         DBG("-");
561 }