From 7e10572e8bdbb03a1f3d317542685e9432c97275 Mon Sep 17 00:00:00 2001 From: liaowenhao Date: Thu, 20 Aug 2020 15:31:45 +0800 Subject: [PATCH] modify console by using console REPL environment --- .../bluedroid/classic_bt/hfp_ag/README.md | 83 ++---- .../classic_bt/hfp_ag/main/CMakeLists.txt | 1 - .../classic_bt/hfp_ag/main/app_hf_msg_set.c | 249 ++++++++++++++++- .../classic_bt/hfp_ag/main/app_hf_msg_set.h | 4 +- .../classic_bt/hfp_ag/main/console_uart.c | 108 -------- .../classic_bt/hfp_ag/main/console_uart.h | 19 -- .../bluedroid/classic_bt/hfp_ag/main/main.c | 30 +- .../bluedroid/classic_bt/hfp_hf/README.md | 103 +++---- .../classic_bt/hfp_hf/main/CMakeLists.txt | 1 - .../classic_bt/hfp_hf/main/app_hf_msg_set.c | 256 +++++++++++++++++- .../classic_bt/hfp_hf/main/app_hf_msg_set.h | 4 +- .../classic_bt/hfp_hf/main/bt_app_hf.c | 2 +- .../classic_bt/hfp_hf/main/console_uart.c | 119 -------- .../classic_bt/hfp_hf/main/console_uart.h | 19 -- .../bluedroid/classic_bt/hfp_hf/main/main.c | 27 +- 15 files changed, 596 insertions(+), 429 deletions(-) delete mode 100644 examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/console_uart.c delete mode 100644 examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/console_uart.h delete mode 100644 examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/console_uart.c delete mode 100644 examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/console_uart.h diff --git a/examples/bluetooth/bluedroid/classic_bt/hfp_ag/README.md b/examples/bluetooth/bluedroid/classic_bt/hfp_ag/README.md index d858278095..22b6404c17 100644 --- a/examples/bluetooth/bluedroid/classic_bt/hfp_ag/README.md +++ b/examples/bluetooth/bluedroid/classic_bt/hfp_ag/README.md @@ -43,47 +43,24 @@ See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/l When you flash and monitor this example, the commands help table prints the following log at the very begining: ``` -######################################################################## -HFP AG command usage manual -HFP AG commands begins with "hf" and end with ";" -Supported commands are as follows, arguments are embraced with < and > +Type 'help' to get the list of commands. +Use UP/DOWN arrows to navigate through command history. +Press TAB when typing command name to auto-complete. + + ================================================== + | Steps to test hfp_ag | + | | + | 1. Print 'help' to gain overview of commands | + | 2. Setup a service level connection | + | 3. Run hfp_ag to test | + | | + ================================================= -hf con; -- set up connection with peer device -hf dis; -- release connection with peer device -hf cona; -- set up audio connection with peer device -hf disa; -- release audio connection with peer device -hf vron; -- start voice recognition -hf vroff; -- stop voice recognition -hf vu ; -- volume update - tgt: 0-speaker, 1-microphone - vol: volume gain ranges from 0 to 15 -hf ind ; -- unsolicited indication device status to HF Client - call: call status [0,1] - callsetup: call setup status [0,3] - ntk: network status [0,1] - sig: signal strength value from 0~5 -hf ate ; -- send extended at error code - rep: response code from 0 to 7 - err: error code from 0 to 32 -hf iron; -- in-band ring tone provided -hf iroff; -- in-band ring tone not provided -hf ac; -- Answer Incoming Call from AG -hf rc; -- Reject Incoming Call from AG -hf d ; -- Dial Number by AG, e.g. hf d 11223344 -hf end; -- End a call by AG -hf h; -- to see the command for HFP AG -######################################################################## ``` -**Note:** - -- This command help table will print out in monitor whenever you type `hf h;` or if you input a command that is not required by the command parse rule. -- The command you type will not echo in monitor and your command should always start with `hf` and end with `;` or the example will not respond. -- The command you type in will not echo in monitor. - ### Service Level Connection and Disconnection -You can type `hf con;` to establish a service level connection with HF Unit device and log prints such as: +You can type `con` to establish a service level connection with HF Unit device and log prints such as: ``` W (2211) BT_APPL: new conn_srvc id:5, app_id:0 @@ -97,10 +74,9 @@ I (2331) BT_APP_HF: --connection state SLC_CONNECTED, peer feats 0xff, chld_feat **Note: Only after Hands-free Profile(HFP) service is initialized and a service level connection exists between an HF Unit and an AG device, could other commands be available.** -You can type `hf dis;` to disconnect with the connected HF Unit device, and log prints such as: +You can type `dis` to disconnect with the connected HF Unit device, and log prints such as: ``` -E (100147) CNSL: Command [hf dis;] disconnect W (77321) BT_RFCOMM: port_rfc_closed RFCOMM connection in state 2 closed: Closed (res: 19) I (77321) BT_APP_HF: APP HFP event: CONNECTION_STATE_EVT @@ -111,7 +87,7 @@ W (77381) BT_RFCOMM: RFCOMM_DisconnectInd LCID:0x41 ### Audio Connection and Disconnection -You can type `hf cona;` to establish the audio connection between HF Unit and AG device. Also, you can type `hf disa;` to close the audio data stream. +You can type `cona` to establish the audio connection between HF Unit and AG device. Also, you can type `disa` to close the audio data stream. #### Scenarios for Audio Connection @@ -138,10 +114,9 @@ Since CVSD is the default codec in HFP, we just show the scenarios using mSBC: #### Answer an Incoming Call -You can type `hf ac;` to answer an incoming call and log prints such as: +You can type `ac` to answer an incoming call and log prints such as: ``` -E (1066280) CNSL: Command [hf ac;] Answer Call from AG. W (1066280) BT_APPL: BTA_AG_SCO_CODEC_ST: Ignoring event 1 I (1067200) BT_APP_HF: APP HFP event: BCS_EVT @@ -153,10 +128,9 @@ I (1067240) BT_APP_HF: --Audio State connected #### Reject an Incoming Call -You can type `hf rc;` to reject an incoming call and log prints such as: +You can type `rc` to reject an incoming call and log prints such as: ``` -E (10040) CNSL: Command [hf rc;] Reject Call from AG. I (1067240) BT_APP_HF: APP HFP event: AUDIO_STATE_EVT I (1067240) BT_APP_HF: --Audio State disconnected @@ -164,10 +138,9 @@ I (1067240) BT_APP_HF: --Audio State disconnected #### End a Call -You can type `hf end;` to end the current ongoing call and log prints such as: +You can type `end` to end the current ongoing call and log prints such as: ``` -E (157741) CNSL: Command [hf end;] End Call from AG. W (157741) BT_APPL: BTA_AG_SCO_CLOSING_ST: Ignoring event 3 I (159311) BT_APP_HF: APP HFP event: AUDIO_STATE_EVT @@ -177,10 +150,9 @@ I (159311) BT_APP_HF: --ESP AG Audio Connection Disconnected. ### Dial Number -You can type `hf d ;` to dial `` from AG and log prints such as: +You can type `d ` to dial `` from AG and log prints such as: ``` -E (207351) CNSL: Command [hf d 123456;] Dial number 123456 I (207361) BT_APP_HF: APP HFP event: AUDIO_STATE_EVT I (207361) BT_APP_HF: --Audio State connecting @@ -193,19 +165,19 @@ I (208811) BT_APP_HF: --Audio State connected ### Volume Control -You can type `hf vu ;` to update the volume of a headset or microphone. The parameter should be set as follows: +You can type `vu ` to update the volume of a headset or microphone. The parameter should be set as follows: - `` : 0 - headset, 1 - microphone. - `` : Integer among 0 - 15. -For example, `hf vu 0 9;` updates the volume of headset and the log on the AG side prints `Volume Update`, while on the HF Unit side the log prints: +For example, `vu 0 9;` updates the volume of headset and the log on the AG side prints `Volume Update`, while on the HF Unit side the log prints: ``` E (17087) BT_HF: APP HFP event: VOLUME_CONTROL_EVT E (17087) BT_HF: --volume_target: SPEAKER, volume 9 ``` -And also, `hf vu 1 9;` updates the volume of a microphone and the log on the HF Unit side prints: +And also, `vu 1 9` updates the volume of a microphone and the log on the HF Unit side prints: ``` E (32087) BT_HF: APP HFP event: VOLUME_CONTROL_EVT @@ -214,10 +186,9 @@ E (32087) BT_HF: --volume_target: MICROPHONE, volume 9 #### Voice Recognition -You can type `hf vron;` to start the voice recognition and type `hf vroff;` to terminate this function in the AG device. Both commands will notify the HF Unit the status of voice recognition. For example, type `hf vron;` and the log will print: +You can type `vron` to start the voice recognition and type `vroff` to terminate this function in the AG device. Both commands will notify the HF Unit the status of voice recognition. For example, type `vron` and the log will print: ``` -E (244131) CNSL: Command [hf vron;] Start Voice Recognition. I (244141) BT_APP_HF: APP HFP event: AUDIO_STATE_EVT I (244141) BT_APP_HF: --Audio State connecting @@ -228,7 +199,7 @@ I (245311) BT_APP_HF: --Audio State connected #### Device Status Indication -You can type `hf ind ` to send device status of AG to HF Unit. Log on AG prints such as: `Device Indicator Changed!` and on HF Unit side prints such as: +You can type `ind ` to send device status of AG to HF Unit. Log on AG prints such as: `Device Indicator Changed!` and on HF Unit side prints such as: ``` E (293641) BT_HF: APP HFP event: CALL_IND_EVT @@ -243,12 +214,12 @@ E (293661) BT_HF: -- signal strength: 5 #### Send Extended AT Error Code -You can type `hf ate ` to send extended AT error code to HF Unit. The parameter should be set as follows: +You can type `ate ` to send extended AT error code to HF Unit. The parameter should be set as follows: - `` : integer among 0 - 7. - `` : integer among 0 - 32. -When you type `hf ate 7 7;` the log on the AG side prints `Send CME Error.` while on the HF Unit side prints: +When you type `ate 7 7;` the log on the AG side prints `Send CME Error.` while on the HF Unit side prints: ``` E (448146) BT_HF: APP HFP event: AT_RESPONSE @@ -257,7 +228,7 @@ E (448146) BT_HF: --AT response event, code 7, cme 7 #### In-Band Ring Tone Setting -You can type `hf iron;` to enable the in-band ring tone and type `hf iroff;` to disable it. The log on the AG side prints such as `Device Indicator Changed!` and on HF Unit side it prints such as: +You can type `iron` to enable the in-band ring tone and type `iroff` to disable it. The log on the AG side prints such as `Device Indicator Changed!` and on HF Unit side it prints such as: ``` E (19546) BT_HF: APP HFP event: IN-BAND_RING_TONE_EVT diff --git a/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/CMakeLists.txt b/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/CMakeLists.txt index 9ec58efb3f..40a6ff2b4e 100644 --- a/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/CMakeLists.txt +++ b/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/CMakeLists.txt @@ -2,7 +2,6 @@ idf_component_register(SRCS "app_hf_msg_prs.c" "app_hf_msg_set.c" "bt_app_core.c" "bt_app_hf.c" - "console_uart.c" "gpio_pcm_config.c" "main.c" INCLUDE_DIRS ".") diff --git a/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/app_hf_msg_set.c b/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/app_hf_msg_set.c index ee674640a1..06b2840b72 100644 --- a/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/app_hf_msg_set.c +++ b/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/app_hf_msg_set.c @@ -11,10 +11,12 @@ #include "esp_hf_ag_api.h" #include "app_hf_msg_set.h" #include "bt_app_hf.h" +#include "esp_console.h" +#include "argtable3/argtable3.h" +#include "esp_log.h" // if you want to connect a specific device, add it's bda here -// esp_bd_addr_t hf_peer_addr = {0x70,0x26,0x05,0xca,0xeb,0x21}; - +esp_bd_addr_t hf_peer_addr = {0xac, 0x67, 0xb2, 0x53, 0x79, 0xda}; void hf_msg_show_usage(void) { printf("########################################################################\n"); @@ -48,35 +50,40 @@ void hf_msg_show_usage(void) printf("########################################################################\n"); } -#define HF_CMD_HANDLER(cmd) static void hf_##cmd##_handler(int argn, char **argv) +#define HF_CMD_HANDLER(cmd) static int hf_##cmd##_handler(int argn, char **argv) HF_CMD_HANDLER(help) { hf_msg_show_usage(); + return 0; } HF_CMD_HANDLER(conn) { printf("Connect.\n"); esp_bt_hf_connect(hf_peer_addr); + return 0; } HF_CMD_HANDLER(disc) { printf("Disconnect\n"); esp_bt_hf_disconnect(hf_peer_addr); + return 0; } HF_CMD_HANDLER(conn_audio) { printf("Connect Audio\n"); esp_bt_hf_connect_audio(hf_peer_addr); + return 0; } HF_CMD_HANDLER(disc_audio) { printf("Disconnect Audio\n"); esp_bt_hf_disconnect_audio(hf_peer_addr); + return 0; } //AT+BVRA @@ -84,12 +91,14 @@ HF_CMD_HANDLER(vra_on) { printf("Start Voice Recognition.\n"); esp_bt_hf_vra(hf_peer_addr,1); + return 0; } //AT+BVRA HF_CMD_HANDLER(vra_off) { printf("Stop Voicer Recognition.\n"); esp_bt_hf_vra(hf_peer_addr,0); + return 0; } //AT+VGS or AT+VGM @@ -97,22 +106,23 @@ HF_CMD_HANDLER(volume_control) { if (argn != 3) { printf("Insufficient number of arguments"); - return; + return 1; } int target, volume; if (sscanf(argv[1], "%d", &target) != 1 || (target != ESP_HF_VOLUME_CONTROL_TARGET_SPK && target != ESP_HF_VOLUME_CONTROL_TARGET_MIC)) { printf("Invalid argument for target %s\n", argv[1]); - return; + return 1; } if (sscanf(argv[2], "%d", &volume) != 1 || (volume < 0 || volume > 15)) { printf("Invalid argument for volume %s\n", argv[2]); - return; + return 1; } printf("Volume Update\n"); esp_bt_hf_volume_control(hf_peer_addr, target, volume); + return 0; } //+CIEV @@ -120,7 +130,7 @@ HF_CMD_HANDLER(ind_change) { if (argn != 5) { printf("Insufficient number of arguments"); - return; + return 1; } int call_state, ntk_state, call_setup_state, signal; @@ -129,26 +139,27 @@ HF_CMD_HANDLER(ind_change) (call_state != ESP_HF_CALL_STATUS_NO_CALLS && call_state != ESP_HF_CALL_STATUS_CALL_IN_PROGRESS)) { printf("Invalid argument for call state %s\n", argv[1]); - return; + return 1; } if (sscanf(argv[2], "%d", &call_setup_state) != 1 || (call_setup_state < ESP_HF_CALL_SETUP_STATUS_IDLE || call_setup_state > ESP_HF_CALL_SETUP_STATUS_OUTGOING_ALERTING)) { printf("Invalid argument for callsetup state %s\n", argv[2]); - return; + return 1; } if (sscanf(argv[3], "%d", &ntk_state) != 1 || (ntk_state != ESP_HF_NETWORK_STATE_NOT_AVAILABLE && ntk_state != ESP_HF_NETWORK_STATE_AVAILABLE)) { printf("Invalid argument for netwrok state %s\n", argv[3]); - return; + return 1; } if (sscanf(argv[4], "%d", &signal) != 1 || (signal < 0 || signal > 5)) { printf("Invalid argument for signal %s\n", argv[4]); - return; + return 1; } printf("Device Indicator Changed!\n"); esp_bt_hf_indchange_notification(hf_peer_addr, call_state, call_setup_state, ntk_state, signal); + return 0; } //AT+CMEE @@ -156,24 +167,25 @@ HF_CMD_HANDLER(cme_err) { if (argn != 3) { printf("Insufficient number of arguments"); - return; + return 1; } int response_code, error_code; if (sscanf(argv[1], "%d", &response_code) != 1 || (response_code < ESP_HF_AT_RESPONSE_CODE_OK && response_code > ESP_HF_AT_RESPONSE_CODE_CME)) { printf("Invalid argument for response_code %s\n", argv[1]); - return; + return 1; } if (sscanf(argv[2], "%d", &error_code) != 1 || (error_code < ESP_HF_CME_AG_FAILURE || error_code > ESP_HF_CME_NETWORK_NOT_ALLOWED)) { printf("Invalid argument for volume %s\n", argv[2]); - return; + return 1; } printf("Send CME Error.\n"); esp_bt_hf_cmee_response(hf_peer_addr,response_code,error_code); + return 0; } //+BSIR:1 @@ -181,6 +193,7 @@ HF_CMD_HANDLER(ir_on) { printf("Enable Voicer Recognition.\n"); esp_bt_hf_bsir(hf_peer_addr,1); + return 0; } //+BSIR:0 @@ -188,6 +201,7 @@ HF_CMD_HANDLER(ir_off) { printf("Disable Voicer Recognition.\n"); esp_bt_hf_bsir(hf_peer_addr,0); + return 0; } //Answer Call from AG @@ -196,6 +210,7 @@ HF_CMD_HANDLER(ac) printf("Answer Call from AG.\n"); char *number = {"123456"}; esp_bt_hf_answer_call(hf_peer_addr,1,0,1,1,number,0); + return 0; } //Reject Call from AG @@ -204,6 +219,7 @@ HF_CMD_HANDLER(rc) printf("Reject Call from AG.\n"); char *number = {"123456"}; esp_bt_hf_reject_call(hf_peer_addr,0,0,0,0,number,0); + return 0; } //End Call from AG @@ -212,6 +228,7 @@ HF_CMD_HANDLER(end) printf("End Call from AG.\n"); char *number = {"123456"}; esp_bt_hf_end_call(hf_peer_addr,0,0,0,0,number,0); + return 0; } //Dial Call from AG @@ -223,6 +240,7 @@ HF_CMD_HANDLER(d) printf("Dial number %s\n", argv[1]); esp_bt_hf_out_call(hf_peer_addr,1,0,1,2,argv[1],0); } + return 0; } static hf_msg_hdl_t hf_cmd_tbl[] = { @@ -253,3 +271,206 @@ size_t hf_get_cmd_tbl_size(void) { return sizeof(hf_cmd_tbl) / sizeof(hf_msg_hdl_t); } + +#define HF_ORDER(name) name##_cmd +enum hf_cmd_name { + h = 0, /*show command manual*/ + con, /*set up connection with peer device*/ + dis, /*disconnection with peer device*/ + cona, /*set up audio connection with peer device*/ + disa, /*release connection with peer device*/ + vu, /*volume update*/ + ind, /*unsolicited indication device status to HF Client*/ + vron, /*start voice recognition*/ + vroff, /*stop voice recognition*/ + ate, /*send extended at error code*/ + iron, /*in-band ring tone provided*/ + iroff, /*in-band ring tone not provided*/ + ac, /*Answer Incoming Call from AG*/ + rc, /*Reject Incoming Call from AG*/ + end, /*End up a call by AG*/ + d /*Dial Number by AG, e.g. d 11223344*/ +}; +static char *hf_cmd_explain[] = { + "show command manual", + "set up connection with peer device", + "disconnection with peer device", + "set up audio connection with peer device", + "release connection with peer device", + "volume update", + "unsolicited indication device status to HF Client", + "start voice recognition", + "stop voice recognition", + "send extended at error code", + "in-band ring tone provided", + "in-band ring tone not provided", + "Answer Incoming Call from AG", + "Reject Incoming Call from AG", + "End up a call by AG", + "Dial Number by AG, e.g. d 11223344", +}; +typedef struct { + struct arg_str *tgt; + struct arg_str *vol; + struct arg_end *end; +} vu_args_t; + +typedef struct { + struct arg_str *call; + struct arg_str *ntk; + struct arg_str *callsetup; + struct arg_str *sig; + struct arg_end *end; +} ind_args_t; + +typedef struct { + struct arg_str *rep; + struct arg_str *err; + struct arg_end *end; +} ate_args_t; + +static vu_args_t vu_args; +static ind_args_t ind_args; +static ate_args_t ate_args; + +void register_hfp_ag(void) +{ + + const esp_console_cmd_t HF_ORDER(con) = { + .command = "con", + .help = hf_cmd_explain[con], + .hint = NULL, + .func = hf_cmd_tbl[con].handler, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&HF_ORDER(con))); + + const esp_console_cmd_t HF_ORDER(dis) = { + .command = "dis", + .help = hf_cmd_explain[dis], + .hint = NULL, + .func = hf_cmd_tbl[dis].handler, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&HF_ORDER(dis))); + + const esp_console_cmd_t HF_ORDER(cona) = { + .command = "cona", + .help = hf_cmd_explain[cona], + .hint = NULL, + .func = hf_cmd_tbl[cona].handler, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&HF_ORDER(cona))); + + const esp_console_cmd_t HF_ORDER(disa) = { + .command = "disa", + .help = hf_cmd_explain[disa], + .hint = NULL, + .func = hf_cmd_tbl[disa].handler, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&HF_ORDER(disa))); + + + + const esp_console_cmd_t HF_ORDER(ac) = { + .command = "ac", + .help = hf_cmd_explain[ac], + .hint = NULL, + .func = hf_cmd_tbl[ac].handler, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&HF_ORDER(ac))); + + const esp_console_cmd_t HF_ORDER(rc) = { + .command = "rc", + .help = hf_cmd_explain[rc], + .hint = NULL, + .func = hf_cmd_tbl[rc].handler, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&HF_ORDER(rc))); + + const esp_console_cmd_t HF_ORDER(d) = { + .command = "d", + .help = hf_cmd_explain[d], + .hint = "", + .func = hf_cmd_tbl[d].handler, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&HF_ORDER(d))); + + + + const esp_console_cmd_t HF_ORDER(vron) = { + .command = "vron", + .help = hf_cmd_explain[vron], + .hint = NULL, + .func = hf_cmd_tbl[vron].handler, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&HF_ORDER(vron))); + + const esp_console_cmd_t HF_ORDER(vroff) = { + .command = "vroff", + .help = hf_cmd_explain[vroff], + .hint = NULL, + .func = hf_cmd_tbl[vroff].handler, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&HF_ORDER(vroff))); + + vu_args.tgt = arg_str1(NULL, NULL, "", "\n 0-speaker\n 1-microphone"); + vu_args.vol = arg_str1(NULL, NULL, "", "volume gain ranges from 0 to 15"); + vu_args.end = arg_end(1); + const esp_console_cmd_t HF_ORDER(vu) = { + .command = "vu", + .help = hf_cmd_explain[vu], + .hint = NULL, + .func = hf_cmd_tbl[vu].handler, + .argtable = &vu_args + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&HF_ORDER(vu))); + + const esp_console_cmd_t HF_ORDER(end) = { + .command = "end", + .help = hf_cmd_explain[end], + .hint = NULL, + .func = hf_cmd_tbl[end].handler, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&HF_ORDER(end))); + + const esp_console_cmd_t HF_ORDER(iron) = { + .command = "iron", + .help = hf_cmd_explain[iron], + .hint = NULL, + .func = hf_cmd_tbl[iron].handler, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&HF_ORDER(iron))); + + const esp_console_cmd_t HF_ORDER(iroff) = { + .command = "iroff", + .help = hf_cmd_explain[iroff], + .hint = NULL, + .func = hf_cmd_tbl[iroff].handler, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&HF_ORDER(iroff))); + + ind_args.call = arg_str1(NULL, NULL, "", "call status [0,1]"); + ind_args.callsetup = arg_str1(NULL, NULL, "", "call setup status [0,3]"); + ind_args.ntk = arg_str1(NULL, NULL, "", "network status [0,1]"); + ind_args.sig = arg_str1(NULL, NULL, "", "signal strength value from 0~5"); + ind_args.end = arg_end(1); + const esp_console_cmd_t HF_ORDER(ind) = { + .command = "ind", + .help = hf_cmd_explain[ind], + .hint = NULL, + .func = hf_cmd_tbl[ind].handler, + .argtable = &ind_args + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&HF_ORDER(ind))); + + ate_args.err = arg_str1(NULL, NULL, "", "error code from 0 to 32"); + ate_args.rep = arg_str1(NULL, NULL, "", "response code from 0 to 7"); + ate_args.end = arg_end(1); + const esp_console_cmd_t HF_ORDER(ate) = { + .command = "ate", + .help = hf_cmd_explain[ate], + .hint = NULL, + .func = hf_cmd_tbl[ate].handler, + .argtable = &ate_args + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&HF_ORDER(ate))); +} \ No newline at end of file diff --git a/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/app_hf_msg_set.h b/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/app_hf_msg_set.h index de59abf832..5aa7143d1a 100644 --- a/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/app_hf_msg_set.h +++ b/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/app_hf_msg_set.h @@ -11,7 +11,7 @@ #define HF_MSG_ARGS_MAX (8) -typedef void (* hf_cmd_handler)(int argn, char **argv); +typedef int (* hf_cmd_handler)(int argn, char **argv); typedef struct { uint16_t opcode; @@ -23,4 +23,6 @@ extern hf_msg_hdl_t *hf_get_cmd_tbl(void); extern size_t hf_get_cmd_tbl_size(void); void hf_msg_show_usage(void); + +void register_hfp_ag(void); #endif /* __APP_HF_MSG_SET_H__*/ diff --git a/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/console_uart.c b/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/console_uart.c deleted file mode 100644 index 9cdcfa5637..0000000000 --- a/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/console_uart.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ - -#include "driver/uart.h" -#include "freertos/xtensa_api.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" -#include "esp_log.h" -#include "console_uart.h" -#include "app_hf_msg_prs.h" - -#define CONSOLE_UART_NUM UART_NUM_0 - -static QueueHandle_t uart_queue; -static hf_msg_prs_cb_t hf_msg_parser; - -static const uart_config_t uart_cfg = { - .baud_rate = 115200, - .data_bits = UART_DATA_8_BITS, - .parity = UART_PARITY_DISABLE, - .stop_bits = UART_STOP_BITS_1, - .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, - .rx_flow_ctrl_thresh = 127, -}; - -extern void hf_msg_args_parser(char *buf, int len); - -void hf_msg_handler(char *buf, int len) -{ - ESP_LOGE(TAG_CNSL, "Command [%s]", buf); - hf_msg_args_parser(buf, len); -} - -static void console_uart_task(void *pvParameters) -{ - int len; - uart_event_t event; - hf_msg_prs_cb_t *parser = &hf_msg_parser; - hf_msg_parser_reset_state(parser); - hf_msg_parser_register_callback(parser, hf_msg_handler); - hf_msg_show_usage(); -#define TMP_BUF_LEN 128 - uint8_t tmp_buf[TMP_BUF_LEN] = {0}; - - for (;;) { - //Waiting for UART event. - if (xQueueReceive(uart_queue, (void * )&event, (portTickType)portMAX_DELAY)) { - switch (event.type) { - //Event of UART receving data - case UART_DATA: { - len = uart_read_bytes(CONSOLE_UART_NUM, tmp_buf, TMP_BUF_LEN, 0); - for (int i = 0; i < len; i++) { - hf_msg_parse(tmp_buf[i], parser); - } - break; - } - //Event of HW FIFO overflow detected - case UART_FIFO_OVF: - ESP_LOGI(TAG_CNSL, "hw fifo overflow"); - break; - //Event of UART ring buffer full - case UART_BUFFER_FULL: - ESP_LOGI(TAG_CNSL, "ring buffer full"); - break; - //Event of UART RX break detected - case UART_BREAK: - ESP_LOGI(TAG_CNSL, "uart rx break"); - break; - //Event of UART parity check error - case UART_PARITY_ERR: - ESP_LOGI(TAG_CNSL, "uart parity error"); - break; - //Event of UART frame error - case UART_FRAME_ERR: - ESP_LOGI(TAG_CNSL, "uart frame error"); - break; - //Others - default: - break; - } - } - } - vTaskDelete(NULL); -} - - -esp_err_t console_uart_init(void) -{ - esp_err_t ret; - - ret = uart_param_config(CONSOLE_UART_NUM, &uart_cfg); - if (ret != ESP_OK) { - ESP_LOGE(TAG_CNSL, "Uart %d initialize err %04x", CONSOLE_UART_NUM, ret); - return ret; - } - - uart_set_pin(CONSOLE_UART_NUM, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); - uart_driver_install(CONSOLE_UART_NUM, 1024, 1024, 8, &uart_queue, 0); - xTaskCreate(console_uart_task, "uTask", 2048, NULL, 8, NULL); - - return ESP_OK; -} diff --git a/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/console_uart.h b/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/console_uart.h deleted file mode 100644 index 753950de94..0000000000 --- a/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/console_uart.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ - -#ifndef __CONSOLE_UART_H__ -#define __CONSOLE_UART_H__ - -#define TAG_CNSL "CNSL" - -/** - * @brief configure uart console for command input and process - */ -esp_err_t console_uart_init(void); - -#endif /* __BT_APP_HF_H__*/ diff --git a/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/main.c b/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/main.c index 0468761903..0f747e0e1a 100644 --- a/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/main.c +++ b/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/main.c @@ -24,7 +24,8 @@ #include "esp_hf_ag_api.h" #include "bt_app_hf.h" #include "gpio_pcm_config.h" -#include "console_uart.h" +#include "esp_console.h" +#include "app_hf_msg_set.h" #define BT_HF_AG_TAG "HF_AG_DEMO_MAIN" @@ -108,9 +109,6 @@ void app_main(void) /* Bluetooth device name, connection mode and profile set up */ bt_app_work_dispatch(bt_hf_hdl_stack_evt, BT_APP_EVT_STACK_UP, NULL, 0, NULL); - /* initialize console via UART */ - console_uart_init(); - /* configure the PCM interface and PINs used */ app_gpio_pcm_io_cfg(); @@ -118,4 +116,26 @@ void app_main(void) #if ACOUSTIC_ECHO_CANCELLATION_ENABLE app_gpio_aec_io_cfg(); #endif /* ACOUSTIC_ECHO_CANCELLATION_ENABLE */ -} + + esp_console_repl_t *repl = NULL; + esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT(); + esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT(); + repl_config.prompt = "hfp_ag>"; + + // init console REPL environment + ESP_ERROR_CHECK(esp_console_new_repl_uart(&uart_config, &repl_config, &repl)); + + /* Register commands */ + register_hfp_ag(); + printf("\n ==================================================\n"); + printf(" | Steps to test hfp_ag |\n"); + printf(" | |\n"); + printf(" | 1. Print 'help' to gain overview of commands |\n"); + printf(" | 2. Setup a service level connection |\n"); + printf(" | 3. Run hfp_ag to test |\n"); + printf(" | |\n"); + printf(" =================================================\n\n"); + + // start console REPL + ESP_ERROR_CHECK(esp_console_start_repl(repl)); +} \ No newline at end of file diff --git a/examples/bluetooth/bluedroid/classic_bt/hfp_hf/README.md b/examples/bluetooth/bluedroid/classic_bt/hfp_hf/README.md index 010180f525..712e229293 100644 --- a/examples/bluetooth/bluedroid/classic_bt/hfp_hf/README.md +++ b/examples/bluetooth/bluedroid/classic_bt/hfp_hf/README.md @@ -40,54 +40,29 @@ See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/l ## Example Output -When you run this example, the commands help table prints the following at the very begining: +When you run this example, the explain prints the following at the very begining: ``` -######################################################################## -HF client command usage manual -HF client commands begin with "hf" and end with ";" -Supported commands are as follows, arguments are embraced with < and > -hf con; -- setup connection with peer device -hf dis; -- release connection with peer device -hf cona; -- setup audio connection with peer device -hf disa; -- release connection with peer device -hf qop; -- query current operator name -hf qc; -- query current call status -hf ac; -- answer incoming call -hf rc; -- reject incoming call -hf d ; -- dial , e.g. hf d 11223344 -hf rd; -- redial -hf dm ; -- dial memory -hf vron; -- start voice recognition -hf vroff; -- stop voice recognition -hf vu ; -- volume update - tgt: 0-speaker, 1-microphone - vol: volume gain ranges from 0 to 15 -hf rs; -- retrieve subscriber information -hf rv; -- retrieve last voice tag number -hf rh ; -- response and hold - btrh: - 0 - put call on hold, - 1 - accept the held call, - 2 -reject the held call -hf k ; -- send dtmf code. - dtmf: single character in set 0-9, *, #, A-D -hf h; -- show command manual -######################################################################## +Type 'help' to get the list of commands. +Use UP/DOWN arrows to navigate through command history. +Press TAB when typing command name to auto-complete. + + ================================================== + | Steps to test hfp_hf | + | | + | 1. Print 'help' to gain overview of commands | + | 2. Setup a service level connection | + | 3. Run hfp_hf to test | + | | + ================================================= + ``` -**Note:** - -- This command help table will print out in monitor whenever you type `hf h;` or if you input a command that is not required by the command parse rule. -- The command you type will not echo in monitor and your command should always start with `hf` and end with `;` or the example will not responds. -- The command you typed will not echo in monitor. - ### Service Level Connection and Disconnection -You can type `hf con;` to establish a service level connection with AG device and log prints such as: +You can type `con` to establish a service level connection with AG device and log prints such as: ``` -E (78502) CNSL: Command [hf con;] connect W (79632) BT_APPL: new conn_srvc id:27, app_id:1 I (79642) BT_HF: APP HFP event: CONNECTION_STATE_EVT @@ -114,10 +89,9 @@ I (79872) BT_HF: --inband ring state Provided **Note: Only after Hands-Free Profile(HFP) service is initialized and a service level connection exists between an HF Unit and an AG device, could other commands be available.** -You can type `hf dis;` to disconnect with the connected AG device, and log prints such as: +You can type `dis` to disconnect with the connected AG device, and log prints such as: ``` -E (93382) CNSL: Command [hf dis;] disconnect W (93702) BT_RFCOMM: port_rfc_closed RFCOMM connection in state 3 closed: Closed (res: 19) W (93712) BT_APPL: BTA_HF_CLIENT_SCO_SHUTDOWN_ST: Ignoring event 3 @@ -127,10 +101,9 @@ I (93712) BT_HF: --connection state disconnected, peer feats 0x0, chld_feats 0x0 ### Audio Connection and Disconnection -You can type `hf cona;` to establish the audio connection between HF Unit and AG device. Log prints such as: +You can type `cona` to establish the audio connection between HF Unit and AG device. Log prints such as: ``` -E (117232) CNSL: Command [hf cona;] connect audio I (117232) BT_HF: APP HFP event: AUDIO_STATE_EVT I (117232) BT_HF: --audio state connecting @@ -139,10 +112,9 @@ I (117262) BT_HF: APP HFP event: AUDIO_STATE_EVT I (117262) BT_HF: --audio state connected ``` -Also, you can type `hf disa;` to close the audio data stream. Log prints such as: +Also, you can type `disa` to close the audio data stream. Log prints such as: ``` -E (133002) CNSL: Command [hf disa;] disconnect audio I (133262) BT_HF: APP HFP event: AUDIO_STATE_EVT I (133262) BT_HF: --audio state disconnected @@ -172,10 +144,9 @@ Since CVSD is the default codec in HFP, we just show the scenarios using mSBC: #### Answer an incoming call -You can type `hf ac;` to answer an incoming call and log prints such as: +You can type `ac` to answer an incoming call and log prints such as: ``` -E (196982) CNSL: Command [hf ac;] Answer call I (197102) BT_HF: APP HFP event: AT_RESPONSE I (197102) BT_HF: --AT response event, code 0, cme 0 @@ -188,10 +159,9 @@ I (197242) BT_HF: --audio state connected #### Reject an incoming call -You can type `hf rc;` to reject an incoming call and log prints such as: +You can type `rc` to reject an incoming call and log prints such as: ``` -E (210112) CNSL: Command [hf rc;] Reject call I (210822) BT_HF: APP HFP event: AT_RESPONSE I (210822) BT_HF: --AT response event, code 0, cme 0 @@ -205,14 +175,13 @@ I (210902) BT_HF: --Call indicator NO call in progress This example supports three dialing commands: -- `hf d ;` Dial the specific number. -- `hf rd;` Redial the last number. -- `hf dm ` Dial the specific indexed number in the AG memory. +- `d ` Dial the specific number. +- `rd` Redial the last number. +- `dm ` Dial the specific indexed number in the AG memory. -For example, type `hf d 186xxxx5549;` to make an outgoing call to `186xxxx5549` and log prints such as: +For example, type `d 186xxxx5549` to make an outgoing call to `186xxxx5549` and log prints such as: ``` -E (228882) CNSL: Command [hf d 186xxxx5549;] Dial number 186xxxx5549 E (229702) BT_BTM: btm_sco_connected, handle 181 I (229712) BT_HF: APP HFP event: CALL_SETUP_IND_EVT @@ -227,25 +196,25 @@ I (229732) BT_HF: --Call setup indicator NONE #### Respond and Hold -You can type `hf rh ;` to respond or hold the current call. The parameter should be set as follows: +You can type `rh ` to respond or hold the current call. The parameter should be set as follows: - `` : 0 - hold current call, 1 - answer held call, 2 - end held call. #### Volume Control -You can type `hf vu ;` to update volume gain of speaker or microphone. The parameter should be set as follows: +You can type `vu ` to update volume gain of speaker or microphone. The parameter should be set as follows: - `` : 0 - speaker, 1 - microphone. - `` : Integer among 0 - 15. -For example, type `hf vu 0 9;` to update the volume of speaker and log on AG prints: +For example, type `vu 0 9` to update the volume of speaker and log on AG prints: ``` I (43684) BT_APP_HF: APP HFP event: VOLUME_CONTROL_EVT I (43684) BT_APP_HF: --Volume Target: SPEAKER, Volume 9 ``` -And also, `hf vu 1 9;` update the volume gain of microphone and log on AG prints: +And also, `vu 1 9` update the volume gain of microphone and log on AG prints: ``` I (177254) BT_APP_HF: APP HFP event: VOLUME_CONTROL_EVT @@ -254,10 +223,9 @@ I (177254) BT_APP_HF: --Volume Target: MICROPHONE, Volume 9 #### Voice Recognition -You can type `hf vron;` to start the voice recognition of AG and type `hf vroff;` to terminate this function. For example, type `hf vron;` and log prints such as: +You can type `vron` to start the voice recognition of AG and type `vroff` to terminate this function. For example, type `vron` and log prints such as: ``` -E (292432) CNSL: Command [hf vron;] Start voice recognition I (293172) BT_HF: APP HFP event: AT_RESPONSE I (293172) BT_HF: --AT response event, code 0, cme 0 @@ -268,10 +236,9 @@ I (293702) BT_HF: --audio state connecte #### Query Current Operator Name -You can type `hf qop;` to query the current operator name and log prints like: +You can type `qop` to query the current operator name and log prints like: ``` -E (338322) CNSL: Command [hf qop;] Query operator I (339202) BT_HF: APP HFP event: CURRENT_OPERATOR_EVT I (339202) BT_HF: --operator name: 中国联通 @@ -281,10 +248,9 @@ I (339202) BT_HF: --AT response event, code 0, cme 0 #### Retrieve Subscriber Information -You can type `hf rs;` to retrieve subscriber information and log prints such as: +You can type `rs` to retrieve subscriber information and log prints such as: ``` -E (352902) CNSL: Command [hf rs;] Retrieve subscriber information I (353702) BT_HF: APP HFP event: SUBSCRIBER_INFO_EVT I (353702) BT_HF: --subscriber type unknown, number 186xxxx5549 @@ -294,10 +260,9 @@ I (353702) BT_HF: --AT response event, code 0, cme 0 #### Query Current Call Status -You can type `hf qc;` to query current call status and log prints like: +You can type `qc` to query current call status and log prints like: ``` -E (354522) CNSL: Command [hf qc;] Query current call status I (354582) BT_HF: APP HFP event: CLCC_EVT I (354582) BT_HF: --Current call: idx 1, dir incoming, state active, mpty single, number 186xxxx5549 @@ -307,7 +272,7 @@ I (354592) BT_HF: --AT response event, code 0, cme 0 #### Transport DTMF Code -You can type `hf k ;` to transport a DTMF code to AG. Log on HF unit side prints like:`send dtmf code: 9` and log on AG side prints such as: +You can type `k ` to transport a DTMF code to AG. Log on HF unit side prints like:`send dtmf code: 9` and log on AG side prints such as: ``` I (196284) BT_APP_HF: APP HFP event: DTMF_RESPONSE_EVT @@ -320,7 +285,7 @@ If you encounter any problems, please check if the following rules are followed: - You should type the command in the terminal according to the format described in the commands help table. - Not all commands in the table are supported by AG device like _Hands Free Audio Gateway (hfp_ag)_ example from ESP-IDF. -- If you want to use `hf con;` to establish a service level connection with specific AG device, you should add the MAC address of the AG device in `bt_app.c`, for example: `esp_bd_addr_t peer_addr = {0xb4, 0xe6, 0x2d, 0xeb, 0x09, 0x93};` +- If you want to use `con` to establish a service level connection with specific AG device, you should add the MAC address of the AG device in `bt_app.c`, for example: `esp_bd_addr_t peer_addr = {0xb4, 0xe6, 0x2d, 0xeb, 0x09, 0x93};` - Use `esp_hf_client_register_callback()` and `esp_hf_client_init();` before establishing a service level connection. ## Example Breakdown diff --git a/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/CMakeLists.txt b/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/CMakeLists.txt index 9ec58efb3f..40a6ff2b4e 100644 --- a/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/CMakeLists.txt +++ b/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/CMakeLists.txt @@ -2,7 +2,6 @@ idf_component_register(SRCS "app_hf_msg_prs.c" "app_hf_msg_set.c" "bt_app_core.c" "bt_app_hf.c" - "console_uart.c" "gpio_pcm_config.c" "main.c" INCLUDE_DIRS ".") diff --git a/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/app_hf_msg_set.c b/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/app_hf_msg_set.c index 5e5e80c7bf..256fbb834a 100644 --- a/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/app_hf_msg_set.c +++ b/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/app_hf_msg_set.c @@ -10,6 +10,9 @@ #include #include "esp_hf_client_api.h" #include "app_hf_msg_set.h" +#include "esp_console.h" +#include "argtable3/argtable3.h" +#include "esp_log.h" extern esp_bd_addr_t peer_addr; @@ -48,53 +51,61 @@ void hf_msg_show_usage(void) printf("########################################################################\n"); } -#define HF_CMD_HANDLER(cmd) static void hf_##cmd##_handler(int argn, char **argv) +#define HF_CMD_HANDLER(cmd) static int hf_##cmd##_handler(int argn, char **argv) HF_CMD_HANDLER(help) { hf_msg_show_usage(); + return 0; } HF_CMD_HANDLER(conn) { printf("connect\n"); esp_hf_client_connect(peer_addr); + return 0; } HF_CMD_HANDLER(disc) { printf("disconnect\n"); esp_hf_client_disconnect(peer_addr); + return 0; } HF_CMD_HANDLER(conn_audio) { printf("connect audio\n"); esp_hf_client_connect_audio(peer_addr); + return 0; } HF_CMD_HANDLER(disc_audio) { printf("disconnect audio\n"); esp_hf_client_disconnect_audio(peer_addr); + return 0; } HF_CMD_HANDLER(query_op) { printf("Query operator\n"); esp_hf_client_query_current_operator_name(); + return 0; } HF_CMD_HANDLER(answer) { printf("Answer call\n"); esp_hf_client_answer_call(); + return 0; } HF_CMD_HANDLER(reject) { printf("Reject call\n"); esp_hf_client_reject_call(); + return 0; } HF_CMD_HANDLER(dial) @@ -105,28 +116,31 @@ HF_CMD_HANDLER(dial) printf("Dial number %s\n", argv[1]); esp_hf_client_dial(argv[1]); } + return 0; } HF_CMD_HANDLER(redial) { printf("Dial number\n"); esp_hf_client_dial(NULL); + return 0; } HF_CMD_HANDLER(dial_mem) { if (argn != 2) { printf("Insufficient number of arguments"); - return; + return 1; } int index; if (sscanf(argv[1], "%d", &index) != 1) { printf("Invalid argument %s\n", argv[1]); - return; + return 1; } printf("Dial memory %d\n", index); esp_hf_client_dial_memory(index); + return 0; } @@ -134,74 +148,81 @@ HF_CMD_HANDLER(start_vr) { printf("Start voice recognition\n"); esp_hf_client_start_voice_recognition(); + return 0; } HF_CMD_HANDLER(stop_vr) { printf("Stop voice recognition\n"); esp_hf_client_stop_voice_recognition(); + return 0; } HF_CMD_HANDLER(volume_update) { if (argn != 3) { printf("Insufficient number of arguments"); - return; + return 1; } int target, volume; if (sscanf(argv[1], "%d", &target) != 1 || (target != ESP_HF_VOLUME_CONTROL_TARGET_SPK && target != ESP_HF_VOLUME_CONTROL_TARGET_MIC)) { printf("Invalid argument for target %s\n", argv[1]); - return; + return 1; } if (sscanf(argv[2], "%d", &volume) != 1 || (volume < 0 || volume > 15)) { printf("Invalid argument for volume %s\n", argv[2]); - return; + return 1; } printf("volume update\n"); esp_hf_client_volume_update(target, volume); + return 0; } HF_CMD_HANDLER(query_call) { printf("Query current call status\n"); esp_hf_client_query_current_calls(); + return 0; } HF_CMD_HANDLER(retrieve_subscriber) { printf("Retrieve subscriber information\n"); esp_hf_client_retrieve_subscriber_info(); + return 0; } HF_CMD_HANDLER(request_last_voice_tag) { printf("Request last voice tag\n"); esp_hf_client_request_last_voice_tag_number(); + return 0; } HF_CMD_HANDLER(btrh) { if (argn != 2) { printf("Insufficient number of arguments"); - return; + return 1; } int btrh; if (sscanf(argv[1], "%d", &btrh) != 1) { printf("Invalid argument %s\n", argv[1]); - return; + return 1; } if (btrh < ESP_HF_BTRH_CMD_HOLD || btrh > ESP_HF_BTRH_CMD_REJECT) { printf("Invalid argument %s\n", argv[1]); - return; + return 1; } printf("respond and hold command: %d\n", btrh); esp_hf_client_send_btrh_cmd(btrh); + return 0; } static bool is_dtmf_code(char c) @@ -222,16 +243,17 @@ HF_CMD_HANDLER(dtmf) { if (argn != 2) { printf("Insufficient number of arguments"); - return; + return 1; } if (strlen(argv[1]) != 1 || !is_dtmf_code(argv[1][0])) { printf("Invalid argument %s\n", argv[1]); - return; + return 1; } printf("send dtmf code: %s\n", argv[1]); esp_hf_client_send_dtmf(argv[1][0]); + return 0; } static hf_msg_hdl_t hf_cmd_tbl[] = { @@ -265,3 +287,215 @@ size_t hf_get_cmd_tbl_size(void) { return sizeof(hf_cmd_tbl) / sizeof(hf_msg_hdl_t); } + +#define HF_ORDER(name) name##_cmd +enum hf_cmd_name { + h = 0, /*show command manual*/ + con, /*set up connection with peer device*/ + dis, /*release connection with peer device*/ + cona, /*setup audio connection with peer device*/ + disa, /*setup audio connection with peer device*/ + qop, /*query current operator name*/ + qc, /*query current call status*/ + ac, /*answer incoming call*/ + rc, /*reject incoming call*/ + d, /*dial , e.g. d 11223344*/ + rd, /*redial*/ + dm, /*dial memory*/ + vron, /*start voice recognition*/ + vroff, /*stop voice recognition*/ + vu, /*volume update*/ + rs, /*retrieve subscriber information*/ + rv, /*retrieve last voice tag number*/ + rh, /*response and hold*/ + k /*send dtmf code*/ +}; +static char *hf_cmd_explain[] = { + "show command manual", + "set up connection with peer device", + "release connection with peer device", + "setup audio connection with peer device", + "release connection with peer device", + "query current operator name", + "query current call status", + "answer incoming call", + "reject incoming call", + "dial , e.g. d 11223344", + "redial", + "dial memory", + "start voice recognition", + "stop voice recognition", + "volume update", + "retrieve subscriber information", + "retrieve last voice tag number", + "response and hold", + "send dtmf code.\n single character in set 0-9, *, #, A-D", +}; +typedef struct { + struct arg_str *tgt; + struct arg_str *vol; + struct arg_end *end; +} vu_args_t; + +typedef struct { + struct arg_str *btrh; + struct arg_end *end; +} rh_args_t; + +static vu_args_t vu_args; +static rh_args_t rh_args; + +void register_hfp_hf(void) +{ + + const esp_console_cmd_t con_cmd = { + .command = "con", + .help = hf_cmd_explain[con], + .hint = NULL, + .func = hf_cmd_tbl[con].handler, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&con_cmd)); + + const esp_console_cmd_t dis_cmd = { + .command = "dis", + .help = hf_cmd_explain[dis], + .hint = NULL, + .func = hf_cmd_tbl[dis].handler, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&dis_cmd)); + + const esp_console_cmd_t cona_cmd = { + .command = "cona", + .help = hf_cmd_explain[cona], + .hint = NULL, + .func = hf_cmd_tbl[cona].handler, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&cona_cmd)); + + const esp_console_cmd_t disa_cmd = { + .command = "disa", + .help = hf_cmd_explain[disa], + .hint = NULL, + .func = hf_cmd_tbl[disa].handler, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&disa_cmd)); + + const esp_console_cmd_t qop_cmd = { + .command = "qop", + .help = hf_cmd_explain[qop], + .hint = NULL, + .func = hf_cmd_tbl[qop].handler, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&qop_cmd)); + + const esp_console_cmd_t qc_cmd = { + .command = "qc", + .help = hf_cmd_explain[qc], + .hint = NULL, + .func = hf_cmd_tbl[qc].handler, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&qc_cmd)); + + const esp_console_cmd_t ac_cmd = { + .command = "ac", + .help = hf_cmd_explain[ac], + .hint = NULL, + .func = hf_cmd_tbl[ac].handler, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&ac_cmd)); + + const esp_console_cmd_t rc_cmd = { + .command = "rc", + .help = hf_cmd_explain[rc], + .hint = NULL, + .func = hf_cmd_tbl[rc].handler, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&rc_cmd)); + + const esp_console_cmd_t d_cmd = { + .command = "d", + .help = hf_cmd_explain[d], + .hint = "", + .func = hf_cmd_tbl[d].handler, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&d_cmd)); + + const esp_console_cmd_t rd_cmd = { + .command = "rd", + .help = hf_cmd_explain[rd], + .hint = NULL, + .func = hf_cmd_tbl[rd].handler, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&rd_cmd)); + + const esp_console_cmd_t dm_cmd = { + .command = "dm", + .help = hf_cmd_explain[dm], + .hint = "", + .func = hf_cmd_tbl[dm].handler, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&dm_cmd)); + + const esp_console_cmd_t vron_cmd = { + .command = "vron", + .help = hf_cmd_explain[vron], + .hint = NULL, + .func = hf_cmd_tbl[vron].handler, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&vron_cmd)); + + const esp_console_cmd_t vroff_cmd = { + .command = "vroff", + .help = hf_cmd_explain[vroff], + .hint = NULL, + .func = hf_cmd_tbl[vroff].handler, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&vroff_cmd)); + + vu_args.tgt = arg_str1(NULL, NULL, "", "\n 0-speaker\n 1-microphone"); + vu_args.vol = arg_str1(NULL, NULL, "", "volume gain ranges from 0 to 15"); + vu_args.end = arg_end(1); + const esp_console_cmd_t vu_cmd = { + .command = "vu", + .help = hf_cmd_explain[vu], + .hint = NULL, + .func = hf_cmd_tbl[vu].handler, + .argtable = &vu_args + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&vu_cmd)); + + const esp_console_cmd_t rs_cmd = { + .command = "rs", + .help = hf_cmd_explain[rs], + .hint = NULL, + .func = hf_cmd_tbl[rs].handler, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&rs_cmd)); + + const esp_console_cmd_t rv_cmd = { + .command = "rv", + .help = hf_cmd_explain[rv], + .hint = NULL, + .func = hf_cmd_tbl[rv].handler, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&rv_cmd)); + + rh_args.btrh = arg_str1(NULL, NULL, "", "\n 0 - put call on hold,\n 1 - accept the held call,\n 2 -reject the held call"); + rh_args.end = arg_end(1); + const esp_console_cmd_t rh_cmd = { + .command = "rh", + .help = hf_cmd_explain[rh], + .hint = NULL, + .func = hf_cmd_tbl[rh].handler, + .argtable = &rh_args + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&rh_cmd)); + + const esp_console_cmd_t k_cmd = { + .command = "k", + .help = hf_cmd_explain[k], + .hint = "", + .func = hf_cmd_tbl[k].handler, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&k_cmd)); +} \ No newline at end of file diff --git a/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/app_hf_msg_set.h b/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/app_hf_msg_set.h index d7a438543d..5a286c28a5 100644 --- a/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/app_hf_msg_set.h +++ b/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/app_hf_msg_set.h @@ -11,7 +11,7 @@ #define HF_MSG_ARGS_MAX (5) -typedef void (* hf_cmd_handler)(int argn, char **argv); +typedef int (* hf_cmd_handler)(int argn, char **argv); typedef struct { uint16_t opcode; @@ -23,4 +23,6 @@ extern hf_msg_hdl_t *hf_get_cmd_tbl(void); extern size_t hf_get_cmd_tbl_size(void); void hf_msg_show_usage(void); + +void register_hfp_hf(void); #endif /* __APP_HF_MSG_SET_H__*/ diff --git a/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/bt_app_hf.c b/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/bt_app_hf.c index f984395ae1..8a660cb7d2 100644 --- a/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/bt_app_hf.c +++ b/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/bt_app_hf.c @@ -170,7 +170,7 @@ const char *c_inband_ring_state_str[] = { // esp_bd_addr_t peer_addr; // If you want to connect a specific device, add it's address here -esp_bd_addr_t peer_addr = {0xb4, 0xe6, 0x2d, 0xeb, 0x09, 0x93}; +esp_bd_addr_t peer_addr = {0xac, 0x67, 0xb2, 0x53, 0x77, 0xbe}; #if CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_HCI diff --git a/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/console_uart.c b/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/console_uart.c deleted file mode 100644 index ee004860ce..0000000000 --- a/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/console_uart.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ - -#include "driver/uart.h" -#include "freertos/xtensa_api.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" -#include "esp_log.h" -#include "console_uart.h" -#include "app_hf_msg_prs.h" - -#define CONSOLE_UART_NUM UART_NUM_0 - -static QueueHandle_t uart_queue; -static hf_msg_prs_cb_t hf_msg_parser; - -static const uart_config_t uart_cfg = { - .baud_rate = 115200, //1.5M - .data_bits = UART_DATA_8_BITS, - .parity = UART_PARITY_DISABLE, - .stop_bits = UART_STOP_BITS_1, - .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, - .rx_flow_ctrl_thresh = 127, -}; - -extern void hf_msg_args_parser(char *buf, int len); - -void hf_msg_handler(char *buf, int len) -{ - ESP_LOGE(TAG_CNSL, "Command [%s]", buf); - hf_msg_args_parser(buf, len); -} - -static void console_uart_task(void *pvParameters) -{ - int len; - uart_event_t event; - hf_msg_prs_cb_t *parser = &hf_msg_parser; - hf_msg_parser_reset_state(parser); - hf_msg_parser_register_callback(parser, hf_msg_handler); - hf_msg_show_usage(); -#define TMP_BUF_LEN 128 - uint8_t tmp_buf[128] = {0}; - - for (;;) { - //Waiting for UART event. - if (xQueueReceive(uart_queue, (void * )&event, (portTickType)portMAX_DELAY)) { - switch (event.type) { - //Event of UART receving data - case UART_DATA: - { - len = uart_read_bytes(CONSOLE_UART_NUM, tmp_buf, TMP_BUF_LEN, 0); - for (int i = 0; i < len; i++) { - hf_msg_parse(tmp_buf[i], parser); - } - break; - } - //Event of HW FIFO overflow detected - case UART_FIFO_OVF: - { - ESP_LOGI(TAG_CNSL, "hw fifo overflow"); - break; - } - //Event of UART ring buffer full - case UART_BUFFER_FULL: - { - ESP_LOGI(TAG_CNSL, "ring buffer full"); - break; - } - //Event of UART RX break detected - case UART_BREAK: - { - ESP_LOGI(TAG_CNSL, "uart rx break"); - break; - } - //Event of UART parity check error - case UART_PARITY_ERR: - { - ESP_LOGI(TAG_CNSL, "uart parity error"); - break; - } - //Event of UART frame error - case UART_FRAME_ERR: - { - ESP_LOGI(TAG_CNSL, "uart frame error"); - break; - } - //Others - default: - break; - } - } - } - vTaskDelete(NULL); -} - - -esp_err_t console_uart_init(void) -{ - esp_err_t ret; - - ret = uart_param_config(CONSOLE_UART_NUM, &uart_cfg); - if (ret != ESP_OK) { - ESP_LOGE(TAG_CNSL, "Uart %d initialize err %04x", CONSOLE_UART_NUM, ret); - return ret; - } - - uart_set_pin(CONSOLE_UART_NUM, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); - uart_driver_install(CONSOLE_UART_NUM, 1024, 1024, 8, &uart_queue, 0); - xTaskCreate(console_uart_task, "uTask", 2048, NULL, 8, NULL); - - return ESP_OK; -} diff --git a/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/console_uart.h b/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/console_uart.h deleted file mode 100644 index 753950de94..0000000000 --- a/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/console_uart.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ - -#ifndef __CONSOLE_UART_H__ -#define __CONSOLE_UART_H__ - -#define TAG_CNSL "CNSL" - -/** - * @brief configure uart console for command input and process - */ -esp_err_t console_uart_init(void); - -#endif /* __BT_APP_HF_H__*/ diff --git a/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/main.c b/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/main.c index 272caa6ceb..3bd579d11e 100644 --- a/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/main.c +++ b/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/main.c @@ -24,7 +24,8 @@ #include "esp_hf_client_api.h" #include "bt_app_hf.h" #include "gpio_pcm_config.h" -#include "console_uart.h" +#include "esp_console.h" +#include "app_hf_msg_set.h" /* event for handler "bt_av_hdl_stack_up */ enum { @@ -74,9 +75,6 @@ void app_main(void) /* Bluetooth device name, connection mode and profile set up */ bt_app_work_dispatch(bt_hf_client_hdl_stack_evt, BT_APP_EVT_STACK_UP, NULL, 0, NULL); - /* initialize console via UART */ - console_uart_init(); - /* configure the PCM interface and PINs used */ app_gpio_pcm_io_cfg(); @@ -84,6 +82,27 @@ void app_main(void) #if ACOUSTIC_ECHO_CANCELLATION_ENABLE app_gpio_aec_io_cfg(); #endif /* ACOUSTIC_ECHO_CANCELLATION_ENABLE */ + esp_console_repl_t *repl = NULL; + esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT(); + esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT(); + repl_config.prompt = "hfp_hf>"; + + // init console REPL environment + ESP_ERROR_CHECK(esp_console_new_repl_uart(&uart_config, &repl_config, &repl)); + + /* Register commands */ + register_hfp_hf(); + printf("\n ==================================================\n"); + printf(" | Steps to test hfp_hf |\n"); + printf(" | |\n"); + printf(" | 1. Print 'help' to gain overview of commands |\n"); + printf(" | 2. Setup a service level connection |\n"); + printf(" | 3. Run hfp_hf to test |\n"); + printf(" | |\n"); + printf(" =================================================\n\n"); + + // start console REPL + ESP_ERROR_CHECK(esp_console_start_repl(repl)); }