Bluetooth: HFP HF: Handling AG Network error
This patch includes handling AG network error i.e +CME ERROR and report the error number. Change-Id: I19a3158e44568ad0ad21fb0dd790ac2f554c0625 Signed-off-by: Sathish Narasimman <sathish.narasimman@intel.com>
This commit is contained in:
parent
1d44e345be
commit
83bb08fbd9
3 changed files with 91 additions and 9 deletions
|
@ -198,8 +198,22 @@ static int at_state_get_cmd_string(struct at_client *at, struct net_buf *buf)
|
|||
return get_response_string(at, buf, ':', AT_STATE_PROCESS_CMD);
|
||||
}
|
||||
|
||||
static bool is_cmer(struct at_client *at)
|
||||
{
|
||||
if (strncmp(at->buf, "CME ERROR", 9) == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int at_state_process_cmd(struct at_client *at, struct net_buf *buf)
|
||||
{
|
||||
if (is_cmer(at)) {
|
||||
at->state = AT_STATE_PROCESS_AG_NW_ERR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (at->resp) {
|
||||
at->resp(at, buf);
|
||||
return 0;
|
||||
|
@ -215,11 +229,16 @@ static int at_state_get_result_string(struct at_client *at, struct net_buf *buf)
|
|||
|
||||
static int at_state_process_result(struct at_client *at, struct net_buf *buf)
|
||||
{
|
||||
enum at_cme cme_err;
|
||||
enum at_result result;
|
||||
|
||||
if (at_parse_result(at->buf, buf, &result) == 0) {
|
||||
if (at->finish) {
|
||||
at->finish(at, result);
|
||||
/* cme_err is 0 - Is invalid until result is
|
||||
* AT_RESULT_CME_ERROR
|
||||
*/
|
||||
cme_err = 0;
|
||||
at->finish(at, result, cme_err);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -230,6 +249,31 @@ static int at_state_process_result(struct at_client *at, struct net_buf *buf)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int cme_handle(struct at_client *at)
|
||||
{
|
||||
enum at_cme cme_err;
|
||||
int val;
|
||||
|
||||
if (!at_get_number(at, &val) && val <= CME_ERROR_NETWORK_NOT_ALLOWED) {
|
||||
cme_err = val;
|
||||
} else {
|
||||
cme_err = CME_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
if (at->finish) {
|
||||
at->finish(at, AT_RESULT_CME_ERROR, cme_err);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int at_state_process_ag_nw_err(struct at_client *at, struct net_buf *buf)
|
||||
{
|
||||
at->cmd_state = AT_CMD_GET_VALUE;
|
||||
return at_parse_cmd_input(at, buf, NULL, cme_handle,
|
||||
AT_CMD_TYPE_NORMAL);
|
||||
}
|
||||
|
||||
static int at_state_unsolicited_cmd(struct at_client *at, struct net_buf *buf)
|
||||
{
|
||||
if (at->unsolicited) {
|
||||
|
@ -248,6 +292,7 @@ static handle_parse_input_t parser_cb[] = {
|
|||
at_state_process_cmd, /* AT_STATE_PROCESS_CMD */
|
||||
at_state_get_result_string, /* AT_STATE_GET_RESULT_STRING */
|
||||
at_state_process_result, /* AT_STATE_PROCESS_RESULT */
|
||||
at_state_process_ag_nw_err, /* AT_STATE_PROCESS_AG_NW_ERR */
|
||||
at_state_unsolicited_cmd /* AT_STATE_UNSOLICITED_CMD */
|
||||
};
|
||||
|
||||
|
|
|
@ -10,7 +10,35 @@
|
|||
|
||||
enum at_result {
|
||||
AT_RESULT_OK,
|
||||
AT_RESULT_ERROR
|
||||
AT_RESULT_ERROR,
|
||||
AT_RESULT_CME_ERROR
|
||||
};
|
||||
|
||||
enum at_cme {
|
||||
CME_ERROR_AG_FAILURE = 0,
|
||||
CME_ERROR_NO_CONNECTION_TO_PHONE = 1,
|
||||
CME_ERROR_OPERATION_NOT_ALLOWED = 3,
|
||||
CME_ERROR_OPERATION_NOT_SUPPORTED = 4,
|
||||
CME_ERROR_PH_SIM_PIN_REQUIRED = 5,
|
||||
CME_ERROR_SIM_NOT_INSERTED = 10,
|
||||
CME_ERROR_SIM_PIN_REQUIRED = 11,
|
||||
CME_ERROR_SIM_PUK_REQUIRED = 12,
|
||||
CME_ERROR_SIM_FAILURE = 13,
|
||||
CME_ERROR_SIM_BUSY = 14,
|
||||
CME_ERROR_INCORRECT_PASSWORD = 16,
|
||||
CME_ERROR_SIM_PIN2_REQUIRED = 17,
|
||||
CME_ERROR_SIM_PUK2_REQUIRED = 18,
|
||||
CME_ERROR_MEMORY_FULL = 20,
|
||||
CME_ERROR_INVALID_INDEX = 21,
|
||||
CME_ERROR_MEMORY_FAILURE = 23,
|
||||
CME_ERROR_TEXT_STRING_TOO_LONG = 24,
|
||||
CME_ERROR_INVALID_CHARS_IN_TEXT_STRING = 25,
|
||||
CME_ERROR_DIAL_STRING_TO_LONG = 26,
|
||||
CME_ERROR_INVALID_CHARS_IN_DIAL_STRING = 27,
|
||||
CME_ERROR_NO_NETWORK_SERVICE = 30,
|
||||
CME_ERROR_NETWORK_TIMEOUT = 31,
|
||||
CME_ERROR_NETWORK_NOT_ALLOWED = 32,
|
||||
CME_ERROR_UNKNOWN = 33,
|
||||
};
|
||||
|
||||
enum at_state {
|
||||
|
@ -21,6 +49,7 @@ enum at_state {
|
|||
AT_STATE_PROCESS_CMD,
|
||||
AT_STATE_GET_RESULT_STRING,
|
||||
AT_STATE_PROCESS_RESULT,
|
||||
AT_STATE_PROCESS_AG_NW_ERR,
|
||||
AT_STATE_UNSOLICITED_CMD,
|
||||
AT_STATE_END
|
||||
};
|
||||
|
@ -46,9 +75,12 @@ struct at_client;
|
|||
typedef int (*at_resp_cb_t)(struct at_client *at, struct net_buf *buf);
|
||||
|
||||
/* Callback at_finish_cb used to monitor the success or failure of the AT
|
||||
* command received from server
|
||||
* command received from server.
|
||||
* Argument 'cme_err' is valid only when argument 'result' is equal to
|
||||
* AT_RESULT_CME_ERROR
|
||||
*/
|
||||
typedef int (*at_finish_cb_t)(struct at_client *at, enum at_result result);
|
||||
typedef int (*at_finish_cb_t)(struct at_client *at, enum at_result result,
|
||||
enum at_cme cme_err);
|
||||
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,
|
||||
|
|
|
@ -352,7 +352,8 @@ int unsolicited_cb(struct at_client *hf_at, struct net_buf *buf)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
int cmee_finish(struct at_client *hf_at, enum at_result result)
|
||||
int cmee_finish(struct at_client *hf_at, enum at_result result,
|
||||
enum at_cme cme_err)
|
||||
{
|
||||
if (result != AT_RESULT_OK) {
|
||||
BT_ERR("SLC Connection ERROR in response");
|
||||
|
@ -376,7 +377,8 @@ static void slc_completed(struct at_client *hf_at)
|
|||
}
|
||||
}
|
||||
|
||||
int cmer_finish(struct at_client *hf_at, enum at_result result)
|
||||
int cmer_finish(struct at_client *hf_at, enum at_result result,
|
||||
enum at_cme cme_err)
|
||||
{
|
||||
if (result != AT_RESULT_OK) {
|
||||
BT_ERR("SLC Connection ERROR in response");
|
||||
|
@ -389,7 +391,8 @@ int cmer_finish(struct at_client *hf_at, enum at_result result)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int cind_status_finish(struct at_client *hf_at, enum at_result result)
|
||||
int cind_status_finish(struct at_client *hf_at, enum at_result result,
|
||||
enum at_cme cme_err)
|
||||
{
|
||||
struct bt_hfp_hf *hf = CONTAINER_OF(hf_at, struct bt_hfp_hf, at);
|
||||
int err;
|
||||
|
@ -410,7 +413,8 @@ int cind_status_finish(struct at_client *hf_at, enum at_result result)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int cind_finish(struct at_client *hf_at, enum at_result result)
|
||||
int cind_finish(struct at_client *hf_at, enum at_result result,
|
||||
enum at_cme cme_err)
|
||||
{
|
||||
struct bt_hfp_hf *hf = CONTAINER_OF(hf_at, struct bt_hfp_hf, at);
|
||||
int err;
|
||||
|
@ -431,7 +435,8 @@ int cind_finish(struct at_client *hf_at, enum at_result result)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int brsf_finish(struct at_client *hf_at, enum at_result result)
|
||||
int brsf_finish(struct at_client *hf_at, enum at_result result,
|
||||
enum at_cme cme_err)
|
||||
{
|
||||
struct bt_hfp_hf *hf = CONTAINER_OF(hf_at, struct bt_hfp_hf, at);
|
||||
int err;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue