A2DP_TWS:BT IPC initial changes

 - Add aptx dual mono support for TWSP.

change-Id: I63d719db205799388225ba7d43b894a8b7b54ef2

Broadcast_Audio: add support for Broadcast_Audio

 - add support for broadcast audio

change-Id: I5c8d90f6ef440baad55bf8c98d91d0b6d2284707

FR 48725: Support for additional rules related to vendor

- Renamed the properties according to new P treble rules.

Change-Id: Ieb193230d3fc021538831d0cfcd3954b4b2fed88
CRs-Fixed: 2251843
diff --git a/bthost_ipc/bthost_ipc.c b/bthost_ipc/bthost_ipc.c
index a6e66f3..f0a2897 100644
--- a/bthost_ipc/bthost_ipc.c
+++ b/bthost_ipc/bthost_ipc.c
@@ -1,6 +1,27 @@
-/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+/*  Copyright (C) 2016-2017, The Linux Foundation. All rights reserved.
  *
  *  Not a Contribution
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted (subject to the limitations in the
+ *  disclaimer below) provided that the following conditions are met:
+
+      * Redistributions of source code must retain the above copyright
+        notice, this list of conditions and the following disclaimer.
+
+      * Redistributions in binary form must reproduce the above
+        copyright notice, this list of conditions and the following
+        disclaimer in the documentation and/or other materials provided
+        with the distribution.
+
+      * Neither the name of The Linux Foundation nor the names of its
+        contributors may be used to endorse or promote products derived
+        from this software without specific prior written permission.
+
+ *  NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
+ *  GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
+ *  HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  *****************************************************************************/
 /*****************************************************************************
  *  Copyright (C) 2009-2012 Broadcom Corporation
@@ -86,8 +107,10 @@
 
 audio_sbc_encoder_config_t sbc_codec;
 audio_aptx_encoder_config_t aptx_codec;
+audio_aptx_tws_encoder_config_t aptx_tws_codec;
 audio_aac_encoder_config_t aac_codec;
 audio_ldac_encoder_config_t ldac_codec;
+audio_celt_encoder_config_t celt_codec;
 /*****************************************************************************
 **  Functions
 ******************************************************************************/
@@ -397,6 +420,13 @@
             if (sample_freq) *sample_freq = ldac_codec.sampling_rate;
             return ((void *)&ldac_codec);
         }
+        if (codec_cfg[VENDOR_ID_OFFSET] == VENDOR_APTX_HD &&
+            codec_cfg[CODEC_ID_OFFSET] == APTX_TWS_CODEC_ID)
+        {
+            ALOGW("AptX-TWS codec");
+            *codec_type = ENC_CODEC_TYPE_APTX_DUAL_MONO;
+            //aptx_codec.sync_mode = 0x01;
+        }
         memset(&aptx_codec,0,sizeof(audio_aptx_encoder_config_t));
         p_cfg++; //skip dev_idx
         len = *p_cfg++;//LOSC
@@ -424,6 +454,7 @@
         switch (byte & A2D_APTX_CHAN_MASK)
         {
             case A2D_APTX_CHAN_STEREO:
+            case A2D_APTX_TWS_CHAN_MODE:
                  aptx_codec.channels = 2;
                  break;
             case A2D_APTX_CHAN_MONO:
@@ -449,8 +480,86 @@
 
         if(sample_freq) *sample_freq = aptx_codec.sampling_rate;
         ALOGW("APTx: Done copying full codec config");
+        if (*codec_type == ENC_CODEC_TYPE_APTX_DUAL_MONO)
+        {
+            memset(&aptx_tws_codec, 0, sizeof(audio_aptx_tws_encoder_config_t));
+            memcpy(&aptx_tws_codec, &aptx_codec, sizeof(aptx_codec));
+            aptx_tws_codec.sync_mode = 0x02;
+            return ((void *)&aptx_tws_codec);
+        }
         return ((void *)&aptx_codec);
     }
