Просмотр исходного кода

Merge branch 'bugfix/compiler_err_when_performance_optimization_enabled_v4.0' into 'release/v4.0'

Bugfix/compiler err when performance optimization enabled v4.0

See merge request espressif/esp-idf!7978
Jiang Jiang Jian 6 лет назад
Родитель
Сommit
75f6bc2de1

+ 1 - 1
components/bt/controller/bt.c

@@ -972,7 +972,7 @@ static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end)
 esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode)
 {
     bool update = true;
-    intptr_t mem_start, mem_end;
+    intptr_t mem_start=(intptr_t) NULL, mem_end=(intptr_t) NULL;
 
     if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
         return ESP_ERR_INVALID_STATE;

+ 1 - 1
components/bt/host/bluedroid/bta/av/bta_av_api.c

@@ -116,7 +116,7 @@ void BTA_AvRegister(tBTA_AV_CHNL chnl, const char *p_service_name, UINT8 app_id,
         p_buf->hdr.layer_specific   = chnl;
         p_buf->hdr.event = BTA_AV_API_REGISTER_EVT;
         if (p_service_name) {
-            BCM_STRNCPY_S(p_buf->p_service_name, sizeof(p_buf->p_service_name), p_service_name, BTA_SERVICE_NAME_LEN);
+            BCM_STRNCPY_S(p_buf->p_service_name, p_service_name, BTA_SERVICE_NAME_LEN);
             p_buf->p_service_name[BTA_SERVICE_NAME_LEN - 1] = 0;
         } else {
             p_buf->p_service_name[0] = 0;

+ 2 - 3
components/bt/host/bluedroid/bta/av/bta_av_main.c

@@ -483,8 +483,7 @@ static void bta_av_api_sink_enable(tBTA_AV_DATA *p_data)
     activate_sink = p_data->hdr.layer_specific;
     APPL_TRACE_DEBUG("bta_av_api_sink_enable %d \n", activate_sink)
     char p_service_name[BTA_SERVICE_NAME_LEN + 1];
-    BCM_STRNCPY_S(p_service_name, sizeof(p_service_name),
-                  BTIF_AVK_SERVICE_NAME, BTA_SERVICE_NAME_LEN);
+    BCM_STRNCPY_S(p_service_name, BTIF_AVK_SERVICE_NAME, BTA_SERVICE_NAME_LEN);
 
     if (activate_sink) {
         AVDT_SINK_Activate();
@@ -526,7 +525,7 @@ static void bta_av_api_register(tBTA_AV_DATA *p_data)
     tBTA_UTL_COD    cod;
     UINT8           index = 0;
     char p_avk_service_name[BTA_SERVICE_NAME_LEN + 1];
-    BCM_STRNCPY_S(p_avk_service_name, sizeof(p_avk_service_name), BTIF_AVK_SERVICE_NAME, BTA_SERVICE_NAME_LEN);
+    BCM_STRNCPY_S(p_avk_service_name, BTIF_AVK_SERVICE_NAME, BTA_SERVICE_NAME_LEN);
 
     memset(&cs, 0, sizeof(tAVDT_CS));
 

+ 20 - 31
components/bt/host/bluedroid/bta/dm/bta_dm_act.c

@@ -1816,7 +1816,7 @@ void bta_dm_sdp_result (tBTA_DM_MSG *p_data)
                         if (SDP_FindServiceUUIDInRec(p_sdp_rec, &service_uuid)) {
                             /* send result back to app now, one by one */
                             bdcpy (result.disc_ble_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
-                            BCM_STRNCPY_S((char *)result.disc_ble_res.bd_name, sizeof(BD_NAME), bta_dm_get_remname(), (BD_NAME_LEN));
+                            BCM_STRNCPY_S((char *)result.disc_ble_res.bd_name, bta_dm_get_remname(), (BD_NAME_LEN));
                             result.disc_ble_res.bd_name[BD_NAME_LEN] = 0;
                             result.disc_ble_res.service.len = service_uuid.len;
                             result.disc_ble_res.service.uu.uuid16 = service_uuid.uu.uuid16;
@@ -1957,8 +1957,7 @@ void bta_dm_sdp_result (tBTA_DM_MSG *p_data)
 
                 }
                 bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
-                BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, sizeof(BD_NAME),
-                              bta_dm_get_remname(), (BD_NAME_LEN - 1));
+                BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, bta_dm_get_remname(), (BD_NAME_LEN - 1));
 
                 /* make sure the string is null terminated */
                 p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;
@@ -1984,8 +1983,7 @@ void bta_dm_sdp_result (tBTA_DM_MSG *p_data)
             p_msg->disc_result.result.disc_res.result = BTA_FAILURE;
             p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
             bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
-            BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, sizeof(BD_NAME),
-                          bta_dm_get_remname(), (BD_NAME_LEN - 1));
+            BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name,bta_dm_get_remname(), (BD_NAME_LEN - 1));
 
             /* make sure the string is null terminated */
             p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;
@@ -2369,8 +2367,7 @@ static void bta_dm_find_services ( BD_ADDR bd_addr)
             p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
             p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
             bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
-            BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, sizeof(BD_NAME),
-                          bta_dm_get_remname(), (BD_NAME_LEN - 1));
+            BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name,bta_dm_get_remname(), (BD_NAME_LEN - 1));
 
             /* make sure the string is terminated */
             p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;
@@ -2555,8 +2552,7 @@ static void bta_dm_discover_device(BD_ADDR remote_bd_addr)
         p_msg->disc_result.result.disc_res.result = BTA_SUCCESS;
         p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
         bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
-        BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name,  sizeof(BD_NAME),
-                      (char *)bta_dm_search_cb.peer_name, (BD_NAME_LEN - 1));
+        BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name,(char *)bta_dm_search_cb.peer_name, (BD_NAME_LEN - 1));
 
         /* make sure the string is terminated */
         p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;
@@ -2700,7 +2696,7 @@ static void bta_dm_service_search_remname_cback (BD_ADDR bd_addr, DEV_CLASS dc,
             rem_name.length = (BD_NAME_LEN - 1);
             rem_name.remote_bd_name[(BD_NAME_LEN - 1)] = 0;
         }
-        BCM_STRNCPY_S((char *)rem_name.remote_bd_name,  sizeof(BD_NAME), (char *)bd_name, (BD_NAME_LEN - 1));
+        BCM_STRNCPY_S((char *)rem_name.remote_bd_name, (char *)bd_name, (BD_NAME_LEN - 1));
         rem_name.status = BTM_SUCCESS;
 
         bta_dm_remname_cback(&rem_name);
@@ -2743,7 +2739,7 @@ static void bta_dm_remname_cback (tBTM_REMOTE_DEV_NAME *p_remote_name)
 
     /* remote name discovery is done but it could be failed */
     bta_dm_search_cb.name_discover_done = TRUE;
-    BCM_STRNCPY_S((char *)bta_dm_search_cb.peer_name, sizeof(BD_NAME), (char *)p_remote_name->remote_bd_name, (BD_NAME_LEN));
+    BCM_STRNCPY_S((char *)bta_dm_search_cb.peer_name, (char *)p_remote_name->remote_bd_name, (BD_NAME_LEN));
     bta_dm_search_cb.peer_name[BD_NAME_LEN] = 0;
 
     BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
@@ -2756,7 +2752,7 @@ static void bta_dm_remname_cback (tBTM_REMOTE_DEV_NAME *p_remote_name)
 
     if ((p_msg = (tBTA_DM_REM_NAME *) osi_malloc(sizeof(tBTA_DM_REM_NAME))) != NULL) {
         bdcpy (p_msg->result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
-        BCM_STRNCPY_S((char *)p_msg->result.disc_res.bd_name, sizeof(BD_NAME), (char *)p_remote_name->remote_bd_name, (BD_NAME_LEN));
+        BCM_STRNCPY_S((char *)p_msg->result.disc_res.bd_name, (char *)p_remote_name->remote_bd_name, (BD_NAME_LEN));
 
         /* make sure the string is null terminated */
         p_msg->result.disc_res.bd_name[BD_NAME_LEN] = 0;
@@ -2788,7 +2784,7 @@ static UINT8 bta_dm_authorize_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NA
     bdcpy(sec_event.authorize.bd_addr, bd_addr);
     memcpy(sec_event.authorize.dev_class, dev_class, DEV_CLASS_LEN);
 
-    BCM_STRNCPY_S((char *)sec_event.authorize.bd_name, sizeof(BD_NAME), (char *)bd_name, (BD_NAME_LEN - 1));
+    BCM_STRNCPY_S((char *)sec_event.authorize.bd_name, (char *)bd_name, (BD_NAME_LEN - 1));
 
     /* make sure the string is null terminated */
     sec_event.authorize.bd_name[BD_NAME_LEN - 1] = 0;
@@ -2902,7 +2898,7 @@ static UINT8 bta_dm_pin_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_
 
     bdcpy(sec_event.pin_req.bd_addr, bd_addr);
     BTA_COPY_DEVICE_CLASS(sec_event.pin_req.dev_class, dev_class);
-    BCM_STRNCPY_S((char *)sec_event.pin_req.bd_name, sizeof(BD_NAME), (char *)bd_name, (BD_NAME_LEN - 1));
+    BCM_STRNCPY_S((char *)sec_event.pin_req.bd_name, (char *)bd_name, (BD_NAME_LEN - 1));
     sec_event.pin_req.bd_name[BD_NAME_LEN - 1] = 0;
     sec_event.pin_req.min_16_digit = min_16_digit;
 
@@ -3073,8 +3069,7 @@ static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
                    copy these values into key_notif from cfm_req */
                 bdcpy(sec_event.key_notif.bd_addr, p_data->cfm_req.bd_addr);
                 BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->cfm_req.dev_class);
-                BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, sizeof(BD_NAME),
-                              (char *)p_data->cfm_req.bd_name, (BD_NAME_LEN - 1));
+                BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, (char *)p_data->cfm_req.bd_name, (BD_NAME_LEN - 1));
                 sec_event.key_notif.bd_name[BD_NAME_LEN - 1] = 0;
             }
         }
@@ -3095,8 +3090,7 @@ static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
             } else {
                 bdcpy(sec_event.key_notif.bd_addr, p_data->key_notif.bd_addr);
                 BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->key_notif.dev_class);
-                BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, sizeof(BD_NAME),
-                              (char *)p_data->key_notif.bd_name, (BD_NAME_LEN - 1));
+                BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, (char *)p_data->key_notif.bd_name, (BD_NAME_LEN - 1));
                 sec_event.key_notif.bd_name[BD_NAME_LEN - 1] = 0;
             }
         }
@@ -3117,8 +3111,7 @@ static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
             } else {
                 bdcpy(sec_event.key_notif.bd_addr, p_data->key_notif.bd_addr);
                 BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->key_notif.dev_class);
-                BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, sizeof(BD_NAME),
-                              (char *)p_data->key_notif.bd_name, (BD_NAME_LEN - 1));
+                BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name,(char *)p_data->key_notif.bd_name, (BD_NAME_LEN - 1));
                 sec_event.key_notif.bd_name[BD_NAME_LEN - 1] = 0;
             }
         }
@@ -3147,7 +3140,7 @@ static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
 
         bdcpy(sec_event.rmt_oob.bd_addr, p_data->rmt_oob.bd_addr);
         BTA_COPY_DEVICE_CLASS(sec_event.rmt_oob.dev_class, p_data->rmt_oob.dev_class);
-        BCM_STRNCPY_S((char *)sec_event.rmt_oob.bd_name, sizeof(BD_NAME), (char *)p_data->rmt_oob.bd_name, (BD_NAME_LEN - 1));
+        BCM_STRNCPY_S((char *)sec_event.rmt_oob.bd_name, (char *)p_data->rmt_oob.bd_name, (BD_NAME_LEN - 1));
         sec_event.rmt_oob.bd_name[BD_NAME_LEN - 1] = 0;
 
         bta_dm_cb.p_sec_cback(BTA_DM_SP_RMT_OOB_EVT, &sec_event);
@@ -4555,8 +4548,7 @@ static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_D
         bdcpy(sec_event.ble_req.bd_addr, bda);
         p_name = BTM_SecReadDevName(bda);
         if (p_name != NULL) {
-            BCM_STRNCPY_S((char *)sec_event.ble_req.bd_name,
-                          sizeof(BD_NAME), p_name, (BD_NAME_LEN));
+            BCM_STRNCPY_S((char *)sec_event.ble_req.bd_name,p_name, (BD_NAME_LEN));
         } else {
             sec_event.ble_req.bd_name[0] = 0;
         }
@@ -4568,8 +4560,7 @@ static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_D
         bdcpy(sec_event.key_notif.bd_addr, bda);
         p_name = BTM_SecReadDevName(bda);
         if (p_name != NULL) {
-            BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name,
-                          sizeof(BD_NAME), p_name, (BD_NAME_LEN));
+            BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, p_name, (BD_NAME_LEN));
         } else {
             sec_event.key_notif.bd_name[0] = 0;
         }
@@ -4590,7 +4581,7 @@ static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_D
 
     case BTM_LE_NC_REQ_EVT:
         bdcpy(sec_event.key_notif.bd_addr, bda);
