4adffbe76b766a660e77f54f6bfaf7c0435a7b7d
[platform/core/connectivity/bluetooth-frwk.git] / bt-oal / bluez_hal / src / bt-hal-event-receiver.c
1 /*
2  * BLUETOOTH HAL
3  *
4  * Copyright (c) 2015 -2016 Samsung Electronics Co., Ltd All Rights Reserved.
5  *
6  * Contact: Anupam Roy <anupam.r@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *              http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <glib.h>
23 #include <string.h>
24 #include <dlog.h>
25 #include <vconf.h>
26
27 #include <glib.h>
28 #include <gio/gio.h>
29 #include <vconf.h>
30
31 /* BT HAL Headers */
32 #include "bt-hal.h"
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
42 #define BASELEN_PROP_CHANGED (sizeof(struct hal_ev_adapter_props_changed) \
43                 + sizeof(struct hal_property))
44
45 /*TODO: Basic filters are currently added,
46   Need to add different event filters like HID,
47   Device etc in subsequent patches */
48
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;
60
61 /*State Management sepration Control for Adapter and LE */
62 static gboolean is_adapter_activating = FALSE;
63 static gboolean is_le_activating = FALSE;
64
65 typedef struct {
66         gchar* sender_name;
67         gchar* object_path;
68         gchar* interface_name;
69         gchar* signal_name;
70         GVariant *parameters;
71 } bt_hal_main_event_data_t;
72
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);
79
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);
82
83 static void __bt_hal_handle_property_changed_event(GVariant *msg, const char *object_path);
84 static void __bt_hal_adapter_property_changed_event(GVariant *msg);
85 static  void __bt_hal_manager_event_filter(GDBusConnection *connection, const gchar *sender_name,
86                         const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
87                         GVariant *parameters, gpointer user_data);
88 static int __bt_hal_initialize_manager_receiver(void);
89 static gboolean __bt_hal_parse_interface(GVariant *msg);
90 static void __bt_hal_handle_device_event(GVariant *value, GVariant *parameters);
91 static gboolean __bt_hal_parse_device_properties(GVariant *item);
92 static gboolean __bt_hal_discovery_finished_cb(gpointer user_data);
93 static void __bt_hal_device_property_changed_event(GVariant *msg, const char *path);
94 static void __bt_hal_dbus_device_found_properties(const char *device_path);
95 static void __bt_hal_device_properties_lookup(GVariant *result, char *address);
96 static void __bt_hal_handle_device_specific_events(GVariant *msg, const char *member, const char *path);
97 static void __bt_hal_send_device_acl_connection_state_event(gboolean connected, const char *address);
98 static void __bt_hal_handle_input_event(GVariant *msg, const char *path);
99 static void __bt_hal_send_av_connection_state_event(gboolean connected, const char *address);
100 static void __bt_hal_send_a2dp_sink_connection_state_event(gboolean connected, const char *address);
101 static void __bt_hal_send_avrcp_ctrl_connection_state_event(gboolean connected, const char *address);
102 static void __bt_hal_handle_avrcp_ctrl_events(GVariant *msg, const char *member, const char *path);
103
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);
111
112 static gboolean __bt_hal_discovery_finished_cb(gpointer user_data)
113 {
114         event_id = 0;
115         DBG("+");
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));
119         DBG("-");
120
121         return FALSE;
122 }
123
124 static int __bt_hal_parse_event(GVariant *msg)
125 {
126         GVariantIter iter;
127         GVariant *child;
128         char *interface_name = NULL;
129         GVariant *inner_iter = NULL;
130
131         g_variant_iter_init(&iter, msg);
132
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;
153                 }
154                 g_variant_unref(inner_iter);
155                 g_variant_unref(child);
156         }
157
158         return 0;
159 }
160
161 static int __bt_hal_get_owner_info(GVariant *msg, char **name, char **previous, char **current)
162 {
163         g_variant_get(msg, "(sss)", name, previous, current);
164         return BT_HAL_ERROR_NONE;
165 }
166
167 int __bt_insert_hal_properties(void *buf, uint8_t type, uint16_t len, const void *val)
168 {       struct hal_property *prop = buf;
169
170         prop->type = type;
171         prop->len = len;
172
173         if (len)
174                 memcpy(prop->val, val, len);
175
176         return sizeof(*prop) + len;
177 }
178
179 handle_stack_msg _bt_hal_get_stack_message_handler(void)
180 {
181         return event_cb;
182 }
183
184 static void __bt_hal_adapter_property_changed_event(GVariant *msg)
185 {
186         GVariantIter value_iter;
187         GVariant *value = NULL;
188         GDBusProxy *adapter_proxy;
189         GError *err = NULL;
190         char *key = NULL;
191         g_variant_iter_init(&value_iter, msg);
192
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;
196         size_t size = 0;
197         const gchar *address = NULL;
198         gchar *name = 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;
206         gboolean powered;
207         gboolean pairable;
208         unsigned int pairable_timeout;
209         gboolean scan_mode_property_update = FALSE;
210         gboolean is_discovering;
211         gboolean is_le_discovering;
212
213         memset(buf, 0, sizeof(buf));
214         size = sizeof(*ev);
215         ev->num_props = 0;
216         ev->status = BT_STATUS_SUCCESS;
217
218         DBG("+");
219
220         while (g_variant_iter_loop(&value_iter, "{sv}", &key, &value)) {
221                 if (!g_strcmp0(key, "Address")) {
222                         uint8_t bdaddr[6];
223
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);
229                         ev->num_props++;
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);
235                         ev->num_props++;
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);
241                         ev->num_props++;
242                 } else if (!g_strcmp0(key, "Discoverable")) {
243                         discoverable = g_variant_get_boolean(value);
244                         DBG("##Discoverable [%d]", discoverable);
245                         if (discoverable)
246                                 scan_mode = BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE;
247                         else
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);
255                         ev->num_props++;
256                 } else if (!g_strcmp0(key, "Connectable")) {
257                         connectable = g_variant_get_boolean(value);
258                         DBG("##Connectable [%d]", connectable);
259                         if (!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);
269                         ev->num_props++;
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);
275                         ev->num_props++;
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));
285 #ifdef TIZEN_BT_HAL
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));
289 #endif
290                                 /* Destroy Agent */
291                                 _bt_hal_destroy_adapter_agent();
292                         } else {
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));
300                                 }
301 #ifdef TIZEN_BT_HAL
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));
308                                 }
309 #endif
310                                 /* Create Agent */
311                                 _bt_hal_initialize_adapter_agent();
312                         }
313
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")) {
321                         char **uuid_value;
322                         int uuid_count = 0;
323                         gsize size1 = 0;
324                         int i = 0;
325                         size1 = g_variant_get_size(value);
326                         int num_props_tmp = ev->num_props;
327                         if (size1 > 0) {
328                                 uuid_value = (char **)g_variant_get_strv(value, &size1);
329                                 for (i = 0; uuid_value[i] != NULL; i++)
330                                         uuid_count++;
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);
340                                         g_free(uuid_str);
341                                 }
342                                 size += __bt_insert_hal_properties(buf + size, HAL_PROP_ADAPTER_UUIDS,
343                                                 (BT_HAL_STACK_UUID_SIZE * uuid_count),
344                                                 uuids);
345                                 ev->num_props = num_props_tmp + 1;
346                                 g_free(uuid_value);
347                         }
348                 } else if (!g_strcmp0(key, "Discovering")) {
349                         is_discovering = g_variant_get_boolean(value);
350                         DBG("##Discovering = [%d]", is_discovering);
351
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 */
357                                 if (event_id > 0)
358                                         continue;
359
360                                 adapter_proxy = _bt_hal_get_adapter_proxy();
361
362                                 if (adapter_proxy == NULL)
363                                         continue;
364
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",
368                                                 NULL,
369                                                 G_DBUS_CALL_FLAGS_NONE,
370                                                 DBUS_TIMEOUT, NULL,
371                                                 &err);
372                                 if (err) {
373                                         ERR("Dbus Error : %s", err->message);
374
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));
382                                         g_clear_error(&err);
383                                         continue;
384
385                                 } else {
386                                         event_id = g_timeout_add(BT_HAL_DISCOVERY_FINISHED_DELAY,
387                                                         (GSourceFunc)__bt_hal_discovery_finished_cb, NULL);
388                                 }
389
390                         } else {
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));
395                         }
396
397                 } else if (!g_strcmp0(key, "LEDiscovering")) {
398                         GVariant *result;
399
400                         is_le_discovering = g_variant_get_boolean(value);
401                         DBG("##LE Discovering = [%d]", is_le_discovering);
402
403                         if (is_le_discovering)
404                                 continue;
405
406                         adapter_proxy = _bt_hal_get_adapter_proxy();
407                         if (adapter_proxy == NULL) {
408                                 ERR("adapter_proxy == NULL");
409                                 continue;
410                         }
411
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);
416                         if (!result) {
417                                 ERR("Error occured in Proxy call");
418                                 if (err) {
419                                         ERR("(Error: %s)", err->message);
420                                         g_clear_error(&err);
421                                 }
422                                 continue;
423                         }
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");
431                         char *name = NULL;
432                         char *val = NULL;
433                         GVariantIter *iter = NULL;
434                         g_variant_get(value, "as", &iter);
435
436                         if (iter == NULL)
437                                 continue;
438
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);
444                         }
445
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);
450                 } else {
451                         ERR("Unhandled Property:[%s]", key);
452                 }
453         }
454
455         if (scan_mode_property_update) {
456                 size += __bt_insert_hal_properties(buf + size,
457                                 HAL_PROP_ADAPTER_SCAN_MODE, sizeof(int), &scan_mode);
458                 ev->num_props++;
459         }
460
461
462         if (size > 2) {
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);
465         }
466         g_variant_unref(value);
467         DBG("-");
468 }
469
470 void _bt_hal_handle_adapter_event(GVariant *msg, const char *member)
471 {
472         DBG("+");
473
474         if (member == NULL)
475                 return;
476
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");
484                 int slot_id;
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;
494                 int link_type;
495
496                 g_variant_get(msg, "(sib)", &address, &link_type, &status);
497                 DBG("RSSI monitoring %s for %s",
498                                 (status ? "Enabled" : "Disabled"), address);
499
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);
503                 if (!event_cb)
504                         ERR("event_cb is NULL");
505                 else
506                         event_cb(HAL_EV_RSSI_MONITOR_STATE_CHANGED, &ev, sizeof(ev));
507
508                 g_free(address);
509         } else if (strcasecmp(member, "RssiAlert") == 0) {
510                 struct hal_ev_rssi_alert_recieved ev;
511                 int alert_type;
512                 int rssi_dbm;
513                 int link_type;
514                 char *address = NULL;
515
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);
519
520                 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
521                 ev.link_type = link_type;
522                 ev.alert_type = alert_type;
523                 ev.rssi = rssi_dbm;
524
525                 if (!event_cb)
526                         ERR("event_cb is NULL");
527                 else
528                         event_cb(HAL_EV_RSSI_ALERT_RECIEVED, &ev, sizeof(ev));
529
530                 g_free(address);
531         } else if (strcasecmp(member, "RawRssi") == 0) {
532                 struct hal_ev_raw_rssi_recieved ev;
533                 int rssi_dbm;
534                 int link_type;
535                 char *address = NULL;
536
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);
540
541                 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
542                 ev.link_type = link_type;
543                 ev.rssi = rssi_dbm;
544
545                 if (!event_cb)
546                         ERR("event_cb is NULL");
547                 else
548                         event_cb(HAL_EV_RAW_RSSI_RECIEVED, &ev, sizeof(ev));
549
550                 g_free(address);
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");
555
556         }
557         DBG("-");
558 }
559
560 static gboolean __bt_hal_parse_device_properties(GVariant *item)
561 {
562         GVariantIter iter;
563         gchar *key;
564         GVariant *val;
565         gsize len = 0;
566         if (!item)
567                 return FALSE;
568         DBG("+");
569
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;
573         size_t size = 0;
574         memset(buf, 0, sizeof(buf));
575         size = sizeof(*ev);
576         ev->num_props = 0;
577
578         g_variant_iter_init(&iter, item);
579         while (g_variant_iter_loop(&iter, "{sv}", &key, &val)) {
580
581                 if (strcasecmp(key, "Address") == 0)  {
582
583                         char * address = NULL;
584                         address = g_variant_dup_string(val, &len);
585                         uint8_t bdaddr[6];
586                         _bt_hal_convert_addr_string_to_type(bdaddr, address);
587
588                         size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_ADDR,
589                                         sizeof(bdaddr), bdaddr);
590
591                         ev->num_props++;
592                         DBG("Device address [%s] property Num [%d]", address, ev->num_props);
593
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);
598                         ev->num_props++;
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);
602                         if (name) {
603                                 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_NAME,
604                                                 strlen(name) + 1, name);
605                                 ev->num_props++;
606                                 DBG("Device Name [%s] Property num [%d]", name, ev->num_props);
607                         }
608                 } else if (strcasecmp(key, "Connected") == 0) {
609                         unsigned int connected = g_variant_get_uint32(val);
610
611                         size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_CONNECTED,
612                                         sizeof(unsigned int), &connected);
613                         ev->num_props++;
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);
619                         ev->num_props++;
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);
625                         ev->num_props++;
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,
630                                         sizeof(int), &rssi);
631                         ev->num_props++;
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);
640                         ev->num_props++;
641                 } else if (strcasecmp(key, "UUIDs") == 0) {
642                         char **uuid_value;
643                         int uuid_count = 0;
644                         gsize size1 = 0;
645                         int i = 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;
649
650                         if (size1 > 0) {
651                                 uuid_value = (char **)g_variant_get_strv(val, &size1);
652                                 for (i = 0; uuid_value[i] != NULL; i++)
653                                         uuid_count++;
654                                 DBG("UUID count [%d]\n", uuid_count);
655                                 /* UUID collection */
656                                 uint8_t uuids[BT_HAL_STACK_UUID_SIZE * uuid_count];
657
658                                 for (i = 0; uuid_value[i] != NULL; i++) {
659
660                                         char *uuid_str = NULL;
661                                         uint8_t uuid[BT_HAL_STACK_UUID_SIZE];
662                                         memset(uuid, 0x00, BT_HAL_STACK_UUID_SIZE);
663
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);
669                                         g_free(uuid_str);
670                                 }
671
672                                 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_UUIDS,
673                                                 (BT_HAL_STACK_UUID_SIZE * uuid_count),
674                                                 uuids);
675                                 ev->num_props = num_props_tmp + 1;
676                                 g_free(uuid_value);
677                         }
678
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*/
683                 } else {
684                         ERR("Unhandled Property:[%s]", key);
685                 }
686         }
687         DBG("-");
688
689         if (size > 1) {
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);
692         }
693
694         return TRUE;
695 }
696
697 static void __bt_hal_handle_avrcp_tg_events(GVariant *msg, const char *path)
698 {
699         int state;
700         GVariantIter value_iter;
701         char *property = NULL;
702         char *address;
703         GVariant *val = NULL;
704         GVariant *child = NULL;
705
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;
712
713                         gboolean connected = FALSE;
714
715                         g_variant_get(val, "b", &connected);
716
717                         state = connected ? HAL_AVRCP_TG_STATE_CONNECTED :
718                                 HAL_AVRCP_TG_STATE_DISCONNECTED;
719
720                         address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
721
722                         _bt_hal_convert_device_path_to_address(path, address);
723
724                         DBG("connected: %d", connected);
725                         DBG("address: %s", address);
726
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);
730                         ev.state = state;
731                         if (!avrcp_tg_event_cb)
732                                 ERR("AVRCP target DBUS handler callback not registered");
733                         else
734                                 avrcp_tg_event_cb(HAL_EV_AVRCP_TG_CONN_STATE, (void *)&ev, sizeof(ev));
735                         g_free(address);
736                 }
737                 g_free(property);
738                 g_variant_unref(child);
739                 g_variant_unref(val);
740         }
741
742         DBG("-");
743 }
744
745 static void __bt_hal_handle_property_changed_event(GVariant *msg, const char *object_path)
746 {
747         char *interface_name = NULL;
748         GVariant *val = NULL;
749
750         g_variant_get(msg, "(&s@a{sv}@as)", &interface_name, &val, NULL);
751
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);
777         }
778         g_variant_unref(val);
779 }
780
781 static void __bt_hal_handle_device_event(GVariant *value, GVariant *parameters)
782 {
783         DBG("+");
784
785         if (__bt_hal_parse_interface(parameters) == FALSE) {
786                 ERR("Fail to parse the properies");
787                 g_variant_unref(value);
788                 return;
789         }
790
791         DBG("-");
792 }
793
794 static void __bt_hal_send_hid_connection_state_event(
795                 gboolean connected, char *address)
796 {
797         struct hal_ev_hidhost_conn_state ev;
798
799         ev.state = (connected == TRUE) ?
800                 HAL_HIDHOST_STATE_CONNECTED :
801                 HAL_HIDHOST_STATE_DISCONNECTED;
802
803         _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
804
805         if (!hid_event_cb)
806                 ERR("HID event handler not registered");
807         else
808                 hid_event_cb(HAL_EV_HIDHOST_CONN_STATE, &ev, sizeof(ev));
809 }
810
811 static void __bt_hal_handle_input_event(GVariant *msg, const char *path)
812 {
813         gboolean property_flag = FALSE;
814         GVariantIter value_iter;
815         char *property = NULL;
816         GVariant *child = NULL, *val = NULL;
817
818         DBG("+");
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);
822
823                 if (property == NULL)
824                         return;
825
826                 if (strcasecmp(property, "Connected") == 0) {
827                         char *address;
828
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);
833                         g_free(address);
834                 }
835                 g_free(property);
836                 g_variant_unref(val);
837                 g_variant_unref(child);
838         }
839
840         DBG("-");
841 }
842
843 static gboolean __bt_hal_parse_interface(GVariant *msg)
844 {
845         char *path = NULL;
846         GVariant *optional_param;
847         GVariantIter iter;
848         GVariant *child;
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);
854
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");
864                                 return FALSE;
865                         } else {
866                                 g_variant_unref(inner_iter);
867                                 g_variant_unref(child);
868                                 g_variant_unref(optional_param);
869                                 return TRUE;
870                         }
871                 }
872                 g_variant_unref(inner_iter);
873                 g_variant_unref(child);
874         }
875
876         g_variant_unref(optional_param);
877
878         return FALSE;
879 }
880
881 static gboolean __bt_hal_event_manager(gpointer data)
882 {
883         bt_hal_event_type_t bt_event = 0x00;
884         GVariant *value;
885         char *obj_path = NULL;
886
887         bt_hal_main_event_data_t *param = (bt_hal_main_event_data_t*)data;
888         if (strcasecmp(param->signal_name, "InterfacesAdded") == 0) {
889
890                 /*TODO: Handle Interfaces Added Signal from stack */
891                 DBG("Manager Event: Signal Name: InterfacesAdded");
892
893                 g_variant_get(param->parameters, "(&o@a{sa{sv}})", &obj_path, &value);
894
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]");
898                 } else {
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);
906                         }
907                 }
908                 g_variant_unref(value);
909
910         } else if (strcasecmp(param->signal_name, "InterfacesRemoved") == 0) {
911                 char *str;
912                 GVariantIter *iter;
913
914                 /*TODO: Handle Interfaces Removed Signal from stack */
915                 DBG("Manager Event: Signal Name: InterfacesRemoved");
916
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);
922                 }
923                 g_variant_iter_free(iter);
924         } else if (strcasecmp(param->signal_name, "NameOwnerChanged") == 0) {
925                 char *name = NULL;
926                 char *previous = NULL;
927                 char *current = NULL;
928
929                 /* TODO: Handle Name Owener changed Signal */
930                 if (__bt_hal_get_owner_info(param->parameters, &name, &previous, &current)) {
931                         DBG("Fail to get the owner info");
932                         return FALSE;
933                 }
934                 if (current && *current != '\0') {
935                         g_free(name);
936                         g_free(previous);
937                         g_free(current);
938                         return FALSE;
939                 }
940                 if (strcasecmp(name, BT_HAL_BLUEZ_NAME) == 0) {
941                         DBG("Bluetoothd is terminated");
942
943                         /* TODO: Handle Bluetoothd terminating scenario */
944                         _bt_hal_le_deinit();
945                 }
946                 INFO("Name Owner changed [%s]", name);
947                 g_free(name);
948                 g_free(previous);
949                 g_free(current);
950
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);
977         }
978
979         /* Free data */
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);
985
986         return FALSE;
987 }
988
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,
995                 gpointer user_data)
996 {
997         if (signal_name == NULL)
998                 return;
999
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);
1006
1007         g_idle_add(__bt_hal_event_manager, (gpointer)param);
1008         return;
1009 }
1010
1011 static void __bt_hal_handle_headset_events(GVariant *msg, const char *member, const char *path)
1012 {
1013         gboolean property_flag = FALSE;
1014         char *property = NULL;
1015         GVariant *value = NULL;
1016         g_variant_get(msg, "(sv)", &property, &value);
1017
1018         if (property == NULL)
1019                 return;
1020
1021         DBG("Property = %s \n", property);
1022         /* We allow only 1 headset connection (HSP or HFP)*/
1023         if (strcasecmp(property, "Connected") == 0) {
1024                 char *address;
1025                 g_variant_get(value, "b", &property_flag);
1026
1027                 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1028
1029                 /* Fix : NULL_RETURNS */
1030                 if (address == NULL)
1031                         return;
1032
1033                 _bt_hal_convert_device_path_to_address(path, address);
1034                 __bt_hal_send_hf_audio_connection_state_event(property_flag, address);
1035                 g_free(address);
1036         } else if (strcasecmp(property, "State") == 0) {
1037                 char *state = NULL;
1038
1039                 g_variant_get(value, "s", &state);
1040
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");
1049                         else
1050                                 DBG("Sco Disconnected");
1051                 } else {
1052                         ERR("Not handled state - %s", state);
1053                         g_free(state);
1054                         return;
1055                 }
1056                 g_free(state);
1057         } else if (strcasecmp(property, "SpeakerGain") == 0) {
1058                 char *address;
1059
1060                 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1061
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 */
1065
1066                 g_free(address);
1067         } else if (strcasecmp(property, "MicrophoneGain") == 0) {
1068                 char *address;
1069
1070                 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1071
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 */
1075
1076                 g_free(address);
1077         }
1078
1079         if (property)
1080                 g_free(property);
1081         g_variant_unref(value);
1082 }
1083
1084 static int __bt_hal_register_manager_subscribe_signal(GDBusConnection *conn,
1085                 int subscribe)
1086 {
1087         if (conn == NULL)
1088                 return -1;
1089
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;
1095
1096         INFO_C("+");
1097
1098         if (subscribe) {
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,
1104                                         NULL, NULL);
1105                 }
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,
1111                                         NULL, NULL);
1112                 }
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,
1118                                         NULL, NULL);
1119                 }
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,
1125                                         NULL, NULL);
1126                 }
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,
1132                                         NULL, NULL);
1133                 }
1134         } else {
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;
1139                 }
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;
1144                 }
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;
1149                 }
1150                 if (subs_property_id != -1) {
1151                         g_dbus_connection_signal_unsubscribe(conn,
1152                                         subs_property_id);
1153                         subs_property_id = -1;
1154                 }
1155                 if (subs_adapter_id == -1) {
1156                         g_dbus_connection_signal_unsubscribe(conn, subs_adapter_id);
1157                         subs_adapter_id = -1;
1158                 }
1159         }
1160
1161         INFO_C("-");
1162         return 0;
1163 }
1164
1165 static int __bt_hal_register_device_subscribe_signal(GDBusConnection *conn,
1166                 int subscribe)
1167 {
1168         static int subs_device_id = -1;
1169
1170         DBG("+");
1171         if (conn == NULL)
1172                 return -1;
1173
1174         if (subscribe) {
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,
1180                                         NULL, NULL);
1181                 }
1182         } else {
1183                 if (subs_device_id != -1) {
1184                         g_dbus_connection_signal_unsubscribe(conn,
1185                                         subs_device_id);
1186                         subs_device_id = -1;
1187                 }
1188         }
1189
1190         DBG("-");
1191         return 0;
1192 }
1193
1194 static int __bt_hal_register_input_subscribe_signal(GDBusConnection *conn, int subscribe)
1195 {
1196         static int subs_input_id = -1;
1197
1198         DBG("+");
1199
1200         if (conn == NULL)
1201                 return -1;
1202
1203         if (subscribe) {
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,
1209                                         NULL, NULL);
1210                 }
1211         } else {
1212                 if (subs_input_id != -1) {
1213                         g_dbus_connection_signal_unsubscribe(conn,
1214                                         subs_input_id);
1215                         subs_input_id = -1;
1216                 }
1217         }
1218
1219         DBG("-");
1220
1221         return 0;
1222 }
1223
1224 static int __bt_hal_register_service_event(GDBusConnection *g_conn, int event_type)
1225 {
1226         DBG("+");
1227
1228         if (g_conn == NULL)
1229                 return  BT_HAL_ERROR_INTERNAL;
1230
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);
1235                 break;
1236         case BT_HAL_DEVICE_EVENT:
1237                 __bt_hal_register_device_subscribe_signal(g_conn, TRUE);
1238                 break;
1239         case BT_HAL_HID_EVENT:
1240                 __bt_hal_register_input_subscribe_signal(g_conn, TRUE);
1241                 break;
1242         case BT_HAL_HEADSET_EVENT:
1243                  __bt_hal_register_audio_subscribe_signal(g_conn, TRUE);
1244                 break;
1245         default:
1246                 INFO_C("Register Event: event_type [%d]", event_type);
1247                 return BT_HAL_ERROR_NOT_SUPPORT;
1248         }
1249
1250         return BT_HAL_ERROR_NONE;
1251 }
1252
1253 static int __bt_hal_register_audio_subscribe_signal(GDBusConnection *conn,
1254                 int subscribe)
1255 {
1256         if (conn == NULL)
1257                 return -1;
1258
1259         static int subs_headset_id = -1;
1260         static int subs_sink_id = -1;
1261
1262         if (subscribe) {
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,
1268                                         NULL, NULL);
1269                 }
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,
1275                                         NULL, NULL);
1276                 }
1277         } else {
1278                 if (subs_headset_id != -1) {
1279                         g_dbus_connection_signal_unsubscribe(conn,
1280                                         subs_headset_id);
1281                         subs_headset_id = -1;
1282                 }
1283                 if (subs_sink_id != -1) {
1284                         g_dbus_connection_signal_unsubscribe(conn,
1285                                         subs_sink_id);
1286                         subs_sink_id = -1;
1287                 }
1288         }
1289         return 0;
1290 }
1291
1292 static int __bt_hal_initialize_manager_receiver(void)
1293 {
1294         DBG("+");
1295
1296         GError *error = NULL;
1297
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);
1303                 }
1304                 if (manager_conn == NULL)
1305                         goto fail;
1306         }
1307
1308         if (__bt_hal_register_service_event(manager_conn,
1309                                 BT_HAL_MANAGER_EVENT) != BT_HAL_ERROR_NONE)
1310                 goto fail;
1311         if (__bt_hal_register_service_event(manager_conn,
1312                                 BT_HAL_DEVICE_EVENT) != BT_HAL_ERROR_NONE)
1313                 goto fail;
1314         if (__bt_hal_register_service_event(manager_conn,
1315                                 BT_HAL_HID_EVENT) != BT_HAL_ERROR_NONE)
1316                 goto fail;
1317         if (__bt_hal_register_service_event(manager_conn,
1318                                 BT_HAL_HEADSET_EVENT) != BT_HAL_ERROR_NONE)
1319                 goto fail;
1320         return BT_HAL_ERROR_NONE;
1321 fail:
1322         if (manager_conn) {
1323                 g_object_unref(manager_conn);
1324                 manager_conn = NULL;
1325         }
1326
1327         DBG("-");
1328
1329         return BT_HAL_ERROR_INTERNAL;
1330 }
1331
1332 /* To receive the event from bluez */
1333 int _bt_hal_initialize_event_receiver(handle_stack_msg cb)
1334 {
1335         int result;
1336         DBG("+");
1337
1338         if (!cb)
1339                 return BT_HAL_ERROR_INVALID_PARAM;
1340
1341         result = __bt_hal_initialize_manager_receiver();
1342
1343         DBG("Manager event receiver initialization result [%d]", result);
1344         if (result != BT_HAL_ERROR_NONE)
1345                 return result;
1346
1347         /*TODO: Initialize Obexd Event receiver */
1348
1349         event_cb = cb;
1350         DBG("-");
1351
1352         return BT_HAL_ERROR_NONE;
1353 }
1354
1355 static void __bt_hal_device_property_changed_event(GVariant *msg, const char *path)
1356 {
1357         GVariantIter value_iter;
1358         GVariant *value = NULL;
1359         char *key = NULL;
1360         g_variant_iter_init(&value_iter, msg);
1361         DBG("+");
1362
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);
1380                         g_free(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];
1385
1386                         g_variant_get(value, "b", &paired);
1387                         DBG("Device property changed : Paired = %s", (paired ? "TRUE" : "FALSE"));
1388
1389                         _bt_hal_agent_set_canceled(FALSE);
1390                         _bt_hal_convert_device_path_to_address(path, address);
1391
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);
1396
1397                         if (!event_cb) {
1398                                 ERR("Bluetooth HAL event handler not registered");
1399                         } else {
1400                                 DBG("Sending HAL_EV_BOND_STATE_CHANGED event");
1401                                 event_cb(HAL_EV_BOND_STATE_CHANGED, (void*)&ev, sizeof(ev));
1402                         }
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);
1411
1412                         _bt_hal_convert_device_path_to_address(path, address);
1413                         DBG("Device [%s] trusted: [%d]", address, trusted);
1414
1415                         __bt_hal_send_device_trust_state_event(trusted, address);
1416                         g_free(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")) {
1422                         int trust_val = 0;
1423                         char address[BT_HAL_ADDRESS_STRING_SIZE];
1424
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);
1429                 } else {
1430                         ERR("Unhandled Property:[%s]", key);
1431                 }
1432         }
1433         DBG("-");
1434 }
1435
1436 static void __bt_hal_dbus_device_found_properties(const char *device_path)
1437 {
1438         char *address;
1439         GError *error = NULL;
1440         GDBusProxy *device_proxy;
1441         GDBusConnection *conn;
1442         GVariant *result;
1443         DBG("+");
1444
1445         if (!device_path) {
1446                 ERR("Invalid device path");
1447                 return;
1448         }
1449
1450         conn = _bt_hal_get_system_gconn();
1451         if (!conn) {
1452                 ERR("_bt_hal_get_system_gconn failed");
1453                 return;
1454         }
1455
1456         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1457                         NULL,
1458                         BT_HAL_BLUEZ_NAME,
1459                         device_path,
1460                         BT_HAL_PROPERTIES_INTERFACE,
1461                         NULL, NULL);
1462
1463         if (!device_proxy) {
1464                 ERR("Error creating device_proxy");
1465                 return;
1466         }
1467
1468         result = g_dbus_proxy_call_sync(device_proxy,
1469                         "GetAll",
1470                         g_variant_new("(s)", BT_HAL_DEVICE_INTERFACE),
1471                         G_DBUS_CALL_FLAGS_NONE,
1472                         -1,
1473                         NULL,
1474                         &error);
1475         if (!result) {
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);
1480                 }
1481                 g_object_unref(device_proxy);
1482                 return;
1483         }
1484
1485         address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1486         _bt_hal_convert_device_path_to_address(device_path, address);
1487
1488         __bt_hal_device_properties_lookup(result, address);
1489
1490         g_object_unref(device_proxy);
1491         g_free(address);
1492
1493         DBG("-");
1494 }
1495
1496 static void __bt_hal_device_properties_lookup(GVariant *result, char *address)
1497 {
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;
1501         size_t size = 0;
1502         memset(buf, 0, sizeof(buf));
1503         size = sizeof(*ev);
1504         ev->num_props = 0;
1505
1506         GVariant *tmp_value;
1507         GVariant *value;
1508         gchar *name;
1509         gchar *manufacturer_data = NULL;
1510         DBG("+");
1511
1512         if (result != NULL) {
1513                 g_variant_get(result , "(@a{sv})", &value);
1514                 g_variant_unref(result);
1515
1516                 /* Alias */
1517                 tmp_value = g_variant_lookup_value(value, "Alias", G_VARIANT_TYPE_STRING);
1518
1519                 g_variant_get(tmp_value, "s", &name);
1520
1521                 g_variant_unref(tmp_value);
1522                 if (name != NULL) {
1523                         DBG_SECURE("Alias Name [%s]", name);
1524                         size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_NAME,
1525                                         strlen(name) + 1, name);
1526                         ev->num_props++;
1527                         DBG("Device Name [%s] Property num [%d]", name, ev->num_props);
1528                 } else {
1529                         /* Name */
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);
1533
1534                         size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_NAME,
1535                                         strlen(name) + 1, name);
1536                         ev->num_props++;
1537                         DBG("Device Name [%s] Property num [%d]", name, ev->num_props);
1538                         g_variant_get(tmp_value, "s", &name);
1539                 }
1540
1541                 /* Class */
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);
1546                 ev->num_props++;
1547                 g_variant_unref(tmp_value);
1548
1549
1550                 /* Connected */
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);
1555                 ev->num_props++;
1556                 DBG("Device connected [%u] Property num [%d]", connected,  ev->num_props);
1557                 g_variant_unref(tmp_value);
1558
1559                 /* Trust */
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);
1564                 ev->num_props++;
1565                 DBG("Device trusted [%d] Property num [%d]", trust, ev->num_props);
1566                 g_variant_unref(tmp_value);
1567
1568                 /* Paired */
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;
1571
1572                 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_PAIRED,
1573                                 sizeof(uint8_t), &paired);
1574                 ev->num_props++;
1575                 DBG("Device Paired [%d] Property num [%d]", paired, ev->num_props);
1576                 g_variant_unref(tmp_value);
1577
1578                 /* RSSI*/
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);
1583                 ev->num_props++;
1584                 DBG("Device RSSI [%d] Property num [%d]", rssi, ev->num_props);
1585                 g_variant_unref(tmp_value);
1586
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);
1592
1593                 /* Is Alias Set */
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);
1598                 ev->num_props++;
1599                 DBG("IsAliasSet: [%s], Property num [%d]", (is_alias_set ? "TRUE" : "FALSE"), ev->num_props);
1600                 g_variant_unref(tmp_value);
1601
1602                 /* UUID's */
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);
1606                 {
1607                         /* UUID collection */
1608                         int i;
1609 #ifdef __TEST_
1610                         int z;
1611 #endif
1612                         int num_props_tmp = ev->num_props;
1613
1614                         uint8_t uuids[BT_HAL_STACK_UUID_SIZE * uuid_count];
1615
1616                         for (i = 0; uuid_value[i] != NULL; i++) {
1617
1618                                 char *uuid_str = NULL;
1619                                 uint8_t uuid[BT_HAL_STACK_UUID_SIZE];
1620                                 memset(uuid, 0x00, BT_HAL_STACK_UUID_SIZE);
1621
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);
1625
1626                                 _bt_hal_convert_uuid_string_to_type(uuid, uuid_str);
1627 #ifdef __TEST_
1628                                 for (z = 0; z < 16; z++)
1629                                         DBG("[0x%x]", uuid[z]);
1630 #endif
1631
1632                                 memcpy(uuids+i*BT_HAL_STACK_UUID_SIZE, uuid, BT_HAL_STACK_UUID_SIZE);
1633                                 g_free(uuid_str);
1634                         }
1635
1636                         size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_UUIDS,
1637                                         (BT_HAL_STACK_UUID_SIZE * uuid_count),
1638                                         uuids);
1639                         ev->num_props = num_props_tmp + 1;
1640                         g_free(uuid_value);
1641                 }
1642                 g_variant_unref(tmp_value);
1643
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;
1650                 }
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);
1654                   ev->num_props++;*/
1655                 DBG("Device Manufacturer data length [%u]", manufacturer_data_len);
1656
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);
1665                                 ev->num_props++;
1666                         }
1667                 }
1668                 g_variant_unref(tmp_value);
1669
1670                 /* Address */
1671                 uint8_t bdaddr[6];
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);
1675                 ev->num_props++;
1676                 DBG("Device address [%s] property Num [%d]", address, ev->num_props);
1677
1678                 g_free(name);
1679                 g_variant_unref(value);
1680         } else {
1681                 ERR("result  is NULL\n");
1682         }
1683         if (size > 1) {
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);
1686         }
1687         DBG("-");
1688 }
1689
1690 static void __bt_hal_send_device_acl_connection_state_event(gboolean connected, const char *address)
1691 {
1692         DBG("+");
1693         struct hal_ev_acl_state_changed ev;
1694
1695         ev.status = BT_STATUS_SUCCESS;
1696         ev.state = (connected == TRUE) ?
1697                 HAL_ACL_STATE_CONNECTED :
1698                 HAL_ACL_STATE_DISCONNECTED;
1699
1700         _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
1701
1702         if (!event_cb)
1703                 ERR("Bluetooth HAL event handler not registered");
1704         else
1705                 event_cb(HAL_EV_ACL_STATE_CHANGED, &ev, sizeof(ev));
1706         DBG("-");
1707 }
1708
1709 static void __bt_hal_send_device_le_connection_state_event(gboolean connected, const char *address)
1710 {
1711         DBG("+");
1712         struct hal_ev_le_conn_state_changed ev;
1713
1714         ev.status = BT_STATUS_SUCCESS;
1715         ev.state = (connected == TRUE) ?
1716                 HAL_LE_STATE_CONNECTED :
1717                 HAL_LE_STATE_DISCONNECTED;
1718
1719         _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
1720
1721         if (!event_cb)
1722                 ERR("Bluetooth HAL event handler not registered");
1723         else
1724                 event_cb(HAL_EV_LE_CONN_STATE_CHANGED, &ev, sizeof(ev));
1725         DBG("-");
1726 }
1727
1728 static void __bt_hal_send_device_trust_state_event(gboolean is_trusted,
1729                                 const char *address)
1730 {
1731         struct hal_ev_device_trust_state_changed ev;
1732         DBG("+");
1733
1734         ev.trust = (is_trusted == TRUE) ?
1735                 HAL_DEVICE_TRUSTED :
1736                 HAL_DEVICE_UNTRUSTED;
1737
1738         _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
1739
1740         if (!event_cb)
1741                 ERR("Bluetooth HAL event handler not registered");
1742         else
1743                 event_cb(HAL_EV_DEVICE_TRUST_CHANGED, &ev, sizeof(ev));
1744         DBG("-");
1745 }
1746
1747 static void __bt_hal_send_device_trusted_profile_changed_event(
1748                 uint32_t trust_val, const char *address)
1749 {
1750         struct hal_ev_device_trusted_profiles_changed ev;
1751         DBG("+");
1752
1753         _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
1754         ev.trust_val = trust_val;
1755
1756         if (!event_cb)
1757                 ERR("Bluetooth HAL event handler not registered");
1758         else
1759                 event_cb(HAL_EV_DEVICE_TRUSTED_PROFILES_CHANGED, &ev, sizeof(ev));
1760         DBG("-");
1761 }
1762
1763 static void __bt_hal_handle_device_specific_events(GVariant *msg, const char *member,
1764                         const char *path)
1765 {
1766         char *address;
1767         const char *property = NULL;
1768         if (path == NULL)
1769                 return;
1770
1771         if (strcasecmp(member, "PropertyChanged") == 0) {
1772                 g_variant_get(msg, "(s)", &property);
1773                 if (property == NULL)
1774                         return;
1775                 if (strcasecmp(property, "GattConnected") == 0) {
1776                         INFO("GATT Connected");
1777                         gboolean connected = FALSE;
1778                         char *address;
1779                         address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1780
1781                         _bt_hal_convert_device_path_to_address(path, address);
1782                         g_variant_get(msg, "(b)", &connected);
1783
1784                         INFO("Connected device address[%s] connnected[%d]", address, connected);
1785                         g_free(address);
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];
1790
1791                         g_variant_get(msg, "(b)", &paired);
1792                         DBG("Device property changed : Paired = %s", (paired ? "TRUE" : "FALSE"));
1793
1794                         _bt_hal_agent_set_canceled(FALSE);
1795                         _bt_hal_convert_device_path_to_address(path, address);
1796
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);
1801
1802                         if (!event_cb) {
1803                                 ERR("Bluetooth HAL event handler not registered");
1804                         } else {
1805                                 DBG("Sending HAL_EV_BOND_STATE_CHANGED event");
1806                                 event_cb(HAL_EV_BOND_STATE_CHANGED, (void*)&ev, sizeof(ev));
1807                         }
1808                 } else if (strcasecmp(property, "UUIDs") == 0) {
1809                         /* TODO */
1810                 }
1811         } else if (strcasecmp(member, "DeviceConnected") == 0) {
1812                 unsigned char addr_type = 0;
1813
1814                 g_variant_get(msg, "(y)", &addr_type);
1815
1816                 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1817                 _bt_hal_convert_device_path_to_address(path, address);
1818
1819                 DBG("Member: [%s]", member);
1820                 ERR_C("Connected [%s] [%s]", !addr_type ? "BREDR" : "LE", address);
1821                 if (!addr_type)
1822                         __bt_hal_send_device_acl_connection_state_event(TRUE, address);
1823                 else
1824                         __bt_hal_send_device_le_connection_state_event(TRUE, address);
1825                 g_free(address);
1826         } else if (strcasecmp(member, "Disconnected") == 0) {
1827                 unsigned char disc_reason = 0;
1828                 unsigned char addr_type = 0;
1829                 char *name = NULL;
1830
1831                 g_variant_get(msg, "(yy&s)", &addr_type, &disc_reason, &name);
1832
1833                 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1834                 _bt_hal_convert_device_path_to_address(path, address);
1835
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);
1840                 if (!addr_type)
1841                         __bt_hal_send_device_acl_connection_state_event(FALSE, address);
1842                 else
1843                         __bt_hal_send_device_le_connection_state_event(FALSE, address);
1844                 g_free(address);
1845         } else if (strcasecmp(member, "ProfileStateChanged") == 0) {
1846                 int state = 0;
1847                 char *profile_uuid = NULL;
1848
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);
1852
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);
1861                         else
1862                                 DBG("Profile state: %d", state);
1863
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");
1875                         } else {
1876                                 ERR("A2DP Profile state: Invalid");
1877                         }
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");
1889                         }
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");
1901                         } else {
1902                                 ERR("HFP Profile state: Invalid");
1903                         }
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");
1915                         }
1916                 } else {
1917                         DBG("Profile[%s] State changed status [%d] ", profile_uuid, state);
1918                 }
1919                 g_free(address);
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);
1924         }
1925 }
1926
1927 static void __bt_hal_handle_adv_report(GVariant *msg, const char *path)
1928 {
1929         uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
1930         struct hal_ev_gatt_client_scan_result *ev = (void *)buf;
1931         size_t size = 0;
1932         char *address = NULL;
1933         GVariant *value = NULL;
1934         char *buffer = NULL;
1935         int data_len = 0;
1936         int buffer_len = 0;
1937         uint8_t addr_type = 0;
1938         uint8_t adv_type = 0;
1939         int rssi = 0;
1940
1941         if (!gatt_event_cb)
1942                 return;
1943
1944         memset(buf, 0, sizeof(buf));
1945         size = sizeof(*ev);
1946
1947         g_variant_get(msg, "(&syyii@ay)", &address, &addr_type,
1948                         &adv_type, &rssi, &data_len, &value);
1949
1950         buffer_len = g_variant_get_size(value);
1951         if (buffer_len > 0)
1952                 buffer = (char *)g_variant_get_data(value);
1953
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;
1958         }
1959
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);
1962
1963         _bt_hal_convert_addr_string_to_type(ev->bd_addr, address);
1964         ev->addr_type = addr_type;
1965         ev->adv_type = adv_type;
1966         ev->rssi = rssi;
1967         ev->len = data_len;
1968         memcpy(ev->adv_data, buffer, data_len);
1969         size += data_len;
1970
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);
1974 }
1975
1976 /* AVRCP Controller Role(Remote:AVRCP Target) Events */
1977 static void __bt_hal_send_avrcp_ctrl_connection_state_event(gboolean connected, const char *address)
1978 {
1979         DBG("+");
1980         struct hal_ev_avrcp_ctrl_conn_state ev;
1981
1982         if (connected == TRUE)
1983                 INFO("AVRCP(Controller) Profile Connected for address [%s]", address);
1984         else
1985                 INFO("AVRCP(Controller) Profile DisConnected for address [%s]", address);
1986
1987         if (connected == TRUE)
1988                 ev.state = HAL_AVRCP_CTRL_STATE_CONNECTED;
1989         else
1990                 ev.state = HAL_AVRCP_CTRL_STATE_DISCONNECTED;
1991         _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
1992
1993         if (!a2dp_sink_event_cb)
1994                 ERR("AV event handler not registered");
1995         else
1996                 avrcp_ctrl_event_cb(HAL_EV_AVRCP_CTRL_CONN_STATE, &ev, sizeof(ev));
1997 }
1998
1999 static int __bt_media_attr_to_type(const char *str)
2000 {
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;
2009         else
2010                 return 0;
2011 }
2012
2013
2014 static int __bt_hal_play_status_str_to_type(const char *value)
2015 {
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;
2026         else
2027                 return HAL_PLAYSTATE_ERROR;
2028 }
2029
2030 static void __bt_avrcp_control_parse_properties(struct hal_ev_track_changed *ev, GVariant *item)
2031 {
2032         GVariant *value = NULL;
2033         GVariantIter iter;
2034         char *value_string = NULL;
2035         const char *key = NULL;
2036         int i = 0;
2037
2038         if (ev == NULL)
2039                 return;
2040
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);
2048                         i++;
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);
2054                         i++;
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);
2060                         i++;
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);
2066                         i++;
2067                 } else if (strcasecmp(key, "Duration") == 0) {
2068                         long int val;
2069
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);
2074                         i++;
2075                 } else if (strcasecmp(key, "NumberOfTracks") == 0) {
2076                         long int val;
2077
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);
2082                         i++;
2083                 } else if (strcasecmp(key, "TrackNumber") == 0) {
2084                         long int val;
2085
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);
2090                         i++;
2091                 } else {
2092                         DBG("%s not supported, ignoring", key);
2093                 }
2094
2095                 if (i >= HAL_MAX_ATTR_NUM) {
2096                         ERR(" Received max attribute [%d]", i);
2097                         break;
2098                 }
2099         }
2100
2101         ev->num_attr = i;
2102         g_variant_iter_free(&iter);
2103         return;
2104 }
2105
2106 static int __bt_media_attrval_to_val(int type, const char *value)
2107 {
2108         int ret = -1;
2109
2110         switch (type) {
2111         case HAL_PLAYER_ATTR_EQUALIZER:
2112                 if (!strcmp(value, "off"))
2113                         ret = 0x01;
2114                 else
2115                         ret = 0x02;
2116                 break;
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;
2124                 else
2125                         ret = BTRC_PLAYER_VAL_GROUP_REPEAT;
2126                 break;
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;
2132                 else
2133                         ret = BTRC_PLAYER_VAL_GROUP_SHUFFLE;
2134                 break;
2135         case HAL_PLAYER_ATTR_SCAN:
2136                 if (!strcmp(value, "off"))
2137                         ret = 0x01;
2138                 else if (!strcmp(value, "alltracks"))
2139                         ret = 0x02;
2140                 else
2141                         ret = 0x03;
2142                 break;
2143         default:
2144                 ERR("Value not handled");
2145         }
2146
2147         return ret;
2148 }
2149
2150 static void __bt_hal_handle_avrcp_ctrl_events(GVariant *msg, const char *member,
2151                 const char *path)
2152 {
2153         const char *property = NULL;
2154         GVariant *value = NULL;
2155         GVariantIter iter;
2156         char address[BT_HAL_ADDRESS_STRING_SIZE];
2157
2158         if (!msg) {
2159                 ERR("Error returned in method call\n");
2160                 return;
2161         }
2162
2163         if (!avrcp_ctrl_event_cb) {
2164                 ERR("AVRCP controller DBUS handler callback not registered");
2165                 return;
2166         }
2167
2168         g_variant_iter_init(&iter, msg);
2169
2170         _bt_hal_convert_device_path_to_address(path, address);
2171
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;
2179                         const char *valstr;
2180                         int val = 0;
2181
2182                         valstr = g_variant_get_string(value, NULL);
2183                         DBG("Value : %s ", valstr);
2184
2185                         if (valstr)
2186                                 val = __bt_media_attrval_to_val(__bt_media_attr_to_type(property), valstr);
2187
2188                         if (val >= 0) {
2189                                 memset(&ev, 0, sizeof(ev));
2190                                 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2191                                 ev.num_attr = 1;
2192                                 ev.attr_ids[0] = __bt_media_attr_to_type(property);
2193                                 ev.attr_values[0] = val;
2194
2195                                 /* Send event to application */
2196                                 avrcp_ctrl_event_cb(HAL_EV_AVRCP_CTRL_PLAYER_APP_SETTING_CHANGED, &ev, sizeof(ev));
2197                         }
2198                 } else if ((strcasecmp(property, "Status") == 0)) {
2199                         struct hal_ev_play_status_changed ev;
2200                         const char *valstr;
2201
2202                         valstr = g_variant_get_string(value, NULL);
2203                         DBG("Value : %s ", valstr);
2204
2205                         memset(&ev, 0, sizeof(ev));
2206                         _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2207                         if (valstr)
2208                                 ev.status = __bt_hal_play_status_str_to_type(valstr);
2209
2210                         /* Send event to application */
2211                         avrcp_ctrl_event_cb(HAL_EV_AVRCP_CTRL_PLAY_STATUS_CHANGED, &ev, sizeof(ev));
2212
2213                 } else if (strcasecmp(property, "Position") == 0) {
2214                         struct hal_ev_play_position ev;
2215
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);
2220
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;
2225
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);
2229
2230                         /* Send event to application */
2231                         avrcp_ctrl_event_cb(HAL_EV_AVRCP_CTRL_TRACK_CHANGED, &ev, sizeof(ev));
2232                 } else {
2233                         DBG("Property not handled");
2234                 }
2235         }
2236
2237         g_free((char *)property);
2238         g_variant_unref(value);
2239 }
2240
2241 /* A2DP Src Role(Remote:Sink) Events */
2242 static void __bt_hal_send_av_connection_state_event(gboolean connected, const char *address)
2243 {
2244         DBG("+");
2245         struct hal_ev_a2dp_conn_state ev;
2246
2247         if (connected == TRUE)
2248                 INFO("A2DP(Src) Profile Connected for address [%s]", address);
2249         else
2250                 INFO("A2DP(Src) Profile DisConnected for address [%s]", address);
2251
2252         ev.state = (connected == TRUE) ?
2253                 HAL_EV_A2DP_STATE_CONNECTED :
2254                 HAL_EV_A2DP_STATE_DISCONNECTED;
2255
2256         _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2257
2258         if (!av_event_cb)
2259                 ERR("AV event handler not registered");
2260         else
2261                 av_event_cb(HAL_EV_A2DP_CONN_STATE, &ev, sizeof(ev));
2262 }
2263
2264 /* A2DP Sink Role(Remote:Source) Events */
2265 static void __bt_hal_send_a2dp_sink_connection_state_event(gboolean connected, const char *address)
2266 {
2267         DBG("+");
2268         struct hal_ev_a2dp_conn_state ev;
2269
2270         if (connected == TRUE)
2271                 INFO("A2DP(Sink) Profile Connected for address [%s]", address);
2272         else
2273                 INFO("A2DP(Sink) Profile DisConnected for address [%s]", address);
2274
2275         ev.state = (connected == TRUE) ?
2276                 HAL_EV_A2DP_STATE_CONNECTED :
2277                 HAL_EV_A2DP_STATE_DISCONNECTED;
2278
2279         _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2280
2281         if (!a2dp_sink_event_cb)
2282                 ERR("AV event handler not registered");
2283         else
2284                 a2dp_sink_event_cb(HAL_EV_A2DP_SOURCE_CONN_STATE, &ev, sizeof(ev));
2285 }
2286
2287 /* HF(AG Role) Audio Events */
2288 static void __bt_hal_send_hf_audio_connection_state_event(gboolean connected,
2289                                                 const char *address)
2290 {
2291         DBG("+");
2292         struct hal_ev_handsfree_audio_state ev;
2293
2294         if (connected == TRUE)
2295                 INFO("AG Audio Connected for address [%s]", address);
2296         else
2297                 INFO("AG Audio DisConnected for address [%s]", address);
2298
2299         ev.state = (connected == TRUE) ?
2300                 HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTED :
2301                 HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED;
2302
2303         _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2304
2305         if (!hf_event_cb)
2306                 ERR("HF event handler not registered");
2307         else
2308                 hf_event_cb(HAL_EV_HANDSFREE_AUDIO_STATE, &ev, sizeof(ev));
2309 }
2310
2311 /* HF(AG Role) Profile Events */
2312 static void __bt_hal_send_hf_connection_state_event(gboolean connected,
2313                                                 const char *address)
2314 {
2315         DBG("+");
2316         struct hal_ev_handsfree_conn_state ev;
2317
2318         if (connected == TRUE)
2319                 INFO("AG Profile Connected for address [%s]", address);
2320         else
2321                 INFO("AG Profile DisConnected for address [%s]", address);
2322
2323         ev.state = (connected == TRUE) ?
2324                 HAL_EV_HANDSFREE_CONN_STATE_CONNECTED :
2325                 HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED;
2326
2327         _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2328
2329         if (!hf_event_cb)
2330                 ERR("HF event handler not registered");
2331         else
2332                 hf_event_cb(HAL_EV_HANDSFREE_CONN_STATE, &ev, sizeof(ev));
2333 }
2334
2335 void _bt_hal_register_event_handler_cb(bt_hal_module_e module, handle_stack_msg cb)
2336 {
2337         switch (module) {
2338         case HAL_HIDHOST:
2339                 hid_event_cb = cb;
2340                 break;
2341         case HAL_A2DP_SRC:
2342                 av_event_cb = cb;
2343                 break;
2344         case HAL_A2DP_SNK:
2345                 a2dp_sink_event_cb = cb;
2346                 break;
2347         case HAL_HF_AG:
2348                 hf_event_cb = cb;
2349                 break;
2350         case HAL_AVRCP_TG:
2351                 avrcp_tg_event_cb = cb;
2352                 break;
2353         case HAL_AVRCP_CTRL:
2354                 avrcp_ctrl_event_cb = cb;
2355                 break;
2356         case HAL_GATT:
2357                 gatt_event_cb = cb;
2358                 break;
2359         default:
2360                 ERR("Unknown module: %d", module);
2361         }
2362 }
2363
2364 void _bt_hal_unregister_event_handler_cb(bt_hal_module_e module)
2365 {
2366         switch (module) {
2367         case HAL_HIDHOST:
2368                 hid_event_cb = NULL;
2369                 break;
2370         case HAL_A2DP_SRC:
2371                 av_event_cb = NULL;
2372                 break;
2373         case HAL_A2DP_SNK:
2374                 a2dp_sink_event_cb = NULL;
2375                 break;
2376         case HAL_HF_AG:
2377                 hf_event_cb = NULL;
2378                 break;
2379         case HAL_AVRCP_TG:
2380                 avrcp_tg_event_cb = NULL;
2381                 break;
2382         case HAL_AVRCP_CTRL:
2383                 avrcp_ctrl_event_cb = NULL;
2384                 break;
2385         case HAL_GATT:
2386                 gatt_event_cb = NULL;
2387                 break;
2388         default:
2389                 ERR("Unknown module: %d", module);
2390         }
2391 }
2392
2393 bool _bt_hal_get_adapter_request_state(void)
2394 {
2395         return is_adapter_activating;
2396 }
2397
2398 bool _bt_hal_get_le_request_state(void)
2399 {
2400         return is_le_activating;
2401 }
2402
2403 void _bt_hal_set_adapter_request_state(bool enable)
2404 {
2405         DBG("set_adapter_request_state %d", enable);
2406         is_adapter_activating = enable;
2407 }
2408
2409 void _bt_hal_set_le_request_state(bool enable)
2410 {
2411         DBG("set_le_request_state %d", enable);
2412         is_le_activating = enable;
2413 }