return NULL;
}
+static const char *__bt_transport_type_to_str(int type)
+{
+ switch (type) {
+ case BTRC_TRANSPORT_ATTR_DELAY:
+ return "Delay";
+ case BTRC_TRANSPORT_ATTR_VOLUME:
+ return "Volume";
+ default:
+ return NULL;
+ }
+
+ return NULL;
+}
+
bt_status_t _bt_hal_dbus_handler_avrcp_ctrl_set_property(bt_bdaddr_t *bd_addr, uint8_t type, uint8_t value)
{
GVariant *reply, *param = NULL;
DBG("-");
return BT_STATUS_SUCCESS;
}
+
+bt_status_t _bt_hal_dbus_handler_avrcp_transport_set_property(bt_bdaddr_t *bd_addr, int type, unsigned int value)
+{
+ GVariant *reply, *param = NULL;
+ GError *err = NULL;
+ GDBusProxy *proxy = NULL;
+ uint16_t property_level = (uint16_t)value;
+
+ DBG("+");
+ switch (type) {
+ case BTRC_TRANSPORT_ATTR_DELAY:
+ param = g_variant_new("q", property_level);
+ INFO("delay level %d", property_level);
+ break;
+ case BTRC_TRANSPORT_ATTR_VOLUME:
+ param = g_variant_new("q", property_level);
+ INFO("volume level %d", property_level);
+ break;
+ default:
+ ERR("Invalid property type: %d", type);
+ return BT_STATUS_FAIL;
+ }
+
+ proxy = _bt_hal_get_avrcp_transport_properties_proxy(bd_addr);
+ if (proxy == NULL) {
+ ERR("Unable to allocate new proxy \n");
+ if (err) {
+ ERR("%s", err->message);
+ g_clear_error(&err);
+ }
+ return BT_STATUS_FAIL;
+ }
+
+ reply = g_dbus_proxy_call_sync(proxy,
+ "Set", g_variant_new("(ssv)",
+ BT_HAL_MEDIATRANSPORT_INTERFACE,
+ __bt_media_type_to_str(type), param),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
+ g_object_unref(proxy);
+ if (!reply) {
+ ERR("Can't get managed objects");
+ if (err) {
+ ERR("SetProperty Fail: %s", err->message);
+ g_clear_error(&err);
+ return BT_STATUS_FAIL;
+ }
+ }
+
+ g_variant_unref(reply);
+ DBG("-");
+ return BT_STATUS_SUCCESS;
+}
bt_status_t _bt_hal_dbus_handler_avrcp_ctrl_set_property(bt_bdaddr_t *bd_addr, uint8_t type, uint8_t value);
+bt_status_t _bt_hal_dbus_handler_avrcp_transport_set_property(bt_bdaddr_t *bd_addr, int type, unsigned int value);
+
int _bt_media_attr_to_type(const char *str);
int _bt_media_attrval_to_val(int type, const char *value);
return ret;
}
+static bt_status_t avrcp_transport_setting_cmd(bt_bdaddr_t *bd_addr,
+ uint8_t num_attrib, int *type, unsigned int *value)
+{
+ int i = 0;
+ int ret = BT_STATUS_SUCCESS;
+
+ DBG("");
+ for (i = 0; i < num_attrib; i++)
+ ret = _bt_hal_dbus_handler_avrcp_transport_set_property(bd_addr, type[i], value[i]);
+
+ return ret;
+}
+
static void __bt_hal_handle_avrcp_ctrl_conn_state(void *buf, uint16_t len)
{
struct hal_ev_avrcp_ctrl_conn_state *ev = buf;
.disconnect = avrcp_ctrl_disconnect,
.send_pass_through_cmd = avrcp_ctrl_send_pass_through_cmd,
.set_player_app_setting_cmd = avrcp_ctrl_set_player_app_setting_cmd,
+ .set_transport_setting_cmd = avrcp_transport_setting_cmd,
.cleanup = cleanup
};
#define RFCOMM_DEFAULT_PROFILE_CHANNEL 0
static char *avrcp_control_path = NULL;
+static char *avrcp_transport_path = NULL;
static GDBusConnection *system_conn;
static GDBusConnection *session_conn;
return NULL;
}
+static char *__bt_hal_extract_transport_device_path(GVariantIter *iter, char *address)
+{
+ char *object_path = NULL;
+ char *interface_str = NULL;
+ char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
+
+ /* Parse the signature: oa{sa{sv}}} */
+ while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, &interface_str)) {
+ if (object_path == NULL)
+ return NULL;
+
+ if (g_strcmp0(interface_str, BT_HAL_MEDIATRANSPORT_INTERFACE) == 0) {
+ _bt_hal_convert_device_path_to_address(object_path, device_address);
+ if (g_strcmp0(address, device_address) == 0)
+ return g_strdup(object_path);
+ }
+ }
+ return NULL;
+}
+
static char *__bt_hal_get_control_device_object_path(char *address)
{
char *object_path = NULL;
return object_path;
}
+static char *__bt_hal_get_transport_device_object_path(char *address)
+{
+ char *object_path = NULL;
+ GDBusConnection *conn;
+ GDBusProxy *manager_proxy;
+ GVariant *result = NULL;
+ GVariantIter *iter = NULL;
+
+ conn = _bt_hal_get_system_gconn();
+ if (conn == NULL)
+ return NULL;
+
+ manager_proxy = _bt_hal_get_manager_proxy();
+ if (manager_proxy == NULL)
+ return NULL;
+
+ result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL);
+ if (!result) {
+ ERR("Can't get managed objects");
+ return NULL;
+ }
+
+ /* signature of GetManagedObjects: a{oa{sa{sv}}} */
+ g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
+ object_path = __bt_hal_extract_transport_device_path(iter, address);
+ g_variant_iter_free(iter);
+ g_variant_unref(result);
+ return object_path;
+}
+
char *_bt_hal_get_control_device_path(bt_bdaddr_t *bd_addr)
{
char *control_path;
return control_path;
}
+char *_bt_hal_get_transport_device_path(bt_bdaddr_t *bd_addr)
+{
+ char *transport_path;
+ char connected_address[BT_HAL_ADDRESS_STRING_SIZE];
+
+ DBG("+");
+
+ if (avrcp_transport_path != NULL)
+ return avrcp_transport_path;
+
+ _bt_hal_convert_addr_type_to_string(connected_address, bd_addr->address);
+
+ DBG("device address = %s", connected_address);
+
+ transport_path = __bt_hal_get_transport_device_object_path(connected_address);
+ if (transport_path == NULL)
+ return NULL;
+
+ avrcp_transport_path = transport_path;
+ DBG("transport_path = %s", transport_path);
+ return transport_path;
+}
+
static GDBusConnection *__bt_hal_init_system_gconn(void)
{
if (system_conn == NULL)
return proxy;
}
+GDBusProxy *_bt_hal_get_avrcp_transport_properties_proxy(bt_bdaddr_t *bd_addr)
+{
+ GDBusProxy *proxy;
+ GError *error = NULL;
+ char *transport_path = NULL;
+ GDBusConnection *conn = NULL;
+
+ DBG("+");
+ transport_path = _bt_hal_get_transport_device_path(bd_addr);
+ if (transport_path == NULL)
+ return NULL;
+
+ DBG("transport_path = %s", transport_path);
+
+ conn = _bt_hal_get_system_gconn();
+ if (conn == NULL) {
+ ERR("FAIL to get system connection");
+ return NULL;
+ }
+ proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
+ NULL, BT_HAL_BLUEZ_NAME,
+ transport_path, BT_HAL_PROPERTIES_INTERFACE, NULL, &error);
+
+ if (proxy == NULL) {
+ ERR("Unable to allocate new proxy");
+ if (error) {
+ ERR("%s", error->message);
+ g_clear_error(&error);
+ }
+ return NULL;
+ }
+
+ DBG("-");
+ return proxy;
+}
+
GDBusProxy *_bt_hal_get_adapter_properties_proxy(void)
{
return (adapter_properties_proxy) ? adapter_properties_proxy :
} btrc_player_attr_t;
typedef enum {
+ BTRC_TRANSPORT_ATTR_DELAY = 0x01,
+ BTRC_TRANSPORT_ATTR_VOLUME
+} btrc_transport_attr_t;
+
+typedef enum {
BTRC_MEDIA_ATTR_TITLE = 0x01,
BTRC_MEDIA_ATTR_ARTIST = 0x02,
BTRC_MEDIA_ATTR_ALBUM = 0x03,
bt_status_t (*set_player_app_setting_cmd) (bt_bdaddr_t *bd_addr, uint8_t num_attrib,
uint8_t* attrib_ids, uint8_t* attrib_vals);
+ /** send command to set delay, volume to target */
+ bt_status_t (*set_transport_setting_cmd) (bt_bdaddr_t *bd_addr, uint8_t num_attrib,
+ uint8_t* attrib_ids, uint8_t* attrib_vals);
+
/** send command to play a particular item */
bt_status_t (*play_item_cmd) (
bt_bdaddr_t *bd_addr, uint8_t scope, uint8_t *uid, uint16_t uid_counter);
oal_status_t avrcp_ct_set_property(bt_address_t *device_address, avrcp_ct_player_property_type_t type, uint32_t value);
/**
+ * @brief Set media transport properties to target device
+ *
+ * @remarks Target device will receive media player properties.
+ *
+ * @return OAL_STATUS_SUCCESS on success, otherwise non-zero error value.
+ * @retval #OAL_STATUS_SUCCESS Successful
+ *
+ * @pre OAL API must be initialize with avrcp_ct_enable().
+ *
+ */
+oal_status_t avrcp_transport_set_property(bt_address_t *device_address, int type, unsigned int value);
+
+/**
* @brief Get media player properties to target device
*
* @remarks Target device will send media player properties.
track_info->total_track = g_ascii_strtoll(
(const gchar *)p_attrs[idx].text, NULL, 10);
event_data->total_track = track_info->total_track;
- } else {
- BT_WARN("string is null!!!!!!!");
}
break;
case BTRC_MEDIA_ATTR_ID_TRACK_NUM:
track_info->track_number = g_ascii_strtoll(
(const gchar *)p_attrs[idx].text, NULL, 10);
event_data->track_number = track_info->track_number;
- } else {
- BT_WARN("string is null!!!!!!!");
}
break;
case BTRC_MEDIA_ATTR_ID_PLAYING_TIME:
return result;
}
+oal_status_t avrcp_transport_set_property(bt_address_t *device_address, int type, unsigned int value)
+{
+ int result = OAL_STATUS_SUCCESS;
+ bt_status_t status;
+ bdstr_t bdstr;
+
+ API_TRACE();
+
+ CHECK_OAL_AVRCP_CTRL_ENABLED();
+ BT_INFO("BT Audio Address: %s", bdt_bd2str(device_address, &bdstr));
+
+ if (type) {
+ status = avrcp_ct_interface->set_transport_setting_cmd((bt_bdaddr_t *)device_address, NO_OF_ATTRIBUTE,
+ &type, &value);
+ if ((status != BT_STATUS_SUCCESS) && (status != BT_STATUS_DONE)) {
+ BT_ERR("OAL, Set property failed err: %s", status2string(status));
+ result = convert_to_oal_status(status);
+ }
+ } else {
+ result = OAL_STATUS_INTERNAL_ERROR;
+ }
+ return result;
+}
+
static gboolean __send_avrcp_property_event(gpointer data)
{
avrcp_ct_property_value_t *event_data = (avrcp_ct_property_value_t *)data;
return result;
}
+int _bt_avrcp_transport_set_property(int type, unsigned int value)
+{
+ char connected_address[BT_ADDRESS_STRING_SIZE + 1];
+ gboolean connected;
+ bluetooth_device_address_t device_address;
+ oal_status_t status = OAL_STATUS_SUCCESS;
+ int result = BLUETOOTH_ERROR_NONE;
+ BT_INFO("+");
+ connected = _bt_is_headset_type_connected(BT_AVRCP, connected_address);
+
+ if (connected) {
+ _bt_convert_addr_string_to_type(device_address.addr,
+ connected_address);
+ status = avrcp_transport_set_property((bt_address_t*)&device_address,
+ type, value);
+ if (status != OAL_STATUS_SUCCESS) {
+ BT_ERR("Set peoperty err: [%d]", status);
+ result = BLUETOOTH_ERROR_INTERNAL;
+ }
+ } else {
+ BT_ERR("Device is not connected:");
+ return BLUETOOTH_ERROR_NOT_CONNECTED;
+ }
+ return result;
+}
+
int _bt_avrcp_control_get_property(int type)
{
char connected_address[BT_ADDRESS_STRING_SIZE + 1];
result = _bt_avrcp_control_set_property(type, value);
break;
}
+ case BT_AVRCP_TRANSPORT_SET_PROPERTY: {
+ int type;
+ unsigned int value;
+ BT_DBG("+");
+
+ __bt_service_get_parameters(in_param1,
+ &type, sizeof(int));
+ __bt_service_get_parameters(in_param2,
+ &value, sizeof(unsigned int));
+
+ result = _bt_avrcp_transport_set_property(type, value);
+ BT_DBG("-");
+ break;
+ }
case BT_AVRCP_CONTROL_GET_PROPERTY: {
int type;
int _bt_avrcp_control_set_property(int type, unsigned int value);
+int _bt_avrcp_transport_set_property(int type, unsigned int value);
+
int _bt_avrcp_control_get_property(int type);
int _bt_avrcp_control_get_track_info(void);