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) {
460 if (TIZEN_FEATURE_OPP_SUPPORTED) {
461 if (_bt_unregister_obex_server() != BLUETOOTH_ERROR_NONE)
462 BT_ERR("Fail to unregister obex server");
464 } else if (strcasecmp(signal_name, "NameOwnerChanged") == 0) {
467 char *previous = NULL;
468 char *current = NULL;
470 if (g_strcmp0(g_variant_get_type_string(parameters), "(sss)") != 0) {
471 BT_ERR("Invalid variant format");
475 if (__bt_get_owner_info(parameters, &name, &previous, ¤t)) {
476 BT_ERR("Fail to get the owner info");
480 if (*current != '\0')
486 if (strcasecmp(name, BT_BLUEZ_NAME) == 0) {
487 BT_INFO_C("### Bluetoothd is terminated");
489 if (_bt_unregister_obex_server() != BLUETOOTH_ERROR_NONE)
490 BT_ERR("Fail to unregister obex server");
494 _bt_obex_server_check_allocation(&value);
497 /* Check if the obex server was terminated abnormally */
498 _bt_obex_server_check_termination(name);
500 } else if (g_strcmp0(interface_name, BT_AGENT_INTERFACE) == 0) {
501 _bt_handle_agent_event(parameters, signal_name);
502 } else if (g_strcmp0(interface_name, BT_DEVICE_INTERFACE) == 0) {
503 _bt_handle_device_event(parameters, signal_name, object_path);
509 static gboolean __bt_is_obexd_event(GVariant *msg, const char *interface)
512 if (g_strcmp0(interface, BT_PROPERTIES_INTERFACE) == 0) {
513 char *interface_name = NULL;
515 g_variant_get(msg, "(&s@a{sv}@as)", &interface_name, NULL, NULL);
516 retv_if(interface_name == NULL, FALSE);
518 if (strcasecmp(interface_name, BT_OBEX_TRANSFER_INTERFACE) == 0) {
519 BT_DBG("BT_OBEX_TRANSFER_INTERFACE");
527 static void __bt_obexd_event_filter(GDBusConnection *connection,
528 const gchar *sender_name,
529 const gchar *object_path,
530 const gchar *interface_name,
531 const gchar *signal_name,
532 GVariant *parameters,
535 const char *member = signal_name;
536 char *obj_path = NULL;
537 ret_if(member == NULL);
539 if (strcasecmp(member, "InterfacesAdded") == 0) {
540 if (__bt_get_object_path(parameters, &obj_path)) {
541 BT_ERR("Fail to get the path");
545 /*Handle OPP_SERVER_CONNECTED_EVENT here */
546 /* TODO: MAP? see above */
547 if (strncmp(obj_path, BT_SESSION_BASEPATH_SERVER,
548 strlen(BT_SESSION_BASEPATH_SERVER)) != 0) {
553 if (g_strrstr(obj_path, "session") && g_strrstr(obj_path, "transfer")) {
554 BT_DBG("Obex_Server_Session_Transfer connected");
555 _bt_obex_transfer_connected(obj_path);
558 } else if (strcasecmp(member, "InterfacesRemoved") == 0) {
559 /*Handle OPP_SERVER_DISCONNECTED_EVENT here */
560 /* TODO: MAP? see above */
561 if (__bt_get_object_path(parameters, &obj_path)) {
562 BT_ERR("Fail to get the path");
566 if (strncmp(obj_path, BT_SESSION_BASEPATH_CLIENT,
567 strlen(BT_SESSION_BASEPATH_CLIENT)) == 0) {
568 BT_DBG("Call PBAP Disconnected");
569 _bt_obex_pbap_client_disconnect(obj_path);
572 if (strncmp(obj_path, BT_SESSION_BASEPATH_SERVER,
573 strlen(BT_SESSION_BASEPATH_SERVER)) != 0) {
578 if (g_strrstr(obj_path, "session") && g_strrstr(obj_path, "transfer")) {
579 BT_DBG("Obex_Server_Session_Transfer disconnected %s",
582 _bt_obex_transfer_disconnected(obj_path);
585 } else if (__bt_is_obexd_event(parameters, interface_name) == TRUE) {
586 const char *path = object_path;
588 if (strncmp(path, BT_SESSION_BASEPATH_SERVER,
589 strlen(BT_SESSION_BASEPATH_SERVER)) != 0 &&
590 strncmp(path, BT_SESSION_BASEPATH_CLIENT,
591 strlen(BT_SESSION_BASEPATH_CLIENT)) != 0) {
592 BT_DBG("DBUS_HANDLER_RESULT_NOT_YET_HANDLED");
596 _bt_handle_property_changed_event(parameters, path);
601 static gboolean __bt_is_obexd_client_event(GVariant *msg, const char *interface)
605 if (g_strcmp0(interface, BT_PROPERTIES_INTERFACE) == 0) {
606 char *interface_name = NULL;
608 g_variant_get(msg, "(&s@a{sv}@as)", &interface_name, NULL, NULL);
610 retv_if(interface_name == NULL, FALSE);
612 if (strcasecmp(interface_name,
613 BT_OBEX_TRANSFER_INTERFACE) == 0) {
624 static void __bt_opc_event_filter(GDBusConnection *connection,
625 const gchar *sender_name,
626 const gchar *object_path,
627 const gchar *interface_name,
628 const gchar *signal_name,
629 GVariant *parameters,
632 const char *member = signal_name;
633 char *obj_path = NULL;
634 if (strcasecmp(member, "InterfacesAdded") == 0) {
635 BT_DBG("InterfacesAdded");
636 } else if (strcasecmp(member, "InterfacesRemoved") == 0) {
638 if (__bt_get_object_path(parameters, &obj_path)) {
639 BT_ERR("Fail to get the path");
643 BT_DBG("object_path = %s", obj_path);
645 if (strncmp(obj_path, BT_SESSION_BASEPATH_CLIENT,
646 strlen(BT_SESSION_BASEPATH_CLIENT)) != 0
647 || strstr(obj_path, "transfer") == NULL) {
650 } else if (strncmp(obj_path, BT_SESSION_BASEPATH_CLIENT,
651 strlen(BT_SESSION_BASEPATH_CLIENT)) == 0) {
652 BT_DBG("Going to call opc disconnected");
653 _bt_opc_disconnected(obj_path);
658 } else if (__bt_is_obexd_client_event(parameters, interface_name) == TRUE) {
659 char *path = (char *)object_path;
660 BT_INFO("object_path %s", path);
661 if (strncmp(path, BT_SESSION_BASEPATH_CLIENT,
662 strlen(BT_SESSION_BASEPATH_CLIENT)) != 0) {
663 BT_DBG("NOT BT_SESSION_BASEPATH_CLIENT");
667 _bt_opc_property_changed_event(parameters, path);
673 int _bt_opp_client_event_init(void)
675 GError *error = NULL;
677 if (opc_obexd_conn == NULL) {
678 opc_obexd_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
680 if (!opc_obexd_conn) {
682 BT_ERR("Unable to connect to dbus: %s", error->message);
683 g_clear_error(&error);
685 return BLUETOOTH_ERROR_INTERNAL;
689 if (_bt_register_service_event(opc_obexd_conn,
690 BT_OPP_CLIENT_EVENT) != BLUETOOTH_ERROR_NONE) {
691 g_object_unref(opc_obexd_conn);
692 opc_obexd_conn = NULL;
693 return BLUETOOTH_ERROR_INTERNAL;
696 return BLUETOOTH_ERROR_NONE;
699 void _bt_opp_client_event_deinit(void)
701 if (opc_obexd_conn) {
702 _bt_unregister_service_event(opc_obexd_conn,
703 BT_OPP_CLIENT_EVENT);
704 g_object_unref(opc_obexd_conn);
705 opc_obexd_conn = NULL;
709 static void __bt_map_event_filter(GDBusConnection *connection,
710 const gchar *sender_name,
711 const gchar *object_path,
712 const gchar *interface_name,
713 const gchar *signal_name,
714 GVariant *parameters,
717 BT_DBG("Entered __bt_map_event_filter");
718 const char *member = signal_name;
720 if (strcasecmp(member, "InterfacesAdded") == 0) {
721 BT_DBG("------------------------------------ADDED------------------------------------");
722 // currently doing nothing
723 } else if (strcasecmp(member, "InterfacesRemoved") == 0) {
724 BT_DBG("------------------------------------REMOVED------------------------------------");
725 // TODO check if something should be called here?
726 //_bt_map_on_transfer_finished(object_path, error);
727 } else if (__bt_is_obexd_client_event(parameters, interface_name) == TRUE) {
728 BT_DBG("------------------------------------CLIENT EVENT------------------------------------");
729 _bt_map_property_changed_event(parameters, object_path);
735 int _bt_map_client_event_init(void)
737 GError *error = NULL;
739 if (map_obexd_conn == NULL) {
740 map_obexd_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
742 if (!map_obexd_conn) {
744 BT_ERR("Unable to connect to dbus: %s", error->message);
745 g_clear_error(&error);
747 return BLUETOOTH_ERROR_INTERNAL;
751 if (_bt_register_service_event(map_obexd_conn,
752 BT_MAP_CLIENT_EVENT) != BLUETOOTH_ERROR_NONE) {
753 g_object_unref(map_obexd_conn);
754 map_obexd_conn = NULL;
755 return BLUETOOTH_ERROR_INTERNAL;
758 return BLUETOOTH_ERROR_NONE;
761 void _bt_map_client_event_deinit(void)
763 if (map_obexd_conn) {
764 _bt_unregister_service_event(map_obexd_conn,
765 BT_MAP_CLIENT_EVENT);
766 g_object_unref(map_obexd_conn);
767 map_obexd_conn = NULL;
771 #ifdef TIZEN_FEATURE_BT_PERMANENT_LOG
772 static void __bt_dump_event_filter(GDBusConnection *connection,
773 const gchar *sender_name,
774 const gchar *object_path,
775 const gchar *interface_name,
776 const gchar *signal_name,
777 GVariant *parameters,
780 if (strcasecmp(signal_name, BT_DUMP_SERVICE_SIGNAL) == 0) {
784 g_variant_get(parameters, "(i&s)", &mode, &path);
785 _bt_start_log_dump(path);
791 static int __bt_register_dump_subscribe_signal(GDBusConnection *conn,
797 static guint subs_source_id = 0;
800 if (subs_source_id == 0) {
801 subs_source_id = g_dbus_connection_signal_subscribe(conn,
802 NULL, BT_DUMP_SERVICE_INTERFACE,
803 BT_DUMP_SERVICE_SIGNAL, BT_DUMP_SERVICE_PATH, NULL, 0,
804 __bt_dump_event_filter,
808 if (subs_source_id > 0) {
809 g_dbus_connection_signal_unsubscribe(conn,
818 int _bt_register_manager_subscribe_signal(GDBusConnection *conn,
824 static int subs_interface_added_id = -1;
825 static int subs_interface_removed_id = -1;
826 static int subs_name_owner_changed = -1;
829 if (subs_interface_added_id == -1) {
830 subs_interface_added_id = g_dbus_connection_signal_subscribe(conn,
831 NULL, BT_MANAGER_INTERFACE,
832 BT_INTERFACES_ADDED, NULL, NULL, 0,
833 __bt_manager_event_filter,
836 if (subs_interface_removed_id == -1) {
837 subs_interface_removed_id = g_dbus_connection_signal_subscribe(conn,
838 NULL, BT_MANAGER_INTERFACE,
839 BT_INTERFACES_REMOVED, NULL, NULL, 0,
840 __bt_manager_event_filter,
843 if (subs_name_owner_changed == -1) {
844 subs_name_owner_changed = g_dbus_connection_signal_subscribe(conn,
845 NULL, BT_EVENT_FREEDESKTOP,
846 BT_NAME_OWNER_CHANGED, NULL, NULL, 0,
847 __bt_manager_event_filter, NULL, NULL);
851 if (subs_interface_added_id != -1) {
852 g_dbus_connection_signal_unsubscribe(conn,
853 subs_interface_added_id);
854 subs_interface_added_id = -1;
856 if (subs_interface_removed_id != -1) {
857 g_dbus_connection_signal_unsubscribe(conn,
858 subs_interface_removed_id);
859 subs_interface_removed_id = -1;
861 if (subs_name_owner_changed != -1) {
862 g_dbus_connection_signal_unsubscribe(conn,
863 subs_name_owner_changed);
864 subs_name_owner_changed = -1;
871 int _bt_register_device_subscribe_signal(GDBusConnection *conn,
877 static int subs_device_id = -1;
880 if (subs_device_id == -1) {
881 subs_device_id = g_dbus_connection_signal_subscribe(conn,
882 NULL, BT_DEVICE_INTERFACE,
884 __bt_manager_event_filter,
888 if (subs_device_id != -1) {
889 g_dbus_connection_signal_unsubscribe(conn,
897 int _bt_register_input_subscribe_signal(GDBusConnection *conn,
903 static int subs_input_id = -1;
906 if (subs_input_id == -1) {
907 subs_input_id = g_dbus_connection_signal_subscribe(conn,
908 NULL, BT_INPUT_INTERFACE,
910 __bt_manager_event_filter,
914 if (subs_input_id != -1) {
915 g_dbus_connection_signal_unsubscribe(conn,
925 int _bt_register_opp_server_subscribe_signal(GDBusConnection *conn,
931 static int subs_opp_server_interface_added_id = -1;
932 static int subs_opp_server_interface_removed_id = -1;
933 static int subs_opp_server_property_id = -1;
937 if (subs_opp_server_interface_added_id == -1) {
938 subs_opp_server_interface_added_id = g_dbus_connection_signal_subscribe(conn,
939 NULL, BT_MANAGER_INTERFACE,
940 BT_INTERFACES_ADDED, NULL, NULL, 0,
941 __bt_obexd_event_filter,
944 if (subs_opp_server_interface_removed_id == -1) {
945 subs_opp_server_interface_removed_id = g_dbus_connection_signal_subscribe(conn,
946 NULL, BT_MANAGER_INTERFACE,
947 BT_INTERFACES_REMOVED, NULL, NULL, 0,
948 __bt_obexd_event_filter,
951 if (subs_opp_server_property_id == -1) {
952 subs_opp_server_property_id = g_dbus_connection_signal_subscribe(conn,
953 BT_OBEX_SERVICE_NAME, BT_PROPERTIES_INTERFACE,
954 BT_PROPERTIES_CHANGED, NULL, NULL, 0,
955 __bt_obexd_event_filter,
959 if (subs_opp_server_interface_added_id != -1) {
960 g_dbus_connection_signal_unsubscribe(conn,
961 subs_opp_server_interface_added_id);
962 subs_opp_server_interface_added_id = -1;
964 if (subs_opp_server_interface_removed_id != -1) {
965 g_dbus_connection_signal_unsubscribe(conn,
966 subs_opp_server_interface_removed_id);
967 subs_opp_server_interface_removed_id = -1;
969 if (subs_opp_server_property_id != -1) {
970 g_dbus_connection_signal_unsubscribe(conn,
971 subs_opp_server_property_id);
972 subs_opp_server_property_id = -1;
978 int _bt_register_opp_client_subscribe_signal(GDBusConnection *conn,
984 static int subs_opp_client_interface_added_id = -1;
985 static int subs_opp_client_interface_removed_id = -1;
986 static int subs_opp_client_property_id = -1;
990 if (subs_opp_client_interface_added_id == -1) {
991 subs_opp_client_interface_added_id = g_dbus_connection_signal_subscribe(conn,
992 NULL, BT_MANAGER_INTERFACE,
993 BT_INTERFACES_ADDED, NULL, NULL, 0,
994 __bt_opc_event_filter,
997 if (subs_opp_client_interface_removed_id == -1) {
998 subs_opp_client_interface_removed_id = g_dbus_connection_signal_subscribe(conn,
999 NULL, BT_MANAGER_INTERFACE,
1000 BT_INTERFACES_REMOVED, NULL, NULL, 0,
1001 __bt_opc_event_filter,
1004 if (subs_opp_client_property_id == -1) {
1005 subs_opp_client_property_id = g_dbus_connection_signal_subscribe(conn,
1006 BT_OBEX_SERVICE_NAME, BT_PROPERTIES_INTERFACE,
1007 BT_PROPERTIES_CHANGED, NULL, NULL, 0,
1008 __bt_opc_event_filter,
1012 if (subs_opp_client_interface_added_id != -1) {
1013 g_dbus_connection_signal_unsubscribe(conn,
1014 subs_opp_client_interface_added_id);
1015 subs_opp_client_interface_added_id = -1;
1017 if (subs_opp_client_interface_removed_id != -1) {
1018 g_dbus_connection_signal_unsubscribe(conn,
1019 subs_opp_client_interface_removed_id);
1020 subs_opp_client_interface_removed_id = -1;
1022 if (subs_opp_client_property_id != -1) {
1023 g_dbus_connection_signal_unsubscribe(conn,
1024 subs_opp_client_property_id);
1025 subs_opp_client_property_id = -1;
1031 int _bt_register_map_client_subscribe_signal(GDBusConnection *conn,
1037 static int subs_map_client_interface_added_id = -1;
1038 static int subs_map_client_interface_removed_id = -1;
1039 static int subs_map_client_property_id = -1;
1043 if (subs_map_client_interface_added_id == -1) {
1044 subs_map_client_interface_added_id = g_dbus_connection_signal_subscribe(conn,
1045 NULL, BT_MANAGER_INTERFACE,
1046 BT_INTERFACES_ADDED, NULL, NULL, 0,
1047 __bt_map_event_filter,
1050 if (subs_map_client_interface_removed_id == -1) {
1051 subs_map_client_interface_removed_id = g_dbus_connection_signal_subscribe(conn,
1052 NULL, BT_MANAGER_INTERFACE,
1053 BT_INTERFACES_REMOVED, NULL, NULL, 0,
1054 __bt_map_event_filter,
1057 if (subs_map_client_property_id == -1) {
1058 subs_map_client_property_id = g_dbus_connection_signal_subscribe(conn,
1059 BT_OBEX_SERVICE_NAME, BT_PROPERTIES_INTERFACE,
1060 BT_PROPERTIES_CHANGED, NULL, NULL, 0,
1061 __bt_map_event_filter,
1065 if (subs_map_client_interface_added_id != -1) {
1066 g_dbus_connection_signal_unsubscribe(conn,
1067 subs_map_client_interface_added_id);
1068 subs_map_client_interface_added_id = -1;
1070 if (subs_map_client_interface_removed_id != -1) {
1071 g_dbus_connection_signal_unsubscribe(conn,
1072 subs_map_client_interface_removed_id);
1073 subs_map_client_interface_removed_id = -1;
1075 if (subs_map_client_property_id != -1) {
1076 g_dbus_connection_signal_unsubscribe(conn,
1077 subs_map_client_property_id);
1078 subs_map_client_property_id = -1;
1085 int _bt_register_service_event(GDBusConnection *g_conn, int event_type)
1087 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1089 switch (event_type) {
1090 case BT_MANAGER_EVENT:
1091 _bt_register_manager_subscribe_signal(g_conn, TRUE);
1093 case BT_DEVICE_EVENT:
1094 _bt_register_device_subscribe_signal(g_conn, TRUE);
1096 case BT_OPP_SERVER_EVENT:
1097 _bt_register_opp_server_subscribe_signal(g_conn, TRUE);
1099 case BT_OPP_CLIENT_EVENT:
1100 _bt_register_opp_client_subscribe_signal(g_conn, TRUE);
1102 case BT_MAP_CLIENT_EVENT:
1103 _bt_register_map_client_subscribe_signal(g_conn, TRUE);
1106 BT_ERR("Unknown event");
1107 return BLUETOOTH_ERROR_INTERNAL;
1110 return BLUETOOTH_ERROR_NONE;
1113 void _bt_unregister_service_event(GDBusConnection *g_conn, int event_type)
1117 ret_if(g_conn == NULL);
1119 switch (event_type) {
1120 case BT_MANAGER_EVENT:
1121 _bt_register_manager_subscribe_signal(g_conn, FALSE);
1122 _bt_register_device_subscribe_signal(g_conn, FALSE);
1123 _bt_register_input_subscribe_signal(g_conn, FALSE);
1125 case BT_OPP_SERVER_EVENT:
1126 _bt_register_opp_server_subscribe_signal(g_conn, FALSE);
1128 case BT_OPP_CLIENT_EVENT:
1129 _bt_register_opp_client_subscribe_signal(g_conn, FALSE);
1131 case BT_MAP_CLIENT_EVENT:
1132 _bt_register_map_client_subscribe_signal(g_conn, FALSE);
1135 BT_ERR("Unknown event");
1142 static int __bt_init_manager_receiver(void)
1146 GError *error = NULL;
1148 if (manager_conn == NULL) {
1149 manager_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
1150 if (error != NULL) {
1151 BT_ERR("ERROR: Can't get on system bus [%s]", error->message);
1152 g_clear_error(&error);
1154 retv_if(manager_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1157 if (_bt_register_service_event(manager_conn,
1158 BT_MANAGER_EVENT) != BLUETOOTH_ERROR_NONE)
1161 if (_bt_register_service_event(manager_conn,
1162 BT_DEVICE_EVENT) != BLUETOOTH_ERROR_NONE)
1165 #ifdef TIZEN_FEATURE_BT_PERMANENT_LOG
1166 __bt_register_dump_subscribe_signal(manager_conn, TRUE);
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);
1275 #ifdef TIZEN_FEATURE_BT_PERMANENT_LOG
1276 __bt_register_dump_subscribe_signal(manager_conn, FALSE);
1280 g_object_unref(manager_conn);
1281 manager_conn = NULL;
1285 g_object_unref(obexd_conn);
1290 g_source_remove(event_id);