diff options
author | Sathish Narasimman <sathish.narasimman@intel.com> | 2017-01-04 19:47:06 +0530 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@intel.com> | 2017-01-28 08:43:41 +0200 |
commit | d903b53e6ba12b6e89e7aabbdb0bab752a861e1d (patch) | |
tree | 92a939ab9e587e692e28c5b816784447ffa27b32 | |
parent | a45dd12f0c50a13afed8d3434f71ee00d7d2582c (diff) |
Bluetooth: AT: HFP HF: Handle unsolicited reponse
This implemnts the feature to handle the unsolicited response
received from the AG. In the hfp_hf.c file the unsolicited_cb function
process it.
Change-Id: I3ca6c8d4a1522d02f7160e2fe4ae1598cd93ce7e
Signed-off-by: Sathish Narasimman <sathish.narasimman@intel.com>
-rw-r--r-- | subsys/bluetooth/host/at.c | 35 | ||||
-rw-r--r-- | subsys/bluetooth/host/at.h | 13 | ||||
-rw-r--r-- | subsys/bluetooth/host/hfp_hf.c | 15 |
3 files changed, 49 insertions, 14 deletions
diff --git a/subsys/bluetooth/host/at.c b/subsys/bluetooth/host/at.c index 07f5aaab0..7c8a68f75 100644 --- a/subsys/bluetooth/host/at.c +++ b/subsys/bluetooth/host/at.c @@ -232,7 +232,10 @@ static int at_state_process_result(struct at_client *at, struct net_buf *buf) static int at_state_unsolicited_cmd(struct at_client *at, struct net_buf *buf) { - /* TODO return error temporarily*/ + if (at->unsolicited) { + return at->unsolicited(at, buf); + } + return -ENODATA; } @@ -266,10 +269,13 @@ int at_parse_input(struct at_client *at, struct net_buf *buf) } static int at_cmd_start(struct at_client *at, struct net_buf *buf, - const char *prefix, parse_val_t func) + const char *prefix, parse_val_t func, + enum at_cmd_type type) { if (!str_has_prefix(at->buf, prefix)) { - at->state = AT_STATE_UNSOLICITED_CMD; + if (type == AT_CMD_TYPE_NORMAL) { + at->state = AT_STATE_UNSOLICITED_CMD; + } return -ENODATA; } @@ -279,13 +285,15 @@ static int at_cmd_start(struct at_client *at, struct net_buf *buf, } static int at_cmd_get_value(struct at_client *at, struct net_buf *buf, - const char *prefix, parse_val_t func) + const char *prefix, parse_val_t func, + enum at_cmd_type type) { return get_cmd_value(at, buf, '\r', AT_CMD_PROCESS_VALUE); } static int at_cmd_process_value(struct at_client *at, struct net_buf *buf, - const char *prefix, parse_val_t func) + const char *prefix, parse_val_t func, + enum at_cmd_type type) { int ret; @@ -296,7 +304,8 @@ static int at_cmd_process_value(struct at_client *at, struct net_buf *buf, } static int at_cmd_state_end_lf(struct at_client *at, struct net_buf *buf, - const char *prefix, parse_val_t func) + const char *prefix, parse_val_t func, + enum at_cmd_type type) { int err; @@ -319,7 +328,8 @@ static handle_cmd_input_t cmd_parser_cb[] = { }; int at_parse_cmd_input(struct at_client *at, struct net_buf *buf, - const char *prefix, parse_val_t func) + const char *prefix, parse_val_t func, + enum at_cmd_type type) { int ret; @@ -328,12 +338,14 @@ int at_parse_cmd_input(struct at_client *at, struct net_buf *buf, at->cmd_state >= AT_CMD_STATE_END) { return -EINVAL; } - ret = cmd_parser_cb[at->cmd_state](at, buf, prefix, func); + ret = cmd_parser_cb[at->cmd_state](at, buf, prefix, func, type); if (ret < 0) { return ret; } /* Check for main state, the end of cmd parsing and return. */ - if (at->state == AT_STATE_START) { + if (at->state == AT_STATE_START || + (at->state == AT_STATE_UNSOLICITED_CMD && + type == AT_CMD_TYPE_UNSOLICITED)) { return 0; } } @@ -440,6 +452,11 @@ out: return 0; } +void at_register_unsolicited(struct at_client *at, at_resp_cb_t unsolicited) +{ + at->unsolicited = unsolicited; +} + void at_register(struct at_client *at, at_resp_cb_t resp, at_finish_cb_t finish) { at->resp = resp; diff --git a/subsys/bluetooth/host/at.h b/subsys/bluetooth/host/at.h index c3d0d9c27..2d62f1ebf 100644 --- a/subsys/bluetooth/host/at.h +++ b/subsys/bluetooth/host/at.h @@ -33,6 +33,11 @@ enum at_cmd_state { AT_CMD_STATE_END }; +enum at_cmd_type { + AT_CMD_TYPE_NORMAL, + AT_CMD_TYPE_UNSOLICITED +}; + struct at_client; /* Callback at_resp_cb_t used to parse response value received for the @@ -48,7 +53,8 @@ typedef int (*at_finish_cb_t)(struct at_client *at, struct net_buf *buf, typedef int (*parse_val_t)(struct at_client *at); typedef int (*handle_parse_input_t)(struct at_client *at, struct net_buf *buf); typedef int (*handle_cmd_input_t)(struct at_client *at, struct net_buf *buf, - const char *prefix, parse_val_t func); + const char *prefix, parse_val_t func, + enum at_cmd_type type); struct at_client { char *buf; @@ -57,18 +63,21 @@ struct at_client { uint8_t state; uint8_t cmd_state; at_resp_cb_t resp; + at_resp_cb_t unsolicited; at_finish_cb_t finish; }; /* Register the callback functions */ void at_register(struct at_client *at, at_resp_cb_t resp, at_finish_cb_t finish); +void at_register_unsolicited(struct at_client *at, at_resp_cb_t unsolicited); int at_get_number(struct at_client *at, uint32_t *val); /* This parsing will only works for non-fragmented net_buf */ int at_parse_input(struct at_client *at, struct net_buf *buf); /* This command parsing will only works for non-fragmented net_buf */ int at_parse_cmd_input(struct at_client *at, struct net_buf *buf, - const char *prefix, parse_val_t func); + const char *prefix, parse_val_t func, + enum at_cmd_type type); int at_check_byte(struct net_buf *buf, char check_byte); int at_list_get_range(struct at_client *at, uint32_t *min, uint32_t *max); int at_list_get_string(struct at_client *at, char *name, uint8_t len); diff --git a/subsys/bluetooth/host/hfp_hf.c b/subsys/bluetooth/host/hfp_hf.c index d2b0cbc45..8da777bcd 100644 --- a/subsys/bluetooth/host/hfp_hf.c +++ b/subsys/bluetooth/host/hfp_hf.c @@ -112,7 +112,8 @@ int brsf_resp(struct at_client *hf_at, struct net_buf *buf) BT_DBG(""); - err = at_parse_cmd_input(hf_at, buf, "BRSF", brsf_handle); + err = at_parse_cmd_input(hf_at, buf, "BRSF", brsf_handle, + AT_CMD_TYPE_NORMAL); if (err < 0) { /* Returning negative value is avoided before SLC connection * established. @@ -199,7 +200,8 @@ int cind_resp(struct at_client *hf_at, struct net_buf *buf) { int err; - err = at_parse_cmd_input(hf_at, buf, "CIND", cind_handle); + err = at_parse_cmd_input(hf_at, buf, "CIND", cind_handle, + AT_CMD_TYPE_NORMAL); if (err < 0) { BT_ERR("Error parsing CMD input"); hf_slc_error(hf_at); @@ -296,7 +298,8 @@ int cind_status_resp(struct at_client *hf_at, struct net_buf *buf) { int err; - err = at_parse_cmd_input(hf_at, buf, "CIND", cind_status_handle); + err = at_parse_cmd_input(hf_at, buf, "CIND", cind_status_handle, + AT_CMD_TYPE_NORMAL); if (err < 0) { BT_ERR("Error parsing CMD input"); hf_slc_error(hf_at); @@ -305,6 +308,11 @@ int cind_status_resp(struct at_client *hf_at, struct net_buf *buf) return 0; } +int unsolicited_cb(struct at_client *hf_at, struct net_buf *buf) +{ + return -EINVAL; +} + int cmer_finish(struct at_client *hf_at, struct net_buf *buf, enum at_result result) { @@ -329,6 +337,7 @@ int cind_status_finish(struct at_client *hf_at, struct net_buf *buf, return -EINVAL; } + at_register_unsolicited(hf_at, unsolicited_cb); err = hfp_hf_send_cmd(hf, NULL, cmer_finish, "AT+CMER=3,0,0,1"); if (err < 0) { hf_slc_error(hf_at); |