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 guint event_id;
50 static guint session_reinit_timer;
53 * obexd connection type
61 OBEX_PCSUITE = (1 << 6),
62 OBEX_SYNCEVOLUTION = (1 << 7),
65 } bluetooth_obex_connection_type_t;
68 void _bt_handle_property_changed_event(GVariant *msg, const char *object_path);
69 void _bt_opc_property_changed_event(GVariant *msg, char *path);
70 void _bt_map_property_changed_event(GVariant *msg, const char *path);
71 int _bt_register_service_event(GDBusConnection *g_conn, int event_type);
72 void _bt_unregister_service_event(GDBusConnection *g_conn, int event_type);
73 void _bt_opp_client_event_deinit(void);
74 void _bt_map_client_event_deinit(void);
75 void _bt_map_on_transfer_finished(const char *transfer_object_path, const int error);
77 /* Temp Adapter changes required to make OBEX work for handling device events here ,
78 This code will be removed and moved to OAL Event Handling part .
82 static void __bt_get_uuids(GVariant *value, bt_remote_dev_info_t *info)
84 ret_if(value == NULL);
89 info->uuids = g_variant_dup_strv(value, &uuid_count);
90 info->uuid_count = (unsigned int)uuid_count;
92 BT_DBG("uuid count : %d", uuid_count);
96 void _bt_convert_addr_string_to_secure_string(char *addr,
101 ret_if(address == NULL);
102 ret_if(addr == NULL);
104 len = strlen(address);
105 ret_if(len != BT_ADDRESS_STRING_SIZE - 1);
107 g_strlcpy(addr, address, BT_ADDRESS_STRING_SIZE);
115 bt_status_t _bt_adapter_get_status_for_Obex(void)
117 int value = VCONFKEY_BT_STATUS_OFF;
119 /* check VCONFKEY_BT_STATUS */
120 if (vconf_get_int(VCONFKEY_BT_STATUS, &value) != 0) {
121 BT_ERR("fail to get vconf key!");
122 return BLUETOOTH_ADAPTER_DISABLED;
128 static int __bt_get_owner_info(GVariant *msg, char **name,
129 char **previous, char **current)
131 g_variant_get(msg, "(sss)", name, previous, current);
132 return BLUETOOTH_ERROR_NONE;
135 static int __bt_get_agent_signal_info(GVariant *msg, char **address,
136 char **name, char **uuid)
138 g_variant_get(msg, "(sss)", address, name, uuid);
139 return BLUETOOTH_ERROR_NONE;
142 gboolean __bt_handle_is_flight_mode_enabled(void)
144 if (TIZEN_FEATURE_FLIGHTMODE_ENABLED) {
145 int is_flight_mode = 0;
147 ret = vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE, &is_flight_mode);
149 BT_ERR("vconf_get_bool failed");
151 return (is_flight_mode == 0) ? FALSE : TRUE;
157 void _bt_handle_adapter_event(GVariant *msg, const char *member)
160 ret_if(member == NULL);
162 if (strcasecmp(member, "DeviceCreated") == 0) {
163 char *object_path = NULL;
165 ret_if(_bt_is_device_creating() == FALSE);
167 /* Bonding from remote device */
168 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
170 g_variant_get(msg, "(&o)", &object_path);
171 _bt_convert_device_path_to_address((const char*)object_path, address);
174 } else if (strcasecmp(member, BT_HARDWARE_ERROR) == 0) {
175 BT_ERR_C("### Hardware error received from BLUEZ");
176 } else if (strcasecmp(member, BT_TX_TIMEOUT_ERROR) == 0) {
177 BT_ERR_C("### Tx timeout error received from BLUEZ");
182 static void __bt_obex_property_changed_event(GVariant *msg, const char *path)
186 GVariantIter value_iter;
187 GVariant *child = NULL, *val = NULL;
188 char *property = NULL;
189 g_variant_iter_init(&value_iter, msg);
190 while ((child = g_variant_iter_next_value(&value_iter))) {
191 g_variant_get(child, "{sv}", &property, &val);
193 ret_if(property == NULL);
195 BT_DBG("property :%s", property);
197 if (strcasecmp(property, "Status") == 0) {
199 g_variant_get(val, "s", &status);
201 if (strcasecmp(status, "active") == 0) {
202 _bt_obex_transfer_started(path);
203 } else if (strcasecmp(status, "complete") == 0) {
204 _bt_obex_transfer_completed(path, TRUE);
205 _bt_pbap_obex_transfer_completed(path, TRUE);
206 } else if (strcasecmp(status, "error") == 0) {
207 _bt_obex_transfer_completed(path, FALSE);
208 _bt_pbap_obex_transfer_completed(path, FALSE);
211 } else if (strcasecmp(property, "Transferred") == 0) {
212 guint64 transferred = 0;
213 /* As Transferred is expected guint64 so change int to guint64 and
214 * eariler transferred is static because of it can overwrite data
215 * on present on opc_obex_conn or obexd_conn as these are
216 * static memory are in sequential */
217 g_variant_get(val, "t", &transferred);
219 _bt_obex_transfer_progress(path, transferred);
221 /* TODO: MAP, "Complete"? see above */
223 g_variant_unref(val);
224 g_variant_unref(child);
229 void _bt_handle_property_changed_event(GVariant *msg, const char *object_path)
231 char *interface_name = NULL;
232 GVariant *val = NULL;
234 g_variant_get(msg, "(&s@a{sv}@as)", &interface_name, &val, NULL);
235 BT_DBG("_bt_handle_property_changed_event");
237 if (strcasecmp(interface_name, BT_ADAPTER_INTERFACE) == 0) {
238 gboolean ret = FALSE;
239 gboolean powered = FALSE;
241 /* Check if Adapter is disabled, cancle queued transfers if any */
242 ret = g_variant_lookup(msg, "Powered", "b", &powered);
244 _bt_cancel_queued_transfers();
245 } else if (strcasecmp(interface_name, BT_OBEX_TRANSFER_INTERFACE) == 0) {
246 BT_DBG("BT_OBEX_TRANSFER_INTERFACE");
247 __bt_obex_property_changed_event(val,
250 g_variant_unref(val);
253 void __bt_opc_property_changed_event(GVariant *msg,
256 GVariantIter value_iter;
257 char *property = NULL;
258 GVariant *val = NULL;
259 GVariant *child = NULL;
261 g_variant_iter_init(&value_iter, msg);
262 if ((child = g_variant_iter_next_value(&value_iter))) {
263 g_variant_get(child, "{sv}", &property, &val);
264 ret_if(property == NULL);
266 if (strcasecmp(property, "Status") == 0) {
268 g_variant_get(val, "s", &status);
269 BT_DBG("Status is %s", status);
271 if (strcasecmp(status, "active") == 0)
272 _bt_obex_client_started(path);
273 else if (strcasecmp(status, "complete") == 0)
274 _bt_obex_client_completed(path, TRUE);
275 else if (strcasecmp(status, "error") == 0)
276 _bt_obex_client_completed(path, FALSE);
279 } else if (strcasecmp(property, "Transferred") == 0) {
280 guint64 transferred = 0;
281 g_variant_get(val, "t", &transferred);
283 _bt_obex_client_progress(path, transferred);
285 BT_DBG("property : [%s]", property);
288 g_variant_unref(child);
289 g_variant_unref(val);
293 void _bt_opc_property_changed_event(GVariant *msg, char *path)
295 char *interface_name = NULL;
296 GVariant *value = NULL;
297 g_variant_get(msg, "(&s@a{sv}@as)", &interface_name, &value, NULL);
298 BT_INFO("interface_name = %s", interface_name);
299 if (strcasecmp(interface_name, BT_OBEX_TRANSFER_INTERFACE) == 0) {
300 __bt_opc_property_changed_event(value,
303 BT_DBG("interface_name : [%s]", interface_name);
305 g_variant_unref(value);
309 void __bt_map_property_changed_event(GVariant *msg,
313 GVariantIter value_iter;
314 char *property = NULL;
315 GVariant *val = NULL;
316 GVariant *child = NULL;
318 g_variant_iter_init(&value_iter, msg);
319 while ((child = g_variant_iter_next_value(&value_iter))) {
320 g_variant_get(child, "{sv}", &property, &val);
321 ret_if(property == NULL);
323 if (strcasecmp(property, "Status") == 0) {
325 g_variant_get(val, "s", &status);
326 BT_DBG("Status is %s", status);
328 if (strcasecmp(status, "active") == 0) {
329 BT_DBG("EVENT : STARTED");
330 // currently doing nothing
331 } else if (strcasecmp(status, "complete") == 0) {
332 BT_DBG("EVENT : COMPLETED");
333 _bt_map_on_transfer_finished(path, BLUETOOTH_ERROR_NONE);
334 } else if (strcasecmp(status, "error") == 0) {
335 BT_DBG("EVENT : FAILED");
336 _bt_map_on_transfer_finished(path, BLUETOOTH_ERROR_INTERNAL);
339 } else if (strcasecmp(property, "Transferred") == 0) {
340 guint64 transferred = 0;
341 g_variant_get(val, "t", &transferred);
343 BT_DBG("EVENT : PROGRESS CALLBACK");
344 // currently doing nothing - progress callback type is not used
346 BT_DBG("OTHER EVENT : property : [%s]", property);
349 g_variant_unref(child);
350 g_variant_unref(val);
354 void _bt_map_property_changed_event(GVariant *msg, const char *path)
356 BT_DBG("Entered _bt_map_property_changed_event");
357 char *interface_name = NULL;
358 GVariant *value = NULL;
359 g_variant_get(msg, "(&s@a{sv}@as)", &interface_name, &value, NULL);
360 BT_INFO("interface_name = %s", interface_name);
361 if (strcasecmp(interface_name, BT_OBEX_TRANSFER_INTERFACE) == 0) {
362 __bt_map_property_changed_event(value,
365 BT_DBG("interface_name : [%s]", interface_name);
367 g_variant_unref(value);
371 void _bt_handle_agent_event(GVariant *msg, const char *member)
373 int result = BLUETOOTH_ERROR_NONE;
374 char *address = NULL;
377 GVariant *param = NULL;
378 ret_if(member == NULL);
380 if (strcasecmp(member, "ObexAuthorize") == 0) {
381 __bt_get_agent_signal_info(msg, &address, &name, &uuid);
382 param = g_variant_new("(iss)", result, address, name);
383 _bt_send_event(BT_OPP_SERVER_EVENT,
384 BLUETOOTH_EVENT_OBEX_SERVER_CONNECTION_AUTHORIZE,
386 /* TODO: MAP? see above */
392 static int __bt_get_object_path(GVariant *msg, char **path)
394 g_variant_get(msg, "(o*)", path, NULL);
396 return BLUETOOTH_ERROR_INTERNAL;
398 return BLUETOOTH_ERROR_NONE;
401 char *_bt_get_bonded_device_name(char *address)
403 bt_remote_dev_info_t *dev_info;
405 retv_if(address == NULL, strdup(""));
407 dev_info = _bt_service_get_remote_dev_info(address);
408 retv_if(dev_info == NULL, strdup(""));
409 retv_if(dev_info->name == NULL, strdup(""));
411 return g_strdup(dev_info->name);
413 /* Temp Adapter Util changes to make OBEX work.
416 void _bt_handle_device_event(GVariant *msg, const char *member, const char *path)
419 char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 };
420 ret_if(path == NULL);
422 if (strcasecmp(member, "Disconnected") == 0) {
423 unsigned char disc_reason = 0;
424 unsigned char addr_type = 0;
425 char *dev_name = NULL;
426 gboolean sending = FALSE;
428 g_variant_get(msg, "(yys)", &addr_type, &disc_reason, &dev_name);
430 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
432 _bt_convert_device_path_to_address(path, address);
435 0x01 BDADDR_LE_PUBLIC
436 0x02 BDADDR_LE_RANDOM */
437 _bt_convert_addr_string_to_secure_string(secure_address, address);
438 BT_INFO("Address : %s Type : %d", secure_address, addr_type);
439 BT_ERR_C("### Disconnected [%s] [%d : %s] [%s]", !addr_type ? "BREDR" : "LE",
440 disc_reason, _bt_convert_disc_reason_to_string(disc_reason),
441 !addr_type ? dev_name : secure_address);
445 /*Check for any OPP transfer on the device and cancel
448 _bt_obex_check_pending_transfer(address);
449 _bt_opp_client_is_sending(&sending);
451 _bt_opp_client_check_pending_transfer(address);
452 /* TODO: MAP? see above */
455 } else if (strcasecmp(member, "ProfileStateChanged") == 0) {
457 char *profile_uuid = NULL;
458 bluetooth_device_address_t bd_addr;
460 g_variant_get(msg, "(si)", &profile_uuid, &state);
462 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
464 _bt_convert_device_path_to_address(path, address);
465 _bt_convert_addr_string_to_type(bd_addr.addr, address);
467 _bt_convert_addr_string_to_secure_string(secure_address, address);
468 BT_DBG("Address: %s", secure_address);
469 BT_DBG("Profile UUID: %s", profile_uuid);
470 BT_DBG("State: %d", state);
475 static void __bt_manager_event_filter(GDBusConnection *connection,
476 const gchar *sender_name,
477 const gchar *object_path,
478 const gchar *interface_name,
479 const gchar *signal_name,
480 GVariant *parameters,
485 char *obj_path = NULL;
487 if (signal_name == NULL)
490 if (strcasecmp(signal_name, "InterfacesAdded") == 0) {
491 g_variant_get(parameters, "(&o@a{sa{sv}})", &obj_path, &value);
493 if (strcasecmp(obj_path, BT_BLUEZ_HCI_PATH) == 0)
494 if (!TIZEN_FEATURE_BT_USB_DONGLE) {
495 if (_bt_register_obex_server() != BLUETOOTH_ERROR_NONE)
496 BT_ERR("Fail to init obex server");
498 g_variant_unref(value);
499 } else if (strcasecmp(signal_name, "InterfacesRemoved") == 0) {
500 if (TIZEN_FEATURE_BT_USB_DONGLE) {
501 if (_bt_unregister_obex_server() != BLUETOOTH_ERROR_NONE)
502 BT_ERR("Fail to unregister obex server");
504 } else if (strcasecmp(signal_name, "NameOwnerChanged") == 0) {
507 char *previous = NULL;
508 char *current = NULL;
510 if (__bt_get_owner_info(parameters, &name, &previous, ¤t)) {
511 BT_ERR("Fail to get the owner info");
515 if (*current != '\0') {
524 if (strcasecmp(name, BT_BLUEZ_NAME) == 0) {
525 BT_INFO_C("### Bluetoothd is terminated");
527 if (_bt_unregister_obex_server() != BLUETOOTH_ERROR_NONE)
528 BT_ERR("Fail to unregister obex server");
532 _bt_obex_server_check_allocation(&value);
535 /* Check if the obex server was terminated abnormally */
536 _bt_obex_server_check_termination(name);
542 } else if (g_strcmp0(interface_name, BT_AGENT_INTERFACE) == 0) {
543 _bt_handle_agent_event(parameters, signal_name);
544 } else if (g_strcmp0(interface_name, BT_DEVICE_INTERFACE) == 0) {
545 _bt_handle_device_event(parameters, signal_name, object_path);
551 static gboolean __bt_is_obexd_event(GVariant *msg, const char *interface)
554 if (g_strcmp0(interface, BT_PROPERTIES_INTERFACE) == 0) {
555 char *interface_name = NULL;
557 g_variant_get(msg, "(&s@a{sv}@as)", &interface_name, NULL, NULL);
558 retv_if(interface_name == NULL, FALSE);
560 if (strcasecmp(interface_name, BT_OBEX_TRANSFER_INTERFACE) == 0) {
561 BT_DBG("BT_OBEX_TRANSFER_INTERFACE");
569 static void __bt_obexd_event_filter(GDBusConnection *connection,
570 const gchar *sender_name,
571 const gchar *object_path,
572 const gchar *interface_name,
573 const gchar *signal_name,
574 GVariant *parameters,
577 const char *member = signal_name;
578 char *obj_path = NULL;
579 ret_if(member == NULL);
581 if (strcasecmp(member, "InterfacesAdded") == 0) {
582 if (__bt_get_object_path(parameters, &obj_path)) {
583 BT_ERR("Fail to get the path");
586 BT_INFO("object_path = [%s]", obj_path);
588 /*Handle OPP_SERVER_CONNECTED_EVENT here */
589 /* TODO: MAP? see above */
590 if (strncmp(obj_path, BT_SESSION_BASEPATH_SERVER,
591 strlen(BT_SESSION_BASEPATH_SERVER)) != 0) {
596 if (g_strrstr(obj_path, "session") && g_strrstr(obj_path, "transfer")) {
597 BT_DBG("Obex_Server_Session_Transfer connected");
598 _bt_obex_transfer_connected(obj_path);
601 } else if (strcasecmp(member, "InterfacesRemoved") == 0) {
602 /*Handle OPP_SERVER_DISCONNECTED_EVENT here */
603 /* TODO: MAP? see above */
604 if (__bt_get_object_path(parameters, &obj_path)) {
605 BT_ERR("Fail to get the path");
608 BT_INFO("object_path = [%s]", obj_path);
610 if (strncmp(obj_path, BT_SESSION_BASEPATH_CLIENT,
611 strlen(BT_SESSION_BASEPATH_CLIENT)) == 0) {
612 BT_DBG("Call PBAP Disconnected");
613 _bt_obex_pbap_client_disconnect(obj_path);
616 if (strncmp(obj_path, BT_SESSION_BASEPATH_SERVER,
617 strlen(BT_SESSION_BASEPATH_SERVER)) != 0) {
622 if (g_strrstr(obj_path, "session") && g_strrstr(obj_path, "transfer")) {
623 BT_DBG("Obex_Server_Session_Transfer disconnected %s",
626 _bt_obex_transfer_disconnected(obj_path);
629 } else if (__bt_is_obexd_event(parameters, interface_name) == TRUE) {
630 const char *path = object_path;
632 if (strncmp(path, BT_SESSION_BASEPATH_SERVER,
633 strlen(BT_SESSION_BASEPATH_SERVER)) != 0 &&
634 strncmp(path, BT_SESSION_BASEPATH_CLIENT,
635 strlen(BT_SESSION_BASEPATH_CLIENT)) != 0) {
636 BT_DBG("DBUS_HANDLER_RESULT_NOT_YET_HANDLED");
640 _bt_handle_property_changed_event(parameters, path);
645 static gboolean __bt_is_obexd_client_event(GVariant *msg, const char *interface)
649 if (g_strcmp0(interface, BT_PROPERTIES_INTERFACE) == 0) {
650 char *interface_name = NULL;
652 g_variant_get(msg, "(&s@a{sv}@as)", &interface_name, NULL, NULL);
654 retv_if(interface_name == NULL, FALSE);
656 if (strcasecmp(interface_name,
657 BT_OBEX_TRANSFER_INTERFACE) == 0) {
668 static void __bt_opc_event_filter(GDBusConnection *connection,
669 const gchar *sender_name,
670 const gchar *object_path,
671 const gchar *interface_name,
672 const gchar *signal_name,
673 GVariant *parameters,
676 const char *member = signal_name;
677 char *obj_path = NULL;
678 if (strcasecmp(member, "InterfacesAdded") == 0) {
679 BT_DBG("InterfacesAdded");
680 } else if (strcasecmp(member, "InterfacesRemoved") == 0) {
682 if (__bt_get_object_path(parameters, &obj_path)) {
683 BT_ERR("Fail to get the path");
687 BT_DBG("object_path = %s", obj_path);
689 if (strncmp(obj_path, BT_SESSION_BASEPATH_CLIENT,
690 strlen(BT_SESSION_BASEPATH_CLIENT)) != 0
691 || strstr(obj_path, "transfer") == NULL) {
694 } else if (strncmp(obj_path, BT_SESSION_BASEPATH_CLIENT,
695 strlen(BT_SESSION_BASEPATH_CLIENT)) == 0) {
696 BT_DBG("Going to call opc disconnected");
697 _bt_opc_disconnected(obj_path);
702 } else if (__bt_is_obexd_client_event(parameters, interface_name) == TRUE) {
703 char *path = (char *)object_path;
704 BT_INFO("object_path %s", path);
705 if (strncmp(path, BT_SESSION_BASEPATH_CLIENT,
706 strlen(BT_SESSION_BASEPATH_CLIENT)) != 0) {
707 BT_DBG("NOT BT_SESSION_BASEPATH_CLIENT");
711 _bt_opc_property_changed_event(parameters, path);
717 int _bt_opp_client_event_init(void)
719 GError *error = NULL;
721 if (opc_obexd_conn == NULL) {
722 opc_obexd_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
724 if (!opc_obexd_conn) {
726 BT_ERR("Unable to connect to dbus: %s", error->message);
727 g_clear_error(&error);
729 return BLUETOOTH_ERROR_INTERNAL;
733 if (_bt_register_service_event(opc_obexd_conn,
734 BT_OPP_CLIENT_EVENT) != BLUETOOTH_ERROR_NONE) {
735 g_object_unref(opc_obexd_conn);
736 opc_obexd_conn = NULL;
737 return BLUETOOTH_ERROR_INTERNAL;
740 return BLUETOOTH_ERROR_NONE;
743 void _bt_opp_client_event_deinit(void)
745 if (opc_obexd_conn) {
746 _bt_unregister_service_event(opc_obexd_conn,
747 BT_OPP_CLIENT_EVENT);
748 g_object_unref(opc_obexd_conn);
749 opc_obexd_conn = NULL;
753 static void __bt_map_event_filter(GDBusConnection *connection,
754 const gchar *sender_name,
755 const gchar *object_path,
756 const gchar *interface_name,
757 const gchar *signal_name,
758 GVariant *parameters,
761 BT_DBG("Entered __bt_map_event_filter");
762 const char *member = signal_name;
764 if (strcasecmp(member, "InterfacesAdded") == 0) {
765 BT_DBG("------------------------------------ADDED------------------------------------");
766 // currently doing nothing
767 } else if (strcasecmp(member, "InterfacesRemoved") == 0) {
768 BT_DBG("------------------------------------REMOVED------------------------------------");
769 // TODO check if something should be called here?
770 //_bt_map_on_transfer_finished(object_path, error);
771 } else if (__bt_is_obexd_client_event(parameters, interface_name) == TRUE) {
772 BT_DBG("------------------------------------CLIENT EVENT------------------------------------");
773 _bt_map_property_changed_event(parameters, object_path);
779 int _bt_map_client_event_init(void)
781 GError *error = NULL;
783 if (map_obexd_conn == NULL) {
784 map_obexd_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
786 if (!map_obexd_conn) {
788 BT_ERR("Unable to connect to dbus: %s", error->message);
789 g_clear_error(&error);
791 return BLUETOOTH_ERROR_INTERNAL;
795 if (_bt_register_service_event(map_obexd_conn,
796 BT_MAP_CLIENT_EVENT) != BLUETOOTH_ERROR_NONE) {
797 g_object_unref(map_obexd_conn);
798 map_obexd_conn = NULL;
799 return BLUETOOTH_ERROR_INTERNAL;
802 return BLUETOOTH_ERROR_NONE;
805 void _bt_map_client_event_deinit(void)
807 if (map_obexd_conn) {
808 _bt_unregister_service_event(map_obexd_conn,
809 BT_MAP_CLIENT_EVENT);
810 g_object_unref(map_obexd_conn);
811 map_obexd_conn = NULL;
815 int _bt_register_manager_subscribe_signal(GDBusConnection *conn,
821 static int subs_interface_added_id = -1;
822 static int subs_interface_removed_id = -1;
823 static int subs_name_owner_changed = -1;
826 if (subs_interface_added_id == -1) {
827 subs_interface_added_id = g_dbus_connection_signal_subscribe(conn,
828 NULL, BT_MANAGER_INTERFACE,
829 BT_INTERFACES_ADDED, NULL, NULL, 0,
830 __bt_manager_event_filter,
833 if (subs_interface_removed_id == -1) {
834 subs_interface_removed_id = g_dbus_connection_signal_subscribe(conn,
835 NULL, BT_MANAGER_INTERFACE,
836 BT_INTERFACES_REMOVED, NULL, NULL, 0,
837 __bt_manager_event_filter,
840 if (subs_name_owner_changed == -1) {
841 subs_name_owner_changed = g_dbus_connection_signal_subscribe(conn,
842 NULL, BT_EVENT_FREEDESKTOP,
843 BT_NAME_OWNER_CHANGED, NULL, NULL, 0,
844 __bt_manager_event_filter, NULL, NULL);
848 if (subs_interface_added_id != -1) {
849 g_dbus_connection_signal_unsubscribe(conn,
850 subs_interface_added_id);
851 subs_interface_added_id = -1;
853 if (subs_interface_removed_id != -1) {
854 g_dbus_connection_signal_unsubscribe(conn,
855 subs_interface_removed_id);
856 subs_interface_removed_id = -1;
858 if (subs_name_owner_changed != -1) {
859 g_dbus_connection_signal_unsubscribe(conn,
860 subs_name_owner_changed);
861 subs_name_owner_changed = -1;
868 int _bt_register_device_subscribe_signal(GDBusConnection *conn,
874 static int subs_device_id = -1;
877 if (subs_device_id == -1) {
878 subs_device_id = g_dbus_connection_signal_subscribe(conn,
879 NULL, BT_DEVICE_INTERFACE,
881 __bt_manager_event_filter,
885 if (subs_device_id != -1) {
886 g_dbus_connection_signal_unsubscribe(conn,
894 int _bt_register_input_subscribe_signal(GDBusConnection *conn,
900 static int subs_input_id = -1;
903 if (subs_input_id == -1) {
904 subs_input_id = g_dbus_connection_signal_subscribe(conn,
905 NULL, BT_INPUT_INTERFACE,
907 __bt_manager_event_filter,
911 if (subs_input_id != -1) {
912 g_dbus_connection_signal_unsubscribe(conn,
922 int _bt_register_opp_server_subscribe_signal(GDBusConnection *conn,
928 static int subs_opp_server_interface_added_id = -1;
929 static int subs_opp_server_interface_removed_id = -1;
930 static int subs_opp_server_property_id = -1;
934 if (subs_opp_server_interface_added_id == -1) {
935 subs_opp_server_interface_added_id = g_dbus_connection_signal_subscribe(conn,
936 NULL, BT_MANAGER_INTERFACE,
937 BT_INTERFACES_ADDED, NULL, NULL, 0,
938 __bt_obexd_event_filter,
941 if (subs_opp_server_interface_removed_id == -1) {
942 subs_opp_server_interface_removed_id = g_dbus_connection_signal_subscribe(conn,
943 NULL, BT_MANAGER_INTERFACE,
944 BT_INTERFACES_REMOVED, NULL, NULL, 0,
945 __bt_obexd_event_filter,
948 if (subs_opp_server_property_id == -1) {
949 subs_opp_server_property_id = g_dbus_connection_signal_subscribe(conn,
950 NULL, BT_PROPERTIES_INTERFACE,
951 BT_PROPERTIES_CHANGED, NULL, NULL, 0,
952 __bt_obexd_event_filter,
956 if (subs_opp_server_interface_added_id != -1) {
957 g_dbus_connection_signal_unsubscribe(conn,
958 subs_opp_server_interface_added_id);
959 subs_opp_server_interface_added_id = -1;
961 if (subs_opp_server_interface_removed_id != -1) {
962 g_dbus_connection_signal_unsubscribe(conn,
963 subs_opp_server_interface_removed_id);
964 subs_opp_server_interface_removed_id = -1;
966 if (subs_opp_server_property_id != -1) {
967 g_dbus_connection_signal_unsubscribe(conn,
968 subs_opp_server_property_id);
969 subs_opp_server_property_id = -1;
975 int _bt_register_opp_client_subscribe_signal(GDBusConnection *conn,
981 static int subs_opp_client_interface_added_id = -1;
982 static int subs_opp_client_interface_removed_id = -1;
983 static int subs_opp_client_property_id = -1;
987 if (subs_opp_client_interface_added_id == -1) {
988 subs_opp_client_interface_added_id = g_dbus_connection_signal_subscribe(conn,
989 NULL, BT_MANAGER_INTERFACE,
990 BT_INTERFACES_ADDED, NULL, NULL, 0,
991 __bt_opc_event_filter,
994 if (subs_opp_client_interface_removed_id == -1) {
995 subs_opp_client_interface_removed_id = g_dbus_connection_signal_subscribe(conn,
996 NULL, BT_MANAGER_INTERFACE,
997 BT_INTERFACES_REMOVED, NULL, NULL, 0,
998 __bt_opc_event_filter,
1001 if (subs_opp_client_property_id == -1) {
1002 subs_opp_client_property_id = g_dbus_connection_signal_subscribe(conn,
1003 NULL, BT_PROPERTIES_INTERFACE,
1004 BT_PROPERTIES_CHANGED, NULL, NULL, 0,
1005 __bt_opc_event_filter,
1009 if (subs_opp_client_interface_added_id != -1) {
1010 g_dbus_connection_signal_unsubscribe(conn,
1011 subs_opp_client_interface_added_id);
1012 subs_opp_client_interface_added_id = -1;
1014 if (subs_opp_client_interface_removed_id != -1) {
1015 g_dbus_connection_signal_unsubscribe(conn,
1016 subs_opp_client_interface_removed_id);
1017 subs_opp_client_interface_removed_id = -1;
1019 if (subs_opp_client_property_id != -1) {
1020 g_dbus_connection_signal_unsubscribe(conn,
1021 subs_opp_client_property_id);
1022 subs_opp_client_property_id = -1;
1028 int _bt_register_map_client_subscribe_signal(GDBusConnection *conn,
1034 static int subs_map_client_interface_added_id = -1;
1035 static int subs_map_client_interface_removed_id = -1;
1036 static int subs_map_client_property_id = -1;
1040 if (subs_map_client_interface_added_id == -1) {
1041 subs_map_client_interface_added_id = g_dbus_connection_signal_subscribe(conn,
1042 NULL, BT_MANAGER_INTERFACE,
1043 BT_INTERFACES_ADDED, NULL, NULL, 0,
1044 __bt_map_event_filter,
1047 if (subs_map_client_interface_removed_id == -1) {
1048 subs_map_client_interface_removed_id = g_dbus_connection_signal_subscribe(conn,
1049 NULL, BT_MANAGER_INTERFACE,
1050 BT_INTERFACES_REMOVED, NULL, NULL, 0,
1051 __bt_map_event_filter,
1054 if (subs_map_client_property_id == -1) {
1055 subs_map_client_property_id = g_dbus_connection_signal_subscribe(conn,
1056 NULL, BT_PROPERTIES_INTERFACE,
1057 BT_PROPERTIES_CHANGED, NULL, NULL, 0,
1058 __bt_map_event_filter,
1062 if (subs_map_client_interface_added_id != -1) {
1063 g_dbus_connection_signal_unsubscribe(conn,
1064 subs_map_client_interface_added_id);
1065 subs_map_client_interface_added_id = -1;
1067 if (subs_map_client_interface_removed_id != -1) {
1068 g_dbus_connection_signal_unsubscribe(conn,
1069 subs_map_client_interface_removed_id);
1070 subs_map_client_interface_removed_id = -1;
1072 if (subs_map_client_property_id != -1) {
1073 g_dbus_connection_signal_unsubscribe(conn,
1074 subs_map_client_property_id);
1075 subs_map_client_property_id = -1;
1082 int _bt_register_service_event(GDBusConnection *g_conn, int event_type)
1086 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1088 switch (event_type) {
1089 case BT_MANAGER_EVENT:
1090 BT_DBG("BT_MANAGER_EVENT: register service event");
1091 _bt_register_manager_subscribe_signal(g_conn, TRUE);
1093 case BT_DEVICE_EVENT:
1094 BT_DBG("BT_DEVICE_EVENT: register service event");
1095 _bt_register_device_subscribe_signal(g_conn, TRUE);
1097 case BT_OPP_SERVER_EVENT:
1098 BT_DBG("BT_OPP_SERVER_EVENT: register service event");
1099 _bt_register_opp_server_subscribe_signal(g_conn, TRUE);
1101 case BT_OPP_CLIENT_EVENT:
1102 BT_DBG("BT_OPP_CLIENT_EVENT: register service event");
1103 _bt_register_opp_client_subscribe_signal(g_conn, TRUE);
1105 case BT_MAP_CLIENT_EVENT:
1106 BT_DBG("BT_MAP_CLIENT_EVENT: register service event");
1107 _bt_register_map_client_subscribe_signal(g_conn, TRUE);
1110 BT_ERR("Unknown event");
1111 return BLUETOOTH_ERROR_INTERNAL;
1114 return BLUETOOTH_ERROR_NONE;
1117 void _bt_unregister_service_event(GDBusConnection *g_conn, int event_type)
1121 ret_if(g_conn == NULL);
1123 switch (event_type) {
1124 case BT_MANAGER_EVENT:
1125 _bt_register_manager_subscribe_signal(g_conn, FALSE);
1126 _bt_register_device_subscribe_signal(g_conn, FALSE);
1127 _bt_register_input_subscribe_signal(g_conn, FALSE);
1129 case BT_OPP_SERVER_EVENT:
1130 _bt_register_opp_server_subscribe_signal(g_conn, FALSE);
1132 case BT_OPP_CLIENT_EVENT:
1133 _bt_register_opp_client_subscribe_signal(g_conn, FALSE);
1135 case BT_MAP_CLIENT_EVENT:
1136 _bt_register_map_client_subscribe_signal(g_conn, FALSE);
1139 BT_ERR("Unknown event");
1146 static int __bt_init_manager_receiver(void)
1150 GError *error = NULL;
1152 if (manager_conn == NULL) {
1153 manager_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
1154 if (error != NULL) {
1155 BT_ERR("ERROR: Can't get on system bus [%s]", error->message);
1156 g_clear_error(&error);
1158 retv_if(manager_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1161 if (_bt_register_service_event(manager_conn,
1162 BT_MANAGER_EVENT) != BLUETOOTH_ERROR_NONE)
1165 if (_bt_register_service_event(manager_conn,
1166 BT_DEVICE_EVENT) != BLUETOOTH_ERROR_NONE)
1169 return BLUETOOTH_ERROR_NONE;
1172 g_object_unref(manager_conn);
1173 manager_conn = NULL;
1178 return BLUETOOTH_ERROR_INTERNAL;
1181 static int __bt_init_obexd_receiver(void)
1184 if (!TIZEN_PROFILE_TV) { /* TODO: obexd doesn't work in TV profile. It should be resolved later. */
1185 GError *error = NULL;
1187 if (obexd_conn == NULL) {
1188 obexd_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
1189 if (error != NULL) {
1190 BT_ERR("ERROR: Can't get on session bus [%s]", error->message);
1191 g_clear_error(&error);
1193 retv_if(obexd_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1196 if (_bt_register_service_event(obexd_conn,
1197 BT_OPP_SERVER_EVENT) != BLUETOOTH_ERROR_NONE) {
1198 BT_ERR("Error while registering service event");
1199 g_object_unref(obexd_conn);
1201 return BLUETOOTH_ERROR_INTERNAL;
1207 return BLUETOOTH_ERROR_NONE;
1210 gboolean __bt_reinit_obexd_receiver(gpointer user_data)
1212 static int retry_cnt = 0;
1213 int result = BLUETOOTH_ERROR_NONE;
1217 result = __bt_init_obexd_receiver();
1218 if (result != BLUETOOTH_ERROR_NONE) {
1219 /* 20 ms * 50 = 10 seconds. During 10 seconds fail to initialize,
1220 then it is not the timing issue. Just can't use the session bus connection */
1221 if (retry_cnt > 100) {
1222 BT_ERR("Fail to init obexd receiver by 50 times.");
1224 session_reinit_timer = 0;
1228 BT_DBG("Retry to initialize the obexd receiver");
1233 session_reinit_timer = 0;
1240 /* To receive the event from bluez */
1241 int _bt_init_obex_event_receiver(void)
1247 result = __bt_init_manager_receiver();
1248 retv_if(result != BLUETOOTH_ERROR_NONE, result);
1250 result = __bt_init_obexd_receiver();
1251 if (result != BLUETOOTH_ERROR_NONE) {
1252 BT_ERR("Fail to init obexd receiver");
1254 /* Try to re-initialize obexd receiver in the timer */
1255 if (session_reinit_timer > 0)
1256 g_source_remove(session_reinit_timer);
1258 session_reinit_timer = g_timeout_add(200,
1259 (GSourceFunc)__bt_reinit_obexd_receiver, NULL);
1264 return BLUETOOTH_ERROR_NONE;
1267 void _bt_deinit_obex_event_receiver(void)
1271 _bt_unregister_service_event(manager_conn, BT_MANAGER_EVENT);
1273 _bt_unregister_service_event(obexd_conn, BT_OPP_SERVER_EVENT);
1276 g_object_unref(manager_conn);
1277 manager_conn = NULL;
1281 g_object_unref(obexd_conn);
1286 g_source_remove(event_id);