[Adapt:Bluez HAL] Implement Create and Remove Bond
[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         return BT_STATUS_UNSUPPORTED;
124 }
125
126 static int get_remote_device_property(bt_bdaddr_t *remote_addr,
127                 bt_property_type_t type)
128 {
129         return BT_STATUS_UNSUPPORTED;
130 }
131
132 static int set_remote_device_property(bt_bdaddr_t *remote_addr,
133                 const bt_property_t *property)
134 {
135         return BT_STATUS_UNSUPPORTED;
136 }
137
138 static int get_remote_service_record(bt_bdaddr_t *remote_addr, bt_uuid_t *uuid)
139 {
140         return BT_STATUS_UNSUPPORTED;
141
142 }
143
144 static int get_remote_services(bt_bdaddr_t *remote_addr)
145 {
146         return BT_STATUS_UNSUPPORTED;
147 }
148
149 static int start_discovery(void)
150 {
151         return _bt_hal_dbus_start_discovery();
152 }
153
154 static int cancel_discovery(void)
155 {
156         return _bt_hal_dbus_stop_discovery();
157 }
158
159 static int create_bond(const bt_bdaddr_t *bd_addr, int transport)
160 {
161         DBG("+");
162         return _bt_hal_device_create_bond(bd_addr);
163 }
164
165 static int cancel_bond(const bt_bdaddr_t *bd_addr)
166 {
167         return BT_STATUS_UNSUPPORTED;
168 }
169
170 static int remove_bond(const bt_bdaddr_t *bd_addr)
171 {
172         DBG("+");
173         return _bt_hal_device_remove_bond(bd_addr);
174 }
175
176 static int pin_reply(const bt_bdaddr_t *bd_addr, uint8_t accept,
177                 uint8_t pin_len, bt_pin_code_t *pin_code)
178 {
179         return BT_STATUS_UNSUPPORTED;
180 }
181
182 static int ssp_reply(const bt_bdaddr_t *bd_addr, bt_ssp_variant_t variant,
183                 uint8_t accept, uint32_t passkey)
184 {
185         return BT_STATUS_UNSUPPORTED;
186 }
187
188 static const void *get_profile_interface(const char *profile_id)
189 {
190         /*TODO: Profile interfaces to be included later*/
191         DBG("%s", profile_id);
192
193         if (!interface_ready())
194                 return NULL;
195
196         if (!strcmp(profile_id, BT_PROFILE_PAN_ID))
197                 return NULL;
198
199         if (!strcmp(profile_id, BT_PROFILE_ADVANCED_AUDIO_ID))
200                 return NULL;
201
202         if (!strcmp(profile_id, BT_PROFILE_AV_RC_ID))
203                 return NULL;
204
205         if (!strcmp(profile_id, BT_PROFILE_HANDSFREE_ID))
206                 return NULL;
207
208         if (!strcmp(profile_id, BT_PROFILE_GATT_ID))
209                 return NULL;
210
211         if (!strcmp(profile_id, BT_PROFILE_HEALTH_ID))
212                 return NULL;
213
214         if (!strcmp(profile_id, BT_PROFILE_AV_RC_CTRL_ID))
215                 return NULL;
216
217         if (!strcmp(profile_id, BT_PROFILE_HANDSFREE_CLIENT_ID))
218                 return NULL;
219
220         if (!strcmp(profile_id, BT_PROFILE_MAP_CLIENT_ID))
221                 return NULL;
222
223         if (!strcmp(profile_id, BT_PROFILE_ADVANCED_AUDIO_SINK_ID))
224                 return NULL;
225
226         return NULL;
227 }
228
229 static int dut_mode_configure(uint8_t enable)
230 {
231         return BT_STATUS_UNSUPPORTED;
232 }
233
234 static int dut_mode_send(uint16_t opcode, uint8_t *buf, uint8_t buf_len)
235 {
236         return BT_STATUS_UNSUPPORTED;
237 }
238
239 static int le_test_mode(uint16_t opcode, uint8_t *buf, uint8_t buf_len)
240 {
241         return BT_STATUS_UNSUPPORTED;
242 }
243
244 static int config_hci_snoop_log(uint8_t enable)
245 {
246         return BT_STATUS_UNSUPPORTED;
247 }
248
249 static int get_connection_state(const bt_bdaddr_t *bd_addr)
250 {
251         return BT_STATUS_UNSUPPORTED;
252 }
253
254 static int set_os_callouts(bt_os_callouts_t *callouts)
255 {
256         DBG("callouts: %p", callouts);
257
258         /* TODO: implement */
259
260         return BT_STATUS_UNSUPPORTED;
261 }
262
263 static int read_energy_info(void)
264 {
265         return BT_STATUS_UNSUPPORTED;
266 }
267
268 static const bt_interface_t bluetooth_if = {
269         .size = sizeof(bt_interface_t),
270         .init = init,
271         .enable = enable,
272         .disable = disable,
273         .cleanup = cleanup,
274         .get_adapter_properties = get_adapter_properties,
275         .get_adapter_property = get_adapter_property,
276         .set_adapter_property = set_adapter_property,
277         .get_remote_device_properties = get_remote_device_properties,
278         .get_remote_device_property = get_remote_device_property,
279         .set_remote_device_property = set_remote_device_property,
280         .get_remote_service_record = get_remote_service_record,
281         .get_remote_services = get_remote_services,
282         .start_discovery = start_discovery,
283         .cancel_discovery = cancel_discovery,
284         .create_bond = create_bond,
285         .remove_bond = remove_bond,
286         .cancel_bond = cancel_bond,
287         .pin_reply = pin_reply,
288         .ssp_reply = ssp_reply,
289         .get_profile_interface = get_profile_interface,
290         .dut_mode_configure = dut_mode_configure,
291         .dut_mode_send = dut_mode_send,
292         .le_test_mode = le_test_mode,
293         .config_hci_snoop_log = config_hci_snoop_log,
294         .get_connection_state = get_connection_state,
295         .set_os_callouts = set_os_callouts,
296         .read_energy_info = read_energy_info,
297 };
298
299 static const bt_interface_t *get_bluetooth_interface(void)
300 {
301         DBG("");
302         return &bluetooth_if;
303 }
304
305 static int close_bluetooth(struct hw_device_t *device)
306 {
307         DBG("");
308         cleanup();
309         free(device);
310         return 0;
311 }
312
313 static int open_bluetooth(const struct hw_module_t *module, char const *name,
314                 struct hw_device_t **device)
315 {
316         bluetooth_device_t *dev = malloc(sizeof(bluetooth_device_t));
317
318         DBG("");
319
320         memset(dev, 0, sizeof(bluetooth_device_t));
321         dev->common.tag = HARDWARE_DEVICE_TAG;
322         dev->common.version = 0;
323         dev->common.module = (struct hw_module_t *) module;
324         dev->common.close = close_bluetooth;
325         dev->get_bluetooth_interface = get_bluetooth_interface;
326
327         *device = (struct hw_device_t *) dev;
328
329         return 0;
330 }
331
332 static struct hw_module_methods_t bluetooth_module_methods = {
333         .open = open_bluetooth,
334 };
335
336 struct hw_module_t HAL_MODULE_INFO_SYM = {
337         .tag = HARDWARE_MODULE_TAG,
338         .version_major = 1,
339         .version_minor = 0,
340         .id = BT_HARDWARE_MODULE_ID,
341         .name = "Bluetooth stack",
342         .author = "Intel Corporation",
343         .methods = &bluetooth_module_methods
344 };
345
346 static void __bt_hal_handle_adapter_state_changed(void *buf, uint16_t len)
347 {
348         struct hal_ev_adapter_state_changed *ev = buf;
349
350         DBG("Adapter State: %d", ev->state);
351
352         if (bt_hal_cbacks->adapter_state_changed_cb)
353                 bt_hal_cbacks->adapter_state_changed_cb(ev->state);
354 }
355
356 static void __bt_adapter_props_to_hal(bt_property_t *send_props, struct hal_property *prop,
357                 uint8_t num_props, uint16_t len)
358 {
359         void *buf = prop;
360         uint8_t i;
361
362         for (i = 0; i < num_props; i++) {
363                 if (sizeof(*prop) + prop->len > len) {
364                         ERR("invalid adapter properties(%zu > %u), cant process further properties!!!",
365                                         sizeof(*prop) + prop->len, len);
366                         return;
367                 }
368
369                 send_props[i].type = prop->type;
370
371                 switch (prop->type) {
372                         /* TODO: Add Adapter Properties */
373                         default:
374                                 send_props[i].len = prop->len;
375                                 send_props[i].val = prop->val;
376                                 break;
377                 }
378
379                 DBG("prop[%d]: %s", i, btproperty2str(&send_props[i]));
380
381                 len -= sizeof(*prop) + prop->len;
382                 buf += sizeof(*prop) + prop->len;
383                 prop = buf;
384         }
385
386         if (!len)
387                 return;
388 }
389
390 static void __bt_device_props_to_hal(bt_property_t *send_props,
391                 struct hal_property *prop, uint8_t num_props,
392                 uint16_t len)
393 {
394         void *buf = prop;
395         uint8_t i;
396
397         DBG("+");
398
399         for (i = 0; i < num_props; i++) {
400
401                 if (sizeof(*prop) + prop->len > len) {
402                         ERR("invalid device properties (%zu > %u), cant process further properties!!!",
403                                         sizeof(*prop) + prop->len, len);
404                         return;
405                 }
406
407                 send_props[i].type = prop->type;
408
409                 DBG("HAL prop Type [%d]", prop->type);
410
411                 switch (prop->type) {
412                 case HAL_PROP_DEVICE_TYPE:
413                 {
414                         DBG("Device property:HAL_PROP_DEVICE_TYPE:");
415                         enum_prop_to_hal(send_props[i], prop,
416                                         bt_device_type_t);
417                         break;
418                 }
419                 case HAL_PROP_DEVICE_VERSION_INFO:
420                 {
421                         DBG("Device property: HAL_PROP_DEVICE_VERSION_INFO");
422                         static bt_remote_version_t e;
423                         const struct hal_prop_device_info *p;
424                         send_props[i].val = &e;
425                         send_props[i].len = sizeof(e);
426                                 p = (struct hal_prop_device_info *) prop->val;
427                                 e.manufacturer = p->manufacturer;
428                         e.sub_ver = p->sub_version;
429                         e.version = p->version;
430                         break;
431                 }
432                 case HAL_PROP_DEVICE_SERVICE_REC:
433                 {
434                         DBG("Device property: HAL_PROP_DEVICE_SERVICE_REC");
435                         static bt_service_record_t e;
436                         const struct hal_prop_device_service_rec *p;
437                         send_props[i].val = &e;
438                         send_props[i].len = sizeof(e);
439                                 p = (struct hal_prop_device_service_rec *) prop->val;
440                                         memset(&e, 0, sizeof(e));
441                         memcpy(&e.channel, &p->channel, sizeof(e.channel));
442                         memcpy(e.uuid.uu, p->uuid, sizeof(e.uuid.uu));
443                         memcpy(e.name, p->name, p->name_len);
444                         break;
445                 }
446                 default:
447                         send_props[i].len = prop->len;
448                         send_props[i].val = prop->val;
449                         break;
450                 }
451
452                 DBG("prop[%d]: %s", i, btproperty2str(&send_props[i]));
453                 len -= sizeof(*prop) + prop->len;
454                 buf += sizeof(*prop) + prop->len;
455                 prop = buf;
456
457         }
458
459         if (!len) {
460                 DBG("-");
461                 return;
462         }
463
464         ERR("invalid device properties (%u bytes left), ", len);
465 }
466
467 static void __bt_hal_handle_adapter_property_changed(void *buf, uint16_t len)
468 {
469         struct hal_ev_adapter_props_changed *ev = (struct hal_ev_adapter_props_changed *)buf;
470         bt_property_t props[ev->num_props];
471         DBG("+");
472
473         if (!bt_hal_cbacks->adapter_properties_cb)
474                 return;
475
476         len -= sizeof(*ev);
477         __bt_adapter_props_to_hal(props, ev->props, ev->num_props, len);
478
479         if (bt_hal_cbacks->adapter_properties_cb)
480                 bt_hal_cbacks->adapter_properties_cb(ev->status, ev->num_props, props);
481 }
482
483 static void __bt_hal_handle_adapter_discovery_state_changed(void *buf, uint16_t len)
484 {
485         struct hal_ev_discovery_state_changed *ev = (struct hal_ev_discovery_state_changed *)buf;
486
487         DBG("+");
488
489         if (bt_hal_cbacks->discovery_state_changed_cb)
490                 bt_hal_cbacks->discovery_state_changed_cb(ev->state);
491 }
492
493 static void __bt_hal_handle_device_found_event(void *buf, uint16_t len)
494 {
495         struct hal_ev_device_found *ev =  (struct hal_ev_device_found *) buf;
496         bt_property_t props[ev->num_props];
497         DBG("+");
498
499         if (!bt_hal_cbacks->device_found_cb)
500                 return;
501
502         len -= sizeof(*ev);
503         __bt_device_props_to_hal(props, ev->props, ev->num_props, len);
504
505         bt_hal_cbacks->device_found_cb(ev->num_props, props);
506 }
507
508 static void __bt_hal_handle_stack_messages(int message, void *buf, uint16_t len)
509 {
510         DBG("+");
511         switch(message) {
512                 case HAL_EV_ADAPTER_STATE_CHANGED:
513                         DBG("Event: HAL_EV_ADAPTER_STATE_CHANGED");
514                         __bt_hal_handle_adapter_state_changed(buf, len);
515                         break;
516                 case HAL_EV_ADAPTER_PROPS_CHANGED:
517                         DBG("Event: HAL_EV_ADAPTER_PROPS_CHANGED");
518                         __bt_hal_handle_adapter_property_changed(buf, len);
519                         break;
520                 case HAL_EV_DISCOVERY_STATE_CHANGED:
521                         DBG("Event: HAL_EV_DISCOVERY_STATE_CHANGED");
522                         __bt_hal_handle_adapter_discovery_state_changed(buf, len);
523                         break;
524                 case HAL_EV_DEVICE_FOUND:
525                         DBG("Event: HAL_EV_DEVICE_FOUND");
526                         __bt_hal_handle_device_found_event(buf, len);
527                 default:
528                         DBG("Event Currently not handled!!");
529                         break;
530         }
531         DBG("-");
532 }