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"
40 static DBusGConnection *manager_conn;
41 static DBusGConnection *obexd_conn;
43 static guint event_id;
45 static gboolean __bt_parse_device_properties(DBusMessageIter *item_iter,
46 bt_remote_dev_info_t *dev_info)
48 DBusMessageIter value_iter;
51 if (dbus_message_iter_get_arg_type(item_iter) != DBUS_TYPE_ARRAY)
54 dbus_message_iter_recurse(item_iter, &value_iter);
56 while (dbus_message_iter_get_arg_type(&value_iter) ==
57 DBUS_TYPE_DICT_ENTRY) {
59 DBusMessageIter dict_entry;
60 DBusMessageIter iter_dict_val;
62 dbus_message_iter_recurse(&value_iter, &dict_entry);
64 dbus_message_iter_get_basic(&dict_entry, &key);
66 dbus_message_iter_next(&value_iter);
70 if (!dbus_message_iter_next(&dict_entry)) {
71 dbus_message_iter_next(&value_iter);
74 dbus_message_iter_recurse(&dict_entry, &iter_dict_val);
75 if (strcasecmp(key, "Class") == 0) {
76 dbus_message_iter_get_basic(&iter_dict_val, &dev_info->class);
77 } else if (strcasecmp(key, "name") == 0) {
78 dbus_message_iter_get_basic(&iter_dict_val, &value);
79 if (dev_info->name == NULL)
80 dev_info->name = g_strdup(value);
81 } else if (strcasecmp(key, "Connected") == 0) {
82 dbus_message_iter_get_basic(&iter_dict_val,
83 &dev_info->connected);
84 } else if (strcasecmp(key, "paired") == 0) {
85 dbus_message_iter_get_basic(&iter_dict_val,
87 } else if (strcasecmp(key, "Trusted") == 0) {
88 dbus_message_iter_get_basic(&iter_dict_val,
90 } else if (strcasecmp(key, "RSSI") == 0) {
91 dbus_message_iter_get_basic(&iter_dict_val,
93 } else if (strcasecmp(key, "UUIDs") == 0) {
94 DBusMessageIter uuid_iter;
95 DBusMessageIter tmp_iter;
98 dbus_message_iter_recurse(&iter_dict_val, &uuid_iter);
100 tmp_iter = uuid_iter;
102 /* Store the uuid count */
103 while (dbus_message_iter_get_arg_type(&tmp_iter) != DBUS_TYPE_INVALID) {
104 dbus_message_iter_get_basic(&tmp_iter,
107 dev_info->uuid_count++;
108 if (!dbus_message_iter_next(&tmp_iter))
112 /* Store the uuids */
113 if (dev_info->uuid_count > 0) {
114 dev_info->uuids = g_new0(char *,
115 dev_info->uuid_count + 1);
120 while (dbus_message_iter_get_arg_type(&uuid_iter) != DBUS_TYPE_INVALID) {
121 dbus_message_iter_get_basic(&uuid_iter,
123 dev_info->uuids[i] = g_strdup(value);
125 if (!dbus_message_iter_next(&uuid_iter)) {
132 dbus_message_iter_next(&value_iter);
138 char *__bt_get_headset_name(char *address)
140 bluetooth_device_address_t device_address = { {0} };
141 bluetooth_device_info_t dev_info;
143 retv_if(address == NULL, strdup(""));
145 _bt_convert_addr_string_to_type(device_address.addr, address);
147 memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
149 _bt_get_bonded_device_info(&device_address, &dev_info);
151 return g_strdup(dev_info.device_name.name);
154 static int __bt_get_owner_info(DBusMessage *msg, char **name,
155 char **previous, char **current)
157 DBusMessageIter item_iter;
159 dbus_message_iter_init(msg, &item_iter);
161 if (dbus_message_iter_get_arg_type(&item_iter)
162 != DBUS_TYPE_STRING) {
163 BT_ERR("This is bad format dbus\n");
164 return BLUETOOTH_ERROR_INTERNAL;
167 dbus_message_iter_get_basic(&item_iter, name);
169 retv_if(*name == NULL, BLUETOOTH_ERROR_INTERNAL);
171 dbus_message_iter_next(&item_iter);
173 if (dbus_message_iter_get_arg_type(&item_iter)
174 != DBUS_TYPE_STRING) {
175 BT_ERR("This is bad format dbus\n");
176 return BLUETOOTH_ERROR_INTERNAL;
179 dbus_message_iter_get_basic(&item_iter, previous);
181 retv_if(*previous == NULL, BLUETOOTH_ERROR_INTERNAL);
183 dbus_message_iter_next(&item_iter);
185 if (dbus_message_iter_get_arg_type(&item_iter)
186 != DBUS_TYPE_STRING) {
187 BT_ERR("This is bad format dbus\n");
188 return BLUETOOTH_ERROR_INTERNAL;
191 dbus_message_iter_get_basic(&item_iter, current);
193 retv_if(*current == NULL, BLUETOOTH_ERROR_INTERNAL);
195 return BLUETOOTH_ERROR_NONE;
198 static int __bt_get_agent_signal_info(DBusMessage *msg, char **address,
199 char **name, char **uuid)
201 DBusMessageIter item_iter;
203 dbus_message_iter_init(msg, &item_iter);
205 if (dbus_message_iter_get_arg_type(&item_iter)
206 != DBUS_TYPE_STRING) {
207 BT_ERR("This is bad format dbus\n");
208 return BLUETOOTH_ERROR_INTERNAL;
211 dbus_message_iter_get_basic(&item_iter, address);
213 dbus_message_iter_next(&item_iter);
215 if (dbus_message_iter_get_arg_type(&item_iter)
216 != DBUS_TYPE_STRING) {
217 BT_ERR("This is bad format dbus\n");
218 return BLUETOOTH_ERROR_INTERNAL;
221 dbus_message_iter_get_basic(&item_iter, name);
223 dbus_message_iter_next(&item_iter);
225 if (dbus_message_iter_get_arg_type(&item_iter)
226 != DBUS_TYPE_STRING) {
227 BT_ERR("This is bad format dbus\n");
228 return BLUETOOTH_ERROR_INTERNAL;
231 dbus_message_iter_get_basic(&item_iter, uuid);
233 return BLUETOOTH_ERROR_NONE;
236 gboolean _bt_discovery_finished_cb(gpointer user_data)
238 int result = BLUETOOTH_ERROR_NONE;
241 if (_bt_get_discoverying_property() == FALSE) {
242 if (_bt_get_cancel_by_user() == TRUE) {
243 result = BLUETOOTH_ERROR_CANCEL_BY_USER;
246 _bt_set_cancel_by_user(FALSE);
247 _bt_set_discovery_status(FALSE);
248 _bt_send_event(BT_ADAPTER_EVENT,
249 BLUETOOTH_EVENT_DISCOVERY_FINISHED,
250 DBUS_TYPE_INT32, &result,
257 void _bt_handle_adapter_event(DBusMessage *msg)
260 int result = BLUETOOTH_ERROR_NONE;
261 DBusGProxy *adapter_proxy;
262 DBusMessageIter item_iter;
263 DBusMessageIter value_iter;
264 GValue timeout = { 0 };
265 const char *member = dbus_message_get_member(msg);
266 const char *property = NULL;
268 ret_if(member == NULL);
270 if (strcasecmp(member, "PropertyChanged") == 0) {
271 dbus_message_iter_init(msg, &item_iter);
273 if (dbus_message_iter_get_arg_type(&item_iter)
274 != DBUS_TYPE_STRING) {
275 BT_ERR("This is bad format dbus\n");
279 dbus_message_iter_get_basic(&item_iter, &property);
281 ret_if(property == NULL);
283 if (strcasecmp(property, "Discovering") == 0) {
284 gboolean discovering = FALSE;
285 dbus_message_iter_next(&item_iter);
286 dbus_message_iter_recurse(&item_iter, &value_iter);
287 dbus_message_iter_get_basic(&value_iter, &discovering);
289 /* Send event to application */
290 if (discovering == TRUE) {
291 _bt_set_discovery_status(TRUE);
292 _bt_send_event(BT_ADAPTER_EVENT,
293 BLUETOOTH_EVENT_DISCOVERY_STARTED,
294 DBUS_TYPE_INT32, &result,
297 ret_if(event_id > 0);
299 adapter_proxy = _bt_get_adapter_proxy();
300 ret_if(adapter_proxy == NULL);
302 /* Need to stop searching */
303 dbus_g_proxy_call(adapter_proxy,
309 event_id = g_timeout_add(BT_DISCOVERY_FINISHED_DELAY,
310 (GSourceFunc)_bt_discovery_finished_cb, NULL);
312 } else if (strcasecmp(property, "Name") == 0) {
314 dbus_message_iter_next(&item_iter);
315 dbus_message_iter_recurse(&item_iter, &value_iter);
316 dbus_message_iter_get_basic(&value_iter, &name);
318 /* Send event to application */
319 _bt_send_event(BT_ADAPTER_EVENT,
320 BLUETOOTH_EVENT_LOCAL_NAME_CHANGED,
321 DBUS_TYPE_INT32, &result,
322 DBUS_TYPE_STRING, &name,
324 } else if (strcasecmp(property, "Discoverable") == 0) {
325 gboolean discoverable = FALSE;
326 dbus_message_iter_next(&item_iter);
327 dbus_message_iter_recurse(&item_iter, &value_iter);
328 dbus_message_iter_get_basic(&value_iter, &discoverable);
330 if (discoverable == FALSE) {
331 if (_bt_get_discoverable_timeout_property() > 0) {
332 g_value_init(&timeout, G_TYPE_UINT);
333 g_value_set_uint(&timeout, 0);
335 adapter_proxy = _bt_get_adapter_proxy();
336 ret_if(adapter_proxy == NULL);
338 dbus_g_proxy_call_no_reply(adapter_proxy, "SetProperty",
339 G_TYPE_STRING, "DiscoverableTimeout",
340 G_TYPE_VALUE, &timeout,
343 g_value_unset(&timeout);
346 mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
348 /* Send event to application */
349 _bt_send_event(BT_ADAPTER_EVENT,
350 BLUETOOTH_EVENT_DISCOVERABLE_MODE_CHANGED,
351 DBUS_TYPE_INT32, &result,
352 DBUS_TYPE_INT16, &mode,
355 _bt_get_discoverable_mode(&mode);
357 /* Event will be sent by "DiscoverableTimeout" signal */
358 ret_if(mode != BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE);
360 /* Send event to application */
361 _bt_send_event(BT_ADAPTER_EVENT,
362 BLUETOOTH_EVENT_DISCOVERABLE_MODE_CHANGED,
363 DBUS_TYPE_INT32, &result,
364 DBUS_TYPE_INT16, &mode,
367 } else if (strcasecmp(property, "DiscoverableTimeout") == 0) {
368 _bt_get_discoverable_mode(&mode);
370 /* Event was already sent by "Discoverable" signal */
371 ret_if(mode == BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE);
373 /* Send event to application */
374 _bt_send_event(BT_ADAPTER_EVENT,
375 BLUETOOTH_EVENT_DISCOVERABLE_MODE_CHANGED,
376 DBUS_TYPE_INT32, &result,
377 DBUS_TYPE_INT16, &mode,
380 } else if (strcasecmp(member, "DeviceFound") == 0) {
382 bt_remote_dev_info_t *dev_info;
384 ret_if(_bt_is_discovering() == FALSE);
386 dev_info = g_malloc0(sizeof(bt_remote_dev_info_t));
388 dbus_message_iter_init(msg, &item_iter);
389 dbus_message_iter_get_basic(&item_iter, &bdaddr);
390 dbus_message_iter_next(&item_iter);
392 dev_info->address = g_strdup(bdaddr);
394 if (__bt_parse_device_properties(&item_iter, dev_info) == FALSE) {
395 BT_ERR("Fail to parse the properies");
396 _bt_free_device_info(dev_info);
400 if (dev_info->name == NULL)
401 dev_info->name = g_strdup("");
403 _bt_send_event(BT_ADAPTER_EVENT,
404 BLUETOOTH_EVENT_REMOTE_DEVICE_FOUND,
405 DBUS_TYPE_INT32, &result,
406 DBUS_TYPE_STRING, &dev_info->address,
407 DBUS_TYPE_UINT32, &dev_info->class,
408 DBUS_TYPE_INT16, &dev_info->rssi,
409 DBUS_TYPE_STRING, &dev_info->name,
410 DBUS_TYPE_BOOLEAN, &dev_info->paired,
411 DBUS_TYPE_BOOLEAN, &dev_info->connected,
412 DBUS_TYPE_BOOLEAN, &dev_info->trust,
413 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
414 &dev_info->uuids, dev_info->uuid_count,
417 _bt_free_device_info(dev_info);
418 } else if (strcasecmp(member, "DeviceCreated") == 0) {
419 const char *object_path = NULL;
421 bt_remote_dev_info_t *remote_dev_info;
423 ret_if(_bt_is_device_creating() == FALSE);
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 remote_dev_info = _bt_get_remote_device_info(address);
435 if (remote_dev_info == NULL) {
440 _bt_free_device_info(remote_dev_info);
442 } else if (strcasecmp(member, "DeviceRemoved") == 0) {
443 const char *object_path = NULL;
446 /* Bonding from remote device */
447 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
449 dbus_message_iter_init(msg, &item_iter);
450 dbus_message_iter_get_basic(&item_iter, &object_path);
451 dbus_message_iter_next(&item_iter);
453 _bt_convert_device_path_to_address(object_path, address);
455 _bt_send_event(BT_ADAPTER_EVENT,
456 BLUETOOTH_EVENT_BONDED_DEVICE_REMOVED,
457 DBUS_TYPE_INT32, &result,
458 DBUS_TYPE_STRING, &address,
465 void _bt_handle_input_event(DBusMessage *msg)
467 int result = BLUETOOTH_ERROR_NONE;
468 DBusMessageIter item_iter;
469 DBusMessageIter value_iter;
470 gboolean property_flag = FALSE;
471 const char *member = dbus_message_get_member(msg);
472 const char *path = dbus_message_get_path(msg);
473 const char *property = NULL;
475 ret_if(member == NULL);
477 dbus_message_iter_init(msg, &item_iter);
479 if (dbus_message_iter_get_arg_type(&item_iter)
480 != DBUS_TYPE_STRING) {
481 BT_ERR("This is bad format dbus\n");
485 dbus_message_iter_get_basic(&item_iter, &property);
487 ret_if(property == NULL);
489 if (strcasecmp(property, "Connected") == 0) {
490 int event = BLUETOOTH_EVENT_NONE;
493 dbus_message_iter_next(&item_iter);
494 dbus_message_iter_recurse(&item_iter, &value_iter);
495 dbus_message_iter_get_basic(&value_iter, &property_flag);
497 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
499 _bt_convert_device_path_to_address(path, address);
501 event = (property_flag == TRUE) ?
502 BLUETOOTH_HID_CONNECTED :
503 BLUETOOTH_HID_DISCONNECTED;
505 _bt_send_event(BT_HID_EVENT, event,
506 DBUS_TYPE_INT32, &result,
507 DBUS_TYPE_STRING, &address,
514 void _bt_handle_network_server_event(DBusMessage *msg)
516 int result = BLUETOOTH_ERROR_NONE;
517 char *address = NULL;
519 const char *member = dbus_message_get_member(msg);
521 ret_if(member == NULL);
523 if (strcasecmp(member, "PeerConnected") == 0) {
524 if (!dbus_message_get_args(msg, NULL,
525 DBUS_TYPE_STRING, &device,
526 DBUS_TYPE_STRING, &address,
527 DBUS_TYPE_INVALID)) {
528 BT_ERR("Unexpected parameters in signal");
532 _bt_send_event(BT_NETWORK_EVENT, BLUETOOTH_EVENT_NETWORK_SERVER_CONNECTED,
533 DBUS_TYPE_INT32, &result,
534 DBUS_TYPE_STRING, &device,
535 DBUS_TYPE_STRING, &address,
537 } else if (strcasecmp(member, "PeerDisconnected") == 0) {
538 if (!dbus_message_get_args(msg, NULL,
539 DBUS_TYPE_STRING, &device,
540 DBUS_TYPE_STRING, &address,
541 DBUS_TYPE_INVALID)) {
542 BT_ERR("Unexpected parameters in signal");
546 _bt_send_event(BT_NETWORK_EVENT, BLUETOOTH_EVENT_NETWORK_SERVER_DISCONNECTED,
547 DBUS_TYPE_INT32, &result,
548 DBUS_TYPE_STRING, &device,
549 DBUS_TYPE_STRING, &address,
554 void _bt_handle_network_client_event(DBusMessage *msg)
556 int result = BLUETOOTH_ERROR_NONE;
557 DBusMessageIter item_iter;
558 DBusMessageIter value_iter;
559 gboolean property_flag = FALSE;
560 const char *member = dbus_message_get_member(msg);
561 const char *path = dbus_message_get_path(msg);
562 const char *property = NULL;
564 ret_if(member == NULL);
566 dbus_message_iter_init(msg, &item_iter);
568 if (dbus_message_iter_get_arg_type(&item_iter)
569 != DBUS_TYPE_STRING) {
570 BT_ERR("This is bad format dbus\n");
574 dbus_message_iter_get_basic(&item_iter, &property);
576 ret_if(property == NULL);
578 if (strcasecmp(property, "Connected") == 0) {
579 int event = BLUETOOTH_EVENT_NONE;
582 dbus_message_iter_next(&item_iter);
583 dbus_message_iter_recurse(&item_iter, &value_iter);
584 dbus_message_iter_get_basic(&value_iter, &property_flag);
586 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
588 _bt_convert_device_path_to_address(path, address);
590 if (property_flag == TRUE) {
591 event = BLUETOOTH_EVENT_NETWORK_CONNECTED;
593 event = BLUETOOTH_EVENT_NETWORK_DISCONNECTED;
596 _bt_send_event(BT_NETWORK_EVENT, event,
597 DBUS_TYPE_INT32, &result,
598 DBUS_TYPE_STRING, &address,
605 void _bt_handle_device_event(DBusMessage *msg)
608 int result = BLUETOOTH_ERROR_NONE;
609 DBusMessageIter item_iter;
610 DBusMessageIter value_iter;
612 const char *member = dbus_message_get_member(msg);
613 const char *path = dbus_message_get_path(msg);
614 const char *property = NULL;
616 ret_if(path == NULL);
617 ret_if(member == NULL);
619 if (strcasecmp(member, "PropertyChanged") == 0) {
620 dbus_message_iter_init(msg, &item_iter);
622 if (dbus_message_iter_get_arg_type(&item_iter)
623 != DBUS_TYPE_STRING) {
624 BT_ERR("This is bad format dbus\n");
628 dbus_message_iter_get_basic(&item_iter, &property);
630 ret_if(property == NULL);
632 if (strcasecmp(property, "Connected") == 0) {
633 gboolean connected = FALSE;
634 dbus_message_iter_next(&item_iter);
635 dbus_message_iter_recurse(&item_iter, &value_iter);
636 dbus_message_iter_get_basic(&value_iter, &connected);
638 event = connected ? BLUETOOTH_EVENT_DEVICE_CONNECTED :
639 BLUETOOTH_EVENT_DEVICE_DISCONNECTED;
641 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
643 _bt_convert_device_path_to_address(path, address);
645 BT_DBG("connected: %d", connected);
646 BT_DBG("address: %s", address);
648 /* Send event to application */
649 _bt_send_event(BT_DEVICE_EVENT,
651 DBUS_TYPE_INT32, &result,
652 DBUS_TYPE_STRING, &address,
656 } else if (strcasecmp(property, "Paired") == 0) {
657 gboolean paired = FALSE;
658 bt_remote_dev_info_t *remote_dev_info;
659 dbus_message_iter_next(&item_iter);
660 dbus_message_iter_recurse(&item_iter, &value_iter);
661 dbus_message_iter_get_basic(&value_iter, &paired);
663 ret_if(paired == FALSE);
665 /* BlueZ sends paired signal for each paired device */
666 /* during activation, We should ignore this, otherwise*/
667 /* application thinks that a new device got paired */
668 if (_bt_adapter_get_status() != BT_ACTIVATED) {
669 BT_DBG("BT is not activated, so ignore this");
673 if (_bt_is_device_creating() == TRUE) {
674 BT_DBG("Try to Pair by me");
678 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
680 _bt_convert_device_path_to_address(path, address);
682 remote_dev_info = _bt_get_remote_device_info(address);
683 if (remote_dev_info == NULL) {
688 _bt_send_event(BT_ADAPTER_EVENT,
689 BLUETOOTH_EVENT_BONDING_FINISHED,
690 DBUS_TYPE_INT32, &result,
691 DBUS_TYPE_STRING, &address,
692 DBUS_TYPE_UINT32, &remote_dev_info->class,
693 DBUS_TYPE_INT16, &remote_dev_info->rssi,
694 DBUS_TYPE_STRING, &remote_dev_info->name,
695 DBUS_TYPE_BOOLEAN, &remote_dev_info->paired,
696 DBUS_TYPE_BOOLEAN, &remote_dev_info->connected,
697 DBUS_TYPE_BOOLEAN, &remote_dev_info->trust,
698 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
699 &remote_dev_info->uuids, remote_dev_info->uuid_count,
702 _bt_free_device_info(remote_dev_info);
708 void __bt_set_audio_values(gboolean connected, char *address)
711 int bt_device_state = VCONFKEY_BT_DEVICE_NONE;
713 /* Set the headset name */
714 if (connected == TRUE) {
715 name = __bt_get_headset_name(address);
720 if (vconf_set_str(VCONFKEY_BT_HEADSET_NAME,
722 BT_ERR("vconf_set_str failed");
727 /* Set the headset state */
728 if (vconf_get_int(VCONFKEY_BT_DEVICE,
729 &bt_device_state) != 0) {
730 BT_ERR("vconf_get_str failed");
733 if (connected == TRUE) {
734 bt_device_state |= VCONFKEY_BT_DEVICE_HEADSET_CONNECTED;
735 } else if (bt_device_state & VCONFKEY_BT_DEVICE_HEADSET_CONNECTED) {
736 bt_device_state ^= VCONFKEY_BT_DEVICE_HEADSET_CONNECTED;
739 if (vconf_set_int(VCONFKEY_BT_DEVICE,
740 bt_device_state) != 0) {
741 BT_ERR("vconf_set_int failed");
745 void _bt_handle_headset_event(DBusMessage *msg)
747 int result = BLUETOOTH_ERROR_NONE;
748 DBusMessageIter item_iter;
749 DBusMessageIter value_iter;
750 gboolean property_flag = FALSE;
751 const char *member = dbus_message_get_member(msg);
752 const char *path = dbus_message_get_path(msg);
753 const char *property = NULL;
755 ret_if(member == NULL);
757 dbus_message_iter_init(msg, &item_iter);
759 if (dbus_message_iter_get_arg_type(&item_iter)
760 != DBUS_TYPE_STRING) {
761 BT_ERR("This is bad format dbus\n");
765 dbus_message_iter_get_basic(&item_iter, &property);
767 ret_if(property == NULL);
769 /* We allow only 1 headset connection (HSP or HFP)*/
770 if (strcasecmp(property, "Connected") == 0) {
771 int event = BLUETOOTH_EVENT_NONE;
774 dbus_message_iter_next(&item_iter);
775 dbus_message_iter_recurse(&item_iter, &value_iter);
776 dbus_message_iter_get_basic(&value_iter, &property_flag);
778 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
780 _bt_convert_device_path_to_address(path, address);
782 if (property_flag == TRUE) {
783 event = BLUETOOTH_EVENT_AG_CONNECTED;
785 event = BLUETOOTH_EVENT_AG_DISCONNECTED;
788 __bt_set_audio_values(property_flag, address);
790 _bt_send_event(BT_HEADSET_EVENT, event,
791 DBUS_TYPE_INT32, &result,
792 DBUS_TYPE_STRING, &address,
796 } else if (strcasecmp(property, "State") == 0) {
797 int event = BLUETOOTH_EVENT_NONE;
798 int sco_connected = FALSE;
802 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
804 _bt_convert_device_path_to_address(path, address);
806 dbus_message_iter_next(&item_iter);
807 dbus_message_iter_recurse(&item_iter, &value_iter);
808 dbus_message_iter_get_basic(&value_iter, &state);
810 /* This code assumes we support only 1 headset connection */
811 /* Need to use the headset list, if we support multi-headsets */
812 if (strcasecmp(property, "Playing") == 0) {
813 event = BLUETOOTH_EVENT_AG_AUDIO_CONNECTED;
814 sco_connected = TRUE;
815 } else if (strcasecmp(property, "connected") == 0 ||
816 strcasecmp(property, "disconnected") == 0) {
817 event = BLUETOOTH_EVENT_AG_AUDIO_DISCONNECTED;
818 sco_connected = FALSE;
820 BT_ERR("Not handled state");
825 if (vconf_set_bool(VCONFKEY_BT_HEADSET_SCO, sco_connected) < 0)
826 BT_ERR("vconf_set_bool - Failed\n");
828 _bt_send_event(BT_HEADSET_EVENT, event,
829 DBUS_TYPE_INT32, &result,
830 DBUS_TYPE_STRING, &address,
834 } else if (strcasecmp(property, "SpeakerGain") == 0) {
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, &spkr_gain);
846 _bt_send_event(BT_HEADSET_EVENT, BLUETOOTH_EVENT_AG_SPEAKER_GAIN,
847 DBUS_TYPE_INT32, &result,
848 DBUS_TYPE_STRING, &address,
849 DBUS_TYPE_UINT16, &spkr_gain,
853 } else if (strcasecmp(property, "MicrophoneGain") == 0) {
857 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
859 _bt_convert_device_path_to_address(path, address);
861 dbus_message_iter_next(&item_iter);
862 dbus_message_iter_recurse(&item_iter, &value_iter);
863 dbus_message_iter_get_basic(&value_iter, &mic_gain);
865 _bt_send_event(BT_HEADSET_EVENT, BLUETOOTH_EVENT_AG_MIC_GAIN,
866 DBUS_TYPE_INT32, &result,
867 DBUS_TYPE_STRING, &address,
868 DBUS_TYPE_UINT16, &mic_gain,
875 void _bt_handle_sink_event(DBusMessage *msg)
877 int result = BLUETOOTH_ERROR_NONE;
878 DBusMessageIter item_iter;
879 DBusMessageIter value_iter;
880 gboolean property_flag = FALSE;
881 const char *member = dbus_message_get_member(msg);
882 const char *path = dbus_message_get_path(msg);
883 const char *property = NULL;
885 ret_if(member == NULL);
887 dbus_message_iter_init(msg, &item_iter);
889 if (dbus_message_iter_get_arg_type(&item_iter)
890 != DBUS_TYPE_STRING) {
891 BT_ERR("This is bad format dbus\n");
895 dbus_message_iter_get_basic(&item_iter, &property);
897 ret_if(property == NULL);
899 if (strcasecmp(property, "Connected") == 0) {
900 int event = BLUETOOTH_EVENT_NONE;
903 dbus_message_iter_next(&item_iter);
904 dbus_message_iter_recurse(&item_iter, &value_iter);
905 dbus_message_iter_get_basic(&value_iter, &property_flag);
907 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
909 _bt_convert_device_path_to_address(path, address);
911 event = (property_flag == TRUE) ?
912 BLUETOOTH_EVENT_AV_CONNECTED :
913 BLUETOOTH_EVENT_AV_DISCONNECTED;
915 _bt_send_event(BT_HEADSET_EVENT, event,
916 DBUS_TYPE_INT32, &result,
917 DBUS_TYPE_STRING, &address,
920 _bt_send_event(BT_AVRCP_EVENT, event,
921 DBUS_TYPE_INT32, &result,
922 DBUS_TYPE_STRING, &address,
929 void _bt_handle_agent_event(DBusMessage *msg)
931 const char *member = dbus_message_get_member(msg);
932 int result = BLUETOOTH_ERROR_NONE;
933 char *address = NULL;
937 ret_if(member == NULL);
939 if (strcasecmp(member, "ObexAuthorize") == 0) {
940 __bt_get_agent_signal_info(msg, &address, &name, &uuid);
942 _bt_send_event(BT_OPP_SERVER_EVENT,
943 BLUETOOTH_EVENT_OBEX_SERVER_CONNECTION_AUTHORIZE,
944 DBUS_TYPE_INT32, &result,
945 DBUS_TYPE_STRING, &address,
946 DBUS_TYPE_STRING, &name,
948 } else if (strcasecmp(member, "RfcommAuthorize") == 0) {
949 bt_rfcomm_server_info_t *server_info;
951 __bt_get_agent_signal_info(msg, &address, &name, &uuid);
953 server_info = _bt_rfcomm_get_server_info_using_uuid(uuid);
954 ret_if(server_info == NULL);
955 ret_if(server_info->server_type != BT_CUSTOM_SERVER);
957 _bt_send_event(BT_RFCOMM_SERVER_EVENT,
958 BLUETOOTH_EVENT_RFCOMM_AUTHORIZE,
959 DBUS_TYPE_INT32, &result,
960 DBUS_TYPE_STRING, &address,
961 DBUS_TYPE_STRING, &uuid,
962 DBUS_TYPE_STRING, &name,
963 DBUS_TYPE_INT16, &server_info->control_fd,
968 static DBusHandlerResult __bt_manager_event_filter(DBusConnection *conn,
969 DBusMessage *msg, void *data)
971 const char *member = dbus_message_get_member(msg);
973 if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_SIGNAL)
974 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
976 retv_if(member == NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
978 if (strcasecmp(member, "AdapterAdded") == 0) {
979 BT_DBG("AdapterAdded");
980 _bt_handle_adapter_added();
981 } else if (strcasecmp(member, "AdapterRemoved") == 0) {
982 BT_DBG("AdapterRemoved");
983 } else if (strcasecmp(member, "NameOwnerChanged") == 0) {
986 char *previous = NULL;
987 char *current = NULL;
989 if (__bt_get_owner_info(msg, &name, &previous, ¤t)) {
990 BT_ERR("Fail to get the owner info");
991 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
994 if (*current != '\0')
995 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
997 if (strcasecmp(name, "org.bluez") == 0) {
998 BT_DBG("Bluetoothd is terminated");
999 _bt_handle_adapter_removed();
1002 _bt_obex_server_check_allocation(&value);
1004 if (value == TRUE) {
1005 /* Check if the obex server was terminated abnormally */
1006 _bt_obex_server_check_termination(name);
1009 _bt_rfcomm_server_check_existence(&value);
1011 if (value == TRUE) {
1012 /* The obex server was terminated abnormally */
1013 _bt_rfcomm_server_check_termination(name);
1015 } else if (dbus_message_has_interface(msg, BT_ADAPTER_INTERFACE)) {
1016 _bt_handle_adapter_event(msg);
1017 } else if (dbus_message_has_interface(msg, BT_INPUT_INTERFACE)) {
1018 _bt_handle_input_event(msg);
1019 } else if (dbus_message_has_interface(msg, BT_NETWORK_SERVER_INTERFACE)) {
1020 _bt_handle_network_server_event(msg);
1021 } else if (dbus_message_has_interface(msg, BT_NETWORK_CLIENT_INTERFACE)) {
1022 _bt_handle_network_client_event(msg);
1023 } else if (dbus_message_has_interface(msg, BT_HEADSET_INTERFACE)) {
1024 _bt_handle_headset_event(msg);
1025 } else if (dbus_message_has_interface(msg, BT_SINK_INTERFACE)) {
1026 _bt_handle_sink_event(msg);
1027 } else if (dbus_message_has_interface(msg, BT_AGENT_INTERFACE)) {
1028 _bt_handle_agent_event(msg);
1029 } else if (dbus_message_has_interface(msg, BT_DEVICE_INTERFACE)) {
1030 _bt_handle_device_event(msg);
1033 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1036 static DBusHandlerResult __bt_obexd_event_filter(DBusConnection *conn,
1037 DBusMessage *msg, void *data)
1039 const char *path = dbus_message_get_path(msg);
1040 const char *member = dbus_message_get_member(msg);
1042 if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_SIGNAL)
1043 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1045 retv_if(member == NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
1047 if (strcasecmp(member, "TransferStarted") == 0) {
1048 char *transfer_path = NULL;
1050 if (!dbus_message_get_args(msg, NULL,
1051 DBUS_TYPE_OBJECT_PATH, &transfer_path,
1052 DBUS_TYPE_INVALID)) {
1053 BT_ERR("Unexpected parameters in signal");
1054 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1057 _bt_obex_transfer_started(transfer_path);
1058 } else if (strcasecmp(member, "Progress") == 0) {
1062 if (!dbus_message_get_args(msg, NULL,
1063 DBUS_TYPE_INT32, &total,
1064 DBUS_TYPE_INT32, &transfer,
1065 DBUS_TYPE_INVALID)) {
1066 BT_ERR("Unexpected parameters in signal");
1067 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1070 _bt_obex_transfer_progress(path, total, transfer);
1071 } else if (strcasecmp(member, "TransferCompleted") == 0) {
1072 char *transfer_path = NULL;
1075 if (!dbus_message_get_args(msg, NULL,
1076 DBUS_TYPE_OBJECT_PATH, &transfer_path,
1077 DBUS_TYPE_BOOLEAN, &success,
1078 DBUS_TYPE_INVALID)) {
1079 BT_ERR("Unexpected parameters in signal");
1080 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1083 _bt_obex_transfer_completed(transfer_path, success);
1086 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1089 int _bt_register_service_event(DBusGConnection *g_conn, int event_type)
1091 DBusError dbus_error;
1092 char *match1 = NULL;
1093 char *match2 = NULL;
1094 DBusConnection *conn;
1095 DBusHandleMessageFunction event_func = NULL;
1097 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1099 conn = dbus_g_connection_get_connection(g_conn);
1100 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1102 switch (event_type) {
1103 case BT_MANAGER_EVENT:
1104 event_func = __bt_manager_event_filter;
1105 match1 = g_strdup_printf(MANAGER_EVENT_MATCH_RULE,
1106 BT_MANAGER_INTERFACE,
1109 match2 = g_strdup_printf(MANAGER_EVENT_MATCH_RULE,
1110 BT_FREEDESKTOP_INTERFACE,
1111 BT_FREEDESKTOP_PATH);
1113 case BT_DEVICE_EVENT:
1114 match1 = g_strdup_printf(EVENT_MATCH_RULE,
1115 BT_DEVICE_INTERFACE);
1118 match1 = g_strdup_printf(EVENT_MATCH_RULE,
1119 BT_INPUT_INTERFACE);
1121 case BT_NETWORK_EVENT:
1122 match1 = g_strdup_printf(EVENT_MATCH_RULE,
1123 BT_NETWORK_SERVER_INTERFACE);
1125 match2 = g_strdup_printf(EVENT_MATCH_RULE,
1126 BT_NETWORK_CLIENT_INTERFACE);
1128 case BT_HEADSET_EVENT:
1129 match1 = g_strdup_printf(EVENT_MATCH_RULE,
1130 BT_HEADSET_INTERFACE);
1132 match2 = g_strdup_printf(EVENT_MATCH_RULE,
1135 case BT_OPP_SERVER_EVENT:
1136 event_func = __bt_obexd_event_filter;
1137 match1 = g_strdup_printf(MANAGER_EVENT_MATCH_RULE,
1138 BT_OBEXD_MANAGER_INTERFACE,
1141 match2 = g_strdup_printf(EVENT_MATCH_RULE,
1142 BT_OBEXD_TRANSFER_INTERFACE);
1145 BT_ERR("Unknown event");
1146 return BLUETOOTH_ERROR_INTERNAL;
1150 if (!dbus_connection_add_filter(conn, event_func,
1152 BT_ERR("Fail to add filter");
1157 dbus_error_init(&dbus_error);
1160 dbus_bus_add_match(conn, match1, &dbus_error);
1162 if (dbus_error_is_set(&dbus_error)) {
1163 BT_ERR("Fail to add match: %s\n", dbus_error.message);
1164 dbus_error_free(&dbus_error);
1169 dbus_bus_add_match(conn, match2, &dbus_error);
1171 if (dbus_error_is_set(&dbus_error)) {
1172 BT_ERR("Fail to add match: %s\n", dbus_error.message);
1173 dbus_error_free(&dbus_error);
1180 return BLUETOOTH_ERROR_NONE;
1184 return BLUETOOTH_ERROR_INTERNAL;
1187 void _bt_unregister_service_event(DBusGConnection *g_conn, int event_type)
1189 DBusConnection *conn;
1190 DBusHandleMessageFunction event_func;
1192 ret_if(g_conn == NULL);
1193 conn = dbus_g_connection_get_connection(g_conn);
1195 switch (event_type) {
1196 case BT_MANAGER_EVENT:
1197 event_func = __bt_manager_event_filter;
1199 case BT_OPP_SERVER_EVENT:
1200 event_func = __bt_obexd_event_filter;
1203 BT_ERR("Unknown event");
1207 ret_if(conn == NULL);
1209 dbus_connection_remove_filter(conn, event_func, NULL);
1212 static int __bt_init_manager_receiver(void)
1214 GError *error = NULL;
1216 if (manager_conn == NULL) {
1217 manager_conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
1218 if (error != NULL) {
1219 BT_ERR("ERROR: Can't get on system bus [%s]", error->message);
1220 g_error_free(error);
1222 retv_if(manager_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1225 if (_bt_register_service_event(manager_conn,
1226 BT_MANAGER_EVENT) != BLUETOOTH_ERROR_NONE)
1229 if (_bt_register_service_event(manager_conn,
1230 BT_DEVICE_EVENT) != BLUETOOTH_ERROR_NONE)
1233 if (_bt_register_service_event(manager_conn,
1234 BT_HID_EVENT) != BLUETOOTH_ERROR_NONE)
1237 if (_bt_register_service_event(manager_conn,
1238 BT_HEADSET_EVENT) != BLUETOOTH_ERROR_NONE)
1241 if (_bt_register_service_event(manager_conn,
1242 BT_NETWORK_EVENT) != BLUETOOTH_ERROR_NONE)
1245 return BLUETOOTH_ERROR_NONE;
1248 dbus_g_connection_unref(manager_conn);
1249 manager_conn = NULL;
1252 return BLUETOOTH_ERROR_INTERNAL;
1255 static int __bt_init_obexd_receiver(void)
1257 GError *error = NULL;
1259 if (obexd_conn == NULL) {
1260 obexd_conn = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
1261 if (error != NULL) {
1262 BT_ERR("ERROR: Can't get on session bus [%s]", error->message);
1263 g_error_free(error);
1265 retv_if(obexd_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1268 if (_bt_register_service_event(obexd_conn,
1269 BT_OPP_SERVER_EVENT) != BLUETOOTH_ERROR_NONE) {
1270 dbus_g_connection_unref(obexd_conn);
1272 return BLUETOOTH_ERROR_INTERNAL;
1275 return BLUETOOTH_ERROR_NONE;
1278 /* To receive the event from bluez */
1279 int _bt_init_service_event_receiver(void)
1283 result = __bt_init_manager_receiver();
1284 retv_if(result != BLUETOOTH_ERROR_NONE, result);
1286 result = __bt_init_obexd_receiver();
1287 if (result != BLUETOOTH_ERROR_NONE)
1288 BT_ERR("Fail to init obexd receiver");
1290 return BLUETOOTH_ERROR_NONE;
1293 void _bt_deinit_service_event_reciever(void)
1295 _bt_unregister_service_event(manager_conn, BT_MANAGER_EVENT);
1297 _bt_unregister_service_event(obexd_conn, BT_OPP_SERVER_EVENT);
1300 dbus_g_connection_unref(manager_conn);
1301 manager_conn = NULL;
1305 dbus_g_connection_unref(obexd_conn);
1310 g_source_remove(event_id);