From 9d09669b3482ac7eac7cc30ec816dc04c36aabcc Mon Sep 17 00:00:00 2001 From: Hyuk Lee Date: Tue, 3 Apr 2018 11:22:51 +0900 Subject: [PATCH] Add the AVRCP delay changed callback Change-Id: Ieaf16bba7a03aeb8c8984f1a5fab8cada3b9a5eb Signed-off-by: Hyuk Lee --- bt-api/bt-event-handler.c | 7 +++ bt-oal/bluez_hal/inc/bt-hal-msg.h | 9 +++- bt-oal/bluez_hal/src/bt-hal-avrcp-tg.c | 11 +++- bt-oal/bluez_hal/src/bt-hal-event-receiver.c | 58 ++++++++++++++++++++++ bt-oal/hardware/bt_rc.h | 4 ++ bt-oal/include/oal-avrcp-tg.h | 9 ++++ bt-oal/include/oal-event.h | 1 + bt-oal/oal-avrcp-tg.c | 12 +++++ .../services/audio/avrcp/bt-service-avrcp-tg.c | 16 ++++++ .../services/bt-service-event-receiver.c | 1 + .../services/bt-service-event-sender.c | 3 ++ include/bluetooth-api.h | 1 + include/bt-internal-types.h | 1 + 13 files changed, 131 insertions(+), 2 deletions(-) diff --git a/bt-api/bt-event-handler.c b/bt-api/bt-event-handler.c index c281221..776a309 100644 --- a/bt-api/bt-event-handler.c +++ b/bt-api/bt-event-handler.c @@ -1504,6 +1504,13 @@ void __bt_avrcp_event_filter(GDBusConnection *connection, _bt_avrcp_event_cb(BLUETOOTH_EVENT_AVRCP_SETTING_SCAN_STATUS, result, &status, event_info->cb, event_info->user_data); + } else if (strcasecmp(signal_name, BT_MEDIA_DELAY_CHANGE) == 0) { + unsigned int delay; + + g_variant_get(parameters, "(u)", &delay); + _bt_avrcp_event_cb(BLUETOOTH_EVENT_AVRCP_DELAY_CHANGED, + result, &delay, + event_info->cb, event_info->user_data); } } diff --git a/bt-oal/bluez_hal/inc/bt-hal-msg.h b/bt-oal/bluez_hal/inc/bt-hal-msg.h index 1bbbfb6..5cc1b73 100644 --- a/bt-oal/bluez_hal/inc/bt-hal-msg.h +++ b/bt-oal/bluez_hal/inc/bt-hal-msg.h @@ -419,13 +419,20 @@ struct hal_ev_play_status_changed { /* AVRCP TG events */ #ifdef TIZEN_BT_HAL #define HAL_EV_AVRCP_TG_CONN_STATE 0xA2 +#define HAL_EV_AVRCP_TG_DELAY_CHANGE 0xF1 #define HAL_AVRCP_TG_STATE_DISCONNECTED 0x00 #define HAL_AVRCP_TG_STATE_CONNECTED 0x01 -struct hal_ev_avrcp_tg_conn_state { +struct hal_ev_avrcp_tg_conn_state{ uint8_t bdaddr[6]; uint8_t state; } __attribute__((packed)); + +struct hal_ev_avrcp_tg_delay_changed{ + uint8_t bdaddr[6]; + uint16_t value; +} __attribute__((packed)); + #endif /* TIZEN_BT_HAL */ #define HAL_EV_AVRCP_TG_SET_PLAYER_PROPERTY 0xA3 diff --git a/bt-oal/bluez_hal/src/bt-hal-avrcp-tg.c b/bt-oal/bluez_hal/src/bt-hal-avrcp-tg.c index e39a0b0..a6a6673 100644 --- a/bt-oal/bluez_hal/src/bt-hal-avrcp-tg.c +++ b/bt-oal/bluez_hal/src/bt-hal-avrcp-tg.c @@ -247,7 +247,8 @@ static void __bt_hal_handle_avrcp_tg_events(int message, void *buf, uint16_t len switch (message) { #ifdef TIZEN_BT_HAL - case HAL_EV_AVRCP_TG_CONN_STATE: { + case HAL_EV_AVRCP_TG_CONN_STATE: + { struct hal_ev_avrcp_tg_conn_state *ev = buf; if (!bt_hal_avrcp_tg_cbacks->connection_state_cb) @@ -267,6 +268,14 @@ static void __bt_hal_handle_avrcp_tg_events(int message, void *buf, uint16_t len g_idle_add(__bt_avrcp_register_notifications, ev->bdaddr); break; } + case HAL_EV_AVRCP_TG_DELAY_CHANGE: + { + DBG("avrcp tg delay change"); + struct hal_ev_avrcp_tg_delay_changed *ev = buf; + bt_hal_avrcp_tg_cbacks->delay_change_cb( + ev->value, (bt_bdaddr_t *)ev->bdaddr); + break; + } #endif case HAL_EV_AVRCP_TG_SET_PLAYER_PROPERTY: __handle_player_property(buf, len); diff --git a/bt-oal/bluez_hal/src/bt-hal-event-receiver.c b/bt-oal/bluez_hal/src/bt-hal-event-receiver.c index b2e2abc..08acca2 100644 --- a/bt-oal/bluez_hal/src/bt-hal-event-receiver.c +++ b/bt-oal/bluez_hal/src/bt-hal-event-receiver.c @@ -100,6 +100,7 @@ static void __bt_hal_send_av_connection_state_event(gboolean connected, const ch static void __bt_hal_send_a2dp_sink_connection_state_event(gboolean connected, const char *address); static void __bt_hal_send_avrcp_ctrl_connection_state_event(gboolean connected, const char *address); static void __bt_hal_handle_avrcp_ctrl_events(GVariant *msg, const char *member, const char *path); +static void __bt_hal_handle_avrcp_transport_events(GVariant *msg, const char *member, const char *path); static void __bt_hal_send_device_trust_state_event(gboolean is_trusted, const char *address); static int __bt_hal_register_audio_subscribe_signal(GDBusConnection *conn, int subscribe); @@ -746,6 +747,7 @@ static void __bt_hal_handle_property_changed_event(GVariant *msg, const char *ob { char *interface_name = NULL; GVariant *val = NULL; + DBG("+"); g_variant_get(msg, "(&s@a{sv}@as)", &interface_name, &val, NULL); @@ -765,6 +767,9 @@ static void __bt_hal_handle_property_changed_event(GVariant *msg, const char *ob } else if (strcasecmp(interface_name, BT_HAL_PLAYER_CONTROL_INTERFACE) == 0) { DBG("Event: Property Changed: Interface: BT_HAL_PLAYER_CONTROL_INTERFACE"); __bt_hal_handle_avrcp_ctrl_events(val, NULL, object_path); + } else if (strcasecmp(interface_name, BT_HAL_MEDIATRANSPORT_INTERFACE) == 0) { + DBG("Event: Property Changed: Interface: BT_HAL_MEDIATRANSPORT_INTERFACE"); + __bt_hal_handle_avrcp_transport_events(val, NULL, object_path); } else if (strcasecmp(interface_name, BT_HAL_NETWORK_CLIENT_INTERFACE) == 0) { DBG("Event: Property Changed: Interface: BT_HAL_NETWORK_CLIENT_INTERFACE"); /* TODO: Handle event */ @@ -954,6 +959,7 @@ static gboolean __bt_hal_event_manager(gpointer data) g_free(current); } else if (g_strcmp0(param->interface_name, BT_HAL_PROPERTIES_INTERFACE) == 0) { + DBG("Manager Event: Interface Name: BT_HAL_PROPERTIES_INTERFACE"); __bt_hal_handle_property_changed_event(param->parameters, param->object_path); } else if (g_strcmp0(param->interface_name, BT_HAL_ADAPTER_INTERFACE) == 0) { DBG("Manager Event: Interface Name: BT_HAL_ADAPTER_INTERFACE"); @@ -979,8 +985,12 @@ static gboolean __bt_hal_event_manager(gpointer data) } else if (g_strcmp0(param->interface_name, BT_HAL_PLAYER_CONTROL_INTERFACE) == 0) { DBG("Manager Event: Interface Name: BT_HAL_PLAYER_CONTROL_INTERFACE"); __bt_hal_handle_avrcp_ctrl_events(param->parameters, param->signal_name, param->object_path); + } else if (g_strcmp0(param->interface_name, BT_HAL_MEDIATRANSPORT_INTERFACE) == 0) { + DBG("Manager Event: Interface Name: BT_HAL_MEDIATRANSPORT_INTERFACE"); + __bt_hal_handle_avrcp_transport_events(param->parameters, param->signal_name, param->object_path); } + /* Free data */ g_free(param->sender_name); g_free(param->object_path); @@ -2243,6 +2253,54 @@ static void __bt_hal_handle_avrcp_ctrl_events(GVariant *msg, const char *member, g_variant_unref(value); } +static void __bt_hal_handle_avrcp_transport_events(GVariant *msg, const char *member, + const char *path) +{ + const char *property = NULL; + GVariant *value = NULL; + GVariantIter iter; + char address[BT_HAL_ADDRESS_STRING_SIZE]; + DBG("+"); + + if (!msg) { + ERR("Error returned in method call\n"); + return; + } + + if (!avrcp_tg_event_cb) { + ERR("AVRCP target DBUS handler callback not registered"); + return; + } + + g_variant_iter_init(&iter, msg); + + _bt_hal_convert_device_path_to_address(path, address); + + while (g_variant_iter_loop(&iter, "{sv}", &property, &value)) { + DBG("Property = %s \n", property); + if ((strcasecmp(property, "Delay") == 0)) { + struct hal_ev_avrcp_tg_delay_changed ev; + uint16_t val; + + memset(&ev, 0, sizeof(ev)); + _bt_hal_convert_addr_string_to_type(ev.bdaddr, address); + + val = g_variant_get_uint16(value); + DBG("Value : %d", val); + ev.value = val; + + /* Send event to application */ + avrcp_tg_event_cb(HAL_EV_AVRCP_TG_DELAY_CHANGE, &ev, sizeof(ev)); + } else { + DBG("Property not handled"); + } + } + + DBG("-"); + g_free((char *)property); + g_variant_unref(value); +} + /* A2DP Src Role(Remote:Sink) Events */ static void __bt_hal_send_av_connection_state_event(gboolean connected, const char *address) { diff --git a/bt-oal/hardware/bt_rc.h b/bt-oal/hardware/bt_rc.h index 4c47844..76b053a 100644 --- a/bt-oal/hardware/bt_rc.h +++ b/bt-oal/hardware/bt_rc.h @@ -343,6 +343,9 @@ typedef void (*btrc_register_notification_callback) (btrc_event_id_t event_id, u */ typedef void (*btrc_volume_change_callback) (uint8_t volume, uint8_t ctype, bt_bdaddr_t *bd_addr); +/** Callback for delay change **/ +typedef void (*btrc_delay_change_callback) (uint16_t delay, bt_bdaddr_t *bd_addr); + /** Callback for passthrough commands */ typedef void (*btrc_passthrough_cmd_callback) (int id, int key_state, bt_bdaddr_t *bd_addr); @@ -401,6 +404,7 @@ typedef struct { btrc_get_element_attr_callback get_element_attr_cb; btrc_register_notification_callback register_notification_cb; btrc_volume_change_callback volume_change_cb; + btrc_delay_change_callback delay_change_cb; btrc_passthrough_cmd_callback passthrough_cmd_cb; btrc_set_addressed_player_callback set_addressed_player_cb; btrc_set_browsed_player_callback set_browsed_player_cb; diff --git a/bt-oal/include/oal-avrcp-tg.h b/bt-oal/include/oal-avrcp-tg.h index 5283ef5..6b78cd8 100644 --- a/bt-oal/include/oal-avrcp-tg.h +++ b/bt-oal/include/oal-avrcp-tg.h @@ -122,6 +122,15 @@ typedef struct { unsigned int volume; } oal_avrcp_volume_mute_t; +/** + * @brief AVRCP stream Delay + * + * @see OAL_EVENT_AVRCP_DELAY_CHANGED + */ +typedef struct { + unsigned int delay; +} oal_avrcp_delay_t; + typedef struct { int avrcp_feature; bt_address_t address; diff --git a/bt-oal/include/oal-event.h b/bt-oal/include/oal-event.h index 8cefa8e..4d7b030 100644 --- a/bt-oal/include/oal-event.h +++ b/bt-oal/include/oal-event.h @@ -106,6 +106,7 @@ extern "C" { EVENT(OAL_EVENT_AVRCP_SETTING_SHUFFLE_STATUS) /* bt_address_t*/ \ EVENT(OAL_EVENT_AVRCP_SETTING_SCAN_STATUS) /* bt_address_t*/ \ EVENT(OAL_EVENT_AVRCP_VOLUME_MUTE_CHANGED)\ + EVENT(OAL_EVENT_AVRCP_DELAY_CHANGED)\ EVENT(OAL_EVENT_AVRCP_CT_CONNECTED) /* bt_address_t*/ \ EVENT(OAL_EVENT_AVRCP_CT_DISCONNECTED) /* bt_address_t*/ \ EVENT(OAL_EVENT_AVRCP_CT_EQUALIZER_STATUS) /* property_value*/ \ diff --git a/bt-oal/oal-avrcp-tg.c b/bt-oal/oal-avrcp-tg.c index 082aae9..de9df0d 100644 --- a/bt-oal/oal-avrcp-tg.c +++ b/bt-oal/oal-avrcp-tg.c @@ -53,6 +53,7 @@ static void cb_avrcp_set_player_app_value(btrc_player_settings_t *p_vals, bt_bda static void cb_avrcp_get_element_attr(uint8_t num_attr, btrc_media_attr_t *p_attrs, bt_bdaddr_t *bd_addr); static void cb_avrcp_register_notification(btrc_event_id_t event_id, uint32_t param, bt_bdaddr_t *bd_addr); static void cb_avrcp_volume_change(uint8_t volume, uint8_t ctype, bt_bdaddr_t *bd_addr); +static void cb_avrcp_delay_change(uint16_t delay, bt_bdaddr_t *bd_addr); static void cb_avrcp_passthrough_command(int id, int pressed, bt_bdaddr_t *bd_addr); typedef struct { @@ -119,6 +120,7 @@ static btrc_callbacks_t sBluetoothAvrcpCallbacks = { cb_avrcp_get_element_attr, cb_avrcp_register_notification, cb_avrcp_volume_change, + cb_avrcp_delay_change, cb_avrcp_passthrough_command, NULL, /* cb_avrcp_set_addressed_player, */ NULL, /* cb_avrcp_set_browsed_player, */ @@ -750,6 +752,16 @@ static void cb_avrcp_volume_change(uint8_t volume, uint8_t ctype, bt_bdaddr_t *b avrcp_volume_mute, sizeof(oal_avrcp_volume_mute_t)); } +static void cb_avrcp_delay_change(uint16_t delay, bt_bdaddr_t *bd_addr) +{ + BT_INFO("Delay : %d", delay); + oal_avrcp_delay_t *avrcp_delay = g_new0(oal_avrcp_delay_t, 1); + avrcp_delay->delay = delay; + + send_event(OAL_EVENT_AVRCP_DELAY_CHANGED, + avrcp_delay, sizeof(oal_avrcp_delay_t)); +} + static void cb_avrcp_passthrough_command(int id, int key_state, bt_bdaddr_t *bd_addr) { BT_DBG("id: %d, key_state: %d", id, key_state); diff --git a/bt-service-adaptation/services/audio/avrcp/bt-service-avrcp-tg.c b/bt-service-adaptation/services/audio/avrcp/bt-service-avrcp-tg.c index 6639524..76ce276 100644 --- a/bt-service-adaptation/services/audio/avrcp/bt-service-avrcp-tg.c +++ b/bt-service-adaptation/services/audio/avrcp/bt-service-avrcp-tg.c @@ -484,6 +484,19 @@ static void __handle_player_property_scan(unsigned char *value) g_variant_new("(u)", status)); } +static void __handle_transport_property_delay(unsigned int *value) +{ + BT_DBG("+"); + unsigned int delay; + delay = *value; + + _bt_send_event(BT_AVRCP_EVENT, + BLUETOOTH_EVENT_AVRCP_DELAY_CHANGED, + g_variant_new("(u)", delay)); + + BT_DBG("-"); +} + static void __handle_avrcp_connection_event(int event, bt_address_t *bdaddr) { int result = BLUETOOTH_ERROR_NONE; @@ -569,6 +582,9 @@ static void __handle_avrcp_target_events(int event_type, gpointer event_data) break; case OAL_EVENT_AVRCP_VOLUME_MUTE_CHANGED: break; + case OAL_EVENT_AVRCP_DELAY_CHANGED: + __handle_transport_property_delay((unsigned int *)event_data); + break; default: BT_ERR("Unhandled AVRCP target event: %d", event_type); } diff --git a/bt-service-adaptation/services/bt-service-event-receiver.c b/bt-service-adaptation/services/bt-service-event-receiver.c index a08e6fd..c464f28 100644 --- a/bt-service-adaptation/services/bt-service-event-receiver.c +++ b/bt-service-adaptation/services/bt-service-event-receiver.c @@ -280,6 +280,7 @@ static gboolean __bt_handle_oal_events(gpointer data) case OAL_EVENT_AVRCP_SETTING_SHUFFLE_STATUS: case OAL_EVENT_AVRCP_SETTING_SCAN_STATUS: case OAL_EVENT_AVRCP_VOLUME_MUTE_CHANGED: + case OAL_EVENT_AVRCP_DELAY_CHANGED: if (avrcp_cb) avrcp_cb(event_type, event_data); break; diff --git a/bt-service-adaptation/services/bt-service-event-sender.c b/bt-service-adaptation/services/bt-service-event-sender.c index a0e67cc..ed22b0e 100644 --- a/bt-service-adaptation/services/bt-service-event-sender.c +++ b/bt-service-adaptation/services/bt-service-event-sender.c @@ -434,6 +434,9 @@ int _bt_send_event(int event_type, int event, GVariant *param) case BLUETOOTH_EVENT_AVRCP_TRACK_CHANGED: signal = BT_MEDIA_TRACK_CHANGE; break; + case BLUETOOTH_EVENT_AVRCP_DELAY_CHANGED: + signal = BT_MEDIA_DELAY_CHANGE; + break; case BLUETOOTH_EVENT_GATT_CONNECTED: signal = BT_GATT_CONNECTED; BT_INFO_C("### Connected [GATT]"); diff --git a/include/bluetooth-api.h b/include/bluetooth-api.h index 0e555dd..7c21876 100644 --- a/include/bluetooth-api.h +++ b/include/bluetooth-api.h @@ -812,6 +812,7 @@ typedef enum { BLUETOOTH_EVENT_AVRCP_SETTING_EQUALIZER_STATUS, /**