Add interfaces for BT AVC feature (AVRCP Target) 21/224921/4
authorDoHyun Pyun <dh79.pyun@samsung.com>
Fri, 14 Feb 2020 06:08:53 +0000 (15:08 +0900)
committerDoHyun Pyun <dh79.pyun@samsung.com>
Fri, 14 Feb 2020 07:07:11 +0000 (16:07 +0900)
Change-Id: Id45c2c61b4ec917edd9ca5f53e46e81d34756e6e
Signed-off-by: DoHyun Pyun <dh79.pyun@samsung.com>
16 files changed:
bt-api/bt-audio.c
bt-api/bt-common.c
bt-api/bt-event-handler.c
bt-oal/bluez_hal/inc/bt-hal-msg.h
bt-oal/bluez_hal/src/bt-hal-avrcp-tg.c
bt-oal/bluez_hal/src/bt-hal-event-receiver.c
bt-service-adaptation/CMakeLists.txt
bt-service-adaptation/services/audio/avrcp/bt-service-avrcp-tg.c
bt-service-adaptation/services/audio/bt-service-absolute-volume.c [new file with mode: 0644]
bt-service-adaptation/services/bt-request-handler.c
bt-service-adaptation/services/bt-service-event-sender.c
bt-service-adaptation/services/include/bt-service-audio-common.h
include/bluetooth-api.h
include/bluetooth-audio-api.h
include/bt-internal-types.h
packaging/bluetooth-frwk.spec

index 46c29fc..eb1523d 100644 (file)
@@ -451,6 +451,75 @@ BT_EXPORT_API int bluetooth_audio_select_role(bluetooth_audio_role_t role)
        return result;
 }
 
