Files
2026-08-19 16:05:36 +08:00

425 lines
13 KiB
C

#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "app_protocol_api.h"
#include "system/includes.h"
#include "vm.h"
#include "audio_config.h"
#include "app_power_manage.h"
#include "user_cfg.h"
#include "earphone.h"
#include "btstack/avctp_user.h"
#include "btstack/bluetooth.h"
#include "bt_tws.h"
#if AI_APP_PROTOCOL
#if APP_PROTOCOL_GFPS_CODE
extern void *gfps_app_ble_hdl;
/* extern u32 unactice_device_cmd_prepare(USER_CMD_TYPE cmd, u16 param_len, u8 *param); */
extern void tws_dual_conn_close();
extern int gfps_tws_data_deal(u8 *data, int len);
extern void audio_app_volume_set(u8 state, s16 volume, u8 fade);
extern bool get_gfps_pair_state(void);
extern void set_gfps_pair_state(u8 state);
extern void gfps_set_battery_ui_enable(uint8_t enable);
extern void gfps_set_pair_mode(void *priv);
extern void gfps_all_info_recover(u8 name_reset);
extern void gfps_sibling_sync_info();
extern int gfps_disconnect(void *addr);
extern void gfps_bt_ble_adv_enable(u8 enable);
extern void gfps_adv_interval_set(u16 value);
extern void gfps_sibling_data_send(u8 type, u8 *data, u16 len);
extern int gfps_ble_adv_enable(u8 enable);
extern void gfps_battery_update(void);
extern void bt_set_need_keep_scan(u8 en);
extern int audio_digital_vol_update_parm(u8 dvol_idx, s32 param);
extern void set_wait_poweroff_time(u16 time);
/**
弹窗的逻辑:
1、没有任何手机配对记录情况,广播初始配对广播。
2、开机有配对记录广播后续配对广播,回连超时进入配对状态时,广播初始配对广播。
3、回连手机发现linkkey_missing,且没有任何手机配对记录了,广播初始配对广播。
4、连上任意一台手机后, 广播后续配对广播,断开进入配对状态也是广播后续配对广播。(客户要求断开后也广播初始配对广播)
5、恢复出厂设置时,需要调用一下gfps_all_info_recover(1)清除一下GFP的账号信息和修改的蓝牙名字
6、认证的时候,需要有一个UI来触发初始配对广播(调用gfps_set_pair_mode(NULL)),可以为长按左右耳5秒之类的
7、耳机关机要关电量显示
*/
#define TONE_GOOGLE "tone_en/google.*"
#define GFPS_SIBLING_SYNC_TYPE_ADV_MAC_STATE 0x04
#define ADV_INIT_PAIR_IN_PAIR_MODE 0 //进入配对状态广播初始配对广播
struct gfps_protocol_t {
u8 poweron_reconn;
u8 close_icon;
};
static struct gfps_protocol_t gfps_protocol = {0};
#define __this (&gfps_protocol)
#define INIT_PAIR_ADV_INTERVAL 150
#define SUBS_PAIR_ADV_INTERVAL 352
void gfps_set_pair_mode_by_user(u8 disconn_ble)
{
if (disconn_ble) {
gfps_disconnect(NULL);
}
gfps_adv_interval_set(INIT_PAIR_ADV_INTERVAL);
set_gfps_pair_state(0);
gfps_bt_ble_adv_enable(0);
gfps_bt_ble_adv_enable(1);
}
//重写弱函数,获取电量
extern u8 get_charge_online_flag(void);
extern u8 get_tws_sibling_bat_persent(void);
void generate_rfcomm_battery_data(u8 *data)
{
u8 self_val = get_charge_online_flag() << 7 | get_vbat_percent();
#if TCFG_USER_TWS_ENABLE
u8 sibling_val = get_tws_sibling_bat_persent();
data[2] = 0xFF; //充电仓电量
#if TCFG_CHARGESTORE_ENABLE
if (self_val >> 7 || sibling_val >> 7) { //有任意一直耳机充电时才显示充电仓电量
data[2] = chargestore_get_power_level(); //充电仓电量
}
#endif
data[0] = (tws_api_get_local_channel() == 'L') ? self_val : sibling_val; //左耳电量
data[1] = (tws_api_get_local_channel() == 'R') ? self_val : sibling_val; //右耳电量
#else
data[0] = self_val;
data[1] = 0xFF;
data[2] = 0xFF;
#endif
printf("%s, l:%x, r:%x, bat:%x", __func__, data[0], data[1], data[2]);
}
extern int lmp_hci_write_scan_enable(u8 enable);
static void gfps_ctl_bt_enter_pair_mode()
{
printf("%s", __func__);
tws_dual_conn_close();
lmp_hci_write_scan_enable((1 << 1) | 1);
bt_set_need_keep_scan(1);
}
//重写弱函数,GFP-BLE配对认证成功后,需要先断开一个设备或者开可连接,等手机连接经典蓝牙
extern u8 *get_cur_connect_phone_mac_addr(void);
void gfps_before_pair_new_device(u8 *seeker_addr)
{
#if TCFG_USER_GFPS_PROCESS_CTL
app_user_gfps_before_pair_new_device(seeker_addr);
#else
u8 remote_edr_addr[6];
u8 *tmp_addr = NULL;
for (int i = 0; i < 6; i ++) {
remote_edr_addr[i] = seeker_addr[5 - i];
}
if (get_curr_channel_state()) {
tmp_addr = get_cur_connect_phone_mac_addr();
if (memcmp(tmp_addr, remote_edr_addr, 6) != 0) {
printf("Subsequent pair\n");
printf("USER_CTRL_DISCONNECTION_HCI send\n");
user_send_cmd_prepare(USER_CTRL_DISCONNECTION_HCI, 0, NULL);
} else {
printf("Retroactive Pair\n");
}
}
printf("func:%s, line:%d", __FUNCTION__, __LINE__);
#endif
}
struct google_tone_ctl_t {
u8 l_en;
u8 r_en;
u8 l_mute;
u8 r_mute;
};
static struct google_tone_ctl_t google_tone_ctl = {0};
static void google_tone_set_volume()
{
printf("google_tone_set_volume");
/* printf("func:%s:%d", __FUNCTION__, app_audio_volume_max_query(SysVol_TONE)); */
/* u32 param = VOLUME_NODE_CMD_SET_VOL | app_audio_volume_max_query(SysVol_TONE); */
/* jlstream_set_node_param(NODE_UUID_VOLUME_CTRLER, "Vol_BtcRing", &param, sizeof(param)); */
}
/* #if TCFG_USER_TWS_ENABLE */
/* static void tws_google_tone_callback(int priv, enum stream_event event) */
/* { */
/* printf("func:%s, event:%d", __FUNCTION__, event); */
/* if (event == STREAM_EVENT_START) { */
/* int msg[] = {(int)google_tone_set_volume, 0}; */
/* os_taskq_post_type("app_core", Q_CALLBACK, ARRAY_SIZE(msg), msg); */
/* } */
/* } */
/* REGISTER_TWS_TONE_CALLBACK(tws_google_tone_stub) = { */
/* .func_uuid = 0x2EC850AE, */
/* .callback = tws_google_tone_callback, */
/* }; */
/* #endif */
/* static int google_tone_play_callback(void *priv, enum stream_event event) */
/* { */
/* printf("func:%s, event:%d", __FUNCTION__, event); */
/* if (event == STREAM_EVENT_START) { */
/* int msg[] = {(int)google_tone_set_volume, 0}; */
/* os_taskq_post_type("app_core", Q_CALLBACK, ARRAY_SIZE(msg), msg); */
/* } */
/* return 0; */
/* } */
void google_tone_play_deal()
{
if (strcmp(os_current_task(), "app_core")) {
printf("%s, task:%s", __func__, os_current_task());
int msg[] = {(int)google_tone_play_deal, 0};
os_taskq_post_type("app_core", Q_CALLBACK, ARRAY_SIZE(msg), msg);
return;
}
/* tone_player_stop(); */
/* tone_player_play(); */
}
void google_tone_mute_ctl(u8 self, u8 charge_flag)
{
u8 *mute = &google_tone_ctl.l_mute;
if ((tws_api_get_local_channel() == 'L' && !self) ||
(tws_api_get_local_channel() == 'R' && self)) {
mute = &google_tone_ctl.r_mute;
printf("%s, r_mute:%d, charge_flag:%d", __func__, *mute, charge_flag);
} else {
printf("%s, l_mute:%d, charge_flag:%d", __func__, *mute, charge_flag);
}
if (*mute != charge_flag) {
*mute = charge_flag;
google_tone_play_deal();
}
}
int gfps_protocol_tws_send_to_sibling(u16 opcode, u8 *data, u16 len)
{
return tws_api_send_data_to_sibling(data, len, 0x23080315);
}
static void __tws_rx_from_sibling(u8 *data, int len)
{
gfps_tws_data_deal(data, len);
switch (data[0]) {
case GFPS_SIBLING_SYNC_TYPE_ADV_MAC_STATE:
gfps_adv_interval_set(data[1] ? SUBS_PAIR_ADV_INTERVAL : INIT_PAIR_ADV_INTERVAL);
set_gfps_pair_state(data[1]);
le_controller_set_mac((void *)&data[2]);
gfps_bt_ble_adv_enable(0);
gfps_bt_ble_adv_enable(1);
break;
}
free(data);
}
static void gfps_protocol_rx_from_sibling(void *_data, u16 len, bool rx)
{
int err = 0;
if (rx) {
printf(">>>%s \n", __func__);
printf("len :%d\n", len);
put_buf(_data, len);
u8 *rx_data = malloc(len);
if (!rx_data) {
return;
}
memcpy(rx_data, _data, len);
int msg[4];
msg[0] = (int)__tws_rx_from_sibling;
msg[1] = 2;
msg[2] = (int)rx_data;
msg[3] = (int)len;
err = os_taskq_post_type("app_core", Q_CALLBACK, ARRAY_SIZE(msg), msg);
if (err) {
printf("tws rx post fail\n");
}
}
}
//发送给对耳
REGISTER_TWS_FUNC_STUB(app_vol_sync_stub) = {
.func_id = 0x23080315,
.func = gfps_protocol_rx_from_sibling,
};
int gfps_message_deal_handler(int id, int opcode, u8 *data, u32 len)
{
switch (opcode) {
case APP_PROTOCOL_LIB_TWS_DATA_SYNC:
gfps_protocol_tws_send_to_sibling(opcode, data, len);
break;
case APP_PROTOCOL_GFPS_RING_STOP_ALL:
printf("GFPS_RING_STOP_ALL");
google_tone_ctl.l_en = 0;
google_tone_ctl.r_en = 0;
google_tone_play_deal();
break;
case APP_PROTOCOL_GFPS_RING_RIGHT:
printf("GFPS_RING_RIGHT");
google_tone_ctl.l_en = 0;
google_tone_ctl.r_en = 1;
google_tone_play_deal();
break;
case APP_PROTOCOL_GFPS_RING_LEFT:
printf("GFPS_RING_LEFT");
google_tone_ctl.l_en = 1;
google_tone_ctl.r_en = 0;
google_tone_play_deal();
break;
case APP_PROTOCOL_GFPS_RING_ALL:
printf("GFPS_RING_ALL");
google_tone_ctl.l_en = 1;
google_tone_ctl.r_en = 1;
google_tone_play_deal();
break;
case APP_PROTOCOL_GFPS_HEARABLE_CONTROLS:
printf("APP_PROTOCOL_GFPS_HEARABLE_CONTROLS display:%x settable:%x current:%x\n", data[0], data[1], data[2]);
break;
}
return 0;
}
//关机广播收仓
void gfps_need_adv_close_icon_set(u8 en)
{
printf("func:%s, en:%d", __FUNCTION__, en);
__this->close_icon = en;
}
void gfps_poweroff_adv_close_icon()
{
printf("func:%s, line:%d", __FUNCTION__, __LINE__);
if (__this->close_icon) {
void set_wait_poweroff_time(u16 time);
set_wait_poweroff_time(2000); //广播800ms
gfps_adv_interval_set(48); //连接上手机间隔改为30ms
gfps_set_battery_ui_enable(0); //关闭电量显示,会重新开关广播
}
}
int gfps_hci_event_handler(struct bt_event *bt)
{
switch (bt->event) {
case HCI_EVENT_DISCONNECTION_COMPLETE:
switch (bt->value) {
case ERROR_CODE_PIN_OR_KEY_MISSING:
printf("GFP linkkey missing");
if (!btstack_get_num_of_remote_device_recorded()) { //没有配对记录的时候,广播初始配对广播
gfps_all_info_recover(0);
gfps_adv_interval_set(INIT_PAIR_ADV_INTERVAL); //连接上手机间隔改为93.75ms
gfps_set_pair_mode_by_user(0);
}
break;
}
break;
}
return 0;
}
int gfps_bt_status_event_handler(struct bt_event *bt)
{
u8 ret = 0;
switch (bt->event) {
// 需要切换蓝牙的命令
case BT_STATUS_A2DP_MEDIA_START:
break;
case BT_STATUS_INIT_OK:
if (btstack_get_num_of_remote_device_recorded()) {
__this->poweron_reconn = 1;
}
break;
case BT_STATUS_SECOND_CONNECTED:
case BT_STATUS_FIRST_CONNECTED:
__this->poweron_reconn = 0;
gfps_adv_interval_set(SUBS_PAIR_ADV_INTERVAL); //连接上手机间隔改为220ms,防止fast pair validator测试fail
set_gfps_pair_state(1);
gfps_bt_ble_adv_enable(0);
gfps_bt_ble_adv_enable(1);
break;
case BT_STATUS_PHONE_INCOME:
case BT_STATUS_PHONE_OUT:
case BT_STATUS_PHONE_ACTIVE:
gfps_ble_adv_enable(0);
break;
case BT_STATUS_PHONE_HANGUP:
gfps_ble_adv_enable(1);
break;
}
return 0;
}
static int gfps_app_power_event_handler(struct device_event *dev)
{
switch (dev->event) {
#if TCFG_USER_TWS_ENABLE
case POWER_EVENT_SYNC_TWS_VBAT_LEVEL:
printf("update gfps bat");
if (get_tws_sibling_bat_persent() != 0xFF) {
google_tone_mute_ctl(0, get_tws_sibling_bat_persent() >> 7);
}
gfps_battery_update();
break;
#endif
case POWER_EVENT_POWER_CHANGE:
printf("update gfps bat");
google_tone_mute_ctl(1, get_charge_online_flag());
gfps_battery_update();
break;
}
return 0;
}
int gfps_sys_event_handler_specific(struct sys_event *event)
{
switch (event->type) {
case SYS_DEVICE_EVENT:
if ((u32)event->arg == DEVICE_EVENT_FROM_POWER) {
gfps_app_power_event_handler(&event->u.dev);
}
break;
case SYS_BT_EVENT:
if ((u32)event->arg == SYS_BT_EVENT_TYPE_CON_STATUS) {
gfps_bt_status_event_handler(&event->u.bt);
} else if ((u32)event->arg == SYS_BT_EVENT_TYPE_HCI_STATUS) {
gfps_hci_event_handler(&event->u.bt);
}
break;
}
return 0;
}
struct app_protocol_private_handle_t gfps_private_handle = {
.sys_event_handler = gfps_sys_event_handler_specific,
};
#endif
#endif