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 guint event_id;
46 static gboolean __bt_parse_device_properties(DBusMessageIter *item_iter,
47 bt_remote_dev_info_t *dev_info)
49 DBusMessageIter value_iter;
52 if (dbus_message_iter_get_arg_type(item_iter) != DBUS_TYPE_ARRAY)
55 dbus_message_iter_recurse(item_iter, &value_iter);
57 while (dbus_message_iter_get_arg_type(&value_iter) ==
58 DBUS_TYPE_DICT_ENTRY) {
60 DBusMessageIter dict_entry;
61 DBusMessageIter iter_dict_val;
63 dbus_message_iter_recurse(&value_iter, &dict_entry);
65 dbus_message_iter_get_basic(&dict_entry, &key);
67 dbus_message_iter_next(&value_iter);
71 if (!dbus_message_iter_next(&dict_entry)) {
72 dbus_message_iter_next(&value_iter);
75 dbus_message_iter_recurse(&dict_entry, &iter_dict_val);
76 if (strcasecmp(key, "Class") == 0) {
77 dbus_message_iter_get_basic(&iter_dict_val, &dev_info->class);
78 } else if (strcasecmp(key, "name") == 0) {
79 dbus_message_iter_get_basic(&iter_dict_val, &value);
80 if (dev_info->name == NULL)
81 dev_info->name = g_strdup(value);
82 } else if (strcasecmp(key, "Connected") == 0) {
83 dbus_message_iter_get_basic(&iter_dict_val,
84 &dev_info->connected);
85 } else if (strcasecmp(key, "paired") == 0) {
86 dbus_message_iter_get_basic(&iter_dict_val,
88 } else if (strcasecmp(key, "Trusted") == 0) {
89 dbus_message_iter_get_basic(&iter_dict_val,
91 } else if (strcasecmp(key, "RSSI") == 0) {
92 dbus_message_iter_get_basic(&iter_dict_val,
94 } else if (strcasecmp(key, "UUIDs") == 0) {
95 DBusMessageIter uuid_iter;
96 DBusMessageIter tmp_iter;
99 dbus_message_iter_recurse(&iter_dict_val, &uuid_iter);
101 tmp_iter = uuid_iter;
103 /* Store the uuid count */
104 while (dbus_message_iter_get_arg_type(&tmp_iter) != DBUS_TYPE_INVALID) {
105 dbus_message_iter_get_basic(&tmp_iter,
108 dev_info->uuid_count++;
109 if (!dbus_message_iter_next(&tmp_iter))
113 /* Store the uuids */
114 if (dev_info->uuid_count > 0) {
115 dev_info->uuids = g_new0(char *,
116 dev_info->uuid_count + 1);
121 while (dbus_message_iter_get_arg_type(&uuid_iter) != DBUS_TYPE_INVALID) {
122 dbus_message_iter_get_basic(&uuid_iter,
124 dev_info->uuids[i] = g_strdup(value);
126 if (!dbus_message_iter_next(&uuid_iter)) {
133 dbus_message_iter_next(&value_iter);
139 char *__bt_get_headset_name(char *address)
141 bluetooth_device_address_t device_address = { {0} };
142 bluetooth_device_info_t dev_info;
144 retv_if(address == NULL, strdup(""));
146 _bt_convert_addr_string_to_type(device_address.addr, address);
148 memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
150 _bt_get_bonded_device_info(&device_address, &dev_info);
152 return g_strdup(dev_info.device_name.name);
155 static int __bt_get_owner_info(DBusMessage *msg, char **name,
156 char **previous, char **current)
158 DBusMessageIter item_iter;
160 dbus_message_iter_init(msg, &item_iter);
162 if (dbus_message_iter_get_arg_type(&item_iter)
163 != DBUS_TYPE_STRING) {
164 BT_ERR("This is bad format dbus\n");
165 return BLUETOOTH_ERROR_INTERNAL;
168 dbus_message_iter_get_basic(&item_iter, name);
170 retv_if(*name == NULL, BLUETOOTH_ERROR_INTERNAL);
172 dbus_message_iter_next(&item_iter);
174 if (dbus_message_iter_get_arg_type(&item_iter)
175 != DBUS_TYPE_STRING) {
176 BT_ERR("This is bad format dbus\n");
177 return BLUETOOTH_ERROR_INTERNAL;
180 dbus_message_iter_get_basic(&item_iter, previous);
182 retv_if(*previous == NULL, BLUETOOTH_ERROR_INTERNAL);
184 dbus_message_iter_next(&item_iter);
186 if (dbus_message_iter_get_arg_type(&item_iter)
187 != DBUS_TYPE_STRING) {
188 BT_ERR("This is bad format dbus\n");
189 return BLUETOOTH_ERROR_INTERNAL;
192 dbus_message_iter_get_basic(&item_iter, current);
194 retv_if(*current == NULL, BLUETOOTH_ERROR_INTERNAL);
196 return BLUETOOTH_ERROR_NONE;
199 static int __bt_get_agent_signal_info(DBusMessage *msg, char **address,
200 char **name, char **uuid)
202 DBusMessageIter item_iter;
204 dbus_message_iter_init(msg, &item_iter);
206 if (dbus_message_iter_get_arg_type(&item_iter)
207 != DBUS_TYPE_STRING) {
208 BT_ERR("This is bad format dbus\n");
209 return BLUETOOTH_ERROR_INTERNAL;
212 dbus_message_iter_get_basic(&item_iter, address);
214 dbus_message_iter_next(&item_iter);
216 if (dbus_message_iter_get_arg_type(&item_iter)
217 != DBUS_TYPE_STRING) {
218 BT_ERR("This is bad format dbus\n");
219 return BLUETOOTH_ERROR_INTERNAL;
222 dbus_message_iter_get_basic(&item_iter, name);
224 dbus_message_iter_next(&item_iter);
226 if (dbus_message_iter_get_arg_type(&item_iter)
227 != DBUS_TYPE_STRING) {
228 BT_ERR("This is bad format dbus\n");
229 return BLUETOOTH_ERROR_INTERNAL;
232 dbus_message_iter_get_basic(&item_iter, uuid);
234 return BLUETOOTH_ERROR_NONE;
237 gboolean _bt_discovery_finished_cb(gpointer user_data)
239 int result = BLUETOOTH_ERROR_NONE;
242 if (_bt_get_discoverying_property() == FALSE) {
243 if (_bt_get_cancel_by_user() == TRUE) {
244 result = BLUETOOTH_ERROR_CANCEL_BY_USER;
247 _bt_set_cancel_by_user(FALSE);
248 _bt_set_discovery_status(FALSE);
249 _bt_send_event(BT_ADAPTER_EVENT,
250 BLUETOOTH_EVENT_DISCOVERY_FINISHED,
251 DBUS_TYPE_INT32, &result,
258 void _bt_handle_adapter_event(DBusMessage *msg)
261 int result = BLUETOOTH_ERROR_NONE;
262 DBusGProxy *adapter_proxy;
263 DBusMessageIter item_iter;
264 DBusMessageIter value_iter;
265 GValue timeout = { 0 };
266 const char *member = dbus_message_get_member(msg);
267 const char *property = NULL;
269 ret_if(member == NULL);
271 if (strcasecmp(member, "PropertyChanged") == 0) {
272 dbus_message_iter_init(msg, &item_iter);
274 if (dbus_message_iter_get_arg_type(&item_iter)
275 != DBUS_TYPE_STRING) {
276 BT_ERR("This is bad format dbus\n");
280 dbus_message_iter_get_basic(&item_iter, &property);
281 BT_DBG("member = PropertyChanged[%s]", property);
283 ret_if(property == NULL);
285 if (strcasecmp(property, "Discovering") == 0) {
286 gboolean discovering = FALSE;
287 dbus_message_iter_next(&item_iter);
288 dbus_message_iter_recurse(&item_iter, &value_iter);
289 dbus_message_iter_get_basic(&value_iter, &discovering);
291 /* Send event to application */
292 if (discovering == TRUE) {
293 _bt_set_discovery_status(TRUE);
294 _bt_send_event(BT_ADAPTER_EVENT,
295 BLUETOOTH_EVENT_DISCOVERY_STARTED,
296 DBUS_TYPE_INT32, &result,
299 ret_if(event_id > 0);
301 adapter_proxy = _bt_get_adapter_proxy();
302 ret_if(adapter_proxy == NULL);
304 /* Need to stop searching */
305 dbus_g_proxy_call(adapter_proxy,
311 event_id = g_timeout_add(BT_DISCOVERY_FINISHED_DELAY,
312 (GSourceFunc)_bt_discovery_finished_cb, NULL);
314 } else if (strcasecmp(property, "Name") == 0) {
316 dbus_message_iter_next(&item_iter);
317 dbus_message_iter_recurse(&item_iter, &value_iter);
318 dbus_message_iter_get_basic(&value_iter, &name);
320 /* Send event to application */
321 _bt_send_event(BT_ADAPTER_EVENT,
322 BLUETOOTH_EVENT_LOCAL_NAME_CHANGED,
323 DBUS_TYPE_INT32, &result,
324 DBUS_TYPE_STRING, &name,
326 } else if (strcasecmp(property, "Discoverable") == 0) {
327 gboolean discoverable = FALSE;
328 dbus_message_iter_next(&item_iter);
329 dbus_message_iter_recurse(&item_iter, &value_iter);
330 dbus_message_iter_get_basic(&value_iter, &discoverable);
332 if (discoverable == FALSE) {
333 if (_bt_get_discoverable_timeout_property() > 0) {
334 g_value_init(&timeout, G_TYPE_UINT);
335 g_value_set_uint(&timeout, 0);
337 adapter_proxy = _bt_get_adapter_proxy();
338 ret_if(adapter_proxy == NULL);
340 dbus_g_proxy_call_no_reply(adapter_proxy, "SetProperty",
341 G_TYPE_STRING, "DiscoverableTimeout",
342 G_TYPE_VALUE, &timeout,
345 g_value_unset(&timeout);
348 mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
350 /* Send event to application */
351 _bt_send_event(BT_ADAPTER_EVENT,
352 BLUETOOTH_EVENT_DISCOVERABLE_MODE_CHANGED,
353 DBUS_TYPE_INT32, &result,
354 DBUS_TYPE_INT16, &mode,
357 _bt_get_discoverable_mode(&mode);
359 /* Event will be sent by "DiscoverableTimeout" signal */
360 ret_if(mode != BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE);
362 /* Send event to application */
363 _bt_send_event(BT_ADAPTER_EVENT,
364 BLUETOOTH_EVENT_DISCOVERABLE_MODE_CHANGED,
365 DBUS_TYPE_INT32, &result,
366 DBUS_TYPE_INT16, &mode,
369 } else if (strcasecmp(property, "DiscoverableTimeout") == 0) {
370 _bt_get_discoverable_mode(&mode);
372 /* Event was already sent by "Discoverable" signal */
373 ret_if(mode == BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE);
375 /* Send event to application */
376 _bt_send_event(BT_ADAPTER_EVENT,
377 BLUETOOTH_EVENT_DISCOVERABLE_MODE_CHANGED,
378 DBUS_TYPE_INT32, &result,
379 DBUS_TYPE_INT16, &mode,
381 } else if (strcasecmp(property, "Powered") == 0) {
382 gboolean powered = FALSE;
383 dbus_message_iter_next(&item_iter);
384 dbus_message_iter_recurse(&item_iter, &value_iter);
385 dbus_message_iter_get_basic(&value_iter, &powered);
386 BT_DBG("Powered = %d", powered);
387 if (powered == FALSE)
388 _bt_disable_adapter();
390 } else if (strcasecmp(member, "DeviceFound") == 0) {
392 bt_remote_dev_info_t *dev_info;
394 ret_if(_bt_is_discovering() == FALSE);
396 dev_info = g_malloc0(sizeof(bt_remote_dev_info_t));
398 dbus_message_iter_init(msg, &item_iter);
399 dbus_message_iter_get_basic(&item_iter, &bdaddr);
400 dbus_message_iter_next(&item_iter);
402 dev_info->address = g_strdup(bdaddr);
404 if (__bt_parse_device_properties(&item_iter, dev_info) == FALSE) {
405 BT_ERR("Fail to parse the properies");
406 _bt_free_device_info(dev_info);
410 if (dev_info->name == NULL)
411 dev_info->name = g_strdup("");
413 _bt_send_event(BT_ADAPTER_EVENT,
414 BLUETOOTH_EVENT_REMOTE_DEVICE_FOUND,
415 DBUS_TYPE_INT32, &result,
416 DBUS_TYPE_STRING, &dev_info->address,
417 DBUS_TYPE_UINT32, &dev_info->class,
418 DBUS_TYPE_INT16, &dev_info->rssi,
419 DBUS_TYPE_STRING, &dev_info->name,
420 DBUS_TYPE_BOOLEAN, &dev_info->paired,
421 DBUS_TYPE_BOOLEAN, &dev_info->connected,
422 DBUS_TYPE_BOOLEAN, &dev_info->trust,
423 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
424 &dev_info->uuids, dev_info->uuid_count,
427 _bt_free_device_info(dev_info);
428 } else if (strcasecmp(member, "DeviceCreated") == 0) {
429 const char *object_path = NULL;
431 bt_remote_dev_info_t *remote_dev_info;
433 ret_if(_bt_is_device_creating() == FALSE);
435 /* Bonding from remote device */
436 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
438 dbus_message_iter_init(msg, &item_iter);
439 dbus_message_iter_get_basic(&item_iter, &object_path);
440 dbus_message_iter_next(&item_iter);
442 _bt_convert_device_path_to_address(object_path, address);
444 remote_dev_info = _bt_get_remote_device_info(address);
445 if (remote_dev_info == NULL) {
450 _bt_free_device_info(remote_dev_info);
452 } else if (strcasecmp(member, "DeviceRemoved") == 0) {
453 const char *object_path = NULL;
456 /* Bonding from remote device */
457 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
459 dbus_message_iter_init(msg, &item_iter);
460 dbus_message_iter_get_basic(&item_iter, &object_path);
461 dbus_message_iter_next(&item_iter);
463 _bt_convert_device_path_to_address(object_path, address);
465 _bt_send_event(BT_ADAPTER_EVENT,
466 BLUETOOTH_EVENT_BONDED_DEVICE_REMOVED,
467 DBUS_TYPE_INT32, &result,
468 DBUS_TYPE_STRING, &address,
475 void _bt_handle_input_event(DBusMessage *msg)
477 int result = BLUETOOTH_ERROR_NONE;
478 DBusMessageIter item_iter;
479 DBusMessageIter value_iter;
480 gboolean property_flag = FALSE;
481 const char *member = dbus_message_get_member(msg);
482 const char *path = dbus_message_get_path(msg);
483 const char *property = NULL;
485 ret_if(member == NULL);
487 dbus_message_iter_init(msg, &item_iter);
489 if (dbus_message_iter_get_arg_type(&item_iter)
490 != DBUS_TYPE_STRING) {
491 BT_ERR("This is bad format dbus\n");
495 dbus_message_iter_get_basic(&item_iter, &property);
497 ret_if(property == NULL);
499 if (strcasecmp(property, "Connected") == 0) {
500 int event = BLUETOOTH_EVENT_NONE;
503 dbus_message_iter_next(&item_iter);
504 dbus_message_iter_recurse(&item_iter, &value_iter);
505 dbus_message_iter_get_basic(&value_iter, &property_flag);
507 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
509 _bt_convert_device_path_to_address(path, address);
511 event = (property_flag == TRUE) ?
512 BLUETOOTH_HID_CONNECTED :
513 BLUETOOTH_HID_DISCONNECTED;
515 _bt_send_event(BT_HID_EVENT, event,
516 DBUS_TYPE_INT32, &result,
517 DBUS_TYPE_STRING, &address,
524 void _bt_handle_network_server_event(DBusMessage *msg)
526 int result = BLUETOOTH_ERROR_NONE;
527 char *address = NULL;
529 const char *member = dbus_message_get_member(msg);
531 ret_if(member == NULL);
533 if (strcasecmp(member, "PeerConnected") == 0) {
534 if (!dbus_message_get_args(msg, NULL,
535 DBUS_TYPE_STRING, &device,
536 DBUS_TYPE_STRING, &address,
537 DBUS_TYPE_INVALID)) {
538 BT_ERR("Unexpected parameters in signal");
542 _bt_send_event(BT_NETWORK_EVENT, BLUETOOTH_EVENT_NETWORK_SERVER_CONNECTED,
543 DBUS_TYPE_INT32, &result,
544 DBUS_TYPE_STRING, &device,
545 DBUS_TYPE_STRING, &address,
547 } else if (strcasecmp(member, "PeerDisconnected") == 0) {
548 if (!dbus_message_get_args(msg, NULL,
549 DBUS_TYPE_STRING, &device,
550 DBUS_TYPE_STRING, &address,
551 DBUS_TYPE_INVALID)) {
552 BT_ERR("Unexpected parameters in signal");
556 _bt_send_event(BT_NETWORK_EVENT, BLUETOOTH_EVENT_NETWORK_SERVER_DISCONNECTED,
557 DBUS_TYPE_INT32, &result,
558 DBUS_TYPE_STRING, &device,
559 DBUS_TYPE_STRING, &address,
564 void _bt_handle_network_client_event(DBusMessage *msg)
566 int result = BLUETOOTH_ERROR_NONE;
567 DBusMessageIter item_iter;
568 DBusMessageIter value_iter;
569 gboolean property_flag = FALSE;
570 const char *member = dbus_message_get_member(msg);
571 const char *path = dbus_message_get_path(msg);
572 const char *property = NULL;
574 ret_if(member == NULL);
576 dbus_message_iter_init(msg, &item_iter);
578 if (dbus_message_iter_get_arg_type(&item_iter)
579 != DBUS_TYPE_STRING) {
580 BT_ERR("This is bad format dbus\n");
584 dbus_message_iter_get_basic(&item_iter, &property);
586 ret_if(property == NULL);
588 if (strcasecmp(property, "Connected") == 0) {
589 int event = BLUETOOTH_EVENT_NONE;
592 dbus_message_iter_next(&item_iter);
593 dbus_message_iter_recurse(&item_iter, &value_iter);
594 dbus_message_iter_get_basic(&value_iter, &property_flag);
596 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
598 _bt_convert_device_path_to_address(path, address);
600 if (property_flag == TRUE) {
601 event = BLUETOOTH_EVENT_NETWORK_CONNECTED;
603 event = BLUETOOTH_EVENT_NETWORK_DISCONNECTED;
606 _bt_send_event(BT_NETWORK_EVENT, event,
607 DBUS_TYPE_INT32, &result,
608 DBUS_TYPE_STRING, &address,
615 void _bt_handle_device_event(DBusMessage *msg)
618 int result = BLUETOOTH_ERROR_NONE;
619 DBusMessageIter item_iter;
620 DBusMessageIter value_iter;
622 const char *member = dbus_message_get_member(msg);
623 const char *path = dbus_message_get_path(msg);
624 const char *property = NULL;
626 ret_if(path == NULL);
627 ret_if(member == NULL);
629 if (strcasecmp(member, "PropertyChanged") == 0) {
630 dbus_message_iter_init(msg, &item_iter);
632 if (dbus_message_iter_get_arg_type(&item_iter)
633 != DBUS_TYPE_STRING) {
634 BT_ERR("This is bad format dbus\n");
638 dbus_message_iter_get_basic(&item_iter, &property);
640 ret_if(property == NULL);
642 if (strcasecmp(property, "Connected") == 0) {
643 gboolean connected = FALSE;
644 dbus_message_iter_next(&item_iter);
645 dbus_message_iter_recurse(&item_iter, &value_iter);
646 dbus_message_iter_get_basic(&value_iter, &connected);
648 event = connected ? BLUETOOTH_EVENT_DEVICE_CONNECTED :
649 BLUETOOTH_EVENT_DEVICE_DISCONNECTED;
651 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
653 _bt_convert_device_path_to_address(path, address);
655 BT_DBG("connected: %d", connected);
656 BT_DBG("address: %s", address);
658 /* Send event to application */
659 _bt_send_event(BT_DEVICE_EVENT,
661 DBUS_TYPE_INT32, &result,
662 DBUS_TYPE_STRING, &address,
666 } else if (strcasecmp(property, "Paired") == 0) {
667 gboolean paired = FALSE;
668 bt_remote_dev_info_t *remote_dev_info;
669 dbus_message_iter_next(&item_iter);
670 dbus_message_iter_recurse(&item_iter, &value_iter);
671 dbus_message_iter_get_basic(&value_iter, &paired);
673 ret_if(paired == FALSE);
675 /* BlueZ sends paired signal for each paired device */
676 /* during activation, We should ignore this, otherwise*/
677 /* application thinks that a new device got paired */
678 if (_bt_adapter_get_status() != BT_ACTIVATED) {
679 BT_DBG("BT is not activated, so ignore this");
683 if (_bt_is_device_creating() == TRUE) {
684 BT_DBG("Try to Pair by me");
688 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
690 _bt_convert_device_path_to_address(path, address);
692 remote_dev_info = _bt_get_remote_device_info(address);
693 if (remote_dev_info == NULL) {
698 _bt_send_event(BT_ADAPTER_EVENT,
699 BLUETOOTH_EVENT_BONDING_FINISHED,
700 DBUS_TYPE_INT32, &result,
701 DBUS_TYPE_STRING, &address,
702 DBUS_TYPE_UINT32, &remote_dev_info->class,
703 DBUS_TYPE_INT16, &remote_dev_info->rssi,
704 DBUS_TYPE_STRING, &remote_dev_info->name,
705 DBUS_TYPE_BOOLEAN, &remote_dev_info->paired,
706 DBUS_TYPE_BOOLEAN, &remote_dev_info->connected,
707 DBUS_TYPE_BOOLEAN, &remote_dev_info->trust,
708 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
709 &remote_dev_info->uuids, remote_dev_info->uuid_count,
712 _bt_free_device_info(remote_dev_info);
718 void __bt_set_audio_values(gboolean connected, char *address)
721 int bt_device_state = VCONFKEY_BT_DEVICE_NONE;
723 /* Set the headset name */
724 if (connected == TRUE) {
725 name = __bt_get_headset_name(address);
730 if (vconf_set_str(VCONFKEY_BT_HEADSET_NAME,
732 BT_ERR("vconf_set_str failed");
737 /* Set the headset state */
738 if (vconf_get_int(VCONFKEY_BT_DEVICE,
739 &bt_device_state) != 0) {
740 BT_ERR("vconf_get_str failed");
743 if (connected == TRUE) {
744 bt_device_state |= VCONFKEY_BT_DEVICE_HEADSET_CONNECTED;
745 } else if (bt_device_state & VCONFKEY_BT_DEVICE_HEADSET_CONNECTED) {
746 bt_device_state ^= VCONFKEY_BT_DEVICE_HEADSET_CONNECTED;
749 if (vconf_set_int(VCONFKEY_BT_DEVICE,
750 bt_device_state) != 0) {
751 BT_ERR("vconf_set_int failed");
755 void _bt_handle_headset_event(DBusMessage *msg)
757 int result = BLUETOOTH_ERROR_NONE;
758 DBusMessageIter item_iter;
759 DBusMessageIter value_iter;
760 gboolean property_flag = FALSE;
761 const char *member = dbus_message_get_member(msg);
762 const char *path = dbus_message_get_path(msg);
763 const char *property = NULL;
765 ret_if(member == NULL);
767 dbus_message_iter_init(msg, &item_iter);
769 if (dbus_message_iter_get_arg_type(&item_iter)
770 != DBUS_TYPE_STRING) {
771 BT_ERR("This is bad format dbus\n");
775 dbus_message_iter_get_basic(&item_iter, &property);
777 ret_if(property == NULL);
779 BT_DBG("Property = %s \n", property);
781 /* We allow only 1 headset connection (HSP or HFP)*/
782 if (strcasecmp(property, "Connected") == 0) {
783 int event = BLUETOOTH_EVENT_NONE;
784 bt_headset_wait_t *wait_list;
787 dbus_message_iter_next(&item_iter);
788 dbus_message_iter_recurse(&item_iter, &value_iter);
789 dbus_message_iter_get_basic(&value_iter, &property_flag);
791 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
793 _bt_convert_device_path_to_address(path, address);
795 if (property_flag == TRUE) {
796 event = BLUETOOTH_EVENT_AG_CONNECTED;
798 event = BLUETOOTH_EVENT_AG_DISCONNECTED;
801 __bt_set_audio_values(property_flag, address);
803 _bt_send_event(BT_HEADSET_EVENT, event,
804 DBUS_TYPE_INT32, &result,
805 DBUS_TYPE_STRING, &address,
808 if (event == BLUETOOTH_EVENT_AG_DISCONNECTED) {
809 /* Remove data from the connected list */
810 _bt_remove_headset_from_list(BT_AUDIO_HSP, address);
812 wait_list = _bt_get_audio_wait_data();
813 if (wait_list == NULL) {
818 bluetooth_device_address_t device_address;
820 _bt_set_audio_wait_data_flag(TRUE);
822 _bt_convert_addr_string_to_type(device_address.addr,
824 _bt_audio_connect(wait_list->req_id, wait_list->type,
825 &device_address, wait_list->out_param1);
826 } else if (event == BLUETOOTH_EVENT_AG_CONNECTED) {
827 /* Add data to the connected list */
828 _bt_add_headset_to_list(BT_AUDIO_HSP,
829 BT_STATE_CONNECTED, address);
832 } else if (strcasecmp(property, "State") == 0) {
833 int event = BLUETOOTH_EVENT_NONE;
834 int sco_connected = FALSE;
838 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
840 _bt_convert_device_path_to_address(path, address);
842 dbus_message_iter_next(&item_iter);
843 dbus_message_iter_recurse(&item_iter, &value_iter);
844 dbus_message_iter_get_basic(&value_iter, &state);
846 /* This code assumes we support only 1 headset connection */
847 /* Need to use the headset list, if we support multi-headsets */
848 if (strcasecmp(state, "Playing") == 0) {
849 event = BLUETOOTH_EVENT_AG_AUDIO_CONNECTED;
850 sco_connected = TRUE;
851 } else if (strcasecmp(state, "connected") == 0 ||
852 strcasecmp(state, "disconnected") == 0) {
853 event = BLUETOOTH_EVENT_AG_AUDIO_DISCONNECTED;
854 sco_connected = FALSE;
856 BT_ERR("Not handled state - %s", state);
861 if (vconf_set_bool(VCONFKEY_BT_HEADSET_SCO, sco_connected) < 0)
862 BT_ERR("vconf_set_bool - Failed\n");
864 _bt_send_event(BT_HEADSET_EVENT, event,
865 DBUS_TYPE_INT32, &result,
866 DBUS_TYPE_STRING, &address,
870 } else if (strcasecmp(property, "SpeakerGain") == 0) {
874 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
876 _bt_convert_device_path_to_address(path, address);
878 dbus_message_iter_next(&item_iter);
879 dbus_message_iter_recurse(&item_iter, &value_iter);
880 dbus_message_iter_get_basic(&value_iter, &spkr_gain);
882 _bt_send_event(BT_HEADSET_EVENT, BLUETOOTH_EVENT_AG_SPEAKER_GAIN,
883 DBUS_TYPE_INT32, &result,
884 DBUS_TYPE_STRING, &address,
885 DBUS_TYPE_UINT16, &spkr_gain,
889 } else if (strcasecmp(property, "MicrophoneGain") == 0) {
893 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
895 _bt_convert_device_path_to_address(path, address);
897 dbus_message_iter_next(&item_iter);
898 dbus_message_iter_recurse(&item_iter, &value_iter);
899 dbus_message_iter_get_basic(&value_iter, &mic_gain);
901 _bt_send_event(BT_HEADSET_EVENT, BLUETOOTH_EVENT_AG_MIC_GAIN,
902 DBUS_TYPE_INT32, &result,
903 DBUS_TYPE_STRING, &address,
904 DBUS_TYPE_UINT16, &mic_gain,
911 void _bt_handle_sink_event(DBusMessage *msg)
913 int result = BLUETOOTH_ERROR_NONE;
914 DBusMessageIter item_iter;
915 DBusMessageIter value_iter;
916 gboolean property_flag = FALSE;
917 const char *member = dbus_message_get_member(msg);
918 const char *path = dbus_message_get_path(msg);
919 const char *property = NULL;
921 bt_headset_wait_t *wait_list;
923 ret_if(member == NULL);
925 dbus_message_iter_init(msg, &item_iter);
927 if (dbus_message_iter_get_arg_type(&item_iter)
928 != DBUS_TYPE_STRING) {
929 BT_ERR("This is bad format dbus\n");
933 dbus_message_iter_get_basic(&item_iter, &property);
935 ret_if(property == NULL);
937 if (strcasecmp(property, "Connected") == 0) {
938 int event = BLUETOOTH_EVENT_NONE;
941 dbus_message_iter_next(&item_iter);
942 dbus_message_iter_recurse(&item_iter, &value_iter);
943 dbus_message_iter_get_basic(&value_iter, &property_flag);
945 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
947 _bt_convert_device_path_to_address(path, address);
949 event = (property_flag == TRUE) ?
950 BLUETOOTH_EVENT_AV_CONNECTED :
951 BLUETOOTH_EVENT_AV_DISCONNECTED;
953 _bt_send_event(BT_HEADSET_EVENT, event,
954 DBUS_TYPE_INT32, &result,
955 DBUS_TYPE_STRING, &address,
958 _bt_send_event(BT_AVRCP_EVENT, event,
959 DBUS_TYPE_INT32, &result,
960 DBUS_TYPE_STRING, &address,
963 if (event == BLUETOOTH_EVENT_AV_DISCONNECTED) {
964 /* Remove data from the connected list */
965 _bt_remove_headset_from_list(BT_AUDIO_A2DP, address);
966 wait_list = _bt_get_audio_wait_data();
967 if (wait_list == NULL) {
972 if (((wait_list->type == BT_AUDIO_ALL) &&
973 (wait_list->ag_flag == TRUE)) ||
974 (wait_list->type == BT_AUDIO_A2DP) ||
975 (wait_list->disconnection_type == BT_AUDIO_A2DP)) {
976 bluetooth_device_address_t device_address;
977 _bt_convert_addr_string_to_type(
981 _bt_audio_connect(wait_list->req_id,
984 wait_list->out_param1);
986 } else if (event == BLUETOOTH_EVENT_AV_CONNECTED){
987 /* Check for existing Media device to disconnect */
988 char connected_address[BT_ADDRESS_STRING_SIZE + 1];
989 bluetooth_device_address_t device_address;
992 connected = _bt_is_headset_type_connected(BT_AUDIO_A2DP,
995 /* Match connected device address */
996 if (g_strcmp0(connected_address, address) != 0) {
997 /* Convert BD adress from string type */
998 _bt_convert_addr_string_to_type(
1001 _bt_audio_disconnect(0, BT_AUDIO_A2DP,
1002 &device_address, NULL);
1006 /* Add data to the connected list */
1007 _bt_add_headset_to_list(BT_AUDIO_A2DP,
1008 BT_STATE_CONNECTED, address);
1014 void _bt_handle_agent_event(DBusMessage *msg)
1016 const char *member = dbus_message_get_member(msg);
1017 int result = BLUETOOTH_ERROR_NONE;
1018 char *address = NULL;
1022 ret_if(member == NULL);
1024 if (strcasecmp(member, "ObexAuthorize") == 0) {
1025 __bt_get_agent_signal_info(msg, &address, &name, &uuid);
1027 _bt_send_event(BT_OPP_SERVER_EVENT,
1028 BLUETOOTH_EVENT_OBEX_SERVER_CONNECTION_AUTHORIZE,
1029 DBUS_TYPE_INT32, &result,
1030 DBUS_TYPE_STRING, &address,
1031 DBUS_TYPE_STRING, &name,
1033 } else if (strcasecmp(member, "RfcommAuthorize") == 0) {
1034 bt_rfcomm_server_info_t *server_info;
1036 __bt_get_agent_signal_info(msg, &address, &name, &uuid);
1038 server_info = _bt_rfcomm_get_server_info_using_uuid(uuid);
1039 ret_if(server_info == NULL);
1040 ret_if(server_info->server_type != BT_CUSTOM_SERVER);
1042 _bt_send_event(BT_RFCOMM_SERVER_EVENT,
1043 BLUETOOTH_EVENT_RFCOMM_AUTHORIZE,
1044 DBUS_TYPE_INT32, &result,
1045 DBUS_TYPE_STRING, &address,
1046 DBUS_TYPE_STRING, &uuid,
1047 DBUS_TYPE_STRING, &name,
1048 DBUS_TYPE_INT16, &server_info->control_fd,
1053 static DBusHandlerResult __bt_manager_event_filter(DBusConnection *conn,
1054 DBusMessage *msg, void *data)
1056 const char *member = dbus_message_get_member(msg);
1058 if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_SIGNAL)
1059 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1061 retv_if(member == NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
1063 if (strcasecmp(member, "AdapterAdded") == 0) {
1064 BT_DBG("AdapterAdded");
1065 _bt_handle_adapter_added();
1066 } else if (strcasecmp(member, "AdapterRemoved") == 0) {
1067 BT_DBG("AdapterRemoved");
1068 } else if (strcasecmp(member, "NameOwnerChanged") == 0) {
1071 char *previous = NULL;
1072 char *current = NULL;
1074 if (__bt_get_owner_info(msg, &name, &previous, ¤t)) {
1075 BT_ERR("Fail to get the owner info");
1076 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1079 if (*current != '\0')
1080 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1082 if (strcasecmp(name, "org.bluez") == 0) {
1083 BT_DBG("Bluetoothd is terminated");
1084 _bt_handle_adapter_removed();
1087 _bt_obex_server_check_allocation(&value);
1089 if (value == TRUE) {
1090 /* Check if the obex server was terminated abnormally */
1091 _bt_obex_server_check_termination(name);
1094 _bt_rfcomm_server_check_existence(&value);
1096 if (value == TRUE) {
1097 /* The obex server was terminated abnormally */
1098 _bt_rfcomm_server_check_termination(name);
1100 } else if (dbus_message_has_interface(msg, BT_ADAPTER_INTERFACE)) {
1101 _bt_handle_adapter_event(msg);
1102 } else if (dbus_message_has_interface(msg, BT_INPUT_INTERFACE)) {
1103 _bt_handle_input_event(msg);
1104 } else if (dbus_message_has_interface(msg, BT_NETWORK_SERVER_INTERFACE)) {
1105 _bt_handle_network_server_event(msg);
1106 } else if (dbus_message_has_interface(msg, BT_NETWORK_CLIENT_INTERFACE)) {
1107 _bt_handle_network_client_event(msg);
1108 } else if (dbus_message_has_interface(msg, BT_HEADSET_INTERFACE)) {
1109 _bt_handle_headset_event(msg);
1110 } else if (dbus_message_has_interface(msg, BT_SINK_INTERFACE)) {
1111 _bt_handle_sink_event(msg);
1112 } else if (dbus_message_has_interface(msg, BT_AGENT_INTERFACE)) {
1113 _bt_handle_agent_event(msg);
1114 } else if (dbus_message_has_interface(msg, BT_DEVICE_INTERFACE)) {
1115 _bt_handle_device_event(msg);
1118 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1121 static DBusHandlerResult __bt_obexd_event_filter(DBusConnection *conn,
1122 DBusMessage *msg, void *data)
1124 const char *path = dbus_message_get_path(msg);
1125 const char *member = dbus_message_get_member(msg);
1127 if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_SIGNAL)
1128 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1130 retv_if(member == NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
1132 if (strcasecmp(member, "TransferStarted") == 0) {
1133 char *transfer_path = NULL;
1135 if (!dbus_message_get_args(msg, NULL,
1136 DBUS_TYPE_OBJECT_PATH, &transfer_path,
1137 DBUS_TYPE_INVALID)) {
1138 BT_ERR("Unexpected parameters in signal");
1139 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1142 _bt_obex_transfer_started(transfer_path);
1143 } else if (strcasecmp(member, "Progress") == 0) {
1147 if (!dbus_message_get_args(msg, NULL,
1148 DBUS_TYPE_INT32, &total,
1149 DBUS_TYPE_INT32, &transfer,
1150 DBUS_TYPE_INVALID)) {
1151 BT_ERR("Unexpected parameters in signal");
1152 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1155 _bt_obex_transfer_progress(path, total, transfer);
1156 } else if (strcasecmp(member, "TransferCompleted") == 0) {
1157 char *transfer_path = NULL;
1160 if (!dbus_message_get_args(msg, NULL,
1161 DBUS_TYPE_OBJECT_PATH, &transfer_path,
1162 DBUS_TYPE_BOOLEAN, &success,
1163 DBUS_TYPE_INVALID)) {
1164 BT_ERR("Unexpected parameters in signal");
1165 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1168 _bt_obex_transfer_completed(transfer_path, success);
1171 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1174 int _bt_register_service_event(DBusGConnection *g_conn, int event_type)
1176 DBusError dbus_error;
1177 char *match1 = NULL;
1178 char *match2 = NULL;
1179 DBusConnection *conn;
1180 DBusHandleMessageFunction event_func = NULL;
1182 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1184 conn = dbus_g_connection_get_connection(g_conn);
1185 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1187 switch (event_type) {
1188 case BT_MANAGER_EVENT:
1189 event_func = __bt_manager_event_filter;
1190 match1 = g_strdup_printf(MANAGER_EVENT_MATCH_RULE,
1191 BT_MANAGER_INTERFACE,
1194 match2 = g_strdup_printf(MANAGER_EVENT_MATCH_RULE,
1195 BT_FREEDESKTOP_INTERFACE,
1196 BT_FREEDESKTOP_PATH);
1198 case BT_DEVICE_EVENT:
1199 match1 = g_strdup_printf(EVENT_MATCH_RULE,
1200 BT_DEVICE_INTERFACE);
1203 match1 = g_strdup_printf(EVENT_MATCH_RULE,
1204 BT_INPUT_INTERFACE);
1206 case BT_NETWORK_EVENT:
1207 match1 = g_strdup_printf(EVENT_MATCH_RULE,
1208 BT_NETWORK_SERVER_INTERFACE);
1210 match2 = g_strdup_printf(EVENT_MATCH_RULE,
1211 BT_NETWORK_CLIENT_INTERFACE);
1213 case BT_HEADSET_EVENT:
1214 match1 = g_strdup_printf(EVENT_MATCH_RULE,
1215 BT_HEADSET_INTERFACE);
1217 match2 = g_strdup_printf(EVENT_MATCH_RULE,
1220 case BT_OPP_SERVER_EVENT:
1221 event_func = __bt_obexd_event_filter;
1222 match1 = g_strdup_printf(MANAGER_EVENT_MATCH_RULE,
1223 BT_OBEXD_MANAGER_INTERFACE,
1226 match2 = g_strdup_printf(EVENT_MATCH_RULE,
1227 BT_OBEXD_TRANSFER_INTERFACE);
1230 BT_ERR("Unknown event");
1231 return BLUETOOTH_ERROR_INTERNAL;
1235 if (!dbus_connection_add_filter(conn, event_func,
1237 BT_ERR("Fail to add filter");
1242 dbus_error_init(&dbus_error);
1245 dbus_bus_add_match(conn, match1, &dbus_error);
1247 if (dbus_error_is_set(&dbus_error)) {
1248 BT_ERR("Fail to add match: %s\n", dbus_error.message);
1249 dbus_error_free(&dbus_error);
1254 dbus_bus_add_match(conn, match2, &dbus_error);
1256 if (dbus_error_is_set(&dbus_error)) {
1257 BT_ERR("Fail to add match: %s\n", dbus_error.message);
1258 dbus_error_free(&dbus_error);
1265 return BLUETOOTH_ERROR_NONE;
1269 return BLUETOOTH_ERROR_INTERNAL;
1272 void _bt_unregister_service_event(DBusGConnection *g_conn, int event_type)
1274 DBusConnection *conn;
1275 DBusHandleMessageFunction event_func;
1277 ret_if(g_conn == NULL);
1278 conn = dbus_g_connection_get_connection(g_conn);
1280 switch (event_type) {
1281 case BT_MANAGER_EVENT:
1282 event_func = __bt_manager_event_filter;
1284 case BT_OPP_SERVER_EVENT:
1285 event_func = __bt_obexd_event_filter;
1288 BT_ERR("Unknown event");
1292 ret_if(conn == NULL);
1294 dbus_connection_remove_filter(conn, event_func, NULL);
1297 static int __bt_init_manager_receiver(void)
1299 GError *error = NULL;
1301 if (manager_conn == NULL) {
1302 manager_conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
1303 if (error != NULL) {
1304 BT_ERR("ERROR: Can't get on system bus [%s]", error->message);
1305 g_error_free(error);
1307 retv_if(manager_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1310 if (_bt_register_service_event(manager_conn,
1311 BT_MANAGER_EVENT) != BLUETOOTH_ERROR_NONE)
1314 if (_bt_register_service_event(manager_conn,
1315 BT_DEVICE_EVENT) != BLUETOOTH_ERROR_NONE)
1318 if (_bt_register_service_event(manager_conn,
1319 BT_HID_EVENT) != BLUETOOTH_ERROR_NONE)
1322 if (_bt_register_service_event(manager_conn,
1323 BT_HEADSET_EVENT) != BLUETOOTH_ERROR_NONE)
1326 if (_bt_register_service_event(manager_conn,
1327 BT_NETWORK_EVENT) != BLUETOOTH_ERROR_NONE)
1330 return BLUETOOTH_ERROR_NONE;
1333 dbus_g_connection_unref(manager_conn);
1334 manager_conn = NULL;
1337 return BLUETOOTH_ERROR_INTERNAL;
1340 static int __bt_init_obexd_receiver(void)
1342 GError *error = NULL;
1344 if (obexd_conn == NULL) {
1345 obexd_conn = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
1346 if (error != NULL) {
1347 BT_ERR("ERROR: Can't get on session bus [%s]", error->message);
1348 g_error_free(error);
1350 retv_if(obexd_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1353 if (_bt_register_service_event(obexd_conn,
1354 BT_OPP_SERVER_EVENT) != BLUETOOTH_ERROR_NONE) {
1355 dbus_g_connection_unref(obexd_conn);
1357 return BLUETOOTH_ERROR_INTERNAL;
1360 return BLUETOOTH_ERROR_NONE;
1363 /* To receive the event from bluez */
1364 int _bt_init_service_event_receiver(void)
1368 result = __bt_init_manager_receiver();
1369 retv_if(result != BLUETOOTH_ERROR_NONE, result);
1371 result = __bt_init_obexd_receiver();
1372 if (result != BLUETOOTH_ERROR_NONE)
1373 BT_ERR("Fail to init obexd receiver");
1375 return BLUETOOTH_ERROR_NONE;
1378 void _bt_deinit_service_event_reciever(void)
1380 _bt_unregister_service_event(manager_conn, BT_MANAGER_EVENT);
1382 _bt_unregister_service_event(obexd_conn, BT_OPP_SERVER_EVENT);
1385 dbus_g_connection_unref(manager_conn);
1386 manager_conn = NULL;
1390 dbus_g_connection_unref(obexd_conn);
1395 g_source_remove(event_id);