在逗猫棒的基础上实现蓝牙转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,89 @@
#include "adv_adaptive_noise_reduction.h"
#include "syscfg_id.h"
#include "user_cfg_id.h"
#include "rcsp_adv_bluetooth.h"
#if (RCSP_ADV_EN && RCSP_ADV_ANC_VOICE && RCSP_ADV_ADAPTIVE_NOISE_REDUCTION)
#include "audio_anc.h"
/**
* @brief 获取自适应降噪信息开关
*
* @result 1:自适应降噪开 0:自适应降噪关
*/
int get_adaptive_noise_reduction_switch()
{
int sw_result = audio_anc_coeff_mode_get();
return sw_result;
}
/**
* @brief 开启自适应降噪
*/
void set_adaptive_noise_reduction_on()
{
audio_anc_coeff_adaptive_set(1, 1, 1);
}
/**
* @brief 关闭自适应降噪
*/
void set_adaptive_noise_reduction_off()
{
audio_anc_coeff_adaptive_set(0, 1, 1);
}
static u8 adaptive_noise_reduction_reseting = 0; // 重新检测状态,1:进行中 0:结束
static u8 adaptive_noise_reduction_reset_result = 0; // 重新检测结果,1:失败 0:成功
/**
* @brief 自适应降噪重新检测
*/
void set_adaptive_noise_reduction_reset()
{
audio_anc_mode_ear_adaptive();
adaptive_noise_reduction_reseting = 1;
}
/**
* @brief 获取自适应降噪重新检测状态
*
* @result 1:进行中 0:结束
*/
u8 get_adaptive_noise_reduction_reset_status()
{
return adaptive_noise_reduction_reseting;
}
/**
* @brief 获取自适应降噪重新检测结果
*
* @result 1:失败 0:成功
*/
u8 get_adaptive_noise_reduction_reset_result()
{
return adaptive_noise_reduction_reset_result;
}
/**
* @brief 自适应降噪重新检测结果回调
*/
void set_adaptive_noise_reduction_reset_callback(u8 result)
{
adaptive_noise_reduction_reseting = 0;
if (result != 0) {
// 成功
adaptive_noise_reduction_reset_result = 0;
} else {
// 失败
adaptive_noise_reduction_reset_result = 1;
}
// 通知手机APP
/* JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_ANC_VOICE, NULL, 0); */
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_ADAPTIVE_NOISE_REDUCTION, NULL, 0);
}
#endif
@@ -0,0 +1,48 @@
#ifndef __ADV_ADAPTIVE_NOISE_REDUCTION_H__
#define __ADV_ADAPTIVE_NOISE_REDUCTION_H__
#include "le_rcsp_adv_module.h"
/**
* @brief 获取自适应降噪信息开关
*
* @result 1:自适应降噪开 0:自适应降噪关
*/
int get_adaptive_noise_reduction_switch();
/**
* @brief 开启自适应降噪
*/
void set_adaptive_noise_reduction_on();
/**
* @brief 关闭自适应降噪
*/
void set_adaptive_noise_reduction_off();
/**
* @brief 自适应降噪重新检测
*/
void set_adaptive_noise_reduction_reset();
/**
* @brief 获取自适应降噪重新检测状态
*
* @result 1:进行中 0:结束
*/
u8 get_adaptive_noise_reduction_reset_status();
/**
* @brief 获取自适应降噪重新检测结果
*
* @result 1:失败 0:成功
*/
u8 get_adaptive_noise_reduction_reset_result();
/**
* @brief 自适应降噪重新检测结果回调
*/
void set_adaptive_noise_reduction_reset_callback(u8 result);
#endif
@@ -0,0 +1,54 @@
#ifndef __ADV_AI_NO_PICK_H__
#define __ADV_AI_NO_PICK_H__
#include "system/includes.h"
typedef enum {
RCSP_AI_NO_PICK_SENSITIVITY_HIGH = 0x00,
RCSP_AI_NO_PICK_SENSITIVITY_LOW = 0x01,
} RCSP_AI_NO_PICK_SENSITIVITY;
typedef enum {
RCSP_AI_NO_PICK_AUTO_CLOSE_TIME_NONE = 0x00, // 不自动关闭
RCSP_AI_NO_PICK_AUTO_CLOSE_TIME_5s = 0x01,
RCSP_AI_NO_PICK_AUTO_CLOSE_TIME_15s = 0x02,
RCSP_AI_NO_PICK_AUTO_CLOSE_TIME_30s = 0x03,
} RCSP_AI_NO_PICK_AUTO_CLOSE_TIME;
/**
* @brief 获取智能免摘开关
*
* @result bool
*/
bool get_ai_no_pick_switch();
/**
* @brief 开启智能免摘
*/
void set_ai_no_pick_switch(bool p_switch);
/**
* @brief 获取智能免摘敏感度
*
* @result RCSP_AI_NO_PICK_SENSITIVITY
*/
RCSP_AI_NO_PICK_SENSITIVITY get_ai_no_pick_sensitivity();
/**
* @brief 设置智能免摘敏感度
*/
void set_ai_no_pick_sensitivity(RCSP_AI_NO_PICK_SENSITIVITY sensitivity);
/**
* @brief 获取智能免摘自动关闭时间
*
* @result RCSP_AI_NO_PICK_AUTO_CLOSE_TIME
*/
RCSP_AI_NO_PICK_AUTO_CLOSE_TIME get_ai_no_pick_auto_close_time();
/**
* @brief 设置智能免摘自动关闭时间
*/
void set_ai_no_pick_auto_close_time(RCSP_AI_NO_PICK_AUTO_CLOSE_TIME time_type);
#endif // __ADV_AI_NO_PICK_H__
@@ -0,0 +1,335 @@
#include "app_config.h"
#include "syscfg_id.h"
#include "user_cfg_id.h"
#include "le_rcsp_adv_module.h"
#include "adv_anc_voice.h"
#include "adv_setting_common.h"
#include "rcsp_adv_tws_sync.h"
#include "rcsp_adv_opt.h"
#include "rcsp_adv_bluetooth.h"
#if (RCSP_ADV_EN && RCSP_ADV_ANC_VOICE)
#include "audio_anc.h"
// anc信息:mode(1byte/0/1/2) + ( left_max(2byte) + right_max(2byte) + left_cur_val(2byte) + right_cur_val(2byte) ) * 3
static u8 g_anc_info[25] = {0};
extern int get_bt_tws_connect_status();
extern u8 JL_get_cur_bt_channel_sel(void);
static bool check_pos_neg(u8 mode)
{
bool ret = false;
u8 offset = 1 + mode * 8;
#if TCFG_USER_TWS_ENABLE
if ('R' == tws_api_get_local_channel()) {
offset += 2;
}
#endif
s16 val = g_anc_info[offset] << 8 | g_anc_info[offset + 1];
if (val < 0) {
ret = true;
}
return ret;
}
void get_anc_voice_info(u8 *anc_info)
{
memcpy(anc_info, g_anc_info, sizeof(g_anc_info));
}
void set_anc_voice_info(u8 *anc_info)
{
memcpy(g_anc_info, anc_info, sizeof(g_anc_info));
}
static void update_anc_voice_vm_value(u8 *anc_info)
{
u8 anc_vm_info[25] = {-1};
int ret = syscfg_read(CFG_RCSP_ADV_ANC_VOICE_MODE, anc_vm_info, 1);
if (0 != memcmp(anc_vm_info, anc_info, 1)) {
ret = syscfg_write(CFG_RCSP_ADV_ANC_VOICE_MODE, anc_info, 1);
}
ret = syscfg_read(CFG_RCSP_ADV_ANC_VOICE, anc_vm_info + 1, sizeof(anc_vm_info) - 1);
if (0 != memcmp(anc_vm_info + 1, anc_info + 1, sizeof(anc_vm_info) - 1)) {
ret = syscfg_write(CFG_RCSP_ADV_ANC_VOICE, anc_info + 1, sizeof(anc_vm_info) - 1);
}
}
static void anc_voice_sync(u8 *anc_info)
{
#if TCFG_USER_TWS_ENABLE
if (get_bt_tws_connect_status()) {
update_adv_setting(BIT(ATTR_TYPE_ANC_VOICE));
}
#endif
}
static void anc_voice_effect_set(u8 mode, s16 value)
{
static s16 value_old = -1;
#if TCFG_AUDIO_ANC_ENABLE
extern void anc_gain_app_value_set(int app_value);
if (value != value_old) {
/* audio_anc_gain(value, value); */
anc_gain_app_value_set(value);
}
anc_mode_switch(mode + 1, 1);
#endif
value_old = value;
}
static void anc_voice_state_update(void)
{
u8 offset = 0;
u8 mode = g_anc_info[offset++];
offset += mode * 8;
s16 left_max = g_anc_info[offset++] << 8 | g_anc_info[offset++];
s16 right_max = g_anc_info[offset++] << 8 | g_anc_info[offset++];
s16 left_val = g_anc_info[offset++] << 8 | g_anc_info[offset++];
s16 right_val = g_anc_info[offset++] << 8 | g_anc_info[offset++];
#if TCFG_USER_TWS_ENABLE
if ('R' == tws_api_get_local_channel()) {
if (check_pos_neg(mode) && right_val >= right_max) {
anc_voice_effect_set(mode, right_val);
} else if (right_max >= right_val) {
anc_voice_effect_set(mode, right_val);
}
return;
}
#endif
if (check_pos_neg(mode) && left_val >= left_max) {
anc_voice_effect_set(mode, left_val);
} else if (left_max >= left_val) {
anc_voice_effect_set(mode, left_val);
}
}
void deal_anc_voice(u8 *anc_setting, u8 write_vm, u8 tws_sync)
{
u8 anc_info[25] = {0};
if (!anc_setting) {
get_anc_voice_info(anc_info);
} else {
u8 mode = anc_setting[0];
g_anc_info[0] = mode;
memcpy(g_anc_info + 1 + mode * 8, anc_setting + 1, 8);
memcpy(anc_info, g_anc_info, sizeof(anc_info));
}
if (write_vm) {
update_anc_voice_vm_value(anc_info);
}
if (tws_sync) {
anc_voice_sync(anc_info);
}
anc_voice_state_update();
}
#if TCFG_USER_TWS_ENABLE
#define TWS_FUNC_ID_ANC_VOICE_SYNC \
(((u8)('R' + 'C' + 'S' + 'P') << (3 * 8)) | \
((u8)('A' + 'N' + 'C' + 'S') << (2 * 8)) | \
((u8)('V' + 'O' + 'I' + 'C' + 'E') << (1 * 8)) | \
((u8)('S' + 'Y' + 'N' + 'C') << (0 * 8)))
void anc_voice_max_val_swap_sync(u8 *data, u16 len)
{
update_anc_voice_vm_value(g_anc_info);
}
static void anc_voice_state_sync(u8 *data, u16 len)
{
if (NULL == data || 0 == len) {
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_ANC_VOICE, NULL, 0);
return;
}
u8 offset = 9;
// 假如当前是右耳,应该填写左值
// 假如当前是左耳,应该填写右值
if ('L' == tws_api_get_local_channel()) {
offset += 2;
}
// 根据左右耳填充对应的最大值信息
// 降噪(2byte) + 通透(2byte)
memcpy(g_anc_info + offset, data, 2);
memcpy(g_anc_info + offset + 4, data + 4, 2);
offset += 8;
memcpy(g_anc_info + offset, data + 2, 2);
memcpy(g_anc_info + offset + 4, data + 6, 2);
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_ANC_VOICE_MAX_SYNC, NULL, 0);
}
static void adv_anc_voice_tws_func_t(void *data, u16 len, bool rx)
{
if (rx) {
anc_voice_state_sync((u8 *)data, len);
}
}
REGISTER_TWS_FUNC_STUB(adv_tws_sync) = {
.func_id = TWS_FUNC_ID_ANC_VOICE_SYNC,
.func = adv_anc_voice_tws_func_t,
};
#endif
void rcsp_adv_voice_mode_update(u8 mode)
{
u8 anc_info[25] = {0};
get_anc_voice_info(anc_info);
anc_info[0] = mode;
if (mode) {
memcpy(anc_info + 1, anc_info + 1 + mode * 8, 8);
}
deal_anc_voice(anc_info, 1, 0);
#if TCFG_USER_TWS_ENABLE
if (get_bt_tws_connect_status() && TWS_ROLE_SLAVE == tws_api_get_role()) {
tws_api_send_data_to_sibling(NULL, 0, TWS_FUNC_ID_ANC_VOICE_SYNC);
return;
}
#endif
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_ANC_VOICE, NULL, 0);
}
int anc_voice_setting_sync()
{
int ret = 0;
u8 anc_info[8] = {0};
#if (TCFG_AUDIO_ANC_ENABLE)
/* extern int anc_gain_tab[3]; */
/* u16 noise_reduction = (u16)(16384 & (u16) - 1); // 调用接口获取降噪最大值 */
/* u16 transparent = (u16)(16384 & (u16) - 1); // 调用接口获取通透最大值 */
u16 noise_reduction = 16384; // 调用接口获取降噪最大值
u16 transparent = 16384; // 调用接口获取通透最大值
#else
u16 noise_reduction = 0;
u16 transparent = 0;
#endif
anc_info[0] = ((u8 *)&noise_reduction)[1];
anc_info[1] = ((u8 *)&noise_reduction)[0];
anc_info[2] = ((u8 *)&transparent)[1];
anc_info[3] = ((u8 *)&transparent)[0];
u8 offset = 9;
#if TCFG_USER_TWS_ENABLE
if ('R' == tws_api_get_local_channel()) {
offset += 2;
}
#endif
// 初始值最大和当前值都是同一个值
// 默认是左值
u8 tmp_value = -1;
int result = 0;
if ((result = syscfg_read(CFG_RCSP_ADV_ANC_VOICE_MODE, &tmp_value, sizeof(tmp_value))) != sizeof(tmp_value)) {
tmp_value = offset;
memcpy(g_anc_info + tmp_value, anc_info, 2);
tmp_value += 4;
memcpy(g_anc_info + tmp_value, anc_info, 2);
tmp_value += 4;
memcpy(g_anc_info + tmp_value, anc_info + 2, 2);
tmp_value += 4;
memcpy(g_anc_info + tmp_value, anc_info + 2, 2);
}
#if TCFG_USER_TWS_ENABLE
// 填写当前降噪/通透当前值
memcpy(anc_info + 4, g_anc_info + offset + 4, 2);
memcpy(anc_info + 6, g_anc_info + offset + 8 + 4, 2);
// 把自己的最大值发送给对端
if (get_bt_tws_connect_status()) {
tws_api_send_data_to_sibling(anc_info, sizeof(anc_info), TWS_FUNC_ID_ANC_VOICE_SYNC);
}
#endif
return ret;
}
int anc_voice_setting_init(void)
{
int ret = 1;
u8 anc_mode = -1;
if (syscfg_read(CFG_RCSP_ADV_ANC_VOICE_MODE, &anc_mode, sizeof(anc_mode)) != sizeof(anc_mode)) {
anc_voice_setting_sync();
ret = 0;
}
return ret;
}
// ====================================================
enum {
anc_VOICE_GET_PREP_MSG,
anc_VOICE_SET_CUR_MODE,
anc_VOICE_NOTICE_MSG,
anc_VOICE_GET_CUR_MODE,
};
static void s16_pos_neg_conversion(u8 *data)
{
s16 tmp_val = data[0] << 8 | data[1];
tmp_val = -tmp_val;
data[1] = ((u8 *)&tmp_val)[0];
data[0] = ((u8 *)&tmp_val)[1];
}
u8 anc_voice_info_get(u8 *data, u16 len)
{
u8 offset = 0;
u8 anc_info[25] = {0};
get_anc_voice_info(anc_info);
u8 mode = anc_info[0];
data[offset++] = mode;
memcpy(data + offset, anc_info + 1 + mode * 8, 8);
if (check_pos_neg(mode)) {
for (u8 i = 0; i < 8; i += 2) {
s16_pos_neg_conversion(data + 1 + i);
}
}
offset += 8;
return offset;
}
u8 anc_voice_info_fetch_all_get(u8 *data, u16 len)
{
u8 mode = 0;
u8 offset = 1;
u8 anc_info[25] = {0};
get_anc_voice_info(anc_info);
for (u8 resp_offset = 1; offset < sizeof(anc_info); offset += 8) {
data[resp_offset++] = mode;
memcpy(data + resp_offset, anc_info + offset, 8);
if (check_pos_neg(mode)) {
for (u8 i = 0; i < 8; i += 2) {
s16_pos_neg_conversion(data + 2 + mode * 9 + i);
}
}
resp_offset += 8;
mode++;
}
data[0] = mode;
return len;
}
int anc_voice_info_set(u8 *data, u16 len)
{
int ret = 0;
if (check_pos_neg(data[0])) {
for (u8 i = 0; i < 8; i += 2) {
s16_pos_neg_conversion(data + 1 + i);
}
}
deal_anc_voice(data, 1, 1);
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_ANC_VOICE, NULL, 0);
return ret;
}
#endif
@@ -0,0 +1,19 @@
#ifndef __ADV_ANS_VOICE_H__
#define __ADV_ANS_VOICE_H__
#include "le_rcsp_adv_module.h"
int anc_voice_setting_init(void);
int anc_voice_setting_sync(void);
void deal_anc_voice(u8 *anc_setting, u8 write_vm, u8 tws_sync);
void set_anc_voice_info(u8 *anc_info);
void get_anc_voice_info(u8 *anc_info);
u8 anc_voice_info_get(u8 *data, u16 len);
u8 anc_voice_info_fetch_all_get(u8 *data, u16 len);
int anc_voice_info_set(u8 *data, u16 len);
int update_anc_voice_key_opt(void);
void rcsp_adv_voice_mode_update(u8 mode);
#endif
@@ -0,0 +1,94 @@
#include "app_config.h"
#include "syscfg_id.h"
#include "user_cfg_id.h"
#include "key_event_deal.h"
#include "le_rcsp_adv_module.h"
#include "adv_anc_voice_key.h"
#include "adv_setting_common.h"
#include "rcsp_adv_tws_sync.h"
#include "rcsp_adv_opt.h"
#include "adv_anc_voice.h"
#if (RCSP_ADV_EN)
/* #if (RCSP_ADV_KEY_SET_ENABLE && TCFG_AUDIO_ANC_ENABLE) */
#if (RCSP_ADV_KEY_SET_ENABLE)
#include "audio_anc.h"
#define COMMON_FUNCTION 0xFF
#define ANC_VOICE_TYPE_MAX 3
static u8 g_anc_voice_key_mode[4] = {0, 0, 0, BIT(ANC_VOICE_TYPE_MAX) - 1};
extern int get_bt_tws_connect_status();
void set_anc_voice_key_mode(u8 *anc_voice_mode)
{
memcpy(g_anc_voice_key_mode, anc_voice_mode, sizeof(g_anc_voice_key_mode));
}
void get_anc_voice_key_mode(u8 *anc_voice_mode)
{
memcpy(anc_voice_mode, g_anc_voice_key_mode, sizeof(g_anc_voice_key_mode));
}
static void update_anc_voice_key_vm_value(u8 *anc_voice_mode)
{
syscfg_write(CFG_RCSP_ADV_ANC_VOICE_KEY, anc_voice_mode, 4);
}
static void anc_voice_key_sync(u8 *key_setting_info)
{
#if TCFG_USER_TWS_ENABLE
if (get_bt_tws_connect_status()) {
update_adv_setting(BIT(ATTR_TYPE_ANC_VOICE_KEY));
}
#endif
}
void deal_anc_voice_key_setting(u8 *anc_key_setting, u8 write_vm, u8 tws_sync)
{
u8 anc_voice_key_mode[4] = {0};
if (!anc_key_setting) {
get_anc_voice_key_mode(anc_voice_key_mode);
} else {
set_anc_voice_key_mode(anc_key_setting);
memcpy(anc_voice_key_mode, g_anc_voice_key_mode, sizeof(g_anc_voice_key_mode));
}
if (write_vm) {
update_anc_voice_key_vm_value(anc_voice_key_mode);
}
if (tws_sync) {
anc_voice_key_sync(anc_voice_key_mode);
}
}
int update_anc_voice_key_opt(void)
{
int ret = 0;
#if (RCSP_ADV_ANC_VOICE)
u32 mask = g_anc_voice_key_mode[0] << 24 | g_anc_voice_key_mode[1] << 16 | g_anc_voice_key_mode[2] << 8 | g_anc_voice_key_mode[3];
// 获取当前处于什么模式
#if TCFG_AUDIO_ANC_ENABLE
u8 cur_mode = anc_mode_get();
#else
u8 cur_mode = ANC_OFF;
#endif
u8 next_mode = cur_mode % ANC_VOICE_TYPE_MAX;
for (; next_mode < ANC_VOICE_TYPE_MAX; next_mode++) {
if (mask & BIT(next_mode)) {
rcsp_adv_voice_mode_update(next_mode % ANC_VOICE_TYPE_MAX);
return ret;
}
}
if (mask & BIT(next_mode % ANC_VOICE_TYPE_MAX)) {
rcsp_adv_voice_mode_update(next_mode % ANC_VOICE_TYPE_MAX);
}
#endif
return ret;
}
#endif
#endif
@@ -0,0 +1,12 @@
#ifndef __ADV_ANC_VOICE_KEY_H__
#define __ADV_ANC_VOICE_KEY_H__
#include "le_rcsp_adv_module.h"
void deal_anc_voice_key_setting(u8 *anc_key_setting, u8 write_vm, u8 tws_sync);
void get_anc_voice_key_mode(u8 *anc_voice_mode);
void set_anc_voice_key_mode(u8 *anc_voice_mode);
int update_anc_voice_key_opt(void);
#endif
@@ -0,0 +1,67 @@
#include "app_config.h"
#include "user_cfg.h"
#include "syscfg_id.h"
#include "user_cfg_id.h"
#include "le_rcsp_adv_module.h"
#include "adv_bt_name_setting.h"
#include "adv_setting_common.h"
#include "rcsp_adv_tws_sync.h"
#include "rcsp_adv_opt.h"
#if (RCSP_ADV_EN)
#if RCSP_ADV_NAME_SET_ENABLE
extern int get_bt_tws_connect_status();
void adv_edr_name_change_now(void)
{
extern BT_CONFIG bt_cfg;
extern const char *bt_get_local_name();
extern void lmp_hci_write_local_name(const char *name);
memcpy(bt_cfg.edr_name, _s_info.edr_name, LOCAL_NAME_LEN);
lmp_hci_write_local_name(bt_get_local_name());
}
void set_bt_name_setting(u8 *bt_name_setting)
{
memcpy(_s_info.edr_name, bt_name_setting, 32);
}
void get_bt_name_setting(u8 *bt_name_setting)
{
memcpy(bt_name_setting, _s_info.edr_name, 32);
}
// 1、写入VM
static void update_bt_name_vm_value(u8 *bt_name_setting)
{
syscfg_write(CFG_BT_NAME, bt_name_setting, 32);
}
// 2、同步对端
static void bt_name_sync(u8 *bt_name_setting)
{
#if TCFG_USER_TWS_ENABLE
if (get_bt_tws_connect_status()) {
update_adv_setting(BIT(ATTR_TYPE_EDR_NAME));
}
#endif
}
void deal_bt_name_setting(u8 *bt_name_setting, u8 write_vm, u8 tws_sync)
{
u8 bt_name[32] = {0};
if (!bt_name_setting) {
get_bt_name_setting(bt_name);
} else {
memcpy(bt_name, bt_name_setting, 32);
}
if (write_vm) {
update_bt_name_vm_value(bt_name);
}
if (tws_sync) {
bt_name_sync(bt_name);
}
}
#endif
#endif
@@ -0,0 +1,12 @@
#ifndef __ADV_BT_NAME_SETTING_H__
#define __ADV_BT_NAME_SETTING_H__
#include "le_rcsp_adv_module.h"
#if RCSP_ADV_NAME_SET_ENABLE
void set_bt_name_setting(u8 *bt_name_setting);
void get_bt_name_setting(u8 *bt_name_setting);
#endif
#endif
@@ -0,0 +1,218 @@
#include "app_config.h"
#include "syscfg_id.h"
#include "user_cfg_id.h"
#include "le_rcsp_adv_module.h"
#include "adv_eq_setting.h"
#include "adv_setting_common.h"
#include "rcsp_adv_tws_sync.h"
#include "rcsp_adv_opt.h"
#include "application/audio_eq.h"
#if (RCSP_ADV_EN)
#if RCSP_ADV_EQ_SET_ENABLE
extern int get_bt_tws_connect_status();
extern int eq_mode_get_freq(u8 mode, u16 index);
extern s8 eq_mode_get_gain(u8 mode, u16 index);
extern int eq_mode_set_custom_param(u16 index, int gain);
extern int eq_mode_set(u8 mode);
extern int eq_mode_get_cur(void);
static void eq_setting_info_deal(u8 *eq_info_data)
{
u8 data;
u8 status;
u8 mode;
if (eq_info_data[0] >> 7) {
status = eq_info_data[2];
} else {
status = *(((u8 *)eq_info_data) + 1);
}
mode = eq_info_data[0] & 0x7F;
if (mode < EQ_MODE_CUSTOM) {
eq_mode_set(mode);
} else {
// 自定义修改EQ参数
if (EQ_MODE_CUSTOM == mode) {
if (status != 0x7F) {
u8 i;
for (i = 0; i < EQ_SECTION_MAX; i++) {
if (eq_info_data[0] >> 7) {
data = eq_info_data[i + 2];
} else {
data = eq_info_data[i + 1];
}
eq_mode_set_custom_param(i, (s8)data);
}
}
eq_mode_set(mode);
}
}
}
void set_eq_setting(u8 *eq_setting)
{
u8 i;
u8 eq_setting_mode = eq_setting[0];
if (eq_setting_mode >> 7) {
// 多段eq
for (i = 2; i < eq_setting[1] + 2; i++) {
if ((eq_setting[i] > 12) && (eq_setting[i] < -12)) {
eq_setting[i] = 0;
}
}
} else {
// 10段eq
for (i = 1; i < 11; i++) {
if ((eq_setting[i] > 12) && (eq_setting[i] < -12)) {
eq_setting[i] = 0;
}
}
}
memcpy(_s_info.eq_mode_info, eq_setting, 11);
}
void get_eq_setting(u8 *eq_setting)
{
memcpy(eq_setting, _s_info.eq_mode_info, 11);
}
// 1、写入VM
static void update_eq_vm_value(u8 *eq_setting)
{
u8 status = *(((u8 *)eq_setting) + 1);
syscfg_write(CFG_RCSP_ADV_EQ_MODE_SETTING, eq_setting, 1);
/*自定义修改EQ参数*/
if (EQ_MODE_CUSTOM == (eq_setting[0] & 0x7F)) {
if (eq_setting[0] >> 7) {
// 多段eq
status = eq_setting[2];
}
if (status != 0x7F) {
syscfg_write(CFG_RCSP_ADV_EQ_DATA_SETTING, &eq_setting[1], 10);
}
}
}
// 2、同步对端
static void eq_sync(u8 *eq_setting)
{
#if TCFG_USER_TWS_ENABLE
if (get_bt_tws_connect_status()) {
update_adv_setting(BIT(ATTR_TYPE_EQ_SETTING));
}
#endif
}
void deal_eq_setting(u8 *eq_setting, u8 write_vm, u8 tws_sync)
{
u8 eq_info[11] = {0};
if (!eq_setting) {
get_eq_setting(eq_info);
} else {
u8 status = *(((u8 *)eq_setting) + 1);
/*自定义修改EQ参数*/
if (EQ_MODE_CUSTOM == (eq_setting[0] & 0x7F)) {
if (eq_setting[0] >> 7) {
status = eq_setting[2];
}
if (status != 0x7F) {
memcpy(eq_info, eq_setting, 11);
set_eq_setting(eq_info);
} else {
_s_info.eq_mode_info[0] = eq_setting[0];
get_eq_setting(eq_info);
}
} else {
memcpy(eq_info, eq_setting, 11);
_s_info.eq_mode_info[0] = eq_setting[0];
}
}
if (write_vm) {
update_eq_vm_value(eq_info);
}
if (tws_sync) {
eq_sync(eq_info);
}
eq_setting_info_deal(eq_info);
}
u8 app_get_eq_info(u8 *get_eq_info)
{
u16 i;
get_eq_info[0] = eq_mode_get_cur();
u8 data_len = 1;
if (10 == EQ_SECTION_MAX) {
// 10段eq : mode + gain[10byte]
for (i = 0; i < 10; i++) {
get_eq_info[data_len] = eq_mode_get_gain(get_eq_info[0], i);
data_len++;
}
} else {
// 多段eq : mode + num + value(freq[2byte] + gain[1byte])
get_eq_info[1] = EQ_SECTION_MAX;
data_len++;
for (i = 0; i < EQ_SECTION_MAX; i++) {
get_eq_info[data_len] = eq_mode_get_gain(get_eq_info[0], i);
data_len++;
}
get_eq_info[0] |= (1 << 7);
}
return data_len;
}
u8 app_get_eq_all_info(u8 *get_eq_info)
{
u16 i;
u8 mode = EQ_MODE_NORMAL;
get_eq_info[0] = EQ_SECTION_MAX;
u8 data_len = 1;
// get freq
for (i = 0; i < EQ_SECTION_MAX; i++) {
u16 eq_freq = (u16)(eq_mode_get_freq(mode, i) & ((u16) - 1));
eq_freq = ((((u8 *)&eq_freq)[0] << 8) + ((u8 *)&eq_freq)[1]);
memcpy(get_eq_info + data_len, &eq_freq, sizeof(eq_freq));
data_len += 2;
}
// get gain
for (; mode < EQ_MODE_CUSTOM; mode++) {
get_eq_info[data_len] = mode;
if (10 != EQ_SECTION_MAX) {
get_eq_info[data_len] |= (1 << 7);
}
data_len++;
for (i = 0; i < EQ_SECTION_MAX; i++) {
u8 eq_gain = eq_mode_get_gain(mode, i);
get_eq_info[data_len] = eq_gain;
data_len++;
}
}
// get custom
get_eq_info[data_len] = EQ_MODE_CUSTOM;
if (10 != EQ_SECTION_MAX) {
get_eq_info[data_len] |= (1 << 7);
}
data_len++;
for (i = 0; i < EQ_SECTION_MAX; i++) {
if (10 == EQ_SECTION_MAX) {
get_eq_info[data_len] = _s_info.eq_mode_info[i + 1];
} else {
get_eq_info[data_len] = _s_info.eq_mode_info[i + 2];
}
data_len++;
}
return data_len;
}
#endif
#endif
@@ -0,0 +1,20 @@
#ifndef __ADV_EQ_SETTING_H__
#define __ADV_EQ_SETTING_H__
#include "le_rcsp_adv_module.h"
#if defined(RCSP_ADV_EQ_SET_ENABLE) && RCSP_ADV_EQ_SET_ENABLE
struct _EQ_INFO {
u8 mode;
s8 gain_val[10];
};
void set_eq_setting(u8 *eq_setting);
void get_eq_setting(u8 *eq_setting);
void deal_eq_setting(u8 *eq_setting, u8 write_vm, u8 tws_sync);
u8 app_get_eq_info(u8 *get_eq_info);
u8 app_get_eq_all_info(u8 *get_eq_info);
#endif
#endif
@@ -0,0 +1,318 @@
#include "app_config.h"
#include "syscfg_id.h"
#include "le_rcsp_adv_module.h"
#include "adv_hearing_aid_setting.h"
#include "rcsp_adv_tws_sync.h"
#include "JL_rcsp_protocol.h"
#include "rcsp_adv_bluetooth.h"
#include "spp_user.h"
#if (RCSP_ADV_EN && RCSP_ADV_ASSISTED_HEARING)
static u8 g_dha_fitting_data[3 + 2 * 4 * DHA_FITTING_CHANNEL_MAX] = {0};
static u8 g_dha_fitting_info[3 + 2 + 2 * DHA_FITTING_CHANNEL_MAX + 1] = {0};
static bool g_aidIsOperating = false;
static u8 g_aidOpCode = -1;
static u8 g_aidOpCode_SN = -1;
extern int tws_api_get_role(void);
extern u8 deal_adv_setting_string_item(u8 *des, u8 *src, u8 src_len, u8 type);
extern u16 get_adv_sync_tws_len(void);
static u16 adv_hearing_aid_convert(u8 *data);
static void hearing_aid_update_handle(u8 *data, u16 data_len)
{
#if (TCFG_AUDIO_HEARING_AID_ENABLE && TCFG_AUDIO_DHA_FITTING_ENABLE)
hearing_aid_fitting_parse(g_dha_fitting_data, data_len);
#endif /*TCFG_AUDIO_HEARING_AID_ENABLE && TCFG_AUDIO_DHA_FITTING_ENABLE*/
}
static void hearing_aid_update(void)
{
// 跟进不同命令类型调用设置函数
printf("%s\n", __func__);
/* u16 data_len = get_adv_sync_tws_len(); */
/* if (sizeof(g_dha_fitting_data) == data_len) { */
/* data_len = adv_hearing_aid_convert(g_dha_fitting_data); */
/* put_buf(g_dha_fitting_data, data_len); */
/* } */
#if ASSISTED_HEARING_CUSTOM_TRASNDATA
// 从机才触发
u16 data_len = get_adv_sync_tws_len();
#else
u16 data_len = adv_hearing_aid_convert(g_dha_fitting_data);
#endif
put_buf(g_dha_fitting_data, data_len);
hearing_aid_update_handle(g_dha_fitting_data, data_len);
}
#pragma pack(1)
struct hearing_aid_playload {
u8 cmd;
u16 data_len;
dha_fitting_info_t data_info;
};
#pragma pack()
void get_dha_fitting_info(u8 *dha_fitting_info)
{
printf("%s\n", __func__);
struct hearing_aid_playload playload;
playload.cmd = DHA_FITTING_CMD_INFO;
// 如果当前是主动拿,就把所有信息返回
// 获取0x50对应的数据
/* u8 tmp_data[] = {0, DHA_FITTING_CHANNEL_MAX, 0x12, 0x21, 0x23, 0x32, 0x34, 0x43, 0x45, 0x54, 0x56, 0x65, 0x67, 0x76}; // 例子 */
/* playload.data_len = sizeof(tmp_data); */
/* memcpy(&playload.data_info, tmp_data, sizeof(tmp_data)); */
// 获取0x50对应的数据
dha_fitting_info_t dha_info;
#if (TCFG_AUDIO_HEARING_AID_ENABLE && TCFG_AUDIO_DHA_FITTING_ENABLE)
playload.data_len = get_hearing_aid_fitting_info(&dha_info);
#endif /*TCFG_AUDIO_HEARING_AID_ENABLE && TCFG_AUDIO_DHA_FITTING_ENABLE*/
memcpy(&playload.data_info, &dha_info, sizeof(dha_info));
memcpy(g_dha_fitting_info, &playload, sizeof(playload));
// 如果当前是从机通知,就直接memcpy过去,不需要填充前三个头
u16 data_len = adv_hearing_aid_convert(g_dha_fitting_info);
put_buf(g_dha_fitting_info, data_len);
memcpy(dha_fitting_info, g_dha_fitting_info, sizeof(g_dha_fitting_info) - 1);
}
static void hearing_aid_sync(void)
{
#if TCFG_USER_TWS_ENABLE
if (get_bt_tws_connect_status()) {
update_adv_setting(BIT(ATTR_TYPE_ASSISTED_HEARING));
}
#endif
}
static void big_to_little(u8 *data, u8 data_len)
{
u8 tmp_data = 0;
for (u8 i = 0; i < (data_len / 2); i++) {
tmp_data = data[i];
data[i] = data[data_len - i - 1];
data[data_len - i - 1] = tmp_data;
}
}
static u16 adv_hearing_aid_convert(u8 *data)
{
u16 offset = 0;
u16 data_len = 0;
u8 cmd = data[offset++];
dha_fitting_adjust_t *dha_data; // 0x51
dha_fitting_info_t *dha_info; // 0x50
switch (cmd) {
case DHA_FITTING_CMD_INFO:
big_to_little(data + offset, 2);
data_len = data[offset++] << 8 | data[offset++];
dha_info = (dha_fitting_adjust_t *)(data + offset);
offset += 2;
for (; offset < data_len + 3; offset += 2) {
big_to_little(data + offset, 2);
}
break;
case DHA_FITTING_CMD_ADJUST:
data_len = data[offset] << 8 | data[offset + 1];
big_to_little(data + offset, 2);
offset += 2;
dha_data = (dha_fitting_adjust_t *)(data + offset);
offset += 2;
big_to_little((u8 *)&dha_data->freq, sizeof(dha_data->freq));
offset += 2;
big_to_little((u8 *)&dha_data->gain, sizeof(dha_data->gain));
offset += 4;
break;
case DHA_FITTING_CMD_UPDATE:
data_len = data[offset] << 8 | data[offset + 1];
big_to_little(data + offset, 2);
offset += 3;
for (; offset < data_len + 3; offset += 4) {
big_to_little(g_dha_fitting_data + offset, 4);
}
break;
case DHA_FITTING_CMD_STATE:
big_to_little(data + offset, 2);
data_len = data[offset++] << 8 | data[offset++];
offset += 1;
break;
}
if (data_len + 3 == offset) {
return offset;
}
return 0;
}
void set_hearing_aid_setting(u8 *hear_aid_setting)
{
memcpy(g_dha_fitting_data, hear_aid_setting, sizeof(g_dha_fitting_data));
}
void get_hearing_aid_setting(u8 *hear_aid_setting)
{
memcpy(hear_aid_setting, g_dha_fitting_data, sizeof(g_dha_fitting_data));
}
u32 hearing_aid_rcsp_notify(u8 *data, u16 data_len)
{
u32 ret = 0;
u8 *buf = NULL;
if (0 == adv_hearing_aid_convert(data)) {
return -1;
}
buf = zalloc(data_len + 3);
if (NULL == buf) {
return -1;
}
buf[0] = 0xFF;
data_len = add_one_attr(buf + 1, data_len + 2, 0, COMMON_INFO_ATTR_ASSISTED_HEARING, data, data_len);
ret = JL_CMD_send(JL_OPCODE_SYS_INFO_AUTO_UPDATE, buf, data_len + 1, JL_NOT_NEED_RESPOND);
if (buf) {
free(buf);
}
return ret;
}
u32 hearing_aid_rcsp_response(u8 *data, u16 data_len)
{
/*不开辅听功能时,不回复app信息*/
#if (TCFG_AUDIO_HEARING_AID_ENABLE && TCFG_AUDIO_DHA_FITTING_ENABLE)
if (get_hearing_aid_state() == 0)
#endif /*(TCFG_AUDIO_HEARING_AID_ENABLE && TCFG_AUDIO_DHA_FITTING_ENABLE)*/
{
return 0;
}
if ((TWS_ROLE_MASTER == tws_api_get_role()) && (g_aidOpCode >= 0) && (g_aidOpCode_SN >= 0)) {
u32 ret = 0;
ret = JL_CMD_response_send(g_aidOpCode, JL_PRO_STATUS_SUCCESS, g_aidOpCode_SN, data, data_len);
g_aidIsOperating = false;
g_aidOpCode = -1;
g_aidOpCode_SN = -1;
return ret;
} else {
return -1;
}
}
void deal_hearing_aid_setting(u8 opCode, u8 opCode_SN, u8 *hear_aid_setting, u8 write_en, u8 type_sync)
{
if (TWS_ROLE_MASTER == tws_api_get_role()) {
set_hearing_aid_operating_flag();
}
if (g_aidIsOperating) {
return;
}
if (TWS_ROLE_MASTER == tws_api_get_role()) {
g_aidIsOperating = true;
g_aidOpCode = opCode;
g_aidOpCode_SN = opCode_SN;
}
if (hear_aid_setting) {
u16 len = hear_aid_setting[1] << 8 | hear_aid_setting[2];
memcpy(g_dha_fitting_data, hear_aid_setting, len + 2);
}
if (type_sync) {
hearing_aid_sync();
}
#if TCFG_USER_TWS_ENABLE
if (get_bt_tws_connect_status()) {
if (TWS_ROLE_MASTER == tws_api_get_role()) {
hearing_aid_update();
} else if (0 == type_sync) {
hearing_aid_update();
}
} else
#endif
{
hearing_aid_update();
}
}
#if ASSISTED_HEARING_CUSTOM_TRASNDATA
static struct spp_operation_t *spp_opt = NULL;
static void app_third_party_spp_rx_cbk(void *priv, u8 *buf, u16 len)
{
app_third_party_hearing_aid_handle(buf, len);
}
void adv_hearing_aid_init(void)
{
spp_get_operation_table(&spp_opt);
if (spp_opt && spp_opt->regist_recieve_cbk) {
spp_opt->regist_recieve_cbk(NULL, app_third_party_spp_rx_cbk);
}
}
int app_third_party_hearing_aid_handle(u8 *data, u16 len)
{
#if TCFG_USER_TWS_ENABLE
u8 *tmp_buf = NULL;
u16 offset = 1;
if (len < sizeof(g_dha_fitting_data)) {
return -1;
}
tmp_buf = zalloc(1 + 1 + len);
if (NULL == tmp_buf) {
return -1;
}
offset += deal_adv_setting_string_item(tmp_buf + offset, data, len, ATTR_TYPE_ASSISTED_HEARING);
tmp_buf[0] = offset;
if (tws_api_get_role() == TWS_ROLE_MASTER) {
tws_api_send_data_to_sibling(tmp_buf, offset, TWS_FUNC_ID_ADV_SETTING_SYNC);
}
if (tmp_buf) {
free(tmp_buf);
}
#endif
// 处理函数
hearing_aid_update_handle(data, len);
return 0;
}
extern int custom_app_send_user_data(u8 *data, u16 len);
int app_third_party_hearing_aid_resp(u8 *data, u16 len)
{
if (custom_app_send_user_data(data, len)) {
if (spp_opt && spp_opt->send_data) {
return spp_opt->send_data(NULL, data, (u32)len);
}
}
return 0;
}
#else
int app_third_party_hearing_aid_handle(u8 *data, u16 len)
{
return 0;
}
int app_third_party_hearing_aid_resp(u8 *data, u16 len)
{
return 0;
}
void adv_hearing_aid_init(void)
{
}
#endif
#endif
@@ -0,0 +1,26 @@
#ifndef __ADV_HEARING_AID_SETTING_H__
#define __ADV_HEARING_AID_SETTING_H__
#include "le_rcsp_adv_module.h"
#include "audio_hearing_aid.h"
// 是否使用三方的ble/edr数据传输
#define ASSISTED_HEARING_CUSTOM_TRASNDATA 0
void adv_hearing_aid_init(void);
void set_hearing_aid_setting(u8 *hear_aid_setting);
void get_hearing_aid_setting(u8 *hear_aid_setting);
void deal_hearing_aid_setting(u8 opCode, u8 opCode_SN, u8 *hear_aid_setting, u8 write_en, u8 type_sync);
void get_dha_fitting_info(u8 *dha_fitting_info);
// 主动推数给app
u32 hearing_aid_rcsp_notify(u8 *data, u16 data_len);
// app回复函数
u32 hearing_aid_rcsp_response(u8 *data, u16 data_len);
// 第三方调用函数
int app_third_party_hearing_aid_handle(u8 *data, u16 len);
int app_third_party_hearing_aid_resp(u8 *data, u16 len);
#endif
@@ -0,0 +1,18 @@
#ifndef __ADV_HIGH_LOW_VOL__
#define __ADV_HIGH_LOW_VOL__
#include "le_rcsp_adv_module.h"
#if RCSP_ADV_HIGH_LOW_SET
struct _HIGL_LOW_VOL {
int low_vol;
int high_vol;
};
void get_high_low_vol_info(u8 *vol_gain_param);
void set_high_low_vol_info(u8 *vol_gain_param);
void deal_high_low_vol(u8 *vol_gain_data, u8 write_vm, u8 tws_sync);
#endif
#endif
@@ -0,0 +1,81 @@
#include "app_config.h"
#include "syscfg_id.h"
#include "user_cfg_id.h"
#include "adv_high_low_vol.h"
#include "adv_setting_common.h"
#include "rcsp_adv_tws_sync.h"
#include "rcsp_adv_opt.h"
#if (RCSP_ADV_EN)
#if RCSP_ADV_HIGH_LOW_SET
static struct _HIGL_LOW_VOL high_low_vol = {
.low_vol = 12,
.high_vol = 12,
};
extern int get_bt_tws_connect_status();
extern int audio_out_eq_spec_set_gain(u8 idx, int gain);
void get_high_low_vol_info(u8 *vol_gain_param)
{
memcpy(vol_gain_param, &high_low_vol, sizeof(struct _HIGL_LOW_VOL));
}
void set_high_low_vol_info(u8 *vol_gain_param)
{
memcpy(&high_low_vol, vol_gain_param, sizeof(struct _HIGL_LOW_VOL));
}
static void update_high_low_vol_vm_value(u8 *vol_gain_param)
{
syscfg_write(CFG_RCSP_ADV_HIGH_LOW_VOL, vol_gain_param, sizeof(struct _HIGL_LOW_VOL));
}
static void high_low_vol_setting_sync(u8 *vol_gain_param)
{
#if TCFG_USER_TWS_ENABLE
if (get_bt_tws_connect_status()) {
update_adv_setting(BIT(ATTR_TYPE_HIGH_LOW_VOL));
}
#endif
}
static void high_low_vol_state_update(void)
{
#if (TCFG_AUDIO_OUT_EQ_ENABLE != 0)
static int low_vol = 0;
static int high_vol = 0;
if (low_vol != high_low_vol.low_vol) {
audio_out_eq_spec_set_gain(0, high_low_vol.low_vol - 12);
low_vol = high_low_vol.low_vol;
}
if (high_vol != high_low_vol.high_vol) {
audio_out_eq_spec_set_gain(1, high_low_vol.high_vol - 12);
high_vol = high_low_vol.high_vol;
}
#endif
}
void deal_high_low_vol(u8 *vol_gain_data, u8 write_vm, u8 tws_sync)
{
int vol_gain_param[2] = {0};
if (!vol_gain_data) {
get_high_low_vol_info((u8 *)vol_gain_param);
} else {
memcpy((u8 *)&vol_gain_param, vol_gain_data, sizeof(vol_gain_param));
set_high_low_vol_info(vol_gain_data);
printf("low %d, high %d\n", vol_gain_param[0], vol_gain_param[1]);
}
if (write_vm) {
update_high_low_vol_vm_value((u8 *)vol_gain_param);
}
if (tws_sync) {
high_low_vol_setting_sync((u8 *)vol_gain_param);
}
high_low_vol_state_update();
}
#endif
#endif
@@ -0,0 +1,219 @@
#include "app_config.h"
#include "syscfg_id.h"
#include "user_cfg_id.h"
#include "key_event_deal.h"
#include "le_rcsp_adv_module.h"
#include "adv_key_setting.h"
#include "adv_setting_common.h"
#include "rcsp_adv_tws_sync.h"
#include "rcsp_adv_opt.h"
#include "adv_anc_voice_key.h"
#if (RCSP_ADV_EN)
#if RCSP_ADV_KEY_SET_ENABLE
extern int get_bt_tws_connect_status();
static u8 rcsp_adv_key_event_flag = 0x0;
static void enable_adv_key_event(void)
{
rcsp_adv_key_event_flag = 1;
}
static u8 get_adv_key_event_status(void)
{
return rcsp_adv_key_event_flag;
}
static void disable_adv_key_event(void)
{
rcsp_adv_key_event_flag = 0;
}
void set_key_setting(u8 *key_setting_info)
{
_s_info.key_setting[3 * 0 + 2] = key_setting_info[0];
_s_info.key_setting[3 * 2 + 2] = key_setting_info[1];
_s_info.key_setting[3 * 1 + 2] = key_setting_info[2];
_s_info.key_setting[3 * 3 + 2] = key_setting_info[3];
}
void get_key_setting(u8 *key_setting_info)
{
key_setting_info[0] = _s_info.key_setting[3 * 0 + 2];
key_setting_info[1] = _s_info.key_setting[3 * 2 + 2];
key_setting_info[2] = _s_info.key_setting[3 * 1 + 2];
key_setting_info[3] = _s_info.key_setting[3 * 3 + 2];
}
static void update_key_setting_vm_value(u8 *key_setting_info)
{
syscfg_write(CFG_RCSP_ADV_KEY_SETTING, key_setting_info, 4);
}
static void key_setting_sync(u8 *key_setting_info)
{
#if TCFG_USER_TWS_ENABLE
if (get_bt_tws_connect_status()) {
update_adv_setting(BIT(ATTR_TYPE_KEY_SETTING));
}
#endif
}
void deal_key_setting(u8 *key_setting_info, u8 write_vm, u8 tws_sync)
{
u8 key_setting[4];
if (!key_setting_info) {
get_key_setting(key_setting);
} else {
memcpy(key_setting, key_setting_info, 4);
}
// 1、写入VM
if (write_vm) {
update_key_setting_vm_value(key_setting);
}
// 2、同步对端
if (tws_sync) {
key_setting_sync(key_setting);
}
// 3、更新状态
enable_adv_key_event();
}
#define ADV_POWER_ON_OFF 0
enum ADV_KEY_TYPE {
ADV_KEY_TYPE_NULL = 0x0,
#if ADV_POWER_ON_OFF
ADV_KEY_TYPE_POWER_ON,
ADV_KEY_TYPE_POWER_OFF,
#endif
ADV_KEY_TYPE_PREV = 0x3,
ADV_KEY_TYPE_NEXT,
ADV_KEY_TYPE_PP,
ADV_KEY_TYPE_ANSWER_CALL,
ADV_KEY_TYPE_HANG_UP,
ADV_KEY_TYPE_CALL_BACK,
ADV_KEY_TYPE_INC_VOICE,
ADV_KEY_TYPE_DESC_VOICE,
ADV_KEY_TYPE_TAKE_PHOTO,
ADV_KEY_TYPE_ANC_VOICE = 0xFF,
};
static u8 get_adv_key_opt(u8 key_action, u8 channel)
{
u8 opt;
for (opt = 0; opt < sizeof(_s_info.key_setting); opt += 3) {
if (_s_info.key_setting[opt] == channel &&
_s_info.key_setting[opt + 1] == key_action) {
break;
}
}
if (sizeof(_s_info.key_setting) == opt) {
return -1;
}
switch (_s_info.key_setting[opt + 2]) {
case ADV_KEY_TYPE_NULL:
//opt = KEY_NULL;
opt = ADV_KEY_TYPE_NULL;
break;
#if ADV_POWER_ON_OFF
case ADV_KEY_TYPE_POWER_ON:
opt = KEY_POWER_ON;
break;
case ADV_KEY_TYPE_POWER_OFF:
opt = KEY_RCSP_POWEROFF;
break;
#endif
case ADV_KEY_TYPE_PREV:
opt = KEY_MUSIC_PREV;
break;
case ADV_KEY_TYPE_NEXT:
opt = KEY_MUSIC_NEXT;
break;
case ADV_KEY_TYPE_PP:
opt = KEY_MUSIC_PP;
break;
case ADV_KEY_TYPE_ANSWER_CALL:
opt = KEY_CALL_ANSWER;
break;
case ADV_KEY_TYPE_HANG_UP:
opt = KEY_CALL_HANG_UP;
break;
case ADV_KEY_TYPE_CALL_BACK:
opt = KEY_CALL_LAST_NO;
break;
case ADV_KEY_TYPE_INC_VOICE:
opt = KEY_VOL_UP;
break;
case ADV_KEY_TYPE_DESC_VOICE:
opt = KEY_VOL_DOWN;
break;
case ADV_KEY_TYPE_TAKE_PHOTO:
opt = KEY_HID_CONTROL;
break;
case ADV_KEY_TYPE_ANC_VOICE:
update_anc_voice_key_opt();
opt = KEY_NULL;
break;
}
return opt;
}
void set_key_event_by_rcsp_info(struct sys_event *event, u8 *key_event)
{
if (0 == get_adv_key_event_status()) {
return;
}
u8 key_action = 0;
struct key_event *key = &event->u.key;
switch (key->event) {
case 0:
// 单击
key_action = 0x1;
break;
case 4:
// 双击
key_action = 0x2;
break;
default:
return;
}
#if (TCFG_CHARGESTORE_ENABLE && TCFG_USER_TWS_ENABLE)
u8 channel = tws_api_get_local_channel();
if (get_bt_tws_connect_status()) {
channel = tws_api_get_local_channel();
}
#else
u8 channel = 'U';
#endif
switch (channel) {
case 'U':
case 'L':
channel = (u32) event->arg == KEY_EVENT_FROM_TWS ? 2 : 1;
break;
case 'R':
channel = (u32) event->arg == KEY_EVENT_FROM_TWS ? 1 : 2;
break;
default:
return;
}
key_action = get_adv_key_opt(key_action, channel);
if ((u8) - 1 != key_action) {
*key_event = key_action ? key_action : KEY_NULL;
}
}
#else
void set_key_event_by_rcsp_info(struct sys_event *event, u8 *key_event)
{
return;
}
#endif
#endif
@@ -0,0 +1,13 @@
#ifndef __ADV_KEY_SETTING_H__
#define __ADV_KEY_SETTING_H__
#include "le_rcsp_adv_module.h"
#if RCSP_ADV_KEY_SET_ENABLE
void set_key_setting(u8 *key_setting_info);
void get_key_setting(u8 *key_setting_info);
#endif
#endif
@@ -0,0 +1,145 @@
#include "app_config.h"
#include "syscfg_id.h"
#include "user_cfg_id.h"
#include "asm/pwm_led.h"
#include "user_cfg.h"
#include "ui_manage.h"
#include "le_rcsp_adv_module.h"
#include "adv_led_setting.h"
#include "adv_setting_common.h"
#include "rcsp_adv_tws_sync.h"
#include "rcsp_adv_opt.h"
#if (RCSP_ADV_EN)
#if RCSP_ADV_LED_SET_ENABLE
enum ADV_LED_TYPE {
ADV_LED_TYPE_ALL_OFF = 0x0,
ADV_LED_TYPE_RED_ON,
ADV_LED_TYPE_BLUE_ON,
ADV_LED_TYPE_RAD_BREATHE,
ADV_LED_TYPE_BLUE_BREATHE,
ADV_LED_TYPE_FAST_FLASH,
ADV_LED_TYPE_SLOW_FLASH,
};
extern STATUS *get_led_config(void);
extern int get_bt_tws_connect_status();
__attribute__((weak))
u8 adv_get_led_status(void)
{
return 1;
}
static u8 adv_led_value_conversion(u8 adv_led_opt)
{
u8 conversion_value = adv_led_opt;
switch (adv_led_opt) {
case ADV_LED_TYPE_ALL_OFF:
conversion_value = PWM_LED_ALL_OFF;
break;
case ADV_LED_TYPE_RED_ON:
conversion_value = PWM_LED1_ON;
break;
case ADV_LED_TYPE_BLUE_ON:
conversion_value = PWM_LED0_ON;
break;
case ADV_LED_TYPE_RAD_BREATHE:
conversion_value = PWM_LED1_BREATHE;
break;
case ADV_LED_TYPE_BLUE_BREATHE:
conversion_value = PWM_LED0_BREATHE;
break;
case ADV_LED_TYPE_FAST_FLASH:
conversion_value = PWM_LED0_LED1_FAST_FLASH;
break;
case ADV_LED_TYPE_SLOW_FLASH:
conversion_value = PWM_LED0_LED1_SLOW_FLASH;
break;
}
return conversion_value;
}
void set_led_setting(u8 *led_setting_info)
{
_s_info.led_status[2 * 0 + 1] = led_setting_info[0];
_s_info.led_status[2 * 1 + 1] = led_setting_info[1];
_s_info.led_status[2 * 2 + 1] = led_setting_info[2];
}
void get_led_setting(u8 *led_setting_info)
{
led_setting_info[0] = _s_info.led_status[2 * 0 + 1];
led_setting_info[1] = _s_info.led_status[2 * 1 + 1];
led_setting_info[2] = _s_info.led_status[2 * 2 + 1];
}
// 1、写入VM
static void update_led_setting_vm_value(u8 *led_setting_info)
{
syscfg_write(CFG_RCSP_ADV_LED_SETTING, led_setting_info, 3);
}
// 2、同步对端
static void led_setting_sync(u8 *led_setting_info)
{
#if TCFG_USER_TWS_ENABLE
if (get_bt_tws_connect_status()) {
update_adv_setting(BIT(ATTR_TYPE_LED_SETTING));
}
#endif
}
// 3、更新状态
void update_led_setting_state(void)
{
u8 led_setting_info[3];
get_led_setting(led_setting_info);
// 直接修改led表
STATUS *p_led = get_led_config();
// 未配对
p_led->bt_init_ok = adv_led_value_conversion(led_setting_info[0]);
p_led->bt_disconnect = adv_led_value_conversion(led_setting_info[0]);
// 未连接
p_led->tws_connect_ok = adv_led_value_conversion(led_setting_info[1]);
// 连接
p_led->bt_connect_ok = adv_led_value_conversion(led_setting_info[2]);
switch (adv_get_led_status()) {
case STATUS_BT_INIT_OK:
case STATUS_BT_DISCONN:
ui_update_status(STATUS_BT_INIT_OK);
break;
case STATUS_BT_TWS_CONN:
ui_update_status(STATUS_BT_TWS_CONN);
break;
case STATUS_PHONE_ACTIV:
case STATUS_PHONE_OUT:
case STATUS_PHONE_INCOME:
case STATUS_BT_CONN:
ui_update_status(STATUS_BT_CONN);
break;
}
}
void deal_led_setting(u8 *led_setting_info, u8 write_vm, u8 tws_sync)
{
u8 led_setting[3];
if (!led_setting_info) {
get_led_setting(led_setting);
} else {
memcpy(led_setting, led_setting_info, 3);
}
if (write_vm) {
update_led_setting_vm_value(led_setting);
}
if (tws_sync) {
led_setting_sync(led_setting);
}
update_led_setting_state();
}
#endif
#endif
@@ -0,0 +1,13 @@
#ifndef __ADV_LED_SETTING_H__
#define __ADV_LED_SETTING_H__
#include "le_rcsp_adv_module.h"
#if RCSP_ADV_LED_SET_ENABLE
void set_led_setting(u8 *led_setting_info);
void get_led_setting(u8 *led_setting_info);
#endif
#endif
@@ -0,0 +1,155 @@
#include "app_config.h"
#include "syscfg_id.h"
#include "user_cfg_id.h"
#include "le_rcsp_adv_module.h"
#include "adv_mic_setting.h"
#include "adv_setting_common.h"
#include "rcsp_adv_tws_sync.h"
#include "rcsp_adv_opt.h"
#if (RCSP_ADV_EN)
#if RCSP_ADV_MIC_SET_ENABLE
extern void test_esco_role_switch(u8 flag);
extern void tws_conn_switch_role();
extern int get_bt_tws_connect_status();
static void mic_setting_info_deal(u8 mic_info_data)
{
#if TCFG_USER_TWS_ENABLE
u8 channel = tws_api_get_local_channel();
printf("%s, %d\n", __FUNCTION__, channel);
if (tws_api_get_role() == TWS_ROLE_MASTER) {
printf("-----master-----\n");
} else {
printf("-----role-----\n");
}
switch (mic_info_data) {
case 0x01:
if (get_bt_tws_connect_status()) {
printf("-------auto--------\n");
tws_api_auto_role_switch_enable();
}
break;
case 0x02:
if (get_bt_tws_connect_status()) {
if (channel != 'L') {
printf("-------!L--------\n");
tws_api_auto_role_switch_disable();
tws_conn_switch_role();
}
}
break;
case 0x03:
if (get_bt_tws_connect_status()) {
if (channel != 'R') {
printf("-------!R--------\n");
tws_api_auto_role_switch_disable();
tws_conn_switch_role();
}
}
break;
default:
break;
}
#endif
}
void set_mic_setting(u8 mic_setting_info)
{
_s_info.mic_mode = mic_setting_info;
}
u8 get_mic_setting(void)
{
return _s_info.mic_mode;
}
static void update_mic_setting_vm_value(u8 mic_setting_info)
{
syscfg_write(CFG_RCSP_ADV_MIC_SETTING, &mic_setting_info, 1);
}
static void adv_mic_setting_sync(u8 mic_setting_info)
{
#if TCFG_USER_TWS_ENABLE
if (get_bt_tws_connect_status()) {
update_adv_setting(BIT(ATTR_TYPE_MIC_SETTING));
}
#endif
}
void deal_mic_setting(u8 mic_setting_info, u8 write_vm, u8 tws_sync)
{
if (!mic_setting_info) {
mic_setting_info = get_mic_setting();
} else {
set_mic_setting(mic_setting_info);
}
if (write_vm) {
update_mic_setting_vm_value(mic_setting_info);
}
if (tws_sync) {
adv_mic_setting_sync(mic_setting_info);
}
mic_setting_info_deal(mic_setting_info);
}
//通话时,固定mic的位置,mode--esco state
void rcsp_user_mic_fixed_deal(u8 mode)
{
u8 channel = tws_api_get_local_channel();
if (!get_bt_tws_connect_status()) {
return;
}
if (mode == 0) {
test_esco_role_switch(0);
return;
}
if ((tws_api_get_role() == TWS_ROLE_MASTER)
&& (tws_api_get_tws_state() | TWS_STA_ESCO_OPEN)) {
switch (get_mic_setting()) {
case 0x02:
if (get_bt_tws_connect_status()) {
if (channel != 'L') {
printf("mic_sw_l\n");
test_esco_role_switch(1);
}
}
break;
case 0x03:
if (get_bt_tws_connect_status()) {
if (channel != 'R') {
printf("mic_sw_r\n");
test_esco_role_switch(1);
}
}
break;
default:
printf("mic_sw_auto\n");
test_esco_role_switch(0);
break;
}
}
}
#else
void rcsp_user_mic_fixed_deal(u8 mode)
{
return;
}
#endif
#endif
@@ -0,0 +1,15 @@
#ifndef __ADV_MIC_SETTING_H__
#define __ADV_MIC_SETTING_H__
#include "le_rcsp_adv_module.h"
#if RCSP_ADV_MIC_SET_ENABLE
void set_mic_setting(u8 mic_setting_info);
u8 get_mic_setting(void);
#endif
void rcsp_user_mic_fixed_deal(u8 mode);
#endif
@@ -0,0 +1,447 @@
#include "app_config.h"
#include "syscfg_id.h"
#include "user_cfg_id.h"
#include "le_rcsp_adv_module.h"
#include "adv_setting_common.h"
#include "rcsp_adv_tws_sync.h"
#include "rcsp_adv_opt.h"
#include "adv_music_info_setting.h"
#include "btstack/avctp_user.h"
#include "rcsp_adv_bluetooth.h"
#include "bt_tws.h"
#if (RCSP_ADV_EN)
#if RCSP_ADV_MUSIC_INFO_ENABLE
struct music_info_t {
u8 title_len;
char title[64];
u8 artist_len;
char artist[64];
u8 album_len;
char album[64];
u8 num_len;
char number;
u8 total_len;
char total[2];
u8 genre_len;
char genre[16];
char time[8];
u8 player_state;
u8 player_time_min;
u8 player_time_sec;
u32 curr_player_time;
u8 player_time_en;
u32 total_time;
volatile int get_music_player_timer;
};
struct music_info_t music_info;
void JL_rcsp_event_to_user(u32 type, u8 event, u8 *msg, u8 size);
u8 get_player_time_en(void)
{
return music_info.player_time_en;
}
void set_player_time_en(u8 en)
{
music_info.player_time_en = en;
}
void reset_player_time_en(void)
{
music_player_time_timer_deal(music_info.player_time_en);
}
void music_player_time_deal(void *priv)
{
if (BT_STATUS_PLAYING_MUSIC == get_bt_connect_status()) {
user_send_cmd_prepare(USER_CTRL_AVCTP_OPID_GET_PLAY_TIME, 0, NULL);
}
}
void get_music_info(void)
{
//printf("\nsend music info\n");
user_send_cmd_prepare(USER_CTRL_AVCTP_OPID_GET_MUSIC_INFO, 0, NULL);
}
void btstack_avrcp_ch_creat_ok(void)
{
if (tws_api_get_role() == TWS_ROLE_SLAVE) {
//printf("\n\n\n\nrcsp ge music info\n");
tws_api_sync_call_by_uuid('T', SYNC_CMD_MUSIC_INFO, 300);
} else {
if ((tws_api_get_tws_state() & TWS_STA_SIBLING_CONNECTED) == 0) {
//printf("\n\n\nno tws rcsp ge music info\n\n");
get_music_info();
}
}
}
char *get_music_title(void)
{
return music_info.title;
}
u8 get_music_title_len(void)
{
return music_info.title_len;
}
char *get_music_artist(void)
{
return music_info.artist;
}
u8 get_music_artist_len(void)
{
return music_info.artist_len;
}
char *get_music_album(void)
{
return music_info.album;
}
u8 get_music_album_len(void)
{
return music_info.album_len;
}
char *get_music_number(void)
{
return &music_info.number;
}
u8 get_music_number_len(void)
{
return music_info.num_len;
}
char *get_music_total(void)
{
return music_info.total;
}
u8 get_music_total_len(void)
{
return music_info.total_len;
}
char *get_music_genre(void)
{
return music_info.genre;
}
u8 get_music_genre_len(void)
{
return music_info.genre_len;
}
u16 get_music_total_time(void)
{
return (music_info.total_time / 1000);
}
u32 get_music_curr_time(void)
{
return music_info.curr_player_time;
/* return (music_info.player_time_min * 60 + music_info.player_time_sec); */
}
u8 bt_music_total_time(u32 time)
{
music_info.total_time = time;
/* printf("get music time %d\n", music_info.total_time); */
return 0;
}
u8 get_music_player_state(void)
{
return music_info.player_state;
}
void rcsp_update_player_state(void)
{
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_PLAYER_STATE, NULL, 0);
}
void bt_status_change(u8 state)
{
if (BT_STATUS_PLAYING_MUSIC == state) {
music_info.player_state = 1;
} else {
music_info.player_state = 0;
}
if ((tws_api_get_tws_state() & TWS_STA_SIBLING_CONNECTED) == 0) {
rcsp_update_player_state();
} else {
if (tws_api_get_role() == TWS_ROLE_MASTER) {
tws_api_sync_call_by_uuid('T', SYNC_CMD_MUSIC_PLAYER_STATE, 300);
} else {
tws_api_sync_call_by_uuid('T', SYNC_CMD_MUSIC_PLAYER_TIEM_EN, 300);
}
}
}
void stop_get_music_timer(u8 en)
{
if (en) {
music_info.player_time_en = 0;
}
if (music_info.get_music_player_timer) {
sys_timeout_del(music_info.get_music_player_timer);
music_info.get_music_player_timer = 0;
}
}
void music_player_time_timer_deal(u8 en)
{
if (en) {
if (music_info.get_music_player_timer == 0) {
music_info.get_music_player_timer = sys_timer_add(NULL, music_player_time_deal, 800);
}
} else {
if (music_info.get_music_player_timer) {
sys_timer_del(music_info.get_music_player_timer);
music_info.get_music_player_timer = 0;
}
}
}
void music_info_cmd_handle(u8 *p, u16 len)
{
u8 cmd = *p;
u8 *data = p + 1;
switch (cmd) {
case 0x01:
user_send_cmd_prepare(USER_CTRL_AVCTP_OPID_PLAY, 0, NULL);
break;
case 0x02:
user_send_cmd_prepare(USER_CTRL_AVCTP_OPID_PREV, 0, NULL);
break;
case 0x03:
user_send_cmd_prepare(USER_CTRL_AVCTP_OPID_NEXT, 0, NULL);
break;
case 0x04:
music_info.player_time_en = *data;
if (*data) {
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_MUSIC_PLAYER_TIME_TEMER, data, 1);
} else {
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_MUSIC_PLAYER_TIME_TEMER, data, 1);
}
break;
default:
break;
}
}
u32 char_to_hex(char num, u8 ten_num)
{
u32 char_num;
switch (num) {
case '0':
char_num = 0;
break;
case '1':
char_num = 1;
break;
case '2':
char_num = 2;
break;
case '3':
char_num = 3;
break;
case '4':
char_num = 4;
break;
case '5':
char_num = 5;
break;
case '6':
char_num = 6;
break;
case '7':
char_num = 7;
break;
case '8':
char_num = 8;
break;
case '9':
char_num = 9;
break;
default:
char_num = 0;
}
switch (ten_num) {
case 0:
char_num = char_num;
break;
case 1:
char_num = char_num * 10;
break;
case 2:
char_num = char_num * 100;
break;
case 3:
char_num = char_num * 1000;
break;
case 4:
char_num = char_num * 10000;
break;
case 5:
char_num = char_num * 100000;
break;
case 6:
char_num = char_num * 1000000;
break;
case 7:
char_num = char_num * 10000000;
break;
default:
char_num = char_num;
}
return char_num;
}
u32 num_char_to_hex(char *c, len)
{
u32 total_num = 0;
u8 i;
for (i = 0; i < len; i++) {
total_num += char_to_hex(*(c + i), len - i - 1);
}
return total_num;
}
void rcsp_adv_music_info_deal(u8 type, u32 time, u8 *info, u16 len)
{
//printf("info len \n");
//put_buf(info,len);
#if RCSP_ADV_FIND_DEVICE_ENABLE
extern u8 find_device_key_flag_get(void);
if (find_device_key_flag_get()) {
return;
}
#endif
switch (type) {
case 0:
if (time != music_info.total_time) {
/* if(music_info.player_time_en) */
{
music_info.curr_player_time = time;
music_info.player_time_min = time / 1000 / 60;
music_info.player_time_sec = time / 1000 - (music_info.player_time_min * 60);
/* printf("total time %d %d->", music_info.total_time, time); */
/* printf("muisc time %d %d->", music_info.player_time_min, music_info.player_time_sec); */
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_PLAYER_TIME, NULL, 0);
}
}
return;
case 1:
if ((info) && (len)) {
if (len > 64) {
len = 64;
}
music_info.title_len = len;
memcpy(music_info.title, info, len);
}
break;
case 2:
if ((info) && (len)) {
if (len > 64) {
len = 64;
}
music_info.artist_len = len;
memcpy(music_info.artist, info, len);
}
break;
case 3:
if ((info) && (len)) {
if (len > 64) {
len = 64;
}
music_info.album_len = len;
memcpy(music_info.album, info, len);
}
break;
case 4:
if ((info) && (len)) {
len = 1;
music_info.num_len = len;
memcpy(&music_info.number, info, len);
}
break;
case 5:
if ((info) && (len)) {
len = 2;
music_info.total_len = len;
memcpy(music_info.total, info, len);
}
break;
case 6:
if ((info) && (len)) {
if (len > 16) {
len = 16;
}
music_info.genre_len = len;
memcpy(music_info.genre, info, len);
}
break;
case 7:
if ((info) && (len)) {
if (len > 8) {
len = 8;
}
memcpy(music_info.time, info, len);
/* printf("get time %s\n", info); */
/* put_buf(music_info.time, len); */
music_info.total_time = num_char_to_hex(music_info.time, len);
}
break;
default:
break;
}
if (music_info.player_time_en) {
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_MUSIC_INFO, &type, 1);
}
/* os_time_dly(2); */
}
#endif
#endif
@@ -0,0 +1,31 @@
#ifndef __ADV_MUSIC_INFO_SETTING_H__
#define __ADV_MUSIC_INFO_SETTING_H__
#include "le_rcsp_adv_module.h"
#if RCSP_ADV_MUSIC_INFO_ENABLE
char *get_music_title(void);
u8 get_music_title_len(void);
char *get_music_artist(void);
u8 get_music_artist_len(void);
char *get_music_album(void);
u8 get_music_album_len(void);
char *get_music_number(void);
u8 get_music_number_len(void);
char *get_music_total(void);
u8 get_music_total_len(void);
char *get_music_genre(void);
u8 get_music_genre_len(void);
u16 get_music_total_time(void);
u32 get_music_curr_time(void);
u8 get_music_player_state(void);
void music_info_cmd_handle(u8 *p, u16 len);
void stop_get_music_timer(u8 en);
extern void music_player_time_timer_deal(u8 en);
u8 get_player_time_en(void);
void set_player_time_en(u8 en);
void rcsp_adv_music_info_deal(u8 type, u32 time, u8 *info, u16 len);
#endif
#endif
@@ -0,0 +1,27 @@
#ifndef __ADV_SCENE_NOISE_REDUCTION_H__
#define __ADV_SCENE_NOISE_REDUCTION_H__
#include "system/includes.h"
typedef enum {
RCSP_SCENE_NOISE_REDUCTION_TYPE_INTELLIGENT = 0x00,
RCSP_SCENE_NOISE_REDUCTION_TYPE_MILD = 0x01,
RCSP_SCENE_NOISE_REDUCTION_TYPE_BALANCE = 0x02,
RCSP_SCENE_NOISE_REDUCTION_TYPE_DEEPNESS = 0x03,
} RCSP_SCENE_NOISE_REDUCTION_TYPE;
/**
* @brief 获取场景降噪类型
*
* @result RCSP_SCENE_NOISE_REDUCTION_TYPE
*/
RCSP_SCENE_NOISE_REDUCTION_TYPE get_scene_noise_reduction_type();
/**
* @brief 设置场景降噪类型
*/
void set_scene_noise_reduction_type(RCSP_SCENE_NOISE_REDUCTION_TYPE type);
#endif // __ADV_SCENE_NOISE_REDUCTION_H__
@@ -0,0 +1,31 @@
#ifndef __ADV_SETTING_COMMON_H__
#define __ADV_SETTING_COMMON_H__
#include "typedef.h"
#include "event.h"
#if RCSP_ADV_EN
struct t_s_info {
u8 edr_name[32];
u8 key_setting[12];
u8 key_extra_setting[4];
u8 led_status[6];
u8 mic_mode;
u8 work_mode;
u8 eq_mode_info[11];
};
extern struct t_s_info _s_info;
void deal_time_stamp_setting(u32 time_stamp, u8 write_vm, u8 tws_sync);
void deal_bt_name_setting(u8 *bt_name_setting, u8 write_vm, u8 tws_sync);
void deal_key_setting(u8 *key_setting_info, u8 write_vm, u8 tws_sync);
void deal_led_setting(u8 *led_setting_info, u8 write_vm, u8 tws_sync);
void deal_mic_setting(u8 mic_setting_info, u8 write_vm, u8 tws_sync);
void deal_work_setting(u8 work_setting_info, u8 write_vm, u8 tws_sync, u8 poweron);
void adv_setting_init(void);
void update_adv_setting(u16 type);
void update_info_from_adv_vm_info(void);
void modify_bt_name_and_reset(u32 msec);
#endif
#endif
@@ -0,0 +1,87 @@
#include "app_config.h"
#include "syscfg_id.h"
#include "user_cfg_id.h"
#include "rcsp_adv_bluetooth.h"
#include "JL_rcsp_protocol.h"
#include "le_rcsp_adv_module.h"
#include "adv_time_stamp_setting.h"
#include "adv_setting_common.h"
#include "rcsp_adv_tws_sync.h"
#include "rcsp_adv_opt.h"
#if (RCSP_ADV_EN)
extern int get_bt_tws_connect_status();
static u32 adv_time_stamp = 0;
u32 get_adv_time_stamp(void)
{
return adv_time_stamp;
}
void set_adv_time_stamp(u32 time_stamp)
{
adv_time_stamp = time_stamp;
}
void sync_setting_by_time_stamp(void)
{
tws_api_send_data_to_sibling((u8 *)&adv_time_stamp, sizeof(adv_time_stamp), TWS_FUNC_ID_TIME_STAMP_SYNC);
}
void deal_sibling_time_stamp_setting_switch(void *data, u16 len)
{
u32 time_stamp = *((u32 *)data);
if (adv_time_stamp > time_stamp) {
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_ADV_SETTING_SYNC, NULL, 0);
}
}
void deal_adv_setting_gain_time_stamp(void)
{
#if TCFG_USER_TWS_ENABLE
extern u8 adv_info_device_request(u8 * buf, u16 len);
static u8 tws_pair = 0;
u8 buf = 2;
u8 ret = 0;
if (get_bt_tws_connect_status()) {
tws_pair = 1;
} else {
if (tws_pair) {
tws_pair = 0;
ret = adv_info_device_request(&buf, sizeof(buf));
}
}
#endif
}
// 1、写入VM
static void update_time_stamp_vm_value(u32 time_stamp)
{
syscfg_write(CFG_RCSP_ADV_TIME_STAMP, (u8 *)&time_stamp, 4);
}
// 2、同步对端
static void adv_time_stamp_sync(u32 time_stamp)
{
#if TCFG_USER_TWS_ENABLE
if (get_bt_tws_connect_status()) {
update_adv_setting(BIT(ATTR_TYPE_TIME_STAMP));
}
#endif
}
void deal_time_stamp_setting(u32 time_stamp, u8 write_vm, u8 tws_sync)
{
if (!time_stamp) {
time_stamp = get_adv_time_stamp();
} else {
set_adv_time_stamp(time_stamp);
}
if (write_vm) {
update_time_stamp_vm_value(time_stamp);
}
if (tws_sync) {
adv_time_stamp_sync(time_stamp);
}
}
#endif
@@ -0,0 +1,10 @@
#ifndef __ADV_TIME_STAMP_SETTING_H__
#define __ADV_TIME_STAMP_SETTING_H__
void set_adv_time_stamp(u32 time_stamp);
u32 get_adv_time_stamp(void);
void deal_sibling_time_stamp_setting_switch(void *data, u16 len);
extern void sync_setting_by_time_stamp(void);
void deal_adv_setting_gain_time_stamp(void);
#endif
@@ -0,0 +1,18 @@
#ifndef __ADV_VOICE_ENHANCEMENT_MODE_H__
#define __ADV_VOICE_ENHANCEMENT_MODE_H__
#include "system/includes.h"
/**
* @brief 获取人声增强模式开关
*
* @result bool
*/
bool get_voice_enhancement_mode_switch();
/**
* @brief 设置人声增强模式开关
*/
void set_voice_enhancement_mode_switch(bool mode_switch);
#endif // __ADV_VOICE_ENHANCEMENT_MODE_H__
@@ -0,0 +1,18 @@
#ifndef __ADV_WIND_NOISE_DETECTION_H__
#define __ADV_WIND_NOISE_DETECTION_H__
#include "system/includes.h"
/**
* @brief 获取风噪检测开关
*
* @result bool
*/
bool get_wind_noise_detection_switch();
/**
* @brief 设置风噪检测开关
*/
void set_wind_noise_detection_switch(bool detection_switch);
#endif // __ADV_WIND_NOISE_DETECTION_H__
@@ -0,0 +1,104 @@
#include "app_config.h"
#include "syscfg_id.h"
#include "user_cfg_id.h"
#include "le_rcsp_adv_module.h"
#include "adv_work_setting.h"
#include "adv_setting_common.h"
#include "rcsp_adv_tws_sync.h"
#include "rcsp_adv_opt.h"
#include "os/os_api.h"
#include "btstack/avctp_user.h"
#if (RCSP_ADV_EN)
#if RCSP_ADV_WORK_SET_ENABLE
extern int get_bt_tws_connect_status();
extern void bt_set_low_latency_mode(int enable);
void set_work_setting(u8 work_setting_info)
{
_s_info.work_mode = work_setting_info;
}
u8 get_work_setting(void)
{
return _s_info.work_mode;
}
static void adv_work_setting_vm_value(u8 work_setting_info)
{
/* syscfg_write(CFG_RCSP_ADV_WORK_SETTING, &work_setting_info, 1); */
}
static void adv_work_setting_sync(u8 work_setting_info)
{
#if TCFG_USER_TWS_ENABLE
if (get_bt_tws_connect_status()) {
update_adv_setting(BIT(ATTR_TYPE_WORK_MODE));
}
#endif
}
static void __rcsp_work_set_call(void)
{
//r_f_printf("__rcsp_work_set_call\n");
if (1 == _s_info.work_mode) {
bt_set_low_latency_mode(0);
} else if (2 == _s_info.work_mode) {
bt_set_low_latency_mode(1);
}
}
static void rcsp_work_set_deal(void)
{
int err;
int msg[3];
msg[0] = (int) __rcsp_work_set_call;
msg[1] = 1;
msg[2] = 0;
err = os_taskq_post_type("app_core", Q_CALLBACK, 3, msg);
//r_printf("err %x\n",err);
}
static void update_work_setting_state(void)
{
//r_f_printf("set deal\n");
rcsp_work_set_deal();
}
void deal_work_setting(u8 work_setting_info, u8 write_vm, u8 tws_sync, u8 poweron)
{
if (poweron) {
__rcsp_work_set_call();
} else {
if (0 == work_setting_info) {
work_setting_info = get_work_setting();
} else {
set_work_setting(work_setting_info);
}
if (write_vm) {
adv_work_setting_vm_value(work_setting_info);
}
if (tws_sync) {
adv_work_setting_sync(work_setting_info);
}
update_work_setting_state();
}
}
int ble_vendor_is_slow_state(void)
{
if ((BT_STATUS_PLAYING_MUSIC == get_bt_connect_status()) && (2 == _s_info.work_mode)) {
return 1;
} else {
return 0;
}
}
#endif
#endif
@@ -0,0 +1,13 @@
#ifndef __ADV_WORK_SETTING_H__
#define __ADV_WORK_SETTING_H__
#include "le_rcsp_adv_module.h"
#if RCSP_ADV_WORK_SET_ENABLE
void set_work_setting(u8 work_setting_info);
u8 get_work_setting(void);
#endif
#endif
@@ -0,0 +1,131 @@
#ifndef __JL_BLUETOOTH_ADV_H__
#define __JL_BLUETOOTH_ADV_H__
#include "app_config.h"
#include "typedef.h"
#include "system/event.h"
#include "le_common.h"
#include "ble_user.h"
#include "spp_user.h"
#if (RCSP_ADV_EN)
void rcsp_init();
void rcsp_dev_select(u8 type);
void function_change_inform(void);
bool common_msg_deal(u32 param, void *priv);
bool ble_msg_deal(u32 param);
bool music_msg_deal(u32 param, void *priv);
bool linein_msg_deal(u32 param);
bool rtc_msg_deal(u32 param);
#if (RCSP_ADV_ASSISTED_HEARING)
void set_hearing_aid_operating_flag();
#endif
void rcsp_exit(void);
u8 rcsp_get_asr_status(void);
u8 get_rcsp_support_new_reconn_flag(void);
enum {
RCSP_BLE,
RCSP_SPP,
};
enum {
ANDROID,
APPLE_IOS,
};
struct JL_AI_VAR {
ble_state_e JL_ble_status;
struct ble_server_operation_t *rcsp_ble;
u8 JL_spp_status;
struct spp_operation_t *rcsp_spp;
volatile u8 speech_state;
u32 feature_mask;
u8 device_type;
u8 phone_platform;
void (*start_speech)(void);
void (*stop_speech)(void);
u8 err_report;
volatile u8 file_browse_lock_flag;
u32 return_msg;
u8 spec_mode;
struct __rcsp_user_var *rcsp_user;
volatile u8 rcsp_run_flag;
u8 ffr_mode;
u16 ffr_time;
volatile u8 wait_asr_end;
u8 new_reconn_flag; //是否支持新的回连方式(进行地址修改)
};
struct _SPEECH_OVER_DEAL {
u8 last_task;
u8 status;
};
extern struct JL_AI_VAR jl_ai_var;
extern struct _SPEECH_OVER_DEAL speech_deal_val;
#define DEVICE_EVENT_FROM_RCSP (('R' << 24) | ('C' << 16) | ('S' << 8) | 'P')
enum RCSP_MSG_T {
MSG_JL_GET_DEV_UPDATE_FILE_INFO_OFFSET,
MSG_JL_INQUIRE_DEVEICE_IF_CAN_UPDATE,
MSG_JL_LOADER_DOWNLOAD_START,
MSG_JL_UPDATE_START,
MSG_JL_ENTER_UPDATE_MODE,
MSG_JL_DEV_DISCONNECT,
MSG_JL_BLE_UPDATE_START,
MSG_JL_SPP_UPDATE_START,
MSG_JL_ADV_SETTING_SYNC,
MSG_JL_ADV_SETTING_UPDATE,
MSG_JL_UPDATE_EQ,
MSG_JL_UPDATE_SEQ,
MSG_JL_SWITCH_DEVICE,
MSG_JL_UPDATE_PLAYER_TIME,
MSG_JL_UPDATE_PLAYER_STATE,
MSG_JL_UPDATE_MUSIC_INFO,
MSG_JL_UPDATE_MUSIC_PLAYER_TIME_TEMER,
MSG_JL_UPDAET_ADV_STATE_INFO,
MSG_JL_REBOOT_DEV,
MSG_JL_FIND_DEVICE_RESUME,
MSG_JL_FIND_DEVICE_STOP,
MSG_JL_UPDATE_ANC_VOICE,
MSG_JL_UPDATE_ANC_VOICE_MAX_SYNC,
MSG_JL_UPDATE_ADAPTIVE_NOISE_REDUCTION,
MSG_JL_UPDATE_AI_NO_PICK,
MSG_JL_UPDATE_SCENE_NOISE_REDUCTION,
MSG_JL_UPDATE_WIND_NOISE_DETECTION,
MSG_JL_UPDATE_VOICE_ENHANCEMENT_MODE,
MSG_JL_TWS_NEED_UPDATE,
};
void JL_rcsp_event_to_user(u32 type, u8 event, u8 *msg, u8 size);
int JL_rcsp_event_handler(struct rcsp_event *rcsp);
void rcsp_tws_auth_sync_deal(void);
extern u8 JL_get_cur_bt_channel_sel(void);
#define SDK_TYPE_AC690X 0x0
#define SDK_TYPE_AC692X 0x1
#define SDK_TYPE_AC693X 0x2
#define SDK_TYPE_AC695X 0x3
#define SDK_TYPE_AC697X 0x4
#if (defined CONFIG_CPU_BR21)
#define RCSP_SDK_TYPE SDK_TYPE_AC692X
#elif (defined CONFIG_CPU_BR22)
#define RCSP_SDK_TYPE SDK_TYPE_AC693X
#elif (defined CONFIG_CPU_BR23)
#define RCSP_SDK_TYPE SDK_TYPE_AC695X
#elif (defined CONFIG_CPU_BR30)
#define RCSP_SDK_TYPE SDK_TYPE_AC697X
#else
#define RCSP_SDK_TYPE SDK_TYPE_AC693X
#endif
#endif
#endif
@@ -0,0 +1,70 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "string.h"
#include "JL_rcsp_api.h"
#include "JL_rcsp_protocol.h"
#include "JL_rcsp_packet.h"
#include "spp_user.h"
#include "btstack/avctp_user.h"
#include "system/timer.h"
#include "app_core.h"
#include "user_cfg.h"
#include "asm/pwm_led.h"
#include "ui_manage.h"
#include "key_event_deal.h"
#include "syscfg_id.h"
#include "user_cfg_id.h"
#include "classic/tws_api.h"
#include "event.h"
#include "bt_tws.h"
#include "custom_cfg.h"
#include "app_config.h"
#if (RCSP_ADV_EN)
/* #define RCSP_USER_DEBUG_EN */
#ifdef RCSP_USER_DEBUG_EN
#define rcsp_user_putchar(x) putchar(x)
#define rcsp_user_printf printf
#define rcsp_user_printf_buf(x,len) put_buf(x,len)
#else
#define rcsp_user_putchar(...)
#define rcsp_user_printf(...)
#define rcsp_user_printf_buf(...)
#endif
/// 发送需要回复的自定义命令
u32 rcsp_user_send_resp_cmd(u8 *data, u16 len)
{
u32 ret = 0;
rcsp_user_printf("send resp cmd\n");
rcsp_user_printf_buf(data, len);
ret = JL_CMD_send(JL_OPCODE_CUSTOMER_USER, data, len, 1);
return ret;
}
void rcsp_user_recv_resp(u8 *data, u16 len)
{
///收到固件发出去,APP的回复
rcsp_user_printf("resp resp\n");
rcsp_user_printf_buf(data, len);
}
void rcsp_user_recv_cmd_resp(u8 *data, u16 len)
{
///收到app主动发过来的需要回复的自定义命令
///回复在其他地方已完成,开发不需要单独回复
rcsp_user_printf("user recv cmd:\n");
rcsp_user_printf_buf(data, len);
/* rcsp_user_send_resp_cmd(data, len); */
}
#endif
@@ -0,0 +1,17 @@
#ifndef __JL_ADV_CUSTOMER_USER_H__
#define __JL_ADV_CUSTOMER_USER_H__
#include "app_config.h"
#include "typedef.h"
#include "system/event.h"
#include "le_common.h"
#include "spp_user.h"
#if (RCSP_ADV_EN)
void rcsp_user_recv_cmd_resp(u8 *data, u16 len);
void rcsp_user_recv_resp(u8 *data, u16 len);
u32 rcsp_user_send_resp_cmd(u8 *data, u16 len);
#endif
#endif
@@ -0,0 +1,495 @@
#include "app_config.h"
#include "syscfg_id.h"
#include "user_cfg_id.h"
#include "le_rcsp_adv_module.h"
#include "rcsp_adv_bluetooth.h"
#include "rcsp_adv_opt.h"
#include "adv_setting_common.h"
#include "rcsp_adv_tws_sync.h"
#include "adv_time_stamp_setting.h"
#include "adv_bt_name_setting.h"
#include "adv_key_setting.h"
#include "adv_led_setting.h"
#include "adv_mic_setting.h"
#include "adv_work_setting.h"
#include "adv_eq_setting.h"
#include "adv_high_low_vol.h"
#include "adv_anc_voice_key.h"
#include "bt_tws.h"
#include "btstack/avctp_user.h"
#include "adv_anc_voice.h"
#include "adv_hearing_aid_setting.h"
#if (RCSP_ADV_EN)
static u16 adv_setting_event_flag = (u16) - 1;
static void set_adv_setting_event_flag(u16 flag)
{
adv_setting_event_flag = flag;
}
static u16 get_adv_setting_event_flag(void)
{
return adv_setting_event_flag;
}
static u8 deal_adv_setting_string_item(u8 *des, u8 *src, u8 src_len, u8 type)
{
des[0] = type;
memcpy(des + 1, src, src_len);
return src_len + sizeof(type);
}
void update_info_from_adv_vm_info(void)
{
if (get_adv_setting_event_flag() & BIT(ATTR_TYPE_TIME_STAMP)) {
deal_time_stamp_setting(0, 1, 0);
}
#if RCSP_ADV_NAME_SET_ENABLE
if (get_adv_setting_event_flag() & BIT(ATTR_TYPE_EDR_NAME)) {
deal_bt_name_setting(NULL, 1, 0);
}
#endif
#if RCSP_ADV_KEY_SET_ENABLE
if (get_adv_setting_event_flag() & BIT(ATTR_TYPE_KEY_SETTING)) {
deal_key_setting(NULL, 1, 0);
}
if (get_adv_setting_event_flag() & BIT(ATTR_TYPE_ANC_VOICE_KEY)) {
deal_anc_voice_key_setting(NULL, 1, 0);
}
#endif
#if RCSP_ADV_LED_SET_ENABLE
if (get_adv_setting_event_flag() & BIT(ATTR_TYPE_LED_SETTING)) {
deal_led_setting(NULL, 1, 0);
}
#endif
#if RCSP_ADV_MIC_SET_ENABLE
if (get_adv_setting_event_flag() & BIT(ATTR_TYPE_MIC_SETTING)) {
deal_mic_setting(0, 1, 0);
}
#endif
#if RCSP_ADV_WORK_SET_ENABLE
if (get_adv_setting_event_flag() & BIT(ATTR_TYPE_WORK_MODE)) {
deal_work_setting(0, 1, 0, 0);
}
#endif
#if RCSP_ADV_EQ_SET_ENABLE
if (get_adv_setting_event_flag() & BIT(ATTR_TYPE_EQ_SETTING)) {
deal_eq_setting(0, 1, 0);
}
#endif
#if RCSP_ADV_HIGH_LOW_SET
if (get_adv_setting_event_flag() & BIT(ATTR_TYPE_HIGH_LOW_VOL)) {
deal_high_low_vol(NULL, 1, 0);
}
#endif
#if (RCSP_ADV_ANC_VOICE)
if (get_adv_setting_event_flag() & BIT(ATTR_TYPE_ANC_VOICE)) {
deal_anc_voice(NULL, 1, 0);
}
#endif
#if (RCSP_ADV_ASSISTED_HEARING)
if (get_adv_setting_event_flag() & BIT(ATTR_TYPE_ASSISTED_HEARING)) {
deal_hearing_aid_setting(-1, -1, NULL, 1, 0);
}
#endif
set_adv_setting_event_flag(0);
}
static u8 adv_read_data_from_vm(u8 syscfg_id, u8 *buf, u8 buf_len)
{
int len = 0;
u8 i = 0;
len = syscfg_read(syscfg_id, buf, buf_len);
if (len > 0) {
for (i = 0; i < buf_len; i++) {
if (buf[i] != 0xff) {
return (buf_len == len);
}
}
}
return 0;
}
void adv_setting_init(void)
{
u32 time_stamp = 0;
if (adv_read_data_from_vm(CFG_RCSP_ADV_TIME_STAMP, (u8 *)&time_stamp, sizeof(time_stamp))) {
set_adv_time_stamp(time_stamp);
//deal_time_stamp_setting(0, 0, 0);
}
#if RCSP_ADV_NAME_SET_ENABLE
u8 bt_name_info[32] = {0};
if (adv_read_data_from_vm(CFG_BT_NAME, bt_name_info, sizeof(bt_name_info))) {
set_bt_name_setting(bt_name_info);
//deal_bt_name_setting(NULL, 0, 0);
}
#endif
#if RCSP_ADV_KEY_SET_ENABLE
u8 key_setting_info[4] = {0};
if (adv_read_data_from_vm(CFG_RCSP_ADV_KEY_SETTING, key_setting_info, sizeof(key_setting_info))) {
set_key_setting(key_setting_info);
deal_key_setting(NULL, 0, 0);
}
u8 key_anc_voice_mode[4] = {0};
if (adv_read_data_from_vm(CFG_RCSP_ADV_ANC_VOICE_KEY, key_anc_voice_mode, sizeof(key_anc_voice_mode))) {
set_anc_voice_key_mode(key_anc_voice_mode);
deal_anc_voice_key_setting(NULL, 0, 0);
}
#endif
#if RCSP_ADV_LED_SET_ENABLE
u8 led_setting_info[3] = {0};
if (adv_read_data_from_vm(CFG_RCSP_ADV_LED_SETTING, led_setting_info, sizeof(led_setting_info))) {
set_led_setting(led_setting_info);
deal_led_setting(NULL, 0, 0);
}
#endif
#if RCSP_ADV_MIC_SET_ENABLE
u8 mic_setting_info = 0;
if (adv_read_data_from_vm(CFG_RCSP_ADV_MIC_SETTING, &mic_setting_info, sizeof(mic_setting_info))) {
set_mic_setting(mic_setting_info);
deal_mic_setting(0, 0, 0);
}
#endif
#if RCSP_ADV_WORK_SET_ENABLE
u8 work_setting_info = 0;
if (adv_read_data_from_vm(CFG_RCSP_ADV_WORK_SETTING, &work_setting_info, sizeof(work_setting_info))) {
set_work_setting(work_setting_info);
deal_work_setting(0, 0, 0, 1);
}
#endif
#if RCSP_ADV_EQ_SET_ENABLE
u8 eq_setting_vm_info[11] = {0};
u8 eq_setting_info[10] = {0};
u8 eq_setting_mode = 0;
u8 i;
if (adv_read_data_from_vm(CFG_RCSP_ADV_EQ_DATA_SETTING, eq_setting_info, sizeof(eq_setting_info))) {
if (adv_read_data_from_vm(CFG_RCSP_ADV_EQ_MODE_SETTING, &eq_setting_mode, sizeof(eq_setting_mode))) {
eq_setting_vm_info[0] = eq_setting_mode;
memcpy(eq_setting_vm_info + 1, eq_setting_info, sizeof(eq_setting_info));
set_eq_setting(eq_setting_vm_info);
deal_eq_setting(NULL, 0, 0);
}
}
#endif
#if RCSP_ADV_HIGH_LOW_SET
u8 high_low_vol_setting[8] = {0};
if (adv_read_data_from_vm(CFG_RCSP_ADV_HIGH_LOW_VOL, high_low_vol_setting, sizeof(high_low_vol_setting))) {
set_high_low_vol_info(high_low_vol_setting);
deal_high_low_vol(NULL, 0, 0);
}
#endif
#if (RCSP_ADV_ANC_VOICE)
u8 anc_voice_setting[25] = {0};
if (anc_voice_setting_init()) {
if (adv_read_data_from_vm(CFG_RCSP_ADV_ANC_VOICE_MODE, anc_voice_setting, 1)) {
if (adv_read_data_from_vm(CFG_RCSP_ADV_ANC_VOICE, anc_voice_setting + 1, sizeof(anc_voice_setting) - 1)) {
set_anc_voice_info(anc_voice_setting);
deal_anc_voice(NULL, 0, 0);
}
}
}
#endif
}
// type : 0 ~ 8
// mode : 0 - 从vm读出并更新全局变量数据 // 1 - 同步
void update_adv_setting(u16 type)
{
u8 offset = 1;
// total_len time name key led mic work eq vol anc anc_voice
u8 adv_setting_to_sync[1 + (4 + 1) + (32 + 1) + (4 + 1) + (3 + 1) + (1 + 1) + (1 + 1) + (11 + 1) + (8 + 1) + (25 + 1) + (4 + 1)] = {0};
memset(adv_setting_to_sync, 0, sizeof(adv_setting_to_sync));
if (type & BIT(ATTR_TYPE_TIME_STAMP)) {
u32 time_stamp = get_adv_time_stamp();
offset += deal_adv_setting_string_item(adv_setting_to_sync + offset, (u8 *)&time_stamp, sizeof(time_stamp), ATTR_TYPE_TIME_STAMP);
}
#if RCSP_ADV_NAME_SET_ENABLE
if (type & BIT(ATTR_TYPE_EDR_NAME)) {
u8 bt_name_info[32] = {0};
get_bt_name_setting(bt_name_info);
offset += deal_adv_setting_string_item(adv_setting_to_sync + offset, bt_name_info, sizeof(bt_name_info), ATTR_TYPE_EDR_NAME);
}
#endif
#if RCSP_ADV_KEY_SET_ENABLE
if (type & BIT(ATTR_TYPE_KEY_SETTING)) {
u8 key_setting_info[4] = {0};
get_key_setting(key_setting_info);
offset += deal_adv_setting_string_item(adv_setting_to_sync + offset, key_setting_info, sizeof(key_setting_info), ATTR_TYPE_KEY_SETTING);
}
if (type & BIT(ATTR_TYPE_ANC_VOICE_KEY)) {
u8 key_anc_voice_mode[4] = {0};
get_anc_voice_key_mode(key_anc_voice_mode);
offset += deal_adv_setting_string_item(adv_setting_to_sync + offset, key_anc_voice_mode, sizeof(key_anc_voice_mode), ATTR_TYPE_ANC_VOICE_KEY);
}
#endif
#if RCSP_ADV_LED_SET_ENABLE
if (type & BIT(ATTR_TYPE_LED_SETTING)) {
u8 led_setting_info[3] = {0};
get_led_setting(led_setting_info);
offset += deal_adv_setting_string_item(adv_setting_to_sync + offset, led_setting_info, sizeof(led_setting_info), ATTR_TYPE_LED_SETTING);
}
#endif
#if RCSP_ADV_MIC_SET_ENABLE
if (type & BIT(ATTR_TYPE_MIC_SETTING)) {
u8 mic_setting_info = get_mic_setting();
offset += deal_adv_setting_string_item(adv_setting_to_sync + offset, &mic_setting_info, sizeof(mic_setting_info), ATTR_TYPE_MIC_SETTING);
}
#endif
#if RCSP_ADV_WORK_SET_ENABLE
if (type & BIT(ATTR_TYPE_WORK_MODE)) {
u8 work_setting_info = get_work_setting();
offset += deal_adv_setting_string_item(adv_setting_to_sync + offset, &work_setting_info, sizeof(work_setting_info), ATTR_TYPE_WORK_MODE);
}
#endif
#if RCSP_ADV_EQ_SET_ENABLE
if (type & BIT(ATTR_TYPE_EQ_SETTING)) {
u8 eq_setting_info[11];
get_eq_setting(eq_setting_info);
offset += deal_adv_setting_string_item(adv_setting_to_sync + offset, eq_setting_info, sizeof(eq_setting_info), ATTR_TYPE_EQ_SETTING);
}
#endif
#if RCSP_ADV_HIGH_LOW_SET
if (type & BIT(ATTR_TYPE_HIGH_LOW_VOL)) {
u8 high_low_vol[8];
get_high_low_vol_info(high_low_vol);
offset += deal_adv_setting_string_item(adv_setting_to_sync + offset, high_low_vol, sizeof(high_low_vol), ATTR_TYPE_HIGH_LOW_VOL);
}
#endif
#if (RCSP_ADV_ANC_VOICE)
if (type & BIT(ATTR_TYPE_ANC_VOICE)) {
u8 anc_voice_info[25];
get_anc_voice_info(anc_voice_info);
offset += deal_adv_setting_string_item(adv_setting_to_sync + offset, anc_voice_info, sizeof(anc_voice_info), ATTR_TYPE_ANC_VOICE);
}
#endif
#if RCSP_ADV_ASSISTED_HEARING
if (((u16) - 1) != type && type & BIT(ATTR_TYPE_ASSISTED_HEARING)) {
u8 dha_fitting_data[3 + 2 * 4 * DHA_FITTING_CHANNEL_MAX];
get_hearing_aid_setting(dha_fitting_data);
offset += deal_adv_setting_string_item(adv_setting_to_sync + offset, dha_fitting_data, sizeof(dha_fitting_data), ATTR_TYPE_ASSISTED_HEARING);
}
#endif
if (offset > 1) {
adv_setting_to_sync[0] = offset;
if (type == ((u16) - 1)) {
tws_api_send_data_to_sibling(adv_setting_to_sync, sizeof(adv_setting_to_sync), TWS_FUNC_ID_ADV_SETTING_SYNC);
#if RCSP_ADV_LED_SET_ENABLE
tws_api_sync_call_by_uuid('T', SYNC_CMD_APP_RESET_LED_UI, 300);
#endif
} else {
if (tws_api_get_role() == TWS_ROLE_MASTER) {
tws_api_send_data_to_sibling(adv_setting_to_sync, sizeof(adv_setting_to_sync), TWS_FUNC_ID_ADV_SETTING_SYNC);
#if RCSP_ADV_LED_SET_ENABLE
tws_api_sync_call_by_uuid('T', SYNC_CMD_APP_RESET_LED_UI, 300);
#endif
}
}
}
}
void deal_sibling_setting(u8 *buf)
{
u8 type;
u8 len = buf[0];
u8 offset = 1;
u8 *data;
u32 time_stamp = 0;
set_adv_setting_event_flag(0);
while (offset < len) {
type = buf[offset++];
data = buf + offset;
switch (type) {
#if RCSP_ADV_NAME_SET_ENABLE
case ATTR_TYPE_EDR_NAME:
set_bt_name_setting(data);
offset += 32;
break;
#endif
#if RCSP_ADV_KEY_SET_ENABLE
case ATTR_TYPE_KEY_SETTING :
set_key_setting(data);
offset += 4;
break;
case ATTR_TYPE_ANC_VOICE_KEY:
set_anc_voice_key_mode(data);
offset += 4;
break;
#endif
#if RCSP_ADV_LED_SET_ENABLE
case ATTR_TYPE_LED_SETTING :
set_led_setting(data);
offset += 3;
break;
#endif
#if RCSP_ADV_MIC_SET_ENABLE
case ATTR_TYPE_MIC_SETTING :
set_mic_setting(*data);
offset += 1;
break;
#endif
#if RCSP_ADV_WORK_SET_ENABLE
case ATTR_TYPE_WORK_MODE :
set_work_setting(*data);
offset += 1;
break;
#endif
#if RCSP_ADV_EQ_SET_ENABLE
case ATTR_TYPE_EQ_SETTING :
/* g_printf("tws eq setting\n"); */
set_eq_setting(data);
offset += 11;
break;
#endif
#if RCSP_ADV_HIGH_LOW_SET
case ATTR_TYPE_HIGH_LOW_VOL:
set_high_low_vol_info(data);
offset += 8;
break;
#endif
#if (RCSP_ADV_ANC_VOICE)
case ATTR_TYPE_ANC_VOICE:
set_anc_voice_info(data);
offset += 25;
break;
#endif
#if (RCSP_ADV_ASSISTED_HEARING)
case ATTR_TYPE_ASSISTED_HEARING:
set_hearing_aid_setting(data);
offset += 3 + 2 * 4 * DHA_FITTING_CHANNEL_MAX;
break;
#endif
case ATTR_TYPE_TIME_STAMP:
time_stamp = (data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24));//*((u32 *)data);
set_adv_time_stamp(time_stamp);
offset += 4;
break;
default:
return;
}
set_adv_setting_event_flag(get_adv_setting_event_flag() | BIT(type));
}
// 发送事件
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_ADV_SETTING_UPDATE, NULL, 0);
}
#if (0)
static void adv_reset_data_to_vm(u8 syscfg_id, u8 *buf, u8 buf_len)
{
u8 res = 0;
res = syscfg_write(syscfg_id, buf, buf_len);
}
u8 rcsp_setting_info_reset() //恢复默认的APP设置
{
printf("%s", __func__);
u32 time_stamp = 0xffffffff;
adv_reset_data_to_vm(CFG_RCSP_ADV_TIME_STAMP, (u8 *)&time_stamp, sizeof(time_stamp));
/* #if RCSP_ADV_NAME_SET_ENABLE */
/* u8 bt_name_info[32] = {0}; */
/* memset(bt_name_info,0xff,32); */
/* adv_reset_data_to_vm(CFG_BT_NAME, bt_name_info, sizeof(bt_name_info)); */
/* #endif */
#if RCSP_ADV_KEY_SET_ENABLE
u8 key_setting_info[4] = {0};
memset(key_setting_info, 0xff, 4);
adv_reset_data_to_vm(CFG_RCSP_ADV_KEY_SETTING, key_setting_info, sizeof(key_setting_info));
#endif
#if RCSP_ADV_LED_SET_ENABLE
u8 led_setting_info[3] = {0};
memset(led_setting_info, 0xff, 3);
adv_reset_data_to_vm(CFG_RCSP_ADV_LED_SETTING, led_setting_info, sizeof(led_setting_info));
#endif
#if RCSP_ADV_MIC_SET_ENABLE
u8 mic_setting_info = 0xff;
adv_reset_data_to_vm(CFG_RCSP_ADV_MIC_SETTING, &mic_setting_info, sizeof(mic_setting_info));
#endif
#if RCSP_ADV_WORK_SET_ENABLE
u8 work_setting_info = 0xff;
adv_reset_data_to_vm(CFG_RCSP_ADV_WORK_SETTING, &work_setting_info, sizeof(work_setting_info));
#endif
#if RCSP_ADV_EQ_SET_ENABLE
u8 eq_setting_info[10] = {0};
u8 eq_setting_mode = 0xff;
memset(eq_setting_info, 0xff, 10);
adv_reset_data_to_vm(CFG_RCSP_ADV_EQ_DATA_SETTING, &eq_setting_info, sizeof(eq_setting_info));
adv_reset_data_to_vm(CFG_RCSP_ADV_EQ_MODE_SETTING, &eq_setting_mode, sizeof(eq_setting_mode));
#endif
return 0;
}
u8 remap_app_chargestore_data_deal(u8 *buf, u8 len)
{
u8 send_buf[30];
u8 ret = 0;
send_buf[0] = buf[0];
//#define CMD_GET_NAME 0xc1
switch (buf[0]) {
case 0x08:
//printf("\n\n\n\n\n\n---------------reset store sys\n");
ret = 1 ;
void bt_tws_remove_pairs();
bt_tws_remove_pairs();
extern u8 rcsp_setting_info_reset();
rcsp_setting_info_reset();
user_send_cmd_prepare(USER_CTRL_DEL_ALL_REMOTE_INFO, 0, NULL);
os_time_dly(60);
cpu_reset();
break;
default:
break;
}
return ret;
}
#endif
#endif
@@ -0,0 +1,6 @@
#ifndef __RCSP_ADV_OPT_H__
#define __RCSP_ADV_OPT_H__
void deal_sibling_setting(u8 *buf);
#endif
@@ -0,0 +1,105 @@
#include "app_config.h"
#include "rcsp_adv_tws_sync.h"
#include "adv_setting_common.h"
#include "rcsp_adv_opt.h"
#include "adv_time_stamp_setting.h"
#include "rcsp_adv_bluetooth.h"
#include "bt_tws.h"
#if (RCSP_ADV_EN && TCFG_USER_TWS_ENABLE)
static void adv_sync_tws_func_t(void *data, u16 len, bool rx)
{
if (rx) {
deal_sibling_setting((u8 *)data);
}
}
REGISTER_TWS_FUNC_STUB(adv_tws_sync) = {
.func_id = TWS_FUNC_ID_ADV_SETTING_SYNC,
.func = adv_sync_tws_func_t,
};
static void adv_sync_time_stamp_func_t(void *data, u16 len, bool rx)
{
if (rx) {
deal_sibling_time_stamp_setting_switch(data, len);
}
}
REGISTER_TWS_FUNC_STUB(adv_time_stamp_sync) = {
.func_id = TWS_FUNC_ID_TIME_STAMP_SYNC,
.func = adv_sync_time_stamp_func_t,
};
#define TWS_FUNC_ID_ADV_RESET_SYNC \
(((u8)('R' + 'C' + 'S' + 'P') << (3 * 8)) | \
((u8)('A' + 'D' + 'V') << (2 * 8)) | \
((u8)('R' + 'E' + 'S' + 'E' + 'T') << (1 * 8)) | \
((u8)('S' + 'Y' + 'N' + 'C') << (0 * 8)))
static void adv_sync_reset_sync_func_t(int args)
{
extern void cpu_reset();
cpu_reset();
}
TWS_SYNC_CALL_REGISTER(adv_reset_sync) = {
.uuid = TWS_FUNC_ID_ADV_RESET_SYNC,
.func = adv_sync_reset_sync_func_t,
};
void modify_bt_name_and_reset(u32 msec)
{
tws_api_sync_call_by_uuid(TWS_FUNC_ID_ADV_RESET_SYNC, 0, msec);
}
#define TWS_FUNC_ID_ADV_FIND_DEV_SYNC \
(((u8)('A' + 'D' + 'V') << (3 * 8)) | \
((u8)('F' + 'I' + 'N' + 'D') << (2 * 8)) | \
((u8)('D' + 'E' + 'V') << (1 * 8)) | \
((u8)('S' + 'Y' + 'N' + 'C') << (0 * 8)))
static void adv_find_dev_sync_func_t(int args)
{
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_FIND_DEVICE_RESUME, &args, sizeof(args));
}
TWS_SYNC_CALL_REGISTER(adv_find_dev_sync) = {
.uuid = TWS_FUNC_ID_ADV_FIND_DEV_SYNC,
.func = adv_find_dev_sync_func_t,
};
void find_device_sync(u8 *param, u32 msec)
{
int priv = 0;
if (TWS_ROLE_MASTER == tws_api_get_role()) {
memcpy(&priv, param, 3);
tws_api_sync_call_by_uuid(TWS_FUNC_ID_ADV_FIND_DEV_SYNC, priv, msec);
}
}
#define TWS_FUNC_ID_ADV_FIND_DEV_STOP_TIMER_SYNC \
(((u8)('F' + 'I' + 'N' + 'D') << (3 * 8)) | \
((u8)('D' + 'E' + 'V') << (2 * 8)) | \
((u8)('S' + 'T' + 'O' + 'P') << (1 * 8)) | \
((u8)('S' + 'Y' + 'N' + 'C') << (0 * 8)))
static void adv_find_dev_stop_sync_timer_func_t(int args)
{
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_FIND_DEVICE_STOP, &args, sizeof(args));
}
TWS_SYNC_CALL_REGISTER(adv_find_dev_stop_sync) = {
.uuid = TWS_FUNC_ID_ADV_FIND_DEV_STOP_TIMER_SYNC,
.func = adv_find_dev_stop_sync_timer_func_t,
};
void find_devic_stop_timer(u8 *param, u32 msec)
{
int priv = 0;
if (TWS_ROLE_MASTER == tws_api_get_role()) {
memcpy(&priv, param, 3);
tws_api_sync_call_by_uuid(TWS_FUNC_ID_ADV_FIND_DEV_STOP_TIMER_SYNC, priv, msec);
}
}
#endif
@@ -0,0 +1,13 @@
#ifndef __RCSP_ADV_TWS_SYNC_H__
#define __RCSP_ADV_TWS_SYNC_H__
#include "classic/tws_api.h"
#define TWS_FUNC_ID_ADV_SETTING_SYNC \
TWS_FUNC_ID('R', 'C', 'S', 'P')
#define TWS_FUNC_ID_TIME_STAMP_SYNC \
TWS_FUNC_ID('R' + 'C' + 'S' + 'P', \
'A' + 'D' + 'V', \
'T' + 'I' + 'M' + 'E', \
'S' + 'T' + 'A' + 'M' + 'P')
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,205 @@
// binary representation
// attribute size in bytes (16), flags(16), handle (16), uuid (16/128), value(...)
#ifndef _LE_SERVER_MODULE_H
#define _LE_SERVER_MODULE_H
#include <stdint.h>
#include "bt_common.h"
#include "audio_anc.h"
#if (TCFG_BLE_DEMO_SELECT == DEF_BLE_DEMO_ADV_RCSP)
//
// gatt profile include file, generated by jieli gatt_inc_generator.exe
//
///Jim
static const uint8_t profile_data[] = {
//////////////////////////////////////////////////////
//
// 0x0001 PRIMARY_SERVICE 1800
//
//////////////////////////////////////////////////////
0x0a, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x28, 0x00, 0x18,
/* CHARACTERISTIC, 2a00, READ | WRITE | DYNAMIC, */
// 0x0002 CHARACTERISTIC 2a00 READ | WRITE | DYNAMIC
0x0d, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x28, 0x0a, 0x03, 0x00, 0x00, 0x2a,
// 0x0003 VALUE 2a00 READ | WRITE | DYNAMIC
0x08, 0x00, 0x0a, 0x01, 0x03, 0x00, 0x00, 0x2a,
//////////////////////////////////////////////////////
//
// 0x0004 PRIMARY_SERVICE 15f1e600-a277-43fc-a484-dd39ef8a9100
//
//////////////////////////////////////////////////////
0x18, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x28, 0x00, 0x91, 0x8a, 0xef, 0x39, 0xdd, 0x84, 0xa4, 0xfc, 0x43, 0x77, 0xa2, 0x00, 0xe6, 0xf1, 0x15,
/* CHARACTERISTIC, 15f1e601-a277-43fc-a484-dd39ef8a9100, READ |INDICATE| DYNAMIC, */
// 0x0005 CHARACTERISTIC 15f1e601-a277-43fc-a484-dd39ef8a9100 READ |INDICATE| DYNAMIC
0x1b, 0x00, 0x02, 0x00, 0x05, 0x00, 0x03, 0x28, 0x22, 0x06, 0x00, 0x00, 0x91, 0x8a, 0xef, 0x39, 0xdd, 0x84, 0xa4, 0xfc, 0x43, 0x77, 0xa2, 0x01, 0xe6, 0xf1, 0x15,
// 0x0006 VALUE 15f1e601-a277-43fc-a484-dd39ef8a9100 READ |INDICATE| DYNAMIC
0x16, 0x00, 0x22, 0x03, 0x06, 0x00, 0x00, 0x91, 0x8a, 0xef, 0x39, 0xdd, 0x84, 0xa4, 0xfc, 0x43, 0x77, 0xa2, 0x01, 0xe6, 0xf1, 0x15,
// 0x0007 CLIENT_CHARACTERISTIC_CONFIGURATION
0x0a, 0x00, 0x0a, 0x01, 0x07, 0x00, 0x02, 0x29, 0x00, 0x00,
/* CHARACTERISTIC, 15f1e602-a277-43fc-a484-dd39ef8a9100, WRITE|WRITE_WITHOUT_RESPONSE|DYNAMIC, */
// 0x0008 CHARACTERISTIC 15f1e602-a277-43fc-a484-dd39ef8a9100 WRITE|WRITE_WITHOUT_RESPONSE|DYNAMIC
0x1b, 0x00, 0x02, 0x00, 0x08, 0x00, 0x03, 0x28, 0x0c, 0x09, 0x00, 0x00, 0x91, 0x8a, 0xef, 0x39, 0xdd, 0x84, 0xa4, 0xfc, 0x43, 0x77, 0xa2, 0x02, 0xe6, 0xf1, 0x15,
// 0x0009 VALUE 15f1e602-a277-43fc-a484-dd39ef8a9100 WRITE|WRITE_WITHOUT_RESPONSE|DYNAMIC
0x16, 0x00, 0x0c, 0x03, 0x09, 0x00, 0x00, 0x91, 0x8a, 0xef, 0x39, 0xdd, 0x84, 0xa4, 0xfc, 0x43, 0x77, 0xa2, 0x02, 0xe6, 0xf1, 0x15,
#if 1//RCSP_BTMATE_EN
//////////////////////////////////////////////////////
//
// 0x0080 PRIMARY_SERVICE ae00
//
//////////////////////////////////////////////////////
0x0a, 0x00, 0x02, 0x00, 0x80, 0x00, 0x00, 0x28, 0x00, 0xae,
/* CHARACTERISTIC, ae01, WRITE_WITHOUT_RESPONSE | DYNAMIC, */
// 0x0081 CHARACTERISTIC ae01 WRITE_WITHOUT_RESPONSE | DYNAMIC
0x0d, 0x00, 0x02, 0x00, 0x81, 0x00, 0x03, 0x28, 0x04, 0x82, 0x00, 0x01, 0xae,
// 0x0082 VALUE ae01 WRITE_WITHOUT_RESPONSE | DYNAMIC
0x08, 0x00, 0x04, 0x01, 0x82, 0x00, 0x01, 0xae,
/* CHARACTERISTIC, ae02, NOTIFY, */
// 0x0083 CHARACTERISTIC ae02 NOTIFY
0x0d, 0x00, 0x02, 0x00, 0x83, 0x00, 0x03, 0x28, 0x10, 0x84, 0x00, 0x02, 0xae,
// 0x0084 VALUE ae02 NOTIFY
0x08, 0x00, 0x10, 0x00, 0x84, 0x00, 0x02, 0xae,
// 0x0085 CLIENT_CHARACTERISTIC_CONFIGURATION
0x0a, 0x00, 0x0a, 0x01, 0x85, 0x00, 0x02, 0x29, 0x00, 0x00,
#endif // RCSP_BTMATE_EN
// END
0x00, 0x00,
};
//
// characteristics <--> handles
//
#if 1//RCSP_BTMATE_EN
#define ATT_CHARACTERISTIC_ae01_02_VALUE_HANDLE 0x0082
#define ATT_CHARACTERISTIC_ae02_02_VALUE_HANDLE 0x0084
#define ATT_CHARACTERISTIC_ae02_02_CLIENT_CONFIGURATION_HANDLE 0x0085
#endif
#define ATT_CHARACTERISTIC_2a00_01_VALUE_HANDLE 0x0003
#define ATT_CHARACTERISTIC_15f1e601_a277_43fc_a484_dd39ef8a9100_01_VALUE_HANDLE 0x0006
#define ATT_CHARACTERISTIC_15f1e601_a277_43fc_a484_dd39ef8a9100_01_CLIENT_CONFIGURATION_HANDLE 0x0007
#define ATT_CHARACTERISTIC_15f1e602_a277_43fc_a484_dd39ef8a9100_01_VALUE_HANDLE 0x0009
#define JL_OPCODE_SET_ADV 0xC0
#define JL_OPCODE_GET_ADV 0xC1
#define JL_OPCODE_ADV_DEVICE_NOTIFY 0xC2
#define JL_OPCODE_ADV_NOTIFY_SETTING 0xC3
#define JL_OPCODE_ADV_DEVICE_REQUEST 0xC4
#define ATTR_TYPE_BAT_VALUE (0)
#define ATTR_TYPE_EDR_NAME (1)
#define ATTR_TYPE_KEY_SETTING (2)
#define ATTR_TYPE_LED_SETTING (3)
#define ATTR_TYPE_MIC_SETTING (4)
#define ATTR_TYPE_WORK_MODE (5)
#define ATTR_TYPE_PRODUCT_MESSAGE (6)
#define ATTR_TYPE_TIME_STAMP (7)
#define ATTR_TYPE_EQ_SETTING (8)
#define ATTR_TYPE_HIGH_LOW_VOL (9)
#define ATTR_TYPE_ANC_VOICE_KEY (10)
#define ATTR_TYPE_ANC_VOICE (11)
#define ATTR_TYPE_ASSISTED_HEARING (12)
//rcsp功能模块使能
#define RCSP_ADV_NAME_SET_ENABLE 1
#define RCSP_ADV_KEY_SET_ENABLE 1
#define RCSP_ADV_LED_SET_ENABLE 1
#define RCSP_ADV_MIC_SET_ENABLE 1
#define RCSP_ADV_WORK_SET_ENABLE 1
#if (JL_EARPHONE_APP_EN)
#define RCSP_ADV_EQ_SET_ENABLE 1
#define RCSP_ADV_MUSIC_INFO_ENABLE 1
#define RCSP_ADV_HIGH_LOW_SET 1
#define RCSP_ADV_FIND_DEVICE_ENABLE 1
#define RCSP_ADV_AI_NO_PICK 0 // 智能免摘
#define RCSP_ADV_ASSISTED_HEARING 0 // 辅听,注意开启辅听后,需要关闭ANC相关功能
#if !RCSP_ADV_ASSISTED_HEARING
#define RCSP_ADV_ANC_VOICE 0 // 主动降噪
#if RCSP_ADV_ANC_VOICE
#define RCSP_ADV_ADAPTIVE_NOISE_REDUCTION 1 // 自适应降噪
#define RCSP_ADV_SCENE_NOISE_REDUCTION 1 // 场景降噪
#define RCSP_ADV_WIND_NOISE_DETECTION 1 // 风噪检测
#define RCSP_ADV_VOICE_ENHANCEMENT_MODE 1 // 人声增强模式
#endif
#endif
#else
#define RCSP_ADV_EQ_SET_ENABLE 0
#define RCSP_ADV_MUSIC_INFO_ENABLE 0
#define RCSP_ADV_HIGH_LOW_SET 0
#define RCSP_ADV_FIND_DEVICE_ENABLE 0
#define RCSP_ADV_ASSISTED_HEARING 0 // 辅听,注意开启辅听后,需要关闭ANC相关功能
#define RCSP_ADV_ANC_VOICE 0 // 主动降噪
#define RCSP_ADV_ADAPTIVE_NOISE_REDUCTION 0 // 自适应降噪
#define RCSP_ADV_AI_NO_PICK 0 // 智能免摘
#define RCSP_ADV_SCENE_NOISE_REDUCTION 0 // 场景降噪
#define RCSP_ADV_WIND_NOISE_DETECTION 0 // 风噪检测
#define RCSP_ADV_VOICE_ENHANCEMENT_MODE 0 // 人声增强模式
#endif
#define RCSP_ADV_PRODUCT_MSG_ENABLE 1
#if !TCFG_EQ_ENABLE
#undef RCSP_ADV_EQ_SET_ENABLE
#define RCSP_ADV_EQ_SET_ENABLE 0
#endif
#if !ANC_EAR_ADAPTIVE_EN && JL_EARPHONE_APP_EN
#undef RCSP_ADV_ADAPTIVE_NOISE_REDUCTION
#define RCSP_ADV_ADAPTIVE_NOISE_REDUCTION 0 //自适应降噪
#endif
enum {
BT_ADV_ENABLE,
BT_ADV_DISABLE,
BT_ADV_SET_EDR_CON_FLAG,
BT_ADV_SET_BAT_CHARGE_L,
BT_ADV_SET_BAT_CHARGE_R,
BT_ADV_SET_BAT_CHARGE_C,
BT_ADV_SET_BAT_PERCENT_L,
BT_ADV_SET_BAT_PERCENT_R,
BT_ADV_SET_BAT_PERCENT_C,
BT_ADV_SET_NOTIFY_EN,
};
// BT_ADV_SET_EDR_CON_FLAG
#define SECNE_DISMISS (0x00)
#define SECNE_UNCONNECTED (0x01)
#define SECNE_CONNECTED (0x02)
#define SECNE_CONNECTING (0x03)
#define SECNE_CONNECTINLESS (0x04)
#define TWS_FUNC_ID_SEQ_RAND_SYNC (('S' << (3 * 8)) | ('E' << (2 * 8)) | ('Q' << (1 * 8)) | ('\0'))
enum {
TWS_ADV_SEQ_CHANGE = 0,
TWS_VERSON_INFO,
TWS_UPDATE_INFO,
};
//extern int bt_ble_adv_ioctl(u32 cmd, u32 priv, u8 mode);
extern void bt_adv_seq_change(void);
void ble_app_disconnect(void);
void bt_ble_rcsp_adv_enable(void);
void bt_ble_rcsp_adv_disable(void);
u8 get_ble_adv_notify(void);
void set_ble_adv_notify(u8 en);
u8 get_connect_flag(void);
void set_connect_flag(u8 value);
void ble_module_enable(u8 en);
#endif
#endif
@@ -0,0 +1,91 @@
#include "app_config.h"
#include "app_action.h"
#include "system/includes.h"
#include "spp_user.h"
#include "string.h"
#include "circular_buf.h"
#include "3th_profile_api.h"
#include "bt_common.h"
#if 1
extern void printf_buf(u8 *buf, u32 len);
#define log_info printf
#define log_info_hexdump printf_buf
#else
#define log_info(...)
#define log_info_hexdump(...)
#endif
/* #define DEBUG_ENABLE */
/* #include "debug_log.h" */
/* #include "rcsp_spp_user.h" */
#if 0//(RCSP_ADV_EN)
static struct spp_operation_t *spp_api = NULL;
static u8 spp_state;
int rcsp_spp_send_data(u8 *data, u16 len)
{
if (spp_api) {
return spp_api->send_data(NULL, data, len);
}
return SPP_USER_ERR_SEND_FAIL;
}
int rcsp_spp_send_data_check(u16 len)
{
if (spp_api) {
if (spp_api->busy_state()) {
return 0;
}
}
return 1;
}
static void rcsp_spp_state_cbk(u8 state)
{
spp_state = state;
switch (state) {
case SPP_USER_ST_CONNECT:
log_info("SPP_USER_ST_CONNECT ~~~\n");
// set_app_connect_type(TYPE_SPP);
break;
case SPP_USER_ST_DISCONN:
log_info("SPP_USER_ST_DISCONN ~~~\n");
// set_app_connect_type(TYPE_NULL);
break;
default:
break;
}
}
static void rcsp_spp_send_wakeup(void)
{
putchar('W');
}
static void rcsp_spp_recieve_cbk(void *priv, u8 *buf, u16 len)
{
log_info("spp_api_rx ~~~\n");
log_info_hexdump(buf, len);
}
void rcsp_spp_init(void)
{
spp_state = 0;
spp_get_operation_table(&spp_api);
spp_api->regist_recieve_cbk(0, rcsp_spp_recieve_cbk);
spp_api->regist_state_cbk(0, rcsp_spp_state_cbk);
spp_api->regist_wakeup_send(NULL, rcsp_spp_send_wakeup);
}
#endif
@@ -0,0 +1,42 @@
#ifndef TOMCRYPT_H_
#define TOMCRYPT_H_
// #include <stdio.h>
#include <string.h>
#define HARDWARE_METHOD 0
#ifndef WIN32
// #include "hw_cpu.h"
#undef HARDWARE_METHOD
#define HARDWARE_METHOD 1
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*
@param [in] pt[*1] The plaintext
@param ptlen The length of the plaintext(octets) range: 1~32
@param [in] key[*1] The key for encrypt
@param keylen[*1] The length of the key(octets) range: 1~32
@param [out] mac[*1] output : The Message Authentication Code 16 bytes.
*/
extern void btcon_hash(unsigned char *pt, int ptlen, unsigned char *key, int keylen, unsigned char *mac);
#if HARDWARE_METHOD
extern int yf_aes_start_enc(unsigned char key[16], unsigned char plaintext[16], unsigned char encrypt[16]);
#endif
#ifdef __cplusplus
}
#endif
#endif /* TOMCRYPT_H_ */
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,100 @@
#ifndef __JL_BLUETOOTH_H__
#define __JL_BLUETOOTH_H__
#include "typedef.h"
#include "le_common.h"
#include "spp_user.h"
#include "system/event.h"
#include "rcsp_msg.h"
#include "ble_user.h"
#if RCSP_BTMATE_EN
void rcsp_init();
void rcsp_dev_select(u8 type);
void function_change_inform(void);
bool common_msg_deal(u32 param, void *priv);
bool ble_msg_deal(u32 param);
bool music_msg_deal(u32 param, void *priv);
bool linein_msg_deal(u32 param);
bool rtc_msg_deal(u32 param);
void rcsp_exit(void);
u8 rcsp_get_asr_status(void);
u8 get_rcsp_support_new_reconn_flag(void);
// enum {
// RCSP_BLE,
// RCSP_SPP,
// };
enum {
ANDROID,
APPLE_IOS,
};
struct JL_AI_VAR {
ble_state_e JL_ble_status;
struct ble_server_operation_t *rcsp_ble;
u8 JL_spp_status;
struct spp_operation_t *rcsp_spp;
volatile u8 speech_state;
u32 feature_mask;
u8 device_type;
u8 phone_platform;
void (*start_speech)(void);
void (*stop_speech)(void);
u8 err_report;
volatile u8 file_browse_lock_flag;
u32 return_msg;
u8 spec_mode;
struct __rcsp_user_var *rcsp_user;
volatile u8 rcsp_run_flag;
u8 ffr_mode;
u16 ffr_time;
u16 rcsp_timer_hdl;
volatile u8 wait_asr_end;
u8 new_reconn_flag; //是否支持新的回连方式(进行地址修改)
};
struct _SPEECH_OVER_DEAL {
u8 last_task;
u8 status;
};
extern struct JL_AI_VAR jl_ai_var;
extern struct _SPEECH_OVER_DEAL speech_deal_val;
enum RCSP_MSG_T {
MSG_JL_GET_DEV_UPDATE_FILE_INFO_OFFSET = RCSP_MSG_END,
MSG_JL_INQUIRE_DEVEICE_IF_CAN_UPDATE,
MSG_JL_LOADER_DOWNLOAD_START,
MSG_JL_UPDATE_START,
MSG_JL_ENTER_UPDATE_MODE,
MSG_JL_DEV_DISCONNECT,
MSG_JL_BLE_UPDATE_START,
MSG_JL_SPP_UPDATE_START,
};
bool rcsp_msg_post(RCSP_MSG msg, int argc, ...);
#define SDK_TYPE_AC690X 0x0
#define SDK_TYPE_AC692X 0x1
#define SDK_TYPE_AC693X 0x2
#define SDK_TYPE_AC695X 0x3
#define SDK_TYPE_AC697X 0x4
#if (defined CONFIG_CPU_BR21)
#define RCSP_SDK_TYPE SDK_TYPE_AC692X
#elif (defined CONFIG_CPU_BR22)
#define RCSP_SDK_TYPE SDK_TYPE_AC693X
#elif (defined CONFIG_CPU_BR23)
#define RCSP_SDK_TYPE SDK_TYPE_AC695X
#elif (defined CONFIG_CPU_BR30)
#define RCSP_SDK_TYPE SDK_TYPE_AC697X
#else
#define RCSP_SDK_TYPE SDK_TYPE_AC693X
#endif
#endif
#endif
@@ -0,0 +1,13 @@
#ifndef __RCSP_MSG_H__
#define __RCSP_MSG_H__
typedef enum __RCSP_MSG {
RCSP_MSG_UPDATE_EQ = 0,
RCSP_MSG_SET_FMTX_POINT,
RCSP_MSG_BS_END,
RCSP_MSG_BT_SCAN,
RCSP_MSG_END,
} RCSP_MSG;
#endif//__RCSP_MSG_H__
@@ -0,0 +1,574 @@
#include "app_config.h"
#include "rcsp_adv_user_update.h"
#if RCSP_UPDATE_EN
#include "uart.h"
#include "system/timer.h"
#include "update.h"
#include "custom_cfg.h"
#include "btstack/avctp_user.h"
#include "JL_rcsp_packet.h"
#include "JL_rcsp_protocol.h"
#include "rcsp_adv_bluetooth.h"
#include "le_rcsp_adv_module.h"
#include "update_loader_download.h"
#include "classic/tws_api.h"
#include "syscfg_id.h"
#if (RCSP_ADV_EN)
#define RCSP_DEBUG_EN
#ifdef RCSP_DEBUG_EN
#define rcsp_putchar(x) putchar(x)
#define rcsp_printf printf
#define rcsp_printf_buf(x,len) printf_buf(x,len)
#else
#define rcsp_putchar(...)
#define rcsp_printf(...)
#define rcsp_printf_buf(...)
#endif
#define DEV_UPDATE_FILE_INFO_OFFEST 0x00//0x40
#define DEV_UPDATE_FILE_INFO_LEN 0x00//(0x10 + VER_INFO_EXT_COUNT * (VER_INFO_EXT_MAX_LEN + 1))
typedef enum {
UPDATA_START = 0x00,
UPDATA_REV_DATA,
UPDATA_STOP,
} UPDATA_BIT_FLAG;
#if 0
static update_file_id_t update_file_id_info = {
.ver[0] = 0xff,
.ver[1] = 0xff,
};
#else
static update_file_ext_id_t update_file_id_info = {
.update_file_id_info.ver[0] = 0xff,
.update_file_id_info.ver[1] = 0xff,
};
#endif
extern const int support_dual_bank_update_en;
extern void JL_ble_disconnect(void);
extern u8 check_le_pakcet_sent_finish_flag(void);
static u8 update_flag = 0;
static u8 tws_need_update = 0; //标志耳机是否需要强制升级
static u8 tws_need_role_switch = 0; //用于tws连接之后版本号不匹配进行role_switch,低版本号的作为主机进行强制升级
static u8 disconnect_flag = 0;
u8 get_jl_update_flag(void)
{
printf("get_update_flag:%x\n", update_flag);
return update_flag;
}
void set_jl_update_flag(u8 flag)
{
update_flag = flag;
printf("update_flag:%x\n", update_flag);
}
typedef struct _update_mode_t {
u8 opcode;
u8 opcode_sn;
} update_mode_t;
static update_mode_t update_record_info;
void JL_controller_save_curr_cmd_para(u8 OpCode, u8 OpCode_SN)
{
update_record_info.opcode = OpCode;
update_record_info.opcode_sn = OpCode_SN;
}
void JL_controller_get_curr_cmd_para(u8 *OpCode, u8 *OpCode_SN)
{
*OpCode = update_record_info.opcode;
*OpCode_SN = update_record_info.opcode_sn;
}
static void (*fw_update_block_handle)(u8 state, u8 *buf, u16 len) = NULL;
void register_receive_fw_update_block_handle(void (*handle)(u8 state, u8 *buf, u16 len))
{
fw_update_block_handle = handle;
}
static u16 ble_discon_timeout;
static void ble_discon_timeout_handle(void *priv)
{
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_START, NULL, 0);
}
void JL_rcsp_update_cmd_resp(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len)
{
u8 msg[4];
rcsp_printf("%s\n", __FUNCTION__);
switch (OpCode) {
case JL_OPCODE_GET_DEVICE_UPDATE_FILE_INFO_OFFSET:
if (0 == len) {
msg[0] = OpCode;
msg[1] = OpCode_SN;
rcsp_printf("JL_OPCODE_GET_DEVICE_UPDATE_FILE_INFO_OFFSET\n");
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP,
MSG_JL_GET_DEV_UPDATE_FILE_INFO_OFFSET,
msg,
2);
} else {
rcsp_printf("JL_OPCODE_GET_DEVICE_UPDATE_FILE_INFO_OFFSET ERR\n");
}
break;
case JL_OPCODE_INQUIRE_DEVICE_IF_CAN_UPDATE:
rcsp_printf("JL_OPCODE_INQUIRE_DEVICE_IF_CAN_UPDATE:%x %x\n", len, data[0]);
if (len) {
extern void set_curr_update_type(u8 type);
set_curr_update_type(data[0]);
msg[0] = OpCode;
msg[1] = OpCode_SN;
msg[2] = 0x00;
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP,
MSG_JL_INQUIRE_DEVEICE_IF_CAN_UPDATE,
msg,
3);
}
break;
case JL_OPCODE_EXIT_UPDATE_MODE:
rcsp_printf("JL_OPCODE_EXIT_UPDATE_MODE\n");
break;
case JL_OPCODE_ENTER_UPDATE_MODE:
rcsp_printf("JL_OPCODE_ENTER_UPDATE_MODE\n");
msg[0] = OpCode;
msg[1] = OpCode_SN;
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP,
MSG_JL_ENTER_UPDATE_MODE,
msg,
2);
break;
case JL_OPCODE_SEND_FW_UPDATE_BLOCK:
rcsp_printf("JL_OPCODE_SEND_FW_UPDATE_BLOCK\n");
break;
case JL_OPCODE_GET_DEVICE_REFRESH_FW_STATUS:
rcsp_printf("JL_OPCODE_GET_DEVICE_REFRESH_FW_STATUS\n");
JL_controller_save_curr_cmd_para(OpCode, OpCode_SN);
if (fw_update_block_handle) {
fw_update_block_handle(UPDATA_STOP, NULL, 0);
}
break;
/* case JL_OPCODE_SET_DEVICE_REBOOT: */
/* rcsp_printf("JL_OPCODE_SET_DEVICE_REBOOT\n"); */
/* if (support_dual_bank_update_en) { */
/* cpu_reset(); */
/* } */
/* break; */
default:
break;
}
}
static void JL_rcsp_resp_dev_update_file_info_offest(u8 OpCode, u8 OpCode_SN)
{
u8 data[4 + 2];
u16 update_file_info_offset = DEV_UPDATE_FILE_INFO_OFFEST;
u16 update_file_info_len = DEV_UPDATE_FILE_INFO_LEN;
WRITE_BIG_U32(data + 0, update_file_info_offset);
WRITE_BIG_U16(data + 4, update_file_info_len);
JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, data, sizeof(data));
}
static void JL_resp_inquire_device_if_can_update(u8 OpCode, u8 OpCode_SN, u8 update_sta)
{
u8 data[1];
data[0] = update_sta;
JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, data, sizeof(data));
}
enum {
UPDATE_FLAG_OK,
UPDATE_FLAG_LOW_POWER,
UPDATE_FLAG_FW_INFO_ERR,
UPDATE_FLAG_FW_INFO_CONSISTENT,
UPDATE_FLAG_TWS_DISCONNECT,
};
static u8 judge_remote_version_can_update(void)
{
//extern u16 ex_cfg_get_local_version_info(void);
u16 remote_file_ver = READ_BIG_U16(update_file_id_info.update_file_id_info.ver);
//u16 local_ver = ex_cfg_get_local_version_info();
u16 local_ver = get_vid_pid_ver_from_cfg_file(GET_VID_FROM_EX_CFG);
#if (0 == VER_INFO_EXT_COUNT)
//extern u16 ex_cfg_get_local_pid_info(void);
//extern u16 ex_cfg_get_local_vid_info(void);
//u16 local_pid = ex_cfg_get_local_pid_info();
//u16 local_vid = ex_cfg_get_local_vid_info();
u16 local_pid = get_vid_pid_ver_from_cfg_file(GET_PID_FROM_EX_CFG);
u16 local_vid = get_vid_pid_ver_from_cfg_file(GET_VID_FROM_EX_CFG);
u16 remote_file_pid = READ_BIG_U16(update_file_id_info.update_file_id_info.pid);
u16 remote_file_vid = READ_BIG_U16(update_file_id_info.update_file_id_info.vid);
if (remote_file_ver > local_ver || remote_file_pid != local_pid || remote_file_vid != local_vid) {
return UPDATE_FLAG_FW_INFO_ERR;
}
#else
//extern u32 ex_cfg_get_local_authkey_info(u8 * authkey_data[], u8 * authkey_len);
//extern u32 ex_cfg_get_local_procode_info(u8 * procode_data[], u8 * procode_len);
u8 authkey_len = 0;
u8 *local_authkey_data = NULL;
get_authkey_procode_from_cfg_file(&local_authkey_data, &authkey_len, GET_AUTH_KEY_FROM_EX_CFG);
u8 procode_len = 0;
u8 *local_procode_data = NULL;
get_authkey_procode_from_cfg_file(&local_procode_data, &procode_len, GET_PRO_CODE_FROM_EX_CFG);
//ex_cfg_get_local_authkey_info(&local_authkey_data, &authkey_len);
//ex_cfg_get_local_procode_info(&local_procode_data, &procode_len);
u8 *remote_authkey_data = update_file_id_info.ext;
u8 *remote_procode_data = update_file_id_info.ext + authkey_len + 1;
if (remote_file_ver < local_ver
|| 0 != memcmp(remote_authkey_data, local_authkey_data, authkey_len)
|| 0 != memcmp(remote_procode_data, local_procode_data, procode_len)) {
return UPDATE_FLAG_FW_INFO_ERR;
}
#endif
if (remote_file_ver == local_ver) {
rcsp_printf("remote_file_ver is %x, local_ver is %x, remote_file_ver is similar to local_ver\n", remote_file_ver, local_ver);
return UPDATE_FLAG_FW_INFO_CONSISTENT;
}
return UPDATE_FLAG_OK;
}
static bool check_edr_is_disconnct(void)
{
if (get_curr_channel_state()) {
return TRUE;
} else {
return FALSE;
}
}
static bool check_ble_all_packet_sent(void)
{
if (check_le_pakcet_sent_finish_flag()) {
return TRUE;
} else {
return FALSE;
}
}
static u32 rcsp_update_data_read(void *priv, u32 offset_addr, u16 len)
{
u32 err;
u8 data[4 + 2];
WRITE_BIG_U32(data, offset_addr);
WRITE_BIG_U16(data + 4, len);
err = JL_CMD_send(JL_OPCODE_SEND_FW_UPDATE_BLOCK, data, sizeof(data), JL_NEED_RESPOND);
return err;
}
static JL_ERR JL_controller_resp_get_dev_refresh_fw_status(u8 OpCode, u8 OpCode_SN, u8 result)
{
JL_ERR send_err = JL_ERR_NONE;
u8 data[1];
data[0] = result; //0:sucess 1:fail;
send_err = JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, data, sizeof(data));
return send_err;
}
u32 rcsp_update_status_response(void *priv, u8 status)
{
u8 OpCode;
u8 OpCode_SN;
JL_ERR send_err = JL_ERR_NONE;
JL_controller_get_curr_cmd_para(&OpCode, &OpCode_SN);
//log_info("get cmd para:%x %x\n", OpCode, OpCode_SN);
if (JL_OPCODE_GET_DEVICE_REFRESH_FW_STATUS == OpCode) {
send_err = JL_controller_resp_get_dev_refresh_fw_status(OpCode, OpCode_SN, status);
}
return send_err;
}
void JL_rcsp_update_cmd_receive_resp(void *priv, u8 OpCode, u8 status, u8 *data, u16 len)
{
switch (OpCode) {
case JL_OPCODE_SEND_FW_UPDATE_BLOCK:
if (fw_update_block_handle) {
fw_update_block_handle(UPDATA_REV_DATA, data, len);
}
break;
default:
break;
}
}
static void rcsp_loader_download_result_handle(void *priv, u8 type, u8 cmd)
{
if (UPDATE_LOADER_OK == cmd) {
//JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP,MSG_JL_UPDATE_START,NULL,0);
set_jl_update_flag(1);
if (support_dual_bank_update_en) {
rcsp_printf("1111>>>rcsp update succ\n");
update_result_set(UPDATA_SUCC);
}
} else {
rcsp_printf(">>>update loader err\n");
/* #if OTA_TWS_SAME_TIME_ENABLE */
/* if((tws_ota_control(OTA_TYPE_GET) == OTA_TWS)) { */
/* tws_ota_stop(OTA_STOP_UPDATE_OVER_ERR); */
/* } */
/* #endif */
//rcsp_db_update_fail_deal();
}
}
extern void register_receive_fw_update_block_handle(void (*handle)(u8 state, u8 *buf, u16 len));
extern void rcsp_update_data_api_register(u32(*data_send_hdl)(void *priv, u32 offset, u16 len), u32(*send_update_handl)(void *priv, u8 state));
extern void rcsp_update_handle(void *buf, int len);
extern void bt_set_low_latency_mode(int enable);
extern void bt_adv_seq_change(void);
extern int bt_tws_poweroff();
extern void bt_wait_phone_connect_control(u8 enable);
extern int tws_api_get_role(void);
extern void tws_cancle_all_noconn();
extern void bt_ble_rcsp_adv_disable(void);
extern void ble_module_enable(u8 en);
extern void bt_ble_rcsp_adv_enable(void);
extern u32 ex_cfg_fill_content_api(void);
extern void update_param_priv_fill(UPDATA_PARM *p, void *priv, u16 priv_len);
u8 rcsp_get_update_flag(void)
{
return tws_need_update;
}
void rcsp_set_update_flag(u8 flag)
{
tws_need_update = flag;
}
u8 rcsp_update_get_role_switch(void)
{
return tws_need_role_switch;
}
void rcsp_update_set_role_switch(u8 sw)
{
tws_need_role_switch = sw;
}
void update_slave_adv_reopen(void)
{
r_printf("slave reopen adv...\n");
ble_module_enable(1);
bt_ble_rcsp_adv_enable();
}
static void rcsp_update_private_param_fill(UPDATA_PARM *p)
{
u32 exif_addr = ex_cfg_fill_content_api();
update_param_priv_fill(p, (void *)&exif_addr, sizeof(exif_addr));
}
static void rcsp_update_before_jump_handle(int type)
{
#if CONFIG_UPDATE_JUMP_TO_MASK
y_printf(">>>[test]:latch reset update\n");
latch_reset();
#if 0
update_close_hw("null");
ram_protect_close();
/* save_spi_port(); */
extern void __BT_UPDATA_JUMP();
y_printf("update jump to __BT_UPDATA ...\n");
/* clk_set("sys", 48 * 1000000L); */
//跳转到uboot加载完,30ms左右(200410_yzb)
__BT_UPDATA_JUMP();
#endif
#else
cpu_reset();
#endif
}
void JL_rcsp_msg_deal(void *hdl, u8 event, u8 *msg)
{
u16 remote_file_version;
u8 can_update_flag = UPDATE_FLAG_FW_INFO_ERR;
switch (event) {
case MSG_JL_GET_DEV_UPDATE_FILE_INFO_OFFSET:
rcsp_printf("MSG_JL_GET_DEV_UPDATE_FILE_INFO_OFFSET\n");
/* extern void linein_mutex_stop(void *priv); */
/* linein_mutex_stop(NULL); */
/* extern void linein_mute(u8 mute); */
/* linein_mute(1); */
JL_rcsp_resp_dev_update_file_info_offest((u8)msg[0], (u8)msg[1]);
break;
case MSG_JL_INQUIRE_DEVEICE_IF_CAN_UPDATE:
rcsp_printf("MSG_JL_INQUIRE_DEVEICE_IF_CAN_UPDATE\n");
#if 0
remote_file_version = READ_BIG_U16(update_file_id_info.update_file_id_info.ver);
rcsp_printf("remote_file_ver:V%d.%d.%d.%d\n",
(remote_file_version & 0xf000) >> 12,
(remote_file_version & 0x0f00) >> 8,
(remote_file_version & 0x00f0) >> 4,
(remote_file_version & 0x000f));
if (0 == remote_file_version) {
can_update_flag = UPDATE_FLAG_OK;
} else {
can_update_flag = judge_remote_version_can_update();
}
if (UPDATE_FLAG_OK == can_update_flag) {
set_jl_update_flag(1);
}
#else
#if OTA_TWS_SAME_TIME_ENABLE
int get_bt_tws_connect_status();
if (get_bt_tws_connect_status() || (!support_dual_bank_update_en)) { //单备份返回成功
can_update_flag = UPDATE_FLAG_OK;
} else {
can_update_flag = UPDATE_FLAG_TWS_DISCONNECT;
}
#else
can_update_flag = UPDATE_FLAG_OK;
#endif //endif OTA_TWS_SAME_TIME_ENABLE
#endif
//todo;judge voltage
JL_resp_inquire_device_if_can_update((u8)msg[0], (u8)msg[1], can_update_flag);
if (0 == support_dual_bank_update_en) {
if (tws_api_get_role() == TWS_ROLE_MASTER) {
g_printf("tws master start update...\n");
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_LOADER_DOWNLOAD_START, NULL, 0);
//需要通知从机进入了升级
u8 data = TWS_UPDATE_INFO;
tws_api_send_data_to_sibling(&data, sizeof(data), TWS_FUNC_ID_SEQ_RAND_SYNC);
} else {
bt_ble_rcsp_adv_disable();
ble_module_enable(0); //关闭广播防止从机被手机误回连
r_printf("slave close adv...\n");
sys_timeout_add(NULL, update_slave_adv_reopen, 1000 * 60); //延迟一分钟再开广播
}
if (RCSP_SPP == JL_get_cur_bt_channel_sel()) {
#if TCFG_USER_TWS_ENABLE
tws_api_detach(TWS_DETACH_BY_LOCAL); //单备份升级断开tws
tws_cancle_all_noconn();
#endif
}
}
break;
case MSG_JL_DEV_DISCONNECT:
if (check_ble_all_packet_sent()) {
rcsp_printf("MSG_JL_DEV_DISCONNECT\n");
JL_ble_disconnect();
if (check_edr_is_disconnct()) {
puts("-need discon edr\n");
user_send_cmd_prepare(USER_CTRL_POWER_OFF, 0, NULL);
}
ble_discon_timeout = sys_timeout_add(NULL, ble_discon_timeout_handle, 1000);
} else {
rcsp_printf("W");
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_DEV_DISCONNECT, NULL, 0);
}
break;
case MSG_JL_LOADER_DOWNLOAD_START:
rcsp_update_data_api_register(rcsp_update_data_read, rcsp_update_status_response);
register_receive_fw_update_block_handle(rcsp_update_handle);
if (RCSP_BLE == get_curr_device_type()) {
rcsp_update_loader_download_init(BLE_APP_UPDATA, rcsp_loader_download_result_handle);
} else if (RCSP_SPP == get_curr_device_type()) {
rcsp_update_loader_download_init(SPP_APP_UPDATA, rcsp_loader_download_result_handle);
}
break;
case MSG_JL_UPDATE_START:
if (check_edr_is_disconnct()) {
rcsp_printf("b");
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_START, NULL, 0);
break;
}
if (RCSP_BLE == get_curr_device_type()) {
rcsp_printf("BLE_APP_UPDATE\n");
update_mode_api_v2(BLE_APP_UPDATA,
rcsp_update_private_param_fill,
rcsp_update_before_jump_handle);
} else {
rcsp_printf("SPP_APP_UPDATA\n");
update_mode_api_v2(SPP_APP_UPDATA,
rcsp_update_private_param_fill,
rcsp_update_before_jump_handle);
}
break;
case MSG_JL_ENTER_UPDATE_MODE:
rcsp_printf("MSG_JL_ENTER_UPDATE_MODE:%x %x\n", msg[0], msg[1]);
bt_set_low_latency_mode(0);
if (support_dual_bank_update_en && !tws_api_get_role()) {
u8 status = 0;
JL_CMD_response_send(msg[0], JL_PRO_STATUS_SUCCESS, msg[1], &status, 1);
rcsp_update_data_api_register(rcsp_update_data_read, rcsp_update_status_response);
register_receive_fw_update_block_handle(rcsp_update_handle);
rcsp_update_loader_download_init(DUAL_BANK_UPDATA, rcsp_loader_download_result_handle);
}
break;
default:
break;
}
}
#endif
#else
//以下函数是为了编译通过
void update_slave_adv_reopen(void)
{
printf("%s:NULL", __func__);
}
void rcsp_set_update_flag(u8 flag)
{
printf("%s:NULL", __func__);
}
void rcsp_update_set_role_switch(u8 sw)
{
printf("%s:NULL", __func__);
}
u8 get_jl_update_flag(void)
{
printf("%s:NULL", __func__);
return 0;
}
u8 rcsp_get_update_flag(void)
{
printf("%s:NULL", __func__);
return 0;
}
#endif
@@ -0,0 +1,27 @@
#ifndef _RCSP_ADV_USER_UPDATE_H_
#define _RCSP_ADV_USER_UPDATE_H_
//#include "rcsp_protocol.h"
//#include "rcsp_packet.h"
#include "typedef.h"
#define JL_OPCODE_GET_DEVICE_UPDATE_FILE_INFO_OFFSET 0xe1
#define JL_OPCODE_INQUIRE_DEVICE_IF_CAN_UPDATE 0xe2
#define JL_OPCODE_ENTER_UPDATE_MODE 0xe3
#define JL_OPCODE_EXIT_UPDATE_MODE 0xe4
#define JL_OPCODE_SEND_FW_UPDATE_BLOCK 0xe5
#define JL_OPCODE_GET_DEVICE_REFRESH_FW_STATUS 0xe6
#define JL_OPCODE_SET_DEVICE_REBOOT 0xe7
#define JL_OPCODE_NOTIFY_UPDATE_CONENT_SIZE 0xe8
void JL_rcsp_update_cmd_resp(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len);
void JL_rcsp_update_cmd_receive_resp(void *priv, u8 OpCode, u8 status, u8 *data, u16 len);
void JL_rcsp_msg_deal(void *hdl, u8 event, u8 *msg);
u8 get_jl_update_flag(void);
void set_jl_update_flag(u8 flag);
u8 get_curr_device_type(void);
void update_slave_adv_reopen(void);
#endif
@@ -0,0 +1,377 @@
//#include "update_lib.h"
#include "update.h"
#include "uart.h"
#include "update_loader_download.h"
#include "system/fs/fs.h"
#include "rcsp_user_update.h"
#include "JL_rcsp_protocol.h"
#include "os/os_error.h"
#include <string.h>
#if OTA_TWS_SAME_TIME_NEW
#include "update_tws_new.h"
#else
#include "update_tws.h"
#endif
#if TCFG_USER_TWS_ENABLE
#include "bt_tws.h"
#endif
#if ((RCSP_ADV_EN || RCSP_BTMATE_EN))
#define LMP_CH_UPDATE_DEBUG_EN 1
#if LMP_CH_UPDATE_DEBUG_EN
#define deg_puts puts
#define deg_printf printf
#else
#define deg_puts(...)
#define deg_printf(...)
#endif
typedef enum __DEVICE_REFRESH_FW_STATUS {
DEVICE_UPDATE_STA_SUCCESS = 0, //升级成功(default)
DEVICE_UPDATE_STA_VERIFY_ERR, //升级完校验代码出错(default)
DEVICE_UPDATE_STA_FAIL, //升级失败(default)
DEVICE_UPDATE_STA_KEY_ERR, //加密key不匹配
DEVICE_UPDATE_STA_FILE_ERR, //升级文件出错
DEVICE_UPDATE_STA_TYPE_ERR, //升级类型出错,仅code_type;
//DEVICE_UPDATE_STA_MAX_ERR,
DEVICE_UPDATE_STA_LOADER_DOWNLOAD_SUCC = 0x80,
} DEVICE_UPDATE_STA;
enum {
BT_UPDATE_OVER = 0,
BT_UPDATE_KEY_ERR,
BT_UPDATE_CONNECT_ERR,
};
typedef enum {
UPDATA_START = 0x00,
UPDATA_REV_DATA,
UPDATA_STOP,
} UPDATA_BIT_FLAG;
typedef struct _rcsp_update_param_t {
u32 state;
u32 read_len;
u32 need_rx_len;
u8 *read_buf;
void (*resume_hdl)(void *priv);
int (*sleep_hdl)(void *priv);
u32(*data_send_hdl)(void *priv, u32 offset, u16 len);
u32(*send_update_status_hdl)(void *priv, u8 state);
u32 file_offset;
u8 seek_type;
} rcsp_update_param_t;
extern void set_jl_update_flag(u8 flag);
extern const int support_dual_bank_update_en;
static rcsp_update_param_t rcsp_update_param;
#define __this (&rcsp_update_param)
static u8 *bt_read_buf = NULL;
static u16 g_bt_read_len = 0;
static u32 rcsp_file_offset = 0;
static u8 rcsp_seek_type = 0;
//NOTE:测试盒的定义和本sdk文件系统的seek_type定义不一样;
enum {
BT_SEEK_SET = 0x01,
BT_SEEK_CUR = 0x02,
BT_SEEK_TYPE_UPDATE_LEN = 0x10,
};
void tws_api_auto_role_switch_disable();
void tws_api_auto_role_switch_enable();
int rcsp_f_seek(void *fp, u8 type, u32 offset)
{
if (type == SEEK_SET) {
__this->file_offset = offset;
__this->seek_type = BT_SEEK_SET;
} else if (type == SEEK_CUR) {
__this->file_offset += offset;
__this->seek_type = BT_SEEK_CUR;
}
/* lib_printf("---------UPDATA_seek type %d, offsize %d----------\n", bt_seek_type, bt_file_offset); */
return 0;//FR_OK;
}
static u16 rcsp_f_stop(u8 err);
#define RETRY_TIMES 3
u8 get_rcsp_connect_status();
u16 rcsp_f_read(void *fp, u8 *buff, u16 len)
{
//printf("===rcsp_read:%x %x\n", __this->file_offset, len);
u8 retry_cnt = 0;
__this->need_rx_len = len;
__this->state = UPDATA_REV_DATA;
__this->read_len = 0;
__this->read_buf = buff;
__RETRY:
if (!get_rcsp_connect_status()) { //如果已经断开连接直接返回-1
return -1;
}
__this->data_send_hdl(fp, __this->file_offset, len);
while (!((0 == __this->state) && (__this->read_len == len))) {
if (__this->sleep_hdl && get_rcsp_connect_status()) {
__this->sleep_hdl(NULL);
} else {
len = -1;
break;
}
if (!((0 == __this->state) && (__this->read_len == len))) {
if (retry_cnt++ > RETRY_TIMES) {
len = (u16) - 1;
break;
} else {
goto __RETRY;
}
}
}
if ((u16) - 1 != len) {
__this->file_offset += len;
}
return len;
}
u16 rcsp_f_open(void)
{
deg_puts(">>>rcsp_f_open\n");
__this->file_offset = 0;
__this->seek_type = BT_SEEK_SET;
return 1;
}
u16 rcsp_send_update_len(u32 update_len)
{
/* while (0 == (bit(updata_start) & bt_updata_get_flag())); */
/* bt_updata_clr_flag(updata_start); //clr flag */
return 1;
}
static u8 update_result_handle(u8 err)
{
u8 res = DEVICE_UPDATE_STA_LOADER_DOWNLOAD_SUCC;
/* #if OTA_TWS_SAME_TIME_ENABLE */
/* tws_api_auto_role_switch_enable(); */
/* #endif */
if (err & UPDATE_RESULT_FLAG_BITMAP) {
switch (err & 0x7f) {
//升级文件错误
case UPDATE_RESULT_FILE_SIZE_ERR:
case UPDATE_RESULT_LOADER_SIZE_ERR:
case UPDATE_RESULT_REMOTE_FILE_HEAD_ERR:
case UPDATE_RESULT_LOCAL_FILE_HEAD_ERR:
case UPDATE_RESULT_FILE_OPERATION_ERR:
case UPDATE_RESULT_NOT_FIND_TARGET_FILE_ERR:
case UPDATE_RESULT_PRODUCT_INFO_NOT_MATCH:
res = DEVICE_UPDATE_STA_FILE_ERR;
break;
//文件内容校验失败
case UPDATE_RESULT_LOADER_VERIFY_ERR:
case UPDATE_RESULT_FLASH_DATA_VERIFY_ERR:
res = DEVICE_UPDATE_STA_VERIFY_ERR;
break;
}
} else if (BT_UPDATE_OVER == err) {
if (support_dual_bank_update_en) {
res = DEVICE_UPDATE_STA_SUCCESS;
} else {
res = DEVICE_UPDATE_STA_LOADER_DOWNLOAD_SUCC;
}
} else if (BT_UPDATE_KEY_ERR == err) {
res = DEVICE_UPDATE_STA_KEY_ERR;
} else {
res = DEVICE_UPDATE_STA_FAIL;
}
return res;
}
static u16 rcsp_f_stop(u8 err)
{
/* while (0 == (bit(updata_start) & bt_updata_get_flag())); */
/* bt_updata_clr_flag(updata_start); //clr flag */
err = update_result_handle(err);
__this->state = UPDATA_STOP;
printf(">>>rcsp_stop:%x\n", __this->state);
if (__this->data_send_hdl) {
__this->data_send_hdl(NULL, 0, 0);
}
while (!(0 == __this->state)) {
if (__this->sleep_hdl && get_rcsp_connect_status()) {
if (__this->sleep_hdl(NULL) == OS_TIMEOUT) {
break;
}
} else {
break;
}
}
if (__this->send_update_status_hdl) {
__this->send_update_status_hdl(NULL, err);
}
return 1;
}
void db_update_notify_fail_to_phone()
{
if (get_rcsp_connect_status()) {
rcsp_f_stop(DEVICE_UPDATE_STA_FAIL);
}
}
__attribute__((weak))
void user_change_ble_conn_param(u8 param_index)
{
}
static int rcsp_notify_update_content_size(void *priv, u32 size)
{
int err;
u8 data[4];
WRITE_BIG_U32(data, size);
user_change_ble_conn_param(0);
deg_printf("send content_size:%x\n", size);
err = JL_CMD_send(JL_OPCODE_NOTIFY_UPDATE_CONENT_SIZE, data, sizeof(data), JL_NEED_RESPOND);
return err;
}
void rcsp_update_handle(u8 state, void *buf, int len)
{
/* deg_puts("R"); */
if (state != __this->state) {
deg_puts(">>>rcsp state err\n");
return;
}
switch (state) {
case UPDATA_REV_DATA:
if (__this->read_buf) {
memcpy(__this->read_buf, buf, len);
__this->read_len = len;
__this->state = 0;
}
break;
case UPDATA_STOP:
__this->state = 0;
break;
}
if (__this->resume_hdl) {
__this->resume_hdl(NULL);
}
}
void rcsp_resume(void)
{
if (__this->resume_hdl) {
__this->resume_hdl(NULL);
}
}
static void rcsp_update_resume_hdl_register(void (*resume_hdl)(void *priv), int (*sleep_hdl)(void *priv))
{
__this->resume_hdl = resume_hdl;
__this->sleep_hdl = sleep_hdl;
}
void rcsp_update_data_api_register(u32(*data_send_hdl)(void *priv, u32 offset, u16 len), u32(*send_update_status_hdl)(void *priv, u8 state))
{
__this->data_send_hdl = data_send_hdl;
__this->send_update_status_hdl = send_update_status_hdl;
}
void rcsp_update_data_api_unregister(void)
{
__this->data_send_hdl = NULL;
__this->send_update_status_hdl = NULL;
}
void rcsp_ch_update_init(void (*resume_hdl)(void *priv), int (*sleep_hdl)(void *priv))
{
deg_puts("------------rcsp_ch_update_init\n");
rcsp_update_resume_hdl_register(resume_hdl, sleep_hdl);
//register_receive_fw_update_block_handle(rcsp_updata_handle);
}
const update_op_api_t rcsp_update_op = {
.ch_init = rcsp_ch_update_init,
.f_open = rcsp_f_open,
.f_read = rcsp_f_read,
.f_seek = rcsp_f_seek,
.f_stop = rcsp_f_stop,
.notify_update_content_size = rcsp_notify_update_content_size,
};
static void rcsp_update_state_cbk(int type, u32 state, void *priv)
{
update_ret_code_t *ret_code = (update_ret_code_t *)priv;
if (ret_code) {
printf("state:%x err:%x\n", ret_code->stu, ret_code->err_code);
}
switch (state) {
case UPDATE_CH_EXIT:
if (UPDATE_DUAL_BANK_IS_SUPPORT()) {
if ((0 == ret_code->stu) && (0 == ret_code->err_code)) {
set_jl_update_flag(1);
printf("2222>>>rcsp update succ\n");
update_result_set(UPDATA_SUCC);
} else {
update_result_set(UPDATA_DEV_ERR);
printf("3333>>>rcsp update succ\n");
}
} else {
if ((0 == ret_code->stu) && (0 == ret_code->err_code)) {
set_jl_update_flag(1);
}
}
break;
}
}
void rcsp_update_loader_download_init(int update_type, void (*result_cbk)(void *priv, u8 type, u8 cmd))
{
update_mode_info_t info = {
.type = update_type,
.state_cbk = rcsp_update_state_cbk,
.p_op_api = &rcsp_update_op,
.task_en = 1,
};
app_active_update_task_init(&info);
}
#endif //(OTA_TWS_SAME_TIME_ENABLE && (RCSP_ADV_EN || RCSP_BTMATE_EN))
@@ -0,0 +1,564 @@
#include "rcsp_user_update.h"
#include "app_config.h"
#if RCSP_UPDATE_EN
#include "uart.h"
#include "system/timer.h"
#include "update.h"
#include "custom_cfg.h"
#include "btstack/avctp_user.h"
#include "JL_rcsp_packet.h"
#include "JL_rcsp_protocol.h"
#include "rcsp_bluetooth.h"
#include "update_loader_download.h"
#if(TCFG_USER_TWS_ENABLE == 1)
#include "classic/tws_api.h"
#endif
#include "btstack_3th_protocol_user.h"
#if (RCSP_BTMATE_EN)
#define RCSP_DEBUG_EN
#ifdef RCSP_BTMATE_EN
#define rcsp_putchar(x) putchar(x)
#define rcsp_printf printf
#define rcsp_printf_buf(x,len) printf_buf(x,len)
#else
#define rcsp_putchar(...)
#define rcsp_printf(...)
#define rcsp_printf_buf(...)
#endif
#define DEV_UPDATE_FILE_INFO_OFFEST 0x00//0x40
#define DEV_UPDATE_FILE_INFO_LEN 0x00//(0x10 + VER_INFO_EXT_COUNT * (VER_INFO_EXT_MAX_LEN + 1))
typedef enum {
UPDATA_START = 0x00,
UPDATA_REV_DATA,
UPDATA_STOP,
} UPDATA_BIT_FLAG;
typedef struct _update_mode_t {
u8 opcode;
u8 opcode_sn;
} update_mode_t;
extern const int support_dual_bank_update_en;
extern void JL_ble_disconnect(void);
extern void set_curr_update_type(u8 type);
extern u8 check_le_pakcet_sent_finish_flag(void);
extern void register_receive_fw_update_block_handle(void (*handle)(u8 state, u8 *buf, u16 len));
extern void rcsp_update_data_api_register(u32(*data_send_hdl)(void *priv, u32 offset, u16 len), u32(*send_update_handl)(void *priv, u8 state));
extern void rcsp_update_handle(void *buf, int len);
extern u32 ex_cfg_fill_content_api(void);
extern void update_result_set(u16 result);
static u8 rcsp_update_status;
static u8 update_flag = 0;
static u16 ble_discon_timeout;
static void (*fw_update_block_handle)(u8 state, u8 *buf, u16 len) = NULL;
static update_file_ext_id_t update_file_id_info = {
.update_file_id_info.ver[0] = 0xff,
.update_file_id_info.ver[1] = 0xff,
};
static update_mode_t update_record_info;
u8 get_jl_update_flag(void)
{
printf("get_update_flag:%x\n", update_flag);
return update_flag;
}
void set_jl_update_flag(u8 flag)
{
update_flag = flag;
printf("update_flag:%x\n", update_flag);
}
void JL_controller_save_curr_cmd_para(u8 OpCode, u8 OpCode_SN)
{
update_record_info.opcode = OpCode;
update_record_info.opcode_sn = OpCode_SN;
}
void JL_controller_get_curr_cmd_para(u8 *OpCode, u8 *OpCode_SN)
{
*OpCode = update_record_info.opcode;
*OpCode_SN = update_record_info.opcode_sn;
}
void register_receive_fw_update_block_handle(void (*handle)(u8 state, u8 *buf, u16 len))
{
fw_update_block_handle = handle;
}
static void ble_discon_timeout_handle(void *priv)
{
rcsp_msg_post(MSG_JL_UPDATE_START, 0);
}
void JL_rcsp_update_cmd_resp(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len)
{
u8 msg[4];
rcsp_printf("%s\n", __FUNCTION__);
switch (OpCode) {
case JL_OPCODE_GET_DEVICE_UPDATE_FILE_INFO_OFFSET:
if (0 == len) {
rcsp_printf("JL_OPCODE_GET_DEVICE_UPDATE_FILE_INFO_OFFSET\n");
rcsp_msg_post(MSG_JL_GET_DEV_UPDATE_FILE_INFO_OFFSET, 2, OpCode, OpCode_SN);
} else {
rcsp_printf("JL_OPCODE_GET_DEVICE_UPDATE_FILE_INFO_OFFSET ERR\n");
}
break;
case JL_OPCODE_INQUIRE_DEVICE_IF_CAN_UPDATE:
rcsp_printf("JL_OPCODE_INQUIRE_DEVICE_IF_CAN_UPDATE:%x %x\n", len, data[0]);
//if (DEV_UPDATE_FILE_INFO_LEN == len) {
if (len) {
//memcpy((u8 *)&update_file_id_info, data, DEV_UPDATE_FILE_INFO_LEN);
set_curr_update_type(data[0]);
rcsp_msg_post(MSG_JL_INQUIRE_DEVEICE_IF_CAN_UPDATE, 3, OpCode, OpCode_SN, 0x00);
}
break;
case JL_OPCODE_EXIT_UPDATE_MODE:
rcsp_printf("JL_OPCODE_EXIT_UPDATE_MODE\n");
break;
case JL_OPCODE_ENTER_UPDATE_MODE:
rcsp_printf("JL_OPCODE_ENTER_UPDATE_MODE\n");
rcsp_msg_post(MSG_JL_ENTER_UPDATE_MODE, 2, OpCode, OpCode_SN);
break;
case JL_OPCODE_SEND_FW_UPDATE_BLOCK:
rcsp_printf("JL_OPCODE_SEND_FW_UPDATE_BLOCK\n");
break;
case JL_OPCODE_GET_DEVICE_REFRESH_FW_STATUS:
rcsp_printf("JL_OPCODE_GET_DEVICE_REFRESH_FW_STATUS\n");
JL_controller_save_curr_cmd_para(OpCode, OpCode_SN);
if (fw_update_block_handle) {
fw_update_block_handle(UPDATA_STOP, NULL, 0);
}
break;
case JL_OPCODE_SET_DEVICE_REBOOT:
rcsp_printf("JL_OPCODE_SET_DEVICE_REBOOT\n");
if (support_dual_bank_update_en) {
cpu_reset();
}
break;
default:
break;
}
}
static void JL_rcsp_resp_dev_update_file_info_offest(u8 OpCode, u8 OpCode_SN)
{
u8 data[4 + 2];
u16 update_file_info_offset = DEV_UPDATE_FILE_INFO_OFFEST;
u16 update_file_info_len = DEV_UPDATE_FILE_INFO_LEN;
WRITE_BIG_U32(data + 0, update_file_info_offset);
WRITE_BIG_U16(data + 4, update_file_info_len);
JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, data, sizeof(data));
}
static void JL_resp_inquire_device_if_can_update(u8 OpCode, u8 OpCode_SN, u8 update_sta)
{
u8 data[1];
data[0] = update_sta;
JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, data, sizeof(data));
}
enum {
UPDATE_FLAG_OK,
UPDATE_FLAG_LOW_POWER,
UPDATE_FLAG_FW_INFO_ERR,
UPDATE_FLAG_FW_INFO_CONSISTENT,
};
static u8 judge_remote_version_can_update(void)
{
//extern u16 ex_cfg_get_local_version_info(void);
u16 remote_file_ver = READ_BIG_U16(update_file_id_info.update_file_id_info.ver);
//u16 local_ver = ex_cfg_get_local_version_info();
u16 local_ver = get_vid_pid_ver_from_cfg_file(GET_VID_FROM_EX_CFG);
#if (0 == VER_INFO_EXT_COUNT)
//extern u16 ex_cfg_get_local_pid_info(void);
//extern u16 ex_cfg_get_local_vid_info(void);
//u16 local_pid = ex_cfg_get_local_pid_info();
//u16 local_vid = ex_cfg_get_local_vid_info();
u16 local_pid = get_vid_pid_ver_from_cfg_file(GET_PID_FROM_EX_CFG);
u16 local_vid = get_vid_pid_ver_from_cfg_file(GET_VID_FROM_EX_CFG);
u16 remote_file_pid = READ_BIG_U16(update_file_id_info.update_file_id_info.pid);
u16 remote_file_vid = READ_BIG_U16(update_file_id_info.update_file_id_info.vid);
if (remote_file_ver > local_ver || remote_file_pid != local_pid || remote_file_vid != local_vid) {
return UPDATE_FLAG_FW_INFO_ERR;
}
#else
//extern u32 ex_cfg_get_local_authkey_info(u8 * authkey_data[], u8 * authkey_len);
//extern u32 ex_cfg_get_local_procode_info(u8 * procode_data[], u8 * procode_len);
u8 authkey_len = 0;
u8 *local_authkey_data = NULL;
get_authkey_procode_from_cfg_file(&local_authkey_data, &authkey_len, GET_AUTH_KEY_FROM_EX_CFG);
u8 procode_len = 0;
u8 *local_procode_data = NULL;
get_authkey_procode_from_cfg_file(&local_procode_data, &procode_len, GET_PRO_CODE_FROM_EX_CFG);
//ex_cfg_get_local_authkey_info(&local_authkey_data, &authkey_len);
//ex_cfg_get_local_procode_info(&local_procode_data, &procode_len);
u8 *remote_authkey_data = update_file_id_info.ext;
u8 *remote_procode_data = update_file_id_info.ext + authkey_len + 1;
if (remote_file_ver < local_ver
|| 0 != memcmp(remote_authkey_data, local_authkey_data, authkey_len)
|| 0 != memcmp(remote_procode_data, local_procode_data, procode_len)) {
return UPDATE_FLAG_FW_INFO_ERR;
}
#endif
if (remote_file_ver == local_ver) {
rcsp_printf("remote_file_ver is %x, local_ver is %x, remote_file_ver is similar to local_ver\n", remote_file_ver, local_ver);
return UPDATE_FLAG_FW_INFO_CONSISTENT;
}
return UPDATE_FLAG_OK;
}
static bool check_edr_is_disconnct(void)
{
if (get_curr_channel_state()) {
return TRUE;
} else {
return FALSE;
}
}
static bool check_ble_all_packet_sent(void)
{
if (check_le_pakcet_sent_finish_flag()) {
return TRUE;
} else {
return FALSE;
}
}
static u32 rcsp_update_data_read(void *priv, u32 offset_addr, u16 len)
{
u32 err;
u8 data[4 + 2];
WRITE_BIG_U32(data, offset_addr);
WRITE_BIG_U16(data + 4, len);
err = JL_CMD_send(JL_OPCODE_SEND_FW_UPDATE_BLOCK, data, sizeof(data), JL_NEED_RESPOND);
return err;
}
static JL_ERR JL_controller_resp_get_dev_refresh_fw_status(u8 OpCode, u8 OpCode_SN, u8 result)
{
JL_ERR send_err = JL_ERR_NONE;
u8 data[1];
data[0] = result; //0:sucess 1:fail;
send_err = JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, data, sizeof(data));
return send_err;
}
u32 rcsp_update_status_response(void *priv, u8 status)
{
u8 OpCode;
u8 OpCode_SN;
JL_ERR send_err = JL_ERR_NONE;
JL_controller_get_curr_cmd_para(&OpCode, &OpCode_SN);
//log_info("get cmd para:%x %x\n", OpCode, OpCode_SN);
if (JL_OPCODE_GET_DEVICE_REFRESH_FW_STATUS == OpCode) {
send_err = JL_controller_resp_get_dev_refresh_fw_status(OpCode, OpCode_SN, status);
}
return send_err;
}
void JL_rcsp_update_cmd_receive_resp(void *priv, u8 OpCode, u8 status, u8 *data, u16 len)
{
switch (OpCode) {
case JL_OPCODE_SEND_FW_UPDATE_BLOCK:
if (fw_update_block_handle) {
fw_update_block_handle(UPDATA_REV_DATA, data, len);
}
break;
default:
break;
}
}
static void rcsp_loader_download_result_handle(void *priv, u8 type, u8 cmd)
{
if (UPDATE_LOADER_OK == cmd) {
//rcsp_msg(MSG_JL_UPDATE_START, 0);
set_jl_update_flag(1);
if (support_dual_bank_update_en) {
rcsp_printf("4444>>>rcsp update succ\n");
update_result_set(UPDATA_SUCC);
}
} else {
rcsp_printf(">>>update loader err\n");
#if OTA_TWS_SAME_TIME_ENABLE
if ((tws_ota_control(OTA_TYPE_GET) == OTA_TWS)) {
tws_ota_stop(OTA_STOP_UPDATE_OVER_ERR);
}
#endif
}
}
u32 get_jl_rcsp_update_status()
{
return rcsp_update_status;
}
static void rcsp_update_private_param_fill(UPDATA_PARM *p)
{
u32 exif_addr;
exif_addr = ex_cfg_fill_content_api();
update_param_priv_fill(p, (void *)&exif_addr, sizeof(exif_addr));
}
static void rcsp_update_before_jump_handle(int type)
{
#if CONFIG_UPDATE_JUMP_TO_MASK
y_printf(">>>[test]:latch reset update\n");
latch_reset();
#if 0
update_close_hw("null");
ram_protect_close();
/* save_spi_port(); */
extern void __BT_UPDATA_JUMP();
y_printf("update jump to __BT_UPDATA ...\n");
//跳转到uboot加载完,30ms左右(200410_yzb)
/* clk_set("sys", 48 * 1000000L); */
__BT_UPDATA_JUMP();
#endif
#else
cpu_reset();
#endif
}
void JL_rcsp_msg_deal(RCSP_MSG msg, int argc, int *argv)
{
u16 remote_file_version;
u8 can_update_flag = UPDATE_FLAG_FW_INFO_ERR;
switch (msg) {
case MSG_JL_GET_DEV_UPDATE_FILE_INFO_OFFSET:
rcsp_printf("MSG_JL_GET_DEV_UPDATE_FILE_INFO_OFFSET\n");
rcsp_update_status = 1;
/* extern void linein_mutex_stop(void *priv); */
/* linein_mutex_stop(NULL); */
/* extern void linein_mute(u8 mute); */
/* linein_mute(1); */
if (argc < 2) {
rcsp_printf("err: MSG_JL_GET_DEV_UPDATE_FILE_INFO_OFFSET too few argument, argc is %d\n", argc);
return;
}
JL_rcsp_resp_dev_update_file_info_offest((u8)argv[0], (u8)argv[1]);
break;
case MSG_JL_INQUIRE_DEVEICE_IF_CAN_UPDATE:
rcsp_printf("MSG_JL_INQUIRE_DEVEICE_IF_CAN_UPDATE\n");
if (argc < 2) {
rcsp_printf("err: MSG_JL_INQUIRE_DEVEICE_IF_CAN_UPDATE too few argument, argc is %d\n", argc);
return;
}
#if 0
remote_file_version = READ_BIG_U16(update_file_id_info.update_file_id_info.ver);
rcsp_printf("remote_file_ver:V%d.%d.%d.%d\n",
(remote_file_version & 0xf000) >> 12,
(remote_file_version & 0x0f00) >> 8,
(remote_file_version & 0x00f0) >> 4,
(remote_file_version & 0x000f));
if (0 == remote_file_version) {
can_update_flag = UPDATE_FLAG_OK;
} else {
can_update_flag = judge_remote_version_can_update();
}
if (UPDATE_FLAG_OK == can_update_flag) {
set_jl_update_flag(1);
}
#else
can_update_flag = UPDATE_FLAG_OK;
#endif
//todo;judge voltage
JL_resp_inquire_device_if_can_update((u8)argv[0], (u8)argv[1], can_update_flag);
if (0 == support_dual_bank_update_en) {
rcsp_msg_post(MSG_JL_LOADER_DOWNLOAD_START, 0);
}
break;
case MSG_JL_DEV_DISCONNECT:
if (check_ble_all_packet_sent()) {
rcsp_printf("MSG_JL_DEV_DISCONNECT\n");
JL_ble_disconnect();
if (check_edr_is_disconnct()) {
puts("-need discon edr\n");
user_send_cmd_prepare(USER_CTRL_POWER_OFF, 0, NULL);
}
ble_discon_timeout = sys_timeout_add(NULL, ble_discon_timeout_handle, 1000);
} else {
rcsp_printf("W");
rcsp_msg_post(MSG_JL_DEV_DISCONNECT, 0);
}
break;
case MSG_JL_LOADER_DOWNLOAD_START:
rcsp_update_data_api_register(rcsp_update_data_read, rcsp_update_status_response);
register_receive_fw_update_block_handle(rcsp_update_handle);
if (RCSP_BLE == get_curr_device_type()) {
rcsp_update_loader_download_init(BLE_APP_UPDATA, rcsp_loader_download_result_handle);
} else if (RCSP_SPP == get_curr_device_type()) {
rcsp_update_loader_download_init(SPP_APP_UPDATA, rcsp_loader_download_result_handle);
}
break;
case MSG_JL_UPDATE_START:
if (check_edr_is_disconnct()) {
rcsp_printf("b");
rcsp_msg_post(MSG_JL_UPDATE_START, 0);
break;
}
if (RCSP_BLE == get_curr_device_type()) {
rcsp_printf("BLE_APP_UPDATE\n");
update_mode_api_v2(BLE_APP_UPDATA,
rcsp_update_private_param_fill,
rcsp_update_before_jump_handle);
} else {
rcsp_printf("SPP_APP_UPDATA\n");
update_mode_api_v2(SPP_APP_UPDATA,
rcsp_update_private_param_fill,
rcsp_update_before_jump_handle);
}
/* if (RCSP_BLE == get_curr_device_type()) { */
/* rcsp_printf("BLE_APP_UPDATE\n"); */
/* update_mode_api(BLE_APP_UPDATA); */
/* } else { */
/* rcsp_printf("SPP_APP_UPDATA\n"); */
/* update_mode_api(SPP_APP_UPDATA); */
/* } */
break;
case MSG_JL_ENTER_UPDATE_MODE:
if (argc < 2) {
rcsp_printf("err: MSG_JL_ENTER_UPDATE_MODE too few argument, argc is %d\n", argc);
return;
}
rcsp_printf("MSG_JL_ENTER_UPDATE_MODE:%x %x\n", (u8)argv[0], (u8)argv[1]);
#if(TCFG_USER_TWS_ENABLE == 1)
void tws_cancle_all_noconn();
tws_cancle_all_noconn();
#endif
user_send_cmd_prepare(USER_CTRL_WRITE_CONN_DISABLE, 0, NULL);
user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_DISABLE, 0, NULL);
if (support_dual_bank_update_en) {
u8 status = 0;
JL_CMD_response_send((u8)argv[0], JL_PRO_STATUS_SUCCESS, (u8)argv[1], &status, 1);
rcsp_update_data_api_register(rcsp_update_data_read, rcsp_update_status_response);
register_receive_fw_update_block_handle(rcsp_update_handle);
rcsp_update_loader_download_init(DUAL_BANK_UPDATA, rcsp_loader_download_result_handle);
}
break;
default:
break;
}
}
void rcsp_update_jump_for_hid_device()
{
if (RCSP_BLE == get_curr_device_type()) {
rcsp_printf("BLE_APP_UPDATE\n");
update_mode_api_v2(BLE_APP_UPDATA,
rcsp_update_private_param_fill,
rcsp_update_before_jump_handle);
} else {
rcsp_printf("SPP_APP_UPDATA\n");
update_mode_api_v2(SPP_APP_UPDATA,
rcsp_update_private_param_fill,
rcsp_update_before_jump_handle);
}
}
#endif
static u8 rcsp_update_flag = 0;
void set_rcsp_db_update_status(u8 value)
{
rcsp_update_flag = value;
}
u8 get_rcsp_db_update_status()
{
return rcsp_update_flag;
}
void rcsp_before_enter_db_update_mode() //进入双备份升级前
{
r_printf("%s", __func__);
rcsp_update_flag = 1;
void sys_auto_shut_down_disable(void);
if (get_total_connect_dev() == 0) {
sys_auto_shut_down_disable();
}
#if TCFG_USER_TWS_ENABLE
int tws_api_get_role(void);
if (tws_api_get_role() == TWS_ROLE_SLAVE) {
return;
}
#endif
if (get_total_connect_dev()) { //断开蓝牙连接,断开之后不能让他重新开
/* user_send_cmd_prepare(USER_CTRL_DISCONNECTION_HCI, 0, NULL); */
}
#if TCFG_USER_TWS_ENABLE
extern void tws_cancle_all_noconn();
/* tws_cancle_all_noconn() ; */
#else
user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_DISABLE, 0, NULL);
user_send_cmd_prepare(USER_CTRL_WRITE_CONN_DISABLE, 0, NULL);
#endif
}
extern void sys_auto_shut_down_enable(void);
void rcsp_db_update_fail_deal() //双备份升级失败处理
{
r_printf("%s", __func__);
if (rcsp_update_flag) {
rcsp_update_flag = 0;
if (get_total_connect_dev() == 0) {
sys_auto_shut_down_enable();
}
}
/* cpu_reset(); //升级失败直接复位 */
}
#endif
@@ -0,0 +1,25 @@
#ifndef _RCSP_USER_UPDATE_H_
#define _RCSP_USER_UPDATE_H_
//#include "rcsp_protocol.h"
//#include "rcsp_packet.h"
#include "typedef.h"
#define JL_OPCODE_GET_DEVICE_UPDATE_FILE_INFO_OFFSET 0xe1
#define JL_OPCODE_INQUIRE_DEVICE_IF_CAN_UPDATE 0xe2
#define JL_OPCODE_ENTER_UPDATE_MODE 0xe3
#define JL_OPCODE_EXIT_UPDATE_MODE 0xe4
#define JL_OPCODE_SEND_FW_UPDATE_BLOCK 0xe5
#define JL_OPCODE_GET_DEVICE_REFRESH_FW_STATUS 0xe6
#define JL_OPCODE_SET_DEVICE_REBOOT 0xe7
#define JL_OPCODE_NOTIFY_UPDATE_CONENT_SIZE 0xe8
void JL_rcsp_update_cmd_resp(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len);
void JL_rcsp_update_cmd_receive_resp(void *priv, u8 OpCode, u8 status, u8 *data, u16 len);
u8 get_jl_update_flag(void);
void set_jl_update_flag(u8 flag);
u8 get_curr_device_type(void);
#endif