Bluetooth: HFP HF: SLC Connection send/parse CIND
Part of service level connection initilization. Sending AT+CIND=? and parsing its response. < ACL Data TX: Handle 256 flags 0x00 dlen 18 [hci0] 20.888273 Channel: 76 len 14 [PSM 3 mode 0] {chan 0} RFCOMM: Unnumbered Info with Header Check (UIH) (0xef) Address: 0x09 cr 0 dlci 0x02 Control: 0xef poll/final 0 Length: 10 FCS: 0x40 41 54 2b 43 49 4e 44 3d 3f 0d 40 AT+CIND=?.@ > HCI Event: Number of Completed Packets (0x13) plen 5 [hci0] 20.914998 Num handles: 1 Handle: 256 Count: 1 > HCI Event: Number of Completed Packets (0x13) plen 5 [hci0] 20.916863 Num handles: 1 Handle: 256 Count: 1 > ACL Data RX: Handle 256 flags 0x02 dlen 142 [hci0] 20.945835 Channel: 64 len 138 [PSM 3 mode 0] {chan 0} RFCOMM: Unnumbered Info with Header Check (UIH) (0xef) Address: 0x0b cr 1 dlci 0x02 Control: 0xff poll/final 1 Length: 1024 FCS: 0x86 Credits: 1 0d 0a 2b 43 49 4e 44 3a 20 28 22 63 61 6c 6c 22 ..+CIND: ("call" 2c 28 30 2c 31 29 29 2c 28 22 63 61 6c 6c 73 65 ,(0,1)),("callse 74 75 70 22 2c 28 30 2d 33 29 29 2c 28 22 73 65 tup",(0-3)),("se 72 76 69 63 65 22 2c 28 30 2d 31 29 29 2c 28 22 rvice",(0-1)),(" 73 69 67 6e 61 6c 22 2c 28 30 2d 35 29 29 2c 28 signal",(0-5)),( 22 72 6f 61 6d 22 2c 28 30 2c 31 29 29 2c 28 22 "roam",(0,1)),(" 62 61 74 74 63 68 67 22 2c 28 30 2d 35 29 29 2c battchg",(0-5)), 28 22 63 61 6c 6c 68 65 6c 64 22 2c 28 30 2d 32 ("callheld",(0-2 29 29 0d 0a 86 ))... > ACL Data RX: Handle 256 flags 0x02 dlen 14 [hci0] 20.947764 Channel: 64 len 10 [PSM 3 mode 0] {chan 0} RFCOMM: Unnumbered Info with Header Check (UIH) (0xef) Address: 0x0b cr 1 dlci 0x02 Control: 0xef poll/final 0 Length: 6 FCS: 0x9a 0d 0a 4f 4b 0d 0a 9a ..OK... Change-Id: I33126a19641b889f1749b642cbc5e63984d85b6d Signed-off-by: Sathish Narasimman <sathish.narasimman@intel.com>
This commit is contained in:
parent
39e7350a13
commit
128ef4dd99
2 changed files with 133 additions and 4 deletions
|
@ -37,6 +37,8 @@
|
|||
#define BT_DBG(fmt, ...)
|
||||
#endif
|
||||
|
||||
#define MAX_IND_STR_LEN 17
|
||||
|
||||
struct bt_hfp_hf_cb *bt_hf;
|
||||
|
||||
NET_BUF_POOL_DEFINE(hf_pool, CONFIG_BLUETOOTH_MAX_CONN + 1,
|
||||
|
@ -45,6 +47,20 @@ NET_BUF_POOL_DEFINE(hf_pool, CONFIG_BLUETOOTH_MAX_CONN + 1,
|
|||
|
||||
static struct bt_hfp_hf bt_hfp_hf_pool[CONFIG_BLUETOOTH_MAX_CONN];
|
||||
|
||||
static const struct {
|
||||
char *name;
|
||||
uint32_t min;
|
||||
uint32_t max;
|
||||
} ag_ind[] = {
|
||||
{"service", 0, 1},
|
||||
{"call", 0, 1},
|
||||
{"callsetup", 0, 3},
|
||||
{"callheld", 0, 2},
|
||||
{"signal", 0, 5},
|
||||
{"roam", 0, 1},
|
||||
{"battchg", 0, 5}
|
||||
};
|
||||
|
||||
void hf_slc_error(struct at_client *hf_at)
|
||||
{
|
||||
BT_ERR("SLC error: disconnecting");
|
||||
|
@ -121,7 +137,91 @@ int brsf_resp(struct at_client *hf_at, struct net_buf *buf)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int brsf_finish(struct at_client *hf_at, struct net_buf *buf,
|
||||
static void cind_handle_values(struct at_client *hf_at, uint32_t index,
|
||||
char *name, uint32_t min, uint32_t max)
|
||||
{
|
||||
struct bt_hfp_hf *hf = CONTAINER_OF(hf_at, struct bt_hfp_hf, at);
|
||||
int i;
|
||||
|
||||
BT_DBG("index: %u, name: %s, min: %u, max:%u", index, name, min, max);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ag_ind); i++) {
|
||||
if (strcmp(name, ag_ind[i].name) != 0) {
|
||||
continue;
|
||||
}
|
||||
if (min != ag_ind[i].min || max != ag_ind[i].max) {
|
||||
BT_ERR("%s indicator min/max value not matching", name);
|
||||
}
|
||||
|
||||
hf->ind_table[index] = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int cind_handle(struct at_client *hf_at)
|
||||
{
|
||||
uint32_t index = 0;
|
||||
|
||||
/* Parsing Example: CIND: ("call",(0,1)) etc.. */
|
||||
while (at_has_next_list(hf_at)) {
|
||||
char name[MAX_IND_STR_LEN];
|
||||
uint32_t min, max;
|
||||
|
||||
if (at_open_list(hf_at) < 0) {
|
||||
BT_ERR("Could not get open list");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (at_list_get_string(hf_at, name, sizeof(name)) < 0) {
|
||||
BT_ERR("Could not get string");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (at_open_list(hf_at) < 0) {
|
||||
BT_ERR("Could not get open list");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (at_list_get_range(hf_at, &min, &max) < 0) {
|
||||
BT_ERR("Could not get range");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (at_close_list(hf_at) < 0) {
|
||||
BT_ERR("Could not get close list");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (at_close_list(hf_at) < 0) {
|
||||
BT_ERR("Could not get close list");
|
||||
goto error;
|
||||
}
|
||||
|
||||
cind_handle_values(hf_at, index, name, min, max);
|
||||
index++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
error:
|
||||
BT_ERR("Error on CIND response");
|
||||
hf_slc_error(hf_at);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
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);
|
||||
if (err < 0) {
|
||||
BT_ERR("Error parsing CMD input");
|
||||
hf_slc_error(hf_at);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cind_finish(struct at_client *hf_at, struct net_buf *buf,
|
||||
enum at_result result)
|
||||
{
|
||||
if (result != AT_RESULT_OK) {
|
||||
|
@ -130,7 +230,29 @@ int brsf_finish(struct at_client *hf_at, struct net_buf *buf,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Continue with SLC creation */
|
||||
/* Continue SLC creation */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int brsf_finish(struct at_client *hf_at, struct net_buf *buf,
|
||||
enum at_result result)
|
||||
{
|
||||
struct bt_hfp_hf *hf = CONTAINER_OF(hf_at, struct bt_hfp_hf, at);
|
||||
int err;
|
||||
|
||||
if (result != AT_RESULT_OK) {
|
||||
BT_ERR("SLC Connection ERROR in response");
|
||||
hf_slc_error(hf_at);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = hfp_hf_send_cmd(hf, cind_resp, cind_finish, "AT+CIND=?");
|
||||
if (err < 0) {
|
||||
hf_slc_error(hf_at);
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -187,6 +309,7 @@ static int bt_hfp_hf_accept(struct bt_conn *conn, struct bt_rfcomm_dlc **dlc)
|
|||
|
||||
for (i = 0; i < ARRAY_SIZE(bt_hfp_hf_pool); i++) {
|
||||
struct bt_hfp_hf *hf = &bt_hfp_hf_pool[i];
|
||||
int j;
|
||||
|
||||
if (hf->rfcomm_dlc.session) {
|
||||
continue;
|
||||
|
@ -203,6 +326,10 @@ static int bt_hfp_hf_accept(struct bt_conn *conn, struct bt_rfcomm_dlc **dlc)
|
|||
/* Set the supported features*/
|
||||
hf->hf_features = BT_HFP_HF_SUPPORTED_FEATURES;
|
||||
|
||||
for (j = 0; j < HF_MAX_AG_INDICATORS; j++) {
|
||||
hf->ind_table[j] = -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
*/
|
||||
|
||||
#define BLUETOOTH_HFP_MAX_MTU 140
|
||||
#define BLUETOOTH_HF_CLIENT_MAX_PDU 20
|
||||
#define BLUETOOTH_HF_CLIENT_MAX_PDU BLUETOOTH_HFP_MAX_MTU
|
||||
|
||||
/* HFP AG Features */
|
||||
#define BT_HFP_AG_FEATURE_3WAY_CALL 0x00000001 /* Three-way calling */
|
||||
|
@ -51,7 +51,8 @@
|
|||
#define BT_HFP_HF_SUPPORTED_FEATURES (BT_HFP_HF_FEATURE_CLI | \
|
||||
BT_HFP_HF_FEATURE_VOLUME)
|
||||
|
||||
#define HF_MAX_BUF_LEN 20
|
||||
#define HF_MAX_BUF_LEN BLUETOOTH_HF_CLIENT_MAX_PDU
|
||||
#define HF_MAX_AG_INDICATORS 20
|
||||
|
||||
struct bt_hfp_hf {
|
||||
struct bt_rfcomm_dlc rfcomm_dlc;
|
||||
|
@ -59,4 +60,5 @@ struct bt_hfp_hf {
|
|||
struct at_client at;
|
||||
uint32_t hf_features;
|
||||
uint32_t ag_features;
|
||||
int8_t ind_table[HF_MAX_AG_INDICATORS];
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue