1. Bugfix for AG audio crash (change the return position) 2. Fix the error macro name and error return in hfp_hf demo 3. Fix the annotation error using UTF-8 ' (from Github) 4. Change or remove the log in SCO related code region. 5. Correct error of introduction of a function.
402 lines
12 KiB
C
402 lines
12 KiB
C
/*
|
|
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 esp_hf_ag_apiied.
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "esp_log.h"
|
|
|
|
#include "bt_app_core.h"
|
|
#include "bt_app_hf.h"
|
|
#include "esp_bt_main.h"
|
|
#include "esp_bt_device.h"
|
|
#include "esp_gap_bt_api.h"
|
|
#include "esp_hf_client_api.h"
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/task.h"
|
|
#include "freertos/queue.h"
|
|
#include "freertos/semphr.h"
|
|
#include "freertos/ringbuf.h"
|
|
#include "time.h"
|
|
#include "sys/time.h"
|
|
#include "sdkconfig.h"
|
|
|
|
const char *c_hf_evt_str[] = {
|
|
"CONNECTION_STATE_EVT", /*!< connection state changed event */
|
|
"AUDIO_STATE_EVT", /*!< audio connection state change event */
|
|
"VR_STATE_CHANGE_EVT", /*!< voice recognition state changed */
|
|
"CALL_IND_EVT", /*!< call indication event */
|
|
"CALL_SETUP_IND_EVT", /*!< call setup indication event */
|
|
"CALL_HELD_IND_EVT", /*!< call held indicator event */
|
|
"NETWORK_STATE_EVT", /*!< network state change event */
|
|
"SIGNAL_STRENGTH_IND_EVT", /*!< signal strength indication event */
|
|
"ROAMING_STATUS_IND_EVT", /*!< roaming status indication event */
|
|
"BATTERY_LEVEL_IND_EVT", /*!< battery level indication event */
|
|
"CURRENT_OPERATOR_EVT", /*!< current operator name event */
|
|
"RESP_AND_HOLD_EVT", /*!< response and hold event */
|
|
"CLIP_EVT", /*!< Calling Line Identification notification event */
|
|
"CALL_WAITING_EVT", /*!< call waiting notification */
|
|
"CLCC_EVT", /*!< listing current calls event */
|
|
"VOLUME_CONTROL_EVT", /*!< audio volume control event */
|
|
"AT_RESPONSE", /*!< audio volume control event */
|
|
"SUBSCRIBER_INFO_EVT", /*!< subscriber information event */
|
|
"INBAND_RING_TONE_EVT", /*!< in-band ring tone settings */
|
|
"LAST_VOICE_TAG_NUMBER_EVT", /*!< requested number from AG event */
|
|
"RING_IND_EVT", /*!< ring indication event */
|
|
};
|
|
|
|
// esp_hf_client_connection_state_t
|
|
const char *c_connection_state_str[] = {
|
|
"disconnected",
|
|
"connecting",
|
|
"connected",
|
|
"slc_connected",
|
|
"disconnecting",
|
|
};
|
|
|
|
// esp_hf_client_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_service_availability_status_t
|
|
const char *c_service_availability_status_str[] = {
|
|
"unavailable",
|
|
"available",
|
|
};
|
|
|
|
// esp_hf_roaming_status_t
|
|
const char *c_roaming_status_str[] = {
|
|
"inactive",
|
|
"active",
|
|
};
|
|
|
|
// esp_hf_client_call_state_t
|
|
const char *c_call_str[] = {
|
|
"NO call in progress",
|
|
"call in progress",
|
|
};
|
|
|
|
// esp_hf_client_callsetup_t
|
|
const char *c_call_setup_str[] = {
|
|
"NONE",
|
|
"INCOMING",
|
|
"OUTGOING_DIALING",
|
|
"OUTGOING_ALERTING"
|
|
};
|
|
|
|
// esp_hf_client_callheld_t
|
|
const char *c_call_held_str[] = {
|
|
"NONE held",
|
|
"Held and Active",
|
|
"Held",
|
|
};
|
|
|
|
// esp_hf_response_and_hold_status_t
|
|
const char *c_resp_and_hold_str[] = {
|
|
"HELD",
|
|
"HELD ACCEPTED",
|
|
"HELD REJECTED",
|
|
};
|
|
|
|
// esp_hf_client_call_direction_t
|
|
const char *c_call_dir_str[] = {
|
|
"outgoing",
|
|
"incoming",
|
|
};
|
|
|
|
// esp_hf_client_call_state_t
|
|
const char *c_call_state_str[] = {
|
|
"active",
|
|
"held",
|
|
"dialing",
|
|
"alerting",
|
|
"incoming",
|
|
"waiting",
|
|
"held_by_resp_hold",
|
|
};
|
|
|
|
// esp_hf_current_call_mpty_type_t
|
|
const char *c_call_mpty_type_str[] = {
|
|
"single",
|
|
"multi",
|
|
};
|
|
|
|
// esp_hf_volume_control_target_t
|
|
const char *c_volume_control_target_str[] = {
|
|
"SPEAKER",
|
|
"MICROPHONE"
|
|
};
|
|
|
|
// esp_hf_at_response_code_t
|
|
const char *c_at_response_code_str[] = {
|
|
"OK",
|
|
"ERROR"
|
|
"ERR_NO_CARRIER",
|
|
"ERR_BUSY",
|
|
"ERR_NO_ANSWER",
|
|
"ERR_DELAYED",
|
|
"ERR_BLACKLILSTED",
|
|
"ERR_CME",
|
|
};
|
|
|
|
// esp_hf_subscriber_service_type_t
|
|
const char *c_subscriber_service_type_str[] = {
|
|
"unknown",
|
|
"voice",
|
|
"fax",
|
|
};
|
|
|
|
// esp_hf_client_in_band_ring_state_t
|
|
const char *c_inband_ring_state_str[] = {
|
|
"NOT provided",
|
|
"Provided",
|
|
};
|
|
|
|
// 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};
|
|
|
|
#if CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_HCI
|
|
|
|
#define ESP_HFP_RINGBUF_SIZE 3600
|
|
static RingbufHandle_t m_rb = NULL;
|
|
|
|
static void bt_app_hf_client_audio_open(void)
|
|
{
|
|
m_rb = xRingbufferCreate(ESP_HFP_RINGBUF_SIZE, RINGBUF_TYPE_BYTEBUF);
|
|
}
|
|
|
|
static void bt_app_hf_client_audio_close(void)
|
|
{
|
|
if (!m_rb) {
|
|
return ;
|
|
}
|
|
|
|
vRingbufferDelete(m_rb);
|
|
}
|
|
|
|
static uint32_t bt_app_hf_client_outgoing_cb(uint8_t *p_buf, uint32_t sz)
|
|
{
|
|
if (!m_rb) {
|
|
return 0;
|
|
}
|
|
|
|
size_t item_size = 0;
|
|
uint8_t *data = xRingbufferReceiveUpTo(m_rb, &item_size, 0, sz);
|
|
if (item_size == sz) {
|
|
memcpy(p_buf, data, item_size);
|
|
vRingbufferReturnItem(m_rb, data);
|
|
return sz;
|
|
} else if (0 < item_size) {
|
|
vRingbufferReturnItem(m_rb, data);
|
|
return 0;
|
|
} else {
|
|
// data not enough, do not read
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
static void bt_app_hf_client_incoming_cb(const uint8_t *buf, uint32_t sz)
|
|
{
|
|
if (! m_rb) {
|
|
return;
|
|
}
|
|
BaseType_t done = xRingbufferSend(m_rb, (uint8_t *)buf, sz, 0);
|
|
if (! done) {
|
|
ESP_LOGE(BT_HF_TAG, "rb send fail");
|
|
}
|
|
|
|
esp_hf_client_outgoing_data_ready();
|
|
}
|
|
#endif /* #if CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_HCI */
|
|
|
|
/* callback for HF_CLIENT */
|
|
void bt_app_hf_client_cb(esp_hf_client_cb_event_t event, esp_hf_client_cb_param_t *param)
|
|
{
|
|
if (event <= ESP_HF_CLIENT_RING_IND_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_CLIENT_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(peer_addr,param->conn_stat.remote_bda,ESP_BD_ADDR_LEN);
|
|
break;
|
|
}
|
|
|
|
case ESP_HF_CLIENT_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
|
|
if (param->audio_stat.state == ESP_HF_CLIENT_AUDIO_STATE_CONNECTED ||
|
|
param->audio_stat.state == ESP_HF_CLIENT_AUDIO_STATE_CONNECTED_MSBC) {
|
|
esp_hf_client_register_data_callback(bt_app_hf_client_incoming_cb,
|
|
bt_app_hf_client_outgoing_cb);
|
|
bt_app_hf_client_audio_open();
|
|
} else if (param->audio_stat.state == ESP_HF_CLIENT_AUDIO_STATE_DISCONNECTED) {
|
|
bt_app_hf_client_audio_close();
|
|
}
|
|
#endif /* #if CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_HCI */
|
|
break;
|
|
}
|
|
|
|
case ESP_HF_CLIENT_BVRA_EVT:
|
|
{
|
|
ESP_LOGI(BT_HF_TAG, "--VR state %s",
|
|
c_vr_state_str[param->bvra.value]);
|
|
break;
|
|
}
|
|
|
|
case ESP_HF_CLIENT_CIND_SERVICE_AVAILABILITY_EVT:
|
|
{
|
|
ESP_LOGI(BT_HF_TAG, "--NETWORK STATE %s",
|
|
c_service_availability_status_str[param->service_availability.status]);
|
|
break;
|
|
}
|
|
|
|
case ESP_HF_CLIENT_CIND_ROAMING_STATUS_EVT:
|
|
{
|
|
ESP_LOGI(BT_HF_TAG, "--ROAMING: %s",
|
|
c_roaming_status_str[param->roaming.status]);
|
|
break;
|
|
}
|
|
|
|
case ESP_HF_CLIENT_CIND_SIGNAL_STRENGTH_EVT:
|
|
{
|
|
ESP_LOGI(BT_HF_TAG, "-- signal strength: %d",
|
|
param->signal_strength.value);
|
|
break;
|
|
}
|
|
|
|
case ESP_HF_CLIENT_CIND_BATTERY_LEVEL_EVT:
|
|
{
|
|
ESP_LOGI(BT_HF_TAG, "--battery level %d",
|
|
param->battery_level.value);
|
|
break;
|
|
}
|
|
|
|
case ESP_HF_CLIENT_COPS_CURRENT_OPERATOR_EVT:
|
|
{
|
|
ESP_LOGI(BT_HF_TAG, "--operator name: %s",
|
|
param->cops.name);
|
|
break;
|
|
}
|
|
|
|
case ESP_HF_CLIENT_CIND_CALL_EVT:
|
|
{
|
|
ESP_LOGI(BT_HF_TAG, "--Call indicator %s",
|
|
c_call_str[param->call.status]);
|
|
break;
|
|
}
|
|
|
|
case ESP_HF_CLIENT_CIND_CALL_SETUP_EVT:
|
|
{
|
|
ESP_LOGI(BT_HF_TAG, "--Call setup indicator %s",
|
|
c_call_setup_str[param->call_setup.status]);
|
|
break;
|
|
}
|
|
|
|
case ESP_HF_CLIENT_CIND_CALL_HELD_EVT:
|
|
{
|
|
ESP_LOGI(BT_HF_TAG, "--Call held indicator %s",
|
|
c_call_held_str[param->call_held.status]);
|
|
break;
|
|
}
|
|
|
|
case ESP_HF_CLIENT_BTRH_EVT:
|
|
{
|
|
ESP_LOGI(BT_HF_TAG, "--response and hold %s",
|
|
c_resp_and_hold_str[param->btrh.status]);
|
|
break;
|
|
}
|
|
|
|
case ESP_HF_CLIENT_CLIP_EVT:
|
|
{
|
|
ESP_LOGI(BT_HF_TAG, "--clip number %s",
|
|
(param->clip.number == NULL) ? "NULL" : (param->clip.number));
|
|
break;
|
|
}
|
|
|
|
case ESP_HF_CLIENT_CCWA_EVT:
|
|
{
|
|
ESP_LOGI(BT_HF_TAG, "--call_waiting %s",
|
|
(param->ccwa.number == NULL) ? "NULL" : (param->ccwa.number));
|
|
break;
|
|
}
|
|
|
|
case ESP_HF_CLIENT_CLCC_EVT:
|
|
{
|
|
ESP_LOGI(BT_HF_TAG, "--Current call: idx %d, dir %s, state %s, mpty %s, number %s",
|
|
param->clcc.idx,
|
|
c_call_dir_str[param->clcc.dir],
|
|
c_call_state_str[param->clcc.status],
|
|
c_call_mpty_type_str[param->clcc.mpty],
|
|
(param->clcc.number == NULL) ? "NULL" : (param->clcc.number));
|
|
break;
|
|
}
|
|
|
|
case ESP_HF_CLIENT_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_CLIENT_AT_RESPONSE_EVT:
|
|
{
|
|
ESP_LOGI(BT_HF_TAG, "--AT response event, code %d, cme %d",
|
|
param->at_response.code, param->at_response.cme);
|
|
break;
|
|
}
|
|
|
|
case ESP_HF_CLIENT_CNUM_EVT:
|
|
{
|
|
ESP_LOGI(BT_HF_TAG, "--subscriber type %s, number %s",
|
|
c_subscriber_service_type_str[param->cnum.type],
|
|
(param->cnum.number == NULL) ? "NULL" : param->cnum.number);
|
|
break;
|
|
}
|
|
|
|
case ESP_HF_CLIENT_BSIR_EVT:
|
|
{
|
|
ESP_LOGI(BT_HF_TAG, "--inband ring state %s",
|
|
c_inband_ring_state_str[param->bsir.state]);
|
|
break;
|
|
}
|
|
|
|
case ESP_HF_CLIENT_BINP_EVT:
|
|
{
|
|
ESP_LOGI(BT_HF_TAG, "--last voice tag number: %s",
|
|
(param->binp.number == NULL) ? "NULL" : param->binp.number);
|
|
break;
|
|
}
|
|
|
|
default:
|
|
ESP_LOGE(BT_HF_TAG, "HF_CLIENT EVT: %d", event);
|
|
break;
|
|
}
|
|
}
|