719681c5575b0fd2be5cdee019f025f813b92111
[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 #include "bt-hal-gatt-client.h"
42
43 #define BASELEN_PROP_CHANGED (sizeof(struct hal_ev_adapter_props_changed) \
44                 + sizeof(struct hal_property))
45
46 /*TODO: Basic filters are currently added,
47   Need to add different event filters like HID,
48   Device etc in subsequent patches */
49
50 /* Global variables and structures */
51 static GDBusConnection *manager_conn;
52 static handle_stack_msg event_cb = NULL;
53 static handle_stack_msg hid_event_cb = NULL;
54 static handle_stack_msg av_event_cb = NULL;
55 static handle_stack_msg a2dp_sink_event_cb = NULL;
56 static handle_stack_msg hf_event_cb = NULL;
57 static handle_stack_msg avrcp_ctrl_event_cb = NULL;
58 static handle_stack_msg avrcp_tg_event_cb = NULL;
59 static handle_stack_msg gatt_event_cb = NULL;
60 static guint event_id;
61
62 /*State Management sepration Control for Adapter and LE */
63 static gboolean is_adapter_activating = FALSE;
64 static gboolean is_le_activating = FALSE;
65
66 typedef struct {
67         gchar* sender_name;
68         gchar* object_path;
69         gchar* interface_name;
70         gchar* signal_name;
71         GVariant *parameters;
72 } bt_hal_main_event_data_t;
73
74 /* Forward declarations */
75 static gboolean __bt_hal_event_manager(gpointer param);
76 static int __bt_hal_register_service_event(GDBusConnection *g_conn, int event_type);
77 static int __bt_hal_register_manager_subscribe_signal(GDBusConnection *conn, int subscribe);
78 static int __bt_hal_register_device_subscribe_signal(GDBusConnection *conn, int subscribe);
79 static int __bt_hal_register_input_subscribe_signal(GDBusConnection *conn, int subscribe);
80
81 static int __bt_hal_parse_event(GVariant *msg);
82 static int __bt_hal_get_owner_info(GVariant *msg, char **name, char **previous, char **current);
83
84 static void __bt_hal_handle_property_changed_event(GVariant *msg, const char *object_path);
85 static void __bt_hal_adapter_property_changed_event(GVariant *msg);
86 static  void __bt_hal_manager_event_filter(GDBusConnection *connection, const gchar *sender_name,
87                         const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
88                         GVariant *parameters, gpointer user_data);
89 static int __bt_hal_initialize_manager_receiver(void);
90 static gboolean __bt_hal_parse_interface(GVariant *msg);
91 static void __bt_hal_handle_device_event(GVariant *value, GVariant *parameters);
92 static gboolean __bt_hal_parse_device_properties(GVariant *item);
93 static gboolean __bt_hal_discovery_finished_cb(gpointer user_data);
94 static void __bt_hal_device_property_changed_event(GVariant *msg, const char *path);
95 static void __bt_hal_dbus_device_found_properties(const char *device_path);
96 static void __bt_hal_device_properties_lookup(GVariant *result, char *address);
97 static void __bt_hal_handle_device_specific_events(GVariant *msg, const char *member, const char *path);
98 static void __bt_hal_send_device_acl_connection_state_event(int status, gboolean connected, const char *address);
99 static void __bt_hal_handle_input_event(GVariant *msg, const char *path);
100 static void __bt_hal_send_av_connection_state_event(gboolean connected, const char *address);
101 static void __bt_hal_send_a2dp_sink_connection_state_event(gboolean connected, const char *address);
102 static void __bt_hal_send_avrcp_ctrl_connection_state_event(gboolean connected, const char *address);
103 static void __bt_hal_handle_avrcp_ctrl_events(GVariant *msg, const char *member, const char *path);
104 static void __bt_hal_handle_avrcp_transport_events(GVariant *msg, const char *member, const char *path);
105
106 static void __bt_hal_send_device_trust_state_event(gboolean is_trusted, const char *address);
107 static int __bt_hal_register_audio_subscribe_signal(GDBusConnection *conn, int subscribe);
108 static void __bt_hal_handle_headset_events(GVariant *msg, const char *member, const char *path);
109 static void __bt_hal_send_hf_audio_connection_state_event(gboolean connected, const char *address);
110 static void __bt_hal_send_hf_connection_state_event(gboolean connected, const char *address);
111 static void __bt_hal_send_device_trusted_profile_changed_event(uint32_t trust_val, const char *address);
112 static void __bt_hal_handle_adv_report(GVariant *msg, const char *path);
113
114 static gboolean __bt_hal_discovery_finished_cb(gpointer user_data)
115 {
116         event_id = 0;
117         DBG("+");
118         struct hal_ev_discovery_state_changed ev;
119         ev.state = HAL_DISCOVERY_STATE_STOPPED;
120         event_cb(HAL_EV_DISCOVERY_STATE_CHANGED, &ev, sizeof(ev));
121         DBG("-");
122
123         return FALSE;
124 }
125
126 static int __bt_hal_parse_event(GVariant *msg)
127 {
128         GVariantIter iter;
129         GVariant *child;
130         char *interface_name = NULL;
131         GVariant *inner_iter = NULL;
132
133         g_variant_iter_init(&iter, msg);
134
135         while ((child = g_variant_iter_next_value(&iter))) {
136                 g_variant_get(child, "{&s@a{sv}}", &interface_name, &inner_iter);
137                 if (g_strcmp0(interface_name,
138                                         BT_HAL_DEVICE_INTERFACE) == 0) {
139                         DBG("__bt_hal_parse_event: Interface: BT_HAL_DEVICE_INTERFACE");
140                         g_variant_unref(inner_iter);
141                         g_variant_unref(child);
142                         return BT_HAL_DEVICE_EVENT;
143                 } else if (g_strcmp0(interface_name,
144                                         BT_HAL_MEDIATRANSPORT_INTERFACE) == 0) {
145                         DBG("__bt_hal_parse_event: Interface: BT_HAL_MEDIATRANSPORT_INTERFACE");
146                         g_variant_unref(inner_iter);
147                         g_variant_unref(child);
148                         return BT_HAL_MEDIA_TRANSFER_EVENT;
149                 } else if (g_strcmp0(interface_name,
150                                         BT_HAL_PLAYER_CONTROL_INTERFACE) == 0) {
151                         DBG("__bt_hal_parse_event: Interface: BT_HAL_PLAYER_CONTROL_INTERFACE");
152                         g_variant_unref(inner_iter);
153                         g_variant_unref(child);
154                         return BT_HAL_AVRCP_CONTROL_EVENT;
155                 }
156                 g_variant_unref(inner_iter);
157                 g_variant_unref(child);
158         }
159
160         return 0;
161 }
162
163 static int __bt_hal_get_owner_info(GVariant *msg, char **name, char **previous, char **current)
164 {
165         g_variant_get(msg, "(sss)", name, previous, current);
166         return BT_HAL_ERROR_NONE;
167 }
168
169 int __bt_insert_hal_properties(void *buf, uint8_t type, uint16_t len, const void *val)
170 {       struct hal_property *prop = buf;
171
172         prop->type = type;
173         prop->len = len;
174
175         if (len)
176                 memcpy(prop->val, val, len);
177
178         return sizeof(*prop) + len;
179 }
180
181 handle_stack_msg _bt_hal_get_stack_message_handler(void)
182 {
183         return event_cb;
184 }
185
186 static void __bt_hal_adapter_property_changed_event(GVariant *msg)
187 {
188         GVariantIter value_iter;
189         GVariant *value = NULL;
190         GDBusProxy *adapter_proxy;
191         GError *err = NULL;
192         char *key = NULL;
193         g_variant_iter_init(&value_iter, msg);
194
195         /* Buffer and propety count management */
196         uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
197         struct hal_ev_adapter_props_changed *ev = (void*) buf;
198         size_t size = 0;
199         const gchar *address = NULL;
200         gchar *name = NULL;
201         unsigned int cod = 0;
202         gboolean discoverable;
203         gboolean connectable;
204         unsigned int scan_mode = BT_SCAN_MODE_NONE;
205         unsigned int disc_timeout;
206         const gchar *version;
207         gboolean ipsp_initialized;
208         gboolean powered;
209         gboolean pairable;
210         unsigned int pairable_timeout;
211         gboolean scan_mode_property_update = FALSE;
212         gboolean is_discovering;
213         gboolean is_le_discovering;
214
215         memset(buf, 0, sizeof(buf));
216         size = sizeof(*ev);
217         ev->num_props = 0;
218         ev->status = BT_STATUS_SUCCESS;
219
220         DBG("+");
221
222         while (g_variant_iter_loop(&value_iter, "{sv}", &key, &value)) {
223                 if (!g_strcmp0(key, "Address")) {
224                         uint8_t bdaddr[6];
225
226                         address = g_variant_get_string(value, NULL);
227                         DBG("##Address [%s]", address);
228                         _bt_hal_convert_addr_string_to_type(bdaddr, address);
229                         size += __bt_insert_hal_properties(buf + size,
230                                         HAL_PROP_ADAPTER_ADDR, sizeof(bdaddr), bdaddr);
231                         ev->num_props++;
232                 } else if (!g_strcmp0(key, "Alias")) {
233                         g_variant_get(value, "&s", &name);
234                         DBG("##Alias [%s] ", name);
235                         size += __bt_insert_hal_properties(buf + size,
236                                         HAL_PROP_ADAPTER_NAME, strlen(name) + 1, name);
237                         ev->num_props++;
238                 } else if (!g_strcmp0(key, "Class")) {
239                         cod = g_variant_get_uint32(value);
240                         DBG("##Class [%d]", cod);
241                         size += __bt_insert_hal_properties(buf + size,
242                                         HAL_PROP_ADAPTER_CLASS, sizeof(unsigned int), &cod);
243                         ev->num_props++;
244                 } else if (!g_strcmp0(key, "Discoverable")) {
245                         discoverable = g_variant_get_boolean(value);
246                         DBG("##Discoverable [%d]", discoverable);
247                         if (discoverable)
248                                 scan_mode = BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE;
249                         else
250                                 scan_mode = BT_SCAN_MODE_CONNECTABLE;
251                         scan_mode_property_update = TRUE;
252                 } else if (!g_strcmp0(key, "DiscoverableTimeout")) {
253                         disc_timeout = g_variant_get_uint32(value);
254                         DBG("##Discoverable Timeout [%d]", disc_timeout);
255                         size += __bt_insert_hal_properties(buf + size,
256                                         HAL_PROP_ADAPTER_DISC_TIMEOUT, sizeof(unsigned int), &disc_timeout);
257                         ev->num_props++;
258                 } else if (!g_strcmp0(key, "Connectable")) {
259                         connectable = g_variant_get_boolean(value);
260                         DBG("##Connectable [%d]", connectable);
261                         if (!connectable)
262                                 scan_mode = BT_SCAN_MODE_NONE;
263                         else if (scan_mode == BT_SCAN_MODE_NONE)
264                                 scan_mode = BT_SCAN_MODE_CONNECTABLE;
265                         scan_mode_property_update = TRUE;
266                 } else if (!g_strcmp0(key, "Version")) {
267                         version = g_variant_get_string(value, NULL);
268                         DBG("##Version [%s]", version);
269                         size += __bt_insert_hal_properties(buf + size,
270                                         HAL_PROP_ADAPTER_VERSION, strlen(version) + 1, version);
271                         ev->num_props++;
272                 } else if (!g_strcmp0(key, "Name")) {
273                         g_variant_get(value, "&s", &name);
274                         DBG("##Name [%s]", name);
275                         size += __bt_insert_hal_properties(buf + size,
276                                         HAL_PROP_ADAPTER_NAME, strlen(name) + 1, name);
277                         ev->num_props++;
278                 } else if (!g_strcmp0(key, "Powered")) {
279                         powered = g_variant_get_boolean(value);
280                         DBG("##Powered = %d", powered);
281                         /* TODO: Need to check this operation!! */
282                         if (powered == FALSE) {
283                                 DBG("###### Adapter Powered Down ######");
284                                 struct hal_ev_adapter_state_changed ev;
285                                 ev.state = HAL_POWER_OFF;
286                                 event_cb(HAL_EV_ADAPTER_STATE_CHANGED, &ev, sizeof(ev));
287 #ifdef TIZEN_BT_HAL
288                                 struct hal_ev_le_state_changed le_ev;
289                                 le_ev.state = HAL_POWER_OFF;
290                                 event_cb(HAL_EV_LE_STATE_CHANGED, &le_ev, sizeof(le_ev));
291 #endif
292                                 /* Destroy Agent */
293                                 _bt_hal_destroy_adapter_agent();
294                         } else {
295                                 DBG("###### Adapter Powered Up ######");
296                                 if (_bt_hal_get_adapter_request_state()) {
297                                         DBG("Sending STATE CHANGE EVENT for Adapter... ");
298                                         _bt_hal_set_adapter_request_state(FALSE);
299                                         struct hal_ev_adapter_state_changed ev;
300                                         ev.state = HAL_POWER_ON;
301                                         event_cb(HAL_EV_ADAPTER_STATE_CHANGED, &ev, sizeof(ev));
302                                 }
303 #ifdef TIZEN_BT_HAL
304                                 if (_bt_hal_get_le_request_state()) {
305                                         DBG("Sending STATE CHANGE EVENT for LE... ");
306                                         _bt_hal_set_le_request_state(FALSE);
307                                         struct hal_ev_le_state_changed ev;
308                                         ev.state = HAL_POWER_ON;
309                                         event_cb(HAL_EV_LE_STATE_CHANGED, &ev, sizeof(ev));
310                                 }
311 #endif
312                                 /* Create Agent */
313                                 _bt_hal_initialize_adapter_agent();
314                         }
315
316                 } else if (!g_strcmp0(key, "Pairable")) {
317                         pairable = g_variant_get_boolean(value);
318                         DBG("##Pairable [%d]", pairable);
319                 } else if (!g_strcmp0(key, "PairableTimeout")) {
320                         pairable_timeout = g_variant_get_uint32(value);
321                         DBG("##Pairable Timeout = %d", pairable_timeout);
322                 } else if (!g_strcmp0(key, "UUIDs")) {
323                         char **uuid_value;
324                         int uuid_count = 0;
325                         gsize size1 = 0;
326                         int i = 0;
327                         size1 = g_variant_get_size(value);
328                         int num_props_tmp = ev->num_props;
329                         if (size1 > 0) {
330                                 uuid_value = (char **)g_variant_get_strv(value, &size1);
331                                 for (i = 0; uuid_value[i] != NULL; i++)
332                                         uuid_count++;
333                                 /* UUID collection */
334                                 uint8_t uuids[BT_HAL_STACK_UUID_SIZE * uuid_count];
335                                 for (i = 0; uuid_value[i] != NULL; i++) {
336                                         char *uuid_str = NULL;
337                                         uint8_t uuid[BT_HAL_STACK_UUID_SIZE];
338                                         uuid_str = g_strdup(uuid_value[i]);
339                                         DBG("##UUID string [%s]\n", uuid_str);
340                                         _bt_hal_convert_uuid_string_to_type(uuid, uuid_str);
341                                         memcpy(uuids+i*BT_HAL_STACK_UUID_SIZE, uuid, BT_HAL_STACK_UUID_SIZE);
342                                         g_free(uuid_str);
343                                 }
344                                 size += __bt_insert_hal_properties(buf + size, HAL_PROP_ADAPTER_UUIDS,
345                                                 (BT_HAL_STACK_UUID_SIZE * uuid_count),
346                                                 uuids);
347                                 ev->num_props = num_props_tmp + 1;
348                                 g_free(uuid_value);
349                         }
350                 } else if (!g_strcmp0(key, "Discovering")) {
351                         is_discovering = g_variant_get_boolean(value);
352                         DBG("##Discovering = [%d]", is_discovering);
353
354                         if (is_discovering == FALSE) {
355                                 DBG("###### Adapter Has stopped Discovering ######");
356                                 /* In Tizen Bluez, this actually does not mean Discovery is stopped
357                                    in Bluez. Tizen Bluez sends this event after a certain timeout,
358                                    Therefore, we must forecefully call StopDiscovery to stop discovery in BlueZ */
359                                 if (event_id > 0)
360                                         continue;
361
362                                 adapter_proxy = _bt_hal_get_adapter_proxy();
363
364                                 if (adapter_proxy == NULL)
365                                         continue;
366
367                                 /* Need to stop searching */
368                                 DBG("Event though Bluez reported DIscovering stopped, we force stop Discovery ");
369                                 g_dbus_proxy_call_sync(adapter_proxy, "StopDiscovery",
370                                                 NULL,
371                                                 G_DBUS_CALL_FLAGS_NONE,
372                                                 DBUS_TIMEOUT, NULL,
373                                                 &err);
374                                 if (err) {
375                                         ERR("Dbus Error : %s", err->message);
376
377                                         /* This error is thrown by Bluez, as Discovery is already stopped.
378                                            Discovery is stopped if user cancels on going discovery.
379                                            In order to maintain correct state of Bluetooth Discovery state,
380                                            simply send Discovery stopped event to HAL user */
381                                         struct hal_ev_discovery_state_changed ev;
382                                         ev.state = HAL_DISCOVERY_STATE_STOPPED;
383                                         event_cb(HAL_EV_DISCOVERY_STATE_CHANGED, &ev, sizeof(ev));
384                                         g_clear_error(&err);
385                                         continue;
386
387                                 } else {
388                                         event_id = g_timeout_add(BT_HAL_DISCOVERY_FINISHED_DELAY,
389                                                         (GSourceFunc)__bt_hal_discovery_finished_cb, NULL);
390                                 }
391
392                         } else {
393                                 DBG("###### Adapter Has started Discovering ######");
394                                 struct hal_ev_discovery_state_changed ev;
395                                 ev.state = HAL_DISCOVERY_STATE_STARTED;
396                                 event_cb(HAL_EV_DISCOVERY_STATE_CHANGED, &ev, sizeof(ev));
397                         }
398
399                 } else if (!g_strcmp0(key, "LEDiscovering")) {
400                         GVariant *result;
401
402                         is_le_discovering = g_variant_get_boolean(value);
403                         DBG("##LE Discovering = [%d]", is_le_discovering);
404
405                         if (is_le_discovering)
406                                 continue;
407
408                         adapter_proxy = _bt_hal_get_adapter_proxy();
409                         if (adapter_proxy == NULL) {
410                                 ERR("adapter_proxy == NULL");
411                                 continue;
412                         }
413
414                         /* Need to stop searching */
415                         result = g_dbus_proxy_call_sync(adapter_proxy, "StopLEDiscovery",
416                                         NULL, G_DBUS_CALL_FLAGS_NONE,
417                                         DBUS_TIMEOUT, NULL, &err);
418                         if (!result) {
419                                 ERR("Error occured in Proxy call");
420                                 if (err) {
421                                         ERR("(Error: %s)", err->message);
422                                         g_clear_error(&err);
423                                 }
424                                 continue;
425                         }
426                         g_variant_unref(result);
427                 } else if (!g_strcmp0(key, "Modalias")) {
428                         char *modalias = NULL;
429                         g_variant_get(value, "s", &modalias);
430                         DBG("##Adapter ModAlias [%s]", modalias);
431                 } else if (!g_strcmp0(key, "SupportedLEFeatures")) {
432                         DBG("##LE Supported features");
433                         char *name = NULL;
434                         char *val = NULL;
435                         GVariantIter *iter = NULL;
436                         g_variant_get(value, "as", &iter);
437                         bt_local_le_features_t le_features;
438                         gboolean le_features_present = FALSE;
439
440                         if (iter == NULL)
441                                 continue;
442
443                         memset(&le_features, 0x00, sizeof(le_features));
444
445                         while (g_variant_iter_next(iter, "&s", &name) &&
446                                         g_variant_iter_next(iter, "&s", &val)) {
447                                 DBG("name = %s, Value = %s", name, val);
448                                 if (FALSE == _bt_hal_update_le_feature_support(name, val, &le_features))
449                                         ERR("Failed to update LE feature (name = %s, value = %s)", name, val);
450                                 else
451                                         le_features_present = TRUE;
452                         }
453
454                         g_variant_iter_free(iter);
455                         if (le_features_present) {
456                                 size += __bt_insert_hal_properties(buf + size,
457                                                 HAL_PROP_ADAPTER_LOCAL_LE_FEAT, sizeof(le_features), &le_features);
458                                 ev->num_props++;
459                         } else {
460                                 DBG("le supported features values are NOT provided by Stack");
461                         }
462                 } else if (!g_strcmp0(key, "IpspInitStateChanged")) {
463                         g_variant_get(value, "b" , &ipsp_initialized);
464                         DBG("##IPSP Initialized = %d", ipsp_initialized);
465                 } else {
466                         ERR("Unhandled Property:[%s]", key);
467                 }
468         }
469
470         if (scan_mode_property_update) {
471                 size += __bt_insert_hal_properties(buf + size,
472                                 HAL_PROP_ADAPTER_SCAN_MODE, sizeof(int), &scan_mode);
473                 ev->num_props++;
474         }
475
476
477         if (size > 2) {
478                 DBG("Send Adapter properties changed event to HAL user, Num Prop [%d] total size [%zd]", ev->num_props, size);
479                 event_cb(HAL_EV_ADAPTER_PROPS_CHANGED, buf, size);
480         }
481
482         DBG("-");
483 }
484
485 void _bt_hal_handle_adapter_event(GVariant *msg, const char *member)
486 {
487         DBG("+");
488
489         if (member == NULL)
490                 return;
491
492         if (strcasecmp(member, "DeviceCreated") == 0) {
493                 DBG("DeviceCreated: Unhandled");
494         } else if (strcasecmp(member, "InterfacesRemoved") == 0) {
495                 DBG("InterfacesRemoved: Unhandled");
496         } else if (strcasecmp(member, "AdvertisingEnabled") == 0) {
497                 DBG("AdvertisingEnabled");
498                 DBG("Advertising Enabled");
499                 int slot_id;
500                 gboolean status = FALSE;
501                 g_variant_get(msg, "(ib)", &slot_id, &status);
502                 DBG("Advertising Enabled : slot_id [%d]  status [%d]", slot_id, status);
503                 /* Send event to application */
504                 _bt_hal_set_advertising_status(slot_id, status);
505         } else if (strcasecmp(member, "RssiEnabled") == 0) {
506                 struct hal_ev_rssi_monitor_state_changed ev;
507                 gboolean status = FALSE;
508                 char *address = NULL;
509                 int link_type;
510
511                 g_variant_get(msg, "(sib)", &address, &link_type, &status);
512                 DBG("RSSI monitoring %s for %s",
513                                 (status ? "Enabled" : "Disabled"), address);
514
515                 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
516                 ev.link_type = link_type;
517                 ev.state = (status ? HAL_RSSI_MONITORING_ENABLED : HAL_RSSI_MONITORING_DISABLED);
518                 if (!event_cb)
519                         ERR("event_cb is NULL");
520                 else
521                         event_cb(HAL_EV_RSSI_MONITOR_STATE_CHANGED, &ev, sizeof(ev));
522
523                 g_free(address);
524         } else if (strcasecmp(member, "RssiAlert") == 0) {
525                 struct hal_ev_rssi_alert_recieved ev;
526                 int alert_type;
527                 int rssi_dbm;
528                 int link_type;
529                 char *address = NULL;
530
531                 g_variant_get(msg, "(siii)", &address, &link_type, &alert_type, &rssi_dbm);
532                 DBG("RSSI Alert: [Address %s LinkType %d] [Type %d DBM %d]",
533                                 address, alert_type, rssi_dbm, link_type);
534
535                 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
536                 ev.link_type = link_type;
537                 ev.alert_type = alert_type;
538                 ev.rssi = rssi_dbm;
539
540                 if (!event_cb)
541                         ERR("event_cb is NULL");
542                 else
543                         event_cb(HAL_EV_RSSI_ALERT_RECIEVED, &ev, sizeof(ev));
544
545                 g_free(address);
546         } else if (strcasecmp(member, "RawRssi") == 0) {
547                 struct hal_ev_raw_rssi_recieved ev;
548                 int rssi_dbm;
549                 int link_type;
550                 char *address = NULL;
551
552                 g_variant_get(msg, "(sii)", &address, &link_type, &rssi_dbm);
553                 DBG("Raw RSSI: [Address %s] [Link Type %d][RSSI DBM %d]",
554                                 address, link_type, rssi_dbm);
555
556                 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
557                 ev.link_type = link_type;
558                 ev.rssi = rssi_dbm;
559
560                 if (!event_cb)
561                         ERR("event_cb is NULL");
562                 else
563                         event_cb(HAL_EV_RAW_RSSI_RECIEVED, &ev, sizeof(ev));
564
565                 g_free(address);
566         } else if (strcasecmp(member, BT_HAL_HARDWARE_ERROR) == 0) {
567                 DBG("BT Hardware Error: Unhandled");
568         } else if (strcasecmp(member, BT_HAL_TX_TIMEOUT_ERROR) == 0) {
569                 DBG("BT TX Timeout Error: Unhandled");
570
571         }
572         DBG("-");
573 }
574
575 static gboolean __bt_hal_parse_device_properties(GVariant *item)
576 {
577         GVariantIter iter;
578         gchar *key;
579         GVariant *val;
580         gsize len = 0;
581         if (!item)
582                 return FALSE;
583         DBG("+");
584
585         /* Buffer and propety count management */
586         uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
587         struct hal_ev_device_found *ev = (void *) buf;
588         size_t size = 0;
589         memset(buf, 0, sizeof(buf));
590         size = sizeof(*ev);
591         ev->num_props = 0;
592
593         g_variant_iter_init(&iter, item);
594         while (g_variant_iter_loop(&iter, "{sv}", &key, &val)) {
595
596                 if (strcasecmp(key, "Address") == 0)  {
597
598                         char * address = NULL;
599                         address = g_variant_dup_string(val, &len);
600                         uint8_t bdaddr[6];
601                         _bt_hal_convert_addr_string_to_type(bdaddr, address);
602
603                         size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_ADDR,
604                                         sizeof(bdaddr), bdaddr);
605
606                         ev->num_props++;
607                         DBG("Device address [%s] property Num [%d]", address, ev->num_props);
608                         g_free(address);
609                 } else if (strcasecmp(key, "Class") == 0) {
610                         unsigned int class = g_variant_get_uint32(val);
611                         size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_CLASS,
612                                         sizeof(unsigned int), &class);
613                         ev->num_props++;
614                         DBG("Device class [%d] Property num [%d]", class, ev->num_props);
615                 } else if (strcasecmp(key, "name") == 0) {
616                         char *name = g_variant_dup_string(val, &len);
617                         if (name) {
618                                 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_NAME,
619                                                 strlen(name) + 1, name);
620                                 ev->num_props++;
621                                 DBG("Device Name [%s] Property num [%d]", name, ev->num_props);
622                         }
623                         g_free(name);
624                 } else if (strcasecmp(key, "Connected") == 0) {
625                         unsigned int connected = g_variant_get_byte(val);
626
627                         size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_CONNECTED,
628                                         sizeof(unsigned int), &connected);
629                         ev->num_props++;
630                         DBG("Device connected [%u] Property num [%d]", connected,  ev->num_props);
631                 } else if (strcasecmp(key, "paired") == 0) {
632                         uint8_t paired = (g_variant_get_boolean(val) ? 1 : 0);
633                         size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_PAIRED,
634                                         sizeof(uint8_t), &paired);
635                         ev->num_props++;
636                         DBG("Device Paired [%d] Property num [%d]", paired, ev->num_props);
637                 } else if (strcasecmp(key, "Trusted") == 0) {
638                         uint8_t trust = (g_variant_get_boolean(val) ? 1 : 0);
639                         size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_TRUSTED,
640                                         sizeof(uint8_t), &trust);
641                         ev->num_props++;
642                         DBG("Device trusted [%d] Property num [%d]", trust, ev->num_props);
643                 } else if (strcasecmp(key, "RSSI") == 0) {
644                         int rssi = g_variant_get_int16(val);
645                         size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_RSSI,
646                                         sizeof(int), &rssi);
647                         ev->num_props++;
648                         DBG("Device RSSI [%d] Property num [%d]", rssi, ev->num_props);
649                 } else if (strcasecmp(key, "LastAddrType") == 0) {
650                         /* TODO: To be handled later*/
651                 } else if (!g_strcmp0(key, "IsAliasSet")) {
652                         uint8_t is_alias_set = (g_variant_get_boolean(val) ? 1 : 0);
653                         DBG("IsAliasSet: %s", (is_alias_set ? "TRUE" : "FALSE"));
654                         size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_IS_ALIAS_SET,
655                                         sizeof(uint8_t), &is_alias_set);
656                         ev->num_props++;
657                 } else if (strcasecmp(key, "UUIDs") == 0) {
658                         char **uuid_value;
659                         int uuid_count = 0;
660                         gsize size1 = 0;
661                         int i = 0;
662                         size1 = g_variant_get_size(val);
663                         DBG("UUID count from size  [%zu]\n", size1);
664                         int num_props_tmp = ev->num_props;
665
666                         if (size1 > 0) {
667                                 uuid_value = (char **)g_variant_get_strv(val, &size1);
668                                 for (i = 0; uuid_value[i] != NULL; i++)
669                                         uuid_count++;
670                                 DBG("UUID count [%d]\n", uuid_count);
671                                 /* UUID collection */
672                                 uint8_t uuids[BT_HAL_STACK_UUID_SIZE * uuid_count];
673
674                                 for (i = 0; uuid_value[i] != NULL; i++) {
675
676                                         char *uuid_str = NULL;
677                                         uint8_t uuid[BT_HAL_STACK_UUID_SIZE];
678                                         memset(uuid, 0x00, BT_HAL_STACK_UUID_SIZE);
679
680                                         DBG("UUID string from Bluez [%s]\n", uuid_value[i]);
681                                         uuid_str = g_strdup(uuid_value[i]);
682                                         DBG("UUID string [%s]\n", uuid_str);
683                                         _bt_hal_convert_uuid_string_to_type(uuid, uuid_str);
684                                         memcpy(uuids+i*BT_HAL_STACK_UUID_SIZE, uuid, BT_HAL_STACK_UUID_SIZE);
685                                         g_free(uuid_str);
686                                 }
687
688                                 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_UUIDS,
689                                                 (BT_HAL_STACK_UUID_SIZE * uuid_count),
690                                                 uuids);
691                                 ev->num_props = num_props_tmp + 1;
692                                 g_free(uuid_value);
693                         }
694
695                 } else if (strcasecmp(key, "LegacyManufacturerDataLen") == 0) {
696                         /* TODO: To be handled later*/
697                 } else if (strcasecmp(key, "LegacyManufacturerData") == 0) {
698                         /* TODO: To be handled later*/
699                 } else {
700                         ERR("Unhandled Property:[%s]", key);
701                 }
702         }
703         DBG("-");
704
705         if (size > 1) {
706                 DBG("Send Device found event to HAL user, Num Prop [%d] total size [%zd]", ev->num_props, size);
707                 event_cb(HAL_EV_DEVICE_FOUND, (void*) buf, size);
708         }
709
710         return TRUE;
711 }
712
713 static void __bt_hal_handle_avrcp_tg_events(GVariant *msg, const char *path)
714 {
715         int state;
716         GVariantIter value_iter;
717         char *property = NULL;
718         char *address;
719         GVariant *val = NULL;
720         GVariant *child = NULL;
721
722         g_variant_iter_init(&value_iter, msg);
723         while ((child = g_variant_iter_next_value(&value_iter))) {
724                 g_variant_get(child, "{sv}", &property, &val);
725                 INFO("Property %s", property);
726                 if (strcasecmp(property, "Connected") == 0) {
727                         struct hal_ev_avrcp_tg_conn_state ev;
728
729                         gboolean connected = FALSE;
730
731                         g_variant_get(val, "b", &connected);
732
733                         state = connected ? HAL_AVRCP_TG_STATE_CONNECTED :
734                                 HAL_AVRCP_TG_STATE_DISCONNECTED;
735
736                         address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
737
738                         _bt_hal_convert_device_path_to_address(path, address);
739
740                         DBG("connected: %d", connected);
741                         DBG("address: %s", address);
742
743                         /* Prepare to send AVRCP Target connection state event */
744                         memset(&ev, 0, sizeof(ev));
745                         _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
746                         ev.state = state;
747                         if (!avrcp_tg_event_cb)
748                                 ERR("AVRCP target DBUS handler callback not registered");
749                         else
750                                 avrcp_tg_event_cb(HAL_EV_AVRCP_TG_CONN_STATE, (void *)&ev, sizeof(ev));
751                         g_free(address);
752                 }
753                 g_free(property);
754                 g_variant_unref(child);
755                 g_variant_unref(val);
756         }
757
758         DBG("-");
759 }
760
761 static void __bt_hal_handle_property_changed_event(GVariant *msg, const char *object_path)
762 {
763         char *interface_name = NULL;
764         GVariant *val = NULL;
765         DBG("+");
766
767         g_variant_get(msg, "(&s@a{sv}@as)", &interface_name, &val, NULL);
768
769         if (!interface_name) {
770                 DBG("Failed to get interface name");
771
772                 if (val)
773                         g_variant_unref(val);
774                 return;
775         }
776
777         if (strcasecmp(interface_name, BT_HAL_ADAPTER_INTERFACE) == 0) {
778                 DBG("Event: Property Changed: Interface: BT_HAL_ADAPTER_INTERFACE");
779                 __bt_hal_adapter_property_changed_event(val);
780         } else if (strcasecmp(interface_name, BT_HAL_DEVICE_INTERFACE) == 0) {
781                 DBG("Event: Property Changed: Interface: BT_HAL_DEVICE_INTERFACE");
782                 __bt_hal_device_property_changed_event(val, object_path);
783         } else if (strcasecmp(interface_name, BT_HAL_OBEX_TRANSFER_INTERFACE) == 0) {
784                 DBG("Event: Property Changed: Interface: BT_HAL_OBEX_TRANSFER_INTERFACE");
785                 /* TODO: Handle event */
786         } else if (strcasecmp(interface_name, BT_HAL_MEDIA_CONTROL_INTERFACE) == 0) {
787                 DBG("Event: Property Changed: Interface: BT_HAL_MEDIA_CONTROL_INTERFACE");
788                 /* Handle AVRCP target event */
789                 __bt_hal_handle_avrcp_tg_events(val, object_path);
790         } else if (strcasecmp(interface_name, BT_HAL_PLAYER_CONTROL_INTERFACE) == 0) {
791                 DBG("Event: Property Changed: Interface: BT_HAL_PLAYER_CONTROL_INTERFACE");
792                 __bt_hal_handle_avrcp_ctrl_events(val, NULL, object_path);
793         } else if (strcasecmp(interface_name, BT_HAL_MEDIATRANSPORT_INTERFACE) == 0) {
794                 DBG("Event: Property Changed: Interface: BT_HAL_MEDIATRANSPORT_INTERFACE");
795                 __bt_hal_handle_avrcp_transport_events(val, NULL, object_path);
796         } else if (strcasecmp(interface_name, BT_HAL_NETWORK_CLIENT_INTERFACE) == 0) {
797                 DBG("Event: Property Changed: Interface: BT_HAL_NETWORK_CLIENT_INTERFACE");
798                 /* TODO: Handle event */
799         } else if (strcasecmp(interface_name, BT_HAL_GATT_CHAR_INTERFACE) == 0) {
800                 DBG("Event: Property Changed: Interface: BT_HAL_GATT_CHAR_INTERFACE");
801                 /* TODO: Handle event */
802         } else if (strcasecmp(interface_name, BT_HAL_INPUT_INTERFACE) == 0) {
803                 DBG("Event: Property Changed: Interface: BT_HAL_INPUT_INTERFACE");
804                 __bt_hal_handle_input_event(val, object_path);
805         }
806         g_variant_unref(val);
807 }
808
809 static void __bt_hal_handle_device_event(GVariant *value, GVariant *parameters)
810 {
811         DBG("+");
812
813         if (__bt_hal_parse_interface(parameters) == FALSE) {
814                 ERR("Fail to parse the properies");
815                 g_variant_unref(value);
816                 return;
817         }
818
819         DBG("-");
820 }
821
822 static void __bt_hal_send_hid_connection_state_event(
823                 gboolean connected, char *address)
824 {
825         struct hal_ev_hidhost_conn_state ev;
826
827         ev.state = (connected == TRUE) ?
828                 HAL_HIDHOST_STATE_CONNECTED :
829                 HAL_HIDHOST_STATE_DISCONNECTED;
830
831         _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
832
833         if (!hid_event_cb)
834                 ERR("HID event handler not registered");
835         else
836                 hid_event_cb(HAL_EV_HIDHOST_CONN_STATE, &ev, sizeof(ev));
837 }
838
839 static void __bt_hal_handle_input_event(GVariant *msg, const char *path)
840 {
841         gboolean property_flag = FALSE;
842         GVariantIter value_iter;
843         char *property = NULL;
844         GVariant *child = NULL, *val = NULL;
845
846         DBG("+");
847         g_variant_iter_init(&value_iter, msg);
848         while ((child = g_variant_iter_next_value(&value_iter))) {
849                 g_variant_get(child, "{sv}", &property, &val);
850
851                 if (property == NULL)
852                         return;
853
854                 if (strcasecmp(property, "Connected") == 0) {
855                         char *address;
856
857                         g_variant_get(val, "b", &property_flag);
858                         address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
859                         _bt_hal_convert_device_path_to_address(path, address);
860                         __bt_hal_send_hid_connection_state_event(property_flag, address);
861                         g_free(address);
862                 }
863                 g_free(property);
864                 g_variant_unref(val);
865                 g_variant_unref(child);
866         }
867
868         DBG("-");
869 }
870
871 static gboolean __bt_hal_parse_interface(GVariant *msg)
872 {
873         char *path = NULL;
874         GVariant *optional_param;
875         GVariantIter iter;
876         GVariant *child;
877         char *interface_name = NULL;
878         GVariant *inner_iter = NULL;
879         g_variant_get(msg, "(&o@a{sa{sv}})",
880                         &path, &optional_param);
881         g_variant_iter_init(&iter, optional_param);
882
883         while ((child = g_variant_iter_next_value(&iter))) {
884                 g_variant_get(child, "{&s@a{sv}}", &interface_name, &inner_iter);
885                 if (g_strcmp0(interface_name, BT_HAL_DEVICE_INTERFACE) == 0) {
886                         DBG("Found a device: %s", path);
887                         if (__bt_hal_parse_device_properties(inner_iter) == FALSE) {
888                                 g_variant_unref(inner_iter);
889                                 g_variant_unref(child);
890                                 g_variant_unref(optional_param);
891                                 ERR("Fail to parse the properies");
892                                 return FALSE;
893                         } else {
894                                 g_variant_unref(inner_iter);
895                                 g_variant_unref(child);
896                                 g_variant_unref(optional_param);
897                                 return TRUE;
898                         }
899                 }
900                 g_variant_unref(inner_iter);
901                 g_variant_unref(child);
902         }
903
904         g_variant_unref(optional_param);
905
906         return FALSE;
907 }
908
909 void __bt_hal_handle_gatt_char_event(GVariant *parameters, const char *signal_name)
910 {
911         DBG("+");
912
913         if (signal_name == NULL)
914                 return;
915
916         if (strcasecmp(signal_name, "GattValueChanged") == 0) {
917                 DBG("GattValueChanged event received");
918
919                 int result = 0;
920                 const char *char_handle = NULL;
921                 GVariant *char_value_var = NULL;
922                 int len = 0;
923                 char *char_value = NULL;
924
925                 g_variant_get(parameters, "(i&s@ay)", &result, &char_handle, &char_value_var);
926                 DBG("char handle: %s", char_handle);
927
928                 len = g_variant_get_size(char_value_var);
929                 if (len > 0)
930                         char_value = (char *)g_variant_get_data(char_value_var);
931
932                 _bt_hal_handle_gattc_value_changed_event(result, char_handle, char_value, len);
933
934                 g_variant_unref(char_value_var);
935         }
936 }
937
938
939 static gboolean __bt_hal_event_manager(gpointer data)
940 {
941         bt_hal_event_type_t bt_event = 0x00;
942         GVariant *value;
943         char *obj_path = NULL;
944
945         bt_hal_main_event_data_t *param = (bt_hal_main_event_data_t*)data;
946         if (strcasecmp(param->signal_name, "InterfacesAdded") == 0) {
947
948                 /*TODO: Handle Interfaces Added Signal from stack */
949                 DBG("Manager Event: Signal Name: InterfacesAdded");
950
951                 g_variant_get(param->parameters, "(&o@a{sa{sv}})", &obj_path, &value);
952
953                 if (obj_path == NULL) {
954                         DBG("obj_path is NULL");
955                         return FALSE;
956                 }
957
958                 if (strcasecmp(obj_path, BT_HAL_BLUEZ_HCI_PATH) == 0) {
959                         /* TODO: Handle adapter added */
960                         DBG("Manager Event: Signal Name: InterfiacesAdded: Adapter added in bluetoothd: path [hci0]");
961                 } else {
962                         bt_event = __bt_hal_parse_event(value);
963                         if (bt_event == BT_HAL_DEVICE_EVENT) {
964                                 DBG("Device path : %s ", obj_path);
965                                 __bt_hal_handle_device_event(value, param->parameters);
966                         } else if (bt_event == BT_HAL_AVRCP_CONTROL_EVENT) {
967                                 DBG("Device path : %s ", obj_path);
968                                 _bt_hal_set_control_device_path(obj_path);
969                         }
970                 }
971                 g_variant_unref(value);
972
973         } else if (strcasecmp(param->signal_name, "InterfacesRemoved") == 0) {
974                 char *str;
975                 GVariantIter *iter;
976
977                 /*TODO: Handle Interfaces Removed Signal from stack */
978                 DBG("Manager Event: Signal Name: InterfacesRemoved");
979
980                 g_variant_get(param->parameters, "(&oas)", &obj_path, &iter);
981                 DBG("Device path : %s ", obj_path);
982                 while (g_variant_iter_loop(iter, "s", &str)) {
983                         if (g_strcmp0(str, BT_HAL_PLAYER_CONTROL_INTERFACE) == 0)
984                                 _bt_hal_remove_control_device_path(obj_path);
985                 }
986                 g_variant_iter_free(iter);
987         } else if (strcasecmp(param->signal_name, "NameOwnerChanged") == 0) {
988                 char *name = NULL;
989                 char *previous = NULL;
990                 char *current = NULL;
991
992                 /* TODO: Handle Name Owener changed Signal */
993                 if (__bt_hal_get_owner_info(param->parameters, &name, &previous, &current)) {
994                         DBG("Fail to get the owner info");
995                         return FALSE;
996                 }
997                 if (current && *current != '\0') {
998                         g_free(name);
999                         g_free(previous);
1000                         g_free(current);
1001                         return FALSE;
1002                 }
1003                 if (strcasecmp(name, BT_HAL_BLUEZ_NAME) == 0) {
1004                         DBG("Bluetoothd is terminated");
1005
1006                         /* TODO: Handle Bluetoothd terminating scenario */
1007                         _bt_hal_le_deinit();
1008                 }
1009                 INFO("Name Owner changed [%s]", name);
1010                 g_free(name);
1011                 g_free(previous);
1012                 g_free(current);
1013
1014         } else if (g_strcmp0(param->interface_name, BT_HAL_PROPERTIES_INTERFACE) == 0) {
1015                 DBG("Manager Event: Interface Name: BT_HAL_PROPERTIES_INTERFACE");
1016                 __bt_hal_handle_property_changed_event(param->parameters, param->object_path);
1017         } else if (g_strcmp0(param->interface_name, BT_HAL_ADAPTER_INTERFACE) == 0) {
1018                 DBG("Manager Event: Interface Name: BT_HAL_ADAPTER_INTERFACE");
1019                 _bt_hal_handle_adapter_event(param->parameters, param->signal_name);
1020         } else if (g_strcmp0(param->interface_name, BT_HAL_INPUT_INTERFACE) == 0) {
1021                 DBG("Manager Event: Interface Name: BT_HAL_INPUT_INTERFACE");
1022                 __bt_hal_handle_input_event(param->parameters, param->object_path);
1023         } else if (g_strcmp0(param->interface_name, BT_HAL_NETWORK_SERVER_INTERFACE) == 0) {
1024                 /* TODO: Handle Network Server events from stack */
1025                 DBG("Manager Event: Interface Name: BT_HAL_NETWORK_SERVER_INTERFACE");
1026         } else if (g_strcmp0(param->interface_name, BT_HAL_HEADSET_INTERFACE) == 0) {
1027                 DBG("Manager Event: Interface Name: BT_HAL_HEADSET_INTERFACE");
1028                 __bt_hal_handle_headset_events(param->parameters, param->signal_name, param->object_path);
1029         } else if (g_strcmp0(param->interface_name, BT_HAL_SINK_INTERFACE) == 0) {
1030                 /* TODO: Handle Sink interface events from stack */
1031                 DBG("Manager Event: Interface Name:BT_HAL_SINK_INTERFACE");
1032         } else if (g_strcmp0(param->interface_name, BT_HAL_AGENT_INTERFACE) == 0) {
1033                 /* TODO: Handle Agent events from stack */
1034                 DBG("Manager Event: Interface Name:BT_HAL_AGENT_INTERFACE");
1035         } else if (g_strcmp0(param->interface_name, BT_HAL_DEVICE_INTERFACE) == 0) {
1036                 DBG("Manager Event: Interface Name:BT_HAL_DEVICE_INTERFACE");
1037                 __bt_hal_handle_device_specific_events(param->parameters, param->signal_name, param->object_path);
1038         } else if (g_strcmp0(param->interface_name, BT_HAL_PLAYER_CONTROL_INTERFACE) == 0) {
1039                 DBG("Manager Event: Interface Name: BT_HAL_PLAYER_CONTROL_INTERFACE");
1040                 __bt_hal_handle_avrcp_ctrl_events(param->parameters, param->signal_name, param->object_path);
1041         } else if (g_strcmp0(param->interface_name, BT_HAL_MEDIATRANSPORT_INTERFACE) == 0) {
1042                 DBG("Manager Event: Interface Name: BT_HAL_MEDIATRANSPORT_INTERFACE");
1043                 __bt_hal_handle_avrcp_transport_events(param->parameters, param->signal_name, param->object_path);
1044         } else if (g_strcmp0(param->interface_name, BT_HAL_GATT_CHAR_INTERFACE) == 0) {
1045                 DBG("Manager Event: Interface Name: BT_HAL_GATT_CHAR_INTERFACE");
1046                 __bt_hal_handle_gatt_char_event(param->parameters, param->signal_name);
1047         }
1048
1049
1050         /* Free data */
1051         g_free(param->sender_name);
1052         g_free(param->object_path);
1053         g_free(param->interface_name);
1054         g_free(param->signal_name);
1055         g_variant_unref(param->parameters);
1056
1057         return FALSE;
1058 }
1059
1060 static  void __bt_hal_manager_event_filter(GDBusConnection *connection,
1061                 const gchar *sender_name,
1062                 const gchar *object_path,
1063                 const gchar *interface_name,
1064                 const gchar *signal_name,
1065                 GVariant *parameters,
1066                 gpointer user_data)
1067 {
1068         if (signal_name == NULL)
1069                 return;
1070
1071         bt_hal_main_event_data_t *param = g_new0(bt_hal_main_event_data_t, 1);
1072         param->sender_name = g_strdup(sender_name);
1073         param->object_path = g_strdup(object_path);
1074         param->interface_name = g_strdup(interface_name);
1075         param->signal_name = g_strdup(signal_name);
1076         param->parameters = g_variant_ref(parameters);
1077
1078         g_idle_add(__bt_hal_event_manager, (gpointer)param);
1079         return;
1080 }
1081
1082 static void __bt_hal_handle_headset_events(GVariant *msg, const char *member, const char *path)
1083 {
1084         gboolean property_flag = FALSE;
1085         char *property = NULL;
1086         GVariant *value = NULL;
1087         g_variant_get(msg, "(sv)", &property, &value);
1088
1089         if (property == NULL)
1090                 return;
1091
1092         DBG("Property = %s \n", property);
1093         /* We allow only 1 headset connection (HSP or HFP)*/
1094         if (strcasecmp(property, "Connected") == 0) {
1095                 char *address;
1096                 g_variant_get(value, "b", &property_flag);
1097
1098                 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1099
1100                 /* Fix : NULL_RETURNS */
1101                 if (address == NULL)
1102                         return;
1103
1104                 _bt_hal_convert_device_path_to_address(path, address);
1105                 __bt_hal_send_hf_audio_connection_state_event(property_flag, address);
1106                 g_free(address);
1107         } else if (strcasecmp(property, "State") == 0) {
1108                 char *state = NULL;
1109
1110                 g_variant_get(value, "s", &state);
1111
1112                 /* This code assumes we support only 1 headset connection */
1113                 /* Need to use the headset list, if we support multi-headsets */
1114                 if (strcasecmp(state, "Playing") == 0) {
1115                         DBG("Playing: Sco Connected");
1116                 } else if (strcasecmp(state, "connected") == 0 ||
1117                                 strcasecmp(state, "disconnected") == 0) {
1118                         if (strcasecmp(state, "connected") == 0)
1119                                 DBG("Sco Connected");
1120                         else
1121                                 DBG("Sco Disconnected");
1122                 } else {
1123                         ERR("Not handled state - %s", state);
1124                         g_free(state);
1125                         return;
1126                 }
1127                 g_free(state);
1128         } else if (strcasecmp(property, "SpeakerGain") == 0) {
1129                 char *address;
1130
1131                 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1132
1133                 _bt_hal_convert_device_path_to_address(path, address);
1134                 INFO("Speaker Gain for address [%s]", address);
1135                 /* TODO Handle event sending to HAL */
1136
1137                 g_free(address);
1138         } else if (strcasecmp(property, "MicrophoneGain") == 0) {
1139                 char *address;
1140
1141                 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1142
1143                 _bt_hal_convert_device_path_to_address(path, address);
1144                 INFO("Microphone Gain for address [%s]", address);
1145                 /* TODO Handle event sending to HAL */
1146
1147                 g_free(address);
1148         }
1149
1150         if (property)
1151                 g_free(property);
1152         g_variant_unref(value);
1153 }
1154
1155 static int __bt_hal_register_manager_subscribe_signal(GDBusConnection *conn,
1156                 int subscribe)
1157 {
1158         if (conn == NULL)
1159                 return -1;
1160
1161         static int subs_interface_added_id = -1;
1162         static int subs_interface_removed_id = -1;
1163         static int subs_name_owner_id = -1;
1164         static int subs_property_id = -1;
1165         static int subs_adapter_id = -1;
1166
1167         INFO_C("+");
1168
1169         if (subscribe) {
1170                 if (subs_interface_added_id == -1) {
1171                         subs_interface_added_id = g_dbus_connection_signal_subscribe(conn,
1172                                         NULL, BT_HAL_MANAGER_INTERFACE,
1173                                         BT_HAL_INTERFACES_ADDED, NULL, NULL, 0,
1174                                         __bt_hal_manager_event_filter,
1175                                         NULL, NULL);
1176                 }
1177                 if (subs_interface_removed_id == -1) {
1178                         subs_interface_removed_id = g_dbus_connection_signal_subscribe(conn,
1179                                         NULL, BT_HAL_MANAGER_INTERFACE,
1180                                         BT_HAL_INTERFACES_REMOVED, NULL, NULL, 0,
1181                                         __bt_hal_manager_event_filter,
1182                                         NULL, NULL);
1183                 }
1184                 if (subs_name_owner_id == -1) {
1185                         subs_name_owner_id = g_dbus_connection_signal_subscribe(conn,
1186                                         NULL, BT_HAL_FREEDESKTOP_INTERFACE,
1187                                         BT_HAL_NAME_OWNER_CHANGED, NULL, NULL, 0,
1188                                         __bt_hal_manager_event_filter,
1189                                         NULL, NULL);
1190                 }
1191                 if (subs_property_id == -1) {
1192                         subs_property_id = g_dbus_connection_signal_subscribe(conn,
1193                                         NULL, BT_HAL_PROPERTIES_INTERFACE,
1194                                         BT_HAL_PROPERTIES_CHANGED, NULL, NULL, 0,
1195                                         __bt_hal_manager_event_filter,
1196                                         NULL, NULL);
1197                 }
1198                 if (subs_adapter_id == -1) {
1199                         subs_adapter_id = g_dbus_connection_signal_subscribe(conn,
1200                                         NULL, BT_HAL_ADAPTER_INTERFACE,
1201                                         NULL, NULL, NULL, 0,
1202                                         __bt_hal_manager_event_filter,
1203                                         NULL, NULL);
1204                 }
1205         } else {
1206                 if (subs_interface_added_id != -1) {
1207                         g_dbus_connection_signal_unsubscribe(conn,
1208                                         subs_interface_added_id);
1209                         subs_interface_added_id = -1;
1210                 }
1211                 if (subs_interface_removed_id != -1) {
1212                         g_dbus_connection_signal_unsubscribe(conn,
1213                                         subs_interface_removed_id);
1214                         subs_interface_removed_id = -1;
1215                 }
1216                 if (subs_name_owner_id != -1) {
1217                         g_dbus_connection_signal_unsubscribe(conn,
1218                                         subs_name_owner_id);
1219                         subs_name_owner_id = -1;
1220                 }
1221                 if (subs_property_id != -1) {
1222                         g_dbus_connection_signal_unsubscribe(conn,
1223                                         subs_property_id);
1224                         subs_property_id = -1;
1225                 }
1226                 if (subs_adapter_id == -1) {
1227                         g_dbus_connection_signal_unsubscribe(conn, subs_adapter_id);
1228                         subs_adapter_id = -1;
1229                 }
1230         }
1231
1232         INFO_C("-");
1233         return 0;
1234 }
1235
1236 static int __bt_hal_register_device_subscribe_signal(GDBusConnection *conn,
1237                 int subscribe)
1238 {
1239         static int subs_device_id = -1;
1240
1241         DBG("+");
1242         if (conn == NULL)
1243                 return -1;
1244
1245         if (subscribe) {
1246                 if (subs_device_id == -1) {
1247                         subs_device_id = g_dbus_connection_signal_subscribe(conn,
1248                                         NULL, BT_HAL_DEVICE_INTERFACE,
1249                                         NULL, NULL, NULL, 0,
1250                                         __bt_hal_manager_event_filter,
1251                                         NULL, NULL);
1252                 }
1253         } else {
1254                 if (subs_device_id != -1) {
1255                         g_dbus_connection_signal_unsubscribe(conn,
1256                                         subs_device_id);
1257                         subs_device_id = -1;
1258                 }
1259         }
1260
1261         DBG("-");
1262         return 0;
1263 }
1264
1265 static int __bt_hal_register_input_subscribe_signal(GDBusConnection *conn, int subscribe)
1266 {
1267         static int subs_input_id = -1;
1268
1269         DBG("+");
1270
1271         if (conn == NULL)
1272                 return -1;
1273
1274         if (subscribe) {
1275                 if (subs_input_id == -1) {
1276                         subs_input_id = g_dbus_connection_signal_subscribe(conn,
1277                                         NULL, BT_HAL_INPUT_INTERFACE,
1278                                         NULL, NULL, NULL, 0,
1279                                         __bt_hal_manager_event_filter,
1280                                         NULL, NULL);
1281                 }
1282         } else {
1283                 if (subs_input_id != -1) {
1284                         g_dbus_connection_signal_unsubscribe(conn,
1285                                         subs_input_id);
1286                         subs_input_id = -1;
1287                 }
1288         }
1289
1290         DBG("-");
1291
1292         return 0;
1293 }
1294
1295 static int __bt_hal_register_gatt_subscribe_signal(GDBusConnection *conn,
1296                 int subscribe)
1297 {
1298         static int subs_gatt_id = -1;
1299
1300         DBG("+");
1301
1302         if (subscribe) {
1303                 if (subs_gatt_id == -1) {
1304                         subs_gatt_id = g_dbus_connection_signal_subscribe(conn,
1305                                         NULL, BT_HAL_GATT_CHAR_INTERFACE,
1306                                         NULL, NULL, NULL, 0,
1307                                         __bt_hal_manager_event_filter,
1308                                         NULL, NULL);
1309                 }
1310         } else {
1311                 if (subs_gatt_id == -1) {
1312                         g_dbus_connection_signal_unsubscribe(conn,
1313                                         subs_gatt_id);
1314                         subs_gatt_id = -1;
1315                 }
1316         }
1317
1318         return BT_HAL_ERROR_NONE;
1319 }
1320
1321
1322
1323 static int __bt_hal_register_service_event(GDBusConnection *g_conn, int event_type)
1324 {
1325         DBG("+");
1326
1327         if (g_conn == NULL)
1328                 return  BT_HAL_ERROR_INTERNAL;
1329
1330         /* TODO: Add more events in subsequent patches */
1331         switch (event_type) {
1332         case BT_HAL_MANAGER_EVENT:
1333                 __bt_hal_register_manager_subscribe_signal(g_conn, TRUE);
1334                 break;
1335         case BT_HAL_DEVICE_EVENT:
1336                 __bt_hal_register_device_subscribe_signal(g_conn, TRUE);
1337                 break;
1338         case BT_HAL_HID_EVENT:
1339                 __bt_hal_register_input_subscribe_signal(g_conn, TRUE);
1340                 break;
1341         case BT_HAL_HEADSET_EVENT:
1342                  __bt_hal_register_audio_subscribe_signal(g_conn, TRUE);
1343                 break;
1344         case BT_HAL_GATT_EVENT:
1345                 __bt_hal_register_gatt_subscribe_signal(g_conn, TRUE);
1346                 break;
1347         default:
1348                 INFO_C("Register Event: event_type [%d]", event_type);
1349                 return BT_HAL_ERROR_NOT_SUPPORT;
1350         }
1351
1352         return BT_HAL_ERROR_NONE;
1353 }
1354
1355 static int __bt_hal_register_audio_subscribe_signal(GDBusConnection *conn,
1356                 int subscribe)
1357 {
1358         if (conn == NULL)
1359                 return -1;
1360
1361         static int subs_headset_id = -1;
1362         static int subs_sink_id = -1;
1363
1364         if (subscribe) {
1365                 if (subs_headset_id == -1) {
1366                         subs_headset_id = g_dbus_connection_signal_subscribe(conn,
1367                                         NULL, BT_HAL_HEADSET_INTERFACE,
1368                                         NULL, NULL, NULL, 0,
1369                                         __bt_hal_manager_event_filter,
1370                                         NULL, NULL);
1371                 }
1372                 if (subs_sink_id == -1) {
1373                         subs_sink_id = g_dbus_connection_signal_subscribe(conn,
1374                                         NULL, BT_HAL_SINK_INTERFACE,
1375                                         NULL, NULL, NULL, 0,
1376                                         __bt_hal_manager_event_filter,
1377                                         NULL, NULL);
1378                 }
1379         } else {
1380                 if (subs_headset_id != -1) {
1381                         g_dbus_connection_signal_unsubscribe(conn,
1382                                         subs_headset_id);
1383                         subs_headset_id = -1;
1384                 }
1385                 if (subs_sink_id != -1) {
1386                         g_dbus_connection_signal_unsubscribe(conn,
1387                                         subs_sink_id);
1388                         subs_sink_id = -1;
1389                 }
1390         }
1391         return 0;
1392 }
1393
1394 static int __bt_hal_initialize_manager_receiver(void)
1395 {
1396         DBG("+");
1397
1398         GError *error = NULL;
1399
1400         if (manager_conn == NULL) {
1401                 manager_conn =  g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
1402                 if (error != NULL) {
1403                         ERR_C("ERROR: Can't get on system bus [%s]", error->message);
1404                         g_clear_error(&error);
1405                 }
1406                 if (manager_conn == NULL)
1407                         goto fail;
1408         }
1409
1410         if (__bt_hal_register_service_event(manager_conn,
1411                                 BT_HAL_MANAGER_EVENT) != BT_HAL_ERROR_NONE)
1412                 goto fail;
1413         if (__bt_hal_register_service_event(manager_conn,
1414                                 BT_HAL_DEVICE_EVENT) != BT_HAL_ERROR_NONE)
1415                 goto fail;
1416         if (__bt_hal_register_service_event(manager_conn,
1417                                 BT_HAL_HID_EVENT) != BT_HAL_ERROR_NONE)
1418                 goto fail;
1419         if (__bt_hal_register_service_event(manager_conn,
1420                                 BT_HAL_HEADSET_EVENT) != BT_HAL_ERROR_NONE)
1421                 goto fail;
1422         if (__bt_hal_register_service_event(manager_conn,
1423                                 BT_HAL_GATT_EVENT) != BT_HAL_ERROR_NONE)
1424                 goto fail;
1425         return BT_HAL_ERROR_NONE;
1426 fail:
1427         if (manager_conn) {
1428                 g_object_unref(manager_conn);
1429                 manager_conn = NULL;
1430         }
1431
1432         DBG("-");
1433
1434         return BT_HAL_ERROR_INTERNAL;
1435 }
1436
1437 /* To receive the event from bluez */
1438 int _bt_hal_initialize_event_receiver(handle_stack_msg cb)
1439 {
1440         int result;
1441         DBG("+");
1442
1443         if (!cb)
1444                 return BT_HAL_ERROR_INVALID_PARAM;
1445
1446         result = __bt_hal_initialize_manager_receiver();
1447
1448         DBG("Manager event receiver initialization result [%d]", result);
1449         if (result != BT_HAL_ERROR_NONE)
1450                 return result;
1451
1452         /*TODO: Initialize Obexd Event receiver */
1453
1454         event_cb = cb;
1455         DBG("-");
1456
1457         return BT_HAL_ERROR_NONE;
1458 }
1459
1460 static void __bt_hal_device_property_changed_event(GVariant *msg, const char *path)
1461 {
1462         GVariantIter value_iter;
1463         GVariant *value = NULL;
1464         char *key = NULL;
1465         g_variant_iter_init(&value_iter, msg);
1466         DBG("+");
1467
1468         while (g_variant_iter_loop(&value_iter, "{sv}", &key, &value)) {
1469                 if (!g_strcmp0(key, "Connected")) {
1470                         guint connected = 0;
1471                         g_variant_get(value, "i", &connected);
1472                         DBG("Device property changed : Connected [%d]", connected);
1473                 } else if (!g_strcmp0(key, "RSSI")) {
1474                         DBG("Device property changed : RSSI");
1475                         __bt_hal_dbus_device_found_properties(path);
1476                 } else if (!g_strcmp0(key, "GattConnected")) {
1477                         DBG("Device property changed : GattConnected");
1478                         gboolean gatt_connected = FALSE;
1479                         g_variant_get(value, "b", &gatt_connected);
1480                         char *address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1481                         _bt_hal_convert_device_path_to_address(path, address);
1482                         DBG("@@gatt_connected: %d", gatt_connected);
1483                         DBG("@@address: %s", address);
1484                         _bt_hal_gatt_connected_state_event(gatt_connected, address);
1485                         _bt_hal_handle_gattc_connected_event(address, gatt_connected);
1486                         g_free(address);
1487                 } else if (!g_strcmp0(key, "Paired")) {
1488                         gboolean paired = FALSE;
1489                         struct hal_ev_bond_state_changed ev;
1490                         char address[BT_HAL_ADDRESS_STRING_SIZE];
1491
1492                         g_variant_get(value, "b", &paired);
1493                         DBG("Device property changed : Paired = %s", (paired ? "TRUE" : "FALSE"));
1494
1495                         _bt_hal_agent_set_canceled(FALSE);
1496                         _bt_hal_convert_device_path_to_address(path, address);
1497
1498                         /* Prepare to send event to HAL bluetooth */
1499                         ev.status = BT_STATUS_SUCCESS;
1500                         ev.state = paired ? BT_BOND_STATE_BONDED : BT_BOND_STATE_NONE;
1501                         _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
1502
1503                         if (!event_cb) {
1504                                 ERR("Bluetooth HAL event handler not registered");
1505                         } else {
1506                                 DBG("Sending HAL_EV_BOND_STATE_CHANGED event");
1507                                 event_cb(HAL_EV_BOND_STATE_CHANGED, (void*)&ev, sizeof(ev));
1508                         }
1509                 } else if (!g_strcmp0(key, "LegacyPaired")) {
1510                         DBG("Device property changed : LegacyPaired");
1511                 } else if (!g_strcmp0(key, "Trusted")) {
1512                         DBG("Device property changed : Trusted");
1513                         gboolean trusted = FALSE;
1514                         gchar *address = NULL;
1515                         g_variant_get(value, "b", &trusted);
1516                         address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1517
1518                         _bt_hal_convert_device_path_to_address(path, address);
1519                         DBG("Device [%s] trusted: [%d]", address, trusted);
1520
1521                         __bt_hal_send_device_trust_state_event(trusted, address);
1522                         g_free(address);
1523                 } else if (!g_strcmp0(key, "IpspConnected")) {
1524                         DBG("Device property changed : IpspConnected");
1525                 } else if (!g_strcmp0(key, "IpspInitStateChanged")) {
1526                         DBG("Device property changed : IpspInitStateChanged");
1527                 } else if (!g_strcmp0(key, "TrustedProfiles")) {
1528                         int trust_val = 0;
1529                         char address[BT_HAL_ADDRESS_STRING_SIZE];
1530
1531                         g_variant_get(value, "u", &trust_val);
1532                         _bt_hal_convert_device_path_to_address(path, address);
1533                         DBG("Address: %s, TrustedProfiles: 0x%X", address, trust_val);
1534                         __bt_hal_send_device_trusted_profile_changed_event(trust_val, address);
1535                 } else {
1536                         ERR("Unhandled Property:[%s]", key);
1537                 }
1538         }
1539         DBG("-");
1540 }
1541
1542 static void __bt_hal_dbus_device_found_properties(const char *device_path)
1543 {
1544         char *address;
1545         GError *error = NULL;
1546         GDBusProxy *device_proxy;
1547         GDBusConnection *conn;
1548         GVariant *result;
1549         DBG("+");
1550
1551         if (!device_path) {
1552                 ERR("Invalid device path");
1553                 return;
1554         }
1555
1556         conn = _bt_hal_get_system_gconn();
1557         if (!conn) {
1558                 ERR("_bt_hal_get_system_gconn failed");
1559                 return;
1560         }
1561
1562         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1563                         NULL,
1564                         BT_HAL_BLUEZ_NAME,
1565                         device_path,
1566                         BT_HAL_PROPERTIES_INTERFACE,
1567                         NULL, NULL);
1568
1569         if (!device_proxy) {
1570                 ERR("Error creating device_proxy");
1571                 return;
1572         }
1573
1574         result = g_dbus_proxy_call_sync(device_proxy,
1575                         "GetAll",
1576                         g_variant_new("(s)", BT_HAL_DEVICE_INTERFACE),
1577                         G_DBUS_CALL_FLAGS_NONE,
1578                         -1,
1579                         NULL,
1580                         &error);
1581         if (!result) {
1582                 ERR("Error occured in Proxy call");
1583                 if (error != NULL) {
1584                         ERR("Error occured in Proxy call (Error: %s)", error->message);
1585                         g_clear_error(&error);
1586                 }
1587                 g_object_unref(device_proxy);
1588                 return;
1589         }
1590
1591         address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1592         _bt_hal_convert_device_path_to_address(device_path, address);
1593
1594         __bt_hal_device_properties_lookup(result, address);
1595
1596         g_object_unref(device_proxy);
1597         g_free(address);
1598
1599         DBG("-");
1600 }
1601
1602 static void __bt_hal_device_properties_lookup(GVariant *result, char *address)
1603 {
1604         /* Buffer and propety count management */
1605         uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
1606         struct hal_ev_device_found *ev = (void *) buf;
1607         size_t size = 0;
1608         memset(buf, 0, sizeof(buf));
1609         size = sizeof(*ev);
1610         ev->num_props = 0;
1611
1612         GVariant *tmp_value;
1613         GVariant *value;
1614         gchar *name;
1615         gchar *manufacturer_data = NULL;
1616         DBG("+");
1617
1618         if (result != NULL) {
1619                 g_variant_get(result , "(@a{sv})", &value);
1620                 g_variant_unref(result);
1621
1622                 /* Alias */
1623                 tmp_value = g_variant_lookup_value(value, "Alias", G_VARIANT_TYPE_STRING);
1624
1625                 g_variant_get(tmp_value, "s", &name);
1626
1627                 g_variant_unref(tmp_value);
1628                 if (name != NULL) {
1629                         DBG_SECURE("Alias Name [%s]", name);
1630                         size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_NAME,
1631                                         strlen(name) + 1, name);
1632                         ev->num_props++;
1633                         DBG("Device Name [%s] Property num [%d]", name, ev->num_props);
1634                 } else {
1635                         /* Name */
1636                         tmp_value = g_variant_lookup_value(value, "Name", G_VARIANT_TYPE_STRING);
1637                         g_variant_get(tmp_value, "s", &name);
1638                         g_variant_unref(tmp_value);
1639
1640                         size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_NAME,
1641                                         strlen(name) + 1, name);
1642                         ev->num_props++;
1643                         DBG("Device Name [%s] Property num [%d]", name, ev->num_props);
1644                         g_variant_get(tmp_value, "s", &name);
1645                 }
1646
1647                 /* Class */
1648                 tmp_value = g_variant_lookup_value(value, "Class", G_VARIANT_TYPE_UINT32);
1649                 unsigned int class = tmp_value ? g_variant_get_uint32(tmp_value) : 0;
1650                 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_CLASS,
1651                                 sizeof(unsigned int), &class);
1652                 ev->num_props++;
1653                 if (tmp_value)
1654                         g_variant_unref(tmp_value);
1655
1656
1657                 /* Connected */
1658                 tmp_value = g_variant_lookup_value(value, "Connected",  G_VARIANT_TYPE_BOOLEAN);
1659                 unsigned int connected = tmp_value ? g_variant_get_boolean(tmp_value) : 0;
1660                 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_CONNECTED,
1661                                 sizeof(unsigned int), &connected);
1662                 ev->num_props++;
1663                 DBG("Device connected [%u] Property num [%d]", connected,  ev->num_props);
1664                 if (tmp_value)
1665                         g_variant_unref(tmp_value);
1666
1667                 /* Trust */
1668                 tmp_value = g_variant_lookup_value(value, "Trusted",  G_VARIANT_TYPE_BOOLEAN);
1669                 uint8_t trust = tmp_value ? (g_variant_get_boolean(tmp_value) ? 1 : 0) : 0;
1670                 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_TRUSTED,
1671                                 sizeof(uint8_t), &trust);
1672                 ev->num_props++;
1673                 DBG("Device trusted [%d] Property num [%d]", trust, ev->num_props);
1674                 if (tmp_value)
1675                         g_variant_unref(tmp_value);
1676
1677                 /* Paired */
1678                 tmp_value = g_variant_lookup_value(value, "Paired",  G_VARIANT_TYPE_BOOLEAN);
1679                 uint8_t paired = tmp_value ? (g_variant_get_boolean(tmp_value) ? 1 : 0) : 0;
1680
1681                 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_PAIRED,
1682                                 sizeof(uint8_t), &paired);
1683                 ev->num_props++;
1684                 DBG("Device Paired [%d] Property num [%d]", paired, ev->num_props);
1685                 if (tmp_value)
1686                         g_variant_unref(tmp_value);
1687
1688                 /* RSSI*/
1689                 tmp_value = g_variant_lookup_value(value, "RSSI", G_VARIANT_TYPE_INT32);
1690                 int rssi = tmp_value ? g_variant_get_int32(tmp_value) : 0;
1691                 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_RSSI,
1692                                 sizeof(int), &rssi);
1693                 ev->num_props++;
1694                 DBG("Device RSSI [%d] Property num [%d]", rssi, ev->num_props);
1695                 if (tmp_value)
1696                         g_variant_unref(tmp_value);
1697
1698                 /* Last Addr Type */
1699                 tmp_value = g_variant_lookup_value(value, "LastAddrType", G_VARIANT_TYPE_UINT32);
1700                 unsigned int addr_type = tmp_value ? g_variant_get_uint32(tmp_value) : 0;
1701                 if (tmp_value)
1702                         g_variant_unref(tmp_value);
1703                 DBG("Device Last Address Type [0x%x]", addr_type);
1704
1705                 /* Is Alias Set */
1706                 tmp_value = g_variant_lookup_value(value, "IsAliasSet", G_VARIANT_TYPE_UINT32);
1707                 uint8_t is_alias_set = tmp_value ? (g_variant_get_boolean(tmp_value) ? 1 : 0) : 0;
1708                 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_IS_ALIAS_SET,
1709                                         sizeof(uint8_t), &is_alias_set);
1710                 ev->num_props++;
1711                 DBG("IsAliasSet: [%s], Property num [%d]", (is_alias_set ? "TRUE" : "FALSE"), ev->num_props);
1712                 if (tmp_value)
1713                         g_variant_unref(tmp_value);
1714
1715                 /* UUID's */
1716                 tmp_value = g_variant_lookup_value(value, "UUIDs", G_VARIANT_TYPE_STRING_ARRAY);
1717                 gsize uuid_count = g_variant_get_size(tmp_value);
1718                 char **uuid_value = g_variant_dup_strv(tmp_value, &uuid_count);
1719                 {
1720                         /* UUID collection */
1721                         int i;
1722 #ifdef __TEST_
1723                         int z;
1724 #endif
1725                         int num_props_tmp = ev->num_props;
1726
1727                         uint8_t uuids[BT_HAL_STACK_UUID_SIZE * uuid_count];
1728
1729                         for (i = 0; uuid_value[i] != NULL; i++) {
1730
1731                                 char *uuid_str = NULL;
1732                                 uint8_t uuid[BT_HAL_STACK_UUID_SIZE];
1733                                 memset(uuid, 0x00, BT_HAL_STACK_UUID_SIZE);
1734
1735                                 DBG("UUID string from Bluez [%s]\n", uuid_value[i]);
1736                                 uuid_str = g_strdup(uuid_value[i]);
1737                                 DBG("UUID string [%s]\n", uuid_str);
1738
1739                                 _bt_hal_convert_uuid_string_to_type(uuid, uuid_str);
1740 #ifdef __TEST_
1741                                 for (z = 0; z < 16; z++)
1742                                         DBG("[0x%x]", uuid[z]);
1743 #endif
1744
1745                                 memcpy(uuids+i*BT_HAL_STACK_UUID_SIZE, uuid, BT_HAL_STACK_UUID_SIZE);
1746                                 g_free(uuid_str);
1747                         }
1748
1749                         size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_UUIDS,
1750                                         (BT_HAL_STACK_UUID_SIZE * uuid_count),
1751                                         uuids);
1752                         ev->num_props = num_props_tmp + 1;
1753                         g_free(uuid_value);
1754                 }
1755                 g_variant_unref(tmp_value);
1756
1757                 /* LegacyManufacturerDataLen */
1758                 tmp_value = g_variant_lookup_value(value, "LegacyManufacturerDataLen", G_VARIANT_TYPE_UINT32);
1759                 unsigned int manufacturer_data_len = tmp_value ? g_variant_get_uint32(tmp_value) : 0;
1760                 if (manufacturer_data_len > BT_HAL_MANUFACTURER_DATA_LENGTH_MAX) {
1761                         ERR("manufacturer_data_len is too long(len = %d)", manufacturer_data_len);
1762                         manufacturer_data_len = BT_HAL_MANUFACTURER_DATA_LENGTH_MAX;
1763                 }
1764                 if (tmp_value)
1765                         g_variant_unref(tmp_value);
1766                 /*size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_MANUFACTURER_DATA_LEN,
1767                   sizeof(unsigned int), &manufacturer_data_len);
1768                   ev->num_props++;*/
1769                 DBG("Device Legacy Manufacturer data length [%u]", manufacturer_data_len);
1770
1771                 /* ManufacturerData */
1772                 tmp_value = g_variant_lookup_value(value, "LegacyManufacturerData", G_VARIANT_TYPE_BYTESTRING);
1773                 manufacturer_data = value ? (gchar *)g_variant_get_bytestring(tmp_value) : NULL;
1774                 if (manufacturer_data) {
1775                         if (manufacturer_data_len > 0) {
1776                                 //size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_MANUFACTURER_DATA,
1777                                 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_BLE_ADV_DATA,
1778                                                 manufacturer_data_len, manufacturer_data);
1779                                 ev->num_props++;
1780                         }
1781                 }
1782                 if (tmp_value)
1783                         g_variant_unref(tmp_value);
1784
1785                 /* Address */
1786                 uint8_t bdaddr[6];
1787                 _bt_hal_convert_addr_string_to_type(bdaddr, address);
1788                 size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_ADDR,
1789                                 sizeof(bdaddr), bdaddr);
1790                 ev->num_props++;
1791                 DBG("Device address [%s] property Num [%d]", address, ev->num_props);
1792
1793                 g_free(name);
1794                 g_variant_unref(value);
1795         } else {
1796                 ERR("result  is NULL\n");
1797         }
1798         if (size > 1) {
1799                 DBG("Send Device found event to HAL user, Num Prop [%d] total size [%zd]", ev->num_props, size);
1800                 event_cb(HAL_EV_DEVICE_FOUND, (void*) buf, size);
1801         }
1802         DBG("-");
1803 }
1804
1805 static void __bt_hal_send_device_acl_connection_state_event(int status, gboolean connected, const char *address)
1806 {
1807         DBG("+");
1808         struct hal_ev_acl_state_changed ev;
1809
1810         ev.status = status;
1811         ev.state = (connected == TRUE) ?
1812                 HAL_ACL_STATE_CONNECTED :
1813                 HAL_ACL_STATE_DISCONNECTED;
1814
1815         _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
1816
1817         if (!event_cb)
1818                 ERR("Bluetooth HAL event handler not registered");
1819         else
1820                 event_cb(HAL_EV_ACL_STATE_CHANGED, &ev, sizeof(ev));
1821         DBG("-");
1822 }
1823
1824 static void __bt_hal_send_device_le_connection_state_event(int status, gboolean connected, const char *address)
1825 {
1826         DBG("+");
1827         struct hal_ev_le_conn_state_changed ev;
1828
1829         ev.status = status;
1830         ev.state = (connected == TRUE) ?
1831                 HAL_LE_STATE_CONNECTED :
1832                 HAL_LE_STATE_DISCONNECTED;
1833
1834         _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
1835
1836         if (!event_cb)
1837                 ERR("Bluetooth HAL event handler not registered");
1838         else
1839                 event_cb(HAL_EV_LE_CONN_STATE_CHANGED, &ev, sizeof(ev));
1840         DBG("-");
1841 }
1842
1843 static void __bt_hal_send_device_trust_state_event(gboolean is_trusted,
1844                                 const char *address)
1845 {
1846         struct hal_ev_device_trust_state_changed ev;
1847         DBG("+");
1848
1849         ev.trust = (is_trusted == TRUE) ?
1850                 HAL_DEVICE_TRUSTED :
1851                 HAL_DEVICE_UNTRUSTED;
1852
1853         _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
1854
1855         if (!event_cb)
1856                 ERR("Bluetooth HAL event handler not registered");
1857         else
1858                 event_cb(HAL_EV_DEVICE_TRUST_CHANGED, &ev, sizeof(ev));
1859         DBG("-");
1860 }
1861
1862 static void __bt_hal_send_device_trusted_profile_changed_event(
1863                 uint32_t trust_val, const char *address)
1864 {
1865         struct hal_ev_device_trusted_profiles_changed ev;
1866         DBG("+");
1867
1868         _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
1869         ev.trust_val = trust_val;
1870
1871         if (!event_cb)
1872                 ERR("Bluetooth HAL event handler not registered");
1873         else
1874                 event_cb(HAL_EV_DEVICE_TRUSTED_PROFILES_CHANGED, &ev, sizeof(ev));
1875         DBG("-");
1876 }
1877
1878 static void __bt_hal_handle_device_specific_events(GVariant *msg, const char *member,
1879                         const char *path)
1880 {
1881         char *address;
1882         const char *property = NULL;
1883         if (path == NULL)
1884                 return;
1885
1886         if (strcasecmp(member, "PropertyChanged") == 0) {
1887                 g_variant_get(msg, "(s)", &property);
1888                 if (property == NULL)
1889                         return;
1890                 if (strcasecmp(property, "GattConnected") == 0) {
1891                         INFO("GATT Connected");
1892                         gboolean connected = FALSE;
1893                         char *address;
1894                         address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1895
1896                         _bt_hal_convert_device_path_to_address(path, address);
1897                         g_variant_get(msg, "(b)", &connected);
1898
1899                         INFO("Connected device address[%s] connnected[%d]", address, connected);
1900                         g_free(address);
1901                 } else if (strcasecmp(property, "Paired") == 0) {
1902                         gboolean paired = FALSE;
1903                         struct hal_ev_bond_state_changed ev;
1904                         char address[BT_HAL_ADDRESS_STRING_SIZE];
1905
1906                         g_variant_get(msg, "(b)", &paired);
1907                         DBG("Device property changed : Paired = %s", (paired ? "TRUE" : "FALSE"));
1908
1909                         _bt_hal_agent_set_canceled(FALSE);
1910                         _bt_hal_convert_device_path_to_address(path, address);
1911
1912                         /* Prepare to send event to HAL bluetooth */
1913                         ev.status = BT_STATUS_SUCCESS;
1914                         ev.state = paired ? BT_BOND_STATE_BONDED : BT_BOND_STATE_NONE;
1915                         _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
1916
1917                         if (!event_cb) {
1918                                 ERR("Bluetooth HAL event handler not registered");
1919                         } else {
1920                                 DBG("Sending HAL_EV_BOND_STATE_CHANGED event");
1921                                 event_cb(HAL_EV_BOND_STATE_CHANGED, (void*)&ev, sizeof(ev));
1922                         }
1923                 } else if (strcasecmp(property, "UUIDs") == 0) {
1924                         /* TODO */
1925                 }
1926         } else if (strcasecmp(member, "DeviceConnected") == 0) {
1927                 unsigned char addr_type = 0;
1928
1929                 g_variant_get(msg, "(y)", &addr_type);
1930
1931                 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1932                 _bt_hal_convert_device_path_to_address(path, address);
1933
1934                 DBG("Member: [%s]", member);
1935                 ERR_C("Connected [%s] [%s]", !addr_type ? "BREDR" : "LE", address);
1936                 if (!addr_type)
1937                         __bt_hal_send_device_acl_connection_state_event(BT_STATUS_SUCCESS, TRUE, address);
1938                 else
1939                         __bt_hal_send_device_le_connection_state_event(BT_STATUS_SUCCESS, TRUE, address);
1940                 g_free(address);
1941         } else if (strcasecmp(member, "Disconnected") == 0) {
1942                 unsigned char disc_reason = 0;
1943                 unsigned char addr_type = 0;
1944                 char *name = NULL;
1945
1946                 g_variant_get(msg, "(yy&s)", &addr_type, &disc_reason, &name);
1947
1948                 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1949                 _bt_hal_convert_device_path_to_address(path, address);
1950
1951                 DBG("Member: [%s]", member);
1952
1953                 ERR_C("DisConnected [%s] [%s]", !addr_type ? "BREDR" : "LE", address);
1954                 DBG("Disconnected Reason [%d : %s]", disc_reason, _bt_hal_convert_disc_reason_to_string(disc_reason));
1955                 DBG("Name: %s", name);
1956                 if (!addr_type)
1957                         __bt_hal_send_device_acl_connection_state_event(_bt_hal_convert_disc_reason_to_status(disc_reason), FALSE, address);
1958                 else
1959                         __bt_hal_send_device_le_connection_state_event(_bt_hal_convert_disc_reason_to_status(disc_reason), FALSE, address);
1960                 g_free(address);
1961         } else if (strcasecmp(member, "ProfileStateChanged") == 0) {
1962                 int state = 0;
1963                 char *profile_uuid = NULL;
1964
1965                 g_variant_get(msg, "(si)", &profile_uuid, &state);
1966                 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
1967                 _bt_hal_convert_device_path_to_address(path, address);
1968
1969                 DBG("Address: %s", address);
1970                 DBG("Profile UUID: %s", profile_uuid);
1971                 DBG("State: %d", state);
1972                 if (strncmp(profile_uuid, HID_UUID, strlen(HID_UUID)) == 0) {
1973                         if (state == BT_HAL_PROFILE_STATE_CONNECTED)
1974                                 __bt_hal_send_hid_connection_state_event(TRUE, address);
1975                         else if (state == BT_HAL_PROFILE_STATE_DISCONNECTED)
1976                                 __bt_hal_send_hid_connection_state_event(FALSE, address);
1977                         else
1978                                 DBG("Profile state: %d", state);
1979
1980                 } else if ((strncmp(profile_uuid, A2DP_SINK_UUID, strlen(A2DP_SINK_UUID)) == 0)) {
1981                         if (state == BT_HAL_PROFILE_STATE_CONNECTED) {
1982                                 DBG("A2DP Profile state changed: BT_PROFILE_STATE_CONNECTED");
1983                                 __bt_hal_send_av_connection_state_event(TRUE, address);
1984                         } else if (state == BT_HAL_PROFILE_STATE_DISCONNECTED) {
1985                                 DBG("A2DP Profile state changed: BT_PROFILE_STATE_DISCONNECTED");
1986                                 __bt_hal_send_av_connection_state_event(FALSE, address);
1987                         } else if (state == BT_HAL_PROFILE_STATE_DISCONNECTING) {
1988                                 DBG("A2DP Profile state changed: BT_PROFILE_STATE_DISCONNECTING");
1989                         } else if (state == BT_HAL_PROFILE_STATE_CONNECTING) {
1990                                 DBG("A2DP Profile state changed: BT_PROFILE_STATE_CONNECTING");
1991                         } else {
1992                                 ERR("A2DP Profile state: Invalid");
1993                         }
1994                 } else if ((strncmp(profile_uuid, A2DP_SOURCE_UUID, strlen(A2DP_SOURCE_UUID)) == 0)) {
1995                         if (state == BT_HAL_PROFILE_STATE_CONNECTED) {
1996                                 DBG("A2DP Sink Profile state changed: BT_HAL_PROFILE_STATE_CONNECTED");
1997                                 __bt_hal_send_a2dp_sink_connection_state_event(TRUE, address);
1998                         } else if (state == BT_HAL_PROFILE_STATE_DISCONNECTED) {
1999                                 DBG("A2DP Sink Profile state changed: BT_HAL_PROFILE_STATE_DISCONNECTED");
2000                                 __bt_hal_send_a2dp_sink_connection_state_event(FALSE, address);
2001                         } else if (state == BT_HAL_PROFILE_STATE_DISCONNECTING) {
2002                                 DBG("A2DP Sink Profile state changed: BT_HAL_PROFILE_STATE_DISCONNECTING");
2003                         } else if (state == BT_HAL_PROFILE_STATE_CONNECTING) {
2004                                 DBG("A2DP Sink Profile state changed: BT_HAL_PROFILE_STATE_CONNECTING");
2005                         }
2006                 } else if (strncmp(profile_uuid, HFP_HF_UUID, strlen(HFP_HF_UUID)) == 0) {
2007                         if (state == BT_HAL_PROFILE_STATE_CONNECTING)
2008                                 DBG("HFP Profile state changed: BT_PROFILE_STATE_CONNECTING");
2009                         else if (state == BT_HAL_PROFILE_STATE_CONNECTED) {
2010                                 DBG("HFP Profile state changed: BT_PROFILE_STATE_CONNECTED");
2011                                 __bt_hal_send_hf_connection_state_event(TRUE, address);
2012                         } else if (state == BT_HAL_PROFILE_STATE_DISCONNECTED) {
2013                                 DBG("HFP Profile state changed: BT_PROFILE_STATE_DISCONNECTED");
2014                                 __bt_hal_send_hf_connection_state_event(FALSE, address);
2015                         } else if (state == BT_HAL_PROFILE_STATE_DISCONNECTING) {
2016                                 DBG("HFP Profile state changed: BT_PROFILE_STATE_DISCONNECTING");
2017                         } else {
2018                                 ERR("HFP Profile state: Invalid");
2019                         }
2020                 } else if ((strncmp(profile_uuid, AVRCP_TARGET_UUID, strlen(AVRCP_TARGET_UUID)) == 0)) {
2021                         if (state == BT_HAL_PROFILE_STATE_CONNECTED) {
2022                                 DBG("AVRCP Controller Profile state changed: BT_HAL_PROFILE_STATE_CONNECTED");
2023                                 __bt_hal_send_avrcp_ctrl_connection_state_event(TRUE, address);
2024                         } else if (state == BT_HAL_PROFILE_STATE_DISCONNECTED) {
2025                                 DBG("AVRCP Controller Profile state changed: BT_HAL_PROFILE_STATE_DISCONNECTED");
2026                                 __bt_hal_send_avrcp_ctrl_connection_state_event(FALSE, address);
2027                         } else if (state == BT_HAL_PROFILE_STATE_DISCONNECTING) {
2028                                 DBG("AVRCP Controller Profile state changed: BT_HAL_PROFILE_STATE_DISCONNECTING");
2029                         } else if (state == BT_HAL_PROFILE_STATE_CONNECTING) {
2030                                 DBG("AVRCP Controller Profile state changed: BT_HAL_PROFILE_STATE_CONNECTING");
2031                         }
2032                 } else {
2033                         DBG("Profile[%s] State changed status [%d] ", profile_uuid, state);
2034                 }
2035                 g_free(address);
2036                 g_free(profile_uuid);
2037         } else if (strcasecmp(member, "AdvReport") == 0) {
2038                 DBG("Member: [%s]", member);
2039                 __bt_hal_handle_adv_report(msg, path);
2040         }
2041 }
2042
2043 static void __bt_hal_handle_adv_report(GVariant *msg, const char *path)
2044 {
2045         uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
2046         struct hal_ev_gatt_client_scan_result *ev = (void *)buf;
2047         size_t size = 0;
2048         char *address = NULL;
2049         GVariant *value = NULL;
2050         char *buffer = NULL;
2051         int data_len = 0;
2052         int buffer_len = 0;
2053         uint8_t addr_type = 0;
2054         uint8_t adv_type = 0;
2055         int rssi = 0;
2056
2057         if (!gatt_event_cb)
2058                 return;
2059
2060         memset(buf, 0, sizeof(buf));
2061         size = sizeof(*ev);
2062
2063         g_variant_get(msg, "(&syyii@ay)", &address, &addr_type,
2064                         &adv_type, &rssi, &data_len, &value);
2065
2066         buffer_len = g_variant_get_size(value);
2067         if (buffer_len > 0)
2068                 buffer = (char *)g_variant_get_data(value);
2069
2070         if (data_len != buffer_len) {
2071                 ERR("Unexpected: buffer_len: %d, data_len: %d",
2072                                 buffer_len, data_len);
2073                 data_len = buffer_len;
2074         }
2075
2076         DBG("Address: %s, len: %d, rssi: %d, addr_type: 0x%02X, adv_type: 0x%02X",
2077                         address, data_len, rssi, addr_type, adv_type);
2078
2079         _bt_hal_convert_addr_string_to_type(ev->bd_addr, address);
2080         ev->addr_type = addr_type;
2081         ev->adv_type = adv_type;
2082         ev->rssi = rssi;
2083         ev->len = data_len;
2084         memcpy(ev->adv_data, buffer, data_len);
2085         size += data_len;
2086
2087         DBG("Send le scan result event to HAL, size: [%zd]", size);
2088         gatt_event_cb(HAL_EV_GATT_CLIENT_SCAN_RESULT, buf, size);
2089         g_variant_unref(value);
2090 }
2091
2092 /* AVRCP Controller Role(Remote:AVRCP Target) Events */
2093 static void __bt_hal_send_avrcp_ctrl_connection_state_event(gboolean connected, const char *address)
2094 {
2095         DBG("+");
2096         struct hal_ev_avrcp_ctrl_conn_state ev;
2097
2098         if (connected == TRUE)
2099                 INFO("AVRCP(Controller) Profile Connected for address [%s]", address);
2100         else
2101                 INFO("AVRCP(Controller) Profile DisConnected for address [%s]", address);
2102
2103         if (connected == TRUE)
2104                 ev.state = HAL_AVRCP_CTRL_STATE_CONNECTED;
2105         else
2106                 ev.state = HAL_AVRCP_CTRL_STATE_DISCONNECTED;
2107         _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2108
2109         if (!a2dp_sink_event_cb)
2110                 ERR("AV event handler not registered");
2111         else
2112                 avrcp_ctrl_event_cb(HAL_EV_AVRCP_CTRL_CONN_STATE, &ev, sizeof(ev));
2113 }
2114
2115 static int __bt_media_attr_to_type(const char *str)
2116 {
2117         if (!strcasecmp(str, "Equalizer"))
2118                 return HAL_PLAYER_ATTR_EQUALIZER;
2119         else if (!strcasecmp(str, "Repeat"))
2120                 return HAL_PLAYER_ATTR_REPEAT;
2121         else if (!strcasecmp(str, "Shuffle"))
2122                 return HAL_PLAYER_ATTR_SHUFFLE;
2123         else if (!strcasecmp(str, "Scan"))
2124                 return HAL_PLAYER_ATTR_SCAN;
2125         else
2126                 return 0;
2127 }
2128
2129
2130 static int __bt_hal_play_status_str_to_type(const char *value)
2131 {
2132         if (!strcmp(value, "stopped"))
2133                 return HAL_PLAYSTATE_STOPPED;
2134         else if (!strcmp(value, "playing"))
2135                 return HAL_PLAYSTATE_PLAYING;
2136         else if (!strcmp(value, "paused"))
2137                 return HAL_PLAYSTATE_PAUSED;
2138         else if (!strcmp(value, "forward-seek"))
2139                 return HAL_PLAYSTATE_FWD_SEEK;
2140         else if (!strcmp(value, "reverse-seek"))
2141                 return HAL_PLAYSTATE_REV_SEEK;
2142         else
2143                 return HAL_PLAYSTATE_ERROR;
2144 }
2145
2146 static void __bt_avrcp_control_parse_properties(struct hal_ev_track_changed *ev, GVariant *item)
2147 {
2148         GVariant *value = NULL;
2149         GVariantIter iter;
2150         char *value_string = NULL;
2151         const char *key = NULL;
2152         int i = 0;
2153
2154         if (ev == NULL)
2155                 return;
2156
2157         g_variant_iter_init(&iter, item);
2158         while (g_variant_iter_loop(&iter, "{sv}", &key, &value)) {
2159                 if (strcasecmp(key, "Title") == 0) {
2160                         value_string = (char *)g_variant_get_string(value, NULL);
2161                         DBG("Value : %s ", value_string);
2162                         ev->attr[i].attr_id = HAL_MEDIA_ATTR_ID_TITLE;
2163                         g_strlcpy((gchar *)ev->attr[i].text, value_string, HAL_MAX_ATTR_STR_LEN);
2164                         i++;
2165                 } else if (strcasecmp(key, "Artist") == 0) {
2166                         value_string = (char *)g_variant_get_string(value, NULL);
2167                         DBG("Value : %s ", value_string);
2168                         ev->attr[i].attr_id = HAL_MEDIA_ATTR_ID_ARTIST;
2169                         g_strlcpy((gchar *)ev->attr[i].text, value_string, HAL_MAX_ATTR_STR_LEN);
2170                         i++;
2171                 } else if (strcasecmp(key, "Album") == 0) {
2172                         value_string = (char *)g_variant_get_string(value, NULL);
2173                         DBG("Value : %s ", value_string);
2174                         ev->attr[i].attr_id = HAL_MEDIA_ATTR_ID_ALBUM;
2175                         g_strlcpy((gchar *)ev->attr[i].text, value_string, HAL_MAX_ATTR_STR_LEN);
2176                         i++;
2177                 } else if (strcasecmp(key, "Genre") == 0) {
2178                         value_string = (char *)g_variant_get_string(value, NULL);
2179                         DBG("Value : %s ", value_string);
2180                         ev->attr[i].attr_id = HAL_MEDIA_ATTR_ID_GENRE;
2181                         g_strlcpy((gchar *)ev->attr[i].text, value_string, HAL_MAX_ATTR_STR_LEN);
2182                         i++;
2183                 } else if (strcasecmp(key, "Duration") == 0) {
2184                         long int val;
2185
2186                         val = g_variant_get_uint32(value);
2187                         DBG("Value : %li", val);
2188                         ev->attr[i].attr_id = HAL_MEDIA_ATTR_ID_PLAYING_TIME;
2189                         snprintf((char*)ev->attr[i].text, HAL_MAX_ATTR_STR_LEN, "%ld", val);
2190                         i++;
2191                 } else if (strcasecmp(key, "NumberOfTracks") == 0) {
2192                         long int val;
2193
2194                         val = g_variant_get_uint32(value);
2195                         DBG("Value : %li", val);
2196                         ev->attr[i].attr_id = HAL_MEDIA_ATTR_ID_NUM_TRACKS;
2197                         snprintf((char*)ev->attr[i].text, HAL_MAX_ATTR_STR_LEN, "%ld", val);
2198                         i++;
2199                 } else if (strcasecmp(key, "TrackNumber") == 0) {
2200                         long int val;
2201
2202                         val = g_variant_get_uint32(value);
2203                         DBG("Value : %li", val);
2204                         ev->attr[i].attr_id = HAL_MEDIA_ATTR_ID_TRACK_NUM;
2205                         snprintf((char*)ev->attr[i].text, HAL_MAX_ATTR_STR_LEN, "%ld", val);
2206                         i++;
2207                 } else {
2208                         DBG("%s not supported, ignoring", key);
2209                 }
2210
2211                 if (i >= HAL_MAX_ATTR_NUM) {
2212                         ERR(" Received max attribute [%d]", i);
2213                         break;
2214                 }
2215         }
2216
2217         ev->num_attr = i;
2218         g_variant_iter_free(&iter);
2219         return;
2220 }
2221
2222 static int __bt_media_attrval_to_val(int type, const char *value)
2223 {
2224         int ret = -1;
2225
2226         switch (type) {
2227         case HAL_PLAYER_ATTR_EQUALIZER:
2228                 if (!strcmp(value, "off"))
2229                         ret = 0x01;
2230                 else
2231                         ret = 0x02;
2232                 break;
2233         case HAL_PLAYER_ATTR_REPEAT:
2234                 if (!strcmp(value, "off"))
2235                         ret = BTRC_PLAYER_VAL_OFF_REPEAT;
2236                 else if (!strcmp(value, "singletrack"))
2237                         ret = BTRC_PLAYER_VAL_SINGLE_REPEAT;
2238                 else if (!strcmp(value, "alltracks"))
2239                         ret = BTRC_PLAYER_VAL_ALL_REPEAT;
2240                 else
2241                         ret = BTRC_PLAYER_VAL_GROUP_REPEAT;
2242                 break;
2243         case HAL_PLAYER_ATTR_SHUFFLE:
2244                 if (!strcmp(value, "off"))
2245                         ret = BTRC_PLAYER_VAL_OFF_SHUFFLE;
2246                 else if (!strcmp(value, "alltracks"))
2247                         ret = BTRC_PLAYER_VAL_ALL_SHUFFLE;
2248                 else
2249                         ret = BTRC_PLAYER_VAL_GROUP_SHUFFLE;
2250                 break;
2251         case HAL_PLAYER_ATTR_SCAN:
2252                 if (!strcmp(value, "off"))
2253                         ret = 0x01;
2254                 else if (!strcmp(value, "alltracks"))
2255                         ret = 0x02;
2256                 else
2257                         ret = 0x03;
2258                 break;
2259         default:
2260                 ERR("Value not handled");
2261         }
2262
2263         return ret;
2264 }
2265
2266 static void __bt_hal_handle_avrcp_ctrl_events(GVariant *msg, const char *member,
2267                 const char *path)
2268 {
2269         const char *property = NULL;
2270         GVariant *value = NULL;
2271         GVariantIter iter;
2272         char address[BT_HAL_ADDRESS_STRING_SIZE];
2273
2274         if (!msg) {
2275                 ERR("Error returned in method call\n");
2276                 return;
2277         }
2278
2279         if (!avrcp_ctrl_event_cb) {
2280                 ERR("AVRCP controller DBUS handler callback not registered");
2281                 return;
2282         }
2283
2284         g_variant_iter_init(&iter, msg);
2285
2286         _bt_hal_convert_device_path_to_address(path, address);
2287
2288         while (g_variant_iter_loop(&iter, "{sv}", &property, &value)) {
2289                 DBG("Property = %s \n", property);
2290                 if ((strcasecmp(property, "Equalizer") == 0) ||
2291                                 (strcasecmp(property, "Repeat") == 0) ||
2292                                 (strcasecmp(property, "Shuffle") == 0) ||
2293                                 (strcasecmp(property, "Scan") == 0)) {
2294                         struct hal_ev_player_setting ev;
2295                         const char *valstr;
2296                         int val = 0;
2297
2298                         valstr = g_variant_get_string(value, NULL);
2299                         DBG("Value : %s ", valstr);
2300
2301                         if (valstr)
2302                                 val = __bt_media_attrval_to_val(__bt_media_attr_to_type(property), valstr);
2303
2304                         if (val >= 0) {
2305                                 memset(&ev, 0, sizeof(ev));
2306                                 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2307                                 ev.num_attr = 1;
2308                                 ev.attr_ids[0] = __bt_media_attr_to_type(property);
2309                                 ev.attr_values[0] = val;
2310
2311                                 /* Send event to application */
2312                                 avrcp_ctrl_event_cb(HAL_EV_AVRCP_CTRL_PLAYER_APP_SETTING_CHANGED, &ev, sizeof(ev));
2313                         }
2314                 } else if ((strcasecmp(property, "Status") == 0)) {
2315                         struct hal_ev_play_status_changed ev;
2316                         const char *valstr;
2317
2318                         valstr = g_variant_get_string(value, NULL);
2319                         DBG("Value : %s ", valstr);
2320
2321                         memset(&ev, 0, sizeof(ev));
2322                         _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2323                         if (valstr)
2324                                 ev.status = __bt_hal_play_status_str_to_type(valstr);
2325
2326                         /* Send event to application */
2327                         avrcp_ctrl_event_cb(HAL_EV_AVRCP_CTRL_PLAY_STATUS_CHANGED, &ev, sizeof(ev));
2328
2329                 } else if (strcasecmp(property, "Position") == 0) {
2330                         struct hal_ev_play_position ev;
2331
2332                         memset(&ev, 0, sizeof(ev));
2333                         _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2334                         ev.pos = g_variant_get_uint32(value);
2335                         DBG("Value : %d ", ev.pos);
2336
2337                         /* Send event to application */
2338                         avrcp_ctrl_event_cb(HAL_EV_AVRCP_CTRL_PLAY_POSITION_CHANGED, &ev, sizeof(ev));
2339                 } else if (strcasecmp(property, "Track") == 0) {
2340                         struct hal_ev_track_changed ev;
2341
2342                         memset(&ev, 0, sizeof(ev));
2343                         _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2344                         __bt_avrcp_control_parse_properties(&ev, value);
2345
2346                         /* Send event to application */
2347                         avrcp_ctrl_event_cb(HAL_EV_AVRCP_CTRL_TRACK_CHANGED, &ev, sizeof(ev));
2348                 } else {
2349                         DBG("Property not handled");
2350                 }
2351         }
2352
2353         g_free((char *)property);
2354         g_variant_unref(value);
2355 }
2356
2357 static void __bt_hal_handle_avrcp_transport_events(GVariant *msg, const char *member,
2358                 const char *path)
2359 {
2360         const char *property = NULL;
2361         GVariant *value = NULL;
2362         GVariantIter iter;
2363         char address[BT_HAL_ADDRESS_STRING_SIZE];
2364         DBG("+");
2365
2366         if (!msg) {
2367                 ERR("Error returned in method call\n");
2368                 return;
2369         }
2370
2371         if (!avrcp_tg_event_cb) {
2372                 ERR("AVRCP target DBUS handler callback not registered");
2373                 return;
2374         }
2375
2376         g_variant_iter_init(&iter, msg);
2377
2378         _bt_hal_convert_device_path_to_address(path, address);
2379
2380         while (g_variant_iter_loop(&iter, "{sv}", &property, &value)) {
2381                 DBG("Property = %s \n", property);
2382                 if ((strcasecmp(property, "Delay") == 0)) {
2383                         struct hal_ev_avrcp_tg_delay_changed ev;
2384                         uint16_t val;
2385
2386                         memset(&ev, 0, sizeof(ev));
2387                         _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2388
2389                         val = g_variant_get_uint16(value);
2390                         DBG("Value : %d", val);
2391                         ev.value = val;
2392
2393                         /* Send event to application */
2394                         avrcp_tg_event_cb(HAL_EV_AVRCP_TG_DELAY_CHANGE, &ev, sizeof(ev));
2395                 } else {
2396                         DBG("Property not handled");
2397                 }
2398         }
2399
2400         DBG("-");
2401         g_free((char *)property);
2402         g_variant_unref(value);
2403 }
2404
2405 /* A2DP Src Role(Remote:Sink) Events */
2406 static void __bt_hal_send_av_connection_state_event(gboolean connected, const char *address)
2407 {
2408         DBG("+");
2409         struct hal_ev_a2dp_conn_state ev;
2410
2411         if (connected == TRUE)
2412                 INFO("A2DP(Src) Profile Connected for address [%s]", address);
2413         else
2414                 INFO("A2DP(Src) Profile DisConnected for address [%s]", address);
2415
2416         ev.state = (connected == TRUE) ?
2417                 HAL_EV_A2DP_STATE_CONNECTED :
2418                 HAL_EV_A2DP_STATE_DISCONNECTED;
2419
2420         _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2421
2422         if (!av_event_cb)
2423                 ERR("AV event handler not registered");
2424         else
2425                 av_event_cb(HAL_EV_A2DP_CONN_STATE, &ev, sizeof(ev));
2426 }
2427
2428 /* A2DP Sink Role(Remote:Source) Events */
2429 static void __bt_hal_send_a2dp_sink_connection_state_event(gboolean connected, const char *address)
2430 {
2431         DBG("+");
2432         struct hal_ev_a2dp_conn_state ev;
2433
2434         if (connected == TRUE)
2435                 INFO("A2DP(Sink) Profile Connected for address [%s]", address);
2436         else
2437                 INFO("A2DP(Sink) Profile DisConnected for address [%s]", address);
2438
2439         ev.state = (connected == TRUE) ?
2440                 HAL_EV_A2DP_STATE_CONNECTED :
2441                 HAL_EV_A2DP_STATE_DISCONNECTED;
2442
2443         _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2444
2445         if (!a2dp_sink_event_cb)
2446                 ERR("AV event handler not registered");
2447         else
2448                 a2dp_sink_event_cb(HAL_EV_A2DP_SOURCE_CONN_STATE, &ev, sizeof(ev));
2449 }
2450
2451 /* HF(AG Role) Audio Events */
2452 static void __bt_hal_send_hf_audio_connection_state_event(gboolean connected,
2453                                                 const char *address)
2454 {
2455         DBG("+");
2456         struct hal_ev_handsfree_audio_state ev;
2457
2458         if (connected == TRUE)
2459                 INFO("AG Audio Connected for address [%s]", address);
2460         else
2461                 INFO("AG Audio DisConnected for address [%s]", address);
2462
2463         ev.state = (connected == TRUE) ?
2464                 HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTED :
2465                 HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED;
2466
2467         _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2468
2469         if (!hf_event_cb)
2470                 ERR("HF event handler not registered");
2471         else
2472                 hf_event_cb(HAL_EV_HANDSFREE_AUDIO_STATE, &ev, sizeof(ev));
2473 }
2474
2475 /* HF(AG Role) Profile Events */
2476 static void __bt_hal_send_hf_connection_state_event(gboolean connected,
2477                                                 const char *address)
2478 {
2479         DBG("+");
2480         struct hal_ev_handsfree_conn_state ev;
2481
2482         if (connected == TRUE)
2483                 INFO("AG Profile Connected for address [%s]", address);
2484         else
2485                 INFO("AG Profile DisConnected for address [%s]", address);
2486
2487         ev.state = (connected == TRUE) ?
2488                 HAL_EV_HANDSFREE_CONN_STATE_CONNECTED :
2489                 HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED;
2490
2491         _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
2492
2493         if (!hf_event_cb)
2494                 ERR("HF event handler not registered");
2495         else
2496                 hf_event_cb(HAL_EV_HANDSFREE_CONN_STATE, &ev, sizeof(ev));
2497 }
2498
2499 void _bt_hal_register_event_handler_cb(bt_hal_module_e module, handle_stack_msg cb)
2500 {
2501         switch (module) {
2502         case HAL_HIDHOST:
2503                 hid_event_cb = cb;
2504                 break;
2505         case HAL_A2DP_SRC:
2506                 av_event_cb = cb;
2507                 break;
2508         case HAL_A2DP_SNK:
2509                 a2dp_sink_event_cb = cb;
2510                 break;
2511         case HAL_HF_AG:
2512                 hf_event_cb = cb;
2513                 break;
2514         case HAL_AVRCP_TG:
2515                 avrcp_tg_event_cb = cb;
2516                 break;
2517         case HAL_AVRCP_CTRL:
2518                 avrcp_ctrl_event_cb = cb;
2519                 break;
2520         case HAL_GATT:
2521                 gatt_event_cb = cb;
2522                 break;
2523         default:
2524                 ERR("Unknown module: %d", module);
2525         }
2526 }
2527
2528 void _bt_hal_unregister_event_handler_cb(bt_hal_module_e module)
2529 {
2530         switch (module) {
2531         case HAL_HIDHOST:
2532                 hid_event_cb = NULL;
2533                 break;
2534         case HAL_A2DP_SRC:
2535                 av_event_cb = NULL;
2536                 break;
2537         case HAL_A2DP_SNK:
2538                 a2dp_sink_event_cb = NULL;
2539                 break;
2540         case HAL_HF_AG:
2541                 hf_event_cb = NULL;
2542                 break;
2543         case HAL_AVRCP_TG:
2544                 avrcp_tg_event_cb = NULL;
2545                 break;
2546         case HAL_AVRCP_CTRL:
2547                 avrcp_ctrl_event_cb = NULL;
2548                 break;
2549         case HAL_GATT:
2550                 gatt_event_cb = NULL;
2551                 break;
2552         default:
2553                 ERR("Unknown module: %d", module);
2554         }
2555 }
2556
2557 bool _bt_hal_get_adapter_request_state(void)
2558 {
2559         return is_adapter_activating;
2560 }
2561
2562 bool _bt_hal_get_le_request_state(void)
2563 {
2564         return is_le_activating;
2565 }
2566
2567 void _bt_hal_set_adapter_request_state(bool enable)
2568 {
2569         DBG("set_adapter_request_state %d", enable);
2570         is_adapter_activating = enable;
2571 }
2572
2573 void _bt_hal_set_le_request_state(bool enable)
2574 {
2575         DBG("set_le_request_state %d", enable);
2576         is_le_activating = enable;
2577 }