4 * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
20 #include <dbus/dbus-glib.h>
21 #include <dbus/dbus-glib-lowlevel.h>
22 #include <dbus/dbus.h>
27 #include <vconf-internal-bt-keys.h>
29 #include "bluetooth-api.h"
30 #include "bt-internal-types.h"
32 #include "bt-service-common.h"
33 #include "bt-service-event.h"
34 #include "bt-service-main.h"
35 #include "bt-service-adapter.h"
36 #include "bt-service-device.h"
37 #include "bt-service-obex-server.h"
38 #include "bt-service-rfcomm-server.h"
39 #include "bt-service-audio.h"
41 static DBusGConnection *manager_conn;
42 static DBusGConnection *obexd_conn;
44 static gboolean __bt_parse_device_properties(DBusMessageIter *item_iter,
45 bt_remote_dev_info_t *dev_info)
47 DBusMessageIter value_iter;
50 if (dbus_message_iter_get_arg_type(item_iter) != DBUS_TYPE_ARRAY)
53 dbus_message_iter_recurse(item_iter, &value_iter);
55 while (dbus_message_iter_get_arg_type(&value_iter) ==
56 DBUS_TYPE_DICT_ENTRY) {
58 DBusMessageIter dict_entry;
59 DBusMessageIter iter_dict_val;
61 dbus_message_iter_recurse(&value_iter, &dict_entry);
63 dbus_message_iter_get_basic(&dict_entry, &key);
65 dbus_message_iter_next(&value_iter);
69 if (!dbus_message_iter_next(&dict_entry)) {
70 dbus_message_iter_next(&value_iter);
73 dbus_message_iter_recurse(&dict_entry, &iter_dict_val);
74 if (strcasecmp(key, "Class") == 0) {
75 dbus_message_iter_get_basic(&iter_dict_val, &dev_info->class);
76 } else if (strcasecmp(key, "name") == 0) {
77 dbus_message_iter_get_basic(&iter_dict_val, &value);
78 if (dev_info->name == NULL)
79 dev_info->name = g_strdup(value);
80 } else if (strcasecmp(key, "Connected") == 0) {
81 dbus_message_iter_get_basic(&iter_dict_val,
82 &dev_info->connected);
83 } else if (strcasecmp(key, "paired") == 0) {
84 dbus_message_iter_get_basic(&iter_dict_val,
86 } else if (strcasecmp(key, "Trusted") == 0) {
87 dbus_message_iter_get_basic(&iter_dict_val,
89 } else if (strcasecmp(key, "RSSI") == 0) {
90 dbus_message_iter_get_basic(&iter_dict_val,
92 } else if (strcasecmp(key, "UUIDs") == 0) {
93 DBusMessageIter uuid_iter;
94 DBusMessageIter tmp_iter;
97 dbus_message_iter_recurse(&iter_dict_val, &uuid_iter);
101 /* Store the uuid count */
102 while (dbus_message_iter_get_arg_type(&tmp_iter) != DBUS_TYPE_INVALID) {
103 dbus_message_iter_get_basic(&tmp_iter,
106 dev_info->uuid_count++;
107 if (!dbus_message_iter_next(&tmp_iter))
111 /* Store the uuids */
112 if (dev_info->uuid_count > 0) {
113 dev_info->uuids = g_new0(char *,
114 dev_info->uuid_count + 1);
119 while (dbus_message_iter_get_arg_type(&uuid_iter) != DBUS_TYPE_INVALID) {
120 dbus_message_iter_get_basic(&uuid_iter,
122 dev_info->uuids[i] = g_strdup(value);
124 if (!dbus_message_iter_next(&uuid_iter)) {
131 dbus_message_iter_next(&value_iter);
137 char *__bt_get_headset_name(char *address)
139 bluetooth_device_address_t device_address = { {0} };
140 bluetooth_device_info_t dev_info;
142 retv_if(address == NULL, strdup(""));
144 _bt_convert_addr_string_to_type(device_address.addr, address);
146 memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
148 _bt_get_bonded_device_info(&device_address, &dev_info);
150 return g_strdup(dev_info.device_name.name);
153 static int __bt_get_owner_info(DBusMessage *msg, char **name,
154 char **previous, char **current)
156 DBusMessageIter item_iter;
158 dbus_message_iter_init(msg, &item_iter);
160 if (dbus_message_iter_get_arg_type(&item_iter)
161 != DBUS_TYPE_STRING) {
162 BT_ERR("This is bad format dbus\n");
163 return BLUETOOTH_ERROR_INTERNAL;
166 dbus_message_iter_get_basic(&item_iter, name);
168 retv_if(*name == NULL, BLUETOOTH_ERROR_INTERNAL);
170 dbus_message_iter_next(&item_iter);
172 if (dbus_message_iter_get_arg_type(&item_iter)
173 != DBUS_TYPE_STRING) {
174 BT_ERR("This is bad format dbus\n");
175 return BLUETOOTH_ERROR_INTERNAL;
178 dbus_message_iter_get_basic(&item_iter, previous);
180 retv_if(*previous == NULL, BLUETOOTH_ERROR_INTERNAL);
182 dbus_message_iter_next(&item_iter);
184 if (dbus_message_iter_get_arg_type(&item_iter)
185 != DBUS_TYPE_STRING) {
186 BT_ERR("This is bad format dbus\n");
187 return BLUETOOTH_ERROR_INTERNAL;
190 dbus_message_iter_get_basic(&item_iter, current);
192 retv_if(*current == NULL, BLUETOOTH_ERROR_INTERNAL);
194 return BLUETOOTH_ERROR_NONE;
197 static int __bt_get_agent_signal_info(DBusMessage *msg, char **address,
198 char **name, char **uuid)
200 DBusMessageIter item_iter;
202 dbus_message_iter_init(msg, &item_iter);
204 if (dbus_message_iter_get_arg_type(&item_iter)
205 != DBUS_TYPE_STRING) {
206 BT_ERR("This is bad format dbus\n");
207 return BLUETOOTH_ERROR_INTERNAL;
210 dbus_message_iter_get_basic(&item_iter, address);
212 dbus_message_iter_next(&item_iter);
214 if (dbus_message_iter_get_arg_type(&item_iter)
215 != DBUS_TYPE_STRING) {
216 BT_ERR("This is bad format dbus\n");
217 return BLUETOOTH_ERROR_INTERNAL;
220 dbus_message_iter_get_basic(&item_iter, name);
222 dbus_message_iter_next(&item_iter);
224 if (dbus_message_iter_get_arg_type(&item_iter)
225 != DBUS_TYPE_STRING) {
226 BT_ERR("This is bad format dbus\n");
227 return BLUETOOTH_ERROR_INTERNAL;
230 dbus_message_iter_get_basic(&item_iter, uuid);
232 return BLUETOOTH_ERROR_NONE;
235 void _bt_handle_adapter_event(DBusMessage *msg)
238 int result = BLUETOOTH_ERROR_NONE;
239 DBusGProxy *adapter_proxy;
240 DBusMessageIter item_iter;
241 DBusMessageIter value_iter;
242 GValue timeout = { 0 };
243 const char *member = dbus_message_get_member(msg);
244 const char *property = NULL;
246 ret_if(member == NULL);
248 if (strcasecmp(member, "PropertyChanged") == 0) {
249 dbus_message_iter_init(msg, &item_iter);
251 if (dbus_message_iter_get_arg_type(&item_iter)
252 != DBUS_TYPE_STRING) {
253 BT_ERR("This is bad format dbus\n");
257 dbus_message_iter_get_basic(&item_iter, &property);
258 BT_DBG("member = PropertyChanged[%s]", property);
260 ret_if(property == NULL);
262 if (strcasecmp(property, "Discovering") == 0) {
263 gboolean discovering = FALSE;
264 dbus_message_iter_next(&item_iter);
265 dbus_message_iter_recurse(&item_iter, &value_iter);
266 dbus_message_iter_get_basic(&value_iter, &discovering);
268 /* Send event to application */
269 if (discovering == TRUE) {
270 _bt_set_discovery_status(TRUE);
271 _bt_send_event(BT_ADAPTER_EVENT,
272 BLUETOOTH_EVENT_DISCOVERY_STARTED,
273 DBUS_TYPE_INT32, &result,
276 _bt_set_cancel_by_user(FALSE);
277 _bt_set_discovery_status(FALSE);
278 _bt_send_event(BT_ADAPTER_EVENT,
279 BLUETOOTH_EVENT_DISCOVERY_FINISHED,
280 DBUS_TYPE_INT32, &result,
283 } else if (strcasecmp(property, "Name") == 0) {
285 dbus_message_iter_next(&item_iter);
286 dbus_message_iter_recurse(&item_iter, &value_iter);
287 dbus_message_iter_get_basic(&value_iter, &name);
289 /* Send event to application */
290 _bt_send_event(BT_ADAPTER_EVENT,
291 BLUETOOTH_EVENT_LOCAL_NAME_CHANGED,
292 DBUS_TYPE_INT32, &result,
293 DBUS_TYPE_STRING, &name,
295 } else if (strcasecmp(property, "Discoverable") == 0) {
296 gboolean discoverable = FALSE;
297 dbus_message_iter_next(&item_iter);
298 dbus_message_iter_recurse(&item_iter, &value_iter);
299 dbus_message_iter_get_basic(&value_iter, &discoverable);
301 if (discoverable == FALSE) {
302 if (_bt_get_discoverable_timeout_property() > 0) {
303 g_value_init(&timeout, G_TYPE_UINT);
304 g_value_set_uint(&timeout, 0);
306 adapter_proxy = _bt_get_adapter_proxy();
307 ret_if(adapter_proxy == NULL);
309 dbus_g_proxy_call_no_reply(adapter_proxy, "SetProperty",
310 G_TYPE_STRING, "DiscoverableTimeout",
311 G_TYPE_VALUE, &timeout,
314 g_value_unset(&timeout);
317 mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
319 /* Send event to application */
320 _bt_send_event(BT_ADAPTER_EVENT,
321 BLUETOOTH_EVENT_DISCOVERABLE_MODE_CHANGED,
322 DBUS_TYPE_INT32, &result,
323 DBUS_TYPE_INT16, &mode,
326 _bt_get_discoverable_mode(&mode);
328 /* Event will be sent by "DiscoverableTimeout" signal */
329 ret_if(mode != BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE);
331 /* Send event to application */
332 _bt_send_event(BT_ADAPTER_EVENT,
333 BLUETOOTH_EVENT_DISCOVERABLE_MODE_CHANGED,
334 DBUS_TYPE_INT32, &result,
335 DBUS_TYPE_INT16, &mode,
338 } else if (strcasecmp(property, "DiscoverableTimeout") == 0) {
339 _bt_get_discoverable_mode(&mode);
341 /* Event was already sent by "Discoverable" signal */
342 ret_if(mode == BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE);
344 /* Send event to application */
345 _bt_send_event(BT_ADAPTER_EVENT,
346 BLUETOOTH_EVENT_DISCOVERABLE_MODE_CHANGED,
347 DBUS_TYPE_INT32, &result,
348 DBUS_TYPE_INT16, &mode,
350 } else if (strcasecmp(property, "Powered") == 0) {
351 gboolean powered = FALSE;
352 dbus_message_iter_next(&item_iter);
353 dbus_message_iter_recurse(&item_iter, &value_iter);
354 dbus_message_iter_get_basic(&value_iter, &powered);
355 BT_DBG("Powered = %d", powered);
356 if (powered == FALSE)
357 _bt_disable_adapter();
359 } else if (strcasecmp(member, "DeviceFound") == 0) {
361 bt_remote_dev_info_t *dev_info;
363 ret_if(_bt_is_discovering() == FALSE);
365 dev_info = g_malloc0(sizeof(bt_remote_dev_info_t));
367 dbus_message_iter_init(msg, &item_iter);
368 dbus_message_iter_get_basic(&item_iter, &bdaddr);
369 dbus_message_iter_next(&item_iter);
371 dev_info->address = g_strdup(bdaddr);
373 if (__bt_parse_device_properties(&item_iter, dev_info) == FALSE) {
374 BT_ERR("Fail to parse the properies");
375 _bt_free_device_info(dev_info);
379 if (dev_info->name == NULL)
380 dev_info->name = g_strdup("");
382 _bt_send_event(BT_ADAPTER_EVENT,
383 BLUETOOTH_EVENT_REMOTE_DEVICE_FOUND,
384 DBUS_TYPE_INT32, &result,
385 DBUS_TYPE_STRING, &dev_info->address,
386 DBUS_TYPE_UINT32, &dev_info->class,
387 DBUS_TYPE_INT16, &dev_info->rssi,
388 DBUS_TYPE_STRING, &dev_info->name,
389 DBUS_TYPE_BOOLEAN, &dev_info->paired,
390 DBUS_TYPE_BOOLEAN, &dev_info->connected,
391 DBUS_TYPE_BOOLEAN, &dev_info->trust,
392 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
393 &dev_info->uuids, dev_info->uuid_count,
396 _bt_free_device_info(dev_info);
397 } else if (strcasecmp(member, "DeviceCreated") == 0) {
398 const char *object_path = NULL;
400 bt_remote_dev_info_t *remote_dev_info;
402 ret_if(_bt_is_device_creating() == FALSE);
404 /* Bonding from remote device */
405 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
407 dbus_message_iter_init(msg, &item_iter);
408 dbus_message_iter_get_basic(&item_iter, &object_path);
409 dbus_message_iter_next(&item_iter);
411 _bt_convert_device_path_to_address(object_path, address);
413 remote_dev_info = _bt_get_remote_device_info(address);
414 if (remote_dev_info == NULL) {
419 _bt_free_device_info(remote_dev_info);
421 } else if (strcasecmp(member, "DeviceRemoved") == 0) {
422 const char *object_path = NULL;
425 /* Bonding from remote device */
426 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
428 dbus_message_iter_init(msg, &item_iter);
429 dbus_message_iter_get_basic(&item_iter, &object_path);
430 dbus_message_iter_next(&item_iter);
432 _bt_convert_device_path_to_address(object_path, address);
434 _bt_send_event(BT_ADAPTER_EVENT,
435 BLUETOOTH_EVENT_BONDED_DEVICE_REMOVED,
436 DBUS_TYPE_INT32, &result,
437 DBUS_TYPE_STRING, &address,
444 void _bt_handle_input_event(DBusMessage *msg)
446 int result = BLUETOOTH_ERROR_NONE;
447 DBusMessageIter item_iter;
448 DBusMessageIter value_iter;
449 gboolean property_flag = FALSE;
450 const char *member = dbus_message_get_member(msg);
451 const char *path = dbus_message_get_path(msg);
452 const char *property = NULL;
454 ret_if(member == NULL);
456 dbus_message_iter_init(msg, &item_iter);
458 if (dbus_message_iter_get_arg_type(&item_iter)
459 != DBUS_TYPE_STRING) {
460 BT_ERR("This is bad format dbus\n");
464 dbus_message_iter_get_basic(&item_iter, &property);
466 ret_if(property == NULL);
468 if (strcasecmp(property, "Connected") == 0) {
469 int event = BLUETOOTH_EVENT_NONE;
472 dbus_message_iter_next(&item_iter);
473 dbus_message_iter_recurse(&item_iter, &value_iter);
474 dbus_message_iter_get_basic(&value_iter, &property_flag);
476 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
478 _bt_convert_device_path_to_address(path, address);
480 event = (property_flag == TRUE) ?
481 BLUETOOTH_HID_CONNECTED :
482 BLUETOOTH_HID_DISCONNECTED;
484 _bt_send_event(BT_HID_EVENT, event,
485 DBUS_TYPE_INT32, &result,
486 DBUS_TYPE_STRING, &address,
493 void _bt_handle_network_server_event(DBusMessage *msg)
495 int result = BLUETOOTH_ERROR_NONE;
496 char *address = NULL;
498 const char *member = dbus_message_get_member(msg);
500 ret_if(member == NULL);
502 if (strcasecmp(member, "PeerConnected") == 0) {
503 if (!dbus_message_get_args(msg, NULL,
504 DBUS_TYPE_STRING, &device,
505 DBUS_TYPE_STRING, &address,
506 DBUS_TYPE_INVALID)) {
507 BT_ERR("Unexpected parameters in signal");
511 _bt_send_event(BT_NETWORK_EVENT, BLUETOOTH_EVENT_NETWORK_SERVER_CONNECTED,
512 DBUS_TYPE_INT32, &result,
513 DBUS_TYPE_STRING, &device,
514 DBUS_TYPE_STRING, &address,
516 } else if (strcasecmp(member, "PeerDisconnected") == 0) {
517 if (!dbus_message_get_args(msg, NULL,
518 DBUS_TYPE_STRING, &device,
519 DBUS_TYPE_STRING, &address,
520 DBUS_TYPE_INVALID)) {
521 BT_ERR("Unexpected parameters in signal");
525 _bt_send_event(BT_NETWORK_EVENT, BLUETOOTH_EVENT_NETWORK_SERVER_DISCONNECTED,
526 DBUS_TYPE_INT32, &result,
527 DBUS_TYPE_STRING, &device,
528 DBUS_TYPE_STRING, &address,
533 void _bt_handle_network_client_event(DBusMessage *msg)
535 int result = BLUETOOTH_ERROR_NONE;
536 DBusMessageIter item_iter;
537 DBusMessageIter value_iter;
538 gboolean property_flag = FALSE;
539 const char *member = dbus_message_get_member(msg);
540 const char *path = dbus_message_get_path(msg);
541 const char *property = NULL;
543 ret_if(member == NULL);
545 dbus_message_iter_init(msg, &item_iter);
547 if (dbus_message_iter_get_arg_type(&item_iter)
548 != DBUS_TYPE_STRING) {
549 BT_ERR("This is bad format dbus\n");
553 dbus_message_iter_get_basic(&item_iter, &property);
555 ret_if(property == NULL);
557 if (strcasecmp(property, "Connected") == 0) {
558 int event = BLUETOOTH_EVENT_NONE;
561 dbus_message_iter_next(&item_iter);
562 dbus_message_iter_recurse(&item_iter, &value_iter);
563 dbus_message_iter_get_basic(&value_iter, &property_flag);
565 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
567 _bt_convert_device_path_to_address(path, address);
569 if (property_flag == TRUE) {
570 event = BLUETOOTH_EVENT_NETWORK_CONNECTED;
572 event = BLUETOOTH_EVENT_NETWORK_DISCONNECTED;
575 _bt_send_event(BT_NETWORK_EVENT, event,
576 DBUS_TYPE_INT32, &result,
577 DBUS_TYPE_STRING, &address,
584 void _bt_handle_device_event(DBusMessage *msg)
587 int result = BLUETOOTH_ERROR_NONE;
588 DBusMessageIter item_iter;
589 DBusMessageIter value_iter;
591 const char *member = dbus_message_get_member(msg);
592 const char *path = dbus_message_get_path(msg);
593 const char *property = NULL;
595 ret_if(path == NULL);
596 ret_if(member == NULL);
598 if (strcasecmp(member, "PropertyChanged") == 0) {
599 dbus_message_iter_init(msg, &item_iter);
601 if (dbus_message_iter_get_arg_type(&item_iter)
602 != DBUS_TYPE_STRING) {
603 BT_ERR("This is bad format dbus\n");
607 dbus_message_iter_get_basic(&item_iter, &property);
609 ret_if(property == NULL);
611 if (strcasecmp(property, "Connected") == 0) {
612 gboolean connected = FALSE;
613 dbus_message_iter_next(&item_iter);
614 dbus_message_iter_recurse(&item_iter, &value_iter);
615 dbus_message_iter_get_basic(&value_iter, &connected);
617 event = connected ? BLUETOOTH_EVENT_DEVICE_CONNECTED :
618 BLUETOOTH_EVENT_DEVICE_DISCONNECTED;
620 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
622 _bt_convert_device_path_to_address(path, address);
624 BT_DBG("connected: %d", connected);
625 BT_DBG("address: %s", address);
627 /* Send event to application */
628 _bt_send_event(BT_DEVICE_EVENT,
630 DBUS_TYPE_INT32, &result,
631 DBUS_TYPE_STRING, &address,
635 } else if (strcasecmp(property, "Paired") == 0) {
636 gboolean paired = FALSE;
637 bt_remote_dev_info_t *remote_dev_info;
638 dbus_message_iter_next(&item_iter);
639 dbus_message_iter_recurse(&item_iter, &value_iter);
640 dbus_message_iter_get_basic(&value_iter, &paired);
642 ret_if(paired == FALSE);
644 /* BlueZ sends paired signal for each paired device */
645 /* during activation, We should ignore this, otherwise*/
646 /* application thinks that a new device got paired */
647 if (_bt_adapter_get_status() != BT_ACTIVATED) {
648 BT_DBG("BT is not activated, so ignore this");
652 if (_bt_is_device_creating() == TRUE) {
653 BT_DBG("Try to Pair by me");
657 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
659 _bt_convert_device_path_to_address(path, address);
661 remote_dev_info = _bt_get_remote_device_info(address);
662 if (remote_dev_info == NULL) {
667 _bt_send_event(BT_ADAPTER_EVENT,
668 BLUETOOTH_EVENT_BONDING_FINISHED,
669 DBUS_TYPE_INT32, &result,
670 DBUS_TYPE_STRING, &address,
671 DBUS_TYPE_UINT32, &remote_dev_info->class,
672 DBUS_TYPE_INT16, &remote_dev_info->rssi,
673 DBUS_TYPE_STRING, &remote_dev_info->name,
674 DBUS_TYPE_BOOLEAN, &remote_dev_info->paired,
675 DBUS_TYPE_BOOLEAN, &remote_dev_info->connected,
676 DBUS_TYPE_BOOLEAN, &remote_dev_info->trust,
677 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
678 &remote_dev_info->uuids, remote_dev_info->uuid_count,
681 _bt_free_device_info(remote_dev_info);
687 void __bt_set_audio_values(gboolean connected, char *address)
690 int bt_device_state = VCONFKEY_BT_DEVICE_NONE;
692 /* Set the headset name */
693 if (connected == TRUE) {
694 name = __bt_get_headset_name(address);
699 if (vconf_set_str(VCONFKEY_BT_HEADSET_NAME,
701 BT_ERR("vconf_set_str failed");
706 /* Set the headset state */
707 if (vconf_get_int(VCONFKEY_BT_DEVICE,
708 &bt_device_state) != 0) {
709 BT_ERR("vconf_get_str failed");
712 if (connected == TRUE) {
713 bt_device_state |= VCONFKEY_BT_DEVICE_HEADSET_CONNECTED;
714 } else if (bt_device_state & VCONFKEY_BT_DEVICE_HEADSET_CONNECTED) {
715 bt_device_state ^= VCONFKEY_BT_DEVICE_HEADSET_CONNECTED;
718 if (vconf_set_int(VCONFKEY_BT_DEVICE,
719 bt_device_state) != 0) {
720 BT_ERR("vconf_set_int failed");
724 void _bt_handle_headset_event(DBusMessage *msg)
726 int result = BLUETOOTH_ERROR_NONE;
727 DBusMessageIter item_iter;
728 DBusMessageIter value_iter;
729 gboolean property_flag = FALSE;
730 const char *member = dbus_message_get_member(msg);
731 const char *path = dbus_message_get_path(msg);
732 const char *property = NULL;
734 ret_if(member == NULL);
736 dbus_message_iter_init(msg, &item_iter);
738 if (dbus_message_iter_get_arg_type(&item_iter)
739 != DBUS_TYPE_STRING) {
740 BT_ERR("This is bad format dbus\n");
744 dbus_message_iter_get_basic(&item_iter, &property);
746 ret_if(property == NULL);
748 BT_DBG("Property = %s \n", property);
750 /* We allow only 1 headset connection (HSP or HFP)*/
751 if (strcasecmp(property, "Connected") == 0) {
752 int event = BLUETOOTH_EVENT_NONE;
753 bt_headset_wait_t *wait_list;
756 dbus_message_iter_next(&item_iter);
757 dbus_message_iter_recurse(&item_iter, &value_iter);
758 dbus_message_iter_get_basic(&value_iter, &property_flag);
760 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
762 _bt_convert_device_path_to_address(path, address);
764 if (property_flag == TRUE) {
765 event = BLUETOOTH_EVENT_AG_CONNECTED;
767 event = BLUETOOTH_EVENT_AG_DISCONNECTED;
770 __bt_set_audio_values(property_flag, address);
772 _bt_send_event(BT_HEADSET_EVENT, event,
773 DBUS_TYPE_INT32, &result,
774 DBUS_TYPE_STRING, &address,
777 if (event == BLUETOOTH_EVENT_AG_DISCONNECTED) {
778 /* Remove data from the connected list */
779 _bt_remove_headset_from_list(BT_AUDIO_HSP, address);
781 wait_list = _bt_get_audio_wait_data();
782 if (wait_list == NULL) {
787 bluetooth_device_address_t device_address;
789 _bt_set_audio_wait_data_flag(TRUE);
791 _bt_convert_addr_string_to_type(device_address.addr,
793 _bt_audio_connect(wait_list->req_id, wait_list->type,
794 &device_address, wait_list->out_param1);
795 } else if (event == BLUETOOTH_EVENT_AG_CONNECTED) {
796 /* Add data to the connected list */
797 _bt_add_headset_to_list(BT_AUDIO_HSP,
798 BT_STATE_CONNECTED, address);
801 } else if (strcasecmp(property, "State") == 0) {
802 int event = BLUETOOTH_EVENT_NONE;
803 int sco_connected = FALSE;
807 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
809 _bt_convert_device_path_to_address(path, address);
811 dbus_message_iter_next(&item_iter);
812 dbus_message_iter_recurse(&item_iter, &value_iter);
813 dbus_message_iter_get_basic(&value_iter, &state);
815 /* This code assumes we support only 1 headset connection */
816 /* Need to use the headset list, if we support multi-headsets */
817 if (strcasecmp(state, "Playing") == 0) {
818 event = BLUETOOTH_EVENT_AG_AUDIO_CONNECTED;
819 sco_connected = TRUE;
820 } else if (strcasecmp(state, "connected") == 0 ||
821 strcasecmp(state, "disconnected") == 0) {
822 event = BLUETOOTH_EVENT_AG_AUDIO_DISCONNECTED;
823 sco_connected = FALSE;
825 BT_ERR("Not handled state - %s", state);
830 if (vconf_set_bool(VCONFKEY_BT_HEADSET_SCO, sco_connected) < 0)
831 BT_ERR("vconf_set_bool - Failed\n");
833 _bt_send_event(BT_HEADSET_EVENT, event,
834 DBUS_TYPE_INT32, &result,
835 DBUS_TYPE_STRING, &address,
839 } else if (strcasecmp(property, "SpeakerGain") == 0) {
843 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
845 _bt_convert_device_path_to_address(path, address);
847 dbus_message_iter_next(&item_iter);
848 dbus_message_iter_recurse(&item_iter, &value_iter);
849 dbus_message_iter_get_basic(&value_iter, &spkr_gain);
851 _bt_send_event(BT_HEADSET_EVENT, BLUETOOTH_EVENT_AG_SPEAKER_GAIN,
852 DBUS_TYPE_INT32, &result,
853 DBUS_TYPE_STRING, &address,
854 DBUS_TYPE_UINT16, &spkr_gain,
858 } else if (strcasecmp(property, "MicrophoneGain") == 0) {
862 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
864 _bt_convert_device_path_to_address(path, address);
866 dbus_message_iter_next(&item_iter);
867 dbus_message_iter_recurse(&item_iter, &value_iter);
868 dbus_message_iter_get_basic(&value_iter, &mic_gain);
870 _bt_send_event(BT_HEADSET_EVENT, BLUETOOTH_EVENT_AG_MIC_GAIN,
871 DBUS_TYPE_INT32, &result,
872 DBUS_TYPE_STRING, &address,
873 DBUS_TYPE_UINT16, &mic_gain,
880 void _bt_handle_sink_event(DBusMessage *msg)
882 int result = BLUETOOTH_ERROR_NONE;
883 DBusMessageIter item_iter;
884 DBusMessageIter value_iter;
885 gboolean property_flag = FALSE;
886 const char *member = dbus_message_get_member(msg);
887 const char *path = dbus_message_get_path(msg);
888 const char *property = NULL;
890 bt_headset_wait_t *wait_list;
892 ret_if(member == NULL);
894 dbus_message_iter_init(msg, &item_iter);
896 if (dbus_message_iter_get_arg_type(&item_iter)
897 != DBUS_TYPE_STRING) {
898 BT_ERR("This is bad format dbus\n");
902 dbus_message_iter_get_basic(&item_iter, &property);
904 ret_if(property == NULL);
906 if (strcasecmp(property, "Connected") == 0) {
907 int event = BLUETOOTH_EVENT_NONE;
910 dbus_message_iter_next(&item_iter);
911 dbus_message_iter_recurse(&item_iter, &value_iter);
912 dbus_message_iter_get_basic(&value_iter, &property_flag);
914 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
916 _bt_convert_device_path_to_address(path, address);
918 event = (property_flag == TRUE) ?
919 BLUETOOTH_EVENT_AV_CONNECTED :
920 BLUETOOTH_EVENT_AV_DISCONNECTED;
922 _bt_send_event(BT_HEADSET_EVENT, event,
923 DBUS_TYPE_INT32, &result,
924 DBUS_TYPE_STRING, &address,
927 _bt_send_event(BT_AVRCP_EVENT, event,
928 DBUS_TYPE_INT32, &result,
929 DBUS_TYPE_STRING, &address,
932 if (event == BLUETOOTH_EVENT_AV_DISCONNECTED) {
933 /* Remove data from the connected list */
934 _bt_remove_headset_from_list(BT_AUDIO_A2DP, address);
935 wait_list = _bt_get_audio_wait_data();
936 if (wait_list == NULL) {
941 if (((wait_list->type == BT_AUDIO_ALL) &&
942 (wait_list->ag_flag == TRUE)) ||
943 (wait_list->type == BT_AUDIO_A2DP) ||
944 (wait_list->disconnection_type == BT_AUDIO_A2DP)) {
945 bluetooth_device_address_t device_address;
946 _bt_convert_addr_string_to_type(
950 _bt_audio_connect(wait_list->req_id,
953 wait_list->out_param1);
955 } else if (event == BLUETOOTH_EVENT_AV_CONNECTED){
956 /* Check for existing Media device to disconnect */
957 char connected_address[BT_ADDRESS_STRING_SIZE + 1];
958 bluetooth_device_address_t device_address;
961 connected = _bt_is_headset_type_connected(BT_AUDIO_A2DP,
964 /* Match connected device address */
965 if (g_strcmp0(connected_address, address) != 0) {
966 /* Convert BD adress from string type */
967 _bt_convert_addr_string_to_type(
970 _bt_audio_disconnect(0, BT_AUDIO_A2DP,
971 &device_address, NULL);
975 /* Add data to the connected list */
976 _bt_add_headset_to_list(BT_AUDIO_A2DP,
977 BT_STATE_CONNECTED, address);
983 void _bt_handle_agent_event(DBusMessage *msg)
985 const char *member = dbus_message_get_member(msg);
986 int result = BLUETOOTH_ERROR_NONE;
987 char *address = NULL;
991 ret_if(member == NULL);
993 if (strcasecmp(member, "ObexAuthorize") == 0) {
994 __bt_get_agent_signal_info(msg, &address, &name, &uuid);
996 _bt_send_event(BT_OPP_SERVER_EVENT,
997 BLUETOOTH_EVENT_OBEX_SERVER_CONNECTION_AUTHORIZE,
998 DBUS_TYPE_INT32, &result,
999 DBUS_TYPE_STRING, &address,
1000 DBUS_TYPE_STRING, &name,
1002 } else if (strcasecmp(member, "RfcommAuthorize") == 0) {
1003 bt_rfcomm_server_info_t *server_info;
1005 __bt_get_agent_signal_info(msg, &address, &name, &uuid);
1007 server_info = _bt_rfcomm_get_server_info_using_uuid(uuid);
1008 ret_if(server_info == NULL);
1009 ret_if(server_info->server_type != BT_CUSTOM_SERVER);
1011 _bt_send_event(BT_RFCOMM_SERVER_EVENT,
1012 BLUETOOTH_EVENT_RFCOMM_AUTHORIZE,
1013 DBUS_TYPE_INT32, &result,
1014 DBUS_TYPE_STRING, &address,
1015 DBUS_TYPE_STRING, &uuid,
1016 DBUS_TYPE_STRING, &name,
1017 DBUS_TYPE_INT16, &server_info->control_fd,
1022 static DBusHandlerResult __bt_manager_event_filter(DBusConnection *conn,
1023 DBusMessage *msg, void *data)
1025 const char *member = dbus_message_get_member(msg);
1027 if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_SIGNAL)
1028 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1030 retv_if(member == NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
1032 if (strcasecmp(member, "AdapterAdded") == 0) {
1033 BT_DBG("AdapterAdded");
1034 _bt_handle_adapter_added();
1035 } else if (strcasecmp(member, "AdapterRemoved") == 0) {
1036 BT_DBG("AdapterRemoved");
1037 } else if (strcasecmp(member, "NameOwnerChanged") == 0) {
1040 char *previous = NULL;
1041 char *current = NULL;
1043 if (__bt_get_owner_info(msg, &name, &previous, ¤t)) {
1044 BT_ERR("Fail to get the owner info");
1045 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1048 if (*current != '\0')
1049 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1051 if (strcasecmp(name, "org.bluez") == 0) {
1052 BT_DBG("Bluetoothd is terminated");
1053 _bt_handle_adapter_removed();
1056 _bt_obex_server_check_allocation(&value);
1058 if (value == TRUE) {
1059 /* Check if the obex server was terminated abnormally */
1060 _bt_obex_server_check_termination(name);
1063 _bt_rfcomm_server_check_existence(&value);
1065 if (value == TRUE) {
1066 /* The obex server was terminated abnormally */
1067 _bt_rfcomm_server_check_termination(name);
1069 } else if (dbus_message_has_interface(msg, BT_ADAPTER_INTERFACE)) {
1070 _bt_handle_adapter_event(msg);
1071 } else if (dbus_message_has_interface(msg, BT_INPUT_INTERFACE)) {
1072 _bt_handle_input_event(msg);
1073 } else if (dbus_message_has_interface(msg, BT_NETWORK_SERVER_INTERFACE)) {
1074 _bt_handle_network_server_event(msg);
1075 } else if (dbus_message_has_interface(msg, BT_NETWORK_CLIENT_INTERFACE)) {
1076 _bt_handle_network_client_event(msg);
1077 } else if (dbus_message_has_interface(msg, BT_HEADSET_INTERFACE)) {
1078 _bt_handle_headset_event(msg);
1079 } else if (dbus_message_has_interface(msg, BT_SINK_INTERFACE)) {
1080 _bt_handle_sink_event(msg);
1081 } else if (dbus_message_has_interface(msg, BT_AGENT_INTERFACE)) {
1082 _bt_handle_agent_event(msg);
1083 } else if (dbus_message_has_interface(msg, BT_DEVICE_INTERFACE)) {
1084 _bt_handle_device_event(msg);
1087 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1090 static DBusHandlerResult __bt_obexd_event_filter(DBusConnection *conn,
1091 DBusMessage *msg, void *data)
1093 const char *path = dbus_message_get_path(msg);
1094 const char *member = dbus_message_get_member(msg);
1096 if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_SIGNAL)
1097 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1099 retv_if(member == NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
1101 if (strcasecmp(member, "TransferStarted") == 0) {
1102 char *transfer_path = NULL;
1104 if (!dbus_message_get_args(msg, NULL,
1105 DBUS_TYPE_OBJECT_PATH, &transfer_path,
1106 DBUS_TYPE_INVALID)) {
1107 BT_ERR("Unexpected parameters in signal");
1108 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1111 _bt_obex_transfer_started(transfer_path);
1112 } else if (strcasecmp(member, "Progress") == 0) {
1116 if (!dbus_message_get_args(msg, NULL,
1117 DBUS_TYPE_INT32, &total,
1118 DBUS_TYPE_INT32, &transfer,
1119 DBUS_TYPE_INVALID)) {
1120 BT_ERR("Unexpected parameters in signal");
1121 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1124 _bt_obex_transfer_progress(path, total, transfer);
1125 } else if (strcasecmp(member, "TransferCompleted") == 0) {
1126 char *transfer_path = NULL;
1129 if (!dbus_message_get_args(msg, NULL,
1130 DBUS_TYPE_OBJECT_PATH, &transfer_path,
1131 DBUS_TYPE_BOOLEAN, &success,
1132 DBUS_TYPE_INVALID)) {
1133 BT_ERR("Unexpected parameters in signal");
1134 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1137 _bt_obex_transfer_completed(transfer_path, success);
1140 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1143 int _bt_register_service_event(DBusGConnection *g_conn, int event_type)
1145 DBusError dbus_error;
1146 char *match1 = NULL;
1147 char *match2 = NULL;
1148 DBusConnection *conn;
1149 DBusHandleMessageFunction event_func = NULL;
1151 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1153 conn = dbus_g_connection_get_connection(g_conn);
1154 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1156 switch (event_type) {
1157 case BT_MANAGER_EVENT:
1158 event_func = __bt_manager_event_filter;
1159 match1 = g_strdup_printf(MANAGER_EVENT_MATCH_RULE,
1160 BT_MANAGER_INTERFACE,
1163 match2 = g_strdup_printf(MANAGER_EVENT_MATCH_RULE,
1164 BT_FREEDESKTOP_INTERFACE,
1165 BT_FREEDESKTOP_PATH);
1167 case BT_DEVICE_EVENT:
1168 match1 = g_strdup_printf(EVENT_MATCH_RULE,
1169 BT_DEVICE_INTERFACE);
1172 match1 = g_strdup_printf(EVENT_MATCH_RULE,
1173 BT_INPUT_INTERFACE);
1175 case BT_NETWORK_EVENT:
1176 match1 = g_strdup_printf(EVENT_MATCH_RULE,
1177 BT_NETWORK_SERVER_INTERFACE);
1179 match2 = g_strdup_printf(EVENT_MATCH_RULE,
1180 BT_NETWORK_CLIENT_INTERFACE);
1182 case BT_HEADSET_EVENT:
1183 match1 = g_strdup_printf(EVENT_MATCH_RULE,
1184 BT_HEADSET_INTERFACE);
1186 match2 = g_strdup_printf(EVENT_MATCH_RULE,
1189 case BT_OPP_SERVER_EVENT:
1190 event_func = __bt_obexd_event_filter;
1191 match1 = g_strdup_printf(MANAGER_EVENT_MATCH_RULE,
1192 BT_OBEXD_MANAGER_INTERFACE,
1195 match2 = g_strdup_printf(EVENT_MATCH_RULE,
1196 BT_OBEXD_TRANSFER_INTERFACE);
1199 BT_ERR("Unknown event");
1200 return BLUETOOTH_ERROR_INTERNAL;
1204 if (!dbus_connection_add_filter(conn, event_func,
1206 BT_ERR("Fail to add filter");
1211 dbus_error_init(&dbus_error);
1214 dbus_bus_add_match(conn, match1, &dbus_error);
1216 if (dbus_error_is_set(&dbus_error)) {
1217 BT_ERR("Fail to add match: %s\n", dbus_error.message);
1218 dbus_error_free(&dbus_error);
1223 dbus_bus_add_match(conn, match2, &dbus_error);
1225 if (dbus_error_is_set(&dbus_error)) {
1226 BT_ERR("Fail to add match: %s\n", dbus_error.message);
1227 dbus_error_free(&dbus_error);
1234 return BLUETOOTH_ERROR_NONE;
1238 return BLUETOOTH_ERROR_INTERNAL;
1241 void _bt_unregister_service_event(DBusGConnection *g_conn, int event_type)
1243 DBusConnection *conn;
1244 DBusHandleMessageFunction event_func;
1246 ret_if(g_conn == NULL);
1247 conn = dbus_g_connection_get_connection(g_conn);
1249 switch (event_type) {
1250 case BT_MANAGER_EVENT:
1251 event_func = __bt_manager_event_filter;
1253 case BT_OPP_SERVER_EVENT:
1254 event_func = __bt_obexd_event_filter;
1257 BT_ERR("Unknown event");
1261 ret_if(conn == NULL);
1263 dbus_connection_remove_filter(conn, event_func, NULL);
1266 static int __bt_init_manager_receiver(void)
1268 GError *error = NULL;
1270 if (manager_conn == NULL) {
1271 manager_conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
1272 if (error != NULL) {
1273 BT_ERR("ERROR: Can't get on system bus [%s]", error->message);
1274 g_error_free(error);
1276 retv_if(manager_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1279 if (_bt_register_service_event(manager_conn,
1280 BT_MANAGER_EVENT) != BLUETOOTH_ERROR_NONE)
1283 if (_bt_register_service_event(manager_conn,
1284 BT_DEVICE_EVENT) != BLUETOOTH_ERROR_NONE)
1287 if (_bt_register_service_event(manager_conn,
1288 BT_HID_EVENT) != BLUETOOTH_ERROR_NONE)
1291 if (_bt_register_service_event(manager_conn,
1292 BT_HEADSET_EVENT) != BLUETOOTH_ERROR_NONE)
1295 if (_bt_register_service_event(manager_conn,
1296 BT_NETWORK_EVENT) != BLUETOOTH_ERROR_NONE)
1299 return BLUETOOTH_ERROR_NONE;
1302 dbus_g_connection_unref(manager_conn);
1303 manager_conn = NULL;
1306 return BLUETOOTH_ERROR_INTERNAL;
1309 static int __bt_init_obexd_receiver(void)
1311 GError *error = NULL;
1313 if (obexd_conn == NULL) {
1314 obexd_conn = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
1315 if (error != NULL) {
1316 BT_ERR("ERROR: Can't get on session bus [%s]", error->message);
1317 g_error_free(error);
1319 retv_if(obexd_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1322 if (_bt_register_service_event(obexd_conn,
1323 BT_OPP_SERVER_EVENT) != BLUETOOTH_ERROR_NONE) {
1324 dbus_g_connection_unref(obexd_conn);
1326 return BLUETOOTH_ERROR_INTERNAL;
1329 return BLUETOOTH_ERROR_NONE;
1332 /* To receive the event from bluez */
1333 int _bt_init_service_event_receiver(void)
1337 result = __bt_init_manager_receiver();
1338 retv_if(result != BLUETOOTH_ERROR_NONE, result);
1340 result = __bt_init_obexd_receiver();
1341 if (result != BLUETOOTH_ERROR_NONE)
1342 BT_ERR("Fail to init obexd receiver");
1344 return BLUETOOTH_ERROR_NONE;
1347 void _bt_deinit_service_event_reciever(void)
1349 _bt_unregister_service_event(manager_conn, BT_MANAGER_EVENT);
1351 _bt_unregister_service_event(obexd_conn, BT_OPP_SERVER_EVENT);
1354 dbus_g_connection_unref(manager_conn);
1355 manager_conn = NULL;
1359 dbus_g_connection_unref(obexd_conn);