Skip to content

Commit 1e4c740

Browse files
lylezhu2012kartben
authored andcommitted
Bluetooth: HFP_AG: Handle DTMF code
Handle AT command `AT+VTS`. Add a callback `transmit_dtmf_code`. When a valid AT command `AT+VTS` is received, call the callback to notify the upper layer. Signed-off-by: Lyle Zhu <[email protected]>
1 parent a3a1b40 commit 1e4c740

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

include/zephyr/bluetooth/classic/hfp_ag.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,19 @@ struct bt_hfp_ag_cb {
336336
* @return 0 in case of success or negative value in case of error.
337337
*/
338338
int (*request_phone_number)(struct bt_hfp_ag *ag, char **number);
339+
340+
/** Transmit a DTMF Code callback
341+
*
342+
* If this callback is provided it will be called whenever the
343+
* AT command `AT+VTS=<code>` is received.
344+
* During an ongoing call, the HF transmits the AT+VTS command
345+
* to instruct the AG to transmit a specific DTMF code to its
346+
* network connection.
347+
*
348+
* @param ag HFP AG object.
349+
* @param code A specific DTMF code.
350+
*/
351+
void (*transmit_dtmf_code)(struct bt_hfp_ag *ag, char code);
339352
};
340353

341354
/** @brief Register HFP AG profile

subsys/bluetooth/host/classic/hfp_ag.c

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,21 @@ static int get_number(struct net_buf *buf, uint32_t *number)
809809
return err;
810810
}
811811

812+
static int get_char(struct net_buf *buf, char *c)
813+
{
814+
int err = -EINVAL;
815+
816+
skip_space(buf);
817+
if (buf->len > 0) {
818+
*c = (char)buf->data[0];
819+
(void)net_buf_pull(buf, 1);
820+
err = 0;
821+
}
822+
skip_space(buf);
823+
824+
return err;
825+
}
826+
812827
static bool is_char(struct net_buf *buf, uint8_t c)
813828
{
814829
bool found = false;
@@ -2994,6 +3009,43 @@ static int bt_hfp_ag_binp_handler(struct bt_hfp_ag *ag, struct net_buf *buf)
29943009
return -ENOTSUP;
29953010
}
29963011

3012+
static int bt_hfp_ag_vts_handler(struct bt_hfp_ag *ag, struct net_buf *buf)
3013+
{
3014+
int err;
3015+
char code;
3016+
3017+
if (!is_char(buf, '=')) {
3018+
return -ENOTSUP;
3019+
}
3020+
3021+
err = get_char(buf, &code);
3022+
if (err != 0) {
3023+
return -ENOTSUP;
3024+
}
3025+
3026+
if (!is_char(buf, '\r')) {
3027+
return -ENOTSUP;
3028+
}
3029+
3030+
if (!IS_VALID_DTMF(code)) {
3031+
LOG_ERR("Invalid code");
3032+
return -EINVAL;
3033+
}
3034+
3035+
if (!get_active_calls(ag)) {
3036+
LOG_ERR("Not valid ongoing call");
3037+
return -ENOTSUP;
3038+
}
3039+
3040+
if (bt_ag && bt_ag->transmit_dtmf_code) {
3041+
bt_ag->transmit_dtmf_code(ag, code);
3042+
} else {
3043+
return -ENOTSUP;
3044+
}
3045+
3046+
return 0;
3047+
}
3048+
29973049
static struct bt_hfp_ag_at_cmd_handler cmd_handlers[] = {
29983050
{"AT+BRSF", bt_hfp_ag_brsf_handler}, {"AT+BAC", bt_hfp_ag_bac_handler},
29993051
{"AT+CIND", bt_hfp_ag_cind_handler}, {"AT+CMER", bt_hfp_ag_cmer_handler},
@@ -3007,6 +3059,7 @@ static struct bt_hfp_ag_at_cmd_handler cmd_handlers[] = {
30073059
{"AT+VGS", bt_hfp_ag_vgs_handler}, {"AT+NREC", bt_hfp_ag_nrec_handler},
30083060
{"AT+BTRH", bt_hfp_ag_btrh_handler}, {"AT+CCWA", bt_hfp_ag_ccwa_handler},
30093061
{"AT+BVRA", bt_hfp_ag_bvra_handler}, {"AT+BINP", bt_hfp_ag_binp_handler},
3062+
{"AT+VTS", bt_hfp_ag_vts_handler},
30103063
};
30113064

30123065
static void hfp_ag_connected(struct bt_rfcomm_dlc *dlc)

0 commit comments

Comments
 (0)