4 * Copyright (c) 2015 -2016 Samsung Electronics Co., Ltd All Rights Reserved.
6 * Contact: Anupam Roy <anupam.r@samsung.com>
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
33 #include "bt-hal-log.h"
34 #include "bt-hal-msg.h"
35 #include "bt-hal-internal.h"
36 #include "bt-hal-event-receiver.h"
37 #include "bt-hal-dbus-common-utils.h"
38 #include "bt-hal-agent.h"
39 #include "bt-hal-adapter-le.h"
40 #include "bt-hal-gatt-server.h"
42 #define BASELEN_PROP_CHANGED (sizeof(struct hal_ev_adapter_props_changed) \
43 + sizeof(struct hal_property))
45 /*TODO: Basic filters are currently added,
46 Need to add different event filters like HID,
47 Device etc in subsequent patches */
49 /* Global variables and structures */
50 static GDBusConnection *manager_conn;
51 static handle_stack_msg event_cb = NULL;
52 static handle_stack_msg hid_event_cb = NULL;
53 static handle_stack_msg av_event_cb = NULL;
54 static handle_stack_msg a2dp_sink_event_cb = NULL;
55 static handle_stack_msg hf_event_cb = NULL;
56 static handle_stack_msg avrcp_ctrl_event_cb = NULL;
57 static handle_stack_msg avrcp_tg_event_cb = NULL;
58 static handle_stack_msg gatt_event_cb = NULL;
59 static guint event_id;
61 /*State Management sepration Control for Adapter and LE */
62 static gboolean is_adapter_activating = FALSE;
63 static gboolean is_le_activating = FALSE;
68 gchar* interface_name;
71 } bt_hal_main_event_data_t;
73 /* Forward declarations */
74 static gboolean __bt_hal_event_manager(gpointer param);
75 static int __bt_hal_register_service_event(GDBusConnection *g_conn, int event_type);
76 static int __bt_hal_register_manager_subscribe_signal(GDBusConnection *conn, int subscribe);
77 static int __bt_hal_register_device_subscribe_signal(GDBusConnection *conn, int subscribe);
78 static int __bt_hal_register_input_subscribe_signal(GDBusConnection *conn, int subscribe);
80 static int __bt_hal_parse_event(GVariant *msg);
81 static int __bt_hal_get_owner_info(GVariant *msg, char **name, char **previous, char **current);
83 static void __bt_hal_handle_property_changed_event(GVariant *msg, const char *object_path);
84 static void __bt_hal_adapter_property_changed_event(GVariant *msg);
85 static void __bt_hal_manager_event_filter(GDBusConnection *connection, const gchar *sender_name,
86 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
87 GVariant *parameters, gpointer user_data);
88 static int __bt_hal_initialize_manager_receiver(void);
89 static gboolean __bt_hal_parse_interface(GVariant *msg);
90 static void __bt_hal_handle_device_event(GVariant *value, GVariant *parameters);
91 static gboolean __bt_hal_parse_device_properties(GVariant *item);
92 static gboolean __bt_hal_discovery_finished_cb(gpointer user_data);
93 static void __bt_hal_device_property_changed_event(GVariant *msg, const char *path);
94 static void __bt_hal_dbus_device_found_properties(const char *device_path);
95 static void __bt_hal_device_properties_lookup(GVariant *result, char *address);
96 static void __bt_hal_handle_device_specific_events(GVariant *msg, const char *member, const char *path);
97 static void __bt_hal_send_device_acl_connection_state_event(gboolean connected, const char *address);
98 static void __bt_hal_handle_input_event(GVariant *msg, const char *path);
99 static void __bt_hal_send_av_connection_state_event(gboolean connected, const char *address);
100 static void __bt_hal_send_a2dp_sink_connection_state_event(gboolean connected, const char *address);
101 static void __bt_hal_send_avrcp_ctrl_connection_state_event(gboolean connected, const char *address);
102 static void __bt_hal_handle_avrcp_ctrl_events(GVariant *msg, const char *member, const char *path);
103 static void __bt_hal_handle_avrcp_transport_events(GVariant *msg, const char *member, const char *path);
105 static void __bt_hal_send_device_trust_state_event(gboolean is_trusted, const char *address);
106 static int __bt_hal_register_audio_subscribe_signal(GDBusConnection *conn, int subscribe);
107 static void __bt_hal_handle_headset_events(GVariant *msg, const char *member, const char *path);
108 static void __bt_hal_send_hf_audio_connection_state_event(gboolean connected, const char *address);
109 static void __bt_hal_send_hf_connection_state_event(gboolean connected, const char *address);
110 static void __bt_hal_send_device_trusted_profile_changed_event(uint32_t trust_val, const char *address);
111 static void __bt_hal_handle_adv_report(GVariant *msg, const char *path);
113 static gboolean __bt_hal_discovery_finished_cb(gpointer user_data)
117 struct hal_ev_discovery_state_changed ev;
118 ev.state = HAL_DISCOVERY_STATE_STOPPED;
119 event_cb(HAL_EV_DISCOVERY_STATE_CHANGED, &ev, sizeof(ev));
125 static int __bt_hal_parse_event(GVariant *msg)
129 char *interface_name = NULL;
130 GVariant *inner_iter = NULL;
132 g_variant_iter_init(&iter, msg);
134 while ((child = g_variant_iter_next_value(&iter))) {
135 g_variant_get(child, "{&s@a{sv}}", &interface_name, &inner_iter);
136 if (g_strcmp0(interface_name,
137 BT_HAL_DEVICE_INTERFACE) == 0) {
138 DBG("__bt_hal_parse_event: Interface: BT_HAL_DEVICE_INTERFACE");
139 g_variant_unref(inner_iter);
140 g_variant_unref(child);
141 return BT_HAL_DEVICE_EVENT;
142 } else if (g_strcmp0(interface_name,
143 BT_HAL_MEDIATRANSPORT_INTERFACE) == 0) {
144 DBG("__bt_hal_parse_event: Interface: BT_HAL_MEDIATRANSPORT_INTERFACE");
145 g_variant_unref(inner_iter);
146 g_variant_unref(child);
147 return BT_HAL_MEDIA_TRANSFER_EVENT;
148 } else if (g_strcmp0(interface_name,
149 BT_HAL_PLAYER_CONTROL_INTERFACE) == 0) {
150 DBG("__bt_hal_parse_event: Interface: BT_HAL_PLAYER_CONTROL_INTERFACE");
151 g_variant_unref(inner_iter);
152 g_variant_unref(child);
153 return BT_HAL_AVRCP_CONTROL_EVENT;
155 g_variant_unref(inner_iter);
156 g_variant_unref(child);
162 static int __bt_hal_get_owner_info(GVariant *msg, char **name, char **previous, char **current)
164 g_variant_get(msg, "(sss)", name, previous, current);
165 return BT_HAL_ERROR_NONE;
168 int __bt_insert_hal_properties(void *buf, uint8_t type, uint16_t len, const void *val)
169 { struct hal_property *prop = buf;
175 memcpy(prop->val, val, len);
177 return sizeof(*prop) + len;
180 handle_stack_msg _bt_hal_get_stack_message_handler(void)
185 static void __bt_hal_adapter_property_changed_event(GVariant *msg)
187 GVariantIter value_iter;
188 GVariant *value = NULL;
189 GDBusProxy *adapter_proxy;
192 g_variant_iter_init(&value_iter, msg);
194 /* Buffer and propety count management */
195 uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
196 struct hal_ev_adapter_props_changed *ev = (void*) buf;
198 const gchar *address = NULL;
200 unsigned int cod = 0;
201 gboolean discoverable;
202 gboolean connectable;
203 unsigned int scan_mode = BT_SCAN_MODE_NONE;
204 unsigned int disc_timeout;
205 const gchar *version;
206 const gboolean ipsp_initialized;
209 unsigned int pairable_timeout;
210 gboolean scan_mode_property_update = FALSE;
211 gboolean is_discovering;
212 gboolean is_le_discovering;
214 memset(buf, 0, sizeof(buf));
217 ev->status = BT_STATUS_SUCCESS;
221 while (g_variant_iter_loop(&value_iter, "{sv}", &key, &value)) {
222 if (!g_strcmp0(key, "Address")) {
225 address = g_variant_get_string(value, NULL);
226 DBG("##Address [%s]", address);
227 _bt_hal_convert_addr_string_to_type(bdaddr, address);
228 size += __bt_insert_hal_properties(buf + size,
229 HAL_PROP_ADAPTER_ADDR, sizeof(bdaddr), bdaddr);
231 } else if (!g_strcmp0(key, "Alias")) {
232 g_variant_get(value, "&s", &name);
233 DBG("##Alias [%s] ", name);
234 size += __bt_insert_hal_properties(buf + size,
235 HAL_PROP_ADAPTER_NAME, strlen(name) + 1, name);
237 } else if (!g_strcmp0(key, "Class")) {
238 cod = g_variant_get_uint32(value);
239 DBG("##Class [%d]", cod);
240 size += __bt_insert_hal_properties(buf + size,
241 HAL_PROP_ADAPTER_CLASS, sizeof(unsigned int), &cod);
243 } else if (!g_strcmp0(key, "Discoverable")) {
244 discoverable = g_variant_get_boolean(value);
245 DBG("##Discoverable [%d]", discoverable);
247 scan_mode = BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE;
249 scan_mode = BT_SCAN_MODE_CONNECTABLE;
250 scan_mode_property_update = TRUE;
251 } else if (!g_strcmp0(key, "DiscoverableTimeout")) {
252 disc_timeout = g_variant_get_uint32(value);
253 DBG("##Discoverable Timeout [%d]", disc_timeout);
254 size += __bt_insert_hal_properties(buf + size,
255 HAL_PROP_ADAPTER_DISC_TIMEOUT, sizeof(unsigned int), &disc_timeout);
257 } else if (!g_strcmp0(key, "Connectable")) {
258 connectable = g_variant_get_boolean(value);
259 DBG("##Connectable [%d]", connectable);
261 scan_mode = BT_SCAN_MODE_NONE;
262 else if (scan_mode == BT_SCAN_MODE_NONE)
263 scan_mode = BT_SCAN_MODE_CONNECTABLE;
264 scan_mode_property_update = TRUE;
265 } else if (!g_strcmp0(key, "Version")) {
266 version = g_variant_get_string(value, NULL);
267 DBG("##Version [%s]", version);
268 size += __bt_insert_hal_properties(buf + size,
269 HAL_PROP_ADAPTER_VERSION, strlen(version) + 1, version);
271 } else if (!g_strcmp0(key, "Name")) {
272 g_variant_get(value, "&s", &name);
273 DBG("##Name [%s]", name);
274 size += __bt_insert_hal_properties(buf + size,
275 HAL_PROP_ADAPTER_NAME, strlen(name) + 1, name);
277 } else if (!g_strcmp0(key, "Powered")) {
278 powered = g_variant_get_boolean(value);
279 DBG("##Powered = %d", powered);
280 /* TODO: Need to check this operation!! */
281 if (powered == FALSE) {
282 DBG("###### Adapter Powered Down ######");
283 struct hal_ev_adapter_state_changed ev;
284 ev.state = HAL_POWER_OFF;
285 event_cb(HAL_EV_ADAPTER_STATE_CHANGED, &ev, sizeof(ev));
287 struct hal_ev_le_state_changed le_ev;
288 le_ev.state = HAL_POWER_OFF;
289 event_cb(HAL_EV_LE_STATE_CHANGED, &le_ev, sizeof(le_ev));
292 _bt_hal_destroy_adapter_agent();
294 DBG("###### Adapter Powered Up ######");
295 if (_bt_hal_get_adapter_request_state()) {
296 DBG("Sending STATE CHANGE EVENT for Adapter... ");
297 _bt_hal_set_adapter_request_state(FALSE);
298 struct hal_ev_adapter_state_changed ev;
299 ev.state = HAL_POWER_ON;
300 event_cb(HAL_EV_ADAPTER_STATE_CHANGED, &ev, sizeof(ev));
303 if (_bt_hal_get_le_request_state()) {
304 DBG("Sending STATE CHANGE EVENT for LE... ");
305 _bt_hal_set_le_request_state(FALSE);
306 struct hal_ev_le_state_changed ev;
307 ev.state = HAL_POWER_ON;
308 event_cb(HAL_EV_LE_STATE_CHANGED, &ev, sizeof(ev));
312 _bt_hal_initialize_adapter_agent();
315 } else if (!g_strcmp0(key, "Pairable")) {
316 pairable = g_variant_get_boolean(value);
317 DBG("##Pairable [%d]", pairable);
318 } else if (!g_strcmp0(key, "PairableTimeout")) {
319 pairable_timeout = g_variant_get_uint32(value);
320 DBG("##Pairable Timeout = %d", pairable_timeout);
321 } else if (!g_strcmp0(key, "UUIDs")) {
326 size1 = g_variant_get_size(value);
327 int num_props_tmp = ev->num_props;
329 uuid_value = (char **)g_variant_get_strv(value, &size1);
330 for (i = 0; uuid_value[i] != NULL; i++)
332 /* UUID collection */
333 uint8_t uuids[BT_HAL_STACK_UUID_SIZE * uuid_count];
334 for (i = 0; uuid_value[i] != NULL; i++) {
335 char *uuid_str = NULL;
336 uint8_t uuid[BT_HAL_STACK_UUID_SIZE];
337 uuid_str = g_strdup(uuid_value[i]);
338 DBG("##UUID string [%s]\n", uuid_str);
339 _bt_hal_convert_uuid_string_to_type(uuid, uuid_str);
340 memcpy(uuids+i*BT_HAL_STACK_UUID_SIZE, uuid, BT_HAL_STACK_UUID_SIZE);
343 size += __bt_insert_hal_properties(buf + size, HAL_PROP_ADAPTER_UUIDS,
344 (BT_HAL_STACK_UUID_SIZE * uuid_count),
346 ev->num_props = num_props_tmp + 1;
349 } else if (!g_strcmp0(key, "Discovering")) {
350 is_discovering = g_variant_get_boolean(value);
351 DBG("##Discovering = [%d]", is_discovering);
353 if (is_discovering == FALSE) {
354 DBG("###### Adapter Has stopped Discovering ######");
355 /* In Tizen Bluez, this actually does not mean Discovery is stopped
356 in Bluez. Tizen Bluez sends this event after a certain timeout,
357 Therefore, we must forecefully call StopDiscovery to stop discovery in BlueZ */
361 adapter_proxy = _bt_hal_get_adapter_proxy();
363 if (adapter_proxy == NULL)
366 /* Need to stop searching */
367 DBG("Event though Bluez reported DIscovering stopped, we force stop Discovery ");
368 g_dbus_proxy_call_sync(adapter_proxy, "StopDiscovery",
370 G_DBUS_CALL_FLAGS_NONE,
374 ERR("Dbus Error : %s", err->message);
376 /* This error is thrown by Bluez, as Discovery is already stopped.
377 Discovery is stopped if user cancels on going discovery.
378 In order to maintain correct state of Bluetooth Discovery state,
379 simply send Discovery stopped event to HAL user */
380 struct hal_ev_discovery_state_changed ev;
381 ev.state = HAL_DISCOVERY_STATE_STOPPED;
382 event_cb(HAL_EV_DISCOVERY_STATE_CHANGED, &ev, sizeof(ev));
387 event_id = g_timeout_add(BT_HAL_DISCOVERY_FINISHED_DELAY,
388 (GSourceFunc)__bt_hal_discovery_finished_cb, NULL);
392 DBG("###### Adapter Has started Discovering ######");
393 struct hal_ev_discovery_state_changed ev;
394 ev.state = HAL_DISCOVERY_STATE_STARTED;
395 event_cb(HAL_EV_DISCOVERY_STATE_CHANGED, &ev, sizeof(ev));
398 } else if (!g_strcmp0(key, "LEDiscovering")) {
401 is_le_discovering = g_variant_get_boolean(value);
402 DBG("##LE Discovering = [%d]", is_le_discovering);
404 if (is_le_discovering)
407 adapter_proxy = _bt_hal_get_adapter_proxy();
408 if (adapter_proxy == NULL) {
409 ERR("adapter_proxy == NULL");
413 /* Need to stop searching */
414 result = g_dbus_proxy_call_sync(adapter_proxy, "StopLEDiscovery",
415 NULL, G_DBUS_CALL_FLAGS_NONE,
416 DBUS_TIMEOUT, NULL, &err);
418 ERR("Error occured in Proxy call");
420 ERR("(Error: %s)", err->message);
425 g_variant_unref(result);
426 } else if (!g_strcmp0(key, "Modalias")) {
427 char *modalias = NULL;
428 g_variant_get(value, "s", &modalias);
429 DBG("##Adapter ModAlias [%s]", modalias);
430 } else if (!g_strcmp0(key, "SupportedLEFeatures")) {
431 DBG("##LE Supported features");
434 GVariantIter *iter = NULL;
435 g_variant_get(value, "as", &iter);
440 while (g_variant_iter_next(iter, "&s", &name) &&
441 g_variant_iter_next(iter, "&s", &val)) {
442 DBG("name = %s, Value = %s", name, val);
443 if (FALSE == _bt_hal_update_le_feature_support(name, val))
444 ERR("Failed to update LE feature (name = %s, value = %s)", name, val);
447 g_variant_iter_free(iter);
448 } else if (!g_strcmp0(key, "IpspInitStateChanged")) {
449 g_variant_get(value, "b" , &ipsp_initialized);
450 DBG("##IPSP Initialized = %d", ipsp_initialized);
452 ERR("Unhandled Property:[%s]", key);
456 if (scan_mode_property_update) {
457 size += __bt_insert_hal_properties(buf + size,
458 HAL_PROP_ADAPTER_SCAN_MODE, sizeof(int), &scan_mode);
464 DBG("Send Adapter properties changed event to HAL user, Num Prop [%d] total size [%d]", ev->num_props, size);
465 event_cb(HAL_EV_ADAPTER_PROPS_CHANGED, buf, size);
467 g_variant_unref(value);
471 void _bt_hal_handle_adapter_event(GVariant *msg, const char *member)
478 if (strcasecmp(member, "DeviceCreated") == 0) {
479 DBG("DeviceCreated: Unhandled");
480 } else if (strcasecmp(member, "InterfacesRemoved") == 0) {
481 DBG("InterfacesRemoved: Unhandled");
482 } else if (strcasecmp(member, "AdvertisingEnabled") == 0) {
483 DBG("AdvertisingEnabled");
484 DBG("Advertising Enabled");
486 gboolean status = FALSE;
487 g_variant_get(msg, "(ib)", &slot_id, &status);
488 DBG("Advertising Enabled : slot_id [%d] status [%d]", slot_id, status);
489 /* Send event to application */
490 _bt_hal_set_advertising_status(slot_id, status);
491 } else if (strcasecmp(member, "RssiEnabled") == 0) {
492 struct hal_ev_rssi_monitor_state_changed ev;
493 gboolean status = FALSE;
494 char *address = NULL;
497 g_variant_get(msg, "(sib)", &address, &link_type, &status);
498 DBG("RSSI monitoring %s for %s",
499 (status ? "Enabled" : "Disabled"), address);
501 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
502 ev.link_type = link_type;
503 ev.state = (status ? HAL_RSSI_MONITORING_ENABLED : HAL_RSSI_MONITORING_DISABLED);
505 ERR("event_cb is NULL");
507 event_cb(HAL_EV_RSSI_MONITOR_STATE_CHANGED, &ev, sizeof(ev));
510 } else if (strcasecmp(member, "RssiAlert") == 0) {
511 struct hal_ev_rssi_alert_recieved ev;
515 char *address = NULL;
517 g_variant_get(msg, "(siii)", &address, &link_type, &alert_type, &rssi_dbm);
518 DBG("RSSI Alert: [Address %s LinkType %d] [Type %d DBM %d]",
519 address, alert_type, rssi_dbm);
521 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
522 ev.link_type = link_type;
523 ev.alert_type = alert_type;
527 ERR("event_cb is NULL");
529 event_cb(HAL_EV_RSSI_ALERT_RECIEVED, &ev, sizeof(ev));
532 } else if (strcasecmp(member, "RawRssi") == 0) {
533 struct hal_ev_raw_rssi_recieved ev;
536 char *address = NULL;
538 g_variant_get(msg, "(sii)", &address, &link_type, &rssi_dbm);
539 DBG("Raw RSSI: [Address %s] [Link Type %d][RSSI DBM %d]",
540 address, link_type, rssi_dbm);
542 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
543 ev.link_type = link_type;
547 ERR("event_cb is NULL");
549 event_cb(HAL_EV_RAW_RSSI_RECIEVED, &ev, sizeof(ev));
552 } else if (strcasecmp(member, BT_HAL_HARDWARE_ERROR) == 0) {
553 DBG("BT Hardware Error: Unhandled");
554 } else if (strcasecmp(member, BT_HAL_TX_TIMEOUT_ERROR) == 0) {
555 DBG("BT TX Timeout Error: Unhandled");
561 static gboolean __bt_hal_parse_device_properties(GVariant *item)
571 /* Buffer and propety count management */
572 uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
573 struct hal_ev_device_found *ev = (void *) buf;
575 memset(buf, 0, sizeof(buf));
579 g_variant_iter_init(&iter, item);
580 while (g_variant_iter_loop(&iter, "{sv}", &key, &val)) {
582 if (strcasecmp(key, "Address") == 0) {
584 char * address = NULL;
585 address = g_variant_dup_string(val, &len);
587 _bt_hal_convert_addr_string_to_type(bdaddr, address);
589 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_ADDR,
590 sizeof(bdaddr), bdaddr);
593 DBG("Device address [%s] property Num [%d]", address, ev->num_props);
595 } else if (strcasecmp(key, "Class") == 0) {
596 unsigned int class = g_variant_get_uint32(val);
597 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_CLASS,
598 sizeof(unsigned int), &class);
600 DBG("Device class [%d] Property num [%d]", class, ev->num_props);
601 } else if (strcasecmp(key, "name") == 0) {
602 char *name = g_variant_dup_string(val, &len);
604 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_NAME,
605 strlen(name) + 1, name);
607 DBG("Device Name [%s] Property num [%d]", name, ev->num_props);
609 } else if (strcasecmp(key, "Connected") == 0) {
610 unsigned int connected = g_variant_get_uint32(val);
612 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_CONNECTED,
613 sizeof(unsigned int), &connected);
615 DBG("Device connected [%u] Property num [%d]", connected, ev->num_props);
616 } else if (strcasecmp(key, "paired") == 0) {
617 uint8_t paired = (g_variant_get_boolean(val) ? 1 : 0);
618 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_PAIRED,
619 sizeof(uint8_t), &paired);
621 DBG("Device Paired [%d] Property num [%d]", paired, ev->num_props);
622 } else if (strcasecmp(key, "Trusted") == 0) {
623 uint8_t trust = (g_variant_get_boolean(val) ? 1 : 0);
624 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_TRUSTED,
625 sizeof(uint8_t), &trust);
627 DBG("Device trusted [%d] Property num [%d]", trust, ev->num_props);
628 } else if (strcasecmp(key, "RSSI") == 0) {
629 int rssi = g_variant_get_int16(val);
630 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_RSSI,
633 DBG("Device RSSI [%d] Property num [%d]", rssi, ev->num_props);
634 } else if (strcasecmp(key, "LastAddrType") == 0) {
635 /* TODO: To be handled later*/
636 } else if (!g_strcmp0(key, "IsAliasSet")) {
637 uint8_t is_alias_set = (g_variant_get_boolean(val) ? 1 : 0);
638 DBG("IsAliasSet: %s", (is_alias_set ? "TRUE" : "FALSE"));
639 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_IS_ALIAS_SET,
640 sizeof(uint8_t), &is_alias_set);
642 } else if (strcasecmp(key, "UUIDs") == 0) {
647 size1 = g_variant_get_size(val);
648 DBG("UUID count from size [%d]\n", size1);
649 int num_props_tmp = ev->num_props;
652 uuid_value = (char **)g_variant_get_strv(val, &size1);
653 for (i = 0; uuid_value[i] != NULL; i++)
655 DBG("UUID count [%d]\n", uuid_count);
656 /* UUID collection */
657 uint8_t uuids[BT_HAL_STACK_UUID_SIZE * uuid_count];
659 for (i = 0; uuid_value[i] != NULL; i++) {
661 char *uuid_str = NULL;
662 uint8_t uuid[BT_HAL_STACK_UUID_SIZE];
663 memset(uuid, 0x00, BT_HAL_STACK_UUID_SIZE);
665 DBG("UUID string from Bluez [%s]\n", uuid_value[i]);
666 uuid_str = g_strdup(uuid_value[i]);
667 DBG("UUID string [%s]\n", uuid_str);
668 _bt_hal_convert_uuid_string_to_type(uuid, uuid_str);
669 memcpy(uuids+i*BT_HAL_STACK_UUID_SIZE, uuid, BT_HAL_STACK_UUID_SIZE);
673 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_UUIDS,
674 (BT_HAL_STACK_UUID_SIZE * uuid_count),
676 ev->num_props = num_props_tmp + 1;
680 } else if (strcasecmp(key, "ManufacturerDataLen") == 0) {
681 /* TODO: To be handled later*/
682 } else if (strcasecmp(key, "ManufacturerData") == 0) {
683 /* TODO: To be handled later*/
685 ERR("Unhandled Property:[%s]", key);
691 DBG("Send Device found event to HAL user, Num Prop [%d] total size [%d]", ev->num_props, size);
692 event_cb(HAL_EV_DEVICE_FOUND, (void*) buf, size);
698 static void __bt_hal_handle_avrcp_tg_events(GVariant *msg, const char *path)
701 GVariantIter value_iter;
702 char *property = NULL;
704 GVariant *val = NULL;
705 GVariant *child = NULL;
707 g_variant_iter_init(&value_iter, msg);
708 while ((child = g_variant_iter_next_value(&value_iter))) {
709 g_variant_get(child, "{sv}", &property, &val);
710 INFO("Property %s", property);
711 if (strcasecmp(property, "Connected") == 0) {
712 struct hal_ev_avrcp_tg_conn_state ev;
714 gboolean connected = FALSE;
716 g_variant_get(val, "b", &connected);
718 state = connected ? HAL_AVRCP_TG_STATE_CONNECTED :
719 HAL_AVRCP_TG_STATE_DISCONNECTED;
721 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
723 _bt_hal_convert_device_path_to_address(path, address);
725 DBG("connected: %d", connected);
726 DBG("address: %s", address);
728 /* Prepare to send AVRCP Target connection state event */
729 memset(&ev, 0, sizeof(ev));
730 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
732 if (!avrcp_tg_event_cb)
733 ERR("AVRCP target DBUS handler callback not registered");
735 avrcp_tg_event_cb(HAL_EV_AVRCP_TG_CONN_STATE, (void *)&ev, sizeof(ev));
739 g_variant_unref(child);
740 g_variant_unref(val);
746 static void __bt_hal_handle_property_changed_event(GVariant *msg, const char *object_path)
748 char *interface_name = NULL;
749 GVariant *val = NULL;
752 g_variant_get(msg, "(&s@a{sv}@as)", &interface_name, &val, NULL);
754 if (!interface_name) {
755 DBG("Failed to get interface name");
758 g_variant_unref(val);
762 if (strcasecmp(interface_name, BT_HAL_ADAPTER_INTERFACE) == 0) {
763 DBG("Event: Property Changed: Interface: BT_HAL_ADAPTER_INTERFACE");
764 __bt_hal_adapter_property_changed_event(val);
765 } else if (strcasecmp(interface_name, BT_HAL_DEVICE_INTERFACE) == 0) {
766 DBG("Event: Property Changed: Interface: BT_HAL_DEVICE_INTERFACE");
767 __bt_hal_device_property_changed_event(val, object_path);
768 } else if (strcasecmp(interface_name, BT_HAL_OBEX_TRANSFER_INTERFACE) == 0) {
769 DBG("Event: Property Changed: Interface: BT_HAL_OBEX_TRANSFER_INTERFACE");
770 /* TODO: Handle event */
771 } else if (strcasecmp(interface_name, BT_HAL_MEDIA_CONTROL_INTERFACE) == 0) {
772 DBG("Event: Property Changed: Interface: BT_HAL_MEDIA_CONTROL_INTERFACE");
773 /* Handle AVRCP target event */
774 __bt_hal_handle_avrcp_tg_events(val, object_path);
775 } else if (strcasecmp(interface_name, BT_HAL_PLAYER_CONTROL_INTERFACE) == 0) {
776 DBG("Event: Property Changed: Interface: BT_HAL_PLAYER_CONTROL_INTERFACE");
777 __bt_hal_handle_avrcp_ctrl_events(val, NULL, object_path);
778 } else if (strcasecmp(interface_name, BT_HAL_MEDIATRANSPORT_INTERFACE) == 0) {
779 DBG("Event: Property Changed: Interface: BT_HAL_MEDIATRANSPORT_INTERFACE");
780 __bt_hal_handle_avrcp_transport_events(val, NULL, object_path);
781 } else if (strcasecmp(interface_name, BT_HAL_NETWORK_CLIENT_INTERFACE) == 0) {
782 DBG("Event: Property Changed: Interface: BT_HAL_NETWORK_CLIENT_INTERFACE");
783 /* TODO: Handle event */
784 } else if (strcasecmp(interface_name, BT_HAL_GATT_CHAR_INTERFACE) == 0) {
785 DBG("Event: Property Changed: Interface: BT_HAL_GATT_CHAR_INTERFACE");
786 /* TODO: Handle event */
787 } else if (strcasecmp(interface_name, BT_HAL_INPUT_INTERFACE) == 0) {
788 DBG("Event: Property Changed: Interface: BT_HAL_INPUT_INTERFACE");
789 __bt_hal_handle_input_event(val, object_path);
791 g_variant_unref(val);
794 static void __bt_hal_handle_device_event(GVariant *value, GVariant *parameters)
798 if (__bt_hal_parse_interface(parameters) == FALSE) {
799 ERR("Fail to parse the properies");
800 g_variant_unref(value);
807 static void __bt_hal_send_hid_connection_state_event(
808 gboolean connected, char *address)
810 struct hal_ev_hidhost_conn_state ev;
812 ev.state = (connected == TRUE) ?
813 HAL_HIDHOST_STATE_CONNECTED :
814 HAL_HIDHOST_STATE_DISCONNECTED;
816 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
819 ERR("HID event handler not registered");
821 hid_event_cb(HAL_EV_HIDHOST_CONN_STATE, &ev, sizeof(ev));
824 static void __bt_hal_handle_input_event(GVariant *msg, const char *path)
826 gboolean property_flag = FALSE;
827 GVariantIter value_iter;
828 char *property = NULL;
829 GVariant *child = NULL, *val = NULL;
832 g_variant_iter_init(&value_iter, msg);
833 while ((child = g_variant_iter_next_value(&value_iter))) {
834 g_variant_get(child, "{sv}", &property, &val);
836 if (property == NULL)
839 if (strcasecmp(property, "Connected") == 0) {
842 g_variant_get(val, "b", &property_flag);
843 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
844 _bt_hal_convert_device_path_to_address(path, address);
845 __bt_hal_send_hid_connection_state_event(property_flag, address);
849 g_variant_unref(val);
850 g_variant_unref(child);
856 static gboolean __bt_hal_parse_interface(GVariant *msg)
859 GVariant *optional_param;
862 char *interface_name = NULL;
863 GVariant *inner_iter = NULL;
864 g_variant_get(msg, "(&o@a{sa{sv}})",
865 &path, &optional_param);
866 g_variant_iter_init(&iter, optional_param);
868 while ((child = g_variant_iter_next_value(&iter))) {
869 g_variant_get(child, "{&s@a{sv}}", &interface_name, &inner_iter);
870 if (g_strcmp0(interface_name, BT_HAL_DEVICE_INTERFACE) == 0) {
871 DBG("Found a device: %s", path);
872 if (__bt_hal_parse_device_properties(inner_iter) == FALSE) {
873 g_variant_unref(inner_iter);
874 g_variant_unref(child);
875 g_variant_unref(optional_param);
876 ERR("Fail to parse the properies");
879 g_variant_unref(inner_iter);
880 g_variant_unref(child);
881 g_variant_unref(optional_param);
885 g_variant_unref(inner_iter);
886 g_variant_unref(child);
889 g_variant_unref(optional_param);
894 static gboolean __bt_hal_event_manager(gpointer data)
896 bt_hal_event_type_t bt_event = 0x00;
898 char *obj_path = NULL;
900 bt_hal_main_event_data_t *param = (bt_hal_main_event_data_t*)data;
901 if (strcasecmp(param->signal_name, "InterfacesAdded") == 0) {
903 /*TODO: Handle Interfaces Added Signal from stack */
904 DBG("Manager Event: Signal Name: InterfacesAdded");
906 g_variant_get(param->parameters, "(&o@a{sa{sv}})", &obj_path, &value);
908 if (obj_path == NULL) {
909 DBG("obj_path is NULL");
913 if (strcasecmp(obj_path, BT_HAL_BLUEZ_HCI_PATH) == 0) {
914 /* TODO: Handle adapter added */
915 DBG("Manager Event: Signal Name: InterfiacesAdded: Adapter added in bluetoothd: path [hci0]");
917 bt_event = __bt_hal_parse_event(value);
918 if (bt_event == BT_HAL_DEVICE_EVENT) {
919 DBG("Device path : %s ", obj_path);
920 __bt_hal_handle_device_event(value, param->parameters);
921 } else if (bt_event == BT_HAL_AVRCP_CONTROL_EVENT) {
922 DBG("Device path : %s ", obj_path);
923 _bt_hal_set_control_device_path(obj_path);
926 g_variant_unref(value);
928 } else if (strcasecmp(param->signal_name, "InterfacesRemoved") == 0) {
932 /*TODO: Handle Interfaces Removed Signal from stack */
933 DBG("Manager Event: Signal Name: InterfacesRemoved");
935 g_variant_get(param->parameters, "(&oas)", &obj_path, &iter);
936 DBG("Device path : %s ", obj_path);
937 while (g_variant_iter_loop(iter, "s", &str)) {
938 if (g_strcmp0(str, BT_HAL_PLAYER_CONTROL_INTERFACE) == 0)
939 _bt_hal_remove_control_device_path(obj_path);
941 g_variant_iter_free(iter);
942 } else if (strcasecmp(param->signal_name, "NameOwnerChanged") == 0) {
944 char *previous = NULL;
945 char *current = NULL;
947 /* TODO: Handle Name Owener changed Signal */
948 if (__bt_hal_get_owner_info(param->parameters, &name, &previous, ¤t)) {
949 DBG("Fail to get the owner info");
952 if (current && *current != '\0') {
958 if (strcasecmp(name, BT_HAL_BLUEZ_NAME) == 0) {
959 DBG("Bluetoothd is terminated");
961 /* TODO: Handle Bluetoothd terminating scenario */
964 INFO("Name Owner changed [%s]", name);
969 } else if (g_strcmp0(param->interface_name, BT_HAL_PROPERTIES_INTERFACE) == 0) {
970 DBG("Manager Event: Interface Name: BT_HAL_PROPERTIES_INTERFACE");
971 __bt_hal_handle_property_changed_event(param->parameters, param->object_path);
972 } else if (g_strcmp0(param->interface_name, BT_HAL_ADAPTER_INTERFACE) == 0) {
973 DBG("Manager Event: Interface Name: BT_HAL_ADAPTER_INTERFACE");
974 _bt_hal_handle_adapter_event(param->parameters, param->signal_name);
975 } else if (g_strcmp0(param->interface_name, BT_HAL_INPUT_INTERFACE) == 0) {
976 DBG("Manager Event: Interface Name: BT_HAL_INPUT_INTERFACE");
977 __bt_hal_handle_input_event(param->parameters, param->object_path);
978 } else if (g_strcmp0(param->interface_name, BT_HAL_NETWORK_SERVER_INTERFACE) == 0) {
979 /* TODO: Handle Network Server events from stack */
980 DBG("Manager Event: Interface Name: BT_HAL_NETWORK_SERVER_INTERFACE");
981 } else if (g_strcmp0(param->interface_name, BT_HAL_HEADSET_INTERFACE) == 0) {
982 DBG("Manager Event: Interface Name: BT_HAL_HEADSET_INTERFACE");
983 __bt_hal_handle_headset_events(param->parameters, param->signal_name, param->object_path);
984 } else if (g_strcmp0(param->interface_name, BT_HAL_SINK_INTERFACE) == 0) {
985 /* TODO: Handle Sink interface events from stack */
986 DBG("Manager Event: Interface Name:BT_HAL_SINK_INTERFACE");
987 } else if (g_strcmp0(param->interface_name, BT_HAL_AGENT_INTERFACE) == 0) {
988 /* TODO: Handle Agent events from stack */
989 DBG("Manager Event: Interface Name:BT_HAL_AGENT_INTERFACE");
990 } else if (g_strcmp0(param->interface_name, BT_HAL_DEVICE_INTERFACE) == 0) {
991 DBG("Manager Event: Interface Name:BT_HAL_DEVICE_INTERFACE");
992 __bt_hal_handle_device_specific_events(param->parameters, param->signal_name, param->object_path);
993 } else if (g_strcmp0(param->interface_name, BT_HAL_PLAYER_CONTROL_INTERFACE) == 0) {
994 DBG("Manager Event: Interface Name: BT_HAL_PLAYER_CONTROL_INTERFACE");
995 __bt_hal_handle_avrcp_ctrl_events(param->parameters, param->signal_name, param->object_path);
996 } else if (g_strcmp0(param->interface_name, BT_HAL_MEDIATRANSPORT_INTERFACE) == 0) {
997 DBG("Manager Event: Interface Name: BT_HAL_MEDIATRANSPORT_INTERFACE");
998 __bt_hal_handle_avrcp_transport_events(param->parameters, param->signal_name, param->object_path);
1003 g_free(param->sender_name);
1004 g_free(param->object_path);
1005 g_free(param->interface_name);
1006 g_free(param->signal_name);
1007 g_variant_unref(param->parameters);
1012 static void __bt_hal_manager_event_filter(GDBusConnection *connection,
1013 const gchar *sender_name,
1014 const gchar *object_path,
1015 const gchar *interface_name,
1016 const gchar *signal_name,
1017 GVariant *parameters,
1020 if (signal_name == NULL)
1023 bt_hal_main_event_data_t *param = g_new0(bt_hal_main_event_data_t, 1);
1024 param->sender_name = g_strdup(sender_name);
1025 param->object_path = g_strdup(object_path);
1026 param->interface_name = g_strdup(interface_name);
1027 param->signal_name = g_strdup(signal_name);
1028 param->parameters = g_variant_ref(parameters);
1030 g_idle_add(__bt_hal_event_manager, (gpointer)param);
1034 static void __bt_hal_handle_headset_events(GVariant *msg, const char *member, const char *path)
1036 gboolean property_flag = FALSE;
1037 char *property = NULL;
1038 GVariant *value = NULL;
1039 g_variant_get(msg, "(sv)", &property, &value);
1041 if (property == NULL)
1044 DBG("Property = %s \n", property);
1045 /* We allow only 1 headset connection (HSP or HFP)*/
1046 if (strcasecmp(property, "Connected") == 0) {
1048 g_variant_get(value, "b", &property_flag);
1050 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1052 /* Fix : NULL_RETURNS */
1053 if (address == NULL)
1056 _bt_hal_convert_device_path_to_address(path, address);
1057 __bt_hal_send_hf_audio_connection_state_event(property_flag, address);
1059 } else if (strcasecmp(property, "State") == 0) {
1062 g_variant_get(value, "s", &state);
1064 /* This code assumes we support only 1 headset connection */
1065 /* Need to use the headset list, if we support multi-headsets */
1066 if (strcasecmp(state, "Playing") == 0) {
1067 DBG("Playing: Sco Connected");
1068 } else if (strcasecmp(state, "connected") == 0 ||
1069 strcasecmp(state, "disconnected") == 0) {
1070 if (strcasecmp(state, "connected") == 0)
1071 DBG("Sco Connected");
1073 DBG("Sco Disconnected");
1075 ERR("Not handled state - %s", state);
1080 } else if (strcasecmp(property, "SpeakerGain") == 0) {
1083 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1085 _bt_hal_convert_device_path_to_address(path, address);
1086 INFO("Speaker Gain for address [%s]", address);
1087 /* TODO Handle event sending to HAL */
1090 } else if (strcasecmp(property, "MicrophoneGain") == 0) {
1093 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1095 _bt_hal_convert_device_path_to_address(path, address);
1096 INFO("Microphone Gain for address [%s]", address);
1097 /* TODO Handle event sending to HAL */
1104 g_variant_unref(value);
1107 static int __bt_hal_register_manager_subscribe_signal(GDBusConnection *conn,
1113 static int subs_interface_added_id = -1;
1114 static int subs_interface_removed_id = -1;
1115 static int subs_name_owner_id = -1;
1116 static int subs_property_id = -1;
1117 static int subs_adapter_id = -1;
1122 if (subs_interface_added_id == -1) {
1123 subs_interface_added_id = g_dbus_connection_signal_subscribe(conn,
1124 NULL, BT_HAL_MANAGER_INTERFACE,
1125 BT_HAL_INTERFACES_ADDED, NULL, NULL, 0,
1126 __bt_hal_manager_event_filter,
1129 if (subs_interface_removed_id == -1) {
1130 subs_interface_removed_id = g_dbus_connection_signal_subscribe(conn,
1131 NULL, BT_HAL_MANAGER_INTERFACE,
1132 BT_HAL_INTERFACES_REMOVED, NULL, NULL, 0,
1133 __bt_hal_manager_event_filter,
1136 if (subs_name_owner_id == -1) {
1137 subs_name_owner_id = g_dbus_connection_signal_subscribe(conn,
1138 NULL, BT_HAL_FREEDESKTOP_INTERFACE,
1139 BT_HAL_NAME_OWNER_CHANGED, NULL, NULL, 0,
1140 __bt_hal_manager_event_filter,
1143 if (subs_property_id == -1) {
1144 subs_property_id = g_dbus_connection_signal_subscribe(conn,
1145 NULL, BT_HAL_PROPERTIES_INTERFACE,
1146 BT_HAL_PROPERTIES_CHANGED, NULL, NULL, 0,
1147 __bt_hal_manager_event_filter,
1150 if (subs_adapter_id == -1) {
1151 subs_adapter_id = g_dbus_connection_signal_subscribe(conn,
1152 NULL, BT_HAL_ADAPTER_INTERFACE,
1153 NULL, NULL, NULL, 0,
1154 __bt_hal_manager_event_filter,
1158 if (subs_interface_added_id != -1) {
1159 g_dbus_connection_signal_unsubscribe(conn,
1160 subs_interface_added_id);
1161 subs_interface_added_id = -1;
1163 if (subs_interface_removed_id != -1) {
1164 g_dbus_connection_signal_unsubscribe(conn,
1165 subs_interface_removed_id);
1166 subs_interface_removed_id = -1;
1168 if (subs_name_owner_id != -1) {
1169 g_dbus_connection_signal_unsubscribe(conn,
1170 subs_name_owner_id);
1171 subs_name_owner_id = -1;
1173 if (subs_property_id != -1) {
1174 g_dbus_connection_signal_unsubscribe(conn,
1176 subs_property_id = -1;
1178 if (subs_adapter_id == -1) {
1179 g_dbus_connection_signal_unsubscribe(conn, subs_adapter_id);
1180 subs_adapter_id = -1;
1188 static int __bt_hal_register_device_subscribe_signal(GDBusConnection *conn,
1191 static int subs_device_id = -1;
1198 if (subs_device_id == -1) {
1199 subs_device_id = g_dbus_connection_signal_subscribe(conn,
1200 NULL, BT_HAL_DEVICE_INTERFACE,
1201 NULL, NULL, NULL, 0,
1202 __bt_hal_manager_event_filter,
1206 if (subs_device_id != -1) {
1207 g_dbus_connection_signal_unsubscribe(conn,
1209 subs_device_id = -1;
1217 static int __bt_hal_register_input_subscribe_signal(GDBusConnection *conn, int subscribe)
1219 static int subs_input_id = -1;
1227 if (subs_input_id == -1) {
1228 subs_input_id = g_dbus_connection_signal_subscribe(conn,
1229 NULL, BT_HAL_INPUT_INTERFACE,
1230 NULL, NULL, NULL, 0,
1231 __bt_hal_manager_event_filter,
1235 if (subs_input_id != -1) {
1236 g_dbus_connection_signal_unsubscribe(conn,
1247 static int __bt_hal_register_service_event(GDBusConnection *g_conn, int event_type)
1252 return BT_HAL_ERROR_INTERNAL;
1254 /* TODO: Add more events in subsequent patches */
1255 switch (event_type) {
1256 case BT_HAL_MANAGER_EVENT:
1257 __bt_hal_register_manager_subscribe_signal(g_conn, TRUE);
1259 case BT_HAL_DEVICE_EVENT:
1260 __bt_hal_register_device_subscribe_signal(g_conn, TRUE);
1262 case BT_HAL_HID_EVENT:
1263 __bt_hal_register_input_subscribe_signal(g_conn, TRUE);
1265 case BT_HAL_HEADSET_EVENT:
1266 __bt_hal_register_audio_subscribe_signal(g_conn, TRUE);
1269 INFO_C("Register Event: event_type [%d]", event_type);
1270 return BT_HAL_ERROR_NOT_SUPPORT;
1273 return BT_HAL_ERROR_NONE;
1276 static int __bt_hal_register_audio_subscribe_signal(GDBusConnection *conn,
1282 static int subs_headset_id = -1;
1283 static int subs_sink_id = -1;
1286 if (subs_headset_id == -1) {
1287 subs_headset_id = g_dbus_connection_signal_subscribe(conn,
1288 NULL, BT_HAL_HEADSET_INTERFACE,
1289 NULL, NULL, NULL, 0,
1290 __bt_hal_manager_event_filter,
1293 if (subs_sink_id == -1) {
1294 subs_sink_id = g_dbus_connection_signal_subscribe(conn,
1295 NULL, BT_HAL_SINK_INTERFACE,
1296 NULL, NULL, NULL, 0,
1297 __bt_hal_manager_event_filter,
1301 if (subs_headset_id != -1) {
1302 g_dbus_connection_signal_unsubscribe(conn,
1304 subs_headset_id = -1;
1306 if (subs_sink_id != -1) {
1307 g_dbus_connection_signal_unsubscribe(conn,
1315 static int __bt_hal_initialize_manager_receiver(void)
1319 GError *error = NULL;
1321 if (manager_conn == NULL) {
1322 manager_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
1323 if (error != NULL) {
1324 ERR_C("ERROR: Can't get on system bus [%s]", error->message);
1325 g_clear_error(&error);
1327 if (manager_conn == NULL)
1331 if (__bt_hal_register_service_event(manager_conn,
1332 BT_HAL_MANAGER_EVENT) != BT_HAL_ERROR_NONE)
1334 if (__bt_hal_register_service_event(manager_conn,
1335 BT_HAL_DEVICE_EVENT) != BT_HAL_ERROR_NONE)
1337 if (__bt_hal_register_service_event(manager_conn,
1338 BT_HAL_HID_EVENT) != BT_HAL_ERROR_NONE)
1340 if (__bt_hal_register_service_event(manager_conn,
1341 BT_HAL_HEADSET_EVENT) != BT_HAL_ERROR_NONE)
1343 return BT_HAL_ERROR_NONE;
1346 g_object_unref(manager_conn);
1347 manager_conn = NULL;
1352 return BT_HAL_ERROR_INTERNAL;
1355 /* To receive the event from bluez */
1356 int _bt_hal_initialize_event_receiver(handle_stack_msg cb)
1362 return BT_HAL_ERROR_INVALID_PARAM;
1364 result = __bt_hal_initialize_manager_receiver();
1366 DBG("Manager event receiver initialization result [%d]", result);
1367 if (result != BT_HAL_ERROR_NONE)
1370 /*TODO: Initialize Obexd Event receiver */
1375 return BT_HAL_ERROR_NONE;
1378 static void __bt_hal_device_property_changed_event(GVariant *msg, const char *path)
1380 GVariantIter value_iter;
1381 GVariant *value = NULL;
1383 g_variant_iter_init(&value_iter, msg);
1386 while (g_variant_iter_loop(&value_iter, "{sv}", &key, &value)) {
1387 if (!g_strcmp0(key, "Connected")) {
1388 guint connected = 0;
1389 g_variant_get(value, "i", &connected);
1390 DBG("Device property changed : Connected [%d]", connected);
1391 } else if (!g_strcmp0(key, "RSSI")) {
1392 DBG("Device property changed : RSSI");
1393 __bt_hal_dbus_device_found_properties(path);
1394 } else if (!g_strcmp0(key, "GattConnected")) {
1395 DBG("Device property changed : GattConnected");
1396 gboolean gatt_connected = FALSE;
1397 g_variant_get(value, "b", &gatt_connected);
1398 char *address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1399 _bt_hal_convert_device_path_to_address(path, address);
1400 DBG("@@gatt_connected: %d", gatt_connected);
1401 DBG("@@address: %s", address);
1402 _bt_hal_gatt_connected_state_event(gatt_connected, address);
1404 } else if (!g_strcmp0(key, "Paired")) {
1405 gboolean paired = FALSE;
1406 struct hal_ev_bond_state_changed ev;
1407 char address[BT_HAL_ADDRESS_STRING_SIZE];
1409 g_variant_get(value, "b", &paired);
1410 DBG("Device property changed : Paired = %s", (paired ? "TRUE" : "FALSE"));
1412 _bt_hal_agent_set_canceled(FALSE);
1413 _bt_hal_convert_device_path_to_address(path, address);
1415 /* Prepare to send event to HAL bluetooth */
1416 ev.status = BT_STATUS_SUCCESS;
1417 ev.state = paired ? BT_BOND_STATE_BONDED : BT_BOND_STATE_NONE;
1418 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
1421 ERR("Bluetooth HAL event handler not registered");
1423 DBG("Sending HAL_EV_BOND_STATE_CHANGED event");
1424 event_cb(HAL_EV_BOND_STATE_CHANGED, (void*)&ev, sizeof(ev));
1426 } else if (!g_strcmp0(key, "LegacyPaired")) {
1427 DBG("Device property changed : LegacyPaired");
1428 } else if (!g_strcmp0(key, "Trusted")) {
1429 DBG("Device property changed : Trusted");
1430 gboolean trusted = FALSE;
1431 gchar *address = NULL;
1432 g_variant_get(value, "b", &trusted);
1433 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1435 _bt_hal_convert_device_path_to_address(path, address);
1436 DBG("Device [%s] trusted: [%d]", address, trusted);
1438 __bt_hal_send_device_trust_state_event(trusted, address);
1440 } else if (!g_strcmp0(key, "IpspConnected")) {
1441 DBG("Device property changed : IpspConnected");
1442 } else if (!g_strcmp0(key, "IpspInitStateChanged")) {
1443 DBG("Device property changed : IpspInitStateChanged");
1444 } else if (!g_strcmp0(key, "TrustedProfiles")) {
1446 char address[BT_HAL_ADDRESS_STRING_SIZE];
1448 g_variant_get(value, "u", &trust_val);
1449 _bt_hal_convert_device_path_to_address(path, address);
1450 DBG("Address: %s, TrustedProfiles: 0x%X", address, trust_val);
1451 __bt_hal_send_device_trusted_profile_changed_event(trust_val, address);
1453 ERR("Unhandled Property:[%s]", key);
1459 static void __bt_hal_dbus_device_found_properties(const char *device_path)
1462 GError *error = NULL;
1463 GDBusProxy *device_proxy;
1464 GDBusConnection *conn;
1469 ERR("Invalid device path");
1473 conn = _bt_hal_get_system_gconn();
1475 ERR("_bt_hal_get_system_gconn failed");
1479 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1483 BT_HAL_PROPERTIES_INTERFACE,
1486 if (!device_proxy) {
1487 ERR("Error creating device_proxy");
1491 result = g_dbus_proxy_call_sync(device_proxy,
1493 g_variant_new("(s)", BT_HAL_DEVICE_INTERFACE),
1494 G_DBUS_CALL_FLAGS_NONE,
1499 ERR("Error occured in Proxy call");
1500 if (error != NULL) {
1501 ERR("Error occured in Proxy call (Error: %s)", error->message);
1502 g_clear_error(&error);
1504 g_object_unref(device_proxy);
1508 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1509 _bt_hal_convert_device_path_to_address(device_path, address);
1511 __bt_hal_device_properties_lookup(result, address);
1513 g_object_unref(device_proxy);
1519 static void __bt_hal_device_properties_lookup(GVariant *result, char *address)
1521 /* Buffer and propety count management */
1522 uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
1523 struct hal_ev_device_found *ev = (void *) buf;
1525 memset(buf, 0, sizeof(buf));
1529 GVariant *tmp_value;
1532 gchar *manufacturer_data = NULL;
1535 if (result != NULL) {
1536 g_variant_get(result , "(@a{sv})", &value);
1537 g_variant_unref(result);
1540 tmp_value = g_variant_lookup_value(value, "Alias", G_VARIANT_TYPE_STRING);
1542 g_variant_get(tmp_value, "s", &name);
1544 g_variant_unref(tmp_value);
1546 DBG_SECURE("Alias Name [%s]", name);
1547 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_NAME,
1548 strlen(name) + 1, name);
1550 DBG("Device Name [%s] Property num [%d]", name, ev->num_props);
1553 tmp_value = g_variant_lookup_value(value, "Name", G_VARIANT_TYPE_STRING);
1554 g_variant_get(tmp_value, "s", &name);
1555 g_variant_unref(tmp_value);
1557 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_NAME,
1558 strlen(name) + 1, name);
1560 DBG("Device Name [%s] Property num [%d]", name, ev->num_props);
1561 g_variant_get(tmp_value, "s", &name);
1565 tmp_value = g_variant_lookup_value(value, "Class", G_VARIANT_TYPE_UINT32);
1566 unsigned int class = tmp_value ? g_variant_get_uint32(tmp_value) : 0;
1567 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_CLASS,
1568 sizeof(unsigned int), &class);
1570 g_variant_unref(tmp_value);
1574 tmp_value = g_variant_lookup_value(value, "Connected", G_VARIANT_TYPE_BOOLEAN);
1575 unsigned int connected = tmp_value ? g_variant_get_boolean(tmp_value) : 0;
1576 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_CONNECTED,
1577 sizeof(unsigned int), &connected);
1579 DBG("Device connected [%u] Property num [%d]", connected, ev->num_props);
1580 g_variant_unref(tmp_value);
1583 tmp_value = g_variant_lookup_value(value, "Trusted", G_VARIANT_TYPE_BOOLEAN);
1584 uint8_t trust = tmp_value ? (g_variant_get_boolean(tmp_value) ? 1 : 0) : 0;
1585 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_TRUSTED,
1586 sizeof(uint8_t), &trust);
1588 DBG("Device trusted [%d] Property num [%d]", trust, ev->num_props);
1589 g_variant_unref(tmp_value);
1592 tmp_value = g_variant_lookup_value(value, "Paired", G_VARIANT_TYPE_BOOLEAN);
1593 uint8_t paired = tmp_value ? (g_variant_get_boolean(tmp_value) ? 1 : 0) : 0;
1595 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_PAIRED,
1596 sizeof(uint8_t), &paired);
1598 DBG("Device Paired [%d] Property num [%d]", paired, ev->num_props);
1599 g_variant_unref(tmp_value);
1602 tmp_value = g_variant_lookup_value(value, "RSSI", G_VARIANT_TYPE_INT32);
1603 int rssi = tmp_value ? g_variant_get_int32(tmp_value) : 0;
1604 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_RSSI,
1605 sizeof(int), &rssi);
1607 DBG("Device RSSI [%d] Property num [%d]", rssi, ev->num_props);
1608 g_variant_unref(tmp_value);
1610 /* Last Addr Type */
1611 tmp_value = g_variant_lookup_value(value, "LastAddrType", G_VARIANT_TYPE_UINT32);
1612 unsigned int addr_type = tmp_value ? g_variant_get_uint32(tmp_value) : 0;
1613 g_variant_unref(tmp_value);
1614 DBG("Device Last Address Type [0x%x]", addr_type);
1617 tmp_value = g_variant_lookup_value(value, "IsAliasSet", G_VARIANT_TYPE_UINT32);
1618 uint8_t is_alias_set = tmp_value ? (g_variant_get_boolean(tmp_value) ? 1 : 0) : 0;
1619 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_IS_ALIAS_SET,
1620 sizeof(uint8_t), &is_alias_set);
1622 DBG("IsAliasSet: [%s], Property num [%d]", (is_alias_set ? "TRUE" : "FALSE"), ev->num_props);
1623 g_variant_unref(tmp_value);
1626 tmp_value = g_variant_lookup_value(value, "UUIDs", G_VARIANT_TYPE_STRING_ARRAY);
1627 gsize uuid_count = g_variant_get_size(tmp_value);
1628 char **uuid_value = g_variant_dup_strv(tmp_value, &uuid_count);
1630 /* UUID collection */
1635 int num_props_tmp = ev->num_props;
1637 uint8_t uuids[BT_HAL_STACK_UUID_SIZE * uuid_count];
1639 for (i = 0; uuid_value[i] != NULL; i++) {
1641 char *uuid_str = NULL;
1642 uint8_t uuid[BT_HAL_STACK_UUID_SIZE];
1643 memset(uuid, 0x00, BT_HAL_STACK_UUID_SIZE);
1645 DBG("UUID string from Bluez [%s]\n", uuid_value[i]);
1646 uuid_str = g_strdup(uuid_value[i]);
1647 DBG("UUID string [%s]\n", uuid_str);
1649 _bt_hal_convert_uuid_string_to_type(uuid, uuid_str);
1651 for (z = 0; z < 16; z++)
1652 DBG("[0x%x]", uuid[z]);
1655 memcpy(uuids+i*BT_HAL_STACK_UUID_SIZE, uuid, BT_HAL_STACK_UUID_SIZE);
1659 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_UUIDS,
1660 (BT_HAL_STACK_UUID_SIZE * uuid_count),
1662 ev->num_props = num_props_tmp + 1;
1665 g_variant_unref(tmp_value);
1667 /* ManufacturerDataLen */
1668 tmp_value = g_variant_lookup_value(value, "ManufacturerDataLen", G_VARIANT_TYPE_UINT32);
1669 unsigned int manufacturer_data_len = tmp_value ? g_variant_get_uint32(tmp_value) : 0;
1670 if (manufacturer_data_len > BT_HAL_MANUFACTURER_DATA_LENGTH_MAX) {
1671 ERR("manufacturer_data_len is too long(len = %d)", manufacturer_data_len);
1672 manufacturer_data_len = BT_HAL_MANUFACTURER_DATA_LENGTH_MAX;
1674 g_variant_unref(tmp_value);
1675 /*size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_MANUFACTURER_DATA_LEN,
1676 sizeof(unsigned int), &manufacturer_data_len);
1678 DBG("Device Manufacturer data length [%u]", manufacturer_data_len);
1680 /* ManufacturerData */
1681 tmp_value = g_variant_lookup_value(value, "ManufacturerData", G_VARIANT_TYPE_BYTESTRING);
1682 manufacturer_data = value ? (gchar *)g_variant_get_bytestring(tmp_value) : NULL;
1683 if (manufacturer_data) {
1684 if (manufacturer_data_len > 0) {
1685 //size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_MANUFACTURER_DATA,
1686 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_BLE_ADV_DATA,
1687 manufacturer_data_len, manufacturer_data);
1691 g_variant_unref(tmp_value);
1695 _bt_hal_convert_addr_string_to_type(bdaddr, address);
1696 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_ADDR,
1697 sizeof(bdaddr), bdaddr);
1699 DBG("Device address [%s] property Num [%d]", address, ev->num_props);
1702 g_variant_unref(value);
1704 ERR("result is NULL\n");
1707 DBG("Send Device found event to HAL user, Num Prop [%d] total size [%d]", ev->num_props, size);
1708 event_cb(HAL_EV_DEVICE_FOUND, (void*) buf, size);
1713 static void __bt_hal_send_device_acl_connection_state_event(gboolean connected, const char *address)
1716 struct hal_ev_acl_state_changed ev;
1718 ev.status = BT_STATUS_SUCCESS;
1719 ev.state = (connected == TRUE) ?
1720 HAL_ACL_STATE_CONNECTED :
1721 HAL_ACL_STATE_DISCONNECTED;
1723 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
1726 ERR("Bluetooth HAL event handler not registered");
1728 event_cb(HAL_EV_ACL_STATE_CHANGED, &ev, sizeof(ev));
1732 static void __bt_hal_send_device_le_connection_state_event(gboolean connected, const char *address)
1735 struct hal_ev_le_conn_state_changed ev;
1737 ev.status = BT_STATUS_SUCCESS;
1738 ev.state = (connected == TRUE) ?
1739 HAL_LE_STATE_CONNECTED :
1740 HAL_LE_STATE_DISCONNECTED;
1742 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
1745 ERR("Bluetooth HAL event handler not registered");
1747 event_cb(HAL_EV_LE_CONN_STATE_CHANGED, &ev, sizeof(ev));
1751 static void __bt_hal_send_device_trust_state_event(gboolean is_trusted,
1752 const char *address)
1754 struct hal_ev_device_trust_state_changed ev;
1757 ev.trust = (is_trusted == TRUE) ?
1758 HAL_DEVICE_TRUSTED :
1759 HAL_DEVICE_UNTRUSTED;
1761 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
1764 ERR("Bluetooth HAL event handler not registered");
1766 event_cb(HAL_EV_DEVICE_TRUST_CHANGED, &ev, sizeof(ev));
1770 static void __bt_hal_send_device_trusted_profile_changed_event(
1771 uint32_t trust_val, const char *address)
1773 struct hal_ev_device_trusted_profiles_changed ev;
1776 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
1777 ev.trust_val = trust_val;
1780 ERR("Bluetooth HAL event handler not registered");
1782 event_cb(HAL_EV_DEVICE_TRUSTED_PROFILES_CHANGED, &ev, sizeof(ev));
1786 static void __bt_hal_handle_device_specific_events(GVariant *msg, const char *member,
1790 const char *property = NULL;
1794 if (strcasecmp(member, "PropertyChanged") == 0) {
1795 g_variant_get(msg, "(s)", &property);
1796 if (property == NULL)
1798 if (strcasecmp(property, "GattConnected") == 0) {
1799 INFO("GATT Connected");
1800 gboolean connected = FALSE;
1802 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1804 _bt_hal_convert_device_path_to_address(path, address);
1805 g_variant_get(msg, "(b)", &connected);
1807 INFO("Connected device address[%s] connnected[%d]", address, connected);
1809 } else if (strcasecmp(property, "Paired") == 0) {
1810 gboolean paired = FALSE;
1811 struct hal_ev_bond_state_changed ev;
1812 char address[BT_HAL_ADDRESS_STRING_SIZE];
1814 g_variant_get(msg, "(b)", &paired);
1815 DBG("Device property changed : Paired = %s", (paired ? "TRUE" : "FALSE"));
1817 _bt_hal_agent_set_canceled(FALSE);
1818 _bt_hal_convert_device_path_to_address(path, address);
1820 /* Prepare to send event to HAL bluetooth */
1821 ev.status = BT_STATUS_SUCCESS;
1822 ev.state = paired ? BT_BOND_STATE_BONDED : BT_BOND_STATE_NONE;
1823 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
1826 ERR("Bluetooth HAL event handler not registered");
1828 DBG("Sending HAL_EV_BOND_STATE_CHANGED event");
1829 event_cb(HAL_EV_BOND_STATE_CHANGED, (void*)&ev, sizeof(ev));
1831 } else if (strcasecmp(property, "UUIDs") == 0) {
1834 } else if (strcasecmp(member, "DeviceConnected") == 0) {
1835 unsigned char addr_type = 0;
1837 g_variant_get(msg, "(y)", &addr_type);
1839 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1840 _bt_hal_convert_device_path_to_address(path, address);
1842 DBG("Member: [%s]", member);
1843 ERR_C("Connected [%s] [%s]", !addr_type ? "BREDR" : "LE", address);
1845 __bt_hal_send_device_acl_connection_state_event(TRUE, address);
1847 __bt_hal_send_device_le_connection_state_event(TRUE, address);
1849 } else if (strcasecmp(member, "Disconnected") == 0) {
1850 unsigned char disc_reason = 0;
1851 unsigned char addr_type = 0;
1854 g_variant_get(msg, "(yy&s)", &addr_type, &disc_reason, &name);
1856 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1857 _bt_hal_convert_device_path_to_address(path, address);
1859 DBG("Member: [%s]", member);
1860 ERR_C("DisConnected [%s] [%s]", !addr_type ? "BREDR" : "LE", address);
1861 DBG("Disconnect Reason: %d", disc_reason);
1862 DBG("Name: %s", name);
1864 __bt_hal_send_device_acl_connection_state_event(FALSE, address);
1866 __bt_hal_send_device_le_connection_state_event(FALSE, address);
1868 } else if (strcasecmp(member, "ProfileStateChanged") == 0) {
1870 char *profile_uuid = NULL;
1872 g_variant_get(msg, "(si)", &profile_uuid, &state);
1873 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1874 _bt_hal_convert_device_path_to_address(path, address);
1876 DBG("Address: %s", address);
1877 DBG("Profile UUID: %s", profile_uuid);
1878 DBG("State: %d", state);
1879 if (strncmp(profile_uuid, HID_UUID, strlen(HID_UUID)) == 0) {
1880 if (state == BT_HAL_PROFILE_STATE_CONNECTED)
1881 __bt_hal_send_hid_connection_state_event(TRUE, address);
1882 else if (state == BT_HAL_PROFILE_STATE_DISCONNECTED)
1883 __bt_hal_send_hid_connection_state_event(FALSE, address);
1885 DBG("Profile state: %d", state);
1887 } else if ((strncmp(profile_uuid, A2DP_SINK_UUID, strlen(A2DP_SINK_UUID)) == 0)) {
1888 if (state == BT_HAL_PROFILE_STATE_CONNECTED) {
1889 DBG("A2DP Profile state changed: BT_PROFILE_STATE_CONNECTED");
1890 __bt_hal_send_av_connection_state_event(TRUE, address);
1891 } else if (state == BT_HAL_PROFILE_STATE_DISCONNECTED) {
1892 DBG("A2DP Profile state changed: BT_PROFILE_STATE_DISCONNECTED");
1893 __bt_hal_send_av_connection_state_event(FALSE, address);
1894 } else if (state == BT_HAL_PROFILE_STATE_DISCONNECTING) {
1895 DBG("A2DP Profile state changed: BT_PROFILE_STATE_DISCONNECTING");
1896 } else if (state == BT_HAL_PROFILE_STATE_CONNECTING) {
1897 DBG("A2DP Profile state changed: BT_PROFILE_STATE_CONNECTING");
1899 ERR("A2DP Profile state: Invalid");
1901 } else if ((strncmp(profile_uuid, A2DP_SOURCE_UUID, strlen(A2DP_SOURCE_UUID)) == 0)) {
1902 if (state == BT_HAL_PROFILE_STATE_CONNECTED) {
1903 DBG("A2DP Sink Profile state changed: BT_HAL_PROFILE_STATE_CONNECTED");
1904 __bt_hal_send_a2dp_sink_connection_state_event(TRUE, address);
1905 } else if (state == BT_HAL_PROFILE_STATE_DISCONNECTED) {
1906 DBG("A2DP Sink Profile state changed: BT_HAL_PROFILE_STATE_DISCONNECTED");
1907 __bt_hal_send_a2dp_sink_connection_state_event(FALSE, address);
1908 } else if (state == BT_HAL_PROFILE_STATE_DISCONNECTING) {
1909 DBG("A2DP Sink Profile state changed: BT_HAL_PROFILE_STATE_DISCONNECTING");
1910 } else if (state == BT_HAL_PROFILE_STATE_CONNECTING) {
1911 DBG("A2DP Sink Profile state changed: BT_HAL_PROFILE_STATE_CONNECTING");
1913 } else if (strncmp(profile_uuid, HFP_HF_UUID, strlen(HFP_HF_UUID)) == 0) {
1914 if (state == BT_HAL_PROFILE_STATE_CONNECTING)
1915 DBG("HFP Profile state changed: BT_PROFILE_STATE_CONNECTING");
1916 else if (state == BT_HAL_PROFILE_STATE_CONNECTED) {
1917 DBG("HFP Profile state changed: BT_PROFILE_STATE_CONNECTED");
1918 __bt_hal_send_hf_connection_state_event(TRUE, address);
1919 } else if (state == BT_HAL_PROFILE_STATE_DISCONNECTED) {
1920 DBG("HFP Profile state changed: BT_PROFILE_STATE_DISCONNECTED");
1921 __bt_hal_send_hf_connection_state_event(FALSE, address);
1922 } else if (state == BT_HAL_PROFILE_STATE_DISCONNECTING) {
1923 DBG("HFP Profile state changed: BT_PROFILE_STATE_DISCONNECTING");
1925 ERR("HFP Profile state: Invalid");
1927 } else if ((strncmp(profile_uuid, AVRCP_TARGET_UUID, strlen(AVRCP_TARGET_UUID)) == 0)) {
1928 if (state == BT_HAL_PROFILE_STATE_CONNECTED) {
1929 DBG("AVRCP Controller Profile state changed: BT_HAL_PROFILE_STATE_CONNECTED");
1930 __bt_hal_send_avrcp_ctrl_connection_state_event(TRUE, address);
1931 } else if (state == BT_HAL_PROFILE_STATE_DISCONNECTED) {
1932 DBG("AVRCP Controller Profile state changed: BT_HAL_PROFILE_STATE_DISCONNECTED");
1933 __bt_hal_send_avrcp_ctrl_connection_state_event(FALSE, address);
1934 } else if (state == BT_HAL_PROFILE_STATE_DISCONNECTING) {
1935 DBG("AVRCP Controller Profile state changed: BT_HAL_PROFILE_STATE_DISCONNECTING");
1936 } else if (state == BT_HAL_PROFILE_STATE_CONNECTING) {
1937 DBG("AVRCP Controller Profile state changed: BT_HAL_PROFILE_STATE_CONNECTING");
1940 DBG("Profile[%s] State changed status [%d] ", profile_uuid, state);
1943 g_free(profile_uuid);
1944 } else if (strcasecmp(member, "AdvReport") == 0) {
1945 DBG("Member: [%s]", member);
1946 __bt_hal_handle_adv_report(msg, path);
1950 static void __bt_hal_handle_adv_report(GVariant *msg, const char *path)
1952 uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
1953 struct hal_ev_gatt_client_scan_result *ev = (void *)buf;
1955 char *address = NULL;
1956 GVariant *value = NULL;
1957 char *buffer = NULL;
1960 uint8_t addr_type = 0;
1961 uint8_t adv_type = 0;
1967 memset(buf, 0, sizeof(buf));
1970 g_variant_get(msg, "(&syyii@ay)", &address, &addr_type,
1971 &adv_type, &rssi, &data_len, &value);
1973 buffer_len = g_variant_get_size(value);
1975 buffer = (char *)g_variant_get_data(value);
1977 if (data_len != buffer_len) {
1978 ERR("Unexpected: buffer_len: %d, data_len: %d",
1979 buffer_len, data_len);
1980 data_len = buffer_len;
1983 DBG("Address: %s, len: %d, rssi: %d, addr_type: 0x%02X, adv_type: 0x%02X",
1984 address, data_len, rssi, addr_type, adv_type);
1986 _bt_hal_convert_addr_string_to_type(ev->bd_addr, address);
1987 ev->addr_type = addr_type;
1988 ev->adv_type = adv_type;
1991 memcpy(ev->adv_data, buffer, data_len);
1994 DBG("Send le scan result event to HAL, size: [%d]", size);
1995 gatt_event_cb(HAL_EV_GATT_CLIENT_SCAN_RESULT, buf, size);
1996 g_variant_unref(value);
1999 /* AVRCP Controller Role(Remote:AVRCP Target) Events */
2000 static void __bt_hal_send_avrcp_ctrl_connection_state_event(gboolean connected, const char *address)
2003 struct hal_ev_avrcp_ctrl_conn_state ev;
2005 if (connected == TRUE)
2006 INFO("AVRCP(Controller) Profile Connected for address [%s]", address);
2008 INFO("AVRCP(Controller) Profile DisConnected for address [%s]", address);
2010 if (connected == TRUE)
2011 ev.state = HAL_AVRCP_CTRL_STATE_CONNECTED;
2013 ev.state = HAL_AVRCP_CTRL_STATE_DISCONNECTED;
2014 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2016 if (!a2dp_sink_event_cb)
2017 ERR("AV event handler not registered");
2019 avrcp_ctrl_event_cb(HAL_EV_AVRCP_CTRL_CONN_STATE, &ev, sizeof(ev));
2022 static int __bt_media_attr_to_type(const char *str)
2024 if (!strcasecmp(str, "Equalizer"))
2025 return HAL_PLAYER_ATTR_EQUALIZER;
2026 else if (!strcasecmp(str, "Repeat"))
2027 return HAL_PLAYER_ATTR_REPEAT;
2028 else if (!strcasecmp(str, "Shuffle"))
2029 return HAL_PLAYER_ATTR_SHUFFLE;
2030 else if (!strcasecmp(str, "Scan"))
2031 return HAL_PLAYER_ATTR_SCAN;
2037 static int __bt_hal_play_status_str_to_type(const char *value)
2039 if (!strcmp(value, "stopped"))
2040 return HAL_PLAYSTATE_STOPPED;
2041 else if (!strcmp(value, "playing"))
2042 return HAL_PLAYSTATE_PLAYING;
2043 else if (!strcmp(value, "paused"))
2044 return HAL_PLAYSTATE_PAUSED;
2045 else if (!strcmp(value, "forward-seek"))
2046 return HAL_PLAYSTATE_FWD_SEEK;
2047 else if (!strcmp(value, "reverse-seek"))
2048 return HAL_PLAYSTATE_REV_SEEK;
2050 return HAL_PLAYSTATE_ERROR;
2053 static void __bt_avrcp_control_parse_properties(struct hal_ev_track_changed *ev, GVariant *item)
2055 GVariant *value = NULL;
2057 char *value_string = NULL;
2058 const char *key = NULL;
2064 g_variant_iter_init(&iter, item);
2065 while (g_variant_iter_loop(&iter, "{sv}", &key, &value)) {
2066 if (strcasecmp(key, "Title") == 0) {
2067 value_string = (char *)g_variant_get_string(value, NULL);
2068 DBG("Value : %s ", value_string);
2069 ev->attr[i].attr_id = HAL_MEDIA_ATTR_ID_TITLE;
2070 g_strlcpy((gchar *)ev->attr[i].text, value_string, HAL_MAX_ATTR_STR_LEN);
2072 } else if (strcasecmp(key, "Artist") == 0) {
2073 value_string = (char *)g_variant_get_string(value, NULL);
2074 DBG("Value : %s ", value_string);
2075 ev->attr[i].attr_id = HAL_MEDIA_ATTR_ID_ARTIST;
2076 g_strlcpy((gchar *)ev->attr[i].text, value_string, HAL_MAX_ATTR_STR_LEN);
2078 } else if (strcasecmp(key, "Album") == 0) {
2079 value_string = (char *)g_variant_get_string(value, NULL);
2080 DBG("Value : %s ", value_string);
2081 ev->attr[i].attr_id = HAL_MEDIA_ATTR_ID_ALBUM;
2082 g_strlcpy((gchar *)ev->attr[i].text, value_string, HAL_MAX_ATTR_STR_LEN);
2084 } else if (strcasecmp(key, "Genre") == 0) {
2085 value_string = (char *)g_variant_get_string(value, NULL);
2086 DBG("Value : %s ", value_string);
2087 ev->attr[i].attr_id = HAL_MEDIA_ATTR_ID_GENRE;
2088 g_strlcpy((gchar *)ev->attr[i].text, value_string, HAL_MAX_ATTR_STR_LEN);
2090 } else if (strcasecmp(key, "Duration") == 0) {
2093 val = g_variant_get_uint32(value);
2094 DBG("Value : %d", val);
2095 ev->attr[i].attr_id = HAL_MEDIA_ATTR_ID_PLAYING_TIME;
2096 snprintf((char*)ev->attr[i].text, HAL_MAX_ATTR_STR_LEN, "%ld", val);
2098 } else if (strcasecmp(key, "NumberOfTracks") == 0) {
2101 val = g_variant_get_uint32(value);
2102 DBG("Value : %d", val);
2103 ev->attr[i].attr_id = HAL_MEDIA_ATTR_ID_NUM_TRACKS;
2104 snprintf((char*)ev->attr[i].text, HAL_MAX_ATTR_STR_LEN, "%ld", val);
2106 } else if (strcasecmp(key, "TrackNumber") == 0) {
2109 val = g_variant_get_uint32(value);
2110 DBG("Value : %d", val);
2111 ev->attr[i].attr_id = HAL_MEDIA_ATTR_ID_TRACK_NUM;
2112 snprintf((char*)ev->attr[i].text, HAL_MAX_ATTR_STR_LEN, "%ld", val);
2115 DBG("%s not supported, ignoring", key);
2118 if (i >= HAL_MAX_ATTR_NUM) {
2119 ERR(" Received max attribute [%d]", i);
2125 g_variant_iter_free(&iter);
2129 static int __bt_media_attrval_to_val(int type, const char *value)
2134 case HAL_PLAYER_ATTR_EQUALIZER:
2135 if (!strcmp(value, "off"))
2140 case HAL_PLAYER_ATTR_REPEAT:
2141 if (!strcmp(value, "off"))
2142 ret = BTRC_PLAYER_VAL_OFF_REPEAT;
2143 else if (!strcmp(value, "singletrack"))
2144 ret = BTRC_PLAYER_VAL_SINGLE_REPEAT;
2145 else if (!strcmp(value, "alltracks"))
2146 ret = BTRC_PLAYER_VAL_ALL_REPEAT;
2148 ret = BTRC_PLAYER_VAL_GROUP_REPEAT;
2150 case HAL_PLAYER_ATTR_SHUFFLE:
2151 if (!strcmp(value, "off"))
2152 ret = BTRC_PLAYER_VAL_OFF_SHUFFLE;
2153 else if (!strcmp(value, "alltracks"))
2154 ret = BTRC_PLAYER_VAL_ALL_SHUFFLE;
2156 ret = BTRC_PLAYER_VAL_GROUP_SHUFFLE;
2158 case HAL_PLAYER_ATTR_SCAN:
2159 if (!strcmp(value, "off"))
2161 else if (!strcmp(value, "alltracks"))
2167 ERR("Value not handled");
2173 static void __bt_hal_handle_avrcp_ctrl_events(GVariant *msg, const char *member,
2176 const char *property = NULL;
2177 GVariant *value = NULL;
2179 char address[BT_HAL_ADDRESS_STRING_SIZE];
2182 ERR("Error returned in method call\n");
2186 if (!avrcp_ctrl_event_cb) {
2187 ERR("AVRCP controller DBUS handler callback not registered");
2191 g_variant_iter_init(&iter, msg);
2193 _bt_hal_convert_device_path_to_address(path, address);
2195 while (g_variant_iter_loop(&iter, "{sv}", &property, &value)) {
2196 DBG("Property = %s \n", property);
2197 if ((strcasecmp(property, "Equalizer") == 0) ||
2198 (strcasecmp(property, "Repeat") == 0) ||
2199 (strcasecmp(property, "Shuffle") == 0) ||
2200 (strcasecmp(property, "Scan") == 0)) {
2201 struct hal_ev_player_setting ev;
2205 valstr = g_variant_get_string(value, NULL);
2206 DBG("Value : %s ", valstr);
2209 val = __bt_media_attrval_to_val(__bt_media_attr_to_type(property), valstr);
2212 memset(&ev, 0, sizeof(ev));
2213 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2215 ev.attr_ids[0] = __bt_media_attr_to_type(property);
2216 ev.attr_values[0] = val;
2218 /* Send event to application */
2219 avrcp_ctrl_event_cb(HAL_EV_AVRCP_CTRL_PLAYER_APP_SETTING_CHANGED, &ev, sizeof(ev));
2221 } else if ((strcasecmp(property, "Status") == 0)) {
2222 struct hal_ev_play_status_changed ev;
2225 valstr = g_variant_get_string(value, NULL);
2226 DBG("Value : %s ", valstr);
2228 memset(&ev, 0, sizeof(ev));
2229 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2231 ev.status = __bt_hal_play_status_str_to_type(valstr);
2233 /* Send event to application */
2234 avrcp_ctrl_event_cb(HAL_EV_AVRCP_CTRL_PLAY_STATUS_CHANGED, &ev, sizeof(ev));
2236 } else if (strcasecmp(property, "Position") == 0) {
2237 struct hal_ev_play_position ev;
2239 memset(&ev, 0, sizeof(ev));
2240 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2241 ev.pos = g_variant_get_uint32(value);
2242 DBG("Value : %d ", ev.pos);
2244 /* Send event to application */
2245 avrcp_ctrl_event_cb(HAL_EV_AVRCP_CTRL_PLAY_POSITION_CHANGED, &ev, sizeof(ev));
2246 } else if (strcasecmp(property, "Track") == 0) {
2247 struct hal_ev_track_changed ev;
2249 memset(&ev, 0, sizeof(ev));
2250 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2251 __bt_avrcp_control_parse_properties(&ev, value);
2253 /* Send event to application */
2254 avrcp_ctrl_event_cb(HAL_EV_AVRCP_CTRL_TRACK_CHANGED, &ev, sizeof(ev));
2256 DBG("Property not handled");
2260 g_free((char *)property);
2261 g_variant_unref(value);
2264 static void __bt_hal_handle_avrcp_transport_events(GVariant *msg, const char *member,
2267 const char *property = NULL;
2268 GVariant *value = NULL;
2270 char address[BT_HAL_ADDRESS_STRING_SIZE];
2274 ERR("Error returned in method call\n");
2278 if (!avrcp_tg_event_cb) {
2279 ERR("AVRCP target DBUS handler callback not registered");
2283 g_variant_iter_init(&iter, msg);
2285 _bt_hal_convert_device_path_to_address(path, address);
2287 while (g_variant_iter_loop(&iter, "{sv}", &property, &value)) {
2288 DBG("Property = %s \n", property);
2289 if ((strcasecmp(property, "Delay") == 0)) {
2290 struct hal_ev_avrcp_tg_delay_changed ev;
2293 memset(&ev, 0, sizeof(ev));
2294 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2296 val = g_variant_get_uint16(value);
2297 DBG("Value : %d", val);
2300 /* Send event to application */
2301 avrcp_tg_event_cb(HAL_EV_AVRCP_TG_DELAY_CHANGE, &ev, sizeof(ev));
2303 DBG("Property not handled");
2308 g_free((char *)property);
2309 g_variant_unref(value);
2312 /* A2DP Src Role(Remote:Sink) Events */
2313 static void __bt_hal_send_av_connection_state_event(gboolean connected, const char *address)
2316 struct hal_ev_a2dp_conn_state ev;
2318 if (connected == TRUE)
2319 INFO("A2DP(Src) Profile Connected for address [%s]", address);
2321 INFO("A2DP(Src) Profile DisConnected for address [%s]", address);
2323 ev.state = (connected == TRUE) ?
2324 HAL_EV_A2DP_STATE_CONNECTED :
2325 HAL_EV_A2DP_STATE_DISCONNECTED;
2327 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2330 ERR("AV event handler not registered");
2332 av_event_cb(HAL_EV_A2DP_CONN_STATE, &ev, sizeof(ev));
2335 /* A2DP Sink Role(Remote:Source) Events */
2336 static void __bt_hal_send_a2dp_sink_connection_state_event(gboolean connected, const char *address)
2339 struct hal_ev_a2dp_conn_state ev;
2341 if (connected == TRUE)
2342 INFO("A2DP(Sink) Profile Connected for address [%s]", address);
2344 INFO("A2DP(Sink) Profile DisConnected for address [%s]", address);
2346 ev.state = (connected == TRUE) ?
2347 HAL_EV_A2DP_STATE_CONNECTED :
2348 HAL_EV_A2DP_STATE_DISCONNECTED;
2350 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2352 if (!a2dp_sink_event_cb)
2353 ERR("AV event handler not registered");
2355 a2dp_sink_event_cb(HAL_EV_A2DP_SOURCE_CONN_STATE, &ev, sizeof(ev));
2358 /* HF(AG Role) Audio Events */
2359 static void __bt_hal_send_hf_audio_connection_state_event(gboolean connected,
2360 const char *address)
2363 struct hal_ev_handsfree_audio_state ev;
2365 if (connected == TRUE)
2366 INFO("AG Audio Connected for address [%s]", address);
2368 INFO("AG Audio DisConnected for address [%s]", address);
2370 ev.state = (connected == TRUE) ?
2371 HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTED :
2372 HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED;
2374 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2377 ERR("HF event handler not registered");
2379 hf_event_cb(HAL_EV_HANDSFREE_AUDIO_STATE, &ev, sizeof(ev));
2382 /* HF(AG Role) Profile Events */
2383 static void __bt_hal_send_hf_connection_state_event(gboolean connected,
2384 const char *address)
2387 struct hal_ev_handsfree_conn_state ev;
2389 if (connected == TRUE)
2390 INFO("AG Profile Connected for address [%s]", address);
2392 INFO("AG Profile DisConnected for address [%s]", address);
2394 ev.state = (connected == TRUE) ?
2395 HAL_EV_HANDSFREE_CONN_STATE_CONNECTED :
2396 HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED;
2398 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2401 ERR("HF event handler not registered");
2403 hf_event_cb(HAL_EV_HANDSFREE_CONN_STATE, &ev, sizeof(ev));
2406 void _bt_hal_register_event_handler_cb(bt_hal_module_e module, handle_stack_msg cb)
2416 a2dp_sink_event_cb = cb;
2422 avrcp_tg_event_cb = cb;
2424 case HAL_AVRCP_CTRL:
2425 avrcp_ctrl_event_cb = cb;
2431 ERR("Unknown module: %d", module);
2435 void _bt_hal_unregister_event_handler_cb(bt_hal_module_e module)
2439 hid_event_cb = NULL;
2445 a2dp_sink_event_cb = NULL;
2451 avrcp_tg_event_cb = NULL;
2453 case HAL_AVRCP_CTRL:
2454 avrcp_ctrl_event_cb = NULL;
2457 gatt_event_cb = NULL;
2460 ERR("Unknown module: %d", module);
2464 bool _bt_hal_get_adapter_request_state(void)
2466 return is_adapter_activating;
2469 bool _bt_hal_get_le_request_state(void)
2471 return is_le_activating;
2474 void _bt_hal_set_adapter_request_state(bool enable)
2476 DBG("set_adapter_request_state %d", enable);
2477 is_adapter_activating = enable;
2480 void _bt_hal_set_le_request_state(bool enable)
2482 DBG("set_le_request_state %d", enable);
2483 is_le_activating = enable;