2019-12-02 07:29:55 +00:00
|
|
|
/*
|
|
|
|
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 <stdint.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include "esp_log.h"
|
|
|
|
#include "esp_bt_main.h"
|
|
|
|
#include "esp_bt_device.h"
|
|
|
|
#include "esp_gap_bt_api.h"
|
|
|
|
#include "esp_hf_ag_api.h"
|
|
|
|
#include "freertos/FreeRTOS.h"
|
|
|
|
#include "freertos/task.h"
|
|
|
|
#include "freertos/queue.h"
|
|
|
|
#include "freertos/semphr.h"
|
|
|
|
#include "time.h"
|
|
|
|
#include "sys/time.h"
|
|
|
|
#include "sdkconfig.h"
|
|
|
|
#include "bt_app_core.h"
|
|
|
|
#include "bt_app_hf.h"
|
|
|
|
|
|
|
|
const char *c_hf_evt_str[] = {
|
|
|
|
"CONNECTION_STATE_EVT", /*!< SERVICE LEVEL CONNECTION STATE CONTROL */
|
|
|
|
"AUDIO_STATE_EVT", /*!< AUDIO CONNECTION STATE CONTROL */
|
|
|
|
"VR_STATE_CHANGE_EVT", /*!< VOICE RECOGNITION CHANGE */
|
|
|
|
"VOLUME_CONTROL_EVT", /*!< AUDIO VOLUME CONTROL */
|
|
|
|
"UNKNOW_AT_CMD", /*!< UNKNOW AT COMMAND RECIEVED */
|
2019-12-04 08:41:04 +00:00
|
|
|
"IND_UPDATE", /*!< INDICATION UPDATE */
|
2019-12-02 07:29:55 +00:00
|
|
|
"CIND_RESPONSE_EVT", /*!< CALL & DEVICE INDICATION */
|
|
|
|
"COPS_RESPONSE_EVT", /*!< CURRENT OPERATOR EVENT */
|
|
|
|
"CLCC_RESPONSE_EVT", /*!< LIST OF CURRENT CALL EVENT */
|
|
|
|
"CNUM_RESPONSE_EVT", /*!< SUBSCRIBER INFORTMATION OF CALL EVENT */
|
|
|
|
"DTMF_RESPONSE_EVT", /*!< DTMF TRANSFER EVT */
|
|
|
|
"NREC_RESPONSE_EVT", /*!< NREC RESPONSE EVT */
|
|
|
|
"ANSWER_INCOMING_EVT", /*!< ANSWER INCOMING EVT */
|
|
|
|
"REJECT_INCOMING_EVT", /*!< AREJECT INCOMING EVT */
|
|
|
|
"DIAL_EVT", /*!< DIAL INCOMING EVT */
|
2019-12-02 10:17:44 +00:00
|
|
|
"WBS_EVT", /*!< CURRENT CODEC EVT */
|
2019-12-02 07:29:55 +00:00
|
|
|
"BCS_EVT", /*!< CODEC NEGO EVT */
|
|
|
|
};
|
|
|
|
|
|
|
|
//esp_hf_connection_state_t
|
|
|
|
const char *c_connection_state_str[] = {
|
|
|
|
"DISCONNECTED",
|
|
|
|
"CONNECTING",
|
|
|
|
"CONNECTED",
|
|
|
|
"SLC_CONNECTED",
|
|
|
|
"DISCONNECTING",
|
|
|
|
};
|
|
|
|
|
|
|
|
// esp_hf_audio_state_t
|
|
|
|
const char *c_audio_state_str[] = {
|
|
|
|
"disconnected",
|
|
|
|
"connecting",
|
|
|
|
"connected",
|
|
|
|
"connected_msbc",
|
|
|
|
};
|
|
|
|
|
|
|
|
/// esp_hf_vr_state_t
|
|
|
|
const char *c_vr_state_str[] = {
|
|
|
|
"Disabled",
|
|
|
|
"Enabled",
|
|
|
|
};
|
|
|
|
|
|
|
|
// esp_hf_nrec_t
|
|
|
|
const char *c_nrec_status_str[] = {
|
|
|
|
"NREC DISABLE",
|
|
|
|
"NREC ABLE",
|
|
|
|
};
|
|
|
|
|
|
|
|
// esp_hf_control_target_t
|
|
|
|
const char *c_volume_control_target_str[] = {
|
|
|
|
"SPEAKER",
|
|
|
|
"MICROPHONE",
|
|
|
|
};
|
|
|
|
|
|
|
|
// esp_hf_subscriber_service_type_t
|
|
|
|
char *c_operator_name_str[] = {
|
|
|
|
"中国移动",
|
|
|
|
"中国联通",
|
|
|
|
"中国电信",
|
|
|
|
};
|
|
|
|
|
|
|
|
// esp_hf_subscriber_service_type_t
|
|
|
|
char *c_subscriber_service_type_str[] = {
|
|
|
|
"UNKNOWN",
|
|
|
|
"VOICE",
|
|
|
|
"FAX",
|
|
|
|
};
|
|
|
|
|
|
|
|
// esp_hf_nego_codec_status_t
|
|
|
|
const char *c_codec_mode_str[] = {
|
|
|
|
"CVSD Only",
|
|
|
|
"Use CVSD",
|
|
|
|
"Use MSBC",
|
|
|
|
};
|
|
|
|
|
|
|
|
#if CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_HCI
|
|
|
|
// Produce a sine audio
|
|
|
|
static const int16_t sine_int16[] = {
|
|
|
|
0, 2057, 4107, 6140, 8149, 10126, 12062, 13952, 15786, 17557,
|
|
|
|
19260, 20886, 22431, 23886, 25247, 26509, 27666, 28714, 29648, 30466,
|
|
|
|
31163, 31738, 32187, 32509, 32702, 32767, 32702, 32509, 32187, 31738,
|
|
|
|
31163, 30466, 29648, 28714, 27666, 26509, 25247, 23886, 22431, 20886,
|
|
|
|
19260, 17557, 15786, 13952, 12062, 10126, 8149, 6140, 4107, 2057,
|
|
|
|
0, -2057, -4107, -6140, -8149, -10126, -12062, -13952, -15786, -17557,
|
|
|
|
-19260, -20886, -22431, -23886, -25247, -26509, -27666, -28714, -29648, -30466,
|
|
|
|
-31163, -31738, -32187, -32509, -32702, -32767, -32702, -32509, -32187, -31738,
|
|
|
|
-31163, -30466, -29648, -28714, -27666, -26509, -25247, -23886, -22431, -20886,
|
|
|
|
-19260, -17557, -15786, -13952, -12062, -10126, -8149, -6140, -4107, -2057,
|
|
|
|
};
|
|
|
|
|
|
|
|
#define TABLE_SIZE_CVSD 100
|
|
|
|
static uint32_t bt_app_hf_outgoing_cb(uint8_t *p_buf, uint32_t sz)
|
|
|
|
{
|
|
|
|
int sine_phase = esp_random();
|
|
|
|
|
|
|
|
for (int i = 0; i < TABLE_SIZE_CVSD; i++) {
|
|
|
|
p_buf[i * 2] = sine_int16[sine_phase];
|
|
|
|
p_buf[i * 2 + 1] = sine_int16[sine_phase];
|
|
|
|
++sine_phase;
|
|
|
|
if (sine_phase >= TABLE_SIZE_CVSD) {
|
|
|
|
sine_phase -= TABLE_SIZE_CVSD;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return sz;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void bt_app_hf_incoming_cb(const uint8_t *buf, uint32_t sz)
|
|
|
|
{
|
|
|
|
// direct to i2s
|
|
|
|
esp_hf_outgoing_data_ready();
|
|
|
|
}
|
|
|
|
#endif /* #if CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_HCI */
|
|
|
|
|
|
|
|
void bt_app_hf_cb(esp_hf_cb_event_t event, esp_hf_cb_param_t *param)
|
|
|
|
{
|
|
|
|
if (event <= ESP_HF_BCS_RESPONSE_EVT) {
|
|
|
|
ESP_LOGI(BT_HF_TAG, "APP HFP event: %s", c_hf_evt_str[event]);
|
|
|
|
} else {
|
|
|
|
ESP_LOGE(BT_HF_TAG, "APP HFP invalid event %d", event);
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (event) {
|
|
|
|
case ESP_HF_CONNECTION_STATE_EVT:
|
|
|
|
{
|
|
|
|
ESP_LOGI(BT_HF_TAG, "--connection state %s, peer feats 0x%x, chld_feats 0x%x",
|
|
|
|
c_connection_state_str[param->conn_stat.state],
|
|
|
|
param->conn_stat.peer_feat,
|
|
|
|
param->conn_stat.chld_feat);
|
|
|
|
memcpy(hf_peer_addr, param->conn_stat.remote_bda, ESP_BD_ADDR_LEN);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case ESP_HF_AUDIO_STATE_EVT:
|
|
|
|
{
|
|
|
|
ESP_LOGI(BT_HF_TAG, "--Audio State %s", c_audio_state_str[param->audio_stat.state]);
|
|
|
|
#if CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_HCI
|
2020-02-20 09:53:34 +00:00
|
|
|
if (param->audio_stat.state == ESP_HF_AUDIO_STATE_CONNECTED ||
|
|
|
|
param->audio_stat.state == ESP_HF_AUDIO_STATE_CONNECTED_MSBC)
|
|
|
|
{
|
2019-12-02 07:29:55 +00:00
|
|
|
esp_bt_hf_register_data_callback(bt_app_hf_incoming_cb, bt_app_hf_outgoing_cb);
|
|
|
|
} else if (param->audio_stat.state == ESP_HF_AUDIO_STATE_DISCONNECTED) {
|
|
|
|
ESP_LOGI(BT_HF_TAG, "--ESP AG Audio Connection Disconnected.");
|
|
|
|
}
|
|
|
|
#endif /* #if CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_HCI */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case ESP_HF_BVRA_RESPONSE_EVT:
|
|
|
|
{
|
|
|
|
ESP_LOGI(BT_HF_TAG, "--Voice Recognition is %s", c_vr_state_str[param->vra_rep.value]);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case ESP_HF_VOLUME_CONTROL_EVT:
|
|
|
|
{
|
|
|
|
ESP_LOGI(BT_HF_TAG, "--Volume Target: %s, Volume %d", c_volume_control_target_str[param->volume_control.type], param->volume_control.volume);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case ESP_HF_UNAT_RESPONSE_EVT:
|
|
|
|
{
|
|
|
|
ESP_LOGI(BT_HF_TAG, "--UNKOW AT CMD: %s", param->unat_rep.unat);
|
2020-01-20 03:32:26 +00:00
|
|
|
esp_hf_unat_response(hf_peer_addr, NULL);
|
2019-12-02 07:29:55 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case ESP_HF_IND_UPDATE_EVT:
|
|
|
|
{
|
|
|
|
ESP_LOGI(BT_HF_TAG, "--UPDATE INDCATOR!");
|
|
|
|
esp_hf_call_status_t call_state = 1;
|
|
|
|
esp_hf_call_setup_status_t call_setup_state = 2;
|
|
|
|
esp_hf_network_state_t ntk_state = 1;
|
|
|
|
int signal = 2;
|
|
|
|
esp_bt_hf_indchange_notification(hf_peer_addr,call_state,call_setup_state,ntk_state,signal);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case ESP_HF_CIND_RESPONSE_EVT:
|
|
|
|
{
|
|
|
|
ESP_LOGI(BT_HF_TAG, "--CIND Start.");
|
|
|
|
esp_hf_call_status_t call_status = 0;
|
|
|
|
esp_hf_call_setup_status_t call_setup_status = 0;
|
|
|
|
esp_hf_network_state_t ntk_state = 1;
|
|
|
|
int signal = 4;
|
|
|
|
esp_hf_roaming_status_t roam = 0;
|
|
|
|
int batt_lev = 3;
|
|
|
|
esp_hf_call_held_status_t call_held_status = 0;
|
|
|
|
esp_bt_hf_cind_response(hf_peer_addr,call_status,call_setup_status,ntk_state,signal,roam,batt_lev,call_held_status);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case ESP_HF_COPS_RESPONSE_EVT:
|
|
|
|
{
|
|
|
|
const int svc_type = 1;
|
|
|
|
esp_bt_hf_cops_response(hf_peer_addr, c_operator_name_str[svc_type]);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case ESP_HF_CLCC_RESPONSE_EVT:
|
|
|
|
{
|
|
|
|
int index = 1;
|
|
|
|
//mandatory
|
|
|
|
esp_hf_current_call_direction_t dir = 1;
|
|
|
|
esp_hf_current_call_status_t current_call_status = 0;
|
|
|
|
esp_hf_current_call_mode_t mode = 0;
|
|
|
|
esp_hf_current_call_mpty_type_t mpty = 0;
|
|
|
|
//option
|
2019-12-02 10:17:44 +00:00
|
|
|
char *number = {"123456"};
|
2019-12-02 07:29:55 +00:00
|
|
|
esp_hf_call_addr_type_t type = ESP_HF_CALL_ADDR_TYPE_UNKNOWN;
|
|
|
|
|
|
|
|
ESP_LOGI(BT_HF_TAG, "--Calling Line Identification.");
|
|
|
|
esp_bt_hf_clcc_response(hf_peer_addr, index, dir, current_call_status, mode, mpty, number, type);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case ESP_HF_CNUM_RESPONSE_EVT:
|
|
|
|
{
|
2019-12-02 10:17:44 +00:00
|
|
|
char *number = {"123456"};
|
2019-12-02 07:29:55 +00:00
|
|
|
esp_hf_subscriber_service_type_t type = 1;
|
|
|
|
ESP_LOGI(BT_HF_TAG, "--Current Number is %s ,Type is %s.", number, c_subscriber_service_type_str[type]);
|
|
|
|
esp_bt_hf_cnum_response(hf_peer_addr, number,type);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case ESP_HF_VTS_RESPONSE_EVT:
|
|
|
|
{
|
|
|
|
ESP_LOGI(BT_HF_TAG, "--DTMF code is: %s.", param->vts_rep.code);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case ESP_HF_NREC_RESPONSE_EVT:
|
|
|
|
{
|
|
|
|
ESP_LOGI(BT_HF_TAG, "--NREC status is: %s.", c_nrec_status_str[param->nrec.state]);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case ESP_HF_ATA_RESPONSE_EVT:
|
|
|
|
{
|
|
|
|
ESP_LOGI(BT_HF_TAG, "--Asnwer Incoming Call.");
|
2019-12-04 07:37:31 +00:00
|
|
|
char *number = {"123456"};
|
2019-12-02 07:29:55 +00:00
|
|
|
esp_bt_hf_answer_call(hf_peer_addr,1,0,1,0,number,0);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case ESP_HF_CHUP_RESPONSE_EVT:
|
|
|
|
{
|
|
|
|
ESP_LOGI(BT_HF_TAG, "--Reject Incoming Call.");
|
2019-12-04 07:37:31 +00:00
|
|
|
char *number = {"123456"};
|
2019-12-02 07:29:55 +00:00
|
|
|
esp_bt_hf_reject_call(hf_peer_addr,0,0,0,0,number,0);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case ESP_HF_DIAL_EVT:
|
|
|
|
{
|
|
|
|
if (param->out_call.num_or_loc) {
|
|
|
|
//dia_num_or_mem
|
|
|
|
ESP_LOGI(BT_HF_TAG, "--Dial \"%s\".", param->out_call.num_or_loc);
|
|
|
|
esp_bt_hf_out_call(hf_peer_addr,1,0,1,0,param->out_call.num_or_loc,0);
|
|
|
|
} else {
|
|
|
|
//dia_last
|
|
|
|
ESP_LOGI(BT_HF_TAG, "--Dial last number.");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2019-12-02 10:17:44 +00:00
|
|
|
#if (BTM_WBS_INCLUDED == TRUE)
|
|
|
|
case ESP_HF_WBS_RESPONSE_EVT:
|
|
|
|
{
|
|
|
|
ESP_LOGI(BT_HF_TAG, "--Current codec: %s",c_codec_mode_str[param->wbs_rep.codec]);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
#endif
|
2019-12-02 07:29:55 +00:00
|
|
|
case ESP_HF_BCS_RESPONSE_EVT:
|
|
|
|
{
|
2019-12-02 10:17:44 +00:00
|
|
|
ESP_LOGI(BT_HF_TAG, "--Consequence of codec negotiation: %s",c_codec_mode_str[param->bcs_rep.mode]);
|
2019-12-02 07:29:55 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
ESP_LOGI(BT_HF_TAG, "Unsupported HF_AG EVT: %d.", event);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|