2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
22 #include <vconf-internal-bt-keys.h>
24 #include "bluetooth-api.h"
25 #include "bt-internal-types.h"
27 #include "bt-service-common.h"
28 #include "bt-service-event.h"
29 #include "bt-service-main.h"
30 #include "bt-service-core-device.h"
31 #include "bt-service-obex-server.h"
32 #include "bt-service-obex-agent.h"
33 #include "bt-service-pbap.h"
34 #include "bt-service-opp-client.h"
35 #include "bt-service-map-client.h"
36 #include "bt-service-core-adapter.h"
38 #ifdef TIZEN_FEATURE_BT_DPM
39 #include "bt-service-dpm.h"
42 #define DBUS_TIMEOUT 20 * 1000 /* 20 Sec */
43 static GDBusConnection *manager_conn;
44 static GDBusConnection *obexd_conn;
45 static GDBusConnection *opc_obexd_conn;
46 static GDBusConnection *map_obexd_conn;
48 static GList *p_cache_list = NULL;
50 static guint event_id;
52 static guint session_reinit_timer;
55 bt_remote_dev_info_t *dev_info;
59 * obexd connection type
67 OBEX_PCSUITE = (1 << 6),
68 OBEX_SYNCEVOLUTION = (1 << 7),
71 } bluetooth_obex_connection_type_t;
74 void _bt_handle_property_changed_event(GVariant *msg, const char *object_path);
75 void _bt_opc_property_changed_event(GVariant *msg, char *path);
76 void _bt_map_property_changed_event(GVariant *msg, const char *path);
77 int _bt_register_service_event(GDBusConnection *g_conn, int event_type);
78 void _bt_unregister_service_event(GDBusConnection *g_conn, int event_type);
79 void _bt_opp_client_event_deinit(void);
80 void _bt_map_client_event_deinit(void);
81 void _bt_map_on_transfer_finished(const char *transfer_object_path, const int error);
83 static void __bt_free_cache_info(bt_cache_info_t *cache_info)
85 ret_if(cache_info == NULL);
86 _bt_free_remote_dev(cache_info->dev_info);
91 /* Temp Adapter changes required to make OBEX work for handling device events here ,
92 This code will be removed and moved to OAL Event Handling part .
96 static void __bt_get_uuids(GVariant *value, bt_remote_dev_info_t *info)
98 ret_if(value == NULL);
101 gsize uuid_count = 0;
103 info->uuids = g_variant_dup_strv(value, &uuid_count);
104 info->uuid_count = (unsigned int)uuid_count;
106 BT_DBG("uuid count : %d", uuid_count);
110 void _bt_convert_addr_string_to_secure_string(char *addr,
115 ret_if(address == NULL);
116 ret_if(addr == NULL);
118 len = strlen(address);
119 ret_if(len != BT_ADDRESS_STRING_SIZE - 1);
121 g_strlcpy(addr, address, BT_ADDRESS_STRING_SIZE);
129 bt_status_t _bt_adapter_get_status_for_Obex(void)
131 int value = VCONFKEY_BT_STATUS_OFF;
133 /* check VCONFKEY_BT_STATUS */
134 if (vconf_get_int(VCONFKEY_BT_STATUS, &value) != 0) {
135 BT_ERR("fail to get vconf key!");
136 return BLUETOOTH_ADAPTER_DISABLED;
142 static int __bt_get_owner_info(GVariant *msg, char **name,
143 char **previous, char **current)
145 g_variant_get(msg, "(sss)", name, previous, current);
146 return BLUETOOTH_ERROR_NONE;
149 static int __bt_get_agent_signal_info(GVariant *msg, char **address,
150 char **name, char **uuid)
152 g_variant_get(msg, "(sss)", address, name, uuid);
153 return BLUETOOTH_ERROR_NONE;
156 void __bt_update_remote_cache_devinfo(const char *address, gboolean paired_status)
160 ret_if(address == NULL);
163 bt_cache_info_t *cache_info;
164 bt_remote_dev_info_t *dev_info;
166 node = g_list_first(p_cache_list);
168 while (node != NULL) {
169 cache_info = (bt_cache_info_t *)node->data;
171 if (cache_info == NULL) {
172 node = g_list_next(node);
176 dev_info = cache_info->dev_info;
177 if (strcasecmp(dev_info->address,
179 BT_DBG("Device Found");
180 if (paired_status == TRUE)
181 cache_info->dev_info->paired = TRUE;
183 cache_info->dev_info->paired = FALSE;
186 node = g_list_next(node);
191 gboolean __bt_handle_is_flight_mode_enabled(void)
193 if (TIZEN_FEATURE_FLIGHTMODE_ENABLED) {
194 int is_flight_mode = 0;
196 ret = vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE, &is_flight_mode);
198 BT_ERR("vconf_get_bool failed");
200 return (is_flight_mode == 0) ? FALSE : TRUE;
206 void _bt_handle_adapter_event(GVariant *msg, const char *member)
209 ret_if(member == NULL);
211 if (strcasecmp(member, "DeviceCreated") == 0) {
212 char *object_path = NULL;
214 ret_if(_bt_is_device_creating() == FALSE);
216 /* Bonding from remote device */
217 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
219 g_variant_get(msg, "(&o)", &object_path);
220 _bt_convert_device_path_to_address((const char*)object_path, address);
223 } else if (strcasecmp(member, "InterfacesRemoved") == 0) {
224 char *object_path = NULL;
226 bt_cache_info_t *cache_info;
227 bt_remote_dev_info_t *dev_info;
230 /* Bonding from remote device */
231 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
233 g_variant_get(msg, "(&o)", &object_path);
235 _bt_convert_device_path_to_address((const char *)object_path, address);
237 node = g_list_first(p_cache_list);
239 while (node != NULL) {
240 cache_info = (bt_cache_info_t *)node->data;
242 if (cache_info == NULL) {
243 node = g_list_next(node);
247 dev_info = cache_info->dev_info;
248 if (strcasecmp(dev_info->address,
250 p_cache_list = g_list_remove(p_cache_list,
252 __bt_free_cache_info(cache_info);
255 node = g_list_next(node);
258 } else if (strcasecmp(member, BT_HARDWARE_ERROR) == 0) {
259 BT_ERR_C("### Hardware error received from BLUEZ");
260 } else if (strcasecmp(member, BT_TX_TIMEOUT_ERROR) == 0) {
261 BT_ERR_C("### Tx timeout error received from BLUEZ");
265 static void __bt_obex_property_changed_event(GVariant *msg, const char *path)
269 GVariantIter value_iter;
270 GVariant *child = NULL, *val = NULL;
271 char *property = NULL;
272 g_variant_iter_init(&value_iter, msg);
273 while ((child = g_variant_iter_next_value(&value_iter))) {
274 g_variant_get(child, "{sv}", &property, &val);
276 ret_if(property == NULL);
278 BT_DBG("property :%s", property);
280 if (strcasecmp(property, "Status") == 0) {
282 g_variant_get(val, "s", &status);
284 if (strcasecmp(status, "active") == 0) {
285 _bt_obex_transfer_started(path);
286 } else if (strcasecmp(status, "complete") == 0) {
287 _bt_obex_transfer_completed(path, TRUE);
288 _bt_pbap_obex_transfer_completed(path, TRUE);
289 } else if (strcasecmp(status, "error") == 0) {
290 _bt_obex_transfer_completed(path, FALSE);
291 _bt_pbap_obex_transfer_completed(path, FALSE);
294 } else if (strcasecmp(property, "Transferred") == 0) {
295 guint64 transferred = 0;
296 /* As Transferred is expected guint64 so change int to guint64 and
297 * eariler transferred is static because of it can overwrite data
298 * on present on opc_obex_conn or obexd_conn as these are
299 * static memory are in sequential */
300 g_variant_get(val, "t", &transferred);
302 _bt_obex_transfer_progress(path, transferred);
304 /* TODO: MAP, "Complete"? see above */
306 g_variant_unref(val);
307 g_variant_unref(child);
313 static void __bt_device_remote_connected_properties(
314 bt_remote_dev_info_t *remote_dev_info,
315 char *address, gboolean connected)
317 int result = BLUETOOTH_ERROR_NONE;
319 GVariant *param = NULL;
322 if (remote_dev_info->uuid_count > 0) {
323 for (i = 0; i < remote_dev_info->uuid_count; i++) {
324 char *uuid = remote_dev_info->uuids[i];
325 if (strcasecmp(uuid, HID_UUID) == 0) {
326 int event = BLUETOOTH_EVENT_NONE;
328 event = (connected == TRUE) ?
329 BLUETOOTH_HID_CONNECTED :
330 BLUETOOTH_HID_DISCONNECTED;
331 param = g_variant_new("(is)", result,
333 _bt_send_event(BT_HID_EVENT, event,
343 bt_remote_dev_info_t *_bt_get_remote_device_info_by_object_path(
344 const char *object_path)
346 bt_remote_dev_info_t *dev_info;
347 GDBusProxy *adapter_proxy;
348 GDBusProxy *device_proxy;
353 GDBusConnection *conn;
354 GError *error = NULL;
355 GVariant *result = NULL;
356 GVariantIter *value_iter;
360 adapter_proxy = _bt_get_adapter_proxy();
361 retv_if(adapter_proxy == NULL, NULL);
363 retv_if(object_path == NULL, NULL);
365 conn = _bt_gdbus_get_system_gconn();
367 BT_ERR("conn == NULL");
371 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
372 NULL, BT_BLUEZ_NAME, object_path,
373 BT_PROPERTIES_INTERFACE, NULL, NULL);
375 retv_if(device_proxy == NULL, NULL);
377 result = g_dbus_proxy_call_sync(device_proxy, "GetAll",
378 g_variant_new("(s)", BT_DEVICE_INTERFACE),
379 G_DBUS_CALL_FLAGS_NONE,
384 g_object_unref(device_proxy);
386 dev_info = g_malloc0(sizeof(bt_remote_dev_info_t));
388 if (result != NULL) {
389 g_variant_get(result , "(@a{sv})", &value);
390 g_variant_unref(result);
392 tmp_value = g_variant_lookup_value(value, "Alias", G_VARIANT_TYPE_STRING);
394 g_variant_get(tmp_value, "s", &name);
395 g_variant_unref(tmp_value);
397 DBG_SECURE("Alias Name [%s]", name);
399 tmp_value = g_variant_lookup_value(value, "Name", G_VARIANT_TYPE_STRING);
400 g_variant_get(tmp_value, "s", &name);
401 g_variant_unref(tmp_value);
404 tmp_value = g_variant_lookup_value(value, "IsAliasSet", G_VARIANT_TYPE_BOOLEAN);
406 dev_info->is_alias_set = g_variant_get_boolean(tmp_value);
407 g_variant_unref(tmp_value);
409 dev_info->is_alias_set = FALSE;
411 BT_DBG("IsAliasSet: [%s]", dev_info->is_alias_set ? "TRUE" : "FALSE");
413 tmp_value = g_variant_lookup_value(value, "Class", G_VARIANT_TYPE_UINT32);
415 dev_info->class = g_variant_get_uint32(tmp_value);
416 g_variant_unref(tmp_value);
420 tmp_value = g_variant_lookup_value(value, "Connected", G_VARIANT_TYPE_BYTE);
422 dev_info->connected = g_variant_get_byte(tmp_value);
423 g_variant_unref(tmp_value);
425 dev_info->connected = BLUETOOTH_CONNECTED_LINK_NONE;
426 BT_DBG("connected link : %d", dev_info->connected);
428 tmp_value = g_variant_lookup_value(value, "Trusted", G_VARIANT_TYPE_BOOLEAN);
430 dev_info->trust = g_variant_get_boolean(tmp_value);
431 g_variant_unref(tmp_value);
433 dev_info->trust = FALSE;
435 tmp_value = g_variant_lookup_value(value, "Paired", G_VARIANT_TYPE_BOOLEAN);
437 dev_info->paired = g_variant_get_boolean(tmp_value);
438 g_variant_unref(tmp_value);
440 dev_info->paired = FALSE;
442 tmp_value = g_variant_lookup_value(value, "RSSI", G_VARIANT_TYPE_INT16);
444 dev_info->rssi = g_variant_get_int16(tmp_value);
445 g_variant_unref(tmp_value);
449 tmp_value = g_variant_lookup_value(value, "LastAddrType", G_VARIANT_TYPE_BYTE);
451 dev_info->addr_type = g_variant_get_byte(tmp_value);
452 g_variant_unref(tmp_value);
454 dev_info->addr_type = 0;
456 tmp_value = g_variant_lookup_value(value, "UUIDs", G_VARIANT_TYPE_STRING_ARRAY);
458 __bt_get_uuids(tmp_value, dev_info);
459 g_variant_unref(tmp_value);
462 tmp_value = g_variant_lookup_value(value, "ManufacturerDataLen", G_VARIANT_TYPE_UINT16);
464 dev_info->manufacturer_data_len = g_variant_get_uint16(tmp_value);
465 if (dev_info->manufacturer_data_len > BLUETOOTH_MANUFACTURER_DATA_LENGTH_MAX) {
466 BT_ERR("manufacturer_data_len is too long(len = %d)", dev_info->manufacturer_data_len);
467 dev_info->manufacturer_data_len = BLUETOOTH_MANUFACTURER_DATA_LENGTH_MAX;
469 g_variant_unref(tmp_value);
471 dev_info->manufacturer_data_len = 0;
473 tmp_value = g_variant_lookup_value(value, "ManufacturerData", G_VARIANT_TYPE_ARRAY);
475 if ((dev_info->manufacturer_data_len == 0) ||
476 dev_info->manufacturer_data_len != g_variant_get_size(tmp_value)) {
477 BT_ERR("manufacturer data length doesn't match");
478 dev_info->manufacturer_data_len = 0;
479 dev_info->manufacturer_data = NULL;
481 dev_info->manufacturer_data = g_malloc0(dev_info->manufacturer_data_len);
482 g_variant_get(tmp_value, "ay", &value_iter);
483 while (g_variant_iter_loop(value_iter, "y", &m_value))
484 dev_info->manufacturer_data[i++] = m_value;
486 g_variant_unref(tmp_value);
488 BT_INFO("manufacture data is not a G_VARIANT_TYPE_ARRAY ");
489 dev_info->manufacturer_data_len = 0;
490 dev_info->manufacturer_data = NULL;
493 tmp_value = g_variant_lookup_value(value, "Address", G_VARIANT_TYPE_STRING);
494 g_variant_get(tmp_value, "s", &address);
495 g_variant_unref(tmp_value);
497 dev_info->address = g_strdup(address);
498 dev_info->name = g_strdup(name);
500 g_variant_unref(value);
502 BT_ERR("result is NULL\n");
511 void _bt_handle_property_changed_event(GVariant *msg, const char *object_path)
513 char *interface_name = NULL;
514 GVariant *val = NULL;
516 g_variant_get(msg, "(&s@a{sv}@as)", &interface_name, &val, NULL);
517 BT_DBG("_bt_handle_property_changed_event");
519 if (strcasecmp(interface_name, BT_OBEX_TRANSFER_INTERFACE) == 0) {
520 BT_DBG("BT_OBEX_TRANSFER_INTERFACE");
521 __bt_obex_property_changed_event(val,
524 g_variant_unref(val);
527 void __bt_opc_property_changed_event(GVariant *msg,
530 GVariantIter value_iter;
531 char *property = NULL;
532 GVariant *val = NULL;
533 GVariant *child = NULL;
535 g_variant_iter_init(&value_iter, msg);
536 if ((child = g_variant_iter_next_value(&value_iter))) {
537 g_variant_get(child, "{sv}", &property, &val);
538 ret_if(property == NULL);
540 if (strcasecmp(property, "Status") == 0) {
542 g_variant_get(val, "s", &status);
543 BT_DBG("Status is %s", status);
545 if (strcasecmp(status, "active") == 0)
546 _bt_obex_client_started(path);
547 else if (strcasecmp(status, "complete") == 0)
548 _bt_obex_client_completed(path, TRUE);
549 else if (strcasecmp(status, "error") == 0)
550 _bt_obex_client_completed(path, FALSE);
553 } else if (strcasecmp(property, "Transferred") == 0) {
554 guint64 transferred = 0;
555 g_variant_get(val, "t", &transferred);
557 _bt_obex_client_progress(path, transferred);
559 BT_DBG("property : [%s]", property);
562 g_variant_unref(child);
563 g_variant_unref(val);
567 void _bt_opc_property_changed_event(GVariant *msg, char *path)
569 char *interface_name = NULL;
570 GVariant *value = NULL;
571 g_variant_get(msg, "(&s@a{sv}@as)", &interface_name, &value, NULL);
572 BT_INFO("interface_name = %s", interface_name);
573 if (strcasecmp(interface_name, BT_OBEX_TRANSFER_INTERFACE) == 0) {
574 __bt_opc_property_changed_event(value,
577 BT_DBG("interface_name : [%s]", interface_name);
579 g_variant_unref(value);
583 void __bt_map_property_changed_event(GVariant *msg,
587 GVariantIter value_iter;
588 char *property = NULL;
589 GVariant *val = NULL;
590 GVariant *child = NULL;
592 g_variant_iter_init(&value_iter, msg);
593 while ((child = g_variant_iter_next_value(&value_iter))) {
594 g_variant_get(child, "{sv}", &property, &val);
595 ret_if(property == NULL);
597 if (strcasecmp(property, "Status") == 0) {
599 g_variant_get(val, "s", &status);
600 BT_DBG("Status is %s", status);
602 if (strcasecmp(status, "active") == 0) {
603 BT_DBG("EVENT : STARTED");
604 // currently doing nothing
605 } else if (strcasecmp(status, "complete") == 0) {
606 BT_DBG("EVENT : COMPLETED");
607 _bt_map_on_transfer_finished(path, BLUETOOTH_ERROR_NONE);
608 } else if (strcasecmp(status, "error") == 0) {
609 BT_DBG("EVENT : FAILED");
610 _bt_map_on_transfer_finished(path, BLUETOOTH_ERROR_INTERNAL);
613 } else if (strcasecmp(property, "Transferred") == 0) {
614 guint64 transferred = 0;
615 g_variant_get(val, "t", &transferred);
617 BT_DBG("EVENT : PROGRESS CALLBACK");
618 // currently doing nothing - progress callback type is not used
620 BT_DBG("OTHER EVENT : property : [%s]", property);
623 g_variant_unref(child);
624 g_variant_unref(val);
628 void _bt_map_property_changed_event(GVariant *msg, const char *path)
630 BT_DBG("Entered _bt_map_property_changed_event");
631 char *interface_name = NULL;
632 GVariant *value = NULL;
633 g_variant_get(msg, "(&s@a{sv}@as)", &interface_name, &value, NULL);
634 BT_INFO("interface_name = %s", interface_name);
635 if (strcasecmp(interface_name, BT_OBEX_TRANSFER_INTERFACE) == 0) {
636 __bt_map_property_changed_event(value,
639 BT_DBG("interface_name : [%s]", interface_name);
641 g_variant_unref(value);
645 void _bt_handle_agent_event(GVariant *msg, const char *member)
647 int result = BLUETOOTH_ERROR_NONE;
648 char *address = NULL;
651 GVariant *param = NULL;
652 ret_if(member == NULL);
654 if (strcasecmp(member, "ObexAuthorize") == 0) {
655 __bt_get_agent_signal_info(msg, &address, &name, &uuid);
656 param = g_variant_new("(iss)", result, address, name);
657 _bt_send_event(BT_OPP_SERVER_EVENT,
658 BLUETOOTH_EVENT_OBEX_SERVER_CONNECTION_AUTHORIZE,
660 /* TODO: MAP? see above */
666 static int __bt_get_object_path(GVariant *msg, char **path)
668 g_variant_get(msg, "(o*)", path, NULL);
670 return BLUETOOTH_ERROR_INTERNAL;
672 return BLUETOOTH_ERROR_NONE;
676 static void __bt_get_service_list(GVariant *value, bluetooth_device_info_t *dev)
683 ret_if(value == NULL);
686 dev->service_index = 0;
688 g_variant_get(value, "as", &iter);
689 while (g_variant_iter_loop(iter, "s", &uuid)) {
690 g_strlcpy(dev->uuids[i], uuid, BLUETOOTH_UUID_STRING_MAX);
691 parts = g_strsplit(uuid, "-", -1);
693 if (parts == NULL || parts[0] == NULL) {
698 dev->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
701 dev->service_index++;
704 g_variant_iter_free(iter);
707 static int __bt_get_bonded_device_info(gchar *device_path,
708 bluetooth_device_info_t *dev_info)
710 GError *error = NULL;
711 GDBusProxy *device_proxy;
712 gchar *address = NULL;
714 unsigned int cod = 0;
716 gboolean trust = FALSE;
717 gboolean paired = FALSE;
718 guchar connected = 0;
719 GByteArray *manufacturer_data = NULL;
721 GDBusConnection *conn;
723 GVariantIter *property_iter;
727 GVariantIter *char_value_iter;
729 BT_CHECK_PARAMETER(device_path, return);
730 BT_CHECK_PARAMETER(dev_info, return);
732 conn = _bt_gdbus_get_system_gconn();
733 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
735 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
739 BT_PROPERTIES_INTERFACE,
742 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
744 result = g_dbus_proxy_call_sync(device_proxy,
746 g_variant_new("(s)", BT_DEVICE_INTERFACE),
747 G_DBUS_CALL_FLAGS_NONE,
753 BT_ERR("Error occured in Proxy call");
755 BT_ERR("Error occured in Proxy call (Error: %s)", error->message);
756 g_clear_error(&error);
758 g_object_unref(device_proxy);
759 return BLUETOOTH_ERROR_INTERNAL;
762 g_object_unref(device_proxy);
764 g_variant_get(result, "(a{sv})", &property_iter);
766 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
767 if (!g_strcmp0(key, "Paired")) {
768 paired = g_variant_get_boolean(value);
769 } else if (!g_strcmp0(key, "Address")) {
770 g_variant_get(value, "s", &address);
771 } else if (!g_strcmp0(key, "Alias")) {
772 g_variant_get(value, "s", &name);
773 } else if (!g_strcmp0(key, "Name")) {
775 g_variant_get(value, "s", &name);
776 } else if (!g_strcmp0(key, "Class")) {
777 cod = g_variant_get_uint32(value);
778 } else if (!g_strcmp0(key, "Connected")) {
779 connected = g_variant_get_byte(value);
780 } else if (!g_strcmp0(key, "Trusted")) {
781 trust = g_variant_get_boolean(value);
782 } else if (!g_strcmp0(key, "RSSI")) {
783 rssi = g_variant_get_int16(value);
784 } else if (!g_strcmp0(key, "UUIDs")) {
785 __bt_get_service_list(value, dev_info);
786 } else if (!g_strcmp0(key, "ManufacturerDataLen")) {
787 dev_info->manufacturer_data.data_len = g_variant_get_uint16(value);
788 } else if (!g_strcmp0(key, "ManufacturerData")) {
789 manufacturer_data = g_byte_array_new();
790 g_variant_get(value, "ay", &char_value_iter);
791 while (g_variant_iter_loop(char_value_iter, "y", &char_value))
792 g_byte_array_append(manufacturer_data, &char_value, 1);
794 g_variant_iter_free(char_value_iter);
796 if (manufacturer_data) {
797 if (manufacturer_data->len > 0) {
798 memcpy(dev_info->manufacturer_data.data, manufacturer_data->data,
799 manufacturer_data->len);
802 g_byte_array_free(manufacturer_data, TRUE);
805 g_variant_iter_free(property_iter);
807 BT_DBG("trust: %d, paired: %d", trust, paired);
809 g_variant_unref(result);
811 if ((paired == FALSE) && (trust == FALSE)) {
814 return BLUETOOTH_ERROR_NOT_PAIRED;
817 _bt_convert_addr_string_to_type(dev_info->device_address.addr,
820 _bt_divide_device_class(&dev_info->device_class, cod);
822 g_strlcpy(dev_info->device_name.name, name,
823 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
825 dev_info->rssi = rssi;
826 dev_info->trust = trust;
827 dev_info->paired = paired;
828 dev_info->connected = connected;
829 ret = BLUETOOTH_ERROR_NONE;
836 int _bt_get_bonded_device_info(bluetooth_device_address_t *device_address,
837 bluetooth_device_info_t *dev_info)
839 char *object_path = NULL;
840 GDBusProxy *adapter_proxy;
841 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
842 int ret = BLUETOOTH_ERROR_NONE;
844 BT_CHECK_PARAMETER(device_address, return);
845 BT_CHECK_PARAMETER(dev_info, return);
847 adapter_proxy = _bt_get_adapter_proxy();
848 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
850 _bt_convert_addr_type_to_string(address, device_address->addr);
852 object_path = _bt_get_device_object_path(address);
854 retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
856 ret = __bt_get_bonded_device_info(object_path, dev_info);
863 char *_bt_get_bonded_device_name(char *address)
865 bt_remote_dev_info_t *dev_info;
867 retv_if(address == NULL, strdup(""));
869 dev_info = _bt_service_get_remote_dev_info(address);
870 retv_if(dev_info == NULL, strdup(""));
871 retv_if(dev_info->name == NULL, strdup(""));
873 return g_strdup(dev_info->name);
875 /* Temp Adapter Util changes to make OBEX work.
878 void _bt_handle_device_event(GVariant *msg, const char *member, const char *path)
881 int result = BLUETOOTH_ERROR_NONE;
883 char *dev_name = NULL;
884 // const char *property = NULL;
885 GVariant *param = NULL;
886 char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 };
887 ret_if(path == NULL);
889 if (strcasecmp(member, "DeviceConnected") == 0) {
890 unsigned char addr_type = 0;
892 g_variant_get(msg, "(y)", &addr_type);
894 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
896 _bt_convert_device_path_to_address(path, address);
897 dev_name = _bt_get_bonded_device_name(address);
899 _bt_convert_addr_string_to_secure_string(secure_address, address);
900 BT_INFO("Address : %s Type : %d", secure_address, addr_type);
901 BT_ERR_C("### Connected [%s] [%s]", !addr_type ? "BREDR" : "LE",
902 !addr_type ? dev_name : secure_address);
905 _bt_logging_connection(TRUE, addr_type);
906 param = g_variant_new("(isy)", result, address, addr_type);
907 /*Send event to application*/
908 _bt_send_event(BT_DEVICE_EVENT,
909 BLUETOOTH_EVENT_DEVICE_CONNECTED,
912 } else if (strcasecmp(member, "Disconnected") == 0) {
913 unsigned char disc_reason = 0;
914 unsigned char addr_type = 0;
915 char *dev_name = NULL;
916 gboolean sending = FALSE;
918 g_variant_get(msg, "(yys)", &addr_type, &disc_reason, &dev_name);
920 result = disc_reason;
922 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
924 _bt_convert_device_path_to_address(path, address);
927 0x01 BDADDR_LE_PUBLIC
928 0x02 BDADDR_LE_RANDOM */
929 _bt_convert_addr_string_to_secure_string(secure_address, address);
930 BT_INFO("Address : %s Type : %d", secure_address, addr_type);
931 BT_ERR_C("### Disconnected [%s] [%d : %s] [%s]", !addr_type ? "BREDR" : "LE",
932 disc_reason, _bt_convert_disc_reason_to_string(disc_reason),
933 !addr_type ? dev_name : secure_address);
936 //_bt_headset_set_local_connection(FALSE);
937 _bt_logging_connection(FALSE, addr_type);
940 #ifdef TIZEN_BT_A2DP_SINK_AUTO_CONNECT
942 int bt_device_state = VCONFKEY_BT_DEVICE_NONE;
944 if (vconf_get_int(VCONFKEY_BT_DEVICE, &bt_device_state) != 0)
945 BT_ERR("vconf_get_int failed");
947 BT_INFO("conn_state[0x%x], adapter_state [%d]",
948 bt_device_state, _bt_adapter_get_status_for_Obex());
950 if (disc_reason == BLUETOOTH_ERROR_CONNECTION_TIMEOUT) {
951 _bt_audio_start_auto_connect(TRUE);
952 } else if (bt_device_state &
953 VCONFKEY_BT_DEVICE_A2DP_SOURCE_CONNECTED) {
954 BT_INFO("Disconnected due to turning BT off. Skip a address");
956 char *last_connected = NULL;
957 last_connected = vconf_get_str(BT_LAST_CONNECTED_DEVICE);
958 if (!g_strcmp0(address, last_connected))
959 _bt_audio_set_auto_connect_device_addr("");
961 free(last_connected);
966 /*Check for any OPP transfer on the device and cancel
969 _bt_obex_check_pending_transfer(address);
970 _bt_opp_client_is_sending(&sending);
972 _bt_opp_client_check_pending_transfer(address);
973 /* TODO: MAP? see above */
975 param = g_variant_new("(isy)", result, address, addr_type);
976 _bt_send_event(BT_DEVICE_EVENT,
977 BLUETOOTH_EVENT_DEVICE_DISCONNECTED,
980 } else if (strcasecmp(member, "ProfileStateChanged") == 0) {
982 char *profile_uuid = NULL;
983 bluetooth_device_address_t bd_addr;
985 g_variant_get(msg, "(si)", &profile_uuid, &state);
987 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
989 _bt_convert_device_path_to_address(path, address);
990 _bt_convert_addr_string_to_type(bd_addr.addr, address);
992 _bt_convert_addr_string_to_secure_string(secure_address, address);
993 BT_DBG("Address: %s", secure_address);
994 BT_DBG("Profile UUID: %s", profile_uuid);
995 BT_DBG("State: %d", state);
999 static gboolean __bt_parse_device_properties(GVariant *item,
1000 bt_remote_dev_info_t *dev_info)
1009 g_variant_iter_init(&iter, item);
1010 while (g_variant_iter_loop(&iter, "{sv}", &key, &val)) {
1011 if (strcasecmp(key, "Address") == 0) {
1012 dev_info->address = g_variant_dup_string(val, &len);
1013 } else if (strcasecmp(key, "Class") == 0) {
1014 dev_info->class = g_variant_get_uint32(val);
1015 } else if (strcasecmp(key, "name") == 0) {
1016 if (dev_info->name == NULL)
1017 dev_info->name = g_variant_dup_string(val, &len);
1018 } else if (strcasecmp(key, "Connected") == 0) {
1019 dev_info->connected = g_variant_get_byte(val);
1020 } else if (strcasecmp(key, "paired") == 0) {
1021 dev_info->paired = g_variant_get_boolean(val);
1022 } else if (strcasecmp(key, "Trusted") == 0) {
1023 dev_info->trust = g_variant_get_boolean(val);
1024 } else if (strcasecmp(key, "RSSI") == 0) {
1025 dev_info->rssi = g_variant_get_int16(val);
1026 } else if (strcasecmp(key, "LastAddrType") == 0) {
1027 dev_info->addr_type = g_variant_get_byte(val);
1028 } else if (strcasecmp(key, "UUIDs") == 0) {
1032 size = g_variant_get_size(val);
1035 uuid_value = (char **)g_variant_get_strv(val, &size);
1036 if (dev_info->uuids == NULL)
1037 dev_info->uuids = g_malloc0(sizeof(char *) * size);
1039 for (i = 0; uuid_value[i] != NULL; i++) {
1040 dev_info->uuid_count++;
1041 dev_info->uuids[i] = g_strdup(uuid_value[i]);
1045 } else if (strcasecmp(key, "ManufacturerDataLen") == 0) {
1046 g_variant_get(val, "q", &dev_info->manufacturer_data_len);
1047 if (dev_info->manufacturer_data_len > BLUETOOTH_MANUFACTURER_DATA_LENGTH_MAX) {
1048 BT_ERR("manufacturer_data_len is too long(len = %d)", dev_info->manufacturer_data_len);
1049 dev_info->manufacturer_data_len = BLUETOOTH_MANUFACTURER_DATA_LENGTH_MAX;
1052 if (dev_info->manufacturer_data_len == 0)
1053 dev_info->manufacturer_data = g_strdup("");
1054 } else if (strcasecmp(key, "ManufacturerData") == 0) {
1057 GVariantIter *value_iter;
1060 len = g_variant_get_size(val);
1064 dev_info->manufacturer_data = g_malloc0(len);
1066 g_variant_get(val, "ay", &value_iter);
1067 while (g_variant_iter_loop(value_iter, "y", &m_value))
1068 dev_info->manufacturer_data[i++] = m_value;
1069 g_variant_iter_free(value_iter);
1077 static gboolean __bt_parse_interface(GVariant *msg,
1078 bt_remote_dev_info_t *dev_info)
1081 GVariant *optional_param = NULL;
1084 char *interface_name = NULL;
1085 GVariant *inner_iter = NULL;
1086 g_variant_get(msg, "(&o@a{sa{sv}})",
1087 &path, &optional_param);
1088 g_variant_iter_init(&iter, optional_param);
1090 retv_if(optional_param == NULL, FALSE);
1092 while ((child = g_variant_iter_next_value(&iter))) {
1093 g_variant_get(child, "{&s@a{sv}}", &interface_name, &inner_iter);
1094 if (g_strcmp0(interface_name, BT_DEVICE_INTERFACE) == 0) {
1095 BT_DBG("Found a device: %s", path);
1096 if (__bt_parse_device_properties(inner_iter,
1097 dev_info) == FALSE) {
1098 g_variant_unref(inner_iter);
1099 g_variant_unref(child);
1100 g_variant_unref(optional_param);
1101 BT_ERR("Fail to parse the properies");
1104 g_variant_unref(inner_iter);
1105 g_variant_unref(child);
1106 g_variant_unref(optional_param);
1110 g_variant_unref(inner_iter);
1111 g_variant_unref(child);
1114 g_variant_unref(optional_param);
1119 static int __bt_parse_event(GVariant *msg)
1123 char *interface_name = NULL;
1124 GVariant *inner_iter = NULL;
1126 g_variant_iter_init(&iter, msg);
1128 while ((child = g_variant_iter_next_value(&iter))) {
1129 g_variant_get(child, "{&s@a{sv}}", &interface_name, &inner_iter);
1130 if (g_strcmp0(interface_name,
1131 BT_DEVICE_INTERFACE) == 0) {
1132 g_variant_unref(inner_iter);
1133 g_variant_unref(child);
1134 return BT_DEVICE_EVENT;
1135 } else if (g_strcmp0(interface_name,
1136 BT_MEDIATRANSPORT_INTERFACE) == 0) {
1137 g_variant_unref(inner_iter);
1138 g_variant_unref(child);
1139 return BT_MEDIA_TRANSFER_EVENT;
1140 } else if (g_strcmp0(interface_name,
1141 BT_PLAYER_CONTROL_INTERFACE) == 0) {
1142 g_variant_unref(inner_iter);
1143 g_variant_unref(child);
1144 return BT_AVRCP_CONTROL_EVENT;
1146 g_variant_unref(inner_iter);
1147 g_variant_unref(child);
1153 static void __bt_manager_event_filter(GDBusConnection *connection,
1154 const gchar *sender_name,
1155 const gchar *object_path,
1156 const gchar *interface_name,
1157 const gchar *signal_name,
1158 GVariant *parameters,
1162 bt_event_type_t bt_event = 0x00;
1163 int result = BLUETOOTH_ERROR_NONE;
1165 char *obj_path = NULL;
1166 GVariant *param = NULL;
1167 #ifdef TIZEN_FEATURE_BT_DPM
1168 int desktop_state = DPM_BT_ERROR;
1171 if (signal_name == NULL)
1174 if (strcasecmp(signal_name, "InterfacesAdded") == 0) {
1175 g_variant_get(parameters, "(&o@a{sa{sv}})", &obj_path, &value);
1177 if (strcasecmp(obj_path, BT_BLUEZ_HCI_PATH) == 0) {
1178 if (!TIZEN_FEATURE_BT_USB_DONGLE) {
1179 if (_bt_register_obex_server() != BLUETOOTH_ERROR_NONE)
1180 BT_ERR("Fail to init obex server");
1183 bt_event = __bt_parse_event(value);
1184 if (bt_event == BT_DEVICE_EVENT) {
1185 bt_cache_info_t *cache_info;
1186 bt_remote_dev_info_t *dev_info;
1188 if (_bt_is_discovering() == FALSE) {
1189 g_variant_unref(value);
1193 cache_info = g_malloc0(sizeof(bt_cache_info_t));
1194 ret_if(cache_info == NULL);
1196 dev_info = g_malloc0(sizeof(bt_remote_dev_info_t));
1197 if (dev_info == NULL) {
1198 __bt_free_cache_info(cache_info);
1202 cache_info->dev_info = dev_info;
1204 if (__bt_parse_interface(parameters, dev_info) == FALSE) {
1205 BT_ERR("Fail to parse the properies");
1206 __bt_free_cache_info(cache_info);
1207 g_variant_unref(value);
1211 if (dev_info->addr_type != BDADDR_BREDR) {
1212 /* Whenever emit the property changed from bluez,
1213 some property doesn't reach to bt-service.
1214 So LE device is handled as AdvReport signal */
1215 __bt_free_cache_info(cache_info);
1216 g_variant_unref(value);
1220 if (dev_info->name == NULL)
1221 /* If Remote device name is NULL or still RNR is not done
1222 * then display address as name.
1224 dev_info->name = g_strdup(dev_info->address);
1226 #ifdef TIZEN_FEATURE_BT_DPM
1227 _bt_dpm_get_bluetooth_desktop_connectivity_state(&desktop_state);
1228 if (desktop_state == DPM_RESTRICTED) {
1229 bluetooth_device_class_t device_class;
1230 _bt_divide_device_class(&device_class, dev_info->class);
1231 BT_DBG("[%s]device_class.major_class : %d", dev_info->name, device_class.major_class);
1233 if (device_class.major_class ==
1234 BLUETOOTH_DEVICE_MAJOR_CLASS_COMPUTER) {
1235 __bt_free_cache_info(cache_info);
1236 g_variant_unref(value);
1242 GVariant *uuids = NULL;
1243 GVariantBuilder *builder = NULL;
1245 builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
1246 for (i = 0; i < dev_info->uuid_count; i++) {
1247 g_variant_builder_add(builder, "s",
1248 dev_info->uuids[i]);
1250 uuids = g_variant_new("as", builder);
1251 g_variant_builder_unref(builder);
1252 GVariant *manufacturer_data = NULL;
1253 manufacturer_data = g_variant_new_from_data(
1254 G_VARIANT_TYPE_BYTESTRING,
1255 dev_info->manufacturer_data,
1256 dev_info->manufacturer_data_len,
1258 param = g_variant_new("(isunsbub@asn@ay)", result,
1264 dev_info->connected,
1267 dev_info->manufacturer_data_len,
1269 _bt_send_event(BT_ADAPTER_EVENT,
1270 BLUETOOTH_EVENT_REMOTE_DEVICE_FOUND,
1272 p_cache_list = g_list_append(p_cache_list, cache_info);
1273 } else if (bt_event == BT_AVRCP_CONTROL_EVENT) {
1274 BT_DBG("Device path : %s ", obj_path);
1275 //_bt_set_control_device_path(obj_path);
1278 g_variant_unref(value);
1279 } else if (strcasecmp(signal_name, "InterfacesRemoved") == 0) {
1280 if (TIZEN_FEATURE_BT_USB_DONGLE) {
1281 if (_bt_unregister_obex_server() != BLUETOOTH_ERROR_NONE)
1282 BT_ERR("Fail to unregister obex server");
1284 } else if (strcasecmp(signal_name, "NameOwnerChanged") == 0) {
1287 char *previous = NULL;
1288 char *current = NULL;
1290 if (__bt_get_owner_info(parameters, &name, &previous, ¤t)) {
1291 BT_ERR("Fail to get the owner info");
1295 if (*current != '\0') {
1304 if (strcasecmp(name, BT_BLUEZ_NAME) == 0) {
1305 BT_INFO_C("### Bluetoothd is terminated");
1307 if (_bt_unregister_obex_server() != BLUETOOTH_ERROR_NONE)
1308 BT_ERR("Fail to unregister obex server");
1312 _bt_obex_server_check_allocation(&value);
1314 if (value == TRUE) {
1315 /* Check if the obex server was terminated abnormally */
1316 _bt_obex_server_check_termination(name);
1322 } else if (g_strcmp0(interface_name, BT_AGENT_INTERFACE) == 0) {
1323 _bt_handle_agent_event(parameters, signal_name);
1324 } else if (g_strcmp0(interface_name, BT_DEVICE_INTERFACE) == 0) {
1325 _bt_handle_device_event(parameters, signal_name, object_path);
1331 static gboolean __bt_is_obexd_event(GVariant *msg, const char *interface)
1334 if (g_strcmp0(interface, BT_PROPERTIES_INTERFACE) == 0) {
1335 char *interface_name = NULL;
1337 g_variant_get(msg, "(&s@a{sv}@as)", &interface_name, NULL, NULL);
1338 retv_if(interface_name == NULL, FALSE);
1340 if (strcasecmp(interface_name, BT_OBEX_TRANSFER_INTERFACE) == 0) {
1341 BT_DBG("BT_OBEX_TRANSFER_INTERFACE");
1349 static void __bt_obexd_event_filter(GDBusConnection *connection,
1350 const gchar *sender_name,
1351 const gchar *object_path,
1352 const gchar *interface_name,
1353 const gchar *signal_name,
1354 GVariant *parameters,
1357 const char *member = signal_name;
1358 char *obj_path = NULL;
1359 ret_if(member == NULL);
1361 if (strcasecmp(member, "InterfacesAdded") == 0) {
1362 if (__bt_get_object_path(parameters, &obj_path)) {
1363 BT_ERR("Fail to get the path");
1366 BT_INFO("object_path = [%s]", obj_path);
1368 /*Handle OPP_SERVER_CONNECTED_EVENT here */
1369 /* TODO: MAP? see above */
1370 if (strncmp(obj_path, BT_SESSION_BASEPATH_SERVER,
1371 strlen(BT_SESSION_BASEPATH_SERVER)) != 0) {
1376 if (g_strrstr(obj_path, "session") && g_strrstr(obj_path, "transfer")) {
1377 BT_DBG("Obex_Server_Session_Transfer connected");
1378 _bt_obex_transfer_connected(obj_path);
1381 } else if (strcasecmp(member, "InterfacesRemoved") == 0) {
1382 /*Handle OPP_SERVER_DISCONNECTED_EVENT here */
1383 /* TODO: MAP? see above */
1384 if (__bt_get_object_path(parameters, &obj_path)) {
1385 BT_ERR("Fail to get the path");
1388 BT_INFO("object_path = [%s]", obj_path);
1390 if (strncmp(obj_path, BT_SESSION_BASEPATH_CLIENT,
1391 strlen(BT_SESSION_BASEPATH_CLIENT)) == 0) {
1392 BT_DBG("Call PBAP Disconnected");
1393 _bt_obex_pbap_client_disconnect(obj_path);
1396 if (strncmp(obj_path, BT_SESSION_BASEPATH_SERVER,
1397 strlen(BT_SESSION_BASEPATH_SERVER)) != 0) {
1402 if (g_strrstr(obj_path, "session") && g_strrstr(obj_path, "transfer")) {
1403 BT_DBG("Obex_Server_Session_Transfer disconnected %s",
1406 _bt_obex_transfer_disconnected(obj_path);
1409 } else if (__bt_is_obexd_event(parameters, interface_name) == TRUE) {
1410 const char *path = object_path;
1412 if (strncmp(path, BT_SESSION_BASEPATH_SERVER,
1413 strlen(BT_SESSION_BASEPATH_SERVER)) != 0 &&
1414 strncmp(path, BT_SESSION_BASEPATH_CLIENT,
1415 strlen(BT_SESSION_BASEPATH_CLIENT)) != 0) {
1416 BT_DBG("DBUS_HANDLER_RESULT_NOT_YET_HANDLED");
1420 _bt_handle_property_changed_event(parameters, path);
1426 static gboolean __bt_is_obexd_client_event(GVariant *msg, const char *interface)
1430 if (g_strcmp0(interface, BT_PROPERTIES_INTERFACE) == 0) {
1431 char *interface_name = NULL;
1433 g_variant_get(msg, "(&s@a{sv}@as)", &interface_name, NULL, NULL);
1435 retv_if(interface_name == NULL, FALSE);
1437 if (strcasecmp(interface_name,
1438 BT_OBEX_TRANSFER_INTERFACE) == 0) {
1449 static void __bt_opc_event_filter(GDBusConnection *connection,
1450 const gchar *sender_name,
1451 const gchar *object_path,
1452 const gchar *interface_name,
1453 const gchar *signal_name,
1454 GVariant *parameters,
1457 const char *member = signal_name;
1458 char *obj_path = NULL;
1459 if (strcasecmp(member, "InterfacesAdded") == 0) {
1460 BT_DBG("InterfacesAdded");
1461 } else if (strcasecmp(member, "InterfacesRemoved") == 0) {
1463 if (__bt_get_object_path(parameters, &obj_path)) {
1464 BT_ERR("Fail to get the path");
1468 BT_DBG("object_path = %s", obj_path);
1470 if (strncmp(obj_path, BT_SESSION_BASEPATH_CLIENT,
1471 strlen(BT_SESSION_BASEPATH_CLIENT)) != 0
1472 || strstr(obj_path, "transfer") == NULL) {
1475 } else if (strncmp(obj_path, BT_SESSION_BASEPATH_CLIENT,
1476 strlen(BT_SESSION_BASEPATH_CLIENT)) == 0) {
1477 BT_DBG("Going to call opc disconnected");
1478 _bt_opc_disconnected(obj_path);
1481 _bt_sending_files();
1483 } else if (__bt_is_obexd_client_event(parameters, interface_name) == TRUE) {
1484 char *path = (char *)object_path;
1485 BT_INFO("object_path %s", path);
1486 if (strncmp(path, BT_SESSION_BASEPATH_CLIENT,
1487 strlen(BT_SESSION_BASEPATH_CLIENT)) != 0) {
1488 BT_DBG("NOT BT_SESSION_BASEPATH_CLIENT");
1492 _bt_opc_property_changed_event(parameters, path);
1498 int _bt_opp_client_event_init(void)
1500 GError *error = NULL;
1502 if (opc_obexd_conn == NULL) {
1503 opc_obexd_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
1505 if (!opc_obexd_conn) {
1507 BT_ERR("Unable to connect to dbus: %s", error->message);
1508 g_clear_error(&error);
1510 return BLUETOOTH_ERROR_INTERNAL;
1514 if (_bt_register_service_event(opc_obexd_conn,
1515 BT_OPP_CLIENT_EVENT) != BLUETOOTH_ERROR_NONE) {
1516 g_object_unref(opc_obexd_conn);
1517 opc_obexd_conn = NULL;
1518 return BLUETOOTH_ERROR_INTERNAL;
1521 return BLUETOOTH_ERROR_NONE;
1524 void _bt_opp_client_event_deinit(void)
1526 if (opc_obexd_conn) {
1527 _bt_unregister_service_event(opc_obexd_conn,
1528 BT_OPP_CLIENT_EVENT);
1529 g_object_unref(opc_obexd_conn);
1530 opc_obexd_conn = NULL;
1534 static void __bt_map_event_filter(GDBusConnection *connection,
1535 const gchar *sender_name,
1536 const gchar *object_path,
1537 const gchar *interface_name,
1538 const gchar *signal_name,
1539 GVariant *parameters,
1542 BT_DBG("Entered __bt_map_event_filter");
1543 const char *member = signal_name;
1545 if (strcasecmp(member, "InterfacesAdded") == 0) {
1546 BT_DBG("------------------------------------ADDED------------------------------------");
1547 // currently doing nothing
1548 } else if (strcasecmp(member, "InterfacesRemoved") == 0) {
1549 BT_DBG("------------------------------------REMOVED------------------------------------");
1550 // TODO check if something should be called here?
1551 //_bt_map_on_transfer_finished(object_path, error);
1552 } else if (__bt_is_obexd_client_event(parameters, interface_name) == TRUE) {
1553 BT_DBG("------------------------------------CLIENT EVENT------------------------------------");
1554 _bt_map_property_changed_event(parameters, object_path);
1560 int _bt_map_client_event_init(void)
1562 GError *error = NULL;
1564 if (map_obexd_conn == NULL) {
1565 map_obexd_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
1567 if (!map_obexd_conn) {
1569 BT_ERR("Unable to connect to dbus: %s", error->message);
1570 g_clear_error(&error);
1572 return BLUETOOTH_ERROR_INTERNAL;
1576 if (_bt_register_service_event(map_obexd_conn,
1577 BT_MAP_CLIENT_EVENT) != BLUETOOTH_ERROR_NONE) {
1578 g_object_unref(map_obexd_conn);
1579 map_obexd_conn = NULL;
1580 return BLUETOOTH_ERROR_INTERNAL;
1583 return BLUETOOTH_ERROR_NONE;
1586 void _bt_map_client_event_deinit(void)
1588 if (map_obexd_conn) {
1589 _bt_unregister_service_event(map_obexd_conn,
1590 BT_MAP_CLIENT_EVENT);
1591 g_object_unref(map_obexd_conn);
1592 map_obexd_conn = NULL;
1596 int _bt_register_manager_subscribe_signal(GDBusConnection *conn,
1602 static int subs_interface_added_id = -1;
1603 static int subs_interface_removed_id = -1;
1606 if (subs_interface_added_id == -1) {
1607 subs_interface_added_id = g_dbus_connection_signal_subscribe(conn,
1608 NULL, BT_MANAGER_INTERFACE,
1609 BT_INTERFACES_ADDED, NULL, NULL, 0,
1610 __bt_manager_event_filter,
1613 if (subs_interface_removed_id == -1) {
1614 subs_interface_removed_id = g_dbus_connection_signal_subscribe(conn,
1615 NULL, BT_MANAGER_INTERFACE,
1616 BT_INTERFACES_REMOVED, NULL, NULL, 0,
1617 __bt_manager_event_filter,
1622 if (subs_interface_added_id != -1) {
1623 g_dbus_connection_signal_unsubscribe(conn,
1624 subs_interface_added_id);
1625 subs_interface_added_id = -1;
1627 if (subs_interface_removed_id != -1) {
1628 g_dbus_connection_signal_unsubscribe(conn,
1629 subs_interface_removed_id);
1630 subs_interface_removed_id = -1;
1636 int _bt_register_device_subscribe_signal(GDBusConnection *conn,
1642 static int subs_device_id = -1;
1645 if (subs_device_id == -1) {
1646 subs_device_id = g_dbus_connection_signal_subscribe(conn,
1647 NULL, BT_DEVICE_INTERFACE,
1648 NULL, NULL, NULL, 0,
1649 __bt_manager_event_filter,
1653 if (subs_device_id != -1) {
1654 g_dbus_connection_signal_unsubscribe(conn,
1656 subs_device_id = -1;
1662 int _bt_register_input_subscribe_signal(GDBusConnection *conn,
1668 static int subs_input_id = -1;
1671 if (subs_input_id == -1) {
1672 subs_input_id = g_dbus_connection_signal_subscribe(conn,
1673 NULL, BT_INPUT_INTERFACE,
1674 NULL, NULL, NULL, 0,
1675 __bt_manager_event_filter,
1679 if (subs_input_id != -1) {
1680 g_dbus_connection_signal_unsubscribe(conn,
1690 int _bt_register_opp_server_subscribe_signal(GDBusConnection *conn,
1696 static int subs_opp_server_interface_added_id = -1;
1697 static int subs_opp_server_interface_removed_id = -1;
1698 static int subs_opp_server_property_id = -1;
1702 if (subs_opp_server_interface_added_id == -1) {
1703 subs_opp_server_interface_added_id = g_dbus_connection_signal_subscribe(conn,
1704 NULL, BT_MANAGER_INTERFACE,
1705 BT_INTERFACES_ADDED, NULL, NULL, 0,
1706 __bt_obexd_event_filter,
1709 if (subs_opp_server_interface_removed_id == -1) {
1710 subs_opp_server_interface_removed_id = g_dbus_connection_signal_subscribe(conn,
1711 NULL, BT_MANAGER_INTERFACE,
1712 BT_INTERFACES_REMOVED, NULL, NULL, 0,
1713 __bt_obexd_event_filter,
1716 if (subs_opp_server_property_id == -1) {
1717 subs_opp_server_property_id = g_dbus_connection_signal_subscribe(conn,
1718 NULL, BT_PROPERTIES_INTERFACE,
1719 BT_PROPERTIES_CHANGED, NULL, NULL, 0,
1720 __bt_obexd_event_filter,
1724 if (subs_opp_server_interface_added_id != -1) {
1725 g_dbus_connection_signal_unsubscribe(conn,
1726 subs_opp_server_interface_added_id);
1727 subs_opp_server_interface_added_id = -1;
1729 if (subs_opp_server_interface_removed_id != -1) {
1730 g_dbus_connection_signal_unsubscribe(conn,
1731 subs_opp_server_interface_removed_id);
1732 subs_opp_server_interface_removed_id = -1;
1734 if (subs_opp_server_property_id != -1) {
1735 g_dbus_connection_signal_unsubscribe(conn,
1736 subs_opp_server_property_id);
1737 subs_opp_server_property_id = -1;
1743 int _bt_register_opp_client_subscribe_signal(GDBusConnection *conn,
1749 static int subs_opp_client_interface_added_id = -1;
1750 static int subs_opp_client_interface_removed_id = -1;
1751 static int subs_opp_client_property_id = -1;
1755 if (subs_opp_client_interface_added_id == -1) {
1756 subs_opp_client_interface_added_id = g_dbus_connection_signal_subscribe(conn,
1757 NULL, BT_MANAGER_INTERFACE,
1758 BT_INTERFACES_ADDED, NULL, NULL, 0,
1759 __bt_opc_event_filter,
1762 if (subs_opp_client_interface_removed_id == -1) {
1763 subs_opp_client_interface_removed_id = g_dbus_connection_signal_subscribe(conn,
1764 NULL, BT_MANAGER_INTERFACE,
1765 BT_INTERFACES_REMOVED, NULL, NULL, 0,
1766 __bt_opc_event_filter,
1769 if (subs_opp_client_property_id == -1) {
1770 subs_opp_client_property_id = g_dbus_connection_signal_subscribe(conn,
1771 NULL, BT_PROPERTIES_INTERFACE,
1772 BT_PROPERTIES_CHANGED, NULL, NULL, 0,
1773 __bt_opc_event_filter,
1777 if (subs_opp_client_interface_added_id != -1) {
1778 g_dbus_connection_signal_unsubscribe(conn,
1779 subs_opp_client_interface_added_id);
1780 subs_opp_client_interface_added_id = -1;
1782 if (subs_opp_client_interface_removed_id != -1) {
1783 g_dbus_connection_signal_unsubscribe(conn,
1784 subs_opp_client_interface_removed_id);
1785 subs_opp_client_interface_removed_id = -1;
1787 if (subs_opp_client_property_id != -1) {
1788 g_dbus_connection_signal_unsubscribe(conn,
1789 subs_opp_client_property_id);
1790 subs_opp_client_property_id = -1;
1796 int _bt_register_map_client_subscribe_signal(GDBusConnection *conn,
1802 static int subs_map_client_interface_added_id = -1;
1803 static int subs_map_client_interface_removed_id = -1;
1804 static int subs_map_client_property_id = -1;
1808 if (subs_map_client_interface_added_id == -1) {
1809 subs_map_client_interface_added_id = g_dbus_connection_signal_subscribe(conn,
1810 NULL, BT_MANAGER_INTERFACE,
1811 BT_INTERFACES_ADDED, NULL, NULL, 0,
1812 __bt_map_event_filter,
1815 if (subs_map_client_interface_removed_id == -1) {
1816 subs_map_client_interface_removed_id = g_dbus_connection_signal_subscribe(conn,
1817 NULL, BT_MANAGER_INTERFACE,
1818 BT_INTERFACES_REMOVED, NULL, NULL, 0,
1819 __bt_map_event_filter,
1822 if (subs_map_client_property_id == -1) {
1823 subs_map_client_property_id = g_dbus_connection_signal_subscribe(conn,
1824 NULL, BT_PROPERTIES_INTERFACE,
1825 BT_PROPERTIES_CHANGED, NULL, NULL, 0,
1826 __bt_map_event_filter,
1830 if (subs_map_client_interface_added_id != -1) {
1831 g_dbus_connection_signal_unsubscribe(conn,
1832 subs_map_client_interface_added_id);
1833 subs_map_client_interface_added_id = -1;
1835 if (subs_map_client_interface_removed_id != -1) {
1836 g_dbus_connection_signal_unsubscribe(conn,
1837 subs_map_client_interface_removed_id);
1838 subs_map_client_interface_removed_id = -1;
1840 if (subs_map_client_property_id != -1) {
1841 g_dbus_connection_signal_unsubscribe(conn,
1842 subs_map_client_property_id);
1843 subs_map_client_property_id = -1;
1850 int _bt_register_service_event(GDBusConnection *g_conn, int event_type)
1854 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1856 switch (event_type) {
1857 case BT_MANAGER_EVENT:
1858 BT_DBG("BT_MANAGER_EVENT: register service event");
1859 _bt_register_manager_subscribe_signal(g_conn, TRUE);
1861 case BT_DEVICE_EVENT:
1862 BT_DBG("BT_DEVICE_EVENT: register service event");
1863 _bt_register_device_subscribe_signal(g_conn, TRUE);
1865 case BT_OPP_SERVER_EVENT:
1866 BT_DBG("BT_OPP_SERVER_EVENT: register service event");
1867 _bt_register_opp_server_subscribe_signal(g_conn, TRUE);
1869 case BT_OPP_CLIENT_EVENT:
1870 BT_DBG("BT_OPP_CLIENT_EVENT: register service event");
1871 _bt_register_opp_client_subscribe_signal(g_conn, TRUE);
1873 case BT_MAP_CLIENT_EVENT:
1874 BT_DBG("BT_MAP_CLIENT_EVENT: register service event");
1875 _bt_register_map_client_subscribe_signal(g_conn, TRUE);
1878 BT_ERR("Unknown event");
1879 return BLUETOOTH_ERROR_INTERNAL;
1882 return BLUETOOTH_ERROR_NONE;
1885 void _bt_unregister_service_event(GDBusConnection *g_conn, int event_type)
1889 ret_if(g_conn == NULL);
1891 switch (event_type) {
1892 case BT_MANAGER_EVENT:
1893 _bt_register_manager_subscribe_signal(g_conn, FALSE);
1894 _bt_register_device_subscribe_signal(g_conn, FALSE);
1895 _bt_register_input_subscribe_signal(g_conn, FALSE);
1897 case BT_OPP_SERVER_EVENT:
1898 _bt_register_opp_server_subscribe_signal(g_conn, FALSE);
1900 case BT_OPP_CLIENT_EVENT:
1901 _bt_register_opp_client_subscribe_signal(g_conn, FALSE);
1903 case BT_MAP_CLIENT_EVENT:
1904 _bt_register_map_client_subscribe_signal(g_conn, FALSE);
1907 BT_ERR("Unknown event");
1914 static int __bt_init_manager_receiver(void)
1918 GError *error = NULL;
1920 if (manager_conn == NULL) {
1921 manager_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
1922 if (error != NULL) {
1923 BT_ERR("ERROR: Can't get on system bus [%s]", error->message);
1924 g_clear_error(&error);
1926 retv_if(manager_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1929 if (_bt_register_service_event(manager_conn,
1930 BT_MANAGER_EVENT) != BLUETOOTH_ERROR_NONE)
1933 if (_bt_register_service_event(manager_conn,
1934 BT_DEVICE_EVENT) != BLUETOOTH_ERROR_NONE)
1937 return BLUETOOTH_ERROR_NONE;
1940 g_object_unref(manager_conn);
1941 manager_conn = NULL;
1946 return BLUETOOTH_ERROR_INTERNAL;
1949 static int __bt_init_obexd_receiver(void)
1952 if (!TIZEN_PROFILE_TV) { /* TODO: obexd doesn't work in TV profile. It should be resolved later. */
1953 GError *error = NULL;
1955 if (obexd_conn == NULL) {
1956 obexd_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
1957 if (error != NULL) {
1958 BT_ERR("ERROR: Can't get on session bus [%s]", error->message);
1959 g_clear_error(&error);
1961 retv_if(obexd_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1964 if (_bt_register_service_event(obexd_conn,
1965 BT_OPP_SERVER_EVENT) != BLUETOOTH_ERROR_NONE) {
1966 BT_ERR("Error while registering service event");
1967 g_object_unref(obexd_conn);
1969 return BLUETOOTH_ERROR_INTERNAL;
1975 return BLUETOOTH_ERROR_NONE;
1978 gboolean __bt_reinit_obexd_receiver(gpointer user_data)
1980 static int retry_cnt = 0;
1981 int result = BLUETOOTH_ERROR_NONE;
1985 result = __bt_init_obexd_receiver();
1986 if (result != BLUETOOTH_ERROR_NONE) {
1987 /* 20 ms * 50 = 10 seconds. During 10 seconds fail to initialize,
1988 then it is not the timing issue. Just can't use the session bus connection */
1989 if (retry_cnt > 100) {
1990 BT_ERR("Fail to init obexd receiver by 50 times.");
1992 session_reinit_timer = 0;
1996 BT_DBG("Retry to initialize the obexd receiver");
2001 session_reinit_timer = 0;
2008 /* To receive the event from bluez */
2009 int _bt_init_obex_event_receiver(void)
2015 result = __bt_init_manager_receiver();
2016 retv_if(result != BLUETOOTH_ERROR_NONE, result);
2018 result = __bt_init_obexd_receiver();
2019 if (result != BLUETOOTH_ERROR_NONE) {
2020 BT_ERR("Fail to init obexd receiver");
2022 /* Try to re-initialize obexd receiver in the timer */
2023 if (session_reinit_timer > 0)
2024 g_source_remove(session_reinit_timer);
2026 session_reinit_timer = g_timeout_add(200,
2027 (GSourceFunc)__bt_reinit_obexd_receiver, NULL);
2032 return BLUETOOTH_ERROR_NONE;
2035 void _bt_deinit_obex_event_receiver(void)
2039 _bt_unregister_service_event(manager_conn, BT_MANAGER_EVENT);
2041 _bt_unregister_service_event(obexd_conn, BT_OPP_SERVER_EVENT);
2044 g_object_unref(manager_conn);
2045 manager_conn = NULL;
2049 g_object_unref(obexd_conn);
2054 g_source_remove(event_id);