+BT_EXPORT_API int bluetooth_audio_set_absolute_volume(unsigned int volume)
+{
+       int result;
+
+       BT_CHECK_ENABLED(return);
+
+       BT_INIT_PARAMS();
+       BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+       g_array_append_vals(in_param1, &volume, sizeof(unsigned int));
+
+       result = _bt_send_request(BT_BLUEZ_SERVICE, BT_AUDIO_SET_ABSOLUTE_VOLUME,
+               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_audio_get_absolute_volume(unsigned int *volume)
+{
+       int result;
+
+       BT_CHECK_PARAMETER(volume, return);
+       BT_CHECK_ENABLED(return);
+
+       BT_INIT_PARAMS();
+       BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+       result = _bt_send_request(BT_BLUEZ_SERVICE, BT_AUDIO_GET_ABSOLUTE_VOLUME,
+               in_param1, in_param2, in_param3, in_param4, &out_param);
+
+       if (result == BLUETOOTH_ERROR_NONE) {
+               *volume = g_array_index(out_param,
+                               unsigned int, 0);
+       }
+
+       BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+       return result;
+}
+
+BT_EXPORT_API int bluetooth_audio_is_avc_activated(bool *activated)
+{
+       int result;
+
+       BT_CHECK_PARAMETER(activated, return);
+
+       if (bluetooth_check_adapter() == BLUETOOTH_ADAPTER_DISABLED) {
+               BT_DBG("BT is not enabled. So activated value is false");
+               *activated = false;
+               return BLUETOOTH_ERROR_NONE;
+       }
+
+       BT_INIT_PARAMS();
+       BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+       result = _bt_send_request(BT_BLUEZ_SERVICE, BT_AUDIO_IS_AVC_ACTIVATED,
+               in_param1, in_param2, in_param3, in_param4, &out_param);
+
+       if (result == BLUETOOTH_ERROR_NONE) {
+               *activated = g_array_index(out_param,
+                               bool, 0);
+       }
+
+       BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+       return result;
+}
+
 BT_EXPORT_API int bluetooth_ag_get_headset_volume(unsigned int *speaker_gain)
 {
        int result;
index a4dbd38..496d94b 100644 (file)
@@ -590,6 +590,9 @@ const char *_bt_convert_service_function_to_string(int function)
                {BT_SET_SPEAKER_GAIN, "BT_SET_SPEAKER_GAIN"},
                {BT_SET_CONTENT_PROTECT, "BT_SET_CONTENT_PROTECT"},
                {BT_AUDIO_SELECT_ROLE, "BT_AUDIO_SELECT_ROLE"},
+               {BT_AUDIO_SET_ABSOLUTE_VOLUME, "BT_AUDIO_SET_ABSOLUTE_VOLUME"},
+               {BT_AUDIO_GET_ABSOLUTE_VOLUME, "BT_AUDIO_GET_ABSOLUTE_VOLUME"},
+               {BT_AUDIO_IS_AVC_ACTIVATED, "BT_AUDIO_IS_AVC_ACTIVATED"},
                {BT_OOB_READ_LOCAL_DATA, "BT_OOB_READ_LOCAL_DATA"},
                {BT_OOB_ADD_REMOTE_DATA, "BT_OOB_ADD_REMOTE_DATA"},
                {BT_OOB_REMOVE_REMOTE_DATA, "BT_OOB_REMOVE_REMOTE_DATA"},
index ea3d35e..c45e644 100644 (file)
@@ -1653,6 +1653,13 @@ void __bt_avrcp_event_filter(GDBusConnection *connection,
                _bt_avrcp_event_cb(BLUETOOTH_EVENT_AVRCP_DELAY_CHANGED,
                                result, &delay,
                                event_info->cb, event_info->user_data);
+       }  else if (strcasecmp(signal_name, BT_MEDIA_VOLUME_CHANGE) == 0) {
+               unsigned int volume;
+
+               g_variant_get(parameters, "(u)", &volume);
+               _bt_avrcp_event_cb(BLUETOOTH_EVENT_AVRCP_VOLUME_CHANGED,
+                               result, &volume,
+                               event_info->cb, event_info->user_data);
        }
 }
 
index 2c46056..af9675b 100644 (file)
@@ -436,6 +436,7 @@ struct hal_ev_play_status_changed {
 #ifdef TIZEN_BT_HAL
 #define HAL_EV_AVRCP_TG_CONN_STATE             0xA2
 #define HAL_EV_AVRCP_TG_DELAY_CHANGE   0xF1
+#define HAL_EV_AVRCP_TG_VOLUME_CHANGE  0xF2
 
 #define HAL_AVRCP_TG_STATE_DISCONNECTED        0x00
 #define HAL_AVRCP_TG_STATE_CONNECTED   0x01
@@ -449,6 +450,11 @@ struct hal_ev_avrcp_tg_delay_changed{
        uint16_t value;
 } __attribute__((packed));
 
+struct hal_ev_avrcp_tg_volume_changed{
+       uint8_t bdaddr[6];
+       uint16_t volume;
+} __attribute__((packed));
+
 #endif /* TIZEN_BT_HAL */
 
 #define HAL_EV_AVRCP_TG_SET_PLAYER_PROPERTY              0xA3
index a6a6673..ce19459 100644 (file)
@@ -276,6 +276,14 @@ static void __bt_hal_handle_avrcp_tg_events(int message, void *buf, uint16_t len
                                ev->value, (bt_bdaddr_t *)ev->bdaddr);
                break;
        }
+       case HAL_EV_AVRCP_TG_VOLUME_CHANGE:
+       {
+               DBG("avrcp tg volume change");
+               struct hal_ev_avrcp_tg_volume_changed *ev = buf;
+               bt_hal_avrcp_tg_cbacks->volume_change_cb(
+                               ev->volume, 0, (bt_bdaddr_t *)ev->bdaddr);
+               break;
+       }
 #endif
        case HAL_EV_AVRCP_TG_SET_PLAYER_PROPERTY:
                __handle_player_property(buf, len);
index 46a172b..29caf36 100644 (file)
@@ -2500,6 +2500,19 @@ static void __bt_hal_handle_avrcp_transport_events(GVariant *msg, const char *me
 
                        /* Send event to application */
                        avrcp_tg_event_cb(HAL_EV_AVRCP_TG_DELAY_CHANGE, &ev, sizeof(ev));
+               } else if ((strcasecmp(property, "Volume") == 0)) {
+                       struct hal_ev_avrcp_tg_volume_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.volume = val;
+
+                       /* Send event to application */
+                       avrcp_tg_event_cb(HAL_EV_AVRCP_TG_VOLUME_CHANGE, &ev, sizeof(ev));
                } else {
                        DBG("Property not handled");
                }
index 73c5603..5e6d30a 100644 (file)
@@ -52,6 +52,9 @@ LIST(APPEND SRCS ./services/ipsp/bt-service-ipsp.c)
 LIST(APPEND SRCS ./services/ipsp/bt-service-ipsp-event-receiver.c)
 ENDIF()
 
+IF("$ENV{CFLAGS}" MATCHES "-DTIZEN_FEATURE_BT_AVC_TARGET")
+LIST(APPEND SRCS ./services/audio/bt-service-absolute-volume.c)
+ENDIF()
 
 IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
         SET(CMAKE_BUILD_TYPE "Release")
index 5023648..5e2c064 100644 (file)
@@ -497,6 +497,23 @@ static void __handle_transport_property_delay(unsigned int *value)
        BT_DBG("-");
 }
 
+static void __handle_transport_property_volume(unsigned int avrcp_volume)
+{
+#ifdef TIZEN_FEATURE_BT_AVC_TARGET
+       unsigned int system_volume = 0;
+
+       BT_DBG("+");
+
+       /* Need to add the logic for platform */
+
+       _bt_send_event(BT_AVRCP_EVENT,
+                       BLUETOOTH_EVENT_AVRCP_VOLUME_CHANGED,
+                       g_variant_new("(u)", system_volume));
+
+       BT_DBG("-");
+#endif
+}
+
 static void __handle_avrcp_connection_event(int event, bt_address_t *bdaddr)
 {
        int result = BLUETOOTH_ERROR_NONE;
@@ -582,8 +599,13 @@ static void __handle_avrcp_target_events(int event_type, gpointer event_data)
                break;
        case OAL_EVENT_AVRCP_REMOTE_FEATURES:
                break;
-       case OAL_EVENT_AVRCP_VOLUME_MUTE_CHANGED:
+       case OAL_EVENT_AVRCP_VOLUME_MUTE_CHANGED: {
+               oal_avrcp_volume_mute_t *volume_mute = (oal_avrcp_volume_mute_t *)event_data;
+
+               if (volume_mute)
+                       __handle_transport_property_volume(volume_mute->volume);
                break;
+       }
        case OAL_EVENT_AVRCP_DELAY_CHANGED:
                 __handle_transport_property_delay((unsigned int *)event_data);
                break;
diff --git a/bt-service-adaptation/services/audio/bt-service-absolute-volume.c b/bt-service-adaptation/services/audio/bt-service-absolute-volume.c
new file mode 100644 (file)
index 0000000..753162b
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Bluetooth-frwk
+ *
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:  Dohyun Pyun <dh79.pyun@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 <vconf.h>
+
+#include <oal-event.h>
+#include <oal-hardware.h>
+#include <oal-audio-src.h>
+
+#include "bt-service-common.h"
+#include "bt-service-audio-common.h"
+
+static unsigned int absolute_volume = 0;
+static unsigned int bt_volume = 0;
+static int avc_mode = BT_AVC_OFF;
+
+int _bt_audio_set_absolute_volume(unsigned int volume)
+{
+       int result = BLUETOOTH_ERROR_NONE;
+
+       /* 1. Translate the absolute volume to bt volume */
+
+       /* Convert system gain to BT
+               BT volume range : 0 ~ 127
+               system volume range : 0 ~ 150 */
+
+       bt_volume = 127 * volume / 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_volume > 0 && bt_volume < 127)
+               bt_volume++;
+
+       /* 2. Notify the bt_volume to transport (BT Headset) */
+
+       /* 3. Notify the avc mode to the pulseaudio if it is needed */
+
+       return result;
+}
+
+/* Just return the absolute_volume value */
+int _bt_audio_get_absolute_volume(unsigned int *volume)
+{
+       int result = BLUETOOTH_ERROR_NONE;
+
+       *volume = absolute_volume;
+
+       return result;
+}
+
+int _bt_audio_is_avc_activated(bool *activated)
+{
+       *activated = (avc_mode == BT_AVC_OFF) ? false : true;
+
+       return BLUETOOTH_ERROR_NONE;
+}
+
+/* 1. When a2dp headset is connected, we should set 'AVC' mode into pulseaudio */
+/* 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 */
+
index a24c73c..ef3bfd8 100644 (file)
@@ -1527,6 +1527,31 @@ int __bt_bluez_request(int function_name,
                }
                break;
        }
