Files

550 lines
18 KiB
C
Raw Permalink 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 "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