-        BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, sizeof(BD_NAME), bta_dm_get_remname(), (BD_NAME_LEN));
+        BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name,bta_dm_get_remname(), (BD_NAME_LEN));
         sec_event.ble_req.bd_name[BD_NAME_LEN] = 0;
         sec_event.key_notif.passkey = p_data->key_notif;
         bta_dm_cb.p_sec_cback(BTA_DM_BLE_NC_REQ_EVT, &sec_event);
@@ -4610,8 +4601,7 @@ static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_D
 #endif
         p_name = BTM_SecReadDevName(bda);
         if (p_name != NULL) {
-            BCM_STRNCPY_S((char *)sec_event.auth_cmpl.bd_name,
-                          sizeof(BD_NAME), p_name, (BD_NAME_LEN));
+            BCM_STRNCPY_S((char *)sec_event.auth_cmpl.bd_name, p_name, (BD_NAME_LEN));
         } else {
             sec_event.auth_cmpl.bd_name[0] = 0;
         }
@@ -5895,7 +5885,7 @@ static void bta_dm_gatt_disc_result(tBTA_GATT_ID service_id)
 
         /* send result back to app now, one by one */
         bdcpy (result.disc_ble_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
-        BCM_STRNCPY_S((char *)result.disc_ble_res.bd_name, sizeof(BD_NAME), bta_dm_get_remname(), (BD_NAME_LEN - 1));
+        BCM_STRNCPY_S((char *)result.disc_ble_res.bd_name, bta_dm_get_remname(), (BD_NAME_LEN - 1));
         result.disc_ble_res.bd_name[BD_NAME_LEN] = 0;
         memcpy(&result.disc_ble_res.service, &service_id.uuid, sizeof(tBT_UUID));
 
@@ -5938,8 +5928,7 @@ static void bta_dm_gatt_disc_complete(UINT16 conn_id, tBTA_GATT_STATUS status)
             p_msg->disc_result.result.disc_res.num_uuids = 0;
             p_msg->disc_result.result.disc_res.p_uuid_list = NULL;
             bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
-            BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, sizeof(BD_NAME),
-                          bta_dm_get_remname(), (BD_NAME_LEN - 1));
+            BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name,bta_dm_get_remname(), (BD_NAME_LEN - 1));
 
             /* make sure the string is terminated */
             p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;

+ 1 - 1
components/bt/host/bluedroid/bta/dm/bta_dm_api.c

