./src/bt-hal-avrcp-tg-dbus-handler.c
./src/bt-hal-avrcp-ctrl.c
./src/bt-hal-avrcp-ctrl-dbus-handler.c
+./src/bt-hal-avrcp-transport-dbus-handler.c
./src/bt-hal-hf.c
./src/bt-hal-hf-dbus-handler.c
./src/bt-hal-hid-dbus-handler.c
return NULL;
}
-#if 0
-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;
-}
-#endif
-
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;
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);
#include "bt-hal-msg.h"
#include "bt-hal-utils.h"
#include "bt-hal-avrcp-ctrl-dbus-handler.h"
+#include "bt-hal-avrcp-transport-dbus-handler.h"
#define AVRC_MAX_NUM_MEDIA_ATTR_ID 7
#include "bt-hal-event-receiver.h"
#include "bt-hal-avrcp-tg-dbus-handler.h"
+#include "bt-hal-avrcp-transport-dbus-handler.h"
static const btrc_callbacks_t *bt_hal_avrcp_tg_cbacks;
return BT_STATUS_SUCCESS;
}
-bt_status_t set_volume(uint8_t volume)
+bt_status_t set_volume(bt_bdaddr_t *bd_addr, uint32_t volume)
{
- return BT_STATUS_UNSUPPORTED;
+ int ret = BT_STATUS_SUCCESS;
+
+ ret = _bt_hal_dbus_handler_avrcp_transport_set_property(bd_addr, BTRC_TRANSPORT_ATTR_VOLUME, volume);
+
+ return ret;
+}
+
+bt_status_t get_volume(bt_bdaddr_t *bd_addr, uint32_t *volume)
+{
+ int ret = BT_STATUS_SUCCESS;
+
+ ret = _bt_hal_dbus_handler_avrcp_transport_get_property(bd_addr, BTRC_TRANSPORT_ATTR_VOLUME, volume);
+
+ return ret;
}
bt_status_t set_addressed_player_rsp(bt_bdaddr_t *bd_addr, btrc_status_t rsp_status)
.set_player_app_value_rsp = set_player_app_value_rsp,
.register_notification_rsp = register_notification_rsp,
.set_volume = set_volume,
+ .get_volume = get_volume,
.set_addressed_player_rsp = set_addressed_player_rsp,
.set_browsed_player_rsp = set_browsed_player_rsp,
.get_folder_items_list_rsp = get_folder_items_list_rsp,
--- /dev/null
+/*
+ *
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Nilesh Trimbake <t.shripati@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 <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include <glib.h>
+#include <gio/gio.h>
+#include <dlog.h>
+#include <vconf.h>
+
+#include "bt-hal-avrcp-transport-dbus-handler.h"
+#include "bt-hal-dbus-common-utils.h"
+#include "bt-hal-internal.h"
+
+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_transport_get_property(bt_bdaddr_t *bd_addr, int type, unsigned int *value)
+{
+ GDBusProxy *proxy = NULL;
+ GError *err = NULL;
+ GVariant *reply = NULL;
+ GVariant *temp = NULL;
+
+ proxy = _bt_hal_get_avrcp_transport_properties_proxy(bd_addr);
+ if (proxy == NULL) {
+ ERR("Unable to get proxy \n");
+ return BT_STATUS_FAIL;
+ }
+
+ reply = g_dbus_proxy_call_sync(proxy,
+ "Get", g_variant_new("(ss)", BT_HAL_MEDIATRANSPORT_INTERFACE,
+ __bt_transport_type_to_str(type)),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
+
+ g_object_unref(proxy);
+
+ if (!reply) {
+ ERR("Can't get managed objects");
+ if (err) {
+ ERR("%s", err->message);
+ g_clear_error(&err);
+ }
+ return BT_STATUS_FAIL;
+ }
+
+ g_variant_get(reply, "(v)", &temp);
+ *value = g_variant_get_uint16(temp);
+ g_variant_unref(temp);
+
+ DBG("Type[%s] and Value[%d]", __bt_transport_type_to_str(type), *value);
+
+ g_variant_unref(reply);
+ 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;
+
+ 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 get proxy \n");
+ return BT_STATUS_FAIL;
+ }
+
+ reply = g_dbus_proxy_call_sync(proxy,
+ "Set", g_variant_new("(ssv)",
+ BT_HAL_MEDIATRANSPORT_INTERFACE,
+ __bt_transport_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);
+
+ return BT_STATUS_SUCCESS;
+}
--- /dev/null
+/* Bluetooth-frwk
+ *
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Nilesh Trimbake <t.shripati@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.
+ *
+ */
+
+
+#ifndef _BT_HAL_AVRCP_TRANSPORT_DBUS_HANDLER_H_
+#define _BT_HAL_AVRCP_TRANSPORT_DBUS_HANDLER_H_
+
+#include <glib.h>
+#include <sys/types.h>
+
+#include "bt-hal.h"
+#include "bt-hal-log.h"
+#include "bt-hal-msg.h"
+
+#include "bt-hal-event-receiver.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+bt_status_t _bt_hal_dbus_handler_avrcp_transport_get_property(bt_bdaddr_t *bd_addr, int type, unsigned int *value);
+
+bt_status_t _bt_hal_dbus_handler_avrcp_transport_set_property(bt_bdaddr_t *bd_addr, int type, unsigned int value);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* _BT_HAL_AVRCP_TRANSPORT_DBUS_HANDLER_H_*/
** With RelateVolume, we will send VOLUME_UP/VOLUME_DOWN opposed to absolute volume level
** volume: Should be in the range 0-127. bit7 is reseved and cannot be set
*/
- bt_status_t (*set_volume)(uint8_t volume);
+ bt_status_t (*set_volume)(bt_bdaddr_t *bd_addr, uint32_t volume);
+
+ bt_status_t (*get_volume)(bt_bdaddr_t *bd_addr, uint32_t *volume);
/* Set addressed player response from TG to CT */
bt_status_t (*set_addressed_player_rsp)(bt_bdaddr_t *bd_addr, btrc_status_t rsp_status);
*/
oal_status_t avrcp_set_track_info(oal_media_metadata_attributes_t *meta_data);
+/**
+ * @brief Set the transport volue of remote device
+ *
+ * @return OAL_STATUS_SUCCESS on success, otherwise a non-zero error value.
+ * @retval #OAL_STATUS_SUCCESS Successful
+ *
+ * @pre AVRCP should be enabled with avrcp_enable().
+ *
+ * @see avrcp_enable()
+ */
+oal_status_t avrcp_tg_set_volume(bt_address_t *rem_addr, unsigned int volume);
+
+/**
+ * @brief Get the transport volue of remote device
+ *
+ * @return OAL_STATUS_SUCCESS on success, otherwise a non-zero error value.
+ * @retval #OAL_STATUS_SUCCESS Successful
+ *
+ * @pre AVRCP should be enabled with avrcp_enable().
+ *
+ * @see avrcp_enable()
+ */
+oal_status_t avrcp_tg_get_volume(bt_address_t *rem_addr, unsigned int *volume);
+
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
return OAL_STATUS_SUCCESS;
}
+oal_status_t avrcp_tg_set_volume(bt_address_t *rem_addr, unsigned int volume)
+{
+ int result = OAL_STATUS_SUCCESS;
+ bt_status_t status;
+ bdstr_t bdstr;
+
+ API_TRACE();
+
+ CHECK_OAL_AVRCP_ENABLED();
+ OAL_CHECK_PARAMETER(rem_addr, return);
+
+ BT_INFO("BT Audio Address: %s", bdt_bd2str(rem_addr, &bdstr));
+
+#ifdef TIZEN_BT_HAL
+ status = avrcp_api->set_volume((bt_bdaddr_t *)rem_addr, volume);
+ if ((status != BT_STATUS_SUCCESS) && (status != BT_STATUS_DONE)) {
+ BT_ERR("set volume failed, err: %s", status2string(status));;
+ result = convert_to_oal_status(status);
+ }
+#else
+ BT_INFO("Not Supported");
+ result = OAL_STATUS_NOT_SUPPORT;
+#endif
+
+ return result;
+}
+
+oal_status_t avrcp_tg_get_volume(bt_address_t *rem_addr, unsigned int *volume)
+{
+ int result = OAL_STATUS_SUCCESS;
+ bt_status_t status;
+ bdstr_t bdstr;
+
+ API_TRACE();
+
+ CHECK_OAL_AVRCP_ENABLED();
+ OAL_CHECK_PARAMETER(rem_addr, return);
+
+ BT_INFO("BT Audio Address: %s", bdt_bd2str(rem_addr, &bdstr));
+
+#ifdef TIZEN_BT_HAL
+ status = avrcp_api->get_volume((bt_bdaddr_t *)rem_addr, volume);
+ if ((status != BT_STATUS_SUCCESS) && (status != BT_STATUS_DONE)) {
+ BT_ERR("set volume failed, err: %s", status2string(status));;
+ result = convert_to_oal_status(status);
+ }
+#else
+ BT_INFO("Not Supported");
+ result = OAL_STATUS_NOT_SUPPORT;
+#endif
+
+ return result;
+}
+
+
#ifdef TIZEN_BT_HAL
static void cb_connection_state(bt_bdaddr_t* bd_addr, btrc_connection_state_t state)
{
return BLUETOOTH_ERROR_NONE;
}
+int _bt_avrcp_target_notify_volume(bluetooth_device_address_t *address, unsigned int volume)
+{
+ int result = BLUETOOTH_ERROR_NONE;
+ bt_address_t bdaddr;
+
+ memcpy(bdaddr.addr, address->addr, BT_ADDRESS_BYTES_NUM);
+
+ result = avrcp_tg_set_volume(&bdaddr, volume);
+ if (result != OAL_STATUS_SUCCESS) {
+ BT_ERR("hid_connect error: [%d]", result);
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_avrcp_target_get_volume(bluetooth_device_address_t *address, unsigned int *volume)
+{
+ int result = BLUETOOTH_ERROR_NONE;
+ bt_address_t bdaddr;
+
+ memcpy(bdaddr.addr, address->addr, BT_ADDRESS_BYTES_NUM);
+
+ result = avrcp_tg_get_volume(&bdaddr, volume);
+ if (result != OAL_STATUS_SUCCESS) {
+ BT_ERR("hid_connect error: [%d]", result);
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
int _bt_avrcp_set_properties(media_player_settings_t *properties)
{
int ret;
#include "bt-service-common.h"
#include "bt-service-audio-common.h"
#include "bt-service-event.h"
+#include "bt-service-avrcp-tg.h"
/* Avoid the build error related to vconf.h's dependency */
#ifndef VCONFKEY_BT_AVC_MODE
static unsigned int bt_volume = BT_VOLUME_MAX + 1;
static unsigned int avc_mode = BT_AVC_OFF;
+static void __bt_audio_covert_system_to_bt_volume(unsigned int sys_vol, unsigned int *bt_vol)
+{
+ /* Convert system gain to BT
+ BT volume range : 0 ~ 127
+ system volume range : 0 ~ 150 */
+
+ *bt_vol = 127 * ((float)sys_vol / 150);
+
+ /* volume table
+ system volume : 0 10 20 30 40 50 60 70 80 90 100 110 120 130 140 150
+ avrcp volume : 0 9 17 26 34 43 51 60 68 77 85 94 102 111 119 127 */
+
+ if (*bt_vol > 0 && *bt_vol < 127)
+ *bt_vol = *bt_vol + 1;
+
+ BT_DBG("System volume [%d], BT volume [%d]", sys_vol, *bt_vol);
+}
+
+static void __bt_audio_covert_bt_to_system_volume(unsigned int bt_vol, unsigned int *sys_vol)
+{
+ /* Convert BT gain to system
+ BT volume range : 0 ~ 127
+ system volume range : 0 ~ 150 */
+
+ *sys_vol = 150 * ((float)bt_vol / 127);
+
+ /* volume table
+ system volume : 0 10 20 30 40 50 60 70 80 90 100 110 120 130 140 150
+ avrcp volume : 0 9 17 26 34 43 51 60 68 77 85 94 102 111 119 127 */
+
+ if (*sys_vol > 0 && *sys_vol < 150)
+ *sys_vol = *sys_vol + 1;
+
+ BT_DBG("System volume [%d], BT volume [%d]", *sys_vol, bt_vol);
+}
+
static int __bt_audio_get_active_headset_volume(void)
{
+ int result = BLUETOOTH_ERROR_NONE;
char connected_address[BT_ADDRESS_STRING_SIZE + 1];
+ bluetooth_device_address_t device_address;
gboolean connected = FALSE;
- int volume = -1;
+ unsigned int volume = BT_VOLUME_MAX + 1;
/* 1. Get active A2DP headset path */
return -1;
}
+ _bt_convert_addr_string_to_type(device_address.addr, connected_address);
+
/* 2. Get volume info for active transport for the path */
+ result = _bt_avrcp_target_get_volume(&device_address, &volume);
+ if (result != BLUETOOTH_ERROR_NONE) {
+ BT_ERR("Fail to notify BT volume to headset");
+ return -1;
+ }
- /*
- _bt_avrcp_transport_get_property(VOLUME, &volume)
- */
+ if (volume > BT_VOLUME_MAX) {
+ BT_DBG("Absolute Volume is not set in transport");
+ return -1;
+ }
return volume;
}
avc_mode = mode;
}
+static void __bt_audio_sync_absolute_volume(unsigned int bt_vol)
+{
+ if (absolute_volume > ABSOLUTE_VOLUME_MAX || bt_volume > BT_VOLUME_MAX) {
+ unsigned int sys_vol = 0;
+
+ BT_DBG("synchronize the system and bt volume");
+
+ __bt_audio_covert_bt_to_system_volume(bt_vol, &sys_vol);
+
+ bt_volume = bt_vol;
+ absolute_volume = sys_vol;
+ }
+}
+
static void __bt_audio_set_user_avc_value(bool mode)
{
int volume = 0;
__bt_audio_set_avc_mode(BT_AVC_MAX);
}
- if (absolute_volume > ABSOLUTE_VOLUME_MAX || bt_volume > BT_VOLUME_MAX) {
- BT_DBG("synchronize the system and bt volume");
-
- /* Add Sync volumes */
- }
+ __bt_audio_sync_absolute_volume(volume);
}
static void __bt_audio_user_avc_mode_cb(keynode_t *node, void *data)
int _bt_audio_set_absolute_volume(unsigned int volume)
{
int result = BLUETOOTH_ERROR_NONE;
+ unsigned int bt_vol = 0;
+ char connected_address[BT_ADDRESS_STRING_SIZE + 1];
+ bluetooth_device_address_t device_address;
+ gboolean connected = FALSE;
+
+ if (volume > 150) {
+ BT_ERR("The volume exceeded 150");
+ return BLUETOOTH_ERROR_INVALID_PARAM;
+ }
if (avc_mode == BT_AVC_OFF) {
BT_ERR("AVC mode is off");
return BLUETOOTH_ERROR_INTERNAL;
}
- /* 1. Translate the absolute volume to bt volume */
+ /* We should modify this function to get the active headset in later */
+ connected = _bt_is_headset_type_connected(BT_AUDIO_A2DP, connected_address);
- /* Convert system gain to BT
- BT volume range : 0 ~ 127
- system volume range : 0 ~ 150 */
+ if (connected == FALSE) {
+ BT_DBG("There is no active A2DP headset");
+ return BLUETOOTH_ERROR_NOT_CONNECTED;
+ }
- bt_volume = 127 * volume / 150;
+ _bt_convert_addr_string_to_type(device_address.addr, connected_address);
- /* volume table
- system volume : 0 10 20 30 40 50 60 70 80 90 100 110 120 130 140 150
- avrcp_ volume : 0 9 17 26 34 43 51 60 68 77 85 94 102 111 119 127 */
+ /* 1. Translate the absolute volume to bt volume */
+ __bt_audio_covert_system_to_bt_volume(volume, &bt_vol);
- if (bt_volume > 0 && bt_volume < 127)
- bt_volume++;
+ bt_volume = bt_vol;
+ absolute_volume = volume;
/* 2. Notify the bt_volume to transport (BT Headset) */
-
- /*
- _bt_avrcp_transport_set_property(VOLUME, bt_volume)
- */
+ result = _bt_avrcp_target_notify_volume(&device_address, bt_volume);
+ if (result != BLUETOOTH_ERROR_NONE)
+ BT_ERR("Fail to notify BT volume to headset");
/* 3. Notify the avc mode to the pulseaudio if it is needed */
if (volume == 0) {
__bt_audio_set_avc_mode(BT_AVC_NULL);
} else {
- BT_DBG("BT volume: %d", volume);
+ BT_DBG("System volume: %d", volume);
__bt_audio_set_avc_mode(BT_AVC_MAX);
}
*mode = BT_AVC_MAX;
}
- if (absolute_volume > ABSOLUTE_VOLUME_MAX || bt_volume > BT_VOLUME_MAX) {
- BT_DBG("synchronize the system and bt volume");
-
- /* Add Sync volumes */
- }
+ __bt_audio_sync_absolute_volume(volume);
return BLUETOOTH_ERROR_NONE;
}
/* 2. If the avc mode is changed, we should inform 'AVC' mode to pulseaudio */
/* 3. If BT is off, we should send 'AVC' off mode event for application */
/* 4. If BT A2DP is disconnected, we should send 'AVC' off mode event for application */
+/* 5. When we recieve the volume changed, we shuld sync up the volume */
int _bt_avrcp_set_track_info(media_metadata_attributes_t *meta_data);
+int _bt_avrcp_target_notify_volume(bluetooth_device_address_t *address, unsigned int volume);
+
+int _bt_avrcp_target_get_volume(bluetooth_device_address_t *address, unsigned int *volume);
+
int _bt_avrcp_set_properties(media_player_settings_t *properties);
int _bt_avrcp_set_property(int type, unsigned int value);