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"
37 #include "bt-service-dpm.h"
39 #define DBUS_TIMEOUT 20 * 1000 /* 20 Sec */
40 static GDBusConnection *manager_conn;
41 static GDBusConnection *obexd_conn;
42 static GDBusConnection *opc_obexd_conn;
43 static GDBusConnection *map_obexd_conn;
45 static guint event_id;
47 static guint session_reinit_timer;
50 * obexd connection type
58 OBEX_PCSUITE = (1 << 6),
59 OBEX_SYNCEVOLUTION = (1 << 7),
62 } bluetooth_obex_connection_type_t;
65 void _bt_handle_property_changed_event(GVariant *msg, const char *object_path);
66 void _bt_opc_property_changed_event(GVariant *msg, char *path);
67 void _bt_map_property_changed_event(GVariant *msg, const char *path);
68 int _bt_register_service_event(GDBusConnection *g_conn, int event_type);
69 void _bt_unregister_service_event(GDBusConnection *g_conn, int event_type);
70 void _bt_opp_client_event_deinit(void);
71 void _bt_map_client_event_deinit(void);
72 void _bt_map_on_transfer_finished(const char *transfer_object_path, const int error);
74 /* Temp Adapter changes required to make OBEX work for handling device events here ,
75 This code will be removed and moved to OAL Event Handling part .
78 void _bt_convert_addr_string_to_secure_string(char *addr,
83 ret_if(address == NULL);
86 len = strlen(address);
87 ret_if(len != BT_ADDRESS_STRING_SIZE - 1);
89 strncpy(addr, address, len);
104 bt_status_t _bt_adapter_get_status_for_Obex(void)
106 int value = VCONFKEY_BT_STATUS_OFF;
108 /* check VCONFKEY_BT_STATUS */
109 if (vconf_get_int(VCONFKEY_BT_STATUS, &value) != 0) {
110 BT_ERR("fail to get vconf key!");
111 return BLUETOOTH_ADAPTER_DISABLED;
117 static int __bt_get_owner_info(GVariant *msg, char **name,
118 char **previous, char **current)
120 g_variant_get(msg, "(&s&s&s)", name, previous, current);
121 return BLUETOOTH_ERROR_NONE;
124 static int __bt_get_agent_signal_info(GVariant *msg, char **address,
125 char **name, char **uuid)
127 g_variant_get(msg, "(&s&s&s)", address, name, uuid);
128 return BLUETOOTH_ERROR_NONE;
131 gboolean __bt_handle_is_flight_mode_enabled(void)
133 if (TIZEN_FEATURE_FLIGHTMODE_ENABLED) {
134 int is_flight_mode = 0;
136 ret = vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE, &is_flight_mode);
138 BT_ERR("vconf_get_bool failed");
140 return (is_flight_mode == 0) ? FALSE : TRUE;
146 void _bt_handle_adapter_event(GVariant *msg, const char *member)
149 ret_if(member == NULL);
151 if (strcasecmp(member, "DeviceCreated") == 0) {
152 char *object_path = NULL;
154 ret_if(_bt_is_device_creating() == FALSE);
156 /* Bonding from remote device */
157 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
159 g_variant_get(msg, "(&o)", &object_path);
160 _bt_convert_device_path_to_address((const char*)object_path, address);
163 } else if (strcasecmp(member, BT_HARDWARE_ERROR) == 0) {
164 BT_ERR_C("### Hardware error received from BLUEZ");
165 } else if (strcasecmp(member, BT_TX_TIMEOUT_ERROR) == 0) {
166 BT_ERR_C("### Tx timeout error received from BLUEZ");
171 static void __bt_obex_property_changed_event(GVariant *msg, const char *path)
175 GVariantIter value_iter;
176 GVariant *child = NULL, *val = NULL;
177 char *property = NULL;
178 g_variant_iter_init(&value_iter, msg);
179 while ((child = g_variant_iter_next_value(&value_iter))) {
180 g_variant_get(child, "{sv}", &property, &val);
182 ret_if(property == NULL);
184 BT_DBG("property :%s", property);
186 if (strcasecmp(property, "Status") == 0) {
188 g_variant_get(val, "s", &status);
190 if (strcasecmp(status, "active") == 0) {
191 _bt_obex_transfer_started(path);
192 } else if (strcasecmp(status, "complete") == 0) {
193 _bt_obex_transfer_completed(path, TRUE);
194 _bt_pbap_obex_transfer_completed(path, TRUE);
195 } else if (strcasecmp(status, "error") == 0) {
196 _bt_obex_transfer_completed(path, FALSE);
197 _bt_pbap_obex_transfer_completed(path, FALSE);
200 } else if (strcasecmp(property, "Transferred") == 0) {
201 guint64 transferred = 0;
202 /* As Transferred is expected guint64 so change int to guint64 and
203 * eariler transferred is static because of it can overwrite data
204 * on present on opc_obex_conn or obexd_conn as these are
205 * static memory are in sequential */
206 g_variant_get(val, "t", &transferred);
208 _bt_obex_transfer_progress(path, transferred);
210 /* TODO: MAP, "Complete"? see above */
212 g_variant_unref(val);
213 g_variant_unref(child);
218 void _bt_handle_property_changed_event(GVariant *msg, const char *object_path)
220 char *interface_name = NULL;
221 GVariant *val = NULL;
223 g_variant_get(msg, "(&s@a{sv}@as)", &interface_name, &val, NULL);
224 BT_DBG("_bt_handle_property_changed_event");
226 if (strcasecmp(interface_name, BT_ADAPTER_INTERFACE) == 0) {
227 gboolean ret = FALSE;
228 gboolean powered = FALSE;
230 /* Check if Adapter is disabled, cancle queued transfers if any */
231 ret = g_variant_lookup(msg, "Powered", "b", &powered);
233 _bt_cancel_queued_transfers();
234 } else if (strcasecmp(interface_name, BT_OBEX_TRANSFER_INTERFACE) == 0) {
235 BT_DBG("BT_OBEX_TRANSFER_INTERFACE");
236 __bt_obex_property_changed_event(val,
239 g_variant_unref(val);
242 void __bt_opc_property_changed_event(GVariant *msg,
245 GVariantIter value_iter;
246 char *property = NULL;
247 GVariant *val = NULL;
248 GVariant *child = NULL;
250 g_variant_iter_init(&value_iter, msg);
251 if ((child = g_variant_iter_next_value(&value_iter))) {
252 g_variant_get(child, "{sv}", &property, &val);
253 ret_if(property == NULL);
255 if (strcasecmp(property, "Status") == 0) {
257 g_variant_get(val, "s", &status);
258 BT_DBG("Status is %s", status);
260 if (strcasecmp(status, "active") == 0)
261 _bt_obex_client_started(path);
262 else if (strcasecmp(status, "complete") == 0)
263 _bt_obex_client_completed(path, TRUE);
264 else if (strcasecmp(status, "error") == 0)
265 _bt_obex_client_completed(path, FALSE);
268 } else if (strcasecmp(property, "Transferred") == 0) {
269 guint64 transferred = 0;
270 g_variant_get(val, "t", &transferred);
272 _bt_obex_client_progress(path, transferred);
274 BT_DBG("property : [%s]", property);
277 g_variant_unref(child);
278 g_variant_unref(val);
282 void _bt_opc_property_changed_event(GVariant *msg, char *path)
284 char *interface_name = NULL;
285 GVariant *value = NULL;
286 g_variant_get(msg, "(&s@a{sv}@as)", &interface_name, &value, NULL);
287 BT_INFO("interface_name = %s", interface_name);
288 if (strcasecmp(interface_name, BT_OBEX_TRANSFER_INTERFACE) == 0) {
289 __bt_opc_property_changed_event(value,
292 BT_DBG("interface_name : [%s]", interface_name);
294 g_variant_unref(value);
298 void __bt_map_property_changed_event(GVariant *msg,
302 GVariantIter value_iter;
303 char *property = NULL;
304 GVariant *val = NULL;
305 GVariant *child = NULL;
307 g_variant_iter_init(&value_iter, msg);
308 while ((child = g_variant_iter_next_value(&value_iter))) {
309 g_variant_get(child, "{sv}", &property, &val);
310 ret_if(property == NULL);
312 if (strcasecmp(property, "Status") == 0) {
314 g_variant_get(val, "s", &status);
315 BT_DBG("Status is %s", status);
317 if (strcasecmp(status, "active") == 0) {
318 BT_DBG("EVENT : STARTED");
319 // currently doing nothing
320 } else if (strcasecmp(status, "complete") == 0) {
321 BT_DBG("EVENT : COMPLETED");
322 _bt_map_on_transfer_finished(path, BLUETOOTH_ERROR_NONE);
323 } else if (strcasecmp(status, "error") == 0) {
324 BT_DBG("EVENT : FAILED");
325 _bt_map_on_transfer_finished(path, BLUETOOTH_ERROR_INTERNAL);
328 } else if (strcasecmp(property, "Transferred") == 0) {
329 guint64 transferred = 0;
330 g_variant_get(val, "t", &transferred);
332 BT_DBG("EVENT : PROGRESS CALLBACK");
333 // currently doing nothing - progress callback type is not used
335 BT_DBG("OTHER EVENT : property : [%s]", property);
338 g_variant_unref(child);
339 g_variant_unref(val);
343 void _bt_map_property_changed_event(GVariant *msg, const char *path)
345 BT_DBG("Entered _bt_map_property_changed_event");
346 char *interface_name = NULL;
347 GVariant *value = NULL;
348 g_variant_get(msg, "(&s@a{sv}@as)", &interface_name, &value, NULL);
349 BT_INFO("interface_name = %s", interface_name);
350 if (strcasecmp(interface_name, BT_OBEX_TRANSFER_INTERFACE) == 0) {
351 __bt_map_property_changed_event(value,
354 BT_DBG("interface_name : [%s]", interface_name);
356 g_variant_unref(value);
360 void _bt_handle_agent_event(GVariant *msg, const char *member)
362 int result = BLUETOOTH_ERROR_NONE;
363 char *address = NULL;
366 GVariant *param = NULL;
367 ret_if(member == NULL);
369 if (strcasecmp(member, "ObexAuthorize") == 0) {
370 __bt_get_agent_signal_info(msg, &address, &name, &uuid);
371 param = g_variant_new("(iss)", result, address, name);
372 _bt_send_event(BT_OPP_SERVER_EVENT,
373 BLUETOOTH_EVENT_OBEX_SERVER_CONNECTION_AUTHORIZE,
375 /* TODO: MAP? see above */
379 static int __bt_get_object_path(GVariant *msg, char **path)
381 g_variant_get(msg, "(o*)", path, NULL);
383 return BLUETOOTH_ERROR_INTERNAL;
385 return BLUETOOTH_ERROR_NONE;
388 char *_bt_get_bonded_device_name(char *address)
390 bt_remote_dev_info_t *dev_info;
392 retv_if(address == NULL, strdup(""));
394 dev_info = _bt_service_get_remote_dev_info(address);
395 retv_if(dev_info == NULL, strdup(""));
396 retv_if(dev_info->name == NULL, strdup(""));
398 return g_strdup(dev_info->name);
400 /* Temp Adapter Util changes to make OBEX work.
403 void _bt_handle_device_event(GVariant *msg, const char *member, const char *path)
406 ret_if(path == NULL);
408 if (strcasecmp(member, "Disconnected") == 0) {
409 unsigned char disc_reason = 0;
410 unsigned char addr_type = 0;
411 char *dev_name = NULL;
412 gboolean sending = FALSE;
414 g_variant_get(msg, "(yys)", &addr_type, &disc_reason, &dev_name);
416 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
418 _bt_convert_device_path_to_address(path, address);
421 /*Check for any OPP transfer on the device and cancel
424 _bt_obex_check_pending_transfer(address);
425 _bt_opp_client_is_sending(&sending);
427 _bt_opp_client_check_pending_transfer(address);
428 /* TODO: MAP? see above */
435 static void __bt_manager_event_filter(GDBusConnection *connection,
436 const gchar *sender_name,
437 const gchar *object_path,
438 const gchar *interface_name,
439 const gchar *signal_name,
440 GVariant *parameters,
445 char *obj_path = NULL;
447 if (signal_name == NULL)
450 if (strcasecmp(signal_name, "InterfacesAdded") == 0) {
451 g_variant_get(parameters, "(&o@a{sa{sv}})", &obj_path, &value);
453 if (strcasecmp(obj_path, BT_BLUEZ_HCI_PATH) == 0)
454 if (TIZEN_FEATURE_OPP_SUPPORTED) {
455 if (_bt_register_obex_server() != BLUETOOTH_ERROR_NONE)
456 BT_ERR("Fail to init obex server");
458 g_variant_unref(value);
459 } else if (strcasecmp(signal_name, "InterfacesRemoved") == 0) {
461 if (TIZEN_FEATURE_OPP_SUPPORTED) {
462 if (_bt_unregister_obex_server() != BLUETOOTH_ERROR_NONE)
463 BT_ERR("Fail to unregister obex server");
466 } else if (strcasecmp(signal_name, "NameOwnerChanged") == 0) {
469 char *previous = NULL;
470 char *current = NULL;
472 if (g_strcmp0(g_variant_get_type_string(parameters), "(sss)") != 0) {
473 BT_ERR("Invalid variant format");
477 if (__bt_get_owner_info(parameters, &name, &previous, ¤t)) {
478 BT_ERR("Fail to get the owner info");
482 if (*current != '\0')
488 if (strcasecmp(name, BT_BLUEZ_NAME) == 0) {
489 BT_INFO_C("### Bluetoothd is terminated");
491 if (_bt_unregister_obex_server() != BLUETOOTH_ERROR_NONE)
492 BT_ERR("Fail to unregister obex server");
496 _bt_obex_server_check_allocation(&value);
499 /* Check if the obex server was terminated abnormally */
500 _bt_obex_server_check_termination(name);
502 } else if (g_strcmp0(interface_name, BT_AGENT_INTERFACE) == 0) {
503 _bt_handle_agent_event(parameters, signal_name);
504 } else if (g_strcmp0(interface_name, BT_DEVICE_INTERFACE) == 0) {
505 _bt_handle_device_event(parameters, signal_name, object_path);
511 static gboolean __bt_is_obexd_event(GVariant *msg, const char *interface)
514 if (g_strcmp0(interface, BT_PROPERTIES_INTERFACE) == 0) {
515 char *interface_name = NULL;
517 g_variant_get(msg, "(&s@a{sv}@as)", &interface_name, NULL, NULL);
518 retv_if(interface_name == NULL, FALSE);
520 if (strcasecmp(interface_name, BT_OBEX_TRANSFER_INTERFACE) == 0) {
521 BT_DBG("BT_OBEX_TRANSFER_INTERFACE");
529 static void __bt_obexd_event_filter(GDBusConnection *connection,
530 const gchar *sender_name,
531 const gchar *object_path,
532 const gchar *interface_name,
533 const gchar *signal_name,
534 GVariant *parameters,
537 const char *member = signal_name;
538 char *obj_path = NULL;
539 ret_if(member == NULL);
541 if (strcasecmp(member, "InterfacesAdded") == 0) {
542 if (__bt_get_object_path(parameters, &obj_path)) {
543 BT_ERR("Fail to get the path");
547 /*Handle OPP_SERVER_CONNECTED_EVENT here */
548 /* TODO: MAP? see above */
549 if (strncmp(obj_path, BT_SESSION_BASEPATH_SERVER,
550 strlen(BT_SESSION_BASEPATH_SERVER)) != 0) {
555 if (g_strrstr(obj_path, "session") && g_strrstr(obj_path, "transfer")) {
556 BT_DBG("Obex_Server_Session_Transfer connected");
557 _bt_obex_transfer_connected(obj_path);
560 } else if (strcasecmp(member, "InterfacesRemoved") == 0) {
561 /*Handle OPP_SERVER_DISCONNECTED_EVENT here */
562 /* TODO: MAP? see above */
563 if (__bt_get_object_path(parameters, &obj_path)) {
564 BT_ERR("Fail to get the path");
568 if (strncmp(obj_path, BT_SESSION_BASEPATH_CLIENT,
569 strlen(BT_SESSION_BASEPATH_CLIENT)) == 0) {
570 BT_DBG("Call PBAP Disconnected");
571 _bt_obex_pbap_client_disconnect(obj_path);
574 if (strncmp(obj_path, BT_SESSION_BASEPATH_SERVER,
575 strlen(BT_SESSION_BASEPATH_SERVER)) != 0) {
580 if (g_strrstr(obj_path, "session") && g_strrstr(obj_path, "transfer")) {
581 BT_DBG("Obex_Server_Session_Transfer disconnected %s",
584 _bt_obex_transfer_disconnected(obj_path);
587 } else if (__bt_is_obexd_event(parameters, interface_name) == TRUE) {
588 const char *path = object_path;
590 if (strncmp(path, BT_SESSION_BASEPATH_SERVER,
591 strlen(BT_SESSION_BASEPATH_SERVER)) != 0 &&
592 strncmp(path, BT_SESSION_BASEPATH_CLIENT,
593 strlen(BT_SESSION_BASEPATH_CLIENT)) != 0) {
594 BT_DBG("DBUS_HANDLER_RESULT_NOT_YET_HANDLED");
598 _bt_handle_property_changed_event(parameters, path);
603 static gboolean __bt_is_obexd_client_event(GVariant *msg, const char *interface)
607 if (g_strcmp0(interface, BT_PROPERTIES_INTERFACE) == 0) {
608 char *interface_name = NULL;
610 g_variant_get(msg, "(&s@a{sv}@as)", &interface_name, NULL, NULL);
612 retv_if(interface_name == NULL, FALSE);
614 if (strcasecmp(interface_name,
615 BT_OBEX_TRANSFER_INTERFACE) == 0) {
626 static void __bt_opc_event_filter(GDBusConnection *connection,
627 const gchar *sender_name,
628 const gchar *object_path,
629 const gchar *interface_name,
630 const gchar *signal_name,
631 GVariant *parameters,
634 const char *member = signal_name;
635 char *obj_path = NULL;
636 if (strcasecmp(member, "InterfacesAdded") == 0) {
637 BT_DBG("InterfacesAdded");
638 } else if (strcasecmp(member, "InterfacesRemoved") == 0) {
640 if (__bt_get_object_path(parameters, &obj_path)) {
641 BT_ERR("Fail to get the path");
645 BT_DBG("object_path = %s", obj_path);
647 if (strncmp(obj_path, BT_SESSION_BASEPATH_CLIENT,
648 strlen(BT_SESSION_BASEPATH_CLIENT)) != 0
649 || strstr(obj_path, "transfer") == NULL) {
652 } else if (strncmp(obj_path, BT_SESSION_BASEPATH_CLIENT,
653 strlen(BT_SESSION_BASEPATH_CLIENT)) == 0) {
654 BT_DBG("Going to call opc disconnected");
655 _bt_opc_disconnected(obj_path);
660 } else if (__bt_is_obexd_client_event(parameters, interface_name) == TRUE) {
661 char *path = (char *)object_path;
662 BT_INFO("object_path %s", path);
663 if (strncmp(path, BT_SESSION_BASEPATH_CLIENT,
664 strlen(BT_SESSION_BASEPATH_CLIENT)) != 0) {
665 BT_DBG("NOT BT_SESSION_BASEPATH_CLIENT");
669 _bt_opc_property_changed_event(parameters, path);
675 int _bt_opp_client_event_init(void)
677 GError *error = NULL;
679 if (opc_obexd_conn == NULL) {
680 opc_obexd_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
682 if (!opc_obexd_conn) {
684 BT_ERR("Unable to connect to dbus: %s", error->message);
685 g_clear_error(&error);
687 return BLUETOOTH_ERROR_INTERNAL;
691 if (_bt_register_service_event(opc_obexd_conn,
692 BT_OPP_CLIENT_EVENT) != BLUETOOTH_ERROR_NONE) {
693 g_object_unref(opc_obexd_conn);
694 opc_obexd_conn = NULL;
695 return BLUETOOTH_ERROR_INTERNAL;
698 return BLUETOOTH_ERROR_NONE;
701 void _bt_opp_client_event_deinit(void)
703 if (opc_obexd_conn) {
704 _bt_unregister_service_event(opc_obexd_conn,
705 BT_OPP_CLIENT_EVENT);
706 g_object_unref(opc_obexd_conn);
707 opc_obexd_conn = NULL;
711 static void __bt_map_event_filter(GDBusConnection *connection,
712 const gchar *sender_name,
713 const gchar *object_path,
714 const gchar *interface_name,
715 const gchar *signal_name,
716 GVariant *parameters,
719 BT_DBG("Entered __bt_map_event_filter");
720 const char *member = signal_name;
722 if (strcasecmp(member, "InterfacesAdded") == 0) {
723 BT_DBG("------------------------------------ADDED------------------------------------");
724 // currently doing nothing
725 } else if (strcasecmp(member, "InterfacesRemoved") == 0) {
726 BT_DBG("------------------------------------REMOVED------------------------------------");
727 // TODO check if something should be called here?
728 //_bt_map_on_transfer_finished(object_path, error);
729 } else if (__bt_is_obexd_client_event(parameters, interface_name) == TRUE) {
730 BT_DBG("------------------------------------CLIENT EVENT------------------------------------");
731 _bt_map_property_changed_event(parameters, object_path);
737 int _bt_map_client_event_init(void)
739 GError *error = NULL;
741 if (map_obexd_conn == NULL) {
742 map_obexd_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
744 if (!map_obexd_conn) {
746 BT_ERR("Unable to connect to dbus: %s", error->message);
747 g_clear_error(&error);
749 return BLUETOOTH_ERROR_INTERNAL;
753 if (_bt_register_service_event(map_obexd_conn,
754 BT_MAP_CLIENT_EVENT) != BLUETOOTH_ERROR_NONE) {
755 g_object_unref(map_obexd_conn);
756 map_obexd_conn = NULL;
757 return BLUETOOTH_ERROR_INTERNAL;
760 return BLUETOOTH_ERROR_NONE;
763 void _bt_map_client_event_deinit(void)
765 if (map_obexd_conn) {
766 _bt_unregister_service_event(map_obexd_conn,
767 BT_MAP_CLIENT_EVENT);
768 g_object_unref(map_obexd_conn);
769 map_obexd_conn = NULL;
773 #ifdef TIZEN_FEATURE_BT_PERMANENT_LOG
774 static void __bt_dump_event_filter(GDBusConnection *connection,
775 const gchar *sender_name,
776 const gchar *object_path,
777 const gchar *interface_name,
778 const gchar *signal_name,
779 GVariant *parameters,
782 if (strcasecmp(signal_name, BT_DUMP_SERVICE_SIGNAL) == 0) {
786 g_variant_get(parameters, "(i&s)", &mode, &path);
787 _bt_start_log_dump(path);
793 static int __bt_register_dump_subscribe_signal(GDBusConnection *conn,
799 static guint subs_source_id = 0;
802 if (subs_source_id == 0) {
803 subs_source_id = g_dbus_connection_signal_subscribe(conn,
804 NULL, BT_DUMP_SERVICE_INTERFACE,
805 BT_DUMP_SERVICE_SIGNAL, BT_DUMP_SERVICE_PATH, NULL, 0,
806 __bt_dump_event_filter,
810 if (subs_source_id > 0) {
811 g_dbus_connection_signal_unsubscribe(conn,
820 int _bt_register_manager_subscribe_signal(GDBusConnection *conn,
826 static int subs_interface_added_id = -1;
827 static int subs_interface_removed_id = -1;
828 static int subs_name_owner_changed = -1;
831 if (subs_interface_added_id == -1) {
832 subs_interface_added_id = g_dbus_connection_signal_subscribe(conn,
833 NULL, BT_MANAGER_INTERFACE,
834 BT_INTERFACES_ADDED, NULL, NULL, 0,
835 __bt_manager_event_filter,
838 if (subs_interface_removed_id == -1) {
839 subs_interface_removed_id = g_dbus_connection_signal_subscribe(conn,
840 NULL, BT_MANAGER_INTERFACE,
841 BT_INTERFACES_REMOVED, NULL, NULL, 0,
842 __bt_manager_event_filter,
845 if (subs_name_owner_changed == -1) {
846 subs_name_owner_changed = g_dbus_connection_signal_subscribe(conn,
847 NULL, BT_EVENT_FREEDESKTOP,
848 BT_NAME_OWNER_CHANGED, NULL, NULL, 0,
849 __bt_manager_event_filter, NULL, NULL);
853 if (subs_interface_added_id != -1) {
854 g_dbus_connection_signal_unsubscribe(conn,
855 subs_interface_added_id);
856 subs_interface_added_id = -1;
858 if (subs_interface_removed_id != -1) {
859 g_dbus_connection_signal_unsubscribe(conn,
860 subs_interface_removed_id);
861 subs_interface_removed_id = -1;
863 if (subs_name_owner_changed != -1) {
864 g_dbus_connection_signal_unsubscribe(conn,
865 subs_name_owner_changed);
866 subs_name_owner_changed = -1;
873 int _bt_register_device_subscribe_signal(GDBusConnection *conn,
879 static int subs_device_id = -1;
882 if (subs_device_id == -1) {
883 subs_device_id = g_dbus_connection_signal_subscribe(conn,
884 NULL, BT_DEVICE_INTERFACE,
886 __bt_manager_event_filter,
890 if (subs_device_id != -1) {
891 g_dbus_connection_signal_unsubscribe(conn,
899 int _bt_register_input_subscribe_signal(GDBusConnection *conn,
905 static int subs_input_id = -1;
908 if (subs_input_id == -1) {
909 subs_input_id = g_dbus_connection_signal_subscribe(conn,
910 NULL, BT_INPUT_INTERFACE,
912 __bt_manager_event_filter,
916 if (subs_input_id != -1) {
917 g_dbus_connection_signal_unsubscribe(conn,
927 int _bt_register_opp_server_subscribe_signal(GDBusConnection *conn,
933 static int subs_opp_server_interface_added_id = -1;
934 static int subs_opp_server_interface_removed_id = -1;
935 static int subs_opp_server_property_id = -1;
939 if (subs_opp_server_interface_added_id == -1) {
940 subs_opp_server_interface_added_id = g_dbus_connection_signal_subscribe(conn,
941 NULL, BT_MANAGER_INTERFACE,
942 BT_INTERFACES_ADDED, NULL, NULL, 0,
943 __bt_obexd_event_filter,
946 if (subs_opp_server_interface_removed_id == -1) {
947 subs_opp_server_interface_removed_id = g_dbus_connection_signal_subscribe(conn,
948 NULL, BT_MANAGER_INTERFACE,
949 BT_INTERFACES_REMOVED, NULL, NULL, 0,
950 __bt_obexd_event_filter,
953 if (subs_opp_server_property_id == -1) {
954 subs_opp_server_property_id = g_dbus_connection_signal_subscribe(conn,
955 BT_OBEX_SERVICE_NAME, BT_PROPERTIES_INTERFACE,
956 BT_PROPERTIES_CHANGED, NULL, NULL, 0,
957 __bt_obexd_event_filter,
961 if (subs_opp_server_interface_added_id != -1) {
962 g_dbus_connection_signal_unsubscribe(conn,
963 subs_opp_server_interface_added_id);
964 subs_opp_server_interface_added_id = -1;
966 if (subs_opp_server_interface_removed_id != -1) {
967 g_dbus_connection_signal_unsubscribe(conn,
968 subs_opp_server_interface_removed_id);
969 subs_opp_server_interface_removed_id = -1;
971 if (subs_opp_server_property_id != -1) {
972 g_dbus_connection_signal_unsubscribe(conn,
973 subs_opp_server_property_id);
974 subs_opp_server_property_id = -1;
980 int _bt_register_opp_client_subscribe_signal(GDBusConnection *conn,
986 static int subs_opp_client_interface_added_id = -1;
987 static int subs_opp_client_interface_removed_id = -1;
988 static int subs_opp_client_property_id = -1;
992 if (subs_opp_client_interface_added_id == -1) {
993 subs_opp_client_interface_added_id = g_dbus_connection_signal_subscribe(conn,
994 NULL, BT_MANAGER_INTERFACE,
995 BT_INTERFACES_ADDED, NULL, NULL, 0,
996 __bt_opc_event_filter,
999 if (subs_opp_client_interface_removed_id == -1) {
1000 subs_opp_client_interface_removed_id = g_dbus_connection_signal_subscribe(conn,
1001 NULL, BT_MANAGER_INTERFACE,
1002 BT_INTERFACES_REMOVED, NULL, NULL, 0,
1003 __bt_opc_event_filter,
1006 if (subs_opp_client_property_id == -1) {
1007 subs_opp_client_property_id = g_dbus_connection_signal_subscribe(conn,
1008 BT_OBEX_SERVICE_NAME, BT_PROPERTIES_INTERFACE,
1009 BT_PROPERTIES_CHANGED, NULL, NULL, 0,
1010 __bt_opc_event_filter,
1014 if (subs_opp_client_interface_added_id != -1) {
1015 g_dbus_connection_signal_unsubscribe(conn,
1016 subs_opp_client_interface_added_id);
1017 subs_opp_client_interface_added_id = -1;
1019 if (subs_opp_client_interface_removed_id != -1) {
1020 g_dbus_connection_signal_unsubscribe(conn,
1021 subs_opp_client_interface_removed_id);
1022 subs_opp_client_interface_removed_id = -1;
1024 if (subs_opp_client_property_id != -1) {
1025 g_dbus_connection_signal_unsubscribe(conn,
1026 subs_opp_client_property_id);
1027 subs_opp_client_property_id = -1;
1033 int _bt_register_map_client_subscribe_signal(GDBusConnection *conn,
1039 static int subs_map_client_interface_added_id = -1;
1040 static int subs_map_client_interface_removed_id = -1;
1041 static int subs_map_client_property_id = -1;
1045 if (subs_map_client_interface_added_id == -1) {
1046 subs_map_client_interface_added_id = g_dbus_connection_signal_subscribe(conn,
1047 NULL, BT_MANAGER_INTERFACE,
1048 BT_INTERFACES_ADDED, NULL, NULL, 0,
1049 __bt_map_event_filter,
1052 if (subs_map_client_interface_removed_id == -1) {
1053 subs_map_client_interface_removed_id = g_dbus_connection_signal_subscribe(conn,
1054 NULL, BT_MANAGER_INTERFACE,
1055 BT_INTERFACES_REMOVED, NULL, NULL, 0,
1056 __bt_map_event_filter,
1059 if (subs_map_client_property_id == -1) {
1060 subs_map_client_property_id = g_dbus_connection_signal_subscribe(conn,
1061 BT_OBEX_SERVICE_NAME, BT_PROPERTIES_INTERFACE,
1062 BT_PROPERTIES_CHANGED, NULL, NULL, 0,
1063 __bt_map_event_filter,
1067 if (subs_map_client_interface_added_id != -1) {
1068 g_dbus_connection_signal_unsubscribe(conn,
1069 subs_map_client_interface_added_id);
1070 subs_map_client_interface_added_id = -1;
1072 if (subs_map_client_interface_removed_id != -1) {
1073 g_dbus_connection_signal_unsubscribe(conn,
1074 subs_map_client_interface_removed_id);
1075 subs_map_client_interface_removed_id = -1;
1077 if (subs_map_client_property_id != -1) {
1078 g_dbus_connection_signal_unsubscribe(conn,
1079 subs_map_client_property_id);
1080 subs_map_client_property_id = -1;
1087 int _bt_register_service_event(GDBusConnection *g_conn, int event_type)
1089 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1091 switch (event_type) {
1092 case BT_MANAGER_EVENT:
1093 _bt_register_manager_subscribe_signal(g_conn, TRUE);
1095 case BT_DEVICE_EVENT:
1096 _bt_register_device_subscribe_signal(g_conn, TRUE);
1098 case BT_OPP_SERVER_EVENT:
1099 _bt_register_opp_server_subscribe_signal(g_conn, TRUE);
1101 case BT_OPP_CLIENT_EVENT:
1102 _bt_register_opp_client_subscribe_signal(g_conn, TRUE);
1104 case BT_MAP_CLIENT_EVENT:
1105 _bt_register_map_client_subscribe_signal(g_conn, TRUE);
1108 BT_ERR("Unknown event");
1109 return BLUETOOTH_ERROR_INTERNAL;
1112 return BLUETOOTH_ERROR_NONE;
1115 void _bt_unregister_service_event(GDBusConnection *g_conn, int event_type)
1119 ret_if(g_conn == NULL);
1121 switch (event_type) {
1122 case BT_MANAGER_EVENT:
1123 _bt_register_manager_subscribe_signal(g_conn, FALSE);
1124 _bt_register_device_subscribe_signal(g_conn, FALSE);
1125 _bt_register_input_subscribe_signal(g_conn, FALSE);
1127 case BT_OPP_SERVER_EVENT:
1128 _bt_register_opp_server_subscribe_signal(g_conn, FALSE);
1130 case BT_OPP_CLIENT_EVENT:
1131 _bt_register_opp_client_subscribe_signal(g_conn, FALSE);
1133 case BT_MAP_CLIENT_EVENT:
1134 _bt_register_map_client_subscribe_signal(g_conn, FALSE);
1137 BT_ERR("Unknown event");
1144 static int __bt_init_manager_receiver(void)
1148 GError *error = NULL;
1150 if (manager_conn == NULL) {
1151 manager_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
1152 if (error != NULL) {
1153 BT_ERR("ERROR: Can't get on system bus [%s]", error->message);
1154 g_clear_error(&error);
1156 retv_if(manager_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1159 if (_bt_register_service_event(manager_conn,
1160 BT_MANAGER_EVENT) != BLUETOOTH_ERROR_NONE)
1163 if (_bt_register_service_event(manager_conn,
1164 BT_DEVICE_EVENT) != BLUETOOTH_ERROR_NONE)
1167 #ifdef TIZEN_FEATURE_BT_PERMANENT_LOG
1168 __bt_register_dump_subscribe_signal(manager_conn, TRUE);
1171 return BLUETOOTH_ERROR_NONE;
1174 g_object_unref(manager_conn);
1175 manager_conn = NULL;
1180 return BLUETOOTH_ERROR_INTERNAL;
1183 static int __bt_init_obexd_receiver(void)
1186 if (!TIZEN_PROFILE_TV) { /* TODO: obexd doesn't work in TV profile. It should be resolved later. */
1187 GError *error = NULL;
1189 if (obexd_conn == NULL) {
1190 obexd_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
1191 if (error != NULL) {
1192 BT_ERR("ERROR: Can't get on session bus [%s]", error->message);
1193 g_clear_error(&error);
1195 retv_if(obexd_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1198 if (_bt_register_service_event(obexd_conn,
1199 BT_OPP_SERVER_EVENT) != BLUETOOTH_ERROR_NONE) {
1200 BT_ERR("Error while registering service event");
1201 g_object_unref(obexd_conn);
1203 return BLUETOOTH_ERROR_INTERNAL;
1209 return BLUETOOTH_ERROR_NONE;
1212 gboolean __bt_reinit_obexd_receiver(gpointer user_data)
1214 static int retry_cnt = 0;
1215 int result = BLUETOOTH_ERROR_NONE;
1219 result = __bt_init_obexd_receiver();
1220 if (result != BLUETOOTH_ERROR_NONE) {
1221 /* 20 ms * 50 = 10 seconds. During 10 seconds fail to initialize,
1222 then it is not the timing issue. Just can't use the session bus connection */
1223 if (retry_cnt > 100) {
1224 BT_ERR("Fail to init obexd receiver by 50 times.");
1226 session_reinit_timer = 0;
1230 BT_DBG("Retry to initialize the obexd receiver");
1235 session_reinit_timer = 0;
1242 /* To receive the event from bluez */
1243 int _bt_init_obex_event_receiver(void)
1249 result = __bt_init_manager_receiver();
1250 retv_if(result != BLUETOOTH_ERROR_NONE, result);
1252 result = __bt_init_obexd_receiver();
1253 if (result != BLUETOOTH_ERROR_NONE) {
1254 BT_ERR("Fail to init obexd receiver");
1256 /* Try to re-initialize obexd receiver in the timer */
1257 if (session_reinit_timer > 0)
1258 g_source_remove(session_reinit_timer);
1260 session_reinit_timer = g_timeout_add(200,
1261 (GSourceFunc)__bt_reinit_obexd_receiver, NULL);
1266 return BLUETOOTH_ERROR_NONE;
1269 void _bt_deinit_obex_event_receiver(void)
1273 _bt_unregister_service_event(manager_conn, BT_MANAGER_EVENT);
1275 _bt_unregister_service_event(obexd_conn, BT_OPP_SERVER_EVENT);
1277 #ifdef TIZEN_FEATURE_BT_PERMANENT_LOG
1278 __bt_register_dump_subscribe_signal(manager_conn, FALSE);
1282 g_object_unref(manager_conn);
1283 manager_conn = NULL;
1287 g_object_unref(obexd_conn);
1292 g_source_remove(event_id);