在逗猫棒的基础上实现蓝牙转USB功能,目前功能已经实现,还需裁剪掉之前逗猫棒的业务程序

This commit is contained in:
2026-07-24 11:41:08 +08:00
commit b3f06697a6
1569 changed files with 515355 additions and 0 deletions
@@ -0,0 +1,549 @@
#include "app_umidigi_chargestore.h"
#include "init.h"
#include "app_config.h"
#include "system/includes.h"
#include "asm/charge.h"
#include "user_cfg.h"
#include "app_chargestore.h"
#include "device/vm.h"
#include "btstack/avctp_user.h"
#include "app_power_manage.h"
#include "app_action.h"
#include "app_main.h"
#include "app_charge.h"
#include "app_testbox.h"
#include "classic/tws_api.h"
#include "update.h"
#include "bt_ble.h"
#include "bt_tws.h"
#include "app_action.h"
#include "bt_common.h"
#include "le_rcsp_adv_module.h"
#include "tone_player.h"
#include "app_msg.h"
#include "key_event_deal.h"
#define LOG_TAG_CONST APP_UMIDIGI_CHARGESTORE
#define LOG_TAG "[APP_UMIDIGI_CHARGESTORE]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
extern void bt_tws_remove_pairs();
extern void cpu_reset();
#if TCFG_UMIDIGI_BOX_ENABLE
struct umidigi_chargestore_info {
int timer; //合盖之后定时进入休眠的句柄
u8 cover_status; //充电舱盖子状态 0: 合盖 1:开盖
u8 ear_number; //合盖时耳机在线数
u8 close_ing; //等待合窗超时
u8 bt_init_ok; //蓝牙协议栈初始化成功
u8 active_disconnect; //主动断开连接
u8 sibling_chg_lev; //对耳同步的充电舱电量
u8 pair_flag; //配对标记
u8 power_sync; //第一次获取到充电舱电量时,同步到对耳
u8 switch2bt; //开盖切换到蓝牙的标记位
u8 pre_power_lvl;
/*以下为充电舱发送CMD时携带的信息*/
u8 case_charger_state; //充电舱自身充电状态 0: 不在充电 1: 充电中
u8 case_battery_level; //充电舱电量百分比
u8 l_ear_whether_in_box; //左耳是否在舱 0: 左耳不在仓 1:左耳在仓
u8 r_ear_whether_in_box; //右耳是否在舱 0: 右耳不在仓 1:右耳在仓
u8 usb_state; //usb插入/拔出标志(本地播放专用) 0: USB OUT 1: USB IN
u16 open_case_timer; //延迟处理开盖命令定时器
u16 pair_timer; //延迟处理配对命令定时器
};
static struct umidigi_chargestore_info info = {
.case_charger_state = 1,
.ear_number = 1,
.case_battery_level = 0xff,
.sibling_chg_lev = 0xff,
};
#define __this (&info)
/*获取充电舱电池电量*/
u8 umidigi_chargestore_get_power_level(void)
{
if ((__this->case_battery_level == 0xff) ||
((!get_charge_online_flag()) &&
(__this->sibling_chg_lev != 0xff))) {
return __this->sibling_chg_lev;
}
return __this->case_battery_level;
}
/*获取充电舱充电状态*/
u8 umidigi_chargestore_get_power_status(void)
{
return __this->case_charger_state;
}
/*获取充电舱合盖或开盖状态*/
u8 umidigi_chargestore_get_cover_status(void)
{
return __this->cover_status;
}
/*获取合盖状态时耳机在仓数量*/
u8 umidigi_chargestore_get_earphone_online(void)
{
return __this->ear_number;
}
/*获取蓝牙初始化成功标志位*/
void umidigi_chargestore_set_bt_init_ok(u8 flag)
{
__this->bt_init_ok = flag;
}
#if TCFG_USER_TWS_ENABLE
static void umidigi_set_tws_sibling_charge_level(void *_data, u16 len, bool rx)
{
if (rx) {
u8 *data = (u8 *)_data;
umidigi_chargestore_set_sibling_chg_lev(data[0]);
}
}
REGISTER_TWS_FUNC_STUB(charge_level_stub) = {
.func_id = TWS_FUNC_ID_CHARGE_SYNC,
.func = umidigi_set_tws_sibling_charge_level,
};
#endif //TCFG_USER_TWS_ENABLE
int umidigi_chargestore_sync_chg_level(void)
{
#if TCFG_USER_TWS_ENABLE
int err = -1;
struct application *app = get_current_app();
if (app && (!strcmp(app->name, "earphone")) && (!app_var.goto_poweroff_flag)) {
err = tws_api_send_data_to_sibling((u8 *)&__this->case_battery_level, 1,
TWS_FUNC_ID_CHARGE_SYNC);
}
return err;
#else
return 0;
#endif
}
/*设置对耳同步的充电舱电量*/
void umidigi_chargestore_set_sibling_chg_lev(u8 chg_lev)
{
__this->sibling_chg_lev = chg_lev;
}
/*设置充电舱电池电量*/
void umidigi_chargestore_set_power_level(u8 power)
{
__this->case_battery_level = power;
}
/*获取允许poweroff标志位*/
u8 umidigi_chargestore_check_going_to_poweroff(void)
{
return __this->close_ing;
}
void umidigi_chargestore_set_phone_disconnect(void)
{
#if (TCFG_BLE_DEMO_SELECT == DEF_BLE_DEMO_ADV)
#if (!CONFIG_NO_DISPLAY_BUTTON_ICON)
if (__this->pair_flag && get_tws_sibling_connect_state()) {
//check ble inquiry
//printf("get box log_key...con_dev=%d\n",get_tws_phone_connect_state());
if ((bt_ble_icon_get_adv_state() == ADV_ST_RECONN)
|| (bt_ble_icon_get_adv_state() == ADV_ST_DISMISS)
|| (bt_ble_icon_get_adv_state() == ADV_ST_END)) {
bt_ble_icon_reset();
bt_ble_icon_open(ICON_TYPE_INQUIRY);
}
}
#endif
__this->pair_flag = 0;
#elif (TCFG_BLE_DEMO_SELECT == DEF_BLE_DEMO_ADV_RCSP)
#if (!CONFIG_NO_DISPLAY_BUTTON_ICON)
if (__this->pair_flag && get_tws_sibling_connect_state()) {
//check ble inquiry
bt_ble_adv_ioctl(BT_ADV_SET_EDR_CON_FLAG, SECNE_UNCONNECTED, 1);
}
#endif
__this->pair_flag = 0;
#endif
}
void umidigi_chargestore_set_phone_connect(void)
{
__this->active_disconnect = 0;
}
extern void sys_enter_soft_poweroff(void *priv);
void umidigi_chargestore_timeout_deal(void *priv)
{
__this->timer = 0;
__this->close_ing = 0;
//该类型的充电仓获取不到充电在线状态时,认为出仓了。
//避免盒盖马上开盖迅速拔出,收不到开盖消息,导致连上又复位系统。
if (get_charge_online_flag() == 0) {
__this->cover_status = 1;
}
if ((!__this->cover_status) || __this->active_disconnect) {//当前为合盖或者主动断开连接
struct application *app = get_current_app();
if (app && strcmp(app->name, "idle")) {
sys_enter_soft_poweroff((void *)1);
}
} else {
#if (TCFG_BLE_DEMO_SELECT == DEF_BLE_DEMO_ADV)
/* if ((!get_total_connect_dev()) && (tws_api_get_role() == TWS_ROLE_MASTER) && (get_bt_tws_connect_status())) { */
if (tws_api_get_role() == TWS_ROLE_MASTER) {
printf("charge_icon_ctl...\n");
bt_ble_icon_reset();
#if CONFIG_NO_DISPLAY_BUTTON_ICON
if (get_total_connect_dev()) {
//蓝牙未真正断开;重新广播
bt_ble_icon_open(ICON_TYPE_RECONNECT);
} else {
//蓝牙未连接,重新开可见性
bt_ble_icon_open(ICON_TYPE_INQUIRY);
}
#else
//不管蓝牙是否连接,默认打开
bt_ble_icon_open(ICON_TYPE_RECONNECT);
#endif
}
#elif (TCFG_BLE_DEMO_SELECT == DEF_BLE_DEMO_ADV_RCSP)
if (tws_api_get_role() == TWS_ROLE_MASTER) {
printf("charge_icon_ctl...\n");
#if CONFIG_NO_DISPLAY_BUTTON_ICON
if (get_total_connect_dev()) {
//蓝牙未真正断开;重新广播
bt_ble_adv_ioctl(BT_ADV_SET_EDR_CON_FLAG, SECNE_CONNECTED, 1);
} else {
//蓝牙未连接,重新开可见性
bt_ble_adv_ioctl(BT_ADV_SET_EDR_CON_FLAG, SECNE_UNCONNECTED, 1);
}
#else
//不管蓝牙是否连接,默认打开
bt_ble_adv_ioctl(BT_ADV_SET_EDR_CON_FLAG, SECNE_CONNECTED, 1);
#endif
}
#endif
}
__this->ear_number = 1;
}
/*开盖命令处理函数*/
static void open_case_callback(void *priv)
{
struct application *app = get_current_app();
if (__this->cover_status) {
//电压过低,不进响应开盖命令
#if TCFG_SYS_LVD_EN
if (get_vbat_need_shutdown() == TRUE) {
log_info(" lowpower deal!\n");
__this->open_case_timer = 0;
return;
}
#endif
if (__this->cover_status) {//当前为开盖
if (__this->power_sync) {
if (umidigi_chargestore_sync_chg_level() == 0) {
__this->power_sync = 0;
}
}
if (app && strcmp(app->name, APP_NAME_BT) && (app_var.goto_poweroff_flag == 0)) {
/* app_var.play_poweron_tone = 1; */
app_var.play_poweron_tone = 0;
power_set_mode(TCFG_LOWPOWER_POWER_SEL);
r_printf("switch to bt\n");
__this->switch2bt = 1;
#if TCFG_SYS_LVD_EN
vbat_check_init();
#endif
task_switch_to_bt();
__this->switch2bt = 0;
}
}
__this->open_case_timer = 0;
} else {
__this->open_case_timer = 0;
}
}
/*等待蓝牙初始化完成再进行对耳*/
static void tws_pair_wait_bt_init_callback(void *priv)
{
#if TCFG_USER_TWS_ENABLE
if (bt_tws_get_local_channel() == 'L') {
r_printf("L channel\n");
//充电仓不支持 双击回播电话,也不支持 双击配对和取消配对
#if (!TCFG_CHARGESTORE_ENABLE)
#if TCFG_USER_TWS_ENABLE
if (bt_tws_start_search_sibling()) {
tone_play_index(IDEX_TONE_NORMAL, 1);
}
#endif
#endif
if (bt_user_priv_var.last_call_type == BT_STATUS_PHONE_INCOME) {
user_send_cmd_prepare(USER_CTRL_DIAL_NUMBER, bt_user_priv_var.income_phone_len, bt_user_priv_var.income_phone_num);
} else {
user_send_cmd_prepare(USER_CTRL_HFP_CALL_LAST_NO, 0, NULL);
}
} else if (bt_tws_get_local_channel() == 'R') {
r_printf("R channel\n");
} else if (bt_tws_get_local_channel() == 'U') {
r_printf("U channel\n");
}
#endif
__this->pair_timer = 0;
}
/*配对命令处理函数*/
static void tws_pair_callback(void *priv)
{
struct application *app = get_current_app();
#if CONFIG_TWS_PAIR_MODE == CONFIG_TWS_PAIR_BY_CLICK
if (app && strcmp(app->name, APP_NAME_BT) && (app_var.goto_poweroff_flag == 0)) {
/* app_var.play_poweron_tone = 1; */
app_var.play_poweron_tone = 0;
power_set_mode(TCFG_LOWPOWER_POWER_SEL);
r_printf("switch to bt\n");
task_switch_to_bt();
}
sys_timeout_add(NULL, tws_pair_wait_bt_init_callback, 1000);
#endif
}
/*充电舱命令处理函数,所有命令携带8bit有效数据*/
int app_umidigi_chargestore_event_handler(struct umidigi_chargestore_event *umidigi_chargestore_dev)
{
int ret = false;
struct application *app = get_current_app();
#if defined(TCFG_CHARGE_KEEP_UPDATA) && TCFG_CHARGE_KEEP_UPDATA
//在升级过程中,不响应智能充电舱app层消息
if (dual_bank_update_exist_flag_get() || classic_update_task_exist_flag_get()) {
return ret;
}
#endif
switch (umidigi_chargestore_dev->event) {
case CMD_RESERVED_0:
log_info("event_CMD_RESERVED_0\n");
break;
case CMD_FACTORY_RESET:
log_info("event_CMD_FACTORY_RESET\n");
/*该命令携带固定数据0x55*/
if (umidigi_chargestore_dev->value != 0x55) {
break;
}
#if TCFG_USER_TWS_ENABLE
bt_tws_remove_pairs();
#endif
user_send_cmd_prepare(USER_CTRL_DEL_ALL_REMOTE_INFO, 0, NULL);
cpu_reset();
break;
case CMD_RESERVED_2:
log_info("event_CMD_RESERVED_2\n");
break;
case CMD_OPEN_CASE:
log_info("event_CMD_OPEN_CASE\n");
/*在收到其中一个开盖命令后,延迟2s进行耳机端开盖的相关操作*/
/*防止被其他开盖命令导致的通讯口电平变化所影响*/
if (!__this->open_case_timer) {
__this->open_case_timer = sys_timeout_add(NULL, open_case_callback, 2000);
}
if (__this->case_battery_level == 0xff) {
__this->power_sync = 1;
}
/*该命令携带的8bit dataBIT[7]为充电舱状态 BIT[6:0]为充电舱电量*/
__this->case_charger_state = umidigi_chargestore_dev->value >> 7;
__this->case_battery_level = umidigi_chargestore_dev->value & 0x7f;
if (__this->case_battery_level != __this->pre_power_lvl) {
__this->power_sync = 1;
}
__this->pre_power_lvl = __this->case_battery_level;
break;
case CMD_CLOSE_CASE:
log_info("event_CMD_CLOSE_CASE\n");
/*该命令携带的8bit dataBIT[7:2]为固定数据0x15*/
/*BIT[1]1:右耳在仓 0:右耳不在仓, BIT[0]:1:左耳在仓 0:左耳不在仓*/
if ((umidigi_chargestore_dev->value >> 2) != 0x15) {
break;
}
__this->r_ear_whether_in_box = (umidigi_chargestore_dev->value & 0x02) >> 1;
__this->l_ear_whether_in_box = umidigi_chargestore_dev->value & 0x01;
__this->ear_number = __this->r_ear_whether_in_box + __this->l_ear_whether_in_box;
/* r_printf("r=%d l=%d\n", __this->r_ear_whether_in_box, __this->l_ear_whether_in_box); */
/* r_printf("ear_number = %d\n", __this->ear_number); */
if (!__this->cover_status) {//当前为合盖
#if (TCFG_BLE_DEMO_SELECT == DEF_BLE_DEMO_ADV)
if ((__this->bt_init_ok) && (tws_api_get_role() == TWS_ROLE_MASTER)) {
bt_ble_icon_close(1);
}
#elif (TCFG_BLE_DEMO_SELECT == DEF_BLE_DEMO_ADV_RCSP)
if ((__this->bt_init_ok) && (tws_api_get_role() == TWS_ROLE_MASTER)) {
bt_ble_adv_ioctl(BT_ADV_SET_EDR_CON_FLAG, SECNE_DISMISS, 1);
}
#endif
if (!__this->timer) {
__this->timer = sys_timeout_add(NULL, umidigi_chargestore_timeout_deal, 2000);
if (!__this->timer) {
log_error("timer alloc err!\n");
} else {
__this->close_ing = 1;
}
} else {
sys_timer_modify(__this->timer, 2000);
__this->close_ing = 1;
}
} else {
__this->ear_number = 1;
__this->close_ing = 0;
}
break;
case CMD_ENTER_PAIRING_MODE:
log_info("event_CMD_ENTER_PAIRING_MODE\n");
/*该命令携带固定数据0x55*/
if (umidigi_chargestore_dev->value != 0x55) {
break;
}
if (!__this->pair_timer) {
__this->pair_timer = sys_timeout_add(NULL, tws_pair_callback, 2000);
}
break;
case CMD_DUT_MODE_CMD:
log_info("event_CMD_DUT_MODE_CMD\n");
break;
case CMD_USB_STATE:
log_info("event_CMD_USB_STATE\n");
/*该命令携带固定数据0x05或0x70 0x05: USB IN, 0x70: USB OUT*/
if (umidigi_chargestore_dev->value == 0x05) {
__this->usb_state = 1;
} else if (umidigi_chargestore_dev->value == 0x70) {
__this->usb_state = 0;
}
break;
case CMD_RESERVED_B:
log_info("event_CMD_RESERVED_B\n");
break;
case CMD_SEND_CASE_BATTERY:
log_info("event_CMD_SEND_CASE_BATTERY\n");
/*该命令携带的8bit dataBIT[7]为充电舱状态 BIT[6:0]为充电舱电量*/
__this->case_charger_state = umidigi_chargestore_dev->value >> 7;
__this->case_battery_level = umidigi_chargestore_dev->value & 0x7f;
break;
default:
break;
}
}
void umidigi_chargestore_event_to_user(u32 type, u8 event, u8 data)
{
struct sys_event e;
e.type = SYS_DEVICE_EVENT;
e.arg = (void *)type;
e.u.umidigi_chargestore.event = event;
e.u.umidigi_chargestore.value = data;
sys_event_notify(&e);
}
/*umidigi充电舱消息处理*/
void app_umidigi_chargetore_message_deal(u16 message)
{
u8 cmd, data;
cmd = (message & CMD_IN_MESSAGE) >> 10;
data = (message & DATA_IN_MESSAGE) >> 2;
#if TCFG_TEST_BOX_ENABLE
//测试盒在线时,不解码数据
if (testbox_get_status()) {
return;
}
#endif
switch (cmd) {
case CMD_RESERVED_0:
log_info("reserved0\n");
umidigi_chargestore_event_to_user(DEVICE_EVENT_UMIDIGI_CHARGE_STORE, CMD_RESERVED_0, data);
break;
case CMD_FACTORY_RESET:
//充电仓不删除配对信息
break;
__this->cover_status = 1;
__this->close_ing = 0;
r_printf("factory reset\n");
umidigi_chargestore_event_to_user(DEVICE_EVENT_UMIDIGI_CHARGE_STORE, CMD_FACTORY_RESET, data);
break;
case CMD_RESERVED_2:
log_info("reserved2\n");
umidigi_chargestore_event_to_user(DEVICE_EVENT_UMIDIGI_CHARGE_STORE, CMD_RESERVED_2, data);
break;
case CMD_OPEN_CASE:
__this->cover_status = 1;
__this->close_ing = 0;
log_info("open case\n");
//切模式过程中不发送消息,防止堆满消息
if (__this->switch2bt == 0) {
umidigi_chargestore_event_to_user(DEVICE_EVENT_UMIDIGI_CHARGE_STORE, CMD_OPEN_CASE, data);
}
break;
case CMD_CLOSE_CASE:
__this->cover_status = 0;
log_info("close case\n");
umidigi_chargestore_event_to_user(DEVICE_EVENT_UMIDIGI_CHARGE_STORE, CMD_CLOSE_CASE, data);
break;
case CMD_ENTER_PAIRING_MODE:
__this->cover_status = 1;
log_info("enter pairing mode\n");
umidigi_chargestore_event_to_user(DEVICE_EVENT_UMIDIGI_CHARGE_STORE, CMD_ENTER_PAIRING_MODE, data);
break;
case CMD_DUT_MODE_CMD:
log_info("dut mode\n");
umidigi_chargestore_event_to_user(DEVICE_EVENT_UMIDIGI_CHARGE_STORE, CMD_DUT_MODE_CMD, data);
break;
case CMD_USB_STATE:
log_info("usb state\n");
umidigi_chargestore_event_to_user(DEVICE_EVENT_UMIDIGI_CHARGE_STORE, CMD_USB_STATE, data);
break;
case CMD_RESERVED_B:
log_info("reservedB\n");
umidigi_chargestore_event_to_user(DEVICE_EVENT_UMIDIGI_CHARGE_STORE, CMD_RESERVED_B, data);
break;
case CMD_SEND_CASE_BATTERY:
log_info("received case battery\n");
umidigi_chargestore_event_to_user(DEVICE_EVENT_UMIDIGI_CHARGE_STORE, CMD_SEND_CASE_BATTERY, data);
break;
default:
log_info("received an invalid message!\n");
break;
}
}
#endif