初版
This commit is contained in:
@@ -0,0 +1,512 @@
|
||||
#include "bt.h"
|
||||
#include "app_config.h"
|
||||
#include "app_main.h"
|
||||
#include "app_msg.h"
|
||||
#include "btstack/avctp_user.h"
|
||||
#include "dual_conn.h"
|
||||
#include "jlui_app/ui_api.h"
|
||||
#include "file_player.h"
|
||||
|
||||
#define LOG_TAG "[EMITTER]"
|
||||
#define LOG_ERROR_ENABLE
|
||||
#define LOG_DEBUG_ENABLE
|
||||
#define LOG_INFO_ENABLE
|
||||
#define LOG_CLI_ENABLE
|
||||
#include "debug.h"
|
||||
|
||||
#if TCFG_USER_EMITTER_ENABLE
|
||||
|
||||
#define BT_EMITTER_TEST 0
|
||||
|
||||
#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
|
||||
|
||||
struct list_head inquiry_noname_list;
|
||||
struct inquiry_noname_remote {
|
||||
struct list_head entry;
|
||||
u8 match;
|
||||
s8 rssi;
|
||||
u8 addr[6];
|
||||
u32 class;
|
||||
};
|
||||
|
||||
u8 restore_remote_device_info_profile(bd_addr_t mac_addr, u8 device_num, u8 id, u8 profile);
|
||||
|
||||
static u8 read_name_start = 0;
|
||||
static u8 search_spp_device = 0;
|
||||
|
||||
extern struct file_player *get_music_file_player(void); //返回第一个打开的音乐播放器指针
|
||||
extern int music_file_get_player_status(struct file_player *music_player);
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**@brief 蓝牙发射发起搜索设备
|
||||
@param 无
|
||||
@return 无
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void bt_search_device(void)
|
||||
{
|
||||
if (is_bredr_close() == 1) {
|
||||
ASSERT(0, "bt close should user bt_emitter_start_search_device()");
|
||||
}
|
||||
if (!bt_check_already_initializes()) {
|
||||
log_info("bt on init >>>>>>>>>>>>>>>>>>>>>>>\n");
|
||||
return;
|
||||
}
|
||||
u8 inquiry_length = 20; // inquiry_length * 1.28s
|
||||
bt_cmd_prepare(USER_CTRL_SEARCH_DEVICE, 1, &inquiry_length);
|
||||
log_info("bt_search_start >>>>>>>>>>>>>>>>>>>>>>>\n");
|
||||
}
|
||||
void bt_search_stop(void)
|
||||
{
|
||||
bt_cmd_prepare(USER_CTRL_INQUIRY_CANCEL, 0, NULL);
|
||||
log_info("bt_search_stop >>>>>>>>>>>>>>>>>>>>>>>\n");
|
||||
}
|
||||
|
||||
void emitter_bt_connect(u8 *mac)
|
||||
{
|
||||
if (is_bredr_close() == 1) {
|
||||
bredr_conn_dev(mac);
|
||||
} else {
|
||||
dual_conn_user_bt_connect(mac);
|
||||
}
|
||||
}
|
||||
|
||||
void bt_emitter_start_search_device()
|
||||
{
|
||||
if (g_bt_hdl.emitter_or_receiver != BT_EMITTER_EN) {
|
||||
return ;
|
||||
}
|
||||
if (is_bredr_close() == 1) {
|
||||
bredr_search_device();
|
||||
} else {
|
||||
/* user_send_cmd_prepare(USER_CTRL_PAGE_CANCEL, 0, NULL); */
|
||||
/* 关闭可发现 */
|
||||
bt_cmd_prepare(USER_CTRL_WRITE_CONN_DISABLE, 0, NULL);
|
||||
bt_cmd_prepare(USER_CTRL_WRITE_SCAN_DISABLE, 0, NULL);
|
||||
////发起扫描
|
||||
bt_search_device();
|
||||
}
|
||||
}
|
||||
|
||||
#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)
|
||||
u8 bd_name_filt[][32] = {
|
||||
"TG-294",
|
||||
"JL709_VOL_ADAP",
|
||||
};
|
||||
|
||||
u8 bd_spp_name_filt[20][30] = {
|
||||
"AC69_BT_SDK",
|
||||
};
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**@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;
|
||||
|
||||
if ((len > (sizeof(bd_name))) || (len == 0) || !data) {
|
||||
//printf("bd_name_len error:%d\n", len);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memset(bd_name, 0, sizeof(bd_name));
|
||||
memcpy(bd_name, data, len);
|
||||
log_info("name:%s,len:%d,class %x ,rssi %d\n", bd_name, len, dev_class, rssi);
|
||||
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)
|
||||
{
|
||||
log_info("name:%s,len:%d,class %x ,rssi %d\n", name, name_len, dev_class, rssi);
|
||||
if (name == NULL) {
|
||||
struct inquiry_noname_remote *remote = malloc(sizeof(struct inquiry_noname_remote));
|
||||
ASSERT(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;
|
||||
bt_cmd_prepare(USER_CTRL_READ_REMOTE_NAME, 6, addr);
|
||||
}
|
||||
}
|
||||
|
||||
if (name) {
|
||||
extern void bt_menu_list_add(char *name, u8 * mac, u8 rssi);
|
||||
bt_menu_list_add(name, addr, rssi);
|
||||
log_info("name:%s,len:%d,class %x ,rssi %d\n", name, name_len, dev_class, rssi);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
#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("name:%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 */
|
||||
/* dual_conn_user_bt_connect(addr); */
|
||||
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
#if (SEARCH_LIMITED_MODE == SEARCH_NULL_LIMITED)
|
||||
/*没有指定限制,则搜到什么就连接什么*/
|
||||
return TRUE;
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
void bt_emitter_init()
|
||||
{
|
||||
/* bt_emitter_start = 1; */
|
||||
INIT_LIST_HEAD(&inquiry_noname_list);
|
||||
bt_inquiry_result_handle_register(emitter_search_result);
|
||||
lmp_set_sniff_establish_by_remote(1);
|
||||
bt_emitter_set_enable_flag(1);
|
||||
g_bt_hdl.emitter_or_receiver = BT_EMITTER_EN;
|
||||
bt_a2dp_source_init(NULL, 0, 1);
|
||||
#if (TCFG_BT_SUPPORT_HFP_AG==1)
|
||||
bt_hfp_ag_buf_init(NULL, 0, 1);
|
||||
#endif
|
||||
|
||||
#if BT_EMITTER_TEST
|
||||
bt_emitter_start_search_device();
|
||||
#endif
|
||||
}
|
||||
|
||||
void emitter_search_stop_handle(u8 result)
|
||||
{
|
||||
log_info("%s == %d", __func__, result);
|
||||
struct inquiry_noname_remote *remote, *n;
|
||||
u8 wait_connect_flag = 1;
|
||||
if (!list_empty(&inquiry_noname_list)) {
|
||||
bt_cmd_prepare(USER_CTRL_PAGE_CANCEL, 0, NULL);
|
||||
}
|
||||
if (!result) {
|
||||
list_for_each_entry_safe(remote, n, &inquiry_noname_list, entry) {
|
||||
if (remote->match) {
|
||||
dual_conn_user_bt_connect(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 (bt_get_total_connect_dev() == 2) { */
|
||||
/* write_scan_conn_enable(0, 0); */
|
||||
/* } else if (bt_get_total_connect_dev() == 1 && bt_get_connect_status() != BT_STATUS_WAITINT_CONN) { */
|
||||
/* write_scan_conn_enable(0, 1); */
|
||||
/* } else { */
|
||||
/* write_scan_conn_enable(1, 1); */
|
||||
/* } */
|
||||
}
|
||||
}
|
||||
|
||||
void printf_malloc(void *pive)
|
||||
{
|
||||
int count = 10000;
|
||||
/* malloc_list_status_printf_all(count); */
|
||||
}
|
||||
u8 bt_emitter_stu_set(u8 *addr, u8 pp)
|
||||
{
|
||||
log_info("total con dev:%d ", bt_get_total_connect_dev());
|
||||
if (pp && (bt_get_total_connect_dev() == 0) && !(bt_emitter_get_curr_channel_state() & A2DP_SRC_CH)) {
|
||||
pp = 0;
|
||||
}
|
||||
if (pp) {
|
||||
//开音频编码
|
||||
app_var.a2dp_source_open_flag = 1;
|
||||
/* sys_timer_add(NULL, printf_malloc, 300); */
|
||||
bt_emitter_cmd_prepare(USER_CTRL_AVCTP_OPID_SEND_VOL, 0, NULL);
|
||||
} else {
|
||||
//关音频编码
|
||||
app_var.a2dp_source_open_flag = 0;
|
||||
}
|
||||
bt_emitter_send_media_toggle(NULL, pp);
|
||||
return pp;
|
||||
}
|
||||
|
||||
u8 bt_emitter_pp(u8 pp)
|
||||
{
|
||||
return bt_emitter_stu_set(NULL, pp);
|
||||
}
|
||||
|
||||
void emitter_open(u8 source)
|
||||
{
|
||||
bt_emitter_pp(1);
|
||||
}
|
||||
|
||||
void emitter_close(u8 source)
|
||||
{
|
||||
bt_emitter_pp(0);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**@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_send_message(APP_MSG_MUSIC_NEXT, 0);
|
||||
break;
|
||||
case AVCTP_OPID_PREV:
|
||||
log_info("AVCTP_OPID_PREV\n");
|
||||
app_send_message(APP_MSG_MUSIC_PREV, 0);
|
||||
break;
|
||||
case AVCTP_OPID_PAUSE:
|
||||
case AVCTP_OPID_STOP:
|
||||
log_info("AVCTP_OPID_PAUSE\n");
|
||||
app_send_message(APP_MSG_BT_EMITTER_PAUSE, 0);
|
||||
break;
|
||||
case AVCTP_OPID_PLAY:
|
||||
log_info("AVCTP_OPID_PP\n");
|
||||
app_send_message(APP_MSG_BT_EMITTER_PLAY, 0);
|
||||
break;
|
||||
case AVCTP_OPID_VOLUME_UP:
|
||||
log_info("AVCTP_OPID_VOLUME_UP\n");
|
||||
app_send_message(APP_MSG_VOL_UP, 0);
|
||||
break;
|
||||
case AVCTP_OPID_VOLUME_DOWN:
|
||||
log_info("AVCTP_OPID_VOLUME_DOWN\n");
|
||||
app_send_message(APP_MSG_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);
|
||||
}
|
||||
|
||||
////回链手机
|
||||
u8 connect_last_source_device_from_vm()
|
||||
{
|
||||
u8 mac_addr[6];
|
||||
u8 flag = 0;
|
||||
flag = restore_remote_device_info_profile((u8 *)&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);
|
||||
dual_conn_user_bt_connect(mac_addr);
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
static int bt_emitter_btstack_event_handler(int *msg)
|
||||
{
|
||||
struct bt_event *bt = (struct bt_event *)msg;
|
||||
|
||||
switch (bt->event) {
|
||||
case BT_STATUS_INIT_OK:
|
||||
log_info(" BT_STATUS_INIT_OK \n");
|
||||
bt_emitter_init();
|
||||
break;
|
||||
case BT_STATUS_CONN_A2DP_CH:
|
||||
log_info("++++++++ BT_STATUS_CONN_A2DP_CH +++++++++ 0x%x \n", bt->value);
|
||||
if (bt->value & A2DP_SRC_CH) {
|
||||
#if BT_EMITTER_TEST
|
||||
bt_emitter_pp(1);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
APP_MSG_HANDLER(emitter_stack_msg_entry) = {
|
||||
.owner = 0xff,
|
||||
.from = MSG_FROM_BT_STACK,
|
||||
.handler = bt_emitter_btstack_event_handler,
|
||||
};
|
||||
|
||||
static int bt_emitter_hci_event_handler(struct bt_event *bt)
|
||||
{
|
||||
//对应原来的蓝牙连接上断开处理函数 ,bt->value=reason
|
||||
log_info("-----------bt_hci_event_handler reason %x %x", bt->event, bt->value);
|
||||
switch (bt->event) {
|
||||
case HCI_EVENT_INQUIRY_COMPLETE:
|
||||
log_info(" HCI_EVENT_INQUIRY_COMPLETE \n");
|
||||
emitter_search_stop_handle(bt->value);
|
||||
UI_MSG_POST("bt_emitter_status:hci_event=%4", bt->event);
|
||||
break;
|
||||
case HCI_EVENT_CONNECTION_COMPLETE:
|
||||
UI_MSG_POST("bt_emitter_status:hci_value=%4", bt->value);
|
||||
break;
|
||||
case HCI_EVENT_DISCONNECTION_COMPLETE:
|
||||
#if !TCFG_COLOR_SCREEN_CHARGING_CASE_ENABLE
|
||||
UI_MSG_POST("bt_emitter_status:hci_event=%4", bt->event);
|
||||
#else
|
||||
UI_MSG_POST("bt_emitter_status:hci_event=%4:hci_value=%4", bt->event, bt->value);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bt_emitter_hci_msg_handler(int *msg)
|
||||
{
|
||||
struct bt_event *event = (struct bt_event *)msg;
|
||||
bt_emitter_hci_event_handler(event);
|
||||
return 0;
|
||||
}
|
||||
|
||||
APP_MSG_HANDLER(emitter_hci_msg_handler) = {
|
||||
.owner = 0xff,
|
||||
.from = MSG_FROM_BT_HCI,
|
||||
.handler = bt_emitter_hci_msg_handler,
|
||||
};
|
||||
|
||||
static int bt_emitter_app_msg_handler(int *msg)
|
||||
{
|
||||
struct file_player *file_player = NULL;
|
||||
switch (msg[0]) {
|
||||
case APP_MSG_BT_EMITTER_PLAY:
|
||||
#if TCFG_APP_MUSIC_EN
|
||||
file_player = get_music_file_player();
|
||||
if (music_file_get_player_status(file_player) != FILE_PLAYER_START) {
|
||||
app_send_message(APP_MSG_MUSIC_PP, 0);
|
||||
}
|
||||
#endif
|
||||
bt_emitter_pp(1);
|
||||
break;
|
||||
case APP_MSG_BT_EMITTER_PAUSE:
|
||||
#if TCFG_APP_MUSIC_EN
|
||||
file_player = get_music_file_player();
|
||||
if (music_file_get_player_status(file_player) == FILE_PLAYER_START) {
|
||||
app_send_message(APP_MSG_MUSIC_PP, 0);
|
||||
}
|
||||
#endif
|
||||
bt_emitter_pp(0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
APP_MSG_HANDLER(bt_emitter_app_msg_entry) = {
|
||||
.owner = 0xff,
|
||||
.from = MSG_FROM_APP,
|
||||
.handler = bt_emitter_app_msg_handler,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user