Set BT SCO devices only after obtaining 'bt-sco-ready' from routing option 30/148430/1 accepted/tizen/unified/20170914.154134 submit/tizen/20170913.051034
authorSangchul Lee <sc11.lee@samsung.com>
Thu, 7 Sep 2017 11:28:22 +0000 (20:28 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Fri, 8 Sep 2017 02:26:27 +0000 (02:26 +0000)
In this target, there are several UCM BT SCO devices depending on its bandwidth
and network bandwidth. To work well, BT bandwidth should be got right after
BT SCO is ready. This patch makes it possible to set the BT SCO device properly
by keeping the call sequences with 'bt-sco-ready' and 'bt-wideband' options.

[Version] 0.1.7
[Profile] Wearable
[Issue Type] Enhancement

Change-Id: I079328c55e299acb7b9ea8b3dba0b42dfd95ca8b
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
packaging/audio-hal-wm1831-tw2.spec
tizen-audio-internal.h
tizen-audio-routing.c

index 481eb274a597c8277d809da15182da2b0b1a2d79..ffb7a5a0fbfda94f09654a311ef70cabd3e1e788 100644 (file)
@@ -1,6 +1,6 @@
 Name:       audio-hal-wm1831-tw2
 Summary:    TIZEN Audio HAL for WM1831(TW2)
-Version:    0.1.6
+Version:    0.1.7
 Release:    0
 Group:      System/Libraries
 License:    Apache-2.0
index d1a386765ec5cb4bcc05f37c82cdc193fa09b519..862ba5cfc2aa044b9810e3a48b7ec8c0874d20ea 100644 (file)
@@ -203,6 +203,7 @@ typedef struct audio_hal_device {
     audio_pcm_devices_t bt_pcm;
     audio_route_mode_t mode;
     bool bt_wideband;
+    bool bt_sco_ready;
 } audio_hal_device_t;
 
 /* Volume */
@@ -292,11 +293,13 @@ typedef enum audio_sample_format {
 } audio_sample_format_t;
 
 /* Overall */
+#define MAX_DIRECTION 2
 typedef struct audio_hal {
     audio_hal_device_t device;
     audio_hal_volume_t volume;
     audio_hal_ucm_t ucm;
     audio_hal_mixer_t mixer;
+    audio_route_info_t *saved_route_infos[MAX_DIRECTION];
     bool call_wideband;
 } audio_hal_t;
 
@@ -309,8 +312,6 @@ audio_return_t _audio_stream_deinit(audio_hal_t *ah);
 audio_return_t _audio_pcm_init(audio_hal_t *ah);
 audio_return_t _audio_pcm_deinit(audio_hal_t *ah);
 
-audio_return_t _audio_update_route_voicecall(audio_hal_t *ah, device_info_t *devices, int32_t num_of_devices);
-
 typedef struct _dump_data {
     char *strbuf;
     int left;
index fa47e8fba99283ed8e730ee5c3eb4632c5076ffb..1b43573e581ce3da963d0c246acdb7260cfa1d14 100644 (file)
@@ -209,6 +209,51 @@ static audio_return_t __set_devices(audio_hal_t *ah, const char *verb, device_in
     return audio_ret;
 }
 
+static audio_return_t __save_route_infos(audio_hal_t *ah, device_info_t *devices, int32_t num_of_devices)
+{
+    int i = 0;
+
+    AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
+    AUDIO_RETURN_VAL_IF_FAIL(devices, AUDIO_ERR_PARAMETER);
+
+    for (i = 0; i < MAX_DIRECTION; i++) {
+        if (!ah->saved_route_infos[i]) {
+            ah->saved_route_infos[i] = malloc(sizeof(audio_route_info_t));
+            memset(ah->saved_route_infos[i], 0, sizeof(audio_route_info_t));
+
+            ah->saved_route_infos[i]->device_infos = malloc(sizeof(device_info_t));
+            memcpy(ah->saved_route_infos[i]->device_infos, devices, sizeof(device_info_t));
+
+            ah->saved_route_infos[i]->num_of_devices = num_of_devices;
+
+            AUDIO_LOG_INFO("SAVE route infos[%d]: device_infos->type[%s],id[%u]",
+                           i, ah->saved_route_infos[i]->device_infos->type, ah->saved_route_infos[i]->device_infos->id);
+            return AUDIO_RET_OK;
+        }
+    }
+
+    AUDIO_LOG_ERROR("could not find empty slot to save route infos");
+    return AUDIO_ERR_INTERNAL;
+}
+
+static void __reset_saved_route_infos(void *audio_handle)
+{
+    audio_hal_t *ah = (audio_hal_t *)audio_handle;
+    int i = 0;
+
+    AUDIO_RETURN_IF_FAIL(ah);
+
+    for (i = 0; i < MAX_DIRECTION; i++) {
+        if (ah->saved_route_infos[i]) {
+            if (ah->saved_route_infos[i]->device_infos)
+                free(ah->saved_route_infos[i]->device_infos);
+            free(ah->saved_route_infos[i]);
+            ah->saved_route_infos[i] = NULL;
+            AUDIO_LOG_INFO("reset saved route infos[%d] well", i);
+        }
+    }
+}
+
 static audio_return_t __update_route_ap_playback_capture(audio_hal_t *ah, audio_route_info_t *route_info)
 {
     audio_return_t audio_ret = AUDIO_RET_OK;
@@ -246,6 +291,10 @@ static audio_return_t __update_route_voicecall(audio_hal_t *ah, device_info_t *d
 
     AUDIO_LOG_INFO("update_route_voicecall++");
 
+    if (!strncmp(devices[0].type, "bt-sco", MAX_NAME_LEN))
+        if (!ah->device.bt_sco_ready)
+            return __save_route_infos(ah, devices, num_of_devices);
+
     if ((audio_ret = __set_devices(ah, verb, devices, num_of_devices))) {
         AUDIO_LOG_ERROR("Failed to set devices: error = 0x%x", audio_ret);
         return audio_ret;
@@ -422,6 +471,8 @@ static audio_return_t __update_route_reset(audio_hal_t *ah, uint32_t direction)
         }
     }
 
+    __reset_saved_route_infos(ah);
+
     if (active_devices[0] == NULL) {
         AUDIO_LOG_DEBUG("active device is NULL, no need to update.");
         return AUDIO_RET_OK;
@@ -433,15 +484,11 @@ static audio_return_t __update_route_reset(audio_hal_t *ah, uint32_t direction)
     /* reset bandwidth information */
     ah->device.bt_wideband = false;
     ah->call_wideband = false;
+    ah->device.bt_sco_ready = false;
 
     return audio_ret;
 }
 
-audio_return_t _audio_update_route_voicecall(audio_hal_t *ah, device_info_t *devices, int32_t num_of_devices)
-{
-    return __update_route_voicecall(ah, devices, num_of_devices);
-}
-
 audio_return_t _audio_routing_init(audio_hal_t *ah)
 {
     audio_return_t audio_ret = AUDIO_RET_OK;
@@ -527,10 +574,22 @@ audio_return_t audio_update_route_option(void *audio_handle, audio_route_option_
         ah->device.bt_wideband = (option->value > 0) ? true : false;
     } else if (!strncmp("call-wideband", option->name, MAX_NAME_LEN)) {
         ah->call_wideband = (option->value > 0) ? true : false;
+    } else if (!strncmp("bt-sco-ready", option->name, MAX_NAME_LEN)) {
+        ah->device.bt_sco_ready = (option->value > 0) ? true : false;
+        if (ah->device.bt_sco_ready) {
+            int i = 0;
+            for (i = 0; i < MAX_DIRECTION; i++) {
+                if (ah->saved_route_infos[i]) {
+                    if ((audio_ret = __update_route_voicecall(ah, ah->saved_route_infos[i]->device_infos, ah->saved_route_infos[i]->num_of_devices)))
+                        AUDIO_LOG_WARN("update voicecall route from SAVED return 0x%x", audio_ret);
+                }
+            }
+        }
+        __reset_saved_route_infos(ah);
     } else {
         AUDIO_LOG_ERROR("undefined route option");
         audio_ret = AUDIO_ERR_UNDEFINED;
     }
 
     return audio_ret;
-}
+}
\ No newline at end of file