BT_DBG("request_id : %d", request_id);
_bt_add_push_request_id(request_id);
}
-
+#ifdef TIZEN_FEATURE_BT_OBEX
+ else if (cb_data->service_function == BT_MAP_LIST_FOLDERS) {
+ request_id = g_array_index(out_param1, int, 0);
+ BT_DBG("request_id : %d", request_id);
+ _bt_add_push_request_id(request_id);
+ } else if (cb_data->service_function == BT_MAP_LIST_FILTER_FIELDS) {
+ request_id = g_array_index(out_param1, int, 0);
+ BT_DBG("request_id : %d", request_id);
+ _bt_add_push_request_id(request_id);
+ } else if (cb_data->service_function == BT_MAP_LIST_MESSAGES) {
+ request_id = g_array_index(out_param1, int, 0);
+ BT_DBG("request_id : %d", request_id);
+ _bt_add_push_request_id(request_id);
+ } else if (cb_data->service_function == BT_MAP_GET_MESSAGE) {
+ request_id = g_array_index(out_param1, int, 0);
+ BT_DBG("request_id : %d", request_id);
+ _bt_add_push_request_id(request_id);
+ } else if (cb_data->service_function == BT_MAP_PUSH_MESSAGE) {
+ request_id = g_array_index(out_param1, int, 0);
+ BT_DBG("request_id : %d", request_id);
+ _bt_add_push_request_id(request_id);
+ }
+#endif
goto done;
}
}
PROJECT(bt-service C)
#Include Source files for bluetooth service common files only
+IF("$ENV{CFLAGS}" MATCHES "-DTIZEN_FEATURE_BT_OBEX")
SET(SRCS
marshal.c
./services/bt-service-main.c
./services/audio/avrcp/bt-service-avrcp-tg.c
./services/audio/avrcp/bt-service-avrcp-ctrl.c
./services/gatt/bt-service-gatt.c
+./services/obex/bt-service-obex-agent.c
+./services/obex/bt-service-obex-server.c
+./services/obex/bt-service-map-client.c
+./services/obex/bt-service-opp-client.c
+./services/obex/bt-service-pbap.c
+./services/obex/bt-service-gap-agent.c
+./services/obex/bt-service-network.c
+./services/obex/bt-service-avrcp.c
+./services/obex/bt-service-agent.c
+./services/obex/bt-service-obex-event-receiver.c
+./services/obex/bt-service-oob.c
)
+ELSE ()
+SET(SRCS
+marshal.c
+./services/bt-service-main.c
+./services/bt-service-common.c
+./services/bt-service-event-sender.c
+./services/bt-service-util.c
+./services/bt-request-handler.c
+./services/adapter/bt-service-core-adapter.c
+./services/adapter/bt-service-core-adapter-le.c
+./services/device/bt-service-core-device.c
+./services/bt-service-event-receiver.c
+./services/bt-service-dpm.c
+./services/bt-service-agent-util.c
+./services/hid/bt-service-hidhost.c
+./services/socket/bt-service-socket.c
+./services/rfcomm/bt-service-rfcomm.c
+./services/audio/bt-service-audio.c
+./services/audio/hf/bt-service-hf.c
+./services/audio/a2dp_src/bt-service-a2dp-src.c
+./services/audio/a2dp_sink/bt-service-a2dp-sink.c
+./services/health/bt-service-hdp.c
+./services/audio/avrcp/bt-service-avrcp-tg.c
+./services/audio/avrcp/bt-service-avrcp-ctrl.c
+./services/gatt/bt-service-gatt.c
+)
+ENDIF()
IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
SET(CMAKE_BUILD_TYPE "Release")
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/services/include)
+IF("$ENV{CFLAGS}" MATCHES "-DTIZEN_FEATURE_BT_OBEX")
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/services/obex/include)
+ENDIF()
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../bt-oal/include)
LINK_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../bt-oal)
#include "bt-service-audio-common.h"
#include "bt-service-core-adapter-le.h"
#include "bt-service-gatt.h"
-
+#ifdef TIZEN_FEATURE_BT_OBEX
+#include "bt-service-avrcp.h"
+#include "bt-service-opp-client.h"
+#include "bt-service-obex-server.h"
+#endif
#ifdef TIZEN_DPM_ENABLE
#include "bt-service-dpm.h"
#endif
int alarm_id;
} bt_adapter_timer_t;
+#ifdef TIZEN_FEATURE_BT_OBEX
+typedef struct {
+ alarm_id_t alarm_id;
+ bt_set_alarm_cb callback;
+ void *user_data;
+} bt_service_alarm_t;
+
+typedef struct {
+ gboolean is_alarm_initialized;
+ GList *g_alarm_list;
+} bt_service_alarm_mgr_t;
+
+static bt_service_alarm_mgr_t alarm_mgr = {0, };
+static gboolean is_recovery_mode = FALSE;
+static gboolean is_discovering;
+static void *adapter_agent = NULL;
+static guint le_timer_id = 0;
+static bt_le_status_t adapter_le_status = BT_LE_DEACTIVATED;
+static uint status_reg_id;
+static void alarm_data_free(void *data);
+#endif
+
static bt_adapter_timer_t visible_timer;
static guint timer_id = 0;
+
/* Adapter default states */
static bt_status_t adapter_state = BT_DEACTIVATED;
static bt_adapter_discovery_state_t adapter_discovery_state = ADAPTER_DISCOVERY_STOPPED;
{
return __bt_adapter_state_handle_request(FALSE);
}
-
-
+#ifdef TIZEN_FEATURE_BT_OBEX
+static void alarm_data_free(void *data)
+{
+ bt_service_alarm_t *p_data = (bt_service_alarm_t *)data;
+ g_free(p_data);
+ return;
+}
+#endif
int _bt_start_discovery(unsigned short max_response,
unsigned short duration, unsigned int cod_mask)
{
else
return FALSE;
}
+#ifdef TIZEN_FEATURE_BT_OBEX
+void _bt_adapter_set_le_status(bt_le_status_t status)
+{
+ BT_INFO("adapter_le_status changed [%d] -> [%d]", adapter_le_status, status);
+ adapter_le_status = status;
+}
+
+bt_le_status_t _bt_adapter_get_le_status(void)
+{
+ return adapter_le_status;
+}
+#endif
int _bt_get_local_address(void)
{
free(phone_name);
}
#endif
+#ifdef TIZEN_FEATURE_BT_OBEX
+void _bt_set_discovery_status(gboolean mode)
+{
+ is_discovering = mode;
+}
+
+int _bt_check_adapter(int *status)
+{
+#ifndef TIZEN_PROFILE_TV
+{
+ char *adapter_path = NULL;
+
+ BT_CHECK_PARAMETER(status, return);
+
+ *status = BT_ADAPTER_DISABLED;
+
+ adapter_path = _bt_get_adapter_path();
+
+
+ if (adapter_path != NULL)
+ *status = BT_ADAPTER_ENABLED;
+
+ g_free(adapter_path);
+ return BLUETOOTH_ERROR_NONE;
+}
+#else
+{
+ GDBusProxy *proxy;
+ GError *error = NULL;
+ GVariant *result;
+ GVariant *temp;
+ gboolean powered = FALSE;
+
+ BT_CHECK_PARAMETER(status, return);
+
+ *status = BT_ADAPTER_DISABLED;
+
+ proxy = _bt_get_adapter_properties_proxy();
+ retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ result = g_dbus_proxy_call_sync(proxy,
+ "Get",
+ g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
+ "Powered"),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+
+ if (!result) {
+ BT_ERR("Failed to get local address");
+ if (error != NULL) {
+ BT_ERR("Failed to get local address (Error: %s)", error->message);
+ g_clear_error(&error);
+ }
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ g_variant_get(result, "(v)", &temp);
+ powered = g_variant_get_boolean(temp);
+ BT_DBG("powered: %d", powered);
+
+ if (powered)
+ *status = BT_ADAPTER_ENABLED;
+
+ g_variant_unref(result);
+ g_variant_unref(temp);
+ return BLUETOOTH_ERROR_NONE;
+}
+#endif
+}
+
+static int __bt_set_enabled(void)
+{
+ int adapter_status = BT_ADAPTER_DISABLED;
+ int result = BLUETOOTH_ERROR_NONE;
+
+ if (timer_id > 0) {
+ BT_DBG("g_source is removed");
+ g_source_remove(timer_id);
+ timer_id = 0;
+ }
+
+ _bt_check_adapter(&adapter_status);
+
+ if (adapter_status == BT_ADAPTER_DISABLED) {
+ BT_ERR("Bluetoothd is not running");
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ #if defined(TIZEN_PROFILE_MOBILE) || defined(TIZEN_PROFILE_IVI)
+
+ /* BT setting UI will control Mobile's visible mode. So in the FRWK...set the visible mode as off: */
+ if (_bt_set_discoverable_mode(
+ BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0) != BLUETOOTH_ERROR_NONE)
+ BT_ERR("Set connectable mode failed");
+
+ #else
+ #if defined(TIZEN_PROFILE_TV)
+
+ if (_bt_set_discoverable_mode(
+ BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE, 0) != BLUETOOTH_ERROR_NONE)
+ BT_ERR("Fail to set discoverable mode");
+ #endif
+ #endif
+
+ /* Update Bluetooth Status to notify other modules */
+ if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0)
+ BT_ERR("Set vconf failed\n");
+
+ if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
+ BT_ERR("Set vconf failed\n");
+
+ if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
+ EVT_VAL_BT_ON) != ES_R_OK)
+ BT_ERR("Fail to set value");
+
+ /* Send enabled event to API */
+ _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
+ g_variant_new("(i)", result));
+
+#ifdef TIZEN_BT_A2DP_SINK_AUTO_CONNECT
+ _bt_audio_start_auto_connect(FALSE);
+#endif
+
+ __bt_set_local_name();
+ _bt_set_discovery_status(FALSE);
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+void _bt_set_disabled(int result)
+{
+ int power_off_status = 0;
+ int ret;
+ int ret_pm_ignore;
+ int pm_ignore_mode = 0;
+
+ ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
+ BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
+
+ ret_pm_ignore = vconf_get_int(VCONFKEY_PM_KEY_IGNORE, &pm_ignore_mode);
+
+ /* Update the vconf BT status in normal Deactivation case only */
+ if (ret == 0 && power_off_status == VCONFKEY_SYSMAN_POWER_OFF_NONE &&
+ ret_pm_ignore == 0 && pm_ignore_mode != VCONFKEY_PM_KEY_LOCK) {
+
+ BT_DBG("Update vconf for BT normal Deactivation");
+
+ if (result == BLUETOOTH_ERROR_TIMEOUT)
+ if (vconf_set_int(BT_OFF_DUE_TO_TIMEOUT, 1) != 0)
+ BT_ERR("Set vconf failed");
+
+ /* Update Bluetooth Status to notify other modules */
+ if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
+ BT_ERR("Set vconf failed");
+
+ if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
+ EVT_VAL_BT_OFF) != ES_R_OK)
+ BT_ERR("Fail to set value");
+ }
+
+ if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
+ BT_ERR("Set vconf failed\n");
+
+ _bt_cancel_queued_transfers();
+// _bt_adapter_set_status(BT_DEACTIVATED);
+ _bt_set_discovery_status(FALSE);
+
+#ifdef TIZEN_FEATURE_BT_USB_DONGLE
+ if (_bt_adapter_get_le_status() != BT_LE_DEACTIVATED) {
+ /* Send disabled event */
+ _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
+ g_variant_new("(i)", result));
+ }
+#endif
+ BT_INFO("Adapter disabled");
+}
+
+#if 0
+void _bt_adapter_set_status(bt_status_t status)
+{
+ BT_INFO("adapter_status changed [%d] -> [%d]", adapter_status, status);
+ adapter_status = status;
+}
+#endif
+bt_status_t _bt_adapter_get_status(void)
+{
+ int value = VCONFKEY_BT_STATUS_OFF;
+
+ /* check VCONFKEY_BT_STATUS */
+ if (vconf_get_int(VCONFKEY_BT_STATUS, &value) != 0) {
+ BT_ERR("fail to get vconf key!");
+ return BLUETOOTH_ADAPTER_DISABLED;
+ }
+
+ return value;
+}
+
+void *_bt_get_adapter_agent(void)
+{
+ return adapter_agent;
+}
+
+
+static int __bt_set_le_enabled(void)
+{
+ BT_DBG("+");
+ int result = BLUETOOTH_ERROR_NONE;
+ bt_status_t status;
+
+ /* Update Bluetooth Status to notify other modules */
+ if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_ON) != 0)
+ BT_ERR("Set vconf failed\n");
+
+ if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
+ EVT_VAL_BT_LE_ON) != ES_R_OK)
+ BT_ERR("Fail to set value");
+
+ /* Send enabled event to API */
+ /*
+ _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
+ DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
+ */
+ status = _bt_adapter_get_status();
+ if (status == BT_DEACTIVATED) {
+ BT_INFO("BREDR is off, turn off PSCAN");
+ _bt_set_connectable(FALSE);
+ }
+ if (le_timer_id > 0) {
+ g_source_remove(le_timer_id);
+ le_timer_id = 0;
+ }
+
+ /* Send enabled event to API */
+ _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_ENABLED,
+ g_variant_new("(i)", result));
+
+ __bt_set_local_name();
+
+ BT_DBG("-");
+ return BLUETOOTH_ERROR_NONE;
+}
+
+static void __bt_state_event_handler(const char *event_name, bundle *data, void *user_data)
+{
+ const char *bt_status = NULL;
+ const char *bt_le_status = NULL;
+ BT_DBG("bt state set event(%s) received", event_name);
+
+ bt_status = bundle_get_val(data, EVT_KEY_BT_STATE);
+ BT_DBG("bt_state: (%s)", bt_status);
+
+ bt_le_status = bundle_get_val(data, EVT_KEY_BT_LE_STATE);
+ BT_DBG("bt_state: (%s)", bt_le_status);
+}
+
+
+void _bt_handle_adapter_added(void)
+{
+ BT_DBG("+");
+ bt_status_t status;
+ bt_le_status_t le_status;
+ int ret;
+
+ status = _bt_adapter_get_status();
+ le_status = _bt_adapter_get_le_status();
+ BT_DBG("status : %d", status);
+ BT_DBG("le_status : %d", le_status);
+
+#ifndef TIZEN_FEATURE_BT_USB_DONGLE
+ {
+ adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE);
+ if (!adapter_agent) {
+ BT_ERR("Fail to register agent");
+ return;
+ }
+ }
+#else
+ {
+ if (adapter_agent == NULL) {
+ adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE);
+ if (!adapter_agent) {
+ BT_ERR("Fail to register agent");
+ return;
+ }
+ }
+ }
+#endif
+
+ if (_bt_register_media_player() != BLUETOOTH_ERROR_NONE)
+ BT_ERR("Fail to register media player");
+
+ if (_bt_register_obex_server() != BLUETOOTH_ERROR_NONE)
+ BT_ERR("Fail to init obex server");
+
+#ifdef TIZEN_BT_PAN_NAP_ENABLED
+ if (_bt_network_activate() != BLUETOOTH_ERROR_NONE)
+ BT_ERR("Fail to activate network");
+#endif
+
+ /* add the vconf noti handler */
+ ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
+ __bt_phone_name_changed_cb, NULL);
+ if (ret < 0)
+ BT_ERR("Unable to register key handler");
+
+ if (le_status == BT_LE_ACTIVATING ||
+ status == BT_ACTIVATING) {
+ __bt_set_le_enabled();
+ _bt_adapter_set_le_status(BT_LE_ACTIVATED);
+ }
+
+ if (status == BT_ACTIVATING) {
+ __bt_set_enabled();
+ //_bt_adapter_set_status(BT_ACTIVATED);
+ }
+
+ /* eventsystem */
+ if (eventsystem_register_event(SYS_EVENT_BT_STATE, &status_reg_id,
+ (eventsystem_handler)__bt_state_event_handler, NULL) != ES_R_OK) {
+ BT_ERR("Fail to register system event");
+ }
+}
+
+void _bt_handle_adapter_removed(void)
+{
+ int ret;
+
+ //_bt_adapter_set_status(BT_DEACTIVATED);
+
+ __bt_visibility_alarm_remove();
+
+ if (alarm_mgr.is_alarm_initialized == TRUE) {
+ alarmmgr_fini();
+ alarm_mgr.is_alarm_initialized = FALSE;
+ g_list_free_full(alarm_mgr.g_alarm_list, alarm_data_free);
+ alarm_mgr.g_alarm_list = NULL;
+ }
+
+#ifdef TIZEN_BT_A2DP_SINK_AUTO_CONNECT
+ _bt_audio_stop_auto_connect();
+#endif
+
+ ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
+ (vconf_callback_fn)__bt_phone_name_changed_cb);
+ if (0 != ret)
+ ERR("vconf_ignore_key_changed failed\n");
+
+/* unregister all the services/servers/profiles registered on bluez-adapter
+ once adapter is removed, reinitializing of the state-varaibles becomes
+ a problem */
+ if (_bt_unregister_obex_server() != BLUETOOTH_ERROR_NONE)
+ BT_ERR("Fail to unregister obex server");
+
+ if (_bt_unregister_media_player() != BLUETOOTH_ERROR_NONE)
+ BT_ERR("Fail to unregister media player");
+
+/* Other unregister APIs should be placed here */
+
+#ifndef TIZEN_FEATURE_BT_USB_DONGLE_D
+{
+ _bt_destroy_agent(adapter_agent);
+ adapter_agent = NULL;
+
+ if (is_recovery_mode == TRUE) {
+ /* Send disabled event */
+ _bt_set_disabled(BLUETOOTH_ERROR_NONE);
+
+ /* Will recover BT by bt-core, so set the mode as activating */
+// _bt_adapter_set_status(BT_ACTIVATING);
+ is_recovery_mode = FALSE;
+ } else {
+ _bt_reliable_terminate_service(NULL);
+ }
+ }
+#else
+ {
+ _bt_set_disabled(BLUETOOTH_ERROR_NONE);
+ }
+#endif
+
+ if (eventsystem_unregister_event(status_reg_id) != ES_R_OK)
+ BT_ERR("Fail to unregister system event");
+}
+#endif
#include "bt-service-rfcomm.h"
#include "bt-service-hdp.h"
+#ifdef TIZEN_FEATURE_BT_OBEX
+/*Obex*/
+#include "bt-service-obex-server.h"
+#include "bt-service-opp-client.h"
+#include "bt-service-map-client.h"
+#include "bt-service-pbap.h"
+#include "bt-service-oob.h"
+#endif
+
/* For AVRCP target role */
static char *current_sender_playing = NULL;
result = BLUETOOTH_ERROR_NONE;
break;
}
+#ifdef TIZEN_FEATURE_BT_OBEX
+ case BT_OOB_READ_LOCAL_DATA: { //208
+ bt_oob_data_t local_oob_data;
+
+ memset(&local_oob_data, 0x00, sizeof(bt_oob_data_t));
+ result = _bt_oob_read_local_data(&local_oob_data);
+
+ g_array_append_vals(*out_param1, &local_oob_data,
+ sizeof(bt_oob_data_t));
+
+ break;
+ }
+ case BT_OOB_ADD_REMOTE_DATA: { //209
+ bluetooth_device_address_t address = { {0} };
+ unsigned short address_type;
+ bt_oob_data_t remote_oob_data;
+
+ __bt_service_get_parameters(in_param1,
+ &address, sizeof(bluetooth_device_address_t));
+ __bt_service_get_parameters(in_param2,
+ &address_type, sizeof(unsigned short));
+ __bt_service_get_parameters(in_param3,
+ &remote_oob_data, sizeof(bt_oob_data_t));
+
+ result = _bt_oob_add_remote_data(&address, address_type, &remote_oob_data);
+
+ break;
+ }
+ case BT_OOB_REMOVE_REMOTE_DATA: { //210
+ bluetooth_device_address_t address = { {0} };
+
+ __bt_service_get_parameters(in_param1,
+ &address, sizeof(bluetooth_device_address_t));
+
+ result = _bt_oob_remove_remote_data(&address);
+
+ break;
+ }
+#endif
case BT_AVRCP_SET_TRACK_INFO: {
media_metadata_t data;
media_metadata_attributes_t meta_data;
return result;
}
+#ifdef TIZEN_FEATURE_BT_OBEX
+/* Function definitions*/
+static void __bt_fill_garray_from_variant(GVariant *var, GArray *param)
+{
+ char *data;
+ int size;
+
+ size = g_variant_get_size(var);
+ if (size > 0) {
+ data = (char *)g_variant_get_data(var);
+ if (data)
+ param = g_array_append_vals(param, data, size);
+
+ }
+}
+#endif
int __bt_obexd_request(int function_name,
int request_type,
BT_DBG("function_name : %x", function_name);
switch (function_name) {
- /*TODO*/
+#ifdef TIZEN_FEATURE_BT_OBEX
+ case BT_OPP_PUSH_FILES: {
+ BT_DBG("BT_OPP_PUSH_FILES");
+ int i;
+ bluetooth_device_address_t address = { {0} };
+ bt_file_path_t path;
+ char **file_path;
+ int file_count;
+ GArray *param2;
+
+ __bt_service_get_parameters(in_param1, &address,
+ sizeof(bluetooth_device_address_t));
+ __bt_service_get_parameters(in_param3, &file_count,
+ sizeof(int));
+
+ file_path = g_new0(char *, file_count + 1);
+
+ param2 = g_array_new(TRUE, TRUE, sizeof(gchar));
+ __bt_fill_garray_from_variant(in_param2, param2);
+
+ for (i = 0; i < file_count; i++) {
+ path = g_array_index(param2, bt_file_path_t, i);
+ file_path[i] = g_strdup(path.path);
+ }
+ BT_DBG("_bt_opp_client_push_files");
+ result = _bt_opp_client_push_files(request_id, context,
+ &address, file_path,
+ file_count);
+
+ for (i = 0; i < file_count; i++)
+ g_free(file_path[i]);
+
+ g_free(file_path);
+ g_array_free(param2, TRUE);
+
+ break;
+ }
+ case BT_OPP_CANCEL_PUSH: {
+ result = _bt_opp_client_cancel_push();
+
+ break;
+ }
+ case BT_OPP_IS_PUSHING_FILES: {
+ gboolean is_sending = FALSE;
+
+ result = _bt_opp_client_is_sending(&is_sending);
+
+ g_array_append_vals(*out_param1, &is_sending,
+ sizeof(gboolean));
+ break;
+ }
+ case BT_OPP_GET_TRANSFER_PROGRESS: {
+ int direction;
+ int transfer_id;
+ guint8 progress = 0;
+
+ __bt_service_get_parameters(in_param1, &direction,
+ sizeof(int));
+ __bt_service_get_parameters(in_param2, &transfer_id,
+ sizeof(int));
+ if (direction)
+ result = _bt_opp_get_client_progress(&progress);
+ else
+ result = _bt_opp_get_server_progress(transfer_id, &progress);
+
+ g_array_append_vals(*out_param1, &progress,
+ sizeof(guint8));
+
+ break;
+ }
+
+ case BT_MAP_CREATE_SESSION: {
+ BT_DBG("BT_MAP_CREATE_SESSION");
+ char *address = (char *)g_variant_get_data(in_param1);
+ char *session_id = NULL;
+ result = _bt_create_session_sync(address, &session_id);
+ if (result == BLUETOOTH_ERROR_NONE)
+ g_array_append_vals(*out_param1, session_id, strlen(session_id)+1);
+ break;
+ }
+
+ case BT_MAP_DESTROY_SESSION: {
+ BT_DBG("BT_MAP_DESTROY_SESSION");
+ char* session_id = (char *)g_variant_get_data(in_param1);
+ result = _bt_destroy_session_sync(session_id);
+ if (result == BLUETOOTH_ERROR_NONE)
+ BT_DBG("successfully destroyed session");
+ break;
+ }
+
+ case BT_MAP_SET_FOLDER: {
+ BT_DBG("BT_MAP_SET_FOLDER");
+ char *session_id = (char *)g_variant_get_data(in_param1);
+ char *name = (char *)g_variant_get_data(in_param2);
+ result = _bt_map_client_set_folder(session_id, name);
+ break;
+ }
+
+ case BT_MAP_LIST_FOLDERS: {
+ BT_DBG("BT_MAP_LIST_FOLDERS");
+
+ char* session_id = (char *)g_variant_get_data(in_param1);
+ char* filter_serialized = (char*)g_variant_get_data(in_param2);
+
+ result = _bt_map_client_list_folders(request_id, context, session_id, filter_serialized);
+ if (result == BLUETOOTH_ERROR_NONE)
+ BT_DBG("_bt_map_client_list_folders succeed");
+
+ break;
+ }
+
+ case BT_MAP_LIST_FILTER_FIELDS: {
+ BT_DBG("BT_MAP_LIST_FILTER_FIELDS");
+
+ char* session_id = (char *)g_variant_get_data(in_param1);
+
+ result = _bt_map_client_list_filter_fields(request_id, context, session_id);
+ if (result == BLUETOOTH_ERROR_NONE)
+ BT_DBG("_bt_map_client_list_filter_fields succeed");
+
+ break;
+ }
+
+ case BT_MAP_LIST_MESSAGES: {
+ BT_DBG("BT_MAP_LIST_MESSAGES");
+
+ char* session_id = (char*)g_variant_get_data(in_param1);
+ char* folder = (char*)g_variant_get_data(in_param2);
+ char* filter_serialized = (char*)g_variant_get_data(in_param3);
+
+ result = _bt_map_client_list_messages(request_id, context, session_id, folder, filter_serialized);
+ if (result == BLUETOOTH_ERROR_NONE)
+ BT_DBG("_bt_map_client_list_messages succeed");
+ else
+ BT_DBG("_bt_map_client_list_messages failed");
+
+ break;
+ }
+
+ case BT_MAP_UPDATE_INBOX: {
+ BT_DBG("BT_MAP_UPDATE_INBOX");
+ char* session_id = (char *)g_variant_get_data(in_param1);
+ result = _bt_map_client_update_inbox(session_id);
+ break;
+ }
+
+ case BT_MAP_PUSH_MESSAGE: {
+ BT_DBG("BT_MAP_PUSH_MESSAGE");
+
+ char* session_id = (char *)g_variant_get_data(in_param1);
+ char* source_file = (char *)g_variant_get_data(in_param2);
+ char* folder = (char *)g_variant_get_data(in_param3);
+ char* args_serialized = (char *)g_variant_get_data(in_param4);
+
+ result = _bt_map_client_push_message(
+ request_id, context, session_id, source_file, folder, args_serialized);
+ if (result == BLUETOOTH_ERROR_NONE)
+ BT_DBG("_bt_map_client_push_message succeed");
+ else
+ BT_ERR("_bt_map_client_push_message failed");
+
+ break;
+ }
+
+ case BT_MAP_GET_MESSAGE: {
+ BT_DBG("BT_MAP_GET_MESSAGE");
+ // TODO session currently is not used, but should be valid
+ //char* session_id = (char *)g_variant_get_data(in_param1);
+ char* message_object = (char *)g_variant_get_data(in_param2);
+ char* target_file = (char *)g_variant_get_data(in_param3);
+ bool attachment = false;
+ __bt_service_get_parameters(in_param4, &attachment, sizeof(bool));
+
+ result = _bt_map_client_get_message(request_id, context, message_object,
+ target_file, attachment);
+ if (result == BLUETOOTH_ERROR_NONE)
+ BT_DBG("_bt_map_client_get_message succeed");
+
+ break;
+ }
+
+ case BT_OBEX_SERVER_ALLOCATE: {
+ int app_pid;
+ gboolean is_native;
+ char *path;
+ char *sender;
+
+ sender = (char *)g_dbus_method_invocation_get_sender(context);
+
+ path = (char *)g_variant_get_data(in_param1);
+ __bt_service_get_parameters(in_param2, &is_native,
+ sizeof(gboolean));
+ __bt_service_get_parameters(in_param3, &app_pid,
+ sizeof(int));
+
+ result = _bt_obex_server_allocate(sender,
+ path, app_pid, is_native);
+
+ break;
+ }
+ case BT_OBEX_SERVER_DEALLOCATE: {
+ int app_pid;
+ gboolean is_native;
+
+ __bt_service_get_parameters(in_param1, &is_native,
+ sizeof(gboolean));
+ __bt_service_get_parameters(in_param2, &app_pid,
+ sizeof(int));
+
+ result = _bt_obex_server_deallocate(app_pid, is_native);
+ break;
+ }
+ case BT_OBEX_SERVER_IS_ACTIVATED: {
+ gboolean is_activated = FALSE;
+
+ result = _bt_obex_server_is_activated(&is_activated);
+
+ g_array_append_vals(*out_param1, &is_activated,
+ sizeof(gboolean));
+
+ break;
+ }
+ case BT_OBEX_SERVER_ACCEPT_CONNECTION: {
+ result = _bt_obex_server_accept_connection(request_id);
+
+ break;
+ }
+ case BT_OBEX_SERVER_REJECT_CONNECTION: {
+ result = _bt_obex_server_reject_connection();
+
+ break;
+ }
+ case BT_OBEX_SERVER_ACCEPT_FILE: {
+ char *file_name;
+
+ file_name = (char *)g_variant_get_data(in_param1);
+
+ result = _bt_obex_server_accept_authorize(file_name, TRUE);
+
+ break;
+ }
+ case BT_OBEX_SERVER_REJECT_FILE: {
+ result = _bt_obex_server_reject_authorize();
+
+ break;
+ }
+ case BT_OBEX_SERVER_SET_PATH: {
+ gboolean is_native;
+ char *destination_path;
+
+ destination_path = (char *)g_variant_get_data(in_param1);
+ __bt_service_get_parameters(in_param2, &is_native,
+ sizeof(gboolean));
+
+ result = _bt_obex_server_set_destination_path(destination_path,
+ is_native);
+
+ break;
+ }
+ case BT_OBEX_SERVER_SET_ROOT: {
+ char *root;
+
+ root = (char *)g_variant_get_data(in_param1);
+
+ result = _bt_obex_server_set_root(root);
+
+ break;
+ }
+ case BT_OBEX_SERVER_CANCEL_TRANSFER: {
+ int transfer_id;
+
+ __bt_service_get_parameters(in_param1, &transfer_id,
+ sizeof(int));
+
+ result = _bt_obex_server_cancel_transfer(transfer_id);
+
+ break;
+ }
+ case BT_OBEX_SERVER_CANCEL_ALL_TRANSFERS: {
+ result = _bt_obex_server_cancel_all_transfers();
+
+ break;
+ }
+ case BT_OBEX_SERVER_IS_RECEIVING: {
+ gboolean is_receiving = FALSE;
+
+ result = _bt_obex_server_is_receiving(&is_receiving);
+
+ g_array_append_vals(*out_param1, &is_receiving,
+ sizeof(gboolean));
+ break;
+ }
+ case BT_PBAP_CONNECT: {
+ bluetooth_device_address_t address = { {0} };
+
+ __bt_service_get_parameters(in_param1, &address,
+ sizeof(bluetooth_device_address_t));
+
+ result = _bt_pbap_connect(&address);
+ break;
+ }
+ case BT_PBAP_DISCONNECT: {
+ bluetooth_device_address_t address = { {0} };
+
+ __bt_service_get_parameters(in_param1, &address,
+ sizeof(bluetooth_device_address_t));
+
+ result = _bt_pbap_disconnect(&address);
+ break;
+ }
+ case BT_PBAP_GET_PHONEBOOK_SIZE: {
+ bluetooth_device_address_t address = { {0} };
+ bt_pbap_folder_t folder = { 0, };
+
+ __bt_service_get_parameters(in_param1, &address,
+ sizeof(bluetooth_device_address_t));
+ __bt_service_get_parameters(in_param2, &folder,
+ sizeof(bt_pbap_folder_t));
+
+ result = _bt_pbap_get_phonebook_size(&address,
+ folder.addressbook, folder.folder_type);
+ break;
+ }
+ case BT_PBAP_GET_PHONEBOOK: {
+ bluetooth_device_address_t address = { {0} };
+ bt_pbap_folder_t folder = { 0, };
+ bt_pbap_pull_parameters_t app_param = { 0, };
+
+ __bt_service_get_parameters(in_param1, &address,
+ sizeof(bluetooth_device_address_t));
+ __bt_service_get_parameters(in_param2, &folder,
+ sizeof(bt_pbap_folder_t));
+ __bt_service_get_parameters(in_param3, &app_param,
+ sizeof(bt_pbap_pull_parameters_t));
+
+ result = _bt_pbap_get_phonebook(&address, folder.addressbook,
+ folder.folder_type, &app_param);
+ break;
+ }
+ case BT_PBAP_GET_LIST: {
+ bluetooth_device_address_t address = { {0} };
+ bt_pbap_folder_t folder = { 0, };
+ bt_pbap_list_parameters_t app_param = { 0, };
+
+ __bt_service_get_parameters(in_param1, &address,
+ sizeof(bluetooth_device_address_t));
+ __bt_service_get_parameters(in_param2, &folder,
+ sizeof(bt_pbap_folder_t));
+ __bt_service_get_parameters(in_param3, &app_param,
+ sizeof(bt_pbap_list_parameters_t));
+
+ result = _bt_pbap_get_list(&address, folder.addressbook,
+ folder.folder_type, &app_param);
+ break;
+ }
+ case BT_PBAP_PULL_VCARD: {
+ bluetooth_device_address_t address = { {0} };
+ bt_pbap_folder_t folder = { 0, };
+ bt_pbap_pull_vcard_parameters_t app_param = { 0, };
+
+ __bt_service_get_parameters(in_param1, &address,
+ sizeof(bluetooth_device_address_t));
+ __bt_service_get_parameters(in_param2, &folder,
+ sizeof(bt_pbap_folder_t));
+ __bt_service_get_parameters(in_param3, &app_param,
+ sizeof(bt_pbap_pull_vcard_parameters_t));
+
+ result = _bt_pbap_pull_vcard(&address, folder.addressbook,
+ folder.folder_type, &app_param);
+ break;
+ }
+ case BT_PBAP_PHONEBOOK_SEARCH: {
+ bluetooth_device_address_t address = { {0} };
+ bt_pbap_folder_t folder = { 0, };
+ bt_pbap_search_parameters_t app_param = { 0, };
+
+ __bt_service_get_parameters(in_param1, &address,
+ sizeof(bluetooth_device_address_t));
+ __bt_service_get_parameters(in_param2, &folder,
+ sizeof(bt_pbap_folder_t));
+ __bt_service_get_parameters(in_param3, &app_param,
+ sizeof(bt_pbap_search_parameters_t));
+
+ result = _bt_pbap_phonebook_search(&address, folder.addressbook,
+ folder.folder_type, &app_param);
+ break;
+ }
+#endif
default:
+#ifdef TIZEN_FEATURE_BT_OBEX
+ BT_ERR("Unknown function!");
+ result = BLUETOOTH_ERROR_INTERNAL;
+#endif
break;
}
#include "bluetooth-api.h"
#include "bt-service-common.h"
+#ifdef TIZEN_FEATURE_BT_OBEX
+#include "bt-service-agent.h"
+#endif
#include <oal-manager.h>
BT_DBG("-");
return TRUE;
}
+#ifdef TIZEN_FEATURE_BT_OBEX
+int _bt_register_osp_server_in_agent(int type, char *uuid, char *path, int fd)
+{
+ BT_DBG("+");
+ if (!_bt_agent_register_osp_server(type, uuid, path, fd))
+ return BLUETOOTH_ERROR_INTERNAL;
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_unregister_osp_server_in_agent(int type, char *uuid)
+{
+ BT_DBG("+");
+ if (!_bt_agent_unregister_osp_server(type, uuid))
+ return BLUETOOTH_ERROR_INTERNAL;
+
+ return BLUETOOTH_ERROR_NONE;
+}
+#endif
int _bt_set_socket_non_blocking(int socket_fd)
{
return BLUETOOTH_ERROR_NONE;
}
+#ifdef TIZEN_FEATURE_BT_OBEX
+void __bt_get_auth_info(GVariant *reply, char *auth_info)
+{
+ int cursor;
+ GVariant *tmp_value;
+ char *manufacturer_data = NULL;
+ int manufacturer_data_len;
+ gboolean is_alias_set;
+ GVariantIter *value_iter;
+ guint8 m_value;
+ int i = 0;
+
+ tmp_value = g_variant_lookup_value(reply, "IsAliasSet",
+ G_VARIANT_TYPE_BOOLEAN);
+ if (tmp_value) {
+ is_alias_set = g_variant_get_boolean(tmp_value);
+ g_variant_unref(tmp_value);
+ } else {
+ is_alias_set = FALSE;
+ }
+ if (is_alias_set == FALSE) {
+ tmp_value = g_variant_lookup_value(reply, "ManufacturerDataLen",
+ G_VARIANT_TYPE_UINT16);
+ if (tmp_value) {
+ manufacturer_data_len = g_variant_get_uint16(tmp_value);
+ if (manufacturer_data_len >
+ BLUETOOTH_MANUFACTURER_DATA_LENGTH_MAX) {
+ BT_ERR("manufacturer_data_len is too long");
+ manufacturer_data_len = BLUETOOTH_MANUFACTURER_DATA_LENGTH_MAX;
+ }
+ g_variant_unref(tmp_value);
+ } else
+ manufacturer_data_len = 0;
+
+ tmp_value = g_variant_lookup_value(reply, "ManufacturerData",
+ G_VARIANT_TYPE_ARRAY);
+ if (tmp_value) {
+ if ((manufacturer_data_len == 0) ||
+ manufacturer_data_len != g_variant_get_size(tmp_value)) {
+ BT_ERR("manufacturer data length doesn't match");
+ manufacturer_data_len = 0;
+ manufacturer_data = NULL;
+ } else {
+ manufacturer_data = g_malloc0(manufacturer_data_len);
+ g_variant_get(tmp_value, "ay", &value_iter);
+ while (g_variant_iter_loop(value_iter, "y", &m_value))
+ manufacturer_data[i++] = m_value;
+ }
+ g_variant_unref(tmp_value);
+ } else {
+ BT_INFO("manufacture data is not a G_VARIANT_TYPE_ARRAY ");
+ manufacturer_data_len = 0;
+ manufacturer_data = NULL;
+ }
+ /*minimum Size of the samsung specific manufacturer data is greater than 30 */
+ if (manufacturer_data_len < 30) {
+ g_free(manufacturer_data);
+ return;
+ }
+ if (manufacturer_data[0] != 0x00 || manufacturer_data[1] != 0x75) {
+ BT_DBG("This is not a samsung specific manufaturer data");
+ g_free(manufacturer_data);
+ return;
+ }
+
+ /* 2 samsung (0x00 0x75) + 1 (control and version) + 1 (service ID) +
+ 1 (discovery version) + 1 (associated service ID)
+ 2 (Proxamity and locality) + 2 (Device type and icon) */
+
+ cursor = 10;
+
+ memcpy(auth_info, &(manufacturer_data[cursor]), 5);
+ }
+ g_free(manufacturer_data);
+}
+#endif
BT_ERR("Fail to init cynara");
return EXIT_FAILURE;
}
-
+#ifdef TIZEN_FEATURE_BT_OBEX
+ /* Event reciever Init */
+ if (_bt_init_service_event_receiver() != BLUETOOTH_ERROR_NONE) {
+ BT_ERR("Fail to init event reciever");
+ return 0;
+ }
+#endif
/* Event sender Init */
if (_bt_init_service_event_sender() != BLUETOOTH_ERROR_NONE) {
BT_ERR("Fail to init event sender");
BT_ERR("Fail to init BT Stack");
return 0;
}
+#ifdef TIZEN_FEATURE_BT_OBEX
+ bluetooth_plugin_init();
+#endif
g_timeout_add(500, (GSourceFunc)__bt_check_bt_service, NULL);
g_main_loop_run(main_loop);
BT_DBG("g_main_loop_quit called!");
+#ifdef TIZEN_FEATURE_BT_OBEX
+ bluetooth_plugin_deinit();
+#endif
if (main_loop != NULL) {
g_main_loop_unref(main_loop);
#include <glib.h>
#include <dlog.h>
#include <gio/gio.h>
+#ifdef TIZEN_FEATURE_BT_OBEX
+#include <dlfcn.h>
+#endif
#include "bluetooth-api.h"
#include "bt-service-common.h"
#include "bt-service-util.h"
+#ifdef TIZEN_FEATURE_BT_OBEX
+static GSList *req_list = NULL;
+
+/* available request id : 0 ~ 244 */
+#define BT_REQUEST_ID_RANGE_MAX 245
+
+static int assigned_id;
+static gboolean req_id_used[BT_REQUEST_ID_RANGE_MAX];
+
+bt_plugin_info_t *headed_plugin_info = NULL;
+
+void _bt_init_request_id(void)
+{
+ assigned_id = 0;
+ memset(req_id_used, 0x00, BT_REQUEST_ID_RANGE_MAX);
+}
+
+int _bt_assign_request_id(void)
+{
+ int index;
+
+ index = assigned_id + 1;
+
+ if (index >= BT_REQUEST_ID_RANGE_MAX)
+ index = 0;
+
+ while (req_id_used[index] == TRUE) {
+ if (index == assigned_id) {
+ /* No available ID */
+ BT_ERR("All request ID is used");
+ return -1;
+ }
+
+ index++;
+
+ if (index >= BT_REQUEST_ID_RANGE_MAX)
+ index = 0;
+ }
+
+ assigned_id = index;
+ req_id_used[index] = TRUE;
+
+ return assigned_id;
+}
+
+void _bt_delete_request_id(int request_id)
+{
+ ret_if(request_id >= BT_REQUEST_ID_RANGE_MAX);
+ ret_if(request_id < 0);
+
+ req_id_used[request_id] = FALSE;
+}
+
+void _bt_init_request_list(void)
+{
+ _bt_clear_request_list();
+}
+
+/* insert request next to head */
+int _bt_insert_request_list(int req_id, int service_function,
+ char *name, GDBusMethodInvocation *context)
+{
+ request_info_t *info;
+
+ info = g_malloc0(sizeof(request_info_t));
+ /* Fix : NULL_RETURNS */
+ retv_if(info == NULL, BLUETOOTH_ERROR_MEMORY_ALLOCATION);
+
+ info->req_id = req_id;
+ info->service_function = service_function;
+ info->context = context;
+
+ req_list = g_slist_append(req_list, info);
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+request_info_t *_bt_get_request_info(int req_id)
+{
+ GSList *l;
+ request_info_t *info;
+
+ for (l = req_list; l != NULL; l = g_slist_next(l)) {
+ info = l->data;
+ if (info == NULL)
+ continue;
+
+ if (info->req_id == req_id)
+ return info;
+ }
+
+ return NULL;
+}
+/* delete request which has the target req_id */
+int _bt_delete_request_list(int req_id)
+{
+ GSList *l;
+ request_info_t *info;
+
+ for (l = req_list; l != NULL; l = g_slist_next(l)) {
+ info = l->data;
+ if (info == NULL)
+ continue;
+
+ if (info->req_id == req_id) {
+ req_list = g_slist_remove(req_list, info);
+ _bt_delete_request_id(info->req_id);
+ g_free(info);
+ return BLUETOOTH_ERROR_NONE;
+ }
+ }
+
+ return BLUETOOTH_ERROR_NOT_FOUND;
+}
+
+void _bt_clear_request_list(void)
+{
+ if (req_list) {
+ g_slist_foreach(req_list, (GFunc)g_free, NULL);
+ g_slist_free(req_list);
+ req_list = NULL;
+ }
+}
+
+#endif
void _bt_service_convert_uuid_type_to_string(char *str, const unsigned char *uuid)
{
ret_if(str == NULL);
return str;
}
+
+#ifdef TIZEN_FEATURE_BT_OBEX
+
+void bluetooth_plugin_init()
+{
+ headed_plugin_info = g_malloc0(sizeof(bt_plugin_info_t));
+ if (!headed_plugin_info) {
+ BT_ERR("Can not memory alloc headed plugin");
+ return;
+ }
+
+ /* check ARCH 64 or 32*/
+ if (!access(FILEPATH_ARCH_64, 0)) {
+ BT_INFO("plugin loading for ARCH 64");
+ headed_plugin_info->handle_headed = dlopen(HEADED_PLUGIN_FILEPATH64, RTLD_NOW);
+ } else {
+ BT_INFO("plugin loading for ARCH 32");
+ headed_plugin_info->handle_headed = dlopen(HEADED_PLUGIN_FILEPATH, RTLD_NOW);
+ }
+
+ if (!headed_plugin_info->handle_headed) {
+ BT_ERR("Can not load plugin %s", dlerror());
+ headed_plugin_info->plugin_headed_enabled = FALSE;
+ return;
+ }
+
+ headed_plugin_info->headed_plugin = dlsym(headed_plugin_info->handle_headed, "headed_plugin");
+ if (!headed_plugin_info->headed_plugin) {
+ BT_ERR("Can not load symbol : %s", dlerror());
+ dlclose(headed_plugin_info->handle_headed);
+ headed_plugin_info->plugin_headed_enabled = FALSE;
+ return;
+ }
+
+ headed_plugin_info->plugin_headed_enabled = TRUE;
+ BT_INFO("Bluetooth Headed Plugin Initialized");
+}
+
+void bluetooth_plugin_deinit()
+{
+ BT_INFO("Bluetooth Headed Plugin Deintialized");
+ if (!headed_plugin_info->plugin_headed_enabled) {
+ g_free(headed_plugin_info);
+ headed_plugin_info = NULL;
+ return;
+ }
+
+ dlclose(headed_plugin_info->handle_headed);
+ headed_plugin_info->plugin_headed_enabled = FALSE;
+ g_free(headed_plugin_info);
+ headed_plugin_info = NULL;
+}
+#endif
+
bt_bond_data_t *trigger_unbond_info;
bt_pairing_data_t *trigger_pairing_info;
bt_service_search_info_data_t *service_search_info;
+#ifdef TIZEN_FEATURE_BT_OBEX
+gboolean is_device_creating;
+static GSList *pin_info_list = NULL;
+#endif
typedef enum {
BT_DEVICE_BOND_STATE_NONE,
static void __bt_device_trusted_callback(gboolean trusted, event_dev_trust_t* info);
+#ifdef TIZEN_FEATURE_BT_OBEX
+gboolean _bt_is_device_creating(void)
+{
+ return is_device_creating;
+}
+#endif
+
void _bt_device_state_handle_callback_set_request(void)
{
_bt_service_register_event_handler_callback(
BT_DBG("-");
}
+#ifdef TIZEN_FEATURE_BT_OBEX
+char *_bt_get_trusted_profile_uuid(bluetooth_trusted_profile_t profile)
+{
+ switch (profile) {
+ case TRUSTED_PROFILE_PBAP:
+ return g_strdup("00001130-0000-1000-8000-00805f9b34fb");
+ case TRUSTED_PROFILE_MAP:
+ return g_strdup("00001134-0000-1000-8000-00805f9b34fb");
+ case TRUSTED_PROFILE_SAP:
+ return g_strdup("0000112D-0000-1000-8000-00805f9b34fb");
+ case TRUSTED_PROFILE_ALL:
+ return NULL;
+ }
+
+ return NULL;
+}
+
+
+int _bt_set_trust_profile(bluetooth_device_address_t *bd_addr,
+ bluetooth_trusted_profile_t profile, gboolean trust)
+{
+ int ret = BLUETOOTH_ERROR_NONE;
+ GDBusConnection *conn;
+ GDBusProxy *proxy;
+ GError *error = NULL;
+ char *device_path = NULL;
+ char *uuid = NULL;
+ char address[BT_ADDRESS_STRING_SIZE] = { 0 };
+ GVariant *reply;
+
+ BT_CHECK_PARAMETER(bd_addr, return);
+ BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X] profile[%d] trust[%d]",
+ bd_addr->addr[0], bd_addr->addr[1],
+ bd_addr->addr[2], bd_addr->addr[3],
+ bd_addr->addr[4], bd_addr->addr[5],
+ profile, trust);
+
+ conn = _bt_gdbus_get_system_gconn();
+ retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ _bt_convert_addr_type_to_string(address, bd_addr->addr);
+
+ device_path = _bt_get_device_object_path(address);
+ retv_if(device_path == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
+ NULL, BT_BLUEZ_NAME, device_path,
+ BT_DEVICE_INTERFACE, NULL, NULL);
+
+ g_free(device_path);
+ retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ uuid = _bt_get_trusted_profile_uuid(profile);
+ if (uuid == NULL) {
+ g_object_unref(proxy);
+ return BLUETOOTH_ERROR_NOT_SUPPORT;
+ }
+
+ reply = g_dbus_proxy_call_sync(proxy, "SetTrustedProfile",
+ g_variant_new("(sb)", uuid, trust),
+ G_DBUS_CALL_FLAGS_NONE, -1,
+ NULL, &error);
+ g_object_unref(proxy);
+
+ if (reply == NULL) {
+ BT_ERR("Failed to Set Profile Trusted");
+ ret = BLUETOOTH_ERROR_INTERNAL;
+ if (error) {
+ BT_ERR("Error %s[%s]", error->message, address);
+ g_error_free(error);
+ }
+ goto finish;
+ }
+ g_variant_unref(reply);
+
+finish:
+ g_free(uuid);
+ return ret;
+}
+
+bluetooth_trusted_profile_t _bt_get_trusted_profile_enum(const char *uuid)
+{
+ if (g_strcmp0("0000112f-0000-1000-8000-00805f9b34fb", uuid) == 0)
+ return TRUSTED_PROFILE_PBAP;
+ else if (g_strcmp0("00001132-0000-1000-8000-00805f9b34fb", uuid) == 0)
+ return TRUSTED_PROFILE_MAP;
+ else if (g_strcmp0("0000112D-0000-1000-8000-00805f9b34fb", uuid) == 0)
+ return TRUSTED_PROFILE_SAP;
+
+ return 0; /* 0 - Unknown Profile */
+}
+
+
+int _bt_get_device_pin_code(const char *address, char *pin_code)
+{
+ GSList *l = NULL;
+
+ BT_CHECK_PARAMETER(address, return);
+ BT_CHECK_PARAMETER(pin_code, return);
+
+ for (l = pin_info_list; l != NULL; l = l->next) {
+ bt_pin_code_info_t *pin_info = l->data;
+
+ if (g_strcmp0(pin_info->address, address) == 0) {
+ g_strlcpy(pin_code, pin_info->pin_code,
+ BLUETOOTH_PIN_CODE_MAX_LENGTH + 1);
+
+ return BLUETOOTH_ERROR_NONE;
+ }
+ }
+
+ return BLUETOOTH_ERROR_NOT_FOUND;
+}
+
+#endif
static void __bt_handle_ongoing_device_service_search(bt_remote_dev_info_t *remote_dev_info)
{
#include "bluetooth-api.h"
#include "bt-request-handler.h"
#include <oal-manager.h>
+#ifdef TIZEN_FEATURE_BT_OBEX
+#include "bt-service-agent.h"
+#endif
#ifdef __cplusplus
extern "C" {
SLOGI_IF(TRUE, LOG_COLOR_RED" "fmt" "LOG_COLOR_RESET, ##arg)
#define DBG_SECURE(fmt, args...) SECURE_SLOGD(fmt, ##args)
+#ifdef TIZEN_FEATURE_BT_OBEX
+#define INFO_SECURE(fmt, args...) SECURE_SLOGI(fmt, ##args)
+#endif
#define ERR_SECURE(fmt, args...) SECURE_SLOGE(fmt, ##args)
#define ret_if(expr) \
#define BT_OBEX_SERVICE_NAME "org.bluez.obex"
#define BT_OBEX_CLIENT_PATH "/org/bluez/obex"
#define BT_OBEX_CLIENT_INTERFACE "org.bluez.obex.Client1"
-
-
+#ifdef TIZEN_FEATURE_BT_OBEX
+#define BT_OBEX_MESSAGE_INTERFACE "org.bluez.obex.MessageAccess1"
+#endif
#define BT_OBEX_TRANSFER_INTERFACE "org.bluez.obex.Transfer1"
#define BT_OBEX_AGENT_INTERFACE "org.bluez.obex.Agent1"
#define BT_LE_ADV_SCAN_IND 0x02
#define BT_LE_ADV_NONCONN_IND 0x03
#define BT_LE_ADV_SCAN_RSP 0x04
+#ifdef TIZEN_FEATURE_BT_OBEX
+#define HEADED_PLUGIN_FILEPATH "/usr/lib/bt-plugin-headed.so"
+#define HEADED_PLUGIN_FILEPATH64 "/usr/lib64/bt-plugin-headed.so"
+#define FILEPATH_ARCH_64 "/usr/lib64"
+#endif
/* Profile states matched to btd_service_state_t of bluez service.h */
typedef enum {
gboolean paired;
bluetooth_connected_link_t connected;
gboolean trust;
+#ifdef TIZEN_FEATURE_BT_OBEX
+ gboolean is_alias_set;
+#endif
char *manufacturer_data;
int manufacturer_data_len;
guchar addr_type;
void _bt_free_remote_dev(bt_remote_dev_info_t * dev_info);
invocation_info_t* _bt_get_request_info_data(int service_function, char *address);
+#ifdef TIZEN_FEATURE_BT_OBEX
+void __bt_get_auth_info(GVariant *reply, char *auth_info);
+#endif
void _bt_set_device_values(gboolean connected, int state);
int _bt_get_ad_data_by_type(char *in_data, int in_len,
char in_type, char **data, int *data_len);
+#ifdef TIZEN_FEATURE_BT_OBEX
+struct bluetooth_headed_plugin_t {
+ int (*bt_launch_dpmpopup) (char *mode);
+ int (*bt_launch_system_popup)(bt_agent_event_type_t event_type,
+ const char *device_name,
+ const unsigned char *auth_info,
+ char *passkey,
+ const char *filename,
+ const char *agent_path);
+ void (*bt_destroy_popup_all)(void);
+ gboolean (*bt_launch_unable_to_pairing_syspopup)(int result);
+};
+
+typedef struct {
+ gboolean plugin_headed_enabled;
+ void *handle_headed;
+ struct bluetooth_headed_plugin_t *headed_plugin;
+} bt_plugin_info_t;
+
+
+extern bt_plugin_info_t *headed_plugin_info;
+
+
+GDBusConnection *_bt_gdbus_get_system_gconn(void);
+#endif
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
#define _BT_SERVICE_CORE_ADAPTER_H_
#include <sys/types.h>
-
+#ifdef TIZEN_FEATURE_BT_OBEX
+#include "alarm.h"
+#endif
#ifdef __cplusplus
extern "C" {
#endif
BT_ACTIVATING,
BT_DEACTIVATING,
} bt_status_t;
+#ifdef TIZEN_FEATURE_BT_OBEX
+typedef enum {
+ BT_LE_DEACTIVATED,
+ BT_LE_ACTIVATED,
+ BT_LE_ACTIVATING,
+ BT_LE_DEACTIVATING,
+} bt_le_status_t;
+#endif
int _bt_enable_adapter(void);
int _bt_cleanup_profiles(void);
+#ifdef TIZEN_FEATURE_BT_OBEX
+
+void _bt_adapter_set_status(bt_status_t status);
+
+bt_status_t _bt_adapter_get_status(void);
+
+void _bt_adapter_set_le_status(bt_le_status_t status);
+
+bt_le_status_t _bt_adapter_get_le_status(void);
+
+void _bt_set_disabled(int result);
+
+typedef int (*bt_set_alarm_cb) (alarm_id_t alarm_id, void* user_param);
+void *_bt_get_adapter_agent(void);
+
+void _bt_handle_adapter_added(void);
+#endif
+
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
extern "C" {
#endif
+#ifdef TIZEN_FEATURE_BT_OBEX
+typedef struct {
+ char *address;
+ char *pin_code;
+} bt_pin_code_info_t;
+
+
+gboolean _bt_is_device_creating(void);
+
+bluetooth_trusted_profile_t _bt_get_trusted_profile_enum(const char *uuid);
+
+
+int _bt_set_trust_profile(bluetooth_device_address_t *bd_addr,
+ bluetooth_trusted_profile_t profile, gboolean trust);
+
+
+int _bt_get_device_pin_code(const char *address, char *pin_code);
+#endif
+
void _bt_device_state_handle_callback_set_request(void);
int _bt_device_get_bonded_device_info(bluetooth_device_address_t *addr);
0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb
};
+#ifdef TIZEN_FEATURE_BT_OBEX
+typedef struct {
+ int req_id;
+ int service_function;
+ char name[BT_NODE_NAME_LEN];
+ GDBusMethodInvocation *context;
+} request_info_t;
+
+
+void _bt_init_request_id(void);
+
+int _bt_assign_request_id(void);
+
+void _bt_delete_request_id(int request_id);
+
+
+void _bt_init_request_list(void);
+
+int _bt_insert_request_list(int req_id, int service_function,
+ char *name, GDBusMethodInvocation *context);
+
+int _bt_delete_request_list(int req_id);
+
+request_info_t *_bt_get_request_info(int req_id);
+
+void _bt_clear_request_list(void);
+
+void bluetooth_plugin_init();
+void bluetooth_plugin_deinit();
+#endif
+
void _bt_service_convert_uuid_type_to_string(char *str, const unsigned char *uuid);
void _bt_service_convert_uuid_string_to_type(unsigned char *uuid, const char *str);
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <malloc.h>
+#include <stacktrim.h>
+#include <vconf.h>
+#include <bundle_internal.h>
+
+#ifdef TIZEN_FEATURE_NETWORK_TETHERING_ENABLE
+#include <tethering.h>
+#endif
+
+#include "bt-internal-types.h"
+#include "bt-service-common.h"
+#include "bt-service-agent.h"
+#include "bt-service-gap-agent.h"
+#include "bt-service-core-adapter.h"
+#include "bt-service-event.h"
+//#include "bt-service-rfcomm-server.h"
+#include "bt-service-device.h"
+#include "bt-service-audio.h"
+
+#ifdef TIZEN_FEATURE_BT_DPM
+#include "bt-service-dpm.h"
+#endif
+
+#define BT_APP_AUTHENTICATION_TIMEOUT 35
+#define BT_APP_AUTHORIZATION_TIMEOUT 15
+
+#define HFP_AUDIO_GATEWAY_UUID "0000111f-0000-1000-8000-00805f9b34fb"
+#define HSP_AUDIO_GATEWAY_UUID "00001112-0000-1000-8000-00805f9b34fb"
+#define A2DP_UUID "0000110D-0000-1000-8000-00805F9B34FB"
+#define AVRCP_TARGET_UUID "0000110c-0000-1000-8000-00805f9b34fb"
+#define OPP_UUID "00001105-0000-1000-8000-00805f9b34fb"
+#define FTP_UUID "00001106-0000-1000-8000-00805f9b34fb"
+#define SPP_UUID "00001101-0000-1000-8000-00805f9b34fb"
+#define PBAP_UUID "0000112f-0000-1000-8000-00805f9b34fb"
+#define MAP_UUID "00001132-0000-1000-8000-00805f9b34fb"
+#define NAP_UUID "00001116-0000-1000-8000-00805f9b34fb"
+#define GN_UUID "00001117-0000-1000-8000-00805f9b34fb"
+#define BNEP_UUID "0000000f-0000-1000-8000-00805f9b34fb"
+#define HID_UUID "00001124-0000-1000-8000-00805f9b34fb"
+#define HID_DEVICE_UUID "00001124-0000-1000-8000-00805f9b43bf"
+#define SAP_UUID_OLD "a49eb41e-cb06-495c-9f4f-bb80a90cdf00"
+#define SAP_UUID_NEW "a49eb41e-cb06-495c-9f4f-aa80a90cdf4a"
+#define IOTIVITY_UUID "12341234-1C25-481F-9DFB-59193D238280"
+
+#define BT_AGENT_OBJECT "/org/bluez/agent/frwk_agent"
+
+#define BT_AGENT_INTERFACE "org.bluez.Agent1"
+
+#define BT_AGENT_SIGNAL_RFCOMM_AUTHORIZE "RfcommAuthorize"
+#define BT_AGENT_SIGNAL_OBEX_AUTHORIZE "ObexAuthorize"
+
+#define BT_PASSKEY_MAX_LENGTH 4
+
+#define BT_AGENT_SYSPOPUP_TIMEOUT_FOR_MULTIPLE_POPUPS 200
+#define BT_AGENT_SYSPOPUP_MAX_ATTEMPT 3
+#define BT_PAN_MAX_CONNECTION 4
+
+extern guint nap_connected_device_count;
+
+static char *passkey_watcher = NULL;
+
+#define G_VARIANT_UNREF(variant) \
+ g_variant_unref(variant); \
+ variant = NULL
+
+static int __bt_agent_is_auto_response(uint32_t dev_class, const gchar *address,
+ const gchar *name);
+static gboolean __bt_agent_is_hid_keyboard(uint32_t dev_class);
+static int __bt_agent_generate_passkey(char *passkey, int size);
+
+static void __bt_agent_release_memory(void)
+{
+ /* Release Malloc Memory*/
+ malloc_trim(0);
+
+ /* Release Stack Memory*/
+ stack_trim();
+}
+
+static GVariant *__bt_service_getall(GDBusProxy *device, const char *interface)
+{
+ GError *error = NULL;
+ GVariant *reply;
+
+ reply = g_dbus_proxy_call_sync(device,
+ "GetAll", g_variant_new("(s)", interface),
+ G_DBUS_CALL_FLAGS_NONE, -1,
+ NULL, &error);
+ if (reply == NULL) {
+ ERR("GetAll dBUS-RPC failed");
+ if (error) {
+ ERR("D-Bus API failure: errCode[%x], message[%s]",
+ error->code, error->message);
+ g_clear_error(&error);
+ }
+ return NULL;
+ }
+
+ return reply;
+}
+
+static gboolean __pincode_request(GapAgentPrivate *agent, GDBusProxy *device)
+{
+ uint32_t device_class;
+ gchar *address = NULL;
+ unsigned char auth_info[5] = {0, };
+ gchar *name = NULL;
+ GVariant *reply = NULL;
+ GVariant *reply_temp = NULL;
+ GVariant *tmp_value;
+ char pin_code[BLUETOOTH_PIN_CODE_MAX_LENGTH + 1];
+ int ret = BLUETOOTH_ERROR_NONE;
+#ifdef TIZEN_FEATURE_BT_DPM
+ int pairing_state = DPM_STATUS_ERROR;
+#endif
+
+ BT_DBG("+");
+
+#ifdef TIZEN_FEATURE_BT_DPM
+ _bt_dpm_get_bluetooth_pairing_state(&pairing_state);
+ if (pairing_state == DPM_RESTRICTED) {
+ BT_ERR("Not allow to pair the device");
+ gap_agent_reply_confirmation(agent, GAP_AGENT_REJECT, NULL);
+ __bt_agent_release_memory();
+ return TRUE;
+ }
+#endif
+
+ reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
+
+ if (reply_temp == NULL) {
+ gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
+ NULL);
+ goto done;
+ }
+
+ g_variant_get(reply_temp, "(@a{sv})", &reply); /* Format of reply a{sv}*/
+
+ tmp_value = g_variant_lookup_value(reply, "Class", G_VARIANT_TYPE_UINT32);
+ g_variant_get(tmp_value, "u", &device_class);
+ G_VARIANT_UNREF(tmp_value);
+
+ tmp_value = g_variant_lookup_value(reply, "Address", G_VARIANT_TYPE_STRING);
+ g_variant_get(tmp_value, "s", &address);
+ G_VARIANT_UNREF(tmp_value);
+ if (!address) {
+ gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
+ goto done;
+ }
+
+ tmp_value = g_variant_lookup_value(reply, "Name", G_VARIANT_TYPE_STRING);
+ g_variant_get(tmp_value, "s", &name);
+ G_VARIANT_UNREF(tmp_value);
+ if (!name) {
+ BT_DBG("Replacing the name with address");
+ name = g_strdup(address);
+ } else {
+ BT_INFO("Name = %s, Address = %s, Class = 0x%x", name, address, device_class);
+ if (name[0] == '\0') {
+ g_free(name);
+ BT_DBG("Name[0]=NULL, Replacing the name with address");
+ name = g_strdup(address);
+ }
+ }
+
+ __bt_get_auth_info(reply, (char *)auth_info);
+ if (_bt_is_device_creating() == TRUE &&
+ _bt_is_bonding_device_address(address) == TRUE &&
+ __bt_agent_is_auto_response(device_class, address, name)) {
+ BT_DBG("0000 Auto Pair");
+ /* Use Fixed PIN "0000" for basic pairing */
+ _bt_set_autopair_status_in_bonding_info(TRUE);
+ gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT, "0000",
+ NULL);
+ } else if (__bt_agent_is_hid_keyboard(device_class)) {
+ BT_DBG("HID Keyboard");
+ char str_passkey[BT_PASSKEY_MAX_LENGTH + 1] = { 0 };
+
+ if (__bt_agent_generate_passkey(str_passkey,
+ BT_PASSKEY_MAX_LENGTH) != 0) {
+ gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT,
+ "", NULL);
+ goto done;
+ }
+
+ gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT,
+ str_passkey, NULL);
+
+ if (headed_plugin_info->plugin_headed_enabled) {
+ headed_plugin_info->headed_plugin->bt_launch_system_popup(BT_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST,
+ name, auth_info, str_passkey, NULL, _gap_agent_get_path(agent));
+ } else {
+ GVariant *param = NULL;
+ param = g_variant_new("(isss)", ret, address, name, str_passkey);
+ _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_KEYBOARD_PASSKEY_DISPLAY, param);
+ }
+ } else if (_bt_get_device_pin_code(address, pin_code)
+ == BLUETOOTH_ERROR_NONE) {
+ BT_DBG("Use stored PIN code(%s)", pin_code);
+ gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT, pin_code,
+ NULL);
+ goto done;
+ } else {
+ if (headed_plugin_info->plugin_headed_enabled) {
+ BT_DBG("Show Pin entry");
+ headed_plugin_info->headed_plugin->bt_launch_system_popup(BT_AGENT_EVENT_PIN_REQUEST, name, auth_info,
+ NULL, NULL, _gap_agent_get_path(agent));
+ } else {
+ BT_INFO("Plugin Headed not Enabled");
+ GVariant *param = NULL;
+ param = g_variant_new("(iss)", ret, address, name);
+ _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_PIN_REQUEST, param);
+ }
+ }
+
+done:
+ g_variant_unref(reply);
+ g_variant_unref(reply_temp);
+ g_free(address);
+ g_free(name);
+ __bt_agent_release_memory();
+ BT_DBG("-");
+
+ return TRUE;
+}
+
+static gboolean __passkey_request(GapAgentPrivate *agent, GDBusProxy *device)
+{
+ gchar *address = NULL;
+ gchar *name = NULL;
+ unsigned char auth_info[5] = {0, };
+ GVariant *reply = NULL;
+ GVariant *reply_temp = NULL;
+ GVariant *tmp_value;
+ int ret = BLUETOOTH_ERROR_NONE;
+#ifdef TIZEN_FEATURE_BT_DPM
+ int pairing_state = DPM_STATUS_ERROR;
+#endif
+
+ BT_DBG("+");
+
+#ifdef TIZEN_FEATURE_BT_DPM
+ _bt_dpm_get_bluetooth_pairing_state(&pairing_state);
+ if (pairing_state == DPM_RESTRICTED) {
+ BT_ERR("Not allow to pair the device");
+ gap_agent_reply_confirmation(agent, GAP_AGENT_REJECT, NULL);
+ __bt_agent_release_memory();
+ return TRUE;
+ }
+#endif
+
+ reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
+
+ if (reply_temp == NULL) {
+ gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
+ NULL);
+ goto done;
+ }
+
+ g_variant_get(reply_temp, "(@a{sv})", &reply); /* Format of reply a{sv}*/
+
+ tmp_value = g_variant_lookup_value(reply, "Address", G_VARIANT_TYPE_STRING);
+ g_variant_get(tmp_value, "s", &address);
+ G_VARIANT_UNREF(tmp_value);
+ if (!address) {
+ gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
+ goto done;
+ }
+
+ tmp_value = g_variant_lookup_value(reply, "Name", G_VARIANT_TYPE_STRING);
+ g_variant_get(tmp_value, "s", &name);
+ G_VARIANT_UNREF(tmp_value);
+ if (!name)
+ name = g_strdup(address);
+
+ __bt_get_auth_info(reply, (char *)auth_info);
+
+ if (headed_plugin_info->plugin_headed_enabled) {
+ headed_plugin_info->headed_plugin->bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_REQUEST, name, auth_info,
+ NULL, NULL, _gap_agent_get_path(agent));
+ } else {
+ BT_INFO("Plugin Headed not Enabled");
+ GVariant *param = NULL;
+ param = g_variant_new("(iss)", ret, address, name);
+ _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_PASSKEY_REQUEST, param);
+ }
+
+
+done:
+ g_variant_unref(reply);
+ g_variant_unref(reply_temp);
+ g_free(address);
+ g_free(name);
+ __bt_agent_release_memory();
+
+ BT_DBG("-");
+ return TRUE;
+}
+
+static gboolean __display_request(GapAgentPrivate *agent, GDBusProxy *device,
+ guint passkey)
+{
+ gchar *address = NULL;
+ gchar *name = NULL;
+ unsigned char auth_info[5] = {0, };
+ char *str_passkey;
+ GVariant *reply = NULL;
+ GVariant *reply_temp = NULL;
+ GVariant *tmp_value = NULL;
+ int ret = BLUETOOTH_ERROR_NONE;
+
+ BT_DBG("+");
+
+ reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
+ if (reply_temp == NULL) {
+ gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
+ NULL);
+ goto done;
+ }
+
+ g_variant_get(reply_temp, "(@a{sv})", &reply); /* Format of reply a{sv}*/
+
+ tmp_value = g_variant_lookup_value(reply, "Address", G_VARIANT_TYPE_STRING);
+ g_variant_get(tmp_value, "s", &address);
+ G_VARIANT_UNREF(tmp_value);
+ if (!address) {
+ gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
+ goto done;
+ }
+
+ tmp_value = g_variant_lookup_value(reply, "Name", G_VARIANT_TYPE_STRING);
+ g_variant_get(tmp_value, "s", &name);
+ G_VARIANT_UNREF(tmp_value);
+ if (!name)
+ name = g_strdup(address);
+
+ __bt_get_auth_info(reply, (char *)auth_info);
+
+ str_passkey = g_strdup_printf("%06d", passkey);
+
+ GVariant *param = NULL;
+ param = g_variant_new("(ss)", address, str_passkey);
+
+ if (passkey_watcher) {
+ BT_INFO("Send passkey to %s", passkey_watcher);
+ _bt_send_event_to_dest(passkey_watcher, BT_ADAPTER_EVENT,
+ BLUETOOTH_EVENT_PASSKEY_NOTIFICATION, param);
+ } else {
+ if (headed_plugin_info->plugin_headed_enabled) {
+ BT_INFO("Plugin Headed Enabled");
+ headed_plugin_info->headed_plugin->bt_launch_system_popup(BT_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST, name,
+ auth_info, str_passkey, NULL, _gap_agent_get_path(agent));
+ } else {
+ BT_INFO("Plugin Headed not Enabled");
+ GVariant *param = NULL;
+ param = g_variant_new("(isss)", ret, address, name, str_passkey);
+ _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_KEYBOARD_PASSKEY_DISPLAY, param);
+ }
+ }
+
+ g_free(str_passkey);
+
+done:
+ g_variant_unref(reply);
+ g_variant_unref(reply_temp);
+ g_free(address);
+ g_free(name);
+ __bt_agent_release_memory();
+
+ BT_DBG("-");
+ return TRUE;
+}
+
+static gboolean __confirm_request(GapAgentPrivate *agent, GDBusProxy *device,
+ guint passkey)
+{
+ gchar *address = NULL;
+ gchar *name = NULL;
+ unsigned char auth_info[5] = {0, };
+ char str_passkey[7];
+ GVariant *reply_temp = NULL;
+ GVariant *reply = NULL;
+ GVariant *tmp_value;
+ int ret = BLUETOOTH_ERROR_NONE;
+#ifdef TIZEN_FEATURE_BT_DPM
+ int pairing_state = DPM_STATUS_ERROR;
+#endif
+ BT_DBG("+ passkey[%.6d]", passkey);
+
+#ifdef TIZEN_FEATURE_BT_DPM
+ _bt_dpm_get_bluetooth_pairing_state(&pairing_state);
+ if (pairing_state == DPM_RESTRICTED) {
+ BT_ERR("Not allow to pair the device");
+ gap_agent_reply_confirmation(agent, GAP_AGENT_REJECT, NULL);
+ __bt_agent_release_memory();
+ return TRUE;
+ }
+#endif
+
+ snprintf(str_passkey, sizeof(str_passkey), "%.6d", passkey);
+
+ reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
+
+ if (reply_temp == NULL) {
+ BT_ERR("Device doesn't exist");
+ gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
+ NULL);
+ goto done;
+ }
+
+ g_variant_get(reply_temp, "(@a{sv})", &reply); /* Format of reply a{sv}*/
+
+ tmp_value = g_variant_lookup_value(reply, "Address", G_VARIANT_TYPE_STRING);
+ g_variant_get(tmp_value, "s", &address);
+ G_VARIANT_UNREF(tmp_value);
+ if (!address) {
+ gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
+ goto done;
+ }
+
+ tmp_value = g_variant_lookup_value(reply, "Name", G_VARIANT_TYPE_STRING);
+ g_variant_get(tmp_value, "s", &name);
+ G_VARIANT_UNREF(tmp_value);
+ if (!name)
+ name = g_strdup(address);
+ __bt_get_auth_info(reply, (char *)auth_info);
+
+ if (headed_plugin_info->plugin_headed_enabled) {
+ BT_DBG("LAUNCH SYSPOPUP");
+ headed_plugin_info->headed_plugin->bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_CONFIRM_REQUEST, name,
+ auth_info, str_passkey, NULL,
+ _gap_agent_get_path(agent));
+ } else {
+ BT_DBG("Headless Confirmation");
+ GVariant *param = NULL;
+ param = g_variant_new("(isss)", ret, address, name, str_passkey);
+ _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_PASSKEY_CONFIRM_REQUEST, param);
+ }
+
+done:
+ g_variant_unref(reply);
+ g_variant_unref(reply_temp);
+ g_free(address);
+ g_free(name);
+ __bt_agent_release_memory();
+ BT_DBG("-");
+
+ return TRUE;
+}
+
+static gboolean __pairing_cancel_request(GapAgentPrivate *agent, const char *address)
+{
+ BT_DBG("On Going Pairing is cancelled by remote\n");
+
+ if (headed_plugin_info->plugin_headed_enabled)
+ headed_plugin_info->headed_plugin->bt_destroy_popup_all();
+
+ __bt_agent_release_memory();
+
+ return TRUE;
+}
+
+static gboolean __a2dp_authorize_request_check(void)
+{
+ /* Check for existing Media device to disconnect */
+ return _bt_is_headset_type_connected(BT_AUDIO_A2DP, NULL);
+}
+
+static gboolean __authorize_request(GapAgentPrivate *agent, GDBusProxy *device,
+ const char *uuid)
+{
+ gchar *address = NULL;
+ gchar *name = NULL;
+ unsigned char auth_info[5] = {0, };
+ gboolean trust;
+ GVariant *reply = NULL;
+ GVariant *reply_temp = NULL;
+ GVariant *tmp_value;
+ int result = BLUETOOTH_ERROR_NONE;
+ int request_type = BT_AGENT_EVENT_AUTHORIZE_REQUEST;
+
+#ifdef TIZEN_FEATURE_NETWORK_TETHERING_ENABLE
+ bool enabled;
+ tethering_h tethering = NULL;
+#endif
+
+ BT_DBG("+");
+
+ /* Check if already Media connection exsist */
+ if (!strcasecmp(uuid, A2DP_UUID)) {
+ gboolean ret = FALSE;
+
+ ret = __a2dp_authorize_request_check();
+
+ if (ret) {
+ BT_ERR("Already one A2DP device connected \n");
+ gap_agent_reply_authorize(agent, GAP_AGENT_REJECT,
+ NULL);
+ goto done;
+ }
+ }
+ /* Check completed */
+
+ if (!strcasecmp(uuid, HFP_AUDIO_GATEWAY_UUID) ||
+ !strcasecmp(uuid, HSP_AUDIO_GATEWAY_UUID) ||
+ !strcasecmp(uuid, HFP_HS_UUID) ||
+ !strcasecmp(uuid, HSP_HS_UUID) ||
+ !strcasecmp(uuid, A2DP_UUID) ||
+ !strcasecmp(uuid, HID_UUID) ||
+ !strcasecmp(uuid, HID_DEVICE_UUID) ||
+ !strcasecmp(uuid, SAP_UUID_OLD) ||
+ !strcasecmp(uuid, SAP_UUID_NEW) ||
+ !strcasecmp(uuid, IOTIVITY_UUID) ||
+ !strcasecmp(uuid, AVRCP_TARGET_UUID)) {
+ BT_DBG("Auto accept authorization for audio device (HFP, A2DP, AVRCP) [%s]", uuid);
+ gap_agent_reply_authorize(agent, GAP_AGENT_ACCEPT,
+ NULL);
+
+ goto done;
+ }
+
+ if (!strcasecmp(uuid, NAP_UUID) ||
+ !strcasecmp(uuid, GN_UUID) ||
+ !strcasecmp(uuid, BNEP_UUID)) {
+
+ BT_DBG("Network connection request: %s", uuid);
+#ifdef TIZEN_FEATURE_NETWORK_TETHERING_ENABLE
+ {
+ if (nap_connected_device_count >=
+ BT_PAN_MAX_CONNECTION) {
+ BT_ERR("Max connection exceeded");
+ goto fail;
+ }
+ int ret;
+ ret = tethering_create(&tethering);
+
+ if (ret != TETHERING_ERROR_NONE) {
+ BT_ERR("Fail to create tethering: %d", ret);
+ goto fail;
+ }
+
+ enabled = tethering_is_enabled(tethering, TETHERING_TYPE_BT);
+
+ ret = tethering_destroy(tethering);
+
+ if (ret != TETHERING_ERROR_NONE)
+ BT_ERR("Fail to create tethering: %d", ret);
+
+ if (enabled != true) {
+ BT_ERR("BT tethering is not enabled");
+ goto fail;
+ }
+ }
+#endif
+
+ gap_agent_reply_authorize(agent, GAP_AGENT_ACCEPT,
+ NULL);
+ goto done;
+#ifdef TIZEN_FEATURE_NETWORK_TETHERING_ENABLE
+fail:
+ gap_agent_reply_authorize(agent, GAP_AGENT_REJECT,
+ NULL);
+
+ goto done;
+#endif
+ }
+
+ reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
+ if (reply_temp == NULL) {
+ gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
+ NULL);
+ goto done;
+ }
+
+ g_variant_get(reply_temp, "(@a{sv})", &reply); /* Format of reply a{sv}*/
+
+ tmp_value = g_variant_lookup_value(reply, "Address", G_VARIANT_TYPE_STRING);
+ g_variant_get(tmp_value, "s", &address);
+ G_VARIANT_UNREF(tmp_value);
+ if (!address) {
+ gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
+ goto done;
+ }
+
+ tmp_value = g_variant_lookup_value(reply, "Alias", G_VARIANT_TYPE_STRING);
+ g_variant_get(tmp_value, "s", &name);
+ G_VARIANT_UNREF(tmp_value);
+ if (!name)
+ name = g_strdup(address);
+
+ tmp_value = g_variant_lookup_value(reply, "Trusted", G_VARIANT_TYPE_BOOLEAN);
+ g_variant_get(tmp_value, "b", &trust);
+ G_VARIANT_UNREF(tmp_value);
+
+ __bt_get_auth_info(reply, (char *)auth_info);
+
+ BT_INFO("Authorization request for device [%s] Service:[%s]\n", address, uuid);
+
+ if (strcasecmp(uuid, OPP_UUID) == 0 &&
+ _gap_agent_exist_osp_server(agent, BT_OBEX_SERVER,
+ NULL) == TRUE) {
+ _bt_send_event(BT_OPP_SERVER_EVENT,
+ BLUETOOTH_EVENT_OBEX_SERVER_CONNECTION_AUTHORIZE,
+ g_variant_new("(iss)", result, address, name));
+
+ goto done;
+ }
+ /* TODO: MAP? see above */
+
+ if (_gap_agent_exist_osp_server(agent, BT_RFCOMM_SERVER,
+ (char *)uuid) == TRUE) {
+ bt_agent_osp_server_t *osp_serv;
+ osp_serv = _gap_agent_get_osp_server(agent,
+ BT_RFCOMM_SERVER, (char *)uuid);
+
+ if (osp_serv) {
+ _bt_send_event(BT_RFCOMM_SERVER_EVENT,
+ BLUETOOTH_EVENT_RFCOMM_AUTHORIZE,
+ g_variant_new("(issssn)", result, address, uuid,
+ name, osp_serv->path, osp_serv->fd));
+ }
+
+ goto done;
+ }
+
+ if (!strcasecmp(uuid, OPP_UUID))
+ request_type = BT_AGENT_EVENT_EXCHANGE_REQUEST;
+ else if (!strcasecmp(uuid, PBAP_UUID))
+ request_type = BT_AGENT_EVENT_PBAP_REQUEST;
+ else if (!strcasecmp(uuid, MAP_UUID))
+ request_type = BT_AGENT_EVENT_MAP_REQUEST;
+ /* TODO: MAP is already here */
+
+ if (trust || !headed_plugin_info->plugin_headed_enabled) {
+ BT_INFO("Trusted or Headless device, so authorize\n");
+ gap_agent_reply_authorize(agent,
+ GAP_AGENT_ACCEPT, NULL);
+
+ goto done;
+ }
+
+ if (headed_plugin_info->plugin_headed_enabled) {
+ headed_plugin_info->headed_plugin->bt_launch_system_popup(request_type, name, auth_info, NULL, NULL,
+ _gap_agent_get_path(agent));
+ }
+
+done:
+ if (reply)
+ g_variant_unref(reply);
+
+ if (reply_temp)
+ g_variant_unref(reply_temp);
+
+ g_free(name);
+ g_free(address);
+ __bt_agent_release_memory();
+ BT_DBG("-");
+
+ return TRUE;
+}
+
+static gboolean __authorization_cancel_request(GapAgentPrivate *agent,
+ const char *address)
+{
+ BT_DBG("On Going Authorization is cancelled by remote\n");
+
+ gap_agent_reply_authorize(agent, GAP_AGENT_CANCEL, NULL);
+
+ if (headed_plugin_info->plugin_headed_enabled)
+ headed_plugin_info->headed_plugin->bt_destroy_popup_all();
+
+ __bt_agent_release_memory();
+
+ return TRUE;
+}
+
+void _bt_destroy_agent(void *agent)
+{
+ if (!agent)
+ return;
+
+ _gap_agent_reset_dbus((GapAgentPrivate *)agent);
+
+ g_free(agent);
+}
+
+void* _bt_create_agent(const char *path, gboolean adapter)
+{
+ GAP_AGENT_FUNC_CB func_cb;
+ GDBusProxy *adapter_proxy;
+ GapAgentPrivate *agent;
+
+ adapter_proxy = _bt_get_adapter_proxy();
+ if (!adapter_proxy)
+ return NULL;
+
+ func_cb.pincode_func = __pincode_request;
+ func_cb.display_func = __display_request;
+ func_cb.passkey_func = __passkey_request;
+ func_cb.confirm_func = __confirm_request;
+ func_cb.authorize_func = __authorize_request;
+ func_cb.pairing_cancel_func = __pairing_cancel_request;
+ func_cb.authorization_cancel_func = __authorization_cancel_request;
+
+ /* Allocate memory*/
+ agent = g_new0(GapAgentPrivate, 1);
+
+ _gap_agent_setup_dbus(agent, &func_cb, path, adapter_proxy);
+
+ if (adapter) {
+ if (!_gap_agent_register(agent)) {
+ _bt_destroy_agent(agent);
+ agent = NULL;
+ }
+ }
+
+ return agent;
+}
+
+gboolean _bt_agent_register_osp_server(const gint type,
+ const char *uuid, char *path, int fd)
+{
+ void *agent = _bt_get_adapter_agent();
+ if (!agent)
+ return FALSE;
+
+ return _gap_agent_register_osp_server(agent, type, uuid, path, fd);
+
+}
+
+gboolean _bt_agent_unregister_osp_server(const gint type, const char *uuid)
+{
+ void *agent = _bt_get_adapter_agent();
+
+ if (!agent)
+ return FALSE;
+
+ return _gap_agent_unregister_osp_server(agent, type, uuid);
+}
+
+gboolean _bt_agent_reply_authorize(gboolean accept)
+{
+ guint accept_val;
+
+ void *agent = _bt_get_adapter_agent();
+ if (!agent)
+ return FALSE;
+
+ accept_val = accept ? GAP_AGENT_ACCEPT : GAP_AGENT_REJECT;
+
+ return gap_agent_reply_authorize(agent, accept_val, NULL);
+}
+
+gboolean _bt_agent_is_canceled(void)
+{
+ void *agent = _bt_get_adapter_agent();
+ if (!agent)
+ return FALSE;
+
+ return _gap_agent_is_canceled(agent);
+}
+
+void _bt_agent_set_canceled(gboolean value)
+{
+ void *agent = _bt_get_adapter_agent();
+ if (!agent)
+ return;
+
+ return _gap_agent_set_canceled(agent, value);
+}
+
+int _bt_agent_reply_cancellation(void)
+{
+ void *agent = _bt_get_adapter_agent();
+
+ if (!agent)
+ return BLUETOOTH_ERROR_INTERNAL;
+
+ if (gap_agent_reply_confirmation(agent, GAP_AGENT_CANCEL, NULL) != TRUE) {
+ BT_ERR("Fail to reply agent");
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+static gboolean __bt_agent_is_hid_keyboard(uint32_t dev_class)
+{
+ switch ((dev_class & 0x1f00) >> 8) {
+ case 0x05:
+ switch ((dev_class & 0xc0) >> 6) {
+ case 0x01:
+ /* input-keyboard" */
+ return TRUE;
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+static gboolean __bt_agent_find_device_by_address_exactname(char *buffer,
+ const char *address)
+{
+ char *pch;
+ char *last;
+
+ pch = strtok_r(buffer, "= ,", &last);
+
+ if (pch == NULL)
+ return FALSE;
+
+ while ((pch = strtok_r(NULL, ",", &last))) {
+ if (0 == g_strcmp0(pch, address)) {
+ BT_DBG("Match found\n");
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static gboolean __bt_agent_find_device_by_partial_name(char *buffer,
+ const char *partial_name)
+{
+ char *pch;
+ char *last;
+
+ pch = strtok_r(buffer, "= ,", &last);
+
+ if (pch == NULL)
+ return FALSE;
+
+ while ((pch = strtok_r(NULL, ",", &last))) {
+ if (g_str_has_prefix(partial_name, pch)) {
+ BT_DBG("Match found\n");
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static gboolean __bt_agent_is_device_blacklist(const char *address,
+ const char *name)
+{
+ char *buffer;
+ char **lines;
+ int i;
+ FILE *fp;
+ long size;
+ size_t result;
+
+ BT_DBG("+");
+
+ fp = fopen(BT_AGENT_AUTO_PAIR_BLACKLIST_FILE, "r");
+
+ if (fp == NULL) {
+ BT_ERR("Unable to open blacklist file");
+ return FALSE;
+ }
+
+ fseek(fp, 0, SEEK_END);
+ size = ftell(fp);
+ if (size <= 0) {
+ BT_DBG("size is not a positive number");
+ fclose(fp);
+ return FALSE;
+ }
+
+ rewind(fp);
+
+ buffer = g_malloc0(sizeof(char) * size);
+ result = fread((char *)buffer, 1, size, fp);
+ fclose(fp);
+ if (result != size) {
+ BT_ERR("Read Error");
+ g_free(buffer);
+ return FALSE;
+ }
+
+ BT_DBG("Buffer = %s", buffer);
+
+ lines = g_strsplit_set(buffer, BT_AGENT_NEW_LINE, 0);
+ g_free(buffer);
+
+ if (lines == NULL) {
+ BT_ERR("No lines in the file");
+ return FALSE;
+ }
+
+ for (i = 0; lines[i] != NULL; i++) {
+ if (g_str_has_prefix(lines[i], "AddressBlacklist"))
+ if (__bt_agent_find_device_by_address_exactname(
+ lines[i], address))
+ goto done;
+ if (g_str_has_prefix(lines[i], "ExactNameBlacklist"))
+ if (__bt_agent_find_device_by_address_exactname(
+ lines[i], name))
+ goto done;
+ if (g_str_has_prefix(lines[i], "PartialNameBlacklist"))
+ if (__bt_agent_find_device_by_partial_name(lines[i],
+ name))
+ goto done;
+ if (g_str_has_prefix(lines[i], "KeyboardAutoPair"))
+ if (__bt_agent_find_device_by_address_exactname(
+ lines[i], address))
+ goto done;
+ }
+ g_strfreev(lines);
+ BT_DBG("-");
+ return FALSE;
+done:
+ BT_DBG("Found the device");
+ g_strfreev(lines);
+ return TRUE;
+}
+
+static gboolean __bt_agent_is_auto_response(uint32_t dev_class,
+ const gchar *address, const gchar *name)
+{
+ gboolean is_headset = FALSE;
+ gboolean is_mouse = FALSE;
+ char lap_address[BT_LOWER_ADDRESS_LENGTH];
+
+ BT_DBG("bt_agent_is_headset_class, %d +", dev_class);
+
+ if (address == NULL)
+ return FALSE;
+
+ switch ((dev_class & 0x1f00) >> 8) {
+ case 0x04:
+ switch ((dev_class & 0xfc) >> 2) {
+ case 0x01:
+ case 0x02:
+ /* Headset */
+ is_headset = TRUE;
+ break;
+ case 0x06:
+ /* Headphone */
+ is_headset = TRUE;
+ break;
+ case 0x0b: /* VCR */
+ case 0x0c: /* Video Camera */
+ case 0x0d: /* Camcorder */
+ break;
+ default:
+ /* Other audio device */
+ is_headset = TRUE;
+ break;
+ }
+ break;
+ case 0x05:
+ switch (dev_class & 0xff) {
+ case 0x80: /* 0x80: Pointing device(Mouse) */
+ is_mouse = TRUE;
+ break;
+
+ case 0x40: /* 0x40: input device (BT keyboard) */
+
+ /* Get the LAP(Lower Address part) */
+ g_strlcpy(lap_address, address, sizeof(lap_address));
+
+ /* Need to Auto pair the blacklisted Keyboard */
+ if (__bt_agent_is_device_blacklist(lap_address, name) != TRUE) {
+ BT_DBG("Device is not black listed\n");
+ return FALSE;
+ } else {
+ BT_ERR("Device is black listed\n");
+ return TRUE;
+ }
+ }
+ }
+
+ if ((!is_headset) && (!is_mouse))
+ return FALSE;
+
+ /* Get the LAP(Lower Address part) */
+ g_strlcpy(lap_address, address, sizeof(lap_address));
+
+ BT_DBG("Device address = %s\n", address);
+ BT_DBG("Address 3 byte = %s\n", lap_address);
+
+ if (__bt_agent_is_device_blacklist(lap_address, name)) {
+ BT_ERR("Device is black listed\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static int __bt_agent_generate_passkey(char *passkey, int size)
+{
+ int i;
+ ssize_t len;
+ int random_fd;
+ unsigned int value = 0;
+
+ if (passkey == NULL)
+ return -1;
+
+ if (size <= 0)
+ return -1;
+
+ random_fd = open("/dev/urandom", O_RDONLY);
+
+ if (random_fd < 0)
+ return -1;
+
+ for (i = 0; i < size; i++) {
+ len = read(random_fd, &value, sizeof(value));
+ if (len > 0)
+ passkey[i] = '0' + (value % 10);
+ }
+
+ close(random_fd);
+
+ BT_DBG("passkey: %s", passkey);
+
+ return 0;
+}
+
+int _bt_set_passkey_notification(const char *sender, gboolean enable)
+{
+ BT_INFO("Set passkey notification(sender:%s, %s)",
+ sender, enable ? "Enable" : "Disable");
+
+ g_free(passkey_watcher);
+ if (enable == TRUE)
+ passkey_watcher = g_strdup(sender);
+ else
+ passkey_watcher = NULL;
+
+ return BLUETOOTH_ERROR_NONE;
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <gio/gio.h>
+#include <glib.h>
+#include <dlog.h>
+#include <string.h>
+#include <syspopup_caller.h>
+
+#include "bluetooth-api.h"
+#include "bt-internal-types.h"
+#include "bt-service-common.h"
+#include "bt-service-avrcp.h"
+#include "bt-service-event.h"
+#include "bt-service-util.h"
+#include "bt-service-audio.h"
+
+static bt_player_settinngs_t loopstatus_settings[] = {
+ { REPEAT_INVALID, "" },
+ { REPEAT_MODE_OFF, "None" },
+ { REPEAT_SINGLE_TRACK, "Track" },
+ { REPEAT_ALL_TRACK, "Playlist" },
+ { REPEAT_INVALID, "" }
+};
+
+static bt_player_settinngs_t shuffle_settings[] = {
+ { SHUFFLE_INVALID, "" },
+ { SHUFFLE_MODE_OFF, "off" },
+ { SHUFFLE_ALL_TRACK, "alltracks" },
+ { SHUFFLE_GROUP, "group" },
+ { SHUFFLE_INVALID, "" }
+};
+
+static bt_player_settinngs_t player_status[] = {
+ { STATUS_STOPPED, "stopped" },
+ { STATUS_PLAYING, "playing" },
+ { STATUS_PAUSED, "paused" },
+ { STATUS_FORWARD_SEEK, "forward-seek" },
+ { STATUS_REVERSE_SEEK, "reverse-seek" },
+ { STATUS_ERROR, "error" },
+ { STATUS_INVALID, "" }
+};
+
+static guint avrcp_reg_id = 0;
+
+/* Introspection data exposed from bt-service */
+static const gchar bt_avrcp_bluez_introspection_xml[] =
+"<node name='/'>"
+" <interface name='org.freedesktop.DBus.Properties'>"
+" <method name='Set'>"
+" <arg type='s' name='interface' direction='in'/>"
+" <arg type='s' name='property' direction='in'/>"
+" <arg type='v' name='value' direction='in'/>"
+" </method>"
+" </interface>"
+"</node>";
+
+static gboolean __bt_media_emit_property_changed(GDBusConnection *connection,
+ const char *path, const char *interface, const char *name,
+ const GVariant *variant)
+{
+ GVariantBuilder *builder = NULL;
+ GError *error = NULL;
+
+ builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+ g_variant_builder_add(builder, "{sv}", name, variant);
+
+ g_dbus_connection_emit_signal(connection, NULL, path,
+ BT_PROPERTIES_INTERFACE,
+ "PropertiesChanged",
+ g_variant_new("(sa{sv})",
+ interface, builder),
+ &error);
+
+ g_variant_builder_unref(builder);
+ if (error) {
+ BT_ERR("Could not Emit PropertiesChanged Signal: errCode[%x], message[%s]",
+ error->code, error->message);
+ g_clear_error(&error);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static GQuark __bt_avrcp_error_quark(void)
+{
+ static GQuark quark = 0;
+
+ if (!quark)
+ quark = g_quark_from_static_string("bt-avrcp");
+
+ return quark;
+}
+
+static GError *__bt_avrcp_set_error(bt_avrcp_error_t error)
+{
+ BT_ERR("error[%d]\n", error);
+
+ switch (error) {
+ case BT_AVRCP_ERROR_INVALID_PARAM:
+ return g_error_new(BT_AVRCP_ERROR, error,
+ BT_ERROR_INVALID_PARAM);
+ case BT_AVRCP_ERROR_INVALID_INTERFACE:
+ return g_error_new(BT_AVRCP_ERROR, error,
+ BT_ERROR_INVALID_INTERFACE);
+ case BT_AVRCP_ERROR_INTERNAL:
+ default:
+ return g_error_new(BT_AVRCP_ERROR, error,
+ BT_ERROR_INTERNAL);
+ }
+}
+
+static void __bt_avrcp_agent_method(GDBusConnection *connection,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *method_name,
+ GVariant *parameters,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data)
+{
+ BT_DBG("+");
+ BT_INFO("method %s", method_name);
+ BT_INFO("object_path %s", object_path);
+ int ret = BT_AVRCP_ERROR_NONE;
+ GError *err = NULL;
+ gboolean shuffle_status;
+ guint32 status;
+ gchar *interface = NULL;
+ gchar *property = NULL;
+ gchar *loop_status = NULL;
+ GVariant *value = NULL;
+
+ if (g_strcmp0(method_name, "Set") == 0) {
+ g_variant_get(parameters, "(&s&sv)", &interface, &property,
+ &value);
+
+ if (g_strcmp0(interface, BT_MEDIA_PLAYER_INTERFACE) != 0) {
+ ret = BT_AVRCP_ERROR_INVALID_INTERFACE;
+ goto fail;
+ }
+ }
+
+ if (value == NULL) {
+ BT_ERR("value is NULL");
+ goto fail;
+ }
+
+ BT_DBG("Property: %s\n", property);
+ if (g_strcmp0(property, "Shuffle") == 0) {
+
+ if (!g_variant_is_of_type(value, G_VARIANT_TYPE_BOOLEAN)) {
+ BT_ERR("Error");
+ ret = BT_AVRCP_ERROR_INVALID_PARAM;
+ goto fail;
+ }
+
+ shuffle_status = g_variant_get_boolean(value);
+ BT_DBG("Value: %s\n", shuffle_status ? "TRUE" : "FALSE");
+ if (shuffle_status == TRUE)
+ status = SHUFFLE_ALL_TRACK;
+ else
+ status = SHUFFLE_MODE_OFF;
+
+ _bt_send_event(BT_AVRCP_EVENT,
+ BLUETOOTH_EVENT_AVRCP_SETTING_SHUFFLE_STATUS,
+ g_variant_new("(u)", status));
+ } else if (g_strcmp0(property, "LoopStatus") == 0) {
+
+ if (!g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
+ BT_ERR("Error");
+ ret = BT_AVRCP_ERROR_INVALID_PARAM;
+ goto fail;
+ }
+
+ loop_status = (gchar *)g_variant_get_string(value, NULL);
+ BT_DBG("Value: %s\n", loop_status);
+
+ if (g_strcmp0(loop_status, "Track") == 0)
+ status = REPEAT_SINGLE_TRACK;
+ else if (g_strcmp0(loop_status, "Playlist") == 0)
+ status = REPEAT_ALL_TRACK;
+ else if (g_strcmp0(loop_status, "None") == 0)
+ status = REPEAT_MODE_OFF;
+ else
+ status = REPEAT_INVALID;
+
+ _bt_send_event(BT_AVRCP_EVENT,
+ BLUETOOTH_EVENT_AVRCP_SETTING_REPEAT_STATUS,
+ g_variant_new("(u)", status));
+ }
+
+ BT_DBG("-");
+ return;
+
+fail:
+ if (value)
+ g_variant_unref(value);
+ err = __bt_avrcp_set_error(ret);
+ g_dbus_method_invocation_return_gerror(invocation, err);
+ g_clear_error(&err);
+ BT_INFO("-");
+}
+
+static const GDBusInterfaceVTable method_table = {
+ __bt_avrcp_agent_method,
+ NULL,
+ NULL,
+};
+
+static GDBusNodeInfo *__bt_avrcp_create_method_node_info
+ (const gchar *introspection_data)
+{
+ GError *err = NULL;
+ GDBusNodeInfo *node_info = NULL;
+
+ if (introspection_data == NULL)
+ return NULL;
+
+ node_info = g_dbus_node_info_new_for_xml(introspection_data, &err);
+
+ if (err) {
+ BT_ERR("Unable to create node: %s", err->message);
+ g_clear_error(&err);
+ }
+
+ return node_info;
+}
+
+int _bt_register_media_player(void)
+{
+ BT_DBG("+");
+ GDBusConnection *g_conn;
+ gchar *adapter_path;
+ gboolean shuffle_status;
+ gchar *path;
+ GDBusNodeInfo *node_info;
+ GDBusProxy *proxy;
+ GVariantBuilder *builder;
+ GVariant *ret;
+ GError *error = NULL;
+
+ media_player_settings_t player_settings = {0,};
+
+ player_settings.repeat = REPEAT_MODE_OFF;
+ player_settings.status = STATUS_STOPPED;
+ player_settings.position = 0;
+ shuffle_status = FALSE;
+
+ g_conn = _bt_gdbus_get_system_gconn();
+ retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ node_info = __bt_avrcp_create_method_node_info(
+ bt_avrcp_bluez_introspection_xml);
+ if (node_info == NULL)
+ return BLUETOOTH_ERROR_INTERNAL;
+
+ avrcp_reg_id = g_dbus_connection_register_object(g_conn,
+ BT_MEDIA_OBJECT_PATH,
+ node_info->interfaces[0],
+ &method_table,
+ NULL, NULL, &error);
+ g_dbus_node_info_unref(node_info);
+
+ if (avrcp_reg_id == 0) {
+ BT_ERR("Failed to register: %s", error->message);
+ g_clear_error(&error);
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ adapter_path = _bt_get_adapter_path();
+ retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ proxy = g_dbus_proxy_new_sync(g_conn,
+ G_DBUS_PROXY_FLAGS_NONE, NULL,
+ BT_BLUEZ_NAME, adapter_path,
+ BT_MEDIA_INTERFACE, NULL, &error);
+ g_free(adapter_path);
+
+ if (proxy == NULL) {
+ BT_ERR("Unable to create proxy");
+ if (error) {
+ BT_ERR("Error: %s", error->message);
+ g_clear_error(&error);
+ }
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+
+ g_variant_builder_add(builder, "{sv}", "LoopStatus",
+ g_variant_new("s",
+ loopstatus_settings[player_settings.repeat].property));
+ BT_ERR("LoopStatus: %s", loopstatus_settings[player_settings.repeat].property);
+
+ g_variant_builder_add(builder, "{sv}", "Shuffle",
+ g_variant_new("b", shuffle_status));
+
+ g_variant_builder_add(builder, "{sv}", "PlaybackStatus",
+ g_variant_new("s",
+ player_status[player_settings.status].property));
+ BT_ERR("PlaybackStatus: %s", player_status[player_settings.status].property);
+
+ g_variant_builder_add(builder, "{sv}", "Position",
+ g_variant_new("u", player_settings.position));
+
+ path = g_strdup(BT_MEDIA_OBJECT_PATH);
+ ret = g_dbus_proxy_call_sync(proxy, "RegisterPlayer",
+ g_variant_new("(oa{sv})", path, builder),
+ G_DBUS_CALL_FLAGS_NONE, -1,
+ NULL, &error);
+
+ g_object_unref(proxy);
+ g_free(path);
+ g_variant_builder_unref(builder);
+
+ if (ret == NULL) {
+ BT_ERR("Call RegisterPlayer Failed");
+ if (error) {
+ BT_ERR("errCode[%x], message[%s]",
+ error->code, error->message);
+ g_clear_error(&error);
+ }
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ g_variant_unref(ret);
+ return BLUETOOTH_ERROR_NONE;
+}
+
+static void __bt_avrcp_unregister_object_path(void)
+{
+ GDBusConnection *g_conn;
+
+ g_conn = _bt_gdbus_get_system_gconn();
+ ret_if(g_conn == NULL);
+
+ if (avrcp_reg_id > 0) {
+ g_dbus_connection_unregister_object(g_conn,
+ avrcp_reg_id);
+ avrcp_reg_id = 0;
+ }
+}
+
+int _bt_unregister_media_player(void)
+{
+ BT_DBG("+");
+ GDBusConnection *g_conn;
+ GDBusProxy *proxy;
+ gchar *adapter_path;
+ GVariant *ret;
+ GError *error = NULL;
+ gchar *path;
+ int result = BLUETOOTH_ERROR_NONE;
+
+ adapter_path = _bt_get_adapter_path();
+ if (adapter_path == NULL) {
+ result = BLUETOOTH_ERROR_INTERNAL;
+ goto FAIL;
+ }
+
+ g_conn = _bt_gdbus_get_system_gconn();
+ if (g_conn == NULL) {
+ BT_ERR("g_conn is NULL");
+ g_free(adapter_path);
+ result = BLUETOOTH_ERROR_INTERNAL;
+ goto FAIL;
+ }
+
+ proxy = g_dbus_proxy_new_sync(g_conn,
+ G_DBUS_PROXY_FLAGS_NONE, NULL,
+ BT_BLUEZ_NAME, adapter_path,
+ BT_MEDIA_INTERFACE, NULL, &error);
+ g_free(adapter_path);
+
+ if (proxy == NULL) {
+ BT_ERR("Unable to create proxy");
+ if (error) {
+ BT_ERR("Error: %s", error->message);
+ g_clear_error(&error);
+ }
+ result = BLUETOOTH_ERROR_INTERNAL;
+ goto FAIL;
+ }
+
+ path = g_strdup(BT_MEDIA_OBJECT_PATH);
+ BT_DBG("path is [%s]", path);
+
+ ret = g_dbus_proxy_call_sync(proxy, "UnregisterPlayer",
+ g_variant_new("(o)", path),
+ G_DBUS_CALL_FLAGS_NONE, -1,
+ NULL, &error);
+ g_free(path);
+ g_object_unref(proxy);
+
+ if (ret == NULL) {
+ BT_ERR("UnregisterPlayer failed");
+ if (error) {
+ BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
+ error->code, error->message);
+ g_clear_error(&error);
+ }
+ result = BLUETOOTH_ERROR_INTERNAL;
+ }
+ g_variant_unref(ret);
+
+FAIL:
+ __bt_avrcp_unregister_object_path();
+
+ BT_DBG("-");
+ return result;
+}
+#if 0
+int _bt_avrcp_set_track_info(media_metadata_attributes_t *meta_data)
+{
+ BT_DBG("+");
+ char *interface = BT_MEDIA_PLAYER_INTERFACE;
+ GDBusConnection *g_conn;
+ GError *error = NULL;
+ GVariantBuilder *builder = NULL;
+ GVariantBuilder *inner_builder = NULL;
+ GVariant *children[1];
+ gboolean ret;
+
+ retv_if(meta_data == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ g_conn = _bt_gdbus_get_system_gconn();;
+ retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+ inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+
+ g_variant_builder_add(inner_builder, "{sv}",
+ "xesam:title", g_variant_new_string(meta_data->title));
+
+ children[0] = g_variant_new_string(meta_data->artist);
+ g_variant_builder_add(inner_builder, "{sv}",
+ "xesam:artist", g_variant_new_array(G_VARIANT_TYPE_STRING,
+ children, 1));
+
+ g_variant_builder_add(inner_builder, "{sv}",
+ "xesam:album", g_variant_new_string(meta_data->album));
+
+ children[0] = g_variant_new_string(meta_data->genre);
+ g_variant_builder_add(inner_builder, "{sv}",
+ "xesam:genre", g_variant_new_array(G_VARIANT_TYPE_STRING,
+ children, 1));
+
+ g_variant_builder_add(inner_builder, "{sv}",
+ "xesam:totalTracks", g_variant_new_int32(meta_data->total_tracks));
+
+ g_variant_builder_add(inner_builder, "{sv}",
+ "xesam:trackNumber", g_variant_new_int32(meta_data->number));
+
+ g_variant_builder_add(inner_builder, "{sv}",
+ "mpris:length", g_variant_new_int64(meta_data->duration));
+
+ g_variant_builder_add(builder, "{sv}",
+ "Metadata", g_variant_new("a{sv}", inner_builder));
+
+ ret = g_dbus_connection_emit_signal(g_conn, NULL, BT_MEDIA_OBJECT_PATH,
+ BT_PROPERTIES_INTERFACE,
+ "PropertiesChanged",
+ g_variant_new("(sa{sv})",
+ interface, builder),
+ &error);
+
+ g_variant_builder_unref(inner_builder);
+ g_variant_builder_unref(builder);
+
+ if (!ret) {
+ if (error != NULL) {
+ BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
+ error->code, error->message);
+ g_clear_error(&error);
+ }
+ }
+
+ BT_DBG("-");
+ return BLUETOOTH_ERROR_NONE;
+}
+#endif
+int _bt_avrcp_set_interal_property(int type, media_player_settings_t *properties)
+{
+ BT_DBG("+");
+ GDBusConnection *g_conn;
+ int value;
+ media_metadata_attributes_t meta_data;
+ gboolean shuffle;
+ GVariantBuilder *builder = NULL;
+ GVariant *children[1];
+
+ g_conn = _bt_gdbus_get_system_gconn();;
+ retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ switch (type) {
+ case REPEAT:
+ value = properties->repeat;
+ if (!__bt_media_emit_property_changed(g_conn, BT_MEDIA_OBJECT_PATH,
+ BT_MEDIA_PLAYER_INTERFACE, "LoopStatus",
+ g_variant_new_string(loopstatus_settings[value].property))) {
+ BT_ERR("Error sending the PropertyChanged signal \n");
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+ break;
+ case SHUFFLE:
+ value = properties->shuffle;
+ if (g_strcmp0(shuffle_settings[value].property, "off") == 0)
+ shuffle = FALSE;
+ else
+ shuffle = TRUE;
+
+ if (!__bt_media_emit_property_changed(g_conn, BT_MEDIA_OBJECT_PATH,
+ BT_MEDIA_PLAYER_INTERFACE, "Shuffle",
+ g_variant_new_boolean(shuffle))) {
+ BT_ERR("Error sending the PropertyChanged signal \n");
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+ break;
+ case STATUS:
+ value = properties->status;
+ if (!__bt_media_emit_property_changed(g_conn, BT_MEDIA_OBJECT_PATH,
+ BT_MEDIA_PLAYER_INTERFACE, "PlaybackStatus",
+ g_variant_new_string(player_status[value].property))) {
+ BT_ERR("Error sending the PropertyChanged signal \n");
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+ break;
+ case POSITION:
+ value = properties->position;
+ if (!__bt_media_emit_property_changed(g_conn, BT_MEDIA_OBJECT_PATH,
+ BT_MEDIA_PLAYER_INTERFACE, "Position",
+ g_variant_new_uint32(value))) {
+ BT_ERR("Error sending the PropertyChanged signal \n");
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+ break;
+ case METADATA:
+ meta_data = properties->metadata;
+
+ builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+ g_variant_builder_add(builder, "{sv}",
+ "xesam:title", g_variant_new_string(meta_data.title));
+
+ children[0] = g_variant_new_string(meta_data.artist);
+ g_variant_builder_add(builder, "{sv}",
+ "xesam:artist", g_variant_new_array(G_VARIANT_TYPE_STRING,
+ children, 1));
+
+ g_variant_builder_add(builder, "{sv}",
+ "xesam:album", g_variant_new_string(meta_data.album));
+
+ children[0] = g_variant_new_string(meta_data.genre);
+ g_variant_builder_add(builder, "{sv}",
+ "xesam:genre", g_variant_new_array(G_VARIANT_TYPE_STRING,
+ children, 1));
+
+ g_variant_builder_add(builder, "{sv}",
+ "xesam:totalTracks", g_variant_new_int32(meta_data.total_tracks));
+
+ g_variant_builder_add(builder, "{sv}",
+ "xesam:trackNumber", g_variant_new_int32(meta_data.number));
+
+ g_variant_builder_add(builder, "{sv}",
+ "mpris:length", g_variant_new_int64(meta_data.duration));
+
+ if (!__bt_media_emit_property_changed(g_conn, BT_MEDIA_OBJECT_PATH,
+ BT_MEDIA_PLAYER_INTERFACE, "Metadata",
+ g_variant_new("a{sv}", builder))) {
+ BT_ERR("Error sending the PropertyChanged signal \n");
+ g_variant_builder_unref(builder);
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+ g_variant_builder_unref(builder);
+ break;
+ default:
+ BT_ERR("Invalid Type\n");
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+ BT_DBG("-");
+ return BLUETOOTH_ERROR_NONE;
+}
+#if 0
+int _bt_avrcp_set_properties(media_player_settings_t *properties)
+{
+ BT_DBG("+");
+
+ if (_bt_avrcp_set_interal_property(REPEAT,
+ properties) != BLUETOOTH_ERROR_NONE) {
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+ if (_bt_avrcp_set_interal_property(SHUFFLE,
+ properties) != BLUETOOTH_ERROR_NONE) {
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ if (_bt_avrcp_set_interal_property(STATUS,
+ properties) != BLUETOOTH_ERROR_NONE) {
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ if (_bt_avrcp_set_interal_property(POSITION,
+ properties) != BLUETOOTH_ERROR_NONE) {
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ if (_bt_avrcp_set_interal_property(METADATA,
+ properties) != BLUETOOTH_ERROR_NONE) {
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+ BT_DBG("-");
+ return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_avrcp_set_property(int type, unsigned int value)
+{
+ BT_DBG("+");
+ media_player_settings_t properties;
+
+ switch (type) {
+ case REPEAT:
+ properties.repeat = value;
+ break;
+ case SHUFFLE:
+ properties.shuffle = value;
+ break;
+ case STATUS:
+ properties.status = value;
+ break;
+ case POSITION:
+ properties.position = value;
+ break;
+ default:
+ BT_DBG("Invalid Type\n");
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ if (_bt_avrcp_set_interal_property(type,
+ &properties) != BLUETOOTH_ERROR_NONE)
+ return BLUETOOTH_ERROR_INTERNAL;
+
+ BT_DBG("-");
+
+ return BLUETOOTH_ERROR_NONE;
+}
+#endif
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <vconf.h>
+#include <vconf-keys.h>
+
+#include "bt-internal-types.h"
+#include "bt-service-common.h"
+#include "bt-service-obex-agent.h"
+#include "bt-service-gap-agent.h"
+#include "bt-service-core-adapter.h"
+
+#include "bt-service-device.h"
+#include "bt-service-gap-agent.h"
+
+static GDBusConnection *connection = NULL;
+
+typedef enum {
+ GAP_AGENT_ERROR_REJECT,
+ GAP_AGENT_ERROR_CANCEL,
+ GAP_AGENT_ERROR_TIMEOUT,
+} GapAgentError;
+
+#define GAP_AGENT_ERROR (gap_agent_error_quark())
+
+static GQuark gap_agent_error_quark(void)
+{
+ static GQuark quark = 0;
+ if (!quark)
+ quark = g_quark_from_static_string("agent");
+
+ return quark;
+}
+
+#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
+
+static gint gap_agent_id = -1;
+
+static bt_agent_osp_server_t *__gap_agent_find_server(GSList *servers,
+ int type,
+ const char *uuid)
+{
+ GSList *l;
+ bt_agent_osp_server_t *transfer;
+
+ for (l = servers; l != NULL; l = l->next) {
+ transfer = l->data;
+
+ if (transfer == NULL)
+ continue;
+
+ /* No uuid in obex server */
+ if (type == BT_OBEX_SERVER &&
+ transfer->type == BT_OBEX_SERVER)
+ return transfer;
+
+ if (g_strcmp0(transfer->uuid, uuid) == 0)
+ return transfer;
+ }
+
+ return NULL;
+}
+
+static void __gap_agent_remove_osp_servers(GSList *osp_servers)
+{
+ GSList *l;
+ bt_agent_osp_server_t *server;
+
+ for (l = osp_servers; l != NULL; l = g_slist_next(l)) {
+ server = l->data;
+
+ if (server == NULL)
+ continue;
+
+ g_free(server->uuid);
+ g_free(server);
+ }
+}
+
+gboolean _gap_agent_register_osp_server(GapAgentPrivate *agent,
+ const gint type,
+ const char *uuid,
+ const char *path,
+ int fd)
+{
+ bt_agent_osp_server_t *server;
+
+ BT_DBG("+");
+
+ GapAgentPrivate *priv = agent;
+
+ if (priv == NULL)
+ return FALSE;
+
+ /* type: BT_OBEX_SERVER / BT_RFCOMM_SERVER*/
+ if (type > BT_RFCOMM_SERVER)
+ return FALSE;
+
+ server = g_malloc0(sizeof(bt_agent_osp_server_t));
+ server->type = type;
+ if (type == BT_RFCOMM_SERVER) {
+ server->uuid = g_strdup(uuid);
+ server->path = g_strdup(path);
+ server->fd = fd;
+ }
+
+ priv->osp_servers = g_slist_append(priv->osp_servers, server);
+
+ BT_DBG("-");
+
+ return TRUE;
+}
+
+gboolean _gap_agent_unregister_osp_server(GapAgentPrivate *agent,
+ const gint type,
+ const char *uuid)
+{
+ bt_agent_osp_server_t *server;
+
+ BT_DBG("+");
+
+ GapAgentPrivate *priv = agent;
+
+ if (priv == NULL)
+ return FALSE;
+
+ /* type: BT_OBEX_SERVER / BT_RFCOMM_SERVER*/
+ if (type > BT_RFCOMM_SERVER)
+ return FALSE;
+
+ server = __gap_agent_find_server(priv->osp_servers, type, uuid);
+
+ if (server == NULL)
+ return FALSE;
+
+ priv->osp_servers = g_slist_remove(priv->osp_servers, server);
+
+ g_free(server->uuid);
+ g_free(server);
+
+ BT_DBG("-");
+
+ return TRUE;
+}
+
+gboolean gap_agent_reply_pin_code(GapAgentPrivate *agent, const guint accept,
+ const char *pin_code,
+ GDBusMethodInvocation *context)
+{
+ BT_DBG("+");
+
+ GapAgentPrivate *priv = agent;
+ retv_if(priv == NULL, FALSE);
+
+ if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
+ priv->reply_context != NULL) {
+ if (accept == GAP_AGENT_ACCEPT) {
+ g_dbus_method_invocation_return_value(priv->reply_context,
+ g_variant_new("(s)", pin_code));
+ priv->canceled = FALSE;
+ } else {
+ switch (accept) {
+ case GAP_AGENT_CANCEL:
+ g_dbus_method_invocation_return_error(priv->reply_context,
+ GAP_AGENT_ERROR, GAP_AGENT_ERROR_CANCEL,
+ "CanceledbyUser");
+ priv->canceled = TRUE;
+ break;
+ case GAP_AGENT_TIMEOUT:
+ case GAP_AGENT_REJECT:
+ default:
+ g_dbus_method_invocation_return_error(priv->reply_context,
+ GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
+ "Pairing request rejected");
+ priv->canceled = FALSE;
+ break;
+ }
+ }
+ }
+
+ priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
+ priv->reply_context = NULL;
+ memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
+
+ BT_DBG("-");
+
+ return TRUE;
+}
+
+gboolean gap_agent_reply_passkey(GapAgentPrivate *agent, const guint accept,
+ const char *passkey,
+ GDBusMethodInvocation *context)
+{
+ BT_DBG("+");
+
+ GapAgentPrivate *priv = agent;
+ retv_if(priv == NULL, FALSE);
+
+ if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
+ priv->reply_context != NULL) {
+ if (accept == GAP_AGENT_ACCEPT) {
+ guint pass_key = atoi(passkey);
+ g_dbus_method_invocation_return_value(priv->reply_context,
+ g_variant_new("(u)", pass_key));
+ priv->canceled = FALSE;
+ } else {
+ switch (accept) {
+ case GAP_AGENT_CANCEL:
+ g_dbus_method_invocation_return_error(priv->reply_context,
+ GAP_AGENT_ERROR, GAP_AGENT_ERROR_CANCEL,
+ "CanceledbyUser");
+ priv->canceled = TRUE;
+ break;
+ case GAP_AGENT_TIMEOUT:
+ case GAP_AGENT_REJECT:
+ default:
+ g_dbus_method_invocation_return_error(priv->reply_context,
+ GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
+ "Passkey request rejected");
+ priv->canceled = FALSE;
+ break;
+ }
+ }
+ }
+
+ priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
+ priv->reply_context = NULL;
+ memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
+
+ BT_DBG("-");
+
+ return TRUE;
+}
+
+gboolean gap_agent_reply_confirmation(GapAgentPrivate *agent, const guint accept,
+ GDBusMethodInvocation *context)
+{
+ BT_DBG("+");
+
+ GapAgentPrivate *priv = agent;
+ retv_if(priv == NULL, FALSE);
+
+ if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
+ priv->reply_context != NULL) {
+ if (accept == GAP_AGENT_ACCEPT) {
+ g_dbus_method_invocation_return_value(priv->reply_context, NULL);
+ priv->canceled = FALSE;
+ } else {
+ switch (accept) {
+ case GAP_AGENT_CANCEL:
+ g_dbus_method_invocation_return_error(priv->reply_context,
+ GAP_AGENT_ERROR, GAP_AGENT_ERROR_CANCEL,
+ "CanceledbyUser");
+ priv->canceled = TRUE;
+ break;
+ case GAP_AGENT_TIMEOUT:
+ case GAP_AGENT_REJECT:
+ default:
+ g_dbus_method_invocation_return_error(priv->reply_context,
+ GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
+ "Confirmation request rejected");
+ priv->canceled = FALSE;
+ break;
+ }
+ }
+ }
+
+ priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
+ priv->reply_context = NULL;
+ memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
+
+ BT_DBG("-");
+
+ return TRUE;
+}
+
+gboolean gap_agent_reply_authorize(GapAgentPrivate *agent, const guint accept,
+ GDBusMethodInvocation *context)
+{
+ gboolean ret = TRUE;
+
+ BT_DBG("+");
+
+ GapAgentPrivate *priv = agent;
+ retv_if(priv == NULL, FALSE);
+
+ if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
+ priv->reply_context != NULL) {
+ if (accept == GAP_AGENT_ACCEPT) {
+ g_dbus_method_invocation_return_value(priv->reply_context, NULL);
+ } else if (accept == GAP_AGENT_ACCEPT_ALWAYS) {
+ bluetooth_device_address_t addr = { { 0, } };
+ int result;
+
+ _bt_convert_addr_string_to_type(addr.addr,
+ priv->authorize_addr);
+
+ /* Do not set device as Trusted*/
+ /* result = _bt_set_authorization(&addr, TRUE); */
+ result = _bt_set_trust_profile(&addr,
+ _bt_get_trusted_profile_enum(priv->uuid),
+ TRUE);
+ if (result == BLUETOOTH_ERROR_NONE) {
+ BT_INFO("[%s] Profile added as trusted for Device[%s]",
+ priv->uuid, priv->authorize_addr);
+ }
+
+ g_dbus_method_invocation_return_value(priv->reply_context, NULL);
+ } else {
+ switch (accept) {
+ case GAP_AGENT_CANCEL:
+ g_dbus_method_invocation_return_error(priv->reply_context,
+ GAP_AGENT_ERROR, GAP_AGENT_ERROR_CANCEL,
+ "CanceledbyUser");
+ break;
+ case GAP_AGENT_REJECT: {
+ bluetooth_device_address_t addr = { { 0, } };
+ int result;
+
+ _bt_convert_addr_string_to_type(addr.addr,
+ priv->authorize_addr);
+
+ /* Set Profile as blocked */
+ result = _bt_set_trust_profile(&addr,
+ _bt_get_trusted_profile_enum(priv->uuid),
+ FALSE);
+ if (result == BLUETOOTH_ERROR_NONE) {
+ BT_INFO("[%s] Profile added as blocked for Device[%s]",
+ priv->uuid, priv->authorize_addr);
+ }
+
+ g_dbus_method_invocation_return_error(priv->reply_context,
+ GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
+ "Authorization request rejected");
+ break;
+ }
+ case GAP_AGENT_TIMEOUT:
+ default:
+ g_dbus_method_invocation_return_error(priv->reply_context,
+ GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
+ "Authorization request rejected");
+ break;
+ }
+ }
+
+ if (context)
+ g_dbus_method_invocation_return_value(context, NULL);
+ } else {
+ BT_ERR("No context");
+
+ if (context)
+ g_dbus_method_invocation_return_error(context,
+ GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
+ "No context");
+ ret = FALSE;
+ }
+
+ if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION) {
+ priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
+ priv->reply_context = NULL;
+ memset(priv->authorize_addr, 0x00, sizeof(priv->authorize_addr));
+ g_free(priv->uuid);
+ priv->uuid = NULL;
+ }
+
+ BT_DBG("-");
+
+ return ret;
+}
+
+gboolean _gap_agent_register(GapAgentPrivate *agent)
+{
+ GapAgentPrivate *priv = agent;
+ GDBusProxy *agent_manager;
+ GError *error = NULL;
+ GVariant *reply;
+
+ retv_if(priv == NULL, FALSE);
+ retv_if(connection == NULL, FALSE);
+
+ if (priv->agent_manager == NULL) {
+ agent_manager = g_dbus_proxy_new_sync(connection,
+ G_DBUS_PROXY_FLAGS_NONE, NULL,
+ BT_BLUEZ_NAME, BT_BLUEZ_PATH,
+ BT_AGENT_MANAGER_INTERFACE, NULL, &error);
+ if (!agent_manager) {
+ if (error) {
+ ERR("Unable to create proxy: %s", error->message);
+ g_clear_error(&error);
+ }
+ return FALSE;
+ }
+ } else {
+ agent_manager = priv->agent_manager;
+ }
+
+ reply = g_dbus_proxy_call_sync(agent_manager, "RegisterAgent",
+#ifdef TIZEN_BT_IO_CAPA_NO_INPUT_OUTPUT
+ g_variant_new("(os)", priv->path, "NoInputNoOutput"),
+#elif defined(TIZEN_BT_IO_CAPA_DISPLAY_ONLY)
+ g_variant_new("(os)", priv->path, "DisplayOnly"),
+#else
+ g_variant_new("(os)", priv->path, "KeyboardDisplay"),
+#endif
+ G_DBUS_CALL_FLAGS_NONE, -1,
+ NULL, &error);
+ if (reply == NULL) {
+ BT_ERR("Agent registration failed");
+ if (error) {
+ BT_ERR("Agent registration failed: errCode[%x], message[%s]",
+ error->code, error->message);
+ g_clear_error(&error);
+ }
+ g_object_unref(agent_manager);
+ priv->agent_manager = NULL;
+ return FALSE;
+ }
+ g_variant_unref(reply);
+ reply = NULL;
+
+ /* Set the defalut agent */
+ BT_DBG("agent_manager[%p] priv->path[%s]", agent_manager, priv->path);
+ reply = g_dbus_proxy_call_sync(agent_manager, "RequestDefaultAgent",
+ g_variant_new("(o)", priv->path),
+ G_DBUS_CALL_FLAGS_NONE, -1,
+ NULL, &error);
+ if (reply == NULL) {
+ ERR("Request Default Agent failed");
+ if (error) {
+ ERR("Request Default Agent failed: errCode[%x], message[%s]",
+ error->code, error->message);
+ g_clear_error(&error);
+ }
+ g_object_unref(agent_manager);
+ priv->agent_manager = NULL;
+ return FALSE;
+ }
+ g_variant_unref(reply);
+
+ priv->agent_manager = agent_manager;
+
+ return TRUE;
+}
+
+static gboolean __gap_agent_unregister(GapAgentPrivate *agent)
+{
+ GapAgentPrivate *priv = agent;
+ GDBusProxy *agent_manager;
+ GError *error = NULL;
+ GVariant *reply;
+
+ retv_if(priv == NULL, FALSE);
+ retv_if(priv->path == NULL, FALSE);
+ retv_if(connection == NULL, FALSE);
+
+ if (priv->agent_manager == NULL) {
+ agent_manager = g_dbus_proxy_new_sync(connection,
+ G_DBUS_PROXY_FLAGS_NONE, NULL,
+ BT_BLUEZ_NAME, BT_BLUEZ_PATH,
+ BT_AGENT_MANAGER_INTERFACE, NULL, &error);
+ if (!agent_manager) {
+ if (error) {
+ ERR("Unable to create proxy: %s", error->message);
+ g_clear_error(&error);
+ }
+ return FALSE;
+ }
+ } else {
+ agent_manager = priv->agent_manager;
+ }
+
+ reply = g_dbus_proxy_call_sync(agent_manager, "UnregisterAgent",
+ g_variant_new("(o)", priv->path),
+ G_DBUS_CALL_FLAGS_NONE, -1,
+ NULL, &error);
+ g_object_unref(agent_manager);
+ priv->agent_manager = NULL;
+
+ if (reply == NULL) {
+ ERR("Agent unregistration failed");
+ if (error) {
+ ERR("Agent unregistration failed: errCode[%x], message[%s]",
+ error->code, error->message);
+ g_clear_error(&error);
+ }
+ return FALSE;
+ }
+ g_variant_unref(reply);
+
+ return TRUE;
+}
+
+static const gchar gap_agent_bluez_introspection_xml[] =
+"<node name='/'>"
+" <interface name='org.bluez.Agent1'>"
+" <method name='RequestConfirmation'>"
+" <arg type='o' name='target' direction='in'/>"
+" <arg type='u' name='passkey' direction='in'/>"
+" </method>"
+" <method name='RequestPinCode'>"
+" <arg type='o' name='target' direction='in'/>"
+" <arg type='s' name='pincode' direction='out'/>"
+" </method>"
+" <method name='RequestAuthorization'>"
+" <arg type='o' name='target' direction='in'/>"
+" </method>"
+" <method name='RequestPasskey'>"
+" <arg type='o' name='target' direction='in'/>"
+" <arg type='u' name='passkey' direction='out'/>"
+" </method>"
+" <method name='AuthorizeService'>"
+" <arg type='o' name='target' direction='in'/>"
+" <arg type='s' name='uuid' direction='in'/>"
+" </method>"
+" <method name='DisplayPasskey'>"
+" <arg type='o' name='target' direction='in'/>"
+" <arg type='u' name='passkey' direction='in'/>"
+" <arg type='q' name='entered' direction='in'/>"
+" </method>"
+" <method name='ReplyConfirmation'>"
+" <arg type='u' name='accept' direction='in'/>"
+" </method>"
+" <method name='ReplyPinCode'>"
+" <arg type='u' name='accept' direction='in'/>"
+" <arg type='s' name='pincode' direction='in'/>"
+" </method>"
+" <method name='ReplyAuthorize'>"
+" <arg type='u' name='accept' direction='in'/>"
+" </method>"
+" <method name='ReplyPasskey'>"
+" <arg type='u' name='accept' direction='in'/>"
+" <arg type='s' name='passkey' direction='in'/>"
+" </method>"
+" <method name='GetDiscoverableTimeout'>"
+" <arg type='u' name='timeout' direction='out'/>"
+" </method>"
+" <method name='ConfirmModeChange'>"
+" <arg type='s' name='mode' direction='in'/>"
+" </method>"
+" <method name='Cancel'>"
+" </method>"
+" <method name='Release'>"
+" </method>"
+" </interface>"
+"</node>";
+
+static GDBusNodeInfo *__bt_service_create_method_node_info
+ (const gchar *introspection_data)
+{
+ GError *err = NULL;
+ GDBusNodeInfo *node_info = NULL;
+
+ if (introspection_data == NULL)
+ return NULL;
+
+ node_info = g_dbus_node_info_new_for_xml(introspection_data, &err);
+
+ if (err) {
+ ERR("Unable to create node: %s", err->message);
+ g_clear_error(&err);
+ }
+ return node_info;
+}
+
+static void __bt_gap_agent_method(GDBusConnection *connection,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *method_name,
+ GVariant *parameters,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data)
+{
+ FN_START;
+
+ BT_DBG("Method[%s] Object Path[%s] Interface Name[%s]",
+ method_name, object_path, interface_name);
+
+ GError *err = NULL;
+
+ if (g_strcmp0(method_name, "RequestPinCode") == 0) {
+ GapAgentPrivate *agent = user_data;
+ char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
+ GDBusProxy *device;
+ char *addr;
+ char *path;
+ GDBusConnection *conn;
+
+ if (sender == NULL)
+ return;
+
+ g_variant_get(parameters, "(&o)", &path);
+ BT_INFO("Request pin code, Device Path :%s", path);
+
+ /* Need to check
+ if (g_strcmp0(sender, agent->busname) != 0)
+ return;
+ */
+
+ if (!agent->cb.passkey_func)
+ return;
+
+ conn = _bt_gdbus_get_system_gconn();
+ if (conn == NULL)
+ return;
+
+ device = g_dbus_proxy_new_sync(conn,
+ G_DBUS_PROXY_FLAGS_NONE, NULL,
+ BT_BLUEZ_NAME, path,
+ BT_PROPERTIES_INTERFACE, NULL, &err);
+
+ if (!device) {
+ BT_ERR("Fail to make device proxy");
+
+ g_dbus_method_invocation_return_error(invocation,
+ GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
+ "No proxy for device");
+
+ if (err) {
+ ERR("Unable to create proxy: %s", err->message);
+ g_clear_error(&err);
+ }
+
+ return;
+ }
+
+ agent->exec_type = GAP_AGENT_EXEC_PAIRING;
+ agent->reply_context = invocation;
+
+ addr = strstr(path, "dev_");
+ if (addr != NULL) {
+ char *pos = NULL;
+ addr += 4;
+ g_strlcpy(agent->pairing_addr, addr, sizeof(agent->pairing_addr));
+
+ while ((pos = strchr(agent->pairing_addr, '_')) != NULL)
+ *pos = ':';
+ }
+
+ agent->cb.pincode_func(agent, device);
+
+ g_object_unref(device);
+ return;
+
+ } else if (g_strcmp0(method_name, "RequestPasskey") == 0) {
+ GapAgentPrivate *priv = user_data;
+ char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
+ GDBusProxy *device;
+ char *addr;
+ char *path;
+ GDBusConnection *conn;
+
+ if (sender == NULL)
+ return;
+
+ g_variant_get(parameters, "(&o)", &path);
+ BT_INFO("Request passkey : sender %s priv->busname %s Device Path :%s",
+ sender, priv->busname, path);
+
+ /* Need to check
+ if (g_strcmp0(sender, agent->busname) != 0)
+ return;
+ */
+
+ if (!priv->cb.passkey_func)
+ return;
+
+ conn = _bt_gdbus_get_system_gconn();
+ if (conn == NULL)
+ return;
+
+ device = g_dbus_proxy_new_sync(conn,
+ G_DBUS_PROXY_FLAGS_NONE, NULL,
+ BT_BLUEZ_NAME, path,
+ BT_PROPERTIES_INTERFACE, NULL, &err);
+
+ if (!device) {
+ BT_ERR("Fail to make device proxy");
+
+ g_dbus_method_invocation_return_error(invocation,
+ GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
+ "No proxy for device");
+
+ if (err) {
+ ERR("Unable to create proxy: %s", err->message);
+ g_clear_error(&err);
+ }
+
+ return;
+ }
+
+ priv->exec_type = GAP_AGENT_EXEC_PAIRING;
+ priv->reply_context = invocation;
+
+ addr = strstr(path, "dev_");
+ if (addr != NULL) {
+ char *pos = NULL;
+ addr += 4;
+ g_strlcpy(priv->pairing_addr, addr, sizeof(priv->pairing_addr));
+
+ while ((pos = strchr(priv->pairing_addr, '_')) != NULL)
+ *pos = ':';
+ }
+
+ priv->cb.passkey_func(priv, device);
+
+ g_object_unref(device);
+ return;
+
+ } else if (g_strcmp0(method_name, "DisplayPasskey") == 0) {
+ GapAgentPrivate *priv = user_data;
+ char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
+ GDBusProxy *device;
+ guint passkey;
+ guint16 entered;
+ char *path;
+ GDBusConnection *conn;
+
+ if (sender == NULL)
+ return;
+
+ g_variant_get(parameters, "(&ouq)", &path, &passkey, &entered);
+ BT_INFO("Request passkey display :sender %s priv->busname %s"
+ " Device Path :%s, Passkey: %06d, Entered: %d",
+ sender, priv->busname, path, passkey, entered);
+
+ /* Do not show popup for Key event while typing*/
+ if (entered)
+ return;
+
+ /* Need to check
+ if (g_strcmp0(sender, agent->busname) != 0)
+ return;
+ */
+
+ if (!priv->cb.display_func)
+ return;
+
+ conn = _bt_gdbus_get_system_gconn();
+ if (conn == NULL)
+ return;
+
+ device = g_dbus_proxy_new_sync(conn,
+ G_DBUS_PROXY_FLAGS_NONE, NULL,
+ BT_BLUEZ_NAME, path,
+ BT_PROPERTIES_INTERFACE, NULL, &err);
+
+ if (!device) {
+ BT_ERR("Fail to make device proxy");
+
+ g_dbus_method_invocation_return_error(invocation,
+ GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
+ "No proxy for device");
+
+ if (err) {
+ ERR("Unable to create proxy: %s", err->message);
+ g_clear_error(&err);
+ }
+
+ return;
+ }
+
+ g_dbus_method_invocation_return_value(invocation, NULL);
+
+ priv->cb.display_func(priv, device, passkey);
+
+ g_object_unref(device);
+ return;
+
+ } else if (g_strcmp0(method_name, "RequestConfirmation") == 0) {
+ GapAgentPrivate *priv = user_data;
+ char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
+ GDBusProxy *device;
+ guint passkey;
+ char *path;
+ char *addr;
+ GDBusConnection *conn;
+
+ if (sender == NULL)
+ return;
+
+ g_variant_get(parameters, "(&ou)", &path, &passkey);
+ BT_INFO_C("### Request passkey confirmation");
+ INFO_SECURE("Device Path :%s, Passkey: %d", path, passkey);
+
+ BT_DBG("Sender: [%s] priv->busname: [%s]", sender, priv->busname);
+ /* Need to check
+ if (g_strcmp0(sender, agent->busname) != 0)
+ return;
+ */
+
+ BT_DBG("priv->cb.confirm_func [%p]", priv->cb.confirm_func);
+ if (!priv->cb.confirm_func)
+ return;
+
+ conn = _bt_gdbus_get_system_gconn();
+ if (conn == NULL)
+ return;
+
+ device = g_dbus_proxy_new_sync(conn,
+ G_DBUS_PROXY_FLAGS_NONE, NULL,
+ BT_BLUEZ_NAME, path,
+ BT_PROPERTIES_INTERFACE, NULL, &err);
+
+ if (!device) {
+ BT_ERR("Fail to make device proxy");
+
+ g_dbus_method_invocation_return_error(invocation,
+ GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
+ "No proxy for device");
+
+ if (err) {
+ ERR("Unable to create proxy: %s", err->message);
+ g_clear_error(&err);
+ }
+
+ return;
+ }
+
+ priv->exec_type = GAP_AGENT_EXEC_PAIRING;
+ priv->reply_context = invocation;
+
+ addr = strstr(path, "dev_");
+ if (addr != NULL) {
+ char *pos = NULL;
+ addr += 4;
+ g_strlcpy(priv->pairing_addr, addr, sizeof(priv->pairing_addr));
+
+ while ((pos = strchr(priv->pairing_addr, '_')) != NULL)
+ *pos = ':';
+ }
+
+ priv->cb.confirm_func(priv, device, passkey);
+
+ g_object_unref(device);
+ return;
+
+ } else if (g_strcmp0(method_name, "AuthorizeService") == 0) {
+ GapAgentPrivate *priv = user_data;
+ char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
+ GDBusProxy *device;
+ GDBusConnection *conn;
+ char *addr;
+ char *path;
+ char *uuid;
+
+ if (sender == NULL)
+ return;
+
+ g_variant_get(parameters, "(&o&s)", &path, &uuid);
+ BT_DBG("Request authorization :sender %s priv->busname %s "
+ "Device Path :%s UUID: %s",
+ sender, priv->busname, path, uuid);
+
+ /* Need to check
+ if (g_strcmp0(sender, agent->busname) != 0)
+ return;
+ */
+
+ if (!priv->cb.authorize_func)
+ return;
+
+ conn = _bt_gdbus_get_system_gconn();
+ if (conn == NULL)
+ return;
+
+ device = g_dbus_proxy_new_sync(conn,
+ G_DBUS_PROXY_FLAGS_NONE, NULL,
+ BT_BLUEZ_NAME, path,
+ BT_PROPERTIES_INTERFACE, NULL, &err);
+
+ if (!device) {
+ BT_ERR("Fail to make device proxy");
+
+ g_dbus_method_invocation_return_error(invocation,
+ GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
+ "No proxy for device");
+
+ if (err) {
+ ERR("Unable to create proxy: %s", err->message);
+ g_clear_error(&err);
+ }
+
+ return;
+ }
+
+ priv->exec_type = GAP_AGENT_EXEC_AUTHORZATION;
+ priv->reply_context = invocation;
+ priv->uuid = g_strdup(uuid);
+
+ addr = strstr(path, "dev_");
+ if (addr != NULL) {
+ char *pos = NULL;
+ addr += 4;
+ g_strlcpy(priv->authorize_addr, addr,
+ sizeof(priv->authorize_addr));
+
+ while ((pos = strchr(priv->authorize_addr, '_')) != NULL)
+ *pos = ':';
+ }
+
+ priv->cb.authorize_func(priv, device, uuid);
+
+ g_object_unref(device);
+ return;
+
+ } else if (g_strcmp0(method_name, "RequestAuthorization") == 0) {
+ g_dbus_method_invocation_return_value(invocation, NULL);
+ } else if (g_strcmp0(method_name, "ConfirmModeChange") == 0) {
+ g_dbus_method_invocation_return_value(invocation, NULL);
+ } else if (g_strcmp0(method_name, "Cancel") == 0) {
+ GapAgentPrivate *priv = user_data;
+ char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
+
+ if (sender == NULL)
+ return;
+
+ BT_DBG("Cancelled : agent %p sender %s", sender);
+
+ /* Need to check
+ if (g_strcmp0(sender, agent->busname) != 0)
+ return;
+ */
+
+ if (priv->cb.authorization_cancel_func &&
+ priv->exec_type == GAP_AGENT_EXEC_AUTHORZATION) {
+ priv->cb.authorization_cancel_func(priv,
+ priv->authorize_addr);
+ memset(priv->authorize_addr, 0x00,
+ sizeof(priv->authorize_addr));
+ } else if (priv->cb.pairing_cancel_func &&
+ priv->exec_type == GAP_AGENT_EXEC_PAIRING) {
+ priv->cb.pairing_cancel_func(priv,
+ priv->pairing_addr);
+ memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
+ }
+
+ if (priv->exec_type != GAP_AGENT_EXEC_CONFIRM_MODE &&
+ priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
+ priv->reply_context != NULL) {
+
+ g_dbus_method_invocation_return_error(priv->reply_context,
+ GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
+ "Rejected by remote cancel");
+ }
+
+ /* Canceled flag is set when user cancels pairing request
+ * Since here bluez has cancelled pairing request, we set the flag to false
+ */
+ priv->canceled = FALSE;
+ priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
+ priv->reply_context = NULL;
+
+ return;
+ } else if (g_strcmp0(method_name, "Release") == 0) {
+ GapAgentPrivate *priv = user_data;
+ char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
+
+ if (sender == NULL)
+ return;
+
+ BT_DBG("Released : sender %s\n", sender);
+
+ /* Need to check
+ if (g_strcmp0(sender, agent->busname) != 0)
+ return;
+ */
+
+ g_dbus_method_invocation_return_value(invocation, NULL);
+
+ priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
+ priv->reply_context = NULL;
+
+ memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
+ memset(priv->authorize_addr, 0x00, sizeof(priv->authorize_addr));
+
+ return;
+ } else if (g_strcmp0(method_name, "GetDiscoverableTimeout") == 0) {
+ BT_DBG("+");
+
+ int timeout;
+
+ _bt_get_timeout_value(&timeout);
+
+ g_dbus_method_invocation_return_value(invocation,
+ g_variant_new("(i)", timeout));
+
+ BT_DBG("-");
+
+ return;
+ } else if (g_strcmp0(method_name, "ReplyPinCode") == 0) {
+ GapAgentPrivate *priv = user_data;
+ const char *pin_code;
+ const guint accept;
+
+ g_variant_get(parameters, "(u&s)", &accept, &pin_code);
+ BT_DBG("Accept: %d PinCode: %s", accept, pin_code);
+ gap_agent_reply_pin_code(priv, accept, pin_code, invocation);
+ } else if (g_strcmp0(method_name, "ReplyPasskey") == 0) {
+ GapAgentPrivate *priv = user_data;
+ const char *passkey;
+ const guint accept;
+
+ g_variant_get(parameters, "(u&s)", &accept, &passkey);
+ BT_DBG("Accept: %d PinCode: %s", accept, passkey);
+ gap_agent_reply_passkey(priv, accept, passkey, invocation);
+ } else if (g_strcmp0(method_name, "ReplyConfirmation") == 0) {
+ GapAgentPrivate *priv = user_data;
+ const guint accept;
+
+ g_variant_get(parameters, "(u)", &accept);
+ BT_DBG("Accept: %d", accept);
+ gap_agent_reply_confirmation(priv, accept, invocation);
+ } else if (g_strcmp0(method_name, "ReplyAuthorize") == 0) {
+ GapAgentPrivate *priv = user_data;
+ const guint accept;
+
+ g_variant_get(parameters, "(u)", &accept);
+ BT_DBG("Accept: %d", accept);
+ gap_agent_reply_authorize(priv, accept, invocation);
+ }
+}
+
+static const GDBusInterfaceVTable method_table = {
+ __bt_gap_agent_method,
+ NULL,
+ NULL,
+};
+
+void _gap_agent_setup_dbus(GapAgentPrivate *agent, GAP_AGENT_FUNC_CB *func_cb,
+ const char *path,
+ GDBusProxy *adapter)
+{
+ GapAgentPrivate *priv = agent;
+ GDBusProxy *proxy;
+ GDBusNodeInfo *node_info;
+ GError *error = NULL;
+
+ priv->path = g_strdup(path);
+
+
+ node_info = __bt_service_create_method_node_info(
+ gap_agent_bluez_introspection_xml);
+ if (node_info == NULL)
+ return;
+
+ BT_DBG("path is [%s]", path);
+
+ if (connection == NULL) {
+ connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+ if (!connection) {
+ if (error) {
+ ERR("Unable to connect to gdbus: %s", error->message);
+ g_clear_error(&error);
+ }
+ g_dbus_node_info_unref(node_info);
+ return;
+ }
+ }
+
+ if (gap_agent_id == -1) {
+ gap_agent_id = g_dbus_connection_register_object(connection, path,
+ node_info->interfaces[0],
+ &method_table, priv,
+ NULL, &error);
+ }
+
+ g_dbus_node_info_unref(node_info);
+
+ if (gap_agent_id == 0) {
+ BT_ERR("Failed to register for Path: %s", path);
+ if (error) {
+ BT_ERR("Failed to register: %s", error->message);
+ g_clear_error(&error);
+ }
+ return;
+ }
+
+ memcpy(&priv->cb, func_cb, sizeof(GAP_AGENT_FUNC_CB));
+
+ priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
+ memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
+ memset(priv->authorize_addr, 0x00, sizeof(priv->authorize_addr));
+ priv->reply_context = NULL;
+
+ BT_DBG("path: %s", path);
+
+ proxy = g_dbus_proxy_new_sync(connection,
+ G_DBUS_PROXY_FLAGS_NONE, NULL,
+ BT_BLUEZ_NAME, path,
+ BT_AGENT_INTERFACE, NULL, &error);
+
+ if (!proxy) {
+ ERR("Unable to create proxy");
+ if (error) {
+ ERR("Error: %s", error->message);
+ g_clear_error(&error);
+ }
+ priv->busname = NULL;
+ } else {
+ priv->busname = g_strdup(g_dbus_proxy_get_name(proxy));
+ g_object_unref(proxy);
+ BT_DBG("Busname: %s", priv->busname);
+ }
+
+}
+
+void _gap_agent_reset_dbus(GapAgentPrivate *agent)
+{
+ GapAgentPrivate *priv = agent;
+ if (priv == NULL)
+ return;
+
+ __gap_agent_unregister(agent);
+
+ if (gap_agent_id > 0) {
+ g_dbus_connection_unregister_object(connection,
+ gap_agent_id);
+ gap_agent_id = -1;
+ }
+
+ if (connection) {
+ g_object_unref(connection);
+ connection = NULL;
+ }
+
+ if (priv->osp_servers) {
+ __gap_agent_remove_osp_servers(priv->osp_servers);
+ g_slist_free(priv->osp_servers);
+ priv->osp_servers = NULL;
+ }
+
+ g_free(priv->path);
+ priv->path = NULL;
+
+ g_free(priv->busname);
+ priv->busname = NULL;
+}
+
+gboolean _gap_agent_exist_osp_server(GapAgentPrivate *agent, int type, char *uuid)
+{
+ GapAgentPrivate *priv = agent;
+
+ if (priv == NULL)
+ return FALSE;
+
+ if (__gap_agent_find_server(priv->osp_servers,
+ type, uuid) != NULL) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+bt_agent_osp_server_t *_gap_agent_get_osp_server(GapAgentPrivate *agent, int type,
+ char *uuid)
+{
+ GapAgentPrivate *priv = agent;
+ bt_agent_osp_server_t *osp_serv = NULL;
+ if (priv == NULL)
+ return NULL;
+
+ osp_serv = __gap_agent_find_server(priv->osp_servers,
+ type, uuid);
+ if (!osp_serv)
+ return NULL;
+
+ return osp_serv;
+}
+
+gchar* _gap_agent_get_path(GapAgentPrivate *agent)
+{
+ GapAgentPrivate *priv = agent;
+ if (priv == NULL)
+ return NULL;
+
+ return priv->path;
+}
+
+gboolean _gap_agent_is_canceled(GapAgentPrivate *agent)
+{
+ GapAgentPrivate *priv = agent;
+
+ return priv->canceled;
+}
+
+void _gap_agent_set_canceled(GapAgentPrivate *agent, gboolean value)
+{
+ GapAgentPrivate *priv = agent;
+ if (priv == NULL)
+ return;
+
+ priv->canceled = value;
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/">
+ <interface name="org.bluez.Agent">
+ <method name="RequestPinCode">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <arg type="o" name="target"/>
+ <arg type="s" name="pincode" direction="out"/>
+ </method>
+
+ <method name="RequestPasskey">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <arg type="o" name="target"/>
+ <arg type="u" name="passkey" direction="out"/>
+ </method>
+
+ <method name="DisplayPasskey">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <arg type="o" name="target"/>
+ <arg type="u" name="passkey"/>
+ </method>
+
+ <method name="RequestConfirmation">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <arg type="o" name="target"/>
+ <arg type="u" name="passkey"/>
+ </method>
+
+ <method name="Authorize">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <arg type="o" name="target"/>
+ <arg type="s" name="uuid"/>
+ </method>
+
+ <method name="Cancel">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ </method>
+
+ <method name="Release">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ </method>
+
+ <method name="ReplyPinCode">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <arg type="u" name="accept"/>
+ <arg type="s" name="pincode"/>
+ </method>
+
+ <method name="ReplyPasskey">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <arg type="u" name="accept"/>
+ <arg type="s" name="passkey"/>
+ </method>
+
+ <method name="ReplyConfirmation">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <arg type="u" name="accept"/>
+ </method>
+
+ <method name="ReplyAuthorize">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <arg type="u" name="accept"/>
+ </method>
+
+ <method name="ConfirmModeChange">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <arg type="s" name="mode"/>
+ </method>
+
+ <method name="GetDiscoverableTimeout">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <arg type="u" name="timeout" direction="out"/>
+ </method>
+ </interface>
+</node>
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <glib.h>
+#include <dlog.h>
+#include <string.h>
+#include <mime_type.h>
+#include <glib.h>
+#include <gio/gio.h>
+
+#include "bluetooth-api.h"
+#include "bt-internal-types.h"
+
+#include "bt-service-common.h"
+#include "bt-service-event.h"
+#include "bt-service-util.h"
+#include "bt-service-map-client.h"
+#include "bt-service-obex-agent.h"
+#include "bt-service-core-adapter.h"
+
+#define DBUS_TIMEOUT 20 * 1000 /* 20 Seconds */
+
+enum bt_map_transfer_type {
+ BT_MAP_TRANSFER_GET_MESSAGE = 0,
+ BT_MAP_TRANSFER_PUSH_MESSAGE
+};
+
+typedef struct {
+ enum bt_map_transfer_type transfer_type;
+ char *transfer_path;
+ int request_id;
+} bt_map_callback_data_t;
+
+static GSList *transfer_list = NULL;
+
+bt_session_info_t *session_info;
+
+static void __bt_free_session_info(bt_session_info_t *info)
+{
+ ret_if(info == NULL);
+ g_free(info->address);
+ g_free(info);
+}
+
+void _bt_map_disconnected(const char *session_path)
+{
+ BT_DBG("+");
+ GVariant *param = NULL;
+ ret_if(session_info == NULL);
+
+ if (g_strcmp0(session_info->session_path,
+ session_path) != 0) {
+ BT_INFO("Path mismatch, previous transfer failed! Returning");
+ return;
+ }
+
+ param = g_variant_new("(isi)", session_info->result,
+ session_info->address,
+ session_info->request_id);
+ _bt_send_event(BT_MAP_CLIENT_EVENT,
+ BLUETOOTH_EVENT_MAP_DISCONNECTED,
+ param);
+
+ __bt_free_session_info(session_info);
+ session_info = NULL;
+
+ BT_DBG("-");
+}
+
+int _bt_create_session_sync(const char* address, char** session_id)
+{
+ BT_DBG("Entered SERVICE create session");
+ GDBusConnection *g_conn;
+ GDBusProxy *session_proxy;
+ GError *err = NULL;
+
+ retv_if(address == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
+
+ g_conn = _bt_get_session_gconn();
+ retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ session_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
+ NULL, BT_OBEX_SERVICE_NAME,
+ BT_OBEX_CLIENT_PATH,
+ BT_OBEX_CLIENT_INTERFACE,
+ NULL, &err);
+ if (err) {
+ BT_ERR("Unable to create session_proxy: %s", err->message);
+ g_clear_error(&err);
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+ retv_if(session_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ GVariantBuilder* builder = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
+ g_variant_builder_add(builder, "{sv}", "Target",
+ g_variant_new("s", "map"));
+ GVariant *args = g_variant_builder_end(builder);
+ g_variant_builder_unref(builder);
+ GVariant *param = g_variant_new("(s@a{sv})", address, args);
+
+ GVariant *value = g_dbus_proxy_call_sync(session_proxy, "CreateSession", param,
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
+ if (err != NULL) {
+ BT_ERR("Could not create session: %s\n", err->message);
+ g_error_free(err);
+ return BLUETOOTH_ERROR_INTERNAL;
+ } else {
+ if (NULL == value) {
+ BT_ERR("create session returned value is null\n");
+ return BLUETOOTH_ERROR_INTERNAL;
+ } else {
+ BT_DBG("create session succeed\n");
+ }
+ }
+
+ g_variant_get(value, "(&o)", session_id);
+ BT_DBG("session_id = \"%s\"\n", *session_id);
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_destroy_session_sync(const char* session_id)
+{
+ BT_DBG("Entered SERVICE destroy session with id: \"%s\"", session_id);
+ GDBusConnection *g_conn;
+ GDBusProxy *session_proxy;
+ GError *err = NULL;
+
+ retv_if(session_id == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
+
+ g_conn = _bt_get_session_gconn();
+ retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ session_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
+ NULL, BT_OBEX_SERVICE_NAME,
+ BT_OBEX_CLIENT_PATH,
+ BT_OBEX_CLIENT_INTERFACE,
+ NULL, &err);
+ if (err) {
+ BT_ERR("Unable to create session_proxy: %s", err->message);
+ g_clear_error(&err);
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+ retv_if(session_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ GVariant *param = g_variant_new("(o)", session_id);
+
+ g_dbus_proxy_call_sync(session_proxy, "RemoveSession", param,
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
+ if (err != NULL) {
+ BT_ERR("Could not remove session: %s\n", err->message);
+ g_error_free(err);
+ return BLUETOOTH_ERROR_INTERNAL;
+ } else {
+ BT_DBG("remove session succeed\n");
+ }
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_map_client_set_folder(const char* session_id, const char* name)
+{
+ BT_DBG("+");
+
+ GError *err = NULL;
+ GDBusConnection *g_conn;
+ GDBusProxy *message_proxy;
+ GVariant *ret = NULL;
+
+ g_conn = _bt_get_session_gconn();
+ retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ message_proxy = g_dbus_proxy_new_sync(g_conn,
+ G_DBUS_PROXY_FLAGS_NONE, NULL,
+ BT_OBEX_SERVICE_NAME, session_id,
+ BT_OBEX_MESSAGE_INTERFACE, NULL, &err);
+
+ retv_if(message_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ ret = g_dbus_proxy_call_sync(message_proxy,
+ "SetFolder", g_variant_new("(s)", name),
+ G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT,
+ NULL, &err);
+
+ if (ret == NULL) {
+ if (err != NULL) {
+ BT_ERR("SetFolder Error: %s\n", err->message);
+ g_error_free(err);
+ }
+ } else {
+ g_variant_unref(ret);
+ }
+
+ g_object_unref(message_proxy);
+
+ BT_DBG("-");
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+static void __bt_list_folders_cb(GDBusProxy *proxy,
+ GAsyncResult *res, gpointer user_data)
+{
+ BT_DBG("+");
+
+ GError *error = NULL;
+ GVariant *value, *in_param, *param;
+
+ int result = BLUETOOTH_ERROR_NONE;
+ int request_id;
+
+ in_param = (GVariant*) user_data;
+ g_variant_get(in_param, "(i)", &request_id);
+
+ value = g_dbus_proxy_call_finish(proxy, res, &error);
+
+ if (error) {
+ BT_ERR("%s", error->message);
+ g_clear_error(&error);
+ result = BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ param = g_variant_new("(iiv)", result, request_id, value);
+ BT_DBG("RequestID[%d]", request_id);
+ result = _bt_send_event(BT_MAP_CLIENT_EVENT,
+ BLUETOOTH_EVENT_MAP_LIST_FOLDERS_COMPLETE, param);
+
+ g_variant_unref(value);
+ g_variant_unref(in_param);
+
+ BT_DBG("-");
+}
+
+int _bt_map_client_list_folders(
+ int request_id,
+ GDBusMethodInvocation *context,
+ const char* session_id,
+ const char* filter_serialized)
+{
+ BT_DBG("Entered _bt_map_list_folders with session id: \"%s\"", session_id);
+ GDBusConnection *g_conn;
+ GDBusProxy *message_access_proxy;
+ GError *error = NULL;
+ int result = BLUETOOTH_ERROR_NONE;
+
+ retv_if(session_id == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
+
+ g_conn = _bt_get_session_gconn();
+ retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ GVariant *out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
+ &request_id, sizeof(int),
+ TRUE, NULL, NULL);
+ g_dbus_method_invocation_return_value(context,
+ g_variant_new("(iv)", result, out_param1));
+
+ // create message access proxy
+ g_clear_error(&error);
+ message_access_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
+ BT_OBEX_SERVICE_NAME, session_id, "org.bluez.obex.MessageAccess1",
+ NULL, &error);
+ if (error != NULL) {
+ BT_ERR("Could not create message access proxy: %s\n", error->message);
+ result = BLUETOOTH_ERROR_INTERNAL;
+ } else {
+ if (!message_access_proxy) {
+ BT_ERR("message proxy handle is null\n");
+ result = BLUETOOTH_ERROR_INTERNAL;
+ } else {
+ BT_DBG("message proxy set");
+
+ GVariant *filter_variant = g_variant_parse(NULL, filter_serialized, NULL, NULL, NULL);
+
+ GVariant *params = g_variant_new("(@a{sv})", filter_variant);
+ GVariant *param = g_variant_new("(i)", request_id);
+
+ g_dbus_proxy_call(message_access_proxy,
+ "ListFolders", params,
+ G_DBUS_CALL_FLAGS_NONE, -1,
+ NULL,
+ (GAsyncReadyCallback)__bt_list_folders_cb,
+ (void*)param);
+ }
+ }
+
+ g_object_unref(message_access_proxy);
+ BT_DBG("-");
+
+ return result;
+}
+
+static void __bt_list_filter_fields_cb(GDBusProxy *proxy,
+ GAsyncResult *res, gpointer user_data)
+{
+ BT_DBG("+");
+
+ GError *error = NULL;
+ GVariant *value, *in_param, *param;
+
+ int result = BLUETOOTH_ERROR_NONE;
+ int request_id;
+
+ in_param = (GVariant*) user_data;
+ g_variant_get(in_param, "(i)", &request_id);
+
+ value = g_dbus_proxy_call_finish(proxy, res, &error);
+
+ if (error) {
+ BT_ERR("%s", error->message);
+ g_clear_error(&error);
+ result = BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ param = g_variant_new("(ivi)", result, value, request_id);
+
+ _bt_send_event(BT_MAP_CLIENT_EVENT, BLUETOOTH_EVENT_MAP_LIST_FILTER_FIELD_COMPLETE,
+ param);
+
+ g_variant_unref(value);
+ g_variant_unref(in_param);
+
+ BT_DBG("-");
+}
+
+int _bt_map_client_list_filter_fields(int request_id, GDBusMethodInvocation *context, const char* session_id)
+{
+ BT_DBG("+");
+
+ GError *err = NULL;
+ GDBusConnection *g_conn;
+ GDBusProxy *message_proxy;
+ int result = BLUETOOTH_ERROR_NONE;
+
+ retv_if(session_id == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
+
+ g_conn = _bt_get_session_gconn();
+ retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ GVariant *out_param = g_variant_new_from_data((const GVariantType *)"ay",
+ &request_id, sizeof(int),
+ TRUE, NULL, NULL);
+
+ g_dbus_method_invocation_return_value(context,
+ g_variant_new("(iv)", result, out_param));
+
+
+ message_proxy = g_dbus_proxy_new_sync(g_conn,
+ G_DBUS_PROXY_FLAGS_NONE, NULL,
+ BT_OBEX_SERVICE_NAME, session_id,
+ BT_OBEX_MESSAGE_INTERFACE, NULL, &err);
+
+ retv_if(message_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ GVariant *param = g_variant_new("(i)", request_id);
+
+ g_dbus_proxy_call(message_proxy,
+ "ListFilterFields", g_variant_new("()"),
+ G_DBUS_CALL_FLAGS_NONE, -1,
+ NULL,
+ (GAsyncReadyCallback)__bt_list_filter_fields_cb,
+ (void*)param);
+
+ g_object_unref(message_proxy);
+
+ BT_DBG("-");
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+static void __bt_list_messages_cb(
+ GDBusProxy *proxy, GAsyncResult *res, gpointer user_data)
+{
+ BT_DBG("+");
+
+ GError *error = NULL;
+ GVariant *value, *in_param, *param;
+
+ int result = BLUETOOTH_ERROR_NONE;
+ int request_id;
+
+ in_param = (GVariant*) user_data;
+ g_variant_get(in_param, "(i)", &request_id);
+
+ value = g_dbus_proxy_call_finish(proxy, res, &error);
+
+ if (error) {
+ BT_ERR("%s", error->message);
+ g_clear_error(&error);
+ result = BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ param = g_variant_new("(iiv)", result, request_id, value);
+ BT_DBG("RequestID[%d]", request_id);
+ result = _bt_send_event(BT_MAP_CLIENT_EVENT,
+ BLUETOOTH_EVENT_MAP_LIST_MESSAGES_COMPLETE, param);
+
+ g_variant_unref(value);
+ g_variant_unref(in_param);
+
+ BT_DBG("-");
+}
+
+int _bt_map_client_list_messages(
+ int request_id,
+ GDBusMethodInvocation *context,
+ const char* session_id,
+ const char* folder,
+ const char* filter_serialized)
+{
+ BT_DBG("Entered _bt_map_client_list_messages with session id: \"%s\"", session_id);
+ BT_DBG("Entered folder: %s", folder);
+ GDBusConnection *g_conn;
+ GDBusProxy *message_access_proxy;
+ GError *error = NULL;
+ int result = BLUETOOTH_ERROR_NONE;
+
+ retv_if(session_id == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
+
+ g_conn = _bt_get_session_gconn();
+ retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ GVariant *out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
+ &request_id, sizeof(int),
+ TRUE, NULL, NULL);
+ g_dbus_method_invocation_return_value(context,
+ g_variant_new("(iv)", result, out_param1));
+
+ // create message access proxy
+ g_clear_error(&error);
+ message_access_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
+ BT_OBEX_SERVICE_NAME, session_id, "org.bluez.obex.MessageAccess1",
+ NULL, &error);
+ if (error != NULL) {
+ BT_ERR("Could not create message access proxy: %s\n", error->message);
+ result = BLUETOOTH_ERROR_INTERNAL;
+ } else {
+ if (!message_access_proxy) {
+ BT_ERR("message proxy handle is null\n");
+ result = BLUETOOTH_ERROR_INTERNAL;
+ } else {
+ BT_DBG("message proxy set");
+
+ GVariant *filter_variant = g_variant_parse(NULL, filter_serialized, NULL, NULL, NULL);
+
+ GVariant *params = g_variant_new("(s@a{sv})", folder, filter_variant);
+ GVariant *param = g_variant_new("(i)", request_id);
+
+ g_dbus_proxy_call(message_access_proxy,
+ "ListMessages", params,
+ G_DBUS_CALL_FLAGS_NONE, -1,
+ NULL,
+ (GAsyncReadyCallback)__bt_list_messages_cb,
+ (void*)param);
+ }
+ }
+
+ g_object_unref(message_access_proxy);
+ BT_DBG("-");
+
+ return result;
+}
+
+int _bt_map_client_update_inbox(const char* session_id)
+{
+ BT_DBG("+");
+
+ GError *err = NULL;
+ GDBusConnection *g_conn;
+ GDBusProxy *message_proxy;
+ GVariant *ret = NULL;
+
+ g_conn = _bt_get_session_gconn();
+ retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ message_proxy = g_dbus_proxy_new_sync(g_conn,
+ G_DBUS_PROXY_FLAGS_NONE, NULL,
+ BT_OBEX_SERVICE_NAME, session_id,
+ BT_OBEX_MESSAGE_INTERFACE, NULL, &err);
+
+ retv_if(message_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ ret = g_dbus_proxy_call_sync(message_proxy,
+ "UpdateInbox", g_variant_new("()"),
+ G_DBUS_CALL_FLAGS_NONE, -1,
+ NULL, &err);
+
+ if (ret == NULL) {
+ if (err != NULL) {
+ BT_ERR("UpdateInbox Error: %s\n", err->message);
+ g_error_free(err);
+ }
+ } else {
+ g_variant_unref(ret);
+ }
+
+ g_object_unref(message_proxy);
+
+ BT_DBG("-");
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+void _bt_map_on_transfer_finished(const char *transfer_object_path, const int error)
+{
+ BT_DBG("Entered _bt_map_on_transfer_finished");
+ BT_DBG("Looking for transfer %s id", transfer_object_path);
+
+ bt_map_callback_data_t *callback_data = NULL;
+ GSList* transfer = NULL;
+ for (transfer = transfer_list; transfer != NULL; transfer = g_slist_next(transfer)) {
+ callback_data = transfer->data;
+ if (NULL == callback_data)
+ continue;
+
+ if (0 == strcmp(transfer_object_path, callback_data->transfer_path)) {
+ BT_DBG("request id FOUND - triggering event");
+
+ GVariant *param = g_variant_new("(ii)", error, callback_data->request_id);
+
+ int event = -1;
+ switch (callback_data->transfer_type) {
+ case BT_MAP_TRANSFER_GET_MESSAGE:
+ event = BLUETOOTH_EVENT_MAP_GET_MESSAGE_COMPLETE;
+ break;
+ case BT_MAP_TRANSFER_PUSH_MESSAGE:
+ event = BLUETOOTH_EVENT_MAP_PUSH_MESSAGE_COMPLETE;
+ break;
+ }
+
+ _bt_send_event(BT_MAP_CLIENT_EVENT, event, param);
+
+ // remove callback data from list
+ transfer_list = g_slist_remove(transfer_list, transfer);
+
+ //free memory and break loop
+ free(callback_data->transfer_path);
+ callback_data->transfer_path = NULL;
+ free(callback_data);
+ break;
+ }
+
+ }
+}
+
+static void __bt_push_message_cb(GDBusProxy *proxy,
+ GAsyncResult *res, gpointer user_data)
+{
+ BT_DBG("+");
+
+ GError *error = NULL;
+ GVariant *value, *in_param;
+
+ char *transfer_object_path = NULL;
+ GVariantIter *iter = NULL;
+
+ int request_id;
+
+ in_param = (GVariant*) user_data;
+ g_variant_get(in_param, "(i)", &request_id);
+
+ value = g_dbus_proxy_call_finish(proxy, res, &error);
+ if (error) {
+ BT_ERR("%s", error->message);
+ g_clear_error(&error);
+ }
+
+ if (value) {
+ g_variant_get(value, "(oa{sv})", &transfer_object_path, &iter);
+ g_variant_unref(value);
+ }
+
+ BT_DBG("transfer object path: [%s]", transfer_object_path);
+
+ BT_DBG("Adding request id %d - transfer [%s]", request_id, transfer_object_path);
+ bt_map_callback_data_t* callback_data = malloc(sizeof(*callback_data));
+ callback_data->transfer_type = BT_MAP_TRANSFER_PUSH_MESSAGE;
+ callback_data->request_id = request_id;
+ callback_data->transfer_path = transfer_object_path;
+
+ transfer_list = g_slist_append(transfer_list, callback_data);
+
+ g_variant_unref(value);
+ g_variant_unref(in_param);
+
+ BT_DBG("-");
+}
+
+int _bt_map_client_push_message(
+ int request_id,
+ GDBusMethodInvocation *context,
+ const char* session_id,
+ const char* source_file,
+ const char* folder,
+ const char* args_serialized)
+{
+ BT_DBG("Entered _bt_map_client_push_message with session id: \"%s\"", session_id);
+ BT_DBG("Entered source_file: %s", source_file);
+ BT_DBG("Entered folder: %s", folder);
+
+ GDBusConnection *g_conn;
+ GDBusProxy *message_access_proxy;
+ GError *error = NULL;
+ int result = BLUETOOTH_ERROR_NONE;
+
+ retv_if(session_id == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
+
+ // TODO event listeners registration on first call, where should it be unregistered??
+// _bt_map_client_event_init(); --need to do
+
+ g_conn = _bt_get_session_gconn();
+ retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ GVariant *out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
+ &request_id, sizeof(int),
+ TRUE, NULL, NULL);
+ g_dbus_method_invocation_return_value(context, g_variant_new("(iv)", result, out_param1));
+
+ // create message access proxy
+ g_clear_error(&error);
+ message_access_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
+ BT_OBEX_SERVICE_NAME, session_id, BT_OBEX_MESSAGE_INTERFACE,
+ NULL, &error);
+ if (error != NULL) {
+ BT_ERR("Could not create message access proxy: %s\n", error->message);
+ result = BLUETOOTH_ERROR_INTERNAL;
+ } else {
+ if (!message_access_proxy) {
+ BT_ERR("message proxy handle is null\n");
+ result = BLUETOOTH_ERROR_INTERNAL;
+ } else {
+ BT_DBG("message proxy set");
+
+ GVariant *args_variant = g_variant_parse(NULL, args_serialized, NULL, NULL, NULL);
+
+ GVariant *params = g_variant_new("(ss@a{sv})", source_file, folder, args_variant);
+ GVariant *req_id = g_variant_new("(i)", request_id);
+
+ g_dbus_proxy_call(message_access_proxy,
+ "PushMessage", params,
+ G_DBUS_CALL_FLAGS_NONE, -1,
+ NULL, (GAsyncReadyCallback)__bt_push_message_cb,
+ (void*)req_id);
+ }
+ }
+
+ g_object_unref(message_access_proxy);
+ BT_DBG("-");
+
+ return result;
+}
+
+static void __bt_get_message_cb(GDBusProxy *proxy,
+ GAsyncResult *res, gpointer user_data)
+{
+ BT_DBG("+");
+
+ GError *error = NULL;
+ GVariant *value, *in_param;
+
+ char *transfer_object_path = NULL;
+ GVariantIter *iter = NULL;
+
+ int request_id;
+
+ in_param = (GVariant*) user_data;
+ g_variant_get(in_param, "(i)", &request_id);
+
+ value = g_dbus_proxy_call_finish(proxy, res, &error);
+ if (error) {
+ BT_ERR("%s", error->message);
+ g_clear_error(&error);
+ }
+
+ if (value) {
+ g_variant_get(value, "(oa{sv})", &transfer_object_path, &iter);
+ g_variant_unref(value);
+ }
+
+ BT_DBG("transfer object path: [%s]", transfer_object_path);
+
+ BT_DBG("Adding request id %d - transfer [%s]", request_id, transfer_object_path);
+ bt_map_callback_data_t* callback_data = malloc(sizeof(*callback_data));
+ callback_data->transfer_type = BT_MAP_TRANSFER_GET_MESSAGE;
+ callback_data->request_id = request_id;
+ callback_data->transfer_path = transfer_object_path;
+
+ transfer_list = g_slist_append(transfer_list, callback_data);
+
+ g_variant_unref(value);
+ g_variant_unref(in_param);
+
+ BT_DBG("-");
+}
+
+int _bt_map_client_get_message(
+ int request_id,
+ GDBusMethodInvocation *context,
+ const char* message_object,
+ const char* target_file,
+ bool attachment)
+{
+ BT_DBG("Entered _bt_map_client_get_message");
+
+ GDBusConnection *g_conn;
+ GDBusProxy *message_proxy;
+ GError *error = NULL;
+ int result = BLUETOOTH_ERROR_NONE;
+
+ retv_if(message_object == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
+
+ // TODO event listeners registration on first call, where should it be unregistered??
+// _bt_map_client_event_init();
+
+ g_conn = _bt_get_session_gconn();
+ retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ GVariant *out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
+ &request_id, sizeof(int),
+ TRUE, NULL, NULL);
+ g_dbus_method_invocation_return_value(context, g_variant_new("(iv)", result, out_param1));
+
+ // create message proxy
+ g_clear_error(&error);
+ message_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
+ BT_OBEX_SERVICE_NAME, message_object, "org.bluez.obex.Message1",
+ NULL, &error);
+ if (error != NULL) {
+ BT_ERR("Could not create message proxy: %s\n", error->message);
+ result = BLUETOOTH_ERROR_INTERNAL;
+ } else {
+ if (!message_proxy) {
+ BT_ERR("message proxy handle is null\n");
+ result = BLUETOOTH_ERROR_INTERNAL;
+ } else {
+ BT_DBG("message proxy set");
+ GVariant *params = g_variant_new("(sb)", target_file, attachment);
+ GVariant *req_id = g_variant_new("(i)", request_id);
+
+ g_dbus_proxy_call(message_proxy, "Get", params, G_DBUS_CALL_FLAGS_NONE, -1,
+ NULL, (GAsyncReadyCallback)__bt_get_message_cb, (void*)req_id);
+ }
+ }
+
+ g_object_unref(message_proxy);
+ BT_DBG("-");
+
+ return result;
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <glib.h>
+#include <gio/gio.h>
+#include <dlog.h>
+#include <string.h>
+#include <stdio.h>
+#include <syspopup_caller.h>
+#include <net_connection.h>
+
+#include "bluetooth-api.h"
+#include "bt-service-network.h"
+#include "bt-service-common.h"
+#include "bt-service-event.h"
+#include "bt-service-util.h"
+#include "bt-internal-types.h"
+
+void _bt_util_addr_type_to_addr_net_string(char *address,
+ unsigned char *addr)
+{
+ ret_if(address == NULL);
+ ret_if(addr == NULL);
+
+ snprintf(address, BT_ADDRESS_STR_LEN, "%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X", addr[0],
+ addr[1], addr[2], addr[3], addr[4], addr[5]);
+}
+
+static connection_profile_h __bt_get_net_profile(void *connection,
+ connection_iterator_type_e type,
+ unsigned char *address)
+{
+ int result;
+ gchar **split_string;
+ char net_address[BT_ADDRESS_STR_LEN + 1] = { 0 };
+ char *profile_name = NULL;
+ connection_profile_iterator_h profile_iter;
+ connection_profile_h profile_h;
+ connection_profile_type_e profile_type;
+
+ retv_if(connection == NULL, NULL);
+ retv_if(address == NULL, NULL);
+
+ BT_DBG("net_conn: %x", connection);
+
+ _bt_util_addr_type_to_addr_net_string(net_address, address);
+
+ result = connection_get_profile_iterator(connection,
+ type,
+ &profile_iter);
+ if (result != CONNECTION_ERROR_NONE) {
+ BT_ERR("Fail to get profile iterator [%d]", result);
+ return NULL;
+ }
+
+ while (connection_profile_iterator_has_next(profile_iter)) {
+ profile_name = NULL;
+ profile_h = NULL;
+ split_string = NULL;
+
+ if (connection_profile_iterator_next(profile_iter,
+ &profile_h) != CONNECTION_ERROR_NONE) {
+ BT_ERR("Fail to get profile handle");
+ return NULL;
+ }
+
+ if (connection_profile_get_type(profile_h,
+ &profile_type) != CONNECTION_ERROR_NONE) {
+ BT_ERR("Fail to get profile type");
+ continue;
+ }
+
+ if (profile_type != CONNECTION_PROFILE_TYPE_BT)
+ continue;
+
+ if (connection_profile_get_name(profile_h,
+ &profile_name) != CONNECTION_ERROR_NONE) {
+ BT_ERR("Fail to get profile name");
+ return NULL;
+ }
+
+ split_string = g_strsplit(profile_name, "_", 3);
+
+ g_free(profile_name);
+
+ if (g_strv_length(split_string) < 3)
+ continue;
+
+ if (g_ascii_strcasecmp(split_string[2], net_address) == 0) {
+ BT_DBG("matched profile");
+ g_strfreev(split_string);
+ return profile_h;
+ }
+
+ g_strfreev(split_string);
+ }
+
+ return NULL;
+}
+
+int _bt_is_network_connected(void *connection, unsigned char *address,
+ gboolean *is_connected)
+{
+ void *handle = NULL;
+ handle = __bt_get_net_profile(connection,
+ CONNECTION_ITERATOR_TYPE_CONNECTED,
+ address);
+ if (handle)
+ *is_connected = TRUE;
+ else
+ *is_connected = FALSE;
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+static void __bt_network_connect_cb(GDBusProxy *proxy, GAsyncResult *res,
+ gpointer user_data)
+{
+ GError *g_error = NULL;
+ GVariant *out_param1 = NULL;
+ GVariant *reply = NULL;
+ bluetooth_device_address_t device_addr = { {0} };
+ int result = BLUETOOTH_ERROR_NONE;
+ bt_function_data_t *func_data;
+ request_info_t *req_info;
+
+ reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
+ g_object_unref(proxy);
+
+ if (reply == NULL) {
+ BT_ERR("Network Connect Dbus Call Error");
+ if (g_error) {
+ BT_ERR("Error: %s\n", g_error->message);
+ g_clear_error(&g_error);
+ }
+ result = BLUETOOTH_ERROR_INTERNAL;
+ }
+ g_variant_unref(reply);
+
+ func_data = user_data;
+ if (func_data == NULL) {
+ /* Send reply */
+ BT_ERR("func_data == NULL");
+ goto done;
+ }
+
+ BT_ERR("func_data->req_id: %d", func_data->req_id);
+ req_info = _bt_get_request_info(func_data->req_id);
+ if (req_info == NULL) {
+ BT_ERR("req_info == NULL");
+ goto done;
+ }
+
+ if (req_info->context == NULL)
+ goto done;
+
+ _bt_convert_addr_string_to_type(device_addr.addr,
+ func_data->address);
+
+ out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
+ &device_addr, sizeof(bluetooth_device_address_t), TRUE, NULL, NULL);
+
+ g_dbus_method_invocation_return_value(req_info->context,
+ g_variant_new("iv", result, out_param1));
+
+ _bt_delete_request_list(req_info->req_id);
+
+done:
+ if (func_data) {
+ g_free(func_data->address);
+ g_free(func_data);
+ }
+}
+
+static void __bt_network_disconnect_cb(GDBusProxy *proxy, GAsyncResult *res,
+ gpointer user_data)
+{
+ GError *g_error = NULL;
+ GVariant *out_param1 = NULL;
+ GVariant *reply = NULL;
+ bluetooth_device_address_t device_addr = { {0} };
+ int result = BLUETOOTH_ERROR_NONE;
+ bt_function_data_t *func_data;
+ request_info_t *req_info;
+
+ reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
+ g_object_unref(proxy);
+
+ if (reply == NULL) {
+ BT_ERR("Network Disconnect Dbus Call Error");
+ if (g_error) {
+ BT_ERR("Error: %s\n", g_error->message);
+ g_clear_error(&g_error);
+ }
+ result = BLUETOOTH_ERROR_INTERNAL;
+ }
+ g_variant_unref(reply);
+
+ func_data = user_data;
+ if (func_data == NULL) {
+ /* Send reply */
+ BT_ERR("func_data == NULL");
+ goto done;
+ }
+ BT_ERR("func_data->req_id: %d", func_data->req_id);
+ req_info = _bt_get_request_info(func_data->req_id);
+ if (req_info == NULL) {
+ BT_ERR("req_info == NULL");
+ goto done;
+ }
+
+ if (g_error != NULL) {
+ BT_ERR("Network Connect Dbus Call Error: %s\n", g_error->message);
+ result = BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ if (req_info->context == NULL)
+ goto done;
+
+ out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
+ &device_addr, sizeof(bluetooth_device_address_t), TRUE, NULL, NULL);
+
+ g_dbus_method_invocation_return_value(req_info->context,
+ g_variant_new("iv", result, out_param1));
+
+ _bt_delete_request_list(req_info->req_id);
+
+done:
+ if (func_data) {
+ g_free(func_data->address);
+ g_free(func_data);
+ }
+}
+
+int _bt_network_activate(void)
+{
+ int ret = BLUETOOTH_ERROR_NONE;
+ char *adapter_path;
+ GVariant *result = NULL;
+ GError *err = NULL;
+ GDBusConnection *conn;
+ GDBusProxy *server_proxy;
+
+ conn = _bt_gdbus_get_system_gconn();
+ retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ adapter_path = _bt_get_adapter_path();
+ retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ server_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
+ NULL, BT_BLUEZ_NAME,
+ adapter_path, BT_NETWORK_SERVER_INTERFACE, NULL, NULL);
+ g_free(adapter_path);
+
+ if (server_proxy == NULL) {
+ BT_ERR("Failed to get the network server proxy\n");
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ result = g_dbus_proxy_call_sync(server_proxy, "Register",
+ g_variant_new("(ss)", NAP_UUID_NAME, NET_BRIDGE_INTERFACE),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &err);
+ if (result == NULL) {
+ if (err != NULL) {
+ g_dbus_error_strip_remote_error(err);
+ BT_ERR("Network server register Error: %s\n", err->message);
+ if (g_strcmp0(err->message, "Already Exists") == 0)
+ ret = BLUETOOTH_ERROR_ALREADY_INITIALIZED;
+ else
+ ret = BLUETOOTH_ERROR_INTERNAL;
+
+ g_error_free(err);
+ }
+ } else {
+ g_variant_unref(result);
+ }
+
+ g_object_unref(server_proxy);
+
+ return ret;
+}
+
+int _bt_network_deactivate(void)
+{
+ char *adapter_path;
+ GVariant *result = NULL;
+ GError *err = NULL;
+ GDBusConnection *conn;
+ GDBusProxy *server_proxy;
+ int ret = BLUETOOTH_ERROR_NONE;
+
+ conn = _bt_gdbus_get_system_gconn();
+ retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ adapter_path = _bt_get_adapter_path();
+ retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ server_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
+ NULL, BT_BLUEZ_NAME,
+ adapter_path, BT_NETWORK_SERVER_INTERFACE, NULL, NULL);
+ g_free(adapter_path);
+
+ if (server_proxy == NULL) {
+ BT_ERR("Failed to get the network server proxy\n");
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ result = g_dbus_proxy_call_sync(server_proxy, "Unregister",
+ g_variant_new("(s)", NAP_UUID_NAME),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &err);
+ if (result == NULL) {
+ if (err != NULL) {
+ g_dbus_error_strip_remote_error(err);
+ BT_ERR("Network server unregister Error: %s\n", err->message);
+ if (g_strcmp0(err->message,
+ "Operation currently not available") == 0) {
+ ret = BLUETOOTH_ERROR_ALREADY_DEACTIVATED;
+ } else {
+ ret = BLUETOOTH_ERROR_INTERNAL;
+ }
+ g_error_free(err);
+ }
+ } else {
+ g_variant_unref(result);
+ }
+
+ g_object_unref(server_proxy);
+
+ return ret;
+}
+
+int _bt_network_connect(int request_id, int role,
+ bluetooth_device_address_t *device_address)
+{
+ const gchar *device_path = NULL;
+ char address[BT_ADDRESS_STRING_SIZE] = { 0 };
+ char remote_role[BLUETOOTH_UUID_STRING_MAX] = { 0 };
+ bt_function_data_t *func_data;
+ GDBusProxy *adapter_proxy;
+ GDBusProxy *profile_proxy;
+ GDBusConnection *conn;
+ GVariant *result = NULL;
+ GError*err = NULL;
+
+ BT_CHECK_PARAMETER(device_address, return);
+
+ switch (role) {
+ case BLUETOOTH_NETWORK_PANU_ROLE:
+ g_strlcpy(remote_role, PANU_UUID_NAME, BLUETOOTH_UUID_STRING_MAX);
+ break;
+
+ case BLUETOOTH_NETWORK_NAP_ROLE:
+ g_strlcpy(remote_role, NAP_UUID_NAME, BLUETOOTH_UUID_STRING_MAX);
+ break;
+
+ case BLUETOOTH_NETWORK_GN_ROLE:
+ g_strlcpy(remote_role, GN_UUID_NAME, BLUETOOTH_UUID_STRING_MAX);
+ break;
+ default:
+ BT_ERR("Unknown role");
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ adapter_proxy = _bt_get_adapter_proxy();
+ retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ conn = _bt_gdbus_get_system_gconn();
+ retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ _bt_convert_addr_type_to_string(address, device_address->addr);
+
+ result = g_dbus_proxy_call_sync(adapter_proxy, "FindDevice",
+ g_variant_new("(s)", address),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1, NULL, &err);
+ if (result == NULL) {
+ BT_ERR("Error occurred in call to FindDevice");
+ if (err) {
+ BT_ERR("Error: %s", err->message);
+ g_clear_error(&err);
+ }
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ device_path = g_variant_get_string(result, NULL);
+ if (device_path == NULL) {
+ BT_ERR("No paired device");
+ g_variant_unref(result);
+ return BLUETOOTH_ERROR_NOT_PAIRED;
+ }
+
+ profile_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
+ NULL, BT_BLUEZ_NAME,
+ device_path, BT_NETWORK_CLIENT_INTERFACE, NULL, NULL);
+
+ g_variant_unref(result);
+ retv_if(profile_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
+ func_data = g_malloc0(sizeof(bt_function_data_t));
+ func_data->address = g_strdup(address);
+ func_data->req_id = request_id;
+
+ g_dbus_proxy_call(profile_proxy, "Connect",
+ g_variant_new("(s)", remote_role),
+ G_DBUS_CALL_FLAGS_NONE,
+ BT_MAX_DBUS_TIMEOUT,
+ NULL,
+ (GAsyncReadyCallback)__bt_network_connect_cb,
+ func_data);
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_network_disconnect(int request_id,
+ bluetooth_device_address_t *device_address)
+{
+ const gchar *device_path = NULL;
+ char address[BT_ADDRESS_STRING_SIZE] = { 0 };
+ bt_function_data_t *func_data;
+ GDBusProxy *adapter_proxy;
+ GDBusProxy *profile_proxy;
+ GDBusConnection *conn;
+ GVariant *result = NULL;
+ GError*err = NULL;
+
+ BT_CHECK_PARAMETER(device_address, return);
+
+ adapter_proxy = _bt_get_adapter_proxy();
+ retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ conn = _bt_gdbus_get_system_gconn();
+ retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ _bt_convert_addr_type_to_string(address, device_address->addr);
+
+ result = g_dbus_proxy_call_sync(adapter_proxy, "FindDevice",
+ g_variant_new("(s)", address),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1, NULL, &err);
+ if (result == NULL) {
+ BT_ERR("Error occurred in call to FindDevice");
+ if (err) {
+ BT_ERR("Error: %s", err->message);
+ g_clear_error(&err);
+ }
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ device_path = g_variant_get_string(result, NULL);
+ if (device_path == NULL) {
+ BT_ERR("No paired device");
+ g_variant_unref(result);
+ return BLUETOOTH_ERROR_NOT_PAIRED;
+ }
+
+ profile_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
+ NULL, BT_BLUEZ_NAME,
+ device_path, BT_NETWORK_CLIENT_INTERFACE, NULL, NULL);
+
+ g_variant_unref(result);
+ retv_if(profile_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
+ func_data = g_malloc0(sizeof(bt_function_data_t));
+ func_data->address = g_strdup(address);
+ func_data->req_id = request_id;
+
+ g_dbus_proxy_call(profile_proxy, "Disconnect",
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ BT_MAX_DBUS_TIMEOUT,
+ NULL,
+ (GAsyncReadyCallback)__bt_network_disconnect_cb,
+ func_data);
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_network_server_disconnect(int request_id,
+ bluetooth_device_address_t *device_address)
+{
+ gchar *adapter_path = NULL;
+ char address[BT_ADDRESS_STRING_SIZE] = { 0 };
+ bt_function_data_t *func_data;
+ GDBusProxy *profile_proxy;
+ GDBusConnection *conn;
+
+ BT_CHECK_PARAMETER(device_address, return);
+
+ conn = _bt_gdbus_get_system_gconn();
+ retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ adapter_path = _bt_get_adapter_path();
+ if (adapter_path == NULL) {
+ BT_ERR("No adapter found");
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ _bt_convert_addr_type_to_string(address, device_address->addr);
+
+ profile_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
+ NULL, BT_BLUEZ_NAME,
+ adapter_path, BT_NETWORK_SERVER_INTERFACE, NULL, NULL);
+ g_free(adapter_path);
+ retv_if(profile_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
+ func_data = g_malloc0(sizeof(bt_function_data_t));
+
+ func_data->address = g_strdup(address);
+ func_data->req_id = request_id;
+
+ g_dbus_proxy_call(profile_proxy, "Disconnect",
+ g_variant_new("(s)", address),
+ G_DBUS_CALL_FLAGS_NONE,
+ BT_MAX_DBUS_TIMEOUT,
+ NULL,
+ (GAsyncReadyCallback)__bt_network_disconnect_cb,
+ func_data);
+
+ return BLUETOOTH_ERROR_NONE;
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <glib.h>
+#include <dlog.h>
+#include <string.h>
+#include <gio/gio.h>
+
+#include "bluetooth-api.h"
+#include "bt-service-common.h"
+#include "bt-service-event.h"
+#include "bt-service-util.h"
+#include "bt-service-obex-agent.h"
+#include "bt-service-obex-server.h"
+//#include "marshal.h"
+
+static GDBusConnection *conn = NULL;
+static GDBusConnection *auth_reply_conn = NULL;
+static GSList *obex_agent_list = NULL;
+
+typedef struct {
+ gchar *name;
+ gchar *path;
+
+ int openobex_id;
+ int obex_agent_id;
+ int obex_reply_id;
+
+ /* callback data */
+ gpointer authorize_data;
+ gpointer release_data;
+ gpointer request_data;
+ gpointer progress_data;
+ gpointer complete_data;
+ gpointer error_data;
+
+ /* callback function */
+ bt_obex_authorize_cb authorize_cb;
+ bt_obex_release_cb release_cb;
+ bt_obex_request_cb request_cb;
+ bt_obex_progress_cb progress_cb;
+ bt_obex_complete_cb complete_cb;
+ bt_obex_error_cb error_cb;
+} bt_obex_agent_info;
+
+static void __new_connection_method(GDBusConnection *connection,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *method_name,
+ GVariant *parameters,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data);
+static const GDBusInterfaceVTable method_table = {
+ __new_connection_method,
+ NULL,
+ NULL,
+};
+
+static const gchar obex_service_agent_xml1[] =
+"<node name='/'>"
+" <interface name='org.openobex.Agent'>"
+" <method name='Request'>"
+" <annotation name='org.freedesktop.DBus.GLib.Async' value=''/>"
+" <arg type='o' name='transfer'/>"
+" <arg type='s' name='name' direction='out'/>"
+" </method>"
+" <method name='Progress'>"
+" <annotation name='org.freedesktop.DBus.GLib.Async' value=''/>"
+" <arg type='o' name='transfer'/>"
+" <arg type='t' name='transferred'/>"
+" </method>"
+" <method name='Complete'>"
+" <annotation name='org.freedesktop.DBus.GLib.Async' value=''/>"
+" <arg type='o' name='transfer'/>"
+" </method>"
+" <method name='Release'>"
+" <annotation name='org.freedesktop.DBus.GLib.Async' value=''/>"
+" </method>"
+" <method name='Error'>"
+" <annotation name='org.freedesktop.DBus.GLib.Async' value=''/>"
+" <arg type='o' name='transfer'/>"
+" <arg type='s' name='message'/>"
+" </method>"
+" <method name='Authorize'>"
+" <annotation name='org.freedesktop.DBus.GLib.Async' value=''/>"
+" <arg type='o' name='objpath'/>"
+" <arg type='s' name='bdaddress'/>"
+" <arg type='s' name='name'/>"
+" <arg type='s' name='type'/>"
+" <arg type='i' name='length'/>"
+" <arg type='i' name='time'/>"
+" <arg type='s' name='filepath' direction='out'/>"
+" </method>"
+" </interface>"
+"</node>";
+
+static const gchar obex_service_agent_xml2[] =
+"<node name='/'>"
+" <interface name='org.bluez.obex.Agent1'>"
+" <method name='AuthorizePush'>"
+" <annotation name='org.freedesktop.DBus.GLib.Async' value=''/>"
+" <arg type='o' name='objpath'/>"
+" <arg type='s' name='filepath' direction='out'/>"
+" </method>"
+" </interface>"
+"</node>";
+
+static const gchar obex_service_reply_xml3[] =
+"<node name='/'>"
+" <interface name='org.bluez.obex.reply'>"
+" <method name='ReplyAuthorize'>"
+" <arg type='u' name='accept' direction='in'/>"
+" </method>"
+" </interface>"
+"</node>";
+
+static bt_obex_agent_info *__find_obex_agent_info(char *path)
+{
+ GSList *l;
+
+ for (l = obex_agent_list; l != NULL; l = l->next) {
+ bt_obex_agent_info *info = l->data;
+
+ if (g_strcmp0(info->path, path) == 0)
+ return info;
+ }
+
+ return NULL;
+}
+
+
+static void __new_connection_method(GDBusConnection *connection,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *method_name,
+ GVariant *parameters,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data)
+{
+ BT_DBG("method_name %s", method_name);
+ if (g_strcmp0(method_name, "AuthorizePush") == 0) {
+ bt_obex_agent_info *info;
+ char *path = NULL;
+ info = __find_obex_agent_info((char *)object_path);
+
+ if (info == NULL)
+ goto fail;
+
+ if (info->authorize_cb == NULL)
+ goto fail;
+
+ g_variant_get(parameters, "(&o)", &path);
+
+ info->authorize_cb(invocation, path,
+ info->authorize_data);
+
+ return;
+ } else if (g_strcmp0(method_name, "Authorize") == 0) {
+ g_dbus_method_invocation_return_value(invocation, NULL);
+ } else if (g_strcmp0(method_name, "Request") == 0) {
+ char *sender;
+ bt_obex_agent_info *info;
+ GDBusProxy *proxy;
+ char *path = NULL;
+ char *name = NULL;
+ GError *err = NULL;
+
+ info = __find_obex_agent_info((char *)object_path);
+
+ if (info == NULL)
+ goto fail;
+
+ if (conn == NULL)
+ goto fail;
+
+ sender = (char *)g_dbus_method_invocation_get_sender(invocation);
+
+ if (info->name == NULL) {
+ info->name = sender;
+ } else {
+ if (g_strcmp0(sender, info->name) != 0)
+ goto fail;
+ }
+
+ if (info->request_cb == NULL)
+ goto fail;
+
+ g_variant_get(parameters, "(&o&s)", &path, &name);
+ proxy = g_dbus_proxy_new_sync(conn, G_DBUS_CALL_FLAGS_NONE,
+ NULL,
+ BT_OBEX_SERVICE_NAME,
+ path,
+ BT_OBEX_TRANSFER_INTERFACE,
+ NULL, &err);
+
+ if (err) {
+ BT_ERR("Dbus Err: %s", err->message);
+ g_clear_error(&err);
+ goto fail;
+ }
+
+ info->request_cb(invocation, proxy, info->request_data);
+ g_object_unref(proxy);
+ return;
+
+ } else if (g_strcmp0(method_name, "Progress") == 0) {
+ BT_DBG("+");
+
+ bt_obex_agent_info *info;
+ char *sender;
+ char *path = NULL;
+ gint64 transferred;
+ GDBusProxy *proxy;
+ GError *err = NULL;
+
+ info = __find_obex_agent_info((char *)object_path);
+
+ if (info == NULL)
+ goto fail;
+
+ if (conn == NULL)
+ goto fail;
+
+ sender = (char *)g_dbus_method_invocation_get_sender(invocation);
+
+ if (g_strcmp0(sender, info->name) != 0)
+ goto fail;
+
+ if (info->progress_cb == NULL)
+ goto fail;
+
+ g_variant_get(parameters, "(&ot)", &path, &transferred);
+ proxy = g_dbus_proxy_new_sync(conn, G_DBUS_CALL_FLAGS_NONE,
+ NULL,
+ BT_OBEX_SERVICE_NAME,
+ path,
+ BT_OBEX_TRANSFER_INTERFACE,
+ NULL, &err);
+
+ if (err) {
+ BT_ERR("Dbus Err: %s", err->message);
+ g_clear_error(&err);
+ goto fail;
+ }
+
+ info->progress_cb(invocation, proxy, transferred, info->progress_data);
+
+ g_object_unref(proxy);
+
+ BT_DBG("-");
+
+ return;
+ } else if (g_strcmp0(method_name, "Error") == 0) {
+ bt_obex_agent_info *info;
+ char *sender;
+ GDBusProxy *proxy;
+ char *path, *message;
+ GError *err = NULL;
+
+ info = __find_obex_agent_info((char *)object_path);
+
+ if (info == NULL)
+ goto fail;
+
+ if (conn == NULL)
+ goto fail;
+
+ sender = (char *)g_dbus_method_invocation_get_sender(invocation);
+
+ if (g_strcmp0(sender, info->name) != 0)
+ goto fail;
+
+ if (info->error_cb == NULL)
+ goto fail;
+ g_variant_get(parameters, "(&o&s)", &path, &message);
+ proxy = g_dbus_proxy_new_sync(conn, G_DBUS_CALL_FLAGS_NONE,
+ NULL,
+ BT_OBEX_SERVICE_NAME,
+ path,
+ BT_OBEX_TRANSFER_INTERFACE,
+ NULL, &err);
+ if (err) {
+ BT_ERR("Dbus Err: %s", err->message);
+ g_clear_error(&err);
+ goto fail;
+ }
+ info->error_cb(invocation, proxy, message, info->progress_data);
+
+ g_object_unref(proxy);
+
+ return;
+ } else if (g_strcmp0(method_name, "Complete") == 0) {
+ bt_obex_agent_info *info;
+ char *sender;
+ GDBusProxy *proxy;
+ char *path = NULL;
+ GError *err = NULL;
+
+ info = __find_obex_agent_info((char *)object_path);
+
+ if (info == NULL)
+ goto fail;
+
+ if (conn == NULL)
+ goto fail;
+
+ sender = (char *)g_dbus_method_invocation_get_sender(invocation);
+
+ if (g_strcmp0(sender, info->name) != 0)
+ goto fail;
+
+ if (info->complete_cb == NULL)
+ goto fail;
+
+ g_variant_get(parameters, "(&o)", &path);
+ proxy = g_dbus_proxy_new_sync(conn, G_DBUS_CALL_FLAGS_NONE,
+ NULL,
+ BT_OBEX_SERVICE_NAME,
+ path,
+ BT_OBEX_TRANSFER_INTERFACE,
+ NULL, &err);
+ if (err) {
+ BT_ERR("Dbus Err: %s", err->message);
+ g_clear_error(&err);
+ goto fail;
+ }
+
+ info->complete_cb(invocation, proxy, info->complete_data);
+
+ g_object_unref(proxy);
+
+ return;
+ } else if (g_strcmp0(method_name, "Release") == 0) {
+ bt_obex_agent_info *info;
+ char *sender;
+
+ info = __find_obex_agent_info((char *)object_path);
+
+ if (info == NULL)
+ goto fail;
+
+ sender = (char *)g_dbus_method_invocation_get_sender(invocation);
+
+ if (info->name) {
+ /*In H2 if user denies auth,release will come without request and hence
+ info->name will be NULL */
+ if (g_strcmp0(sender, info->name) != 0)
+ goto fail;
+ }
+
+ if (info->release_cb == NULL)
+ goto fail;
+
+ info->release_cb(invocation, info->release_data);
+
+ return;
+ } else if (g_strcmp0(method_name, "ReplyAuthorize") == 0) {
+ const guint accept;
+
+ g_variant_get(parameters, "(u)", &accept);
+ BT_DBG("Accept: %d", accept);
+
+ if (accept == 0) {
+ BT_DBG("Transfer accepted");
+ _bt_obex_server_reply_accept();
+ } else {
+ BT_ERR("Transfer denied");
+ _bt_obex_server_reject_authorize();
+ }
+ }
+fail:
+ BT_ERR("Fail case");
+ g_dbus_method_invocation_return_value(invocation, NULL);
+}
+
+void _bt_obex_agent_new(char *path)
+{
+ bt_obex_agent_info *info = NULL;
+ GError *error = NULL;
+
+ if (conn == NULL) {
+ conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
+ if (error != NULL) {
+ BT_ERR("Fail to get dbus: %s", error->message);
+ g_error_free(error);
+ return;
+ }
+ auth_reply_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+ if (error != NULL) {
+ BT_ERR("Fail to get dbus: %s", error->message);
+ g_error_free(error);
+ return;
+ }
+ }
+ info = (bt_obex_agent_info *)malloc(sizeof(bt_obex_agent_info));
+ if (info) {
+ memset(info, 0, sizeof(bt_obex_agent_info));
+ info->path = g_strdup(path);
+ obex_agent_list = g_slist_append(obex_agent_list, info);
+ }
+}
+
+void _bt_obex_agent_destroy(char *path)
+{
+ bt_obex_agent_info *info = NULL;
+ info = __find_obex_agent_info(path);
+ if (info == NULL) {
+ BT_ERR("obex agent info not found on path %s", path);
+ return;
+ }
+ obex_agent_list = g_slist_remove(obex_agent_list, info);
+ if (info->path)
+ g_free(info->path);
+ if (info->name)
+ g_free(info->name);
+ if (info->openobex_id)
+ g_dbus_connection_unregister_object(conn,
+ info->openobex_id);
+ if (info->obex_agent_id)
+ g_dbus_connection_unregister_object(conn,
+ info->obex_agent_id);
+ if (info->obex_reply_id)
+ g_dbus_connection_unregister_object(auth_reply_conn,
+ info->obex_reply_id);
+
+ g_free(info);
+}
+gboolean _bt_obex_setup(const char *path)
+{
+ bt_obex_agent_info *info;
+ GDBusProxy *proxy;
+ GDBusNodeInfo *new_conn_node = NULL;
+ GDBusNodeInfo *auth_reply_node = NULL;
+ GError *err = NULL;
+
+ info = __find_obex_agent_info((char *)path);
+
+ retv_if(info == NULL, FALSE);
+
+ proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SESSION,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ BT_OBEX_SERVICE_NAME,
+ BT_OBEX_CLIENT_PATH,
+ BT_OBEX_AGENT_INTERFACE,
+ NULL,
+ &err);
+
+ g_free(info->name);
+
+ if (proxy != NULL) {
+ info->name = g_strdup(g_dbus_proxy_get_name(proxy));
+ g_object_unref(proxy);
+ } else {
+ info->name = NULL;
+ }
+
+ new_conn_node = g_dbus_node_info_new_for_xml(obex_service_agent_xml1, NULL);
+ if (new_conn_node == NULL)
+ return FALSE;
+
+ info->openobex_id = g_dbus_connection_register_object(conn, info->path,
+ new_conn_node->interfaces[0],
+ &method_table,
+ NULL, NULL, &err);
+ g_dbus_node_info_unref(new_conn_node);
+ if (err) {
+ BT_ERR("Dbus Err: %s", err->message);
+ g_clear_error(&err);
+ return FALSE;
+ }
+ if (info->openobex_id == 0)
+ BT_ERR("Error while registering object");
+
+ new_conn_node = g_dbus_node_info_new_for_xml(obex_service_agent_xml2, NULL);
+ if (new_conn_node == NULL)
+ return FALSE;
+
+ info->obex_agent_id = g_dbus_connection_register_object(conn, info->path,
+ new_conn_node->interfaces[0],
+ &method_table,
+ NULL, NULL, &err);
+ g_dbus_node_info_unref(new_conn_node);
+ if (info->obex_agent_id == 0)
+ BT_ERR("Error while registering object");
+ if (err) {
+ BT_ERR("Dbus Err: %s", err->message);
+ g_clear_error(&err);
+ return FALSE;
+ }
+
+ auth_reply_node = g_dbus_node_info_new_for_xml(obex_service_reply_xml3, NULL);
+
+ if (auth_reply_node == NULL) {
+ BT_ERR("Fail to create the node info for xml");
+ return FALSE;
+ }
+
+ info->obex_reply_id = g_dbus_connection_register_object(auth_reply_conn, info->path,
+ auth_reply_node->interfaces[0], &method_table, NULL, NULL, &err);
+ g_dbus_node_info_unref(auth_reply_node);
+ if (info->obex_reply_id == 0)
+ BT_ERR("Error while registering object");
+ if (err) {
+ BT_ERR("Dbus Err: %s", err->message);
+ g_clear_error(&err);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void _bt_obex_set_authorize_cb(char *object_path,
+ bt_obex_authorize_cb func, gpointer data)
+{
+ bt_obex_agent_info *info = __find_obex_agent_info(object_path);;
+ if (info == NULL)
+ return;
+
+ info->authorize_cb = func;
+ info->authorize_data = data;
+}
+
+void _bt_obex_set_release_cb(char *object_path,
+ bt_obex_release_cb func, gpointer data)
+{
+ bt_obex_agent_info *info = __find_obex_agent_info(object_path);;
+ if (info == NULL)
+ return;
+
+ info->release_cb = func;
+ info->release_data = data;
+}
+
+void _bt_obex_set_request_cb(char *object_path,
+ bt_obex_request_cb func, gpointer data)
+{
+ bt_obex_agent_info *info = __find_obex_agent_info(object_path);;
+ if (info == NULL)
+ return;
+
+ info->request_cb = func;
+ info->request_data = data;
+}
+
+void _bt_obex_set_progress_cb(char *object_path,
+ bt_obex_progress_cb func, gpointer data)
+{
+ bt_obex_agent_info *info = __find_obex_agent_info(object_path);;
+ if (info == NULL)
+ return;
+
+ info->progress_cb = func;
+ info->progress_data = data;
+}
+
+void _bt_obex_set_complete_cb(char *object_path,
+ bt_obex_complete_cb func, gpointer data)
+{
+ bt_obex_agent_info *info = __find_obex_agent_info(object_path);;
+ if (info == NULL)
+ return;
+
+ info->complete_cb = func;
+ info->complete_data = data;
+}
+
+void _bt_obex_set_error_cb(char *object_path,
+ bt_obex_error_cb func, gpointer data)
+{
+ bt_obex_agent_info *info = __find_obex_agent_info(object_path);;
+ if (info == NULL)
+ return;
+
+ info->error_cb = func;
+ info->error_data = data;
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <glib.h>
+#include <string.h>
+#include <dlog.h>
+#include <vconf.h>
+#include <vconf-internal-bt-keys.h>
+
+#include "bluetooth-api.h"
+#include "bt-internal-types.h"
+
+#include "bt-service-common.h"
+#include "bt-service-event.h"
+#include "bt-service-main.h"
+#include "bt-service-device.h"
+#include "bt-service-obex-server.h"
+#include "bt-service-agent.h"
+#include "bt-service-pbap.h"
+#include "bt-service-opp-client.h"
+#include "bt-service-map-client.h"
+#include "bt-service-core-adapter.h"
+//#include "bt-service-avrcp-ctrl.h"
+
+#ifdef TIZEN_FEATURE_BT_DPM
+#include "bt-service-dpm.h"
+#endif
+
+#define DBUS_TIMEOUT 20 * 1000 /* 20 Sec */
+static GDBusConnection *manager_conn;
+static GDBusConnection *obexd_conn;
+static GDBusConnection *opc_obexd_conn;
+static GDBusConnection *map_obexd_conn;
+
+static GList *p_cache_list = NULL;
+
+static guint event_id;
+
+static guint session_reinit_timer;
+guint nap_connected_device_count = 0;
+
+typedef struct {
+ bt_remote_dev_info_t *dev_info;
+} bt_cache_info_t;
+
+/**
+ * obexd connection type
+ */
+typedef enum {
+ OBEX_OPP = (1 << 1),
+ OBEX_FTP = (1 << 2),
+ OBEX_BIP = (1 << 3),
+ OBEX_PBAP = (1 << 4),
+ OBEX_IRMC = (1 << 5),
+ OBEX_PCSUITE = (1 << 6),
+ OBEX_SYNCEVOLUTION = (1 << 7),
+ OBEX_MAS = (1 << 8),
+ OBEX_MAP = (1 << 9),
+} bluetooth_obex_connection_type_t;
+
+
+void _bt_handle_property_changed_event(GVariant *msg, const char *object_path);
+void _bt_opc_property_changed_event(GVariant *msg, char *path);
+void _bt_map_property_changed_event(GVariant *msg, const char *path);
+int _bt_register_service_event(GDBusConnection *g_conn, int event_type);
+void _bt_unregister_service_event(GDBusConnection *g_conn, int event_type);
+void _bt_opp_client_event_deinit(void);
+void _bt_map_client_event_deinit(void);
+void _bt_handle_network_client_event(GVariant *msg_iter,
+ const char *path);
+void _bt_map_on_transfer_finished(const char *transfer_object_path, const int error);
+
+static void __bt_free_cache_info(bt_cache_info_t *cache_info)
+{
+ ret_if(cache_info == NULL);
+ _bt_free_device_info(cache_info->dev_info);
+ g_free(cache_info);
+}
+
+
+/* Temp Adapter changes required to make OBEX work for handling device events here ,
+ This code will be removed and moved to OAL Event Handling part .
+*/
+
+static void __bt_get_uuids(GVariant *value, bt_remote_dev_info_t *info)
+{
+ ret_if(value == NULL);
+ ret_if(info == NULL);
+
+ gsize uuid_count = 0;
+
+ info->uuids = g_variant_dup_strv(value, &uuid_count);
+ info->uuid_count = (unsigned int)uuid_count;
+
+ BT_DBG("uuid count : %d", uuid_count);
+}
+
+void _bt_convert_addr_string_to_secure_string(char *addr,
+ const char *address)
+{
+ int len;
+
+ ret_if(address == NULL);
+ ret_if(addr == NULL);
+
+ len = strlen(address);
+ ret_if(len != BT_ADDRESS_STRING_SIZE - 1);
+
+ strncpy(addr, address, len);
+
+ addr[len-1] = 'X';
+ addr[len-2] = 'X';
+
+ return;
+}
+
+bt_status_t _bt_adapter_get_status_for_Obex(void)
+{
+ int value = VCONFKEY_BT_STATUS_OFF;
+
+ /* check VCONFKEY_BT_STATUS */
+ if (vconf_get_int(VCONFKEY_BT_STATUS, &value) != 0) {
+ BT_ERR("fail to get vconf key!");
+ return BLUETOOTH_ADAPTER_DISABLED;
+ }
+
+ return value;
+}
+
+static int __bt_get_owner_info(GVariant *msg, char **name,
+ char **previous, char **current)
+{
+ g_variant_get(msg, "(sss)", name, previous, current);
+ return BLUETOOTH_ERROR_NONE;
+}
+
+static int __bt_get_agent_signal_info(GVariant *msg, char **address,
+ char **name, char **uuid)
+{
+ g_variant_get(msg, "(sss)", address, name, uuid);
+ return BLUETOOTH_ERROR_NONE;
+}
+
+void __bt_set_device_values(gboolean connected, int state)
+{
+ int bt_device_state = VCONFKEY_BT_DEVICE_NONE;
+
+ if (vconf_get_int(VCONFKEY_BT_DEVICE, &bt_device_state) != 0)
+ BT_ERR("vconf_get_int failed");
+
+ if (connected == TRUE)
+ bt_device_state |= state;
+ else if (bt_device_state & state)
+ bt_device_state ^= state;
+
+ if (vconf_set_int(VCONFKEY_BT_DEVICE, bt_device_state) != 0)
+ BT_ERR("vconf_set_int failed");
+}
+
+void __bt_update_remote_cache_devinfo(const char *address, gboolean paired_status)
+{
+ BT_DBG("+");
+
+ ret_if(address == NULL);
+
+ GList * node;
+ bt_cache_info_t *cache_info;
+ bt_remote_dev_info_t *dev_info;
+
+ node = g_list_first(p_cache_list);
+
+ while (node != NULL) {
+ cache_info = (bt_cache_info_t *)node->data;
+
+ if (cache_info == NULL) {
+ node = g_list_next(node);
+ continue;
+ }
+
+ dev_info = cache_info->dev_info;
+ if (strcasecmp(dev_info->address,
+ address) == 0) {
+ BT_DBG("Device Found");
+ if (paired_status == TRUE)
+ cache_info->dev_info->paired = TRUE;
+ else
+ cache_info->dev_info->paired = FALSE;
+ break;
+ }
+ node = g_list_next(node);
+ }
+ BT_DBG("-");
+}
+
+gboolean __bt_handle_is_flight_mode_enabled(void)
+{
+#ifdef TIZEN_FEATURE_FLIGHTMODE_ENABLED
+ int is_flight_mode = 0;
+ int ret = -1;
+ ret = vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE, &is_flight_mode);
+ if (ret != 0)
+ BT_ERR("vconf_get_bool failed");
+
+ return (is_flight_mode == 0) ? FALSE : TRUE;
+#else
+ return FALSE;
+#endif
+}
+
+void _bt_handle_adapter_event(GVariant *msg, const char *member)
+{
+ BT_DBG("+");
+ ret_if(member == NULL);
+
+ if (strcasecmp(member, "DeviceCreated") == 0) {
+ char *object_path = NULL;
+ char *address;
+ ret_if(_bt_is_device_creating() == FALSE);
+
+ /* Bonding from remote device */
+ address = g_malloc0(BT_ADDRESS_STRING_SIZE);
+
+ g_variant_get(msg, "(&o)", &object_path);
+ _bt_convert_device_path_to_address((const char*)object_path, address);
+
+ g_free(address);
+ } else if (strcasecmp(member, "InterfacesRemoved") == 0) {
+ char *object_path = NULL;
+ char *address;
+ bt_cache_info_t *cache_info;
+ bt_remote_dev_info_t *dev_info;
+ GList * node;
+
+ /* Bonding from remote device */
+ address = g_malloc0(BT_ADDRESS_STRING_SIZE);
+
+ g_variant_get(msg, "(&o)", &object_path);
+
+ _bt_convert_device_path_to_address((const char *)object_path, address);
+
+ node = g_list_first(p_cache_list);
+
+ while (node != NULL) {
+ cache_info = (bt_cache_info_t *)node->data;
+
+ if (cache_info == NULL) {
+ node = g_list_next(node);
+ continue;
+ }
+
+ dev_info = cache_info->dev_info;
+ if (strcasecmp(dev_info->address,
+ address) == 0) {
+ p_cache_list = g_list_remove(p_cache_list,
+ cache_info);
+ __bt_free_cache_info(cache_info);
+ break;
+ }
+ node = g_list_next(node);
+ }
+ g_free(address);
+ }else if (strcasecmp(member, BT_HARDWARE_ERROR) == 0) {
+ BT_ERR_C("### Hardware error received from BLUEZ");
+ } else if (strcasecmp(member, BT_TX_TIMEOUT_ERROR) == 0) {
+ BT_ERR_C("### Tx timeout error received from BLUEZ");
+ }
+ BT_DBG("-");
+}
+static void __bt_obex_property_changed_event(GVariant *msg, const char *path)
+{
+ BT_DBG("+");
+
+ GVariantIter value_iter;
+ GVariant *child = NULL, *val = NULL;
+ char *property = NULL;
+ g_variant_iter_init(&value_iter, msg);
+ while ((child = g_variant_iter_next_value(&value_iter))) {
+ g_variant_get(child, "{sv}", &property, &val);
+
+ ret_if(property == NULL);
+
+ BT_DBG("property :%s", property);
+
+ if (strcasecmp(property, "Status") == 0) {
+ char *status;
+ g_variant_get(val, "s", &status);
+
+ if (strcasecmp(status, "active") == 0) {
+ _bt_obex_transfer_started(path);
+ } else if (strcasecmp(status, "complete") == 0) {
+ _bt_obex_transfer_completed(path, TRUE);
+ _bt_pbap_obex_transfer_completed(path, TRUE);
+ } else if (strcasecmp(status, "error") == 0) {
+ _bt_obex_transfer_completed(path, FALSE);
+ _bt_pbap_obex_transfer_completed(path, FALSE);
+ }
+ g_free(status);
+ } else if (strcasecmp(property, "Transferred") == 0) {
+ guint64 transferred = 0;
+ /* As Transferred is expected guint64 so change int to guint64 and
+ * eariler transferred is static because of it can overwrite data
+ * on present on opc_obex_conn or obexd_conn as these are
+ * static memory are in sequential */
+ g_variant_get(val, "t", &transferred);
+
+ _bt_obex_transfer_progress(path, transferred);
+ }
+ /* TODO: MAP, "Complete"? see above */
+ g_free(property);
+ g_variant_unref(val);
+ g_variant_unref(child);
+ }
+ BT_DBG("-");
+}
+
+static void __bt_device_remote_connected_properties(
+ bt_remote_dev_info_t *remote_dev_info,
+ char *address, gboolean connected)
+{
+ int result = BLUETOOTH_ERROR_NONE;
+ int i;
+ GVariant *param = NULL;
+ BT_DBG("+");
+
+ if (remote_dev_info->uuid_count > 0) {
+ for (i = 0; i < remote_dev_info->uuid_count; i++) {
+ char *uuid = remote_dev_info->uuids[i];
+ if (strcasecmp(uuid, HID_UUID) == 0) {
+ int event = BLUETOOTH_EVENT_NONE;
+
+ event = (connected == TRUE) ?
+ BLUETOOTH_HID_CONNECTED :
+ BLUETOOTH_HID_DISCONNECTED;
+ param = g_variant_new("(is)", result,
+ address);
+ _bt_send_event(BT_HID_EVENT, event,
+ param);
+ break;
+ }
+ }
+ }
+
+ BT_DBG("-");
+}
+
+bt_remote_dev_info_t *_bt_get_remote_device_info_by_object_path(
+ const char *object_path)
+{
+ bt_remote_dev_info_t *dev_info;
+ GDBusProxy *adapter_proxy;
+ GDBusProxy *device_proxy;
+ GVariant *value;
+ GVariant *tmp_value;
+ gchar *name;
+ gchar * address;
+ GDBusConnection *conn;
+ GError *error = NULL;
+ GVariant *result = NULL;
+ GVariantIter *value_iter;
+ guint8 m_value;
+ int i = 0;
+
+ adapter_proxy = _bt_get_adapter_proxy();
+ retv_if(adapter_proxy == NULL, NULL);
+
+ retv_if(object_path == NULL, NULL);
+
+ conn = _bt_gdbus_get_system_gconn();
+ if (conn == NULL) {
+ BT_ERR("conn == NULL");
+ return NULL;
+ }
+
+ device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
+ NULL, BT_BLUEZ_NAME, object_path,
+ BT_PROPERTIES_INTERFACE, NULL, NULL);
+
+ retv_if(device_proxy == NULL, NULL);
+
+ result = g_dbus_proxy_call_sync(device_proxy, "GetAll",
+ g_variant_new("(s)", BT_DEVICE_INTERFACE),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+
+ g_object_unref(device_proxy);
+
+ dev_info = g_malloc0(sizeof(bt_remote_dev_info_t));
+
+ if (result != NULL) {
+ g_variant_get(result , "(@a{sv})", &value);
+ g_variant_unref(result);
+
+ tmp_value = g_variant_lookup_value(value, "Alias", G_VARIANT_TYPE_STRING);
+
+ g_variant_get(tmp_value, "s", &name);
+ g_variant_unref(tmp_value);
+ if (name != NULL)
+ DBG_SECURE("Alias Name [%s]", name);
+ else {
+ tmp_value = g_variant_lookup_value(value, "Name", G_VARIANT_TYPE_STRING);
+ g_variant_get(tmp_value, "s", &name);
+ g_variant_unref(tmp_value);
+ }
+
+ tmp_value = g_variant_lookup_value(value, "IsAliasSet", G_VARIANT_TYPE_BOOLEAN);
+ if (tmp_value) {
+ dev_info->is_alias_set = g_variant_get_boolean(tmp_value);
+ g_variant_unref(tmp_value);
+ } else {
+ dev_info->is_alias_set = FALSE;
+ }
+ BT_DBG("IsAliasSet: [%s]", dev_info->is_alias_set ? "TRUE" : "FALSE");
+
+ tmp_value = g_variant_lookup_value(value, "Class", G_VARIANT_TYPE_UINT32);
+ if (tmp_value) {
+ dev_info->class = g_variant_get_uint32(tmp_value);
+ g_variant_unref(tmp_value);
+ } else
+ dev_info->class = 0;
+
+ tmp_value = g_variant_lookup_value(value, "Connected", G_VARIANT_TYPE_BYTE);
+ if (tmp_value) {
+ dev_info->connected = g_variant_get_byte(tmp_value);
+ g_variant_unref(tmp_value);
+ } else
+ dev_info->connected = BLUETOOTH_CONNECTED_LINK_NONE;
+ BT_DBG("connected link : %d", dev_info->connected);
+
+ tmp_value = g_variant_lookup_value(value, "Trusted", G_VARIANT_TYPE_BOOLEAN);
+ if (tmp_value) {
+ dev_info->trust = g_variant_get_boolean(tmp_value);
+ g_variant_unref(tmp_value);
+ } else
+ dev_info->trust = FALSE;
+
+ tmp_value = g_variant_lookup_value(value, "Paired", G_VARIANT_TYPE_BOOLEAN);
+ if (tmp_value) {
+ dev_info->paired = g_variant_get_boolean(tmp_value);
+ g_variant_unref(tmp_value);
+ } else
+ dev_info->paired = FALSE;
+
+ tmp_value = g_variant_lookup_value(value, "RSSI", G_VARIANT_TYPE_INT16);
+ if (tmp_value) {
+ dev_info->rssi = g_variant_get_int16(tmp_value);
+ g_variant_unref(tmp_value);
+ } else
+ dev_info->rssi = 0;
+
+ tmp_value = g_variant_lookup_value(value, "LastAddrType", G_VARIANT_TYPE_BYTE);
+ if (tmp_value) {
+ dev_info->addr_type = g_variant_get_byte(tmp_value);
+ g_variant_unref(tmp_value);
+ } else
+ dev_info->addr_type = 0;
+
+ tmp_value = g_variant_lookup_value(value, "UUIDs", G_VARIANT_TYPE_STRING_ARRAY);
+ if (tmp_value) {
+ __bt_get_uuids(tmp_value, dev_info);
+ g_variant_unref(tmp_value);
+ }
+
+ tmp_value = g_variant_lookup_value(value, "ManufacturerDataLen", G_VARIANT_TYPE_UINT16);
+ if (tmp_value) {
+ dev_info->manufacturer_data_len = g_variant_get_uint16(tmp_value);
+ if (dev_info->manufacturer_data_len > BLUETOOTH_MANUFACTURER_DATA_LENGTH_MAX) {
+ BT_ERR("manufacturer_data_len is too long(len = %d)", dev_info->manufacturer_data_len);
+ dev_info->manufacturer_data_len = BLUETOOTH_MANUFACTURER_DATA_LENGTH_MAX;
+ }
+ g_variant_unref(tmp_value);
+ } else
+ dev_info->manufacturer_data_len = 0;
+
+ tmp_value = g_variant_lookup_value(value, "ManufacturerData", G_VARIANT_TYPE_ARRAY);
+ if (tmp_value) {
+ if ((dev_info->manufacturer_data_len == 0) ||
+ dev_info->manufacturer_data_len != g_variant_get_size(tmp_value)) {
+ BT_ERR("manufacturer data length doesn't match");
+ dev_info->manufacturer_data_len = 0;
+ dev_info->manufacturer_data = NULL;
+ } else {
+ dev_info->manufacturer_data = g_malloc0(dev_info->manufacturer_data_len);
+ g_variant_get(tmp_value, "ay", &value_iter);
+ while (g_variant_iter_loop(value_iter, "y", &m_value))
+ dev_info->manufacturer_data[i++] = m_value;
+ }
+ g_variant_unref(tmp_value);
+ } else {
+ BT_INFO("manufacture data is not a G_VARIANT_TYPE_ARRAY ");
+ dev_info->manufacturer_data_len = 0;
+ dev_info->manufacturer_data = NULL;
+ }
+
+ tmp_value = g_variant_lookup_value(value, "Address", G_VARIANT_TYPE_STRING);
+ g_variant_get(tmp_value, "s", &address);
+ g_variant_unref(tmp_value);
+
+ dev_info->address = g_strdup(address);
+ dev_info->name = g_strdup(name);
+ g_free(name);
+ g_variant_unref(value);
+ } else {
+ BT_ERR("result is NULL\n");
+ g_free(dev_info);
+ dev_info = NULL;
+ }
+
+ return dev_info;
+}
+
+
+static void __bt_device_property_changed_event(GVariant *msg, const char *path)
+{
+ BT_DBG("+");
+
+ int event;
+ int result = BLUETOOTH_ERROR_NONE;
+ GVariantIter value_iter;
+ GVariant *val;
+ char *property = NULL;
+ char *address;
+ GVariant *param = NULL;
+ bt_remote_dev_info_t *remote_dev_info;
+ g_variant_iter_init(&value_iter, msg);
+#ifdef TIZEN_FEATURE_BT_DPM
+ int desktop_state = DPM_BT_ERROR;
+#endif
+ while ((g_variant_iter_loop(&value_iter, "{sv}", &property, &val))) {
+ BT_DBG("Property %s", property);
+ if (strcasecmp(property, "Connected") == 0) {
+ guint connected = 0;
+
+ g_variant_get(val, "i", &connected);
+
+ event = (connected != BLUETOOTH_CONNECTED_LINK_NONE) ?
+ BLUETOOTH_EVENT_DEVICE_CONNECTED :
+ BLUETOOTH_EVENT_DEVICE_DISCONNECTED;
+
+ address = g_malloc0(BT_ADDRESS_STRING_SIZE);
+
+ _bt_convert_device_path_to_address(path, address);
+
+ BT_DBG("connected: %d", connected);
+ BT_DBG("address: %s", address);
+
+ remote_dev_info = _bt_get_remote_device_info_by_object_path(path);
+
+ if (remote_dev_info != NULL) {
+ __bt_device_remote_connected_properties(
+ remote_dev_info, address,
+ connected != BLUETOOTH_CONNECTED_LINK_NONE ?
+ TRUE : FALSE);
+ _bt_free_device_info(remote_dev_info);
+ }
+ param = g_variant_new("(is)", result, address);
+ /* Send event to application */
+ _bt_send_event(BT_DEVICE_EVENT,
+ event,
+ param);
+ g_free(address);
+ } else if (strcasecmp(property, "RSSI") == 0) {
+ bt_remote_dev_info_t *remote_dev_info;
+
+ address = g_malloc0(BT_ADDRESS_STRING_SIZE);
+
+ _bt_convert_device_path_to_address(path, address);
+ BT_DBG("address: %s", address);
+
+ g_free(address);
+
+ remote_dev_info = _bt_get_remote_device_info_by_object_path(path);
+ if (remote_dev_info == NULL) {
+ g_free(property);
+ g_variant_unref(val);
+ return;
+ }
+ BT_DBG("Address type %d", remote_dev_info->addr_type);
+
+ if (remote_dev_info->addr_type == 0) {
+ BT_DBG("Name %s", remote_dev_info->name);
+
+#ifdef TIZEN_FEATURE_BT_DPM
+ _bt_dpm_get_bluetooth_desktop_connectivity_state(&desktop_state);
+ if (desktop_state == DPM_RESTRICTED) {
+ bluetooth_device_class_t device_class;
+ _bt_divide_device_class(&device_class, remote_dev_info->class);
+
+ if (device_class.major_class ==
+ BLUETOOTH_DEVICE_MAJOR_CLASS_COMPUTER) {
+ _bt_free_device_info(remote_dev_info);
+ g_free(property);
+ g_variant_unref(val);
+ return;
+ }
+ }
+#endif
+
+ GVariant *uuids = NULL;
+ GVariantBuilder *builder = NULL;
+ int i = 0;
+ builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
+ for (i = 0; i < remote_dev_info->uuid_count; i++) {
+ g_variant_builder_add(builder, "s",
+ remote_dev_info->uuids[i]);
+ }
+ uuids = g_variant_new("as", builder);
+ g_variant_builder_unref(builder);
+ GVariant *manufacturer_data = NULL;
+ manufacturer_data = g_variant_new_from_data(G_VARIANT_TYPE_BYTESTRING,
+ remote_dev_info->manufacturer_data,
+ remote_dev_info->manufacturer_data_len,
+ TRUE,
+ NULL, NULL);
+ param = g_variant_new("(isunsbub@asn@ay)", result,
+ remote_dev_info->address,
+ remote_dev_info->class,
+ remote_dev_info->rssi,
+ remote_dev_info->name,
+ remote_dev_info->paired,
+ remote_dev_info->connected,
+ remote_dev_info->trust,
+ uuids,
+ remote_dev_info->manufacturer_data_len,
+ manufacturer_data);
+
+ _bt_send_event(BT_ADAPTER_EVENT,
+ BLUETOOTH_EVENT_REMOTE_DEVICE_FOUND,
+ param);
+ }
+ _bt_free_device_info(remote_dev_info);
+ } else if (strcasecmp(property, "GattConnected") == 0) {
+ gboolean gatt_connected = FALSE;
+
+ g_variant_get(val, "b", &gatt_connected);
+
+ event = gatt_connected ? BLUETOOTH_EVENT_GATT_CONNECTED :
+ BLUETOOTH_EVENT_GATT_DISCONNECTED;
+
+ address = g_malloc0(BT_ADDRESS_STRING_SIZE);
+
+ _bt_convert_device_path_to_address(path, address);
+
+ BT_DBG("gatt_connected: %d", gatt_connected);
+ BT_DBG("address: %s", address);
+ param = g_variant_new("(is)", result, address);
+ /* Send event to application */
+ _bt_send_event(BT_DEVICE_EVENT,
+ event,
+ param);
+ g_free(address);
+ } else if (strcasecmp(property, "Paired") == 0) {
+ gboolean paired = FALSE;
+ bt_remote_dev_info_t *remote_dev_info;
+ g_variant_get(val, "b", &paired);
+ _bt_agent_set_canceled(FALSE);
+ /* BlueZ sends paired signal for each paired device */
+ /* during activation, We should ignore this, otherwise*/
+ /* application thinks that a new device got paired */
+ if (_bt_adapter_get_status_for_Obex() != BT_ACTIVATED) {
+ BT_DBG("BT is not activated, so ignore this");
+ g_free(property);
+ g_variant_unref(val);
+ return;
+ }
+
+ address = g_malloc0(BT_ADDRESS_STRING_SIZE);
+
+ _bt_convert_device_path_to_address(path, address);
+
+ remote_dev_info = _bt_get_remote_device_info_by_object_path(path);
+ if (remote_dev_info == NULL) {
+ g_free(property);
+ g_variant_unref(val);
+ g_free(address);
+ return;
+ }
+
+ if (paired == FALSE) {
+ BT_INFO("Unpaired: %s", address);
+ __bt_update_remote_cache_devinfo(address, FALSE);
+ param = g_variant_new("(is)", result, address);
+ _bt_send_event(BT_ADAPTER_EVENT,
+ BLUETOOTH_EVENT_BONDED_DEVICE_REMOVED,
+ param);
+#ifdef TIZEN_BT_A2DP_SINK_AUTO_CONNECT
+ {
+ char *last_connected = NULL;
+ last_connected = vconf_get_str(BT_LAST_CONNECTED_DEVICE);
+ if (!g_strcmp0(address, last_connected))
+ _bt_audio_set_auto_connect_device_addr("");
+ if (last_connected)
+ free(last_connected);
+ }
+#endif
+ } else {
+ char secure_addr[BT_ADDRESS_STRING_SIZE] = { 0 };
+
+ _bt_convert_addr_string_to_secure_string(secure_addr, address);
+ BT_INFO("### Paired: %s", secure_addr);
+ __bt_update_remote_cache_devinfo(address, TRUE);
+
+ if (_bt_is_device_creating() == TRUE) {
+ BT_DBG("Try to Pair by me");
+ _bt_free_device_info(remote_dev_info);
+ g_free(address);
+ g_free(property);
+ g_variant_unref(val);
+ return;
+ }
+ GVariant *uuids = NULL;
+ GVariantBuilder *builder = NULL;
+ int i = 0;
+ builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
+ for (i = 0; i < remote_dev_info->uuid_count; i++) {
+ g_variant_builder_add(builder, "s",
+ remote_dev_info->uuids[i]);
+ }
+ uuids = g_variant_new("as", builder);
+ g_variant_builder_unref(builder);
+ GVariant *manufacturer_data = NULL;
+ manufacturer_data = g_variant_new_from_data(G_VARIANT_TYPE_BYTESTRING,
+ remote_dev_info->manufacturer_data,
+ remote_dev_info->manufacturer_data_len,
+ TRUE,
+ NULL, NULL);
+
+ param = g_variant_new("(isunsbub@asn@ay)", result,
+ address, remote_dev_info->class,
+ remote_dev_info->rssi,
+ remote_dev_info->name,
+ remote_dev_info->paired,
+ remote_dev_info->connected,
+ remote_dev_info->trust,
+ uuids,
+ remote_dev_info->manufacturer_data_len,
+ manufacturer_data);
+ _bt_send_event(BT_ADAPTER_EVENT,
+ BLUETOOTH_EVENT_BONDING_FINISHED,
+ param);
+ }
+ _bt_free_device_info(remote_dev_info);
+ g_free(address);
+ } else if (strcasecmp(property, "LegacyPaired") == 0) {
+ gboolean paired = FALSE;
+ bt_remote_dev_info_t *remote_dev_info;
+ unsigned char auth_info[5] = {0, };
+
+ if (_bt_adapter_get_status_for_Obex() != BT_ACTIVATED) {
+ BT_DBG("BT is not activated, so ignore this");
+ g_free(property);
+ g_variant_unref(val);
+ return;
+ }
+
+ g_variant_get(val, "b", &paired);
+ address = g_malloc0(BT_ADDRESS_STRING_SIZE);
+ BT_DBG("LegacyPaired: %d", paired);
+ _bt_convert_device_path_to_address(path, address);
+
+ remote_dev_info = _bt_get_remote_device_info_by_object_path(path);
+ if (remote_dev_info == NULL) {
+ g_free(address);
+ g_free(property);
+ g_variant_unref(val);
+ return;
+ }
+ if (remote_dev_info->is_alias_set == FALSE) {
+ /*minimum Size of the samsung specific manufacturer data is greater than 30 */
+ if ((remote_dev_info->manufacturer_data_len > 30) &&
+ (remote_dev_info->manufacturer_data[0] == 0x00) &&
+ (remote_dev_info->manufacturer_data[1] == 0x75)) {
+
+ /* 2 samsung (0x00 0x75) + 1 (control and version) + 1 (service ID) +
+ 1 (discovery version) + 1 (associated service ID)
+ 2 (Proxamity and locality) + 2 (Device type and icon) = 10 */
+
+ memcpy(auth_info, &(remote_dev_info->manufacturer_data[10]), 5);
+ }
+ }
+
+ BT_DBG("LegacyPairing Failed with %s. Show Error Popup", remote_dev_info->name);
+ if (headed_plugin_info->plugin_headed_enabled)
+ headed_plugin_info->headed_plugin->bt_launch_system_popup(BT_AGENT_EVENT_LEGACY_PAIR_FAILED_FROM_REMOTE,
+ remote_dev_info->name, auth_info, NULL, NULL, NULL);
+
+ _bt_free_device_info(remote_dev_info);
+ g_free(address);
+ } else if (strcasecmp(property, "Trusted") == 0) {
+ gboolean trusted = FALSE;
+
+ g_variant_get(val, "b", &trusted);
+
+ event = trusted ? BLUETOOTH_EVENT_DEVICE_AUTHORIZED :
+ BLUETOOTH_EVENT_DEVICE_UNAUTHORIZED;
+
+ address = g_malloc0(BT_ADDRESS_STRING_SIZE);
+
+ _bt_convert_device_path_to_address(path, address);
+
+ BT_DBG("trusted: %d", trusted);
+ BT_DBG("address: %s", address);
+ param = g_variant_new("(is)", result, address);
+ /* Send event to application */
+ _bt_send_event(BT_DEVICE_EVENT,
+ event,
+ param);
+ g_free(address);
+ } else if (strcasecmp(property, "TrustedProfiles") == 0) {
+ int trusted = 0;
+
+ g_variant_get(val, "u", &trusted);
+
+ address = g_malloc0(BT_ADDRESS_STRING_SIZE);
+ _bt_convert_device_path_to_address(path, address);
+
+ BT_DBG("Address: %s, TrustedProfiles: %d", address, trusted);
+ _bt_send_event(BT_DEVICE_EVENT,
+ BLUETOOTH_EVENT_SUPPORTED_PROFILE_TRUSTED,
+ g_variant_new("(isi)", result, address, trusted));
+ g_free(address);
+ } else if (strcasecmp(property, "IpspConnected") == 0) {
+ gboolean connected = FALSE;
+
+ g_variant_get(val, "b", &connected);
+
+
+ event = connected ? BLUETOOTH_EVENT_IPSP_CONNECTED :
+ BLUETOOTH_EVENT_IPSP_DISCONNECTED;
+
+ address = g_malloc0(BT_ADDRESS_STRING_SIZE);
+
+ _bt_convert_device_path_to_address(path, address);
+
+ BT_DBG("Ipspconnected: %d", connected);
+ BT_DBG("address: %s", address);
+ param = g_variant_new("(is)", result, address);
+
+ /* Send event to application */
+ _bt_send_event(BT_DEVICE_EVENT,
+ event,
+ param);
+ g_free(address);
+ } else if (strcasecmp(property, "IpspBtInterfaceInfo") == 0) {
+ char *ifname = NULL;
+
+ g_variant_get(val, "s", &ifname);
+
+ address = g_malloc0(BT_ADDRESS_STRING_SIZE);
+
+ _bt_convert_device_path_to_address(path, address);
+
+ BT_DBG("Ipsp BT Interface Name: %s", ifname);
+ BT_DBG("address: %s", address);
+ param = g_variant_new("(iss)", result, address, ifname);
+
+ /* Send event to application */
+ _bt_send_event(BT_DEVICE_EVENT,
+ BLUETOOTH_EVENT_IPSP_INTERFACE_INFO,
+ param);
+ g_free(address);
+ }
+ }
+ BT_DBG("-");
+}
+
+
+void _bt_handle_property_changed_event(GVariant *msg, const char *object_path)
+{
+ char *interface_name = NULL;
+ GVariant *val = NULL;
+
+ g_variant_get(msg, "(&s@a{sv}@as)", &interface_name, &val, NULL);
+ BT_DBG("_bt_handle_property_changed_event");
+
+ if (strcasecmp(interface_name, BT_OBEX_TRANSFER_INTERFACE) == 0) {
+ BT_DBG("BT_OBEX_TRANSFER_INTERFACE");
+ __bt_obex_property_changed_event(val,
+ object_path);
+ } else if (strcasecmp(interface_name, BT_DEVICE_INTERFACE) == 0) {
+ __bt_device_property_changed_event(val, object_path);
+ }
+ g_variant_unref(val);
+}
+
+void __bt_opc_property_changed_event(GVariant *msg,
+ const char *path)
+{
+ GVariantIter value_iter;
+ char *property = NULL;
+ GVariant *val = NULL;
+ GVariant *child = NULL;
+
+ g_variant_iter_init(&value_iter, msg);
+ if ((child = g_variant_iter_next_value(&value_iter))) {
+ g_variant_get(child, "{sv}", &property, &val);
+ ret_if(property == NULL);
+
+ if (strcasecmp(property, "Status") == 0) {
+ char *status = NULL;
+ g_variant_get(val, "s", &status);
+ BT_DBG("Status is %s", status);
+
+ if (strcasecmp(status, "active") == 0)
+ _bt_obex_client_started(path);
+ else if (strcasecmp(status, "complete") == 0)
+ _bt_obex_client_completed(path, TRUE);
+ else if (strcasecmp(status, "error") == 0)
+ _bt_obex_client_completed(path, FALSE);
+
+ g_free(status);
+ } else if (strcasecmp(property, "Transferred") == 0) {
+ guint64 transferred = 0;
+ g_variant_get(val, "t", &transferred);
+
+ _bt_obex_client_progress(path, transferred);
+ } else {
+ BT_DBG("property : [%s]", property);
+ }
+ g_free(property);
+ g_variant_unref(child);
+ g_variant_unref(val);
+ }
+}
+
+void _bt_opc_property_changed_event(GVariant *msg, char *path)
+{
+ char *interface_name = NULL;
+ GVariant *value = NULL;
+ g_variant_get(msg, "(&s@a{sv}@as)", &interface_name, &value, NULL);
+ BT_INFO("interface_name = %s", interface_name);
+ if (strcasecmp(interface_name, BT_OBEX_TRANSFER_INTERFACE) == 0) {
+ __bt_opc_property_changed_event(value,
+ path);
+ } else {
+ BT_DBG("interface_name : [%s]", interface_name);
+ }
+ g_variant_unref(value);
+}
+
+
+void __bt_map_property_changed_event(GVariant *msg,
+ const char *path)
+{
+ BT_DBG("Entered");
+ GVariantIter value_iter;
+ char *property = NULL;
+ GVariant *val = NULL;
+ GVariant *child = NULL;
+
+ g_variant_iter_init(&value_iter, msg);
+ while ((child = g_variant_iter_next_value(&value_iter))) {
+ g_variant_get(child, "{sv}", &property, &val);
+ ret_if(property == NULL);
+
+ if (strcasecmp(property, "Status") == 0) {
+ char *status = NULL;
+ g_variant_get(val, "s", &status);
+ BT_DBG("Status is %s", status);
+
+ if (strcasecmp(status, "active") == 0) {
+ BT_DBG("EVENT : STARTED");
+ // currently doing nothing
+ } else if (strcasecmp(status, "complete") == 0) {
+ BT_DBG("EVENT : COMPLETED");
+ _bt_map_on_transfer_finished(path, BLUETOOTH_ERROR_NONE);
+ } else if (strcasecmp(status, "error") == 0) {
+ BT_DBG("EVENT : FAILED");
+ _bt_map_on_transfer_finished(path, BLUETOOTH_ERROR_INTERNAL);
+ }
+ g_free(status);
+ } else if (strcasecmp(property, "Transferred") == 0) {
+ guint64 transferred = 0;
+ g_variant_get(val, "t", &transferred);
+
+ BT_DBG("EVENT : PROGRESS CALLBACK");
+ // currently doing nothing - progress callback type is not used
+ } else {
+ BT_DBG("OTHER EVENT : property : [%s]", property);
+ }
+ g_free(property);
+ g_variant_unref(child);
+ g_variant_unref(val);
+ }
+}
+
+void _bt_map_property_changed_event(GVariant *msg, const char *path)
+{
+ BT_DBG("Entered _bt_map_property_changed_event");
+ char *interface_name = NULL;
+ GVariant *value = NULL;
+ g_variant_get(msg, "(&s@a{sv}@as)", &interface_name, &value, NULL);
+ BT_INFO("interface_name = %s", interface_name);
+ if (strcasecmp(interface_name, BT_OBEX_TRANSFER_INTERFACE) == 0) {
+ __bt_map_property_changed_event(value,
+ path);
+ } else {
+ BT_DBG("interface_name : [%s]", interface_name);
+ }
+ g_variant_unref(value);
+}
+
+void _bt_handle_network_server_event(GVariant *msg, const char *member)
+{
+ int result = BLUETOOTH_ERROR_NONE;
+ char *address = NULL;
+ char *device = NULL;
+ GVariant *param = NULL;
+ ret_if(member == NULL);
+ if (strcasecmp(member, "PeerConnected") == 0) {
+ g_variant_get(msg, "(ss)", &device, &address);
+
+ __bt_set_device_values(TRUE,
+ VCONFKEY_BT_DEVICE_PAN_CONNECTED);
+ param = g_variant_new("(iss)", result, device, address);
+ _bt_send_event(BT_NETWORK_EVENT, BLUETOOTH_EVENT_NETWORK_SERVER_CONNECTED,
+ param);
+ g_free(device);
+ g_free(address);
+ nap_connected_device_count++;
+ } else if (strcasecmp(member, "PeerDisconnected") == 0) {
+ g_variant_get(msg, "(ss)", &device, &address);
+ nap_connected_device_count--;
+ if (nap_connected_device_count == 0)
+ __bt_set_device_values(FALSE,
+ VCONFKEY_BT_DEVICE_PAN_CONNECTED);
+ param = g_variant_new("(iss)", result, device, address);
+ _bt_send_event(BT_NETWORK_EVENT, BLUETOOTH_EVENT_NETWORK_SERVER_DISCONNECTED,
+ param);
+ g_free(device);
+ g_free(address);
+ }
+}
+
+void _bt_handle_network_client_event(GVariant *msg,
+ const char *path)
+{
+ BT_DBG("+");
+
+ int result = BLUETOOTH_ERROR_NONE;
+ gboolean property_flag = FALSE;
+ char *property = NULL;
+ GVariant *val = NULL;
+ GVariantIter value_iter;
+ GVariant *param = NULL;
+ g_variant_iter_init(&value_iter, msg);
+ while ((g_variant_iter_loop(&value_iter, "{sv}", &property, &val))) {
+ if (strcasecmp(property, "Connected") == 0) {
+ int event = BLUETOOTH_EVENT_NONE;
+ char *address;
+
+ g_variant_get(val, "b", &property_flag);
+ address = g_malloc0(BT_ADDRESS_STRING_SIZE);
+
+ _bt_convert_device_path_to_address(path, address);
+
+ BT_DBG("property_flag %d", property_flag);
+ if (property_flag == TRUE) {
+ event = BLUETOOTH_EVENT_NETWORK_CONNECTED;
+ nap_connected_device_count++;
+ __bt_set_device_values(TRUE,
+ VCONFKEY_BT_DEVICE_PAN_CONNECTED);
+ } else {
+ event = BLUETOOTH_EVENT_NETWORK_DISCONNECTED;
+ nap_connected_device_count--;
+ if (nap_connected_device_count == 0)
+ __bt_set_device_values(FALSE,
+ VCONFKEY_BT_DEVICE_PAN_CONNECTED);
+ }
+ param = g_variant_new("(is)", result, address);
+ _bt_send_event(BT_NETWORK_EVENT, event,
+ param);
+
+ g_free(address);
+ }
+ }
+ BT_DBG("-");
+}
+
+void _bt_handle_agent_event(GVariant *msg, const char *member)
+{
+ int result = BLUETOOTH_ERROR_NONE;
+ char *address = NULL;
+ char *name = NULL;
+ char *uuid = NULL;
+ GVariant *param = NULL;
+ ret_if(member == NULL);
+
+ if (strcasecmp(member, "ObexAuthorize") == 0) {
+ __bt_get_agent_signal_info(msg, &address, &name, &uuid);
+ param = g_variant_new("(iss)", result, address, name);
+ _bt_send_event(BT_OPP_SERVER_EVENT,
+ BLUETOOTH_EVENT_OBEX_SERVER_CONNECTION_AUTHORIZE,
+ param);
+ /* TODO: MAP? see above */
+ g_free(address);
+ g_free(name);
+ }
+}
+
+static int __bt_get_object_path(GVariant *msg, char **path)
+{
+ g_variant_get(msg, "(o*)", path, NULL);
+ if (*path == NULL)
+ return BLUETOOTH_ERROR_INTERNAL;
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+
+static void __bt_get_service_list(GVariant *value, bluetooth_device_info_t *dev)
+{
+ int i = 0;
+ char **parts;
+ GVariantIter *iter;
+ gchar *uuid = NULL;
+
+ ret_if(value == NULL);
+ ret_if(dev == NULL);
+
+ dev->service_index = 0;
+
+ g_variant_get(value, "as", &iter);
+ while (g_variant_iter_loop(iter, "s", &uuid)) {
+ g_strlcpy(dev->uuids[i], uuid, BLUETOOTH_UUID_STRING_MAX);
+ parts = g_strsplit(uuid, "-", -1);
+
+ if (parts == NULL || parts[0] == NULL) {
+ g_free(uuid);
+ break;
+ }
+
+ dev->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
+ g_strfreev(parts);
+
+ dev->service_index++;
+ i++;
+ }
+ g_variant_iter_free(iter);
+}
+
+static int __bt_get_bonded_device_info(gchar *device_path,
+ bluetooth_device_info_t *dev_info)
+{
+ GError *error = NULL;
+ GDBusProxy *device_proxy;
+ gchar *address = NULL;
+ gchar *name = NULL;
+ unsigned int cod = 0;
+ gint rssi = 0;
+ gboolean trust = FALSE;
+ gboolean paired = FALSE;
+ guchar connected = 0;
+ GByteArray *manufacturer_data = NULL;
+ int ret;
+ GDBusConnection *conn;
+ GVariant *result;
+ GVariantIter *property_iter;
+ const gchar *key;
+ GVariant *value;
+ guint8 char_value;
+ GVariantIter *char_value_iter;
+
+ BT_CHECK_PARAMETER(device_path, return);
+ BT_CHECK_PARAMETER(dev_info, return);
+
+ conn = _bt_gdbus_get_system_gconn();
+ retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ BT_BLUEZ_NAME,
+ device_path,
+ BT_PROPERTIES_INTERFACE,
+ NULL, NULL);
+
+ retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ result = g_dbus_proxy_call_sync(device_proxy,
+ "GetAll",
+ g_variant_new("(s)", BT_DEVICE_INTERFACE),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+
+ if (!result) {
+ BT_ERR("Error occured in Proxy call");
+ if (error != NULL) {
+ BT_ERR("Error occured in Proxy call (Error: %s)", error->message);
+ g_clear_error(&error);
+ }
+ g_object_unref(device_proxy);
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ g_object_unref(device_proxy);
+
+ g_variant_get(result, "(a{sv})", &property_iter);
+
+ while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
+ if (!g_strcmp0(key, "Paired")) {
+ paired = g_variant_get_boolean(value);
+ } else if (!g_strcmp0(key, "Address")) {
+ g_variant_get(value, "s", &address);
+ } else if (!g_strcmp0(key, "Alias")) {
+ g_variant_get(value, "s", &name);
+ } else if (!g_strcmp0(key, "Name")) {
+ if (!name)
+ g_variant_get(value, "s", &name);
+ } else if (!g_strcmp0(key, "Class")) {
+ cod = g_variant_get_uint32(value);
+ } else if (!g_strcmp0(key, "Connected")) {
+ connected = g_variant_get_byte(value);
+ } else if (!g_strcmp0(key, "Trusted")) {
+ trust = g_variant_get_boolean(value);
+ } else if (!g_strcmp0(key, "RSSI")) {
+ rssi = g_variant_get_int16(value);
+ } else if (!g_strcmp0(key, "UUIDs")) {
+ __bt_get_service_list(value, dev_info);
+ } else if (!g_strcmp0(key, "ManufacturerDataLen")) {
+ dev_info->manufacturer_data.data_len = g_variant_get_uint16(value);
+ } else if (!g_strcmp0(key, "ManufacturerData")) {
+ manufacturer_data = g_byte_array_new();
+ g_variant_get(value, "ay", &char_value_iter);
+ while (g_variant_iter_loop(char_value_iter, "y", &char_value))
+ g_byte_array_append(manufacturer_data, &char_value, 1);
+
+ g_variant_iter_free(char_value_iter);
+
+ if (manufacturer_data) {
+ if (manufacturer_data->len > 0) {
+ memcpy(dev_info->manufacturer_data.data, manufacturer_data->data,
+ manufacturer_data->len);
+ }
+ }
+ g_byte_array_free(manufacturer_data, TRUE);
+ }
+ }
+ g_variant_iter_free(property_iter);
+
+ BT_DBG("trust: %d, paired: %d", trust, paired);
+
+ g_variant_unref(result);
+
+ if ((paired == FALSE) && (trust == FALSE)) {
+ g_free(address);
+ g_free(name);
+ return BLUETOOTH_ERROR_NOT_PAIRED;
+ }
+
+ _bt_convert_addr_string_to_type(dev_info->device_address.addr,
+ address);
+
+ _bt_divide_device_class(&dev_info->device_class, cod);
+
+ g_strlcpy(dev_info->device_name.name, name,
+ BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
+
+ dev_info->rssi = rssi;
+ dev_info->trust = trust;
+ dev_info->paired = paired;
+ dev_info->connected = connected;
+ ret = BLUETOOTH_ERROR_NONE;
+ g_free(address);
+ g_free(name);
+
+ return ret;
+}
+
+int _bt_get_bonded_device_info(bluetooth_device_address_t *device_address,
+ bluetooth_device_info_t *dev_info)
+{
+ char *object_path = NULL;
+ GDBusProxy *adapter_proxy;
+ char address[BT_ADDRESS_STRING_SIZE] = { 0 };
+ int ret = BLUETOOTH_ERROR_NONE;
+
+ BT_CHECK_PARAMETER(device_address, return);
+ BT_CHECK_PARAMETER(dev_info, return);
+
+ adapter_proxy = _bt_get_adapter_proxy();
+ retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ _bt_convert_addr_type_to_string(address, device_address->addr);
+
+ object_path = _bt_get_device_object_path(address);
+
+ retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
+
+ ret = __bt_get_bonded_device_info(object_path, dev_info);
+ g_free(object_path);
+
+ return ret;
+}
+
+char *_bt_get_bonded_device_name(char *address)
+{
+ bluetooth_device_address_t device_address = { {0} };
+ bluetooth_device_info_t dev_info;
+
+ retv_if(address == NULL, strdup(""));
+
+ _bt_convert_addr_string_to_type(device_address.addr, address);
+
+ memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
+
+ _bt_get_bonded_device_info(&device_address, &dev_info);
+
+ return g_strdup(dev_info.device_name.name);
+}
+/* Temp Adapter Util changes to make OBEX work.
+*/
+
+void _bt_handle_device_event(GVariant *msg, const char *member, const char *path)
+{
+// int event = 0;
+ int result = BLUETOOTH_ERROR_NONE;
+ char *address;
+ char *dev_name = NULL;
+// const char *property = NULL;
+ GVariant *param = NULL;
+ char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 };
+ ret_if(path == NULL);
+
+ if (strcasecmp(member, "DeviceConnected") == 0) {
+ unsigned char addr_type = 0;
+
+ g_variant_get(msg, "(y)", &addr_type);
+
+ address = g_malloc0(BT_ADDRESS_STRING_SIZE);
+
+ _bt_convert_device_path_to_address(path, address);
+ dev_name = _bt_get_bonded_device_name(address);
+
+ _bt_convert_addr_string_to_secure_string(secure_address, address);
+ BT_INFO("Address : %s Type : %d", secure_address, addr_type);
+ BT_ERR_C("### Connected [%s] [%s]", !addr_type ? "BREDR" : "LE",
+ !addr_type ? dev_name : secure_address);
+ g_free(dev_name);
+
+ _bt_logging_connection(TRUE, addr_type);
+ param = g_variant_new("(isy)", result, address, addr_type);
+ /*Send event to application*/
+ _bt_send_event(BT_DEVICE_EVENT,
+ BLUETOOTH_EVENT_DEVICE_CONNECTED,
+ param);
+ g_free(address);
+ } else if (strcasecmp(member, "Disconnected") == 0) {
+ unsigned char disc_reason = 0;
+ unsigned char addr_type = 0;
+ char *dev_name = NULL;
+ gboolean sending = FALSE;
+
+ g_variant_get(msg, "(yys)", &addr_type, &disc_reason, &dev_name);
+
+ result = disc_reason;
+
+ address = g_malloc0(BT_ADDRESS_STRING_SIZE);
+
+ _bt_convert_device_path_to_address(path, address);
+
+ /* 0x00 BDADDR_BRDER
+ 0x01 BDADDR_LE_PUBLIC
+ 0x02 BDADDR_LE_RANDOM */
+ _bt_convert_addr_string_to_secure_string(secure_address, address);
+ BT_INFO("Address : %s Type : %d", secure_address, addr_type);
+ BT_ERR_C("### Disconnected [%s] [%d : %s] [%s]", !addr_type ? "BREDR" : "LE",
+ disc_reason, _bt_convert_disc_reason_to_string(disc_reason),
+ !addr_type ? dev_name : secure_address);
+ g_free(dev_name);
+
+ //_bt_headset_set_local_connection(FALSE);
+ _bt_logging_connection(FALSE, addr_type);
+
+ if (!addr_type) {
+#ifdef TIZEN_BT_A2DP_SINK_AUTO_CONNECT
+ {
+ int bt_device_state = VCONFKEY_BT_DEVICE_NONE;
+
+ if (vconf_get_int(VCONFKEY_BT_DEVICE, &bt_device_state) != 0)
+ BT_ERR("vconf_get_int failed");
+
+ BT_INFO("conn_state[0x%x], adapter_state [%d]",
+ bt_device_state, _bt_adapter_get_status_for_Obex());
+
+ if (disc_reason == BLUETOOTH_ERROR_CONNECTION_TIMEOUT) {
+ _bt_audio_start_auto_connect(TRUE);
+ } else if (bt_device_state &
+ VCONFKEY_BT_DEVICE_A2DP_SOURCE_CONNECTED) {
+ BT_INFO("Disconnected due to turning BT off. Skip a address");
+ } else {
+ char *last_connected = NULL;
+ last_connected = vconf_get_str(BT_LAST_CONNECTED_DEVICE);
+ if (!g_strcmp0(address, last_connected))
+ _bt_audio_set_auto_connect_device_addr("");
+ if (last_connected)
+ free(last_connected);
+ }
+ }
+
+#endif
+ /*Check for any OPP transfer on the device and cancel
+ * the transfer
+ */
+ _bt_obex_check_pending_transfer(address);
+ _bt_opp_client_is_sending(&sending);
+ if (sending == TRUE)
+ _bt_opp_client_check_pending_transfer(address);
+ /* TODO: MAP? see above */
+ }
+ param = g_variant_new("(isy)", result, address, addr_type);
+ _bt_send_event(BT_DEVICE_EVENT,
+ BLUETOOTH_EVENT_DEVICE_DISCONNECTED,
+ param);
+ g_free(address);
+ }
+ else if (strcasecmp(member, "ProfileStateChanged") == 0) {
+ int state = 0;
+ char *profile_uuid = NULL;
+ bluetooth_device_address_t bd_addr;
+
+ g_variant_get(msg, "(si)", &profile_uuid, &state);
+
+ address = g_malloc0(BT_ADDRESS_STRING_SIZE);
+
+ _bt_convert_device_path_to_address(path, address);
+ _bt_convert_addr_string_to_type(bd_addr.addr, address);
+
+ _bt_convert_addr_string_to_secure_string(secure_address, address);
+ BT_DBG("Address: %s", secure_address);
+ BT_DBG("Profile UUID: %s", profile_uuid);
+ BT_DBG("State: %d", state);
+ }
+}
+static gboolean __bt_parse_device_properties(GVariant *item,
+ bt_remote_dev_info_t *dev_info)
+{
+ GVariantIter iter;
+ gchar *key;
+ GVariant *val;
+ gsize len = 0;
+ if (item == NULL)
+ return FALSE;
+
+ g_variant_iter_init(&iter, item);
+ while (g_variant_iter_loop(&iter, "{sv}", &key, &val)) {
+ if (strcasecmp(key, "Address") == 0) {
+ dev_info->address = g_variant_dup_string(val, &len);
+ } else if (strcasecmp(key, "Class") == 0) {
+ dev_info->class = g_variant_get_uint32(val);
+ } else if (strcasecmp(key, "name") == 0) {
+ if (dev_info->name == NULL)
+ dev_info->name = g_variant_dup_string(val, &len);
+ } else if (strcasecmp(key, "Connected") == 0) {
+ dev_info->connected = g_variant_get_byte(val);
+ } else if (strcasecmp(key, "paired") == 0) {
+ dev_info->paired = g_variant_get_boolean(val);
+ } else if (strcasecmp(key, "Trusted") == 0) {
+ dev_info->trust = g_variant_get_boolean(val);
+ } else if (strcasecmp(key, "RSSI") == 0) {
+ dev_info->rssi = g_variant_get_int16(val);
+ } else if (strcasecmp(key, "LastAddrType") == 0) {
+ dev_info->addr_type = g_variant_get_byte(val);
+ } else if (strcasecmp(key, "UUIDs") == 0) {
+ char **uuid_value;
+ gsize size = 0;
+ int i = 0;
+ size = g_variant_get_size(val);
+
+ if (size > 0) {
+ uuid_value = (char **)g_variant_get_strv(val, &size);
+ if (dev_info->uuids == NULL)
+ dev_info->uuids = g_malloc0(sizeof(char *) * size);
+
+ for (i = 0; uuid_value[i] != NULL; i++) {
+ dev_info->uuid_count++;
+ dev_info->uuids[i] = g_strdup(uuid_value[i]);
+ }
+ g_free(uuid_value);
+ }
+ } else if (strcasecmp(key, "ManufacturerDataLen") == 0) {
+ g_variant_get(val, "q", &dev_info->manufacturer_data_len);
+ if (dev_info->manufacturer_data_len > BLUETOOTH_MANUFACTURER_DATA_LENGTH_MAX) {
+ BT_ERR("manufacturer_data_len is too long(len = %d)", dev_info->manufacturer_data_len);
+ dev_info->manufacturer_data_len = BLUETOOTH_MANUFACTURER_DATA_LENGTH_MAX;
+ }
+
+ if (dev_info->manufacturer_data_len == 0)
+ dev_info->manufacturer_data = g_strdup("");
+ } else if (strcasecmp(key, "ManufacturerData") == 0) {
+ int i = 0;
+ int len = 0;
+ GVariantIter *value_iter;
+ guint8 m_value;
+
+ len = g_variant_get_size(val);
+ if (len <= 0)
+ continue;
+
+ dev_info->manufacturer_data = g_malloc0(len);
+
+ g_variant_get(val, "ay", &value_iter);
+ while (g_variant_iter_loop(value_iter, "y", &m_value))
+ dev_info->manufacturer_data[i++] = m_value;
+ g_variant_iter_free(value_iter);
+ }
+ }
+
+ BT_DBG("-");
+ return TRUE;
+}
+
+static gboolean __bt_parse_interface(GVariant *msg,
+ bt_remote_dev_info_t *dev_info)
+{
+ char *path = NULL;
+ GVariant *optional_param = NULL;
+ GVariantIter iter;
+ GVariant *child;
+ char *interface_name = NULL;
+ GVariant *inner_iter = NULL;
+ g_variant_get(msg, "(&o@a{sa{sv}})",
+ &path, &optional_param);
+ g_variant_iter_init(&iter, optional_param);
+
+ retv_if(optional_param == NULL, FALSE);
+
+ while ((child = g_variant_iter_next_value(&iter))) {
+ g_variant_get(child, "{&s@a{sv}}", &interface_name, &inner_iter);
+ if (g_strcmp0(interface_name, BT_DEVICE_INTERFACE) == 0) {
+ BT_DBG("Found a device: %s", path);
+ if (__bt_parse_device_properties(inner_iter,
+ dev_info) == FALSE) {
+ g_variant_unref(inner_iter);
+ g_variant_unref(child);
+ g_variant_unref(optional_param);
+ BT_ERR("Fail to parse the properies");
+ return FALSE;
+ } else {
+ g_variant_unref(inner_iter);
+ g_variant_unref(child);
+ g_variant_unref(optional_param);
+ return TRUE;
+ }
+ }
+ g_variant_unref(inner_iter);
+ g_variant_unref(child);
+ }
+
+ g_variant_unref(optional_param);
+
+ return FALSE;
+}
+
+static int __bt_parse_event(GVariant *msg)
+{
+ GVariantIter iter;
+ GVariant *child;
+ char *interface_name = NULL;
+ GVariant *inner_iter = NULL;
+
+ g_variant_iter_init(&iter, msg);
+
+ while ((child = g_variant_iter_next_value(&iter))) {
+ g_variant_get(child, "{&s@a{sv}}", &interface_name, &inner_iter);
+ if (g_strcmp0(interface_name,
+ BT_DEVICE_INTERFACE) == 0) {
+ g_variant_unref(inner_iter);
+ g_variant_unref(child);
+ return BT_DEVICE_EVENT;
+ } else if (g_strcmp0(interface_name,
+ BT_MEDIATRANSPORT_INTERFACE) == 0) {
+ g_variant_unref(inner_iter);
+ g_variant_unref(child);
+ return BT_MEDIA_TRANSFER_EVENT;
+ } else if (g_strcmp0(interface_name,
+ BT_PLAYER_CONTROL_INTERFACE) == 0) {
+ g_variant_unref(inner_iter);
+ g_variant_unref(child);
+ return BT_AVRCP_CONTROL_EVENT;
+ }
+ g_variant_unref(inner_iter);
+ g_variant_unref(child);
+ }
+
+ return 0;
+}
+
+static void __bt_manager_event_filter(GDBusConnection *connection,
+ const gchar *sender_name,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *signal_name,
+ GVariant *parameters,
+ gpointer user_data)
+{
+
+ bt_event_type_t bt_event = 0x00;
+ int result = BLUETOOTH_ERROR_NONE;
+ GVariant *value;
+ char *obj_path = NULL;
+ GVariant *param = NULL;
+
+
+ if (signal_name == NULL)
+ return;
+
+ if (strcasecmp(signal_name, "InterfacesAdded") == 0) {
+ g_variant_get(parameters, "(&o@a{sa{sv}})", &obj_path, &value);
+
+ if (strcasecmp(obj_path, BT_BLUEZ_HCI_PATH) == 0) {
+#ifdef USB_BLUETOOTH
+ BT_DBG("Enable Adapter");
+ _bt_enable_adapter();
+#else
+ _bt_handle_adapter_added();
+#endif
+ } else {
+ bt_event = __bt_parse_event(value);
+ if (bt_event == BT_DEVICE_EVENT) {
+ bt_cache_info_t *cache_info;
+ bt_remote_dev_info_t *dev_info;
+
+ ret_if(_bt_is_discovering() == FALSE);
+
+ cache_info = g_malloc0(sizeof(bt_cache_info_t));
+ ret_if(cache_info == NULL);
+
+ dev_info = g_malloc0(sizeof(bt_remote_dev_info_t));
+ if (dev_info == NULL) {
+ __bt_free_cache_info(cache_info);
+ return;
+ }
+
+ cache_info->dev_info = dev_info;
+
+ if (__bt_parse_interface(parameters, dev_info) == FALSE) {
+ BT_ERR("Fail to parse the properies");
+ __bt_free_cache_info(cache_info);
+ g_variant_unref(value);
+ return;
+ }
+
+ if (dev_info->addr_type != BDADDR_BREDR) {
+ /* Whenever emit the property changed from bluez,
+ some property doesn't reach to bt-service.
+ So LE device is handled as AdvReport signal */
+ __bt_free_cache_info(cache_info);
+ g_variant_unref(value);
+ return;
+ }
+
+ if (dev_info->name == NULL)
+ /* If Remote device name is NULL or still RNR is not done
+ * then display address as name.
+ */
+ dev_info->name = g_strdup(dev_info->address);
+
+#ifdef TIZEN_FEATURE_BT_DPM
+ if (_bt_dpm_get_bluetooth_desktop_connectivity_state() ==
+ DPM_RESTRICTED) {
+ bluetooth_device_class_t device_class;
+ _bt_divide_device_class(&device_class, dev_info->class);
+ BT_DBG("[%s]device_class.major_class : %d", dev_info->name, device_class.major_class);
+
+ if (device_class.major_class ==
+ BLUETOOTH_DEVICE_MAJOR_CLASS_COMPUTER) {
+ __bt_free_cache_info(cache_info);
+ g_variant_unref(value);
+ return;
+ }
+ }
+#endif
+
+ GVariant *uuids = NULL;
+ GVariantBuilder *builder = NULL;
+ int i = 0;
+ builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
+ for (i = 0; i < dev_info->uuid_count; i++) {
+ g_variant_builder_add(builder, "s",
+ dev_info->uuids[i]);
+ }
+ uuids = g_variant_new("as", builder);
+ g_variant_builder_unref(builder);
+ GVariant *manufacturer_data = NULL;
+ manufacturer_data = g_variant_new_from_data(
+ G_VARIANT_TYPE_BYTESTRING,
+ dev_info->manufacturer_data,
+ dev_info->manufacturer_data_len,
+ TRUE, NULL, NULL);
+ param = g_variant_new("(isunsbub@asn@ay)", result,
+ dev_info->address,
+ dev_info->class,
+ dev_info->rssi,
+ dev_info->name,
+ dev_info->paired,
+ dev_info->connected,
+ dev_info->trust,
+ uuids,
+ dev_info->manufacturer_data_len,
+ manufacturer_data);
+ _bt_send_event(BT_ADAPTER_EVENT,
+ BLUETOOTH_EVENT_REMOTE_DEVICE_FOUND,
+ param);
+ p_cache_list = g_list_append(p_cache_list, cache_info);
+ } else if (bt_event == BT_AVRCP_CONTROL_EVENT) {
+ BT_DBG("Device path : %s ", obj_path);
+ //_bt_set_control_device_path(obj_path);
+ }
+ }
+ g_variant_unref(value);
+ } else if (strcasecmp(signal_name, "InterfacesRemoved") == 0) {
+#ifdef USB_BLUETOOTH
+ BT_DBG("InterfacesRemoved");
+ _bt_handle_adapter_removed();
+#endif
+ if (g_strcmp0(interface_name, BT_MEDIATRANSPORT_INTERFACE) == 0)
+ bt_event = BT_MEDIA_TRANSFER_EVENT;
+ else if (g_strcmp0(interface_name, BT_DEVICE_INTERFACE) == 0)
+ bt_event = BT_DEVICE_EVENT;
+ else if (g_strcmp0(interface_name, BT_PLAYER_CONTROL_INTERFACE) == 0)
+ bt_event = BT_AVRCP_CONTROL_EVENT;
+
+ if ((bt_event != 0) && (bt_event != BT_MEDIA_TRANSFER_EVENT)) {
+ _bt_handle_adapter_event(parameters, signal_name);
+ if (bt_event == BT_AVRCP_CONTROL_EVENT) {
+ BT_INFO("Object Path %s", obj_path);
+ //_bt_remove_control_device_path(obj_path);
+ }
+ }
+ } else if (strcasecmp(signal_name, "NameOwnerChanged") == 0) {
+ gboolean value;
+ char *name = NULL;
+ char *previous = NULL;
+ char *current = NULL;
+
+ if (__bt_get_owner_info(parameters, &name, &previous, ¤t)) {
+ BT_ERR("Fail to get the owner info");
+ return;
+ }
+
+ if (*current != '\0') {
+ g_free(current);
+ if (name)
+ g_free(name);
+ if (previous)
+ g_free(previous);
+ return;
+ }
+
+
+ _bt_obex_server_check_allocation(&value);
+
+ if (value == TRUE) {
+ /* Check if the obex server was terminated abnormally */
+ _bt_obex_server_check_termination(name);
+ }
+
+ g_free(name);
+ g_free(previous);
+ g_free(current);
+ } else if (g_strcmp0(interface_name, BT_AGENT_INTERFACE) == 0) {
+ _bt_handle_agent_event(parameters, signal_name);
+ } else if (g_strcmp0(interface_name, BT_DEVICE_INTERFACE) == 0) {
+ _bt_handle_device_event(parameters, signal_name, object_path);
+ }
+
+ return;
+}
+
+static gboolean __bt_is_obexd_event(GVariant *msg, const char *interface)
+{
+
+ if (g_strcmp0(interface, BT_PROPERTIES_INTERFACE) == 0) {
+ char *interface_name = NULL;
+
+ g_variant_get(msg, "(&s@a{sv}@as)", &interface_name, NULL, NULL);
+ retv_if(interface_name == NULL, FALSE);
+
+ if (strcasecmp(interface_name, BT_OBEX_TRANSFER_INTERFACE) == 0) {
+ BT_DBG("BT_OBEX_TRANSFER_INTERFACE");
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+static void __bt_obexd_event_filter(GDBusConnection *connection,
+ const gchar *sender_name,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *signal_name,
+ GVariant *parameters,
+ gpointer user_data)
+{
+ const char *member = signal_name;
+ char *obj_path = NULL;
+ ret_if(member == NULL);
+
+ if (strcasecmp(member, "InterfacesAdded") == 0) {
+ if (__bt_get_object_path(parameters, &obj_path)) {
+ BT_ERR("Fail to get the path");
+ return;
+ }
+ BT_INFO("object_path = [%s]", obj_path);
+
+ /*Handle OPP_SERVER_CONNECTED_EVENT here */
+ /* TODO: MAP? see above */
+ if (strncmp(obj_path, BT_SESSION_BASEPATH_SERVER,
+ strlen(BT_SESSION_BASEPATH_SERVER)) != 0) {
+ g_free(obj_path);
+ return;
+ }
+
+ if (g_strrstr(obj_path, "session") && g_strrstr(obj_path, "transfer")) {
+ BT_DBG("Obex_Server_Session_Transfer connected");
+ _bt_obex_transfer_connected(obj_path);
+ }
+ g_free(obj_path);
+ } else if (strcasecmp(member, "InterfacesRemoved") == 0) {
+ /*Handle OPP_SERVER_DISCONNECTED_EVENT here */
+ /* TODO: MAP? see above */
+ if (__bt_get_object_path(parameters, &obj_path)) {
+ BT_ERR("Fail to get the path");
+ return;
+ }
+ BT_INFO("object_path = [%s]", obj_path);
+
+ if (strncmp(obj_path, BT_SESSION_BASEPATH_CLIENT,
+ strlen(BT_SESSION_BASEPATH_CLIENT)) == 0) {
+ BT_DBG("Call PBAP Disconnected");
+ _bt_obex_pbap_client_disconnect(obj_path);
+ }
+
+ if (strncmp(obj_path, BT_SESSION_BASEPATH_SERVER,
+ strlen(BT_SESSION_BASEPATH_SERVER)) != 0) {
+ g_free(obj_path);
+ return;
+ }
+
+ if (g_strrstr(obj_path, "session") && g_strrstr(obj_path, "transfer")) {
+ BT_DBG("Obex_Server_Session_Transfer disconnected %s",
+ obj_path);
+
+ _bt_obex_transfer_disconnected(obj_path);
+ }
+ g_free(obj_path);
+ } else if (__bt_is_obexd_event(parameters, interface_name) == TRUE) {
+ const char *path = object_path;
+
+ if (strncmp(path, BT_SESSION_BASEPATH_SERVER,
+ strlen(BT_SESSION_BASEPATH_SERVER)) != 0 &&
+ strncmp(path, BT_SESSION_BASEPATH_CLIENT,
+ strlen(BT_SESSION_BASEPATH_CLIENT)) != 0) {
+ BT_DBG("DBUS_HANDLER_RESULT_NOT_YET_HANDLED");
+ return;
+ }
+
+ _bt_handle_property_changed_event(parameters, path);
+ }
+ BT_DBG("-");
+ return;
+}
+
+static gboolean __bt_is_obexd_client_event(GVariant *msg, const char *interface)
+{
+ BT_DBG("+");
+
+ if (g_strcmp0(interface, BT_PROPERTIES_INTERFACE) == 0) {
+ char *interface_name = NULL;
+
+ g_variant_get(msg, "(&s@a{sv}@as)", &interface_name, NULL, NULL);
+
+ retv_if(interface_name == NULL, FALSE);
+
+ if (strcasecmp(interface_name,
+ BT_OBEX_TRANSFER_INTERFACE) == 0) {
+ BT_DBG("-");
+ return TRUE;
+ }
+ }
+
+ BT_DBG("-");
+
+ return FALSE;
+}
+
+static void __bt_opc_event_filter(GDBusConnection *connection,
+ const gchar *sender_name,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *signal_name,
+ GVariant *parameters,
+ gpointer user_data)
+{
+ const char *member = signal_name;
+ char *obj_path = NULL;
+ if (strcasecmp(member, "InterfacesAdded") == 0) {
+ BT_DBG("InterfacesAdded");
+ } else if (strcasecmp(member, "InterfacesRemoved") == 0) {
+
+ if (__bt_get_object_path(parameters, &obj_path)) {
+ BT_ERR("Fail to get the path");
+ return;
+ }
+
+ BT_DBG("object_path = %s", obj_path);
+
+ if (strncmp(obj_path, BT_SESSION_BASEPATH_CLIENT,
+ strlen(BT_SESSION_BASEPATH_CLIENT)) != 0
+ || strstr(obj_path, "transfer") == NULL) {
+ g_free(obj_path);
+ return;
+ } else if (strncmp(obj_path, BT_SESSION_BASEPATH_CLIENT,
+ strlen(BT_SESSION_BASEPATH_CLIENT)) == 0) {
+ BT_DBG("Going to call opc disconnected");
+ _bt_opc_disconnected(obj_path);
+ }
+
+ _bt_sending_files();
+ g_free(obj_path);
+ } else if (__bt_is_obexd_client_event(parameters, interface_name) == TRUE) {
+ char *path = (char *)object_path;
+ BT_INFO("object_path %s", path);
+ if (strncmp(path, BT_SESSION_BASEPATH_CLIENT,
+ strlen(BT_SESSION_BASEPATH_CLIENT)) != 0) {
+ BT_DBG("NOT BT_SESSION_BASEPATH_CLIENT");
+ return;
+ }
+
+ _bt_opc_property_changed_event(parameters, path);
+ }
+
+ return;
+}
+
+int _bt_opp_client_event_init(void)
+{
+ GError *error = NULL;
+
+ if (opc_obexd_conn == NULL) {
+ opc_obexd_conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
+
+ if (!opc_obexd_conn) {
+ if (error) {
+ BT_ERR("Unable to connect to dbus: %s", error->message);
+ g_clear_error(&error);
+ }
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+ }
+
+ if (_bt_register_service_event(opc_obexd_conn,
+ BT_OPP_CLIENT_EVENT) != BLUETOOTH_ERROR_NONE) {
+ g_object_unref(opc_obexd_conn);
+ opc_obexd_conn = NULL;
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+void _bt_opp_client_event_deinit(void)
+{
+ if (opc_obexd_conn) {
+ _bt_unregister_service_event(opc_obexd_conn,
+ BT_OPP_CLIENT_EVENT);
+ g_object_unref(opc_obexd_conn);
+ opc_obexd_conn = NULL;
+ }
+}
+
+static void __bt_map_event_filter(GDBusConnection *connection,
+ const gchar *sender_name,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *signal_name,
+ GVariant *parameters,
+ gpointer user_data)
+{
+ BT_DBG("Entered __bt_map_event_filter");
+ const char *member = signal_name;
+
+ if (strcasecmp(member, "InterfacesAdded") == 0) {
+ BT_DBG("------------------------------------ADDED------------------------------------");
+ // currently doing nothing
+ } else if (strcasecmp(member, "InterfacesRemoved") == 0) {
+ BT_DBG("------------------------------------REMOVED------------------------------------");
+ // TODO check if something should be called here?
+ //_bt_map_on_transfer_finished(object_path, error);
+ } else if (__bt_is_obexd_client_event(parameters, interface_name) == TRUE) {
+ BT_DBG("------------------------------------CLIENT EVENT------------------------------------");
+ _bt_map_property_changed_event(parameters, object_path);
+ }
+
+ return;
+}
+
+int _bt_map_client_event_init(void)
+{
+ GError *error = NULL;
+
+ if (map_obexd_conn == NULL) {
+ map_obexd_conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
+
+ if (!map_obexd_conn) {
+ if (error) {
+ BT_ERR("Unable to connect to dbus: %s", error->message);
+ g_clear_error(&error);
+ }
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+ }
+
+ if (_bt_register_service_event(map_obexd_conn,
+ BT_MAP_CLIENT_EVENT) != BLUETOOTH_ERROR_NONE) {
+ g_object_unref(map_obexd_conn);
+ map_obexd_conn = NULL;
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+void _bt_map_client_event_deinit(void)
+{
+ if (map_obexd_conn) {
+ _bt_unregister_service_event(map_obexd_conn,
+ BT_MAP_CLIENT_EVENT);
+ g_object_unref(map_obexd_conn);
+ map_obexd_conn = NULL;
+ }
+}
+
+int _bt_register_manager_subscribe_signal(GDBusConnection *conn,
+ int subscribe)
+{
+ if (conn == NULL)
+ return -1;
+
+ static int subs_interface_added_id = -1;
+ static int subs_interface_removed_id = -1;
+ static int subs_name_owner_id = -1;
+ static int subs_property_id = -1;
+ static int subs_adapter_id = -1;
+ static int subs_gatt_id = -1;
+
+ if (subscribe) {
+ if (subs_interface_added_id == -1) {
+ subs_interface_added_id = g_dbus_connection_signal_subscribe(conn,
+ NULL, BT_MANAGER_INTERFACE,
+ BT_INTERFACES_ADDED, NULL, NULL, 0,
+ __bt_manager_event_filter,
+ NULL, NULL);
+ }
+ if (subs_interface_removed_id == -1) {
+ subs_interface_removed_id = g_dbus_connection_signal_subscribe(conn,
+ NULL, BT_MANAGER_INTERFACE,
+ BT_INTERFACES_REMOVED, NULL, NULL, 0,
+ __bt_manager_event_filter,
+ NULL, NULL);
+ }
+ if (subs_name_owner_id == -1) {
+ subs_name_owner_id = g_dbus_connection_signal_subscribe(conn,
+ NULL, BT_FREEDESKTOP_INTERFACE,
+ BT_NAME_OWNER_CHANGED, NULL, NULL, 0,
+ __bt_manager_event_filter,
+ NULL, NULL);
+ }
+ if (subs_property_id == -1) {
+ subs_property_id = g_dbus_connection_signal_subscribe(conn,
+ NULL, BT_PROPERTIES_INTERFACE,
+ BT_PROPERTIES_CHANGED, NULL, NULL, 0,
+ __bt_manager_event_filter,
+ NULL, NULL);
+ }
+ if (subs_adapter_id == -1) {
+ subs_adapter_id = g_dbus_connection_signal_subscribe(conn,
+ NULL, BT_ADAPTER_INTERFACE,
+ NULL, NULL, NULL, 0,
+ __bt_manager_event_filter,
+ NULL, NULL);
+ }
+ if (subs_gatt_id == -1) {
+ subs_gatt_id = g_dbus_connection_signal_subscribe(conn,
+ NULL, BT_GATT_CHAR_INTERFACE,
+ NULL, NULL, NULL, 0,
+ __bt_manager_event_filter,
+ NULL, NULL);
+ }
+ } else {
+ if (subs_interface_added_id != -1) {
+ g_dbus_connection_signal_unsubscribe(conn,
+ subs_interface_added_id);
+ subs_interface_added_id = -1;
+ }
+ if (subs_interface_removed_id != -1) {
+ g_dbus_connection_signal_unsubscribe(conn,
+ subs_interface_removed_id);
+ subs_interface_removed_id = -1;
+ }
+ if (subs_name_owner_id != -1) {
+ g_dbus_connection_signal_unsubscribe(conn,
+ subs_name_owner_id);
+ subs_name_owner_id = -1;
+ }
+ if (subs_property_id != -1) {
+ g_dbus_connection_signal_unsubscribe(conn,
+ subs_property_id);
+ subs_property_id = -1;
+ }
+ if (subs_adapter_id != -1) {
+ g_dbus_connection_signal_unsubscribe(conn, subs_adapter_id);
+ subs_adapter_id = -1;
+ }
+ if (subs_gatt_id != -1) {
+ g_dbus_connection_signal_unsubscribe(conn, subs_gatt_id);
+ subs_gatt_id = -1;
+ }
+ }
+ return 0;
+}
+
+int _bt_register_device_subscribe_signal(GDBusConnection *conn,
+ int subscribe)
+{
+ if (conn == NULL)
+ return -1;
+
+ static int subs_device_id = -1;
+
+ if (subscribe) {
+ if (subs_device_id == -1) {
+ subs_device_id = g_dbus_connection_signal_subscribe(conn,
+ NULL, BT_DEVICE_INTERFACE,
+ NULL, NULL, NULL, 0,
+ __bt_manager_event_filter,
+ NULL, NULL);
+ }
+ } else {
+ if (subs_device_id != -1) {
+ g_dbus_connection_signal_unsubscribe(conn,
+ subs_device_id);
+ subs_device_id = -1;
+ }
+ }
+ return 0;
+}
+
+int _bt_register_input_subscribe_signal(GDBusConnection *conn,
+ int subscribe)
+{
+ if (conn == NULL)
+ return -1;
+
+ static int subs_input_id = -1;
+
+ if (subscribe) {
+ if (subs_input_id == -1) {
+ subs_input_id = g_dbus_connection_signal_subscribe(conn,
+ NULL, BT_INPUT_INTERFACE,
+ NULL, NULL, NULL, 0,
+ __bt_manager_event_filter,
+ NULL, NULL);
+ }
+ } else {
+ if (subs_input_id != -1) {
+ g_dbus_connection_signal_unsubscribe(conn,
+ subs_input_id);
+ subs_input_id = -1;
+ }
+ }
+ return 0;
+}
+
+int _bt_register_network_subscribe_signal(GDBusConnection *conn,
+ int subscribe)
+{
+ if (conn == NULL)
+ return -1;
+
+ static int subs_serv_id = -1;
+ static int subs_client_id = -1;
+
+ if (subscribe) {
+ if (subs_serv_id == -1) {
+ subs_serv_id = g_dbus_connection_signal_subscribe(conn,
+ NULL, BT_NETWORK_SERVER_INTERFACE,
+ NULL, NULL, NULL, 0,
+ __bt_manager_event_filter,
+ NULL, NULL);
+ }
+ if (subs_client_id == -1) {
+ subs_client_id = g_dbus_connection_signal_subscribe(conn,
+ NULL, BT_NETWORK_CLIENT_INTERFACE,
+ NULL, NULL, NULL, 0,
+ __bt_manager_event_filter,
+ NULL, NULL);
+ }
+ } else {
+ if (subs_serv_id != -1) {
+ g_dbus_connection_signal_unsubscribe(conn,
+ subs_serv_id);
+ subs_serv_id = -1;
+ }
+ if (subs_client_id != -1) {
+ g_dbus_connection_signal_unsubscribe(conn,
+ subs_client_id);
+ subs_client_id = -1;
+ }
+ }
+ return 0;
+}
+
+int _bt_register_opp_server_subscribe_signal(GDBusConnection *conn,
+ int subscribe)
+{
+ if (conn == NULL)
+ return -1;
+
+ static int subs_opp_server_interface_added_id = -1;
+ static int subs_opp_server_interface_removed_id = -1;
+ static int subs_opp_server_property_id = -1;
+
+
+ if (subscribe) {
+ if (subs_opp_server_interface_added_id == -1) {
+ subs_opp_server_interface_added_id = g_dbus_connection_signal_subscribe(conn,
+ NULL, BT_MANAGER_INTERFACE,
+ BT_INTERFACES_ADDED, NULL, NULL, 0,
+ __bt_obexd_event_filter,
+ NULL, NULL);
+ }
+ if (subs_opp_server_interface_removed_id == -1) {
+ subs_opp_server_interface_removed_id = g_dbus_connection_signal_subscribe(conn,
+ NULL, BT_MANAGER_INTERFACE,
+ BT_INTERFACES_REMOVED, NULL, NULL, 0,
+ __bt_obexd_event_filter,
+ NULL, NULL);
+ }
+ if (subs_opp_server_property_id == -1) {
+ subs_opp_server_property_id = g_dbus_connection_signal_subscribe(conn,
+ NULL, BT_PROPERTIES_INTERFACE,
+ BT_PROPERTIES_CHANGED, NULL, NULL, 0,
+ __bt_obexd_event_filter,
+ NULL, NULL);
+ }
+ } else {
+ if (subs_opp_server_interface_added_id != -1) {
+ g_dbus_connection_signal_unsubscribe(conn,
+ subs_opp_server_interface_added_id);
+ subs_opp_server_interface_added_id = -1;
+ }
+ if (subs_opp_server_interface_removed_id != -1) {
+ g_dbus_connection_signal_unsubscribe(conn,
+ subs_opp_server_interface_removed_id);
+ subs_opp_server_interface_removed_id = -1;
+ }
+ if (subs_opp_server_property_id != -1) {
+ g_dbus_connection_signal_unsubscribe(conn,
+ subs_opp_server_property_id);
+ subs_opp_server_property_id = -1;
+ }
+ }
+ return 0;
+}
+
+int _bt_register_opp_client_subscribe_signal(GDBusConnection *conn,
+ int subscribe)
+{
+ if (conn == NULL)
+ return -1;
+
+ static int subs_opp_client_interface_added_id = -1;
+ static int subs_opp_client_interface_removed_id = -1;
+ static int subs_opp_client_property_id = -1;
+
+
+ if (subscribe) {
+ if (subs_opp_client_interface_added_id == -1) {
+ subs_opp_client_interface_added_id = g_dbus_connection_signal_subscribe(conn,
+ NULL, BT_MANAGER_INTERFACE,
+ BT_INTERFACES_ADDED, NULL, NULL, 0,
+ __bt_opc_event_filter,
+ NULL, NULL);
+ }
+ if (subs_opp_client_interface_removed_id == -1) {
+ subs_opp_client_interface_removed_id = g_dbus_connection_signal_subscribe(conn,
+ NULL, BT_MANAGER_INTERFACE,
+ BT_INTERFACES_REMOVED, NULL, NULL, 0,
+ __bt_opc_event_filter,
+ NULL, NULL);
+ }
+ if (subs_opp_client_property_id == -1) {
+ subs_opp_client_property_id = g_dbus_connection_signal_subscribe(conn,
+ NULL, BT_PROPERTIES_INTERFACE,
+ BT_PROPERTIES_CHANGED, NULL, NULL, 0,
+ __bt_opc_event_filter,
+ NULL, NULL);
+ }
+ } else {
+ if (subs_opp_client_interface_added_id != -1) {
+ g_dbus_connection_signal_unsubscribe(conn,
+ subs_opp_client_interface_added_id);
+ subs_opp_client_interface_added_id = -1;
+ }
+ if (subs_opp_client_interface_removed_id != -1) {
+ g_dbus_connection_signal_unsubscribe(conn,
+ subs_opp_client_interface_removed_id);
+ subs_opp_client_interface_removed_id = -1;
+ }
+ if (subs_opp_client_property_id != -1) {
+ g_dbus_connection_signal_unsubscribe(conn,
+ subs_opp_client_property_id);
+ subs_opp_client_property_id = -1;
+ }
+ }
+ return 0;
+}
+
+int _bt_register_map_client_subscribe_signal(GDBusConnection *conn,
+ int subscribe)
+{
+ if (conn == NULL)
+ return -1;
+
+ static int subs_map_client_interface_added_id = -1;
+ static int subs_map_client_interface_removed_id = -1;
+ static int subs_map_client_property_id = -1;
+
+
+ if (subscribe) {
+ if (subs_map_client_interface_added_id == -1) {
+ subs_map_client_interface_added_id = g_dbus_connection_signal_subscribe(conn,
+ NULL, BT_MANAGER_INTERFACE,
+ BT_INTERFACES_ADDED, NULL, NULL, 0,
+ __bt_map_event_filter,
+ NULL, NULL);
+ }
+ if (subs_map_client_interface_removed_id == -1) {
+ subs_map_client_interface_removed_id = g_dbus_connection_signal_subscribe(conn,
+ NULL, BT_MANAGER_INTERFACE,
+ BT_INTERFACES_REMOVED, NULL, NULL, 0,
+ __bt_map_event_filter,
+ NULL, NULL);
+ }
+ if (subs_map_client_property_id == -1) {
+ subs_map_client_property_id = g_dbus_connection_signal_subscribe(conn,
+ NULL, BT_PROPERTIES_INTERFACE,
+ BT_PROPERTIES_CHANGED, NULL, NULL, 0,
+ __bt_map_event_filter,
+ NULL, NULL);
+ }
+ } else {
+ if (subs_map_client_interface_added_id != -1) {
+ g_dbus_connection_signal_unsubscribe(conn,
+ subs_map_client_interface_added_id);
+ subs_map_client_interface_added_id = -1;
+ }
+ if (subs_map_client_interface_removed_id != -1) {
+ g_dbus_connection_signal_unsubscribe(conn,
+ subs_map_client_interface_removed_id);
+ subs_map_client_interface_removed_id = -1;
+ }
+ if (subs_map_client_property_id != -1) {
+ g_dbus_connection_signal_unsubscribe(conn,
+ subs_map_client_property_id);
+ subs_map_client_property_id = -1;
+ }
+ }
+ return 0;
+}
+
+
+int _bt_register_service_event(GDBusConnection *g_conn, int event_type)
+{
+ BT_DBG("+");
+
+ retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ switch (event_type) {
+ case BT_MANAGER_EVENT:
+ _bt_register_manager_subscribe_signal(g_conn, TRUE);
+ break;
+ case BT_DEVICE_EVENT:
+ _bt_register_device_subscribe_signal(g_conn, TRUE);
+ break;
+ case BT_NETWORK_EVENT:
+ _bt_register_network_subscribe_signal(g_conn, TRUE);
+ break;
+ case BT_OPP_SERVER_EVENT:
+ BT_ERR("BT_OPP_SERVER_EVENT: register service event");
+ _bt_register_opp_server_subscribe_signal(g_conn, TRUE);
+ break;
+ case BT_OPP_CLIENT_EVENT:
+ BT_ERR("BT_OPP_CLIENT_EVENT: register service event");
+ _bt_register_opp_client_subscribe_signal(g_conn, TRUE);
+ break;
+ case BT_MAP_CLIENT_EVENT:
+ BT_ERR("BT_MAP_CLIENT_EVENT: register service event");
+ _bt_register_map_client_subscribe_signal(g_conn, TRUE);
+ break;
+ default:
+ BT_ERR("Unknown event");
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+void _bt_unregister_service_event(GDBusConnection *g_conn, int event_type)
+{
+ BT_DBG("+");
+
+ ret_if(g_conn == NULL);
+
+ switch (event_type) {
+ case BT_MANAGER_EVENT:
+ _bt_register_manager_subscribe_signal(g_conn, FALSE);
+ _bt_register_device_subscribe_signal(g_conn, FALSE);
+ _bt_register_input_subscribe_signal(g_conn, FALSE);
+ _bt_register_network_subscribe_signal(g_conn, FALSE);
+ break;
+ case BT_OPP_SERVER_EVENT:
+ _bt_register_opp_server_subscribe_signal(g_conn, FALSE);
+ break;
+ case BT_OPP_CLIENT_EVENT:
+ _bt_register_opp_client_subscribe_signal(g_conn, FALSE);
+ break;
+ case BT_MAP_CLIENT_EVENT:
+ _bt_register_map_client_subscribe_signal(g_conn, FALSE);
+ break;
+ default:
+ BT_ERR("Unknown event");
+ return;
+ }
+
+ BT_DBG("-");
+}
+
+static int __bt_init_manager_receiver(void)
+{
+ BT_DBG("+");
+
+ GError *error = NULL;
+
+ if (manager_conn == NULL) {
+ manager_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+ if (error != NULL) {
+ BT_ERR("ERROR: Can't get on system bus [%s]", error->message);
+ g_clear_error(&error);
+ }
+ retv_if(manager_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+ }
+
+ if (_bt_register_service_event(manager_conn,
+ BT_MANAGER_EVENT) != BLUETOOTH_ERROR_NONE)
+ goto fail;
+ if (_bt_register_service_event(manager_conn,
+ BT_DEVICE_EVENT) != BLUETOOTH_ERROR_NONE)
+ goto fail;
+
+
+ if (_bt_register_service_event(manager_conn,
+ BT_NETWORK_EVENT) != BLUETOOTH_ERROR_NONE)
+ goto fail;
+
+
+ return BLUETOOTH_ERROR_NONE;
+fail:
+ if (manager_conn) {
+ g_object_unref(manager_conn);
+ manager_conn = NULL;
+ }
+
+ BT_DBG("-");
+
+ return BLUETOOTH_ERROR_INTERNAL;
+}
+
+static int __bt_init_obexd_receiver(void)
+{
+ BT_DBG("+");
+#ifndef TIZEN_PROFILE_TV
+ { /* TODO: obexd doesn't work in TV profile. It should be resolved later. */
+ GError *error = NULL;
+
+ if (obexd_conn == NULL) {
+ obexd_conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
+ if (error != NULL) {
+ BT_ERR("ERROR: Can't get on session bus [%s]", error->message);
+ g_clear_error(&error);
+ }
+ retv_if(obexd_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+ }
+
+ if (_bt_register_service_event(obexd_conn,
+ BT_OPP_SERVER_EVENT) != BLUETOOTH_ERROR_NONE) {
+ BT_ERR("Error while registering service event");
+ g_object_unref(obexd_conn);
+ obexd_conn = NULL;
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+ }
+#endif
+ BT_DBG("-");
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+gboolean __bt_reinit_obexd_receiver(gpointer user_data)
+{
+ static int retry_cnt = 0;
+ int result = BLUETOOTH_ERROR_NONE;
+
+ BT_DBG("+");
+
+ result = __bt_init_obexd_receiver();
+ if (result != BLUETOOTH_ERROR_NONE) {
+ /* 20 ms * 50 = 10 seconds. During 10 seconds fail to initialize,
+ then it is not the timing issue. Just can't use the session bus connection */
+ if (retry_cnt > 100) {
+ BT_ERR("Fail to init obexd receiver by 50 times.");
+ retry_cnt = 0;
+ session_reinit_timer = 0;
+ return FALSE;
+ }
+ retry_cnt++;
+ BT_DBG("Retry to initialize the obexd receiver");
+ return TRUE;
+ }
+
+ retry_cnt = 0;
+ session_reinit_timer = 0;
+
+ BT_DBG("-");
+
+ return FALSE;
+}
+
+/* To receive the event from bluez */
+int _bt_init_service_event_receiver(void)
+{
+ BT_DBG("+");
+
+ int result;
+
+ result = __bt_init_manager_receiver();
+ retv_if(result != BLUETOOTH_ERROR_NONE, result);
+
+ result = __bt_init_obexd_receiver();
+ if (result != BLUETOOTH_ERROR_NONE) {
+ BT_ERR("Fail to init obexd receiver");
+
+ /* Try to re-initialize obexd receiver in the timer */
+ if (session_reinit_timer > 0)
+ g_source_remove(session_reinit_timer);
+
+ session_reinit_timer = g_timeout_add(200,
+ (GSourceFunc)__bt_reinit_obexd_receiver, NULL);
+ }
+
+ BT_DBG("-");
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+void _bt_deinit_service_event_receiver(void)
+{
+ BT_DBG("+");
+
+ _bt_unregister_service_event(manager_conn, BT_MANAGER_EVENT);
+
+ _bt_unregister_service_event(obexd_conn, BT_OPP_SERVER_EVENT);
+
+ if (manager_conn) {
+ g_object_unref(manager_conn);
+ manager_conn = NULL;
+ }
+
+ if (obexd_conn) {
+ g_object_unref(obexd_conn);
+ obexd_conn = NULL;
+ }
+
+ if (event_id > 0)
+ g_source_remove(event_id);
+ event_id = 0;
+
+ BT_DBG("-");
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <glib.h>
+#include <dlog.h>
+#include <string.h>
+#include <dirent.h>
+#ifdef TIZEN_FEATURE_BT_DPM
+#include "bt-service-dpm.h"
+#endif
+
+#include <vconf.h>
+
+#include <gio/gio.h>
+
+#include "bluetooth-api.h"
+#include "bt-internal-types.h"
+
+#include "bt-service-common.h"
+#include "bt-service-event.h"
+#include "bt-service-util.h"
+#include "bt-service-obex-agent.h"
+#include "bt-service-obex-server.h"
+#include "bt-service-agent.h"
+
+
+#define DBUS_TIMEOUT 20 * 1000 /* 20 Seconds */
+#define BT_OBEX_SERVER_AGENT_PATH "/org/obex/server_agent"
+
+#define BT_OBEX_SERVICE "org.bluez.obex"
+#define BT_OBEX_MANAGER "org.bluez.obex.AgentManager1"
+#define BT_OBEX_PATH "/org/bluez/obex"
+
+#define BT_OBEX_PATH_PREFIX "/opt/usr/media"
+#define BT_OBEX_DEFAULT_PATH "/opt/usr/home/owner/media"
+#define BT_OBEX_PATH_MAX_LENGTH 255
+
+
+typedef struct {
+ char *filename;
+ char *file_path;
+ char *path;
+ char *type;
+ char *device_name;
+ int transfer_id;
+ gint64 file_size;
+ gint64 progress;
+ char *address;
+} bt_transfer_info_t;
+
+typedef struct {
+ GDBusMethodInvocation *reply_context;
+ guint64 file_size;
+ char *filename;
+ char *file_path;
+ char *device_name;
+ char *transfer_path;
+ char *address;
+ unsigned char contact_auth_info[5];
+} bt_auth_info_t;
+
+typedef struct {
+ char *dest_path;
+ char *sender;
+ int app_pid;
+} bt_server_info_t;
+
+typedef struct {
+ GDBusProxy *proxy;
+ int server_type;
+ int accept_id;
+ bt_auth_info_t *auth_info;
+ bt_server_info_t *native_server;
+ bt_server_info_t *custom_server;
+} bt_obex_agent_info_t;
+
+typedef struct {
+ char *path;
+ char *address;
+ gboolean authorized;
+} bt_session_info_t;
+
+static GSList *transfers;
+static bt_obex_agent_info_t agent_info;
+static GSList *session_list = NULL;
+
+static bt_session_info_t *__bt_find_session_by_path(char *transfer_path)
+{
+ GSList *l;
+ bt_session_info_t *session;
+
+ retv_if(transfer_path == NULL, NULL);
+
+ for (l = session_list; l != NULL; l = l->next) {
+ session = l->data;
+
+ if (session == NULL)
+ continue;
+
+ if (g_strcmp0(session->path, transfer_path) == 0)
+ return session;
+ }
+
+ return NULL;
+}
+
+static GQuark __bt_obex_error_quark(void)
+{
+ static GQuark quark = 0;
+ if (!quark)
+ quark = g_quark_from_static_string("agent");
+
+ return quark;
+}
+
+static bt_transfer_info_t *__bt_find_transfer_by_id(int transfer_id)
+{
+ GSList *l;
+ bt_transfer_info_t *transfer;
+
+ for (l = transfers; l != NULL; l = l->next) {
+ transfer = l->data;
+
+ if (transfer == NULL)
+ continue;
+
+ if (transfer->transfer_id == transfer_id)
+ return transfer;
+ }
+
+ return NULL;
+}
+
+bt_transfer_info_t *__bt_find_transfer_by_address(const char *address)
+{
+ BT_DBG("+");
+ GSList *l;
+ bt_transfer_info_t *transfer;
+
+ retv_if(address == NULL, NULL);
+
+ for (l = transfers; l != NULL; l = l->next) {
+ transfer = l->data;
+
+ if (transfer == NULL)
+ continue;
+
+ if (g_strcmp0(transfer->address, address) == 0)
+ return transfer;
+ }
+ BT_DBG("-");
+ return NULL;
+}
+
+static bt_transfer_info_t *__bt_find_transfer_by_path(const char *transfer_path)
+{
+ GSList *l;
+ bt_transfer_info_t *transfer;
+
+ retv_if(transfer_path == NULL, NULL);
+
+ for (l = transfers; l != NULL; l = l->next) {
+ transfer = l->data;
+
+ if (transfer == NULL)
+ continue;
+
+ if (g_strcmp0(transfer->path, transfer_path) == 0)
+ return transfer;
+ }
+
+ return NULL;
+}
+
+static void __bt_free_server_info(bt_server_info_t *server_info)
+{
+ ret_if(server_info == NULL);
+
+ g_free(server_info->sender);
+ g_free(server_info->dest_path);
+ g_free(server_info);
+}
+
+static void __bt_free_auth_info(bt_auth_info_t *auto_info)
+{
+ ret_if(auto_info == NULL);
+
+ g_free(auto_info->filename);
+ g_free(auto_info->transfer_path);
+ g_free(auto_info->device_name);
+ g_free(auto_info->address);
+ g_free(auto_info);
+}
+
+static void __bt_free_transfer_info(bt_transfer_info_t *transfer_info)
+{
+ ret_if(transfer_info == NULL);
+
+ g_free(transfer_info->path);
+ g_free(transfer_info->filename);
+ g_free(transfer_info->file_path);
+ g_free(transfer_info->type);
+ g_free(transfer_info->device_name);
+ g_free(transfer_info->address);
+ g_free(transfer_info);
+}
+
+void _bt_obex_check_pending_transfer(const char *address)
+{
+ BT_DBG("+");
+ GVariant *param = NULL;
+ bt_transfer_info_t *transfer_info = __bt_find_transfer_by_address(address);
+ if (transfer_info != NULL) {
+ int result = BLUETOOTH_ERROR_CANCEL;
+ param = g_variant_new("(issssstii)", result,
+ transfer_info->filename,
+ transfer_info->type,
+ transfer_info->device_name,
+ transfer_info->file_path,
+ transfer_info->address,
+ transfer_info->file_size,
+ transfer_info->transfer_id,
+ agent_info.server_type);
+ _bt_send_event(BT_OPP_SERVER_EVENT,
+ BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_COMPLETED,
+ param);
+ transfers = g_slist_remove(transfers, transfer_info);
+ __bt_free_transfer_info(transfer_info);
+ }
+ BT_DBG("-");
+}
+
+static char *__bt_get_remote_device_name(const char *bdaddress)
+{
+ char *device_path = NULL;
+ char *name = NULL;
+ GVariant *value;
+ GVariant *result = NULL;
+ GError *err = NULL;
+ GDBusProxy *device_proxy;
+ GDBusConnection *conn;
+
+ retv_if(bdaddress == NULL, NULL);
+
+ device_path = _bt_get_device_object_path((char *)bdaddress);
+ retv_if(device_path == NULL, NULL);
+
+ conn = _bt_get_system_gconn();
+ retv_if(conn == NULL, NULL);
+ BT_INFO("Device_path %s", device_path);
+ device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
+ NULL, BT_BLUEZ_NAME,
+ device_path,
+ BT_PROPERTIES_INTERFACE,
+ NULL, &err);
+
+ g_free(device_path);
+ retv_if(device_proxy == NULL, NULL);
+
+ result = g_dbus_proxy_call_sync(device_proxy, "GetAll",
+ g_variant_new("(s)", BT_DEVICE_INTERFACE),
+ G_DBUS_CALL_FLAGS_NONE,
+ DBUS_TIMEOUT, NULL,
+ &err);
+ if (err) {
+ BT_ERR("DBus Error : %s", err->message);
+ g_clear_error(&err);
+ return NULL;
+ }
+ if (result == NULL) {
+ BT_ERR("g_dbus_proxy_call_sync function return NULL");
+ return NULL;
+ }
+ g_variant_get(result, "(@a{sv})", &value);
+
+ if (value) {
+ GVariant *temp_value = g_variant_lookup_value(value, "Alias",
+ G_VARIANT_TYPE_STRING);
+ g_variant_get(temp_value, "s", &name);
+ if (temp_value)
+ g_variant_unref(temp_value);
+
+ if (name != NULL)
+ DBG_SECURE("Alias Name [%s]", name);
+ else {
+ temp_value = g_variant_lookup_value(value, "Name", G_VARIANT_TYPE_STRING);
+ g_variant_get(temp_value, "s", &name);
+ if (temp_value)
+ g_variant_unref(temp_value);
+ DBG_SECURE("Name = %s", name);
+ }
+ }
+ g_variant_unref(result);
+ g_object_unref(device_proxy);
+ return name;
+}
+
+static void __bt_get_remote_device_name_authinfo(const char *bdaddress,
+ char **device_name, unsigned char *auth_info)
+{
+ char *device_path = NULL;
+ char *name = NULL;
+ gboolean is_alias_set;
+ GVariant *value;
+ GVariant *result = NULL;
+ GError *err = NULL;
+ GDBusProxy *device_proxy;
+ GDBusConnection *conn;
+
+ ret_if(bdaddress == NULL);
+
+ device_path = _bt_get_device_object_path((char *)bdaddress);
+ ret_if(device_path == NULL);
+
+ conn = _bt_get_system_gconn();
+ ret_if(conn == NULL);
+ BT_INFO("Device_path %s", device_path);
+ device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
+ NULL, BT_BLUEZ_NAME,
+ device_path,
+ BT_PROPERTIES_INTERFACE,
+ NULL, &err);
+
+ g_free(device_path);
+ ret_if(device_proxy == NULL);
+
+ result = g_dbus_proxy_call_sync(device_proxy, "GetAll",
+ g_variant_new("(s)", BT_DEVICE_INTERFACE),
+ G_DBUS_CALL_FLAGS_NONE,
+ DBUS_TIMEOUT, NULL,
+ &err);
+ if (err) {
+ BT_ERR("DBus Error : %s", err->message);
+ g_clear_error(&err);
+ return;
+ }
+ if (result == NULL) {
+ BT_ERR("g_dbus_proxy_call_sync function return NULL");
+ return;
+ }
+ g_variant_get(result, "(@a{sv})", &value);
+
+ if (value) {
+ GVariant *temp_value = g_variant_lookup_value(value, "Alias",
+ G_VARIANT_TYPE_STRING);
+ g_variant_get(temp_value, "s", &name);
+ if (temp_value)
+ g_variant_unref(temp_value);
+
+ if (name != NULL)
+ DBG_SECURE("Alias Name [%s]", name);
+ else {
+ temp_value = g_variant_lookup_value(value, "Name", G_VARIANT_TYPE_STRING);
+ g_variant_get(temp_value, "s", &name);
+ if (temp_value)
+ g_variant_unref(temp_value);
+ DBG_SECURE("Name = %s", name);
+ }
+ temp_value = g_variant_lookup_value(value, "IsAliasSet", G_VARIANT_TYPE_BOOLEAN);
+ if (temp_value) {
+ is_alias_set = g_variant_get_boolean(temp_value);
+ g_variant_unref(temp_value);
+ } else {
+ is_alias_set = FALSE;
+ }
+
+ if (is_alias_set == FALSE)
+ {
+ DBG_SECURE("Do Nothing");
+ __bt_get_auth_info(value, (char *)auth_info);
+ }
+ }
+ g_variant_unref(result);
+ g_object_unref(device_proxy);
+
+ *device_name = g_strdup(name);
+ g_free(name);
+ return;
+}
+
+static int __bt_get_transfer_id(const char *path)
+{
+ char *tmp = NULL;
+ if (path == NULL)
+ return -1;
+
+ tmp = strrchr(path, 'r') + 1;
+ retv_if(tmp == NULL, -1);
+
+ return atoi(tmp);
+}
+
+static GDBusProxy *__bt_get_transfer_proxy(const char *transfer_path)
+{
+ GDBusConnection *conn;
+ GDBusProxy *proxy;
+ GError *err = NULL;
+
+ conn = _bt_get_session_gconn();
+ retv_if(conn == NULL, NULL);
+
+ proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
+ NULL, BT_OBEX_SERVICE_NAME,
+ transfer_path,
+ BT_OBEX_TRANSFER_INTERFACE,
+ NULL, &err);
+
+ if (err) {
+ BT_ERR("Error : %s", err->message);
+ g_clear_error(&err);
+ return NULL;
+ }
+
+ return proxy;
+}
+
+static GDBusProxy *__bt_get_transfer_properties_proxy(const char *transfer_path)
+{
+ GDBusConnection *conn;
+ GDBusProxy *proxy;
+ GError *err = NULL;
+ conn = _bt_get_session_gconn();
+ retv_if(conn == NULL, NULL);
+
+ proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
+ NULL, BT_OBEX_SERVICE_NAME,
+ transfer_path,
+ BT_PROPERTIES_INTERFACE,
+ NULL, &err);
+ if (err) {
+ BT_ERR("Error : %s", err->message);
+ g_clear_error(&err);
+ return NULL;
+ }
+ return proxy;
+}
+
+static int __bt_get_transfer_properties(bt_transfer_info_t *transfer_info,
+ const char *transfer_path)
+{
+ GDBusProxy *transfer_proxy;
+ GVariant *result = NULL;
+ GError *err = NULL;
+ GVariantIter *iter = NULL;
+ BT_CHECK_PARAMETER(transfer_info, return);
+ BT_CHECK_PARAMETER(transfer_path, return);
+
+ transfer_proxy = __bt_get_transfer_properties_proxy(transfer_path);
+
+ retv_if(transfer_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ result = g_dbus_proxy_call_sync(transfer_proxy, "GetAll",
+ g_variant_new("(s)", BT_OBEX_TRANSFER_INTERFACE),
+ G_DBUS_CALL_FLAGS_NONE,
+ DBUS_TIMEOUT, NULL,
+ &err);
+
+ if (err) {
+ BT_ERR("DBus Error : %s", err->message);
+ g_clear_error(&err);
+ goto fail;
+ }
+ if (result == NULL) {
+ BT_ERR("g_dbus_proxy_call_sync function return NULL");
+ goto fail;
+ }
+
+ g_variant_get(result, "(a{sv})", &iter);
+ g_variant_unref(result);
+ if (iter) {
+ const gchar *key;
+ GVariant *val;
+ gsize len = 0;
+ while (g_variant_iter_loop(iter, "{sv}", &key, &val)) {
+ if (g_strcmp0(key, "Operation") == 0) {
+ transfer_info->type = g_variant_dup_string(val, &len);
+ } else if (g_strcmp0(key, "Name") == 0) {
+ transfer_info->filename = g_variant_dup_string(val, &len);
+ } else if (g_strcmp0(key, "Size") == 0) {
+ transfer_info->file_size = g_variant_get_uint64(val);
+ } else if (g_strcmp0(key, "Address") == 0) {
+ transfer_info->address = g_variant_dup_string(val, &len);
+ BT_INFO("addressss %s", transfer_info->address);
+ } else if (g_strcmp0(key, "Filename") == 0) {
+ transfer_info->file_path = g_variant_dup_string(val, &len);
+ if (!transfer_info->file_path)
+ transfer_info->file_path = g_strdup(transfer_info->filename);
+ }
+ }
+ g_variant_iter_free(iter);
+
+ if (transfer_info->address == NULL)
+ goto fail;
+ transfer_info->device_name = __bt_get_remote_device_name(transfer_info->address);
+ transfer_info->transfer_id = __bt_get_transfer_id(transfer_path);
+ if (!transfer_info->device_name)
+ transfer_info->device_name = g_strdup(transfer_info->address);
+
+ if (transfer_info->type == NULL)
+ goto fail;
+
+ transfer_info->path = g_strdup(transfer_path);
+ }
+
+ g_object_unref(transfer_proxy);
+ return BLUETOOTH_ERROR_NONE;
+
+fail:
+ g_object_unref(transfer_proxy);
+ return BLUETOOTH_ERROR_INTERNAL;
+}
+
+static gboolean __bt_authorize_cb(GDBusMethodInvocation *context,
+ const char *path,
+ gpointer user_data)
+{
+ char *device_name = NULL;
+ unsigned char auth_info[5] = {0, };
+ int result = BLUETOOTH_ERROR_NONE;
+ GDBusProxy *transfer_properties_proxy;
+ char * bdaddress = NULL;
+ GVariant *ret;
+ GVariantIter *iter;
+ GVariant *param = NULL;
+ GError *err = NULL;
+ bt_session_info_t *session_info = NULL;
+#ifdef TIZEN_FEATURE_BT_DPM
+ int value = DPM_BT_ERROR;
+#endif
+
+ BT_DBG(" path [%s] \n", path);
+
+ transfer_properties_proxy = __bt_get_transfer_properties_proxy(path);
+
+ retv_if(transfer_properties_proxy == NULL, FALSE);
+
+ ret = g_dbus_proxy_call_sync(transfer_properties_proxy, "GetAll",
+ g_variant_new("(s)", BT_OBEX_TRANSFER_INTERFACE),
+ G_DBUS_CALL_FLAGS_NONE,
+ DBUS_TIMEOUT, NULL,
+ &err);
+ if (err) {
+ BT_ERR("DBus Error : %s", err->message);
+ g_clear_error(&err);
+ return FALSE;
+ }
+ if (ret == NULL) {
+ BT_ERR("g_dbus_proxy_call_sync function return NULL");
+ return FALSE;
+ }
+ g_variant_get(ret, "(a{sv})", &iter);
+ g_variant_unref(ret);
+ if (iter == NULL) {
+ g_object_unref(transfer_properties_proxy);
+ return FALSE;
+ }
+
+ __bt_free_auth_info(agent_info.auth_info);
+
+ agent_info.auth_info = g_malloc(sizeof(bt_auth_info_t));
+
+ memset(agent_info.auth_info, 0, sizeof(bt_auth_info_t));
+
+ agent_info.auth_info->reply_context = context;
+
+ agent_info.auth_info->transfer_path = g_strdup(path);
+
+#ifdef TIZEN_FEATURE_BT_DPM
+ _bt_dpm_get_allow_bluetooth_mode(&value);
+ if (value == DPM_BT_HANDSFREE_ONLY) {
+ /* Free auth info in next function */
+ _bt_obex_server_reject_authorize();
+ return FALSE;
+ }
+#endif
+ if (iter) {
+ const gchar *key;
+ GVariant *val;
+ gsize len = 0;
+ while (g_variant_iter_loop(iter, "{sv}", &key, &val)) {
+ if (g_strcmp0(key, "Name") == 0)
+ agent_info.auth_info->filename = g_variant_dup_string(val, &len);
+ else if (g_strcmp0(key, "Address") == 0)
+ bdaddress = g_variant_dup_string(val, &len);
+ else if (g_strcmp0(key, "Size") == 0)
+ agent_info.auth_info->file_size = g_variant_get_uint64(val);
+ }
+ g_variant_iter_free(iter);
+ }
+
+ __bt_get_remote_device_name_authinfo(bdaddress, &device_name, auth_info);
+
+ if (!device_name)
+ device_name = g_strdup(bdaddress);
+
+ agent_info.auth_info->address = g_strdup(bdaddress);
+ agent_info.auth_info->device_name = device_name;
+ memcpy(agent_info.auth_info->contact_auth_info, auth_info, 5);
+
+ session_info = __bt_find_session_by_path((char *)path);
+ if (NULL == session_info) {
+ session_info = g_malloc0(sizeof(bt_session_info_t));
+ session_info->path = g_strdup(path);
+ session_info->address = g_strdup(bdaddress);
+ session_info->authorized = FALSE;
+ session_list = g_slist_append(session_list, session_info);
+ }
+
+ g_object_unref(transfer_properties_proxy);
+ g_free(bdaddress);
+
+ if (agent_info.server_type == BT_CUSTOM_SERVER) {
+ /* No need to send the event */
+ _bt_obex_server_accept_authorize(agent_info.auth_info->filename, FALSE);
+ return TRUE;
+ }
+
+ if (session_info->authorized == FALSE) {
+ if (headed_plugin_info->plugin_headed_enabled)
+ headed_plugin_info->headed_plugin->bt_launch_system_popup(BT_AGENT_EVENT_EXCHANGE_REQUEST, device_name,
+ auth_info, NULL, NULL, BT_OBEX_SERVER_AGENT_PATH);
+ } else {
+ param = g_variant_new("(istss)", result,
+ agent_info.auth_info->filename,
+ agent_info.auth_info->file_size,
+ agent_info.auth_info->address,
+ agent_info.auth_info->device_name);
+ _bt_send_event(BT_OPP_SERVER_EVENT,
+ BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_AUTHORIZE, param);
+ }
+
+ return TRUE;
+}
+
+void _bt_obex_transfer_started(const char *transfer_path)
+{
+ bt_transfer_info_t *transfer_info;
+ request_info_t *req_info;
+ GVariant *out_param1 = NULL;
+ GVariant *param = NULL;
+ GVariantBuilder *builder = NULL;
+ int result = BLUETOOTH_ERROR_NONE;
+ int i = 0;
+
+ BT_DBG("%s", transfer_path);
+
+ transfer_info = g_malloc0(sizeof(bt_transfer_info_t));
+
+ if (agent_info.auth_info != NULL
+ && g_strcmp0(transfer_path, agent_info.auth_info->transfer_path) == 0) {
+ transfer_info->filename = g_strdup(agent_info.auth_info->filename);
+ transfer_info->file_size = agent_info.auth_info->file_size;
+ transfer_info->type = g_strdup(TRANSFER_PUT);
+ transfer_info->path = g_strdup(agent_info.auth_info->transfer_path);
+ transfer_info->device_name = g_strdup(agent_info.auth_info->device_name);
+ transfer_info->transfer_id = __bt_get_transfer_id(transfer_path);
+ transfer_info->file_path = agent_info.auth_info->file_path;
+ transfer_info->address = g_strdup(agent_info.auth_info->address);
+
+ } else {
+ if (__bt_get_transfer_properties(transfer_info, transfer_path) < 0) {
+ BT_ERR("Get Properties failed");
+ __bt_free_transfer_info(transfer_info);
+ return;
+ }
+ agent_info.server_type = BT_FTP_SERVER;
+ }
+
+ if (agent_info.server_type == BT_CUSTOM_SERVER) {
+ if (agent_info.custom_server == NULL) {
+ __bt_free_transfer_info(transfer_info);
+ __bt_free_auth_info(agent_info.auth_info);
+ agent_info.auth_info = NULL;
+ return;
+ }
+
+ req_info = _bt_get_request_info(agent_info.accept_id);
+ if (req_info == NULL || req_info->context == NULL) {
+ BT_ERR("info is NULL");
+ goto done;
+ }
+
+ agent_info.accept_id = 0;
+ result = BLUETOOTH_ERROR_NONE;
+ GArray *g_out_param1 = NULL;
+ g_out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
+ if (out_param1 == NULL) {
+ out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
+ g_out_param1->data, g_out_param1->len,
+ TRUE, NULL, NULL);
+ }
+
+ g_dbus_method_invocation_return_value(req_info->context,
+ g_variant_new("(iv)", result, out_param1));
+ g_array_free(g_out_param1, TRUE);
+ _bt_delete_request_list(req_info->req_id);
+ }
+done:
+ transfers = g_slist_append(transfers, transfer_info);
+
+ BT_DBG("Transfer id %d", transfer_info->transfer_id);
+
+ builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
+ for (i = 0; i < 5; i++) {
+ if (agent_info.auth_info)
+ g_variant_builder_add(builder, "y", agent_info.auth_info->contact_auth_info[i]);
+ }
+
+ param = g_variant_new("(isssstii(ay))", result,
+ transfer_info->device_name,
+ transfer_info->filename,
+ transfer_info->type,
+ transfer_info->address,
+ transfer_info->file_size,
+ transfer_info->transfer_id,
+ agent_info.server_type,
+ builder);
+
+ __bt_free_auth_info(agent_info.auth_info);
+ agent_info.auth_info = NULL;
+
+ g_variant_builder_unref(builder);
+
+ _bt_send_event(BT_OPP_SERVER_EVENT,
+ BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_STARTED,
+ param);
+}
+
+void _bt_obex_transfer_progress(const char *transfer_path,
+ guint64 transferred)
+{
+ BT_DBG("+");
+ bt_transfer_info_t *transfer_info;
+ int current_progress = 0;
+ int previous_progress;
+ GVariant *param = NULL;
+ int result = BLUETOOTH_ERROR_NONE;
+
+ transfer_info = __bt_find_transfer_by_path(transfer_path);
+ ret_if(transfer_info == NULL);
+
+ current_progress = (int)(((gdouble)transferred /
+ (gdouble)transfer_info->file_size) * 100);
+
+ previous_progress = (int)(((gdouble)transfer_info->progress /
+ (gdouble)transfer_info->file_size) * 100);
+
+ if (current_progress == previous_progress) {
+ BT_DBG("Same Percentage Value: Do not emit Signal");
+ return;
+ }
+
+ transfer_info->progress = transferred;
+ param = g_variant_new("(isssstiii)", result,
+ transfer_info->filename,
+ transfer_info->type,
+ transfer_info->device_name,
+ transfer_info->address,
+ transfer_info->file_size,
+ transfer_info->transfer_id,
+ current_progress,
+ agent_info.server_type);
+ _bt_send_event(BT_OPP_SERVER_EVENT,
+ BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_PROGRESS,
+ param);
+ BT_DBG("-");
+}
+
+void _bt_obex_transfer_completed(const char *transfer_path, gboolean success)
+{
+ bt_transfer_info_t *transfer_info;
+ GVariantBuilder *builder = NULL;
+ GVariant *param = NULL;
+ int result;
+ int i = 0;
+ BT_DBG("Transfer [%s] Success [%d] \n", transfer_path, success);
+
+ result = (success == TRUE) ? BLUETOOTH_ERROR_NONE
+ : BLUETOOTH_ERROR_CANCEL;
+
+ transfer_info = __bt_find_transfer_by_path(transfer_path);
+
+ if (transfer_info == NULL) {
+ BT_DBG("Very small files receiving case, did not get Active status from obexd");
+ if (agent_info.auth_info == NULL ||
+ g_strcmp0(transfer_path,
+ agent_info.auth_info->transfer_path) != 0) {
+ BT_ERR("auth_info is NULL, returning");
+ return;
+ }
+
+ transfer_info = g_new0(bt_transfer_info_t, 1);
+
+ transfer_info->filename = g_strdup(agent_info.auth_info->filename);
+ transfer_info->file_size = agent_info.auth_info->file_size;
+ transfer_info->type = g_strdup(TRANSFER_PUT);
+ transfer_info->path = g_strdup(agent_info.auth_info->transfer_path);
+ transfer_info->device_name = g_strdup(agent_info.auth_info->device_name);
+ transfer_info->transfer_id = __bt_get_transfer_id(transfer_path);
+ transfer_info->file_path = agent_info.auth_info->file_path;
+ transfer_info->address = g_strdup(agent_info.auth_info->address);
+
+ builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
+ for (i = 0; i < 5; i++)
+ g_variant_builder_add(builder, "y", agent_info.auth_info->contact_auth_info[i]);
+
+ param = g_variant_new("(isssstii(ay))", result,
+ transfer_info->device_name,
+ transfer_info->filename,
+ transfer_info->type,
+ transfer_info->address,
+ transfer_info->file_size,
+ transfer_info->transfer_id,
+ agent_info.server_type,
+ builder);
+ _bt_send_event(BT_OPP_SERVER_EVENT,
+ BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_STARTED,
+ param);
+ g_variant_builder_unref(builder);
+ }
+ param = g_variant_new("(issssstii)", result,
+ transfer_info->filename,
+ transfer_info->type,
+ transfer_info->device_name,
+ transfer_info->file_path,
+ transfer_info->address,
+ transfer_info->file_size,
+ transfer_info->transfer_id,
+ agent_info.server_type);
+ _bt_send_event(BT_OPP_SERVER_EVENT,
+ BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_COMPLETED,
+ param);
+ transfers = g_slist_remove(transfers, transfer_info);
+ __bt_free_transfer_info(transfer_info);
+}
+
+void _bt_obex_transfer_connected(const char *obj_path)
+{
+ BT_DBG("+");
+
+ int result = BLUETOOTH_ERROR_NONE;
+ GVariant *param = NULL;
+ bt_transfer_info_t *transfer_info = NULL;
+
+ transfer_info = g_new0(bt_transfer_info_t, 1);
+ __bt_get_transfer_properties(transfer_info, obj_path);
+ DBG_SECURE("Address[%s] Name[%s] TransferID[%d] ", transfer_info->address,
+ transfer_info->device_name, transfer_info->transfer_id);
+
+ param = g_variant_new("(issi)", result, transfer_info->address,
+ transfer_info->device_name, transfer_info->transfer_id);
+
+ _bt_send_event(BT_OPP_SERVER_EVENT,
+ BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_CONNECTED,
+ param);
+
+ __bt_free_transfer_info(transfer_info);
+ BT_DBG("-");
+}
+
+void _bt_obex_transfer_disconnected(char * obj_path)
+{
+ BT_DBG("+");
+
+ int result = BLUETOOTH_ERROR_NONE;
+ GVariant *param = NULL;
+ bt_session_info_t *session = NULL;
+ int transfer_id = -1;
+
+ session = __bt_find_session_by_path(obj_path);
+ ret_if(session == NULL);
+
+ transfer_id = __bt_get_transfer_id(obj_path);
+ DBG_SECURE("transfer_id: [%d]", transfer_id);
+
+ DBG_SECURE("%s", session->address);
+ param = g_variant_new("(isi)", result, session->address, transfer_id);
+ _bt_send_event(BT_OPP_SERVER_EVENT,
+ BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_DISCONNECTED,
+ param);
+ session_list = g_slist_remove(session_list, session);
+ g_free(session->address);
+ g_free(session->path);
+ g_free(session);
+ BT_DBG("-");
+}
+
+int _bt_register_obex_server(void)
+{
+ GDBusConnection *g_conn;
+ GDBusProxy *manager_proxy;
+ GVariant *result = NULL;
+ GError *g_error = NULL;
+
+ /* Get the session bus. */
+ g_conn = _bt_get_session_gconn();
+ retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ _bt_obex_agent_new(BT_OBEX_SERVER_AGENT_PATH);
+
+ _bt_obex_setup(BT_OBEX_SERVER_AGENT_PATH);
+
+ _bt_obex_set_authorize_cb(BT_OBEX_SERVER_AGENT_PATH,
+ __bt_authorize_cb, NULL);
+
+ manager_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
+ NULL, BT_OBEX_SERVICE,
+ BT_OBEX_PATH,
+ BT_OBEX_MANAGER,
+ NULL, &g_error);
+
+ if (manager_proxy == NULL)
+ return BLUETOOTH_ERROR_INTERNAL;
+
+ result = g_dbus_proxy_call_sync(manager_proxy, "RegisterAgent",
+ g_variant_new("(o)", BT_OBEX_SERVER_AGENT_PATH),
+ G_DBUS_CALL_FLAGS_NONE,
+ DBUS_TIMEOUT, NULL,
+ &g_error);
+
+ if (g_error != NULL) {
+ BT_ERR("Agent registration failed: %s\n", g_error->message);
+ g_object_unref(manager_proxy);
+ g_error_free(g_error);
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ if (result)
+ g_variant_unref(result);
+
+ agent_info.proxy = manager_proxy;
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_unregister_obex_server(void)
+{
+ GVariant *result = NULL;
+ GError *g_error = NULL;
+
+ retv_if(agent_info.proxy == NULL,
+ BLUETOOTH_ERROR_INTERNAL);
+
+ result = g_dbus_proxy_call_sync(agent_info.proxy, "UnregisterAgent",
+ g_variant_new("(o)", BT_OBEX_SERVER_AGENT_PATH),
+ G_DBUS_CALL_FLAGS_NONE,
+ DBUS_TIMEOUT, NULL,
+ &g_error);
+ if (g_error != NULL) {
+ BT_ERR("Agent unregistration failed: %s", g_error->message);
+ g_error_free(g_error);
+ }
+
+ if (result)
+ g_variant_unref(result);
+
+ _bt_obex_agent_destroy(BT_OBEX_SERVER_AGENT_PATH);
+ g_object_unref(agent_info.proxy);
+ agent_info.proxy = NULL;
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+gboolean __bt_check_folder_path(const char *dest_path)
+{
+ DIR *dp;
+
+ retv_if(dest_path == NULL, FALSE);
+
+ dp = opendir(dest_path);
+
+ if (dp == NULL) {
+ BT_ERR("The directory does not exist");
+ return FALSE;
+ }
+
+ closedir(dp);
+
+ return TRUE;
+}
+
+char *__bt_transfer_folder_path(char *dest_path)
+{
+ char *dst_path = (char *)g_malloc0(BT_OBEX_PATH_MAX_LENGTH);
+ if (g_str_has_prefix(dest_path, BT_OBEX_PATH_PREFIX))
+ snprintf(dst_path, BT_OBEX_PATH_MAX_LENGTH, BT_OBEX_DEFAULT_PATH"%s", dest_path + strlen(BT_OBEX_PATH_PREFIX));
+ else
+ snprintf(dst_path, BT_OBEX_PATH_MAX_LENGTH, "%s", dest_path);
+
+ BT_INFO("obex transfed path : %s", dst_path);
+ return dst_path;
+}
+
+int _bt_obex_server_allocate(char *sender, const char *dest_path, int app_pid, gboolean is_native)
+{
+ BT_DBG("+");
+
+ char *dst_path;
+ dst_path = __bt_transfer_folder_path((char *)dest_path);
+
+ if (__bt_check_folder_path(dst_path) == FALSE) {
+ g_free(dst_path);
+ return BLUETOOTH_ERROR_INVALID_PARAM;
+ }
+
+ if (is_native == TRUE) {
+ if (agent_info.native_server) {
+ BT_ERR("obex native server busy");
+ g_free(dst_path);
+ return BLUETOOTH_ERROR_DEVICE_BUSY;
+ }
+
+ /* Force to change the control to native */
+ agent_info.native_server = g_malloc0(sizeof(bt_server_info_t));
+ agent_info.native_server->dest_path = g_strdup(dst_path);
+ agent_info.native_server->sender = g_strdup(sender);
+ agent_info.native_server->app_pid = app_pid;
+ agent_info.server_type = BT_NATIVE_SERVER;
+ _bt_unregister_osp_server_in_agent(BT_OBEX_SERVER, NULL);
+ } else {
+ if (agent_info.custom_server) {
+ BT_ERR("obex custom server busy");
+ g_free(dst_path);
+ return BLUETOOTH_ERROR_DEVICE_BUSY;
+ }
+
+ /* Force to change the control to custom */
+ agent_info.custom_server = g_malloc0(sizeof(bt_server_info_t));
+ agent_info.custom_server->dest_path = g_strdup(dst_path);
+ agent_info.custom_server->sender = g_strdup(sender);
+ agent_info.custom_server->app_pid = app_pid;
+ agent_info.server_type = BT_CUSTOM_SERVER;
+ _bt_register_osp_server_in_agent(BT_OBEX_SERVER, NULL, NULL, -1);
+ }
+
+ g_free(dst_path);
+ BT_DBG("-");
+ return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_obex_server_deallocate(int app_pid, gboolean is_native)
+{
+ if (is_native == TRUE) {
+ retv_if(agent_info.native_server == NULL,
+ BLUETOOTH_ERROR_AGENT_DOES_NOT_EXIST);
+
+ retv_if(agent_info.native_server->app_pid != app_pid,
+ BLUETOOTH_ERROR_ACCESS_DENIED);
+
+ __bt_free_server_info(agent_info.native_server);
+ agent_info.native_server = NULL;
+
+ /* Change the control to custom */
+ if (agent_info.custom_server) {
+ agent_info.server_type = BT_CUSTOM_SERVER;
+ _bt_register_osp_server_in_agent(BT_OBEX_SERVER,
+ NULL, NULL, -1);
+ }
+ } else {
+ retv_if(agent_info.custom_server == NULL,
+ BLUETOOTH_ERROR_AGENT_DOES_NOT_EXIST);
+
+ retv_if(agent_info.custom_server->app_pid != app_pid,
+ BLUETOOTH_ERROR_ACCESS_DENIED);
+
+ __bt_free_server_info(agent_info.custom_server);
+ agent_info.custom_server = NULL;
+
+ _bt_unregister_osp_server_in_agent(BT_OBEX_SERVER, NULL);
+
+ /* Change the control to native */
+ if (agent_info.native_server)
+ agent_info.server_type = BT_NATIVE_SERVER;
+ }
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_obex_server_accept_authorize(const char *filename, gboolean is_native)
+{
+ char file_path[BT_FILE_PATH_MAX] = { 0 };
+ bt_server_info_t *server_info;
+
+ BT_CHECK_PARAMETER(filename, return);
+
+ retv_if(agent_info.auth_info == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ retv_if(agent_info.auth_info->reply_context == NULL,
+ BLUETOOTH_ERROR_INTERNAL);
+
+ if (is_native == TRUE)
+ server_info = agent_info.native_server;
+ else
+ server_info = agent_info.custom_server;
+
+ retv_if(server_info == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ if (server_info->dest_path != NULL)
+ snprintf(file_path, sizeof(file_path), "%s/%s",
+ server_info->dest_path, filename);
+ else
+ snprintf(file_path, sizeof(file_path), "%s", filename);
+
+ g_dbus_method_invocation_return_value(agent_info.auth_info->reply_context,
+ g_variant_new("(s)", &file_path));
+ agent_info.auth_info->reply_context = NULL;
+ agent_info.auth_info->file_path = g_strdup(file_path);
+ g_free(agent_info.auth_info->filename);
+ agent_info.auth_info->filename = g_strdup(filename);
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+void _bt_obex_server_reply_accept(void)
+{
+ GVariant *param = NULL;
+ bt_session_info_t *session_info = NULL;
+ int result = BLUETOOTH_ERROR_NONE;
+ param = g_variant_new("(istss)", result,
+ agent_info.auth_info->filename,
+ agent_info.auth_info->file_size,
+ agent_info.auth_info->address,
+ agent_info.auth_info->device_name);
+ BT_INFO("Send Obex Authorize");
+ _bt_send_event(BT_OPP_SERVER_EVENT, BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_AUTHORIZE, param);
+
+ session_info = __bt_find_session_by_path(agent_info.auth_info->transfer_path);
+
+ if (NULL == session_info)
+ BT_ERR("Couldn't get the session info from the list");
+ else
+ session_info->authorized = TRUE;
+}
+
+int _bt_obex_server_reject_authorize(void)
+{
+ GError *g_error;
+
+ retv_if(agent_info.auth_info->reply_context == NULL,
+ BLUETOOTH_ERROR_INTERNAL);
+
+ g_error = g_error_new(__bt_obex_error_quark(),
+ BT_OBEX_AGENT_ERROR_CANCEL,
+ "CancelledByUser");
+
+ g_dbus_method_invocation_return_gerror(agent_info.auth_info->reply_context,
+ g_error);
+ g_error_free(g_error);
+
+ __bt_free_auth_info(agent_info.auth_info);
+ agent_info.auth_info = NULL;
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_obex_server_set_destination_path(const char *dest_path,
+ gboolean is_native)
+{
+ bt_server_info_t *server_info;
+ BT_CHECK_PARAMETER(dest_path, return);
+
+ char *dst_path;
+ dst_path = __bt_transfer_folder_path((char *)dest_path);
+
+ DIR *dp = NULL;
+
+ dp = opendir(dst_path);
+
+ if (dp == NULL) {
+ BT_ERR("The directory does not exist");
+ g_free(dst_path);
+ return BLUETOOTH_ERROR_INVALID_PARAM;
+ }
+
+ closedir(dp);
+
+ if (is_native == TRUE)
+ server_info = agent_info.native_server;
+ else
+ server_info = agent_info.custom_server;
+
+ if (!server_info) {
+ BT_ERR("obex server info is NULL");
+ g_free(dst_path);
+ return BLUETOOTH_ERROR_AGENT_DOES_NOT_EXIST;
+ }
+
+ g_free(server_info->dest_path);
+ server_info->dest_path = g_strdup(dst_path);
+
+ g_free(dst_path);
+ return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_obex_server_set_root(const char *root)
+{
+ GVariant *result = NULL;
+ GError *g_error = NULL;
+ GVariant *folder = NULL;
+ char *string = "Root";
+ DIR *dp = NULL;
+
+ BT_CHECK_PARAMETER(root, return);
+
+ char *dst_root;
+ dst_root = __bt_transfer_folder_path((char *)root);
+
+ if (!agent_info.proxy) {
+ BT_ERR("obex agent_info proxy error");
+ g_free(dst_root);
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ dp = opendir(dst_root);
+
+ if (dp == NULL) {
+ BT_ERR("The directory does not exist");
+ g_free(dst_root);
+ return BLUETOOTH_ERROR_INVALID_PARAM;
+ }
+
+ closedir(dp);
+
+ folder = g_variant_new_string(dst_root);
+ result = g_dbus_proxy_call_sync(agent_info.proxy, "SetProperty",
+ g_variant_new("(sv)", string, folder),
+ G_DBUS_CALL_FLAGS_NONE,
+ DBUS_TIMEOUT, NULL,
+ &g_error);
+
+ if (g_error) {
+ BT_ERR("SetProperty Fail: %s", g_error->message);
+ g_error_free(g_error);
+ g_free(dst_root);
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ if (result)
+ g_variant_unref(result);
+
+ g_free(dst_root);
+ return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_obex_server_cancel_transfer(int transfer_id)
+{
+ bt_transfer_info_t *transfer = NULL;
+ GDBusProxy *proxy;
+ GVariant *result = NULL;
+ GError *err = NULL;
+ BT_DBG("+");
+ transfer = __bt_find_transfer_by_id(transfer_id);
+
+ retv_if(transfer == NULL, BLUETOOTH_ERROR_NOT_FOUND);
+ proxy = __bt_get_transfer_proxy(transfer->path);
+
+ retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ result = g_dbus_proxy_call_sync(proxy, "Cancel", NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ DBUS_TIMEOUT, NULL, &err);
+ if (err) {
+ BT_ERR("Dbus Err: %s", err->message);
+ g_clear_error(&err);
+ }
+
+ g_object_unref(proxy);
+
+ if (result)
+ g_variant_unref(result);
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_obex_server_cancel_all_transfers(void)
+{
+ GSList *l;
+ bt_transfer_info_t *transfer;
+
+ for (l = transfers; l != NULL; l = l->next) {
+ transfer = l->data;
+
+ if (transfer == NULL)
+ continue;
+
+ _bt_obex_server_cancel_transfer(transfer->transfer_id);
+ }
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_obex_server_is_activated(gboolean *activated)
+{
+ BT_CHECK_PARAMETER(activated, return);
+
+ if (agent_info.custom_server)
+ *activated = TRUE;
+ else
+ *activated = FALSE;
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_obex_server_check_allocation(gboolean *allocation)
+{
+ BT_CHECK_PARAMETER(allocation, return);
+
+ if (agent_info.native_server || agent_info.custom_server)
+ *allocation = TRUE;
+ else
+ *allocation = FALSE;
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_obex_server_check_termination(char *sender)
+{
+ BT_CHECK_PARAMETER(sender, return);
+
+ if (agent_info.native_server) {
+ if (g_strcmp0(sender, agent_info.native_server->sender) == 0) {
+ _bt_obex_server_deallocate(agent_info.native_server->app_pid,
+ TRUE);
+ }
+ }
+
+ if (agent_info.custom_server) {
+ if (g_strcmp0(sender, agent_info.custom_server->sender) == 0) {
+ _bt_obex_server_deallocate(agent_info.custom_server->app_pid,
+ FALSE);
+ }
+ }
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_obex_server_is_receiving(gboolean *receiving)
+{
+ BT_CHECK_PARAMETER(receiving, return);
+
+ if (transfers == NULL || g_slist_length(transfers) == 0)
+ *receiving = FALSE;
+ else
+ *receiving = TRUE;
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+gboolean __bt_obex_server_accept_timeout_cb(gpointer user_data)
+{
+ request_info_t *req_info;
+ GVariant *out_param1 = NULL;
+ int result = BLUETOOTH_ERROR_TIMEOUT;
+
+ /* Already reply in _bt_obex_transfer_started */
+ retv_if(agent_info.accept_id == 0, FALSE);
+
+ req_info = _bt_get_request_info(agent_info.accept_id);
+ if (req_info == NULL || req_info->context == NULL) {
+ BT_ERR("info is NULL");
+ return FALSE;
+ }
+
+ agent_info.accept_id = 0;
+ GArray *g_out_param1 = NULL;
+ g_out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
+ if (out_param1 == NULL) {
+ out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
+ g_out_param1->data, g_out_param1->len,
+ TRUE, NULL, NULL);
+ }
+
+ g_dbus_method_invocation_return_value(req_info->context,
+ g_variant_new("(iv)", result, out_param1));
+ g_array_free(g_out_param1, TRUE);
+ _bt_delete_request_list(req_info->req_id);
+
+ return FALSE;
+}
+
+/* To support the BOT */
+int _bt_obex_server_accept_connection(int request_id)
+{
+ if (!_bt_agent_reply_authorize(TRUE))
+ return BLUETOOTH_ERROR_INTERNAL;
+
+ agent_info.accept_id = request_id;
+
+ g_timeout_add(BT_SERVER_ACCEPT_TIMEOUT,
+ (GSourceFunc)__bt_obex_server_accept_timeout_cb,
+ NULL);
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+/* To support the BOT */
+int _bt_obex_server_reject_connection(void)
+{
+ if (!_bt_agent_reply_authorize(FALSE))
+ return BLUETOOTH_ERROR_INTERNAL;
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_opp_get_server_progress(int transfer_id, guint8 *progress)
+{
+ bt_transfer_info_t *requested_transfer = NULL;
+ requested_transfer = __bt_find_transfer_by_id(transfer_id);
+ if (requested_transfer == NULL) {
+ BT_ERR("No Matching Inbound transfer");
+ return BLUETOOTH_ERROR_NOT_FOUND;
+ }
+
+ *progress = (int)(((double)requested_transfer->progress /
+ requested_transfer->file_size) * 100);
+
+ BT_DBG("Percentage: %d", *progress);
+ return BLUETOOTH_ERROR_NONE;
+}
--- /dev/null
+/*
+ * Bluetooth-frwk
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Hocheol Seo <hocheol.seo@samsung.com>
+ * Girishashok Joshi <girish.joshi@samsung.com>
+ * Chanyeol Park <chanyeol.park@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <glib.h>
+#include <dlog.h>
+#include <string.h>
+#include <gio/gio.h>
+
+#include "bluetooth-api.h"
+#include "bt-service-common.h"
+#include "bt-service-oob.h"
+#include "bt-service-event.h"
+
+static int __get_oob_data_from_variant(GVariant *variant,
+ unsigned char *buf, int size)
+{
+ int i;
+ unsigned char *v;
+
+ i = g_variant_get_size(variant);
+ v = (unsigned char *)g_variant_get_data(variant);
+ if (i && v) {
+ i = i > size ? size : i;
+ memcpy(buf, v, i);
+ }
+
+ return i;
+}
+
+int _bt_oob_read_local_data(bt_oob_data_t *local_oob_data)
+{
+ GDBusProxy *proxy;
+ GVariant *reply;
+ GError *err = NULL;
+ char *adapter_path;
+ GDBusConnection *conn;
+ GVariant *hash192 = NULL;
+ GVariant *randomizer192 = NULL;
+ GVariant *hash256 = NULL;
+ GVariant *randomizer256 = NULL;
+
+ BT_CHECK_PARAMETER(local_oob_data, return);
+
+ conn = _bt_gdbus_get_system_gconn();
+ retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ adapter_path = _bt_get_adapter_path();
+ retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ proxy = g_dbus_proxy_new_sync(conn,
+ G_DBUS_PROXY_FLAGS_NONE, NULL,
+ BT_BLUEZ_NAME, adapter_path,
+ BT_OOB_INTERFACE, NULL, &err);
+ g_free(adapter_path);
+ if (!proxy) {
+ BT_ERR("Unable to create proxy");
+ if (err) {
+ BT_ERR("Error: %s", err->message);
+ g_clear_error(&err);
+ }
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ reply = g_dbus_proxy_call_sync(proxy, "ReadLocalData",
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE, -1,
+ NULL, &err);
+ g_object_unref(proxy);
+
+ if (reply == NULL) {
+ BT_ERR("ReadLocalData dBUS-RPC is failed");
+ if (err != NULL) {
+ BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
+ err->code, err->message);
+ g_clear_error(&err);
+ }
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ g_variant_get(reply, "(@ay@ay@ay@ay)", &hash192, &randomizer192,
+ &hash256, &randomizer256);
+ g_variant_unref(reply);
+
+ if (hash192) {
+ local_oob_data->hash_len = __get_oob_data_from_variant(hash192,
+ local_oob_data->hash,
+ sizeof(local_oob_data->hash));
+ g_variant_unref(hash192);
+ }
+
+ if (randomizer192) {
+ local_oob_data->randomizer_len = __get_oob_data_from_variant(randomizer192,
+ local_oob_data->randomizer,
+ sizeof(local_oob_data->randomizer));
+ g_variant_unref(randomizer192);
+ }
+
+ if (hash256) {
+ local_oob_data->hash256_len = __get_oob_data_from_variant(hash256,
+ local_oob_data->hash256,
+ sizeof(local_oob_data->hash256));
+ g_variant_unref(hash256);
+ }
+
+ if (randomizer256) {
+ local_oob_data->randomizer256_len = __get_oob_data_from_variant(randomizer256,
+ local_oob_data->randomizer256,
+ sizeof(local_oob_data->randomizer256));
+ g_variant_unref(randomizer256);
+ }
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_oob_add_remote_data(
+ bluetooth_device_address_t *remote_device_address,
+ unsigned short address_type,
+ bt_oob_data_t *remote_oob_data)
+{
+ int i;
+ GDBusProxy *proxy;
+ GVariant *reply;
+ GError *err = NULL;
+ char *dev_addr;
+ char *adapter_path;
+ char address[BT_ADDRESS_STRING_SIZE] = { 0 };
+ unsigned char *remote_hash;
+ unsigned char *remote_randomizer;
+ GDBusConnection *conn;
+ GVariantBuilder *builder;
+ GVariantBuilder *builder2;
+ GVariant *hash192;
+ GVariant *randomizer192;
+ GVariant *hash256;
+ GVariant *randomizer256;
+
+ BT_CHECK_PARAMETER(remote_device_address, return);
+ BT_CHECK_PARAMETER(remote_oob_data, return);
+
+ conn = _bt_gdbus_get_system_gconn();
+ retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ adapter_path = _bt_get_adapter_path();
+ retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ _bt_convert_addr_type_to_string(address, remote_device_address->addr);
+
+ proxy = g_dbus_proxy_new_sync(conn,
+ G_DBUS_PROXY_FLAGS_NONE, NULL,
+ BT_BLUEZ_NAME, adapter_path,
+ BT_OOB_INTERFACE, NULL, &err);
+ g_free(adapter_path);
+ if (!proxy) {
+ BT_ERR("Unable to create proxy");
+ if (err) {
+ BT_ERR("Error: %s", err->message);
+ g_clear_error(&err);
+ }
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ BT_DBG("address type: %d", address_type);
+
+ /* Remote address */
+ dev_addr = g_strdup(address);
+
+ /* P-192 */
+ remote_hash = remote_oob_data->hash;
+ remote_randomizer = remote_oob_data->randomizer;
+
+ builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
+ builder2 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
+
+ for (i = 0; i < remote_oob_data->hash_len; i++)
+ g_variant_builder_add(builder, "y", remote_hash[i]);
+
+ for (i = 0; i < remote_oob_data->randomizer_len; i++)
+ g_variant_builder_add(builder2, "y", remote_randomizer[i]);
+
+ hash192 = g_variant_new("ay", builder);
+ randomizer192 = g_variant_new("ay", builder2);
+
+ g_variant_builder_unref(builder2);
+ g_variant_builder_unref(builder);
+
+ /* P-256 */
+ remote_hash = remote_oob_data->hash256;
+ remote_randomizer = remote_oob_data->randomizer256;
+
+ builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
+ builder2 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
+
+ for (i = 0; i < remote_oob_data->hash256_len; i++)
+ g_variant_builder_add(builder, "y", remote_hash[i]);
+
+ for (i = 0; i < remote_oob_data->randomizer256_len; i++)
+ g_variant_builder_add(builder2, "y", remote_randomizer[i]);
+
+ hash256 = g_variant_new("ay", builder);
+ randomizer256 = g_variant_new("ay", builder2);
+
+ g_variant_builder_unref(builder2);
+ g_variant_builder_unref(builder);
+
+ /* Call AddRemoteData Method */
+ reply = g_dbus_proxy_call_sync(proxy, "AddRemoteData",
+ g_variant_new("(sy@ay@ay@ay@ay)", dev_addr, address_type,
+ hash192, randomizer192, hash256, randomizer256),
+ G_DBUS_CALL_FLAGS_NONE, -1,
+ NULL, &err);
+ g_object_unref(proxy);
+ g_free(dev_addr);
+
+ BT_DBG("Add remote OOB data!!");
+
+ /* Check the reply */
+ if (reply == NULL) {
+ BT_ERR("AddRemoteData dBUS-RPC is failed");
+ if (err != NULL) {
+ BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
+ err->code, err->message);
+ g_clear_error(&err);
+ }
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+ g_variant_unref(reply);
+
+ BT_DBG("No error");
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_oob_remove_remote_data(
+ bluetooth_device_address_t *remote_device_address)
+{
+ GDBusProxy *proxy;
+ GVariant *reply;
+ GError *err = NULL;
+ char *dev_addr;
+ char *adapter_path;
+ char address[BT_ADDRESS_STRING_SIZE] = { 0 };
+ GDBusConnection *conn;
+
+ BT_CHECK_PARAMETER(remote_device_address, return);
+
+ conn = _bt_gdbus_get_system_gconn();
+ retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ adapter_path = _bt_get_adapter_path();
+ retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ _bt_convert_addr_type_to_string(address,
+ remote_device_address->addr);
+
+ proxy = g_dbus_proxy_new_sync(conn,
+ G_DBUS_PROXY_FLAGS_NONE, NULL,
+ BT_BLUEZ_NAME, adapter_path,
+ BT_OOB_INTERFACE, NULL, &err);
+ g_free(adapter_path);
+ if (!proxy) {
+ BT_ERR("Unable to create proxy");
+ if (err) {
+ BT_ERR("Error: %s", err->message);
+ g_clear_error(&err);
+ }
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ dev_addr = g_strdup(address);
+
+ /* Call RemoveRemoteData Method*/
+ reply = g_dbus_proxy_call_sync(proxy, "RemoveRemoteData",
+ g_variant_new("(s)", dev_addr),
+ G_DBUS_CALL_FLAGS_NONE, -1,
+ NULL, &err);
+ g_object_unref(proxy);
+ g_free(dev_addr);
+
+ /* Check the reply*/
+ if (reply == NULL) {
+ BT_ERR("RemoveRemoteData dBUS-RPC is failed");
+ if (err != NULL) {
+ BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
+ err->code, err->message);
+ g_clear_error(&err);
+ }
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ g_variant_unref(reply);
+ return BLUETOOTH_ERROR_NONE;
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <glib.h>
+#include <dlog.h>
+#include <string.h>
+#include <mime_type.h>
+#include <glib.h>
+#include <gio/gio.h>
+
+#include "bluetooth-api.h"
+#include "bt-internal-types.h"
+
+#include "bt-service-common.h"
+#include "bt-service-event.h"
+#include "bt-service-util.h"
+#include "bt-service-opp-client.h"
+#include "bt-service-obex-agent.h"
+#include "bt-service-core-adapter.h"
+
+
+#define BT_MIME_TYPE_MAX_LEN 20
+
+static GSList *transfer_list = NULL;
+bt_sending_info_t *sending_info;
+static int file_offset = 0;
+
+#define DBUS_TIEMOUT 20 * 1000 /* 20 Seconds */
+static gboolean __bt_sending_release();
+static int _bt_remove_session();
+
+static int __bt_opp_client_start_sending(int request_id, char *address,
+ char **file_name_array, int file_count);
+
+static GQuark __bt_opc_error_quark(void)
+{
+ static GQuark quark = 0;
+ if (!quark)
+ quark = g_quark_from_static_string("agent");
+
+ return quark;
+}
+
+static void __bt_free_transfer_info(bt_transfer_info_t *info)
+{
+ ret_if(info == NULL);
+
+ if (info->proxy)
+ g_object_unref(info->proxy);
+
+ if (info->properties_proxy)
+ g_object_unref(info->properties_proxy);
+
+
+ g_free(info->transfer_name);
+ g_free(info->file_name);
+ g_free(info);
+}
+
+static void __bt_free_sending_info(bt_sending_info_t *info)
+{
+ ret_if(info == NULL);
+
+ /* Free the sending variable */
+ __bt_free_transfer_info(info->transfer_info);
+
+ g_free(info->file_name_array);
+
+ g_free(info->address);
+ g_free(info);
+}
+
+static gboolean __bt_cancel_push_cb(gpointer data)
+{
+ BT_DBG("+");
+
+ int result = BLUETOOTH_ERROR_CANCEL_BY_USER;
+ GVariant *param = NULL;
+ retv_if(sending_info == NULL, FALSE);
+ sending_info->result = result;
+
+ param = g_variant_new("(isi)", result,
+ sending_info->address,
+ sending_info->request_id);
+ /* Send the event in only error none case */
+ _bt_send_event(BT_OPP_CLIENT_EVENT,
+ BLUETOOTH_EVENT_OPC_CONNECTED,
+ param);
+ __bt_free_sending_info(sending_info);
+ sending_info = NULL;
+
+ _bt_opp_client_event_deinit();
+
+ BT_DBG("Length of transfer list is %d", g_slist_length(transfer_list));
+
+ /*Operate remain works*/
+ if (g_slist_length(transfer_list) > 0) {
+ bt_sending_data_t *node = NULL;
+
+ node = transfer_list->data;
+ if (node == NULL) {
+ BT_ERR("data is NULL");
+ return FALSE;
+ }
+
+ transfer_list = g_slist_remove(transfer_list, node);
+
+ if (__bt_opp_client_start_sending(node->request_id,
+ node->address, node->file_path,
+ node->file_count) != BLUETOOTH_ERROR_NONE) {
+ BT_ERR("Fail to start sending");
+ }
+ }
+ BT_DBG("-");
+ return FALSE;
+}
+
+gboolean _bt_obex_client_progress(const char *transfer_path, guint64 transferred)
+{
+ BT_DBG("+");
+
+ int percentage_progress;
+ int previous_progress;
+ guint64 size;
+ int result = BLUETOOTH_ERROR_NONE;
+ GVariant *param = NULL;
+ retv_if(sending_info == NULL, TRUE);
+ retv_if(sending_info->transfer_info == NULL, TRUE);
+
+ if (g_strcmp0(sending_info->transfer_info->transfer_path,
+ transfer_path) != 0) {
+ BT_INFO("Path mismatch, previous transfer failed! Returning");
+ return FALSE;
+ }
+
+ size = sending_info->transfer_info->size;
+ if (size != 0)
+ percentage_progress = (int)(((gdouble)transferred /(gdouble)size) * 100);
+ else
+ percentage_progress = 0;
+
+ sending_info->transfer_info->transfer_status = BT_TRANSFER_STATUS_PROGRESS;
+ sending_info->result = result;
+
+ previous_progress = (int)(((gdouble)sending_info->transfer_info->progress /(gdouble)size) * 100);
+ if (percentage_progress == previous_progress &&
+ sending_info->transfer_info->progress) {
+ sending_info->transfer_info->progress = transferred;
+ return TRUE;
+ }
+ BT_DBG("Sending progress [prev %d] [curr %d]",
+ previous_progress, percentage_progress);
+
+ sending_info->transfer_info->progress = transferred;
+
+ /* Send the event in only error none case */
+ param = g_variant_new("(istii)", result,
+ sending_info->transfer_info->file_name,
+ sending_info->transfer_info->size,
+ percentage_progress,
+ sending_info->request_id);
+
+
+ _bt_send_event(BT_OPP_CLIENT_EVENT,
+ BLUETOOTH_EVENT_OPC_TRANSFER_PROGRESS,
+ param);
+ BT_DBG("-");
+
+ return TRUE;
+}
+
+gboolean _bt_obex_client_completed(const char *transfer_path, gboolean success)
+{
+ BT_DBG("+");
+
+ int result = BLUETOOTH_ERROR_NONE;
+ GVariant *param = NULL;
+ retv_if(sending_info == NULL, TRUE);
+ retv_if(sending_info->transfer_info == NULL, TRUE);
+
+ if (g_strcmp0(sending_info->transfer_info->transfer_path,
+ transfer_path) != 0) {
+ BT_INFO("Path mismatch, previous transfer failed! Returning");
+ return FALSE;
+ }
+
+ result = (success == TRUE) ? BLUETOOTH_ERROR_NONE : BLUETOOTH_ERROR_CANCEL;
+
+ sending_info->transfer_info->transfer_status = BT_TRANSFER_STATUS_COMPLETED;
+ sending_info->result = result;
+
+ if (!success) { /*In case of remote device reject, we need to send BLUETOOTH_EVENT_OPC_DISCONNECTED */
+ BT_DBG("completed with error");
+ if (!sending_info->is_canceled) {
+ param = g_variant_new("(issti)", result,
+ sending_info->address,
+ sending_info->transfer_info->file_name,
+ sending_info->transfer_info->size,
+ sending_info->request_id);
+ _bt_send_event(BT_OPP_CLIENT_EVENT,
+ BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
+ param);
+ __bt_free_transfer_info(sending_info->transfer_info);
+ sending_info->transfer_info = NULL;
+ /* Reset the file offset as we will cancelled remaining files also */
+ file_offset = 0;
+ }
+ param = g_variant_new("(isi)", sending_info->result,
+ sending_info->address,
+ sending_info->request_id);
+ _bt_send_event(BT_OPP_CLIENT_EVENT,
+ BLUETOOTH_EVENT_OPC_DISCONNECTED,
+ param);
+ __bt_sending_release();
+ /* Sending info should not freed after sending_release it's
+ * already freed in that API and if any pending request is
+ * present then it recreate sending_info again.
+ * And if we free it here then CreateSession method call will
+ * made but RemoveSession method call will not done.
+ */
+ } else {
+ BT_DBG("complete success");
+ /* Send the event in only error none case */
+ param = g_variant_new("(issti)", result,
+ sending_info->address,
+ sending_info->transfer_info->file_name,
+ sending_info->transfer_info->size,
+ sending_info->request_id);
+ _bt_send_event(BT_OPP_CLIENT_EVENT,
+ BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
+ param);
+ __bt_free_transfer_info(sending_info->transfer_info);
+ sending_info->transfer_info = NULL;
+ }
+
+ BT_DBG("-");
+
+ return TRUE;
+}
+
+gboolean _bt_obex_client_started(const char *transfer_path)
+{
+ BT_DBG("+");
+
+ int result = BLUETOOTH_ERROR_NONE;
+ GError *error = NULL;
+ GVariant *param = NULL;
+ GDBusConnection *g_conn;
+ GDBusProxy *properties_proxy;
+ GDBusProxy *transfer_proxy;
+
+ if (sending_info == NULL || sending_info->is_canceled == TRUE) {
+ result = BLUETOOTH_ERROR_CANCEL_BY_USER;
+ goto canceled;
+ }
+
+ /* Get the session bus. */
+ g_conn = _bt_get_session_gconn();
+ retv_if(g_conn == NULL, FALSE);
+ properties_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
+ NULL, BT_OBEXD_DBUS_NAME,
+ transfer_path, BT_PROPERTIES_INTERFACE,
+ NULL, &error);
+
+ retv_if(properties_proxy == NULL, FALSE);
+
+ sending_info->transfer_info->properties_proxy = properties_proxy;
+
+ transfer_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
+ NULL, BT_OBEXD_DBUS_NAME,
+ transfer_path, BT_OBEX_TRANSFER_INTERFACE,
+ NULL, &error);
+
+ retv_if(transfer_proxy == NULL, FALSE);
+
+ sending_info->transfer_info->proxy = transfer_proxy;
+
+ sending_info->transfer_info->transfer_status = BT_TRANSFER_STATUS_STARTED;
+ sending_info->result = result;
+
+ param = g_variant_new("(issti)", result,
+ sending_info->address,
+ sending_info->transfer_info->file_name,
+ sending_info->transfer_info->size,
+ sending_info->request_id);
+ _bt_send_event(BT_OPP_CLIENT_EVENT,
+ BLUETOOTH_EVENT_OPC_TRANSFER_STARTED,
+ param);
+
+ BT_DBG("-");
+ return TRUE;
+canceled:
+ error = g_error_new(__bt_opc_error_quark(), BT_OBEX_AGENT_ERROR_CANCEL,
+ "CancelledByUser");
+
+ g_error_free(error);
+
+ BT_DBG("-");
+ return FALSE;
+}
+
+static void __bt_free_sending_data(gpointer data)
+{
+ int i;
+ bt_sending_data_t *info = data;
+
+ ret_if(info == NULL);
+
+ for (i = 0; i < info->file_count; i++)
+ g_free(info->file_path[i]);
+
+ _bt_delete_request_id(info->request_id);
+
+ g_free(info->file_path);
+ g_free(info->address);
+ g_free(info);
+}
+
+static void __bt_sending_release_cb(GDBusProxy *proxy,
+ GAsyncResult *res, gpointer user_data)
+{
+ BT_DBG("+");
+ ret_if(sending_info == NULL);
+
+ GError *error = NULL;
+ int result = BLUETOOTH_ERROR_NONE;
+ GVariant *param = NULL;
+ GVariant *reply = NULL;
+
+ reply = g_dbus_proxy_call_finish(proxy, res, &error);
+ if (proxy)
+ g_object_unref(proxy);
+ if (reply)
+ g_variant_unref(reply);
+
+ if (error) {
+ BT_ERR("%s", error->message);
+ g_error_free(error);
+
+ result = BLUETOOTH_ERROR_INTERNAL;
+ } else {
+ file_offset = 0;
+ BT_DBG("Session Removed");
+ }
+
+ sending_info->result = result;
+ param = g_variant_new("(isi)", sending_info->result,
+ sending_info->address,
+ sending_info->request_id);
+ /* Send the event in only error none case */
+ _bt_send_event(BT_OPP_CLIENT_EVENT,
+ BLUETOOTH_EVENT_OPC_DISCONNECTED,
+ param);
+
+ __bt_free_sending_info(sending_info);
+ sending_info = NULL;
+
+ _bt_opp_client_event_deinit();
+
+ /* Operate remain works */
+ if (g_slist_length(transfer_list) > 0) {
+ bt_sending_data_t *data = NULL;
+
+ data = transfer_list->data;
+ if (data == NULL)
+ goto fail;
+
+ transfer_list = g_slist_remove(transfer_list, data);
+
+ BT_DBG("calling __bt_opp_client_start_sending");
+
+ if (__bt_opp_client_start_sending(data->request_id,
+ data->address, data->file_path,
+ data->file_count) != BLUETOOTH_ERROR_NONE) {
+ goto fail;
+ }
+ }
+
+ return;
+fail:
+ g_slist_free_full(transfer_list,
+ (GDestroyNotify)__bt_free_sending_data);
+ transfer_list = NULL;
+
+ BT_DBG("-");
+
+ return;
+}
+
+static int _bt_remove_session()
+{
+ GDBusConnection *g_conn;
+ GDBusProxy *session_proxy;
+ GError *err = NULL;
+
+ g_conn = _bt_get_session_gconn();
+ retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+ retv_if(sending_info->session_path == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
+
+ session_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
+ NULL, BT_OBEXD_DBUS_NAME,
+ BT_OBEX_CLIENT_PATH,
+ BT_OBEX_CLIENT_INTERFACE,
+ NULL, &err);
+
+ retv_if(session_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ g_dbus_proxy_call(session_proxy, "RemoveSession",
+ g_variant_new("(o)", sending_info->session_path),
+ G_DBUS_CALL_FLAGS_NONE,
+ DBUS_TIEMOUT, NULL,
+ (GAsyncReadyCallback)__bt_sending_release_cb,
+ NULL);
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+static gboolean __bt_sending_release()
+{
+ BT_DBG("+");
+
+ retv_if(sending_info == NULL, FALSE);
+
+ retv_if(_bt_remove_session() != BLUETOOTH_ERROR_NONE, FALSE);
+
+ BT_DBG("-");
+ return TRUE;
+}
+
+void _bt_opc_disconnected(const char *session_path)
+{
+ BT_DBG("+");
+ GVariant *param = NULL;
+ ret_if(sending_info == NULL);
+
+ if (g_strcmp0(sending_info->session_path,
+ session_path) != 0) {
+ BT_INFO("Path mismatch, previous transfer failed! Returning");
+ return;
+ }
+
+ if (sending_info->transfer_info) {
+ if (sending_info->transfer_info->transfer_status == BT_TRANSFER_STATUS_PROGRESS ||
+ sending_info->transfer_info->transfer_status == BT_TRANSFER_STATUS_STARTED) {
+ BT_INFO("Abnormal termination");
+ param = g_variant_new("(issti)", sending_info->result,
+ sending_info->address,
+ sending_info->transfer_info->file_name,
+ sending_info->transfer_info->size,
+ sending_info->request_id);
+ _bt_send_event(BT_OPP_CLIENT_EVENT,
+ BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
+ param);
+ __bt_free_transfer_info(sending_info->transfer_info);
+ }
+ }
+ param = g_variant_new("(isi)", sending_info->result,
+ sending_info->address,
+ sending_info->request_id);
+ _bt_send_event(BT_OPP_CLIENT_EVENT,
+ BLUETOOTH_EVENT_OPC_DISCONNECTED,
+ param);
+
+ __bt_free_sending_info(sending_info);
+ sending_info = NULL;
+
+ BT_DBG("-");
+}
+
+static void __bt_send_file_cb(GDBusProxy *proxy,
+ GAsyncResult *res, gpointer user_data)
+{
+ BT_DBG("+");
+ GVariant *value = NULL;
+ GError *error = NULL;
+ char *session_path = NULL;
+ const char *transfer_name = NULL;
+ const char *file_name = NULL;
+ int size = 0;
+ GVariantIter *iter = NULL;
+ value = g_dbus_proxy_call_finish(proxy, res, &error);
+ if (error) {
+ g_dbus_error_strip_remote_error(error);
+ BT_ERR("%s", error->message);
+ /* If Obex is not able to open a file then continue with other if any */
+ if (g_strcmp0("Unable to open file", error->message) == 0) {
+ GVariant *param = NULL;
+ gint64 size = 0;
+
+ BT_ERR("Unable to open file [%s]", sending_info->file_name_array[file_offset]);
+
+ param = g_variant_new("(issti)", BLUETOOTH_ERROR_NOT_FOUND,
+ sending_info->address,
+ sending_info->file_name_array[file_offset],
+ size,
+ sending_info->request_id);
+ _bt_send_event(BT_OPP_CLIENT_EVENT,
+ BLUETOOTH_EVENT_OPC_TRANSFER_STARTED,
+ param);
+
+ param = g_variant_new("(issti)", BLUETOOTH_ERROR_NOT_FOUND,
+ sending_info->address,
+ sending_info->file_name_array[file_offset],
+ size,
+ sending_info->request_id);
+ _bt_send_event(BT_OPP_CLIENT_EVENT,
+ BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
+ param);
+ g_error_free(error);
+ if (proxy)
+ g_object_unref(proxy);
+ file_offset++;
+ _bt_sending_files();
+ }
+ return;
+ }
+ if (proxy)
+ g_object_unref(proxy);
+
+ if (value) {
+ g_variant_get(value, "(oa{sv})", &session_path, &iter);
+ g_variant_unref(value);
+ }
+
+ __bt_free_transfer_info(sending_info->transfer_info);
+
+ sending_info->transfer_info = g_malloc0(sizeof(bt_transfer_info_t));
+
+ if (iter) {
+ const gchar *key;
+ GVariant *val;
+ gsize len = 0;
+ while (g_variant_iter_loop(iter, "{sv}", &key, &val)) {
+ if (g_strcmp0(key, "Name") == 0)
+ transfer_name = g_variant_dup_string(val, &len);
+ else if (g_strcmp0(key, "Filename") == 0)
+ file_name = g_variant_dup_string(val, &len);
+ else if (g_strcmp0(key, "Size") == 0)
+ size = g_variant_get_uint64(val);
+ }
+ g_variant_iter_free(iter);
+ }
+
+ sending_info->transfer_info->transfer_name = g_strdup(transfer_name);
+ sending_info->transfer_info->file_name = g_strdup(file_name);
+ sending_info->transfer_info->size = size;
+ sending_info->transfer_info->progress = 0;
+ sending_info->transfer_info->transfer_path = session_path;
+ sending_info->transfer_info->transfer_status = BT_TRANSFER_STATUS_QUEUED;
+ sending_info->result = BLUETOOTH_ERROR_NONE;
+ file_offset++;
+
+ g_free((gchar *)transfer_name);
+ g_free((gchar *)file_name);
+}
+
+void _bt_sending_files(void)
+{
+ BT_DBG("+");
+
+ GError *err = NULL;
+ GDBusConnection *g_conn;
+ GDBusProxy *client_proxy;
+ gchar *mime_type = NULL;
+
+ if (sending_info == NULL)
+ return;
+ if (file_offset < sending_info->file_count) {
+ /* Get the session bus. */
+ g_conn = _bt_get_session_gconn();
+ ret_if(g_conn == NULL);
+
+ client_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
+ NULL, BT_OBEXD_DBUS_NAME,
+ sending_info->session_path,
+ BT_OBEX_OBJECT_PUSH_INTERFACE,
+ NULL, &err);
+ ret_if(client_proxy == NULL);
+ if (mime_type_get_mime_type(sending_info->file_name_array[file_offset], &mime_type) == MIME_TYPE_ERROR_NONE) {
+ BT_DBG("MLME type = %s", mime_type);
+
+ /* For IOPT compliance, change "text/x-iMelody" to "audio/imelody"
+ * because few devices(multimedia players) reject the OPP put for text objects
+ * since they support only multimedia files exchange */
+ if (!strcasecmp(mime_type, "text/x-iMelody")) {
+ strncpy(mime_type, "audio/imelody", BT_MIME_TYPE_MAX_LEN);
+ BT_DBG("over writing mime type to = %s", mime_type);
+ }
+ if (!strcasecmp(mime_type, "text/vcard")) {
+ strncpy(mime_type, "text/x-vcard", BT_MIME_TYPE_MAX_LEN);
+ BT_DBG("over writing mime type to = %s", mime_type);
+ }
+ }
+
+ BT_DBG("Calling SendFile");
+ g_dbus_proxy_call(client_proxy, "SendFile",
+ g_variant_new("(ss)", sending_info->file_name_array[file_offset],
+ mime_type),
+ G_DBUS_CALL_FLAGS_NONE,
+ DBUS_TIEMOUT, NULL,
+ (GAsyncReadyCallback)__bt_send_file_cb,
+ sending_info);
+ if (err != NULL) {
+ BT_ERR("Calling SendFile failed: [%s]\n", err->message);
+ g_clear_error(&err);
+ g_free(mime_type);
+ return;
+ }
+
+ } else {
+ file_offset = 0;
+ __bt_sending_release();
+ }
+
+ g_free(mime_type);
+ BT_DBG("-");
+}
+
+static void __bt_create_session_cb(GDBusProxy *proxy,
+ GAsyncResult *res, gpointer user_data)
+{
+ BT_DBG("+");
+
+ GError *error = NULL;
+ GVariant *value;
+ int result = BLUETOOTH_ERROR_NONE;
+ char *session_path = NULL;
+ GVariant *param = NULL;
+
+ value = g_dbus_proxy_call_finish(proxy, res, &error);
+ if (value) {
+ g_variant_get(value, "(o)", &session_path);
+ g_variant_unref(value);
+ }
+ if (error) {
+
+ BT_ERR("%s", error->message);
+ g_clear_error(&error);
+
+ result = BLUETOOTH_ERROR_INTERNAL;
+ } else {
+ BT_DBG("Session created");
+ if (sending_info != NULL)
+ sending_info->session_path = g_strdup(session_path);
+ }
+ g_free(session_path);
+ g_object_unref(proxy);
+ ret_if(sending_info == NULL);
+
+ sending_info->result = result;
+ param = g_variant_new("(isi)", result,
+ sending_info->address,
+ sending_info->request_id);
+ /* Send the event in only error none case */
+ _bt_send_event(BT_OPP_CLIENT_EVENT,
+ BLUETOOTH_EVENT_OPC_CONNECTED,
+ param);
+
+ if (result != BLUETOOTH_ERROR_NONE) {
+ BT_ERR("Calling __bt_sending_release");
+ gboolean ret = __bt_sending_release();
+
+ __bt_free_sending_info(sending_info);
+ sending_info = NULL;
+
+ if (ret == FALSE) {
+ BT_DBG("ReleaseSession Not called");
+ /* Operate remain works */
+ if (g_slist_length(transfer_list) > 0) {
+ bt_sending_data_t *data = NULL;
+
+ data = transfer_list->data;
+ ret_if(data == NULL);
+
+ transfer_list = g_slist_remove(transfer_list, data);
+
+ BT_DBG("calling __bt_opp_client_start_sending");
+
+ if (__bt_opp_client_start_sending(data->request_id,
+ data->address, data->file_path,
+ data->file_count) != BLUETOOTH_ERROR_NONE) {
+ BT_ERR("Sending Enqueued Transfer Failed");
+ }
+ }
+ }
+ } else {
+ BT_DBG("Calling sending_files");
+ _bt_sending_files();
+ }
+ BT_DBG("-");
+
+}
+
+static int __bt_opp_client_start_sending(int request_id, char *address,
+ char **file_name_array, int file_count)
+{
+ GVariantBuilder *builder;
+ int i;
+ GDBusConnection *g_conn;
+ GDBusProxy *client_proxy;
+ GError *error = NULL;
+ BT_DBG("+");
+
+ BT_CHECK_PARAMETER(address, return);
+ BT_CHECK_PARAMETER(file_name_array, return);
+
+ /* Get the session bus. */
+ g_conn = _bt_get_session_gconn();
+ retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ client_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
+ NULL, BT_OBEX_SERVICE_NAME,
+ BT_OBEX_CLIENT_PATH,
+ BT_OBEX_CLIENT_INTERFACE,
+ NULL, &error);
+
+ if (error) {
+ BT_ERR("Unable to create client proxy: %s", error->message);
+ g_clear_error(&error);
+ }
+
+ retv_if(client_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ builder = g_variant_builder_new(
+ G_VARIANT_TYPE("a{sv}"));
+
+ g_variant_builder_add(builder, "{sv}", "Target",
+ g_variant_new_string("OPP"));
+
+ __bt_free_sending_info(sending_info);
+
+ sending_info = g_malloc0(sizeof(bt_sending_info_t));
+ sending_info->address = g_strdup(address);
+ sending_info->request_id = request_id;
+
+ sending_info->file_count = file_count;
+ sending_info->file_offset = 0;
+ sending_info->file_name_array = g_new0(char *, file_count + 1);
+
+ for (i = 0; i < file_count; i++) {
+ sending_info->file_name_array[i] = g_strdup(file_name_array[i]);
+ BT_DBG("file[%d]: %s", i, sending_info->file_name_array[i]);
+ }
+
+ _bt_opp_client_event_deinit();
+ _bt_opp_client_event_init();
+ //_bt_obex_client_started(agent_path);
+
+ BT_DBG("Adapter Status %d", _bt_adapter_get_status());
+ if (_bt_adapter_get_status() == BT_ACTIVATED) {
+ BT_DBG("Going to call CreateSession");
+ g_dbus_proxy_call(client_proxy, "CreateSession",
+ g_variant_new("(sa{sv})", address, builder),
+ G_DBUS_CALL_FLAGS_NONE,
+ DBUS_TIEMOUT, NULL,
+ (GAsyncReadyCallback)__bt_create_session_cb,
+ NULL);
+ } else {
+ GVariant *param = g_variant_new("(isi)", BLUETOOTH_ERROR_INTERNAL,
+ sending_info->address, sending_info->request_id);
+
+ BT_DBG("Address[%s] RequestID[%d]", sending_info->address, sending_info->request_id);
+ _bt_send_event(BT_OPP_CLIENT_EVENT, BLUETOOTH_EVENT_OPC_CONNECTED,
+ param);
+ __bt_free_sending_info(sending_info);
+ sending_info = NULL;
+ }
+ g_variant_builder_unref(builder);
+
+ BT_DBG("-");
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_opp_client_push_files(int request_id, GDBusMethodInvocation *context,
+ bluetooth_device_address_t *remote_address,
+ char **file_path, int file_count)
+{
+ BT_DBG("+");
+ char address[BT_ADDRESS_STRING_SIZE] = { 0 };
+ bt_sending_data_t *data;
+
+ GVariant *out_param1 = NULL;
+
+ int result = BLUETOOTH_ERROR_NONE;
+ int i;
+
+ BT_CHECK_PARAMETER(remote_address, return);
+ BT_CHECK_PARAMETER(file_path, return);
+
+ /* Implement the queue */
+ _bt_convert_addr_type_to_string(address, remote_address->addr);
+
+ if (sending_info == NULL) {
+ result = __bt_opp_client_start_sending(request_id,
+ address, file_path, file_count);
+ if (result != BLUETOOTH_ERROR_NONE)
+ return result;
+ } else {
+ /* Insert data in the queue */
+ data = g_malloc0(sizeof(bt_sending_data_t));
+ data->file_path = g_new0(char *, file_count + 1);
+ data->address = g_strdup(address);
+ data->file_count = file_count;
+ data->request_id = request_id;
+
+ for (i = 0; i < file_count; i++) {
+ data->file_path[i] = g_strdup(file_path[i]);
+ DBG_SECURE("file[%d]: %s", i, data->file_path[i]);
+ }
+
+ transfer_list = g_slist_append(transfer_list, data);
+ }
+
+ out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
+ &request_id, sizeof(int),
+ TRUE, NULL, NULL);
+
+
+ g_dbus_method_invocation_return_value(context,
+ g_variant_new("(iv)", result, out_param1));
+
+ BT_DBG("-");
+
+ return result;
+}
+
+int _bt_opp_client_cancel_push(void)
+{
+ BT_DBG("+");
+
+ GError *err = NULL;
+ int result = BLUETOOTH_ERROR_CANCEL_BY_USER;
+ GVariant *ret = NULL;
+ GVariant *param = NULL;
+ retv_if(sending_info == NULL, BLUETOOTH_ERROR_NOT_IN_OPERATION);
+
+ sending_info->is_canceled = TRUE;
+ sending_info->result = result;
+
+ if (sending_info->transfer_info) {
+
+ ret = g_dbus_proxy_call_sync(sending_info->transfer_info->proxy,
+ "Cancel", NULL,
+ G_DBUS_CALL_FLAGS_NONE, -1,
+ NULL, &err);
+ if (ret == NULL) {
+ if (err != NULL) {
+ BT_ERR("Cancel Error: %s\n", err->message);
+ g_error_free(err);
+ }
+ } else {
+ g_variant_unref(ret);
+ }
+
+ param = g_variant_new("(issti)", result,
+ sending_info->address,
+ sending_info->transfer_info->file_name,
+ sending_info->transfer_info->size,
+ sending_info->request_id);
+ _bt_send_event(BT_OPP_CLIENT_EVENT,
+ BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
+ param);
+
+ if (result == BLUETOOTH_ERROR_CANCEL_BY_USER) {
+ BT_ERR("result is not BLUETOOTH_ERROR_NONE");
+ __bt_sending_release();
+ file_offset = 0;
+ }
+
+ } else {
+ g_idle_add(__bt_cancel_push_cb, NULL);
+ }
+
+ BT_DBG("-");
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_opp_client_cancel_all_transfers(void)
+{
+ BT_DBG("+");
+ if (transfer_list) {
+ g_slist_free_full(transfer_list,
+ (GDestroyNotify)__bt_free_sending_data);
+
+ transfer_list = NULL;
+ }
+
+ _bt_opp_client_cancel_push();
+ BT_DBG("-");
+ return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_opp_client_is_sending(gboolean *sending)
+{
+ BT_CHECK_PARAMETER(sending, return);
+
+ *sending = sending_info ? TRUE : FALSE;
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+void _bt_opp_client_check_pending_transfer(const char *address)
+{
+ BT_DBG("+");
+
+ int result = BLUETOOTH_ERROR_CANCEL;
+ GVariant *param = NULL;
+ ret_if(sending_info == NULL);
+ ret_if(sending_info->transfer_info == NULL);
+
+ if (g_strcmp0(sending_info->address, address) == 0) {
+ BT_INFO("Address Match.Cancel current transfer");
+ sending_info->transfer_info->transfer_status = BT_TRANSFER_STATUS_COMPLETED;
+ sending_info->result = result;
+
+ if (!sending_info->is_canceled) {
+ param = g_variant_new("(issti)", result,
+ sending_info->address,
+ sending_info->transfer_info->file_name,
+ sending_info->transfer_info->size,
+ sending_info->request_id);
+ _bt_send_event(BT_OPP_CLIENT_EVENT,
+ BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
+ param);
+ __bt_free_transfer_info(sending_info->transfer_info);
+ sending_info->transfer_info = NULL;
+ /* Reset the file offset as we will cancelled remaining files also */
+ file_offset = 0;
+ }
+ param = g_variant_new("(isi)", sending_info->result,
+ sending_info->address,
+ sending_info->request_id);
+ _bt_send_event(BT_OPP_CLIENT_EVENT,
+ BLUETOOTH_EVENT_OPC_DISCONNECTED,
+ param);
+
+ __bt_sending_release();
+ }
+ BT_DBG("-");
+}
+
+int _bt_opp_get_client_progress(guint8 *progress)
+{
+ if (sending_info == NULL || sending_info->transfer_info == NULL) {
+ BT_ERR("No Active Outbound transfer");
+ return BLUETOOTH_ERROR_NOT_FOUND;
+ }
+
+ *progress = (int)(((double)sending_info->transfer_info->progress /
+ sending_info->transfer_info->size) * 100);
+
+ BT_DBG("Percentage: %d", *progress);
+ return BLUETOOTH_ERROR_NONE;
+}
+
+void _bt_cancel_queued_transfers(void)
+{
+ bt_sending_data_t *data = NULL;
+ GVariant *param = NULL;
+
+ BT_INFO("Cancel queued Transfers:: Length of transfer list is %d",
+ g_slist_length(transfer_list));
+
+ while (transfer_list) {
+ data = transfer_list->data;
+ param = g_variant_new("(isi)", BLUETOOTH_ERROR_INTERNAL,
+ data->address, data->request_id);
+
+ BT_DBG("Address[%s] RequestID[%d]", data->address, data->request_id);
+ _bt_send_event(BT_OPP_CLIENT_EVENT, BLUETOOTH_EVENT_OPC_CONNECTED,
+ param);
+
+ transfer_list = g_slist_remove(transfer_list, data);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <malloc.h>
+#include <stacktrim.h>
+#include <syspopup_caller.h>
+#include <vconf.h>
+#include <storage.h>
+
+#include "bt-internal-types.h"
+#include "bt-service-common.h"
+#include "bt-service-event.h"
+#include "bt-service-pbap.h"
+#include <glib.h>
+#include <gio/gio.h>
+
+#define PBAP_OBEX_CLIENT_SERVICE "org.bluez.obex"
+#define PBAP_OBEX_CLIENT_PATH "/org/bluez/obex"
+#define PBAP_OBEX_CLIENT_INTERFACE "org.bluez.obex.Client1"
+
+#define PBAP_SESSION_SERVICE "org.bluez.obex"
+#define PBAP_SESSION_INTERFACE "org.bluez.obex.PhonebookAccess1"
+#define PBAP_VCARDLIST_MAXLENGTH 256
+
+#define PBAP_NUM_OF_FIELDS_ENTRY 29
+#define PBAP_FIELD_ALL (0xFFFFFFFFFFFFFFFFULL)
+
+#define PBAP_DEFAULT_DOWNLAOD_PATH "/opt/usr/home/owner/media/Downloads"
+#define PBAP_DEFAULT_FILE_NAME "pb.vcf"
+
+char *FIELDS[] = {
+ "VERSION",
+ "FN",
+ "N",
+ "PHOTO",
+ "BDAY",
+ "ADR",
+ "LABEL",
+ "TEL",
+ "EMAIL",
+ "MAILER",
+ "TZ",
+ "GEO",
+ "TITLE",
+ "ROLE",
+ "LOGO",
+ "AGENT",
+ "ORG",
+ "NOTE",
+ "REV",
+ "SOUND",
+ "URL",
+ "UID",
+ "KEY",
+ "NICKNAME",
+ "CATEGORIES",
+ "PROID",
+ "CLASS",
+ "SORT-STRING",
+ "X-IRMC-CALL-DATETIME", /* 29 */
+};
+
+char *SOURCE[] = {
+ "int", //Phone memory
+ "sim" // SIM memory
+};
+
+char *TYPE[] = {
+ "pb", //Phonebook for the saved contacts
+ "ich", //Incoming call history
+ "och", //Outgoing call history
+ "mch", //Missed call history
+ "cch", //Combined Call History cch = ich + och + mch
+};
+
+char *FORMAT[] = {
+ "vcard21", // vCard Format 2.1 (Default)
+ "vcard30", // vCard Format 3.0
+};
+
+char *ORDER[] = {
+ "indexed", // Index (default)
+ "alphanumeric", // Alphanumeric
+ "phonetic", // Phonetic
+};
+
+char *SEARCH_FIELD[] = {
+ "name", // Search by Name(default)
+ "number", // Search by Phone Number
+ "sound", // Search by phonetic sound
+};
+
+static char *g_pbap_session_path = NULL;
+static char *g_pbap_server_address = NULL;
+static GDBusProxy *g_pbap_proxy = NULL;
+
+static struct {
+ int type;
+ int folder;
+} selected_path = { -1, -1};
+
+typedef enum {
+ PBAP_NONE,
+ GET_SIZE,
+ PULL_ALL,
+ GET_LIST,
+ GET_VCARD,
+ PB_SEARCH,
+} bt_pbap_operation_e;
+
+typedef struct {
+ bt_pbap_operation_e operation;
+ void *data;
+ void *app_param;
+} bt_pbap_data_t;
+
+typedef struct {
+ char *path;
+ char *filename;
+ char *remote_device;
+ bt_pbap_operation_e operation;
+} bt_pbap_transfer_info_t;
+
+static GSList *transfers;
+
+int __bt_pbap_call_get_phonebook_size(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
+int __bt_pbap_call_get_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
+int __bt_pbap_call_get_vcards_list(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
+int __bt_pbap_call_get_vcard(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
+int __bt_pbap_call_search_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
+
+static void __bt_pbap_free_data(bt_pbap_data_t *pbap_data)
+{
+ g_free(pbap_data->app_param);
+ g_free(pbap_data->data);
+ g_free(pbap_data);
+}
+
+static bt_pbap_transfer_info_t *__bt_find_transfer_by_path(const char *transfer_path)
+{
+ GSList *l;
+ bt_pbap_transfer_info_t *transfer;
+
+ retv_if(transfer_path == NULL, NULL);
+
+ for (l = transfers; l != NULL; l = l->next) {
+ transfer = l->data;
+
+ if (transfer == NULL)
+ continue;
+
+ if (g_strcmp0(transfer->path, transfer_path) == 0)
+ return transfer;
+ }
+
+ return NULL;
+}
+
+static void __bt_free_transfer_info(bt_pbap_transfer_info_t *transfer_info)
+{
+ ret_if(transfer_info == NULL);
+
+ g_free(transfer_info->path);
+ g_free(transfer_info->filename);
+ g_free(transfer_info->remote_device);
+ g_free(transfer_info);
+}
+
+void _bt_pbap_obex_transfer_completed(const char *transfer_path, gboolean transfer_status)
+{
+ bt_pbap_transfer_info_t *transfer_info;
+ int result = 0;
+ int success = transfer_status;
+ GVariant *signal = NULL;
+ BT_DBG("Transfer [%s] Success [%d] \n", transfer_path, success);
+
+ result = (success == TRUE) ? BLUETOOTH_ERROR_NONE
+ : BLUETOOTH_ERROR_INTERNAL;
+
+ transfer_info = __bt_find_transfer_by_path(transfer_path);
+ ret_if(transfer_info == NULL);
+
+ BT_DBG("Remote Device [%s] FileName: [%s] Operation[%d]",
+ transfer_info->remote_device, transfer_info->filename,
+ transfer_info->operation);
+
+ signal = g_variant_new("(issi)", result,
+ transfer_info->remote_device,
+ transfer_info->filename, success);
+ switch (transfer_info->operation) {
+ case PULL_ALL: {
+ _bt_send_event(BT_PBAP_CLIENT_EVENT,
+ BLUETOOTH_PBAP_PHONEBOOK_PULL,
+ signal);
+ break;
+ }
+ case GET_VCARD: {
+ _bt_send_event(BT_PBAP_CLIENT_EVENT,
+ BLUETOOTH_PBAP_VCARD_PULL,
+ signal);
+ break;
+ }
+ default:
+ BT_INFO("Case not handled");
+ break;
+
+ }
+
+ transfers = g_slist_remove(transfers, transfer_info);
+ __bt_free_transfer_info(transfer_info);
+}
+
+void _bt_obex_pbap_client_disconnect(char *path)
+{
+ if (g_strcmp0(g_pbap_session_path, path) == 0) {
+ int result = BLUETOOTH_ERROR_NONE;
+ GVariant *signal = g_variant_new("(is)", result,
+ g_pbap_server_address);
+
+ _bt_send_event(BT_PBAP_CLIENT_EVENT,
+ BLUETOOTH_PBAP_DISCONNECTED,
+ signal);
+
+ g_free(g_pbap_session_path);
+ g_pbap_session_path = NULL;
+
+ g_free(g_pbap_server_address);
+ g_pbap_server_address = NULL;
+
+ g_object_unref(g_pbap_proxy);
+ g_pbap_proxy = NULL;
+
+ selected_path.folder = -1;
+ selected_path.type = -1;
+ }
+ BT_DBG("-");
+}
+
+void __bt_pbap_connect_cb(GDBusProxy *proxy,
+ GAsyncResult *res, gpointer user_data)
+{
+ char *session_path = NULL;
+ char *address_string = user_data;
+ GError *error = NULL;
+ GVariant *value;
+ GVariant *signal = NULL;
+ int result = BLUETOOTH_ERROR_INTERNAL;
+
+ value = g_dbus_proxy_call_finish(proxy, res, &error);
+ BT_DBG("Address = %s", address_string);
+
+ if (value == NULL) {
+ BT_ERR("g_dbus_proxy_call_finish failed");
+ if (error) {
+ BT_ERR("errCode[%x], message[%s]\n",
+ error->code, error->message);
+ g_clear_error(&error);
+ }
+ g_object_unref(g_pbap_proxy);
+ g_pbap_proxy = NULL;
+ } else {
+ g_variant_get(value, "(&o)", &session_path);
+
+ g_pbap_session_path = g_strdup(session_path);
+ BT_DBG("Session Path = %s\n", g_pbap_session_path);
+ result = BLUETOOTH_ERROR_NONE;
+ g_pbap_server_address = g_strdup(address_string);
+
+ g_variant_unref(value);
+ }
+
+ signal = g_variant_new("(is)", result, address_string);
+
+ _bt_send_event(BT_PBAP_CLIENT_EVENT,
+ BLUETOOTH_PBAP_CONNECTED,
+ signal);
+
+ g_free(address_string);
+ BT_DBG("-");
+}
+
+int _bt_pbap_connect(const bluetooth_device_address_t *address)
+{
+ BT_DBG("+");
+ GDBusConnection *g_conn;
+ GError *error = NULL;
+ char address_string[18] = { 0, };
+ char *ptr = NULL;
+ GVariantBuilder builder;
+ GVariant *args;
+
+ BT_CHECK_PARAMETER(address, return);
+
+ /* check if already connected */
+ if (g_pbap_session_path)
+ return BLUETOOTH_ERROR_ALREADY_CONNECT;
+
+ BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
+ address->addr[0], address->addr[1],
+ address->addr[2], address->addr[3],
+ address->addr[4], address->addr[5]);
+
+ _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
+ BT_DBG("Address String: %s", address_string);
+ g_conn = _bt_get_session_gconn();
+ if (g_conn == NULL) {
+ BT_ERR("Couldn't connect to session bus");
+ return EXIT_FAILURE;
+ }
+ g_pbap_proxy = g_dbus_proxy_new_sync(g_conn,
+ G_DBUS_PROXY_FLAGS_NONE, NULL,
+ PBAP_OBEX_CLIENT_SERVICE, PBAP_OBEX_CLIENT_PATH,
+ PBAP_OBEX_CLIENT_INTERFACE, NULL, &error);
+ if (!g_pbap_proxy) {
+ BT_ERR("Failed to get a proxy for D-Bus\n");
+ if (error) {
+ ERR("Unable to create proxy: %s", error->message);
+ g_clear_error(&error);
+ }
+ return -1;
+ }
+
+ /* Create Hash*/
+ g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
+ g_variant_builder_add(&builder, "{sv}", "Target",
+ g_variant_new("s", "pbap"));
+ args = g_variant_builder_end(&builder);
+
+ ptr = g_strdup(address_string);
+
+ GVariant *temp = g_variant_new("(s@a{sv})", ptr, args);
+
+ g_dbus_proxy_call(g_pbap_proxy, "CreateSession",
+ temp,
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL,
+ (GAsyncReadyCallback)__bt_pbap_connect_cb, ptr);
+
+ BT_DBG("-");
+ return 0;
+}
+
+void __bt_pbap_disconnect_cb(GDBusProxy *proxy,
+ GAsyncResult *res, gpointer user_data)
+{
+ char *address_string = user_data;
+ GError *error = NULL;
+ GVariant *value;
+ int result = BLUETOOTH_ERROR_INTERNAL ;
+
+ BT_DBG("Address = %s", address_string);
+
+ value = g_dbus_proxy_call_finish(proxy, res, &error);
+ BT_DBG("Address = %s", address_string);
+
+ if (value == NULL) {
+ BT_ERR("g_dbus_proxy_call_finish failed");
+ if (error) {
+ BT_ERR("errCode[%x], message[%s]\n",
+ error->code, error->message);
+ g_clear_error(&error);
+ }
+ } else {
+ g_object_unref(g_pbap_proxy);
+ g_pbap_proxy = NULL;
+
+ g_free(g_pbap_session_path);
+ g_pbap_session_path = NULL;
+
+ g_free(g_pbap_server_address);
+ g_pbap_server_address = NULL;
+
+ result = BLUETOOTH_ERROR_NONE;
+ selected_path.folder = -1;
+ selected_path.type = -1;
+
+ g_variant_unref(value);
+ }
+
+ /* If the result is success, the event reciever will send the disconnect event */
+ if (result != BLUETOOTH_ERROR_NONE) {
+ GVariant *signal = NULL;
+
+ signal = g_variant_new("(is)", result, address_string);
+ _bt_send_event(BT_PBAP_CLIENT_EVENT,
+ BLUETOOTH_PBAP_DISCONNECTED,
+ signal);
+ }
+
+ g_free(address_string);
+ BT_DBG("-");
+}
+
+int _bt_pbap_disconnect(const bluetooth_device_address_t *address)
+{
+ BT_DBG("+");
+ char address_string[18] = { 0, };
+ char *ptr = NULL;
+ BT_CHECK_PARAMETER(address, return);
+
+ /* check if connected */
+ if (g_pbap_session_path == NULL)
+ return BLUETOOTH_ERROR_NOT_CONNECTED;
+
+ BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
+ address->addr[0], address->addr[1],
+ address->addr[2], address->addr[3],
+ address->addr[4], address->addr[5]);
+
+ _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
+ BT_DBG("Address String: %s", address_string);
+ BT_DBG("Session Path: %s", g_pbap_session_path);
+
+ ptr = g_strdup(address_string);
+
+ g_dbus_proxy_call(g_pbap_proxy, "RemoveSession",
+ g_variant_new("(o)", g_pbap_session_path),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL,
+ (GAsyncReadyCallback)__bt_pbap_disconnect_cb, ptr);
+
+ return 0;
+}
+
+void __bt_pbap_select_cb(GDBusProxy *proxy,
+ GAsyncResult *res, gpointer user_data)
+{
+ BT_DBG("+");
+ GError *error = NULL;
+ GVariant *value;
+ bt_pbap_data_t *pbap_data = user_data;
+ char *address_string = pbap_data->data;
+
+ BT_DBG("Address = %s", address_string);
+
+ value = g_dbus_proxy_call_finish(proxy, res, &error);
+ if (value == NULL) {
+ BT_ERR("g_dbus_proxy_call_finish failed");
+ if (error) {
+ BT_ERR("errCode[%x], message[%s]\n",
+ error->code, error->message);
+ g_clear_error(&error);
+ }
+
+ selected_path.folder = -1;
+ selected_path.type = -1;
+
+ g_object_unref(proxy);
+ __bt_pbap_free_data(pbap_data);
+ return;
+ }
+
+ switch (pbap_data->operation) {
+ case GET_SIZE: {
+ __bt_pbap_call_get_phonebook_size(proxy, pbap_data);
+ break;
+ }
+ case PULL_ALL: {
+ __bt_pbap_call_get_phonebook(proxy, pbap_data);
+ break;
+ }
+ case GET_LIST: {
+ __bt_pbap_call_get_vcards_list(proxy, pbap_data);
+ break;
+ }
+ case GET_VCARD: {
+ __bt_pbap_call_get_vcard(proxy, pbap_data);
+ break;
+ }
+ case PB_SEARCH: {
+ __bt_pbap_call_search_phonebook(proxy, pbap_data);
+ break;
+ }
+ default: {
+ selected_path.folder = -1;
+ selected_path.type = -1;
+ g_object_unref(proxy);
+ __bt_pbap_free_data(pbap_data);
+ }
+ } // End of Case
+
+ g_variant_unref(value);
+ BT_DBG("-");
+}
+
+
+void __bt_pbap_get_phonebook_size_cb(GDBusProxy *proxy,
+ GAsyncResult *res, gpointer user_data)
+{
+ BT_DBG("+");
+ GError *error = NULL;
+ int result = BLUETOOTH_ERROR_INTERNAL;
+ bt_pbap_data_t *pbap_data = user_data;
+ char *address_string = pbap_data->data;
+ unsigned short int size = 0;
+ GVariant *value;
+ GVariant *signal = NULL;
+
+ BT_DBG("Address = %s", address_string);
+ value = g_dbus_proxy_call_finish(proxy, res, &error);
+
+ if (value == NULL) {
+ BT_ERR("g_dbus_proxy_call_finish failed");
+ if (error) {
+ BT_ERR("errCode[%x], message[%s]\n",
+ error->code, error->message);
+ g_clear_error(&error);
+ }
+ } else {
+ g_variant_get(value, "(q)", &size);
+ result = BLUETOOTH_ERROR_NONE;
+ }
+
+ BT_DBG("Size of Phonebook: %d", size);
+
+ signal = g_variant_new("(isi)", result, address_string, size);
+ _bt_send_event(BT_PBAP_CLIENT_EVENT,
+ BLUETOOTH_PBAP_PHONEBOOK_SIZE,
+ signal);
+
+ g_variant_unref(value);
+ g_object_unref(proxy);
+ __bt_pbap_free_data(pbap_data);
+ BT_DBG("-");
+}
+
+void __bt_pbap_get_phonebook_cb(GDBusProxy *proxy,
+ GAsyncResult *res, gpointer user_data)
+{
+ BT_DBG("+");
+ GError *error = NULL;
+ bt_pbap_data_t *pbap_data = user_data;
+ char *address_string = pbap_data->data;
+ bt_pbap_transfer_info_t *transfer_info;
+ char *transfer = NULL;
+ const gchar *filename = NULL;
+ GVariant *value;
+ GVariant *properties;
+
+ BT_DBG("Address = %s", address_string);
+ value = g_dbus_proxy_call_finish(proxy, res, &error);
+ if (value == NULL) {
+ BT_ERR("g_dbus_proxy_call_finish failed");
+ if (error) {
+ BT_ERR("errCode[%x], message[%s]\n",
+ error->code, error->message);
+ g_clear_error(&error);
+ }
+ } else {
+ g_variant_get(value, "(o@a{sv})", &transfer, &properties);
+
+ if (g_variant_lookup(properties, "Filename", "s", &filename) == FALSE)
+ filename = NULL;
+
+ BT_DBG("Transfer Path: %s", transfer);
+ BT_DBG("File Name: %s", filename);
+ transfer_info = g_new0(bt_pbap_transfer_info_t, 1);
+ transfer_info->path = transfer;
+ transfer_info->remote_device = g_strdup(address_string);
+ transfer_info->filename = (char *)filename;
+ transfer_info->operation = PULL_ALL;
+ transfers = g_slist_append(transfers, transfer_info);
+
+ g_variant_unref(value);
+ }
+
+ g_object_unref(proxy);
+ __bt_pbap_free_data(pbap_data);
+ BT_DBG("-");
+}
+
+void __bt_pbap_get_vcard_list_cb(GDBusProxy *proxy,
+ GAsyncResult *res, gpointer user_data)
+{
+ BT_DBG("+");
+ GError *error = NULL;
+ int i;
+ int result = BLUETOOTH_ERROR_INTERNAL;
+ bt_pbap_data_t *pbap_data = user_data;
+ char *address_string = pbap_data->data;
+ char **vcard_list = NULL;
+ char list_entry[PBAP_VCARDLIST_MAXLENGTH] = { 0, };
+ int length = 0;
+ GVariant *value;
+ GVariant *signal = NULL;
+
+ value = g_dbus_proxy_call_finish(proxy, res, &error);
+ if (value == NULL) {
+ BT_ERR("g_dbus_proxy_call_finish failed");
+ if (error) {
+ BT_ERR("errCode[%x], message[%s]\n",
+ error->code, error->message);
+ g_clear_error(&error);
+ }
+ } else {
+ result = BLUETOOTH_ERROR_NONE;
+ gchar *elname, *elval;
+
+ GVariantIter iter;
+ GVariant *child = NULL;
+ GVariant *value1 = NULL;
+
+ g_variant_get(value, "(@a(ss))", &value1); /* Format for value1 a(ss)*/
+ gsize items = g_variant_iter_init(&iter, value1);
+ vcard_list = g_new0(char *, items + 1);
+
+ for (i = 0; (child = g_variant_iter_next_value(&iter)) != NULL; i++) {
+ g_variant_get(child, "(&s&s)", &elname, &elval);
+
+ memset(list_entry, 0, PBAP_VCARDLIST_MAXLENGTH);
+#if 0
+ g_snprintf(list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
+ "<card handle = \"%s\" name = \"%s\"/>", elname, elval);
+#else
+ g_snprintf(list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
+ "%s", elval);
+#endif
+ //If possible send as Array of <STRING, STRING>
+ BT_DBG("%s", list_entry);
+ vcard_list[i] = g_strdup(list_entry);
+ g_variant_unref(child);
+ }
+
+ length = i;
+ g_variant_unref(value1);
+ g_variant_unref(value);
+ }
+
+ BT_DBG("Address = %s", address_string);
+ GVariant *temp = g_variant_new_strv((const gchar * const *)vcard_list, length);
+ signal = g_variant_new("(isv)", result, address_string, temp);
+
+ _bt_send_event(BT_PBAP_CLIENT_EVENT,
+ BLUETOOTH_PBAP_VCARD_LIST,
+ signal);
+
+ for (i = 0; i < length; i++)
+ g_free(vcard_list[i]);
+
+ g_free(vcard_list);
+ g_object_unref(proxy);
+ __bt_pbap_free_data(pbap_data);
+ BT_DBG("-");
+}
+
+void __bt_pbap_get_vcard_cb(GDBusProxy *proxy,
+ GAsyncResult *res, gpointer user_data)
+{
+ BT_DBG("+");
+ GError *error = NULL;
+ bt_pbap_data_t *pbap_data = user_data;
+ char *address_string = pbap_data->data;
+ bt_pbap_transfer_info_t *transfer_info;
+ char *transfer = NULL;
+ const gchar *filename = NULL;
+ GVariant *value;
+ GVariant *properties;
+
+ BT_DBG("Address = %s", address_string);
+ value = g_dbus_proxy_call_finish(proxy, res, &error);
+ if (value == NULL) {
+ BT_ERR("g_dbus_proxy_call_finish failed");
+ if (error) {
+ BT_ERR("errCode[%x], message[%s]\n",
+ error->code, error->message);
+ g_clear_error(&error);
+ }
+ } else {
+ g_variant_get(value, "(o@a{sv})", &transfer, &properties);
+
+ if (g_variant_lookup(properties, "Filename", "s", &filename) == FALSE)
+ filename = NULL;
+
+ BT_DBG("Transfer Path: %s", transfer);
+ BT_DBG("File Name: %s", filename);
+ transfer_info = g_new0(bt_pbap_transfer_info_t, 1);
+ transfer_info->path = transfer;
+ transfer_info->remote_device = g_strdup(address_string);
+ transfer_info->filename = (char *)filename;
+ transfer_info->operation = GET_VCARD;
+ transfers = g_slist_append(transfers, transfer_info);
+
+ g_variant_unref(properties);
+ g_variant_unref(value);
+ }
+
+ g_object_unref(proxy);
+ __bt_pbap_free_data(pbap_data);
+ BT_DBG("-");
+}
+
+void __bt_pbap_search_phonebook_cb(GDBusProxy *proxy,
+ GAsyncResult *res, gpointer user_data)
+{
+ BT_DBG("+");
+ GError *error = NULL;
+ int i;
+ bt_pbap_data_t *pbap_data = user_data;
+ char *address_string = pbap_data->data;
+ char **vcard_list = NULL;
+ char list_entry[PBAP_VCARDLIST_MAXLENGTH] = { 0, };
+ int length = 0;
+ int result = BLUETOOTH_ERROR_INTERNAL;
+ GVariant *value;
+ GVariant *signal = NULL;
+
+ value = g_dbus_proxy_call_finish(proxy, res, &error);
+ if (value == NULL) {
+ BT_ERR("g_dbus_proxy_call_finish failed");
+ if (error) {
+ BT_ERR("errCode[%x], message[%s]\n",
+ error->code, error->message);
+ g_clear_error(&error);
+ }
+ } else {
+ result = BLUETOOTH_ERROR_NONE;
+ gchar *elname, *elval;
+
+ GVariantIter iter;
+ GVariant *child = NULL;
+ GVariant *value1 = NULL;
+
+ g_variant_get(value, "(@a(ss))", &value1);
+ gsize items = g_variant_iter_init(&iter, value1);
+ vcard_list = g_new0(char *, items + 1);
+
+ for (i = 0; (child = g_variant_iter_next_value(&iter)) != NULL; i++) {
+ g_variant_get(child, "(&s&s)", &elname, &elval);
+
+ memset(list_entry, 0, PBAP_VCARDLIST_MAXLENGTH);
+ g_snprintf(list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
+ "<card handle = \"%s\" name = \"%s\"/>", elname, elval);
+ //If possible send as Array of <STRING, STRING>
+ BT_DBG("%s", list_entry);
+ vcard_list[i] = g_strdup(list_entry);
+
+ g_variant_unref(child);
+ }
+ length = i;
+ g_variant_unref(value1);
+ g_variant_unref(value);
+ }
+
+ BT_DBG("Address = %s", address_string);
+
+ signal = g_variant_new("(is@as)", result, address_string,
+ g_variant_new_strv((const gchar * const *)vcard_list, length));
+
+ _bt_send_event(BT_PBAP_CLIENT_EVENT,
+ BLUETOOTH_PBAP_PHONEBOOK_SEARCH,
+ signal);
+
+ for (i = 0; i < length; i++)
+ g_free(vcard_list[i]);
+
+ g_free(vcard_list);
+ g_object_unref(proxy);
+ __bt_pbap_free_data(pbap_data);
+ BT_DBG("-");
+}
+
+int __bt_pbap_call_get_phonebook_size(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
+{
+ BT_DBG("+");
+
+ g_dbus_proxy_call(proxy, "GetSize",
+ NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
+ (GAsyncReadyCallback)__bt_pbap_get_phonebook_size_cb,
+ pbap_data);
+
+ BT_DBG("-");
+ return BLUETOOTH_ERROR_NONE;
+}
+
+int __bt_pbap_call_get_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
+{
+ BT_DBG("+");
+
+ int i;
+ int ret;
+ char *format_str = NULL;
+ char *fields_str = NULL;
+ char *order_str = NULL;
+ char *download_path = NULL;
+ char *target_file = NULL;
+ bt_pbap_pull_parameters_t *app_param = pbap_data->app_param;
+ GVariantBuilder builder;
+ GVariantBuilder inner_builder;
+ GVariant *filters;
+
+
+ g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
+ g_variant_builder_init(&inner_builder, G_VARIANT_TYPE_ARRAY);
+
+ /* Add MaxlistCount*/
+ g_variant_builder_add(&builder, "{sv}", "MaxCount",
+ g_variant_new("u", app_param->maxlist));
+
+ /* Add Order Filter only if other than Indexed (default)*/
+ if (app_param->order > 0) {
+ order_str = g_strdup(ORDER[app_param->order]);
+ g_variant_builder_add(&builder, "{sv}", "Order",
+ g_variant_new("s", order_str));
+ }
+
+ /* Add Offset Filter only if other than 0 (default)*/
+ if (app_param->offset > 0) {
+ g_variant_builder_add(&builder, "{sv}", "Offset",
+ g_variant_new("u", app_param->offset));
+ }
+
+ /* Add Format Filter only if other than vCard 2.1 (default)*/
+ if (app_param->format > 0) {
+ format_str = g_strdup(FORMAT[app_param->format]);
+ g_variant_builder_add(&builder, "{sv}", "Format",
+ g_variant_new("s", format_str));
+ }
+
+ /* Add Filter AttributeMask (64bit) */
+ if (app_param->fields > 0) {
+ if (app_param->fields == PBAP_FIELD_ALL) {
+ BT_DBG("** CHECKED ALL **");
+ fields_str = g_strdup("ALL");
+ g_variant_builder_add(&inner_builder, "s", fields_str);
+ g_free(fields_str);
+ } else {
+ for (i = 0; i < PBAP_NUM_OF_FIELDS_ENTRY; i++) {
+ if (app_param->fields & (1ULL << i)) {
+ BT_DBG("** CHECKED[%d]", i);
+ fields_str = g_strdup(FIELDS[i]);
+ g_variant_builder_add(&inner_builder, "s", fields_str);
+ g_free(fields_str);
+ }
+ }
+ }
+
+ g_variant_builder_add(&builder, "{sv}", "Fields",
+ g_variant_new("as", &inner_builder));
+ }
+
+ filters = g_variant_builder_end(&builder);
+
+//****************************
+// Add code for Fields
+//
+//****************************
+
+ ret = storage_get_directory(STORAGE_TYPE_INTERNAL,
+ STORAGE_DIRECTORY_DOWNLOADS, &download_path);
+
+ if (ret != STORAGE_ERROR_NONE) {
+ target_file = g_strdup_printf("%s/%s", PBAP_DEFAULT_DOWNLAOD_PATH,
+ PBAP_DEFAULT_FILE_NAME);
+ } else {
+ target_file = g_strdup_printf("%s/%s", download_path,
+ PBAP_DEFAULT_FILE_NAME);
+
+ if (download_path)
+ free(download_path);
+ }
+
+ DBG_SECURE("Target flie: %s", target_file);
+
+ g_dbus_proxy_call(proxy, "PullAll",
+ g_variant_new("(s@a{sv})", target_file, filters),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL,
+ (GAsyncReadyCallback)__bt_pbap_get_phonebook_cb,
+ pbap_data);
+
+ g_free(format_str);
+ g_free(order_str);
+ g_free(target_file);
+
+ BT_DBG("-");
+ return BLUETOOTH_ERROR_NONE;
+}
+
+int __bt_pbap_call_get_vcards_list(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
+{
+ BT_DBG("+");
+ char *order_str = NULL;
+ char *folder = NULL;
+ GVariantBuilder builder;
+ GVariant *filters;
+
+ bt_pbap_list_parameters_t *app_param = pbap_data->app_param;
+
+ g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
+
+ /* Add MaxlistCount*/
+ g_variant_builder_add(&builder, "{sv}", "MaxCount",
+ g_variant_new("u", app_param->maxlist));
+
+ /* Add Order Filter only if other than Indexed (default)*/
+ if (app_param->order > 0) {
+ order_str = g_strdup(ORDER[app_param->order]);
+ g_variant_builder_add(&builder, "{sv}", "Order",
+ g_variant_new("s", order_str));
+ }
+
+ /* Add Offset Filter only if other than 0 (default)*/
+ if (app_param->offset > 0) {
+ g_variant_builder_add(&builder, "{sv}", "Offset",
+ g_variant_new("u", app_param->offset));
+ }
+
+ filters = g_variant_builder_end(&builder);
+
+ folder = g_strdup(TYPE[selected_path.type]);
+ BT_DBG("Folder: %s", folder);
+
+
+ g_dbus_proxy_call(proxy, "List",
+ g_variant_new("(s@a{sv})", folder, filters),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL,
+ (GAsyncReadyCallback)__bt_pbap_get_vcard_list_cb,
+ pbap_data);
+
+ g_free(folder);
+ g_free(order_str);
+ g_hash_table_unref((GHashTable *)filters);
+ /* In _bt_pbap_get_list(), path(type) is set to "nil", but current type is not null.
+ The path should be reset here */
+ selected_path.type = -1;
+
+ BT_DBG("-");
+ return BLUETOOTH_ERROR_NONE;
+}
+
+int __bt_pbap_call_get_vcard(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
+{
+ BT_DBG("+");
+
+ int i;
+ int ret;
+ char *format_str = NULL;
+ char *fields_str = NULL;
+ char *target_file = NULL;
+ char *download_path = NULL;
+ char *vcard_handle = NULL;
+ char vcard[20] = { 0, };
+ GVariantBuilder builder;
+ GVariantBuilder inner_builder;
+ GVariant *filters;
+ bt_pbap_pull_vcard_parameters_t *app_param = pbap_data->app_param;
+
+ g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
+ g_variant_builder_init(&inner_builder, G_VARIANT_TYPE_ARRAY);
+
+ /* Add Format Filter only if other than vCard 2.1 (default)*/
+// if (app_param->format > 0) {
+ format_str = g_strdup(FORMAT[app_param->format]);
+ g_variant_builder_add(&builder, "{sv}", "Format",
+ g_variant_new("s", format_str));
+// }
+
+ /* Add Filter AttributeMask (64bit) */
+ if (app_param->fields > 0) {
+ if (app_param->fields == PBAP_FIELD_ALL) {
+ BT_DBG("** CHECKED ALL **");
+ fields_str = g_strdup("ALL");
+ g_variant_builder_add(&inner_builder, "s", fields_str);
+ g_free(fields_str);
+ } else {
+ for (i = 0; i < PBAP_NUM_OF_FIELDS_ENTRY; i++) {
+ if (app_param->fields & (1ULL << i)) {
+ BT_DBG("** CHECKED[%d]", i);
+ fields_str = g_strdup(FIELDS[i]);
+ g_variant_builder_add(&inner_builder, "s", fields_str);
+ g_free(fields_str);
+ }
+ }
+ }
+
+ g_variant_builder_add(&builder, "{sv}", "Fields",
+ g_variant_new("as", &inner_builder));
+ }
+
+ filters = g_variant_builder_end(&builder);
+
+//****************************
+// Add code for Fields
+//
+//****************************
+
+ snprintf(vcard, 20, "%d.vcf", app_param->index);
+ BT_DBG("Handle: %s", vcard);
+ vcard_handle = g_strdup(vcard);
+ BT_DBG("vcard_handle: %s", vcard_handle);
+
+ ret = storage_get_directory(STORAGE_TYPE_INTERNAL,
+ STORAGE_DIRECTORY_DOWNLOADS, &download_path);
+
+ if (ret != STORAGE_ERROR_NONE) {
+ target_file = g_strdup_printf("%s/%s", PBAP_DEFAULT_DOWNLAOD_PATH,
+ PBAP_DEFAULT_FILE_NAME);
+ } else {
+ if (vcard_handle)
+ target_file = g_strdup_printf("%s/%s", download_path,
+ vcard_handle);
+ else
+ target_file = g_strdup_printf("%s/%s", download_path,
+ PBAP_DEFAULT_FILE_NAME);
+
+ if (download_path)
+ free(download_path);
+ }
+
+ DBG_SECURE("Target flie: %s", target_file);
+
+ GVariant *temp = g_variant_new("(ss@a{sv})", vcard_handle, target_file, filters);
+
+ g_dbus_proxy_call(proxy, "Pull",
+ temp,
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL,
+ (GAsyncReadyCallback)__bt_pbap_get_vcard_cb,
+ pbap_data);
+
+ g_free(format_str);
+ g_free(vcard_handle);
+ g_free(target_file);
+
+ BT_DBG("-");
+ return BLUETOOTH_ERROR_NONE;
+}
+
+int __bt_pbap_call_search_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
+{
+ BT_DBG("+");
+
+ char *order_str = NULL;
+ char *field = NULL;
+ char *value = NULL;
+ bt_pbap_search_parameters_t *app_param = pbap_data->app_param;
+ GVariantBuilder builder;
+ GVariant *filters;
+
+ g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
+
+ /* Add MaxlistCount*/
+ g_variant_builder_add(&builder, "{sv}", "MaxCount",
+ g_variant_new("u", app_param->maxlist));
+
+ /* Add Order Filter only if other than Indexed (default)*/
+ if (app_param->order > 0) {
+ order_str = g_strdup(ORDER[app_param->order]);
+ g_variant_builder_add(&builder, "{sv}", "Order",
+ g_variant_new("s", order_str));
+ }
+
+ /* Add Offset Filter only if other than 0 (default)*/
+ if (app_param->offset > 0) {
+ g_variant_builder_add(&builder, "{sv}", "Offset",
+ g_variant_new("u", app_param->offset));
+ }
+
+ filters = g_variant_builder_end(&builder);
+
+ field = g_strdup(SEARCH_FIELD[app_param->search_attribute]);
+ value = g_strdup(app_param->search_value);
+
+ g_dbus_proxy_call(proxy, "Search",
+ g_variant_new("(ss@a{sv})", field, value, filters),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL,
+ (GAsyncReadyCallback)__bt_pbap_search_phonebook_cb,
+ pbap_data);
+
+ g_free(value);
+ g_free(order_str);
+ g_free(field);
+
+ BT_DBG("-");
+ return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_pbap_is_connected(bluetooth_device_address_t *device_address,
+ gboolean *connected)
+{
+ char address_string[18] = { 0, };
+
+ BT_CHECK_PARAMETER(device_address, return);
+ BT_CHECK_PARAMETER(connected, return);
+
+ /* In now, only 1 pbap connection is allowed */
+ if (g_pbap_server_address == NULL) {
+ *connected = FALSE;
+ return 0;
+ }
+
+ _bt_convert_addr_type_to_string(address_string,
+ (unsigned char *)device_address->addr);
+ BT_DBG("Address String: %s", address_string);
+
+ if (g_strcmp0(address_string, g_pbap_server_address) == 0)
+ *connected = TRUE;
+ else
+ *connected = FALSE;
+
+ return 0;
+}
+
+int _bt_pbap_get_phonebook_size(const bluetooth_device_address_t *address,
+ int source, int type)
+{
+ BT_DBG("+");
+ GDBusConnection *g_conn;
+ GDBusProxy *g_pbap_session_proxy = NULL;
+ char address_string[18] = { 0, };
+ char *source_string = NULL;
+ char *type_string = NULL;
+ GError *err = NULL;
+ bt_pbap_data_t *pbap_data = NULL;
+
+ BT_CHECK_PARAMETER(address, return);
+
+ /* check if connected */
+ if (g_pbap_session_path == NULL) {
+ BT_ERR("NOT CONNECTED");
+ return BLUETOOTH_ERROR_NOT_CONNECTED;
+ }
+
+ BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
+ address->addr[0], address->addr[1],
+ address->addr[2], address->addr[3],
+ address->addr[4], address->addr[5]);
+
+ _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
+ BT_DBG("Address String: %s", address_string);
+ source_string = g_strdup(SOURCE[source]);
+ type_string = g_strdup(TYPE[type]);
+
+ BT_DBG("Address[%s] Source[%s] Type[%s]",
+ address_string, source_string, type_string);
+ BT_DBG("Session Path = %s\n", g_pbap_session_path);
+
+ g_conn = _bt_get_session_gconn();
+ if (g_conn == NULL) {
+ BT_ERR("Couldn't connect to session bus");
+ g_free(source_string);
+ g_free(type_string);
+ return 0;
+ }
+ g_pbap_session_proxy = g_dbus_proxy_new_sync(g_conn,
+ G_DBUS_PROXY_FLAGS_NONE, NULL,
+ PBAP_SESSION_SERVICE, g_pbap_session_path,
+ PBAP_SESSION_INTERFACE, NULL, &err);
+
+ if (!g_pbap_session_proxy) {
+ BT_ERR("Failed to get a proxy for D-Bus\n");
+ if (err) {
+ ERR("Unable to create proxy: %s", err->message);
+ g_clear_error(&err);
+ }
+ g_free(source_string);
+ g_free(type_string);
+ return -1;
+ }
+
+ BT_DBG("Prepare PBAP data");
+ pbap_data = g_new0(bt_pbap_data_t, 1);
+ pbap_data->operation = GET_SIZE;
+ pbap_data->data = g_strdup(address_string);
+
+ if (source == selected_path.folder && type == selected_path.type) {
+ BT_DBG("Call get_phonebook_size directly");
+ g_free(source_string);
+ g_free(type_string);
+ return __bt_pbap_call_get_phonebook_size(g_pbap_session_proxy, pbap_data);
+ }
+
+ BT_DBG("Call SELECT");
+ g_dbus_proxy_call(g_pbap_session_proxy, "Select",
+ g_variant_new("(ss)", source_string, type_string),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL,
+ (GAsyncReadyCallback)__bt_pbap_select_cb,
+ pbap_data);
+
+ BT_DBG("Set Folders");
+ selected_path.folder = source;
+ selected_path.type = type;
+
+ g_free(source_string);
+ g_free(type_string);
+ return 0;
+}
+
+int _bt_pbap_get_phonebook(const bluetooth_device_address_t *address,
+ int source, int type, bt_pbap_pull_parameters_t *app_param)
+{
+ BT_DBG("+");
+ GDBusConnection *g_conn;
+ GDBusProxy *g_pbap_session_proxy = NULL;
+ char address_string[18] = { 0, };
+ char *source_string = NULL;
+ char *type_string = NULL;
+ GError *err = NULL;
+
+ bt_pbap_data_t *pbap_data = NULL;
+ bt_pbap_pull_parameters_t *param = NULL;
+
+ BT_CHECK_PARAMETER(address, return);
+
+ /* check if connected */
+ if (g_pbap_session_path == NULL) {
+ BT_ERR("NOT CONNECTED");
+ return BLUETOOTH_ERROR_NOT_CONNECTED;
+ }
+
+ BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
+ address->addr[0], address->addr[1],
+ address->addr[2], address->addr[3],
+ address->addr[4], address->addr[5]);
+
+ _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
+ BT_DBG("Address String: %s", address_string);
+
+ source_string = g_strdup(SOURCE[source]);
+ type_string = g_strdup(TYPE[type]);
+
+ BT_DBG("Address[%s] Source[%s] Type[%s]",
+ address_string, source_string, type_string);
+
+ BT_DBG("Session Path = %s\n", g_pbap_session_path);
+
+ g_conn = _bt_get_session_gconn();
+ if (g_conn == NULL) {
+ BT_ERR("Couldn't connect to session bus");
+ g_free(source_string);
+ g_free(type_string);
+ return 0;
+ }
+ g_pbap_session_proxy = g_dbus_proxy_new_sync(g_conn,
+ G_DBUS_PROXY_FLAGS_NONE, NULL,
+ PBAP_SESSION_SERVICE, g_pbap_session_path,
+ PBAP_SESSION_INTERFACE, NULL, &err);
+
+ if (!g_pbap_session_proxy) {
+ BT_ERR("Failed to get a proxy for D-Bus\n");
+ if (err) {
+ ERR("Unable to create proxy: %s", err->message);
+ g_clear_error(&err);
+ }
+ g_free(source_string);
+ g_free(type_string);
+ return -1;
+ }
+
+ pbap_data = g_new0(bt_pbap_data_t, 1);
+ pbap_data->operation = PULL_ALL;
+ pbap_data->data = g_strdup(address_string);
+ param = g_new0(bt_pbap_pull_parameters_t, 1);
+ memcpy(param, app_param, sizeof(bt_pbap_pull_parameters_t));
+ pbap_data->app_param = param;
+
+ if (source == selected_path.folder && type == selected_path.type) {
+ g_free(source_string);
+ g_free(type_string);
+ return __bt_pbap_call_get_phonebook(g_pbap_session_proxy, pbap_data);
+ }
+
+ g_dbus_proxy_call(g_pbap_session_proxy, "Select",
+ g_variant_new("(ss)", source_string, type_string),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL,
+ (GAsyncReadyCallback)__bt_pbap_select_cb,
+ pbap_data);
+
+ selected_path.folder = source;
+ selected_path.type = type;
+ g_free(source_string);
+ g_free(type_string);
+
+ return 0;
+}
+
+int _bt_pbap_get_list(const bluetooth_device_address_t *address, int source,
+ int type, bt_pbap_list_parameters_t *app_param)
+{
+ BT_DBG("+");
+ GDBusConnection *g_conn;
+ GDBusProxy *g_pbap_session_proxy = NULL;
+ char address_string[18] = { 0, };
+ char *source_string = NULL;
+ char *type_string = NULL;
+ GError *err = NULL;
+
+ bt_pbap_data_t *pbap_data = NULL;
+ bt_pbap_list_parameters_t *param = NULL;
+
+ BT_CHECK_PARAMETER(address, return);
+
+ /* check if connected */
+ if (g_pbap_session_path == NULL) {
+ BT_ERR("NOT CONNECTED");
+ return BLUETOOTH_ERROR_NOT_CONNECTED;
+ }
+
+ BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
+ address->addr[0], address->addr[1],
+ address->addr[2], address->addr[3],
+ address->addr[4], address->addr[5]);
+
+ _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
+ BT_DBG("Address String: %s", address_string);
+
+ source_string = g_strdup(SOURCE[source]);
+ type_string = g_strdup("nil");
+
+ BT_DBG("Address[%s] Source[%s] Type[%s]",
+ address_string, source_string, type_string);
+
+ BT_DBG("Session Path = %s\n", g_pbap_session_path);
+
+ g_conn = _bt_get_session_gconn();
+ if (g_conn == NULL) {
+ BT_ERR("Couldn't connect to session bus");
+ g_free(source_string);
+ g_free(type_string);
+ return 0;
+ }
+ g_pbap_session_proxy = g_dbus_proxy_new_sync(g_conn,
+ G_DBUS_PROXY_FLAGS_NONE, NULL,
+ PBAP_SESSION_SERVICE, g_pbap_session_path,
+ PBAP_SESSION_INTERFACE, NULL, &err);
+
+ if (!g_pbap_session_proxy) {
+ BT_ERR("Failed to get a proxy for D-Bus\n");
+ if (err) {
+ ERR("Unable to create proxy: %s", err->message);
+ g_clear_error(&err);
+ }
+ g_free(source_string);
+ g_free(type_string);
+ return -1;
+ }
+
+ BT_DBG("Set PBAP Data");
+ pbap_data = g_new0(bt_pbap_data_t, 1);
+ pbap_data->operation = GET_LIST;
+ pbap_data->data = g_strdup(address_string);
+ param = g_new0(bt_pbap_list_parameters_t, 1);
+ memcpy(param, app_param, sizeof(bt_pbap_list_parameters_t));
+ pbap_data->app_param = param;
+
+ /* Always Call Select for vCardListing
+ if (source == selected_path.folder && type == selected_path.type) {
+ BT_DBG("Call Directly");
+ return __bt_pbap_call_get_vcards_list(g_pbap_session_proxy, pbap_data);
+ } */
+ BT_DBG("Call SELECT");
+ g_dbus_proxy_call(g_pbap_session_proxy, "Select",
+ g_variant_new("(ss)", source_string, type_string),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL,
+ (GAsyncReadyCallback)__bt_pbap_select_cb,
+ pbap_data);
+ BT_DBG("Set Folders");
+ selected_path.folder = source;
+ selected_path.type = type;
+ g_free(source_string);
+ g_free(type_string);
+
+ return 0;
+}
+
+
+int _bt_pbap_pull_vcard(const bluetooth_device_address_t *address,
+ int source, int type, bt_pbap_pull_vcard_parameters_t *app_param)
+{
+ BT_DBG("+");
+ GDBusConnection *g_conn;
+ GDBusProxy *g_pbap_session_proxy = NULL;
+ char address_string[18] = { 0, };
+ char *source_string = NULL;
+ char *type_string = NULL;
+ bt_pbap_data_t *pbap_data = NULL;
+ bt_pbap_pull_vcard_parameters_t *param = NULL;
+ GError *err = NULL;
+
+ BT_CHECK_PARAMETER(address, return);
+
+ /* check if connected */
+ if (g_pbap_session_path == NULL) {
+ BT_ERR("NOT CONNECTED");
+ return BLUETOOTH_ERROR_NOT_CONNECTED;
+ }
+
+ BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
+ address->addr[0], address->addr[1],
+ address->addr[2], address->addr[3],
+ address->addr[4], address->addr[5]);
+
+ _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
+ BT_DBG("Address String: %s", address_string);
+
+ source_string = g_strdup(SOURCE[source]);
+ type_string = g_strdup(TYPE[type]);
+
+ BT_DBG("Address[%s] Source[%s] Type[%s]",
+ address_string, source_string, type_string);
+
+ BT_DBG("Session Path = %s\n", g_pbap_session_path);
+
+ g_conn = _bt_get_session_gconn();
+ if (g_conn == NULL) {
+ BT_ERR("Couldn't connect to session bus");
+ g_free(source_string);
+ g_free(type_string);
+ return 0;
+ }
+ g_pbap_session_proxy = g_dbus_proxy_new_sync(g_conn,
+ G_DBUS_PROXY_FLAGS_NONE, NULL,
+ PBAP_SESSION_SERVICE, g_pbap_session_path,
+ PBAP_SESSION_INTERFACE, NULL, &err);
+
+ if (!g_pbap_session_proxy) {
+ BT_ERR("Failed to get a proxy for D-Bus\n");
+ if (err) {
+ ERR("Unable to create proxy: %s", err->message);
+ g_clear_error(&err);
+ }
+ g_free(source_string);
+ g_free(type_string);
+ return -1;
+ }
+
+ pbap_data = g_new0(bt_pbap_data_t, 1);
+ pbap_data->operation = GET_VCARD;
+ pbap_data->data = g_strdup(address_string);
+ param = g_new0(bt_pbap_pull_vcard_parameters_t, 1);
+ memcpy(param, app_param, sizeof(bt_pbap_pull_vcard_parameters_t));
+ pbap_data->app_param = param;
+
+ if (source == selected_path.folder && type == selected_path.type) {
+ g_free(source_string);
+ g_free(type_string);
+ return __bt_pbap_call_get_vcard(g_pbap_session_proxy, pbap_data);
+ }
+
+ g_dbus_proxy_call(g_pbap_session_proxy, "Select",
+ g_variant_new("(ss)", source_string, type_string),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL,
+ (GAsyncReadyCallback)__bt_pbap_select_cb,
+ pbap_data);
+
+ selected_path.folder = source;
+ selected_path.type = type;
+ g_free(source_string);
+ g_free(type_string);
+
+ return 0;
+}
+
+int _bt_pbap_phonebook_search(const bluetooth_device_address_t *address,
+ int source, int type, bt_pbap_search_parameters_t *app_param)
+{
+ BT_DBG("+");
+ GDBusConnection *g_conn;
+ GDBusProxy *g_pbap_session_proxy = NULL;
+ char address_string[18] = { 0, };
+ char *source_string = NULL;
+ char *type_string = NULL;
+ bt_pbap_data_t *pbap_data = NULL;
+ bt_pbap_search_parameters_t *param = NULL;
+ GError *err = NULL;
+
+ BT_CHECK_PARAMETER(address, return);
+
+ /* check if connected */
+ if (g_pbap_session_path == NULL) {
+ BT_ERR("NOT CONNECTED");
+ return BLUETOOTH_ERROR_NOT_CONNECTED;
+ }
+
+ BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
+ address->addr[0], address->addr[1],
+ address->addr[2], address->addr[3],
+ address->addr[4], address->addr[5]);
+
+ _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
+ BT_DBG("Address String: %s", address_string);
+
+ source_string = g_strdup(SOURCE[source]);
+ type_string = g_strdup(TYPE[type]);
+
+ BT_DBG("Address[%s] Source[%s] Type[%s]",
+ address_string, source_string, type_string);
+
+ BT_DBG("Session Path = %s\n", g_pbap_session_path);
+
+ g_conn = _bt_get_session_gconn();
+ if (g_conn == NULL) {
+ BT_ERR("Couldn't connect to session bus");
+ g_free(source_string);
+ g_free(type_string);
+ return 0;
+ }
+ g_pbap_session_proxy = g_dbus_proxy_new_sync(g_conn,
+ G_DBUS_PROXY_FLAGS_NONE, NULL,
+ PBAP_SESSION_SERVICE, g_pbap_session_path,
+ PBAP_SESSION_INTERFACE, NULL, &err);
+
+ if (!g_pbap_session_proxy) {
+ BT_ERR("Failed to get a proxy for D-Bus\n");
+ if (err) {
+ ERR("Unable to create proxy: %s", err->message);
+ g_clear_error(&err);
+ }
+ g_free(source_string);
+ g_free(type_string);
+ return -1;
+ }
+
+ pbap_data = g_new0(bt_pbap_data_t, 1);
+ pbap_data->operation = PB_SEARCH;
+ pbap_data->data = g_strdup(address_string);
+ param = g_new0(bt_pbap_search_parameters_t, 1);
+ memcpy(param, app_param, sizeof(bt_pbap_search_parameters_t));
+ pbap_data->app_param = param;
+
+ /* Call Select for vCardListing
+ if (source == selected_path.folder && type == selected_path.type) {
+ return __bt_pbap_call_search_phonebook(g_pbap_session_proxy, pbap_data);
+ }*/
+
+ g_dbus_proxy_call(g_pbap_session_proxy, "Select",
+ g_variant_new("(ss)", source_string, type_string),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL,
+ (GAsyncReadyCallback)__bt_pbap_select_cb,
+ pbap_data);
+
+ selected_path.folder = source;
+ selected_path.type = type;
+
+ g_free(source_string);
+ g_free(type_string);
+
+ return 0;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef BT_SERVICE_AGENT_H
+#define BT_SERVICE_AGENT_H
+
+#include <stdint.h>
+#include <glib.h>
+#include <unistd.h>
+#include <dlog.h>
+#include <stdio.h>
+
+#undef LOG_TAG
+#define LOG_TAG "BLUETOOTH_FRWK_SERVICE"
+#define ERR(fmt, args...) SLOGE(fmt, ##args)
+
+#define BT_MAX_EVENT_STR_LENGTH 50
+
+#define BT_FILE_VISIBLE_TIME "file/private/libug-setting-bluetooth-efl/visibility_time"
+
+typedef enum {
+ HS_PROFILE_UUID = ((unsigned short)0x1108), /**<HS*/
+ AUDIO_SOURCE_UUID = ((unsigned short)0x110A), /**<AUDIO SOURCE*/
+ AUDIO_SINK_UUID = ((unsigned short)0x110B), /**<AUDIO SINK*/
+ AV_REMOTE_CONTROL_TARGET_UUID = ((unsigned short)0x110C),/**<AV REMOTE CONTROL TARGET*/
+ ADVANCED_AUDIO_PROFILE_UUID = ((unsigned short)0x110D), /**<A2DP*/
+ AV_REMOTE_CONTROL_UUID = ((unsigned short)0x110E), /**<AV REMOTE CONTROL UUID*/
+ HF_PROFILE_UUID = ((unsigned short)0x111E), /**<HF*/
+} bt_agent_service_uuid_list_t;
+
+
+//needed
+typedef enum {
+ BT_AGENT_EVENT_PIN_REQUEST,
+ BT_AGENT_EVENT_PASSKEY_CONFIRM_REQUEST,
+ BT_AGENT_EVENT_PASSKEY_AUTO_ACCEPTED,
+ BT_AGENT_EVENT_PASSKEY_REQUEST,
+ BT_AGENT_EVENT_PASSKEY_DISPLAY_REQUEST,
+ BT_AGENT_EVENT_AUTHORIZE_REQUEST,
+ BT_AGENT_EVENT_CONFIRM_MODE_REQUEST,
+ BT_AGENT_EVENT_APP_CONFIRM_REQUEST,
+ BT_AGENT_EVENT_FILE_RECEIVED,
+ BT_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST,
+ BT_AGENT_EVENT_SECURITY,
+ BT_AGENT_EVENT_TERMINATE,
+ BT_AGENT_EVENT_EXCHANGE_REQUEST,
+ BT_AGENT_EVENT_PBAP_REQUEST,
+ BT_AGENT_EVENT_MAP_REQUEST,
+ BT_AGENT_EVENT_SYSTEM_RESET_REQUEST,
+ BT_AGENT_EVENT_LEGACY_PAIR_FAILED_FROM_REMOTE,
+} bt_agent_event_type_t;
+
+typedef struct {
+ int type;
+ char *uuid;
+ char *path;
+ int fd;
+} bt_agent_osp_server_t;
+
+void* _bt_create_agent(const char *path, gboolean adapter);
+
+void _bt_destroy_agent(void *agent);
+
+gboolean _bt_agent_is_canceled(void);
+void _bt_agent_set_canceled(gboolean value);
+
+gboolean _bt_agent_register_osp_server(const gint type,
+ const char *uuid, char *path, int fd);
+
+gboolean _bt_agent_unregister_osp_server(const gint type, const char *uuid);
+
+gboolean _bt_agent_reply_authorize(gboolean accept);
+
+int _bt_agent_reply_cancellation(void);
+
+int _bt_set_passkey_notification(const char *sender, gboolean enable);
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+#ifndef _BT_SERVICE_AUDIO_H_
+#define _BT_SERVICE_AUDIO_H_
+
+#include <glib.h>
+#include <sys/types.h>
+#include "bluetooth-api.h"
+#include "bluetooth-audio-api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ int req_id;
+ int type;
+ int disconnection_type;
+ char *address;
+ gboolean ag_flag;
+} bt_headset_wait_t;
+
+typedef struct {
+ int key;
+ const char *property;
+} bt_player_settinngs_t;
+
+typedef enum {
+ BT_PENDING_NONE = 0x00,
+ BT_PENDING_CONNECT,
+ BT_PENDING_DISCONNECT
+} bt_pending_request_t;
+
+typedef struct {
+ int req_id;
+ char *address;
+ bt_pending_request_t pending;
+ int type;
+} bt_audio_function_data_t;
+
+typedef enum {
+ BT_AUDIO_HSP = 0x01,
+ BT_AUDIO_A2DP,
+ BT_AUDIO_ALL,
+ BT_AVRCP,
+ BT_AUDIO_A2DP_SOURCE,
+ BT_AVRCP_TARGET
+} bt_audio_type_t;
+
+typedef enum {
+ BT_STATE_NONE = 0x00,
+ BT_STATE_CONNECTING,
+ BT_STATE_CONNECTED,
+ BT_STATE_DISCONNECTING,
+ BT_STATE_DISCONNECTED
+} bt_headset_device_state_t;
+
+#define BT_CONTENT_PROTECTION_PATH "/org/tizen/bluetooth/a2dpcontentprotection"
+#define BT_CONTENT_PROTECTION_INTERFACE "org.tizen.bluetooth.A2dpContentProtection"
+
+#ifdef TIZEN_BT_A2DP_SINK_AUTO_CONNECT
+#define BT_AUTO_CONNECT_TIMEOUT_AFTER_BT_ACTIVATED 2 /* 2 sec */
+#define BT_AUTO_CONNECT_TIMEOUT_AFTER_LINKLOSS 30 /* 30 sec */
+#define BT_AUTO_CONNECT_TIMEOUT_RETRY_TIME 3600 /* 60 minute */
+#endif
+
+typedef enum {
+ BLUETOOTH_A2DP_SOURCE,
+ BLUETOOTH_A2DP_SINK,
+} bluetooth_audio_role_t;
+
+int _bt_audio_select_role(bluetooth_audio_role_t role);
+
+int _bt_audio_connect(int request_id, int type,
+ bluetooth_device_address_t *device_address,
+ GArray *out_param1);
+
+int _bt_audio_disconnect(int request_id, int type,
+ bluetooth_device_address_t *device_address,
+ GArray *out_param1);
+
+int _bt_hf_connect(int request_id,
+ bluetooth_device_address_t *device_address,
+ GArray *out_param1);
+
+int _bt_hf_disconnect(int request_id,
+ bluetooth_device_address_t *device_address,
+ GArray *out_param1);
+
+int _bt_audio_get_speaker_gain(unsigned int *gain);
+
+int _bt_audio_set_speaker_gain(unsigned int gain);
+
+int _bt_audio_set_content_protect(gboolean status);
+
+void _bt_set_audio_wait_data_flag(gboolean flag);
+
+bt_headset_wait_t *_bt_get_audio_wait_data(void);
+
+void _bt_rel_wait_data(void);
+
+void _bt_add_headset_to_list(int type, int status, const char *address);
+
+void _bt_remove_headset_from_list(int type, const char *address);
+
+gboolean _bt_is_headset_type_connected(int type, char *address);
+#ifdef TIZEN_BT_DUAL_HEADSET_CONNECT
+void _bt_check_already_connected_headset(int type, char *address);
+#endif
+void _bt_remove_from_connected_list(const char *address);
+
+int _bt_get_device_state_from_list(int type, const char *address);
+
+void _bt_remove_from_connected_list(const char *address);
+
+void _bt_audio_check_pending_connect();
+
+gboolean _bt_is_service_connected(char *address, int type);
+
+#ifdef TIZEN_BT_A2DP_SINK_AUTO_CONNECT
+int _bt_audio_start_auto_connect(gboolean linkloss_flag);
+
+int _bt_audio_stop_auto_connect(void);
+
+void _bt_audio_set_auto_connect_device_addr(const char *address);
+#endif
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /*_BT_SERVICE_AUDIO_H_*/
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+#ifndef _BT_SERVICE_AVRCP_H_
+#define _BT_SERVICE_AVRCP_H_
+
+#include <glib.h>
+#include <sys/types.h>
+
+#include "bluetooth-api.h"
+#include "bluetooth-media-control.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BT_MEDIA_OBJECT_PATH "/Musicplayer"
+
+#define BT_AVRCP_ERROR (__bt_avrcp_error_quark())
+
+#define BT_ERROR_INTERNAL "InternalError"
+#define BT_ERROR_INVALID_PARAM "InvalidParameters"
+#define BT_ERROR_INVALID_INTERFACE "InvalidInterface"
+
+typedef enum {
+ BT_AVRCP_ERROR_NONE,
+ BT_AVRCP_ERROR_INTERNAL,
+ BT_AVRCP_ERROR_INVALID_PARAM,
+ BT_AVRCP_ERROR_NOT_SUPPORTED,
+ BT_AVRCP_ERROR_INVALID_INTERFACE
+} bt_avrcp_error_t;
+
+int _bt_register_media_player(void);
+
+int _bt_unregister_media_player(void);
+
+int _bt_avrcp_set_track_info(media_metadata_attributes_t *meta_data);
+
+int _bt_avrcp_set_properties(media_player_settings_t *properties);
+
+int _bt_avrcp_set_property(int type, unsigned int value);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /*_BT_SERVICE_AVRCP_H_*/
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+#ifndef _BT_SERVICE_DEVICE_H_
+#define _BT_SERVICE_DEVICE_H_
+
+#include <glib.h>
+#include <sys/types.h>
+#include "bluetooth-api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int _bt_bond_device(int request_id,
+ bluetooth_device_address_t *device_address,
+ unsigned short conn_type, GArray **out_param1);
+
+int _bt_cancel_bonding(void);
+
+int _bt_passkey_reply(const char *passkey, gboolean authentication_reply);
+
+int _bt_passkey_confirmation_reply(gboolean confirmation_reply);
+
+int _bt_unbond_device(int request_id,
+ bluetooth_device_address_t *device_address,
+ GArray **out_param1);
+
+int _bt_cancel_search_device(void);
+
+int _bt_search_device(int request_id,
+ bluetooth_device_address_t *device_address);
+
+int _bt_set_alias(bluetooth_device_address_t *device_address,
+ const char *alias);
+
+int _bt_set_authorization(bluetooth_device_address_t *device_address,
+ gboolean authorize);
+
+int _bt_is_gatt_connected(bluetooth_device_address_t *device_address,
+ gboolean *is_connected);
+
+int _bt_is_device_connected(bluetooth_device_address_t *device_address,
+ int connection_type, gboolean *is_connected);
+
+int _bt_get_connected_link(bluetooth_device_address_t *device_address,
+ bluetooth_connected_link_t *connected);
+
+int _bt_set_pin_code(bluetooth_device_address_t *device_address,
+ bluetooth_device_pin_code_t *pin_code);
+
+int _bt_unset_pin_code(bluetooth_device_address_t *device_address);
+
+int _bt_get_device_pin_code(const char *address, char *pin_code);
+
+gboolean _bt_is_device_creating(void);
+
+void _bt_set_autopair_status_in_bonding_info(gboolean is_autopair);
+
+bt_remote_dev_info_t *_bt_get_remote_device_info(char *address);
+
+bt_remote_dev_info_t *_bt_get_remote_device_info_by_object_path(const char *object_path);
+
+char *_bt_get_bonded_device_name(char *address);
+
+gboolean _bt_is_bonding_device_address(const char *address);
+
+void _bt_pending_connect_le_device(void);
+
+int _bt_connect_le_device(int req_id, const bluetooth_device_address_t *bd_addr,
+ gboolean auto_connect);
+
+int _bt_disconnect_le_device(int req_id,
+ const bluetooth_device_address_t *bd_addr);
+
+int _bt_le_conn_update(unsigned char *device_address,
+ float interval_min, float interval_max,
+ guint16 latency, guint16 time_out);
+
+int _bt_get_le_connection_parameter(bluetooth_le_connection_mode_t mode,
+ bluetooth_le_connection_param_t *param);
+
+int _bt_connect_profile(char *address, char *uuid,
+ void *cb, gpointer func_data);
+
+int _bt_disconnect_all(char *address);
+
+int _bt_disconnect_profile(char *address, char *uuid,
+ void *cb, gpointer func_data);
+
+int _bt_request_att_mtu(int request_id, bluetooth_device_address_t *device_address,
+ unsigned int mtu);
+
+int _bt_get_att_mtu(bluetooth_device_address_t *device_address,
+ unsigned int *mtu);
+
+int _bt_get_device_ida(bluetooth_device_address_t *device_address,
+ bluetooth_device_address_t *id_address);
+
+int _bt_set_trust_profile(bluetooth_device_address_t *bd_addr,
+ bluetooth_trusted_profile_t profile, gboolean trust);
+
+int _bt_get_trust_profile(bluetooth_device_address_t *bd_addr,
+ bluetooth_trusted_profile_t profile, guint *trust);
+
+int _bt_set_restrict_profile(bluetooth_device_address_t *bd_addr,
+ bluetooth_restricted_profile_t profile, gboolean restricted);
+
+int _bt_get_restrict_profile(bluetooth_device_address_t *bd_addr,
+ bluetooth_restricted_profile_t profile, guint *restricted);
+
+bluetooth_trusted_profile_t _bt_get_trusted_profile_enum(const char *uuid);
+
+int _bt_connect_le_ipsp_device(const bluetooth_device_address_t *bd_addr);
+
+int _bt_disconnect_le_ipsp_device(const bluetooth_device_address_t *bd_addr);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /*_BT_SERVICE_ADAPTER_H_*/
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+#ifndef _BT_SERVICE_EVENT_H_
+#define _BT_SERVICE_EVENT_H_
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int _bt_send_event(int event_type, int event, GVariant *param);
+
+int _bt_send_event_to_dest(const char* dest, int event_type, int event, GVariant *param);
+
+int _bt_init_service_event_sender(void);
+void _bt_deinit_service_event_sender(void);
+
+//int _bt_init_service_event_receiver(void);
+void _bt_deinit_service_event_receiver(void);
+
+int _bt_opp_client_event_init(void);
+void _bt_opp_client_event_deinit(void);
+
+int _bt_map_client_event_init(void);
+void _bt_map_client_event_deinit(void);
+
+int _bt_send_hf_local_term_event(char *address);
+int _bt_init_hf_local_term_event_sender(void);
+void _bt_deinit_hf_local_term_event_sender(void);
+
+int _bt_send_dump_signal(char *signal);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /*_BT_SERVICE_EVENT_H_*/
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef SC_CORE_AGENT_H
+#define SC_CORE_AGENT_H
+
+#include <stdint.h>
+#include <glib.h>
+#include <gio/gio.h>
+
+#define BLUEZ_DEVICE_INTERFACE "org.bluez.Device"
+
+typedef enum {
+ GAP_AGENT_EXEC_NO_OPERATION,
+ GAP_AGENT_EXEC_PAIRING,
+ GAP_AGENT_EXEC_AUTHORZATION,
+ GAP_AGENT_EXEC_CONFIRM_MODE,
+} GapAgentExecType;
+
+typedef struct _GapAgentPrivate GapAgentPrivate;
+
+typedef gboolean(*GapAgentPasskeyFunc) (GapAgentPrivate *agent,
+ GDBusProxy *device);
+typedef gboolean(*GapAgentDisplayFunc) (GapAgentPrivate *agent, GDBusProxy *device,
+ guint passkey);
+typedef gboolean(*GapAgentConfirmFunc) (GapAgentPrivate *agent, GDBusProxy *device,
+ guint passkey);
+typedef gboolean(*GapAgentAuthorizeFunc) (GapAgentPrivate *agent,
+ GDBusProxy *device, const char *uuid);
+typedef gboolean(*GapAgentConfirmModeFunc) (GapAgentPrivate *agent,
+ const char *mode, const char *sender,
+ gboolean need_popup, void *data);
+typedef gboolean(*GapAgentCancelFunc) (GapAgentPrivate *agent,
+ const char *address);
+typedef gboolean(*GapAgentIgnoreAutoPairingFunc) (const char *address);
+typedef uint8_t bool_t;
+
+typedef struct {
+ GapAgentPasskeyFunc pincode_func;
+ GapAgentDisplayFunc display_func;
+ GapAgentPasskeyFunc passkey_func;
+ GapAgentConfirmFunc confirm_func;
+ GapAgentAuthorizeFunc authorize_func;
+ GapAgentCancelFunc pairing_cancel_func;
+ GapAgentCancelFunc authorization_cancel_func;
+} GAP_AGENT_FUNC_CB;
+
+typedef enum {
+ GAP_AGENT_ACCEPT,
+ GAP_AGENT_REJECT,
+ GAP_AGENT_CANCEL,
+ GAP_AGENT_TIMEOUT,
+ GAP_AGENT_ACCEPT_ALWAYS,
+} GAP_AGENT_ACCEPT_TYPE_T;
+
+struct _GapAgentPrivate {
+ gchar *busname;
+ gchar *path;
+
+ GDBusProxy *agent_manager;
+
+ GDBusProxy *dbus_proxy;
+
+ GapAgentExecType exec_type;
+ GDBusMethodInvocation *reply_context;
+ char *uuid;
+
+ char pairing_addr[18];
+ char authorize_addr[18];
+
+ GSList *osp_servers;
+
+ GAP_AGENT_FUNC_CB cb;
+ gboolean canceled;
+};
+
+void _gap_agent_setup_dbus(GapAgentPrivate *agent, GAP_AGENT_FUNC_CB *func_cb,
+ const char *path, GDBusProxy *adapter);
+gboolean _gap_agent_register(GapAgentPrivate *agent);
+void _gap_agent_reset_dbus(GapAgentPrivate *agent);
+
+gboolean gap_agent_reply_pin_code(GapAgentPrivate *agent, const guint accept,
+ const char *pin_code,
+ GDBusMethodInvocation *context);
+gboolean gap_agent_reply_passkey(GapAgentPrivate *agent, const guint accept,
+ const char *passkey,
+ GDBusMethodInvocation *context);
+gboolean gap_agent_reply_confirmation(GapAgentPrivate *agent, const guint accept,
+ GDBusMethodInvocation *context);
+gboolean gap_agent_reply_authorize(GapAgentPrivate *agent, const guint accept,
+ GDBusMethodInvocation *context);
+
+gboolean _gap_agent_exist_osp_server(GapAgentPrivate *agent, int type, char *uuid);
+
+bt_agent_osp_server_t *_gap_agent_get_osp_server(GapAgentPrivate *agent, int type,
+ char *uuid);
+
+gchar* _gap_agent_get_path(GapAgentPrivate *agent);
+
+gboolean _gap_agent_is_canceled(GapAgentPrivate *agent);
+
+void _gap_agent_set_canceled(GapAgentPrivate *agent, gboolean value);
+
+gboolean _gap_agent_register_osp_server(GapAgentPrivate *agent,
+ const gint type,
+ const char *uuid,
+ const char *path,
+ int fd);
+
+gboolean _gap_agent_unregister_osp_server(GapAgentPrivate *agent,
+ const gint type,
+ const char *uuid);
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+#ifndef _BT_SERVICE_MAP_CLIENT_H_
+#define _BT_SERVICE_MAP_CLIENT_H_
+
+#include <glib.h>
+#include <sys/types.h>
+#include <gio/gio.h>
+#include "bluetooth-api.h"
+#include "bt-internal-types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BT_OBEX_CLIENT_AGENT_PATH "/org/obex/client_agent"
+
+/* TODO: MAP */
+
+typedef struct {
+ int request_id;
+ int result;
+
+ char *session_path;
+
+ char *address;
+
+/* int file_count;
+ int file_offset;
+ char **file_name_array;
+ gboolean is_canceled; */
+
+ /* TODO: MAP */
+
+} bt_session_info_t; /* TODO: "session"? */
+
+typedef struct {
+ char *address;
+ int request_id;
+
+ /* char **file_path;
+ int file_count; */
+
+ /* TODO: MAP */
+
+} bt_session_data_t; /* TODO: "session"? */
+
+int _bt_create_session_sync(
+ const char* address,
+ char** session_id);
+int _bt_destroy_session_sync(
+ const char* session_id);
+int _bt_map_client_set_folder(
+ const char* session_id,
+ const char* name);
+int _bt_map_client_list_folders(
+ int request_id,
+ GDBusMethodInvocation *context,
+ const char* session_id,
+ const char* filter_serialized);
+int _bt_map_client_list_filter_fields(
+ int request_id,
+ GDBusMethodInvocation *context,
+ const char* session_id);
+int _bt_map_client_list_messages(
+ int request_id,
+ GDBusMethodInvocation *context,
+ const char* session_id,
+ const char* folder,
+ const char* filter_serialized);
+int _bt_map_client_update_inbox(
+ const char* session_id);
+int _bt_map_client_push_message(
+ int request_id,
+ GDBusMethodInvocation *context,
+ const char* session_id,
+ const char* source_file,
+ const char* folder,
+ const char* args_serialized);
+int _bt_map_client_get_message(
+ int request_id,
+ GDBusMethodInvocation *context,
+ const char* message_object,
+ const char* target_file,
+ bool attachment);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /*_BT_SERVICE_MAP_CLIENT_H_*/
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+#ifndef _BT_SERVICE_NETWORK_H_
+#define _BT_SERVICE_NETWORK_H_
+
+#include <glib.h>
+#include <sys/types.h>
+#include "bluetooth-api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NAP_UUID_NAME "nap"
+#define GN_UUID_NAME "gn"
+#define PANU_UUID_NAME "panu"
+#define NET_BRIDGE_INTERFACE "pan0"
+
+int _bt_network_activate(void);
+
+int _bt_network_deactivate(void);
+
+int _bt_network_connect(int request_id, int role,
+ bluetooth_device_address_t *device_address);
+
+int _bt_network_disconnect(int request_id,
+ bluetooth_device_address_t *device_address);
+
+int _bt_network_server_disconnect(int request_id,
+ bluetooth_device_address_t *device_address);
+
+void *_bt_network_connected_profile(void *connection, unsigned char *address);
+
+int _bt_is_network_connected(void *connection, unsigned char *address,
+ gboolean *is_connected);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /*_BT_SERVICE_NETWORK_H_*/
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __BT_SERVICE_OBEX_AGENT_H
+#define __BT_SERVICE_OBEX_AGENT_H
+
+#include <glib-object.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ BT_OBEX_AGENT_ERROR_REJECT,
+ BT_OBEX_AGENT_ERROR_CANCEL,
+ BT_OBEX_AGENT_ERROR_TIMEOUT,
+} bt_agent_error_t;
+
+G_BEGIN_DECLS
+typedef struct {
+ GObject parent;
+} BtObexAgent;
+
+typedef struct {
+ GObjectClass parent_class;
+} BtObexAgentClass;
+
+GType bt_obex_agent_get_type(void);
+
+#define BT_OBEX_TYPE_AGENT (bt_obex_agent_get_type())
+#define BT_OBEX_AGENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), BT_OBEX_TYPE_AGENT, BtObexAgent))
+#define BT_OBEX_AGENT_CLASS(agent_class) (G_TYPE_CHECK_CLASS_CAST((agent_class), BT_OBEX_TYPE_AGENT, BtObexAgentClass))
+#define BT_OBEX_GET_AGENT_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), BT_OBEX_TYPE_AGENT, BtObexAgentClass))
+
+typedef gboolean(*bt_obex_authorize_cb)(GDBusMethodInvocation *context,
+ const char *path,
+ gpointer data);
+
+typedef gboolean(*bt_obex_request_cb)(GDBusMethodInvocation *context,
+ GDBusProxy *transfer,
+ gpointer data);
+
+typedef gboolean(*bt_obex_progress_cb)(GDBusMethodInvocation *context,
+ GDBusProxy *transfer,
+ guint64 transferred,
+ gpointer data);
+
+typedef gboolean(*bt_obex_error_cb)(GDBusMethodInvocation *context,
+ GDBusProxy *transfer,
+ const char *message,
+ gpointer data);
+
+typedef gboolean(*bt_obex_complete_cb)(GDBusMethodInvocation *context,
+ GDBusProxy *transfer,
+ gpointer data);
+
+typedef gboolean(*bt_obex_release_cb)(GDBusMethodInvocation *context,
+ gpointer data);
+
+G_END_DECLS
+
+void _bt_obex_set_authorize_cb(char *object_path,
+ bt_obex_authorize_cb func,
+ gpointer data);
+
+void _bt_obex_set_request_cb(char *object_path,
+ bt_obex_request_cb func,
+ gpointer data);
+
+void _bt_obex_set_progress_cb(char *object_path,
+ bt_obex_progress_cb func,
+ gpointer data);
+
+void _bt_obex_set_error_cb(char *object_path,
+ bt_obex_error_cb func,
+ gpointer data);
+
+void _bt_obex_set_complete_cb(char *object_path,
+ bt_obex_complete_cb func,
+ gpointer data);
+
+void _bt_obex_set_release_cb(char *object_path,
+ bt_obex_release_cb func,
+ gpointer data);
+
+void _bt_obex_agent_new(char *path);
+
+void _bt_obex_agent_destroy(char *path);
+
+gboolean _bt_obex_setup(const char *path);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __BT_SERVICE_OBEX_AGENT_H */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+#ifndef _BT_SERVICE_OBEX_SERVER_H_
+#define _BT_SERVICE_OBEX_SERVER_H_
+
+#include <glib.h>
+#include <sys/types.h>
+#include "bluetooth-api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int _bt_register_obex_server(void);
+
+int _bt_unregister_obex_server(void);
+
+int _bt_obex_server_allocate(char *sender, const char *dest_path, int app_pid,
+ gboolean is_native);
+
+int _bt_obex_server_deallocate(int app_pid, gboolean is_native);
+
+int _bt_obex_server_accept_authorize(const char *filename, gboolean is_native);
+
+int _bt_obex_server_reject_authorize(void);
+
+int _bt_obex_server_set_destination_path(const char *dest_path,
+ gboolean is_native);
+
+int _bt_obex_server_set_root(const char *root);
+
+int _bt_obex_server_cancel_transfer(int transfer_id);
+
+int _bt_obex_server_cancel_all_transfers(void);
+
+int _bt_obex_server_is_activated(gboolean *activated);
+
+int _bt_obex_server_check_allocation(gboolean *allocation);
+
+int _bt_obex_server_check_termination(char *sender);
+
+int _bt_obex_server_accept_connection(int request_id);
+
+int _bt_obex_server_reject_connection(void);
+
+int _bt_opp_get_server_progress(int transfer_id, guint8 *progress);
+
+int _bt_obex_server_is_receiving(gboolean *receiving);
+
+
+void _bt_obex_transfer_progress(const char *transfer_path,
+ guint64 transferred);
+void _bt_obex_transfer_completed(const char *transfer_path, gboolean success);
+
+void _bt_obex_transfer_started(const char *transfer_path);
+
+void _bt_obex_check_pending_transfer(const char *address);
+
+void _bt_obex_transfer_connected(const char *obj_path);
+
+void _bt_obex_transfer_disconnected(char *address);
+
+int _bt_obex_get_native_pid(void);
+
+void _bt_obex_server_reply_accept(void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /*_BT_SERVICE_OBEX_SERVER_H_*/
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+#ifndef _BT_SERVICE_OOB_H_
+#define _BT_SERVICE_OOB_H_
+
+#include <glib.h>
+#include <sys/types.h>
+#include "bluetooth-api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int _bt_oob_read_local_data(bt_oob_data_t *local_oob_data);
+
+int _bt_oob_add_remote_data(
+ bluetooth_device_address_t *remote_device_address,
+ unsigned short address_type,
+ bt_oob_data_t *remote_oob_data);
+
+int _bt_oob_remove_remote_data(
+ bluetooth_device_address_t *remote_device_address);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /*_BT_SERVICE_OOB_H_*/
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+#ifndef _BT_SERVICE_OPP_CLIENT_H_
+#define _BT_SERVICE_OPP_CLIENT_H_
+
+#include <glib.h>
+#include <sys/types.h>
+#include <gio/gio.h>
+#include "bluetooth-api.h"
+#include "bt-internal-types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BT_OBEX_CLIENT_AGENT_PATH "/org/obex/client_agent"
+
+typedef enum {
+ BT_TRANSFER_STATUS_QUEUED = 0x00,
+ BT_TRANSFER_STATUS_STARTED,
+ BT_TRANSFER_STATUS_PROGRESS,
+ BT_TRANSFER_STATUS_COMPLETED,
+} bt_transfer_status_t;
+
+typedef struct {
+ char path[BT_FILE_PATH_MAX];
+} bt_file_path_t;
+
+typedef struct {
+ GDBusProxy *proxy;
+ GDBusProxy *properties_proxy;
+ char *transfer_name;
+ char *file_name;
+ char *transfer_path;
+ bt_transfer_status_t transfer_status;
+ gint64 size;
+ guint64 progress;
+} bt_transfer_info_t;
+
+typedef struct {
+ int request_id;
+ int result;
+
+ int file_count;
+ int file_offset;
+ char **file_name_array;
+ char *session_path;
+
+ char *address;
+ gboolean is_canceled;
+ bt_transfer_info_t *transfer_info;
+} bt_sending_info_t;
+
+typedef struct {
+ char *address;
+ char **file_path;
+ int file_count;
+ int request_id;
+} bt_sending_data_t;
+
+
+int _bt_opp_client_push_files(int request_id, GDBusMethodInvocation *context,
+ bluetooth_device_address_t *remote_address,
+ char **file_path, int file_count);
+
+int _bt_opp_client_cancel_push(void);
+
+int _bt_opp_client_cancel_all_transfers(void);
+
+int _bt_opp_client_is_sending(gboolean *sending);
+
+void _bt_sending_files(void);
+
+void _bt_opc_disconnected(const char *session_path);
+
+gboolean _bt_obex_client_progress(const char *transfer_path, guint64 transferred);
+
+gboolean _bt_obex_client_started(const char *transfer_path);
+
+gboolean _bt_obex_client_completed(const char *transfer_path, gboolean success);
+
+void _bt_opp_client_check_pending_transfer(const char *address);
+
+int _bt_opp_get_client_progress(guint8 *progress);
+
+void _bt_cancel_queued_transfers(void);
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /*_BT_SERVICE_OPP_CLIENT_H_*/
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef BT_SERVICE_PBAP_H
+#define BT_SERVICE_PBAP_H
+
+#include <stdint.h>
+#include <glib.h>
+#include <unistd.h>
+#include <dlog.h>
+#include <stdio.h>
+
+#undef LOG_TAG
+#define LOG_TAG "BLUETOOTH_FRWK_SERVICE"
+#define ERR(fmt, args...) SLOGE(fmt, ##args)
+
+int _bt_pbap_connect(const bluetooth_device_address_t *address);
+
+int _bt_pbap_disconnect(const bluetooth_device_address_t *address);
+
+int _bt_pbap_is_connected(bluetooth_device_address_t *device_address,
+ gboolean *connected);
+
+int _bt_pbap_get_phonebook_size(const bluetooth_device_address_t *address,
+ int source, int type);
+
+int _bt_pbap_get_phonebook(const bluetooth_device_address_t *address,
+ int source, int type, bt_pbap_pull_parameters_t *app_param);
+
+int _bt_pbap_get_list(const bluetooth_device_address_t *address, int source,
+ int type, bt_pbap_list_parameters_t *app_param);
+
+int _bt_pbap_pull_vcard(const bluetooth_device_address_t *address,
+ int source, int type, bt_pbap_pull_vcard_parameters_t *app_param);
+
+int _bt_pbap_phonebook_search(const bluetooth_device_address_t *address,
+ int source, int type, bt_pbap_search_parameters_t *app_param);
+
+void _bt_pbap_obex_transfer_completed(const char *transfer_path, gboolean transfer_status);
+
+void _bt_obex_pbap_client_disconnect(char *path);
+#endif
#define _BLUETOOTH_API_H_
#include <stdlib.h>
+#ifdef TIZEN_FEATURE_BT_OBEX
+#include <stdbool.h>
+#endif
#include <unistd.h>
#include <glib.h>
/**< Base ID for AVRCP events */
#define BLUETOOTH_EVENT_IPSP_BASE ((int)(BLUETOOTH_EVENT_AVRCP_CONTROL_BASE + 0x0020))
/**< Base ID for IPSP events */
+#ifdef TIZEN_FEATURE_BT_OBEX
+#define BLUETOOTH_EVENT_MAP_BASE ((int)(BLUETOOTH_EVENT_IPSP_BASE + 0x0020))
+ /**< Base ID for MAP events */
+#endif
+
/**
* Bluetooth event type
BLUETOOTH_EVENT_OPC_TRANSFER_STARTED, /* OPC Transfer started event */
BLUETOOTH_EVENT_OPC_TRANSFER_PROGRESS, /* OPC Transfer progress event */
BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE, /* OPC Transfer Complete event */
-
+#ifdef TIZEN_FEATURE_BT_OBEX
+ BLUETOOTH_EVENT_MAP_CONNECTED = BLUETOOTH_EVENT_MAP_BASE,
+ BLUETOOTH_EVENT_MAP_DISCONNECTED,
+ BLUETOOTH_EVENT_MAP_LIST_FOLDERS_COMPLETE,
+ BLUETOOTH_EVENT_MAP_LIST_FOLDERS_INVALID_ARGUMENTS,
+ BLUETOOTH_EVENT_MAP_LIST_FOLDERS_FAILED,
+ BLUETOOTH_EVENT_MAP_LIST_MESSAGES_COMPLETE,
+ BLUETOOTH_EVENT_MAP_LIST_MESSAGES_INVALID_ARGUMENTS,
+ BLUETOOTH_EVENT_MAP_LIST_MESSAGES_FAILED,
+ BLUETOOTH_EVENT_MAP_PUSH_MESSAGE_COMPLETE,
+ BLUETOOTH_EVENT_MAP_PUSH_MESSAGE_INVALID_ARGUMENTS,
+ BLUETOOTH_EVENT_MAP_PUSH_MESSAGE_FAILED,
+ BLUETOOTH_EVENT_MAP_GET_MESSAGE_COMPLETE,
+ BLUETOOTH_EVENT_MAP_GET_MESSAGE_INVALID_ARGUMENTS,
+ BLUETOOTH_EVENT_MAP_GET_MESSAGE_FAILED,
+ BLUETOOTH_EVENT_MAP_LIST_FILTER_FIELD_COMPLETE,
+#endif
BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_AUTHORIZE = BLUETOOTH_EVENT_OBEX_SERVER_BASE,
/* Obex server authorize event*/
BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_STARTED, /* Obex Server transfer started event*/
//#ifndef GATT_DIRECT
BT_GATT_SERVER_EVENT,
//#endif
+#ifdef TIZEN_FEATURE_BT_OBEX
+ BT_MAP_CLIENT_EVENT,
+#endif
} bt_event_type_t;
typedef enum {
#define BT_FUNC_IPSP_BASE ((int)(BT_FUNC_GATT_BASE + 0x0020))
#define BT_FUNC_DPM_BASE ((int)(BT_FUNC_IPSP_BASE + 0x0020))
#define BT_FUNC_PXP_BASE ((int)(BT_FUNC_DPM_BASE + 0x0030)) /* Adding 0x0030 to base, as DPM has more use case */
-
+#ifdef TIZEN_FEATURE_BT_OBEX
+#define BT_FUNC_MAP_BASE ((int)(BT_FUNC_PXP_BASE + 0x0020))
+#endif
typedef enum {
BT_CHECK_ADAPTER = BT_FUNC_BASE,
BT_ENABLE_ADAPTER,
BT_OPP_CANCEL_PUSH,
BT_OPP_IS_PUSHING_FILES,
BT_OPP_GET_TRANSFER_PROGRESS,
+#ifdef TIZEN_FEATURE_BT_OBEX
+ BT_MAP_CREATE_SESSION = BT_FUNC_MAP_BASE,
+ BT_MAP_DESTROY_SESSION,
+ BT_MAP_SET_FOLDER,
+ BT_MAP_LIST_FOLDERS,
+ BT_MAP_LIST_FILTER_FIELDS,
+ BT_MAP_LIST_MESSAGES,
+ BT_MAP_UPDATE_INBOX,
+ BT_MAP_PUSH_MESSAGE,
+ BT_MAP_GET_MESSAGE,
+#endif
BT_OBEX_SERVER_ALLOCATE,
BT_OBEX_SERVER_DEALLOCATE,
BT_OBEX_SERVER_IS_ACTIVATED,
#define BT_IBEACON_DEVICE_FOUND "iBeaconDeviceFound"
#define BT_PXP_PROPERTY_CHANGED "PxpValueChanged"
+#ifdef TIZEN_FEATURE_BT_OBEX
+typedef enum {
+ _PROFILE_UNKNOWN = 0,
+ _PROFILE_MOBILE = 0x1,
+ _PROFILE_WEARABLE = 0x2,
+ _PROFILE_TV = 0x4,
+ _PROFILE_IVI = 0x8,
+ _PROFILE_COMMON = 0x10,
+} tizen_profile_t;
+
+
+/* For optimization, make this extern and define in a shared C file */
+tizen_profile_t profile;
+#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
%build
export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE"
+export CFLAGS="$CFLAGS -DTIZEN_FEATURE_BT_OBEX"
export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE"
export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE"
%if %{bt_bluez_hal} == ENABLED
export BT_INCLUDE_OAL_BLUEZ=ENABLED
export CFLAGS="$CFLAGS -DTIZEN_BT_INCLUDE_OAL_BLUEZ"
-#export CFLAGS="$CFLAGS -DTIZEN_SYSPOPUP_SUPPORTED"
+export CFLAGS="$CFLAGS -DTIZEN_SYSPOPUP_SUPPORTED"
%else
export BT_INCLUDE_OAL_BLUEZ=DISABLED
%endif