4.4. 蓝牙发射器
概述
简单介绍蓝牙发射器的使用流程
4.4.1. 操作说明
在app_config.h中打开宏
#define TCFG_USER_BT_CLASSIC_ENABLE 1 //经典蓝牙功能
#define TCFG_USER_EMITTER_ENABLE 1 //蓝牙发射功能
#define CONFIG_POWER_ON_ENABLE_BT 1 //开机自动打开经典蓝牙(demo_edr默认开启,wifi_story_machine未开启需使用时通过按键开启蓝牙)
蓝牙发射功能(bt_emitter.c):蓝牙发射搜索结果回调处理,根据过滤规则可以做名字过滤、地址过滤、自定义过滤和无限制规则,也可以保存搜索到的所有设备再选择一个进行连接
在选择使用的过滤方式下填入所需连接的蓝牙参数(名称或地址)
蓝牙发射 提供按键切换发射器或者是音箱功能:2:发射 1:接收 0: 关闭
发射器设置回调包括设备名字name、设备名字长度len、设备类型class和设备信号强度rssi等
//bt_emitter.c
//首先通过宏选择使用的过滤方式
#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 //选择过滤方式
//地址过滤
#if (SEARCH_LIMITED_MODE == SEARCH_BD_ADDR_LIMITED)
static const 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*/
//{0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX}, /*填入所需搜索连接蓝牙地址*/
};
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射搜索通过地址过滤
@param 无
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
static u8 search_bd_addr_filt(const u8 *addr)
{
log_i("bd_addr:");
put_buf(addr, 6);
for (u8 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_i("bd_addr not match\n"); */
return FALSE;
}
#endif
//名称过滤
#if (SEARCH_LIMITED_MODE == SEARCH_BD_NAME_LIMITED)
#if 0
static const 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
static const u8 bd_name_filt[][30] = {
"JL-AC79XX-AF0B",
"JL-AC79XX-AAFF",
//"填入所需搜索连接蓝牙名称"
};
#endif
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射搜索通过名字过滤
@param 无
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
u8 search_bd_name_filt(const char *data, u8 len, u32 dev_class, char rssi)
{
char bd_name[64] = {0};
if ((len > (sizeof(bd_name))) || (len == 0)) {
return FALSE;
}
memcpy(bd_name, data, len);
log_i("name:%s,len:%d,class %x ,rssi %d\n", bd_name, len, dev_class, rssi);
for (u8 i = 0; i < (sizeof(bd_name_filt) / sizeof(bd_name_filt[0])); i++) {
if (memcmp(data, bd_name_filt[i], len) == 0) {
log_i("\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 (emitter_or_receiver != BT_EMITTER_EN) {
return 0;
}
#if (SEARCH_LIMITED_MODE == SEARCH_BD_NAME_LIMITED)
if (name == NULL) {
struct inquiry_noname_remote *remote = zalloc(sizeof(struct inquiry_noname_remote));
remote->match = 0;
remote->class = dev_class;
remote->rssi = rssi;
memcpy(remote->addr, addr, 6);
os_mutex_pend(&mutex, 0);
list_add_tail(&remote->entry, &inquiry_noname_list);
if (read_name_start == 0) {
read_name_start = 1;
user_send_cmd_prepare(USER_CTRL_READ_REMOTE_NAME, 6, addr);
}
os_mutex_post(&mutex);
}
#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_i("No_eir\n");
} else {
len = (name_len > 63) ? 63 : name_len;
/* display bd_name */
memcpy(bt_name, name, len);
log_i("name:%s,len:%d,class %x ,rssi %d\n", bt_name, name_len, dev_class, rssi);
}
/* display bd_addr */
put_buf(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
}
//demo_edr在bt_music.c的bt_music_key_event_handler()长按KEY_MODE切换发射器和接收器
case KEY_MODE:
#if TCFG_USER_EMITTER_ENABLE
//发射器或者接收器切换
if (__this->enable) {
if (__this->emitter) {
bt_emitter_disable();
} else {
key_event_disable();
bt_connection_disable();
sys_timeout_add(NULL, bt_emitter_enable, 1000);
}
}
#endif
break;
//wifi_story_machine在app_music.c的app_music_key_long()中切换发射器和接收器
static int app_music_key_long(struct key_event *key)
{
switch (key->value) {
case KEY_OK:
#if TCFG_USER_EMITTER_ENABLE
if (__this->bt_music_enable) {
if (__this->bt_emitter_enable) {
app_music_play_voice_prompt("BtClose.mp3", bt_emitter_switch_to_receiver);
} else {
app_music_play_voice_prompt("BtOpen.mp3", bt_emitter_enable);
bt_connection_disable();
}
}
#endif
break;
4.4.2. 效果展示
demo_edr工程将主机的mic采集数据通过发射器传输到从机播放
wifi_story_machine工程将主机播放的数据通过发射器传输到从机播放
4.4.3. 接口说明
emitter代码文件:bt_emitter.c
bt_emitter接口说明
(1)emitter_rx_avctp_opid_deal :蓝牙发射接收到设备按键消息
(2)emitter_rx_vol_change :蓝牙发射接收设备同步音量
(3)emitter_media_source :蓝牙发射开启关闭通道
4.4.4. 代码流程
demo_edr工程
(1)app_main.c:在app_main函数中调用bt_ble_module_init函数初始化蓝牙模块
(2)bt_music.c:在蓝牙开启的状态长按KEY_MODE按键进行发射器跟接收器的切换,初始化蓝牙发射器
(3)bt_emitter.c:在开启发射器后,设备会先轮询保存在vm中的设备是否可连接,如果是则连接最近的一台接收器,否则从设备过滤清单中找出可连接的设备
wifi_story_machine工程
(1)app_music.c:通过按键打开蓝牙功能app_music_key_click()的KEY_MDOE
(2)app_music.c: 通过长按按键切换到发射器模式app_music_key_long的KEY_OK
(3)bt_emitter.c:在开启发射器后,设备会先轮询保存在vm中的设备是否可连接,如果是则连接最近的一台接收器,否则从设备过滤清单中找出可连接的设备