+#ifdef TIZEN_FEATURE_BT_AVC_TARGET
+       case BT_AUDIO_SET_ABSOLUTE_VOLUME: {
+               unsigned int volume = 0;
+
+               __bt_service_get_parameters(in_param1,
+                               &volume, sizeof(unsigned int));
+
+               result = _bt_audio_set_absolute_volume(volume);
+               break;
+       }
+       case BT_AUDIO_GET_ABSOLUTE_VOLUME: {
+               unsigned int volume = 0;
+
+               result = _bt_audio_get_absolute_volume(&volume);
+               g_array_append_vals(*out_param1, &volume, sizeof(unsigned int));
+               break;
+       }
+       case BT_AUDIO_IS_AVC_ACTIVATED: {
+               bool activated = 0;
+
+               result = _bt_audio_is_avc_activated(&activated);
+               g_array_append_vals(*out_param1, &activated, sizeof(bool));
+               break;
+       }
+#endif
        case BT_AV_CONNECT: {
                bluetooth_device_address_t address = { {0} };
                __bt_service_get_parameters(in_param1,
@@ -3921,6 +3946,12 @@ gboolean __bt_service_check_privilege(int function_name,
        case BT_AVRCP_SET_PROPERTIES:
        case BT_AVRCP_CONTROL_SET_PROPERTY:
 
+#ifdef TIZEN_FEATURE_BT_AVC_TARGET
+       case BT_AUDIO_SET_ABSOLUTE_VOLUME:
+       case BT_AUDIO_GET_ABSOLUTE_VOLUME:
+       case BT_AUDIO_IS_AVC_ACTIVATED:
+#endif
+
        case BT_HF_CONNECT:
        case BT_HF_DISCONNECT:
 
index f4083b9..9919c50 100644 (file)
@@ -447,6 +447,9 @@ int _bt_send_event(int event_type, int event, GVariant *param)
        case BLUETOOTH_EVENT_AVRCP_DELAY_CHANGED:
                signal = BT_MEDIA_DELAY_CHANGE;
                break;
+       case BLUETOOTH_EVENT_AVRCP_VOLUME_CHANGED:
+               signal = BT_MEDIA_VOLUME_CHANGE;
+               break;
 #ifdef TIZEN_GATT_CLIENT
        case BLUETOOTH_EVENT_GATT_SERVER_CONNECTED: /* GATT Server and Client */
                signal = BT_GATT_SERVER_CONNECTED;
index 99b44f5..bb39cca 100644 (file)
@@ -130,6 +130,20 @@ int _bt_audio_select_role(bluetooth_audio_role_t role);
 
 void _bt_audio_set_current_role(bluetooth_audio_role_t role);
 
+#ifdef TIZEN_FEATURE_BT_AVC_TARGET
+typedef enum {
+       BT_AVC_OFF = 0x00,
+       BT_AVC_NULL,
+       BT_AVC_MAX
+} bt_avc_mode_t;
+
+int _bt_audio_set_absolute_volume(unsigned int volume);
+
+int _bt_audio_get_absolute_volume(unsigned int *volume);
+
+int _bt_audio_is_avc_activated(bool *activated);
+#endif
+
 int _bt_hf_connect(bluetooth_device_address_t *device_address);
 
 int _bt_hf_disconnect(bluetooth_device_address_t *device_address);
index 9fef6cc..8e2ba9a 100644 (file)
@@ -868,6 +868,8 @@ typedef enum {
        BLUETOOTH_EVENT_AVRCP_SETTING_REPEAT_STATUS, /**<AVRCP service player repeat status event*/
        BLUETOOTH_EVENT_AVRCP_SETTING_SCAN_STATUS, /**<AVRCP service player scan status event*/
        BLUETOOTH_EVENT_AVRCP_DELAY_CHANGED, /**<AVRCP service transport delay changed event*/
+       BLUETOOTH_EVENT_AVRCP_VOLUME_CHANGED, /**<AVRCP service transport volume changed event*/
+       BLUETOOTH_EVENT_AUDIO_AVC_STATUS, /**<Absolute Volume Control status changed event*/
        BLUETOOTH_EVENT_HF_CONNECTED,
        BLUETOOTH_EVENT_HF_DISCONNECTED,
        BLUETOOTH_EVENT_HF_AUDIO_CONNECTED,
index 6fadb5c..ee02925 100755 (executable)
@@ -222,6 +222,37 @@ int bluetooth_ag_set_speaker_gain(unsigned int speaker_gain);
  */
 int bluetooth_audio_select_role(bluetooth_audio_role_t role);
 
+/**
+ * @brief      The function bluetooth_audio_get_absolute_volume is called to set
+ *     the Aboslute volume.
+ *
+ * @param[in]  volume Headset's volume
+ * @return     int     Zero on Success or reason for error if any.
+ *
+ */
+int bluetooth_audio_set_absolute_volume(unsigned int volume);
+
+/**
+ * @brief      The function bluetooth_audio_get_absolute_volume is called to get
+ *     the Aboslute volume.
+ *
+ * @param[out] volume Headset's volume
+ * @return     int     Zero on Success or reason for error if any.
+ *
+ */
+int bluetooth_audio_get_absolute_volume(unsigned int *volume);
+
+/**
+ * @brief      The function bluetooth_audio_is_avc_activated is called to get
+ *     the Aboslute volume Control mode is activated or not
+ *
+ * @param[out] AVC mode is activated or not
+ * @return     int     Zero on Success or reason for error if any.
+ *
+ */
+int bluetooth_audio_is_avc_activated(bool *activated);
+
+
 typedef struct {
        int event;
        int result;
index c055ded..a232c90 100644 (file)
@@ -268,6 +268,9 @@ typedef enum {
        BT_SET_SPEAKER_GAIN,
        BT_SET_CONTENT_PROTECT,
        BT_AUDIO_SELECT_ROLE,
+       BT_AUDIO_SET_ABSOLUTE_VOLUME,
+       BT_AUDIO_GET_ABSOLUTE_VOLUME,
+       BT_AUDIO_IS_AVC_ACTIVATED,
        BT_OOB_READ_LOCAL_DATA = BT_FUNC_OOB_BASE,
        BT_OOB_ADD_REMOTE_DATA,
        BT_OOB_REMOVE_REMOTE_DATA,
@@ -621,6 +624,7 @@ typedef struct {
 #define BT_MEDIA_POSITION_STATUS "MediaPositionStatus"
 #define BT_MEDIA_TRACK_CHANGE "MediaTrackStatus"
 #define BT_MEDIA_DELAY_CHANGE "MediaDelayStatus"
+#define BT_MEDIA_VOLUME_CHANGE "MediaVolumeStatus"
 #define BT_NAME_OWNER_CHANGED "NameOwnerChanged"
 
 #ifdef TIZEN_GATT_CLIENT
index d200c7e..3862b09 100644 (file)
@@ -22,6 +22,7 @@ Requires: bluetooth-tools
 %define bt_permanent_log DISABLED
 %define bt_http_proxy DISABLED
 %define bt_factory_mode DISABLED
+%define bt_avc_target ENABLED
 
 BuildRequires:  pkgconfig(aul)
 %if %{bt_factory_mode} == ENABLED
@@ -283,6 +284,10 @@ export CFLAGS="$CFLAGS -DTIZEN_FEATURE_BT_HTTP_PROXY"
 export CFLAGS="$CFLAGS -DTIZEN_FEATURE_BT_FACTORY_MODE"
 %endif
 
+%if %{bt_avc_target} == ENABLED
+export CFLAGS="$CFLAGS -DTIZEN_FEATURE_BT_AVC_TARGET"
+%endif
+
 %ifarch %{ix86} x86_64
 export CFLAGS+=" -DTIZEN_TEST_EMUL"
 export CXXFLAGS+=" -DTIZEN_TEST_EMUL"