mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 03:00:34 +03:00
New Clean Commit for AG.
Only Support single AG control block.
This commit is contained in:
@@ -0,0 +1,529 @@
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include "bt_common.h"
|
||||
#include "btc/btc_common.h"
|
||||
#include "btc/btc_dm.h"
|
||||
#include "btc_hf_ag.h"
|
||||
#include "btc/btc_profile_queue.h"
|
||||
#include "btc/btc_manage.h"
|
||||
#include "btc/btc_util.h"
|
||||
#include "bta/bta_ag_api.h"
|
||||
#include "bta/bta_api.h"
|
||||
#include "common/bt_target.h"
|
||||
#include "common/bt_defs.h"
|
||||
#include "device/bdaddr.h"
|
||||
#include "esp_bt.h"
|
||||
#include "esp_hf_ag_api.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_bt_main.h"
|
||||
#include "osi/allocator.h"
|
||||
|
||||
#if (BTC_HF_INCLUDED == TRUE)
|
||||
esp_err_t esp_bt_hf_register_callback(esp_hf_cb_t callback)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
if (callback == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
btc_profile_cb_set(BTC_PID_HF, callback);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hf_init(esp_bd_addr_t remote_addr)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HF;
|
||||
msg.act = BTC_HF_INIT_EVT;
|
||||
|
||||
btc_hf_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||
memcpy(&(arg.init), remote_addr, sizeof(esp_bd_addr_t));
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL);
|
||||
return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hf_deinit(esp_bd_addr_t remote_addr)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HF;
|
||||
msg.act = BTC_HF_DEINIT_EVT;
|
||||
|
||||
btc_hf_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||
memcpy(&(arg.deinit), remote_addr, sizeof(esp_bd_addr_t));
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL);
|
||||
return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hf_connect(esp_bd_addr_t remote_addr)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HF;
|
||||
msg.act = BTC_HF_CONNECT_EVT;
|
||||
|
||||
btc_hf_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||
memcpy(&(arg.connect), remote_addr, sizeof(esp_bd_addr_t));
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL);
|
||||
return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hf_disconnect(esp_bd_addr_t remote_addr)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HF;
|
||||
msg.act = BTC_HF_DISCONNECT_EVT;
|
||||
|
||||
btc_hf_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||
memcpy(&(arg.disconnect), remote_addr, sizeof(esp_bd_addr_t));
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL);
|
||||
return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hf_connect_audio(esp_bd_addr_t remote_addr)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HF;
|
||||
msg.act = BTC_HF_CONNECT_AUDIO_EVT;
|
||||
|
||||
btc_hf_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||
memcpy(&(arg.connect_audio), remote_addr, sizeof(esp_bd_addr_t));
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL);
|
||||
return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hf_disconnect_audio(esp_bd_addr_t remote_addr)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HF;
|
||||
msg.act = BTC_HF_DISCONNECT_AUDIO_EVT;
|
||||
|
||||
btc_hf_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||
memcpy(&(arg.disconnect_audio), remote_addr, sizeof(esp_bd_addr_t));
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL);
|
||||
return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hf_vra(esp_bd_addr_t remote_addr, esp_hf_vr_state_t value)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HF;
|
||||
msg.act = BTC_HF_VRA_EVT;
|
||||
|
||||
btc_hf_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||
arg.vra_rep.value = value;
|
||||
memcpy(&(arg.volcon.remote_addr), remote_addr, sizeof(esp_bd_addr_t));
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL);
|
||||
return (status = BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hf_volume_control(esp_bd_addr_t remote_addr, esp_hf_volume_control_target_t type, int volume)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HF;
|
||||
msg.act = BTC_HF_VOLUME_CONTROL_EVT;
|
||||
|
||||
btc_hf_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||
arg.volcon.target_type = type;
|
||||
arg.volcon.volume = volume;
|
||||
memcpy(&(arg.volcon.remote_addr), remote_addr, sizeof(esp_bd_addr_t));
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL);
|
||||
return (status = BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_hf_unat_response(esp_bd_addr_t remote_addr, char *unat)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HF;
|
||||
msg.act = BTC_HF_UNAT_RESPONSE_EVT;
|
||||
|
||||
btc_hf_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||
arg.unat_rep.unat = unat;
|
||||
memcpy(&(arg.unat_rep.remote_addr), remote_addr, sizeof(esp_bd_addr_t));
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), btc_hf_arg_deep_copy);
|
||||
return (status = BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hf_cmee_response(esp_bd_addr_t remote_addr, esp_hf_at_response_code_t response_code, esp_hf_cme_err_t error_code)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HF;
|
||||
msg.act = BTC_HF_CME_ERR_EVT;
|
||||
|
||||
btc_hf_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||
arg.ext_at.response_code = response_code;
|
||||
arg.ext_at.error_code = error_code;
|
||||
memcpy(&(arg.ext_at.remote_addr), remote_addr, sizeof(esp_bd_addr_t));
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL);
|
||||
return (status = BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hf_indchange_notification(esp_bd_addr_t remote_addr,
|
||||
esp_hf_call_status_t call_state,
|
||||
esp_hf_call_setup_status_t call_setup_state,
|
||||
esp_hf_network_state_t ntk_state, int signal)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HF;
|
||||
msg.act = BTC_HF_IND_NOTIFICATION_EVT;
|
||||
|
||||
btc_hf_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||
memcpy(&(arg.ind_change.remote_addr), remote_addr, sizeof(esp_bd_addr_t));
|
||||
arg.ind_change.call_state = call_state;
|
||||
arg.ind_change.call_setup_state = call_setup_state;
|
||||
arg.ind_change.ntk_state = ntk_state;
|
||||
arg.ind_change.signal = signal;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t state = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL);
|
||||
return (state == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hf_cind_response(esp_bd_addr_t remote_addr,
|
||||
esp_hf_call_status_t call_state,
|
||||
esp_hf_call_setup_status_t call_setup_state,
|
||||
esp_hf_network_state_t ntk_state, int signal, esp_hf_roaming_status_t roam, int batt_lev,
|
||||
esp_hf_call_held_status_t call_held_status)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HF;
|
||||
msg.act = BTC_HF_CIND_RESPONSE_EVT;
|
||||
|
||||
btc_hf_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||
memcpy(&(arg.cind_rep.remote_addr), remote_addr, sizeof(esp_bd_addr_t));
|
||||
arg.cind_rep.call_state = call_state;
|
||||
arg.cind_rep.call_setup_state = call_setup_state;
|
||||
arg.cind_rep.ntk_state = ntk_state;
|
||||
arg.cind_rep.signal = signal;
|
||||
arg.cind_rep.roam = roam;
|
||||
arg.cind_rep.batt_lev = batt_lev;
|
||||
arg.cind_rep.call_held_state = call_held_status;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hf_cops_response(esp_bd_addr_t remote_addr, char *name)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HF;
|
||||
msg.act = BTC_HF_COPS_RESPONSE_EVT;
|
||||
|
||||
btc_hf_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||
memcpy(&(arg.cops_rep.remote_addr), remote_addr, sizeof(esp_bd_addr_t));
|
||||
arg.cops_rep.name = name; //deep_copy
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), btc_hf_arg_deep_copy);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hf_clcc_response(esp_bd_addr_t remote_addr, int index, esp_hf_current_call_direction_t dir,
|
||||
esp_hf_current_call_status_t current_call_state, esp_hf_current_call_mode_t mode,
|
||||
esp_hf_current_call_mpty_type_t mpty, char *number, esp_hf_call_addr_type_t type)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HF;
|
||||
msg.act = BTC_HF_CLCC_RESPONSE_EVT;
|
||||
|
||||
btc_hf_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||
memcpy(&(arg.clcc_rep.remote_addr), remote_addr, sizeof(esp_bd_addr_t));
|
||||
//mandatory args
|
||||
arg.clcc_rep.index = index;
|
||||
arg.clcc_rep.dir = dir;
|
||||
arg.clcc_rep.current_call_state = current_call_state;
|
||||
arg.clcc_rep.mode = mode;
|
||||
arg.clcc_rep.mpty = mpty;
|
||||
// option args
|
||||
arg.clcc_rep.number = number; //deep_copy
|
||||
arg.clcc_rep.type = type;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), btc_hf_arg_deep_copy);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hf_cnum_response(esp_bd_addr_t remote_addr, char *number, esp_hf_subscriber_service_type_t type)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HF;
|
||||
msg.act = BTC_HF_CNUM_RESPONSE_EVT;
|
||||
|
||||
btc_hf_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||
memcpy(&(arg.cnum_rep), remote_addr, sizeof(esp_bd_addr_t));
|
||||
arg.cnum_rep.number = number; //deep_copy
|
||||
arg.cnum_rep.type = type;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), btc_hf_arg_deep_copy);
|
||||
return (status = BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hf_bsir(esp_bd_addr_t remote_addr, esp_hf_in_band_ring_state_t state)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HF;
|
||||
msg.act = BTC_HF_INBAND_RING_EVT;
|
||||
|
||||
btc_hf_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||
memcpy(&(arg.bsir.remote_addr), remote_addr, sizeof(esp_bd_addr_t));
|
||||
arg.bsir.state = state;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL);
|
||||
return (status = BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hf_answer_call(esp_bd_addr_t remote_addr, int num_active, int num_held,
|
||||
esp_hf_call_status_t call_state, esp_hf_call_setup_status_t call_setup_state,
|
||||
char *number, esp_hf_call_addr_type_t call_addr_type)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HF;
|
||||
msg.act = BTC_HF_AC_INCALL_EVT;
|
||||
|
||||
btc_hf_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||
memcpy(&(arg.phone.remote_addr), remote_addr, sizeof(esp_bd_addr_t));
|
||||
arg.phone.num_active = num_active;
|
||||
arg.phone.num_held = num_held;
|
||||
arg.phone.call_state = call_state;
|
||||
arg.phone.call_setup_state = call_setup_state;
|
||||
arg.phone.number = number; //deep_copy
|
||||
arg.phone.call_addr_type = call_addr_type;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), btc_hf_arg_deep_copy);
|
||||
return (status = BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hf_reject_call(esp_bd_addr_t remote_addr, int num_active, int num_held,
|
||||
esp_hf_call_status_t call_state, esp_hf_call_setup_status_t call_setup_state,
|
||||
char *number, esp_hf_call_addr_type_t call_addr_type)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HF;
|
||||
msg.act = BTC_HF_RJ_INCALL_EVT;
|
||||
|
||||
btc_hf_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||
memcpy(&(arg.phone.remote_addr), remote_addr, sizeof(esp_bd_addr_t));
|
||||
arg.phone.num_active = num_active;
|
||||
arg.phone.num_held = num_held;
|
||||
arg.phone.call_state = call_state;
|
||||
arg.phone.call_setup_state = call_setup_state;
|
||||
arg.phone.number = number; //deep_copy
|
||||
arg.phone.call_addr_type = call_addr_type;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), btc_hf_arg_deep_copy);
|
||||
return (status = BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hf_end_call(esp_bd_addr_t remote_addr, int num_active, int num_held,
|
||||
esp_hf_call_status_t call_state, esp_hf_call_setup_status_t call_setup_state,
|
||||
char *number, esp_hf_call_addr_type_t call_addr_type)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HF;
|
||||
msg.act = BTC_HF_END_CALL_EVT;
|
||||
|
||||
btc_hf_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||
memcpy(&(arg.phone.remote_addr), remote_addr, sizeof(esp_bd_addr_t));
|
||||
arg.phone.num_active = num_active;
|
||||
arg.phone.num_held = num_held;
|
||||
arg.phone.call_state = call_state;
|
||||
arg.phone.call_setup_state = call_setup_state;
|
||||
arg.phone.number = number; //deep_copy
|
||||
arg.phone.call_addr_type = call_addr_type;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), btc_hf_arg_deep_copy);
|
||||
return (status = BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hf_out_call(esp_bd_addr_t remote_addr, int num_active, int num_held,
|
||||
esp_hf_call_status_t call_state, esp_hf_call_setup_status_t call_setup_state,
|
||||
char *number, esp_hf_call_addr_type_t call_addr_type)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HF;
|
||||
msg.act = BTC_HF_OUT_CALL_EVT;
|
||||
|
||||
btc_hf_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||
memcpy(&(arg.phone.remote_addr), remote_addr, sizeof(esp_bd_addr_t));
|
||||
arg.phone.num_active = num_active;
|
||||
arg.phone.num_held = num_held;
|
||||
arg.phone.call_state = call_state;
|
||||
arg.phone.call_setup_state = call_setup_state;
|
||||
arg.phone.number = number; //deep_copy
|
||||
arg.phone.call_addr_type = call_addr_type;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), btc_hf_arg_deep_copy);
|
||||
return (status = BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_hf_register_data_callback(esp_hf_incoming_data_cb_t recv, esp_hf_outgoing_data_cb_t send)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HF;
|
||||
msg.act = BTC_HF_REGISTER_DATA_CALLBACK_EVT;
|
||||
|
||||
btc_hf_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||
arg.reg_data_cb.recv = recv;
|
||||
arg.reg_data_cb.send = send;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL);
|
||||
return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
#if (BTM_SCO_HCI_INCLUDED == TRUE)
|
||||
void esp_hf_outgoing_data_ready(void)
|
||||
{
|
||||
BTA_AgCiData();
|
||||
}
|
||||
#endif /* #if (BTM_SCO_HCI_INCLUDED == TRUE ) */
|
||||
|
||||
#endif // BTC_HF_INCLUDED
|
||||
@@ -0,0 +1,535 @@
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef __ESP_HF_AG_API_H__
|
||||
#define __ESP_HF_AG_API_H__
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_bt_defs.h"
|
||||
#include "esp_hf_defs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* features masks of HF AG */
|
||||
#define ESP_HF_PEER_FEAT_3WAY 0x01 /* Three-way calling */
|
||||
#define ESP_HF_PEER_FEAT_ECNR 0x02 /* Echo cancellation and/or noise reduction */
|
||||
#define ESP_HF_PEER_FEAT_VREC 0x04 /* Voice recognition */
|
||||
#define ESP_HF_PEER_FEAT_INBAND 0x08 /* In-band ring tone */
|
||||
#define ESP_HF_PEER_FEAT_VTAG 0x10 /* Attach a phone number to a voice tag */
|
||||
#define ESP_HF_PEER_FEAT_REJECT 0x20 /* Ability to reject incoming call */
|
||||
#define ESP_HF_PEER_FEAT_ECS 0x40 /* Enhanced Call Status */
|
||||
#define ESP_HF_PEER_FEAT_ECC 0x80 /* Enhanced Call Control */
|
||||
#define ESP_HF_PEER_FEAT_EXTERR 0x100 /* Extended error codes */
|
||||
#define ESP_HF_PEER_FEAT_CODEC 0x200 /* Codec Negotiation */
|
||||
|
||||
/* CHLD feature masks of HF AG */
|
||||
#define ESP_HF_CHLD_FEAT_REL 0x01 /* 0 Release waiting call or held calls */
|
||||
#define ESP_HF_CHLD_FEAT_REL_ACC 0x02 /* 1 Release active calls and accept other waiting or held call */
|
||||
#define ESP_HF_CHLD_FEAT_REL_X 0x04 /* 1x Release specified active call only */
|
||||
#define ESP_HF_CHLD_FEAT_HOLD_ACC 0x08 /* 2 Active calls on hold and accept other waiting or held call */
|
||||
#define ESP_HF_CHLD_FEAT_PRIV_X 0x10 /* 2x Request private mode with specified call(put the rest on hold) */
|
||||
#define ESP_HF_CHLD_FEAT_MERGE 0x20 /* 3 Add held call to multiparty */
|
||||
#define ESP_HF_CHLD_FEAT_MERGE_DETACH 0x40 /* 4 Connect two calls and leave(disconnect from multiparty) */
|
||||
|
||||
/// HF callback events
|
||||
typedef enum
|
||||
{
|
||||
ESP_HF_CONNECTION_STATE_EVT = 0, /*!< Connection state changed event */
|
||||
ESP_HF_AUDIO_STATE_EVT, /*!< Audio connection state change event */
|
||||
ESP_HF_BVRA_EVT, /*!< Voice recognition state change event */
|
||||
ESP_HF_VOLUME_CONTROL_EVT, /*!< Audio volume control command from HF Client, provided by +VGM or +VGS message */
|
||||
|
||||
ESP_HF_UNAT_RESPONSE_EVT, /*!< Unknown AT cmd Response*/
|
||||
ESP_HF_CIND_RESPONSE_EVT, /*!< Call And Device Indicator Response*/
|
||||
ESP_HF_COPS_RESPONSE_EVT, /*!< Current operator information */
|
||||
ESP_HF_CLCC_RESPONSE_EVT, /*!< List of current calls notification */
|
||||
ESP_HF_CNUM_RESPONSE_EVT, /*!< Subscriber information response from HF Client */
|
||||
ESP_HF_VTS_RESPONSE_EVT, /*!< Enable or not DTMF */
|
||||
ESP_HF_NREC_RESPONSE_EVT, /*!< Enable or not NREC */
|
||||
|
||||
ESP_HF_ATA_RESPONSE_EVT, /*!< Answer an Incoming Call */
|
||||
ESP_HF_CHUP_RESPONSE_EVT, /*!< Reject an Incoming Call */
|
||||
ESP_HF_DIAL_EVT, /*!< Origin an outgoing call with specific number or the dial the last number */
|
||||
ESP_HF_BAC_RESPONSE_EVT, /*!< Codec Negotiation */
|
||||
ESP_HF_BCS_RESPONSE_EVT, /*!< Codec Negotiation */
|
||||
} esp_hf_cb_event_t;
|
||||
|
||||
// HF callback parameters of corresponding esp event in esp_hf_cb_event_t
|
||||
typedef union
|
||||
{
|
||||
/**
|
||||
* @brief ESP_HS_CONNECTION_STATE_EVT
|
||||
*/
|
||||
struct hf_conn_stat_param {
|
||||
esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */
|
||||
esp_hf_connection_state_t state; /*!< HF connection state */
|
||||
uint32_t peer_feat; /*!< AG supported features */
|
||||
uint32_t chld_feat; /*!< AG supported features on call hold and multiparty services */
|
||||
} conn_stat; /*!< AG callback param of ESP_AG_CONNECTION_STATE_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HF_AUDIO_STATE_EVT
|
||||
*/
|
||||
struct hf_audio_stat_param {
|
||||
esp_bd_addr_t remote_addr; /*!< remote bluetooth device address */
|
||||
esp_hf_audio_state_t state; /*!< audio connection state */
|
||||
} audio_stat; /*!< AG callback param of ESP_AG_AUDIO_STATE_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HF_BVRA_EVT
|
||||
*/
|
||||
struct hf_bvra_param {
|
||||
esp_bd_addr_t remote_addr;
|
||||
esp_hf_vr_state_t value; /*!< voice recognition state */
|
||||
} vra_rep; /*!< AG callback param of ESP_AG_BVRA_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HF_VOLUME_CONTROL_EVT
|
||||
*/
|
||||
struct hf_volume_control_param {
|
||||
esp_hf_volume_type_t type; /*!< volume control target, speaker or microphone */
|
||||
int volume; /*!< gain, ranges from 0 to 15 */
|
||||
} volume_control; /*!< AG callback param of ESP_AG_VOLUME_CONTROL_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HF_UNAT_RESPOSNE_EVT
|
||||
*/
|
||||
struct hf_unat_param {
|
||||
char *unat;
|
||||
}unat_rep;
|
||||
|
||||
/**
|
||||
* @brief ESP_HF_AT_RESPONSE_EVT
|
||||
*/
|
||||
struct hf_at_code_param {
|
||||
esp_hf_at_response_code_t code; /*!< AT response code */
|
||||
esp_hf_cme_err_t cme; /*!< Extended Audio Gateway Error Result Code */
|
||||
} at; /*!< AG callback param of ESP_HF_EXT_AT_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HF_CIND_CALL_EVT
|
||||
*/
|
||||
struct hf_cind_param {
|
||||
esp_hf_call_status_t call_status; /*!< call status indicator */
|
||||
esp_hf_call_setup_status_t call_setup_status; /*!< call setup status indicator */
|
||||
esp_hf_network_state_t svc; /*!< bluetooth proprietary call hold status indicator */
|
||||
int signal_strength; /*!< bluetooth proprietary call hold status indicator */
|
||||
esp_hf_roaming_status_t roam; /*!< bluetooth proprietary call hold status indicator */
|
||||
int battery_level; /*!< battery charge value, ranges from 0 to 5 */
|
||||
esp_hf_call_held_status_t call_held_status; /*!< bluetooth proprietary call hold status indicator */
|
||||
} cind;
|
||||
|
||||
/**
|
||||
* @brief ESP_HF_VTS_RESPOSNE_EVT
|
||||
*/
|
||||
struct hf_vts_param {
|
||||
char *code;
|
||||
}vts_rep;
|
||||
|
||||
/**
|
||||
* @brief ESP_HF_NREC_RESPOSNE_EVT
|
||||
*/
|
||||
struct hf_nrec_param {
|
||||
esp_hf_nrec_t state;
|
||||
} nrec;
|
||||
|
||||
struct hf_outcall_param {
|
||||
esp_bd_addr_t remote_addr;
|
||||
char *num_or_loc;
|
||||
} out_call;
|
||||
|
||||
/**
|
||||
* @brief ESP_HF_BSIR_EVT
|
||||
*/
|
||||
struct hf_bsir_param {
|
||||
esp_bd_addr_t remote_addr;
|
||||
esp_hf_in_band_ring_state_t state; /*!< setting state of in-band ring tone */
|
||||
} bsir;
|
||||
|
||||
/**
|
||||
* @brief ESP_HF_BCS_RESPONSE_EVT
|
||||
*/
|
||||
struct hf_codec_param {
|
||||
esp_hf_wbs_config_t mode;
|
||||
} codec;
|
||||
|
||||
} esp_hf_cb_param_t;
|
||||
|
||||
/**
|
||||
* @brief AG incoming data callback function, the callback is useful in case of
|
||||
* Voice Over HCI.
|
||||
* @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the
|
||||
* buffer is allocated inside bluetooth protocol stack and will be released after
|
||||
* invoke of the callback is finished.
|
||||
* @param[in] len : size(in bytes) in buf
|
||||
*/
|
||||
typedef void (* esp_hf_incoming_data_cb_t)(const uint8_t *buf, uint32_t len);
|
||||
|
||||
/**
|
||||
* @brief AG outgoing data callback function, the callback is useful in case of
|
||||
* Voice Over HCI. Once audio connection is set up and the application layer has
|
||||
* prepared data to send, the lower layer will call this function to read data
|
||||
* and then send. This callback is supposed to be implemented as non-blocking,
|
||||
* and if data is not enough, return value 0 is supposed.
|
||||
*
|
||||
* @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the
|
||||
* buffer is allocated inside bluetooth protocol stack and will be released after
|
||||
* invoke of the callback is finished.
|
||||
* @param[in] len : size(in bytes) in buf
|
||||
* @param[out] length of data successfully read
|
||||
*/
|
||||
typedef uint32_t (* esp_hf_outgoing_data_cb_t) (uint8_t *buf, uint32_t len);
|
||||
|
||||
/**
|
||||
* @brief HF AG callback function type
|
||||
*
|
||||
* @param event : Event type
|
||||
*
|
||||
* @param param : Pointer to callback parameter
|
||||
*/
|
||||
typedef void (* esp_hf_cb_t) (esp_hf_cb_event_t event, esp_hf_cb_param_t *param);
|
||||
|
||||
/************************************************************************************
|
||||
** ESP HF API
|
||||
************************************************************************************/
|
||||
/**
|
||||
* @brief Register application callback function to HFP client module. This function should be called
|
||||
* only after esp_bluedroid_enable() completes successfully, used by HFP client
|
||||
*
|
||||
* @param[in] callback: HFP AG event callback function
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: if callback is a NULL function pointer
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_bt_hf_register_callback(esp_hf_cb_t callback);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Initialize the bluetooth HF AG module. This function should be called
|
||||
* after esp_bluedroid_enable() completes successfully
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: if the initialization request is sent successfully
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_bt_hf_init(esp_bd_addr_t remote_addr);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief De-initialize for HF AG module. This function
|
||||
* should be called only after esp_bluedroid_enable() completes successfully
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_bt_hf_deinit(esp_bd_addr_t remote_addr);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Connect to remote bluetooth HFP client device, must after esp_bt_hf_init()
|
||||
*
|
||||
* @param[in] remote_bda: remote bluetooth HFP client device address
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: connect request is sent to lower layer
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_bt_hf_connect(esp_bd_addr_t remote_bda);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Disconnect from the remote HFP client
|
||||
*
|
||||
* @param[in] remote_bda: remote bluetooth device address
|
||||
* @return
|
||||
* - ESP_OK: disconnect request is sent to lower layer
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_bt_hf_disconnect(esp_bd_addr_t remote_bda);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Create audio connection with remote HFP client. As a precondition to use this API,
|
||||
* Service Level Connection shall exist between HF client and AG.
|
||||
*
|
||||
* @param[in] remote_bda: remote bluetooth device address
|
||||
* @return
|
||||
* - ESP_OK: disconnect request is sent to lower layer
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_bt_hf_connect_audio(esp_bd_addr_t remote_bda);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Release the established audio connection with remote HFP client.
|
||||
*
|
||||
* @param[in] remote_bda: remote bluetooth device address
|
||||
* @return
|
||||
* - ESP_OK: disconnect request is sent to lower layer
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_bt_hf_disconnect_audio(esp_bd_addr_t remote_bda);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Response of Volume Recognition Command(AT+VRA) from HFP client. As a precondition to use this API,
|
||||
* Service Level Connection shall exist with HFP client.
|
||||
*
|
||||
* @param[in] remote: volume control target, speaker or microphone
|
||||
* @param[in] volume: gain of the speaker of microphone, ranges 0 to 15
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: disconnect request is sent to lower layer
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_bt_hf_vra(esp_bd_addr_t remote_bda, esp_hf_vr_state_t value);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Volume synchronization with HFP client. As a precondition to use this API,
|
||||
* Service Level Connection shall exist with HFP client
|
||||
*
|
||||
* @param[in] type: volume control target, speaker or microphone
|
||||
* @param[in] volume: gain of the speaker of microphone, ranges 0 to 15
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: disconnect request is sent to lower layer
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_bt_hf_volume_control(esp_bd_addr_t remote_bda, esp_hf_volume_control_target_t type, int volume);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Handle Unknown AT command from HFP Client.
|
||||
* As a precondition to use this API, Service Level Connection shall exist between AG and HF Client
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: disconnect request is sent to lower layer
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_hf_unat_response(esp_bd_addr_t remote_addr, char *unat);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Unsolicited send extend AT error code to HFP Client.
|
||||
* As a precondition to use this API, Service Level Connection shall exist between AG and HF Client
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: disconnect request is sent to lower layer
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_bt_hf_cmee_response(esp_bd_addr_t remote_bda, esp_hf_at_response_code_t response_code, esp_hf_cme_err_t error_code);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Usolicited send device status notificationto HFP Client.
|
||||
* As a precondition to use this API, Service Level Connection shall exist between AG and HF Client
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: disconnect request is sent to lower layer
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_bt_hf_indchange_notification(esp_bd_addr_t remote_addr, esp_hf_call_status_t call_state,
|
||||
esp_hf_call_setup_status_t call_setup_state,
|
||||
esp_hf_network_state_t ntk_state, int signal);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Response to device individual indicatiors to HFP Client.
|
||||
* As a precondition to use this API, Service Level Connection shall exist between AG and HF Client.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: disconnect request is sent to lower layer
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_bt_hf_cind_response(esp_bd_addr_t remote_addr,
|
||||
esp_hf_call_status_t call_state,
|
||||
esp_hf_call_setup_status_t call_setup_state,
|
||||
esp_hf_network_state_t ntk_state, int signal, esp_hf_roaming_status_t roam, int batt_lev,
|
||||
esp_hf_call_held_status_t call_held_status);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Query the name of currently selected network operator in AG,
|
||||
* As a precondition to use this API, Service Level Connection shall exist with HFP Client
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: disconnect request is sent to lower layer
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_bt_hf_cops_response(esp_bd_addr_t remote_addr, char *name);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Response to Query list of current calls from HFP Client (use AT+CLCC command),
|
||||
* As a precondition to use this API, Service Level Connection shall exist between AG and HF Client
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: disconnect request is sent to lower layer
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_bt_hf_clcc_response(esp_bd_addr_t remote_addr, int index, esp_hf_current_call_direction_t dir,
|
||||
esp_hf_current_call_status_t current_call_state, esp_hf_current_call_mode_t mode,
|
||||
esp_hf_current_call_mpty_type_t mpty, char *number, esp_hf_call_addr_type_t type);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Get subscriber information number from HFP client(send AT+CNUM command),
|
||||
* As a precondition to use this API, Service Level Connection shall exist with AG
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: disconnect request is sent to lower layer
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_bt_hf_cnum_response(esp_bd_addr_t remote_addr, char *number, esp_hf_subscriber_service_type_t type);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Inform HF Client of Provided or not Inband Ring Tone.
|
||||
* As a precondition to use this API, Service Level Connection shall exist with AG
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: disconnect request is sent to lower layer
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_bt_hf_bsir(esp_bd_addr_t remote_addr, esp_hf_in_band_ring_state_t state);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Answer Incoming Call by AG or response to the AT+A command from Hands-Free Unit.
|
||||
* As a precondition to use this API, Service Level Connection shall exist with AG.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: disconnect request is sent to lower layer
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_bt_hf_answer_call(esp_bd_addr_t remote_addr, int num_active, int num_held,
|
||||
esp_hf_call_status_t call_state, esp_hf_call_setup_status_t call_setup_state,
|
||||
char *number, esp_hf_call_addr_type_t call_addr_type);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Reject Incoming Call by AG or response to the AT+CHUP command from Hands-Free Unit.
|
||||
* As a precondition to use this API, Service Level Connection shall exist with AG.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: disconnect request is sent to lower layer
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_bt_hf_reject_call(esp_bd_addr_t remote_addr, int num_active, int num_held,
|
||||
esp_hf_call_status_t call_state, esp_hf_call_setup_status_t call_setup_state,
|
||||
char *number, esp_hf_call_addr_type_t call_addr_type);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Reject Incoming Call by AG or response to the AT+CHUP command from Hands-Free Unit.
|
||||
* As a precondition to use this API, Service Level Connection shall exist with AG.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: disconnect request is sent to lower layer
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_bt_hf_out_call(esp_bd_addr_t remote_addr, int num_active, int num_held,
|
||||
esp_hf_call_status_t call_state, esp_hf_call_setup_status_t call_setup_state,
|
||||
char *number, esp_hf_call_addr_type_t call_addr_type);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Reject Incoming Call by AG or response to the AT+CHUP command from Hands-Free Unit.
|
||||
* As a precondition to use this API, Service Level Connection shall exist with AG.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: disconnect request is sent to lower layer
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_bt_hf_end_call(esp_bd_addr_t remote_addr, int num_active, int num_held,
|
||||
esp_hf_call_status_t call_state, esp_hf_call_setup_status_t call_setup_state,
|
||||
char *number, esp_hf_call_addr_type_t call_addr_type);
|
||||
|
||||
/**
|
||||
* @brief Register AG data output function; the callback is only used in
|
||||
* the case that Voice Over HCI is enabled.
|
||||
*
|
||||
* @param[in] recv: HFP client incoming data callback function
|
||||
* @param[in] send: HFP client outgoing data callback function
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: if callback is a NULL function pointer
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_bt_hf_register_data_callback(esp_hf_incoming_data_cb_t recv, esp_hf_outgoing_data_cb_t send);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Trigger the lower-layer to fetch and send audio data. This function is only
|
||||
* only used in the case that Voice Over HCI is enabled. Precondition is that
|
||||
* the HFP audio connection is connected. After this function is called, lower
|
||||
* layer will invoke esp_hf_client_outgoing_data_cb_t to fetch data
|
||||
*
|
||||
*/
|
||||
void esp_hf_outgoing_data_ready(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //__ESP_HF_AG_API_H__
|
||||
@@ -126,7 +126,7 @@ typedef union {
|
||||
* @brief ESP_HF_CLIENT_CIND_SERVICE_AVAILABILITY_EVT
|
||||
*/
|
||||
struct hf_client_service_availability_param {
|
||||
esp_hf_service_availability_status_t status; /*!< service availability status */
|
||||
esp_hf_network_state_t status; /*!< service availability status */
|
||||
} service_availability; /*!< HF callback param of ESP_HF_CLIENT_CIND_SERVICE_AVAILABILITY_EVT */
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,6 +21,44 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ESP_BT_HF_NUMBER_LEN (32)
|
||||
#define ESP_BT_HF_OPERATOR_NAME_LEN (16)
|
||||
|
||||
#ifndef BTC_HSAG_SERVICE_NAME
|
||||
#define BTC_HSAG_SERVICE_NAME ("Headset Gateway")
|
||||
#endif
|
||||
|
||||
#ifndef BTC_HFAG_SERVICE_NAME
|
||||
#define BTC_HFAG_SERVICE_NAME ("Handsfree Gateway")
|
||||
#endif
|
||||
|
||||
#ifndef BTC_HF_SERVICES
|
||||
#define BTC_HF_SERVICES (BTA_HSP_SERVICE_MASK | BTA_HFP_SERVICE_MASK )
|
||||
#endif
|
||||
|
||||
#ifndef BTC_HF_SERVICE_NAMES
|
||||
#define BTC_HF_SERVICE_NAMES {BTC_HSAG_SERVICE_NAME , BTC_HFAG_SERVICE_NAME}
|
||||
#endif
|
||||
|
||||
#ifndef BTC_HF_SECURITY
|
||||
#define BTC_HF_SECURITY (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT)
|
||||
#endif
|
||||
|
||||
#define BTC_HF_CALL_END_TIMEOUT 6
|
||||
|
||||
#define BTC_HF_INVALID_IDX -1
|
||||
|
||||
/// in-band ring tone state
|
||||
typedef enum {
|
||||
ESP_HF_IN_BAND_RINGTONE_NOT_PROVIDED = 0,
|
||||
ESP_HF_IN_BAND_RINGTONE_PROVIDED,
|
||||
} esp_hf_in_band_ring_state_t;
|
||||
|
||||
/// voice recognition state
|
||||
typedef enum {
|
||||
ESP_HF_VR_STATE_DISABLED = 0, /*!< voice recognition disabled */
|
||||
ESP_HF_VR_STATE_ENABLED, /*!< voice recognition enabled */
|
||||
} esp_hf_vr_state_t;
|
||||
|
||||
/// Bluetooth HFP audio volume control target
|
||||
typedef enum {
|
||||
@@ -28,11 +66,32 @@ typedef enum {
|
||||
ESP_HF_VOLUME_CONTROL_TARGET_MIC, /*!< microphone */
|
||||
} esp_hf_volume_control_target_t;
|
||||
|
||||
/// +CIND roaming status indicator values
|
||||
/// Bluetooth HFP audio connection status
|
||||
typedef enum {
|
||||
ESP_HF_ROAMING_STATUS_INACTIVE = 0, /*!< roaming is not active */
|
||||
ESP_HF_ROAMING_STATUS_ACTIVE, /*!< a roaming is active */
|
||||
} esp_hf_roaming_status_t;
|
||||
ESP_HF_AUDIO_STATE_DISCONNECTED = 0, /*!< audio connection released */
|
||||
ESP_HF_AUDIO_STATE_CONNECTING, /*!< audio connection has been initiated */
|
||||
ESP_HF_AUDIO_STATE_CONNECTED, /*!< audio connection is established */
|
||||
ESP_HF_AUDIO_STATE_CONNECTED_MSBC, /*!< mSBC audio connection is established */
|
||||
} esp_hf_audio_state_t;
|
||||
|
||||
typedef enum {
|
||||
ESP_HF_VOLUME_TYPE_SPK = 0,
|
||||
ESP_HF_VOLUME_TYPE_MIC
|
||||
} esp_hf_volume_type_t;
|
||||
|
||||
/// +CIND network service availability status
|
||||
typedef enum
|
||||
{
|
||||
ESP_HF_NETWORK_STATE_NOT_AVAILABLE = 0,
|
||||
ESP_HF_NETWORK_STATE_AVAILABLE
|
||||
} esp_hf_network_state_t;
|
||||
|
||||
/** +CIEV Service type */
|
||||
typedef enum
|
||||
{
|
||||
ESP_HF_SERVICE_TYPE_HOME = 0,
|
||||
ESP_HF_SERVICE_TYPE_ROAMING
|
||||
} esp_hf_service_type_t;
|
||||
|
||||
/// +CIND call status indicator values
|
||||
typedef enum {
|
||||
@@ -42,12 +101,18 @@ typedef enum {
|
||||
|
||||
/// +CIND call setup status indicator values
|
||||
typedef enum {
|
||||
ESP_HF_CALL_SETUP_STATUS_NONE = 0, /*!< no call setup in progress */
|
||||
ESP_HF_CALL_SETUP_STATUS_IDLE = 0, /*!< no call setup in progress */
|
||||
ESP_HF_CALL_SETUP_STATUS_INCOMING = 1, /*!< incoming call setup in progress */
|
||||
ESP_HF_CALL_SETUP_STATUS_OUTGOING_DIALING = 2, /*!< outgoing call setup in dialing state */
|
||||
ESP_HF_CALL_SETUP_STATUS_OUTGOING_ALERTING = 3, /*!< outgoing call setup in alerting state */
|
||||
} esp_hf_call_setup_status_t;
|
||||
|
||||
/// +CIND roaming status indicator values
|
||||
typedef enum {
|
||||
ESP_HF_ROAMING_STATUS_INACTIVE = 0, /*!< roaming is not active */
|
||||
ESP_HF_ROAMING_STATUS_ACTIVE, /*!< a roaming is active */
|
||||
} esp_hf_roaming_status_t;
|
||||
|
||||
/// +CIND call held indicator values
|
||||
typedef enum {
|
||||
ESP_HF_CALL_HELD_STATUS_NONE = 0, /*!< no calls held */
|
||||
@@ -55,12 +120,6 @@ typedef enum {
|
||||
ESP_HF_CALL_HELD_STATUS_HELD = 2, /*!< call on hold, no active call*/
|
||||
} esp_hf_call_held_status_t;
|
||||
|
||||
/// +CIND network service availability status
|
||||
typedef enum {
|
||||
ESP_HF_SERVICE_AVAILABILITY_STATUS_UNAVAILABLE = 0, /*!< service not available */
|
||||
ESP_HF_SERVICE_AVAILABILITY_STATUS_AVAILABLE, /*!< service available */
|
||||
} esp_hf_service_availability_status_t;
|
||||
|
||||
/// +CLCC status of the call
|
||||
typedef enum {
|
||||
ESP_HF_CURRENT_CALL_STATUS_ACTIVE = 0, /*!< active */
|
||||
@@ -118,23 +177,35 @@ typedef enum {
|
||||
ESP_HF_BTRH_CMD_REJECT = 2, /*!< reject a held incoming call */
|
||||
} esp_hf_btrh_cmd_t;
|
||||
|
||||
/// response indication codes for AT commands
|
||||
typedef enum {
|
||||
ESP_HF_AT_RESPONSE_CODE_OK = 0, /*!< acknowledges execution of a command line */
|
||||
ESP_HF_AT_RESPONSE_CODE_ERR, /*!< command not accepted */
|
||||
ESP_HF_AT_RESPONSE_CODE_NO_CARRIER, /*!< connection terminated */
|
||||
ESP_HF_AT_RESPONSE_CODE_BUSY, /*!< busy signal detected */
|
||||
ESP_HF_AT_RESPONSE_CODE_NO_ANSWER, /*!< connection completion timeout */
|
||||
ESP_HF_AT_RESPONSE_CODE_DELAYED, /*!< delayed */
|
||||
ESP_HF_AT_RESPONSE_CODE_BLACKLISTED, /*!< blacklisted */
|
||||
ESP_HF_AT_RESPONSE_CODE_CME, /*!< CME error */
|
||||
} esp_hf_at_response_code_t;
|
||||
/* +NREC */
|
||||
typedef enum
|
||||
{
|
||||
ESP_HF_NREC_STOP = 0,
|
||||
ESP_HF_NREC_START
|
||||
} esp_hf_nrec_t;
|
||||
|
||||
/// voice recognition state
|
||||
///+CCWA resposne status
|
||||
typedef enum {
|
||||
ESP_HF_VR_STATE_DISABLED = 0, /*!< voice recognition disabled */
|
||||
ESP_HF_VR_STATE_ENABLED, /*!< voice recognition enabled */
|
||||
} esp_hf_vr_state_t;
|
||||
ESP_HF_CALL_WAITING_INACTIVE,
|
||||
ESP_HF_CALL_WAITING_ACTIVE,
|
||||
} esp_hf_call_waiting_status_t;
|
||||
|
||||
/* WBS codec setting */
|
||||
typedef enum
|
||||
{
|
||||
ESP_HF_WBS_NONE,
|
||||
ESP_HF_WBS_NO,
|
||||
ESP_HF_WBS_YES
|
||||
}esp_hf_wbs_config_t;
|
||||
|
||||
/// Bluetooth HFP RFCOMM connection and service level connection status
|
||||
typedef enum {
|
||||
ESP_HF_CONNECTION_STATE_DISCONNECTED = 0, /*!< RFCOMM data link channel released */
|
||||
ESP_HF_CONNECTION_STATE_CONNECTING, /*!< connecting remote device on the RFCOMM data link*/
|
||||
ESP_HF_CONNECTION_STATE_CONNECTED, /*!< RFCOMM connection established */
|
||||
ESP_HF_CONNECTION_STATE_SLC_CONNECTED, /*!< service level connection established */
|
||||
ESP_HF_CONNECTION_STATE_DISCONNECTING, /*!< disconnecting with remote device on the RFCOMM data link*/
|
||||
} esp_hf_connection_state_t;
|
||||
|
||||
/// AT+CHLD command values
|
||||
typedef enum {
|
||||
@@ -147,6 +218,24 @@ typedef enum {
|
||||
ESP_HF_CHLD_TYPE_PRIV_X, /*!< <2x>, request private consultation mode with specified call */
|
||||
} esp_hf_chld_type_t;
|
||||
|
||||
/* AT response code - OK/Error */
|
||||
typedef enum {
|
||||
ESP_HF_AT_RESPONSE_CODE_OK = 0, /*!< acknowledges execution of a command line */
|
||||
ESP_HF_AT_RESPONSE_CODE_ERR, /*!< command not accepted */
|
||||
ESP_HF_AT_RESPONSE_CODE_NO_CARRIER, /*!< connection terminated */
|
||||
ESP_HF_AT_RESPONSE_CODE_BUSY, /*!< busy signal detected */
|
||||
ESP_HF_AT_RESPONSE_CODE_NO_ANSWER, /*!< connection completion timeout */
|
||||
ESP_HF_AT_RESPONSE_CODE_DELAYED, /*!< delayed */
|
||||
ESP_HF_AT_RESPONSE_CODE_BLACKLISTED, /*!< blacklisted */
|
||||
ESP_HF_AT_RESPONSE_CODE_CME, /*!< CME error */
|
||||
} esp_hf_at_response_code_t;
|
||||
|
||||
/* AT response code - OK/Error */
|
||||
typedef enum {
|
||||
ESP_HF_AT_RESPONSE_ERROR = 0,
|
||||
ESP_HF_AT_RESPONSE_OK
|
||||
} esp_hf_at_response_t;
|
||||
|
||||
/// Extended Audio Gateway Error Result Code Response
|
||||
typedef enum {
|
||||
ESP_HF_CME_AG_FAILURE = 0, /*!< ag failure */
|
||||
@@ -174,6 +263,84 @@ typedef enum {
|
||||
ESP_HF_CME_NETWORK_NOT_ALLOWED = 32, /*!< network not allowed --emergency calls only */
|
||||
} esp_hf_cme_err_t;
|
||||
|
||||
/** Callback for connection state change.
|
||||
* state will have one of the values from BtHfConnectionState
|
||||
*/
|
||||
typedef void (* esp_hf_connection_state_callback)(esp_hf_connection_state_t state, esp_bd_addr_t *bd_addr);
|
||||
|
||||
/** Callback for audio connection state change.
|
||||
* state will have one of the values from BtHfAudioState
|
||||
*/
|
||||
typedef void (* esp_hf_audio_state_callback)(esp_hf_audio_state_t state, esp_bd_addr_t *bd_addr);
|
||||
|
||||
/** Callback for VR connection state change.
|
||||
* state will have one of the values from BtHfVRState
|
||||
*/
|
||||
typedef void (* esp_hf_vr_cmd_callback)(esp_hf_vr_state_t state, esp_bd_addr_t *bd_addr);
|
||||
|
||||
/** Callback for answer incoming call (ATA)
|
||||
*/
|
||||
typedef void (* esp_hf_answer_call_cmd_callback)(esp_bd_addr_t *bd_addr);
|
||||
|
||||
/** Callback for disconnect call (AT+CHUP)
|
||||
*/
|
||||
typedef void (* esp_hf_hangup_call_cmd_callback)(esp_bd_addr_t *bd_addr);
|
||||
|
||||
/** Callback for disconnect call (AT+CHUP)
|
||||
* type will denote Speaker/Mic gain (BtHfVolumeControl).
|
||||
*/
|
||||
typedef void (* esp_hf_volume_cmd_callback)(esp_hf_volume_control_target_t type, int volume, esp_bd_addr_t *bd_addr);
|
||||
|
||||
/** Callback for dialing an outgoing call
|
||||
* If number is NULL, redial
|
||||
*/
|
||||
typedef void (* esp_hf_dial_call_cmd_callback)(char *number, esp_bd_addr_t *bd_addr);
|
||||
|
||||
/** Callback for sending DTMF tones
|
||||
* tone contains the dtmf character to be sent
|
||||
*/
|
||||
typedef void (* esp_hf_dtmf_cmd_callback)(char tone, esp_bd_addr_t *bd_addr);
|
||||
|
||||
/** Callback for enabling/disabling noise reduction/echo cancellation
|
||||
* value will be 1 to enable, 0 to disable
|
||||
*/
|
||||
typedef void (* esp_hf_nrec_cmd_callback)(esp_hf_nrec_t nrec, esp_bd_addr_t *bd_addr);
|
||||
|
||||
/** Callback for AT+BCS and event from BAC
|
||||
* WBS enable, WBS disable
|
||||
*/
|
||||
typedef void (* esp_hf_wbs_callback)(esp_hf_wbs_config_t wbs, esp_bd_addr_t *bd_addr);
|
||||
|
||||
/** Callback for call hold handling (AT+CHLD)
|
||||
* value will contain the call hold command (0, 1, 2, 3)
|
||||
*/
|
||||
typedef void (* esp_hf_chld_cmd_callback)(esp_hf_chld_type_t chld, esp_bd_addr_t *bd_addr);
|
||||
|
||||
/** Callback for CNUM (subscriber number)
|
||||
*/
|
||||
typedef void (* esp_hf_cnum_cmd_callback)(esp_bd_addr_t *bd_addr);
|
||||
|
||||
/** Callback for indicators (CIND)
|
||||
*/
|
||||
typedef void (* esp_hf_cind_cmd_callback)(esp_bd_addr_t *bd_addr);
|
||||
|
||||
/** Callback for operator selection (COPS)
|
||||
*/
|
||||
typedef void (* esp_hf_cops_cmd_callback)(esp_bd_addr_t *bd_addr);
|
||||
|
||||
/** Callback for call list (AT+CLCC)
|
||||
*/
|
||||
typedef void (* esp_hf_clcc_cmd_callback) (esp_bd_addr_t *bd_addr);
|
||||
|
||||
/** Callback for unknown AT command recd from AG
|
||||
* at_string will contain the unparsed AT string
|
||||
*/
|
||||
typedef void (* esp_hf_unknown_at_cmd_callback)(char *at_string, esp_bd_addr_t *bd_addr);
|
||||
|
||||
/** Callback for keypressed (HSP) event.
|
||||
*/
|
||||
typedef void (* esp_hf_key_pressed_cmd_callback)(esp_bd_addr_t *bd_addr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user