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