KT24-1110_65E-HA-651B/apps/soundbox/task_manager/bt/bt_ble.c
2024-11-10 18:44:17 +08:00

824 lines
19 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.

#include "system/app_core.h"
#include "system/includes.h"
#include "app_config.h"
#include "app_task.h"
#include "btstack/btstack_task.h"
#include "user_cfg.h"
#include "vm.h"
#include "app_power_manage.h"
#include "btcontroller_modules.h"
#include "app_chargestore.h"
#include "btstack/avctp_user.h"
#include "bt_common.h"
#include "le_common.h"
#include "bt/bt_ble.h"
#if TCFG_APP_BT_EN
#if (TCFG_BLE_DEMO_SELECT == DEF_BLE_DEMO_ADV)
#define LOG_TAG_CONST BT_BLE
#define LOG_TAG "[BT_BLE]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
#if 0
#define ble_puts printf
#define ble_printf printf
#define ble_put_buf printf_buf
#else
#define ble_puts log_info
#define ble_printf log_info
#define ble_put_buf log_debug_hexdump
#endif
#define BLE_TIMER_SET (100)
//停留时间,可以自定义修改
#define ADV_ST_CONN_HOLD_TIME (20000/BLE_TIMER_SET)//phone connect device
#define ADV_ST_RECONN_HOLD_TIME (20000/BLE_TIMER_SET)//device connect phone
//以下时间不建议修改
#define ADV_ST_DISMISS_HOLD_TIME (2000/BLE_TIMER_SET)
#define ADV_ST_PRE1_HOLD_TIME (200/BLE_TIMER_SET)
#define ADV_ST_FAST_DISMISS_HOLD_TIME (1500/BLE_TIMER_SET)//to fast display reconnect
#define PHONE_ICON_ONE_BETA 0 //beta case,one ear case
//0---default,inquiry,connect,reconnect
//1---only inquiry and first connect
#define PHONE_ICON_CTRL_MODE 0 //
#define PHONE_ICON_AUTO_DISMISS 1 //auto dismiss icon
#if TCFG_CHARGESTORE_ENABLE
#define REFLASH_ICON_STATE 1 //auto reflash
#else
#define REFLASH_ICON_STATE 0 //not auto reflash,fixed
#endif
static u32 ble_timer_handle = 0;
static u16 adv_st_count = 0;
static u8 dev_battery_level[3];//master,slave,box
static volatile u8 adv_control_enable;//master
static volatile u8 adv_st_mode;
static volatile u8 adv_st_next_mode;
static volatile u8 adv_enable = 0;
static u8 adv_data[ADV_RSP_PACKET_MAX];
static u8 adv_data_len = 0;
static u8 rsp_data[ADV_RSP_PACKET_MAX];
static u8 rsp_data_len = 0;
static u8 adv_rand;
static u8 adv_open_lock;//lock open 标记
//-------------------user_tag data start----------------------------------------------------------
static u8 user_tag_data[19] = {
0xd6, 0x05,
0x01, 0x00,
0x01, 0x00,
0x00, //6
};
static const u8 user_pre1_tag_data[29] = {
0xd6, 0x05,
0x02, 0x00,
0x02, 0x00,
0x00, //6
};
static const u8 user_pre2_tag_data[29] = {
0xd6, 0x05,
0x03, 0x00,
0x03, 0x00,
0x00, //6
};
static const u8 user_conn_tag_data[29] = {
0xd6, 0x05,
0x04, 0x00,
0x04, 0x00,
0x00, //6
};
static const u8 user_reconn_tag_data[29] = {
0xd6, 0x05,
0x05, 0x00,
0x05, 0x00,
0x00, //6
};
//-----------------------data end------------------------------------------------------
extern const char *bt_get_local_name();
static void adv_rand_init(void);
static u8 update_dev_battery_level(void);
//-------------------------------------------------------
const char ble_name_string[] = "693_ble";
static int make_set_adv_data(u8 *info, u8 len)
{
u8 offset = 0;
u8 *buf = (void *)adv_data;
u8 *tag_buf = (void *)info;
u8 tag_len = len;
/*
#if 0 //BLE广播使用EDR的蓝牙名字防止连接时蓝牙名字变成693_ble蓝牙名字最多只能31-21=10字节。
u8 *edr_name = bt_get_local_name();
offset += make_eir_packet_data(&buf[offset], offset, HCI_EIR_DATATYPE_COMPLETE_LOCAL_NAME, (void *)edr_name, strlen(edr_name));
#else
offset += make_eir_packet_data(&buf[offset], offset, HCI_EIR_DATATYPE_COMPLETE_LOCAL_NAME, (void *)ble_name_string, strlen(ble_name_string));
#endif
*/
offset += make_eir_packet_data(&buf[offset], offset, HCI_EIR_DATATYPE_MANUFACTURER_SPECIFIC_DATA, (void *)tag_buf, tag_len);
if (offset > ADV_RSP_PACKET_MAX) {
ble_puts("***adv_data overflow!!!!!!\n");
return -1;
}
ble_printf("ADV data(%d):", offset);
ble_put_buf(buf, offset);
adv_data_len = offset;
return 0;
}
static int make_set_rsp_data(void)
{
u8 offset = 0;
u8 *buf = (void *)rsp_data;
if (offset > ADV_RSP_PACKET_MAX) {
ble_puts("***rsp_data overflow!!!!!!\n");
return -1;
}
ble_printf("RSP data(%d):,offset");
ble_put_buf(buf, offset);
rsp_data_len = offset;
return 0;
}
static void adv_setup_init(void)
{
u8 adv_type = 3;
u8 adv_channel = 0x07;
u16 adv_interval;
switch (adv_st_mode) {
case ADV_ST_INQUIRY:
case ADV_ST_DISMISS:
case ADV_ST_FAST_DISMISS:
//特殊状态,广播周期快
adv_interval = 0x30;
break;
case ADV_ST_CONN:
case ADV_ST_RECONN:
default:
if (get_total_connect_dev()) {
//连上手机,广播周期慢
adv_interval = 0x60;
} else {
//未连上手机,广播周期快
adv_interval = 0x30;
}
break;
}
ble_printf("adv_interval=%d\n", adv_interval);
ble_user_cmd_prepare(BLE_CMD_ADV_PARAM, 3, adv_interval, adv_type, adv_channel);
ble_user_cmd_prepare(BLE_CMD_ADV_DATA, 2, adv_data_len, adv_data);
ble_user_cmd_prepare(BLE_CMD_RSP_DATA, 2, rsp_data_len, rsp_data);
}
u8 bt_ble_get_adv_enable(void)
{
return adv_enable;
}
void bt_ble_adv_enable(u8 enable)
{
if (adv_enable == enable) {
return;
}
adv_enable = enable;
ble_printf("***** ble_adv_en:%d ******\n", enable);
if (enable) {
adv_setup_init();
}
ble_user_cmd_prepare(BLE_CMD_ADV_ENABLE, 1, enable);
}
//-----------------------
extern u8 get_charge_online_flag(void);
static u8 get_device_bat_percent(void)
{
#if CONFIG_DISPLAY_DETAIL_BAT
u8 val = get_vbat_percent();
#else
u8 val = get_self_battery_level() * 10 + 10;
#endif
if (val > 100) {
val = 100;
}
val = (val | (get_charge_online_flag() << 7));
/* printf("[%d]",val); */
return val;
}
static void reflash_adv_tag_data(const u8 *tag_data, u8 len, u8 spec_val)
{
u8 tmp_tag_data[32];
u8 tmp8;
memcpy(tmp_tag_data, tag_data, len);
memcpy(&tmp_tag_data[14], dev_battery_level, 3);
#if TCFG_CHARGESTORE_ENABLE
//位置14,15,16 对应 R,L,BOX
if (chargestore_get_earphone_pos() == 'L') {
//switch position
ble_puts("is L pos\n");
tmp8 = tmp_tag_data[14];
tmp_tag_data[14] = tmp_tag_data[15];
tmp_tag_data[15] = tmp8;
} else {
ble_puts("is R pos\n");
}
#endif
if (spec_val != 0xff) {
tmp_tag_data[17] = spec_val;
if (spec_val != 9) {
#if TCFG_USER_TWS_ENABLE
/* memset(&tmp_tag_data[14],0xff,3); */
#endif
} else {
memset(&tmp_tag_data[14], 0xFF, 3);//关闭广播的时候不显示电量
}
}
//---
#if (!REFLASH_ICON_STATE) //
if (len == 29) {
#if TCFG_USER_TWS_ENABLE
//fixed do,start,固定分开显示电量,如不分开,可以屏蔽这段代码
ble_puts("fixed two do\n");
/* ble_put_buf(&tmp_tag_data[14],3); */
if ((tmp_tag_data[14] != 0xff)
&& (tmp_tag_data[15] != 0xff)) {
if ((tmp_tag_data[14]&BIT(7))
&& (tmp_tag_data[15]&BIT(7))) {
tmp_tag_data[15] &= 0x7f;
ble_puts("fixed c1\n");
} else {
if (((tmp_tag_data[14]&BIT(7)) == 0)
&& ((tmp_tag_data[15]&BIT(7)) == 0)) {
tmp_tag_data[14] |= BIT(7);
ble_puts("fixed c2\n");
}
}
}
//fixed do,end
#endif
}
#endif
//---
bt_ble_adv_enable(0);
make_set_adv_data(tmp_tag_data, len);
bt_ble_adv_enable(1);
}
static bool check_adv_open_lock(void)
{
if (get_total_connect_dev()) {
//已连上手机
adv_open_lock = 1;
}
return adv_open_lock;
}
static void change_adv_st_mode(u8 mode)
{
if (mode == adv_st_mode) {
return;
}
ble_printf("ble_adv_st:old= %d,new= %d \n", adv_st_mode, mode);
adv_st_mode = mode;
adv_st_count = 0;
switch (mode) {
case ADV_ST_CONN:
check_adv_open_lock();
reflash_adv_tag_data(user_conn_tag_data, sizeof(user_conn_tag_data), 0xff);
break;
case ADV_ST_RECONN:
check_adv_open_lock();
reflash_adv_tag_data(user_reconn_tag_data, sizeof(user_reconn_tag_data), 0xff);
break;
case ADV_ST_DISMISS:
reflash_adv_tag_data(user_tag_data, sizeof(user_tag_data), 0x9);
break;
case ADV_ST_INQUIRY:
reflash_adv_tag_data(user_tag_data, sizeof(user_tag_data), adv_rand);
break;
case ADV_ST_PRE1:
reflash_adv_tag_data(user_pre1_tag_data, sizeof(user_pre1_tag_data), 0xff);
break;
case ADV_ST_PRE2:
reflash_adv_tag_data(user_pre2_tag_data, sizeof(user_pre2_tag_data), 0xff);
break;
case ADV_ST_FAST_DISMISS:
reflash_adv_tag_data(user_tag_data, sizeof(user_tag_data), 0x9);
break;
case ADV_ST_END:
bt_ble_adv_enable(0);
break;
default:
break;
}
}
static void check_dev_pos_changed(u8 cur_adv_mode)
{
#if REFLASH_ICON_STATE
if (update_dev_battery_level()) {
ble_puts("---reflash_dev_state\n");
/* adv_st_next_mode = cur_adv_mode; */
/* change_adv_st_mode(ADV_ST_FAST_DISMISS); */
change_adv_st_mode(ADV_ST_END);
change_adv_st_mode(cur_adv_mode);
}
#endif
}
static void bt_ble_timer_handler(void)
{
u8 bat_percent;
if (!adv_enable) {
return;
}
adv_st_count++;
switch (adv_st_mode) {
case ADV_ST_PRE1:
if (adv_st_count > ADV_ST_PRE1_HOLD_TIME) {
change_adv_st_mode(ADV_ST_PRE2);
}
break;
case ADV_ST_CONN:
if (adv_st_count > ADV_ST_CONN_HOLD_TIME) {
#if PHONE_ICON_AUTO_DISMISS
change_adv_st_mode(ADV_ST_DISMISS);
#else
change_adv_st_mode(ADV_ST_END);
#endif
} else {
check_dev_pos_changed(adv_st_mode);
}
break;
case ADV_ST_RECONN:
if (adv_st_count > ADV_ST_RECONN_HOLD_TIME) {
#if PHONE_ICON_AUTO_DISMISS
change_adv_st_mode(ADV_ST_DISMISS);
#else
change_adv_st_mode(ADV_ST_END);
#endif
} else {
check_dev_pos_changed(adv_st_mode);
}
break;
case ADV_ST_DISMISS:
if (adv_st_count > ADV_ST_DISMISS_HOLD_TIME) {
change_adv_st_mode(ADV_ST_END);
}
break;
case ADV_ST_FAST_DISMISS:
if (adv_st_count > ADV_ST_FAST_DISMISS_HOLD_TIME) {
change_adv_st_mode(adv_st_next_mode);
}
break;
case ADV_ST_INQUIRY:
check_dev_pos_changed(adv_st_mode);
break;
case ADV_ST_NULL:
case ADV_ST_PRE2:
break;
default:
break;
}
}
static void bt_ble_timer_init(void)
{
ble_timer_handle = sys_timer_add(NULL, bt_ble_timer_handler, BLE_TIMER_SET);
}
extern const u8 *bt_get_mac_addr();
extern const u8 *ble_get_mac_addr(void);
extern void swapX(const uint8_t *src, uint8_t *dst, int len);
void bt_ble_test_tag_do(void)
{
ble_puts("bt_ble_test_tag_do\n");
//初始化三个电量值
memset(dev_battery_level, 0xff, sizeof(dev_battery_level));
dev_battery_level[0] = get_device_bat_percent();
swapX(bt_get_mac_addr(), &user_tag_data[7], 6);
ble_puts("\n------master address------\n");
ble_put_buf(&user_tag_data[7], 6);
/* make_set_adv_data(user_tag_data, sizeof(user_tag_data)); */
}
void bt_ble_icon_set_comm_address(u8 *addr)
{
swapX(addr, &user_tag_data[7], 6);
le_controller_set_mac(addr);//将ble广播地址改成公共地址
ble_puts("\n------reset master address------\n");
ble_put_buf(&user_tag_data[7], 6);
}
void bt_ble_icon_reset(void)
{
ble_puts("bt_ble_icon_reset\n");
if (!adv_control_enable) {
return;
}
//重置状态,允许再广播
ble_puts("reset_do\n");
adv_rand_init();
adv_st_mode = ADV_ST_NULL;
adv_open_lock = 0;
bt_ble_adv_enable(0);
}
u8 bt_ble_icon_get_adv_state(void)
{
return adv_st_mode;
}
//return change_flag
static u8 update_dev_battery_level(void)
{
u8 old_dev_battery[3];
memcpy(old_dev_battery, dev_battery_level, 3);
//read bat_level
dev_battery_level[0] = get_device_bat_percent();
u8 sibling_bat_level = dev_battery_level[1];
if (sibling_bat_level == 0xff) {
/* ble_puts("--update_bat_00\n"); */
goto update_dev2;
}
#if TCFG_USER_TWS_ENABLE
extern u8 get_tws_sibling_bat_persent(void);
sibling_bat_level = get_tws_sibling_bat_persent();
#endif
#if TCFG_CHARGESTORE_ENABLE
if (sibling_bat_level == 0xff) {
/* ble_puts("--update_bat_01\n"); */
sibling_bat_level = chargestore_get_sibling_power_level();
}
#endif
if (sibling_bat_level == 0xff) {
/* ble_puts("--update_bat_02\n"); */
dev_battery_level[1] = dev_battery_level[0];
} else {
dev_battery_level[1] = sibling_bat_level;
}
update_dev2:
if (((dev_battery_level[0] & BIT(7)) && (dev_battery_level[0] != 0xff))
|| ((dev_battery_level[1] & BIT(7)) && (dev_battery_level[1] != 0xff))) {
//earphone in charge
#if TCFG_CHARGESTORE_ENABLE
dev_battery_level[2] = chargestore_get_power_level();
#else
dev_battery_level[2] = 0xff;
#endif
} else {
//all not in charge
dev_battery_level[2] = 0xff;
}
u8 i;
u8 change_flag = 0;
for (i = 0; i < 3; i++) {
if ((dev_battery_level[i]&BIT(7)) != (old_dev_battery[i]&BIT(7))) {
break;
}
if ((dev_battery_level[i] == 0xff) && (old_dev_battery[i] != 0xff)) {
break;
}
if ((dev_battery_level[i] != 0xff) && (old_dev_battery[i] == 0xff)) {
break;
}
}
if (i < 3) {
ble_puts("dev_pos_state have changed:");
ble_put_buf(old_dev_battery, 3);
ble_put_buf(dev_battery_level, 3);
change_flag = 1;
}
return change_flag;
}
//open 不同类型广播
void bt_ble_icon_open(u8 type)
{
ble_printf("bt_ble_icon_open: %d\n", type);
if (!adv_control_enable) {
return;
}
if (adv_open_lock) {
ble_puts("open_lock\n");
return;
}
ble_puts("open_do\n");
update_dev_battery_level();
switch (adv_st_mode) {
case ADV_ST_NULL:
#if PHONE_ICON_ONE_BETA
if (type == ICON_TYPE_INQUIRY) {
change_adv_st_mode(ADV_ST_INQUIRY);
} else if (type == ICON_TYPE_CONNECTED || type == ICON_TYPE_RECONNECT) {
//record,and not display
change_adv_st_mode(ADV_ST_END);
}
break;
#endif
#if (PHONE_ICON_CTRL_MODE == 1)
if (type == ICON_TYPE_INQUIRY) {
change_adv_st_mode(ADV_ST_INQUIRY);
} else if (type == ICON_TYPE_CONNECTED || type == ICON_TYPE_RECONNECT) {
//record,and not display
change_adv_st_mode(ADV_ST_END);
}
break;
#endif
if (type == ICON_TYPE_CONNECTED || type == ICON_TYPE_RECONNECT) {
change_adv_st_mode(ADV_ST_RECONN);
} else if (type == ICON_TYPE_PRE_DEV) {
change_adv_st_mode(ADV_ST_PRE1);
} else {
change_adv_st_mode(ADV_ST_INQUIRY);
}
break;
case ADV_ST_INQUIRY:
#if PHONE_ICON_ONE_BETA
if (type == ICON_TYPE_CONNECTED || type == ICON_TYPE_RECONNECT) {
change_adv_st_mode(ADV_ST_DISMISS);
}
break;
#endif
#if (PHONE_ICON_CTRL_MODE == 1)
if (type == ICON_TYPE_CONNECTED || type == ICON_TYPE_RECONNECT) {
change_adv_st_mode(ADV_ST_DISMISS);
}
break;
#endif
switch (type) {
case ICON_TYPE_CONNECTED:
#if TCFG_USER_TWS_ENABLE
change_adv_st_mode(ADV_ST_CONN);
#else
change_adv_st_mode(ADV_ST_DISMISS);
#endif
break;
case ICON_TYPE_RECONNECT:
change_adv_st_mode(ADV_ST_FAST_DISMISS);
adv_st_next_mode = ADV_ST_RECONN;
break;
default:
break;
}
break;
case ADV_ST_PRE1:
case ADV_ST_PRE2:
if (type == ICON_TYPE_INQUIRY) {
//开inquiry
change_adv_st_mode(ADV_ST_INQUIRY);
} else if (type == ICON_TYPE_CONNECTED) {
change_adv_st_mode(ADV_ST_CONN);
} else {
;
}
break;
case ADV_ST_RECONN:
if (type == ICON_TYPE_INQUIRY) {
change_adv_st_mode(ADV_ST_FAST_DISMISS);
adv_st_next_mode = ADV_ST_INQUIRY;
} else if (type == ICON_TYPE_CONNECTED) {
change_adv_st_mode(ADV_ST_FAST_DISMISS);
adv_st_next_mode = ADV_ST_CONN;
} else {
;
}
break;
default:
break;
}
}
//dismiss_flag
void bt_ble_icon_close(u8 dismiss_flag)
{
ble_printf("bt_ble_close: %d\n", dismiss_flag);
if ((!dismiss_flag) || (!adv_control_enable)) {
ble_puts("close_adv\n");
change_adv_st_mode(ADV_ST_END);
return;
}
switch (adv_st_mode) {
case ADV_ST_CONN:
case ADV_ST_RECONN:
case ADV_ST_INQUIRY:
case ADV_ST_PRE1:
case ADV_ST_PRE2:
case ADV_ST_FAST_DISMISS:
case ADV_ST_DISMISS:
case ADV_ST_END://也要做
change_adv_st_mode(ADV_ST_DISMISS);
break;
default:
break;
}
}
//tws,need set en
extern bool get_tws_sibling_connect_state(void);
extern int tws_api_get_role(void);
void bt_ble_icon_slave_en(u8 en)
{
ble_printf("------icon_slave_enable = %d------\n", en);
if (en) {
dev_battery_level[1] = 0xfc;//set flag
} else {
dev_battery_level[1] = 0xff;
}
#if TCFG_USER_TWS_ENABLE
if (get_tws_sibling_connect_state()) {
if (tws_api_get_role()) {
//已配对连接过的从机,记录以后不允许再广播
adv_open_lock = 1;//lock open 接口
bt_ble_icon_close(0);
}
}
#endif
}
//tws,master need set en;使能ICON_OPEN 接口控制
void bt_ble_set_control_en(u8 en)
{
ble_printf("------adv_control_enable = %d------\n", en);
adv_control_enable = en;//set master flag
}
//-----------------------
static void adv_rand_init(void)
{
int ret = syscfg_read(CFG_BLE_MODE_INFO, (u8 *)&adv_rand, 1);
if (!ret) {
adv_rand = (rand32() % 7) + 1;
} else {
adv_rand++;
}
if (adv_rand > 7) {
adv_rand = 1;
}
syscfg_write(CFG_BLE_MODE_INFO, (u8 *)&adv_rand, 1);
ble_printf("------adv_rand = %d------\n", adv_rand);
}
extern void dut_le_hw_open(void);
extern void ble_bqb_test_thread_init(void);
__BANK_INIT_ENTRY
void bt_ble_init(void)
{
ble_printf("***** ble_init******\n");
adv_rand_init();
#if TCFG_USER_TWS_ENABLE
adv_control_enable = 0;//tws,default off
#else
adv_control_enable = 1;//one earphone,default on
#endif
adv_st_mode = ADV_ST_NULL;
adv_open_lock = 0;
bt_ble_test_tag_do();
bt_ble_timer_init();
}
/*
void bt_ble_icon_set(u8 *info, u8 len)
{
ble_printf("***** ble_icon_set******\n");
bt_ble_adv_enable(0);
update_user_tag_data(info, len);
bt_ble_adv_enable(1);
}
*/
void bt_ble_exit(void)
{
ble_printf("***** ble_exit******\n");
bt_ble_adv_enable(0);
adv_st_mode = ADV_ST_NULL;
adv_control_enable = 0;
if (ble_timer_handle) {
sys_timeout_del(ble_timer_handle);
ble_timer_handle = 0;;
}
}
#endif
#endif