@@ -174,7 +174,7 @@ void BTA_DmSetDeviceName(const char *p_name)
     if ((p_msg = (tBTA_DM_API_SET_NAME *) osi_malloc(sizeof(tBTA_DM_API_SET_NAME))) != NULL) {
         p_msg->hdr.event = BTA_DM_API_SET_NAME_EVT;
         /* truncate the name if needed */
-        BCM_STRNCPY_S((char *)p_msg->name, sizeof(p_msg->name), p_name, BD_NAME_LEN - 1);
+        BCM_STRNCPY_S((char *)p_msg->name, p_name, BD_NAME_LEN - 1);
         p_msg->name[BD_NAME_LEN - 1] = 0;
 
         bta_sys_sendmsg(p_msg);

+ 320 - 0
components/bt/host/bluedroid/bta/hf_ag/bta_ag_api.c

@@ -0,0 +1,320 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2003-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the implementation of the API for the audio gateway (AG)
+ *  subsystem of BTA, Broadcom's Bluetooth application layer for mobile
+ *  phones.
+ *
+ ******************************************************************************/
+
+#include <string.h>
+#include "bta/bta_api.h"
+#include "bta/bta_sys.h"
+#include "bta/bta_ag_api.h"
+#include "bta_ag_int.h"
+#include "osi/allocator.h"
+
+#if (BTA_AG_INCLUDED == TRUE)
+/*****************************************************************************
+**  Constants
+*****************************************************************************/
+
+static const tBTA_SYS_REG bta_ag_reg =
+{
+    bta_ag_hdl_event,
+    BTA_AgDisable
+};
+
+/*******************************************************************************
+**
+** Function         BTA_AgEnable
+**
+** Description      Enable the audio gateway service. When the enable
+**                  operation is complete the callback function will be
+**                  called with a BTA_AG_ENABLE_EVT. This function must
+**                  be called before other function in the AG API are
+**                  called.
+**
+** Returns          BTA_SUCCESS if OK, BTA_FAILURE otherwise.
+**
+*******************************************************************************/
+tBTA_STATUS BTA_AgEnable(tBTA_AG_PARSE_MODE parse_mode, tBTA_AG_CBACK *p_cback)
+{
+    tBTA_AG_API_ENABLE  *p_buf;
+    UINT8       idx;
+
+    /* Error if AG is already enabled, or AG is in the middle of disabling. */
+    for (idx = 0; idx < BTA_AG_NUM_SCB; idx++) {
+        if (bta_ag_cb.scb[idx].in_use) {
+            APPL_TRACE_ERROR ("BTA_AgEnable: FAILED, AG already enabled.");
+            return BTA_FAILURE;
+        }
+    }
+    /* register with BTA system manager */
+    bta_sys_register(BTA_ID_AG, &bta_ag_reg);
+
+    if ((p_buf = (tBTA_AG_API_ENABLE *) osi_malloc(sizeof(tBTA_AG_API_ENABLE))) != NULL) {
+        p_buf->hdr.event = BTA_AG_API_ENABLE_EVT;
+        p_buf->parse_mode = parse_mode;
+        p_buf->p_cback = p_cback;
+        bta_sys_sendmsg(p_buf);
+    }
+    return BTA_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function         BTA_AgDisable
+**
+** Description      Disable the audio gateway service
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void BTA_AgDisable(void)
+{
+    BT_HDR  *p_buf;
+    if ((p_buf = (BT_HDR *) osi_malloc(sizeof(BT_HDR))) != NULL) {
+        p_buf->event = BTA_AG_API_DISABLE_EVT;
+        bta_sys_sendmsg(p_buf);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         BTA_AgRegister
+**
+** Description      Register an Audio Gateway service.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void BTA_AgRegister(tBTA_SERVICE_MASK services, tBTA_SEC sec_mask,tBTA_AG_FEAT features,
+                  char * p_service_names[], UINT8 app_id)
+{
+    tBTA_AG_API_REGISTER    *p_buf;
+    int                     i;
+
+    if ((p_buf = (tBTA_AG_API_REGISTER *) osi_malloc(sizeof(tBTA_AG_API_REGISTER))) != NULL) {
+        p_buf->hdr.event = BTA_AG_API_REGISTER_EVT;
+        p_buf->features = features;
+        p_buf->sec_mask = sec_mask;
+        p_buf->services = services;
+        p_buf->app_id = app_id;
+        for (i = 0; i < BTA_AG_NUM_IDX; i++) {
+            if(p_service_names[i]) {
+                BCM_STRNCPY_S(p_buf->p_name[i], p_service_names[i], BTA_SERVICE_NAME_LEN);
+                p_buf->p_name[i][BTA_SERVICE_NAME_LEN] = 0;
+            } else {
+                p_buf->p_name[i][0] = 0;
+            }
+        }
+        bta_sys_sendmsg(p_buf);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         BTA_AgDeregister
+**
+** Description      Deregister an audio gateway service.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void BTA_AgDeregister(UINT16 handle)
+{
+    BT_HDR  *p_buf;
+    if ((p_buf = (BT_HDR *) osi_malloc(sizeof(BT_HDR))) != NULL) {
+        p_buf->event = BTA_AG_API_DEREGISTER_EVT;
+        p_buf->layer_specific = handle;
+        bta_sys_sendmsg(p_buf);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         BTA_AgOpen
+**
+** Description      Opens a connection to a headset or hands-free device.
+**                  When connection is open callback function is called
+**                  with a BTA_AG_OPEN_EVT. Only the data connection is
+**                  opened. The audio connection is not opened.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void BTA_AgOpen(UINT16 handle, BD_ADDR bd_addr, tBTA_SEC sec_mask, tBTA_SERVICE_MASK services)
+{
+    tBTA_AG_API_OPEN  *p_buf;
+
+    if ((p_buf = (tBTA_AG_API_OPEN *) osi_malloc(sizeof(tBTA_AG_API_OPEN))) != NULL) {
+        p_buf->hdr.event = BTA_AG_API_OPEN_EVT;
+        p_buf->hdr.layer_specific = handle;
+        bdcpy(p_buf->bd_addr, bd_addr);
+        p_buf->services = services;
+        p_buf->sec_mask = sec_mask;
+        bta_sys_sendmsg(p_buf);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         BTA_AgClose
+**
+** Description      Close the current connection to a headset or a handsfree
+**                  Any current audio connection will also be closed.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void BTA_AgClose(UINT16 handle)
+{
+    BT_HDR  *p_buf;
+
+    if ((p_buf = (BT_HDR *) osi_malloc(sizeof(BT_HDR))) != NULL) {
+        p_buf->event = BTA_AG_API_CLOSE_EVT;
+        p_buf->layer_specific = handle;
+        bta_sys_sendmsg(p_buf);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         BTA_AgAudioOpen
+**
+** Description      Opens an audio connection to the currently connected
+**                  headset or handsfree.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void BTA_AgAudioOpen(UINT16 handle)
+{
+    BT_HDR  *p_buf;
+
+    if ((p_buf = (BT_HDR *) osi_malloc(sizeof(BT_HDR))) != NULL) {
+        p_buf->event = BTA_AG_API_AUDIO_OPEN_EVT;
+        p_buf->layer_specific = handle;
+        bta_sys_sendmsg(p_buf);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         BTA_AgAudioClose
+**
+** Description      Close the currently active audio connection to a headset
+**                  or handsfree. The data connection remains open
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void BTA_AgAudioClose(UINT16 handle)
+{
+    BT_HDR  *p_buf;
+
+    if ((p_buf = (BT_HDR *) osi_malloc(sizeof(BT_HDR))) != NULL) {
+        p_buf->event = BTA_AG_API_AUDIO_CLOSE_EVT;
+        p_buf->layer_specific = handle;
+        bta_sys_sendmsg(p_buf);
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         BTA_AgResult
+**
+** Description      Send an AT result code to a headset or hands-free device.
+**                  This function is only used when the AG parse mode is set
+**                  to BTA_AG_PARSE.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void BTA_AgResult(UINT16 handle, tBTA_AG_RES result, tBTA_AG_RES_DATA *p_data)
+{
+    tBTA_AG_API_RESULT  *p_buf;
+
+    if ((p_buf = (tBTA_AG_API_RESULT *) osi_malloc(sizeof(tBTA_AG_API_RESULT))) != NULL) {
+        p_buf->hdr.event = BTA_AG_API_RESULT_EVT;
+        p_buf->hdr.layer_specific = handle;
+        p_buf->result = result;
+        if(p_data) {
+            memcpy(&p_buf->data, p_data, sizeof(p_buf->data));
+        }
+        bta_sys_sendmsg(p_buf);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         BTA_AgSetCodec
+**
+** Description      Specify the codec type to be used for the subsequent
+**                  audio connection.
+**
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void BTA_AgSetCodec(UINT16 handle, tBTA_AG_PEER_CODEC codec)
+{
+    tBTA_AG_API_SETCODEC    *p_buf;
+
+    if ((p_buf = (tBTA_AG_API_SETCODEC *) osi_malloc(sizeof(tBTA_AG_API_SETCODEC))) != NULL) {
+        p_buf->hdr.event = BTA_AG_API_SETCODEC_EVT;
+        p_buf->hdr.layer_specific = handle;
+        p_buf->codec = codec;
+        bta_sys_sendmsg(p_buf);
+    }
+}
+
+#if (BTM_SCO_HCI_INCLUDED == TRUE )
+/************************************************************************************************
+ * Function        BTA_AgCiData
+ * 
+ * Description      Trigger the lower-layer to fetch and send audio data. This function is only
+ *                  only used in the case that Voice Over HCI is enabled. Precondition is that
+ *                  the HFP audio connection is connected. After this function is called, lower
+ *                  layer will invoke esp_hf_client_outgoing_data_cb_t to fetch data
+ *
+ ***********************************************************************************************/
+void BTA_AgCiData(void)
+{
+    BT_HDR *p_buf;
+    if ((p_buf = (BT_HDR *) osi_malloc(sizeof(BT_HDR))) != NULL) {
+        p_buf->event = BTA_AG_CI_SCO_DATA_EVT;
+        bta_sys_sendmsg(p_buf);
+    }
+}
+#endif /* #if (BTM_SCO_HCI_INCLUDED == TRUE ) */
+
+#endif /* #if (BTA_AG_INCLUDED == TRUE)*/

+ 1669 - 0
components/bt/host/bluedroid/bta/hf_ag/bta_ag_cmd.c

@@ -0,0 +1,1669 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2004-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains functions for processing AT commands and results.
+ *
+ ******************************************************************************/
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include "common/bt_target.h"
+#include "common/bt_trace.h"
+#include "stack/bt_types.h"
+#include "bta/bta_ag_api.h"
+#include "bta_ag_at.h"
+#include "bta_ag_int.h"
+#include "bta/bta_api.h"
+#include "bta/bta_sys.h"
+#include "osi/allocator.h"
+#include "stack/port_api.h"
+#include "bta/utl.h"
+
+
+#if (BTA_AG_INCLUDED == TRUE)
+/*****************************************************************************
+**  Constants
+*****************************************************************************/
+
+/* ring timeout */
+#define BTA_AG_RING_TOUT        5000
+#define BTA_AG_CMD_MAX_VAL      32767  /* Maximum value is signed 16-bit value */
+
+/* Invalid Chld command */
+#define BTA_AG_INVALID_CHLD        255
+
+/* clip type constants */
+#define BTA_AG_CLIP_TYPE_MIN        128
+#define BTA_AG_CLIP_TYPE_MAX        175
+#define BTA_AG_CLIP_TYPE_DEFAULT    129
+#define BTA_AG_CLIP_TYPE_VOIP       255
+
+/*******************************************
+*              HSP callback 
+********************************************/
+/* callback event lookup table for HSP */
+const tBTA_AG_EVT bta_ag_hsp_cb_evt[] =
+{
+    BTA_AG_AT_CKPD_EVT,     /* BTA_AG_HS_CMD_CKPD */
+    BTA_AG_SPK_EVT,         /* BTA_AG_HS_CMD_VGS */
+    BTA_AG_MIC_EVT          /* BTA_AG_HS_CMD_VGM */
+};
+/* HSP AT commands matches bta_ag_hsp_cmd[] */
+enum
+{
+    BTA_AG_HS_CMD_CKPD,
+    BTA_AG_HS_CMD_VGS,
+    BTA_AG_HS_CMD_VGM
+};
+/* HSP AT command interpreter table */
+const tBTA_AG_AT_CMD bta_ag_hsp_cmd[] =
+{
+    {"+CKPD",   BTA_AG_AT_SET,                      BTA_AG_AT_INT, 200, 200},
+    {"+VGS",    BTA_AG_AT_SET,                      BTA_AG_AT_INT,   0,  15},
+    {"+VGM",    BTA_AG_AT_SET,                      BTA_AG_AT_INT,   0,  15},
+    {"",        BTA_AG_AT_NONE,                     BTA_AG_AT_STR,   0,   0}
+};
+
+/*******************************************
+*              HFP callback 
+********************************************/
+/* callback event lookup table for HFP  (Indexed by command) */
+const tBTA_AG_EVT bta_ag_hfp_cb_evt[] =
+{
+    BTA_AG_AT_A_EVT,        /* BTA_AG_HF_CMD_A */
+    BTA_AG_AT_D_EVT,        /* BTA_AG_HF_CMD_D */
+    BTA_AG_SPK_EVT,         /* BTA_AG_HF_CMD_VGS */
+    BTA_AG_MIC_EVT,         /* BTA_AG_HF_CMD_VGM */
+    0,                      /* BTA_AG_HF_CMD_CCWA */
+    BTA_AG_AT_CHLD_EVT,     /* BTA_AG_HF_CMD_CHLD */
+    BTA_AG_AT_CHUP_EVT,     /* BTA_AG_HF_CMD_CHUP */
+    BTA_AG_AT_CIND_EVT,     /* BTA_AG_HF_CMD_CIND */
+    0,                      /* BTA_AG_HF_CMD_CLIP */
+    0,                      /* BTA_AG_HF_CMD_CMER */
+    BTA_AG_AT_VTS_EVT,      /* BTA_AG_HF_CMD_VTS */
+    BTA_AG_AT_BINP_EVT,     /* BTA_AG_HF_CMD_BINP */
+    BTA_AG_AT_BLDN_EVT,     /* BTA_AG_HF_CMD_BLDN */
+    BTA_AG_AT_BVRA_EVT,     /* BTA_AG_HF_CMD_BVRA */
+    0,                      /* BTA_AG_HF_CMD_BRSF */
+    BTA_AG_AT_NREC_EVT,     /* BTA_AG_HF_CMD_NREC */
+    BTA_AG_AT_CNUM_EVT,     /* BTA_AG_HF_CMD_CNUM */
+    BTA_AG_AT_BTRH_EVT,     /* BTA_AG_HF_CMD_BTRH */
+    BTA_AG_AT_CLCC_EVT,     /* BTA_AG_HF_CMD_CLCC */
+    BTA_AG_AT_COPS_EVT,     /* BTA_AG_HF_CMD_COPS */
+    0,                      /* BTA_AG_HF_CMD_CMEE */
+    0,                      /* BTA_AG_HF_CMD_BIA */
+    BTA_AG_AT_CBC_EVT,      /* BTA_AG_HF_CMD_CBC */
+    0,                      /* BTA_AG_HF_CMD_BCC */
+    BTA_AG_AT_BCS_EVT,      /* BTA_AG_HF_CMD_BCS */
+    BTA_AG_AT_BAC_EVT       /* BTA_AG_HF_CMD_BAC */
+};
+
+/* HFP AT commands matches bta_ag_hfp_cmd[] */
+enum
+{
+    BTA_AG_HF_CMD_A,
+    BTA_AG_HF_CMD_D,
+    BTA_AG_HF_CMD_VGS,
+    BTA_AG_HF_CMD_VGM,
+    BTA_AG_HF_CMD_CCWA,
+    BTA_AG_HF_CMD_CHLD,
+    BTA_AG_HF_CMD_CHUP,
+    BTA_AG_HF_CMD_CIND,
+    BTA_AG_HF_CMD_CLIP,
+    BTA_AG_HF_CMD_CMER,
+    BTA_AG_HF_CMD_VTS,
+    BTA_AG_HF_CMD_BINP,
+    BTA_AG_HF_CMD_BLDN,
+    BTA_AG_HF_CMD_BVRA,
+    BTA_AG_HF_CMD_BRSF,
+    BTA_AG_HF_CMD_NREC,
+    BTA_AG_HF_CMD_CNUM,
+    BTA_AG_HF_CMD_BTRH,
+    BTA_AG_HF_CMD_CLCC,
+    BTA_AG_HF_CMD_COPS,
+    BTA_AG_HF_CMD_CMEE,
+    BTA_AG_HF_CMD_BIA,
+    BTA_AG_HF_CMD_CBC,
+    BTA_AG_HF_CMD_BCC,
+    BTA_AG_HF_CMD_BCS,
+    BTA_AG_HF_CMD_BAC
+};
+
+/* HFP AT command interpreter table */
+const tBTA_AG_AT_CMD bta_ag_hfp_cmd[] =
+{
+    {"A",       BTA_AG_AT_NONE,                     BTA_AG_AT_STR,   0,   0},
+    {"D",       (BTA_AG_AT_NONE | BTA_AG_AT_FREE),  BTA_AG_AT_STR,   0,   0},
+    {"+VGS",    BTA_AG_AT_SET,                      BTA_AG_AT_INT,   0,  15},
+    {"+VGM",    BTA_AG_AT_SET,                      BTA_AG_AT_INT,   0,  15},
+    {"+CCWA",   BTA_AG_AT_SET,                      BTA_AG_AT_INT,   0,   1},
+    /* Consider CHLD as str to take care of indexes for ECC */
+    {"+CHLD",   (BTA_AG_AT_SET | BTA_AG_AT_TEST),   BTA_AG_AT_STR,   0,   4},
+    {"+CHUP",   BTA_AG_AT_NONE,                     BTA_AG_AT_STR,   0,   0},
+    {"+CIND",   (BTA_AG_AT_READ | BTA_AG_AT_TEST),  BTA_AG_AT_STR,   0,   0},
+    {"+CLIP",   BTA_AG_AT_SET,                      BTA_AG_AT_INT,   0,   1},
+    {"+CMER",   BTA_AG_AT_SET,                      BTA_AG_AT_STR,   0,   0},
+    {"+VTS",    BTA_AG_AT_SET,                      BTA_AG_AT_STR,   0,   0},
+    {"+BINP",   BTA_AG_AT_SET,                      BTA_AG_AT_INT,   1,   1},
+    {"+BLDN",   BTA_AG_AT_NONE,                     BTA_AG_AT_STR,   0,   0},
+    {"+BVRA",   BTA_AG_AT_SET,                      BTA_AG_AT_INT,   0,   1},
+    {"+BRSF",   BTA_AG_AT_SET,                      BTA_AG_AT_INT,   0,   BTA_AG_CMD_MAX_VAL},
+    {"+NREC",   BTA_AG_AT_SET,                      BTA_AG_AT_INT,   0,   0},
+    {"+CNUM",   BTA_AG_AT_NONE,                     BTA_AG_AT_STR,   0,   0},
+    {"+BTRH",   (BTA_AG_AT_READ | BTA_AG_AT_SET),   BTA_AG_AT_INT,   0,   2},
+    {"+CLCC",   BTA_AG_AT_NONE,                     BTA_AG_AT_STR,   0,   0},
+    {"+COPS",   (BTA_AG_AT_READ | BTA_AG_AT_SET),   BTA_AG_AT_STR,   0,   0},
+    {"+CMEE",   BTA_AG_AT_SET,                      BTA_AG_AT_INT,   0,   1},
+    {"+BIA",    BTA_AG_AT_SET,                      BTA_AG_AT_STR,   0,   20},
+    {"+CBC",    BTA_AG_AT_SET,                      BTA_AG_AT_INT,   0,   100},
+    {"+BCC",    BTA_AG_AT_NONE,                     BTA_AG_AT_STR,   0,   0},
+    {"+BCS",    BTA_AG_AT_SET,                      BTA_AG_AT_INT,   0,   BTA_AG_CMD_MAX_VAL},
+    {"+BAC",    BTA_AG_AT_SET,                      BTA_AG_AT_STR,   0,   0},
+    {"",        BTA_AG_AT_NONE,                     BTA_AG_AT_STR,   0,   0}
+};
+
+/*******************************************
+*              AT Result 
+********************************************/
+const tBTA_AG_AT_CMD *bta_ag_at_tbl[BTA_AG_NUM_IDX] =
+{
+    bta_ag_hsp_cmd,
+    bta_ag_hfp_cmd
+};
+
+/* AT result code argument types */
+enum
+{
+    BTA_AG_RES_FMT_NONE,       /* no argument */
+    BTA_AG_RES_FMT_INT,        /* integer argument */
+    BTA_AG_RES_FMT_STR         /* string argument */
+};
+
+#if defined(BTA_AG_MULTI_RESULT_INCLUDED) && (BTA_AG_MULTI_RESULT_INCLUDED == TRUE)
+#define BTA_AG_AT_MULTI_LEN            2
+#define AT_SET_RES_CB(res_cb, c, p, i) {res_cb.code = c; res_cb.p_arg = p; res_cb.int_arg = i;}
+
+/* type for AT result code block */
+typedef struct
+{
+    UINT8 code;
+    char *p_arg;
+    INT16 int_arg;
+} tBTA_AG_RESULT_CB;
+
+/* type for multiple AT result codes block */
+typedef struct
+{
+    UINT8 num_result;
+    tBTA_AG_RESULT_CB res_cb[BTA_AG_AT_MULTI_LEN];
+} tBTA_AG_MULTI_RESULT_CB;
+#endif
+
+/* AT result code table element */
+typedef struct
+{
+    const char  *p_res;         /* AT result string */
+    UINT8       fmt;            /* whether argument is int or string */
+} tBTA_AG_RESULT;
+
+/* AT result code constant table  (Indexed by result code) */
+const tBTA_AG_RESULT bta_ag_result_tbl[] =
+{
+    {"OK",      BTA_AG_RES_FMT_NONE},
+    {"ERROR",   BTA_AG_RES_FMT_NONE},
+    {"RING",    BTA_AG_RES_FMT_NONE},
+    {"+VGS: ",  BTA_AG_RES_FMT_INT},
+    {"+VGM: ",  BTA_AG_RES_FMT_INT},
+    {"+CCWA: ", BTA_AG_RES_FMT_STR},
+    {"+CHLD: ", BTA_AG_RES_FMT_STR},
+    {"+CIND: ", BTA_AG_RES_FMT_STR},
+    {"+CLIP: ", BTA_AG_RES_FMT_STR},
+    {"+CIEV: ", BTA_AG_RES_FMT_STR},
+    {"+BINP: ", BTA_AG_RES_FMT_STR},
+    {"+BVRA: ", BTA_AG_RES_FMT_INT},
+    {"+BRSF: ", BTA_AG_RES_FMT_INT},
+    {"+BSIR: ", BTA_AG_RES_FMT_INT},
+    {"+CNUM: ", BTA_AG_RES_FMT_STR},
+    {"+BTRH: ", BTA_AG_RES_FMT_INT},
+    {"+CLCC: ", BTA_AG_RES_FMT_STR},
+    {"+COPS: ", BTA_AG_RES_FMT_STR},
+    {"+CME ERROR: ", BTA_AG_RES_FMT_INT},
+    {"+BCS: ",  BTA_AG_RES_FMT_INT},
+    {"",        BTA_AG_RES_FMT_STR}
+};
+
+/* AT result codes, matches bta_ag_result_tbl[] */
+enum
+{
+    BTA_AG_RES_OK,
+    BTA_AG_RES_ERROR,
+    BTA_AG_RES_RING,
+    BTA_AG_RES_VGS,
+    BTA_AG_RES_VGM,
+    BTA_AG_RES_CCWA,
+    BTA_AG_RES_CHLD,
+    BTA_AG_RES_CIND,
+    BTA_AG_RES_CLIP,
+    BTA_AG_RES_CIEV,
+    BTA_AG_RES_BINP,
+    BTA_AG_RES_BVRA,
+    BTA_AG_RES_BRSF,
+    BTA_AG_RES_BSIR,
+    BTA_AG_RES_CNUM,
+    BTA_AG_RES_BTRH,
+    BTA_AG_RES_CLCC,
+    BTA_AG_RES_COPS,
+    BTA_AG_RES_CMEE,
+    BTA_AG_RES_BCS,
+    BTA_AG_RES_UNAT
+};
+
+/* translation of API result code values to internal values */
+const UINT8 bta_ag_trans_result[] =
+{
+    BTA_AG_RES_VGS,     /* BTA_AG_SPK_RES */
+    BTA_AG_RES_VGM,     /* BTA_AG_MIC_RES */
+    BTA_AG_RES_BSIR,    /* BTA_AG_INBAND_RING_RES */
+    BTA_AG_RES_CIND,    /* BTA_AG_CIND_RES */
+    BTA_AG_RES_BINP,    /* BTA_AG_BINP_RES */
+    BTA_AG_RES_CIEV,    /* BTA_AG_IND_RES */
+    BTA_AG_RES_BVRA,    /* BTA_AG_BVRA_RES */
+    BTA_AG_RES_CNUM,    /* BTA_AG_CNUM_RES */
+    BTA_AG_RES_BTRH,    /* BTA_AG_BTRH_RES */
+    BTA_AG_RES_CLCC,    /* BTA_AG_CLCC_RES */
+    BTA_AG_RES_COPS,    /* BTA_AG_COPS_RES */
+    0,                  /* BTA_AG_IN_CALL_RES */
+    0,                  /* BTA_AG_IN_CALL_CONN_RES */
+    BTA_AG_RES_CCWA,    /* BTA_AG_CALL_WAIT_RES */
+    0,                  /* BTA_AG_OUT_CALL_ORIG_RES */
+    0,                  /* BTA_AG_OUT_CALL_ALERT_RES */
+    0,                  /* BTA_AG_OUT_CALL_CONN_RES */
+    0,                  /* BTA_AG_CALL_CANCEL_RES */
+    0,                  /* BTA_AG_END_CALL_RES */
+    0,                  /* BTA_AG_IN_CALL_HELD_RES */
+    BTA_AG_RES_UNAT     /* BTA_AG_UNAT_RES */
+};
+
+/* callsetup indicator value lookup table */
+const UINT8 bta_ag_callsetup_ind_tbl[] =
+{
+    0,                          /* BTA_AG_SPK_RES */
+    0,                          /* BTA_AG_MIC_RES */
+    0,                          /* BTA_AG_INBAND_RING_RES */
+    0,                          /* BTA_AG_CIND_RES */
+    0,                          /* BTA_AG_BINP_RES */
+    0,                          /* BTA_AG_IND_RES */
+    0,                          /* BTA_AG_BVRA_RES */
+    0,                          /* BTA_AG_CNUM_RES */
+    0,                          /* BTA_AG_BTRH_RES */
+    0,                          /* BTA_AG_CLCC_RES */
+    0,                          /* BTA_AG_COPS_RES */
+    BTA_AG_CALLSETUP_INCOMING,  /* BTA_AG_IN_CALL_RES */
+    BTA_AG_CALLSETUP_NONE,      /* BTA_AG_IN_CALL_CONN_RES */
+    BTA_AG_CALLSETUP_INCOMING,  /* BTA_AG_CALL_WAIT_RES */
+    BTA_AG_CALLSETUP_OUTGOING,  /* BTA_AG_OUT_CALL_ORIG_RES */
+    BTA_AG_CALLSETUP_ALERTING,  /* BTA_AG_OUT_CALL_ALERT_RES */
+    BTA_AG_CALLSETUP_NONE,      /* BTA_AG_OUT_CALL_CONN_RES */
+    BTA_AG_CALLSETUP_NONE,      /* BTA_AG_CALL_CANCEL_RES */
+    BTA_AG_CALLSETUP_NONE,      /* BTA_AG_END_CALL_RES */
+    BTA_AG_CALLSETUP_NONE       /* BTA_AG_IN_CALL_HELD_RES */
+};
+
+#if defined(BTA_HSP_RESULT_REPLACE_COLON) && (BTA_HSP_RESULT_REPLACE_COLON == TRUE)
+#define COLON_IDX_4_VGSVGM    4
+#endif
+
+/*******************************************
+*              Funcitons Result 
+********************************************/
+/*******************************************************************************
+**
+** Function         bta_ag_send_result
+**
+** Description      Send an AT result code.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+static void bta_ag_send_result(tBTA_AG_SCB *p_scb, UINT8 code, char *p_arg, INT16 int_arg)
+{
+    char    buf[BTA_AG_AT_MAX_LEN + 16];
+    char    *p = buf;
+    UINT16  len;
+#if (BTIF_TRACE_DEBUG == TRUE)
+    memset(buf, NULL, sizeof(buf));
+#endif
+    /* init with \r\n */
+    *p++ = '\r';
+    *p++ = '\n';
+
+    /* copy result code string */
+    BCM_STRCPY_S(p, bta_ag_result_tbl[code].p_res);
+#if defined(BTA_HSP_RESULT_REPLACE_COLON) && (BTA_HSP_RESULT_REPLACE_COLON == TRUE)
+    if(p_scb->conn_service == BTA_AG_HSP) {
+        /* If HSP then ":"symbol should be changed as "=" for HSP compatibility */
+        switch(code) {
+            case BTA_AG_RES_VGS:
+            case BTA_AG_RES_VGM:
+            {
+                if(*(p+COLON_IDX_4_VGSVGM) == ':')
+                {
+                    #if defined(BTA_AG_RESULT_DEBUG) && (BTA_AG_RESULT_DEBUG == TRUE)
+                    APPL_TRACE_DEBUG("[HSP] ':'symbol is changed as '=' for HSP compatibility");
+                    #endif
+                    *(p+COLON_IDX_4_VGSVGM) = '=';
+                }
+                break;
+            }
+        }
+    }
+#endif
+    p += strlen(bta_ag_result_tbl[code].p_res);
+
+    /* copy argument if any */
+    if (bta_ag_result_tbl[code].fmt == BTA_AG_RES_FMT_INT) {
+        p += utl_itoa((UINT16) int_arg, p);
+    } else if (bta_ag_result_tbl[code].fmt == BTA_AG_RES_FMT_STR) {
+        BCM_STRCPY_S(p, p_arg);
+        p += strlen(p_arg);
+    }
+    /* finish with \r\n */
+    *p++ = '\r';
+    *p++ = '\n';
+    APPL_TRACE_DEBUG("bta_ag_send_result: %s", buf);
+    /* send to RFCOMM */
+    PORT_WriteData(p_scb->conn_handle, buf, (UINT16) (p - buf), &len);
+}
+
+#if defined(BTA_AG_MULTI_RESULT_INCLUDED) && (BTA_AG_MULTI_RESULT_INCLUDED == TRUE)
+/*******************************************************************************
+**
+** Function         bta_ag_send_multi_result
+**
+** Description      Send multiple AT result codes.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+static void bta_ag_send_multi_result(tBTA_AG_SCB *p_scb, tBTA_AG_MULTI_RESULT_CB *m_res_cb)
+{
+    char    buf[BTA_AG_AT_MAX_LEN * BTA_AG_AT_MULTI_LEN + 16];
+    char    *p = buf;
+    UINT16  len;
+    UINT8   res_idx = 0;
+
+    if((!m_res_cb) || (m_res_cb->num_result == 0) || (m_res_cb->num_result > BTA_AG_AT_MULTI_LEN)) {
+        APPL_TRACE_DEBUG("m_res_cb is NULL or num_result is out of range.");
+        return;
+    }
+
+#if defined(BTA_AG_RESULT_DEBUG) && (BTA_AG_RESULT_DEBUG == TRUE)
+    memset(buf, NULL, sizeof(buf));
+#endif
+
+    while(res_idx < m_res_cb->num_result) {
+        /* init with \r\n */
+        *p++ = '\r';
+        *p++ = '\n';
+
+        /* copy result code string */
+        BCM_STRCPY_S(p, bta_ag_result_tbl[m_res_cb->res_cb[res_idx].code].p_res);
+        p += strlen(bta_ag_result_tbl[m_res_cb->res_cb[res_idx].code].p_res);
+
+        /* copy argument if any */
+        if (bta_ag_result_tbl[m_res_cb->res_cb[res_idx].code].fmt == BTA_AG_RES_FMT_INT) {
+            p += utl_itoa((UINT16) m_res_cb->res_cb[res_idx].int_arg, p);
+        } else if (bta_ag_result_tbl[m_res_cb->res_cb[res_idx].code].fmt == BTA_AG_RES_FMT_STR) {
+            BCM_STRCPY_S(p, m_res_cb->res_cb[res_idx].p_arg);
+            p += strlen(m_res_cb->res_cb[res_idx].p_arg);
+        }
+        /* finish with \r\n */
+        *p++ = '\r';
+        *p++ = '\n';
+        res_idx++;
+    }
+#if defined(BTA_AG_RESULT_DEBUG) && (BTA_AG_RESULT_DEBUG == TRUE)
+    APPL_TRACE_DEBUG("send_result: %s", buf);
+#endif
+    /* send to RFCOMM */
+    PORT_WriteData(p_scb->conn_handle, buf, (UINT16) (p - buf), &len);
+}
+#endif /* #if defined(BTA_AG_MULTI_RESULT_INCLUDED) && (BTA_AG_MULTI_RESULT_INCLUDED == TRUE) */
+
+/*******************************************************************************
+**
+** Function         bta_ag_send_ok
+**
+** Description      Send an OK result code.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+static void bta_ag_send_ok(tBTA_AG_SCB *p_scb)
+{
+    bta_ag_send_result(p_scb, BTA_AG_RES_OK, NULL, 0);
+}
+
+/*******************************************************************************
+**
+** Function         bta_ag_send_error
+**
+** Description      Send an ERROR result code.
+**                      errcode - used to send verbose errocode
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+static void bta_ag_send_error(tBTA_AG_SCB *p_scb, INT16 errcode)
+{
+    /* If HFP and extended audio gateway error codes are enabled */
+    if (p_scb->conn_service == BTA_AG_HFP && p_scb->cmee_enabled) {
+        bta_ag_send_result(p_scb, BTA_AG_RES_CMEE, NULL, errcode);
+    } else {
+        bta_ag_send_result(p_scb, BTA_AG_RES_ERROR, NULL, 0);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         bta_ag_send_ind
+**
+** Description      Send an indicator CIEV result code.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+static void bta_ag_send_ind(tBTA_AG_SCB *p_scb, UINT16 id, UINT16 value, BOOLEAN on_demand)
+{
+    char    str[12];
+    char    *p = str;
+    /* If the indicator is masked out, just return */
+    /* Mandatory indicators can not be masked out. */
+    if ((p_scb->bia_masked_out & ((UINT32)1 << id)) &&
+        ((id != BTA_AG_IND_CALL) && (id != BTA_AG_IND_CALLSETUP) && (id != BTA_AG_IND_CALLHELD)))
+        return;
+
+    /* Ensure we do not send duplicate indicators if not requested by app */
+    /* If it was requested by app, transmit CIEV even if it is duplicate. */
+    if (id == BTA_AG_IND_CALL) {
+        if ((value == p_scb->call_ind) && (on_demand == FALSE)) {
+            return;
+        }
+        p_scb->call_ind = (UINT8)value;
+    }
+    if ((id == BTA_AG_IND_CALLSETUP) && (on_demand == FALSE)) {
+        if (value == p_scb->callsetup_ind) {
+            return;
+        }
+        p_scb->callsetup_ind = (UINT8)value;
+    }
+    if ((id == BTA_AG_IND_SERVICE) && (on_demand == FALSE)) {
+        if (value == p_scb->service_ind) {
+            return;
+        }
+        p_scb->service_ind = (UINT8)value;
+    }
+    if ((id == BTA_AG_IND_SIGNAL) && (on_demand == FALSE)) {
+        if (value == p_scb->signal_ind) {
+            return;
+        }
+        p_scb->signal_ind = (UINT8)value;
+    }
+    if ((id == BTA_AG_IND_ROAM) && (on_demand == FALSE)) {
+        if (value == p_scb->roam_ind) {
+            return;            
+        }
+        p_scb->roam_ind = (UINT8)value;
+    }
+    if ((id == BTA_AG_IND_BATTCHG) && (on_demand == FALSE)) {
+        if (value == p_scb->battchg_ind) {
+            return;
+        }
+        p_scb->battchg_ind = (UINT8)value;
+    }
+    if ((id == BTA_AG_IND_CALLHELD) && (on_demand == FALSE)) {
+        /* call swap could result in sending callheld=1 multiple times */
+        if ((value != 1) && (value == p_scb->callheld_ind)) {
+            return;
+        }
+        p_scb->callheld_ind = (UINT8)value;
+    }
+    if (p_scb->cmer_enabled) {
+        p += utl_itoa(id, p);
+        *p++ = ',';
+        utl_itoa(value, p);
+        bta_ag_send_result(p_scb, BTA_AG_RES_CIEV, str, 0);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         bta_ag_parse_cmer
+**
+** Description      Parse AT+CMER parameter string.
+**
+**
+** Returns          TRUE if parsed ok, FALSE otherwise.
+**
+*******************************************************************************/
+static BOOLEAN bta_ag_parse_cmer(char *p_s, BOOLEAN *p_enabled)
+{
+    INT16   n[4] = {-1, -1, -1, -1};
+    int     i;
+    char    *p;
+
+    for (i = 0; i < 4; i++) {
+        /* skip to comma delimiter */
+        for (p = p_s; *p != ',' && *p != 0; p++);
+        /* get integer value */
+        *p = 0;
+        n[i] = utl_str2int(p_s);
+        p_s = p + 1;
+        if (p_s == 0) {
+            break;
+        }
+    }
+    /* process values */
+    if (n[0] < 0 || n[3] < 0) {
+        return FALSE;
+    }
+    if ((n[0] == 3) && ((n[3] == 1) || (n[3] == 0))) {
+        *p_enabled = (BOOLEAN) n[3];
+    }
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         bta_ag_parse_chld
+**
+** Description      Parse AT+CHLD parameter string.
+**
+**
+** Returns          Returns idx (1-7), 0 if ECC not enabled or BTA_AG_INVALID_CHLD
+                    if idx doesn't exist/1st character of argument is not a digit
+**
+*******************************************************************************/
+static UINT8 bta_ag_parse_chld(tBTA_AG_SCB *p_scb, char *p_s)
+{
+    UINT8   retval = 0;
+    INT16   idx = -1;
+    UNUSED(p_scb);
+
+    if (!isdigit(p_s[0])) {
+        return BTA_AG_INVALID_CHLD;
+    }
+
+    if (p_s[1] != 0) {
+        /* p_idxstr++;  point to beginning of call number */
+        idx = utl_str2int(&p_s[1]);
+        if (idx != -1 && idx < 255) {
+            retval = (UINT8)idx;
+        } else {
+            retval = BTA_AG_INVALID_CHLD;
+        }
+    }
+    return(retval);
+}
+
+#if (BTM_WBS_INCLUDED == TRUE)
+/*******************************************************************************
+**
+** Function         bta_ag_parse_bac
+**
+** Description      Parse AT+BAC parameter string.
+**
+** Returns          Returns bitmap of supported codecs.
+**
+*******************************************************************************/
+static tBTA_AG_PEER_CODEC bta_ag_parse_bac(tBTA_AG_SCB *p_scb, char *p_s)
+{
+    tBTA_AG_PEER_CODEC  retval = BTA_AG_CODEC_NONE;
+    UINT16  uuid_codec;
+    BOOLEAN cont = FALSE;       /* Continue processing */
+    char *p;
+
+    while (p_s) {
+        /* skip to comma delimiter */
+        for (p = p_s; *p != ',' && *p != 0; p++);
+
+        /* get integre value */
+        if (*p != 0) {
+            *p = 0;
+            cont = TRUE;
+        } else {
+            cont = FALSE;
+        }
+        uuid_codec = utl_str2int(p_s);
+        switch(uuid_codec) {
+            case UUID_CODEC_CVSD:   
+                retval |= BTA_AG_CODEC_CVSD;     
+                break;
+            
+            case UUID_CODEC_MSBC:   
+                retval |= BTA_AG_CODEC_MSBC;     
+                break;
+            
+            default:
+                APPL_TRACE_ERROR("Unknown Codec UUID(%d) received", uuid_codec);
+                return BTA_AG_CODEC_NONE;
+        }
+        if (cont) {
+            p_s = p + 1;
+        }
+        else {
+            break;
+        }
+    }
+    return (retval);
+}
+#endif /* #if (BTM_WBS_INCLUDED == TRUE ) */
+
+/*******************************************************************************
+**
+** Function         bta_ag_process_unat_res
+**
+** Description      Process the unat response data and remove extra carriage return
+**                  and line feed
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+static void bta_ag_process_unat_res(char *unat_result)
+{
+    UINT8   str_leng;
+    UINT8   i = 0;
+    UINT8   j = 0;
+    UINT8   pairs_of_nl_cr;
+    char    trim_data[BTA_AG_AT_MAX_LEN];
+
+    str_leng = strlen(unat_result);
+    /* If no extra CR and LF, just return */
+    if(str_leng < 4) {
+        return;
+    }
+
+    /* Remove the carriage return and left feed */
+    while(unat_result[0] =='\r' && unat_result[1] =='\n'
+        && unat_result[str_leng-2] =='\r' && unat_result[str_leng-1] =='\n') {
+        pairs_of_nl_cr = 1;
+        for (i=0;i<(str_leng-4*pairs_of_nl_cr);i++) {
+            trim_data[j++] = unat_result[i+pairs_of_nl_cr*2];
+        }
+        /* Add EOF */
+        trim_data[j] = '\0';
+        str_leng = str_leng - 4;
+        BCM_STRNCPY_S(unat_result, trim_data, BTA_AG_AT_MAX_LEN);
+        i=0;
+        j=0;
+        if(str_leng <4) {
+            return;
+        }
+    }
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         bta_ag_inband_enabled
+**
+** Description      Determine whether in-band ring can be used.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+BOOLEAN bta_ag_inband_enabled(tBTA_AG_SCB *p_scb)
+{
+    /* if feature is enabled and no other scbs connected */
+    if (p_scb->inband_enabled && !bta_ag_other_scb_open(p_scb)) {
+        return TRUE;
+    } else {
+        return FALSE;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         bta_ag_send_call_inds
+**
+** Description      Send call and callsetup indicators.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_ag_send_call_inds(tBTA_AG_SCB *p_scb, tBTA_AG_RES result)
+{
+    UINT8 call = p_scb->call_ind;
+    UINT8 callsetup;
+    /* set new call and callsetup values based on BTA_AgResult */
+    callsetup = bta_ag_callsetup_ind_tbl[result];
+
+    if (result == BTA_AG_END_CALL_RES) {
+        call = BTA_AG_CALL_INACTIVE;
+    } else if (result == BTA_AG_IN_CALL_CONN_RES || result == BTA_AG_OUT_CALL_CONN_RES
+             || result == BTA_AG_IN_CALL_HELD_RES) {
+        call = BTA_AG_CALL_ACTIVE;
+    } else {
+        call = p_scb->call_ind;
+    }
+    /* Send indicator function tracks if the values have actually changed */
+    bta_ag_send_ind(p_scb, BTA_AG_IND_CALL, call, FALSE);
+    bta_ag_send_ind(p_scb, BTA_AG_IND_CALLSETUP, callsetup, FALSE);
+}
+
+/*******************************************************************************
+**
+** Function         bta_ag_at_hsp_cback
+**
+** Description      AT command processing callback for HSP.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_ag_at_hsp_cback(tBTA_AG_SCB *p_scb, UINT16 cmd, UINT8 arg_type,
+                                char *p_arg, INT16 int_arg)
+{
+    tBTA_AG_VAL val;
+    APPL_TRACE_DEBUG("AT cmd:%d arg_type:%d arg:%d arg:%s", cmd, arg_type, int_arg, p_arg);
+
+    /* send OK */
+    bta_ag_send_ok(p_scb);
+    val.hdr.handle = bta_ag_scb_to_idx(p_scb);
+    val.hdr.app_id = p_scb->app_id;
+    val.num = (UINT16) int_arg;
+    BCM_STRNCPY_S(val.str, p_arg, BTA_AG_AT_MAX_LEN);
+    val.str[BTA_AG_AT_MAX_LEN] = 0;
+    /* call callback with event */
+    (*bta_ag_cb.p_cback)(bta_ag_hsp_cb_evt[cmd], (tBTA_AG *) &val);
+}
+
+/*******************************************************************************
+**
+** Function         bta_ag_at_hfp_cback
+**
+** Description      AT command processing callback for HFP.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_ag_at_hfp_cback(tBTA_AG_SCB *p_scb, UINT16 cmd, UINT8 arg_type,
+                                char *p_arg, INT16 int_arg)
+{
+    tBTA_AG_VAL     val;
+    tBTA_AG_EVT     event;
+    tBTA_AG_SCB     *ag_scb;
+    UINT32          i, ind_id;
+    UINT32          bia_masked_out;
+#if (BTM_WBS_INCLUDED == TRUE)
+    tBTA_AG_PEER_CODEC  codec_type, codec_sent;
+#endif
+    if (p_arg == NULL) {
+        APPL_TRACE_ERROR("%s: p_arg is null, send error and return", __func__);
+        bta_ag_send_error(p_scb, BTA_AG_ERR_INV_CHAR_IN_TSTR);
+        return;
+    }
+    APPL_TRACE_DEBUG("HFP AT cmd:%d arg_type:%d arg:%d arg:%s", cmd, arg_type, int_arg, p_arg);
+
+    val.hdr.handle = bta_ag_scb_to_idx(p_scb);
+    val.hdr.app_id = p_scb->app_id;
+    val.num = int_arg;
+    bdcpy(val.bd_addr, p_scb->peer_addr);
+    BCM_STRNCPY_S(val.str, p_arg, BTA_AG_AT_MAX_LEN);
+    val.str[BTA_AG_AT_MAX_LEN] = 0;
+    event = bta_ag_hfp_cb_evt[cmd];
+
+    switch (cmd)
+    {
+        case BTA_AG_HF_CMD_A:
+        case BTA_AG_HF_CMD_VGS:
+        case BTA_AG_HF_CMD_VGM:
+        case BTA_AG_HF_CMD_CHUP:
+        case BTA_AG_HF_CMD_CBC:
+            /* send OK */
+            bta_ag_send_ok(p_scb);
+            break;
+
+        case BTA_AG_HF_CMD_BLDN:
+            /* Do not send OK, App will send error or OK depending on last-dial-umber enabled or not */
+            break;
+
+        case BTA_AG_HF_CMD_D:
+        {
+            /* Do not send OK for Dial cmds Let application decide whether to send OK or ERROR*/
+            /* if mem dial cmd, make sure string contains only digits */
+            if(p_arg[0] == '>') {
+                if(!utl_isintstr(p_arg+1)) {
+                    event = 0;
+                    bta_ag_send_error(p_scb, BTA_AG_ERR_INV_CHAR_IN_DSTR);
+                }
+            } else if (p_arg[0] == 'V') {
+                /* ATDV : Dial VoIP Call */ 
+                /* We do not check string. Code will be added later if needed. */
+                if(!((p_scb->peer_features & BTA_AG_PEER_FEAT_VOIP) && (p_scb->features & BTA_AG_FEAT_VOIP))) {
+                    event = 0;
+                    bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
+                }
+            } else {
+            /* If dial cmd, make sure string contains only dial digits
+            ** Dial digits are 0-9, A-C, *, #, + */
+                if(!utl_isdialstr(p_arg)) {
+                    event = 0;
+                    bta_ag_send_error(p_scb, BTA_AG_ERR_INV_CHAR_IN_DSTR);
+                }
+            }
+            break;
+        }
+
+        case BTA_AG_HF_CMD_CCWA:
+            p_scb->ccwa_enabled = (BOOLEAN) int_arg; /* store setting */
+            bta_ag_send_ok(p_scb); /* send OK */
+            break;
+
+        case BTA_AG_HF_CMD_CHLD:
+        {
+            if (arg_type == BTA_AG_AT_TEST) {
+                /* don't call callback */
+                event = 0;
+                /* send CHLD string */
+                /* Form string based on supported 1.5 feature */
+                if ((p_scb->peer_version >= HFP_VERSION_1_5) &&
+                    (p_scb->features & BTA_AG_FEAT_ECC) &&
+                    (p_scb->peer_features & BTA_AG_PEER_FEAT_ECC)) {
+                    bta_ag_send_result(p_scb, BTA_AG_RES_CHLD, p_bta_ag_cfg->chld_val_ecc, 0);
+                    } else {
+                    bta_ag_send_result(p_scb, BTA_AG_RES_CHLD, p_bta_ag_cfg->chld_val, 0);
+                    }
+                /* send OK */
+                bta_ag_send_ok(p_scb);
+                /* if service level conn. not already open, now it's open */
+                bta_ag_svc_conn_open(p_scb, NULL);
+            } else {
+                val.idx = bta_ag_parse_chld(p_scb, val.str);
+                if (val.idx == BTA_AG_INVALID_CHLD) {
+                    event = 0;
+                    bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
+                    break;
+                }
+                if(val.idx && !((p_scb->features & BTA_AG_FEAT_ECC) && (p_scb->peer_features & BTA_AG_PEER_FEAT_ECC))) {
+                    /* we do not support ECC, but HF is sending us a CHLD with call index*/
+                    event = 0;
+                    bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
+
+                } else {
+                    /* If it is swap between calls, set call held indicator to 3(out of valid 0-2)
+                    ** Application will set it back to 1
+                    ** callheld indicator will be sent across to the peer. */
+                    if(val.str[0] == '2') {
+                        for (i = 0, ag_scb = &bta_ag_cb.scb[0]; i < BTA_AG_NUM_SCB; i++, ag_scb++) {
+                            if (ag_scb->in_use) {
+                                if((ag_scb->call_ind == BTA_AG_CALL_ACTIVE)
+                                    && (ag_scb->callsetup_ind == BTA_AG_CALLSETUP_NONE)) {
+                                    ag_scb->callheld_ind = BTA_AG_CALLHELD_NOACTIVE + 1;
+                                    }
+                            }
+                        }
+                    }
+                }
+            /* Do not send OK. Let app decide after parsing the val str */
+            /* bta_ag_send_ok(p_scb); */
+            }
+            break;
+        }
+
+        case BTA_AG_HF_CMD_CIND:
+            if (arg_type == BTA_AG_AT_TEST) {
+                /* don't call callback */
+                event = 0;
+                /* send CIND string, send OK */
+                bta_ag_send_result(p_scb, BTA_AG_RES_CIND, p_bta_ag_cfg->cind_info, 0);
+                bta_ag_send_ok(p_scb);
+            }
+            break;
+
+        case BTA_AG_HF_CMD_CLIP:
+            /* store setting, send OK */
+            p_scb->clip_enabled = (BOOLEAN) int_arg;
+            bta_ag_send_ok(p_scb);
+            break;
+
+        case BTA_AG_HF_CMD_CMER:
+            /* if parsed ok store setting, send OK */
+            if (bta_ag_parse_cmer(p_arg, &p_scb->cmer_enabled)) {
+                bta_ag_send_ok(p_scb);
+                /* if service level conn. not already open and our features and
+                ** peer features do not have 3-way, service level conn. now open
+                */
+                if (!p_scb->svc_conn && !((p_scb->features & BTA_AG_FEAT_3WAY) && (p_scb->peer_features & BTA_AG_PEER_FEAT_3WAY))) {
+                    bta_ag_svc_conn_open(p_scb, NULL);
+                }
+            } else {
+                bta_ag_send_error(p_scb, BTA_AG_ERR_INV_CHAR_IN_TSTR);
+            }
+            break;
+
+        case BTA_AG_HF_CMD_VTS:
+            /* check argument */
+            if (strlen(p_arg) == 1) {
+                bta_ag_send_ok(p_scb);
+            } else {
+                event = 0;
+                bta_ag_send_error(p_scb, BTA_AG_ERR_INV_CHAR_IN_TSTR);
+            }
+            break;
+
+        case BTA_AG_HF_CMD_BINP:
+            /* if feature not set don't call callback, send ERROR */
+            if (!(p_scb->features & BTA_AG_FEAT_VTAG)) {
+                event = 0;
+                bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
+            }
+            break;
+
+        case BTA_AG_HF_CMD_BVRA:
+            /* if feature not supported don't call callback, send ERROR. App will send OK */
+            if (!(p_scb->features & BTA_AG_FEAT_VREC)) {
+                event = 0;
+                bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
+            } else {
+                bta_ag_send_ok(p_scb);
+            }
+            break;
+
+        case BTA_AG_HF_CMD_BRSF:
+        {
+            /* store peer features */
+            p_scb->peer_features = (UINT16) int_arg;
+            /* send BRSF, send OK */
+            bta_ag_send_result(p_scb, BTA_AG_RES_BRSF, NULL, (INT16) (p_scb->features & BTA_AG_BSRF_FEAT_SPEC));
+            bta_ag_send_ok(p_scb);
+            break;
+        }
+
+        case BTA_AG_HF_CMD_NREC:
+            /* if feature send OK, else don't call callback, send ERROR */
+            if (p_scb->features & BTA_AG_FEAT_ECNR) {
+                bta_ag_send_ok(p_scb);
+            } else {
+                event = 0;
+                bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
+            }
+            break;
+
+        case BTA_AG_HF_CMD_BTRH:
+            /* if feature send BTRH, send OK:, else don't call callback, send ERROR */
+            if (p_scb->features & BTA_AG_FEAT_BTRH) {
+                /* If set command; send response and notify app */
+                if (arg_type == BTA_AG_AT_SET) {
+                    for (i = 0, ag_scb = &bta_ag_cb.scb[0]; i < BTA_AG_NUM_SCB; i++, ag_scb++) {
+                        if (ag_scb->in_use) {
+                            bta_ag_send_result(ag_scb, BTA_AG_RES_BTRH, NULL, int_arg);
+                        }
+                    }
+                    bta_ag_send_ok(p_scb);
+                } else {
+                    /* Read Command */
+                    val.num = BTA_AG_BTRH_READ;
+                }
+            } else {
+                event = 0;
+                bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
+            }
+            break;
+
+        case BTA_AG_HF_CMD_COPS:
+            if (arg_type == BTA_AG_AT_SET) {
+                /* don't call callback */
+                event = 0;
+                /* send OK */
+                bta_ag_send_ok(p_scb);
+            }
+            break;
+
+        case BTA_AG_HF_CMD_CMEE:
+            if (p_scb->features & BTA_AG_FEAT_EXTERR) {
+                /* store setting */
+                p_scb->cmee_enabled = (BOOLEAN) int_arg;
+                /* send OK */
+                bta_ag_send_ok(p_scb);
+            } else {
+                bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
+            }
+            /* don't call callback */
+            event = 0;
+            break;
+
+        case BTA_AG_HF_CMD_BIA:
+        {
+            /* don't call callback */
+            event = 0;
+            bia_masked_out = p_scb->bia_masked_out;
+            /* Parse the indicator mask */
+            for (i = 0, ind_id = 1; (val.str[i] != 0) && (ind_id <= 20); i++, ind_id++) {
+                if (val.str[i] == ',')
+                    continue;
+                if (val.str[i] == '0')
+                    bia_masked_out |= ((UINT32)1 << ind_id);
+                else if (val.str[i] == '1')
+                    bia_masked_out &= ~((UINT32)1 << ind_id);
+                else
+                    break;
+                i++;
+                if ( (val.str[i] != 0) && (val.str[i] != ',') )
+                    break;
+            }
+            if (val.str[i] == 0) {
+                p_scb->bia_masked_out = bia_masked_out;
+                bta_ag_send_ok (p_scb);
+            } else {
+                bta_ag_send_error (p_scb, BTA_AG_ERR_INVALID_INDEX);
+            }
+            break;
+        }
+
+        case BTA_AG_HF_CMD_CNUM:
+            if(!(p_scb->features & BTA_AG_FEAT_ECS)) {
+                event = 0;
+                bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
+            }
+            break;
+        
+        case BTA_AG_HF_CMD_CLCC:
+            if(!(p_scb->features & BTA_AG_FEAT_ECS)) {
+                event = 0;
+                bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
+            }
+            break;
+
+#if (BTM_WBS_INCLUDED == TRUE)
+        case BTA_AG_HF_CMD_BAC:
+        {
+            bta_ag_send_ok(p_scb);
+            /* store available codecs from the peer */
+            if((p_scb->peer_features & BTA_AG_PEER_FEAT_CODEC) && (p_scb->features & BTA_AG_FEAT_CODEC)) {
+                p_scb->peer_codecs = bta_ag_parse_bac(p_scb, p_arg);
+                p_scb->codec_updated = TRUE;
+
+                if (p_scb->peer_codecs & BTA_AG_CODEC_MSBC) {
+                    p_scb->sco_codec = UUID_CODEC_MSBC;
+                    APPL_TRACE_DEBUG("Received AT+BAC, updating sco codec to MSBC");
+                } else {
+                    p_scb->sco_codec = UUID_CODEC_CVSD;
+                    APPL_TRACE_DEBUG("Received AT+BAC, updating sco codec to CVSD");
+                }
+                /* The above logic sets the stack preferred codec based on local and peer codec
+                capabilities. This can be overridden by the application depending on its preference
+                using the bta_ag_setcodec API. We send the peer_codecs to the application. */
+                val.num = p_scb->peer_codecs;
+                /* Received BAC while in codec negotiation. */
+                if ((bta_ag_cb.sco.state == BTA_AG_SCO_CODEC_ST) && (bta_ag_cb.sco.p_curr_scb == p_scb)) {
+                    bta_ag_codec_negotiate (p_scb);
+                }
+            } else {
+                p_scb->peer_codecs = BTA_AG_CODEC_NONE;
+                APPL_TRACE_ERROR("Unexpected CMD:AT+BAC, Codec Negotiation is not supported");
+            }
+            break;
+        }
+
+        case BTA_AG_HF_CMD_BCS:
+        {
+            bta_ag_send_ok(p_scb);
+            /* stop cn timer */
+            bta_sys_stop_timer(&p_scb->cn_timer);
+
+            switch(int_arg) {
+                case UUID_CODEC_CVSD:   
+                    codec_type = BTA_AG_CODEC_CVSD;     
+                    break;
+                
+                case UUID_CODEC_MSBC:   
+                    codec_type = BTA_AG_CODEC_MSBC;
+                    break;
+                
+                default:
+                    APPL_TRACE_ERROR("Unknown codec_uuid %d", int_arg);
+                    codec_type = 0xFFFF;
+                    break;
+            }
+
+            if (p_scb->codec_fallback) {
+                codec_sent = BTA_AG_CODEC_CVSD;
+            } else {
+                codec_sent = p_scb->sco_codec;
+            }
+
+            if(codec_type == codec_sent) {
+                bta_ag_sco_codec_nego(p_scb, TRUE);
+            } else {
+                bta_ag_sco_codec_nego(p_scb, FALSE);
+            }
+            /* send final codec info to callback */
+            val.num = codec_sent;
+            break;
+        }
+
+        case BTA_AG_HF_CMD_BCC:
+        {
+            bta_ag_send_ok(p_scb);
+            bta_ag_sco_open(p_scb, NULL);
+            break;
+        }
+#endif
+        default:
+            bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
+            break;
+    }
+    /* call callback */
+    if (event != 0) {
+        (*bta_ag_cb.p_cback)(event, (tBTA_AG *) &val);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         bta_ag_at_err_cback
+**
+** Description      AT command parser error callback.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_ag_at_err_cback(tBTA_AG_SCB *p_scb, BOOLEAN unknown, char *p_arg)
+{
+    tBTA_AG_VAL     val;
+
+    if(unknown && (!strlen(p_arg))) {
+        APPL_TRACE_DEBUG("Empty AT cmd string received");
+        bta_ag_send_ok(p_scb);
+        return;
+    }
+
+    /* if unknown AT command and configured to pass these to app */
+    if (unknown && (p_scb->features & BTA_AG_FEAT_UNAT)) {
+        val.hdr.handle = bta_ag_scb_to_idx(p_scb);
+        val.hdr.app_id = p_scb->app_id;
+        val.num = 0;
+        BCM_STRNCPY_S(val.str, p_arg, BTA_AG_AT_MAX_LEN);
+        val.str[BTA_AG_AT_MAX_LEN] = 0;
+        (*bta_ag_cb.p_cback)(BTA_AG_AT_UNAT_EVT, (tBTA_AG *) &val);
+    } else {
+        bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         bta_ag_hsp_result
+**
+** Description      Handle API result for HSP connections.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_ag_hsp_result(tBTA_AG_SCB *p_scb, tBTA_AG_API_RESULT *p_result)
+{
+    UINT8 code = bta_ag_trans_result[p_result->result];
+
+    APPL_TRACE_DEBUG("bta_ag_hsp_result : res = %d", p_result->result);
+
+    switch(p_result->result) {
+        case BTA_AG_SPK_RES:
+        case BTA_AG_MIC_RES:
+            bta_ag_send_result(p_scb, code, NULL, p_result->data.num);
+            break;
+
+        case BTA_AG_IN_CALL_RES:
+        {
+            /* tell sys to stop av if any */
+            bta_sys_sco_use(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
+            /* if sco already opened or no inband ring send ring now */
+            if (bta_ag_sco_is_open(p_scb) || !bta_ag_inband_enabled(p_scb) ||
+                (p_scb->features & BTA_AG_FEAT_NOSCO)) {
+                bta_ag_send_ring(p_scb, (tBTA_AG_DATA *) p_result);
+            } else {
+                /* else open sco, send ring after sco opened */
+                /* HSPv1.2: AG shall not send RING if using in-band ring tone. */
+                if (p_scb->hsp_version >= HSP_VERSION_1_2) {
+                    p_scb->post_sco = BTA_AG_POST_SCO_NONE;
+                } else {
+                    p_scb->post_sco = BTA_AG_POST_SCO_RING;
+                }
+                bta_ag_sco_open(p_scb, (tBTA_AG_DATA *) p_result);
+            }
+            break;
+        }
+
+        case BTA_AG_IN_CALL_CONN_RES:
+        case BTA_AG_OUT_CALL_ORIG_RES:
+        {
+            /* if incoming call connected stop ring timer */
+            if (p_result->result == BTA_AG_IN_CALL_CONN_RES) {
+                bta_sys_stop_timer(&p_scb->act_timer);
+            }
+
+            if (!(p_scb->features & BTA_AG_FEAT_NOSCO)) {
+                /* if audio connected to this scb open sco */
+                if (p_result->data.audio_handle == bta_ag_scb_to_idx(p_scb)) {
+                    bta_ag_sco_open(p_scb, (tBTA_AG_DATA *) p_result);
+                } else if (p_result->data.audio_handle == BTA_AG_HANDLE_NONE) {
+                    /* else if no audio at call close sco */
+                    bta_ag_sco_close(p_scb, (tBTA_AG_DATA *) p_result);
+                }
+            }
+            break;
+        }
+
+        case BTA_AG_END_CALL_RES:
+        {
+            /* stop ring timer */
+            bta_sys_stop_timer(&p_scb->act_timer);
+            /* close sco */
+            if ((bta_ag_sco_is_open(p_scb) || bta_ag_sco_is_opening(p_scb)) && !(p_scb->features & BTA_AG_FEAT_NOSCO)) {
+                bta_ag_sco_close(p_scb, (tBTA_AG_DATA *) p_result);
+            } else {
+                /* if av got suspended by this call, let it resume. */
+                bta_sys_sco_unuse(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
+            }
+            break;
+        }
+
+        case BTA_AG_INBAND_RING_RES:
+            p_scb->inband_enabled = p_result->data.state;
+            APPL_TRACE_DEBUG("inband_enabled set to %d", p_scb->inband_enabled);
+            break;
+
+        case BTA_AG_UNAT_RES:
+        {
+            if (p_result->data.ok_flag != BTA_AG_OK_ERROR) {
+                if (p_result->data.str[0] != 0) {
+                    bta_ag_send_result(p_scb, code, p_result->data.str, 0);
+                }
+                if (p_result->data.ok_flag == BTA_AG_OK_DONE) {
+                    bta_ag_send_ok(p_scb);
+                }
+            } else {
+                bta_ag_send_error(p_scb, BTA_AG_ERR_INV_CHAR_IN_TSTR);
+            }
+            break;
+        }
+        default:
+            break; /* ignore all others */
+    }
+}
+
+/*******************************************************************************
+**
+** Function         bta_ag_hfp_result
+**
+** Description      Handle API result for HFP connections.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_ag_hfp_result(tBTA_AG_SCB *p_scb, tBTA_AG_API_RESULT *p_result)
+{
+    UINT8 code = bta_ag_trans_result[p_result->result];
+
+    APPL_TRACE_DEBUG("bta_ag_hfp_result : res = %d", p_result->result);
+
+    switch(p_result->result)
+    {
+        case BTA_AG_SPK_RES:
+        case BTA_AG_MIC_RES:
+            bta_ag_send_result(p_scb, code, NULL, p_result->data.num);
+            break;
+
+        case BTA_AG_IN_CALL_RES:
+        {
+            /* tell sys to stop av if any */
+            bta_sys_sco_use(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
+            /* store caller id string.
+             * append type info at the end.
+             * make sure a valid type info is passed.
+             * otherwise add 129 as default type */
+            if ((p_result->data.num < BTA_AG_CLIP_TYPE_MIN) || (p_result->data.num > BTA_AG_CLIP_TYPE_MAX)) {
+                if (p_result->data.num != BTA_AG_CLIP_TYPE_VOIP) {
+                    p_result->data.num = BTA_AG_CLIP_TYPE_DEFAULT;
+                }
+            }
+            APPL_TRACE_DEBUG("CLIP type :%d", p_result->data.num);
+            p_scb->clip[0] = 0;
+            if (p_result->data.str[0] != 0) {
+                snprintf(p_scb->clip, sizeof(p_scb->clip), "%s,%d", p_result->data.str, p_result->data.num);
+            }
+            /* send callsetup indicator */
+            if (p_scb->post_sco == BTA_AG_POST_SCO_CALL_END) {
+                /* Need to sent 2 callsetup IND's(Call End and Incoming call) after SCO close. */
+                p_scb->post_sco = BTA_AG_POST_SCO_CALL_END_INCALL;
+            } else {
+                bta_ag_send_call_inds(p_scb, p_result->result);
+                /* if sco already opened or no inband ring send ring now */
+                if (bta_ag_sco_is_open(p_scb) || !bta_ag_inband_enabled(p_scb) ||
+                    (p_scb->features & BTA_AG_FEAT_NOSCO)) {
+                    bta_ag_send_ring(p_scb, (tBTA_AG_DATA *) p_result);
+                } else {
+                    /* else open sco, send ring after sco opened */
+                    p_scb->post_sco = BTA_AG_POST_SCO_RING;
+                    bta_ag_sco_open(p_scb, (tBTA_AG_DATA *) p_result);
+                }
+            }
+            break;
+        }
+
+        case BTA_AG_IN_CALL_CONN_RES:
+        {
+            /* stop ring timer */
+            bta_sys_stop_timer(&p_scb->act_timer);
+            /* if sco not opened and we need to open it, send indicators first
+            ** then open sco. */
+            bta_ag_send_call_inds(p_scb, p_result->result);
+
+            if (!(p_scb->features & BTA_AG_FEAT_NOSCO)) {
+                if (p_result->data.audio_handle == bta_ag_scb_to_idx(p_scb)) {
+                    bta_ag_sco_open(p_scb, (tBTA_AG_DATA *) p_result);
+                } else if ((p_result->data.audio_handle == BTA_AG_HANDLE_NONE) && bta_ag_sco_is_open(p_scb)) {
+                    bta_ag_sco_close(p_scb, (tBTA_AG_DATA *) p_result);
+                }
+            }
+            break;
+        }
+
+        case BTA_AG_IN_CALL_HELD_RES:
+            /* stop ring timer */
+            bta_sys_stop_timer(&p_scb->act_timer);
+            bta_ag_send_call_inds(p_scb, p_result->result);
+            break;
+
+        case BTA_AG_OUT_CALL_ORIG_RES:
+            bta_ag_send_call_inds(p_scb, p_result->result);
+            if (p_result->data.audio_handle == bta_ag_scb_to_idx(p_scb) && !(p_scb->features & BTA_AG_FEAT_NOSCO)) {
+                bta_ag_sco_open(p_scb, (tBTA_AG_DATA *) p_result);
+            }
+            break;
+
+        case BTA_AG_OUT_CALL_ALERT_RES:
+            /* send indicators */
+            bta_ag_send_call_inds(p_scb, p_result->result);
+            if (p_result->data.audio_handle == bta_ag_scb_to_idx(p_scb) && !(p_scb->features & BTA_AG_FEAT_NOSCO)) {
+                bta_ag_sco_open(p_scb, (tBTA_AG_DATA *) p_result);
+            }
+            break;
+
+        case BTA_AG_MULTI_CALL_RES:
+            /* open SCO at SLC for this three way call */
+            APPL_TRACE_DEBUG("Headset Connected in three way call");
+            if (!(p_scb->features & BTA_AG_FEAT_NOSCO)) {
+                if (p_result->data.audio_handle == bta_ag_scb_to_idx(p_scb)) {
+                    bta_ag_sco_open(p_scb, (tBTA_AG_DATA *) p_result);
+                } else if (p_result->data.audio_handle == BTA_AG_HANDLE_NONE) {
+                    bta_ag_sco_close(p_scb, (tBTA_AG_DATA *) p_result);
+                }
+            }
+            break;
+
+        case BTA_AG_OUT_CALL_CONN_RES:
+            /* send indicators */
+            bta_ag_send_call_inds(p_scb, p_result->result);
+            /* open or close sco */
+            if (!(p_scb->features & BTA_AG_FEAT_NOSCO)) {
+                if (p_result->data.audio_handle == bta_ag_scb_to_idx(p_scb)) {
+                    bta_ag_sco_open(p_scb, (tBTA_AG_DATA *) p_result);
+                } else if (p_result->data.audio_handle == BTA_AG_HANDLE_NONE) {
+                    bta_ag_sco_close(p_scb, (tBTA_AG_DATA *) p_result);
+                }
+            }
+            break;
+
+        case BTA_AG_CALL_CANCEL_RES:
+            /* send indicators */
+            bta_ag_send_call_inds(p_scb, p_result->result);
+            break;
+
+        case BTA_AG_END_CALL_RES:
+            /* stop ring timer */
+            bta_sys_stop_timer(&p_scb->act_timer);
+            /* if sco open, close sco then send indicator values */
+            if ((bta_ag_sco_is_open(p_scb) || bta_ag_sco_is_opening(p_scb)) && !(p_scb->features & BTA_AG_FEAT_NOSCO)) {
+                p_scb->post_sco = BTA_AG_POST_SCO_CALL_END;
+                bta_ag_sco_close(p_scb, (tBTA_AG_DATA *) p_result);
+            } else if (p_scb->post_sco == BTA_AG_POST_SCO_CALL_END_INCALL) {
+                /* sco closing for outgoing call because of incoming call */
+                /* Send only callsetup end indicator after sco close */
+                p_scb->post_sco = BTA_AG_POST_SCO_CALL_END;
+            } else {
+                bta_ag_send_call_inds(p_scb, p_result->result);
+                /* if av got suspended by this call, let it resume. */
+                bta_sys_sco_unuse(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
+            }
+            break;
+
+        case BTA_AG_INBAND_RING_RES:
+            p_scb->inband_enabled = p_result->data.state;
+            APPL_TRACE_DEBUG("inband_enabled set to %d", p_scb->inband_enabled);
+            bta_ag_send_result(p_scb, code, NULL, p_result->data.state);
+            break;
+
+        case BTA_AG_CIND_RES:
+        {
+            /* store local values */
+            p_scb->call_ind = p_result->data.str[0] - '0';
+            p_scb->callsetup_ind = p_result->data.str[2] - '0';
+            p_scb->service_ind = p_result->data.str[4] - '0';
+            p_scb->signal_ind = p_result->data.str[6] - '0';
+            p_scb->roam_ind = p_result->data.str[8] - '0';
+            p_scb->battchg_ind = p_result->data.str[10] - '0';
+            p_scb->callheld_ind = p_result->data.str[12] - '0';
+            
+            APPL_TRACE_DEBUG("cind call:%d callsetup:%d", p_scb->call_ind, p_scb->callsetup_ind);
+            bta_ag_send_result(p_scb, code, p_result->data.str, 0);
+            bta_ag_send_ok(p_scb);
+            break;
+        }
+
+        case BTA_AG_BINP_RES: // Not supported yet
+        case BTA_AG_CNUM_RES:
+        case BTA_AG_CLCC_RES:
+        case BTA_AG_COPS_RES:
+        {
+            if (p_result->data.ok_flag != BTA_AG_OK_ERROR) {
+                if (p_result->data.str[0] != 0) {
+                   bta_ag_send_result(p_scb, code, p_result->data.str, 0);
+                   bta_ag_send_ok(p_scb);
+                }
+                if (p_result->data.ok_flag == BTA_AG_OK_DONE) {
+                    bta_ag_send_ok(p_scb);
+                }
+            } else {
+                bta_ag_send_error(p_scb, p_result->data.errcode);
+            }
+            break;
+        }
+
+        case BTA_AG_UNAT_RES:
+            if (p_result->data.ok_flag != BTA_AG_OK_ERROR) {
+                if (p_result->data.str[0] != 0) {
+                    bta_ag_process_unat_res(p_result->data.str);
+                    APPL_TRACE_DEBUG("BTA_AG_RES :%s",p_result->data.str);
+                    bta_ag_send_result(p_scb, code, p_result->data.str, 0);
+                }
+
+                if (p_result->data.ok_flag == BTA_AG_OK_DONE) {
+                    bta_ag_send_ok(p_scb);
+                }
+            } else {
+                bta_ag_send_error(p_scb, p_result->data.errcode);
+            }
+            break;
+
+        case BTA_AG_CALL_WAIT_RES:
+            if (p_scb->ccwa_enabled) {
+                bta_ag_send_result(p_scb, code, p_result->data.str, 0);
+            }
+            bta_ag_send_call_inds(p_scb, p_result->result);
+            break;
+
+        case BTA_AG_IND_RES:
+            bta_ag_send_ind(p_scb, p_result->data.ind.type, p_result->data.ind.value, FALSE);
+            break;
+
+        case BTA_AG_BVRA_RES:
+            bta_ag_send_result(p_scb, code, NULL, p_result->data.state);
+            if (p_result->data.ok_flag!= BTA_AG_OK_ERROR)
+            {
+                bta_ag_send_ok(p_scb);
+            } else {
+                bta_ag_send_error(p_scb, p_result->data.errcode);
+            }
+            break;
+
+        case BTA_AG_BTRH_RES: // Not supported yet
+            if (p_result->data.ok_flag != BTA_AG_OK_ERROR) {
+                /* Don't respond to read if not in response & hold state */
+                if (p_result->data.num != BTA_AG_BTRH_NO_RESP) {
+                    bta_ag_send_result(p_scb, code, NULL, p_result->data.num);
+                }
+                /* In case of a response to a read request we need to send OK */
+                if (p_result->data.ok_flag == BTA_AG_OK_DONE) {
+                    bta_ag_send_ok(p_scb);
+                }
+            } else {
+                bta_ag_send_error(p_scb, p_result->data.errcode);
+            }
+            break;
+
+       default:
+            break;
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         bta_ag_result
+**
+** Description      Handle API result.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_ag_result(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
+{
+    if (p_scb->conn_service == BTA_AG_HSP) {
+        bta_ag_hsp_result(p_scb, &p_data->api_result);
+    } else {
+        bta_ag_hfp_result(p_scb, &p_data->api_result);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         bta_ag_send_bcs
+**
+** Description      Send +BCS AT command to peer.
+**
+** Returns          void
+**
+*******************************************************************************/
+#if (BTM_WBS_INCLUDED == TRUE )
+void bta_ag_send_bcs(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
+{
+    UINT16 codec_uuid;
+
+    if (p_scb->codec_fallback) {
+        codec_uuid = UUID_CODEC_CVSD;
+    } else {
+        switch(p_scb->sco_codec) {
+            case BTA_AG_CODEC_NONE:
+                codec_uuid = UUID_CODEC_CVSD;
+                break;
+            
+            case BTA_AG_CODEC_CVSD:
+                codec_uuid = UUID_CODEC_CVSD;
+                break;
+            
+            case BTA_AG_CODEC_MSBC:
+                codec_uuid = UUID_CODEC_MSBC;
+                break;
+            
+            default:
+                APPL_TRACE_ERROR("bta_ag_send_bcs: unknown codec %d, use CVSD", p_scb->sco_codec);
+                codec_uuid = UUID_CODEC_CVSD;
+                break;
+        }
+    }
+    /* send +BCS */
+    APPL_TRACE_DEBUG("send +BCS codec is %d", codec_uuid);
+    bta_ag_send_result(p_scb, BTA_AG_RES_BCS, NULL, codec_uuid);
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         bta_ag_send_ring
+**
+** Description      Send RING result code to peer.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_ag_send_ring(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
+{
+    UNUSED(p_data);
+
+#if defined(BTA_AG_MULTI_RESULT_INCLUDED) && (BTA_AG_MULTI_RESULT_INCLUDED == TRUE)
+    tBTA_AG_MULTI_RESULT_CB m_res_cb;
+    if (p_scb->conn_service == BTA_AG_HFP && p_scb->clip_enabled && p_scb->clip[0] != 0) {
+        memset(&m_res_cb, NULL, sizeof(tBTA_AG_MULTI_RESULT_CB));
+        m_res_cb.num_result = 2;
+        AT_SET_RES_CB(m_res_cb.res_cb[0], BTA_AG_RES_RING, NULL, 0)
+        AT_SET_RES_CB(m_res_cb.res_cb[1], BTA_AG_RES_CLIP, p_scb->clip, 0)
+        bta_ag_send_multi_result(p_scb, &m_res_cb);
+    } else {
+        /* send RING ONLY */
+        bta_ag_send_result(p_scb, BTA_AG_RES_RING, NULL, 0);
+    }
+#else
+    /* send RING */
+    bta_ag_send_result(p_scb, BTA_AG_RES_RING, NULL, 0);
+    /* if HFP and clip enabled and clip data send CLIP */
+    if (p_scb->conn_service == BTA_AG_HFP && p_scb->clip_enabled && p_scb->clip[0] != 0) {
+        bta_ag_send_result(p_scb, BTA_AG_RES_CLIP, p_scb->clip, 0);
+    }
+#endif
+    /* restart ring timer */
+    bta_sys_start_timer(&p_scb->act_timer, BTA_AG_RING_TOUT_EVT, BTA_AG_RING_TOUT);
+}
+
+#endif /* #if (BTA_AG_INCLUDED == TRUE) */

+ 1 - 1
components/bt/host/bluedroid/bta/hf_client/bta_hf_client_api.c

@@ -141,7 +141,7 @@ void BTA_HfClientRegister(tBTA_SEC sec_mask, tBTA_HF_CLIENT_FEAT features,
         p_buf->features = features;
         p_buf->sec_mask = sec_mask;
         if (p_service_name) {
-            BCM_STRNCPY_S(p_buf->name, BTA_SERVICE_NAME_LEN + 1, p_service_name, BTA_SERVICE_NAME_LEN);
+            BCM_STRNCPY_S(p_buf->name, p_service_name, BTA_SERVICE_NAME_LEN);
             p_buf->name[BTA_SERVICE_NAME_LEN] = 0;
         } else {
             p_buf->name[0] = '\0';

+ 1 - 1
components/bt/host/bluedroid/stack/avdt/avdt_api.c

@@ -1195,7 +1195,7 @@ UINT16 AVDT_SendReport(UINT8 handle, AVDT_REPORT_TYPE type,
                     len = AVDT_MAX_CNAME_SIZE;
                 }
                 *p++ = (UINT8)len;
-                BCM_STRNCPY_S((char *)p, len + 1, (char *)p_data->cname, len + 1);
+                BCM_STRNCPY_S((char *)p, (char *)p_data->cname, AVDT_MAX_CNAME_SIZE + 1);
                 p += len;
                 break;
             }

+ 1 - 2
components/bt/host/bluedroid/stack/btm/btm_ble.c

@@ -119,8 +119,7 @@ BOOLEAN BTM_SecAddBleDevice (BD_ADDR bd_addr, BD_NAME bd_name, tBT_DEVICE_TYPE d
 
     if (bd_name && bd_name[0]) {
         p_dev_rec->sec_flags |= BTM_SEC_NAME_KNOWN;
-        BCM_STRNCPY_S ((char *)p_dev_rec->sec_bd_name, sizeof (p_dev_rec->sec_bd_name),
-                       (char *)bd_name, BTM_MAX_REM_BD_NAME_LEN);
+        BCM_STRNCPY_S ((char *)p_dev_rec->sec_bd_name, (char *)bd_name, BTM_MAX_REM_BD_NAME_LEN);
     }
     p_dev_rec->device_type |= dev_type;
     p_dev_rec->ble.ble_addr_type = addr_type;

+ 1 - 2
components/bt/host/bluedroid/stack/btm/btm_dev.c

@@ -107,8 +107,7 @@ BOOLEAN BTM_SecAddDevice (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name,
 
     if (bd_name && bd_name[0]) {
         p_dev_rec->sec_flags |= BTM_SEC_NAME_KNOWN;
-        BCM_STRNCPY_S ((char *)p_dev_rec->sec_bd_name, sizeof (p_dev_rec->sec_bd_name),
-                       (char *)bd_name, BTM_MAX_REM_BD_NAME_LEN);
+        BCM_STRNCPY_S ((char *)p_dev_rec->sec_bd_name, (char *)bd_name, BTM_MAX_REM_BD_NAME_LEN);
     }
 
     p_dev_rec->num_read_pages = 0;

+ 1 - 1
components/bt/host/bluedroid/stack/btm/btm_devctl.c

@@ -457,7 +457,7 @@ tBTM_STATUS BTM_SetLocalDeviceName (char *p_name)
     /* Save the device name if local storage is enabled */
     p = (UINT8 *)btm_cb.cfg.bd_name;
     if (p != (UINT8 *)p_name) {
-        BCM_STRNCPY_S(btm_cb.cfg.bd_name, sizeof(btm_cb.cfg.bd_name), p_name, BTM_MAX_LOC_BD_NAME_LEN);
+        BCM_STRNCPY_S(btm_cb.cfg.bd_name, p_name, BTM_MAX_LOC_BD_NAME_LEN);
         btm_cb.cfg.bd_name[BTM_MAX_LOC_BD_NAME_LEN] = '\0';
     }
 #else

+ 5 - 5
components/bt/host/bluedroid/stack/btm/btm_sec.c

@@ -586,7 +586,7 @@ static BOOLEAN btm_sec_set_security_level (CONNECTION_TYPE conn_type, const char
     if (is_originator) {
         p_srec->orig_mx_chan_id = mx_chan_id;
 #if BTM_SEC_SERVICE_NAME_LEN > 0
-        BCM_STRNCPY_S ((char *)p_srec->orig_service_name, sizeof(p_srec->orig_service_name), p_name, BTM_SEC_SERVICE_NAME_LEN);
+        BCM_STRNCPY_S ((char *)p_srec->orig_service_name, p_name, BTM_SEC_SERVICE_NAME_LEN);
 #endif
         /* clear out the old setting, just in case it exists */
 #if (L2CAP_UCD_INCLUDED == TRUE)
@@ -631,7 +631,7 @@ static BOOLEAN btm_sec_set_security_level (CONNECTION_TYPE conn_type, const char
     } else {
         p_srec->term_mx_chan_id = mx_chan_id;
 #if BTM_SEC_SERVICE_NAME_LEN > 0
-        BCM_STRNCPY_S ((char *)p_srec->term_service_name, sizeof(p_srec->term_service_name), p_name, BTM_SEC_SERVICE_NAME_LEN);
+        BCM_STRNCPY_S ((char *)p_srec->term_service_name, p_name, BTM_SEC_SERVICE_NAME_LEN);
 #endif
         /* clear out the old setting, just in case it exists */
 #if (L2CAP_UCD_INCLUDED == TRUE)
@@ -3025,7 +3025,7 @@ void btm_sec_rmt_name_request_complete (UINT8 *p_bd_addr, UINT8 *p_bd_name, UINT
     if (p_dev_rec) {
         old_sec_state = p_dev_rec->sec_state;
         if (status == HCI_SUCCESS) {
-            BCM_STRNCPY_S ((char *)p_dev_rec->sec_bd_name, sizeof (p_dev_rec->sec_bd_name), (char *)p_bd_name, BTM_MAX_REM_BD_NAME_LEN);
+            BCM_STRNCPY_S ((char *)p_dev_rec->sec_bd_name, (char *)p_bd_name, BTM_MAX_REM_BD_NAME_LEN);
             p_dev_rec->sec_flags |= BTM_SEC_NAME_KNOWN;
             BTM_TRACE_EVENT ("setting BTM_SEC_NAME_KNOWN sec_flags:0x%x\n", p_dev_rec->sec_flags);
         } else {
@@ -3521,7 +3521,7 @@ void btm_proc_sp_req_evt (tBTM_SP_EVT event, UINT8 *p)
         memcpy (evt_data.cfm_req.bd_addr, p_dev_rec->bd_addr, BD_ADDR_LEN);
         memcpy (evt_data.cfm_req.dev_class, p_dev_rec->dev_class, DEV_CLASS_LEN);
 
-        BCM_STRNCPY_S ((char *)evt_data.cfm_req.bd_name, sizeof(evt_data.cfm_req.bd_name), (char *)p_dev_rec->sec_bd_name, BTM_MAX_REM_BD_NAME_LEN);
+        BCM_STRCPY_S ((char *)evt_data.cfm_req.bd_name,(char *)p_dev_rec->sec_bd_name);
 
         switch (event) {
         case BTM_SP_CFM_REQ_EVT:
@@ -3746,7 +3746,7 @@ void btm_rem_oob_req (UINT8 *p)
             btm_cb.api.p_sp_callback) {
         memcpy (evt_data.bd_addr, p_dev_rec->bd_addr, BD_ADDR_LEN);
         memcpy (evt_data.dev_class, p_dev_rec->dev_class, DEV_CLASS_LEN);
-        BCM_STRNCPY_S((char *)evt_data.bd_name, sizeof(evt_data.bd_name), (char *)p_dev_rec->sec_bd_name, BTM_MAX_REM_BD_NAME_LEN + 1);
+        BCM_STRNCPY_S((char *)evt_data.bd_name, (char *)p_dev_rec->sec_bd_name, BTM_MAX_REM_BD_NAME_LEN);
         evt_data.bd_name[BTM_MAX_REM_BD_NAME_LEN] = 0;
 
         btm_sec_change_pairing_state(BTM_PAIR_STATE_WAIT_LOCAL_OOB_RSP);

+ 1 - 1
components/bt/host/bluedroid/stack/gatt/gatt_utils.c

@@ -2325,7 +2325,7 @@ void gatt_dbg_display_uuid(tBT_UUID bt_uuid)
                 bt_uuid.uu.uuid128[3], bt_uuid.uu.uuid128[2],
                 bt_uuid.uu.uuid128[1], bt_uuid.uu.uuid128[0]);
     } else {
-        BCM_STRNCPY_S(str_buf, sizeof(str_buf), "Unknown UUID 0", 15);
+        BCM_STRNCPY_S(str_buf, "Unknown UUID 0", 15);
     }
 
     GATT_TRACE_DEBUG ("UUID=[%s]", str_buf);

+ 2 - 2
components/bt/host/bluedroid/stack/include/stack/bt_types.h

@@ -36,8 +36,8 @@ typedef bool BOOLEAN;
 #define PACKED  __packed
 // #define INLINE  __inline
 
-#define BCM_STRCPY_S(x1,x2,x3)      strcpy((x1),(x3))
-#define BCM_STRNCPY_S(x1,x2,x3,x4)  strncpy((x1),(x3),(x4))
+#define BCM_STRCPY_S(x1,x2)      strcpy((x1),(x2))
+#define BCM_STRNCPY_S(x1,x2,x3)  strncpy((x1),(x2),(x3))
 
 /* READ WELL !!
 **