summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEn-Shuo Hsu <enshuo@chromium.org>2021-02-01 21:11:44 +0800
committerCommit Bot <commit-bot@chromium.org>2021-02-03 11:33:00 +0000
commiteb926695ecca216dd716484593b636c149fb9645 (patch)
tree0e6e28da578f392c4c4be159b1298262b29ca42f
parent6db32db512a77aba7f7d1eec65c94ae7c2b630d8 (diff)
downloadadhd-eb926695ecca216dd716484593b636c149fb9645.tar.gz
cras: Support Plantronics Battery event
Support Plantronics specific battery level feature. BUG=b:160905448 TEST=test on Voyager 3200 Change-Id: I3274433c3926a5edab586c50333fc72c2dce5736 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/adhd/+/2663686 Reviewed-by: Sonny Sasaka <sonnysasaka@chromium.org> Reviewed-by: Hsinyu Chao <hychao@chromium.org> Commit-Queue: En-Shuo Hsu <enshuo@chromium.org> Tested-by: En-Shuo Hsu <enshuo@chromium.org>
-rw-r--r--cras/src/server/cras_hfp_slc.c65
-rw-r--r--cras/src/server/cras_hfp_slc.h1
2 files changed, 66 insertions, 0 deletions
diff --git a/cras/src/server/cras_hfp_slc.c b/cras/src/server/cras_hfp_slc.c
index b83b21d0..65e5e652 100644
--- a/cras/src/server/cras_hfp_slc.c
+++ b/cras/src/server/cras_hfp_slc.c
@@ -936,6 +936,70 @@ static int terminate_call(struct hfp_slc_handle *handle, const char *cmd)
return cras_telephony_event_terminate_call();
}
+/* AT+XEVENT is defined by Android to support vendor specific features.
+ * Currently, the only known supported case for CrOS is the battery event sent
+ * by some Plantronics headsets.
+ */
+static int vendor_specific_features(struct hfp_slc_handle *handle,
+ const char *cmd)
+{
+ char *tokens, *event, *level_str, *num_of_level_str;
+ int level, num_of_level;
+
+ tokens = strdup(cmd);
+ strtok(tokens, "=");
+ event = strtok(NULL, ",");
+ if (!event)
+ goto error_out;
+
+ /* AT+XEVENT=BATTERY,Level,NumberOfLevel,MinutesOfTalkTime,IsCharging
+ * Level: The charge level with a zero-based integer.
+ * NumberOfLevel: How many charging levels there are.
+ * MinuteOfTalkTime: The estimated number of talk minutes remaining.
+ * IsCharging: A 0 or 1 value.
+ *
+ * We only support the battery level and thus only care about the first
+ * 3 arguments.
+ */
+ if (!strncmp(event, "BATTERY", 7)) {
+ level_str = strtok(NULL, ",");
+ num_of_level_str = strtok(NULL, ",");
+ if (!level_str || !num_of_level_str)
+ goto error_out;
+
+ level = atoi(level_str);
+ num_of_level = atoi(num_of_level_str);
+ if (level < 0 || num_of_level <= 1 || level >= num_of_level)
+ goto error_out;
+
+ level = level * 100 / (num_of_level - 1);
+ if (handle->hf_battery != level) {
+ handle->hf_supports_battery_indicator |=
+ CRAS_HFP_BATTERY_INDICATOR_PLANTRONICS;
+ cras_server_metrics_hfp_battery_report(
+ CRAS_HFP_BATTERY_INDICATOR_PLANTRONICS);
+ handle->hf_battery = level;
+ cras_observer_notify_bt_battery_changed(
+ cras_bt_device_address(handle->device),
+ (uint32_t)(level));
+ }
+ }
+
+ free(tokens);
+ /* For Plantronic headsets, it is required to reply "OK" for the first
+ * AT+XEVENT=USER-AGENT... command to tell the headset our support of
+ * the xevent protocol. Otherwise, all following events including
+ * BATTERY won't be sent.
+ */
+ return hfp_send(handle, AT_CMD("OK"));
+
+error_out:
+ syslog(LOG_ERR, "%s: malformed vendor specific command: '%s'", __func__,
+ cmd);
+ free(tokens);
+ return hfp_send(handle, AT_CMD("ERROR"));
+}
+
/* AT commands to support in order to conform HFP specification.
*
* An initialized service level connection is the pre-condition for all
@@ -997,6 +1061,7 @@ static struct at_command at_commands[] = {
{ "AT+VG", signal_gain_setting },
{ "AT+VTS", dtmf_tone },
{ "AT+XAPL", apple_supported_features },
+ { "AT+XEVENT", vendor_specific_features },
{ 0 }
};
diff --git a/cras/src/server/cras_hfp_slc.h b/cras/src/server/cras_hfp_slc.h
index 90c1e79f..99335eab 100644
--- a/cras/src/server/cras_hfp_slc.h
+++ b/cras/src/server/cras_hfp_slc.h
@@ -62,6 +62,7 @@ struct cras_bt_device;
#define CRAS_HFP_BATTERY_INDICATOR_NONE 0x0
#define CRAS_HFP_BATTERY_INDICATOR_HFP 0x1
#define CRAS_HFP_BATTERY_INDICATOR_APPLE 0x2
+#define CRAS_HFP_BATTERY_INDICATOR_PLANTRONICS 0x4
/* Callback to call when service level connection initialized. */
typedef int (*hfp_slc_init_cb)(struct hfp_slc_handle *handle);