Files
99_7018_lmx/apps/earphone/bt_emitter.c
2025-10-29 13:10:02 +08:00

1219 lines
35 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*************************************************************
此文件函数主要是蓝牙发射器接口处理
1、关于AG对讲功能使用说明
发射器需要通过user_emitter_cmd_prepare接口来给接收器发送命令,例如:
(1)发射器主动发起通话,发起通话前需要暂停高级音频
user_emitter_cmd_prepare(USER_CTRL_HFP_CALL_LAST_NO, 0, NULL)
(2)发射器主动关断通话
user_emitter_cmd_prepare(USER_CTRL_HFP_CALL_HANGUP, 0, NULL)
(3)接收器来电接听
user_emitter_cmd_prepare(USER_CTRL_HFP_CALL_ANSWER, 0, NULL)
**************************************************************/
#include "system/app_core.h"
#include "system/includes.h"
#include "app_config.h"
#include "app_task.h"
#include "btstack/btstack_task.h"
#include "btcontroller_modules.h"
#include "btstack/avctp_user.h"
#include "classic/hci_lmp.h"
#include "earphone.h"
#include "bt_emitter.h"
#include "user_cfg.h"
#include "vm.h"
#include "app_main.h"
/* #include "common/app_common.h" */
#include "key_event_deal.h"
#include "rcsp_bluetooth.h"
#include "media/includes.h"
#include "audio_config.h"
#include "audio_digital_vol.h"
#include "audio_enc.h"
/* #include "audio_enc_transmitter.h" */
#include "media/file_decoder.h"
#include "music/music_player.h"
#if TCFG_USER_EMITTER_ENABLE
#define LOG_TAG_CONST EARPHONE
#define LOG_TAG "[EARPHONE]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_DUMP_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
#define SEARCH_BD_ADDR_LIMITED 0
#define SEARCH_BD_NAME_LIMITED 1
#define SEARCH_CUSTOM_LIMITED 2
#define SEARCH_NULL_LIMITED 3
#define SEARCH_LIMITED_MODE SEARCH_BD_NAME_LIMITED
#define SEARCH_NAME_DEBUG 0
#define HOWLING_ENABLE 0
struct remote_name {
u16 crc;
u8 addr[6];
u8 name[32];
};
struct list_head inquiry_noname_list;
struct inquiry_noname_remote {
struct list_head entry;
u8 match;
s8 rssi;
u8 addr[6];
u32 class;
};
extern int music_player_get_play_status(void);
extern int music_player_pp(void);
extern u16 get_emitter_curr_channel_state();
static u8 read_name_start = 0;
static u8 bt_search_busy = 0;
static u8 search_spp_device = 0;
static u8 emitter_dac_mute_en = 0;
static u8 bt_emitter_start = 0;
void bt_emitter_audio_set_mute(u8 mute)
{
emitter_dac_mute_en = !!mute;
}
/*----------------------------------------------------------------------------*/
/**@brief 音频数据清0
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
int audio_data_set_zero(struct audio_stream_entry *entry, struct audio_data_frame *data_buf)
{
if (emitter_dac_mute_en) {
memset(data_buf->data, 0, data_buf->data_len);
}
return 0;
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射发起搜索设备
@param 无
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
void bt_search_device(void)
{
if (!get_bt_init_status()) {
log_info("bt on init >>>>>>>>>>>>>>>>>>>>>>>\n");
return;
}
if (bt_search_busy) {
log_info("bt_search_busy >>>>>>>>>>>>>>>>>>>>>>>\n");
//return;
}
user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_DISABLE, 0, NULL);
user_send_cmd_prepare(USER_CTRL_WRITE_CONN_DISABLE, 0, NULL);
read_name_start = 0;
bt_search_busy = 1;
u8 inquiry_length = 20; // inquiry_length * 1.28s
user_send_cmd_prepare(USER_CTRL_SEARCH_DEVICE, 1, &inquiry_length);
log_info("bt_search_start >>>>>>>>>>>>>>>>>>>>>>>\n");
}
/* ***************************************************************************/
/** @brief :蓝牙发射 提供搜索连接spp设备功能
@param :无
@return :无
@note
*/
/* ***************************************************************************/
void bt_search_spp_device()
{
search_spp_device = 1;
set_start_search_spp_device(1);
bt_search_device();
}
/* ***************************************************************************/
/** @brief :蓝牙发射 搜索设备状态
@param :无
@return :无
@note
*/
/* ***************************************************************************/
u8 bt_search_status()
{
return bt_search_busy;
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射 提供按键断开连接和恢复连接
@param 无
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
void emitter_connect_switch()
{
if (get_emitter_curr_channel_state() != 0) {
user_send_cmd_prepare(USER_CTRL_POWER_OFF, 0, NULL);
while (hci_standard_connect_check() != 0) {
//wait disconnect;
os_time_dly(10);
}
} else {
/* log_info("start connect vm addr\n"); */
user_send_cmd_prepare(USER_CTRL_START_CONNEC_VIA_ADDR_MANUALLY, 0, NULL);
}
}
u8 bt_emitter_role_get()
{
return bt_user_priv_var.emitter_or_receiver;
}
/* ***************************************************************************/
/** @brief :蓝牙发射 取消搜索
@param :无
@return :无
@note
*/
/* ***************************************************************************/
void bt_emitter_stop_search_device()
{
user_send_cmd_prepare(USER_CTRL_INQUIRY_CANCEL, 0, NULL);
}
/* ***************************************************************************/
/** @brief :蓝牙发射 连接指定mac设备
@param mac
@return :无
@note
*/
/* ***************************************************************************/
void emitter_bt_connect(u8 *mac)
{
if (bt_user_priv_var.emitter_or_receiver != BT_EMITTER_EN) {
return ;
}
while (hci_standard_connect_check() == 0x80) {
//wait profile connect ok;
if (get_emitter_curr_channel_state()) {
break;
}
os_time_dly(10);
}
////断开链接
if (get_emitter_curr_channel_state() != 0) {
user_send_cmd_prepare(USER_CTRL_POWER_OFF, 0, NULL);
} else {
if (hci_standard_connect_check()) {
user_send_cmd_prepare(USER_CTRL_PAGE_CANCEL, 0, NULL);
user_send_cmd_prepare(USER_CTRL_CONNECTION_CANCEL, 0, NULL);
}
}
/* if there are some connected channel ,then disconnect*/
while (hci_standard_connect_check() != 0) {
//wait disconnect;
os_time_dly(10);
}
user_send_cmd_prepare(USER_CTRL_START_CONNEC_VIA_ADDR, 6, mac);
}
/* ***************************************************************************/
/** @brief :蓝牙发射 开始搜索设备
@param :无
@return :无
@note
*/
/* ***************************************************************************/
void bt_emitter_start_search_device()
{
if (bt_user_priv_var.emitter_or_receiver != BT_EMITTER_EN) {
return ;
}
while (hci_standard_connect_check() == 0x80) {
//wait profile connect ok;
if (get_emitter_curr_channel_state()) {
break;
}
os_time_dly(10);
}
////断开链接
if (get_emitter_curr_channel_state() != 0) {
user_send_cmd_prepare(USER_CTRL_POWER_OFF, 0, NULL);
} else {
if (hci_standard_connect_check()) {
user_send_cmd_prepare(USER_CTRL_PAGE_CANCEL, 0, NULL);
user_send_cmd_prepare(USER_CTRL_CONNECTION_CANCEL, 0, NULL);
}
}
/* if there are some connected channel ,then disconnect*/
while (hci_standard_connect_check() != 0) {
//wait disconnect;
os_time_dly(10);
}
////关闭可发现可链接
user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_DISABLE, 0, NULL);
user_send_cmd_prepare(USER_CTRL_WRITE_CONN_DISABLE, 0, NULL);
////切换样机状态
bt_search_device();
}
////回链耳机音箱
u8 connect_last_sink_device_from_vm()
{
bd_addr_t mac_addr;
u8 flag = 0;
flag = restore_remote_device_info_profile(&mac_addr, 1, get_remote_dev_info_index(), REMOTE_SINK);
if (flag) {
//connect last conn
printf("last source device addr from vm:");
put_buf(mac_addr, 6);
user_send_cmd_prepare(USER_CTRL_START_CONNEC_VIA_ADDR, 6, mac_addr);
}
//r_printf("connect last vm addr\n");
return flag;
}
////回链手机
u8 connect_last_source_device_from_vm()
{
bd_addr_t mac_addr;
u8 flag = 0;
flag = restore_remote_device_info_profile(&mac_addr, 1, get_remote_dev_info_index(), REMOTE_SOURCE);
if (flag) {
//connect last conn
printf("last source device addr from vm:");
put_buf(mac_addr, 6);
user_send_cmd_prepare(USER_CTRL_START_CONNEC_VIA_ADDR, 6, mac_addr);
}
//r_printf("connect last vm addr\n");
return flag;
}
////自动调用,同步最大音量
void the_first_time_set_vol_change()
{
user_emitter_cmd_prepare(USER_CTRL_AVCTP_OPID_SEND_VOL, 0, NULL);//同步音量
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射 提供按键切换发射器或者是音箱功能
@param 1:发射 0接收
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
void emitter_or_receiver_switch(u8 flag)
{
printf("===emitter_or_receiver_switch %d %x\n", flag, hci_standard_connect_check());
/*如果上一次操作记录跟传进来的参数一致,则不操作*/
if (bt_user_priv_var.emitter_or_receiver == flag) {
return ;
}
while (hci_standard_connect_check() == 0x80) {
//wait profile connect ok;
if (bt_user_priv_var.emitter_or_receiver == BT_EMITTER_EN) { ///蓝牙发射器
r_printf("cur_ch:0x%x", get_emitter_curr_channel_state());
if (get_emitter_curr_channel_state()) {
break;
}
} else {
r_printf("cur_ch:0x%x", get_curr_channel_state());
if (get_emitter_curr_channel_state()) {
break;
}
}
os_time_dly(10);
}
////断开链接
if ((get_curr_channel_state() != 0) || (get_emitter_curr_channel_state() != 0)) {
user_send_cmd_prepare(USER_CTRL_POWER_OFF, 0, NULL);
} else {
if (hci_standard_connect_check()) {
user_send_cmd_prepare(USER_CTRL_PAGE_CANCEL, 0, NULL);
user_send_cmd_prepare(USER_CTRL_CONNECTION_CANCEL, 0, NULL);
}
}
/* if there are some connected channel ,then disconnect*/
while (hci_standard_connect_check() != 0) {
//wait disconnect;
os_time_dly(10);
}
g_printf("===wait to switch to mode %d\n", flag);
bt_user_priv_var.emitter_or_receiver = flag;
if (flag == BT_EMITTER_EN) { ///蓝牙发射器
/* bredr_bulk_change(0); */
////关闭可发现可链接
user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_DISABLE, 0, NULL);
user_send_cmd_prepare(USER_CTRL_WRITE_CONN_DISABLE, 0, NULL);
////切换样机状态
__set_emitter_enable_flag(1);
a2dp_source_init(NULL, 0, 1);
#if (USER_SUPPORT_PROFILE_HFP_AG==1)
hfp_ag_buf_init(NULL, 0, 1);
#endif
////开启搜索设备
if (connect_last_sink_device_from_vm()) {
log_info("start connect device vm addr\n");
} else {
bt_search_device();
}
} else if (flag == BT_RECEIVER_EN) { ///蓝牙接收
/* bredr_bulk_change(1); */
////切换样机状态
__set_emitter_enable_flag(0);
emitter_media_source(NULL, 1, 0);
hci_cancel_inquiry();
a2dp_source_init(NULL, 0, 0);
#if (USER_SUPPORT_PROFILE_HFP_AG==1)
hfp_ag_buf_init(NULL, 0, 0);
#endif
////开启可发现可链接
if (connect_last_source_device_from_vm()) {
log_info("start connect vm addr phone \n");
} else {
user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_ENABLE, 0, NULL);
user_send_cmd_prepare(USER_CTRL_WRITE_CONN_ENABLE, 0, NULL);
}
}
}
/* ***************************************************************************/
/** @brief :蓝牙发射 自动选择发射器与接收器模式
@param :无
@return :无
@note
*/
/* ***************************************************************************/
void bt_emitter_receiver_sw()
{
if (bt_user_priv_var.emitter_or_receiver != BT_EMITTER_EN) {
emitter_or_receiver_switch(BT_EMITTER_EN);
} else {
emitter_or_receiver_switch(BT_RECEIVER_EN);
}
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射变量初始化
@param 无
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
void bt_emitter_init()
{
bt_emitter_start = 1;
INIT_LIST_HEAD(&inquiry_noname_list);
lmp_set_sniff_establish_by_remote(1);
/* audio_sbc_enc_init(); */
#ifdef MEDIA_CODEC_TYPE_SWITCH
__set_support_non_a2dp_flag(1);
#endif
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射搜索设备没有名字的设备,放进需要获取名字链表
@param status : 获取成功 0获取失败
addr:设备地址
name设备名字
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
void emitter_search_noname(u8 status, u8 *addr, u8 *name)
{
struct inquiry_noname_remote *remote, *n;
if (!bt_emitter_start) {
return ;
}
u8 res = 0;
local_irq_disable();
if (status) {
list_for_each_entry_safe(remote, n, &inquiry_noname_list, entry) {
if (!memcmp(addr, remote->addr, 6)) {
list_del(&remote->entry);
free(remote);
}
}
goto __find_next;
}
list_for_each_entry_safe(remote, n, &inquiry_noname_list, entry) {
if (!memcmp(addr, remote->addr, 6)) {
res = emitter_search_result(name, strlen(name), addr, remote->class, remote->rssi);
if (res) {
read_name_start = 0;
remote->match = 1;
user_send_cmd_prepare(USER_CTRL_INQUIRY_CANCEL, 0, NULL);
local_irq_enable();
return;
}
list_del(&remote->entry);
free(remote);
}
}
__find_next:
read_name_start = 0;
remote = NULL;
if (!list_empty(&inquiry_noname_list)) {
remote = list_first_entry(&inquiry_noname_list, struct inquiry_noname_remote, entry);
}
local_irq_enable();
if (remote) {
read_name_start = 1;
user_send_cmd_prepare(USER_CTRL_READ_REMOTE_NAME, 6, remote->addr);
}
}
void remote_name_speciali_deal(u8 status, u8 *addr, u8 *name)
{
emitter_search_noname(status, addr, name);
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射停止搜索
@param 无
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
void emitter_search_stop(u8 result)
{
struct inquiry_noname_remote *remote, *n;
bt_search_busy = 0;
search_spp_device = 0;
set_start_search_spp_device(0);
u8 wait_connect_flag = 1;
if (!list_empty(&inquiry_noname_list)) {
user_send_cmd_prepare(USER_CTRL_PAGE_CANCEL, 0, NULL);
}
if (!result) {
list_for_each_entry_safe(remote, n, &inquiry_noname_list, entry) {
if (remote->match) {
user_send_cmd_prepare(USER_CTRL_START_CONNEC_VIA_ADDR, 6, remote->addr);
wait_connect_flag = 0;
}
list_del(&remote->entry);
free(remote);
}
}
read_name_start = 0;
if (wait_connect_flag) {
/* log_info("wait conenct\n"); */
#if TCFG_SPI_LCD_ENABLE
user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_DISABLE, 0, NULL);
user_send_cmd_prepare(USER_CTRL_WRITE_CONN_DISABLE, 0, NULL);
#else
user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_DISABLE, 0, NULL);
if (!result) {
user_send_cmd_prepare(USER_CTRL_WRITE_CONN_ENABLE, 0, NULL);
}
#endif
}
}
#if (SEARCH_LIMITED_MODE == SEARCH_BD_ADDR_LIMITED)
u8 bd_addr_filt[][6] = {
{0x8E, 0xA7, 0xCA, 0x0A, 0x5E, 0xC8}, /*S10_H*/
{0xA7, 0xDD, 0x05, 0xDD, 0x1F, 0x00}, /*ST-001*/
{0xE9, 0x73, 0x13, 0xC0, 0x1F, 0x00}, /*HBS 730*/
{0x38, 0x7C, 0x78, 0x1C, 0xFC, 0x02}, /*Bluetooth*/
};
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射搜索通过地址过滤
@param 无
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
u8 search_bd_addr_filt(u8 *addr)
{
u8 i;
log_info("bd_addr:");
log_info_hexdump(addr, 6);
for (i = 0; i < (sizeof(bd_addr_filt) / sizeof(bd_addr_filt[0])); i++) {
if (memcmp(addr, bd_addr_filt[i], 6) == 0) {
/* printf("bd_addr match:%d\n", i); */
return TRUE;
}
}
/*log_info("bd_addr not match\n"); */
return FALSE;
}
#endif
#if (SEARCH_LIMITED_MODE == SEARCH_BD_NAME_LIMITED)
#if (0)
u8 bd_name_filt[][32] = {
"BeMine",
"EDIFIER CSR8635",/*CSR*/
"JL-BT-SDK",/*Realtek*/
"I7-TWS",/*ZKLX*/
"TWS-i7",/*ZKLX*/
"I9",/*ZKLX*/
"小米小钢炮蓝牙音箱",/*XiaoMi*/
"小米蓝牙音箱",/*XiaoMi*/
"XMFHZ02",/*XiaoMi*/
"JBL GO 2",
"i7mini",/*JL tws AC690x*/
"S08U",
"AI8006B_TWS00",
"S046",/*BK*/
"AirPods",
"CSD-TWS-01",
"AC692X_wh",
"JBL GO 2",
"JBL Flip 4",
"BT Speaker",
"CSC608",
"QCY-QY19",
"Newmine",
"HT1+",
"S-35",
"T12-JL",
"Redmi AirDots_R",
"Redmi AirDots_L",
"AC69_Bluetooth",
"FlyPods 3",
"MNS",
"Jam Heavy Metal",
"Bluedio",
"HR-686",
"BT MUSIC",
"BW-USB-DONGLE",
"S530",
"XPDQ7",
"MICGEEK Q9S",
"S10_H",
"S10",/*JL AC690x*/
"S11",/*JL AC460x*/
"HBS-730",
"SPORT-S9",
"Q5",
"IAEB25",
"T5-JL",
"MS-808",
"LG HBS-730",
"NG-BT07"
};
#else
u8 bd_name_filt[20][30] = {
"TG-294",
"Shanling UP4",
"Jabra Elite 65t",
"JBL GO",
"G02",
};
#endif
u8 bd_spp_name_filt[20][30] = {
"AC69_BT_SDK",
};
extern const char *bt_get_emitter_connect_name();
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射搜索通过名字过滤
@param 无
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
u8 search_bd_name_filt(char *data, u8 len, u32 dev_class, char rssi)
{
char bd_name[64] = {0};
u8 i;
char *targe_name = NULL;
char char_a = 0, char_b = 0;
if ((len > (sizeof(bd_name))) || (len == 0)) {
//printf("bd_name_len error:%d\n", len);
return FALSE;
}
memset(bd_name, 0, sizeof(bd_name));
memcpy(bd_name, data, len);
log_info("33name:%s,len:%d,class %x ,rssi %d\n", bd_name, len, dev_class, rssi);
#if SEARCH_NAME_DEBUG
extern char *get_edr_name(void);
printf("tar name:%s,len:%d\n", get_edr_name(), strlen(get_edr_name()));
targe_name = (char *)get_edr_name();
#if 1
//不区分大小写
for (i = 0; i < len; i++) {
char_a = bd_name[i];
char_b = targe_name[i];
if ('A' <= char_a && char_a <= 'Z') {
char_a += 32; //转换成小写
}
if ('A' <= char_b && char_b <= 'Z') {
char_b += 32; //转换成小写
}
printf("{%d-%d}", char_a, char_b);
if (char_a != char_b) {
return FALSE;
}
}
log_info("\n*****find dev ok******\n");
return TRUE;
#else
//区分大小写
if (memcmp(data, bt_get_emitter_connect_name(), len) == 0) {
log_info("\n*****find dev ok******\n");
return TRUE;
}
return FALSE;
#endif
#else
if (search_spp_device) {
for (i = 0; i < (sizeof(bd_spp_name_filt) / sizeof(bd_spp_name_filt[0])); i++) {
if (memcmp(data, bd_spp_name_filt[i], len) == 0) {
puts("\n*****find dev ok******\n");
return TRUE;
}
}
} else {
for (i = 0; i < (sizeof(bd_name_filt) / sizeof(bd_name_filt[0])); i++) {
if (memcmp(data, bd_name_filt[i], len) == 0) {
puts("\n*****find dev ok******\n");
return TRUE;
}
}
}
return FALSE;
#endif
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射搜索结果回调处理
@param name : 设备名字
name_len: 设备名字长度
addr: 设备地址
dev_class: 设备类型
rssi: 设备信号强度
@return 无
@note
蓝牙设备搜索结果,可以做名字/地址过滤,也可以保存搜到的所有设备
在选择一个进行连接,获取其他你想要的操作。
返回TRUE表示搜到指定的想要的设备搜索结束直接连接当前设备
返回FALSE则继续搜索直到搜索完成或者超时
*/
/*----------------------------------------------------------------------------*/
u8 emitter_search_result(char *name, u8 name_len, u8 *addr, u32 dev_class, char rssi)
{
#if (SEARCH_LIMITED_MODE == SEARCH_BD_NAME_LIMITED)
if (name == NULL) {
struct inquiry_noname_remote *remote = malloc(sizeof(struct inquiry_noname_remote));
remote->match = 0;
remote->class = dev_class;
remote->rssi = rssi;
memcpy(remote->addr, addr, 6);
local_irq_disable();
list_add_tail(&remote->entry, &inquiry_noname_list);
local_irq_enable();
if (read_name_start == 0) {
read_name_start = 1;
user_send_cmd_prepare(USER_CTRL_READ_REMOTE_NAME, 6, addr);
}
}
#endif
#if (SEARCH_LIMITED_MODE == SEARCH_BD_NAME_LIMITED)
return search_bd_name_filt(name, name_len, dev_class, rssi);
#endif
#if (SEARCH_LIMITED_MODE == SEARCH_BD_ADDR_LIMITED)
return search_bd_addr_filt(addr);
#endif
#if (SEARCH_LIMITED_MODE == SEARCH_CUSTOM_LIMITED)
/*以下为搜索结果自定义处理*/
char bt_name[63] = {0};
u8 len;
if (name_len == 0) {
log_info("No_eir\n");
} else {
len = (name_len > 63) ? 63 : name_len;
/* display bd_name */
memcpy(bt_name, name, len);
log_info("22name:%s,len:%d,class %x ,rssi %d\n", bt_name, name_len, dev_class, rssi);
}
/* display bd_addr */
log_debug_hexdump(addr, 6);
/* You can connect the specified bd_addr by below api */
//user_send_cmd_prepare(USER_CTRL_START_CONNEC_VIA_ADDR,6,addr);
return FALSE;
#endif
#if (SEARCH_LIMITED_MODE == SEARCH_NULL_LIMITED)
/*没有指定限制,则搜到什么就连接什么*/
return TRUE;
#endif
}
typedef enum {
AVCTP_OPID_VOLUME_UP = 0x41,
AVCTP_OPID_VOLUME_DOWN = 0x42,
AVCTP_OPID_MUTE = 0x43,
AVCTP_OPID_PLAY = 0x44,
AVCTP_OPID_STOP = 0x45,
AVCTP_OPID_PAUSE = 0x46,
AVCTP_OPID_NEXT = 0x4B,
AVCTP_OPID_PREV = 0x4C,
} AVCTP_CMD_TYPE;
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射接收到设备按键消息
@param cmd:按键命令
@return 无
@note
发射器收到接收器发过来的控制命令处理
根据实际需求可以在收到控制命令之后做相应的处理
蓝牙库里面定义的是weak函数直接再定义一个同名可获取信息
*/
/*----------------------------------------------------------------------------*/
void emitter_rx_avctp_opid_deal(u8 cmd, u8 id)
{
/* log_debug("avctp_rx_cmd:%x\n", cmd); */
switch (cmd) {
case AVCTP_OPID_NEXT:
log_info("AVCTP_OPID_NEXT\n");
app_task_put_key_msg(KEY_MUSIC_NEXT, 0);
break;
case AVCTP_OPID_PREV:
log_info("AVCTP_OPID_PREV\n");
app_task_put_key_msg(KEY_MUSIC_PREV, 0);
break;
case AVCTP_OPID_PAUSE:
case AVCTP_OPID_STOP:
log_info("AVCTP_OPID_PAUSE\n");
/* bt_emitter_pp(0); */
app_task_put_key_msg(KEY_MUSIC_PP, 0);
break;
case AVCTP_OPID_PLAY:
/* bt_emitter_pp(1); */
app_task_put_key_msg(KEY_MUSIC_PP, 0);
log_info("AVCTP_OPID_PP\n");
break;
case AVCTP_OPID_VOLUME_UP:
log_info("AVCTP_OPID_VOLUME_UP\n");
app_task_put_key_msg(KEY_VOL_UP, 0);
break;
case AVCTP_OPID_VOLUME_DOWN:
log_info("AVCTP_OPID_VOLUME_DOWN\n");
app_task_put_key_msg(KEY_VOL_DOWN, 0);
break;
default:
break;
}
return ;
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射接收设备同步音量
@param vol:接收到设备同步音量
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
void emitter_rx_vol_change(u8 vol)
{
/* log_info("vol_change:%d \n", vol); */
}
typedef struct _EMITTER_INFO {
volatile u8 role;
u8 media_source;
u8 source_record;/*统计当前有多少设备可用*/
u8 reserve;
} EMITTER_INFO_T;
EMITTER_INFO_T emitter_info = {
.role = 0/*EMITTER_ROLE_SLAVE*/,
};
void emitter_open(u8 source)
{
emitter_info.source_record |= source;
if (emitter_info.media_source == source) {
return;
}
emitter_info.media_source = source;
__emitter_send_media_toggle(NULL, 1);
}
void emitter_close(u8 source)
{
if (music_player_get_play_status() == FILE_DEC_STATUS_PLAY) {
music_player_pp();
}
emitter_info.source_record &= ~source;
if (emitter_info.media_source == source) {
emitter_info.media_source = 0/*EMITTER_SOURCE_NULL*/;
__emitter_send_media_toggle(NULL, 0);
//emitter_media_source_next();
}
while (bt_emitter_stu_get()) {
os_time_dly(2);
putchar('K');
}
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射接收设备同步音量
@param source: 高级音频角色 1source 0sink
en:关闭source
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
void emitter_media_source(u8 *addr, u8 source, u8 en)
{
if (en) {
/*关闭当前的source通道*/
//emitter_media_source_close(emitter_info.media_source);
if (music_player_get_play_status() != FILE_DEC_STATUS_PLAY) {
music_player_pp();
}
emitter_info.source_record |= source;
if (emitter_info.media_source == source) {
return;
}
emitter_info.media_source = source;
__emitter_send_media_toggle(NULL, 1);
} else {
if (music_player_get_play_status() == FILE_DEC_STATUS_PLAY) {
music_player_pp();
}
emitter_info.source_record &= ~source;
if (emitter_info.media_source == source) {
emitter_info.media_source = 0/*EMITTER_SOURCE_NULL*/;
__emitter_send_media_toggle(NULL, 0);
//emitter_media_source_next();
}
}
log_info("current source: %x-%x\n", source, emitter_info.source_record);
}
#endif
/* ***************************************************************************/
/** @brief :蓝牙发射 获取音频发射状态
@param :无
@return 1:开启状态2关闭状态
@note
*/
/* ***************************************************************************/
u8 bt_emitter_stu_get(void)
{
return 0;//audio_sbc_enc_is_work();//bt_emitter_on;
}
u8 bt_emitter_stu_set(u8 *addr, u8 on)
{
if (bt_user_priv_var.emitter_or_receiver != BT_EMITTER_EN) {
return 0;
}
if (!(get_emitter_curr_channel_state() & A2DP_SRC_CH)) {
emitter_media_source(NULL, 1, 0);
return 0;
}
log_debug("total con dev:%d ", get_total_connect_dev());
if (on && (get_total_connect_dev() == 0)) {
on = 0;
}
/* bt_emitter_on = on; */
emitter_media_source(NULL, 1, on);
return on;
}
/* ***************************************************************************/
/** @brief :蓝牙发射 高级音频发射开关
@param pp 1开启0关闭
@return :无
@note
*/
/* ***************************************************************************/
u8 bt_emitter_pp(u8 pp)
{
if (bt_user_priv_var.emitter_or_receiver != BT_EMITTER_EN) {
return 0;
}
if (get_total_connect_dev() == 0) {
//如果没有连接就启动一下搜索
/* bt_search_device(); */
return 0;
}
if (!(get_emitter_curr_channel_state() & A2DP_SRC_CH)) {
return 0;
}
return bt_emitter_stu_set(NULL, pp);
}
u8 bt_emitter_stu_sw(void)
{
return bt_emitter_pp(!bt_emitter_stu_get());
}
////////////////////////////////////////////////////////////////////////
//pin code 轮询功能
const char pin_code_list[10][4] = {
{'0', '0', '0', '0'},
{'1', '2', '3', '4'},
{'8', '8', '8', '8'},
{'1', '3', '1', '4'},
{'4', '3', '2', '1'},
{'1', '1', '1', '1'},
{'2', '2', '2', '2'},
{'3', '3', '3', '3'},
{'5', '6', '7', '8'},
{'5', '5', '5', '5'}
};
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射链接pincode 轮询
@param 无
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
const char *bt_get_emitter_pin_code(u8 flag)
{
static u8 index_flag = 0;
int pincode_num = sizeof(pin_code_list) / sizeof(pin_code_list[0]);
if (flag == 1) {
//reset index
index_flag = 0;
} else if (flag == 2) {
//查询是否要开始继续回连尝试pin code。
if (index_flag >= pincode_num) {
//之前已经遍历完了
return NULL;
} else {
index_flag++; //准备使用下一个
}
} else {
/* log_debug("get pin code index %d\n", index_flag); */
}
return &pin_code_list[index_flag][0];
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射链接保存远端设备名字
@param addr:远端设备地址
name:远端设备名字
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
void emitter_save_remote_name(u8 *addr, u8 *name)
{
struct remote_name remote_n;
u16 id = CFG_REMOTE_DN_00;
while (1) {
syscfg_read(id, &remote_n, sizeof(struct remote_name));
if (remote_n.crc == CRC16((u8 *)&remote_n.addr, sizeof(struct remote_name) - 2)) {
if (!memcmp(addr, remote_n.addr, 6)) {
return;
}
} else {
break;
}
id++;
if (id >= 20) {
break;
}
}
memset(&remote_n, 0, sizeof(struct remote_name));
memcpy(remote_n.addr, addr, 6);
memcpy(remote_n.name, name, strlen(name));
remote_n.crc = CRC16((u8 *)&remote_n.addr, sizeof(struct remote_name) - 2);
syscfg_write(id, &remote_n, sizeof(struct remote_name));
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射通过地址来获取设备名字
@param addr:远端设备地址
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
u8 *emitter_get_remote_name(u8 *addr)
{
struct remote_name remote_n;
u16 id = CFG_REMOTE_DN_00;
while (1) {
syscfg_read(id, &remote_n, sizeof(struct remote_name));
if (remote_n.crc == CRC16((u8 *)&remote_n.addr, sizeof(struct remote_name) - 2)) {
if (!memcmp(addr, remote_n.addr, 6)) {
return &remote_n.name;
}
} else {
break;
}
id++;
if (id >= 20) {
break;
}
}
return NULL;
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射通过地址来删除vm的设备名字
@param addr:远端设备地址
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
void emitter_delete_remote_name(u8 *addr)
{
struct remote_name remote_n;
u16 id = CFG_REMOTE_DN_00;
while (1) {
syscfg_read(id, &remote_n, sizeof(struct remote_name));
if (remote_n.crc == CRC16((u8 *)&remote_n.addr, sizeof(struct remote_name) - 2)) {
if (!memcmp(addr, remote_n.addr, 6)) {
memset(&remote_n, 0xff, sizeof(struct remote_name));
syscfg_write(id, &remote_n, sizeof(struct remote_name));
return;
}
}
id++;
}
}
#define BD_ADDR_LEN 6
typedef uint8_t bd_addr_t[BD_ADDR_LEN];
static bd_addr_t remote_addr[20];
extern u8 restore_remote_device_info_opt(bd_addr_t *mac_addr, u8 conn_device_num, u8 id);
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射获取vm设备记忆
@param 无
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
void emitter_get_vm_device()
{
memset(remote_addr, 0, sizeof(remote_addr));
u8 flag = restore_remote_device_info_opt(&remote_addr, 20, get_remote_dev_info_index());
for (u8 i = 0; i < 20; i++) {
log_debug("----- \n");
log_debug_hexdump(remote_addr[i], 6);
}
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙 开关ag_a2dp
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
void bredr_ag_a2dp_open_and_close()
{
if (get_emitter_curr_channel_state() & A2DP_SRC_CH) {
puts("start to disconnect a2dp ");
user_emitter_cmd_prepare(USER_CTRL_DISCONN_A2DP, 0, NULL);
} else {
puts("start to connect a2dp ");
user_emitter_cmd_prepare(USER_CTRL_CONN_A2DP, 0, NULL);
}
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙 开关ag_hfp
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
void bredr_ag_hfp_open_and_close()
{
if (get_emitter_curr_channel_state() & HFP_AG_CH) {
puts("start to disconnect HFP ");
user_emitter_cmd_prepare(USER_CTRL_HFP_DISCONNECT, 0, NULL);
} else {
puts("start to connect HFP ");
user_emitter_cmd_prepare(USER_CTRL_HFP_CMD_BEGIN, 0, NULL);
}
}
#else
void emitter_media_source(u8 *addr, u8 source, u8 en)
{
}
void emitter_or_receiver_switch(u8 flag)
{
}
u8 bt_search_status()
{
return 0;
}
#endif