Merge "Support vendor AT command and response for Hfp Client in bt stack" am: 5b2eb835ac am: 86736a84fa
am: 3eeef397f9
Change-Id: I508031c431b38012da04c97a12e0de04b367c484
diff --git a/binder/android/bluetooth/IBluetoothHeadsetClient.aidl b/binder/android/bluetooth/IBluetoothHeadsetClient.aidl
index 13495ae..6341af4 100644
--- a/binder/android/bluetooth/IBluetoothHeadsetClient.aidl
+++ b/binder/android/bluetooth/IBluetoothHeadsetClient.aidl
@@ -59,6 +59,7 @@
boolean disconnectAudio(in BluetoothDevice device);
void setAudioRouteAllowed(in BluetoothDevice device, boolean allowed);
boolean getAudioRouteAllowed(in BluetoothDevice device);
+ boolean sendVendorAtCommand(in BluetoothDevice device, int vendorId, String atCommand);
Bundle getCurrentAgFeatures(in BluetoothDevice device);
}
diff --git a/bta/hf_client/bta_hf_client_at.cc b/bta/hf_client/bta_hf_client_at.cc
index 5bcc68e..6e4fe26 100644
--- a/bta/hf_client/bta_hf_client_at.cc
+++ b/bta/hf_client/bta_hf_client_at.cc
@@ -724,9 +724,7 @@
******************************************************************************/
void bta_hf_client_cnum(tBTA_HF_CLIENT_CB* client_cb, char* number,
uint16_t service) {
- tBTA_HF_CLIENT evt;
-
- memset(&evt, 0, sizeof(evt));
+ tBTA_HF_CLIENT evt = {};
evt.cnum.service = service;
strlcpy(evt.cnum.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
@@ -736,6 +734,18 @@
bta_hf_client_app_callback(BTA_HF_CLIENT_CNUM_EVT, &evt);
}
+void bta_hf_client_unknown_response(tBTA_HF_CLIENT_CB* client_cb,
+ const char* evt_buffer) {
+ tBTA_HF_CLIENT evt = {};
+
+ strlcpy(evt.unknown.event_string, evt_buffer,
+ BTA_HF_CLIENT_UNKOWN_EVENT_LEN + 1);
+ evt.unknown.event_string[BTA_HF_CLIENT_UNKOWN_EVENT_LEN] = '\0';
+
+ evt.unknown.bd_addr = client_cb->peer_addr;
+ bta_hf_client_app_callback(BTA_HF_CLIENT_UNKNOWN_EVT, &evt);
+}
+
/*******************************************************************************
*
* Function bta_hf_client_binp
@@ -1436,6 +1446,36 @@
return buffer;
}
+static char* bta_hf_client_process_unknown(tBTA_HF_CLIENT_CB* client_cb,
+ char* buffer) {
+ char* start = strstr(buffer, "\r\n");
+ if (start == NULL) {
+ return NULL;
+ }
+ start += sizeof("\r\n") - 1;
+
+ char* end = strstr(start, "\r\n");
+ if (end == NULL) {
+ return NULL;
+ }
+
+ int evt_size = end - start + 1;
+
+ char tmp_buf[BTA_HF_CLIENT_UNKOWN_EVENT_LEN];
+ if (evt_size < BTA_HF_CLIENT_UNKOWN_EVENT_LEN) {
+ strlcpy(tmp_buf, start, evt_size);
+ bta_hf_client_unknown_response(client_cb, tmp_buf);
+ AT_CHECK_RN(end);
+ } else {
+ APPL_TRACE_ERROR("%s: exceed event buffer size. (%d, %d)", __func__,
+ evt_size, BTA_HF_CLIENT_UNKOWN_EVENT_LEN);
+ }
+
+ APPL_TRACE_DEBUG("%s: %s", __func__, buffer);
+
+ return end;
+}
+
/******************************************************************************
* SUPPORTED EVENT MESSAGES
******************************************************************************/
@@ -1461,7 +1501,7 @@
bta_hf_client_parse_cnum, bta_hf_client_parse_btrh,
bta_hf_client_parse_busy, bta_hf_client_parse_delayed,
bta_hf_client_parse_no_carrier, bta_hf_client_parse_no_answer,
- bta_hf_client_parse_blacklisted, bta_hf_client_skip_unknown};
+ bta_hf_client_parse_blacklisted, bta_hf_client_process_unknown};
/* calculate supported event list length */
static const uint16_t bta_hf_client_parser_cb_count =
@@ -1996,6 +2036,25 @@
bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BIA, buf, at_len);
}
+void bta_hf_client_send_at_vendor_specific_cmd(tBTA_HF_CLIENT_CB* client_cb,
+ const char* str) {
+ char buf[BTA_HF_CLIENT_AT_MAX_LEN];
+
+ APPL_TRACE_DEBUG("%s", __func__);
+
+ int at_len = snprintf(buf, sizeof(buf), "AT%s", str);
+
+ if (at_len < 1) {
+ APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
+ return;
+ }
+
+ buf[at_len - 1] = '\r';
+
+ bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_VENDOR_SPECIFIC, buf,
+ at_len);
+}
+
void bta_hf_client_at_init(tBTA_HF_CLIENT_CB* client_cb) {
alarm_free(client_cb->at_cb.resp_timer);
alarm_free(client_cb->at_cb.hold_timer);
@@ -2087,6 +2146,9 @@
case BTA_HF_CLIENT_AT_CMD_NREC:
bta_hf_client_send_at_nrec(client_cb);
break;
+ case BTA_HF_CLIENT_AT_CMD_VENDOR_SPECIFIC_CMD:
+ bta_hf_client_send_at_vendor_specific_cmd(client_cb, p_val->str);
+ break;
default:
APPL_TRACE_ERROR("Default case");
snprintf(buf, BTA_HF_CLIENT_AT_MAX_LEN,
diff --git a/bta/hf_client/bta_hf_client_int.h b/bta/hf_client/bta_hf_client_int.h
index 15ceec2..99967f7 100644
--- a/bta/hf_client/bta_hf_client_int.h
+++ b/bta/hf_client/bta_hf_client_int.h
@@ -97,6 +97,7 @@
BTA_HF_CLIENT_AT_CNUM,
BTA_HF_CLIENT_AT_NREC,
BTA_HF_CLIENT_AT_BINP,
+ BTA_HF_CLIENT_AT_VENDOR_SPECIFIC,
};
/*****************************************************************************
diff --git a/bta/include/bta_hf_client_api.h b/bta/include/bta_hf_client_api.h
index 69dc109..897555d 100644
--- a/bta/include/bta_hf_client_api.h
+++ b/bta/include/bta_hf_client_api.h
@@ -119,6 +119,9 @@
*/
#define BTA_HF_CLIENT_BINP_EVT 20 /* binp number event */
#define BTA_HF_CLIENT_RING_INDICATION 21 /* HF Client ring indication */
+
+#define BTA_HF_CLIENT_UNKNOWN_EVT 22 /* Unknown or vendor specific Event */
+
#define BTA_HF_CLIENT_DISABLE_EVT 30 /* HF Client disabled */
typedef uint8_t tBTA_HF_CLIENT_EVT;
@@ -159,6 +162,7 @@
#define BTA_HF_CLIENT_AT_CMD_BINP 13
#define BTA_HF_CLIENT_AT_CMD_BLDN 14
#define BTA_HF_CLIENT_AT_CMD_NREC 15
+#define BTA_HF_CLIENT_AT_CMD_VENDOR_SPECIFIC_CMD 16
typedef uint8_t tBTA_HF_CLIENT_AT_CMD_TYPE;
@@ -234,6 +238,13 @@
uint16_t value;
} tBTA_HF_CLIENT_VAL;
+/* data associated with BTA_HF_CLIENT_UNKNOWN_EVT event */
+#define BTA_HF_CLIENT_UNKOWN_EVENT_LEN 32
+typedef struct {
+ RawAddress bd_addr;
+ char event_string[BTA_HF_CLIENT_UNKOWN_EVENT_LEN + 1];
+} tBTA_HF_CLIENT_UNKNOWN;
+
/* union of data associated with AG callback */
typedef union {
// Common BD ADDR field for all tyepdefs
@@ -248,6 +259,7 @@
tBTA_HF_CLIENT_AT_RESULT result;
tBTA_HF_CLIENT_CLCC clcc;
tBTA_HF_CLIENT_CNUM cnum;
+ tBTA_HF_CLIENT_UNKNOWN unknown;
} tBTA_HF_CLIENT;
typedef uint32_t tBTA_HF_CLIENT_FEAT;
diff --git a/btif/src/btif_hf_client.cc b/btif/src/btif_hf_client.cc
index e84291d..c999885 100644
--- a/btif/src/btif_hf_client.cc
+++ b/btif/src/btif_hf_client.cc
@@ -999,6 +999,10 @@
case BTA_HF_CLIENT_RING_INDICATION:
HAL_CBACK(bt_hf_client_callbacks, ring_indication_cb, &cb->peer_bda);
break;
+ case BTA_HF_CLIENT_UNKNOWN_EVT:
+ HAL_CBACK(bt_hf_client_callbacks, unknown_event_cb, &cb->peer_bda,
+ p_data->unknown.event_string);
+ break;
default:
BTIF_TRACE_WARNING("%s: Unhandled event: %d", __func__, event);
break;
diff --git a/include/hardware/bt_hf_client.h b/include/hardware/bt_hf_client.h
index a31de0f..d8f3a50 100644
--- a/include/hardware/bt_hf_client.h
+++ b/include/hardware/bt_hf_client.h
@@ -292,6 +292,12 @@
*/
typedef void (*bthf_client_ring_indication_callback)(const RawAddress* bd_addr);
+/**
+ * Callback for sending unknown (vendor specific) event
+ */
+typedef void (*bthf_client_unknown_event_callback)(const RawAddress* bd_addr,
+ const char* unknow_event);
+
/** BT-HF callback structure. */
typedef struct {
/** set to sizeof(BtHfClientCallbacks) */
@@ -317,6 +323,7 @@
bthf_client_in_band_ring_tone_callback in_band_ring_tone_cb;
bthf_client_last_voice_tag_number_callback last_voice_tag_number_callback;
bthf_client_ring_indication_callback ring_indication_cb;
+ bthf_client_unknown_event_callback unknown_event_cb;
} bthf_client_callbacks_t;
/** Represents the standard BT-HF interface. */