+    else if (codec_cfg[CODEC_OFFSET] == CODEC_TYPE_CELT)
+    {
+        uint8_t celt_samp_freq = 0;
+        uint32_t celt_bit_rate = 0;
+        memset(&celt_codec,0,sizeof(audio_celt_encoder_config_t));
+        switch(codec_cfg[4] & A2D_CELT_SAMP_FREQ_MASK)
+        {
+        case A2D_CELT_SAMP_FREQ_48:
+            celt_codec.sampling_rate = 48000;
+            break;
+        case A2D_CELT_SAMP_FREQ_44:
+            celt_codec.sampling_rate = 44100;
+            break;
+        case A2D_CELT_SAMP_FREQ_32:
+            celt_codec.sampling_rate = 32000;
+            break;
+        default:
+            ALOGE("CELT: unknown sampl freq");
+        }
+        switch(codec_cfg[4] & A2D_CELT_CHANNEL_MASK)
+        {
+        case A2D_CELT_CH_MONO:
+            celt_codec.channels = 1;
+            break;
+        case A2D_CELT_CH_STEREO:
+            celt_codec.channels = 2;
+            break;
+        default:
+            ALOGE("CELT: unknown channel");
+        }
+        switch(codec_cfg[5] & A2D_CELT_FRAME_SIZE_MASK)
+        {
+        case A2D_CELT_FRAME_SIZE_64:
+            celt_codec.frame_size = 64;
+            break;
+        case A2D_CELT_FRAME_SIZE_128:
+            celt_codec.frame_size = 128;
+            break;
+        case A2D_CELT_FRAME_SIZE_256:
+            celt_codec.frame_size = 256;
+            break;
+        case A2D_CELT_FRAME_SIZE_512:
+            celt_codec.frame_size = 512;
+            break;
+        default:
+            ALOGE("CELT: unknown frame size");
+        }
+        celt_codec.complexity = codec_cfg[5] & A2D_CELT_COMPLEXITY_MASK;
+        celt_codec.prediction_mode =
+                (codec_cfg[6] & A2D_CELT_PREDICTION_MODE_MASK) >> 4;
+        celt_codec.vbr_flag = codec_cfg[6] & A2D_CELT_VBR_MASK;
+
+        celt_codec.bitrate |= codec_cfg[7];
+        celt_codec.bitrate = celt_codec.bitrate << 8;
+        celt_codec.bitrate |= codec_cfg[8];
+        celt_codec.bitrate = celt_codec.bitrate << 8;
+        celt_codec.bitrate |= codec_cfg[9];
+        celt_codec.bitrate = celt_codec.bitrate << 8;
+        celt_codec.bitrate |= codec_cfg[10];
+        *codec_type = AUDIO_CODEC_TYPE_CELT;
+
+        ALOGE("CELT Bitrate: 0%x", celt_codec.bitrate);
+        ALOGE("CELT channel: 0%x", celt_codec.channels);
+        ALOGE("CELT complexity: 0%x", celt_codec.complexity);
+        ALOGE("CELT frame_size: 0%x", celt_codec.frame_size);
+        ALOGE("CELT prediction_mode: 0%x", celt_codec.prediction_mode);
+        ALOGE("CELT sampl_freq: 0%x", celt_codec.sampling_rate);
+        ALOGE("CELT vbr_flag: 0%x", celt_codec.vbr_flag);
+        ALOGE("CELT codec_type: 0%x", codec_type);
+        return ((void *)(&celt_codec));
+    }
     return NULL;
 }
 
@@ -553,6 +662,14 @@
         pthread_mutex_unlock(&audio_stream.ack_lock);
         return retry;
     }
