return result;
}
+BT_EXPORT_API int bluetooth_media_control_command_to_dest(
+ media_player_control_cmd type,
+ bluetooth_device_address_t *remote_address)
+{
+ int result;
+
+ BT_CHECK_ENABLED(return);
+
+#ifdef TIZEN_FEATURE_BT_DPM
+ if (_bt_check_dpm(BT_DPM_AVRCP, NULL) == BT_DPM_RESTRICTED) {
+ BT_ERR("Not allow to use AVRCP profile");
+ return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
+ }
+#endif
+ BT_INIT_PARAMS();
+ BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+ g_array_append_vals(in_param1, &type, sizeof(int));
+ g_array_append_vals(in_param2, remote_address,
+ sizeof(bluetooth_device_address_t));
+
+ result = _bt_send_request(BT_BLUEZ_SERVICE, BT_AVRCP_HANDLE_CONTROL_TO_DEST,
+ in_param1, in_param2, in_param3, in_param4, &out_param);
+
+ BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+ return result;
+}
+
BT_EXPORT_API int bluetooth_media_control_set_property(
media_player_property_type type,
unsigned int value)
{BT_AVRCP_TARGET_CONNECT, "BT_AVRCP_TARGET_CONNECT"},
{BT_AVRCP_TARGET_DISCONNECT, "BT_AVRCP_TARGET_DISCONNECT"},
{BT_AVRCP_HANDLE_CONTROL, "BT_AVRCP_HANDLE_CONTROL"},
+ {BT_AVRCP_HANDLE_CONTROL_TO_DEST, "BT_AVRCP_HANDLE_CONTROL_TO_DEST"},
{BT_AVRCP_CONTROL_SET_PROPERTY, "BT_AVRCP_CONTROL_SET_PROPERTY"},
{BT_AVRCP_CONTROL_GET_PROPERTY, "BT_AVRCP_CONTROL_GET_PROPERTY"},
{BT_AVRCP_GET_TRACK_INFO, "BT_AVRCP_GET_TRACK_INFO"},
if (profile_gproxy)
return profile_gproxy;
- gconn = _bt_get_system_private_conn();
+ /* Shared connection should be used because rfcomm interface was registered
+ * on shared connection not private. Otherwise, dbus rejection is occured
+ * because dbus policy is only applied on shared connection not private. */
+ gconn = _bt_get_system_shared_conn();
if (gconn == NULL)
return NULL;
NULL, &err);
if (err) {
g_dbus_error_strip_remote_error(err);
- BT_ERR("RegisterProfile failed: %s", err->message);
+ BT_ERR("RegisterProfile2 failed: %s", err->message);
if (g_strrstr(err->message, BT_ACCESS_DENIED_MSG))
result = BLUETOOTH_ERROR_ACCESS_DENIED;
if (err) {
g_dbus_error_strip_remote_error(err);
- BT_ERR("RegisterProfile failed: %s", err->message);
+ BT_ERR("RegisterProfile1 failed: %s", err->message);
if (g_strrstr(err->message, BT_ACCESS_DENIED_MSG))
result = BLUETOOTH_ERROR_ACCESS_DENIED;
conn_info.addr_type = addr_type;
conn_info.disc_reason = result;
- BT_DBG("Sending Event to Framework");
+ BT_DBG("Sending Event to Framework, disconnect reason [0x%x]", result);
_bt_common_event_cb(BLUETOOTH_EVENT_DEVICE_DISCONNECTED,
result, &conn_info,
event_info->cb, event_info->user_data);
} else if (strcasecmp(signal_name, BT_GATT_SERVER_ACQUIRE_NOTIFICATION) == 0) {
- bluetooth_gatt_server_send_acquire_notify_response(parameters);
+ bluetooth_gatt_server_send_acquire_notify_response(parameters, event_info);
} else if (strcasecmp(signal_name, BT_GATT_SERVER_NOTIFICATION_COMPLETED) == 0) {
const char *address = NULL;
BT_INFO("GATT Server: Notification Enabled?? Handle: [%d] address [%s] Is Enabled [%d] result [%d]",
info.handle, address, info.notification, result);
+ if (info.notification == FALSE)
+ cleanup_gatt_acquire_fd(info.handle);
+
_bt_gatt_server_event_cb(BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_STATE_CHANGED,
result, &info,
event_info->cb, event_info->user_data);
static gboolean bluetooth_gatt_write_channel_watch_cb(GIOChannel *gio,
GIOCondition cond, gpointer data)
{
+ BT_INFO("+");
+
bluetooth_gatt_acquire_notify_info_t *chr_info = (bluetooth_gatt_acquire_notify_info_t *)data;
- if (!chr_info)
+ if (!chr_info) {
+ BT_INFO("chr_info is NULL");
return FALSE;
+ }
if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
BT_ERR("Error : GIOCondition %d, []", cond);;
g_io_channel_shutdown(gio, TRUE, NULL);
g_io_channel_unref(gio);
- gatt_characteristic_server_notify_list = g_slist_remove(gatt_characteristic_server_notify_list, chr_info);
- bluetooth_characteristic_info_free(chr_info);
+ if (g_slist_find(gatt_characteristic_server_notify_list, chr_info)) {
+ BT_INFO("found char_info in the list");
+ gatt_characteristic_server_notify_list = g_slist_remove(gatt_characteristic_server_notify_list, chr_info);
+ bluetooth_characteristic_info_free(chr_info);
+ }
return FALSE;
}
+ if (g_slist_find(gatt_characteristic_server_notify_list, chr_info) == NULL) {
+ BT_INFO("chr_info is not in the list");
+ return FALSE;
+ }
+
return TRUE;
}
-void bluetooth_gatt_server_send_acquire_notify_response(GVariant * parameters)
+void bluetooth_gatt_server_send_acquire_notify_response(GVariant * parameters, bt_event_info_t *event_info)
{
int con_id = -1;
int tran_id = -1;
int result = -1;
int fd = -1;
bluetooth_gatt_acquire_notify_info_t *chr_info;
+ const char *address = NULL;
- g_variant_get(parameters, "(iiiiii)",
+ g_variant_get(parameters, "(iiiiiis)",
&result,
&con_id,
&tran_id,
&att_han,
&mtu,
- &offset);
+ &offset,
+ &address);
BT_DBG("GATT ServerAcquire Conn ID: [%d]", con_id);
BT_DBG("GATT Server Acquire notify att handle:[%d]", att_han);
BT_DBG("GATT Server Acquire Notify Offset: [%d]", offset);
+ BT_DBG("GATT Server Acquire Notify address: [%s]", address);
if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipefd) < 0) {
chr_info->write_fd = fd;
+ BT_INFO("setting up g_io channel");
channel = g_io_channel_unix_new(fd);
g_io_channel_set_encoding(channel, NULL, NULL);
g_io_channel_set_buffered(channel, FALSE);
BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+ //send
+ if (result == BLUETOOTH_ERROR_NONE) {
+
+ BT_INFO("sending gatt server notification state changed event");
+ bluetooth_gatt_server_notification_changed_t info;
+ bluetooth_device_address_t dev_address = { {0} };
+ memset(&info, 0x00, sizeof(bluetooth_gatt_server_notification_changed_t));
+
+ _bt_convert_addr_string_to_type(dev_address.addr, address);
+ memcpy(info.device_address.addr,
+ dev_address.addr,
+ BLUETOOTH_ADDRESS_LENGTH);
+ info.handle = att_han;
+ info.notification = TRUE;
+
+ _bt_gatt_server_event_cb(BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_STATE_CHANGED,
+ result, &info,
+ event_info->cb, event_info->user_data);
+
+ }
+}
+
+void cleanup_gatt_acquire_fd(int handle)
+{
+ bluetooth_gatt_acquire_notify_info_t *chr_info = NULL;
+
+ BT_INFO("+");
+
+ chr_info = bluetooth_get_characteristic_info_from_path(handle);
+
+ if (chr_info != NULL) {
+ BT_INFO("GATT Server: acquire notification char info found");
+
+ if (chr_info->write_fd >= 0) {
+ BT_INFO("closing fd");
+ close(chr_info->write_fd);
+ }
+
+ BT_INFO("Removing char_info from the list");
+ gatt_characteristic_server_notify_list = g_slist_remove(gatt_characteristic_server_notify_list, chr_info);
+ bluetooth_characteristic_info_free(chr_info);
+ }
}
void bluetooth_gatt_server_send_acquire_write_response(GVariant * parameter);
-void bluetooth_gatt_server_send_acquire_notify_response(GVariant * parameter);
+void bluetooth_gatt_server_send_acquire_notify_response(GVariant * parameter, bt_event_info_t *event_info);
+
+void cleanup_gatt_acquire_fd(int handle);
+
#ifdef __cplusplus
}
SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g ")
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall -Werror")
FIND_PROGRAM(UNAME NAMES uname)
</policy>
<policy context="default">
<deny own_prefix="org.bt.frwk"/>
- <deny send_destination_prefix="org.bt.frwk"/>
+ <allow own_prefix="org.bt.frwk"/>
+ <deny send_destination_prefix="org.bt.frwk" send_interface="org.bluez.Profile1"/>
<deny own_prefix="org.frwk.gatt_service"/>
- <deny send_destination_prefix="org.frwk.gatt_service"/>
+ <allow own_prefix="org.frwk.gatt_service"/>
+ <deny send_destination_prefix="org.frwk.gatt_service" send_interface="org.bluez.GattDescriptor1"/>
+ <deny send_destination_prefix="org.frwk.gatt_service" send_interface="org.bluez.GattCharacteristic1"/>
</policy>
</busconfig>
* This is RFCOMM default Channel Value
*/
#define RFCOMM_DEFAULT_PROFILE_CHANNEL 0
+#define BT_AUDIO_SOURCE_MAX 2
static char *avrcp_control_path = NULL;
static char *avrcp_transport_path = NULL;
static GDBusProxy *adapter_properties_proxy;
static GDBusProxy *avrcp_ctrl_proxy;
+struct avrcp_proxy {
+ GDBusProxy *avrcp_ctrl_proxy;
+ char *avrcp_control_path;
+ bt_bdaddr_t bd_addr;
+};
+
+struct avrcp_proxy proxy_array[BT_AUDIO_SOURCE_MAX];
+
static GDBusConnection *system_gconn = NULL;
static guint bus_id;
void _bt_hal_set_control_device_path(const char *path)
{
+ int i;
if (path == NULL)
return;
- g_free(avrcp_control_path);
DBG("control_path = %s", path);
- avrcp_control_path = g_strdup(path);
+
+ for (i = 0; i < BT_AUDIO_SOURCE_MAX; i++) {
+ if (proxy_array[i].avrcp_control_path == NULL) {
+ proxy_array[i].avrcp_control_path = g_strdup(path);
+ DBG("PATH %s formed index %d", proxy_array[i].avrcp_control_path, i);
+ return;
+ }
+ }
}
void _bt_hal_remove_control_device_path(const char *path)
{
+ int i;
+
if (path == NULL)
return;
- if (avrcp_control_path &&
- !g_strcmp0(avrcp_control_path, path)) {
- DBG("control_path = %s", path);
- g_free(avrcp_control_path);
- avrcp_control_path = NULL;
+ for (i = 0; i < BT_AUDIO_SOURCE_MAX; i++) {
+ if (g_strcmp0(proxy_array[i].avrcp_control_path, path) == 0) {
+ DBG("Clear AVRCP proxy[%d]", i);
+ g_free(proxy_array[i].avrcp_control_path);
+ g_object_unref(proxy_array[i].avrcp_ctrl_proxy);
+
+ proxy_array[i].avrcp_control_path = NULL;
+ proxy_array[i].avrcp_ctrl_proxy = NULL;
+ memset(proxy_array[i].bd_addr.address, 0, 6);
+ return;
+ }
}
}
{
GDBusProxy *manager_proxy;
GDBusProxy *proxy;
- char *control_path = NULL;
+ GDBusConnection *gconn = NULL;
+ int i;
- if (system_conn == NULL) {
- system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
- if (system_conn == NULL)
- return NULL;
- }
+ gconn = _bt_hal_gdbus_get_system_gconn();
+ if (gconn == NULL)
+ return NULL;
manager_proxy = _bt_hal_get_manager_proxy();
if (manager_proxy == NULL)
return NULL;
- control_path = _bt_hal_get_control_device_path(bd_addr);
- if (control_path == NULL)
- return NULL;
+ for (i = 0; i < BT_AUDIO_SOURCE_MAX; i++) {
+ if (proxy_array[i].avrcp_ctrl_proxy == NULL) {
+ memcpy(proxy_array[i].bd_addr.address, bd_addr->address, 6);
+ DBG("PATH %s formed index %d ", proxy_array[i].avrcp_control_path, i);
+ break;
+ }
+ }
- proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE,
+ if (i == BT_AUDIO_SOURCE_MAX) {
+ ERR("NO free arr proxy space found");
+ return NULL;
+ }
+
+ proxy = g_dbus_proxy_new_sync(gconn, G_DBUS_PROXY_FLAGS_NONE,
NULL, BT_HAL_BLUEZ_NAME,
- control_path, BT_HAL_PLAYER_CONTROL_INTERFACE, NULL, NULL);
+ proxy_array[i].avrcp_control_path, BT_HAL_PLAYER_CONTROL_INTERFACE, NULL, NULL);
if (proxy == NULL)
return NULL;
avrcp_ctrl_proxy = proxy;
+ proxy_array[i].avrcp_ctrl_proxy = proxy;
+
return proxy;
}
GDBusProxy *_bt_hal_get_avrcp_ctrl_proxy(bt_bdaddr_t *bd_addr)
{
- if (avrcp_ctrl_proxy) {
- const char *path = g_dbus_proxy_get_object_path(avrcp_ctrl_proxy);
- if (path == NULL) {
- ERR("Already proxy released hence creating new proxy");
- return __bt_hal_init_avrcp_ctrl_proxy(bd_addr);
- }
+ int i;
+
+ for (i = 0; i < BT_AUDIO_SOURCE_MAX; i++) {
+ if (proxy_array[i].avrcp_ctrl_proxy
+ && (!memcmp(proxy_array[i].bd_addr.address, bd_addr->address, 6))) {
+ const gchar *path = g_dbus_proxy_get_object_path(proxy_array[i].avrcp_ctrl_proxy);
+
+ if (!path) {
+ proxy_array[i].avrcp_ctrl_proxy = NULL;
+ ERR("Already proxy released hence creating new proxy");
+ return __bt_hal_init_avrcp_ctrl_proxy(bd_addr);
+ }
- return avrcp_ctrl_proxy;
+ DBG("address found path PATH %s", path);
+ return proxy_array[i].avrcp_ctrl_proxy;
+ }
}
- return __bt_hal_init_avrcp_ctrl_proxy(bd_addr);
+ DBG("address NOT found");
+
+ return __bt_hal_init_avrcp_ctrl_proxy(bd_addr);
}
GDBusProxy *_bt_hal_get_avrcp_ctrl_properties_proxy(bt_bdaddr_t *bd_addr)
}
}
+int _bt_hal_convert_disc_reason_to_status(int reason)
+{
+ switch (reason) {
+ case 1:
+ return BT_STATUS_CONN_TOUT; //"Link loss"
+ case 2:
+ return BT_STATUS_CONN_TERM_LOCAL_HOST; //"Connection terminated by local host";
+ case 3:
+ return BT_STATUS_CONN_TERM_RMT_HOST; //"Connection terminated by local host";
+ case 0:
+ default:
+ return BT_STATUS_FAIL;
+ }
+}
+
void _bt_hal_logging_connection(gboolean connect, int addr_type)
{
static int le_conn = 0;
GVariant *_bt_hal_get_managed_objects(void);
+ char * _bt_hal_convert_disc_reason_to_string(int reason);
+
+ int _bt_hal_convert_disc_reason_to_status(int reason);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
static void __bt_hal_dbus_device_found_properties(const char *device_path);
static void __bt_hal_device_properties_lookup(GVariant *result, char *address);
static void __bt_hal_handle_device_specific_events(GVariant *msg, const char *member, const char *path);
-static void __bt_hal_send_device_acl_connection_state_event(gboolean connected, const char *address);
+static void __bt_hal_send_device_acl_connection_state_event(int status, gboolean connected, const char *address);
static void __bt_hal_handle_input_event(GVariant *msg, const char *path);
static void __bt_hal_send_av_connection_state_event(gboolean connected, const char *address);
static void __bt_hal_send_a2dp_sink_connection_state_event(gboolean connected, const char *address);
DBG("-");
}
-static void __bt_hal_send_device_acl_connection_state_event(gboolean connected, const char *address)
+static void __bt_hal_send_device_acl_connection_state_event(int status, gboolean connected, const char *address)
{
DBG("+");
struct hal_ev_acl_state_changed ev;
- ev.status = BT_STATUS_SUCCESS;
+ ev.status = status;
ev.state = (connected == TRUE) ?
HAL_ACL_STATE_CONNECTED :
HAL_ACL_STATE_DISCONNECTED;
DBG("-");
}
-static void __bt_hal_send_device_le_connection_state_event(gboolean connected, const char *address)
+static void __bt_hal_send_device_le_connection_state_event(int status, gboolean connected, const char *address)
{
DBG("+");
struct hal_ev_le_conn_state_changed ev;
- ev.status = BT_STATUS_SUCCESS;
+ ev.status = status;
ev.state = (connected == TRUE) ?
HAL_LE_STATE_CONNECTED :
HAL_LE_STATE_DISCONNECTED;
DBG("Member: [%s]", member);
ERR_C("Connected [%s] [%s]", !addr_type ? "BREDR" : "LE", address);
if (!addr_type)
- __bt_hal_send_device_acl_connection_state_event(TRUE, address);
+ __bt_hal_send_device_acl_connection_state_event(BT_STATUS_SUCCESS, TRUE, address);
else
- __bt_hal_send_device_le_connection_state_event(TRUE, address);
+ __bt_hal_send_device_le_connection_state_event(BT_STATUS_SUCCESS, TRUE, address);
g_free(address);
} else if (strcasecmp(member, "Disconnected") == 0) {
unsigned char disc_reason = 0;
_bt_hal_convert_device_path_to_address(path, address);
DBG("Member: [%s]", member);
+
ERR_C("DisConnected [%s] [%s]", !addr_type ? "BREDR" : "LE", address);
- DBG("Disconnect Reason: %d", disc_reason);
+ DBG("Disconnected Reason [%d : %s]", disc_reason, _bt_hal_convert_disc_reason_to_string(disc_reason));
DBG("Name: %s", name);
if (!addr_type)
- __bt_hal_send_device_acl_connection_state_event(FALSE, address);
+ __bt_hal_send_device_acl_connection_state_event(_bt_hal_convert_disc_reason_to_status(disc_reason), FALSE, address);
else
- __bt_hal_send_device_le_connection_state_event(FALSE, address);
+ __bt_hal_send_device_le_connection_state_event(_bt_hal_convert_disc_reason_to_status(disc_reason), FALSE, address);
g_free(address);
} else if (strcasecmp(member, "ProfileStateChanged") == 0) {
int state = 0;
NULL,
(GAsyncReadyCallback)__le_disconnection_req_cb, gattc_data);
return ret;
-fail:
- if (device_proxy)
- g_object_unref(device_proxy);
-
- g_free(gattc_data);
-
- return ret;
}
/** Disconnect a remote device or cancel a pending connection */
(GAsyncReadyCallback)__le_connection_req_cb, gattc_data);
return ret;
-
-fail:
- if (device_proxy)
- g_object_unref(device_proxy);
-
- g_free(gattc_data);
-
- return ret;
}
static bt_status_t _bt_hold_current_advertising()
case BT_STATUS_UNSUPPORTED:
ret = OAL_STATUS_NOT_SUPPORT;
break;
+ case BT_STATUS_CONN_TOUT:
+ ret = OAL_STATUS_LINK_LOSS;
+ break;
+#ifdef TIZEN_BT_HAL
+ case BT_STATUS_CONN_TERM_LOCAL_HOST:
+ ret = OAL_STATUS_CONN_TERM_LOCAL_HOST;
+ break;
+ case BT_STATUS_CONN_TERM_RMT_HOST:
+ ret = OAL_STATUS_CONN_TERM_RMT_HOST;
+ break;
+#endif
case BT_STATUS_UNHANDLED:
case BT_STATUS_FAIL:
case BT_STATUS_NOMEM:
BT_STATUS_UNHANDLED,
BT_STATUS_AUTH_FAILURE,
BT_STATUS_RMT_DEV_DOWN,
- BT_STATUS_AUTH_REJECTED
-
+#ifndef TIZEN_BT_HAL
+ BT_STATUS_CONN_TOUT /* disconnection due to supervision timeout */
+#else
+ BT_STATUS_CONN_TOUT, /* disconnection due to supervision timeout */
+ BT_STATUS_AUTH_REJECTED,
+ BT_STATUS_CONN_TERM_LOCAL_HOST,
+ BT_STATUS_CONN_TERM_RMT_HOST
+#endif
} bt_status_t;
/** Bluetooth PinKey Code */
OAL_STATUS_PENDING,
OAL_STATUS_CONN_TIMEOUT,
/* HID */
- OAL_STATUS_HID_FAILED_MOUSE
+ OAL_STATUS_HID_FAILED_MOUSE,
+#ifndef TIZEN_BT_HAL
+ OAL_STATUS_LINK_LOSS
+#else
+ OAL_STATUS_LINK_LOSS,
+ OAL_STATUS_CONN_TERM_LOCAL_HOST,
+ OAL_STATUS_CONN_TERM_RMT_HOST
+#endif
} oal_status_t;
memcpy(conn_status->address.addr, bd_addr->address, 6);
+#ifdef TIZEN_BT_HAL
+ conn_status->status = convert_to_oal_status(status);
+#else
if (BT_STATUS_SUCCESS != status) {
/* At present only timeout will cause non-success status, later we can add more */
conn_status->status = OAL_STATUS_CONN_TIMEOUT;
conn_status->status = OAL_STATUS_SUCCESS;
memcpy(conn_status->address.addr, bd_addr->address, 6);
+#endif
+
+ BT_INFO("ACL STATE :%d, conn_status->status :%d, BT_ACL_STATE: %d", status, conn_status->status, state);
+
switch (state) {
case BT_ACL_STATE_CONNECTED:
event = OAL_EVENT_DEVICE_ACL_CONNECTED;
BT_DBG("LE conn status:%d, state: %d", status, state);
memcpy(conn_status->address.addr, bd_addr->address, 6);
- if (BT_STATUS_SUCCESS != status)
- /* At present only timeout will cause non-success status, later we can add more */
- conn_status->status = OAL_STATUS_CONN_TIMEOUT;
- else
- conn_status->status = OAL_STATUS_SUCCESS;
+ conn_status->status = convert_to_oal_status(status);
switch (state) {
case BT_LE_CONN_STATE_CONNECTED:
static void __bt_handle_av_source_connected_state(bluetooth_device_address_t *address)
{
char addr[BT_ADDRESS_STRING_SIZE] = { 0 };
- char connected_address[BT_ADDRESS_STRING_SIZE + 1];
- gboolean connected;
+
bt_headset_wait_t *wait_device = NULL;
- bluetooth_device_address_t device_address;
bluetooth_device_address_t wait_device_address;
GVariant *param;
int result = BLUETOOTH_ERROR_NONE;
param = g_variant_new("(is)", result, addr);
_bt_send_event(BT_HEADSET_EVENT, BLUETOOTH_EVENT_AV_SOURCE_CONNECTED, param);
- connected = _bt_is_headset_type_connected(BT_AUDIO_A2DP_SOURCE, connected_address);
- if (connected) {
- if (g_strcmp0(connected_address, addr) != 0) {
- _bt_convert_addr_string_to_type(
- device_address.addr,
- connected_address);
- _bt_audio_disconnect(BT_AUDIO_A2DP_SOURCE, &device_address);
- }
- }
/* Add data from the connected list */
_bt_add_headset_to_list(BT_AUDIO_A2DP_SOURCE, BT_STATE_CONNECTED, addr);
connected = _bt_is_headset_type_connected(BT_AVRCP, connected_address);
- if (connected) {
- _bt_convert_addr_string_to_type(device_address.addr,
- connected_address);
- switch (type) {
- case RC_PASS_CMD_PLAY:
- status = avrcp_ct_play((bt_address_t*)&device_address);
- break;
- case RC_PASS_CMD_PAUSE:
- status = avrcp_ct_pause((bt_address_t*)&device_address);
- break;
- case RC_PASS_CMD_STOP:
- status = avrcp_ct_stop((bt_address_t*)&device_address);
- break;
- case RC_PASS_CMD_NEXT:
- status = avrcp_ct_next_track((bt_address_t*)&device_address);
- break;
- case RC_PASS_CMD_PREVIOUS:
- status = avrcp_ct_prev_track((bt_address_t*)&device_address);
- break;
- case RC_PASS_CMD_PRESS_FAST_FORWARD:
- status = avrcp_ct_fforward((bt_address_t*)&device_address, PRESS_STATE);
- break;
- case RC_PASS_CMD_RELEASE_FAST_FORWARD:
- status = avrcp_ct_fforward((bt_address_t*)&device_address, RELEASE_STATE);
- break;
- case RC_PASS_CMD_PRESS_REWIND:
- status = avrcp_ct_rewind((bt_address_t*)&device_address, PRESS_STATE);
- break;
- case RC_PASS_CMD_RELEASE_REWIND:
- status = avrcp_ct_rewind((bt_address_t*)&device_address, RELEASE_STATE);
- break;
- case RC_PASS_CMD_VOLUME_UP:
- status = avrcp_ct_volume_up((bt_address_t*)&device_address);
- break;
- case RC_PASS_CMD_VOLUME_DOWN:
- status = avrcp_ct_volume_down((bt_address_t*)&device_address);
- break;
- default:
- break;
- }
+ if (!connected) {
+ BT_ERR("Device is not connected:");
+ return BLUETOOTH_ERROR_NOT_CONNECTED;
+ }
- if (status != OAL_STATUS_SUCCESS) {
- BT_ERR("Send pass through command err: [%d]", status);
- result = BLUETOOTH_ERROR_INTERNAL;
- }
- } else {
+ _bt_convert_addr_string_to_type(device_address.addr,
+ connected_address);
+ switch (type) {
+ case RC_PASS_CMD_PLAY:
+ status = avrcp_ct_play((bt_address_t*)&device_address);
+ break;
+ case RC_PASS_CMD_PAUSE:
+ status = avrcp_ct_pause((bt_address_t*)&device_address);
+ break;
+ case RC_PASS_CMD_STOP:
+ status = avrcp_ct_stop((bt_address_t*)&device_address);
+ break;
+ case RC_PASS_CMD_NEXT:
+ status = avrcp_ct_next_track((bt_address_t*)&device_address);
+ break;
+ case RC_PASS_CMD_PREVIOUS:
+ status = avrcp_ct_prev_track((bt_address_t*)&device_address);
+ break;
+ case RC_PASS_CMD_PRESS_FAST_FORWARD:
+ status = avrcp_ct_fforward((bt_address_t*)&device_address, PRESS_STATE);
+ break;
+ case RC_PASS_CMD_RELEASE_FAST_FORWARD:
+ status = avrcp_ct_fforward((bt_address_t*)&device_address, RELEASE_STATE);
+ break;
+ case RC_PASS_CMD_PRESS_REWIND:
+ status = avrcp_ct_rewind((bt_address_t*)&device_address, PRESS_STATE);
+ break;
+ case RC_PASS_CMD_RELEASE_REWIND:
+ status = avrcp_ct_rewind((bt_address_t*)&device_address, RELEASE_STATE);
+ break;
+ case RC_PASS_CMD_VOLUME_UP:
+ status = avrcp_ct_volume_up((bt_address_t*)&device_address);
+ break;
+ case RC_PASS_CMD_VOLUME_DOWN:
+ status = avrcp_ct_volume_down((bt_address_t*)&device_address);
+ break;
+ default:
+ break;
+ }
+
+ if (status != OAL_STATUS_SUCCESS) {
+ BT_ERR("Send pass through command err: [%d]", status);
+ result = BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ return result;
+}
+
+int _bt_avrcp_control_cmd_to_dest(int type, bluetooth_device_address_t *device_address)
+{
+ char connected_address[BT_ADDRESS_STRING_SIZE + 1];
+ gboolean connected;
+ oal_status_t status = OAL_STATUS_SUCCESS;
+ int result = BLUETOOTH_ERROR_NONE;
+ BT_INFO("+");
+
+ _bt_convert_addr_type_to_string(connected_address, device_address->addr);
+
+ connected = _bt_is_headset_address_type_connected(BT_AVRCP,
+ (const char *)connected_address);
+
+ if (!connected) {
BT_ERR("Device is not connected:");
return BLUETOOTH_ERROR_NOT_CONNECTED;
}
+ switch (type) {
+ case RC_PASS_CMD_PLAY:
+ status = avrcp_ct_play((bt_address_t*)device_address);
+ break;
+ case RC_PASS_CMD_PAUSE:
+ status = avrcp_ct_pause((bt_address_t*)device_address);
+ break;
+ case RC_PASS_CMD_STOP:
+ status = avrcp_ct_stop((bt_address_t*)device_address);
+ break;
+ case RC_PASS_CMD_NEXT:
+ status = avrcp_ct_next_track((bt_address_t*)device_address);
+ break;
+ case RC_PASS_CMD_PREVIOUS:
+ status = avrcp_ct_prev_track((bt_address_t*)device_address);
+ break;
+ case RC_PASS_CMD_PRESS_FAST_FORWARD:
+ status = avrcp_ct_fforward((bt_address_t*)device_address, PRESS_STATE);
+ break;
+ case RC_PASS_CMD_RELEASE_FAST_FORWARD:
+ status = avrcp_ct_fforward((bt_address_t*)device_address, RELEASE_STATE);
+ break;
+ case RC_PASS_CMD_PRESS_REWIND:
+ status = avrcp_ct_rewind((bt_address_t*)device_address, PRESS_STATE);
+ break;
+ case RC_PASS_CMD_RELEASE_REWIND:
+ status = avrcp_ct_rewind((bt_address_t*)device_address, RELEASE_STATE);
+ break;
+ case RC_PASS_CMD_VOLUME_UP:
+ status = avrcp_ct_volume_up((bt_address_t*)device_address);
+ break;
+ case RC_PASS_CMD_VOLUME_DOWN:
+ status = avrcp_ct_volume_down((bt_address_t*)device_address);
+ break;
+ default:
+ break;
+ }
+
+ if (status != OAL_STATUS_SUCCESS) {
+ BT_ERR("Send pass through command err: [%d]", status);
+ result = BLUETOOTH_ERROR_INTERNAL;
+ }
+
return result;
}
return FALSE;
}
+
+gboolean _bt_is_headset_address_type_connected(int type, const char *address)
+{
+ GList *node;
+
+ node = g_list_first(g_connected_list);
+ while (node != NULL) {
+ bt_connected_headset_data_t *connected_device = node->data;
+
+ if (connected_device && (connected_device->type & type)) {
+ if (memcmp(connected_device->device_address, address, 19) == 0)
+ return TRUE;
+ }
+
+ node = g_list_next(node);
+ }
+ return FALSE;
+}
+
static void __bt_set_headset_disconnection_type(const char *address)
{
bt_connected_headset_data_t *connected_device;
result = _bt_avrcp_control_cmd(key_code);
break;
}
+ case BT_AVRCP_HANDLE_CONTROL_TO_DEST: {
+ int key_code;
+ bluetooth_device_address_t address = { { 0 } };
+
+ __bt_service_get_parameters(in_param1, &key_code, sizeof(int));
+ __bt_service_get_parameters(in_param2,
+ &address, sizeof(bluetooth_device_address_t));
+
+ result = _bt_avrcp_control_cmd_to_dest(key_code, &address);
+ break;
+ }
case BT_AVRCP_CONTROL_SET_PROPERTY: {
int type;
unsigned int value;
case BT_AVRCP_CONTROL_GET_PROPERTY:
case BT_AVRCP_GET_TRACK_INFO:
case BT_AVRCP_TRANSPORT_SET_PROPERTY:
-
+ case BT_AVRCP_HANDLE_CONTROL_TO_DEST:
case BT_SET_CONTENT_PROTECT:
case BT_BOND_DEVICE_BY_TYPE:
static void __bt_device_handle_bond_removal_event(bt_address_t *bd_addr);
static void __bt_device_handle_bond_failed_event(event_dev_bond_failed_t* bond_fail_event);
static void __bt_handle_ongoing_bond(bt_remote_dev_info_t *remote_dev_info, gboolean incoming_bond);
-static void __bt_device_conn_state_changed_callback(event_dev_conn_status_t *acl_event,
+static void __bt_device_acl_state_changed_callback(event_dev_conn_status_t *acl_event,
gboolean connected, unsigned char type);
static void __bt_free_pairing_info(bt_pairing_data_t **p_info);
case OAL_EVENT_DEVICE_ACL_CONNECTED: {
BT_INFO("ACL Connected event Received");
event_dev_conn_status_t* param = event_data;
- __bt_device_conn_state_changed_callback(param, TRUE, 0);
+ __bt_device_acl_state_changed_callback(param, TRUE, 0);
break;
}
case OAL_EVENT_DEVICE_ACL_DISCONNECTED: {
BT_INFO("ACL Disconnected event Received");
- __bt_device_conn_state_changed_callback((event_dev_conn_status_t *)event_data, FALSE, 0);
+ __bt_device_acl_state_changed_callback((event_dev_conn_status_t *)event_data, FALSE, 0);
break;
}
case OAL_EVENT_DEVICE_LE_CONNECTED: {
BT_INFO("LE Connected event Received");
event_dev_conn_status_t* param = event_data;
- __bt_device_conn_state_changed_callback(param, TRUE, 1);
+ __bt_device_acl_state_changed_callback(param, TRUE, 1);
break;
}
case OAL_EVENT_DEVICE_LE_DISCONNECTED: {
BT_INFO("LE Disconnected event Received");
- __bt_device_conn_state_changed_callback((event_dev_conn_status_t *)event_data, FALSE, 1);
+ __bt_device_acl_state_changed_callback((event_dev_conn_status_t *)event_data, FALSE, 1);
break;
}
case OAL_EVENT_DEVICE_PIN_REQUEST: {
BT_DBG("-");
}
-static void __bt_device_conn_state_changed_callback(event_dev_conn_status_t *acl_event,
+static int __bt_oal_status_to_bt_error(int oal_status)
+{
+ int ret = 0;
+
+ switch (oal_status) {
+ case OAL_STATUS_SUCCESS:
+ ret = BLUETOOTH_ERROR_NONE;
+ break;
+ case OAL_STATUS_CONN_TIMEOUT:
+ case OAL_STATUS_LINK_LOSS:
+ BT_INFO("Connection Timeout");
+ ret = BLUETOOTH_ERROR_CONNECTION_TIMEOUT;
+ break;
+#ifdef TIZEN_BT_HAL
+ case OAL_STATUS_CONN_TERM_LOCAL_HOST:
+ ret = BLUETOOTH_ERROR_LOCAL_HOST_TERM;
+ break;
+ case OAL_STATUS_CONN_TERM_RMT_HOST:
+ ret = BLUETOOTH_ERROR_REMOTE_USER_TERM;
+ break;
+#endif
+ case OAL_STATUS_INTERNAL_ERROR:
+ ret = BLUETOOTH_ERROR_INTERNAL;
+ break;
+ default:
+ ret = BLUETOOTH_ERROR_INTERNAL;
+ break;
+ }
+ return ret;
+}
+
+static void __bt_device_acl_state_changed_callback(event_dev_conn_status_t *acl_event,
gboolean connected, unsigned char type)
{
gchar address[BT_ADDRESS_STR_LEN];
_bt_logging_connection(connected, type);
+ result = __bt_oal_status_to_bt_error(acl_event->status);
+ BT_INFO("Result [0x%x]", result);
+
if (connected) {
param = g_variant_new("(isy)", result, address, type);
_bt_send_event(BT_DEVICE_EVENT,
GVariant *param = NULL;
int result = BLUETOOTH_ERROR_NONE;
struct gatt_server_req_info *req_info = NULL;
+ bluetooth_device_address_t dev_addr;
+ char address[BT_ADDRESS_STRING_SIZE] = { 0 };
BT_INFO("GATT Server ACQUIRE Notify Req Connection ID: [%d]", event->attr_trans.conn_id);
BT_INFO("GATT Server ACQUIRE Notify Req Transaction ID:[%d]", event->attr_trans.trans_id);
BT_INFO("GATT Server ACQUIRE Notify Req Attribute Handle: [%d]", event->attr_trans.attr_handle);
+ BT_INFO("GATT Server ACQUIRE notify Req address : [%s]", address);
+
+ memcpy(dev_addr.addr, event->address.addr, 6);
+ _bt_convert_addr_type_to_string(address,
+ (unsigned char *)dev_addr.addr);
+ BT_INFO("GATT Server ACQUIRE notify Req remote address : [%s]", address);
req_info = g_new0(struct gatt_server_req_info, 1);
req_info->request_id = event->attr_trans.trans_id;
req_info->request_type = BLUETOOTH_GATT_REQUEST_TYPE_ACQUIRE_NOTIFY;
gatt_server_requests = g_slist_append(gatt_server_requests, req_info);
- param = g_variant_new("(iiiiii)", result,
+ param = g_variant_new("(iiiiiis)", result,
event->attr_trans.conn_id,
event->attr_trans.trans_id,
event->attr_trans.attr_handle,
- event->mtu, event->attr_trans.offset);
+ event->mtu, event->attr_trans.offset,
+ address);
BT_INFO("GATT Server ACQUIRE Notify Req Attribute : ");
gboolean _bt_is_headset_type_connected(int type, char *address);
+gboolean _bt_is_headset_address_type_connected(int type, const char *address);
+
void _bt_add_headset_to_list(int type, int status, const char *address);
void _bt_remove_service_search_request(char *address);
int _bt_avrcp_control_cmd(int type);
+int _bt_avrcp_control_cmd_to_dest(int type, bluetooth_device_address_t *address);
+
int _bt_avrcp_control_set_property(int type, unsigned int value);
int _bt_avrcp_transport_set_property(int type, unsigned int value);
int bluetooth_media_control_command(media_player_control_cmd type);
/**
+ * @brief The function bluetooth_media_control_command_to_dest is called to send
+ * the AVRCP Control command like Play, Pause, FF, Rewind to the specific target device.
+ *
+ * @param[in] type media_player_control_cmd.
+ * @param[in] remote_address Bluetooth device address.
+ * @return int Zero on Success or reason for error if any.
+ *
+ */
+int bluetooth_media_control_command_to_dest(media_player_control_cmd type,
+ bluetooth_device_address_t *remote_address);
+
+/**
* @fn int bluetooth_media_control_set_property(media_player_property_type type, unsigned int value)
* @brief Notifies the remote bluetooth target with change in music control settings
*
BT_AVRCP_TARGET_CONNECT,
BT_AVRCP_TARGET_DISCONNECT,
BT_AVRCP_HANDLE_CONTROL,
+ BT_AVRCP_HANDLE_CONTROL_TO_DEST,
BT_AVRCP_CONTROL_SET_PROPERTY,
BT_AVRCP_CONTROL_GET_PROPERTY,
BT_AVRCP_GET_TRACK_INFO,