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"
41 #include "bt-hal-gatt-client.h"
42 #include "bt-hal-adapter-dbus-handler.h"
44 #define BASELEN_PROP_CHANGED (sizeof(struct hal_ev_adapter_props_changed) \
45 + sizeof(struct hal_property))
47 /*TODO: Basic filters are currently added,
48 Need to add different event filters like HID,
49 Device etc in subsequent patches */
51 /* Global variables and structures */
52 static GDBusConnection *manager_conn;
53 static handle_stack_msg event_cb = NULL;
54 static handle_stack_msg hid_event_cb = NULL;
55 static handle_stack_msg av_event_cb = NULL;
56 static handle_stack_msg a2dp_sink_event_cb = NULL;
57 static handle_stack_msg hf_event_cb = NULL;
58 static handle_stack_msg avrcp_ctrl_event_cb = NULL;
59 static handle_stack_msg avrcp_tg_event_cb = NULL;
60 static handle_stack_msg gatt_event_cb = NULL;
61 static guint event_id;
63 /*State Management sepration Control for Adapter and LE */
64 static gboolean is_adapter_activating = FALSE;
65 static gboolean is_le_activating = FALSE;
70 gchar* interface_name;
73 } bt_hal_main_event_data_t;
75 /* Forward declarations */
76 static gboolean __bt_hal_event_manager(gpointer param);
77 static int __bt_hal_register_service_event(GDBusConnection *g_conn, int event_type);
78 static int __bt_hal_register_manager_subscribe_signal(GDBusConnection *conn, int subscribe);
79 static int __bt_hal_register_device_subscribe_signal(GDBusConnection *conn, int subscribe);
80 static int __bt_hal_register_input_subscribe_signal(GDBusConnection *conn, int subscribe);
82 static int __bt_hal_parse_event(GVariant *msg);
83 static int __bt_hal_get_owner_info(GVariant *msg, char **name, char **previous, char **current);
85 static void __bt_hal_handle_property_changed_event(GVariant *msg, const char *object_path);
86 static void __bt_hal_adapter_property_changed_event(GVariant *msg);
87 static void __bt_hal_manager_event_filter(GDBusConnection *connection, const gchar *sender_name,
88 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
89 GVariant *parameters, gpointer user_data);
90 static int __bt_hal_initialize_manager_receiver(void);
91 static gboolean __bt_hal_parse_interface(GVariant *msg);
92 static void __bt_hal_handle_device_event(GVariant *value, GVariant *parameters);
93 static gboolean __bt_hal_parse_device_properties(GVariant *item);
94 static gboolean __bt_hal_discovery_finished_cb(gpointer user_data);
95 static void __bt_hal_device_property_changed_event(GVariant *msg, const char *path);
96 static void __bt_hal_dbus_device_found_properties(const char *device_path);
97 static void __bt_hal_device_properties_lookup(GVariant *result, char *address);
98 static void __bt_hal_handle_device_specific_events(GVariant *msg, const char *member, const char *path);
99 static void __bt_hal_send_device_acl_connection_state_event(int status, gboolean connected, const char *address);
100 static void __bt_hal_handle_input_event(GVariant *msg, const char *path);
101 static void __bt_hal_send_av_connection_state_event(gboolean connected, const char *address);
102 static void __bt_hal_send_a2dp_sink_connection_state_event(gboolean connected, const char *address);
103 static void __bt_hal_send_avrcp_ctrl_connection_state_event(gboolean connected, const char *address);
104 static void __bt_hal_handle_avrcp_ctrl_events(GVariant *msg, const char *member, const char *path);
105 static void __bt_hal_handle_avrcp_transport_events(GVariant *msg, const char *member, const char *path);
107 static void __bt_hal_send_device_trust_state_event(gboolean is_trusted, const char *address);
108 static int __bt_hal_register_audio_subscribe_signal(GDBusConnection *conn, int subscribe);
109 static void __bt_hal_handle_headset_events(GVariant *msg, const char *member, const char *path);
110 static void __bt_hal_send_hf_audio_connection_state_event(gboolean connected, const char *address);
111 static void __bt_hal_send_hf_connection_state_event(gboolean connected, const char *address);
112 static void __bt_hal_send_device_trusted_profile_changed_event(uint32_t trust_val, const char *address);
113 static void __bt_hal_handle_adv_report(GVariant *msg, const char *path);
114 static void __bt_hal_handle_gatts_mtu_changed_event(char *address, int mtu);
117 static gboolean __bt_hal_discovery_finished_cb(gpointer user_data)
121 struct hal_ev_discovery_state_changed ev;
122 ev.state = HAL_DISCOVERY_STATE_STOPPED;
123 event_cb(HAL_EV_DISCOVERY_STATE_CHANGED, &ev, sizeof(ev));
129 static int __bt_hal_parse_event(GVariant *msg)
133 char *interface_name = NULL;
134 GVariant *inner_iter = NULL;
136 g_variant_iter_init(&iter, msg);
138 while ((child = g_variant_iter_next_value(&iter))) {
139 g_variant_get(child, "{&s@a{sv}}", &interface_name, &inner_iter);
140 if (g_strcmp0(interface_name,
141 BT_HAL_DEVICE_INTERFACE) == 0) {
142 DBG("__bt_hal_parse_event: Interface: BT_HAL_DEVICE_INTERFACE");
143 g_variant_unref(inner_iter);
144 g_variant_unref(child);
145 return BT_HAL_DEVICE_EVENT;
146 } else if (g_strcmp0(interface_name,
147 BT_HAL_MEDIATRANSPORT_INTERFACE) == 0) {
148 DBG("__bt_hal_parse_event: Interface: BT_HAL_MEDIATRANSPORT_INTERFACE");
149 g_variant_unref(inner_iter);
150 g_variant_unref(child);
151 return BT_HAL_MEDIA_TRANSFER_EVENT;
152 } else if (g_strcmp0(interface_name,
153 BT_HAL_PLAYER_CONTROL_INTERFACE) == 0) {
154 DBG("__bt_hal_parse_event: Interface: BT_HAL_PLAYER_CONTROL_INTERFACE");
155 g_variant_unref(inner_iter);
156 g_variant_unref(child);
157 return BT_HAL_AVRCP_CONTROL_EVENT;
159 g_variant_unref(inner_iter);
160 g_variant_unref(child);
166 static int __bt_hal_get_owner_info(GVariant *msg, char **name, char **previous, char **current)
168 g_variant_get(msg, "(&s&s&s)", name, previous, current);
169 return BT_HAL_ERROR_NONE;
172 int __bt_insert_hal_properties(void *buf, uint8_t type, uint16_t len, const void *val)
173 { struct hal_property *prop = buf;
179 memcpy(prop->val, val, len);
181 return sizeof(*prop) + len;
184 handle_stack_msg _bt_hal_get_stack_message_handler(void)
189 static void __bt_hal_adapter_property_changed_event(GVariant *msg)
191 GVariantIter value_iter;
192 GVariant *value = NULL;
193 GDBusProxy *adapter_proxy;
196 g_variant_iter_init(&value_iter, msg);
198 /* Buffer and propety count management */
199 uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
200 struct hal_ev_adapter_props_changed *ev = (void*) buf;
202 const gchar *address = NULL;
204 unsigned int cod = 0;
205 gboolean discoverable;
206 gboolean connectable;
207 unsigned int scan_mode = BT_SCAN_MODE_NONE;
208 unsigned int disc_timeout;
209 const gchar *version;
210 gboolean ipsp_initialized;
213 unsigned int pairable_timeout;
214 gboolean scan_mode_property_update = FALSE;
215 gboolean is_discovering;
216 gboolean is_le_discovering;
218 memset(buf, 0, sizeof(buf));
221 ev->status = BT_STATUS_SUCCESS;
225 while (g_variant_iter_loop(&value_iter, "{sv}", &key, &value)) {
226 if (!g_strcmp0(key, "Address")) {
229 address = g_variant_get_string(value, NULL);
230 DBG("##Address [%s]", address);
231 _bt_hal_convert_addr_string_to_type(bdaddr, address);
232 size += __bt_insert_hal_properties(buf + size,
233 HAL_PROP_ADAPTER_ADDR, sizeof(bdaddr), bdaddr);
235 } else if (!g_strcmp0(key, "Alias")) {
236 g_variant_get(value, "&s", &name);
237 DBG("##Alias [%s] ", name);
238 size += __bt_insert_hal_properties(buf + size,
239 HAL_PROP_ADAPTER_NAME, strlen(name) + 1, name);
241 } else if (!g_strcmp0(key, "Class")) {
242 cod = g_variant_get_uint32(value);
243 DBG("##Class [%d]", cod);
244 size += __bt_insert_hal_properties(buf + size,
245 HAL_PROP_ADAPTER_CLASS, sizeof(unsigned int), &cod);
247 } else if (!g_strcmp0(key, "Discoverable")) {
248 discoverable = g_variant_get_boolean(value);
249 DBG("##Discoverable [%d]", discoverable);
251 scan_mode = BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE;
253 scan_mode = BT_SCAN_MODE_CONNECTABLE;
254 scan_mode_property_update = TRUE;
255 } else if (!g_strcmp0(key, "DiscoverableTimeout")) {
256 disc_timeout = g_variant_get_uint32(value);
257 DBG("##Discoverable Timeout [%d]", disc_timeout);
258 size += __bt_insert_hal_properties(buf + size,
259 HAL_PROP_ADAPTER_DISC_TIMEOUT, sizeof(unsigned int), &disc_timeout);
261 } else if (!g_strcmp0(key, "Connectable")) {
262 connectable = g_variant_get_boolean(value);
263 DBG("##Connectable [%d]", connectable);
265 scan_mode = BT_SCAN_MODE_NONE;
266 else if (scan_mode == BT_SCAN_MODE_NONE)
267 scan_mode = BT_SCAN_MODE_CONNECTABLE;
268 scan_mode_property_update = TRUE;
269 } else if (!g_strcmp0(key, "Version")) {
270 version = g_variant_get_string(value, NULL);
271 DBG("##Version [%s]", version);
272 size += __bt_insert_hal_properties(buf + size,
273 HAL_PROP_ADAPTER_VERSION, strlen(version) + 1, version);
275 } else if (!g_strcmp0(key, "Name")) {
276 g_variant_get(value, "&s", &name);
277 DBG("##Name [%s]", name);
278 size += __bt_insert_hal_properties(buf + size,
279 HAL_PROP_ADAPTER_NAME, strlen(name) + 1, name);
281 } else if (!g_strcmp0(key, "Powered")) {
282 powered = g_variant_get_boolean(value);
283 DBG("##Powered = %d", powered);
284 /* TODO: Need to check this operation!! */
285 if (powered == FALSE) {
286 DBG("###### Adapter Powered Down ######");
287 struct hal_ev_adapter_state_changed ev;
288 ev.state = HAL_POWER_OFF;
289 event_cb(HAL_EV_ADAPTER_STATE_CHANGED, &ev, sizeof(ev));
291 struct hal_ev_le_state_changed le_ev;
292 le_ev.state = HAL_POWER_OFF;
293 event_cb(HAL_EV_LE_STATE_CHANGED, &le_ev, sizeof(le_ev));
296 _bt_hal_destroy_adapter_agent();
298 DBG("###### Adapter Powered Up ######");
299 if (_bt_hal_get_adapter_request_state()) {
300 DBG("Sending STATE CHANGE EVENT for Adapter... ");
301 _bt_hal_set_adapter_request_state(FALSE);
302 struct hal_ev_adapter_state_changed ev;
303 ev.state = HAL_POWER_ON;
304 event_cb(HAL_EV_ADAPTER_STATE_CHANGED, &ev, sizeof(ev));
307 if (_bt_hal_get_le_request_state()) {
308 DBG("Sending STATE CHANGE EVENT for LE... ");
309 _bt_hal_set_le_request_state(FALSE);
310 struct hal_ev_le_state_changed ev;
311 ev.state = HAL_POWER_ON;
312 event_cb(HAL_EV_LE_STATE_CHANGED, &ev, sizeof(ev));
316 _bt_hal_initialize_adapter_agent();
319 } else if (!g_strcmp0(key, "Pairable")) {
320 pairable = g_variant_get_boolean(value);
321 DBG("##Pairable [%d]", pairable);
322 } else if (!g_strcmp0(key, "PairableTimeout")) {
323 pairable_timeout = g_variant_get_uint32(value);
324 DBG("##Pairable Timeout = %d", pairable_timeout);
325 } else if (!g_strcmp0(key, "UUIDs")) {
330 size1 = g_variant_get_size(value);
331 int num_props_tmp = ev->num_props;
333 uuid_value = (char **)g_variant_get_strv(value, &size1);
334 for (i = 0; uuid_value[i] != NULL; i++)
336 /* UUID collection */
337 uint8_t uuids[BT_HAL_STACK_UUID_SIZE * uuid_count];
338 for (i = 0; uuid_value[i] != NULL; i++) {
339 char *uuid_str = NULL;
340 uint8_t uuid[BT_HAL_STACK_UUID_SIZE];
341 uuid_str = g_strdup(uuid_value[i]);
342 DBG("##UUID string [%s]\n", uuid_str);
343 _bt_hal_convert_uuid_string_to_type(uuid, uuid_str);
344 memcpy(uuids+i*BT_HAL_STACK_UUID_SIZE, uuid, BT_HAL_STACK_UUID_SIZE);
347 size += __bt_insert_hal_properties(buf + size, HAL_PROP_ADAPTER_UUIDS,
348 (BT_HAL_STACK_UUID_SIZE * uuid_count),
350 ev->num_props = num_props_tmp + 1;
353 } else if (!g_strcmp0(key, "Discovering")) {
354 is_discovering = g_variant_get_boolean(value);
355 DBG("##Discovering = [%d]", is_discovering);
357 if (is_discovering == FALSE) {
358 DBG("###### Adapter Has stopped Discovering ######");
359 /* In Tizen Bluez, this actually does not mean Discovery is stopped
360 in Bluez. Tizen Bluez sends this event after a certain timeout,
361 Therefore, we must forecefully call StopDiscovery to stop discovery in BlueZ */
365 adapter_proxy = _bt_hal_get_adapter_proxy();
367 if (adapter_proxy == NULL)
370 /* Need to stop searching */
371 DBG("Event though Bluez reported DIscovering stopped, we force stop Discovery ");
372 g_dbus_proxy_call_sync(adapter_proxy, "StopDiscovery",
374 G_DBUS_CALL_FLAGS_NONE,
378 ERR("Dbus Error : %s", err->message);
380 /* This error is thrown by Bluez, as Discovery is already stopped.
381 Discovery is stopped if user cancels on going discovery.
382 In order to maintain correct state of Bluetooth Discovery state,
383 simply send Discovery stopped event to HAL user */
384 struct hal_ev_discovery_state_changed ev;
385 ev.state = HAL_DISCOVERY_STATE_STOPPED;
386 event_cb(HAL_EV_DISCOVERY_STATE_CHANGED, &ev, sizeof(ev));
391 event_id = g_timeout_add(BT_HAL_DISCOVERY_FINISHED_DELAY,
392 (GSourceFunc)__bt_hal_discovery_finished_cb, NULL);
396 DBG("###### Adapter Has started Discovering ######");
397 struct hal_ev_discovery_state_changed ev;
398 ev.state = HAL_DISCOVERY_STATE_STARTED;
399 event_cb(HAL_EV_DISCOVERY_STATE_CHANGED, &ev, sizeof(ev));
402 } else if (!g_strcmp0(key, "LEDiscovering")) {
405 is_le_discovering = g_variant_get_boolean(value);
406 DBG("##LE Discovering = [%d]", is_le_discovering);
408 if (is_le_discovering)
411 adapter_proxy = _bt_hal_get_adapter_proxy();
412 if (adapter_proxy == NULL) {
413 ERR("adapter_proxy == NULL");
417 /* Need to stop searching */
418 result = g_dbus_proxy_call_sync(adapter_proxy, "StopLEDiscovery",
419 NULL, G_DBUS_CALL_FLAGS_NONE,
420 DBUS_TIMEOUT, NULL, &err);
422 ERR("Error occured in Proxy call");
424 ERR("(Error: %s)", err->message);
429 g_variant_unref(result);
431 size += __bt_insert_hal_properties(buf + size,
432 HAL_PROP_ADAPTER_LE_DISCOVERY_FINISHED, sizeof(gboolean), &is_le_discovering);
434 } else if (!g_strcmp0(key, "Modalias")) {
435 char *modalias = NULL;
436 g_variant_get(value, "s", &modalias);
437 DBG("##Adapter ModAlias [%s]", modalias);
438 } else if (!g_strcmp0(key, "SupportedLEFeatures")) {
439 DBG("##LE Supported features");
442 GVariantIter *iter = NULL;
443 g_variant_get(value, "as", &iter);
444 bt_local_le_features_t le_features;
445 gboolean le_features_present = FALSE;
450 memset(&le_features, 0x00, sizeof(le_features));
452 while (g_variant_iter_next(iter, "&s", &name) &&
453 g_variant_iter_next(iter, "&s", &val)) {
454 DBG("name = %s, Value = %s", name, val);
455 if (FALSE == _bt_hal_update_le_feature_support(name, val, &le_features))
456 ERR("Failed to update LE feature (name = %s, value = %s)", name, val);
458 le_features_present = TRUE;
461 g_variant_iter_free(iter);
462 if (le_features_present) {
463 size += __bt_insert_hal_properties(buf + size,
464 HAL_PROP_ADAPTER_LOCAL_LE_FEAT, sizeof(le_features), &le_features);
467 DBG("le supported features values are NOT provided by Stack");
469 } else if (!g_strcmp0(key, "IpspInitStateChanged")) {
470 g_variant_get(value, "b" , &ipsp_initialized);
471 DBG("##IPSP Initialized = %d", ipsp_initialized);
473 ERR("Unhandled Property:[%s]", key);
477 if (scan_mode_property_update) {
478 size += __bt_insert_hal_properties(buf + size,
479 HAL_PROP_ADAPTER_SCAN_MODE, sizeof(int), &scan_mode);
485 DBG("Send Adapter properties changed event to HAL user, Num Prop [%d] total size [%zd]", ev->num_props, size);
486 event_cb(HAL_EV_ADAPTER_PROPS_CHANGED, buf, size);
492 static void __bt_hal_flight_ps_mode_cb(keynode_t *node, void *data)
494 gboolean flight_mode = FALSE;
496 DBG_SECURE("HAL callback hit");
497 DBG_SECURE("key=%s", vconf_keynode_get_name(node));
498 type = vconf_keynode_get_type(node);
499 if (type == VCONF_TYPE_BOOL) {
500 flight_mode = vconf_keynode_get_bool(node);
501 if (flight_mode != TRUE) {
502 ERR("Ignore the event");
506 ERR("Flight Mode == TRUE");
509 ERR("Invaild vconf key type : %d", type);
512 DBG("Enabling core now");
513 _bt_hal_enable_core();
516 static void _bt_hal_register_vconf_handler(void)
520 if (vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
521 (vconf_callback_fn)__bt_hal_flight_ps_mode_cb, NULL) < 0)
522 ERR("Unable to register key handler");
523 DBG("Telephony is disabled");
524 if (vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE,
525 (vconf_callback_fn)__bt_hal_flight_ps_mode_cb, NULL) < 0)
526 ERR("Unable to register key handler");
529 void _bt_hal_handle_adapter_event(GVariant *msg, const char *member)
536 if (strcasecmp(member, "DeviceCreated") == 0) {
537 DBG("DeviceCreated: Unhandled");
538 } else if (strcasecmp(member, "InterfacesRemoved") == 0) {
539 DBG("InterfacesRemoved: Unhandled");
540 } else if (strcasecmp(member, "AdvertisingEnabled") == 0) {
541 DBG("AdvertisingEnabled");
542 DBG("Advertising Enabled");
544 gboolean status = FALSE;
545 g_variant_get(msg, "(ib)", &slot_id, &status);
546 DBG("Advertising Enabled : server_slot_id [%d] status [%d]", slot_id, status);
547 /* Send event to application */
548 _bt_hal_set_advertising_status(slot_id, status);
549 } else if (strcasecmp(member, "RssiEnabled") == 0) {
550 struct hal_ev_rssi_monitor_state_changed ev;
551 gboolean status = FALSE;
552 char *address = NULL;
555 g_variant_get(msg, "(sib)", &address, &link_type, &status);
556 DBG("RSSI monitoring %s for %s",
557 (status ? "Enabled" : "Disabled"), address);
559 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
560 ev.link_type = link_type;
561 ev.state = (status ? HAL_RSSI_MONITORING_ENABLED : HAL_RSSI_MONITORING_DISABLED);
563 ERR("event_cb is NULL");
565 event_cb(HAL_EV_RSSI_MONITOR_STATE_CHANGED, &ev, sizeof(ev));
568 } else if (strcasecmp(member, "RssiAlert") == 0) {
569 struct hal_ev_rssi_alert_recieved ev;
573 char *address = NULL;
575 g_variant_get(msg, "(siii)", &address, &link_type, &alert_type, &rssi_dbm);
576 DBG("RSSI Alert: [Address %s LinkType %d] [Type %d DBM %d]",
577 address, alert_type, rssi_dbm, link_type);
579 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
580 ev.link_type = link_type;
581 ev.alert_type = alert_type;
585 ERR("event_cb is NULL");
587 event_cb(HAL_EV_RSSI_ALERT_RECIEVED, &ev, sizeof(ev));
590 } else if (strcasecmp(member, "RawRssi") == 0) {
591 struct hal_ev_raw_rssi_recieved ev;
594 char *address = NULL;
596 g_variant_get(msg, "(sii)", &address, &link_type, &rssi_dbm);
597 DBG("Raw RSSI: [Address %s] [Link Type %d][RSSI DBM %d]",
598 address, link_type, rssi_dbm);
600 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
601 ev.link_type = link_type;
605 ERR("event_cb is NULL");
607 event_cb(HAL_EV_RAW_RSSI_RECIEVED, &ev, sizeof(ev));
610 } else if (strcasecmp(member, BT_HAL_HARDWARE_ERROR) == 0) {
611 DBG("BT Hardware Error: Unhandled");
612 } else if (strcasecmp(member, BT_HAL_TX_TIMEOUT_ERROR) == 0) {
613 DBG("BT TX Timeout Error: Unhandled");
619 static gboolean __bt_hal_parse_device_properties(GVariant *item)
629 /* Buffer and propety count management */
630 uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
631 struct hal_ev_device_found *ev = (void *) buf;
633 memset(buf, 0, sizeof(buf));
637 g_variant_iter_init(&iter, item);
638 while (g_variant_iter_loop(&iter, "{sv}", &key, &val)) {
640 if (strcasecmp(key, "Address") == 0) {
642 char * address = NULL;
643 address = g_variant_dup_string(val, &len);
645 _bt_hal_convert_addr_string_to_type(bdaddr, address);
647 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_ADDR,
648 sizeof(bdaddr), bdaddr);
651 DBG("Device address [%s] property Num [%d]", address, ev->num_props);
653 } else if (strcasecmp(key, "Class") == 0) {
654 unsigned int class = g_variant_get_uint32(val);
655 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_CLASS,
656 sizeof(unsigned int), &class);
658 DBG("Device class [%d] Property num [%d]", class, ev->num_props);
659 } else if (strcasecmp(key, "name") == 0) {
660 char *name = g_variant_dup_string(val, &len);
662 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_NAME,
663 strlen(name) + 1, name);
665 DBG("Device Name [%s] Property num [%d]", name, ev->num_props);
668 } else if (strcasecmp(key, "Connected") == 0) {
669 unsigned int connected = g_variant_get_byte(val);
671 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_CONNECTED,
672 sizeof(unsigned int), &connected);
674 DBG("Device connected [%u] Property num [%d]", connected, ev->num_props);
675 } else if (strcasecmp(key, "paired") == 0) {
676 uint8_t paired = (g_variant_get_boolean(val) ? 1 : 0);
677 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_PAIRED,
678 sizeof(uint8_t), &paired);
680 DBG("Device Paired [%d] Property num [%d]", paired, ev->num_props);
681 } else if (strcasecmp(key, "Trusted") == 0) {
682 uint8_t trust = (g_variant_get_boolean(val) ? 1 : 0);
683 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_TRUSTED,
684 sizeof(uint8_t), &trust);
686 DBG("Device trusted [%d] Property num [%d]", trust, ev->num_props);
687 } else if (strcasecmp(key, "RSSI") == 0) {
688 int rssi = g_variant_get_int16(val);
689 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_RSSI,
692 DBG("Device RSSI [%d] Property num [%d]", rssi, ev->num_props);
693 } else if (strcasecmp(key, "LastAddrType") == 0) {
694 /* TODO: To be handled later*/
695 } else if (!g_strcmp0(key, "IsAliasSet")) {
696 uint8_t is_alias_set = (g_variant_get_boolean(val) ? 1 : 0);
697 DBG("IsAliasSet: %s", (is_alias_set ? "TRUE" : "FALSE"));
698 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_IS_ALIAS_SET,
699 sizeof(uint8_t), &is_alias_set);
701 } else if (strcasecmp(key, "UUIDs") == 0) {
706 size1 = g_variant_get_size(val);
707 DBG("UUID count from size [%zu]\n", size1);
708 int num_props_tmp = ev->num_props;
711 uuid_value = (char **)g_variant_get_strv(val, &size1);
712 for (i = 0; uuid_value[i] != NULL; i++)
714 DBG("UUID count [%d]\n", uuid_count);
715 /* UUID collection */
716 uint8_t uuids[BT_HAL_STACK_UUID_SIZE * uuid_count];
718 for (i = 0; uuid_value[i] != NULL; i++) {
720 char *uuid_str = NULL;
721 uint8_t uuid[BT_HAL_STACK_UUID_SIZE];
722 memset(uuid, 0x00, BT_HAL_STACK_UUID_SIZE);
724 DBG("UUID string from Bluez [%s]\n", uuid_value[i]);
725 uuid_str = g_strdup(uuid_value[i]);
726 DBG("UUID string [%s]\n", uuid_str);
727 _bt_hal_convert_uuid_string_to_type(uuid, uuid_str);
728 memcpy(uuids+i*BT_HAL_STACK_UUID_SIZE, uuid, BT_HAL_STACK_UUID_SIZE);
732 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_UUIDS,
733 (BT_HAL_STACK_UUID_SIZE * uuid_count),
735 ev->num_props = num_props_tmp + 1;
739 } else if (strcasecmp(key, "LegacyManufacturerDataLen") == 0) {
740 /* TODO: To be handled later*/
741 } else if (strcasecmp(key, "LegacyManufacturerData") == 0) {
742 /* TODO: To be handled later*/
744 ERR("Unhandled Property:[%s]", key);
750 DBG("Send Device found event to HAL user, Num Prop [%d] total size [%zd]", ev->num_props, size);
751 event_cb(HAL_EV_DEVICE_FOUND, (void*) buf, size);
757 static void __bt_hal_handle_avrcp_tg_events(GVariant *msg, const char *path)
760 GVariantIter value_iter;
761 char *property = NULL;
763 GVariant *val = NULL;
764 GVariant *child = NULL;
766 g_variant_iter_init(&value_iter, msg);
767 while ((child = g_variant_iter_next_value(&value_iter))) {
768 g_variant_get(child, "{sv}", &property, &val);
769 INFO("Property %s", property);
770 if (strcasecmp(property, "Connected") == 0) {
771 struct hal_ev_avrcp_tg_conn_state ev;
773 gboolean connected = FALSE;
775 g_variant_get(val, "b", &connected);
777 state = connected ? HAL_AVRCP_TG_STATE_CONNECTED :
778 HAL_AVRCP_TG_STATE_DISCONNECTED;
780 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
782 _bt_hal_convert_device_path_to_address(path, address);
784 DBG("connected: %d", connected);
785 DBG("address: %s", address);
787 /* Prepare to send AVRCP Target connection state event */
788 memset(&ev, 0, sizeof(ev));
789 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
791 if (!avrcp_tg_event_cb)
792 ERR("AVRCP target DBUS handler callback not registered");
794 avrcp_tg_event_cb(HAL_EV_AVRCP_TG_CONN_STATE, (void *)&ev, sizeof(ev));
798 g_variant_unref(child);
799 g_variant_unref(val);
805 static void __bt_hal_handle_property_changed_event(GVariant *msg, const char *object_path)
807 char *interface_name = NULL;
808 GVariant *val = NULL;
811 g_variant_get(msg, "(&s@a{sv}@as)", &interface_name, &val, NULL);
813 if (!interface_name) {
814 DBG("Failed to get interface name");
817 g_variant_unref(val);
821 if (strcasecmp(interface_name, BT_HAL_ADAPTER_INTERFACE) == 0) {
822 DBG("Event: Property Changed: Interface: BT_HAL_ADAPTER_INTERFACE");
823 __bt_hal_adapter_property_changed_event(val);
824 } else if (strcasecmp(interface_name, BT_HAL_DEVICE_INTERFACE) == 0) {
825 DBG("Event: Property Changed: Interface: BT_HAL_DEVICE_INTERFACE");
826 __bt_hal_device_property_changed_event(val, object_path);
827 } else if (strcasecmp(interface_name, BT_HAL_OBEX_TRANSFER_INTERFACE) == 0) {
828 DBG("Event: Property Changed: Interface: BT_HAL_OBEX_TRANSFER_INTERFACE");
829 /* TODO: Handle event */
830 } else if (strcasecmp(interface_name, BT_HAL_MEDIA_CONTROL_INTERFACE) == 0) {
831 DBG("Event: Property Changed: Interface: BT_HAL_MEDIA_CONTROL_INTERFACE");
832 /* Handle AVRCP target event */
833 __bt_hal_handle_avrcp_tg_events(val, object_path);
834 } else if (strcasecmp(interface_name, BT_HAL_PLAYER_CONTROL_INTERFACE) == 0) {
835 DBG("Event: Property Changed: Interface: BT_HAL_PLAYER_CONTROL_INTERFACE");
836 __bt_hal_handle_avrcp_ctrl_events(val, NULL, object_path);
837 } else if (strcasecmp(interface_name, BT_HAL_MEDIATRANSPORT_INTERFACE) == 0) {
838 DBG("Event: Property Changed: Interface: BT_HAL_MEDIATRANSPORT_INTERFACE");
839 __bt_hal_handle_avrcp_transport_events(val, NULL, object_path);
840 } else if (strcasecmp(interface_name, BT_HAL_NETWORK_CLIENT_INTERFACE) == 0) {
841 DBG("Event: Property Changed: Interface: BT_HAL_NETWORK_CLIENT_INTERFACE");
842 /* TODO: Handle event */
843 } else if (strcasecmp(interface_name, BT_HAL_GATT_CHAR_INTERFACE) == 0) {
844 DBG("Event: Property Changed: Interface: BT_HAL_GATT_CHAR_INTERFACE");
845 /* TODO: Handle event */
846 } else if (strcasecmp(interface_name, BT_HAL_INPUT_INTERFACE) == 0) {
847 DBG("Event: Property Changed: Interface: BT_HAL_INPUT_INTERFACE");
848 __bt_hal_handle_input_event(val, object_path);
850 g_variant_unref(val);
853 static void __bt_hal_handle_device_event(GVariant *value, GVariant *parameters)
857 if (__bt_hal_parse_interface(parameters) == FALSE) {
858 ERR("Fail to parse the properies");
859 g_variant_unref(value);
866 static void __bt_hal_send_hid_connection_state_event(
867 gboolean connected, char *address)
869 struct hal_ev_hidhost_conn_state ev;
871 ev.state = (connected == TRUE) ?
872 HAL_HIDHOST_STATE_CONNECTED :
873 HAL_HIDHOST_STATE_DISCONNECTED;
875 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
878 ERR("HID event handler not registered");
880 hid_event_cb(HAL_EV_HIDHOST_CONN_STATE, &ev, sizeof(ev));
883 static void __bt_hal_handle_input_event(GVariant *msg, const char *path)
885 gboolean property_flag = FALSE;
886 GVariantIter value_iter;
887 char *property = NULL;
888 GVariant *child = NULL, *val = NULL;
891 g_variant_iter_init(&value_iter, msg);
892 while ((child = g_variant_iter_next_value(&value_iter))) {
893 g_variant_get(child, "{sv}", &property, &val);
895 if (property == NULL)
898 if (strcasecmp(property, "Connected") == 0) {
901 g_variant_get(val, "b", &property_flag);
902 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
903 _bt_hal_convert_device_path_to_address(path, address);
904 __bt_hal_send_hid_connection_state_event(property_flag, address);
908 g_variant_unref(val);
909 g_variant_unref(child);
915 static gboolean __bt_hal_parse_interface(GVariant *msg)
918 GVariant *optional_param;
921 char *interface_name = NULL;
922 GVariant *inner_iter = NULL;
923 g_variant_get(msg, "(&o@a{sa{sv}})",
924 &path, &optional_param);
925 g_variant_iter_init(&iter, optional_param);
927 while ((child = g_variant_iter_next_value(&iter))) {
928 g_variant_get(child, "{&s@a{sv}}", &interface_name, &inner_iter);
929 if (g_strcmp0(interface_name, BT_HAL_DEVICE_INTERFACE) == 0) {
930 DBG("Found a device: %s", path);
931 if (__bt_hal_parse_device_properties(inner_iter) == FALSE) {
932 g_variant_unref(inner_iter);
933 g_variant_unref(child);
934 g_variant_unref(optional_param);
935 ERR("Fail to parse the properies");
938 g_variant_unref(inner_iter);
939 g_variant_unref(child);
940 g_variant_unref(optional_param);
944 g_variant_unref(inner_iter);
945 g_variant_unref(child);
948 g_variant_unref(optional_param);
953 void __bt_hal_handle_gatt_char_event(GVariant *parameters, const char *signal_name)
957 if (signal_name == NULL)
960 if (strcasecmp(signal_name, "GattValueChanged") == 0) {
961 DBG("GattValueChanged event received");
964 const char *char_handle = NULL;
965 GVariant *char_value_var = NULL;
967 char *char_value = NULL;
969 g_variant_get(parameters, "(i&s@ay)", &result, &char_handle, &char_value_var);
970 DBG("char handle: %s", char_handle);
972 len = g_variant_get_size(char_value_var);
974 char_value = (char *)g_variant_get_data(char_value_var);
976 _bt_hal_handle_gattc_value_changed_event(result, char_handle, char_value, len);
978 g_variant_unref(char_value_var);
983 static gboolean __bt_hal_event_manager(gpointer data)
985 bt_hal_event_type_t bt_event = 0x00;
987 char *obj_path = NULL;
989 bt_hal_main_event_data_t *param = (bt_hal_main_event_data_t*)data;
990 if (strcasecmp(param->signal_name, "InterfacesAdded") == 0) {
992 /*TODO: Handle Interfaces Added Signal from stack */
993 DBG("Manager Event: Signal Name: InterfacesAdded");
995 g_variant_get(param->parameters, "(&o@a{sa{sv}})", &obj_path, &value);
997 if (obj_path == NULL) {
998 DBG("obj_path is NULL");
1002 if (strcasecmp(obj_path, BT_HAL_BLUEZ_HCI_PATH) == 0) {
1003 /* TODO: Handle adapter added */
1004 DBG("Manager Event: Signal Name: InterfiacesAdded: Adapter added in bluetoothd: path [hci0]");
1006 bt_event = __bt_hal_parse_event(value);
1007 if (bt_event == BT_HAL_DEVICE_EVENT) {
1008 DBG("Device path : %s ", obj_path);
1009 __bt_hal_handle_device_event(value, param->parameters);
1010 } else if (bt_event == BT_HAL_AVRCP_CONTROL_EVENT) {
1011 DBG("Device path : %s ", obj_path);
1012 _bt_hal_set_control_device_path(obj_path);
1015 g_variant_unref(value);
1017 } else if (strcasecmp(param->signal_name, "InterfacesRemoved") == 0) {
1021 /*TODO: Handle Interfaces Removed Signal from stack */
1022 DBG("Manager Event: Signal Name: InterfacesRemoved");
1024 g_variant_get(param->parameters, "(&oas)", &obj_path, &iter);
1025 DBG("Device path : %s ", obj_path);
1026 while (g_variant_iter_loop(iter, "s", &str)) {
1027 if (g_strcmp0(str, BT_HAL_PLAYER_CONTROL_INTERFACE) == 0)
1028 _bt_hal_remove_control_device_path(obj_path);
1030 g_variant_iter_free(iter);
1031 } else if (strcasecmp(param->signal_name, "NameOwnerChanged") == 0) {
1033 char *previous = NULL;
1034 char *current = NULL;
1036 if (g_strcmp0(g_variant_get_type_string(param->parameters), "(sss)") != 0) {
1037 ERR("Invalid variant format");
1041 /* TODO: Handle Name Owener changed Signal */
1042 if (__bt_hal_get_owner_info(param->parameters, &name, &previous, ¤t)) {
1043 DBG("Fail to get the owner info");
1047 if (*current != '\0')
1053 if (strcasecmp(name, BT_HAL_BLUEZ_NAME) == 0) {
1054 DBG("Bluetoothd is terminated");
1056 /* TODO: Handle Bluetoothd terminating scenario */
1057 _bt_hal_le_deinit();
1059 INFO("Name Owner changed [%s]", name);
1060 } else if (g_strcmp0(param->interface_name, BT_HAL_PROPERTIES_INTERFACE) == 0) {
1061 DBG("Manager Event: Interface Name: BT_HAL_PROPERTIES_INTERFACE");
1062 __bt_hal_handle_property_changed_event(param->parameters, param->object_path);
1063 } else if (g_strcmp0(param->interface_name, BT_HAL_ADAPTER_INTERFACE) == 0) {
1064 DBG("Manager Event: Interface Name: BT_HAL_ADAPTER_INTERFACE");
1065 _bt_hal_handle_adapter_event(param->parameters, param->signal_name);
1066 } else if (g_strcmp0(param->interface_name, BT_HAL_INPUT_INTERFACE) == 0) {
1067 DBG("Manager Event: Interface Name: BT_HAL_INPUT_INTERFACE");
1068 __bt_hal_handle_input_event(param->parameters, param->object_path);
1069 } else if (g_strcmp0(param->interface_name, BT_HAL_NETWORK_SERVER_INTERFACE) == 0) {
1070 /* TODO: Handle Network Server events from stack */
1071 DBG("Manager Event: Interface Name: BT_HAL_NETWORK_SERVER_INTERFACE");
1072 } else if (g_strcmp0(param->interface_name, BT_HAL_HEADSET_INTERFACE) == 0) {
1073 DBG("Manager Event: Interface Name: BT_HAL_HEADSET_INTERFACE");
1074 __bt_hal_handle_headset_events(param->parameters, param->signal_name, param->object_path);
1075 } else if (g_strcmp0(param->interface_name, BT_HAL_SINK_INTERFACE) == 0) {
1076 /* TODO: Handle Sink interface events from stack */
1077 DBG("Manager Event: Interface Name:BT_HAL_SINK_INTERFACE");
1078 } else if (g_strcmp0(param->interface_name, BT_HAL_AGENT_INTERFACE) == 0) {
1079 /* TODO: Handle Agent events from stack */
1080 DBG("Manager Event: Interface Name:BT_HAL_AGENT_INTERFACE");
1081 } else if (g_strcmp0(param->interface_name, BT_HAL_DEVICE_INTERFACE) == 0) {
1082 DBG("Manager Event: Interface Name:BT_HAL_DEVICE_INTERFACE");
1083 __bt_hal_handle_device_specific_events(param->parameters, param->signal_name, param->object_path);
1084 } else if (g_strcmp0(param->interface_name, BT_HAL_PLAYER_CONTROL_INTERFACE) == 0) {
1085 DBG("Manager Event: Interface Name: BT_HAL_PLAYER_CONTROL_INTERFACE");
1086 __bt_hal_handle_avrcp_ctrl_events(param->parameters, param->signal_name, param->object_path);
1087 } else if (g_strcmp0(param->interface_name, BT_HAL_MEDIATRANSPORT_INTERFACE) == 0) {
1088 DBG("Manager Event: Interface Name: BT_HAL_MEDIATRANSPORT_INTERFACE");
1089 __bt_hal_handle_avrcp_transport_events(param->parameters, param->signal_name, param->object_path);
1090 } else if (g_strcmp0(param->interface_name, BT_HAL_GATT_CHAR_INTERFACE) == 0) {
1091 DBG("Manager Event: Interface Name: BT_HAL_GATT_CHAR_INTERFACE");
1092 __bt_hal_handle_gatt_char_event(param->parameters, param->signal_name);
1097 g_free(param->sender_name);
1098 g_free(param->object_path);
1099 g_free(param->interface_name);
1100 g_free(param->signal_name);
1101 g_variant_unref(param->parameters);
1106 static void __bt_hal_manager_event_filter(GDBusConnection *connection,
1107 const gchar *sender_name,
1108 const gchar *object_path,
1109 const gchar *interface_name,
1110 const gchar *signal_name,
1111 GVariant *parameters,
1114 if (signal_name == NULL)
1117 bt_hal_main_event_data_t *param = g_new0(bt_hal_main_event_data_t, 1);
1118 param->sender_name = g_strdup(sender_name);
1119 param->object_path = g_strdup(object_path);
1120 param->interface_name = g_strdup(interface_name);
1121 param->signal_name = g_strdup(signal_name);
1122 param->parameters = g_variant_ref(parameters);
1124 g_idle_add(__bt_hal_event_manager, (gpointer)param);
1128 static void __bt_hal_handle_headset_events(GVariant *msg, const char *member, const char *path)
1130 gboolean property_flag = FALSE;
1131 char *property = NULL;
1132 GVariant *value = NULL;
1133 g_variant_get(msg, "(sv)", &property, &value);
1135 if (property == NULL)
1138 DBG("Property = %s \n", property);
1139 /* We allow only 1 headset connection (HSP or HFP)*/
1140 if (strcasecmp(property, "Connected") == 0) {
1142 g_variant_get(value, "b", &property_flag);
1144 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1146 /* Fix : NULL_RETURNS */
1147 if (address == NULL)
1150 _bt_hal_convert_device_path_to_address(path, address);
1151 __bt_hal_send_hf_audio_connection_state_event(property_flag, address);
1153 } else if (strcasecmp(property, "State") == 0) {
1156 g_variant_get(value, "s", &state);
1158 /* This code assumes we support only 1 headset connection */
1159 /* Need to use the headset list, if we support multi-headsets */
1160 if (strcasecmp(state, "Playing") == 0) {
1161 DBG("Playing: Sco Connected");
1162 } else if (strcasecmp(state, "connected") == 0 ||
1163 strcasecmp(state, "disconnected") == 0) {
1164 if (strcasecmp(state, "connected") == 0)
1165 DBG("Sco Connected");
1167 DBG("Sco Disconnected");
1169 ERR("Not handled state - %s", state);
1174 } else if (strcasecmp(property, "SpeakerGain") == 0) {
1177 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1179 _bt_hal_convert_device_path_to_address(path, address);
1180 INFO("Speaker Gain for address [%s]", address);
1181 /* TODO Handle event sending to HAL */
1184 } else if (strcasecmp(property, "MicrophoneGain") == 0) {
1187 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1189 _bt_hal_convert_device_path_to_address(path, address);
1190 INFO("Microphone Gain for address [%s]", address);
1191 /* TODO Handle event sending to HAL */
1198 g_variant_unref(value);
1201 static int __bt_hal_register_manager_subscribe_signal(GDBusConnection *conn,
1207 static int subs_interface_added_id = -1;
1208 static int subs_interface_removed_id = -1;
1209 static int subs_name_owner_id = -1;
1210 static int subs_property_id = -1;
1211 static int subs_adapter_id = -1;
1216 if (subs_interface_added_id == -1) {
1217 subs_interface_added_id = g_dbus_connection_signal_subscribe(conn,
1218 NULL, BT_HAL_MANAGER_INTERFACE,
1219 BT_HAL_INTERFACES_ADDED, NULL, NULL, 0,
1220 __bt_hal_manager_event_filter,
1223 if (subs_interface_removed_id == -1) {
1224 subs_interface_removed_id = g_dbus_connection_signal_subscribe(conn,
1225 NULL, BT_HAL_MANAGER_INTERFACE,
1226 BT_HAL_INTERFACES_REMOVED, NULL, NULL, 0,
1227 __bt_hal_manager_event_filter,
1230 if (subs_name_owner_id == -1) {
1231 subs_name_owner_id = g_dbus_connection_signal_subscribe(conn,
1232 NULL, BT_HAL_FREEDESKTOP_INTERFACE,
1233 BT_HAL_NAME_OWNER_CHANGED, NULL, NULL, 0,
1234 __bt_hal_manager_event_filter,
1237 if (subs_property_id == -1) {
1238 subs_property_id = g_dbus_connection_signal_subscribe(conn,
1239 NULL, BT_HAL_PROPERTIES_INTERFACE,
1240 BT_HAL_PROPERTIES_CHANGED, NULL, NULL, 0,
1241 __bt_hal_manager_event_filter,
1244 if (subs_adapter_id == -1) {
1245 subs_adapter_id = g_dbus_connection_signal_subscribe(conn,
1246 NULL, BT_HAL_ADAPTER_INTERFACE,
1247 NULL, NULL, NULL, 0,
1248 __bt_hal_manager_event_filter,
1252 if (subs_interface_added_id != -1) {
1253 g_dbus_connection_signal_unsubscribe(conn,
1254 subs_interface_added_id);
1255 subs_interface_added_id = -1;
1257 if (subs_interface_removed_id != -1) {
1258 g_dbus_connection_signal_unsubscribe(conn,
1259 subs_interface_removed_id);
1260 subs_interface_removed_id = -1;
1262 if (subs_name_owner_id != -1) {
1263 g_dbus_connection_signal_unsubscribe(conn,
1264 subs_name_owner_id);
1265 subs_name_owner_id = -1;
1267 if (subs_property_id != -1) {
1268 g_dbus_connection_signal_unsubscribe(conn,
1270 subs_property_id = -1;
1272 if (subs_adapter_id == -1) {
1273 g_dbus_connection_signal_unsubscribe(conn, subs_adapter_id);
1274 subs_adapter_id = -1;
1282 static int __bt_hal_register_device_subscribe_signal(GDBusConnection *conn,
1285 static int subs_device_id = -1;
1292 if (subs_device_id == -1) {
1293 subs_device_id = g_dbus_connection_signal_subscribe(conn,
1294 NULL, BT_HAL_DEVICE_INTERFACE,
1295 NULL, NULL, NULL, 0,
1296 __bt_hal_manager_event_filter,
1300 if (subs_device_id != -1) {
1301 g_dbus_connection_signal_unsubscribe(conn,
1303 subs_device_id = -1;
1311 static int __bt_hal_register_input_subscribe_signal(GDBusConnection *conn, int subscribe)
1313 static int subs_input_id = -1;
1321 if (subs_input_id == -1) {
1322 subs_input_id = g_dbus_connection_signal_subscribe(conn,
1323 NULL, BT_HAL_INPUT_INTERFACE,
1324 NULL, NULL, NULL, 0,
1325 __bt_hal_manager_event_filter,
1329 if (subs_input_id != -1) {
1330 g_dbus_connection_signal_unsubscribe(conn,
1341 static int __bt_hal_register_gatt_subscribe_signal(GDBusConnection *conn,
1344 static int subs_gatt_id = -1;
1349 if (subs_gatt_id == -1) {
1350 subs_gatt_id = g_dbus_connection_signal_subscribe(conn,
1351 NULL, BT_HAL_GATT_CHAR_INTERFACE,
1352 NULL, NULL, NULL, 0,
1353 __bt_hal_manager_event_filter,
1357 if (subs_gatt_id == -1) {
1358 g_dbus_connection_signal_unsubscribe(conn,
1364 return BT_HAL_ERROR_NONE;
1369 static int __bt_hal_register_service_event(GDBusConnection *g_conn, int event_type)
1374 return BT_HAL_ERROR_INTERNAL;
1376 /* TODO: Add more events in subsequent patches */
1377 switch (event_type) {
1378 case BT_HAL_MANAGER_EVENT:
1379 __bt_hal_register_manager_subscribe_signal(g_conn, TRUE);
1381 case BT_HAL_DEVICE_EVENT:
1382 __bt_hal_register_device_subscribe_signal(g_conn, TRUE);
1384 case BT_HAL_HID_EVENT:
1385 __bt_hal_register_input_subscribe_signal(g_conn, TRUE);
1387 case BT_HAL_HEADSET_EVENT:
1388 __bt_hal_register_audio_subscribe_signal(g_conn, TRUE);
1390 case BT_HAL_GATT_EVENT:
1391 __bt_hal_register_gatt_subscribe_signal(g_conn, TRUE);
1394 INFO_C("Register Event: event_type [%d]", event_type);
1395 return BT_HAL_ERROR_NOT_SUPPORT;
1398 return BT_HAL_ERROR_NONE;
1401 static int __bt_hal_register_audio_subscribe_signal(GDBusConnection *conn,
1407 static int subs_headset_id = -1;
1408 static int subs_sink_id = -1;
1411 if (subs_headset_id == -1) {
1412 subs_headset_id = g_dbus_connection_signal_subscribe(conn,
1413 NULL, BT_HAL_HEADSET_INTERFACE,
1414 NULL, NULL, NULL, 0,
1415 __bt_hal_manager_event_filter,
1418 if (subs_sink_id == -1) {
1419 subs_sink_id = g_dbus_connection_signal_subscribe(conn,
1420 NULL, BT_HAL_SINK_INTERFACE,
1421 NULL, NULL, NULL, 0,
1422 __bt_hal_manager_event_filter,
1426 if (subs_headset_id != -1) {
1427 g_dbus_connection_signal_unsubscribe(conn,
1429 subs_headset_id = -1;
1431 if (subs_sink_id != -1) {
1432 g_dbus_connection_signal_unsubscribe(conn,
1440 static int __bt_hal_initialize_manager_receiver(void)
1444 GError *error = NULL;
1446 if (manager_conn == NULL) {
1447 manager_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
1448 if (error != NULL) {
1449 ERR_C("ERROR: Can't get on system bus [%s]", error->message);
1450 g_clear_error(&error);
1452 if (manager_conn == NULL)
1456 if (__bt_hal_register_service_event(manager_conn,
1457 BT_HAL_MANAGER_EVENT) != BT_HAL_ERROR_NONE)
1459 if (__bt_hal_register_service_event(manager_conn,
1460 BT_HAL_DEVICE_EVENT) != BT_HAL_ERROR_NONE)
1462 if (__bt_hal_register_service_event(manager_conn,
1463 BT_HAL_HID_EVENT) != BT_HAL_ERROR_NONE)
1465 if (__bt_hal_register_service_event(manager_conn,
1466 BT_HAL_HEADSET_EVENT) != BT_HAL_ERROR_NONE)
1468 if (__bt_hal_register_service_event(manager_conn,
1469 BT_HAL_GATT_EVENT) != BT_HAL_ERROR_NONE)
1471 return BT_HAL_ERROR_NONE;
1474 g_object_unref(manager_conn);
1475 manager_conn = NULL;
1480 return BT_HAL_ERROR_INTERNAL;
1483 /* To receive the event from bluez */
1484 int _bt_hal_initialize_event_receiver(handle_stack_msg cb)
1490 return BT_HAL_ERROR_INVALID_PARAM;
1492 result = __bt_hal_initialize_manager_receiver();
1494 DBG("Manager event receiver initialization result [%d]", result);
1495 if (result != BT_HAL_ERROR_NONE)
1498 /*TODO: Initialize Obexd Event receiver */
1500 /* Initialize event receiver for flight mode */
1501 _bt_hal_register_vconf_handler();
1506 return BT_HAL_ERROR_NONE;
1509 static void __bt_hal_device_property_changed_event(GVariant *msg, const char *path)
1511 GVariantIter value_iter;
1512 GVariant *value = NULL;
1514 g_variant_iter_init(&value_iter, msg);
1517 while (g_variant_iter_loop(&value_iter, "{sv}", &key, &value)) {
1518 if (!g_strcmp0(key, "Connected")) {
1519 guint connected = 0;
1520 g_variant_get(value, "i", &connected);
1521 DBG("Device property changed : Connected [%d]", connected);
1522 } else if (!g_strcmp0(key, "RSSI")) {
1523 DBG("Device property changed : RSSI");
1524 __bt_hal_dbus_device_found_properties(path);
1525 } else if (!g_strcmp0(key, "GattConnected")) {
1526 DBG("Device property changed : GattConnected");
1527 gboolean gatt_connected = FALSE;
1528 g_variant_get(value, "b", &gatt_connected);
1529 char *address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1530 _bt_hal_convert_device_path_to_address(path, address);
1531 DBG("@@gatt_connected: %d", gatt_connected);
1532 DBG("@@address: %s", address);
1533 if (_bt_hal_check_gattc_is_existing(address) == TRUE) {
1534 DBG("GattConnected event will be handled on CLIENT side");
1535 _bt_hal_handle_gattc_connected_event(address, gatt_connected);
1537 DBG("GattConnected event will be handled on SERVER side");
1538 _bt_hal_gatt_connected_state_event(gatt_connected, address);
1541 } else if (!g_strcmp0(key, "Paired")) {
1542 gboolean paired = FALSE;
1543 struct hal_ev_bond_state_changed ev;
1544 char address[BT_HAL_ADDRESS_STRING_SIZE];
1546 g_variant_get(value, "b", &paired);
1547 DBG("Device property changed : Paired = %s", (paired ? "TRUE" : "FALSE"));
1549 _bt_hal_agent_set_canceled(FALSE);
1550 _bt_hal_convert_device_path_to_address(path, address);
1552 /* Prepare to send event to HAL bluetooth */
1553 ev.status = BT_STATUS_SUCCESS;
1554 ev.state = paired ? BT_BOND_STATE_BONDED : BT_BOND_STATE_NONE;
1555 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
1558 ERR("Bluetooth HAL event handler not registered");
1560 DBG("Sending HAL_EV_BOND_STATE_CHANGED event");
1561 event_cb(HAL_EV_BOND_STATE_CHANGED, (void*)&ev, sizeof(ev));
1563 } else if (!g_strcmp0(key, "LegacyPaired")) {
1564 DBG("Device property changed : LegacyPaired");
1565 } else if (!g_strcmp0(key, "Trusted")) {
1566 DBG("Device property changed : Trusted");
1567 gboolean trusted = FALSE;
1568 gchar *address = NULL;
1569 g_variant_get(value, "b", &trusted);
1570 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1572 _bt_hal_convert_device_path_to_address(path, address);
1573 DBG("Device [%s] trusted: [%d]", address, trusted);
1575 __bt_hal_send_device_trust_state_event(trusted, address);
1577 } else if (!g_strcmp0(key, "IpspConnected")) {
1578 DBG("Device property changed : IpspConnected");
1579 } else if (!g_strcmp0(key, "IpspInitStateChanged")) {
1580 DBG("Device property changed : IpspInitStateChanged");
1581 } else if (!g_strcmp0(key, "TrustedProfiles")) {
1583 char address[BT_HAL_ADDRESS_STRING_SIZE];
1585 g_variant_get(value, "u", &trust_val);
1586 _bt_hal_convert_device_path_to_address(path, address);
1587 DBG("Address: %s, TrustedProfiles: 0x%X", address, trust_val);
1588 __bt_hal_send_device_trusted_profile_changed_event(trust_val, address);
1590 ERR("Unhandled Property:[%s]", key);
1596 static void __bt_hal_dbus_device_found_properties(const char *device_path)
1599 GError *error = NULL;
1600 GDBusProxy *device_proxy;
1601 GDBusConnection *conn;
1606 ERR("Invalid device path");
1610 conn = _bt_hal_get_system_gconn();
1612 ERR("_bt_hal_get_system_gconn failed");
1616 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1620 BT_HAL_PROPERTIES_INTERFACE,
1623 if (!device_proxy) {
1624 ERR("Error creating device_proxy");
1628 result = g_dbus_proxy_call_sync(device_proxy,
1630 g_variant_new("(s)", BT_HAL_DEVICE_INTERFACE),
1631 G_DBUS_CALL_FLAGS_NONE,
1636 ERR("Error occured in Proxy call");
1637 if (error != NULL) {
1638 ERR("Error occured in Proxy call (Error: %s)", error->message);
1639 g_clear_error(&error);
1641 g_object_unref(device_proxy);
1645 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1646 _bt_hal_convert_device_path_to_address(device_path, address);
1648 __bt_hal_device_properties_lookup(result, address);
1650 g_object_unref(device_proxy);
1656 static void __bt_hal_device_properties_lookup(GVariant *result, char *address)
1658 /* Buffer and propety count management */
1659 uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
1660 struct hal_ev_device_found *ev = (void *) buf;
1662 memset(buf, 0, sizeof(buf));
1666 GVariant *tmp_value;
1669 gchar *manufacturer_data = NULL;
1672 if (result != NULL) {
1673 g_variant_get(result , "(@a{sv})", &value);
1674 g_variant_unref(result);
1677 tmp_value = g_variant_lookup_value(value, "Alias", G_VARIANT_TYPE_STRING);
1679 g_variant_get(tmp_value, "s", &name);
1681 g_variant_unref(tmp_value);
1683 DBG_SECURE("Alias Name [%s]", name);
1684 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_NAME,
1685 strlen(name) + 1, name);
1687 DBG("Device Name [%s] Property num [%d]", name, ev->num_props);
1690 tmp_value = g_variant_lookup_value(value, "Name", G_VARIANT_TYPE_STRING);
1691 g_variant_get(tmp_value, "s", &name);
1692 g_variant_unref(tmp_value);
1694 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_NAME,
1695 strlen(name) + 1, name);
1697 DBG("Device Name [%s] Property num [%d]", name, ev->num_props);
1698 g_variant_get(tmp_value, "s", &name);
1702 tmp_value = g_variant_lookup_value(value, "Class", G_VARIANT_TYPE_UINT32);
1703 unsigned int class = tmp_value ? g_variant_get_uint32(tmp_value) : 0;
1704 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_CLASS,
1705 sizeof(unsigned int), &class);
1708 g_variant_unref(tmp_value);
1712 tmp_value = g_variant_lookup_value(value, "Connected", G_VARIANT_TYPE_BOOLEAN);
1713 unsigned int connected = tmp_value ? g_variant_get_boolean(tmp_value) : 0;
1714 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_CONNECTED,
1715 sizeof(unsigned int), &connected);
1717 DBG("Device connected [%u] Property num [%d]", connected, ev->num_props);
1719 g_variant_unref(tmp_value);
1722 tmp_value = g_variant_lookup_value(value, "Trusted", G_VARIANT_TYPE_BOOLEAN);
1723 uint8_t trust = tmp_value ? (g_variant_get_boolean(tmp_value) ? 1 : 0) : 0;
1724 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_TRUSTED,
1725 sizeof(uint8_t), &trust);
1727 DBG("Device trusted [%d] Property num [%d]", trust, ev->num_props);
1729 g_variant_unref(tmp_value);
1732 tmp_value = g_variant_lookup_value(value, "Paired", G_VARIANT_TYPE_BOOLEAN);
1733 uint8_t paired = tmp_value ? (g_variant_get_boolean(tmp_value) ? 1 : 0) : 0;
1735 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_PAIRED,
1736 sizeof(uint8_t), &paired);
1738 DBG("Device Paired [%d] Property num [%d]", paired, ev->num_props);
1740 g_variant_unref(tmp_value);
1743 tmp_value = g_variant_lookup_value(value, "RSSI", G_VARIANT_TYPE_INT32);
1744 int rssi = tmp_value ? g_variant_get_int32(tmp_value) : 0;
1745 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_RSSI,
1746 sizeof(int), &rssi);
1748 DBG("Device RSSI [%d] Property num [%d]", rssi, ev->num_props);
1750 g_variant_unref(tmp_value);
1752 /* Last Addr Type */
1753 tmp_value = g_variant_lookup_value(value, "LastAddrType", G_VARIANT_TYPE_UINT32);
1754 unsigned int addr_type = tmp_value ? g_variant_get_uint32(tmp_value) : 0;
1756 g_variant_unref(tmp_value);
1757 DBG("Device Last Address Type [0x%x]", addr_type);
1760 tmp_value = g_variant_lookup_value(value, "IsAliasSet", G_VARIANT_TYPE_UINT32);
1761 uint8_t is_alias_set = tmp_value ? (g_variant_get_boolean(tmp_value) ? 1 : 0) : 0;
1762 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_IS_ALIAS_SET,
1763 sizeof(uint8_t), &is_alias_set);
1765 DBG("IsAliasSet: [%s], Property num [%d]", (is_alias_set ? "TRUE" : "FALSE"), ev->num_props);
1767 g_variant_unref(tmp_value);
1770 tmp_value = g_variant_lookup_value(value, "UUIDs", G_VARIANT_TYPE_STRING_ARRAY);
1771 gsize uuid_count = g_variant_get_size(tmp_value);
1772 char **uuid_value = g_variant_dup_strv(tmp_value, &uuid_count);
1774 /* UUID collection */
1779 int num_props_tmp = ev->num_props;
1781 uint8_t uuids[BT_HAL_STACK_UUID_SIZE * uuid_count];
1783 for (i = 0; uuid_value[i] != NULL; i++) {
1785 char *uuid_str = NULL;
1786 uint8_t uuid[BT_HAL_STACK_UUID_SIZE];
1787 memset(uuid, 0x00, BT_HAL_STACK_UUID_SIZE);
1789 DBG("UUID string from Bluez [%s]\n", uuid_value[i]);
1790 uuid_str = g_strdup(uuid_value[i]);
1791 DBG("UUID string [%s]\n", uuid_str);
1793 _bt_hal_convert_uuid_string_to_type(uuid, uuid_str);
1795 for (z = 0; z < 16; z++)
1796 DBG("[0x%x]", uuid[z]);
1799 memcpy(uuids+i*BT_HAL_STACK_UUID_SIZE, uuid, BT_HAL_STACK_UUID_SIZE);
1803 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_UUIDS,
1804 (BT_HAL_STACK_UUID_SIZE * uuid_count),
1806 ev->num_props = num_props_tmp + 1;
1809 g_variant_unref(tmp_value);
1811 /* LegacyManufacturerDataLen */
1812 tmp_value = g_variant_lookup_value(value, "LegacyManufacturerDataLen", G_VARIANT_TYPE_UINT32);
1813 unsigned int manufacturer_data_len = tmp_value ? g_variant_get_uint32(tmp_value) : 0;
1814 if (manufacturer_data_len > BT_HAL_MANUFACTURER_DATA_LENGTH_MAX) {
1815 ERR("manufacturer_data_len is too long(len = %d)", manufacturer_data_len);
1816 manufacturer_data_len = BT_HAL_MANUFACTURER_DATA_LENGTH_MAX;
1819 g_variant_unref(tmp_value);
1820 /*size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_MANUFACTURER_DATA_LEN,
1821 sizeof(unsigned int), &manufacturer_data_len);
1823 DBG("Device Legacy Manufacturer data length [%u]", manufacturer_data_len);
1825 /* ManufacturerData */
1826 tmp_value = g_variant_lookup_value(value, "LegacyManufacturerData", G_VARIANT_TYPE_BYTESTRING);
1827 manufacturer_data = value ? (gchar *)g_variant_get_bytestring(tmp_value) : NULL;
1828 if (manufacturer_data) {
1829 if (manufacturer_data_len > 0) {
1830 //size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_MANUFACTURER_DATA,
1831 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_BLE_ADV_DATA,
1832 manufacturer_data_len, manufacturer_data);
1837 g_variant_unref(tmp_value);
1841 _bt_hal_convert_addr_string_to_type(bdaddr, address);
1842 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_ADDR,
1843 sizeof(bdaddr), bdaddr);
1845 DBG("Device address [%s] property Num [%d]", address, ev->num_props);
1848 g_variant_unref(value);
1850 ERR("result is NULL\n");
1853 DBG("Send Device found event to HAL user, Num Prop [%d] total size [%zd]", ev->num_props, size);
1854 event_cb(HAL_EV_DEVICE_FOUND, (void*) buf, size);
1859 static void __bt_hal_send_device_acl_connection_state_event(int status, gboolean connected, const char *address)
1862 struct hal_ev_acl_state_changed ev;
1865 ev.state = (connected == TRUE) ?
1866 HAL_ACL_STATE_CONNECTED :
1867 HAL_ACL_STATE_DISCONNECTED;
1869 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
1872 ERR("Bluetooth HAL event handler not registered");
1874 event_cb(HAL_EV_ACL_STATE_CHANGED, &ev, sizeof(ev));
1878 static void __bt_hal_send_device_le_connection_state_event(int status, gboolean connected, const char *address)
1881 struct hal_ev_le_conn_state_changed ev;
1884 ev.state = (connected == TRUE) ?
1885 HAL_LE_STATE_CONNECTED :
1886 HAL_LE_STATE_DISCONNECTED;
1888 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
1891 ERR("Bluetooth HAL event handler not registered");
1893 event_cb(HAL_EV_LE_CONN_STATE_CHANGED, &ev, sizeof(ev));
1897 static void __bt_hal_send_device_trust_state_event(gboolean is_trusted,
1898 const char *address)
1900 struct hal_ev_device_trust_state_changed ev;
1903 ev.trust = (is_trusted == TRUE) ?
1904 HAL_DEVICE_TRUSTED :
1905 HAL_DEVICE_UNTRUSTED;
1907 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
1910 ERR("Bluetooth HAL event handler not registered");
1912 event_cb(HAL_EV_DEVICE_TRUST_CHANGED, &ev, sizeof(ev));
1916 static void __bt_hal_send_device_trusted_profile_changed_event(
1917 uint32_t trust_val, const char *address)
1919 struct hal_ev_device_trusted_profiles_changed ev;
1922 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
1923 ev.trust_val = trust_val;
1926 ERR("Bluetooth HAL event handler not registered");
1928 event_cb(HAL_EV_DEVICE_TRUSTED_PROFILES_CHANGED, &ev, sizeof(ev));
1932 static void __bt_hal_handle_device_specific_events(GVariant *msg, const char *member,
1936 const char *property = NULL;
1940 if (strcasecmp(member, "PropertyChanged") == 0) {
1941 g_variant_get(msg, "(s)", &property);
1942 if (property == NULL)
1944 if (strcasecmp(property, "GattConnected") == 0) {
1945 INFO("GATT Connected");
1946 gboolean connected = FALSE;
1948 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1950 _bt_hal_convert_device_path_to_address(path, address);
1951 g_variant_get(msg, "(b)", &connected);
1953 INFO("Connected device address[%s] connnected[%d]", address, connected);
1955 } else if (strcasecmp(property, "Paired") == 0) {
1956 gboolean paired = FALSE;
1957 struct hal_ev_bond_state_changed ev;
1958 char address[BT_HAL_ADDRESS_STRING_SIZE];
1960 g_variant_get(msg, "(b)", &paired);
1961 DBG("Device property changed : Paired = %s", (paired ? "TRUE" : "FALSE"));
1963 _bt_hal_agent_set_canceled(FALSE);
1964 _bt_hal_convert_device_path_to_address(path, address);
1966 /* Prepare to send event to HAL bluetooth */
1967 ev.status = BT_STATUS_SUCCESS;
1968 ev.state = paired ? BT_BOND_STATE_BONDED : BT_BOND_STATE_NONE;
1969 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
1972 ERR("Bluetooth HAL event handler not registered");
1974 DBG("Sending HAL_EV_BOND_STATE_CHANGED event");
1975 event_cb(HAL_EV_BOND_STATE_CHANGED, (void*)&ev, sizeof(ev));
1977 } else if (strcasecmp(property, "UUIDs") == 0) {
1980 } else if (strcasecmp(member, "DeviceConnected") == 0) {
1981 unsigned char addr_type = 0;
1983 g_variant_get(msg, "(y)", &addr_type);
1985 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1986 _bt_hal_convert_device_path_to_address(path, address);
1988 DBG("Member: [%s]", member);
1989 ERR_C("Connected [%s] [%s]", !addr_type ? "BREDR" : "LE", address);
1991 __bt_hal_send_device_acl_connection_state_event(BT_STATUS_SUCCESS, TRUE, address);
1993 __bt_hal_send_device_le_connection_state_event(BT_STATUS_SUCCESS, TRUE, address);
1995 } else if (strcasecmp(member, "Disconnected") == 0) {
1996 unsigned char disc_reason = 0;
1997 unsigned char addr_type = 0;
2000 g_variant_get(msg, "(yy&s)", &addr_type, &disc_reason, &name);
2002 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
2003 _bt_hal_convert_device_path_to_address(path, address);
2005 DBG("Member: [%s]", member);
2007 ERR_C("DisConnected [%s] [%s]", !addr_type ? "BREDR" : "LE", address);
2008 DBG("Disconnected Reason [%d : %s]", disc_reason, _bt_hal_convert_disc_reason_to_string(disc_reason));
2009 DBG("Name: %s", name);
2011 __bt_hal_send_device_acl_connection_state_event(_bt_hal_convert_disc_reason_to_status(disc_reason), FALSE, address);
2013 __bt_hal_send_device_le_connection_state_event(_bt_hal_convert_disc_reason_to_status(disc_reason), FALSE, address);
2015 } else if (strcasecmp(member, "ProfileStateChanged") == 0) {
2017 char *profile_uuid = NULL;
2019 g_variant_get(msg, "(si)", &profile_uuid, &state);
2020 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
2021 _bt_hal_convert_device_path_to_address(path, address);
2023 DBG("Address: %s", address);
2024 DBG("Profile UUID: %s", profile_uuid);
2025 DBG("State: %d", state);
2026 if (strncmp(profile_uuid, HID_UUID, strlen(HID_UUID)) == 0) {
2027 if (state == BT_HAL_PROFILE_STATE_CONNECTED)
2028 __bt_hal_send_hid_connection_state_event(TRUE, address);
2029 else if (state == BT_HAL_PROFILE_STATE_DISCONNECTED)
2030 __bt_hal_send_hid_connection_state_event(FALSE, address);
2032 DBG("Profile state: %d", state);
2034 } else if ((strncmp(profile_uuid, A2DP_SINK_UUID, strlen(A2DP_SINK_UUID)) == 0)) {
2035 if (state == BT_HAL_PROFILE_STATE_CONNECTED) {
2036 DBG("A2DP Profile state changed: BT_PROFILE_STATE_CONNECTED");
2037 __bt_hal_send_av_connection_state_event(TRUE, address);
2038 } else if (state == BT_HAL_PROFILE_STATE_DISCONNECTED) {
2039 DBG("A2DP Profile state changed: BT_PROFILE_STATE_DISCONNECTED");
2040 __bt_hal_send_av_connection_state_event(FALSE, address);
2041 } else if (state == BT_HAL_PROFILE_STATE_DISCONNECTING) {
2042 DBG("A2DP Profile state changed: BT_PROFILE_STATE_DISCONNECTING");
2043 } else if (state == BT_HAL_PROFILE_STATE_CONNECTING) {
2044 DBG("A2DP Profile state changed: BT_PROFILE_STATE_CONNECTING");
2046 ERR("A2DP Profile state: Invalid");
2048 } else if ((strncmp(profile_uuid, A2DP_SOURCE_UUID, strlen(A2DP_SOURCE_UUID)) == 0)) {
2049 if (state == BT_HAL_PROFILE_STATE_CONNECTED) {
2050 DBG("A2DP Sink Profile state changed: BT_HAL_PROFILE_STATE_CONNECTED");
2051 __bt_hal_send_a2dp_sink_connection_state_event(TRUE, address);
2052 } else if (state == BT_HAL_PROFILE_STATE_DISCONNECTED) {
2053 DBG("A2DP Sink Profile state changed: BT_HAL_PROFILE_STATE_DISCONNECTED");
2054 __bt_hal_send_a2dp_sink_connection_state_event(FALSE, address);
2055 } else if (state == BT_HAL_PROFILE_STATE_DISCONNECTING) {
2056 DBG("A2DP Sink Profile state changed: BT_HAL_PROFILE_STATE_DISCONNECTING");
2057 } else if (state == BT_HAL_PROFILE_STATE_CONNECTING) {
2058 DBG("A2DP Sink Profile state changed: BT_HAL_PROFILE_STATE_CONNECTING");
2060 } else if (strncmp(profile_uuid, HFP_HF_UUID, strlen(HFP_HF_UUID)) == 0) {
2061 if (state == BT_HAL_PROFILE_STATE_CONNECTING)
2062 DBG("HFP Profile state changed: BT_PROFILE_STATE_CONNECTING");
2063 else if (state == BT_HAL_PROFILE_STATE_CONNECTED) {
2064 DBG("HFP Profile state changed: BT_PROFILE_STATE_CONNECTED");
2065 __bt_hal_send_hf_connection_state_event(TRUE, address);
2066 } else if (state == BT_HAL_PROFILE_STATE_DISCONNECTED) {
2067 DBG("HFP Profile state changed: BT_PROFILE_STATE_DISCONNECTED");
2068 __bt_hal_send_hf_connection_state_event(FALSE, address);
2069 } else if (state == BT_HAL_PROFILE_STATE_DISCONNECTING) {
2070 DBG("HFP Profile state changed: BT_PROFILE_STATE_DISCONNECTING");
2072 ERR("HFP Profile state: Invalid");
2074 } else if ((strncmp(profile_uuid, AVRCP_TARGET_UUID, strlen(AVRCP_TARGET_UUID)) == 0)) {
2075 if (state == BT_HAL_PROFILE_STATE_CONNECTED) {
2076 DBG("AVRCP Controller Profile state changed: BT_HAL_PROFILE_STATE_CONNECTED");
2077 __bt_hal_send_avrcp_ctrl_connection_state_event(TRUE, address);
2078 } else if (state == BT_HAL_PROFILE_STATE_DISCONNECTED) {
2079 DBG("AVRCP Controller Profile state changed: BT_HAL_PROFILE_STATE_DISCONNECTED");
2080 __bt_hal_send_avrcp_ctrl_connection_state_event(FALSE, address);
2081 } else if (state == BT_HAL_PROFILE_STATE_DISCONNECTING) {
2082 DBG("AVRCP Controller Profile state changed: BT_HAL_PROFILE_STATE_DISCONNECTING");
2083 } else if (state == BT_HAL_PROFILE_STATE_CONNECTING) {
2084 DBG("AVRCP Controller Profile state changed: BT_HAL_PROFILE_STATE_CONNECTING");
2087 DBG("Profile[%s] State changed status [%d] ", profile_uuid, state);
2090 g_free(profile_uuid);
2091 } else if (strcasecmp(member, "AttMtuChanged") == 0) {
2095 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
2097 DBG("Member: [%s]", member);
2099 _bt_hal_convert_device_path_to_address(path, address);
2100 g_variant_get(msg, "(q)", &mtu);
2102 __bt_hal_handle_gatts_mtu_changed_event(address, mtu);
2105 } else if (strcasecmp(member, "AdvReport") == 0) {
2106 DBG("Member: [%s]", member);
2107 __bt_hal_handle_adv_report(msg, path);
2111 static void __bt_hal_handle_adv_report(GVariant *msg, const char *path)
2113 uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
2114 struct hal_ev_gatt_client_scan_result *ev = (void *)buf;
2116 char *address = NULL;
2117 GVariant *value = NULL;
2118 char *buffer = NULL;
2121 uint8_t addr_type = 0;
2122 uint8_t adv_type = 0;
2128 memset(buf, 0, sizeof(buf));
2131 g_variant_get(msg, "(&syyii@ay)", &address, &addr_type,
2132 &adv_type, &rssi, &data_len, &value);
2134 buffer_len = g_variant_get_size(value);
2136 buffer = (char *)g_variant_get_data(value);
2138 if (data_len != buffer_len) {
2139 ERR("Unexpected: buffer_len: %d, data_len: %d",
2140 buffer_len, data_len);
2141 data_len = buffer_len;
2144 DBG("Address: %s, len: %d, rssi: %d, addr_type: 0x%02X, adv_type: 0x%02X",
2145 address, data_len, rssi, addr_type, adv_type);
2147 _bt_hal_convert_addr_string_to_type(ev->bd_addr, address);
2148 ev->addr_type = addr_type;
2149 ev->adv_type = adv_type;
2152 memcpy(ev->adv_data, buffer, data_len);
2155 DBG("Send le scan result event to HAL, size: [%zd]", size);
2156 gatt_event_cb(HAL_EV_GATT_CLIENT_SCAN_RESULT, buf, size);
2157 g_variant_unref(value);
2160 static void __bt_hal_handle_gatts_mtu_changed_event(char *address, int mtu)
2162 uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
2163 struct hal_ev_gatt_server_mtu_changed *ev = (void *)buf;
2169 memset(buf, 0, sizeof(buf));
2172 DBG("Address: %s, mtu: %d", address, mtu);
2174 ev->conn_id = _bt_get_remote_gatt_client_conn_id(address);
2177 DBG("Send GATT server mtu changed event to HAL, size: [%zd]", size);
2178 gatt_event_cb(HAL_EV_GATT_SERVER_MTU_CHANGED, buf, size);
2181 /* AVRCP Controller Role(Remote:AVRCP Target) Events */
2182 static void __bt_hal_send_avrcp_ctrl_connection_state_event(gboolean connected, const char *address)
2185 struct hal_ev_avrcp_ctrl_conn_state ev;
2187 if (connected == TRUE)
2188 INFO("AVRCP(Controller) Profile Connected for address [%s]", address);
2190 INFO("AVRCP(Controller) Profile DisConnected for address [%s]", address);
2192 if (connected == TRUE)
2193 ev.state = HAL_AVRCP_CTRL_STATE_CONNECTED;
2195 ev.state = HAL_AVRCP_CTRL_STATE_DISCONNECTED;
2196 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2198 if (!a2dp_sink_event_cb)
2199 ERR("AV event handler not registered");
2201 avrcp_ctrl_event_cb(HAL_EV_AVRCP_CTRL_CONN_STATE, &ev, sizeof(ev));
2204 static int __bt_media_attr_to_type(const char *str)
2206 if (!strcasecmp(str, "Equalizer"))
2207 return HAL_PLAYER_ATTR_EQUALIZER;
2208 else if (!strcasecmp(str, "Repeat"))
2209 return HAL_PLAYER_ATTR_REPEAT;
2210 else if (!strcasecmp(str, "Shuffle"))
2211 return HAL_PLAYER_ATTR_SHUFFLE;
2212 else if (!strcasecmp(str, "Scan"))
2213 return HAL_PLAYER_ATTR_SCAN;
2219 static int __bt_hal_play_status_str_to_type(const char *value)
2221 if (!strcmp(value, "stopped"))
2222 return HAL_PLAYSTATE_STOPPED;
2223 else if (!strcmp(value, "playing"))
2224 return HAL_PLAYSTATE_PLAYING;
2225 else if (!strcmp(value, "paused"))
2226 return HAL_PLAYSTATE_PAUSED;
2227 else if (!strcmp(value, "forward-seek"))
2228 return HAL_PLAYSTATE_FWD_SEEK;
2229 else if (!strcmp(value, "reverse-seek"))
2230 return HAL_PLAYSTATE_REV_SEEK;
2232 return HAL_PLAYSTATE_ERROR;
2235 static void __bt_avrcp_control_parse_properties(struct hal_ev_track_changed *ev, GVariant *item)
2237 GVariant *value = NULL;
2239 char *value_string = NULL;
2240 const char *key = NULL;
2246 g_variant_iter_init(&iter, item);
2247 while (g_variant_iter_loop(&iter, "{sv}", &key, &value)) {
2248 if (strcasecmp(key, "Title") == 0) {
2249 value_string = (char *)g_variant_get_string(value, NULL);
2250 DBG("Value : %s ", value_string);
2251 ev->attr[i].attr_id = HAL_MEDIA_ATTR_ID_TITLE;
2252 g_strlcpy((gchar *)ev->attr[i].text, value_string, HAL_MAX_ATTR_STR_LEN);
2254 } else if (strcasecmp(key, "Artist") == 0) {
2255 value_string = (char *)g_variant_get_string(value, NULL);
2256 DBG("Value : %s ", value_string);
2257 ev->attr[i].attr_id = HAL_MEDIA_ATTR_ID_ARTIST;
2258 g_strlcpy((gchar *)ev->attr[i].text, value_string, HAL_MAX_ATTR_STR_LEN);
2260 } else if (strcasecmp(key, "Album") == 0) {
2261 value_string = (char *)g_variant_get_string(value, NULL);
2262 DBG("Value : %s ", value_string);
2263 ev->attr[i].attr_id = HAL_MEDIA_ATTR_ID_ALBUM;
2264 g_strlcpy((gchar *)ev->attr[i].text, value_string, HAL_MAX_ATTR_STR_LEN);
2266 } else if (strcasecmp(key, "Genre") == 0) {
2267 value_string = (char *)g_variant_get_string(value, NULL);
2268 DBG("Value : %s ", value_string);
2269 ev->attr[i].attr_id = HAL_MEDIA_ATTR_ID_GENRE;
2270 g_strlcpy((gchar *)ev->attr[i].text, value_string, HAL_MAX_ATTR_STR_LEN);
2272 } else if (strcasecmp(key, "Duration") == 0) {
2275 val = g_variant_get_uint32(value);
2276 DBG("Value : %li", val);
2277 ev->attr[i].attr_id = HAL_MEDIA_ATTR_ID_PLAYING_TIME;
2278 snprintf((char*)ev->attr[i].text, HAL_MAX_ATTR_STR_LEN, "%ld", val);
2280 } else if (strcasecmp(key, "NumberOfTracks") == 0) {
2283 val = g_variant_get_uint32(value);
2284 DBG("Value : %li", val);
2285 ev->attr[i].attr_id = HAL_MEDIA_ATTR_ID_NUM_TRACKS;
2286 snprintf((char*)ev->attr[i].text, HAL_MAX_ATTR_STR_LEN, "%ld", val);
2288 } else if (strcasecmp(key, "TrackNumber") == 0) {
2291 val = g_variant_get_uint32(value);
2292 DBG("Value : %li", val);
2293 ev->attr[i].attr_id = HAL_MEDIA_ATTR_ID_TRACK_NUM;
2294 snprintf((char*)ev->attr[i].text, HAL_MAX_ATTR_STR_LEN, "%ld", val);
2297 DBG("%s not supported, ignoring", key);
2300 if (i >= HAL_MAX_ATTR_NUM) {
2301 ERR(" Received max attribute [%d]", i);
2307 g_variant_iter_free(&iter);
2311 static int __bt_media_attrval_to_val(int type, const char *value)
2316 case HAL_PLAYER_ATTR_EQUALIZER:
2317 if (!strcmp(value, "off"))
2322 case HAL_PLAYER_ATTR_REPEAT:
2323 if (!strcmp(value, "off"))
2324 ret = BTRC_PLAYER_VAL_OFF_REPEAT;
2325 else if (!strcmp(value, "singletrack"))
2326 ret = BTRC_PLAYER_VAL_SINGLE_REPEAT;
2327 else if (!strcmp(value, "alltracks"))
2328 ret = BTRC_PLAYER_VAL_ALL_REPEAT;
2330 ret = BTRC_PLAYER_VAL_GROUP_REPEAT;
2332 case HAL_PLAYER_ATTR_SHUFFLE:
2333 if (!strcmp(value, "off"))
2334 ret = BTRC_PLAYER_VAL_OFF_SHUFFLE;
2335 else if (!strcmp(value, "alltracks"))
2336 ret = BTRC_PLAYER_VAL_ALL_SHUFFLE;
2338 ret = BTRC_PLAYER_VAL_GROUP_SHUFFLE;
2340 case HAL_PLAYER_ATTR_SCAN:
2341 if (!strcmp(value, "off"))
2343 else if (!strcmp(value, "alltracks"))
2349 ERR("Value not handled");
2355 static void __bt_hal_handle_avrcp_ctrl_events(GVariant *msg, const char *member,
2358 const char *property = NULL;
2359 GVariant *value = NULL;
2361 char address[BT_HAL_ADDRESS_STRING_SIZE];
2364 ERR("Error returned in method call\n");
2368 if (!avrcp_ctrl_event_cb) {
2369 ERR("AVRCP controller DBUS handler callback not registered");
2373 g_variant_iter_init(&iter, msg);
2375 _bt_hal_convert_device_path_to_address(path, address);
2377 while (g_variant_iter_loop(&iter, "{sv}", &property, &value)) {
2378 DBG("Property = %s \n", property);
2379 if ((strcasecmp(property, "Equalizer") == 0) ||
2380 (strcasecmp(property, "Repeat") == 0) ||
2381 (strcasecmp(property, "Shuffle") == 0) ||
2382 (strcasecmp(property, "Scan") == 0)) {
2383 struct hal_ev_player_setting ev;
2387 valstr = g_variant_get_string(value, NULL);
2388 DBG("Value : %s ", valstr);
2391 val = __bt_media_attrval_to_val(__bt_media_attr_to_type(property), valstr);
2394 memset(&ev, 0, sizeof(ev));
2395 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2397 ev.attr_ids[0] = __bt_media_attr_to_type(property);
2398 ev.attr_values[0] = val;
2400 /* Send event to application */
2401 avrcp_ctrl_event_cb(HAL_EV_AVRCP_CTRL_PLAYER_APP_SETTING_CHANGED, &ev, sizeof(ev));
2403 } else if ((strcasecmp(property, "Status") == 0)) {
2404 struct hal_ev_play_status_changed ev;
2407 valstr = g_variant_get_string(value, NULL);
2408 DBG("Value : %s ", valstr);
2410 memset(&ev, 0, sizeof(ev));
2411 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2413 ev.status = __bt_hal_play_status_str_to_type(valstr);
2415 /* Send event to application */
2416 avrcp_ctrl_event_cb(HAL_EV_AVRCP_CTRL_PLAY_STATUS_CHANGED, &ev, sizeof(ev));
2418 } else if (strcasecmp(property, "Position") == 0) {
2419 struct hal_ev_play_position ev;
2421 memset(&ev, 0, sizeof(ev));
2422 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2423 ev.pos = g_variant_get_uint32(value);
2424 DBG("Value : %d ", ev.pos);
2426 /* Send event to application */
2427 avrcp_ctrl_event_cb(HAL_EV_AVRCP_CTRL_PLAY_POSITION_CHANGED, &ev, sizeof(ev));
2428 } else if (strcasecmp(property, "Track") == 0) {
2429 struct hal_ev_track_changed ev;
2431 memset(&ev, 0, sizeof(ev));
2432 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2433 __bt_avrcp_control_parse_properties(&ev, value);
2435 /* Send event to application */
2436 avrcp_ctrl_event_cb(HAL_EV_AVRCP_CTRL_TRACK_CHANGED, &ev, sizeof(ev));
2438 DBG("Property not handled");
2442 g_free((char *)property);
2443 g_variant_unref(value);
2446 static void __bt_hal_handle_avrcp_transport_events(GVariant *msg, const char *member,
2449 const char *property = NULL;
2450 GVariant *value = NULL;
2452 char address[BT_HAL_ADDRESS_STRING_SIZE];
2456 ERR("Error returned in method call\n");
2460 if (!avrcp_tg_event_cb) {
2461 ERR("AVRCP target DBUS handler callback not registered");
2465 g_variant_iter_init(&iter, msg);
2467 _bt_hal_convert_device_path_to_address(path, address);
2469 while (g_variant_iter_loop(&iter, "{sv}", &property, &value)) {
2470 DBG("Property = %s \n", property);
2471 if ((strcasecmp(property, "Delay") == 0)) {
2472 struct hal_ev_avrcp_tg_delay_changed ev;
2475 memset(&ev, 0, sizeof(ev));
2476 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2478 val = g_variant_get_uint16(value);
2479 DBG("Value : %d", val);
2482 /* Send event to application */
2483 avrcp_tg_event_cb(HAL_EV_AVRCP_TG_DELAY_CHANGE, &ev, sizeof(ev));
2485 DBG("Property not handled");
2490 g_free((char *)property);
2491 g_variant_unref(value);
2494 /* A2DP Src Role(Remote:Sink) Events */
2495 static void __bt_hal_send_av_connection_state_event(gboolean connected, const char *address)
2498 struct hal_ev_a2dp_conn_state ev;
2500 if (connected == TRUE)
2501 INFO("A2DP(Src) Profile Connected for address [%s]", address);
2503 INFO("A2DP(Src) Profile DisConnected for address [%s]", address);
2505 ev.state = (connected == TRUE) ?
2506 HAL_EV_A2DP_STATE_CONNECTED :
2507 HAL_EV_A2DP_STATE_DISCONNECTED;
2509 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2512 ERR("AV event handler not registered");
2514 av_event_cb(HAL_EV_A2DP_CONN_STATE, &ev, sizeof(ev));
2517 /* A2DP Sink Role(Remote:Source) Events */
2518 static void __bt_hal_send_a2dp_sink_connection_state_event(gboolean connected, const char *address)
2521 struct hal_ev_a2dp_conn_state ev;
2523 if (connected == TRUE)
2524 INFO("A2DP(Sink) Profile Connected for address [%s]", address);
2526 INFO("A2DP(Sink) Profile DisConnected for address [%s]", address);
2528 ev.state = (connected == TRUE) ?
2529 HAL_EV_A2DP_STATE_CONNECTED :
2530 HAL_EV_A2DP_STATE_DISCONNECTED;
2532 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2534 if (!a2dp_sink_event_cb)
2535 ERR("AV event handler not registered");
2537 a2dp_sink_event_cb(HAL_EV_A2DP_SOURCE_CONN_STATE, &ev, sizeof(ev));
2540 /* HF(AG Role) Audio Events */
2541 static void __bt_hal_send_hf_audio_connection_state_event(gboolean connected,
2542 const char *address)
2545 struct hal_ev_handsfree_audio_state ev;
2547 if (connected == TRUE)
2548 INFO("AG Audio Connected for address [%s]", address);
2550 INFO("AG Audio DisConnected for address [%s]", address);
2552 ev.state = (connected == TRUE) ?
2553 HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTED :
2554 HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED;
2556 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2559 ERR("HF event handler not registered");
2561 hf_event_cb(HAL_EV_HANDSFREE_AUDIO_STATE, &ev, sizeof(ev));
2564 /* HF(AG Role) Profile Events */
2565 static void __bt_hal_send_hf_connection_state_event(gboolean connected,
2566 const char *address)
2569 struct hal_ev_handsfree_conn_state ev;
2571 if (connected == TRUE)
2572 INFO("AG Profile Connected for address [%s]", address);
2574 INFO("AG Profile DisConnected for address [%s]", address);
2576 ev.state = (connected == TRUE) ?
2577 HAL_EV_HANDSFREE_CONN_STATE_CONNECTED :
2578 HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED;
2580 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2583 ERR("HF event handler not registered");
2585 hf_event_cb(HAL_EV_HANDSFREE_CONN_STATE, &ev, sizeof(ev));
2588 void _bt_hal_register_event_handler_cb(bt_hal_module_e module, handle_stack_msg cb)
2598 a2dp_sink_event_cb = cb;
2604 avrcp_tg_event_cb = cb;
2606 case HAL_AVRCP_CTRL:
2607 avrcp_ctrl_event_cb = cb;
2613 ERR("Unknown module: %d", module);
2617 void _bt_hal_unregister_event_handler_cb(bt_hal_module_e module)
2621 hid_event_cb = NULL;
2627 a2dp_sink_event_cb = NULL;
2633 avrcp_tg_event_cb = NULL;
2635 case HAL_AVRCP_CTRL:
2636 avrcp_ctrl_event_cb = NULL;
2639 gatt_event_cb = NULL;
2642 ERR("Unknown module: %d", module);
2646 bool _bt_hal_get_adapter_request_state(void)
2648 return is_adapter_activating;
2651 bool _bt_hal_get_le_request_state(void)
2653 return is_le_activating;
2656 void _bt_hal_set_adapter_request_state(bool enable)
2658 DBG("set_adapter_request_state %d", enable);
2659 is_adapter_activating = enable;
2662 void _bt_hal_set_le_request_state(bool enable)
2664 DBG("set_le_request_state %d", enable);
2665 is_le_activating = enable;