1
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
63
64
65
71
72
73
77
78
79
83
84
85
89
90
91
95
96
97
103
104
105
110
111
112
117
118
119
123
124
125
126
127
128
129
130
131
132
133
134
135
136
140
141
142
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
165
166
167
171
172
173
174
175
176
177
178
179
180
181
185
186
194
195
196
197
200
201
202
203
214
215
216
217
218
221
222
225
226
227
228
229
230
231
232
233
238
239
240
241
242
243
244
245
246
247
248
249
250
267
274
281
288
295
302
309
316
323
330
337
344
351
352
353
354
355
356
357
358
359
360
361
362
370
377
385
392
398
403
414
417
418
/* ... */
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.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"20 includes
const char *c_hf_evt_str[] = {
"CONNECTION_STATE_EVT",
"AUDIO_STATE_EVT",
"VR_STATE_CHANGE_EVT",
"CALL_IND_EVT",
"CALL_SETUP_IND_EVT",
"CALL_HELD_IND_EVT",
"NETWORK_STATE_EVT",
"SIGNAL_STRENGTH_IND_EVT",
"ROAMING_STATUS_IND_EVT",
"BATTERY_LEVEL_IND_EVT",
"CURRENT_OPERATOR_EVT",
"RESP_AND_HOLD_EVT",
"CLIP_EVT",
"CALL_WAITING_EVT",
"CLCC_EVT",
"VOLUME_CONTROL_EVT",
"AT_RESPONSE",
"SUBSCRIBER_INFO_EVT",
"INBAND_RING_TONE_EVT",
"LAST_VOICE_TAG_NUMBER_EVT",
"RING_IND_EVT",
"PKT_STAT_EVT",
"PROF_STATE_EVT",
}{...};
const char *c_connection_state_str[] = {
"disconnected",
"connecting",
"connected",
"slc_connected",
"disconnecting",
}{...};
const char *c_audio_state_str[] = {
"disconnected",
"connecting",
"connected",
"connected_msbc",
}{...};
const char *c_vr_state_str[] = {
"disabled",
"enabled",
}{...};
const char *c_service_availability_status_str[] = {
"unavailable",
"available",
}{...};
const char *c_roaming_status_str[] = {
"inactive",
"active",
}{...};
const char *c_call_str[] = {
"NO call in progress",
"call in progress",
}{...};
const char *c_call_setup_str[] = {
"NONE",
"INCOMING",
"OUTGOING_DIALING",
"OUTGOING_ALERTING"
}{...};
const char *c_call_held_str[] = {
"NONE held",
"Held and Active",
"Held",
}{...};
const char *c_resp_and_hold_str[] = {
"HELD",
"HELD ACCEPTED",
"HELD REJECTED",
}{...};
const char *c_call_dir_str[] = {
"outgoing",
"incoming",
}{...};
const char *c_call_state_str[] = {
"active",
"held",
"dialing",
"alerting",
"incoming",
"waiting",
"held_by_resp_hold",
}{...};
const char *c_call_mpty_type_str[] = {
"single",
"multi",
}{...};
const char *c_volume_control_target_str[] = {
"SPEAKER",
"MICROPHONE"
}{...};
const char *c_at_response_code_str[] = {
"OK",
"ERROR"
"ERR_NO_CARRIER",
"ERR_BUSY",
"ERR_NO_ANSWER",
"ERR_DELAYED",
"ERR_BLACKLILSTED",
"ERR_CME",
}{...};
const char *c_subscriber_service_type_str[] = {
"unknown",
"voice",
"fax",
}{...};
const char *c_inband_ring_state_str[] = {
"NOT provided",
"Provided",
}{...};
extern esp_bd_addr_t peer_addr;
#if CONFIG_BT_HFP_AUDIO_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 {
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
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_PROF_STATE_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%"PRIx32", chld_feats 0x%"PRIx32,
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_BT_HFP_AUDIO_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
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;
}{...}
case ESP_HF_CLIENT_PKT_STAT_NUMS_GET_EVT:
{
ESP_LOGE(BT_HF_TAG, "ESP_HF_CLIENT_PKT_STAT_NUMS_GET_EVT: %d", event);
break;
}{...}
case ESP_HF_CLIENT_PROF_STATE_EVT:
{
if (ESP_HF_INIT_SUCCESS == param->prof_stat.state) {
ESP_LOGI(BT_HF_TAG, "HF PROF STATE: Init Complete");
}{...} else if (ESP_HF_DEINIT_SUCCESS == param->prof_stat.state) {
ESP_LOGI(BT_HF_TAG, "HF PROF STATE: Deinit Complete");
}{...} else {
ESP_LOGE(BT_HF_TAG, "HF PROF STATE error: %d", param->prof_stat.state);
}{...}
break;
}{...}
default:
ESP_LOGE(BT_HF_TAG, "HF_CLIENT EVT: %d", event);
break;...
}{...}
}{ ... }