+    // in race condition, ack_status is updated as SUCCESS
+    // without ack_recvd made 0.
+    if (audio_stream.ack_status == A2DP_CTRL_ACK_SUCCESS)
+    {
+        ALOGE("ACK Success, no need to wait");
+        pthread_mutex_unlock(&audio_stream.ack_lock);
+        return retry;
+    }
     while (retry < CTRL_CHAN_RETRY_COUNT &&
               ack_recvd == 0)
     {
@@ -605,7 +722,12 @@
 {
     ALOGW("bt_stack_on_stream_started: status = %d",status);
     pthread_mutex_lock(&audio_stream.ack_lock);
-    audio_stream.ack_status = status;
+    if ((audio_stream.ack_status != A2DP_CTRL_ACK_UNKNOWN) && (status == A2DP_CTRL_ACK_PENDING)) {
+        ALOGW("status already changed to = %d, don't update pending",audio_stream.ack_status);
+    }
+    else {
+        audio_stream.ack_status = status;
+    }
     resp_received = true;
     if (!ack_recvd)
     {
@@ -617,23 +739,36 @@
 
 void bt_stack_on_stream_suspended(tA2DP_CTRL_ACK status)
 {
-    ALOGW("bt_stack_on_stream_suspended");
+    ALOGW("bt_stack_on_stream_suspended status = %d, ack_status = %d ", status, audio_stream.ack_status);
     pthread_mutex_lock(&audio_stream.ack_lock);
-    audio_stream.ack_status = status;
+    if ((audio_stream.ack_status != A2DP_CTRL_ACK_UNKNOWN) && (status == A2DP_CTRL_ACK_PENDING)) {
+        ALOGW("status already changed to = %d, don't update pending",audio_stream.ack_status);
+    }
+    else {
+        audio_stream.ack_status = status;
+        ALOGW("bt_stack_on_stream_suspended updating  ack_status = %d ", audio_stream.ack_status);
+    }
     resp_received = true;
     if (!ack_recvd)
     {
         ack_recvd = 1;
+        ALOGW("bt_stack_on_stream_suspended signalling pthread ");
         pthread_cond_signal(&ack_cond);
     }
     pthread_mutex_unlock(&audio_stream.ack_lock);
+    ALOGW("bt_stack_on_stream_suspended mutex unlocked ");
 }
 
 void bt_stack_on_stream_stopped(tA2DP_CTRL_ACK status)
 {
     ALOGW("bt_stack_on_stream_stopped");
     pthread_mutex_lock(&audio_stream.ack_lock);
-    audio_stream.ack_status = status;
+    if ((audio_stream.ack_status != A2DP_CTRL_ACK_UNKNOWN) && (status == A2DP_CTRL_ACK_PENDING)) {
+        ALOGW("status already changed to = %d, don't update pending",audio_stream.ack_status);
+    }
+    else {
+        audio_stream.ack_status = status;
+    }
     resp_received = true;
     if (!ack_recvd)
     {
@@ -1255,22 +1390,11 @@
         ALOGW("audio_is_scrambling_enabled returned false due to stack deinit");
         return false;
     }
-    if( property_get("persist.vendor.bt.splita2dp.44_1_war", value, "true"))
-    {
-        if(!strcmp(value, "false"))
-        {
-            ALOGW("persist.vendor.bt.splita2dp.44_1_war is not set");
-            return false;
-        }
-    }
-    else
-    {
-        ALOGE("Error in fetching persist.vendor.bt.splita2dp.44_1_war property");
-        return false;
-    }
 
-    if( property_get("persist.vendor.bt.soc.scram_freqs", value, "false"))
+    if( property_get("persist.vendor.bluetooth.soc.scram_freqs", value, "false") &&
+        !strcmp(value, "false"))
     {
+        property_get("persist.vendor.bt.soc.scram_freqs", value, "false");
         if(!strcmp(value, "false"))
         {
             ALOGW("persist.vendor.bt.soc.scram_freqs is not set");
@@ -1279,7 +1403,7 @@
     }
     else
     {
-        ALOGE("Error in fetching persist.vendor.bt.soc.scram_freqs property");
+        ALOGE("Error in fetching persist.vendor.bluetooth.soc.scram_freqs property");
         return false;
     }
 
@@ -1298,7 +1422,19 @@
         INFO("%s: a2dp stream not configured,wait 100mse & retry", __func__);
         usleep(100000);
     }
+    if (codec_type == ENC_CODEC_TYPE_APTX_DUAL_MONO) {
+        INFO("%s:TWSP codec, return false",__func__);
+        pthread_mutex_unlock(&audio_stream.lock);
+        return false;
+    }
     if(status == A2DP_CTRL_ACK_SUCCESS) {
+
+        if (codec_type == CODEC_TYPE_CELT) {
+           INFO("%s: BA going on,return false", __func__);
+           pthread_mutex_unlock(&audio_stream.lock);
+           return false;
+        }
+
         ALOGW("audio_is_scrambling_enabled sample_freq %ld",sample_freq);
         switch (sample_freq) {
             case 44100:
diff --git a/bthost_ipc/bthost_ipc.h b/bthost_ipc/bthost_ipc.h
index 96e1b7c..a962c0d 100644
--- a/bthost_ipc/bthost_ipc.h
+++ b/bthost_ipc/bthost_ipc.h
@@ -1,7 +1,28 @@
 /******************************************************************************
- *  Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ *  Copyright (C) 2016-2017, The Linux Foundation. All rights reserved.
  *
  *  Not a Contribution
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted (subject to the limitations in the
+ *  disclaimer below) provided that the following conditions are met:
+
+     * Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+     * Redistributions in binary form must reproduce the above
+       copyright notice, this list of conditions and the following
+       disclaimer in the documentation and/or other materials provided
+       with the distribution.
+
+     * Neither the name of The Linux Foundation nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without specific prior written permission.
+
+ *  NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
+ *  GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
+ *  HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  *****************************************************************************/
 /*****************************************************************************
  *  Copyright (C) 2009-2012 Broadcom Corporation
@@ -101,8 +122,11 @@
 /*
 codec specific definitions
 */
+#define AUDIO_CODEC_TYPE_CELT         603979776u // 0x24000000UL
+#define ENC_CODEC_TYPE_APTX_DUAL_MONO 570425344u // 0x22000000UL
 #define CODEC_TYPE_SBC 0x00
 #define CODEC_TYPE_AAC 0x02
+#define CODEC_TYPE_CELT 0xEF
 #define NON_A2DP_CODEC_TYPE 0xFF
 #define CODEC_OFFSET 3
 #define VENDOR_ID_OFFSET 4
@@ -124,6 +148,9 @@
 #ifndef APTX_HD_CODEC_ID
 #define APTX_HD_CODEC_ID 0x24
 #endif
+#ifndef APTX_TWS_CODEC_ID
+#define APTX_TWS_CODEC_ID 0x25
+#endif
 
 #ifndef VENDOR_LDAC
 #define VENDOR_LDAC 0x12D
@@ -163,6 +190,7 @@
 #define A2D_APTX_CHAN_MASK       0x0F
 #define A2D_APTX_CHAN_STEREO     0x02
 #define A2D_APTX_CHAN_MONO       0x01
+#define A2D_APTX_TWS_CHAN_MODE   0x08
 
 
 /* LDAC bitmask helper */
@@ -195,6 +223,32 @@
 
 #define A2DP_DEFAULT_SINK_LATENCY 0
 
+
+// CELT Codec config in order.
+// 7-4 bits of first byte of codec_info element
+#define A2D_CELT_SAMP_FREQ_MASK    0xF0
+#define A2D_CELT_SAMP_FREQ_48      0x10
+#define A2D_CELT_SAMP_FREQ_44      0x20
+#define A2D_CELT_SAMP_FREQ_32      0x40
+// 0-3 bits of first byte of codec_info element
+#define A2D_CELT_CHANNEL_MASK      0x0F
+#define A2D_CELT_CH_MONO           0x01
+#define A2D_CELT_CH_STEREO         0x02
+// 7-4 bits of second byte: frame size
+#define A2D_CELT_FRAME_SIZE_MASK   0xF0
+#define A2D_CELT_FRAME_SIZE_64     0x10
+#define A2D_CELT_FRAME_SIZE_128    0x20
+#define A2D_CELT_FRAME_SIZE_256    0x40
+#define A2D_CELT_FRAME_SIZE_512    0x80
+//0-3 bits of second byte: actual value of complexity
+#define A2D_CELT_COMPLEXITY_MASK   0x0F
+// 7-4 bits of third byte: prediction mode
+#define A2D_CELT_PREDICTION_MODE_MASK   0xF0
+// 0th bit of third byte: vbr flag
+#define A2D_CELT_VBR_MASK         0x01
+
+// next 2 bytes is actual frame size
+// next 1 bytes is actual complexity
 typedef struct {
     uint32_t subband;    /* 4, 8 */
     uint32_t blk_len;    /* 4, 8, 12, 16 */
@@ -226,6 +280,16 @@
     uint32_t num_levels;
     struct bit_rate_level_map_t bit_rate_level_map[MAX_LEVELS];
 };
+/* Information about BT APTX encoder configuration
+ * This data is used between audio HAL module and
+ * BT IPC library to configure DSP encoder
+ */
+typedef struct {
+    uint16_t sampling_rate;
+    uint8_t  channels;
+    uint32_t bitrate;
+    uint8_t sync_mode;
+} audio_aptx_tws_encoder_config_t;
 
 /* Information about BT LDAC encoder configuration
  * This data is used between audio HAL module and
@@ -252,6 +316,16 @@
     uint32_t bitrate;
 } audio_aac_encoder_config_t;
 
+typedef struct {
+    uint32_t sampling_rate; /* 32000 - 48000, 48000 */
+    uint16_t channels; /* 1-Mono, 2-Stereo, 2*/
+    uint16_t frame_size; /* 64-128-256-512, 512 */
+    uint16_t complexity; /* 0-10, 1 */
+    uint16_t prediction_mode; /* 0-1-2, 0 */
+    uint16_t vbr_flag; /* 0-1, 0*/
+    uint32_t bitrate; /*32000 - 1536000, 139500*/
+} audio_celt_encoder_config_t;
+
 //HIDL callbacks to invoke callback to BT stack
 typedef void (*bt_ipc_start_stream_req_cb)(void);
 typedef void (*bt_ipc_suspend_stream_req_cb)(void);