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);
104 static void __bt_hal_send_device_trust_state_event(gboolean is_trusted, const char *address);
105 static int __bt_hal_register_audio_subscribe_signal(GDBusConnection *conn, int subscribe);
106 static void __bt_hal_handle_headset_events(GVariant *msg, const char *member, const char *path);
107 static void __bt_hal_send_hf_audio_connection_state_event(gboolean connected, const char *address);
108 static void __bt_hal_send_hf_connection_state_event(gboolean connected, const char *address);
109 static void __bt_hal_send_device_trusted_profile_changed_event(uint32_t trust_val, const char *address);
110 static void __bt_hal_handle_adv_report(GVariant *msg, const char *path);
112 static gboolean __bt_hal_discovery_finished_cb(gpointer user_data)
116 struct hal_ev_discovery_state_changed ev;
117 ev.state = HAL_DISCOVERY_STATE_STOPPED;
118 event_cb(HAL_EV_DISCOVERY_STATE_CHANGED, &ev, sizeof(ev));
124 static int __bt_hal_parse_event(GVariant *msg)
128 char *interface_name = NULL;
129 GVariant *inner_iter = NULL;
131 g_variant_iter_init(&iter, msg);
133 while ((child = g_variant_iter_next_value(&iter))) {
134 g_variant_get(child, "{&s@a{sv}}", &interface_name, &inner_iter);
135 if (g_strcmp0(interface_name,
136 BT_HAL_DEVICE_INTERFACE) == 0) {
137 DBG("__bt_hal_parse_event: Interface: BT_HAL_DEVICE_INTERFACE");
138 g_variant_unref(inner_iter);
139 g_variant_unref(child);
140 return BT_HAL_DEVICE_EVENT;
141 } else if (g_strcmp0(interface_name,
142 BT_HAL_MEDIATRANSPORT_INTERFACE) == 0) {
143 DBG("__bt_hal_parse_event: Interface: BT_HAL_MEDIATRANSPORT_INTERFACE");
144 g_variant_unref(inner_iter);
145 g_variant_unref(child);
146 return BT_HAL_MEDIA_TRANSFER_EVENT;
147 } else if (g_strcmp0(interface_name,
148 BT_HAL_PLAYER_CONTROL_INTERFACE) == 0) {
149 DBG("__bt_hal_parse_event: Interface: BT_HAL_PLAYER_CONTROL_INTERFACE");
150 g_variant_unref(inner_iter);
151 g_variant_unref(child);
152 return BT_HAL_AVRCP_CONTROL_EVENT;
154 g_variant_unref(inner_iter);
155 g_variant_unref(child);
161 static int __bt_hal_get_owner_info(GVariant *msg, char **name, char **previous, char **current)
163 g_variant_get(msg, "(sss)", name, previous, current);
164 return BT_HAL_ERROR_NONE;
167 int __bt_insert_hal_properties(void *buf, uint8_t type, uint16_t len, const void *val)
168 { struct hal_property *prop = buf;
174 memcpy(prop->val, val, len);
176 return sizeof(*prop) + len;
179 handle_stack_msg _bt_hal_get_stack_message_handler(void)
184 static void __bt_hal_adapter_property_changed_event(GVariant *msg)
186 GVariantIter value_iter;
187 GVariant *value = NULL;
188 GDBusProxy *adapter_proxy;
191 g_variant_iter_init(&value_iter, msg);
193 /* Buffer and propety count management */
194 uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
195 struct hal_ev_adapter_props_changed *ev = (void*) buf;
197 const gchar *address = NULL;
199 unsigned int cod = 0;
200 gboolean discoverable;
201 gboolean connectable;
202 unsigned int scan_mode = BT_SCAN_MODE_NONE;
203 unsigned int disc_timeout;
204 const gchar *version;
205 const gboolean ipsp_initialized;
208 unsigned int pairable_timeout;
209 gboolean scan_mode_property_update = FALSE;
210 gboolean is_discovering;
211 gboolean is_le_discovering;
213 memset(buf, 0, sizeof(buf));
216 ev->status = BT_STATUS_SUCCESS;
220 while (g_variant_iter_loop(&value_iter, "{sv}", &key, &value)) {
221 if (!g_strcmp0(key, "Address")) {
224 address = g_variant_get_string(value, NULL);
225 DBG("##Address [%s]", address);
226 _bt_hal_convert_addr_string_to_type(bdaddr, address);
227 size += __bt_insert_hal_properties(buf + size,
228 HAL_PROP_ADAPTER_ADDR, sizeof(bdaddr), bdaddr);
230 } else if (!g_strcmp0(key, "Alias")) {
231 g_variant_get(value, "&s", &name);
232 DBG("##Alias [%s] ", name);
233 size += __bt_insert_hal_properties(buf + size,
234 HAL_PROP_ADAPTER_NAME, strlen(name) + 1, name);
236 } else if (!g_strcmp0(key, "Class")) {
237 cod = g_variant_get_uint32(value);
238 DBG("##Class [%d]", cod);
239 size += __bt_insert_hal_properties(buf + size,
240 HAL_PROP_ADAPTER_CLASS, sizeof(unsigned int), &cod);
242 } else if (!g_strcmp0(key, "Discoverable")) {
243 discoverable = g_variant_get_boolean(value);
244 DBG("##Discoverable [%d]", discoverable);
246 scan_mode = BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE;
248 scan_mode = BT_SCAN_MODE_CONNECTABLE;
249 scan_mode_property_update = TRUE;
250 } else if (!g_strcmp0(key, "DiscoverableTimeout")) {
251 disc_timeout = g_variant_get_uint32(value);
252 DBG("##Discoverable Timeout [%d]", disc_timeout);
253 size += __bt_insert_hal_properties(buf + size,
254 HAL_PROP_ADAPTER_DISC_TIMEOUT, sizeof(unsigned int), &disc_timeout);
256 } else if (!g_strcmp0(key, "Connectable")) {
257 connectable = g_variant_get_boolean(value);
258 DBG("##Connectable [%d]", connectable);
260 scan_mode = BT_SCAN_MODE_NONE;
261 else if (scan_mode == BT_SCAN_MODE_NONE)
262 scan_mode = BT_SCAN_MODE_CONNECTABLE;
263 scan_mode_property_update = TRUE;
264 } else if (!g_strcmp0(key, "Version")) {
265 version = g_variant_get_string(value, NULL);
266 DBG("##Version [%s]", version);
267 size += __bt_insert_hal_properties(buf + size,
268 HAL_PROP_ADAPTER_VERSION, strlen(version) + 1, version);
270 } else if (!g_strcmp0(key, "Name")) {
271 g_variant_get(value, "&s", &name);
272 DBG("##Name [%s]", name);
273 size += __bt_insert_hal_properties(buf + size,
274 HAL_PROP_ADAPTER_NAME, strlen(name) + 1, name);
276 } else if (!g_strcmp0(key, "Powered")) {
277 powered = g_variant_get_boolean(value);
278 DBG("##Powered = %d", powered);
279 /* TODO: Need to check this operation!! */
280 if (powered == FALSE) {
281 DBG("###### Adapter Powered Down ######");
282 struct hal_ev_adapter_state_changed ev;
283 ev.state = HAL_POWER_OFF;
284 event_cb(HAL_EV_ADAPTER_STATE_CHANGED, &ev, sizeof(ev));
286 struct hal_ev_le_state_changed le_ev;
287 le_ev.state = HAL_POWER_OFF;
288 event_cb(HAL_EV_LE_STATE_CHANGED, &le_ev, sizeof(le_ev));
291 _bt_hal_destroy_adapter_agent();
293 DBG("###### Adapter Powered Up ######");
294 if (_bt_hal_get_adapter_request_state()) {
295 DBG("Sending STATE CHANGE EVENT for Adapter... ");
296 _bt_hal_set_adapter_request_state(FALSE);
297 struct hal_ev_adapter_state_changed ev;
298 ev.state = HAL_POWER_ON;
299 event_cb(HAL_EV_ADAPTER_STATE_CHANGED, &ev, sizeof(ev));
302 if (_bt_hal_get_le_request_state()) {
303 DBG("Sending STATE CHANGE EVENT for LE... ");
304 _bt_hal_set_le_request_state(FALSE);
305 struct hal_ev_le_state_changed ev;
306 ev.state = HAL_POWER_ON;
307 event_cb(HAL_EV_LE_STATE_CHANGED, &ev, sizeof(ev));
311 _bt_hal_initialize_adapter_agent();
314 } else if (!g_strcmp0(key, "Pairable")) {
315 pairable = g_variant_get_boolean(value);
316 DBG("##Pairable [%d]", pairable);
317 } else if (!g_strcmp0(key, "PairableTimeout")) {
318 pairable_timeout = g_variant_get_uint32(value);
319 DBG("##Pairable Timeout = %d", pairable_timeout);
320 } else if (!g_strcmp0(key, "UUIDs")) {
325 size1 = g_variant_get_size(value);
326 int num_props_tmp = ev->num_props;
328 uuid_value = (char **)g_variant_get_strv(value, &size1);
329 for (i = 0; uuid_value[i] != NULL; i++)
331 /* UUID collection */
332 uint8_t uuids[BT_HAL_STACK_UUID_SIZE * uuid_count];
333 for (i = 0; uuid_value[i] != NULL; i++) {
334 char *uuid_str = NULL;
335 uint8_t uuid[BT_HAL_STACK_UUID_SIZE];
336 uuid_str = g_strdup(uuid_value[i]);
337 DBG("##UUID string [%s]\n", uuid_str);
338 _bt_hal_convert_uuid_string_to_type(uuid, uuid_str);
339 memcpy(uuids+i*BT_HAL_STACK_UUID_SIZE, uuid, BT_HAL_STACK_UUID_SIZE);
342 size += __bt_insert_hal_properties(buf + size, HAL_PROP_ADAPTER_UUIDS,
343 (BT_HAL_STACK_UUID_SIZE * uuid_count),
345 ev->num_props = num_props_tmp + 1;
348 } else if (!g_strcmp0(key, "Discovering")) {
349 is_discovering = g_variant_get_boolean(value);
350 DBG("##Discovering = [%d]", is_discovering);
352 if (is_discovering == FALSE) {
353 DBG("###### Adapter Has stopped Discovering ######");
354 /* In Tizen Bluez, this actually does not mean Discovery is stopped
355 in Bluez. Tizen Bluez sends this event after a certain timeout,
356 Therefore, we must forecefully call StopDiscovery to stop discovery in BlueZ */
360 adapter_proxy = _bt_hal_get_adapter_proxy();
362 if (adapter_proxy == NULL)
365 /* Need to stop searching */
366 DBG("Event though Bluez reported DIscovering stopped, we force stop Discovery ");
367 g_dbus_proxy_call_sync(adapter_proxy, "StopDiscovery",
369 G_DBUS_CALL_FLAGS_NONE,
373 ERR("Dbus Error : %s", err->message);
375 /* This error is thrown by Bluez, as Discovery is already stopped.
376 Discovery is stopped if user cancels on going discovery.
377 In order to maintain correct state of Bluetooth Discovery state,
378 simply send Discovery stopped event to HAL user */
379 struct hal_ev_discovery_state_changed ev;
380 ev.state = HAL_DISCOVERY_STATE_STOPPED;
381 event_cb(HAL_EV_DISCOVERY_STATE_CHANGED, &ev, sizeof(ev));
386 event_id = g_timeout_add(BT_HAL_DISCOVERY_FINISHED_DELAY,
387 (GSourceFunc)__bt_hal_discovery_finished_cb, NULL);
391 DBG("###### Adapter Has started Discovering ######");
392 struct hal_ev_discovery_state_changed ev;
393 ev.state = HAL_DISCOVERY_STATE_STARTED;
394 event_cb(HAL_EV_DISCOVERY_STATE_CHANGED, &ev, sizeof(ev));
397 } else if (!g_strcmp0(key, "LEDiscovering")) {
400 is_le_discovering = g_variant_get_boolean(value);
401 DBG("##LE Discovering = [%d]", is_le_discovering);
403 if (is_le_discovering)
406 adapter_proxy = _bt_hal_get_adapter_proxy();
407 if (adapter_proxy == NULL) {
408 ERR("adapter_proxy == NULL");
412 /* Need to stop searching */
413 result = g_dbus_proxy_call_sync(adapter_proxy, "StopLEDiscovery",
414 NULL, G_DBUS_CALL_FLAGS_NONE,
415 DBUS_TIMEOUT, NULL, &err);
417 ERR("Error occured in Proxy call");
419 ERR("(Error: %s)", err->message);
424 g_variant_unref(result);
425 } else if (!g_strcmp0(key, "Modalias")) {
426 char *modalias = NULL;
427 g_variant_get(value, "s", &modalias);
428 DBG("##Adapter ModAlias [%s]", modalias);
429 } else if (!g_strcmp0(key, "SupportedLEFeatures")) {
430 DBG("##LE Supported features");
433 GVariantIter *iter = NULL;
434 g_variant_get(value, "as", &iter);
439 while (g_variant_iter_next(iter, "&s", &name) &&
440 g_variant_iter_next(iter, "&s", &val)) {
441 DBG("name = %s, Value = %s", name, val);
442 if (FALSE == _bt_hal_update_le_feature_support(name, val))
443 ERR("Failed to update LE feature (name = %s, value = %s)", name, val);
446 g_variant_iter_free(iter);
447 } else if (!g_strcmp0(key, "IpspInitStateChanged")) {
448 g_variant_get(value, "b" , &ipsp_initialized);
449 DBG("##IPSP Initialized = %d", ipsp_initialized);
451 ERR("Unhandled Property:[%s]", key);
455 if (scan_mode_property_update) {
456 size += __bt_insert_hal_properties(buf + size,
457 HAL_PROP_ADAPTER_SCAN_MODE, sizeof(int), &scan_mode);
463 DBG("Send Adapter properties changed event to HAL user, Num Prop [%d] total size [%d]", ev->num_props, size);
464 event_cb(HAL_EV_ADAPTER_PROPS_CHANGED, buf, size);
466 g_variant_unref(value);
470 void _bt_hal_handle_adapter_event(GVariant *msg, const char *member)
477 if (strcasecmp(member, "DeviceCreated") == 0) {
478 DBG("DeviceCreated: Unhandled");
479 } else if (strcasecmp(member, "InterfacesRemoved") == 0) {
480 DBG("InterfacesRemoved: Unhandled");
481 } else if (strcasecmp(member, "AdvertisingEnabled") == 0) {
482 DBG("AdvertisingEnabled");
483 DBG("Advertising Enabled");
485 gboolean status = FALSE;
486 g_variant_get(msg, "(ib)", &slot_id, &status);
487 DBG("Advertising Enabled : slot_id [%d] status [%d]", slot_id, status);
488 /* Send event to application */
489 _bt_hal_set_advertising_status(slot_id, status);
490 } else if (strcasecmp(member, "RssiEnabled") == 0) {
491 struct hal_ev_rssi_monitor_state_changed ev;
492 gboolean status = FALSE;
493 char *address = NULL;
496 g_variant_get(msg, "(sib)", &address, &link_type, &status);
497 DBG("RSSI monitoring %s for %s",
498 (status ? "Enabled" : "Disabled"), address);
500 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
501 ev.link_type = link_type;
502 ev.state = (status ? HAL_RSSI_MONITORING_ENABLED : HAL_RSSI_MONITORING_DISABLED);
504 ERR("event_cb is NULL");
506 event_cb(HAL_EV_RSSI_MONITOR_STATE_CHANGED, &ev, sizeof(ev));
509 } else if (strcasecmp(member, "RssiAlert") == 0) {
510 struct hal_ev_rssi_alert_recieved ev;
514 char *address = NULL;
516 g_variant_get(msg, "(siii)", &address, &link_type, &alert_type, &rssi_dbm);
517 DBG("RSSI Alert: [Address %s LinkType %d] [Type %d DBM %d]",
518 address, alert_type, rssi_dbm);
520 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
521 ev.link_type = link_type;
522 ev.alert_type = alert_type;
526 ERR("event_cb is NULL");
528 event_cb(HAL_EV_RSSI_ALERT_RECIEVED, &ev, sizeof(ev));
531 } else if (strcasecmp(member, "RawRssi") == 0) {
532 struct hal_ev_raw_rssi_recieved ev;
535 char *address = NULL;
537 g_variant_get(msg, "(sii)", &address, &link_type, &rssi_dbm);
538 DBG("Raw RSSI: [Address %s] [Link Type %d][RSSI DBM %d]",
539 address, link_type, rssi_dbm);
541 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
542 ev.link_type = link_type;
546 ERR("event_cb is NULL");
548 event_cb(HAL_EV_RAW_RSSI_RECIEVED, &ev, sizeof(ev));
551 } else if (strcasecmp(member, BT_HAL_HARDWARE_ERROR) == 0) {
552 DBG("BT Hardware Error: Unhandled");
553 } else if (strcasecmp(member, BT_HAL_TX_TIMEOUT_ERROR) == 0) {
554 DBG("BT TX Timeout Error: Unhandled");
560 static gboolean __bt_hal_parse_device_properties(GVariant *item)
570 /* Buffer and propety count management */
571 uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
572 struct hal_ev_device_found *ev = (void *) buf;
574 memset(buf, 0, sizeof(buf));
578 g_variant_iter_init(&iter, item);
579 while (g_variant_iter_loop(&iter, "{sv}", &key, &val)) {
581 if (strcasecmp(key, "Address") == 0) {
583 char * address = NULL;
584 address = g_variant_dup_string(val, &len);
586 _bt_hal_convert_addr_string_to_type(bdaddr, address);
588 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_ADDR,
589 sizeof(bdaddr), bdaddr);
592 DBG("Device address [%s] property Num [%d]", address, ev->num_props);
594 } else if (strcasecmp(key, "Class") == 0) {
595 unsigned int class = g_variant_get_uint32(val);
596 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_CLASS,
597 sizeof(unsigned int), &class);
599 DBG("Device class [%d] Property num [%d]", class, ev->num_props);
600 } else if (strcasecmp(key, "name") == 0) {
601 char *name = g_variant_dup_string(val, &len);
603 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_NAME,
604 strlen(name) + 1, name);
606 DBG("Device Name [%s] Property num [%d]", name, ev->num_props);
608 } else if (strcasecmp(key, "Connected") == 0) {
609 unsigned int connected = g_variant_get_uint32(val);
611 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_CONNECTED,
612 sizeof(unsigned int), &connected);
614 DBG("Device connected [%u] Property num [%d]", connected, ev->num_props);
615 } else if (strcasecmp(key, "paired") == 0) {
616 uint8_t paired = (g_variant_get_boolean(val) ? 1 : 0);
617 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_PAIRED,
618 sizeof(uint8_t), &paired);
620 DBG("Device Paired [%d] Property num [%d]", paired, ev->num_props);
621 } else if (strcasecmp(key, "Trusted") == 0) {
622 uint8_t trust = (g_variant_get_boolean(val) ? 1 : 0);
623 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_TRUSTED,
624 sizeof(uint8_t), &trust);
626 DBG("Device trusted [%d] Property num [%d]", trust, ev->num_props);
627 } else if (strcasecmp(key, "RSSI") == 0) {
628 int rssi = g_variant_get_int16(val);
629 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_RSSI,
632 DBG("Device RSSI [%d] Property num [%d]", rssi, ev->num_props);
633 } else if (strcasecmp(key, "LastAddrType") == 0) {
634 /* TODO: To be handled later*/
635 } else if (!g_strcmp0(key, "IsAliasSet")) {
636 uint8_t is_alias_set = (g_variant_get_boolean(val) ? 1 : 0);
637 DBG("IsAliasSet: %s", (is_alias_set ? "TRUE" : "FALSE"));
638 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_IS_ALIAS_SET,
639 sizeof(uint8_t), &is_alias_set);
641 } else if (strcasecmp(key, "UUIDs") == 0) {
646 size1 = g_variant_get_size(val);
647 DBG("UUID count from size [%d]\n", size1);
648 int num_props_tmp = ev->num_props;
651 uuid_value = (char **)g_variant_get_strv(val, &size1);
652 for (i = 0; uuid_value[i] != NULL; i++)
654 DBG("UUID count [%d]\n", uuid_count);
655 /* UUID collection */
656 uint8_t uuids[BT_HAL_STACK_UUID_SIZE * uuid_count];
658 for (i = 0; uuid_value[i] != NULL; i++) {
660 char *uuid_str = NULL;
661 uint8_t uuid[BT_HAL_STACK_UUID_SIZE];
662 memset(uuid, 0x00, BT_HAL_STACK_UUID_SIZE);
664 DBG("UUID string from Bluez [%s]\n", uuid_value[i]);
665 uuid_str = g_strdup(uuid_value[i]);
666 DBG("UUID string [%s]\n", uuid_str);
667 _bt_hal_convert_uuid_string_to_type(uuid, uuid_str);
668 memcpy(uuids+i*BT_HAL_STACK_UUID_SIZE, uuid, BT_HAL_STACK_UUID_SIZE);
672 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_UUIDS,
673 (BT_HAL_STACK_UUID_SIZE * uuid_count),
675 ev->num_props = num_props_tmp + 1;
679 } else if (strcasecmp(key, "ManufacturerDataLen") == 0) {
680 /* TODO: To be handled later*/
681 } else if (strcasecmp(key, "ManufacturerData") == 0) {
682 /* TODO: To be handled later*/
684 ERR("Unhandled Property:[%s]", key);
690 DBG("Send Device found event to HAL user, Num Prop [%d] total size [%d]", ev->num_props, size);
691 event_cb(HAL_EV_DEVICE_FOUND, (void*) buf, size);
697 static void __bt_hal_handle_avrcp_tg_events(GVariant *msg, const char *path)
700 GVariantIter value_iter;
701 char *property = NULL;
703 GVariant *val = NULL;
704 GVariant *child = NULL;
706 g_variant_iter_init(&value_iter, msg);
707 while ((child = g_variant_iter_next_value(&value_iter))) {
708 g_variant_get(child, "{sv}", &property, &val);
709 INFO("Property %s", property);
710 if (strcasecmp(property, "Connected") == 0) {
711 struct hal_ev_avrcp_tg_conn_state ev;
713 gboolean connected = FALSE;
715 g_variant_get(val, "b", &connected);
717 state = connected ? HAL_AVRCP_TG_STATE_CONNECTED :
718 HAL_AVRCP_TG_STATE_DISCONNECTED;
720 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
722 _bt_hal_convert_device_path_to_address(path, address);
724 DBG("connected: %d", connected);
725 DBG("address: %s", address);
727 /* Prepare to send AVRCP Target connection state event */
728 memset(&ev, 0, sizeof(ev));
729 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
731 if (!avrcp_tg_event_cb)
732 ERR("AVRCP target DBUS handler callback not registered");
734 avrcp_tg_event_cb(HAL_EV_AVRCP_TG_CONN_STATE, (void *)&ev, sizeof(ev));
738 g_variant_unref(child);
739 g_variant_unref(val);
745 static void __bt_hal_handle_property_changed_event(GVariant *msg, const char *object_path)
747 char *interface_name = NULL;
748 GVariant *val = NULL;
750 g_variant_get(msg, "(&s@a{sv}@as)", &interface_name, &val, NULL);
752 if (strcasecmp(interface_name, BT_HAL_ADAPTER_INTERFACE) == 0) {
753 DBG("Event: Property Changed: Interface: BT_HAL_ADAPTER_INTERFACE");
754 __bt_hal_adapter_property_changed_event(val);
755 } else if (strcasecmp(interface_name, BT_HAL_DEVICE_INTERFACE) == 0) {
756 DBG("Event: Property Changed: Interface: BT_HAL_DEVICE_INTERFACE");
757 __bt_hal_device_property_changed_event(val, object_path);
758 } else if (strcasecmp(interface_name, BT_HAL_OBEX_TRANSFER_INTERFACE) == 0) {
759 DBG("Event: Property Changed: Interface: BT_HAL_OBEX_TRANSFER_INTERFACE");
760 /* TODO: Handle event */
761 } else if (strcasecmp(interface_name, BT_HAL_MEDIA_CONTROL_INTERFACE) == 0) {
762 DBG("Event: Property Changed: Interface: BT_HAL_MEDIA_CONTROL_INTERFACE");
763 /* Handle AVRCP target event */
764 __bt_hal_handle_avrcp_tg_events(val, object_path);
765 } else if (strcasecmp(interface_name, BT_HAL_PLAYER_CONTROL_INTERFACE) == 0) {
766 DBG("Event: Property Changed: Interface: BT_HAL_PLAYER_CONTROL_INTERFACE");
767 __bt_hal_handle_avrcp_ctrl_events(val, NULL, object_path);
768 } else if (strcasecmp(interface_name, BT_HAL_NETWORK_CLIENT_INTERFACE) == 0) {
769 DBG("Event: Property Changed: Interface: BT_HAL_NETWORK_CLIENT_INTERFACE");
770 /* TODO: Handle event */
771 } else if (strcasecmp(interface_name, BT_HAL_GATT_CHAR_INTERFACE) == 0) {
772 DBG("Event: Property Changed: Interface: BT_HAL_GATT_CHAR_INTERFACE");
773 /* TODO: Handle event */
774 } else if (strcasecmp(interface_name, BT_HAL_INPUT_INTERFACE) == 0) {
775 DBG("Event: Property Changed: Interface: BT_HAL_INPUT_INTERFACE");
776 __bt_hal_handle_input_event(val, object_path);
778 g_variant_unref(val);
781 static void __bt_hal_handle_device_event(GVariant *value, GVariant *parameters)
785 if (__bt_hal_parse_interface(parameters) == FALSE) {
786 ERR("Fail to parse the properies");
787 g_variant_unref(value);
794 static void __bt_hal_send_hid_connection_state_event(
795 gboolean connected, char *address)
797 struct hal_ev_hidhost_conn_state ev;
799 ev.state = (connected == TRUE) ?
800 HAL_HIDHOST_STATE_CONNECTED :
801 HAL_HIDHOST_STATE_DISCONNECTED;
803 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
806 ERR("HID event handler not registered");
808 hid_event_cb(HAL_EV_HIDHOST_CONN_STATE, &ev, sizeof(ev));
811 static void __bt_hal_handle_input_event(GVariant *msg, const char *path)
813 gboolean property_flag = FALSE;
814 GVariantIter value_iter;
815 char *property = NULL;
816 GVariant *child = NULL, *val = NULL;
819 g_variant_iter_init(&value_iter, msg);
820 while ((child = g_variant_iter_next_value(&value_iter))) {
821 g_variant_get(child, "{sv}", &property, &val);
823 if (property == NULL)
826 if (strcasecmp(property, "Connected") == 0) {
829 g_variant_get(val, "b", &property_flag);
830 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
831 _bt_hal_convert_device_path_to_address(path, address);
832 __bt_hal_send_hid_connection_state_event(property_flag, address);
836 g_variant_unref(val);
837 g_variant_unref(child);
843 static gboolean __bt_hal_parse_interface(GVariant *msg)
846 GVariant *optional_param;
849 char *interface_name = NULL;
850 GVariant *inner_iter = NULL;
851 g_variant_get(msg, "(&o@a{sa{sv}})",
852 &path, &optional_param);
853 g_variant_iter_init(&iter, optional_param);
855 while ((child = g_variant_iter_next_value(&iter))) {
856 g_variant_get(child, "{&s@a{sv}}", &interface_name, &inner_iter);
857 if (g_strcmp0(interface_name, BT_HAL_DEVICE_INTERFACE) == 0) {
858 DBG("Found a device: %s", path);
859 if (__bt_hal_parse_device_properties(inner_iter) == FALSE) {
860 g_variant_unref(inner_iter);
861 g_variant_unref(child);
862 g_variant_unref(optional_param);
863 ERR("Fail to parse the properies");
866 g_variant_unref(inner_iter);
867 g_variant_unref(child);
868 g_variant_unref(optional_param);
872 g_variant_unref(inner_iter);
873 g_variant_unref(child);
876 g_variant_unref(optional_param);
881 static gboolean __bt_hal_event_manager(gpointer data)
883 bt_hal_event_type_t bt_event = 0x00;
885 char *obj_path = NULL;
887 bt_hal_main_event_data_t *param = (bt_hal_main_event_data_t*)data;
888 if (strcasecmp(param->signal_name, "InterfacesAdded") == 0) {
890 /*TODO: Handle Interfaces Added Signal from stack */
891 DBG("Manager Event: Signal Name: InterfacesAdded");
893 g_variant_get(param->parameters, "(&o@a{sa{sv}})", &obj_path, &value);
895 if (strcasecmp(obj_path, BT_HAL_BLUEZ_HCI_PATH) == 0) {
896 /* TODO: Handle adapter added */
897 DBG("Manager Event: Signal Name: InterfiacesAdded: Adapter added in bluetoothd: path [hci0]");
899 bt_event = __bt_hal_parse_event(value);
900 if (bt_event == BT_HAL_DEVICE_EVENT) {
901 DBG("Device path : %s ", obj_path);
902 __bt_hal_handle_device_event(value, param->parameters);
903 } else if (bt_event == BT_HAL_AVRCP_CONTROL_EVENT) {
904 DBG("Device path : %s ", obj_path);
905 _bt_hal_set_control_device_path(obj_path);
908 g_variant_unref(value);
910 } else if (strcasecmp(param->signal_name, "InterfacesRemoved") == 0) {
914 /*TODO: Handle Interfaces Removed Signal from stack */
915 DBG("Manager Event: Signal Name: InterfacesRemoved");
917 g_variant_get(param->parameters, "(&oas)", &obj_path, &iter);
918 DBG("Device path : %s ", obj_path);
919 while (g_variant_iter_loop(iter, "s", &str)) {
920 if (g_strcmp0(str, BT_HAL_PLAYER_CONTROL_INTERFACE) == 0)
921 _bt_hal_remove_control_device_path(obj_path);
923 g_variant_iter_free(iter);
924 } else if (strcasecmp(param->signal_name, "NameOwnerChanged") == 0) {
926 char *previous = NULL;
927 char *current = NULL;
929 /* TODO: Handle Name Owener changed Signal */
930 if (__bt_hal_get_owner_info(param->parameters, &name, &previous, ¤t)) {
931 DBG("Fail to get the owner info");
934 if (current && *current != '\0') {
940 if (strcasecmp(name, BT_HAL_BLUEZ_NAME) == 0) {
941 DBG("Bluetoothd is terminated");
943 /* TODO: Handle Bluetoothd terminating scenario */
946 INFO("Name Owner changed [%s]", name);
951 } else if (g_strcmp0(param->interface_name, BT_HAL_PROPERTIES_INTERFACE) == 0) {
952 __bt_hal_handle_property_changed_event(param->parameters, param->object_path);
953 } else if (g_strcmp0(param->interface_name, BT_HAL_ADAPTER_INTERFACE) == 0) {
954 DBG("Manager Event: Interface Name: BT_HAL_ADAPTER_INTERFACE");
955 _bt_hal_handle_adapter_event(param->parameters, param->signal_name);
956 } else if (g_strcmp0(param->interface_name, BT_HAL_INPUT_INTERFACE) == 0) {
957 DBG("Manager Event: Interface Name: BT_HAL_INPUT_INTERFACE");
958 __bt_hal_handle_input_event(param->parameters, param->object_path);
959 } else if (g_strcmp0(param->interface_name, BT_HAL_NETWORK_SERVER_INTERFACE) == 0) {
960 /* TODO: Handle Network Server events from stack */
961 DBG("Manager Event: Interface Name: BT_HAL_NETWORK_SERVER_INTERFACE");
962 } else if (g_strcmp0(param->interface_name, BT_HAL_HEADSET_INTERFACE) == 0) {
963 DBG("Manager Event: Interface Name: BT_HAL_HEADSET_INTERFACE");
964 __bt_hal_handle_headset_events(param->parameters, param->signal_name, param->object_path);
965 } else if (g_strcmp0(param->interface_name, BT_HAL_SINK_INTERFACE) == 0) {
966 /* TODO: Handle Sink interface events from stack */
967 DBG("Manager Event: Interface Name:BT_HAL_SINK_INTERFACE");
968 } else if (g_strcmp0(param->interface_name, BT_HAL_AGENT_INTERFACE) == 0) {
969 /* TODO: Handle Agent events from stack */
970 DBG("Manager Event: Interface Name:BT_HAL_AGENT_INTERFACE");
971 } else if (g_strcmp0(param->interface_name, BT_HAL_DEVICE_INTERFACE) == 0) {
972 DBG("Manager Event: Interface Name:BT_HAL_DEVICE_INTERFACE");
973 __bt_hal_handle_device_specific_events(param->parameters, param->signal_name, param->object_path);
974 } else if (g_strcmp0(param->interface_name, BT_HAL_PLAYER_CONTROL_INTERFACE) == 0) {
975 DBG("Manager Event: Interface Name: BT_HAL_PLAYER_CONTROL_INTERFACE");
976 __bt_hal_handle_avrcp_ctrl_events(param->parameters, param->signal_name, param->object_path);
980 g_free(param->sender_name);
981 g_free(param->object_path);
982 g_free(param->interface_name);
983 g_free(param->signal_name);
984 g_variant_unref(param->parameters);
989 static void __bt_hal_manager_event_filter(GDBusConnection *connection,
990 const gchar *sender_name,
991 const gchar *object_path,
992 const gchar *interface_name,
993 const gchar *signal_name,
994 GVariant *parameters,
997 if (signal_name == NULL)
1000 bt_hal_main_event_data_t *param = g_new0(bt_hal_main_event_data_t, 1);
1001 param->sender_name = g_strdup(sender_name);
1002 param->object_path = g_strdup(object_path);
1003 param->interface_name = g_strdup(interface_name);
1004 param->signal_name = g_strdup(signal_name);
1005 param->parameters = g_variant_ref(parameters);
1007 g_idle_add(__bt_hal_event_manager, (gpointer)param);
1011 static void __bt_hal_handle_headset_events(GVariant *msg, const char *member, const char *path)
1013 gboolean property_flag = FALSE;
1014 char *property = NULL;
1015 GVariant *value = NULL;
1016 g_variant_get(msg, "(sv)", &property, &value);
1018 if (property == NULL)
1021 DBG("Property = %s \n", property);
1022 /* We allow only 1 headset connection (HSP or HFP)*/
1023 if (strcasecmp(property, "Connected") == 0) {
1025 g_variant_get(value, "b", &property_flag);
1027 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1029 /* Fix : NULL_RETURNS */
1030 if (address == NULL)
1033 _bt_hal_convert_device_path_to_address(path, address);
1034 __bt_hal_send_hf_audio_connection_state_event(property_flag, address);
1036 } else if (strcasecmp(property, "State") == 0) {
1039 g_variant_get(value, "s", &state);
1041 /* This code assumes we support only 1 headset connection */
1042 /* Need to use the headset list, if we support multi-headsets */
1043 if (strcasecmp(state, "Playing") == 0) {
1044 DBG("Playing: Sco Connected");
1045 } else if (strcasecmp(state, "connected") == 0 ||
1046 strcasecmp(state, "disconnected") == 0) {
1047 if (strcasecmp(state, "connected") == 0)
1048 DBG("Sco Connected");
1050 DBG("Sco Disconnected");
1052 ERR("Not handled state - %s", state);
1057 } else if (strcasecmp(property, "SpeakerGain") == 0) {
1060 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1062 _bt_hal_convert_device_path_to_address(path, address);
1063 INFO("Speaker Gain for address [%s]", address);
1064 /* TODO Handle event sending to HAL */
1067 } else if (strcasecmp(property, "MicrophoneGain") == 0) {
1070 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1072 _bt_hal_convert_device_path_to_address(path, address);
1073 INFO("Microphone Gain for address [%s]", address);
1074 /* TODO Handle event sending to HAL */
1081 g_variant_unref(value);
1084 static int __bt_hal_register_manager_subscribe_signal(GDBusConnection *conn,
1090 static int subs_interface_added_id = -1;
1091 static int subs_interface_removed_id = -1;
1092 static int subs_name_owner_id = -1;
1093 static int subs_property_id = -1;
1094 static int subs_adapter_id = -1;
1099 if (subs_interface_added_id == -1) {
1100 subs_interface_added_id = g_dbus_connection_signal_subscribe(conn,
1101 NULL, BT_HAL_MANAGER_INTERFACE,
1102 BT_HAL_INTERFACES_ADDED, NULL, NULL, 0,
1103 __bt_hal_manager_event_filter,
1106 if (subs_interface_removed_id == -1) {
1107 subs_interface_removed_id = g_dbus_connection_signal_subscribe(conn,
1108 NULL, BT_HAL_MANAGER_INTERFACE,
1109 BT_HAL_INTERFACES_REMOVED, NULL, NULL, 0,
1110 __bt_hal_manager_event_filter,
1113 if (subs_name_owner_id == -1) {
1114 subs_name_owner_id = g_dbus_connection_signal_subscribe(conn,
1115 NULL, BT_HAL_FREEDESKTOP_INTERFACE,
1116 BT_HAL_NAME_OWNER_CHANGED, NULL, NULL, 0,
1117 __bt_hal_manager_event_filter,
1120 if (subs_property_id == -1) {
1121 subs_property_id = g_dbus_connection_signal_subscribe(conn,
1122 NULL, BT_HAL_PROPERTIES_INTERFACE,
1123 BT_HAL_PROPERTIES_CHANGED, NULL, NULL, 0,
1124 __bt_hal_manager_event_filter,
1127 if (subs_adapter_id == -1) {
1128 subs_adapter_id = g_dbus_connection_signal_subscribe(conn,
1129 NULL, BT_HAL_ADAPTER_INTERFACE,
1130 NULL, NULL, NULL, 0,
1131 __bt_hal_manager_event_filter,
1135 if (subs_interface_added_id != -1) {
1136 g_dbus_connection_signal_unsubscribe(conn,
1137 subs_interface_added_id);
1138 subs_interface_added_id = -1;
1140 if (subs_interface_removed_id != -1) {
1141 g_dbus_connection_signal_unsubscribe(conn,
1142 subs_interface_removed_id);
1143 subs_interface_removed_id = -1;
1145 if (subs_name_owner_id != -1) {
1146 g_dbus_connection_signal_unsubscribe(conn,
1147 subs_name_owner_id);
1148 subs_name_owner_id = -1;
1150 if (subs_property_id != -1) {
1151 g_dbus_connection_signal_unsubscribe(conn,
1153 subs_property_id = -1;
1155 if (subs_adapter_id == -1) {
1156 g_dbus_connection_signal_unsubscribe(conn, subs_adapter_id);
1157 subs_adapter_id = -1;
1165 static int __bt_hal_register_device_subscribe_signal(GDBusConnection *conn,
1168 static int subs_device_id = -1;
1175 if (subs_device_id == -1) {
1176 subs_device_id = g_dbus_connection_signal_subscribe(conn,
1177 NULL, BT_HAL_DEVICE_INTERFACE,
1178 NULL, NULL, NULL, 0,
1179 __bt_hal_manager_event_filter,
1183 if (subs_device_id != -1) {
1184 g_dbus_connection_signal_unsubscribe(conn,
1186 subs_device_id = -1;
1194 static int __bt_hal_register_input_subscribe_signal(GDBusConnection *conn, int subscribe)
1196 static int subs_input_id = -1;
1204 if (subs_input_id == -1) {
1205 subs_input_id = g_dbus_connection_signal_subscribe(conn,
1206 NULL, BT_HAL_INPUT_INTERFACE,
1207 NULL, NULL, NULL, 0,
1208 __bt_hal_manager_event_filter,
1212 if (subs_input_id != -1) {
1213 g_dbus_connection_signal_unsubscribe(conn,
1224 static int __bt_hal_register_service_event(GDBusConnection *g_conn, int event_type)
1229 return BT_HAL_ERROR_INTERNAL;
1231 /* TODO: Add more events in subsequent patches */
1232 switch (event_type) {
1233 case BT_HAL_MANAGER_EVENT:
1234 __bt_hal_register_manager_subscribe_signal(g_conn, TRUE);
1236 case BT_HAL_DEVICE_EVENT:
1237 __bt_hal_register_device_subscribe_signal(g_conn, TRUE);
1239 case BT_HAL_HID_EVENT:
1240 __bt_hal_register_input_subscribe_signal(g_conn, TRUE);
1242 case BT_HAL_HEADSET_EVENT:
1243 __bt_hal_register_audio_subscribe_signal(g_conn, TRUE);
1246 INFO_C("Register Event: event_type [%d]", event_type);
1247 return BT_HAL_ERROR_NOT_SUPPORT;
1250 return BT_HAL_ERROR_NONE;
1253 static int __bt_hal_register_audio_subscribe_signal(GDBusConnection *conn,
1259 static int subs_headset_id = -1;
1260 static int subs_sink_id = -1;
1263 if (subs_headset_id == -1) {
1264 subs_headset_id = g_dbus_connection_signal_subscribe(conn,
1265 NULL, BT_HAL_HEADSET_INTERFACE,
1266 NULL, NULL, NULL, 0,
1267 __bt_hal_manager_event_filter,
1270 if (subs_sink_id == -1) {
1271 subs_sink_id = g_dbus_connection_signal_subscribe(conn,
1272 NULL, BT_HAL_SINK_INTERFACE,
1273 NULL, NULL, NULL, 0,
1274 __bt_hal_manager_event_filter,
1278 if (subs_headset_id != -1) {
1279 g_dbus_connection_signal_unsubscribe(conn,
1281 subs_headset_id = -1;
1283 if (subs_sink_id != -1) {
1284 g_dbus_connection_signal_unsubscribe(conn,
1292 static int __bt_hal_initialize_manager_receiver(void)
1296 GError *error = NULL;
1298 if (manager_conn == NULL) {
1299 manager_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
1300 if (error != NULL) {
1301 ERR_C("ERROR: Can't get on system bus [%s]", error->message);
1302 g_clear_error(&error);
1304 if (manager_conn == NULL)
1308 if (__bt_hal_register_service_event(manager_conn,
1309 BT_HAL_MANAGER_EVENT) != BT_HAL_ERROR_NONE)
1311 if (__bt_hal_register_service_event(manager_conn,
1312 BT_HAL_DEVICE_EVENT) != BT_HAL_ERROR_NONE)
1314 if (__bt_hal_register_service_event(manager_conn,
1315 BT_HAL_HID_EVENT) != BT_HAL_ERROR_NONE)
1317 if (__bt_hal_register_service_event(manager_conn,
1318 BT_HAL_HEADSET_EVENT) != BT_HAL_ERROR_NONE)
1320 return BT_HAL_ERROR_NONE;
1323 g_object_unref(manager_conn);
1324 manager_conn = NULL;
1329 return BT_HAL_ERROR_INTERNAL;
1332 /* To receive the event from bluez */
1333 int _bt_hal_initialize_event_receiver(handle_stack_msg cb)
1339 return BT_HAL_ERROR_INVALID_PARAM;
1341 result = __bt_hal_initialize_manager_receiver();
1343 DBG("Manager event receiver initialization result [%d]", result);
1344 if (result != BT_HAL_ERROR_NONE)
1347 /*TODO: Initialize Obexd Event receiver */
1352 return BT_HAL_ERROR_NONE;
1355 static void __bt_hal_device_property_changed_event(GVariant *msg, const char *path)
1357 GVariantIter value_iter;
1358 GVariant *value = NULL;
1360 g_variant_iter_init(&value_iter, msg);
1363 while (g_variant_iter_loop(&value_iter, "{sv}", &key, &value)) {
1364 if (!g_strcmp0(key, "Connected")) {
1365 guint connected = 0;
1366 g_variant_get(value, "i", &connected);
1367 DBG("Device property changed : Connected [%d]", connected);
1368 } else if (!g_strcmp0(key, "RSSI")) {
1369 DBG("Device property changed : RSSI");
1370 __bt_hal_dbus_device_found_properties(path);
1371 } else if (!g_strcmp0(key, "GattConnected")) {
1372 DBG("Device property changed : GattConnected");
1373 gboolean gatt_connected = FALSE;
1374 g_variant_get(value, "b", &gatt_connected);
1375 char *address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1376 _bt_hal_convert_device_path_to_address(path, address);
1377 DBG("@@gatt_connected: %d", gatt_connected);
1378 DBG("@@address: %s", address);
1379 _bt_hal_gatt_connected_state_event(gatt_connected, address);
1381 } else if (!g_strcmp0(key, "Paired")) {
1382 gboolean paired = FALSE;
1383 struct hal_ev_bond_state_changed ev;
1384 char address[BT_HAL_ADDRESS_STRING_SIZE];
1386 g_variant_get(value, "b", &paired);
1387 DBG("Device property changed : Paired = %s", (paired ? "TRUE" : "FALSE"));
1389 _bt_hal_agent_set_canceled(FALSE);
1390 _bt_hal_convert_device_path_to_address(path, address);
1392 /* Prepare to send event to HAL bluetooth */
1393 ev.status = BT_STATUS_SUCCESS;
1394 ev.state = paired ? BT_BOND_STATE_BONDED : BT_BOND_STATE_NONE;
1395 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
1398 ERR("Bluetooth HAL event handler not registered");
1400 DBG("Sending HAL_EV_BOND_STATE_CHANGED event");
1401 event_cb(HAL_EV_BOND_STATE_CHANGED, (void*)&ev, sizeof(ev));
1403 } else if (!g_strcmp0(key, "LegacyPaired")) {
1404 DBG("Device property changed : LegacyPaired");
1405 } else if (!g_strcmp0(key, "Trusted")) {
1406 DBG("Device property changed : Trusted");
1407 gboolean trusted = FALSE;
1408 gchar *address = NULL;
1409 g_variant_get(value, "b", &trusted);
1410 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1412 _bt_hal_convert_device_path_to_address(path, address);
1413 DBG("Device [%s] trusted: [%d]", address, trusted);
1415 __bt_hal_send_device_trust_state_event(trusted, address);
1417 } else if (!g_strcmp0(key, "IpspConnected")) {
1418 DBG("Device property changed : IpspConnected");
1419 } else if (!g_strcmp0(key, "IpspInitStateChanged")) {
1420 DBG("Device property changed : IpspInitStateChanged");
1421 } else if (!g_strcmp0(key, "TrustedProfiles")) {
1423 char address[BT_HAL_ADDRESS_STRING_SIZE];
1425 g_variant_get(value, "u", &trust_val);
1426 _bt_hal_convert_device_path_to_address(path, address);
1427 DBG("Address: %s, TrustedProfiles: 0x%X", address, trust_val);
1428 __bt_hal_send_device_trusted_profile_changed_event(trust_val, address);
1430 ERR("Unhandled Property:[%s]", key);
1436 static void __bt_hal_dbus_device_found_properties(const char *device_path)
1439 GError *error = NULL;
1440 GDBusProxy *device_proxy;
1441 GDBusConnection *conn;
1446 ERR("Invalid device path");
1450 conn = _bt_hal_get_system_gconn();
1452 ERR("_bt_hal_get_system_gconn failed");
1456 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1460 BT_HAL_PROPERTIES_INTERFACE,
1463 if (!device_proxy) {
1464 ERR("Error creating device_proxy");
1468 result = g_dbus_proxy_call_sync(device_proxy,
1470 g_variant_new("(s)", BT_HAL_DEVICE_INTERFACE),
1471 G_DBUS_CALL_FLAGS_NONE,
1476 ERR("Error occured in Proxy call");
1477 if (error != NULL) {
1478 ERR("Error occured in Proxy call (Error: %s)", error->message);
1479 g_clear_error(&error);
1481 g_object_unref(device_proxy);
1485 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1486 _bt_hal_convert_device_path_to_address(device_path, address);
1488 __bt_hal_device_properties_lookup(result, address);
1490 g_object_unref(device_proxy);
1496 static void __bt_hal_device_properties_lookup(GVariant *result, char *address)
1498 /* Buffer and propety count management */
1499 uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
1500 struct hal_ev_device_found *ev = (void *) buf;
1502 memset(buf, 0, sizeof(buf));
1506 GVariant *tmp_value;
1509 gchar *manufacturer_data = NULL;
1512 if (result != NULL) {
1513 g_variant_get(result , "(@a{sv})", &value);
1514 g_variant_unref(result);
1517 tmp_value = g_variant_lookup_value(value, "Alias", G_VARIANT_TYPE_STRING);
1519 g_variant_get(tmp_value, "s", &name);
1521 g_variant_unref(tmp_value);
1523 DBG_SECURE("Alias Name [%s]", name);
1524 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_NAME,
1525 strlen(name) + 1, name);
1527 DBG("Device Name [%s] Property num [%d]", name, ev->num_props);
1530 tmp_value = g_variant_lookup_value(value, "Name", G_VARIANT_TYPE_STRING);
1531 g_variant_get(tmp_value, "s", &name);
1532 g_variant_unref(tmp_value);
1534 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_NAME,
1535 strlen(name) + 1, name);
1537 DBG("Device Name [%s] Property num [%d]", name, ev->num_props);
1538 g_variant_get(tmp_value, "s", &name);
1542 tmp_value = g_variant_lookup_value(value, "Class", G_VARIANT_TYPE_UINT32);
1543 unsigned int class = tmp_value ? g_variant_get_uint32(tmp_value) : 0;
1544 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_CLASS,
1545 sizeof(unsigned int), &class);
1547 g_variant_unref(tmp_value);
1551 tmp_value = g_variant_lookup_value(value, "Connected", G_VARIANT_TYPE_BOOLEAN);
1552 unsigned int connected = tmp_value ? g_variant_get_boolean(tmp_value) : 0;
1553 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_CONNECTED,
1554 sizeof(unsigned int), &connected);
1556 DBG("Device connected [%u] Property num [%d]", connected, ev->num_props);
1557 g_variant_unref(tmp_value);
1560 tmp_value = g_variant_lookup_value(value, "Trusted", G_VARIANT_TYPE_BOOLEAN);
1561 uint8_t trust = tmp_value ? (g_variant_get_boolean(tmp_value) ? 1 : 0) : 0;
1562 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_TRUSTED,
1563 sizeof(uint8_t), &trust);
1565 DBG("Device trusted [%d] Property num [%d]", trust, ev->num_props);
1566 g_variant_unref(tmp_value);
1569 tmp_value = g_variant_lookup_value(value, "Paired", G_VARIANT_TYPE_BOOLEAN);
1570 uint8_t paired = tmp_value ? (g_variant_get_boolean(tmp_value) ? 1 : 0) : 0;
1572 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_PAIRED,
1573 sizeof(uint8_t), &paired);
1575 DBG("Device Paired [%d] Property num [%d]", paired, ev->num_props);
1576 g_variant_unref(tmp_value);
1579 tmp_value = g_variant_lookup_value(value, "RSSI", G_VARIANT_TYPE_INT32);
1580 int rssi = tmp_value ? g_variant_get_int32(tmp_value) : 0;
1581 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_RSSI,
1582 sizeof(int), &rssi);
1584 DBG("Device RSSI [%d] Property num [%d]", rssi, ev->num_props);
1585 g_variant_unref(tmp_value);
1587 /* Last Addr Type */
1588 tmp_value = g_variant_lookup_value(value, "LastAddrType", G_VARIANT_TYPE_UINT32);
1589 unsigned int addr_type = tmp_value ? g_variant_get_uint32(tmp_value) : 0;
1590 g_variant_unref(tmp_value);
1591 DBG("Device Last Address Type [0x%x]", addr_type);
1594 tmp_value = g_variant_lookup_value(value, "IsAliasSet", G_VARIANT_TYPE_UINT32);
1595 uint8_t is_alias_set = tmp_value ? (g_variant_get_boolean(tmp_value) ? 1 : 0) : 0;
1596 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_IS_ALIAS_SET,
1597 sizeof(uint8_t), &is_alias_set);
1599 DBG("IsAliasSet: [%s], Property num [%d]", (is_alias_set ? "TRUE" : "FALSE"), ev->num_props);
1600 g_variant_unref(tmp_value);
1603 tmp_value = g_variant_lookup_value(value, "UUIDs", G_VARIANT_TYPE_STRING_ARRAY);
1604 gsize uuid_count = g_variant_get_size(tmp_value);
1605 char **uuid_value = g_variant_dup_strv(tmp_value, &uuid_count);
1607 /* UUID collection */
1612 int num_props_tmp = ev->num_props;
1614 uint8_t uuids[BT_HAL_STACK_UUID_SIZE * uuid_count];
1616 for (i = 0; uuid_value[i] != NULL; i++) {
1618 char *uuid_str = NULL;
1619 uint8_t uuid[BT_HAL_STACK_UUID_SIZE];
1620 memset(uuid, 0x00, BT_HAL_STACK_UUID_SIZE);
1622 DBG("UUID string from Bluez [%s]\n", uuid_value[i]);
1623 uuid_str = g_strdup(uuid_value[i]);
1624 DBG("UUID string [%s]\n", uuid_str);
1626 _bt_hal_convert_uuid_string_to_type(uuid, uuid_str);
1628 for (z = 0; z < 16; z++)
1629 DBG("[0x%x]", uuid[z]);
1632 memcpy(uuids+i*BT_HAL_STACK_UUID_SIZE, uuid, BT_HAL_STACK_UUID_SIZE);
1636 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_UUIDS,
1637 (BT_HAL_STACK_UUID_SIZE * uuid_count),
1639 ev->num_props = num_props_tmp + 1;
1642 g_variant_unref(tmp_value);
1644 /* ManufacturerDataLen */
1645 tmp_value = g_variant_lookup_value(value, "ManufacturerDataLen", G_VARIANT_TYPE_UINT32);
1646 unsigned int manufacturer_data_len = tmp_value ? g_variant_get_uint32(tmp_value) : 0;
1647 if (manufacturer_data_len > BT_HAL_MANUFACTURER_DATA_LENGTH_MAX) {
1648 ERR("manufacturer_data_len is too long(len = %d)", manufacturer_data_len);
1649 manufacturer_data_len = BT_HAL_MANUFACTURER_DATA_LENGTH_MAX;
1651 g_variant_unref(tmp_value);
1652 /*size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_MANUFACTURER_DATA_LEN,
1653 sizeof(unsigned int), &manufacturer_data_len);
1655 DBG("Device Manufacturer data length [%u]", manufacturer_data_len);
1657 /* ManufacturerData */
1658 tmp_value = g_variant_lookup_value(value, "ManufacturerData", G_VARIANT_TYPE_BYTESTRING);
1659 manufacturer_data = value ? (gchar *)g_variant_get_bytestring(tmp_value) : NULL;
1660 if (manufacturer_data) {
1661 if (manufacturer_data_len > 0) {
1662 //size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_MANUFACTURER_DATA,
1663 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_BLE_ADV_DATA,
1664 manufacturer_data_len, manufacturer_data);
1668 g_variant_unref(tmp_value);
1672 _bt_hal_convert_addr_string_to_type(bdaddr, address);
1673 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_ADDR,
1674 sizeof(bdaddr), bdaddr);
1676 DBG("Device address [%s] property Num [%d]", address, ev->num_props);
1679 g_variant_unref(value);
1681 ERR("result is NULL\n");
1684 DBG("Send Device found event to HAL user, Num Prop [%d] total size [%d]", ev->num_props, size);
1685 event_cb(HAL_EV_DEVICE_FOUND, (void*) buf, size);
1690 static void __bt_hal_send_device_acl_connection_state_event(gboolean connected, const char *address)
1693 struct hal_ev_acl_state_changed ev;
1695 ev.status = BT_STATUS_SUCCESS;
1696 ev.state = (connected == TRUE) ?
1697 HAL_ACL_STATE_CONNECTED :
1698 HAL_ACL_STATE_DISCONNECTED;
1700 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
1703 ERR("Bluetooth HAL event handler not registered");
1705 event_cb(HAL_EV_ACL_STATE_CHANGED, &ev, sizeof(ev));
1709 static void __bt_hal_send_device_le_connection_state_event(gboolean connected, const char *address)
1712 struct hal_ev_le_conn_state_changed ev;
1714 ev.status = BT_STATUS_SUCCESS;
1715 ev.state = (connected == TRUE) ?
1716 HAL_LE_STATE_CONNECTED :
1717 HAL_LE_STATE_DISCONNECTED;
1719 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
1722 ERR("Bluetooth HAL event handler not registered");
1724 event_cb(HAL_EV_LE_CONN_STATE_CHANGED, &ev, sizeof(ev));
1728 static void __bt_hal_send_device_trust_state_event(gboolean is_trusted,
1729 const char *address)
1731 struct hal_ev_device_trust_state_changed ev;
1734 ev.trust = (is_trusted == TRUE) ?
1735 HAL_DEVICE_TRUSTED :
1736 HAL_DEVICE_UNTRUSTED;
1738 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
1741 ERR("Bluetooth HAL event handler not registered");
1743 event_cb(HAL_EV_DEVICE_TRUST_CHANGED, &ev, sizeof(ev));
1747 static void __bt_hal_send_device_trusted_profile_changed_event(
1748 uint32_t trust_val, const char *address)
1750 struct hal_ev_device_trusted_profiles_changed ev;
1753 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
1754 ev.trust_val = trust_val;
1757 ERR("Bluetooth HAL event handler not registered");
1759 event_cb(HAL_EV_DEVICE_TRUSTED_PROFILES_CHANGED, &ev, sizeof(ev));
1763 static void __bt_hal_handle_device_specific_events(GVariant *msg, const char *member,
1767 const char *property = NULL;
1771 if (strcasecmp(member, "PropertyChanged") == 0) {
1772 g_variant_get(msg, "(s)", &property);
1773 if (property == NULL)
1775 if (strcasecmp(property, "GattConnected") == 0) {
1776 INFO("GATT Connected");
1777 gboolean connected = FALSE;
1779 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1781 _bt_hal_convert_device_path_to_address(path, address);
1782 g_variant_get(msg, "(b)", &connected);
1784 INFO("Connected device address[%s] connnected[%d]", address, connected);
1786 } else if (strcasecmp(property, "Paired") == 0) {
1787 gboolean paired = FALSE;
1788 struct hal_ev_bond_state_changed ev;
1789 char address[BT_HAL_ADDRESS_STRING_SIZE];
1791 g_variant_get(msg, "(b)", &paired);
1792 DBG("Device property changed : Paired = %s", (paired ? "TRUE" : "FALSE"));
1794 _bt_hal_agent_set_canceled(FALSE);
1795 _bt_hal_convert_device_path_to_address(path, address);
1797 /* Prepare to send event to HAL bluetooth */
1798 ev.status = BT_STATUS_SUCCESS;
1799 ev.state = paired ? BT_BOND_STATE_BONDED : BT_BOND_STATE_NONE;
1800 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
1803 ERR("Bluetooth HAL event handler not registered");
1805 DBG("Sending HAL_EV_BOND_STATE_CHANGED event");
1806 event_cb(HAL_EV_BOND_STATE_CHANGED, (void*)&ev, sizeof(ev));
1808 } else if (strcasecmp(property, "UUIDs") == 0) {
1811 } else if (strcasecmp(member, "DeviceConnected") == 0) {
1812 unsigned char addr_type = 0;
1814 g_variant_get(msg, "(y)", &addr_type);
1816 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1817 _bt_hal_convert_device_path_to_address(path, address);
1819 DBG("Member: [%s]", member);
1820 ERR_C("Connected [%s] [%s]", !addr_type ? "BREDR" : "LE", address);
1822 __bt_hal_send_device_acl_connection_state_event(TRUE, address);
1824 __bt_hal_send_device_le_connection_state_event(TRUE, address);
1826 } else if (strcasecmp(member, "Disconnected") == 0) {
1827 unsigned char disc_reason = 0;
1828 unsigned char addr_type = 0;
1831 g_variant_get(msg, "(yy&s)", &addr_type, &disc_reason, &name);
1833 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1834 _bt_hal_convert_device_path_to_address(path, address);
1836 DBG("Member: [%s]", member);
1837 ERR_C("DisConnected [%s] [%s]", !addr_type ? "BREDR" : "LE", address);
1838 DBG("Disconnect Reason: %d", disc_reason);
1839 DBG("Name: %s", name);
1841 __bt_hal_send_device_acl_connection_state_event(FALSE, address);
1843 __bt_hal_send_device_le_connection_state_event(FALSE, address);
1845 } else if (strcasecmp(member, "ProfileStateChanged") == 0) {
1847 char *profile_uuid = NULL;
1849 g_variant_get(msg, "(si)", &profile_uuid, &state);
1850 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1851 _bt_hal_convert_device_path_to_address(path, address);
1853 DBG("Address: %s", address);
1854 DBG("Profile UUID: %s", profile_uuid);
1855 DBG("State: %d", state);
1856 if (strncmp(profile_uuid, HID_UUID, strlen(HID_UUID)) == 0) {
1857 if (state == BT_HAL_PROFILE_STATE_CONNECTED)
1858 __bt_hal_send_hid_connection_state_event(TRUE, address);
1859 else if (state == BT_HAL_PROFILE_STATE_DISCONNECTED)
1860 __bt_hal_send_hid_connection_state_event(FALSE, address);
1862 DBG("Profile state: %d", state);
1864 } else if ((strncmp(profile_uuid, A2DP_SINK_UUID, strlen(A2DP_SINK_UUID)) == 0)) {
1865 if (state == BT_HAL_PROFILE_STATE_CONNECTED) {
1866 DBG("A2DP Profile state changed: BT_PROFILE_STATE_CONNECTED");
1867 __bt_hal_send_av_connection_state_event(TRUE, address);
1868 } else if (state == BT_HAL_PROFILE_STATE_DISCONNECTED) {
1869 DBG("A2DP Profile state changed: BT_PROFILE_STATE_DISCONNECTED");
1870 __bt_hal_send_av_connection_state_event(FALSE, address);
1871 } else if (state == BT_HAL_PROFILE_STATE_DISCONNECTING) {
1872 DBG("A2DP Profile state changed: BT_PROFILE_STATE_DISCONNECTING");
1873 } else if (state == BT_HAL_PROFILE_STATE_CONNECTING) {
1874 DBG("A2DP Profile state changed: BT_PROFILE_STATE_CONNECTING");
1876 ERR("A2DP Profile state: Invalid");
1878 } else if ((strncmp(profile_uuid, A2DP_SOURCE_UUID, strlen(A2DP_SOURCE_UUID)) == 0)) {
1879 if (state == BT_HAL_PROFILE_STATE_CONNECTED) {
1880 DBG("A2DP Sink Profile state changed: BT_HAL_PROFILE_STATE_CONNECTED");
1881 __bt_hal_send_a2dp_sink_connection_state_event(TRUE, address);
1882 } else if (state == BT_HAL_PROFILE_STATE_DISCONNECTED) {
1883 DBG("A2DP Sink Profile state changed: BT_HAL_PROFILE_STATE_DISCONNECTED");
1884 __bt_hal_send_a2dp_sink_connection_state_event(FALSE, address);
1885 } else if (state == BT_HAL_PROFILE_STATE_DISCONNECTING) {
1886 DBG("A2DP Sink Profile state changed: BT_HAL_PROFILE_STATE_DISCONNECTING");
1887 } else if (state == BT_HAL_PROFILE_STATE_CONNECTING) {
1888 DBG("A2DP Sink Profile state changed: BT_HAL_PROFILE_STATE_CONNECTING");
1890 } else if (strncmp(profile_uuid, HFP_HF_UUID, strlen(HFP_HF_UUID)) == 0) {
1891 if (state == BT_HAL_PROFILE_STATE_CONNECTING)
1892 DBG("HFP Profile state changed: BT_PROFILE_STATE_CONNECTING");
1893 else if (state == BT_HAL_PROFILE_STATE_CONNECTED) {
1894 DBG("HFP Profile state changed: BT_PROFILE_STATE_CONNECTED");
1895 __bt_hal_send_hf_connection_state_event(TRUE, address);
1896 } else if (state == BT_HAL_PROFILE_STATE_DISCONNECTED) {
1897 DBG("HFP Profile state changed: BT_PROFILE_STATE_DISCONNECTED");
1898 __bt_hal_send_hf_connection_state_event(FALSE, address);
1899 } else if (state == BT_HAL_PROFILE_STATE_DISCONNECTING) {
1900 DBG("HFP Profile state changed: BT_PROFILE_STATE_DISCONNECTING");
1902 ERR("HFP Profile state: Invalid");
1904 } else if ((strncmp(profile_uuid, AVRCP_TARGET_UUID, strlen(AVRCP_TARGET_UUID)) == 0)) {
1905 if (state == BT_HAL_PROFILE_STATE_CONNECTED) {
1906 DBG("AVRCP Controller Profile state changed: BT_HAL_PROFILE_STATE_CONNECTED");
1907 __bt_hal_send_avrcp_ctrl_connection_state_event(TRUE, address);
1908 } else if (state == BT_HAL_PROFILE_STATE_DISCONNECTED) {
1909 DBG("AVRCP Controller Profile state changed: BT_HAL_PROFILE_STATE_DISCONNECTED");
1910 __bt_hal_send_avrcp_ctrl_connection_state_event(FALSE, address);
1911 } else if (state == BT_HAL_PROFILE_STATE_DISCONNECTING) {
1912 DBG("AVRCP Controller Profile state changed: BT_HAL_PROFILE_STATE_DISCONNECTING");
1913 } else if (state == BT_HAL_PROFILE_STATE_CONNECTING) {
1914 DBG("AVRCP Controller Profile state changed: BT_HAL_PROFILE_STATE_CONNECTING");
1917 DBG("Profile[%s] State changed status [%d] ", profile_uuid, state);
1920 g_free(profile_uuid);
1921 } else if (strcasecmp(member, "AdvReport") == 0) {
1922 DBG("Member: [%s]", member);
1923 __bt_hal_handle_adv_report(msg, path);
1927 static void __bt_hal_handle_adv_report(GVariant *msg, const char *path)
1929 uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
1930 struct hal_ev_gatt_client_scan_result *ev = (void *)buf;
1932 char *address = NULL;
1933 GVariant *value = NULL;
1934 char *buffer = NULL;
1937 uint8_t addr_type = 0;
1938 uint8_t adv_type = 0;
1944 memset(buf, 0, sizeof(buf));
1947 g_variant_get(msg, "(&syyii@ay)", &address, &addr_type,
1948 &adv_type, &rssi, &data_len, &value);
1950 buffer_len = g_variant_get_size(value);
1952 buffer = (char *)g_variant_get_data(value);
1954 if (data_len != buffer_len) {
1955 ERR("Unexpected: buffer_len: %d, data_len: %d",
1956 buffer_len, data_len);
1957 data_len = buffer_len;
1960 DBG("Address: %s, len: %d, rssi: %d, addr_type: 0x%02X, adv_type: 0x%02X",
1961 address, data_len, rssi, addr_type, adv_type);
1963 _bt_hal_convert_addr_string_to_type(ev->bd_addr, address);
1964 ev->addr_type = addr_type;
1965 ev->adv_type = adv_type;
1968 memcpy(ev->adv_data, buffer, data_len);
1971 DBG("Send le scan result event to HAL, size: [%d]", size);
1972 gatt_event_cb(HAL_EV_GATT_CLIENT_SCAN_RESULT, buf, size);
1973 g_variant_unref(value);
1976 /* AVRCP Controller Role(Remote:AVRCP Target) Events */
1977 static void __bt_hal_send_avrcp_ctrl_connection_state_event(gboolean connected, const char *address)
1980 struct hal_ev_avrcp_ctrl_conn_state ev;
1982 if (connected == TRUE)
1983 INFO("AVRCP(Controller) Profile Connected for address [%s]", address);
1985 INFO("AVRCP(Controller) Profile DisConnected for address [%s]", address);
1987 if (connected == TRUE)
1988 ev.state = HAL_AVRCP_CTRL_STATE_CONNECTED;
1990 ev.state = HAL_AVRCP_CTRL_STATE_DISCONNECTED;
1991 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
1993 if (!a2dp_sink_event_cb)
1994 ERR("AV event handler not registered");
1996 avrcp_ctrl_event_cb(HAL_EV_AVRCP_CTRL_CONN_STATE, &ev, sizeof(ev));
1999 static int __bt_media_attr_to_type(const char *str)
2001 if (!strcasecmp(str, "Equalizer"))
2002 return HAL_PLAYER_ATTR_EQUALIZER;
2003 else if (!strcasecmp(str, "Repeat"))
2004 return HAL_PLAYER_ATTR_REPEAT;
2005 else if (!strcasecmp(str, "Shuffle"))
2006 return HAL_PLAYER_ATTR_SHUFFLE;
2007 else if (!strcasecmp(str, "Scan"))
2008 return HAL_PLAYER_ATTR_SCAN;
2014 static int __bt_hal_play_status_str_to_type(const char *value)
2016 if (!strcmp(value, "stopped"))
2017 return HAL_PLAYSTATE_STOPPED;
2018 else if (!strcmp(value, "playing"))
2019 return HAL_PLAYSTATE_PLAYING;
2020 else if (!strcmp(value, "paused"))
2021 return HAL_PLAYSTATE_PAUSED;
2022 else if (!strcmp(value, "forward-seek"))
2023 return HAL_PLAYSTATE_FWD_SEEK;
2024 else if (!strcmp(value, "reverse-seek"))
2025 return HAL_PLAYSTATE_REV_SEEK;
2027 return HAL_PLAYSTATE_ERROR;
2030 static void __bt_avrcp_control_parse_properties(struct hal_ev_track_changed *ev, GVariant *item)
2032 GVariant *value = NULL;
2034 char *value_string = NULL;
2035 const char *key = NULL;
2041 g_variant_iter_init(&iter, item);
2042 while (g_variant_iter_loop(&iter, "{sv}", &key, &value)) {
2043 if (strcasecmp(key, "Title") == 0) {
2044 value_string = (char *)g_variant_get_string(value, NULL);
2045 DBG("Value : %s ", value_string);
2046 ev->attr[i].attr_id = HAL_MEDIA_ATTR_ID_TITLE;
2047 g_strlcpy((gchar *)ev->attr[i].text, value_string, HAL_MAX_ATTR_STR_LEN);
2049 } else if (strcasecmp(key, "Artist") == 0) {
2050 value_string = (char *)g_variant_get_string(value, NULL);
2051 DBG("Value : %s ", value_string);
2052 ev->attr[i].attr_id = HAL_MEDIA_ATTR_ID_ARTIST;
2053 g_strlcpy((gchar *)ev->attr[i].text, value_string, HAL_MAX_ATTR_STR_LEN);
2055 } else if (strcasecmp(key, "Album") == 0) {
2056 value_string = (char *)g_variant_get_string(value, NULL);
2057 DBG("Value : %s ", value_string);
2058 ev->attr[i].attr_id = HAL_MEDIA_ATTR_ID_ALBUM;
2059 g_strlcpy((gchar *)ev->attr[i].text, value_string, HAL_MAX_ATTR_STR_LEN);
2061 } else if (strcasecmp(key, "Genre") == 0) {
2062 value_string = (char *)g_variant_get_string(value, NULL);
2063 DBG("Value : %s ", value_string);
2064 ev->attr[i].attr_id = HAL_MEDIA_ATTR_ID_GENRE;
2065 g_strlcpy((gchar *)ev->attr[i].text, value_string, HAL_MAX_ATTR_STR_LEN);
2067 } else if (strcasecmp(key, "Duration") == 0) {
2070 val = g_variant_get_uint32(value);
2071 DBG("Value : %d", val);
2072 ev->attr[i].attr_id = HAL_MEDIA_ATTR_ID_PLAYING_TIME;
2073 snprintf((char*)ev->attr[i].text, HAL_MAX_ATTR_STR_LEN, "%ld", val);
2075 } else if (strcasecmp(key, "NumberOfTracks") == 0) {
2078 val = g_variant_get_uint32(value);
2079 DBG("Value : %d", val);
2080 ev->attr[i].attr_id = HAL_MEDIA_ATTR_ID_NUM_TRACKS;
2081 snprintf((char*)ev->attr[i].text, HAL_MAX_ATTR_STR_LEN, "%ld", val);
2083 } else if (strcasecmp(key, "TrackNumber") == 0) {
2086 val = g_variant_get_uint32(value);
2087 DBG("Value : %d", val);
2088 ev->attr[i].attr_id = HAL_MEDIA_ATTR_ID_TRACK_NUM;
2089 snprintf((char*)ev->attr[i].text, HAL_MAX_ATTR_STR_LEN, "%ld", val);
2092 DBG("%s not supported, ignoring", key);
2095 if (i >= HAL_MAX_ATTR_NUM) {
2096 ERR(" Received max attribute [%d]", i);
2102 g_variant_iter_free(&iter);
2106 static int __bt_media_attrval_to_val(int type, const char *value)
2111 case HAL_PLAYER_ATTR_EQUALIZER:
2112 if (!strcmp(value, "off"))
2117 case HAL_PLAYER_ATTR_REPEAT:
2118 if (!strcmp(value, "off"))
2119 ret = BTRC_PLAYER_VAL_OFF_REPEAT;
2120 else if (!strcmp(value, "singletrack"))
2121 ret = BTRC_PLAYER_VAL_SINGLE_REPEAT;
2122 else if (!strcmp(value, "alltracks"))
2123 ret = BTRC_PLAYER_VAL_ALL_REPEAT;
2125 ret = BTRC_PLAYER_VAL_GROUP_REPEAT;
2127 case HAL_PLAYER_ATTR_SHUFFLE:
2128 if (!strcmp(value, "off"))
2129 ret = BTRC_PLAYER_VAL_OFF_SHUFFLE;
2130 else if (!strcmp(value, "alltracks"))
2131 ret = BTRC_PLAYER_VAL_ALL_SHUFFLE;
2133 ret = BTRC_PLAYER_VAL_GROUP_SHUFFLE;
2135 case HAL_PLAYER_ATTR_SCAN:
2136 if (!strcmp(value, "off"))
2138 else if (!strcmp(value, "alltracks"))
2144 ERR("Value not handled");
2150 static void __bt_hal_handle_avrcp_ctrl_events(GVariant *msg, const char *member,
2153 const char *property = NULL;
2154 GVariant *value = NULL;
2156 char address[BT_HAL_ADDRESS_STRING_SIZE];
2159 ERR("Error returned in method call\n");
2163 if (!avrcp_ctrl_event_cb) {
2164 ERR("AVRCP controller DBUS handler callback not registered");
2168 g_variant_iter_init(&iter, msg);
2170 _bt_hal_convert_device_path_to_address(path, address);
2172 while (g_variant_iter_loop(&iter, "{sv}", &property, &value)) {
2173 DBG("Property = %s \n", property);
2174 if ((strcasecmp(property, "Equalizer") == 0) ||
2175 (strcasecmp(property, "Repeat") == 0) ||
2176 (strcasecmp(property, "Shuffle") == 0) ||
2177 (strcasecmp(property, "Scan") == 0)) {
2178 struct hal_ev_player_setting ev;
2182 valstr = g_variant_get_string(value, NULL);
2183 DBG("Value : %s ", valstr);
2186 val = __bt_media_attrval_to_val(__bt_media_attr_to_type(property), valstr);
2189 memset(&ev, 0, sizeof(ev));
2190 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2192 ev.attr_ids[0] = __bt_media_attr_to_type(property);
2193 ev.attr_values[0] = val;
2195 /* Send event to application */
2196 avrcp_ctrl_event_cb(HAL_EV_AVRCP_CTRL_PLAYER_APP_SETTING_CHANGED, &ev, sizeof(ev));
2198 } else if ((strcasecmp(property, "Status") == 0)) {
2199 struct hal_ev_play_status_changed ev;
2202 valstr = g_variant_get_string(value, NULL);
2203 DBG("Value : %s ", valstr);
2205 memset(&ev, 0, sizeof(ev));
2206 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2208 ev.status = __bt_hal_play_status_str_to_type(valstr);
2210 /* Send event to application */
2211 avrcp_ctrl_event_cb(HAL_EV_AVRCP_CTRL_PLAY_STATUS_CHANGED, &ev, sizeof(ev));
2213 } else if (strcasecmp(property, "Position") == 0) {
2214 struct hal_ev_play_position ev;
2216 memset(&ev, 0, sizeof(ev));
2217 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2218 ev.pos = g_variant_get_uint32(value);
2219 DBG("Value : %d ", ev.pos);
2221 /* Send event to application */
2222 avrcp_ctrl_event_cb(HAL_EV_AVRCP_CTRL_PLAY_POSITION_CHANGED, &ev, sizeof(ev));
2223 } else if (strcasecmp(property, "Track") == 0) {
2224 struct hal_ev_track_changed ev;
2226 memset(&ev, 0, sizeof(ev));
2227 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2228 __bt_avrcp_control_parse_properties(&ev, value);
2230 /* Send event to application */
2231 avrcp_ctrl_event_cb(HAL_EV_AVRCP_CTRL_TRACK_CHANGED, &ev, sizeof(ev));
2233 DBG("Property not handled");
2237 g_free((char *)property);
2238 g_variant_unref(value);
2241 /* A2DP Src Role(Remote:Sink) Events */
2242 static void __bt_hal_send_av_connection_state_event(gboolean connected, const char *address)
2245 struct hal_ev_a2dp_conn_state ev;
2247 if (connected == TRUE)
2248 INFO("A2DP(Src) Profile Connected for address [%s]", address);
2250 INFO("A2DP(Src) Profile DisConnected for address [%s]", address);
2252 ev.state = (connected == TRUE) ?
2253 HAL_EV_A2DP_STATE_CONNECTED :
2254 HAL_EV_A2DP_STATE_DISCONNECTED;
2256 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2259 ERR("AV event handler not registered");
2261 av_event_cb(HAL_EV_A2DP_CONN_STATE, &ev, sizeof(ev));
2264 /* A2DP Sink Role(Remote:Source) Events */
2265 static void __bt_hal_send_a2dp_sink_connection_state_event(gboolean connected, const char *address)
2268 struct hal_ev_a2dp_conn_state ev;
2270 if (connected == TRUE)
2271 INFO("A2DP(Sink) Profile Connected for address [%s]", address);
2273 INFO("A2DP(Sink) Profile DisConnected for address [%s]", address);
2275 ev.state = (connected == TRUE) ?
2276 HAL_EV_A2DP_STATE_CONNECTED :
2277 HAL_EV_A2DP_STATE_DISCONNECTED;
2279 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2281 if (!a2dp_sink_event_cb)
2282 ERR("AV event handler not registered");
2284 a2dp_sink_event_cb(HAL_EV_A2DP_SOURCE_CONN_STATE, &ev, sizeof(ev));
2287 /* HF(AG Role) Audio Events */
2288 static void __bt_hal_send_hf_audio_connection_state_event(gboolean connected,
2289 const char *address)
2292 struct hal_ev_handsfree_audio_state ev;
2294 if (connected == TRUE)
2295 INFO("AG Audio Connected for address [%s]", address);
2297 INFO("AG Audio DisConnected for address [%s]", address);
2299 ev.state = (connected == TRUE) ?
2300 HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTED :
2301 HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED;
2303 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2306 ERR("HF event handler not registered");
2308 hf_event_cb(HAL_EV_HANDSFREE_AUDIO_STATE, &ev, sizeof(ev));
2311 /* HF(AG Role) Profile Events */
2312 static void __bt_hal_send_hf_connection_state_event(gboolean connected,
2313 const char *address)
2316 struct hal_ev_handsfree_conn_state ev;
2318 if (connected == TRUE)
2319 INFO("AG Profile Connected for address [%s]", address);
2321 INFO("AG Profile DisConnected for address [%s]", address);
2323 ev.state = (connected == TRUE) ?
2324 HAL_EV_HANDSFREE_CONN_STATE_CONNECTED :
2325 HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED;
2327 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2330 ERR("HF event handler not registered");
2332 hf_event_cb(HAL_EV_HANDSFREE_CONN_STATE, &ev, sizeof(ev));
2335 void _bt_hal_register_event_handler_cb(bt_hal_module_e module, handle_stack_msg cb)
2345 a2dp_sink_event_cb = cb;
2351 avrcp_tg_event_cb = cb;
2353 case HAL_AVRCP_CTRL:
2354 avrcp_ctrl_event_cb = cb;
2360 ERR("Unknown module: %d", module);
2364 void _bt_hal_unregister_event_handler_cb(bt_hal_module_e module)
2368 hid_event_cb = NULL;
2374 a2dp_sink_event_cb = NULL;
2380 avrcp_tg_event_cb = NULL;
2382 case HAL_AVRCP_CTRL:
2383 avrcp_ctrl_event_cb = NULL;
2386 gatt_event_cb = NULL;
2389 ERR("Unknown module: %d", module);
2393 bool _bt_hal_get_adapter_request_state(void)
2395 return is_adapter_activating;
2398 bool _bt_hal_get_le_request_state(void)
2400 return is_le_activating;
2403 void _bt_hal_set_adapter_request_state(bool enable)
2405 DBG("set_adapter_request_state %d", enable);
2406 is_adapter_activating = enable;
2409 void _bt_hal_set_le_request_state(bool enable)
2411 DBG("set_le_request_state %d", enable);
2412 is_le_activating = enable;