初版
This commit is contained in:
+471
@@ -0,0 +1,471 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".rcsp_browser.data.bss")
|
||||
#pragma data_seg(".rcsp_browser.data")
|
||||
#pragma const_seg(".rcsp_browser.text.const")
|
||||
#pragma code_seg(".rcsp_browser.text")
|
||||
#endif
|
||||
#include "rcsp_browser.h"
|
||||
#include "app_config.h"
|
||||
#include "rcsp.h"
|
||||
#include "dev_manager.h"
|
||||
#include "file_operate/file_bs_deal.h"
|
||||
#include "rcsp_event.h"
|
||||
#include "ble_rcsp_server.h"
|
||||
#include "JL_rcsp_api.h"
|
||||
#include "rcsp_functions/rcsp_config.h"
|
||||
|
||||
#if RCSP_MODE && RCSP_FILE_OPT
|
||||
#include "music/music_player.h"
|
||||
|
||||
#define LOG_TAG_CONST RCSP
|
||||
#define LOG_TAG "[browser]"
|
||||
#define LOG_ERROR_ENABLE
|
||||
#define LOG_DEBUG_ENABLE
|
||||
#define LOG_INFO_ENABLE
|
||||
#define LOG_CLI_ENABLE
|
||||
#include "debug.h"
|
||||
|
||||
#define FILE_BROWSE_BUF_LEN 250//要小于RCSP MTU, 不要随意改大
|
||||
#define FILE_BROWSE_NAME_MAX_LIMIT 128//限制最大文件夹名称大小
|
||||
|
||||
#define FILE_BROWSE_TASK_NAME "rcsp_file_bs"
|
||||
#if defined(CONFIG_FAT_MAX_DEEPTH) && (CONFIG_FAT_MAX_DEEPTH > 0)
|
||||
#define MAX_DEEPTH CONFIG_FAT_MAX_DEEPTH
|
||||
#else
|
||||
#define MAX_DEEPTH 9/* 0~9 deepth of system */
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
RCSPBrowserObjectTypeFolder = 0,
|
||||
RCSPBrowserObjectTypeFile,
|
||||
} RCSPBrowserObjectType;
|
||||
|
||||
typedef enum {
|
||||
RCSPBrowserFileDataFormatUnicode = 0,
|
||||
RCSPBrowserFileDataFormatANSI,
|
||||
} RCSPBrowserFileDataFormat;
|
||||
|
||||
static const char *dev_logo[] = {
|
||||
[RCSPDevMapUDISK] = "udisk0",
|
||||
[RCSPDevMapSD0] = "sd0",
|
||||
[RCSPDevMapSD1] = "sd1",
|
||||
#if TCFG_NANDFLASH_UI_FAT_ENABLE
|
||||
[RCSPDevMapFLASH] = TCFG_NANDFLASH_UI_FAT_LOGO,
|
||||
#else
|
||||
[RCSPDevMapFLASH] = "virfat_flash",
|
||||
#endif
|
||||
[RCSPDevMapFLASH_2] = "fat_nor",
|
||||
#ifdef TCFG_NANDFLASH_FAT_ROOT
|
||||
[RCSPDevMapNANDFLASH] = TCFG_NANDFLASH_FAT_ROOT,
|
||||
#else
|
||||
[RCSPDevMapNANDFLASH] = "NULL",
|
||||
#endif
|
||||
};
|
||||
|
||||
#pragma pack(1)
|
||||
struct __browser {
|
||||
u8 path_type;///
|
||||
u8 read_file_num;
|
||||
u16 start_num;
|
||||
u32 dev_handle;
|
||||
u16 path_len;
|
||||
u32 path_clust[MAX_DEEPTH];
|
||||
};
|
||||
|
||||
#if (defined TCFG_NANDFLASH_DEV_ENABLE && TCFG_NANDFLASH_DEV_ENABLE)
|
||||
struct JL_FILE_DATA {
|
||||
u8 type : 1;
|
||||
u8 format : 1;
|
||||
u8 device : 5;
|
||||
u8 reserve : 1;
|
||||
u32 clust;
|
||||
u16 file_num;
|
||||
u8 name_len;
|
||||
u8 file_data[0];
|
||||
};
|
||||
#else
|
||||
struct JL_FILE_DATA {
|
||||
u8 type : 1;
|
||||
u8 format : 1;
|
||||
u8 device : 3;
|
||||
u8 reserve : 3;
|
||||
u32 clust;
|
||||
u16 file_num;
|
||||
u8 name_len;
|
||||
u8 file_data[0];
|
||||
};
|
||||
#endif
|
||||
#pragma pack()
|
||||
|
||||
|
||||
|
||||
static const char dec_file_ext[][3] = {
|
||||
#if (WATCH_FILE_TO_FLASH)
|
||||
{"ALL"},
|
||||
{'\0'},
|
||||
#else // WATCH_FILE_TO_FLASH
|
||||
#if (TCFG_DEC_MP3_ENABLE)
|
||||
{"MP1"},
|
||||
{"MP2"},
|
||||
{"MP3"},
|
||||
#endif
|
||||
|
||||
#if (TCFG_DEC_WMA_ENABLE)
|
||||
{"WMA"},
|
||||
#endif
|
||||
|
||||
#if (TCFG_DEC_WAV_ENABLE || TCFG_DEC_DTS_ENABLE)
|
||||
{"WAV"},
|
||||
#endif
|
||||
|
||||
#if (TCFG_DEC_FLAC_ENABLE)
|
||||
{"FLA"},
|
||||
#endif
|
||||
|
||||
#if (TCFG_DEC_APE_ENABLE)
|
||||
{"APE"},
|
||||
#endif
|
||||
|
||||
#if (TCFG_DEC_DECRYPT_ENABLE)
|
||||
{"SMP"},
|
||||
#endif
|
||||
|
||||
#if (TCFG_DEC_AMR_ENABLE)
|
||||
{"AMR"},
|
||||
#endif
|
||||
|
||||
#if (TCFG_DEC_M4A_ENABLE)
|
||||
{"M4A"},
|
||||
{"AAC"},
|
||||
#endif
|
||||
#if (TCFG_DEC_M4A_ENABLE || TCFG_DEC_ALAC_ENABLE)
|
||||
{"MP4"},
|
||||
#endif
|
||||
{"TMP"},
|
||||
{'\0'},
|
||||
#endif // WATCH_FILE_TO_FLASH
|
||||
};
|
||||
|
||||
static struct __browser *browser = NULL;
|
||||
|
||||
//rcsp获取文件浏览后缀配置
|
||||
char *rcsp_browser_file_ext(void)
|
||||
{
|
||||
return (char *)dec_file_ext;
|
||||
}
|
||||
|
||||
//rcsp获取文件浏览后缀配置数据长度
|
||||
u16 rcsp_browser_file_ext_size(void)
|
||||
{
|
||||
return strlen((const char *)dec_file_ext);
|
||||
}
|
||||
|
||||
//rcsp浏览设备映射
|
||||
char *rcsp_browser_dev_remap(RCSPDevMap index)
|
||||
{
|
||||
if (index >= RCSPDevMapMax) {
|
||||
return NULL;
|
||||
}
|
||||
return (char *)dev_logo[index];
|
||||
}
|
||||
|
||||
//rcsp限制文件名长度(包括文件夹,如:xxx~~~, 省略以"~~~"表示)
|
||||
u16 rcsp_file_name_cut(u8 *name, u16 len, u16 len_limit)
|
||||
{
|
||||
u8 ex_type[8];
|
||||
u8 three_point_hex[] = {0x2E, 0x00, 0x2E, 0x00, 0x2E, 0x00}; //... 显示unicode码
|
||||
if (len > len_limit) {
|
||||
memcpy(name + len_limit - sizeof(three_point_hex), three_point_hex, sizeof(three_point_hex));
|
||||
return len_limit;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
static bool browser_get_dir_info(FILE_BS_DEAL *fil_bs, u8 *path_buf, u16 len, RCSPBrowserObjectType type, void *ptr)
|
||||
{
|
||||
s16 ret = 0;
|
||||
u16 i, j = 0;
|
||||
u32 deep_clust = 0;
|
||||
FS_DIR_INFO dir_info;
|
||||
//open root
|
||||
ret = file_bs_entern_dir(fil_bs, NULL);
|
||||
if (ret == 0) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (len == 4 && type == RCSPBrowserObjectTypeFolder) {
|
||||
/* log_info("root deep\n"); */
|
||||
if (ptr) {
|
||||
*((u32 *)ptr) = ret;
|
||||
}
|
||||
goto end;
|
||||
} else if (len == 4 && type == RCSPBrowserObjectTypeFile) {
|
||||
/* log_info("play file path\n"); */
|
||||
memcpy((u8 *)&deep_clust, path_buf, 4);
|
||||
deep_clust = app_ntohl(deep_clust);
|
||||
if (ptr) {
|
||||
*((u32 *)ptr) = deep_clust;
|
||||
}
|
||||
goto end;
|
||||
}
|
||||
//deep check
|
||||
u8 deep = len / 4;
|
||||
if (deep > MAX_DEEPTH) {
|
||||
log_error("deep err : %d\n", deep);
|
||||
return false;
|
||||
}
|
||||
/* log_info("get deep%d data\n", deep - 1); */
|
||||
for (i = 1; i < deep; i++) {
|
||||
memcpy((u8 *)&deep_clust, path_buf + 4 * i, 4);
|
||||
deep_clust = app_ntohl(deep_clust);
|
||||
/* log_info("deep_clust:%x\n", deep_clust); */
|
||||
for (j = 1; j < ret + 1; j++) {
|
||||
file_bs_get_dir_info(fil_bs, &dir_info, j, 1);
|
||||
if (dir_info.sclust == deep_clust) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i < deep - 1) {
|
||||
ret = file_bs_entern_dir(fil_bs, &dir_info);
|
||||
if (ret == 0) {
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (type == RCSPBrowserObjectTypeFile) {
|
||||
if (ptr) {
|
||||
*((u32 *)ptr) = dir_info.sclust; //file return clust
|
||||
}
|
||||
goto end;
|
||||
} else {
|
||||
ret = file_bs_entern_dir(fil_bs, &dir_info);
|
||||
if (ret == 0) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (ptr) {
|
||||
*((u32 *)ptr) = ret; //file return clust
|
||||
}
|
||||
}
|
||||
end:
|
||||
return true;
|
||||
}
|
||||
|
||||
static u32 browse_open_dir(FILE_BS_DEAL *fil_bs, u8 *path_buf, u16 len)
|
||||
{
|
||||
u32 file_cnt = 0;
|
||||
browser_get_dir_info(fil_bs, path_buf, len, RCSPBrowserObjectTypeFolder, (void *)&file_cnt);
|
||||
return file_cnt;
|
||||
}
|
||||
|
||||
static void file_printf_dir(FS_DIR_INFO *dir_inf, u8 cnt)
|
||||
{
|
||||
u8 i;
|
||||
LONG_FILE_NAME *l_name_pt;
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
/* log_info("file type %d nt:%d clust %x \n", dir_inf[i].dir_type, dir_inf[i].fn_type, dir_inf[i].sclust); */
|
||||
l_name_pt = &dir_inf[i].lfn_buf;
|
||||
if (dir_inf[i].fn_type == BS_FNAME_TYPE_SHORT) {
|
||||
file_comm_display_83name((void *)&l_name_pt->lfn[32], (void *)l_name_pt->lfn);
|
||||
strcpy(l_name_pt->lfn, &l_name_pt->lfn[32]);
|
||||
l_name_pt->lfn_cnt = strlen(l_name_pt->lfn);
|
||||
log_info("%s\n", l_name_pt->lfn);
|
||||
} else {
|
||||
if (l_name_pt->lfn_cnt > 510) {
|
||||
l_name_pt->lfn_cnt = 510;
|
||||
log_error("***get long name err!!!");
|
||||
}
|
||||
l_name_pt->lfn_cnt = file_comm_long_name_fix((void *)l_name_pt->lfn, l_name_pt->lfn_cnt);
|
||||
l_name_pt->lfn[l_name_pt->lfn_cnt] = 0;
|
||||
l_name_pt->lfn[l_name_pt->lfn_cnt + 1] = 0;
|
||||
|
||||
/* log_info("file name len : %d \n", l_name_pt->lfn_cnt); */
|
||||
/* log_info_hexdump((u8 *)l_name_pt->lfn, l_name_pt->lfn_cnt); */
|
||||
}
|
||||
}
|
||||
}
|
||||
static u16 add_one_iterm_to_sendbuf(u8 *dest, u16 max_buf_len, u16 offset, FS_DIR_INFO *p_dir_info, u16 file_cnt, u8 dev_type)
|
||||
{
|
||||
struct JL_FILE_DATA file_data;
|
||||
memset((u8 *)&file_data, 0, sizeof(struct JL_FILE_DATA));
|
||||
|
||||
|
||||
file_data.type = p_dir_info->dir_type;
|
||||
|
||||
if (p_dir_info->fn_type == BS_FNAME_TYPE_SHORT) {
|
||||
file_data.format = RCSPBrowserFileDataFormatANSI;
|
||||
} else {
|
||||
file_data.format = RCSPBrowserFileDataFormatUnicode;
|
||||
}
|
||||
|
||||
///限制文件名长度
|
||||
p_dir_info->lfn_buf.lfn_cnt = rcsp_file_name_cut((u8 *)p_dir_info->lfn_buf.lfn, p_dir_info->lfn_buf.lfn_cnt, FILE_BROWSE_NAME_MAX_LIMIT);
|
||||
|
||||
file_data.device = dev_type;
|
||||
file_data.clust = app_htonl(p_dir_info->sclust);
|
||||
file_data.file_num = app_htons(file_cnt);
|
||||
file_data.name_len = p_dir_info->lfn_buf.lfn_cnt;
|
||||
|
||||
memcpy(dest + offset, (u8 *)&file_data, sizeof(struct JL_FILE_DATA));
|
||||
memcpy(dest + offset + sizeof(struct JL_FILE_DATA), (u8 *)p_dir_info->lfn_buf.lfn, p_dir_info->lfn_buf.lfn_cnt);
|
||||
|
||||
/* log_info("add send data:"); */
|
||||
/* log_info_hexdump(dest+offset,p_dir_info->lfn_buf.lfn_cnt + sizeof(struct JL_FILE_DATA)); */
|
||||
return (p_dir_info->lfn_buf.lfn_cnt + sizeof(struct JL_FILE_DATA));
|
||||
}
|
||||
|
||||
static void rcsp_browser_task(void *p)
|
||||
{
|
||||
u8 reason = 0;
|
||||
u32 play_file_clust = 0;
|
||||
FS_DIR_INFO dir_info;
|
||||
FILE_BS_DEAL fil_bs;
|
||||
u8 *path_data = NULL;
|
||||
|
||||
memset((u8 *)&dir_info, 0, sizeof(FS_DIR_INFO));
|
||||
memset((u8 *)&fil_bs, 0, sizeof(FILE_BS_DEAL));
|
||||
|
||||
fil_bs.dev = dev_manager_find_spec(rcsp_browser_dev_remap(browser->dev_handle), 0);
|
||||
if (fil_bs.dev == NULL) {
|
||||
reason = 1;
|
||||
log_error("dev nofound!!!\n");
|
||||
goto _EXIT;
|
||||
}
|
||||
file_bs_open_handle(&fil_bs, (u8 *)rcsp_browser_file_ext());
|
||||
|
||||
u32 dir_file_cnt = browse_open_dir(&fil_bs, (u8 *)browser->path_clust, browser->path_len);
|
||||
if (browser->start_num + browser->read_file_num >= dir_file_cnt) {
|
||||
log_error("file range err\n");
|
||||
reason = 1;
|
||||
browser->read_file_num = dir_file_cnt - browser->start_num + 1;
|
||||
}
|
||||
/* log_info("start num:%d read file num:%d\n", browser->start_num, browser->read_file_num); */
|
||||
|
||||
u16 offset = 0;
|
||||
u32 ret = 0;
|
||||
path_data = (u8 *)zalloc(FILE_BROWSE_BUF_LEN);
|
||||
if (path_data == NULL) {
|
||||
reason = 1;
|
||||
log_error("no ram for path_data!! \n");
|
||||
goto _EXIT;
|
||||
}
|
||||
for (int i = browser->start_num ; i < (browser->start_num + browser->read_file_num); i++) {
|
||||
ret = file_bs_get_dir_info(&fil_bs, &dir_info, i, 1);
|
||||
if (!ret) {
|
||||
break;
|
||||
}
|
||||
|
||||
file_printf_dir(&dir_info, 1);
|
||||
if (offset && ((offset + dir_info.lfn_buf.lfn_cnt + sizeof(struct JL_FILE_DATA)) > FILE_BROWSE_BUF_LEN)) {
|
||||
///如果buf不够填充了, 先将数据发送了先,再重新填充
|
||||
ret = JL_DATA_send(JL_OPCODE_DATA, JL_OPCODE_FILE_BROWSE_REQUEST_START, path_data, offset, JL_NOT_NEED_RESPOND, 0, NULL);
|
||||
if (ret) {
|
||||
log_error("send data err: %d, %d\n", ret, offset);
|
||||
goto _EXIT;
|
||||
}
|
||||
//reset send buf
|
||||
offset = 0;
|
||||
memset(path_data, 0, FILE_BROWSE_BUF_LEN);
|
||||
offset += add_one_iterm_to_sendbuf(path_data, FILE_BROWSE_BUF_LEN, offset, &dir_info, i, browser->dev_handle);
|
||||
} else {
|
||||
offset += add_one_iterm_to_sendbuf(path_data, FILE_BROWSE_BUF_LEN, offset, &dir_info, i, browser->dev_handle);
|
||||
}
|
||||
}
|
||||
|
||||
//send last package
|
||||
if (offset) {
|
||||
ret = JL_DATA_send(JL_OPCODE_DATA, JL_OPCODE_FILE_BROWSE_REQUEST_START, path_data, offset, JL_NOT_NEED_RESPOND, 0, NULL);
|
||||
if (ret) {
|
||||
log_error("send data err: %d\n", ret);
|
||||
goto _EXIT;
|
||||
}
|
||||
}
|
||||
|
||||
_EXIT:
|
||||
file_bs_close_handle(&fil_bs);
|
||||
if (path_data) {
|
||||
free(path_data);
|
||||
}
|
||||
rcsp_msg_post(
|
||||
USER_MSG_RCSP_BS_END,
|
||||
4,
|
||||
(int)rcsp_handle_get(),
|
||||
(int)reason,
|
||||
(int)rcsp_browser_dev_remap(browser->dev_handle),
|
||||
(int)play_file_clust);
|
||||
|
||||
while (1) {
|
||||
os_time_dly(10);
|
||||
}
|
||||
}
|
||||
|
||||
//rcsp文件浏览开始
|
||||
void rcsp_browser_start(u8 *data, u16 len)
|
||||
{
|
||||
///检查数据是否有效
|
||||
log_info("%s\n", __func__);
|
||||
if (len > sizeof(struct __browser)) {
|
||||
return ;
|
||||
}
|
||||
///创建数据解析句柄
|
||||
browser = (struct __browser *)zalloc(sizeof(struct __browser));
|
||||
if (browser == NULL) {
|
||||
return ;
|
||||
}
|
||||
///解析数据
|
||||
memcpy((u8 *)browser, data, sizeof(struct __browser));
|
||||
browser->start_num = app_ntohs(browser->start_num);
|
||||
browser->dev_handle = app_ntohl(browser->dev_handle);
|
||||
browser->path_len = app_ntohs(browser->path_len);
|
||||
///检查设备范围
|
||||
if (browser->dev_handle >= RCSPDevMapMax) {
|
||||
log_error("bs dev hdl err !!\n");
|
||||
free(browser);
|
||||
browser = NULL;
|
||||
return ;
|
||||
}
|
||||
///检查是否是已经选定好文件播放
|
||||
if (browser->path_type) {
|
||||
u8 reason = 2;
|
||||
u32 play_file_clust = app_ntohl(browser->path_clust[0]);
|
||||
rcsp_msg_post(
|
||||
USER_MSG_RCSP_BS_END,
|
||||
4,
|
||||
(int)rcsp_handle_get(),
|
||||
(int)reason,
|
||||
(int)rcsp_browser_dev_remap(browser->dev_handle),
|
||||
(int)play_file_clust);
|
||||
return ;
|
||||
}
|
||||
///目录浏览线程创建
|
||||
if (task_create(rcsp_browser_task, (void *)NULL, FILE_BROWSE_TASK_NAME)) {
|
||||
free(browser);
|
||||
browser = NULL;
|
||||
log_error("rcsp_browser_task creat fail\n");
|
||||
}
|
||||
}
|
||||
|
||||
//rcsp文件浏览繁忙查询
|
||||
bool rcsp_browser_busy(void)
|
||||
{
|
||||
if (browser) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//rcsp文件浏览停止
|
||||
void rcsp_browser_stop(void)
|
||||
{
|
||||
///删除线程,释放资源
|
||||
task_kill(FILE_BROWSE_TASK_NAME);
|
||||
if (browser) {
|
||||
free(browser);
|
||||
browser = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
#ifndef __RCSP_BROWSER_H__
|
||||
#define __RCSP_BROWSER_H__
|
||||
|
||||
#include "typedef.h"
|
||||
#include "app_config.h"
|
||||
|
||||
///rcsp 对应的设备id枚举
|
||||
typedef enum {
|
||||
RCSPDevMapUDISK = 0,
|
||||
RCSPDevMapSD0,
|
||||
RCSPDevMapSD1,
|
||||
RCSPDevMapFLASH,
|
||||
RCSPDevMapAUX,
|
||||
RCSPDevMapFLASH_2,
|
||||
RCSPDevMapNANDFLASH,
|
||||
RCSPDevMapMax,
|
||||
} RCSPDevMap;
|
||||
|
||||
//rcsp浏览设备映射
|
||||
char *rcsp_browser_dev_remap(RCSPDevMap index);
|
||||
//rcsp获取文件浏览后缀配置
|
||||
char *rcsp_browser_file_ext(void);
|
||||
//rcsp获取文件浏览后缀配置数据长度
|
||||
u16 rcsp_browser_file_ext_size(void);
|
||||
//rcsp限制文件名长度(包括文件夹,如:xxx~~~, 省略以"~~~"表示)
|
||||
u16 rcsp_file_name_cut(u8 *name, u16 len, u16 len_limit);
|
||||
//rcsp文件浏览开始
|
||||
void rcsp_browser_start(u8 *data, u16 len);
|
||||
//rcsp文件浏览停止
|
||||
void rcsp_browser_stop(void);
|
||||
//rcsp文件浏览繁忙查询
|
||||
bool rcsp_browser_busy(void);
|
||||
|
||||
#endif // __RCSP_BROWSER_H__
|
||||
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".rcsp_bt_func.data.bss")
|
||||
#pragma data_seg(".rcsp_bt_func.data")
|
||||
#pragma const_seg(".rcsp_bt_func.text.const")
|
||||
#pragma code_seg(".rcsp_bt_func.text")
|
||||
#endif
|
||||
#include "rcsp_bt_func.h"
|
||||
#include "rcsp_device_info_func_common.h"
|
||||
#include "rcsp_device_status.h"
|
||||
#include "rcsp_config.h"
|
||||
#include "rcsp_event.h"
|
||||
#include "app_action.h"
|
||||
|
||||
#include "ble_rcsp_server.h"
|
||||
#include "rcsp_music_info_setting.h"
|
||||
#include "JL_rcsp_protocol.h"
|
||||
#include "JL_rcsp_attr.h"
|
||||
|
||||
#if (RCSP_MODE)
|
||||
// 后续需要全部从JL_rcsp_protocol.h中拷贝出来
|
||||
#define BT_INFO_ATTR_MUSIC_TITLE (0)
|
||||
#define BT_INFO_ATTR_MUSIC_ARTIST (1)
|
||||
#define BT_INFO_ATTR_MUSIC_ALBUM (2)
|
||||
#define BT_INFO_ATTR_MUSIC_NUMBER (3)
|
||||
#define BT_INFO_ATTR_MUSIC_TOTAL (4)
|
||||
#define BT_INFO_ATTR_MUSIC_GENRE (5)
|
||||
#define BT_INFO_ATTR_MUSIC_TIME (6)
|
||||
#define BT_INFO_ATTR_MUSIC_STATE (7)
|
||||
#define BT_INFO_ATTR_MUSIC_CURR_TIME (8)
|
||||
#define BT_INFO_ATTR_IRK (0x0A)
|
||||
|
||||
typedef uint8_t sm_key_t[16];
|
||||
extern bool sm_get_local_irk(sm_key_t irk);
|
||||
extern bool ble_vendor_random_address_generate(u8 *address, u8 type);
|
||||
//设置固件bt行为
|
||||
bool rcsp_bt_func_set(void *priv, u8 *data, u16 len)
|
||||
{
|
||||
#if RCSP_ADV_MUSIC_INFO_ENABLE
|
||||
music_info_cmd_handle(data, len);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
//获取固件bt信息
|
||||
u32 rcsp_bt_func_get(void *priv, u8 *buf, u16 buf_size, u32 mask)
|
||||
{
|
||||
u16 offset = 0;
|
||||
#if RCSP_ADV_MUSIC_INFO_ENABLE
|
||||
u8 player_time[4];
|
||||
|
||||
if (mask & BIT(BT_INFO_ATTR_MUSIC_TITLE)) {
|
||||
offset += add_one_attr(buf, buf_size, offset, BT_INFO_ATTR_MUSIC_TITLE, (u8 *)get_music_title(), get_music_title_len());
|
||||
}
|
||||
if (mask & BIT(BT_INFO_ATTR_MUSIC_ARTIST)) {
|
||||
offset += add_one_attr(buf, buf_size, offset, BT_INFO_ATTR_MUSIC_ARTIST, (u8 *)get_music_artist(), get_music_artist_len());
|
||||
}
|
||||
if (mask & BIT(BT_INFO_ATTR_MUSIC_ALBUM)) {
|
||||
offset += add_one_attr(buf, buf_size, offset, BT_INFO_ATTR_MUSIC_ALBUM, (u8 *)get_music_album(), get_music_album_len());
|
||||
}
|
||||
if (mask & BIT(BT_INFO_ATTR_MUSIC_NUMBER)) {
|
||||
offset += add_one_attr(buf, buf_size, offset, BT_INFO_ATTR_MUSIC_NUMBER, (u8 *)get_music_number(), get_music_number_len());
|
||||
}
|
||||
if (mask & BIT(BT_INFO_ATTR_MUSIC_TOTAL)) {
|
||||
offset += add_one_attr(buf, buf_size, offset, BT_INFO_ATTR_MUSIC_TOTAL, (u8 *)get_music_total(), get_music_total_len());
|
||||
}
|
||||
if (mask & BIT(BT_INFO_ATTR_MUSIC_GENRE)) {
|
||||
offset += add_one_attr(buf, buf_size, offset, BT_INFO_ATTR_MUSIC_GENRE, (u8 *)get_music_genre(), get_music_genre_len());
|
||||
}
|
||||
if (mask & BIT(BT_INFO_ATTR_MUSIC_TIME)) {
|
||||
u16 music_sec = get_music_total_time();
|
||||
player_time[0] = music_sec >> 8;
|
||||
player_time[1] = music_sec;
|
||||
offset += add_one_attr(buf, buf_size, offset, BT_INFO_ATTR_MUSIC_TIME, player_time, 2);
|
||||
}
|
||||
if (mask & BIT(BT_INFO_ATTR_MUSIC_STATE)) {
|
||||
//printf("\n music state\n");
|
||||
u8 music_state = get_music_player_state();
|
||||
offset += add_one_attr(buf, buf_size, offset, BT_INFO_ATTR_MUSIC_STATE, &music_state, 1);
|
||||
}
|
||||
if (mask & BIT(BT_INFO_ATTR_MUSIC_CURR_TIME)) {
|
||||
//printf("\nmusic curr time\n");
|
||||
u32 curr_music_sec = get_music_curr_time();
|
||||
player_time[0] = curr_music_sec >> 24;
|
||||
player_time[1] = curr_music_sec >> 16;
|
||||
player_time[2] = curr_music_sec >> 8;
|
||||
player_time[3] = curr_music_sec;
|
||||
offset += add_one_attr(buf, buf_size, offset, BT_INFO_ATTR_MUSIC_CURR_TIME, player_time, 4);
|
||||
}
|
||||
#endif
|
||||
#if CONFIG_USE_RANDOM_ADDRESS_ENABLE
|
||||
if (mask & BIT(BT_INFO_ATTR_IRK)) {
|
||||
u8 irk_flag = 0;
|
||||
sm_key_t irk;
|
||||
irk_flag = sm_get_local_irk(irk);
|
||||
u8 irk_reponse[18];
|
||||
irk_reponse[0] = irk_flag;
|
||||
irk_reponse[1] = irk_flag ? 16 : 0;
|
||||
memcpy(irk_reponse + 2, irk, 16);
|
||||
offset += add_one_attr(buf, buf_size, offset, BT_INFO_ATTR_IRK, irk_reponse, irk_flag ? 18 : 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
#endif
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
#ifndef __RCSP_BT_FUNC_H__
|
||||
#define __RCSP_BT_FUNC_H__
|
||||
#include "typedef.h"
|
||||
#include "app_config.h"
|
||||
#endif
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
#ifndef __RCSP_DEVICE_INFO_CMD_COMMON_H__
|
||||
#define __RCSP_DEVICE_INFO_CMD_COMMON_H__
|
||||
|
||||
//设置固件fm行为
|
||||
bool rcsp_fm_func_set(void *priv, u8 *data, u16 len);
|
||||
//获取固件fm信息
|
||||
u32 rcsp_fm_func_get(void *priv, u8 *buf, u16 buf_size, u32 mask);
|
||||
|
||||
//设置固件rtc行为
|
||||
bool rcsp_rtc_func_set(void *priv, u8 *data, u16 len);
|
||||
//获取固件rtc信息
|
||||
u32 rcsp_rtc_func_get(void *priv, u8 *buf, u16 buf_size, u32 mask);
|
||||
//rtc消息处理
|
||||
void rcsp_rtc_msg_deal(int msg);
|
||||
|
||||
//获取固件播放器信息
|
||||
u32 rcsp_music_func_get(void *priv, u8 *buf, u16 buf_size, u32 mask);
|
||||
//设置固件播放器行为
|
||||
bool rcsp_music_func_set(void *priv, u8 *data, u16 len);
|
||||
//停止音乐功能
|
||||
void rcsp_music_func_stop(void);
|
||||
|
||||
//设置固件bt行为
|
||||
bool rcsp_bt_func_set(void *priv, u8 *data, u16 len);
|
||||
//获取固件bt信息
|
||||
u32 rcsp_bt_func_get(void *priv, u8 *buf, u16 buf_size, u32 mask);
|
||||
|
||||
//设置固件linein行为
|
||||
bool rcsp_linein_func_set(void *priv, u8 *data, u16 len);
|
||||
//获取固件linein信息
|
||||
u32 rcsp_linein_func_get(void *priv, u8 *buf, u16 buf_size, u32 mask);
|
||||
//停止linein功能
|
||||
void rcsp_linein_func_stop(void);
|
||||
#endif
|
||||
+269
@@ -0,0 +1,269 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".rcsp_fm_func.data.bss")
|
||||
#pragma data_seg(".rcsp_fm_func.data")
|
||||
#pragma const_seg(".rcsp_fm_func.text.const")
|
||||
#pragma code_seg(".rcsp_fm_func.text")
|
||||
#endif
|
||||
#include "rcsp_fm_func.h"
|
||||
#include "rcsp_device_info_func_common.h"
|
||||
#include "rcsp_device_status.h"
|
||||
#include "rcsp_config.h"
|
||||
#include "rcsp_event.h"
|
||||
#include "app_action.h"
|
||||
#include "key_event_deal.h"
|
||||
#include "rcsp_functions/rcsp_config.h"
|
||||
|
||||
#if (RCSP_MODE && TCFG_APP_FM_EN)
|
||||
#include "fm_api.h"
|
||||
#include "fm_rw.h"
|
||||
|
||||
#pragma pack(1)
|
||||
struct _FM_STATUS_INFO {
|
||||
u8 status;
|
||||
u8 cur_channel;
|
||||
u16 cur_fre;
|
||||
u8 mode;
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
#define FM_INFO_ATTR_STATUS (0)
|
||||
#define FM_INFO_ATTR_FRE (1)
|
||||
|
||||
#define SCANE_ALL (0x01)
|
||||
#define SCANE_DOWN (0x02)
|
||||
#define SCANE_UP (0x03)
|
||||
|
||||
enum {
|
||||
FM_FUNC_MUSIC_PP = 0x1,
|
||||
FM_FUNC_PREV_FREQ,
|
||||
FM_FUNC_NEXT_FREQ,
|
||||
FM_FUNC_PREV_STATION,
|
||||
FM_FUNC_NEXT_STATION,
|
||||
FM_FUNC_SCAN,
|
||||
FM_FUNC_SET_STATION,
|
||||
FM_FUNC_DEL_STATION,
|
||||
FM_FUNC_SET_FRE,
|
||||
FM_FUNC_DEL_FRE,
|
||||
};
|
||||
|
||||
enum {
|
||||
FM_FUNC_SCAN_ALL = 0x0,
|
||||
FM_FUNC_SCAN_ALL_DOWN,
|
||||
FM_FUNC_SCAN_ALL_UP,
|
||||
FM_FUNC_SCAN_STOP,
|
||||
};
|
||||
|
||||
enum {
|
||||
FM_FUNC_STATUS_PLAY = 0x01,
|
||||
FM_FUNC_STATUS_PAUSE,
|
||||
FM_FUNC_STATUS_SCANING,
|
||||
};
|
||||
|
||||
static u8 fm_get_status(u8 scan_all_en)
|
||||
{
|
||||
extern u8 fm_get_scan_flag(void);
|
||||
extern u8 fm_get_fm_dev_mute(void);
|
||||
u8 scan_flag = fm_get_scan_flag();
|
||||
u8 fm_dev_mute = fm_get_fm_dev_mute();
|
||||
if (SCANE_DOWN == scan_flag || SCANE_UP == scan_flag) {
|
||||
return FM_FUNC_STATUS_SCANING;
|
||||
} else if (SCANE_ALL == scan_flag) {
|
||||
if (scan_all_en && 0 == fm_dev_mute) {
|
||||
rcsp_device_status_update(FM_FUNCTION_MASK, BIT(FM_INFO_ATTR_STATUS) | BIT(FM_INFO_ATTR_FRE));
|
||||
}
|
||||
return FM_FUNC_STATUS_SCANING;
|
||||
} else if (0 == fm_dev_mute) {
|
||||
return FM_FUNC_STATUS_PLAY;
|
||||
} else {
|
||||
return FM_FUNC_STATUS_PAUSE;
|
||||
}
|
||||
}
|
||||
|
||||
static u16 fm_scan_timer = 0;
|
||||
static void fm_scan_state_func(void *priv)
|
||||
{
|
||||
/* printf("fm_scan_state_func\n"); */
|
||||
if (FM_FUNC_STATUS_SCANING == fm_get_status(1)) {
|
||||
return;
|
||||
}
|
||||
if (fm_scan_timer) {
|
||||
sys_hi_timer_del(fm_scan_timer);
|
||||
fm_scan_timer = 0;
|
||||
}
|
||||
// 更新
|
||||
rcsp_device_status_update(FM_FUNCTION_MASK, BIT(FM_INFO_ATTR_STATUS) | BIT(FM_INFO_ATTR_FRE));
|
||||
}
|
||||
|
||||
bool rcsp_fm_func_set(void *priv, u8 *data, u16 len)
|
||||
{
|
||||
/* printf("rcsp_fm_func_set\n"); */
|
||||
/* put_buf(data, len); */
|
||||
u8 fun_cmd = data[0];
|
||||
u16 cmd_param = 0;
|
||||
u16 param_len = len - 1;
|
||||
switch (fun_cmd) {
|
||||
case FM_FUNC_MUSIC_PP:
|
||||
printf("fm pp\n");
|
||||
fm_volume_pp();
|
||||
rcsp_device_status_update(FM_FUNCTION_MASK, BIT(FM_INFO_ATTR_STATUS) | BIT(FM_INFO_ATTR_FRE));
|
||||
break;
|
||||
case FM_FUNC_PREV_FREQ:
|
||||
printf("fm prev fre\n");
|
||||
fm_prev_freq();
|
||||
rcsp_device_status_update(FM_FUNCTION_MASK, BIT(FM_INFO_ATTR_STATUS) | BIT(FM_INFO_ATTR_FRE));
|
||||
break;
|
||||
case FM_FUNC_NEXT_FREQ:
|
||||
printf("fm next fre\n");
|
||||
fm_next_freq();
|
||||
rcsp_device_status_update(FM_FUNCTION_MASK, BIT(FM_INFO_ATTR_STATUS) | BIT(FM_INFO_ATTR_FRE));
|
||||
break;
|
||||
case FM_FUNC_PREV_STATION:
|
||||
printf("fm prev station\n");
|
||||
fm_prev_station();
|
||||
rcsp_device_status_update(FM_FUNCTION_MASK, BIT(FM_INFO_ATTR_STATUS) | BIT(FM_INFO_ATTR_FRE));
|
||||
break;
|
||||
case FM_FUNC_NEXT_STATION:
|
||||
printf("fm next station\n");
|
||||
fm_next_station();
|
||||
rcsp_device_status_update(FM_FUNCTION_MASK, BIT(FM_INFO_ATTR_STATUS) | BIT(FM_INFO_ATTR_FRE));
|
||||
break;
|
||||
case FM_FUNC_SCAN:
|
||||
printf("fm scan\n");
|
||||
if (1 == param_len) {
|
||||
cmd_param = data[1];
|
||||
switch (cmd_param) {
|
||||
case FM_FUNC_SCAN_ALL:
|
||||
printf("fm scan all\n");
|
||||
fm_scan_all();
|
||||
break;
|
||||
case FM_FUNC_SCAN_ALL_DOWN:
|
||||
printf("fm scan prev\n");
|
||||
fm_scan_up();
|
||||
break;
|
||||
case FM_FUNC_SCAN_ALL_UP:
|
||||
printf("fm scan next\n");
|
||||
fm_scan_down();
|
||||
break;
|
||||
case FM_FUNC_SCAN_STOP:
|
||||
printf("fm scan stop\n");
|
||||
if (FM_FUNC_STATUS_SCANING == fm_get_status(0)) {
|
||||
fm_scan_stop();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf("fm scan default\n");
|
||||
break;
|
||||
}
|
||||
if (0 == fm_scan_timer) {
|
||||
fm_scan_timer = sys_hi_timer_add(NULL, fm_scan_state_func, 1000);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FM_FUNC_SET_STATION:
|
||||
printf("fm sel station\n");
|
||||
extern void fm_sel_station(u8 channel);
|
||||
if (1 == param_len) {
|
||||
cmd_param = data[1];
|
||||
fm_sel_station(cmd_param);
|
||||
}
|
||||
break;
|
||||
case FM_FUNC_DEL_STATION:
|
||||
printf("fm del station\n");
|
||||
break;
|
||||
case FM_FUNC_SET_FRE:
|
||||
printf("fm sel fre\n");
|
||||
extern u8 fm_set_fre(u16 fre);
|
||||
printf("param_len : %d\n", param_len);
|
||||
for (u8 i = 0; i < param_len; i++) {
|
||||
printf("data[%d] : 0x%x\n", i, data[i + 1]);
|
||||
}
|
||||
if (2 == param_len) {
|
||||
cmd_param = (data[1] << 8 | data[2]) * 10;
|
||||
printf("fm target = %d\n", cmd_param);
|
||||
fm_set_fre(cmd_param);
|
||||
}
|
||||
break;
|
||||
case FM_FUNC_DEL_FRE:
|
||||
printf("fm del ...\n");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (fun_cmd) {
|
||||
case FM_FUNC_SET_FRE:
|
||||
case FM_FUNC_SET_STATION:
|
||||
// 更新状态
|
||||
rcsp_msg_post(USER_MSG_RCSP_FM_UPDATE_STATE, 1, (int)priv);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//获取固件fm信息
|
||||
u32 rcsp_fm_func_get(void *priv, u8 *buf, u16 buf_size, u32 mask)
|
||||
{
|
||||
u16 offset = 0;
|
||||
if (mask & BIT(FM_INFO_ATTR_STATUS)) {
|
||||
extern u8 fm_get_cur_channel(void);
|
||||
extern u16 fm_get_cur_fre(void);
|
||||
extern u8 fm_get_mode(void);
|
||||
|
||||
struct _FM_STATUS_INFO fm_status_info;
|
||||
u16 fre = fm_get_cur_fre();
|
||||
fre = app_htons(fre);
|
||||
fm_status_info.cur_fre = fre;
|
||||
fm_status_info.cur_channel = fm_get_cur_channel();
|
||||
fm_status_info.status = fm_get_status(0);
|
||||
if (FM_FUNC_STATUS_PLAY != fm_status_info.status) {
|
||||
fm_status_info.status = 0;
|
||||
}
|
||||
fm_status_info.mode = fm_get_mode();
|
||||
|
||||
/* printf("rcsp_fm_func_get, %d, %d, %d, %d\n", fm_status_info.cur_fre, fm_status_info.cur_channel, fm_status_info.status, fm_status_info.mode); */
|
||||
offset = add_one_attr(buf, buf_size, offset, FM_INFO_ATTR_STATUS, (u8 *)&fm_status_info, sizeof(fm_status_info));
|
||||
}
|
||||
|
||||
if (mask & BIT(FM_INFO_ATTR_FRE)) {
|
||||
FM_INFO fm_info = {0};
|
||||
fm_read_info(&fm_info);
|
||||
/* printf("get_fm_channel_fre_info:\n"); */
|
||||
/* put_buf(&fm_info, sizeof(fm_info)); */
|
||||
u8 fm_info_size = fm_info.total_chanel * 3 + 1;
|
||||
u8 *fm_fre_info = zalloc(fm_info_size);
|
||||
if (fm_fre_info) {
|
||||
u8 *ptr = fm_fre_info;
|
||||
u16 fm_fre = 0;
|
||||
u8 total = 1;
|
||||
u8 i;
|
||||
u8 k;
|
||||
*ptr++ = fm_info.total_chanel;
|
||||
for (i = 0; i < (MEM_FM_LEN); i++) {
|
||||
for (k = 0; k < 8; k++) {
|
||||
if (fm_info.dat[i] & BIT(k)) {
|
||||
fm_fre = i * 8 + k + 874;
|
||||
fm_fre = app_htons(fm_fre);
|
||||
*ptr++ = total++;
|
||||
memcpy(ptr, &fm_fre, sizeof(fm_fre));
|
||||
ptr += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
offset += add_one_attr(buf, buf_size, offset, FM_INFO_ATTR_FRE, fm_fre_info, fm_info_size);
|
||||
free(fm_fre_info);
|
||||
}
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
void rcsp_fm_msg_deal(int msg)
|
||||
{
|
||||
struct RcspModel *rcspModel = rcsp_handle_get();
|
||||
if (rcspModel == NULL) {
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
#ifndef __RCSP_FM_FUNC_H__
|
||||
#define __RCSP_FM_FUNC_H__
|
||||
#include "typedef.h"
|
||||
#include "app_config.h"
|
||||
#endif
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".rcsp_linein_func.data.bss")
|
||||
#pragma data_seg(".rcsp_linein_func.data")
|
||||
#pragma const_seg(".rcsp_linein_func.text.const")
|
||||
#pragma code_seg(".rcsp_linein_func.text")
|
||||
#endif
|
||||
#include "rcsp_linein_func.h"
|
||||
#include "rcsp_device_info_func_common.h"
|
||||
#include "rcsp_device_status.h"
|
||||
#include "rcsp_config.h"
|
||||
#include "rcsp_event.h"
|
||||
#include "app_action.h"
|
||||
#include "app_msg.h"
|
||||
#include "key_event_deal.h"
|
||||
#include "tone_player.h"
|
||||
|
||||
#if RCSP_MODE && TCFG_APP_LINEIN_EN && !SOUNDCARD_ENABLE
|
||||
#include "linein.h"
|
||||
|
||||
#define LINEIN_INFO_ATTR_STATUS (0)
|
||||
//设置固件linein行为
|
||||
bool rcsp_linein_func_set(void *priv, u8 *data, u16 len)
|
||||
{
|
||||
if (0 != linein_get_status()) {
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//获取固件linein信息
|
||||
u32 rcsp_linein_func_get(void *priv, u8 *buf, u16 buf_size, u32 mask)
|
||||
{
|
||||
u16 offset = 0;
|
||||
if (mask & BIT(LINEIN_INFO_ATTR_STATUS)) {
|
||||
u8 status = linein_get_status();
|
||||
offset = add_one_attr(buf, buf_size, offset, LINEIN_INFO_ATTR_STATUS, (u8 *)&status, sizeof(status));
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
void rcsp_linein_msg_deal(int msg, u8 ret)
|
||||
{
|
||||
struct RcspModel *rcspModel = rcsp_handle_get();
|
||||
if (rcspModel == NULL) {
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
||||
//停止linein功能
|
||||
void rcsp_linein_func_stop(void)
|
||||
{
|
||||
#if RCSP_MSG_DISTRIBUTION_VER != RCSP_MSG_DISTRIBUTION_VER_VISUAL_CFG_TOOL
|
||||
if (linein_get_status()) {
|
||||
app_task_put_key_msg(KEY_MUSIC_PP, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
#ifndef __RCSP_LINEIN_FUNC_H__
|
||||
#define __RCSP_LINEIN_FUNC_H__
|
||||
#include "typedef.h"
|
||||
#include "app_config.h"
|
||||
#endif
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".rcsp_music_func.data.bss")
|
||||
#pragma data_seg(".rcsp_music_func.data")
|
||||
#pragma const_seg(".rcsp_music_func.text.const")
|
||||
#pragma code_seg(".rcsp_music_func.text")
|
||||
#endif
|
||||
#include "rcsp_music_func.h"
|
||||
#include "rcsp_device_info_func_common.h"
|
||||
#include "rcsp.h"
|
||||
#include "app_task.h"
|
||||
#include "rcsp_device_status.h"
|
||||
#include "rcsp_config.h"
|
||||
#include "key_event_deal.h"
|
||||
#include "JL_rcsp_attr.h"
|
||||
#include "JL_rcsp_api.h"
|
||||
#include "music/music_player.h"
|
||||
|
||||
#if (RCSP_MODE && TCFG_APP_MUSIC_EN)
|
||||
#define MUSIC_INFO_ATTR_STATUS (0)
|
||||
#define MUSIC_INFO_ATTR_FILE_NAME (1)
|
||||
#define MUSIC_INFO_ATTR_FILE_PLAY_MODE (2)
|
||||
|
||||
#pragma pack(1)
|
||||
struct _MUSIC_STATUS_info {
|
||||
u8 status;
|
||||
u32 cur_time;
|
||||
u32 total_time;
|
||||
u8 cur_dev;
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
enum {
|
||||
MUSIC_FUNC_PP = 0x1,
|
||||
MUSIC_FUNC_PREV,
|
||||
MUSIC_FUNC_NEXT,
|
||||
MUSIC_FUNC_MODE,
|
||||
MUSIC_FUNC_EQ_MODE,
|
||||
MUSIC_FUNC_REWIND,
|
||||
MUSIC_FUNC_FAST_FORWORD,
|
||||
};
|
||||
|
||||
|
||||
enum {
|
||||
REPEAT_MODE_ALL = 0x1,
|
||||
REPEAT_MODE_DEV,
|
||||
REPEAT_MODE_ONE,
|
||||
REPEAT_MODE_RANDOM,
|
||||
REPEAT_MODE_FOLDER,
|
||||
};
|
||||
|
||||
const u8 rcsp_repeat_mode_remap[] = {
|
||||
[FCYCLE_ALL] = REPEAT_MODE_ALL,
|
||||
[FCYCLE_ONE] = REPEAT_MODE_ONE,
|
||||
[FCYCLE_FOLDER] = REPEAT_MODE_FOLDER,
|
||||
[FCYCLE_RANDOM] = REPEAT_MODE_RANDOM,
|
||||
};
|
||||
|
||||
|
||||
#define RCSP_MUSIC_FILE_NAME_MAX_LIMIT (128)
|
||||
|
||||
// 本文件内用到
|
||||
static u8 music_func_add_one_attr_ex(u8 *buf, u16 max_len, u8 offset, u8 type, u8 *data, u8 size, u8 att_size)
|
||||
{
|
||||
if (offset + size + 2 > max_len) {
|
||||
printf("add attr err\n");
|
||||
return 0;
|
||||
}
|
||||
buf[offset] = att_size + 1;
|
||||
buf[offset + 1] = type;
|
||||
memcpy(&buf[offset + 2], data, size);
|
||||
return size + 2;
|
||||
}
|
||||
|
||||
// 本文件内用到
|
||||
static u8 mucis_func_add_one_attr_continue(u8 *buf, u16 max_len, u8 offset, u8 type, u8 *data, u8 size)
|
||||
{
|
||||
if ((offset + size) > max_len) {
|
||||
printf("add attr err 2\n");
|
||||
return 0;
|
||||
}
|
||||
memcpy(&buf[offset], data, size);
|
||||
return size;
|
||||
}
|
||||
|
||||
//获取固件播放器信息
|
||||
u32 rcsp_music_func_get(void *priv, u8 *buf, u16 buf_size, u32 mask)
|
||||
{
|
||||
u16 offset = 0;
|
||||
#if (TCFG_APP_MUSIC_EN && !RCSP_APP_MUSIC_EN)
|
||||
u8 app = app_get_curr_task();
|
||||
if (app != APP_MUSIC_TASK) {
|
||||
return 0;
|
||||
}
|
||||
///获取当前播放状态
|
||||
struct RcspModel *rcspModel = (struct RcspModel *) priv;
|
||||
extern struct __music music_hdl;
|
||||
FILE *file = music_hdl.player_hd->file;
|
||||
|
||||
if (mask & BIT(MUSIC_INFO_ATTR_STATUS)) {
|
||||
/* printf("MUSIC_INFO_ATTR_STATUS\n"); */
|
||||
struct _MUSIC_STATUS_info music_info;
|
||||
// RCSP TODO:
|
||||
printf("RCSP TODO!!!");
|
||||
music_info.status = 0;
|
||||
music_info.cur_time = 0;//app_htonl(file_dec_get_cur_time());
|
||||
music_info.total_time = 60;//app_htonl(file_dec_get_total_time());
|
||||
char *logo = dev_manager_get_logo(dev_manager_find_active(1));
|
||||
char *tmp = NULL;
|
||||
if (logo) {
|
||||
for (int i = 0; i < RCSPDevMapMax; i++) {
|
||||
tmp = rcsp_browser_dev_remap(i);
|
||||
if (tmp && strcmp(tmp, logo) == 0) {
|
||||
music_info.cur_dev = i;
|
||||
offset += add_one_attr(buf, buf_size, offset, MUSIC_INFO_ATTR_STATUS, (u8 *)&music_info, sizeof(music_info));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mask & BIT(MUSIC_INFO_ATTR_FILE_NAME) && file) {
|
||||
/* printf("MUSIC_INFO_ATTR_FILE_NAME\n"); */
|
||||
u8 *lfn_buf = zalloc(512);
|
||||
if (lfn_buf) {
|
||||
int lfn_len = fget_name(file, lfn_buf, 512);
|
||||
lfn_len = rcsp_file_name_cut(lfn_buf, lfn_len, RCSP_MUSIC_FILE_NAME_MAX_LIMIT);
|
||||
struct vfs_attr tmp_attr = {0};
|
||||
fget_attrs(file, &tmp_attr);
|
||||
u32 clust = app_htonl(tmp_attr.sclust);
|
||||
/* u32 clust = tmp_attr.sclust; */
|
||||
/* printf("clust %x\n", clust); */
|
||||
u8 code_type = 1;
|
||||
u8 *tmp_buf = lfn_buf;
|
||||
if (lfn_buf[0] == '\\' && lfn_buf[1] == 'U') {
|
||||
code_type = 0;
|
||||
lfn_len -= 2;
|
||||
tmp_buf += 2;
|
||||
}
|
||||
|
||||
offset += music_func_add_one_attr_ex(buf, buf_size, offset, MUSIC_INFO_ATTR_FILE_NAME, (u8 *)&clust, sizeof(u32), lfn_len + sizeof(code_type) + sizeof(clust));
|
||||
offset += mucis_func_add_one_attr_continue(buf, buf_size, offset, MUSIC_INFO_ATTR_FILE_NAME, (u8 *)&code_type, 1);
|
||||
offset += mucis_func_add_one_attr_continue(buf, buf_size, offset, MUSIC_INFO_ATTR_FILE_NAME, tmp_buf, lfn_len);
|
||||
free(lfn_buf);
|
||||
}
|
||||
}
|
||||
|
||||
if (mask & BIT(MUSIC_INFO_ATTR_FILE_PLAY_MODE)) {
|
||||
/* printf("MUSIC_INFO_ATTR_FILE_PLAY_MODE\n"); */
|
||||
u8 play_mode = music_player_get_repeat_mode();
|
||||
/* printf("play_mode = %d\n", play_mode); */
|
||||
play_mode = rcsp_repeat_mode_remap[play_mode];
|
||||
/* printf("remap = %d\n", play_mode); */
|
||||
offset += add_one_attr(buf, buf_size, offset, MUSIC_INFO_ATTR_FILE_PLAY_MODE, &play_mode, 1);
|
||||
}
|
||||
#endif
|
||||
return offset;
|
||||
}
|
||||
|
||||
//设置固件播放器行为
|
||||
bool rcsp_music_func_set(void *priv, u8 *data, u16 len)
|
||||
{
|
||||
/* printf("%s, %d\n", __func__, data[0]); */
|
||||
#if (TCFG_APP_MUSIC_EN && !RCSP_APP_MUSIC_EN)
|
||||
RCSP_UPDATE(MUSIC_FUNCTION_MASK,
|
||||
BIT(MUSIC_INFO_ATTR_STATUS) | BIT(MUSIC_INFO_ATTR_FILE_PLAY_MODE));
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
//停止音乐功能
|
||||
void rcsp_music_func_stop(void)
|
||||
{
|
||||
#if (RCSP_MSG_DISTRIBUTION_VER != RCSP_MSG_DISTRIBUTION_VER_VISUAL_CFG_TOOL)
|
||||
if (music_player_get_play_status() == FILE_DEC_STATUS_PLAY) {
|
||||
app_task_put_key_msg(KEY_MUSIC_PP, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
#ifndef __RCSP_MUSIC_FUNC_H__
|
||||
#define __RCSP_MUSIC_FUNC_H__
|
||||
#include "typedef.h"
|
||||
#include "app_config.h"
|
||||
#endif
|
||||
+911
@@ -0,0 +1,911 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".rcsp_rtc_func.data.bss")
|
||||
#pragma data_seg(".rcsp_rtc_func.data")
|
||||
#pragma const_seg(".rcsp_rtc_func.text.const")
|
||||
#pragma code_seg(".rcsp_rtc_func.text")
|
||||
#endif
|
||||
#include "app_config.h"
|
||||
#include "rcsp_rtc_func.h"
|
||||
#include "rcsp_device_status.h"
|
||||
#include "rcsp_config.h"
|
||||
#include "rcsp_event.h"
|
||||
#include "app_action.h"
|
||||
#include "rcsp_music_info_setting.h"
|
||||
#include "btstack/avctp_user.h"
|
||||
#include "JL_rcsp_packet.h"
|
||||
#include "key_event_deal.h"
|
||||
#include "app_msg.h"
|
||||
#include "rcsp_manage.h"
|
||||
#include "tone_player.h"
|
||||
#include "rcsp_browser.h"
|
||||
#include "rcsp_functions/rcsp_config.h"
|
||||
#include "JL_rcsp_api.h"
|
||||
#include "JL_rcsp_attr.h"
|
||||
|
||||
#if (RCSP_MODE && TCFG_RTC_ENABLE && RCSP_APP_RTC_EN)
|
||||
#include "rcsp_device_info_func_common.h"
|
||||
#if TCFG_APP_LINEIN_EN
|
||||
#include "linein/linein.h"
|
||||
#endif
|
||||
#include "alarm.h"
|
||||
#include "music/music_player.h"
|
||||
#include "music/general_player.h"
|
||||
|
||||
#define LOG_TAG_CONST RCSP
|
||||
#define LOG_TAG "[rtc]"
|
||||
#define LOG_ERROR_ENABLE
|
||||
#define LOG_DEBUG_ENABLE
|
||||
#define LOG_INFO_ENABLE
|
||||
#define LOG_CLI_ENABLE
|
||||
#include "debug.h"
|
||||
|
||||
#define RTC_INFO_ATTR_RTC_TIME (0)
|
||||
#define RTC_INFO_ATTR_RTC_ALRAM (1)
|
||||
#define RTC_INFO_ATTR_RTC_ALRAM_ACTIVE (2)
|
||||
#define RTC_INFO_ATTR_RTC_ALRAM_UNACTIVE (3)
|
||||
#define RTC_INFO_ATTR_RTC_ALRAM_STRUCTURE (4)
|
||||
#define RTC_INFO_ATTR_RTC_ALRAM_DEFAULT_RING (5)
|
||||
#define RTC_INFO_ATTR_RTC_ALRAM_RING_AUDITION (6)
|
||||
#define RTC_INFO_ATTR_RTC_ALARM_EX (7)
|
||||
|
||||
// 0是不停止
|
||||
#define RCSP_ALARM_RING_MAX 50
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct __APP_ALARM__ {
|
||||
u8 index;
|
||||
u8 sw;
|
||||
u8 mode;
|
||||
u8 bHour;
|
||||
u8 bMin;
|
||||
u8 name_len;
|
||||
} T_ALARM_APP, *PT_ALARM_APP;
|
||||
|
||||
typedef struct __APP_ALARM_EXTRA_DATA__ {
|
||||
u8 type;
|
||||
u8 dev;
|
||||
u32 clust;
|
||||
u8 ring_name_len;
|
||||
u8 ring_name[32];
|
||||
} T_ALARM_APP_EXTRA_DATA, *PT_ALARM_APP_EXTRA_DATA;
|
||||
|
||||
typedef struct __APP_ALARM_RING_AUDITION__ {
|
||||
u8 prev_app_mode;
|
||||
u8 ring_op;
|
||||
u8 ring_type;
|
||||
u8 ring_dev;
|
||||
u32 ring_clust;
|
||||
u32 ring_timeout;
|
||||
} T_ALARM_APP_RING_AUDITION, *PT_ALARM_APP_RING_AUDITION;
|
||||
|
||||
typedef struct __APP_ALARM_DATA_EX {
|
||||
u8 len;
|
||||
u8 index;
|
||||
u8 count;
|
||||
u8 interval;
|
||||
u8 alarmTime;
|
||||
} T_ALARM_APP_DATA_EX, *PT_ALARM_APP_DATA_EX;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
enum {
|
||||
E_ALARM_SET = 0x00,
|
||||
E_ALARM_DELETE,
|
||||
E_ALARM_UNACTIVE,
|
||||
};
|
||||
|
||||
enum {
|
||||
ALARM_IDEX_TONE_NUM_0 = 0,
|
||||
ALARM_IDEX_TONE_NUM_1 = 1,
|
||||
ALARM_IDEX_TONE_NUM_2 = 2,
|
||||
ALARM_IDEX_TONE_NUM_3 = 3,
|
||||
ALARM_IDEX_TONE_NUM_4 = 4,
|
||||
ALARM_IDEX_TONE_NUM_5 = 5,
|
||||
ALARM_IDEX_TONE_NUM_6 = 6,
|
||||
ALARM_IDEX_TONE_NUM_7 = 7,
|
||||
ALARM_IDEX_TONE_NUM_8 = 8,
|
||||
ALARM_IDEX_TONE_NUM_9 = 9,
|
||||
|
||||
ALARM_IDEX_TONE_MAX_NUM = 10,
|
||||
};
|
||||
static const char *default_ringtone_table[] = {
|
||||
[ALARM_IDEX_TONE_NUM_0] = "tone_zh/0.*",
|
||||
[ALARM_IDEX_TONE_NUM_1] = "tone_zh/1.*",
|
||||
[ALARM_IDEX_TONE_NUM_2] = "tone_zh/2.*",
|
||||
[ALARM_IDEX_TONE_NUM_3] = "tone_zh/3.*",
|
||||
[ALARM_IDEX_TONE_NUM_4] = "tone_zh/4.*",
|
||||
[ALARM_IDEX_TONE_NUM_5] = "tone_zh/5.*",
|
||||
[ALARM_IDEX_TONE_NUM_6] = "tone_zh/6.*",
|
||||
[ALARM_IDEX_TONE_NUM_7] = "tone_zh/7.*",
|
||||
[ALARM_IDEX_TONE_NUM_8] = "tone_zh/8.*",
|
||||
[ALARM_IDEX_TONE_NUM_9] = "tone_zh/9.*",
|
||||
};
|
||||
|
||||
static const char *default_ringtone_name_table[] = {
|
||||
[ALARM_IDEX_TONE_NUM_0] = "提示音0",
|
||||
[ALARM_IDEX_TONE_NUM_1] = "1",
|
||||
[ALARM_IDEX_TONE_NUM_2] = "2",
|
||||
[ALARM_IDEX_TONE_NUM_3] = "3",
|
||||
[ALARM_IDEX_TONE_NUM_4] = "4",
|
||||
[ALARM_IDEX_TONE_NUM_5] = "5",
|
||||
[ALARM_IDEX_TONE_NUM_6] = "6",
|
||||
[ALARM_IDEX_TONE_NUM_7] = "7",
|
||||
[ALARM_IDEX_TONE_NUM_8] = "8",
|
||||
[ALARM_IDEX_TONE_NUM_9] = "9",
|
||||
};
|
||||
|
||||
static void scan_enter(struct __dev *dev)
|
||||
{
|
||||
/* clock_add_set(SCAN_DISK_CLK); */
|
||||
}
|
||||
|
||||
static void scan_exit(struct __dev *dev)
|
||||
{
|
||||
/* clock_remove_set(SCAN_DISK_CLK); */
|
||||
}
|
||||
|
||||
static const struct __scan_callback scan_cb = {
|
||||
.enter = scan_enter,
|
||||
.exit = scan_exit,
|
||||
.scan_break = general_player_scandisk_break,
|
||||
};
|
||||
|
||||
static const u8 rtc_func_structure_flag = CUR_RTC_ALARM_MODE;
|
||||
static u8 rtc_ringing_prev_mode = -1;
|
||||
static T_ALARM_APP_RING_AUDITION g_ring_audition = {
|
||||
.prev_app_mode = -1,
|
||||
};
|
||||
|
||||
static u8 count = 0;
|
||||
static u8 flag = 0;
|
||||
static u8 count_flag = 0;
|
||||
static u16 rcsp_rtc_ex_timer = 0;
|
||||
static u16 rcsp_rtc_ex_timer1 = 0;
|
||||
u8 index_flag = -1;
|
||||
|
||||
extern void file_trans_idle_set(u8 file_trans_idle_flag);
|
||||
|
||||
static u8 rcsp_rtc_get_alarm_info(PT_ALARM_APP p, u8 index)
|
||||
{
|
||||
extern u8 alarm_get_info(PT_ALARM p, u8 index);
|
||||
u8 ret = 0;
|
||||
T_ALARM alarm_param;
|
||||
ret = alarm_get_info(&alarm_param, index);
|
||||
p->index = alarm_param.index;
|
||||
p->sw = alarm_param.sw;
|
||||
p->mode = alarm_param.mode;
|
||||
p->bHour = alarm_param.time.hour;
|
||||
p->bMin = alarm_param.time.min;
|
||||
p->name_len = alarm_param.name_len;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static u8 rcsp_rtc_get_alarm_total(void)
|
||||
{
|
||||
extern u8 alarm_get_total(void);
|
||||
u8 total = 0;
|
||||
total = alarm_get_total();
|
||||
return total;
|
||||
}
|
||||
|
||||
static u8 m_func_alarm_get_active_index(void)
|
||||
{
|
||||
extern u8 alarm_get_active_index(void);
|
||||
return alarm_get_active_index();
|
||||
}
|
||||
|
||||
static u8 m_func_alarm_name_get(u8 *p, u8 index)
|
||||
{
|
||||
extern u8 alarm_name_get(u8 * p, u8 index);
|
||||
return alarm_name_get(p, index);
|
||||
}
|
||||
|
||||
static void rcsp_rtc_update_time(RTC_TIME *p)
|
||||
{
|
||||
extern void rtc_update_time_api(struct sys_time * time);
|
||||
struct sys_time time = {0};
|
||||
time.year = p->dYear;
|
||||
time.month = p->bMonth;
|
||||
time.day = p->bDay;
|
||||
time.hour = p->bHour;
|
||||
time.min = p->bMin;
|
||||
time.sec = p->bSec;
|
||||
rtc_update_time_api(&time);
|
||||
}
|
||||
|
||||
static u8 mfunc_alarm_deal_data(PT_ALARM_APP p)
|
||||
{
|
||||
extern u8 alarm_add(PT_ALARM p, u8 index);
|
||||
T_ALARM tmp_alarm = {0};
|
||||
tmp_alarm.index = p->index;
|
||||
tmp_alarm.sw = p->sw;
|
||||
tmp_alarm.mode = p->mode;
|
||||
tmp_alarm.time.hour = p->bHour;
|
||||
tmp_alarm.time.min = p->bMin;
|
||||
tmp_alarm.name_len = p->name_len;
|
||||
return alarm_add(&tmp_alarm, p->index);
|
||||
}
|
||||
|
||||
static void m_func_alarm_name_set(u8 *p, u8 index, u8 len)
|
||||
{
|
||||
extern void alarm_name_set(u8 * p, u8 index, u8 len);
|
||||
alarm_name_set(p, index, len);
|
||||
}
|
||||
|
||||
static void m_func_alarm_delete(u8 index)
|
||||
{
|
||||
extern void alarm_delete(u8 index);
|
||||
alarm_delete(index);
|
||||
}
|
||||
|
||||
static u8 rcsp_rtc_alarm_extra_data_set(u8 index, u8 *p, u8 len)
|
||||
{
|
||||
u8 offset = 0;
|
||||
T_ALARM_APP_EXTRA_DATA data = {0};
|
||||
data.type = p[offset++];
|
||||
data.dev = p[offset++];
|
||||
data.clust = READ_BIG_U32(p + offset);
|
||||
offset += sizeof(data.clust);
|
||||
u8 data_len = p[offset++];
|
||||
data.ring_name_len = data_len > 32 ? 32 : data_len;
|
||||
memcpy(data.ring_name, p + offset, data.ring_name_len);
|
||||
offset += data.ring_name_len;
|
||||
log_info("ring_type : %d, ring_dev : %d, ring_clust : %d, ring_name_len : %d\n", data.type, data.dev, data.clust, data.ring_name_len);
|
||||
syscfg_write(VM_ALARM_RING_NAME_0 + index, &data, sizeof(data));
|
||||
return offset;
|
||||
}
|
||||
|
||||
static u8 rcsp_rtc_alarm_deal(void *priv, u8 *p, u8 len)
|
||||
{
|
||||
u8 ret = E_SUCCESS;
|
||||
u8 op = 0;
|
||||
u8 nums = 0;
|
||||
u8 index = 0;
|
||||
u8 *pTmp = 0;
|
||||
u8 i = 0;
|
||||
u8 ring_info_offset = 0;
|
||||
|
||||
T_ALARM_APP alarm_tab;
|
||||
|
||||
if (len >= 3) {
|
||||
op = p[2];
|
||||
log_info("op = %d\n", op);
|
||||
}
|
||||
if (len >= 4) {
|
||||
nums = p[3];
|
||||
log_info("nums = %d\n", nums);
|
||||
}
|
||||
if (nums > M_MAX_ALARM_NUMS) {
|
||||
log_error("nums is error\n");
|
||||
return E_FAILURE;
|
||||
}
|
||||
|
||||
switch (op) {
|
||||
case E_ALARM_SET:
|
||||
log_info("E_ALARM_SET\n");
|
||||
for (i = 0; i < nums; i++) {
|
||||
pTmp = &(p[4 + i * (6 + alarm_tab.name_len) + ring_info_offset]);
|
||||
alarm_tab.index = pTmp[0];
|
||||
alarm_tab.sw = pTmp[1];
|
||||
alarm_tab.mode = pTmp[2];
|
||||
alarm_tab.bHour = pTmp[3];
|
||||
alarm_tab.bMin = pTmp[4];
|
||||
alarm_tab.name_len = pTmp[5];
|
||||
|
||||
log_info("index : %d, sw : %d, mode : %d, hour : %d, min : %d, name_len : %d\n", pTmp[0], pTmp[1], pTmp[2], pTmp[3], pTmp[4], pTmp[5]);
|
||||
ret = mfunc_alarm_deal_data(&alarm_tab);
|
||||
if (E_SUCCESS == ret) {
|
||||
m_func_alarm_name_set(&(pTmp[6]), alarm_tab.index, alarm_tab.name_len);
|
||||
}
|
||||
|
||||
if (rtc_func_structure_flag) {
|
||||
ring_info_offset += rcsp_rtc_alarm_extra_data_set(alarm_tab.index, &pTmp[6 + alarm_tab.name_len], len);
|
||||
}
|
||||
}
|
||||
if (rcsp_rtc_ex_timer) {
|
||||
sys_timer_del(rcsp_rtc_ex_timer);
|
||||
rcsp_rtc_ex_timer = 0;
|
||||
}
|
||||
if (rcsp_rtc_ex_timer1) {
|
||||
sys_timer_del(rcsp_rtc_ex_timer1);
|
||||
rcsp_rtc_ex_timer1 = 0;
|
||||
}
|
||||
break;
|
||||
case E_ALARM_DELETE:
|
||||
log_info("E_ALARM_DELETE\n");
|
||||
for (i = 0; i < nums; i++) {
|
||||
index = p[4 + i];
|
||||
m_func_alarm_delete(index);
|
||||
}
|
||||
if (rcsp_rtc_ex_timer) {
|
||||
sys_timer_del(rcsp_rtc_ex_timer);
|
||||
rcsp_rtc_ex_timer = 0;
|
||||
}
|
||||
if (rcsp_rtc_ex_timer1) {
|
||||
sys_timer_del(rcsp_rtc_ex_timer1);
|
||||
rcsp_rtc_ex_timer1 = 0;
|
||||
}
|
||||
break;
|
||||
case E_ALARM_UNACTIVE:
|
||||
log_info("E_ALARM_UNACTIVE\n");
|
||||
index_flag = -1;
|
||||
alarm_stop(1);
|
||||
if (rcsp_rtc_ex_timer) {
|
||||
sys_timer_del(rcsp_rtc_ex_timer);
|
||||
rcsp_rtc_ex_timer = 0;
|
||||
}
|
||||
if (rcsp_rtc_ex_timer1) {
|
||||
sys_timer_del(rcsp_rtc_ex_timer1);
|
||||
rcsp_rtc_ex_timer1 = 0;
|
||||
}
|
||||
rcsp_device_status_update(RTC_FUNCTION_MASK, BIT(RTC_INFO_ATTR_RTC_ALRAM_UNACTIVE));
|
||||
break;
|
||||
default:
|
||||
log_warn("alarm no action!\n");
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static u8 rcsp_rtc_play_dev_ring(PT_ALARM_APP_RING_AUDITION ring_param)
|
||||
{
|
||||
u8 ret = (u8) - 1;
|
||||
#if TCFG_APP_MUSIC_EN
|
||||
log_info("neet to play the dev music, dev %s, clust %x\n", rcsp_browser_dev_remap(ring_param->ring_dev), ring_param->ring_clust);
|
||||
/* ret = general_play_by_sculst(rcsp_browser_dev_remap(ring_param->ring_dev), ring_param->ring_clust); */
|
||||
#endif /* #if TCFG_APP_MUSIC_EN */
|
||||
if (ret) {
|
||||
ring_param->ring_type = 0;
|
||||
ring_param->ring_clust = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static u8 rcsp_rtc_ring_audition_deal(PT_ALARM_APP_RING_AUDITION ring_param)
|
||||
{
|
||||
u8 ret = 0;
|
||||
log_info("ring stop");
|
||||
tone_player_stop();
|
||||
#if TCFG_APP_MUSIC_EN
|
||||
/* general_player_stop(0); */
|
||||
#endif /* #if TCFG_APP_MUSIC_EN */
|
||||
if (1 == ring_param->ring_op) {
|
||||
log_info("ringing\n");
|
||||
if (0 == ring_param->ring_type) {
|
||||
#if TCFG_APP_MUSIC_EN
|
||||
/* general_player_stop(0); */
|
||||
#endif /* #if TCFG_APP_MUSIC_EN */
|
||||
play_tone_file(default_ringtone_table[ring_param->ring_clust]);
|
||||
} else if (1 == ring_param->ring_type) {
|
||||
tone_player_stop();
|
||||
rcsp_rtc_play_dev_ring(ring_param);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static u8 rcsp_rtc_ring_audition_prepare(void *priv, u8 *data, u16 len)
|
||||
{
|
||||
u8 ret = 0;
|
||||
struct RcspModel *rcspModel = (struct RcspModel *)priv;
|
||||
g_ring_audition.ring_op = data[0];
|
||||
switch (g_ring_audition.ring_op) {
|
||||
case 0:
|
||||
// 回到原来的模式
|
||||
file_trans_idle_set(1);
|
||||
if ((u8) - 1 != g_ring_audition.prev_app_mode) {
|
||||
rcsp_msg_post(USER_MSG_RCSP_MODE_SWITCH, 2, (int)rcspModel, g_ring_audition.prev_app_mode);
|
||||
g_ring_audition.prev_app_mode = -1;
|
||||
} else {
|
||||
rcsp_rtc_ring_audition_deal(&g_ring_audition);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
file_trans_idle_set(0);
|
||||
g_ring_audition.ring_type = data[1];
|
||||
g_ring_audition.ring_dev = data[2];
|
||||
g_ring_audition.ring_clust = READ_BIG_U32(data + 3);
|
||||
// 进入rtc模式
|
||||
if (RTC_FUNCTION != rcspModel->cur_app_mode) {
|
||||
g_ring_audition.prev_app_mode = rcspModel->cur_app_mode;
|
||||
// 切换rtc模式
|
||||
rcsp_msg_post(USER_MSG_RCSP_MODE_SWITCH, 2, (int)rcspModel, RTC_FUNCTION_MASK);
|
||||
} else {
|
||||
rcsp_rtc_ring_audition_deal(&g_ring_audition);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
//设置固件rtc行为
|
||||
bool rcsp_rtc_func_set(void *priv, u8 *data, u16 len)
|
||||
{
|
||||
u8 ret = 0;
|
||||
u8 offset = 0;
|
||||
RTC_TIME time_info;
|
||||
while (offset < len) {
|
||||
u8 len_tmp = data[offset];
|
||||
u8 type = data[offset + 1];
|
||||
log_info("rtc info:\n");
|
||||
log_info_hexdump(&data[offset], len_tmp + 1);
|
||||
|
||||
switch (type) {
|
||||
case RTC_INFO_ATTR_RTC_TIME:
|
||||
log_info("RTC_INFO_ATTR_RTC_TIME\n");
|
||||
memcpy((u8 *)&time_info, data + 2, sizeof(time_info));
|
||||
time_info.dYear = app_htons(time_info.dYear);
|
||||
rcsp_rtc_update_time(&time_info);
|
||||
break;
|
||||
case RTC_INFO_ATTR_RTC_ALRAM:
|
||||
log_info("RTC_INFO_ATTR_RTC_ALRAM\n");
|
||||
log_info_hexdump(data, len);
|
||||
ret = rcsp_rtc_alarm_deal(priv, data, len);
|
||||
break;
|
||||
case RTC_INFO_ATTR_RTC_ALRAM_RING_AUDITION:
|
||||
log_info("RTC_INFO_ATTR_RTC_ALRAM_RING_AUDITION\n");
|
||||
ret = rcsp_rtc_ring_audition_prepare(priv, data + offset + 2, len);
|
||||
break;
|
||||
}
|
||||
offset += len_tmp + 1;
|
||||
}
|
||||
return (E_SUCCESS == ret);
|
||||
}
|
||||
|
||||
static bool rcsp_rtc_alarm_deal_ex(void *priv, u8 *data, u16 len)
|
||||
{
|
||||
u8 *tmp_data = data;
|
||||
|
||||
T_ALARM_APP_DATA_EX tmp = {0};
|
||||
tmp.len = tmp_data[0];
|
||||
tmp.index = tmp_data[1];
|
||||
tmp.count = tmp_data[2];
|
||||
tmp.interval = tmp_data[3];
|
||||
tmp.alarmTime = tmp_data[4];
|
||||
log_info_hexdump((u8 *)&tmp, sizeof(tmp));
|
||||
/* syscfg_write(VM_ALARM_EX0 + tmp.index, &tmp, sizeof(tmp)); */
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool rcsp_rtc_func_set_ex(void *priv, u8 *data, u16 len)
|
||||
{
|
||||
log_info("rtc_ex info:\n");
|
||||
log_info_hexdump(data, len);
|
||||
|
||||
return rcsp_rtc_alarm_deal_ex(priv, data, len);
|
||||
}
|
||||
|
||||
u16 rcsp_rtc_func_get_ex(void *priv, u8 *buf, u16 buf_size, u8 mask)
|
||||
{
|
||||
u16 offset = 0;
|
||||
u8 index = 0;
|
||||
T_ALARM_APP_DATA_EX data = {0};
|
||||
data.len = 0x04;
|
||||
data.count |= 0x81;//可设置
|
||||
data.interval |= 0x85;
|
||||
data.alarmTime |= 0x85;
|
||||
u16 size = sizeof(data);
|
||||
log_info("mask==%u", mask);
|
||||
do {
|
||||
if (mask & 0x01) {
|
||||
/* if (sizeof(data) != syscfg_read(VM_ALARM_EX0 + index, &data, size)) { */
|
||||
/* log_info("read VM_ALARM error\n"); */
|
||||
/* } */
|
||||
data.index = index;
|
||||
log_info_hexdump((u8 *)&data, sizeof(data));
|
||||
memcpy(&buf[offset], (u8 *)&data, size);
|
||||
offset = offset + size;
|
||||
}
|
||||
mask = mask >> 1;
|
||||
index++;
|
||||
} while (index < 5);
|
||||
log_info_hexdump(buf, buf_size);
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
static u8 rcsp_rtc_alarm_extra_data_get(u8 *p, u8 index, u8 is_conversion)
|
||||
{
|
||||
u8 offset = 0;
|
||||
T_ALARM_APP_EXTRA_DATA data = {0};
|
||||
if (sizeof(data) != syscfg_read(VM_ALARM_RING_NAME_0 + index, &data, sizeof(data))) {
|
||||
// 默认数据
|
||||
data.type = 0;
|
||||
data.dev = 0;
|
||||
data.clust = 0;
|
||||
memcpy(data.ring_name, default_ringtone_name_table[data.clust], strlen(default_ringtone_name_table[data.clust]) + 1);
|
||||
data.ring_name_len = strlen((const char *)data.ring_name) + 1;
|
||||
}
|
||||
p[offset++] = data.type;
|
||||
p[offset++] = data.dev;
|
||||
if (is_conversion) {
|
||||
WRITE_BIG_U32(p + offset, data.clust);
|
||||
} else {
|
||||
memcpy(p + offset, &data.clust, sizeof(data.clust));
|
||||
}
|
||||
offset += sizeof(data.clust);
|
||||
p[offset++] = data.ring_name_len;
|
||||
memcpy(p + offset, data.ring_name, data.ring_name_len);
|
||||
offset += data.ring_name_len;
|
||||
return offset;
|
||||
}
|
||||
|
||||
//获取固件rtc信息
|
||||
u32 rcsp_rtc_func_get(void *priv, u8 *buf, u16 buf_size, u32 mask)
|
||||
{
|
||||
u16 offset = 0;
|
||||
if (mask & BIT(RTC_INFO_ATTR_RTC_TIME)) {
|
||||
log_info("RTC_INFO_ATTR_RTC_TIME\n");
|
||||
RTC_TIME time_info = {
|
||||
.dYear = 2020,
|
||||
.bMonth = 5,
|
||||
.bDay = 15,
|
||||
.bHour = 19,
|
||||
.bMin = 55,
|
||||
.bSec = 40,
|
||||
};
|
||||
offset += add_one_attr(buf, buf_size, offset, RTC_INFO_ATTR_RTC_TIME, (u8 *)&time_info, sizeof(time_info));
|
||||
}
|
||||
|
||||
if (mask & BIT(RTC_INFO_ATTR_RTC_ALRAM)) {
|
||||
log_info("RTC_INFO_ATTR_RTC_ALRAM\n");
|
||||
u16 data_len = M_MAX_ALARM_NUMS * (sizeof(T_ALARM_APP) + M_MAX_ALARM_NAME_LEN + sizeof(T_ALARM_APP_EXTRA_DATA));
|
||||
u8 *alarm_data = zalloc(data_len);
|
||||
u8 total = 0;
|
||||
u8 index = 0;
|
||||
u8 name_len = 0;
|
||||
u8 *pTmp;
|
||||
u8 ret = 0;
|
||||
|
||||
data_len = 0;
|
||||
pTmp = alarm_data;
|
||||
|
||||
total = rcsp_rtc_get_alarm_total();
|
||||
log_info("total %d alarm!\n", total);
|
||||
|
||||
pTmp[0] = total;
|
||||
|
||||
pTmp++;
|
||||
data_len++;
|
||||
|
||||
for (index = 0; index < 5; index++) {
|
||||
ret = rcsp_rtc_get_alarm_info((PT_ALARM_APP)pTmp, index);
|
||||
log_info("alarm_tab.sw get==%u&&&", ((PT_ALARM_APP)pTmp)->sw);
|
||||
if (0 == ret) {
|
||||
pTmp += sizeof(T_ALARM_APP);
|
||||
data_len += sizeof(T_ALARM_APP);
|
||||
|
||||
name_len = m_func_alarm_name_get(pTmp, index);
|
||||
pTmp += name_len;
|
||||
data_len += name_len;
|
||||
|
||||
if (rtc_func_structure_flag) {
|
||||
name_len = rcsp_rtc_alarm_extra_data_get(pTmp, index, 1);
|
||||
pTmp += name_len;
|
||||
data_len += name_len;
|
||||
}
|
||||
|
||||
log_info("data_len = %d\n", data_len);
|
||||
}
|
||||
}
|
||||
|
||||
log_info_hexdump(alarm_data, data_len);
|
||||
offset += add_one_attr(buf, buf_size, offset, RTC_INFO_ATTR_RTC_ALRAM, alarm_data, data_len);
|
||||
if (alarm_data) {
|
||||
free(alarm_data);
|
||||
}
|
||||
}
|
||||
|
||||
if (mask & BIT(RTC_INFO_ATTR_RTC_ALRAM_ACTIVE)) {
|
||||
log_info("RTC_INFO_ATTR_RTC_ALRAM_ACTIVE\n");
|
||||
u8 index_mask = 0;
|
||||
index_mask = m_func_alarm_get_active_index();
|
||||
log_info("active alarm index : %d\n", index_mask);
|
||||
offset += add_one_attr(buf, buf_size, offset, RTC_INFO_ATTR_RTC_ALRAM_ACTIVE, (u8 *)&index_mask, sizeof(index_mask));
|
||||
|
||||
/* extern void alarm_update_info_after_isr(void); */
|
||||
/* alarm_update_info_after_isr(); */
|
||||
}
|
||||
|
||||
if (mask & BIT(RTC_INFO_ATTR_RTC_ALRAM_UNACTIVE)) {
|
||||
log_info("RTC_INFO_ATTR_RTC_ALRAM_UNACTIVE\n");
|
||||
u8 index_mask = 0;
|
||||
index_mask = m_func_alarm_get_active_index();
|
||||
log_info("active alarm index : %d\n", index_mask);
|
||||
offset += add_one_attr(buf, buf_size, offset, RTC_INFO_ATTR_RTC_ALRAM_UNACTIVE, (u8 *)&index_mask, sizeof(index_mask));
|
||||
}
|
||||
|
||||
if (mask & BIT(RTC_INFO_ATTR_RTC_ALRAM_STRUCTURE)) {
|
||||
log_info("RTC_INFO_ATTR_RTC_ALRAM_STRUCTURE\n");
|
||||
u8 rtc_structure_flag = rtc_func_structure_flag;
|
||||
offset += add_one_attr(buf, buf_size, offset, RTC_INFO_ATTR_RTC_ALRAM_STRUCTURE, &rtc_structure_flag, sizeof(rtc_structure_flag));
|
||||
}
|
||||
|
||||
if (mask & BIT(RTC_INFO_ATTR_RTC_ALRAM_DEFAULT_RING)) {
|
||||
log_info("RTC_INFO_ATTR_RTC_ALRAM_DEFAULT_RING\n");
|
||||
u8 i;
|
||||
// total + index
|
||||
u8 ring_info_len = 1 + ALARM_IDEX_TONE_MAX_NUM;
|
||||
for (i = 0; i < ALARM_IDEX_TONE_MAX_NUM; i++) {
|
||||
// name_len + name_data
|
||||
ring_info_len += 1 + strlen(default_ringtone_name_table[i]) + 1;
|
||||
}
|
||||
|
||||
u8 default_offset = 0;
|
||||
u8 ring_name_len = 0;
|
||||
u8 *default_ring = zalloc(ring_info_len);
|
||||
default_ring[default_offset++] = ALARM_IDEX_TONE_MAX_NUM;
|
||||
for (i = 0; i < ALARM_IDEX_TONE_MAX_NUM; i++) {
|
||||
ring_name_len = strlen(default_ringtone_name_table[i]) + 1;
|
||||
default_ring[default_offset++] = i;
|
||||
default_ring[default_offset++] = ring_name_len;
|
||||
if (ring_name_len) {
|
||||
memcpy(default_ring + default_offset, default_ringtone_name_table[i], ring_name_len);
|
||||
}
|
||||
default_offset += ring_name_len;
|
||||
}
|
||||
|
||||
offset += add_one_attr(buf, buf_size, offset, RTC_INFO_ATTR_RTC_ALRAM_DEFAULT_RING, default_ring, ring_info_len);
|
||||
if (default_ring) {
|
||||
free(default_ring);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (mask & BIT(RTC_INFO_ATTR_RTC_ALARM_EX)) {
|
||||
log_info("RTC_INFO_ATTR_RTC_ALARM_EX\n");
|
||||
u8 tmp[1] = {1};
|
||||
offset += add_one_attr(buf, buf_size, offset, RTC_INFO_ATTR_RTC_ALARM_EX, tmp, 1);
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
//rtc消息处理
|
||||
void rcsp_rtc_msg_deal(int msg)
|
||||
{
|
||||
struct RcspModel *rcspModel = rcsp_handle_get();
|
||||
if (rcspModel == NULL) {
|
||||
return ;
|
||||
}
|
||||
|
||||
switch (msg) {
|
||||
case (int)-1 :
|
||||
rtc_ringing_prev_mode = rcspModel->cur_app_mode;
|
||||
rcsp_device_status_update(RTC_FUNCTION_MASK, BIT(RTC_INFO_ATTR_RTC_ALRAM_ACTIVE));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void rtc_ring_stop_handle(void)
|
||||
{
|
||||
struct RcspModel *rcspModel = rcsp_handle_get();
|
||||
if (rcspModel == NULL) {
|
||||
return ;
|
||||
}
|
||||
rcsp_device_status_update(RTC_FUNCTION_MASK, BIT(RTC_INFO_ATTR_RTC_ALRAM_STRUCTURE) | BIT(RTC_INFO_ATTR_RTC_ALRAM_UNACTIVE));
|
||||
rcsp_device_status_update(RTC_FUNCTION_MASK, BIT(RTC_INFO_ATTR_RTC_ALRAM));
|
||||
if ((u8) - 1 != rtc_ringing_prev_mode) {
|
||||
#if RCSP_MODE == RCSP_MODE_SOUNDBOX
|
||||
extern void alarm_play_timer_del(void);
|
||||
alarm_play_timer_del();
|
||||
rcsp_msg_post(USER_MSG_RCSP_MODE_SWITCH, 2, (int)rcspModel, rtc_ringing_prev_mode);
|
||||
#endif
|
||||
rtc_ringing_prev_mode = -1;
|
||||
}
|
||||
}
|
||||
|
||||
u8 rtc_app_alarm_ring_play(u8 alarm_state);
|
||||
|
||||
void rcsp_rtc_ex_deal1(void *priv)
|
||||
{
|
||||
rtc_app_alarm_ring_play(1);
|
||||
}
|
||||
|
||||
void rcsp_rtc_ex_deal(void *priv)
|
||||
{
|
||||
rtc_ringing_prev_mode = 8;
|
||||
rcsp_rtc_ex_timer1 = sys_timer_add(NULL, rcsp_rtc_ex_deal1, 500);
|
||||
}
|
||||
|
||||
u8 rtc_get_active_index()
|
||||
{
|
||||
u8 index = -1;
|
||||
u8 cur_active_index = alarm_get_active_index();
|
||||
for (int i = 0; i < M_MAX_ALARM_NUMS; i++) {
|
||||
if (cur_active_index & BIT(i)) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
void rtc_sw_set(u8 sw, u8 index)
|
||||
{
|
||||
T_ALARM alarm_param;
|
||||
int ret = alarm_get_info(&alarm_param, index);
|
||||
if (ret) {
|
||||
return;
|
||||
}
|
||||
if (alarm_param.mode == 0) {
|
||||
alarm_param.sw = sw;
|
||||
alarm_add(&alarm_param, index);
|
||||
}
|
||||
}
|
||||
|
||||
void rtc_ring_sw_deal()
|
||||
{
|
||||
if (index_flag != (u8) - 1) {
|
||||
if (rcsp_rtc_ex_timer1) {
|
||||
sys_timer_del(rcsp_rtc_ex_timer1);
|
||||
rcsp_rtc_ex_timer1 = 0;
|
||||
}
|
||||
if (rcsp_rtc_ex_timer) {
|
||||
sys_timer_del(rcsp_rtc_ex_timer);
|
||||
rcsp_rtc_ex_timer = 0;
|
||||
}
|
||||
flag = 0;
|
||||
count_flag = 0;
|
||||
rtc_sw_set(0, index_flag);
|
||||
index_flag = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void ring_play_ex()
|
||||
{
|
||||
T_ALARM_APP_DATA_EX data = {0};
|
||||
data.len = 0x04;
|
||||
data.count |= 0x80;//可设置
|
||||
data.interval |= 0x80;
|
||||
data.alarmTime |= 0x80;
|
||||
u16 size = sizeof(data);
|
||||
index_flag = rtc_get_active_index();
|
||||
/* if (sizeof(data) != syscfg_read(VM_ALARM_EX0 + index_flag, &data, size)) { */
|
||||
/* log_info("read alarm error\n"); */
|
||||
/* } */
|
||||
log_info_hexdump((u8 *)&data, sizeof(data));
|
||||
if (count_flag == 0) {
|
||||
count = data.count & 0x0f;
|
||||
count_flag = 1;
|
||||
}
|
||||
|
||||
u8 interval = data.interval & 0x1f;
|
||||
u8 alarmTime = data.alarmTime & 0x1f;
|
||||
flag++;
|
||||
if (flag == alarmTime * 3) { //闹铃结束
|
||||
flag = 0;
|
||||
count--;
|
||||
/* log_info("count==================================================%d", count); */
|
||||
if (count) {
|
||||
rcsp_rtc_ex_timer = sys_timeout_add(NULL, rcsp_rtc_ex_deal, interval * 60 * 50);
|
||||
} else {
|
||||
count_flag = 0;
|
||||
rtc_sw_set(0, index_flag);
|
||||
index_flag = -1;
|
||||
}
|
||||
alarm_stop(0);
|
||||
if (rcsp_rtc_ex_timer1) {
|
||||
sys_timer_del(rcsp_rtc_ex_timer1);
|
||||
rcsp_rtc_ex_timer1 = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u8 rtc_app_alarm_ring_play(u8 alarm_state)
|
||||
{
|
||||
// 防止g_ring_audition成为临界资源,所以定义多一个局部变量
|
||||
static T_ALARM_APP_RING_AUDITION ringing_info = {0};
|
||||
u8 active_flag = m_func_alarm_get_active_index();
|
||||
u8 index;
|
||||
if (0 == active_flag && 0 == rtc_func_structure_flag) {
|
||||
return rtc_func_structure_flag;
|
||||
}
|
||||
|
||||
if (0 == alarm_state) {
|
||||
file_trans_idle_set(1);
|
||||
ringing_info.prev_app_mode = 0;
|
||||
ringing_info.ring_op = 0;
|
||||
ringing_info.ring_timeout = 0;
|
||||
rcsp_rtc_ring_audition_deal(&ringing_info);
|
||||
if (index_flag != (u8) - 1) {
|
||||
rtc_sw_set(1, index_flag);
|
||||
}
|
||||
rtc_ring_stop_handle();
|
||||
return rtc_func_structure_flag;
|
||||
} else {
|
||||
if ((u32) - 1 == (--ringing_info.ring_timeout)) {
|
||||
ringing_info.ring_timeout = RCSP_ALARM_RING_MAX;
|
||||
} else if (0 == ringing_info.ring_timeout) {
|
||||
#if RCSP_MODE == RCSP_MODE_SOUNDBOX
|
||||
ringing_info.ring_timeout = RCSP_ALARM_RING_MAX;
|
||||
ring_play_ex();
|
||||
#else
|
||||
alarm_stop(1);
|
||||
#endif
|
||||
return rtc_func_structure_flag;
|
||||
}
|
||||
}
|
||||
for (index = 0; index < (M_MAX_ALARM_NUMS + M_MAX_SNOOZE_ALARM_NUM); index++) {
|
||||
if (active_flag & BIT(index)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index < (M_MAX_ALARM_NUMS + M_MAX_SNOOZE_ALARM_NUM)) {
|
||||
if (0 == ringing_info.prev_app_mode) {
|
||||
// 响铃会进入始终模式,这个时全局变量prev_app_mode应该清除
|
||||
g_ring_audition.prev_app_mode = -1;
|
||||
// 暂停正在播放的提示音或设备音乐
|
||||
g_ring_audition.ring_op = 0;
|
||||
rcsp_rtc_ring_audition_deal(&g_ring_audition);
|
||||
|
||||
T_ALARM_APP_EXTRA_DATA data = {0};
|
||||
u32 data_len = 0;
|
||||
|
||||
rcsp_rtc_alarm_extra_data_get((u8 *)&data, index, 0);
|
||||
|
||||
ringing_info.prev_app_mode = -1;
|
||||
ringing_info.ring_op = 1;
|
||||
ringing_info.ring_type = data.type;
|
||||
ringing_info.ring_dev = data.dev;
|
||||
ringing_info.ring_clust = data.clust;
|
||||
}
|
||||
|
||||
if (get_rcsp_connect_status()) {
|
||||
rcsp_device_status_update(RTC_FUNCTION_MASK, BIT(RTC_INFO_ATTR_RTC_ALRAM_ACTIVE));
|
||||
}
|
||||
|
||||
#if TCFG_APP_MUSIC_EN
|
||||
file_trans_idle_set(0);
|
||||
if (ringing_info.ring_type) {
|
||||
if (!music_player_get_play_status()) {
|
||||
// 播放设备音乐
|
||||
log_info("ringing............................\n");
|
||||
rcsp_rtc_play_dev_ring(&ringing_info);
|
||||
}
|
||||
} else
|
||||
#endif /* #if TCFG_APP_MUSIC_EN */
|
||||
{
|
||||
play_tone_file(default_ringtone_table[ringing_info.ring_clust]);
|
||||
}
|
||||
}
|
||||
return rtc_func_structure_flag;
|
||||
}
|
||||
|
||||
u8 rcsp_rtc_ring_tone(void)
|
||||
{
|
||||
#if TCFG_APP_MUSIC_EN
|
||||
/* general_player_init((struct __scan_callback *)&scan_cb); */
|
||||
#endif /* #if TCFG_APP_MUSIC_EN */
|
||||
if ((u8) - 1 != g_ring_audition.prev_app_mode) {
|
||||
rcsp_rtc_ring_audition_deal(&g_ring_audition);
|
||||
} else if ((u8) - 1 == rtc_ringing_prev_mode) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void rcsp_rtc_mode_exit(void)
|
||||
{
|
||||
#if TCFG_APP_MUSIC_EN
|
||||
/* general_player_exit(); */
|
||||
#endif /* #if TCFG_APP_MUSIC_EN */
|
||||
struct RcspModel *rcspModel = rcsp_handle_get();
|
||||
if (rcspModel == NULL) {
|
||||
return ;
|
||||
}
|
||||
file_trans_idle_set(1);
|
||||
if ((u8) - 1 != rtc_ringing_prev_mode) {
|
||||
rtc_ringing_prev_mode = rcspModel->cur_app_mode;
|
||||
rtc_ring_stop_handle();
|
||||
}
|
||||
}
|
||||
|
||||
/*添加、删除闹钟后,更新闹钟信息给app*/
|
||||
void rcsp_update_alarm_info(void)
|
||||
{
|
||||
rcsp_device_status_update(RTC_FUNCTION_MASK, BIT(RTC_INFO_ATTR_RTC_ALRAM));
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
#ifndef __RCSP_RTC_FUNC_H__
|
||||
#define __RCSP_RTC_FUNC_H__
|
||||
#include "typedef.h"
|
||||
#include "app_config.h"
|
||||
|
||||
void rcsp_update_alarm_info(void);
|
||||
|
||||
#endif
|
||||
+466
@@ -0,0 +1,466 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".rcsp_device_feature.data.bss")
|
||||
#pragma data_seg(".rcsp_device_feature.data")
|
||||
#pragma const_seg(".rcsp_device_feature.text.const")
|
||||
#pragma code_seg(".rcsp_device_feature.text")
|
||||
#endif
|
||||
#include "rcsp_device_feature.h"
|
||||
#include "app_config.h"
|
||||
#include "rcsp_config.h"
|
||||
#include "btstack/avctp_user.h"
|
||||
#include "rcsp_event.h"
|
||||
#include "custom_cfg.h"
|
||||
#include "JL_rcsp_packet.h"
|
||||
#include "rcsp_extra_flash_opt.h"
|
||||
#include "rcsp_vol_setting.h"
|
||||
#include "rcsp_device_status.h"
|
||||
#include "JL_rcsp_api.h"
|
||||
#include "JL_rcsp_attr.h"
|
||||
#include "rcsp_functions/rcsp_config.h"
|
||||
#include "app_task.h"
|
||||
|
||||
#define LOG_TAG_CONST RCSP
|
||||
#define LOG_TAG "[dev feature]"
|
||||
#define LOG_ERROR_ENABLE
|
||||
#define LOG_DEBUG_ENABLE
|
||||
#define LOG_INFO_ENABLE
|
||||
#define LOG_CLI_ENABLE
|
||||
#include "debug.h"
|
||||
|
||||
#if (RCSP_MODE)
|
||||
#pragma pack(1)
|
||||
struct _SYS_info {
|
||||
u8 bat_lev;
|
||||
u8 sys_vol;
|
||||
u8 max_vol;
|
||||
u8 vol_is_sync;
|
||||
};
|
||||
|
||||
struct _EDR_info {
|
||||
u8 addr_buf[6];
|
||||
u8 profile;
|
||||
u8 state;
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
static u32 target_feature_attr_protocol_version(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset)
|
||||
{
|
||||
u32 rlen = 0;
|
||||
u8 ver = get_rcsp_version();
|
||||
rlen = add_one_attr(buf, buf_size, offset, attr, &ver, 1);
|
||||
return rlen;
|
||||
}
|
||||
static u32 target_feature_attr_sys_info(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset)
|
||||
{
|
||||
u32 rlen = 0;
|
||||
struct RcspModel *rcspModel = (struct RcspModel *)priv;
|
||||
if (rcspModel == NULL) {
|
||||
return 0;
|
||||
}
|
||||
struct _SYS_info sys_info = {0};
|
||||
#if (RCSP_MODE != RCSP_MODE_EARPHONE)
|
||||
extern u8 get_vbat_percent(void);
|
||||
sys_info.bat_lev = get_vbat_percent(); //get_battery_level() / 10;
|
||||
rcsp_get_max_vol_info(&sys_info.max_vol);
|
||||
rcsp_get_cur_dev_vol_info(&sys_info.sys_vol);
|
||||
#endif
|
||||
#if BT_SUPPORT_MUSIC_VOL_SYNC || TCFG_BT_VOL_SYNC_ENABLE
|
||||
extern u8 avctp_get_remote_vol_sync(bd_addr_t addr);
|
||||
if ((bt_get_current_remote_addr() && avctp_get_remote_vol_sync(bt_get_current_remote_addr())) || (0 == rcspModel->A_platform)) {
|
||||
sys_info.vol_is_sync |= BIT(0);
|
||||
rcspModel->dev_vol_sync = 1;
|
||||
}
|
||||
#endif
|
||||
rlen = add_one_attr(buf, buf_size, offset, attr, (u8 *)&sys_info, sizeof(sys_info));
|
||||
return rlen;
|
||||
}
|
||||
static u32 target_feature_attr_edr_addr(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset)
|
||||
{
|
||||
u32 rlen = 0;
|
||||
struct _EDR_info edr_info;
|
||||
extern const u8 *bt_get_mac_addr();
|
||||
u8 taddr_buf[6];
|
||||
memcpy(taddr_buf, bt_get_mac_addr(), 6);
|
||||
edr_info.addr_buf[0] = taddr_buf[5];
|
||||
edr_info.addr_buf[1] = taddr_buf[4];
|
||||
edr_info.addr_buf[2] = taddr_buf[3];
|
||||
edr_info.addr_buf[3] = taddr_buf[2];
|
||||
edr_info.addr_buf[4] = taddr_buf[1];
|
||||
edr_info.addr_buf[5] = taddr_buf[0];
|
||||
edr_info.profile = 0x0E;
|
||||
if (get_defalut_bt_channel_sel()) {
|
||||
edr_info.profile |= BIT(7);
|
||||
} else {
|
||||
edr_info.profile &= ~BIT(7);
|
||||
}
|
||||
if (bt_get_connect_status() == BT_STATUS_WAITINT_CONN) {
|
||||
edr_info.state = 0;
|
||||
} else {
|
||||
edr_info.state = 1;
|
||||
}
|
||||
rlen = add_one_attr(buf, buf_size, offset, attr, (u8 *)&edr_info, sizeof(struct _EDR_info));
|
||||
return rlen;
|
||||
}
|
||||
static u32 target_feature_attr_platform(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset)
|
||||
{
|
||||
u32 rlen = 0;
|
||||
return rlen;
|
||||
}
|
||||
static u32 target_feature_function_info(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset)
|
||||
{
|
||||
struct RcspModel *rcspModel = (struct RcspModel *)priv;
|
||||
if (rcspModel == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 rlen = 0;
|
||||
u8 tmp_buf[6] = {0};
|
||||
u32 func_mask = app_htonl(rcspModel->function_mask);
|
||||
#if RCSP_DEVICE_STATUS_ENABLE
|
||||
u8 cur_fun = rcsp_get_cur_mode(app_get_curr_task());
|
||||
#else
|
||||
u8 cur_fun = BT_FUNCTION;
|
||||
#endif
|
||||
memcpy(tmp_buf, (u8 *)&func_mask, 4);
|
||||
memcpy(tmp_buf + 4, &cur_fun, 1);
|
||||
memcpy(tmp_buf + 5, &rcspModel->music_icon_mask, 1);
|
||||
rlen = add_one_attr(buf, buf_size, offset, attr, tmp_buf, sizeof(tmp_buf));
|
||||
return rlen;
|
||||
}
|
||||
static u32 target_feature_dev_version(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset)
|
||||
{
|
||||
u32 rlen = 0;
|
||||
u16 ver = get_vid_pid_ver_from_cfg_file(GET_VER_FROM_EX_CFG);
|
||||
ver = READ_BIG_U16(&ver);
|
||||
rlen = add_one_attr(buf, buf_size, offset, attr, (u8 *)&ver, sizeof(ver));
|
||||
return rlen;
|
||||
}
|
||||
static u32 target_feature_sdk_type(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset)
|
||||
{
|
||||
struct RcspModel *rcspModel = (struct RcspModel *)priv;
|
||||
if (rcspModel == NULL) {
|
||||
return 0;
|
||||
}
|
||||
u32 rlen = 0;
|
||||
u8 sdk_type = rcspModel->sdk_type;
|
||||
rlen = add_one_attr(buf, buf_size, offset, attr, &sdk_type, 1);
|
||||
return rlen;
|
||||
}
|
||||
static u32 target_feature_uboot_version(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset)
|
||||
{
|
||||
u32 rlen = 0;
|
||||
u8 *uboot_ver_flag = (u8 *)"10";
|
||||
u8 uboot_version[2] = {uboot_ver_flag[0], uboot_ver_flag[1]};
|
||||
rlen = add_one_attr(buf, buf_size, offset, attr, uboot_version, sizeof(uboot_version));
|
||||
return rlen;
|
||||
}
|
||||
static u32 target_feature_ota_double_parition(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset)
|
||||
{
|
||||
struct RcspModel *rcspModel = (struct RcspModel *)priv;
|
||||
if (rcspModel == NULL) {
|
||||
return 0;
|
||||
}
|
||||
u32 rlen = 0;
|
||||
u8 double_partition_value;
|
||||
u8 ota_loader_need_download_flag;
|
||||
u8 update_channel_sel;
|
||||
u8 update_again_flag = 0;
|
||||
|
||||
if (rcspModel->ota_type) {
|
||||
double_partition_value = 0x1;
|
||||
ota_loader_need_download_flag = 0x00;
|
||||
} else {
|
||||
double_partition_value = 0x0;
|
||||
ota_loader_need_download_flag = 0x01;
|
||||
}
|
||||
update_channel_sel = 0x1; //强制使用BLE升级
|
||||
#if CONFIG_REUSABLE_RESERVE
|
||||
extern u32 reusable_area_flash_space(u32 * start_addr, u32 * free_space);
|
||||
if (reusable_area_flash_space(NULL, NULL)) {
|
||||
update_again_flag = 1;
|
||||
}
|
||||
#elif CONFIG_RESFS_UPDATE_ENABLE
|
||||
extern u32 resfs_area_flash_space(u32 * start_addr, u32 * free_space);
|
||||
if (resfs_area_flash_space(NULL, NULL)) {
|
||||
update_again_flag = 1;
|
||||
}
|
||||
#endif
|
||||
u8 update_param[4] = {
|
||||
double_partition_value,
|
||||
ota_loader_need_download_flag,
|
||||
update_channel_sel,
|
||||
update_again_flag,
|
||||
};
|
||||
|
||||
rlen = add_one_attr(buf, buf_size, offset, attr, (u8 *)update_param, sizeof(update_param));
|
||||
return rlen;
|
||||
}
|
||||
static u32 target_feature_ota_update_status(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset)
|
||||
{
|
||||
u32 rlen = 0;
|
||||
u8 update_status_value[3] = {0x0};
|
||||
#if CONFIG_REUSABLE_RESERVE
|
||||
extern u32 reusable_area_flash_space(u32 * start_addr, u32 * free_space);
|
||||
extern u8 reusable_update_app_flag_handle(u8 state, u8 opt);
|
||||
if (reusable_area_flash_space(NULL, NULL)) {
|
||||
update_status_value[2] = reusable_update_app_flag_handle(0, 0);
|
||||
}
|
||||
#elif CONFIG_RESFS_UPDATE_ENABLE
|
||||
extern u32 resfs_area_flash_space(u32 * start_addr, u32 * free_space);
|
||||
extern u8 resfs_update_app_flag_handle(u8 state, u8 opt);
|
||||
if (resfs_area_flash_space(NULL, NULL)) {
|
||||
update_status_value[2] = resfs_update_app_flag_handle(0, 0);
|
||||
}
|
||||
#endif
|
||||
#if JL_RCSP_EXTRA_FLASH_OPT
|
||||
if (0 == update_status_value[2]) {
|
||||
update_status_value[2] = rcsp_eflash_update_flag_get();
|
||||
}
|
||||
#endif
|
||||
rlen = add_one_attr(buf, buf_size, offset, attr, update_status_value, sizeof(update_status_value));
|
||||
return rlen;
|
||||
}
|
||||
static u32 target_feature_pid_vid(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset)
|
||||
{
|
||||
u32 rlen = 0;
|
||||
u16 pvid[2] = {0};
|
||||
pvid[0] = get_vid_pid_ver_from_cfg_file(GET_VID_FROM_EX_CFG);
|
||||
pvid[1] = get_vid_pid_ver_from_cfg_file(GET_PID_FROM_EX_CFG);
|
||||
pvid[0] = READ_BIG_U16(&pvid[0]);
|
||||
pvid[1] = READ_BIG_U16(&pvid[1]);
|
||||
rlen = add_one_attr(buf, buf_size, offset, attr, (u8 *)&pvid, sizeof(pvid));
|
||||
return rlen;
|
||||
}
|
||||
static u32 target_feature_authkey(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset)
|
||||
{
|
||||
u32 rlen = 0;
|
||||
#if VER_INFO_EXT_COUNT
|
||||
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);
|
||||
if (local_authkey_data && authkey_len) {
|
||||
log_info("%s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__);
|
||||
log_info_hexdump(local_authkey_data, authkey_len);
|
||||
rlen = add_one_attr(buf, buf_size, offset, attr, local_authkey_data, authkey_len);
|
||||
}
|
||||
#endif
|
||||
return rlen;
|
||||
}
|
||||
static u32 target_feature_procode(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset)
|
||||
{
|
||||
u32 rlen = 0;
|
||||
#if VER_INFO_EXT_COUNT
|
||||
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);
|
||||
if (local_procode_data && procode_len) {
|
||||
log_info("%s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__);
|
||||
log_info_hexdump(local_procode_data, procode_len);
|
||||
rlen = add_one_attr(buf, buf_size, offset, attr, local_procode_data, procode_len);
|
||||
}
|
||||
#endif
|
||||
return rlen;
|
||||
}
|
||||
static u32 target_feature_mtu(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset)
|
||||
{
|
||||
u32 rlen = 0;
|
||||
u16 rx_max_mtu = JL_packet_get_rx_max_mtu();
|
||||
u16 tx_max_mtu = JL_packet_get_tx_max_mtu();
|
||||
u8 t_buf[4];
|
||||
t_buf[0] = (tx_max_mtu >> 8) & 0xFF;
|
||||
t_buf[1] = tx_max_mtu & 0xFF;
|
||||
t_buf[2] = (rx_max_mtu >> 8) & 0xFF;
|
||||
t_buf[3] = rx_max_mtu & 0xFF;
|
||||
rlen = add_one_attr(buf, buf_size, offset, attr, t_buf, 4);
|
||||
return rlen;
|
||||
}
|
||||
static u32 target_feature_ble_only(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset)
|
||||
{
|
||||
u32 rlen = 0;
|
||||
|
||||
u8 taddr_buf[7];
|
||||
taddr_buf[0] = 0;
|
||||
#if CONFIG_USE_RANDOM_ADDRESS_ENABLE
|
||||
le_controller_get_random_mac(taddr_buf + 1);
|
||||
#else
|
||||
le_controller_get_mac(taddr_buf + 1);
|
||||
#endif
|
||||
for (u8 i = 0; i < (6 / 2); i++) {
|
||||
taddr_buf[i + 1] ^= taddr_buf[7 - i - 1];
|
||||
taddr_buf[7 - i - 1] ^= taddr_buf[i + 1];
|
||||
taddr_buf[i + 1] ^= taddr_buf[7 - i - 1];
|
||||
}
|
||||
|
||||
rlen = add_one_attr(buf, buf_size, offset, attr, taddr_buf, sizeof(taddr_buf));
|
||||
return rlen;
|
||||
}
|
||||
static u32 target_feature_bt_emitter_info(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset)
|
||||
{
|
||||
struct RcspModel *rcspModel = (struct RcspModel *)priv;
|
||||
if (rcspModel == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 rlen = 0;
|
||||
u8 val = 0;
|
||||
val |= rcspModel->emitter_en;
|
||||
val |= rcspModel->emitter_sw;
|
||||
log_info("val = %d, emitter_en = %d, emitter_sw = %d\n", val, rcspModel->emitter_en, rcspModel->emitter_sw);
|
||||
rlen = add_one_attr(buf, buf_size, offset, attr, &val, 1);
|
||||
return rlen;
|
||||
}
|
||||
|
||||
static u32 target_feature_md5_game_support(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset)
|
||||
{
|
||||
struct RcspModel *rcspModel = (struct RcspModel *)priv;
|
||||
if (rcspModel == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 rlen = 0;
|
||||
u8 ext_function_flag[2] = {0};
|
||||
u8 md5_support = 0;
|
||||
#if RCSP_MODE == RCSP_MODE_EARPHONE
|
||||
md5_support = UPDATE_MD5_ENABLE;
|
||||
#endif
|
||||
#if RCSP_MODE != RCSP_MODE_EARPHONE
|
||||
if (rcspModel->game_mode_en) {
|
||||
#else
|
||||
{
|
||||
#endif
|
||||
md5_support |= BIT(1);
|
||||
}
|
||||
if (rcspModel->find_dev_en) {
|
||||
md5_support |= BIT(2);
|
||||
}
|
||||
if (rcspModel->karaoke_en) {
|
||||
md5_support |= BIT(3);
|
||||
}
|
||||
if (rcspModel->sound_effects_disable) {
|
||||
md5_support |= BIT(4);
|
||||
}
|
||||
if (rcspModel->extra_flash_en) {
|
||||
md5_support |= BIT(5);
|
||||
}
|
||||
#if (RCSP_ADV_ANC_VOICE) || ((defined TCFG_CSC_BT_APP) && TCFG_CSC_BT_APP)
|
||||
md5_support |= BIT(6);
|
||||
#endif
|
||||
#if ((defined CONFIG_DEBUG_RECORD_ENABLE) && CONFIG_DEBUG_RECORD_ENABLE)
|
||||
md5_support |= BIT(7);
|
||||
#endif
|
||||
ext_function_flag[0] = md5_support;
|
||||
u8 ext_function_flag_byte1 = 0;
|
||||
#if (RCSP_ADV_ASSISTED_HEARING)
|
||||
ext_function_flag_byte1 |= BIT(0);
|
||||
#endif
|
||||
#if RCSP_ADV_ADAPTIVE_NOISE_REDUCTION
|
||||
ext_function_flag_byte1 |= BIT(1);
|
||||
#endif
|
||||
#if RCSP_ADV_AI_NO_PICK
|
||||
ext_function_flag_byte1 |= BIT(3);
|
||||
#endif
|
||||
#if RCSP_ADV_SCENE_NOISE_REDUCTION
|
||||
ext_function_flag_byte1 |= BIT(4);
|
||||
#endif
|
||||
#if RCSP_ADV_WIND_NOISE_DETECTION
|
||||
ext_function_flag_byte1 |= BIT(5);
|
||||
#endif
|
||||
#if RCSP_ADV_VOICE_ENHANCEMENT_MODE
|
||||
ext_function_flag_byte1 |= BIT(6);
|
||||
#endif
|
||||
#if TCFG_RCSP_DUAL_CONN_ENABLE
|
||||
// 是否一拖二
|
||||
ext_function_flag_byte1 |= BIT(7);
|
||||
#endif
|
||||
|
||||
#if RCSP_ADV_DEVICE_CONFIG_GET
|
||||
ext_function_flag_byte1 |= BIT(2);
|
||||
#endif
|
||||
|
||||
ext_function_flag[1] = ext_function_flag_byte1;
|
||||
|
||||
rlen = add_one_attr(buf, buf_size, offset, attr, ext_function_flag, 2);
|
||||
|
||||
return rlen;
|
||||
}
|
||||
|
||||
static u32 target_feature_file_transfer_info(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset)
|
||||
{
|
||||
struct RcspModel *rcspModel = (struct RcspModel *)priv;
|
||||
if (rcspModel == NULL) {
|
||||
return 0;
|
||||
}
|
||||
u32 config = 0;
|
||||
u8 send_buf[4] = {0};
|
||||
|
||||
if (rcspModel->file_transfer_mode) {
|
||||
config |= BIT(0);//文件传输是支持配置分包crc校验使能, 这里默认支持
|
||||
}
|
||||
|
||||
if (rcspModel->file_trans_back_mode) {
|
||||
config |= BIT(1); // 文件回传支持手机选择外挂flash还是sd卡
|
||||
}
|
||||
|
||||
if (rcspModel->file_simple_trans_mode) {
|
||||
config |= BIT(2);
|
||||
}
|
||||
|
||||
WRITE_BIG_U32(send_buf, config);
|
||||
|
||||
u32 rlen = add_one_attr(buf, buf_size, offset, attr, send_buf, sizeof(config));
|
||||
return rlen;
|
||||
}
|
||||
|
||||
static const attr_get_func target_feature_mask_get_tab[RCSP_DEVICE_FEATURE_ATTR_TYPE_MAX] = {
|
||||
[RCSP_DEVICE_FEATURE_ATTR_TYPE_PROTOCOL_VERSION ] = target_feature_attr_protocol_version,
|
||||
[RCSP_DEVICE_FEATURE_ATTR_TYPE_SYS_INFO ] = target_feature_attr_sys_info,
|
||||
[RCSP_DEVICE_FEATURE_ATTR_TYPE_EDR_ADDR ] = target_feature_attr_edr_addr,
|
||||
[RCSP_DEVICE_FEATURE_ATTR_TYPE_PLATFORM ] = target_feature_attr_platform,
|
||||
[RCSP_DEVICE_FEATURE_ATTR_TYPE_FUNCTION_INFO ] = target_feature_function_info,
|
||||
[RCSP_DEVICE_FEATURE_ATTR_TYPE_DEV_VERSION ] = target_feature_dev_version,
|
||||
[RCSP_DEVICE_FEATURE_ATTR_TYPE_SDK_TYPE ] = target_feature_sdk_type,
|
||||
[RCSP_DEVICE_FEATURE_ATTR_TYPE_UBOOT_VERSION ] = target_feature_uboot_version,
|
||||
[RCSP_DEVICE_FEATURE_ATTR_TYPE_DOUBLE_PARITION ] = target_feature_ota_double_parition,
|
||||
[RCSP_DEVICE_FEATURE_ATTR_TYPE_UPDATE_STATUS ] = target_feature_ota_update_status,
|
||||
[RCSP_DEVICE_FEATURE_ATTR_TYPE_DEV_VID_PID ] = target_feature_pid_vid,
|
||||
[RCSP_DEVICE_FEATURE_ATTR_TYPE_DEV_AUTHKEY ] = target_feature_authkey,
|
||||
[RCSP_DEVICE_FEATURE_ATTR_TYPE_DEV_PROCODE ] = target_feature_procode,
|
||||
[RCSP_DEVICE_FEATURE_ATTR_TYPE_DEV_MAX_MTU ] = target_feature_mtu,
|
||||
[RCSP_DEVICE_FEATURE_ATTR_TYPE_CONNECT_BLE_ONLY ] = target_feature_ble_only,
|
||||
[RCSP_DEVICE_FEATURE_ATTR_TYPE_BT_EMITTER_INFO ] = target_feature_bt_emitter_info,
|
||||
[RCSP_DEVICE_FEATURE_ATTR_TYPE_MD5_GAME_SUPPORT ] = target_feature_md5_game_support,
|
||||
[RCSP_DEVICE_FEATURE_ATTR_TYPE_FILE_TRANSFER_INFO] = target_feature_file_transfer_info,
|
||||
};
|
||||
|
||||
// 解析设备特征相关的rcsp数据
|
||||
u32 rcsp_target_feature_parse_packet(void *priv, u8 *buf, u16 buf_size, u32 mask)
|
||||
{
|
||||
log_info("rcsp_target_feature_parse_packet, mask = %x\n", mask);
|
||||
return attr_get(priv, buf, buf_size, target_feature_mask_get_tab, RCSP_DEVICE_FEATURE_ATTR_TYPE_MAX, mask);
|
||||
}
|
||||
|
||||
#if TCFG_CONNECTED_ENABLE || TCFG_BROADCAST_ENABLE
|
||||
static RCSP_LeAudioMode _leAudioMode = RCSP_LeAudioModeNone;
|
||||
/**
|
||||
* @brief 设置leaudio的状态
|
||||
*
|
||||
* #param RCSP_LeAudioMode
|
||||
*/
|
||||
void rcsp_set_LeAudio_mode(RCSP_LeAudioMode mode)
|
||||
{
|
||||
_leAudioMode = mode;
|
||||
}
|
||||
/**
|
||||
* @brief 获取leaudio的状态
|
||||
*
|
||||
* @result RCSP_LeAudioMode
|
||||
*/
|
||||
RCSP_LeAudioMode rcsp_get_LeAudio_mode()
|
||||
{
|
||||
return _leAudioMode;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif//RCSP_MODE
|
||||
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
#ifndef __RCSP_DEVICE_FEATURE_H__
|
||||
#define __RCSP_DEVICE_FEATURE_H__
|
||||
|
||||
#include "typedef.h"
|
||||
#include "app_config.h"
|
||||
|
||||
enum {
|
||||
RCSP_DEVICE_FEATURE_ATTR_TYPE_PROTOCOL_VERSION = 0,
|
||||
RCSP_DEVICE_FEATURE_ATTR_TYPE_SYS_INFO = 1,
|
||||
RCSP_DEVICE_FEATURE_ATTR_TYPE_EDR_ADDR = 2,
|
||||
RCSP_DEVICE_FEATURE_ATTR_TYPE_PLATFORM = 3,
|
||||
RCSP_DEVICE_FEATURE_ATTR_TYPE_FUNCTION_INFO = 4,
|
||||
RCSP_DEVICE_FEATURE_ATTR_TYPE_DEV_VERSION = 5,
|
||||
RCSP_DEVICE_FEATURE_ATTR_TYPE_SDK_TYPE = 6,
|
||||
RCSP_DEVICE_FEATURE_ATTR_TYPE_UBOOT_VERSION = 7,
|
||||
RCSP_DEVICE_FEATURE_ATTR_TYPE_DOUBLE_PARITION = 8,
|
||||
RCSP_DEVICE_FEATURE_ATTR_TYPE_UPDATE_STATUS = 9,
|
||||
RCSP_DEVICE_FEATURE_ATTR_TYPE_DEV_VID_PID = 10,
|
||||
RCSP_DEVICE_FEATURE_ATTR_TYPE_DEV_AUTHKEY = 11,
|
||||
RCSP_DEVICE_FEATURE_ATTR_TYPE_DEV_PROCODE = 12,
|
||||
RCSP_DEVICE_FEATURE_ATTR_TYPE_DEV_MAX_MTU = 13,
|
||||
RCSP_DEVICE_FEATURE_ATTR_TYPE_CONNECT_BLE_ONLY = 17,
|
||||
RCSP_DEVICE_FEATURE_ATTR_TYPE_BT_EMITTER_INFO = 18,
|
||||
RCSP_DEVICE_FEATURE_ATTR_TYPE_MD5_GAME_SUPPORT = 19,
|
||||
RCSP_DEVICE_FEATURE_ATTR_TYPE_FILE_TRANSFER_INFO = 21,
|
||||
RCSP_DEVICE_FEATURE_ATTR_TYPE_MAX,
|
||||
};
|
||||
|
||||
// le aduio mode
|
||||
typedef enum {
|
||||
RCSP_LeAudioModeNone = 0x00,
|
||||
RCSP_LeAudioModeBig = 0x01,
|
||||
RCSP_LeAudioModeCig = 0x02,
|
||||
} RCSP_LeAudioMode;
|
||||
/**
|
||||
* @brief 设置leaudio的状态
|
||||
*
|
||||
* #param RCSP_LeAudioMode
|
||||
*/
|
||||
void rcsp_set_LeAudio_mode(RCSP_LeAudioMode mode);
|
||||
/**
|
||||
* @brief 获取leaudio的状态
|
||||
*
|
||||
* @result RCSP_LeAudioMode
|
||||
*/
|
||||
RCSP_LeAudioMode rcsp_get_LeAudio_mode();
|
||||
|
||||
// 解析设备特征相关的rcsp数据
|
||||
u32 rcsp_target_feature_parse_packet(void *priv, u8 *buf, u16 buf_size, u32 mask);
|
||||
|
||||
#endif//__RCSP_DEVICE_FEATURE_H__
|
||||
|
||||
+1186
File diff suppressed because it is too large
Load Diff
+62
@@ -0,0 +1,62 @@
|
||||
#ifndef __RCSP_DEVICE_STATUS_H__
|
||||
#define __RCSP_DEVICE_STATUS_H__
|
||||
|
||||
#include "typedef.h"
|
||||
#include "app_config.h"
|
||||
|
||||
// 0x07、0x08使用以下枚举
|
||||
enum {
|
||||
RCSP_DEVICE_STATUS_ATTR_TYPE_BATTERY = 0,
|
||||
RCSP_DEVICE_STATUS_ATTR_TYPE_VOL = 1,
|
||||
RCSP_DEVICE_STATUS_ATTR_TYPE_DEV_INFO = 2,
|
||||
RCSP_DEVICE_STATUS_ATTR_TYPE_ERROR_STATS = 3,
|
||||
RCSP_DEVICE_STATUS_ATTR_TYPE_EQ_INFO = 4,
|
||||
RCSP_DEVICE_STATUS_ATTR_TYPE_BS_FILE_TYPE = 5,
|
||||
RCSP_DEVICE_STATUS_ATTR_TYPE_FUNCTION_MODE = 6,
|
||||
RCSP_DEVICE_STATUS_ATTR_TYPE_COLOR_LED_SETTING_INFO = 7,
|
||||
RCSP_DEVICE_STATUS_ATTR_TYPE_FMTX_FREQ = 8,
|
||||
RCSP_DEVICE_STATUS_ATTR_TYPE_BT_EMITTER_SW = 9,
|
||||
RCSP_DEVICE_STATUS_ATTR_TYPE_BT_EMITTER_CONNECT_STATES = 10,
|
||||
RCSP_DEVICE_STATUS_ATTR_TYPE_HIGH_LOW_SET = 11,
|
||||
RCSP_DEVICE_STATUS_ATTR_TYPE_PRE_FETCH_ALL_EQ_INFO = 12,
|
||||
RCSP_DEVICE_STATUS_ATTR_TYPE_ANC_VOICE = 13,
|
||||
RCSP_DEVICE_STATUS_ATTR_TYPE_FETCH_ALL_ANC_VOICE = 14,
|
||||
RCSP_DEVICE_STATUS_ATTR_TYPE_PHONE_SCO_STATE_INFO = 15,
|
||||
RCSP_DEVICE_STATUS_ATTR_TYPE_MISC_SETTING_INFO = 16,
|
||||
RCSP_DEVICE_STATUS_ATTR_TYPE_PRE_FETCH_KARAOKE_EQ_INFO = 17,
|
||||
RCSP_DEVICE_STATUS_ATTR_TYPE_KARAOKE_EQ_SETTING_INFO = 18,
|
||||
// 缺一个声卡功能19
|
||||
RCSP_DEVICE_STATUS_ATTR_TYPE_ASSISTED_HEARING = 20,
|
||||
RCSP_DEVICE_STATUS_ATTR_TYPE_ADAPTIVE_NOISE_REDUCTION = 21,
|
||||
RCSP_DEVICE_STATUS_ATTR_TYPE_AI_NO_PICK = 22,
|
||||
RCSP_DEVICE_STATUS_ATTR_TYPE_SCENE_NOISE_REDUCTION = 23,
|
||||
RCSP_DEVICE_STATUS_ATTR_TYPE_WIND_NOISE_DETECTION = 24,
|
||||
RCSP_DEVICE_STATUS_ATTR_TYPE_VOICE_ENHANCEMENT_MODE = 25,
|
||||
RCSP_DEVICE_STATUS_ATTR_TYPE_AI = 26,
|
||||
RCSP_DEVICE_STATUS_ATTR_TYPE_1T2 = 27,
|
||||
RCSP_DEVICE_STATUS_ATTR_TYPE_MAX,
|
||||
};
|
||||
|
||||
// 设备状态更改
|
||||
bool rcsp_device_status_cmd_set(void *priv, u8 OpCode, u8 OpCode_SN, u8 function, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr);
|
||||
// 设备状态更改
|
||||
bool rcsp_device_status_set(void *priv, u8 OpCode, u8 OpCode_SN, u8 function, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr);
|
||||
// 获取设备状态
|
||||
u32 rcsp_device_status_get(void *priv, u8 function, u8 *data, u16 len, u8 *buf, u16 buf_size);
|
||||
// 设备状态更改
|
||||
void rcsp_device_status_update(u8 function, u32 mask);
|
||||
// rcsp功能设置关闭
|
||||
void rcsp_device_status_setting_stop(void);
|
||||
// 获取当前模式
|
||||
u8 rcsp_get_cur_mode(u8 app_mode);
|
||||
|
||||
void function_change_inform(u8 app_mode, u8 ret);
|
||||
|
||||
#if (RCSP_MODE)
|
||||
#define RCSP_UPDATE rcsp_device_status_update
|
||||
#else
|
||||
#define RCSP_UPDATE(...)
|
||||
#endif//RCSP_MODE
|
||||
|
||||
#endif//__RCSP_DEVICE_STATUS_H__
|
||||
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".rcsp_extra_flash_cmd.data.bss")
|
||||
#pragma data_seg(".rcsp_extra_flash_cmd.data")
|
||||
#pragma const_seg(".rcsp_extra_flash_cmd.text.const")
|
||||
#pragma code_seg(".rcsp_extra_flash_cmd.text")
|
||||
#endif
|
||||
#include "app_config.h"
|
||||
#include "rcsp_config.h"
|
||||
#include "rcsp_device_status.h"
|
||||
#include "rcsp.h"
|
||||
#include "rcsp_event.h"
|
||||
#include "rcsp_extra_flash_cmd.h"
|
||||
#include "rcsp_extra_flash_opt.h"
|
||||
#include "ble_rcsp_server.h"
|
||||
#include "rcsp_setting_opt.h"
|
||||
#include "rcsp_manage.h"
|
||||
|
||||
#if (RCSP_MODE && JL_RCSP_EXTRA_FLASH_OPT)
|
||||
/* #define RCSP_DEBUG_EN */
|
||||
#ifdef RCSP_DEBUG_EN
|
||||
#define rcsp_putchar(x) putchar(x)
|
||||
#define rcsp_printf printf
|
||||
#define rcsp_printf_buf(x,len) put_buf(x,len)
|
||||
#else
|
||||
#define rcsp_putchar(...)
|
||||
#define rcsp_printf(...)
|
||||
#define rcsp_printf_buf(...)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief 外挂flash命令发送
|
||||
*
|
||||
* @param dire 非0:命令发送;0:命令回复
|
||||
*/
|
||||
int rcsp_extra_flash_opt_resp(u8 dire, u8 OpCode, u8 OpCode_SN, u8 *resp_data, u16 data_len)
|
||||
{
|
||||
if (OpCode) {
|
||||
if (dire) {
|
||||
JL_CMD_send(OpCode, resp_data, data_len, JL_NOT_NEED_RESPOND, 0, NULL);
|
||||
} else {
|
||||
JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, resp_data, data_len, 0, NULL);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//外挂flash命令处理
|
||||
int JL_rcsp_extra_flash_cmd_resp(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len)
|
||||
{
|
||||
rcsp_printf("JL_rcsp_extra_flash_cmd_resp, OpCode : %x, OpCode_SN : %x\n", OpCode, OpCode_SN);
|
||||
int ret = 0;
|
||||
struct RcspModel *rcspModel = (struct RcspModel *)priv;
|
||||
if (rcspModel == NULL) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
switch (OpCode) {
|
||||
case JL_OPCODE_EXTRA_FLASH_OPT: // 0x1A - 读写外部Flash命令
|
||||
ret = rcsp_extra_flash_opt(data, len, OpCode, OpCode_SN);
|
||||
if (ret < 0) {
|
||||
JL_CMD_response_send(OpCode, JL_PRO_STATUS_FAIL, OpCode_SN, NULL, 0, 0, NULL);
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
break;
|
||||
case JL_OPCODE_EXTRA_FLASH_INFO: // 0xD6 - 获取外部Flash信息
|
||||
ret = rcsp_get_extra_flash_info(priv, data);
|
||||
if (ret >= 0) {
|
||||
u16 data_len = (u16) ret;
|
||||
JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, data, data_len, 0, NULL);
|
||||
ret = rcsp_extra_flash_opt_start();
|
||||
} else {
|
||||
JL_CMD_response_send(OpCode, JL_PRO_STATUS_FAIL, OpCode_SN, NULL, 0, 0, NULL);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
//外挂flash不回复命令处理
|
||||
int JL_rcsp_extra_flash_cmd_no_resp(void *priv, u8 OpCode, u8 *data, u16 len)
|
||||
{
|
||||
rcsp_printf("JL_rcsp_extra_flash_cmd_no_resp, OpCode : %x\n", OpCode);
|
||||
int ret = 0;
|
||||
struct RcspModel *rcspModel = (struct RcspModel *)priv;
|
||||
if (rcspModel == NULL) {
|
||||
return ret;
|
||||
}
|
||||
switch (OpCode) {
|
||||
case JL_OPCODE_EXTRA_FLASH_OPT:
|
||||
ret = rcsp_extra_flash_opt(data, len, 0, 0);
|
||||
break;
|
||||
default:
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
#ifndef _RCSP_EXTRA_FLASH_CMD_H_
|
||||
#define _RCSP_EXTRA_FLASH_CMD_H_
|
||||
#include "typedef.h"
|
||||
#include "system/event.h"
|
||||
|
||||
//外挂flash命令处理
|
||||
int JL_rcsp_extra_flash_cmd_resp(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len);
|
||||
//外挂flash不回复命令处理
|
||||
int JL_rcsp_extra_flash_cmd_no_resp(void *priv, u8 OpCode, u8 *data, u16 len);
|
||||
|
||||
/**
|
||||
* @brief 外挂flash命令发送
|
||||
*
|
||||
* @param dire 非0:命令发送;0:命令回复
|
||||
*/
|
||||
int rcsp_extra_flash_opt_resp(u8 dire, u8 OpCode, u8 OpCode_SN, u8 *resp_data, u16 data_len);
|
||||
|
||||
#endif
|
||||
+2159
File diff suppressed because it is too large
Load Diff
+128
@@ -0,0 +1,128 @@
|
||||
#ifndef _RCSP_EXTRA_FLASH_OPT_H_
|
||||
#define _RCSP_EXTRA_FLASH_OPT_H_
|
||||
#include "typedef.h"
|
||||
#include "system/event.h"
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 外部flash操作函数
|
||||
@param param:数据, len:数据长度,OpCode:命令号,OpCode_SN:数据包序列号
|
||||
@return 0-成功,其他-失败
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int rcsp_extra_flash_opt(u8 *data, u16 len, u8 OpCode, u8 OpCode_SN);
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 填充表盘操作第一条命令的数据回复包
|
||||
@param resp_data:数据回复包
|
||||
@return 负数-失败,正数-数据长度
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int rcsp_get_extra_flash_info(void *priv, u8 *resp_data);
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 外部flash开始操作
|
||||
@param
|
||||
@return 0-成功,其他-失败
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int rcsp_extra_flash_opt_start(void);
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 外部flash结束操作
|
||||
@param
|
||||
@return
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void rcsp_extra_flash_opt_stop(void);
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 主动通知app当前表盘路径,用于表盘操作
|
||||
@param file_path:路径名,file_path_size:路名名长度
|
||||
@return
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void rcsp_extra_flash_opt_dial_nodify(void);
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 主动通知app当前表盘背景路径,用于表盘操作
|
||||
@return
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void rcsp_extra_flash_opt_dial_backgroud_nodify(void);
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 设置异常状态标志位
|
||||
@param eflash_state_type:标志位
|
||||
@return
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void rcsp_eflash_flag_set(u8 eflash_state_type);
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 获取异常状态标志位
|
||||
@param
|
||||
@return 1-处于异常,0-正常
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
u8 rcsp_eflash_flag_get(void);
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 获取升级异常状态标志位
|
||||
@param
|
||||
@return 1-处于异常,0-正常
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void rcsp_eflash_update_flag_set(u8 eflash_state_type);
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 获取升级异常状态标志位
|
||||
@param
|
||||
@return 1-处于异常,0-正常
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
u8 rcsp_eflash_update_flag_get(void);
|
||||
|
||||
// rcsp外挂flash初始化
|
||||
void rcsp_extra_flash_init(void);
|
||||
// rcsp外挂flash事件处理
|
||||
int rcsp_extra_flash_event_deal(int *msg);
|
||||
// rcsp外挂flash关闭
|
||||
void rcsp_extra_flash_close(void);
|
||||
|
||||
// rcsp外挂flash无线断开后操作
|
||||
void rcsp_extra_flash_disconnect_tips(u32 sec);
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 检查当前是否处于表盘升级状态
|
||||
@param param:状态标志
|
||||
@return true-处于升级状态,false-其他状态
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
bool rcsp_exflash_flash_opt_check(void *param);
|
||||
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 大文件传输表盘开始/结束操作
|
||||
@param 0 大文件续传
|
||||
1 新文件(不做任何操作)
|
||||
2 插入结束
|
||||
3 更新表盘与背景关系
|
||||
4 删除表盘
|
||||
-1 重命名前删除重名文件
|
||||
@return 0 成功
|
||||
1 写失败
|
||||
2 数据超出范围
|
||||
3 crc校验失败
|
||||
4 内存不足
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int rcsp_file_transfer_watch_opt(u8 flag, char *root_path);
|
||||
|
||||
|
||||
#endif
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".dev_format.data.bss")
|
||||
#pragma data_seg(".dev_format.data")
|
||||
#pragma const_seg(".dev_format.text.const")
|
||||
#pragma code_seg(".dev_format.text")
|
||||
#endif
|
||||
#include "dev_format.h"
|
||||
#include "rcsp.h"
|
||||
#include "dev_manager.h"
|
||||
|
||||
#if (RCSP_MODE && TCFG_DEV_MANAGER_ENABLE)
|
||||
#include "fs/fs.h"
|
||||
|
||||
enum {
|
||||
DEV_FORMAT_ERR_NONE = 0,
|
||||
DEV_FORMAT_ERR_OFFLINE,
|
||||
DEV_FORMAT_ERR_FAIL,
|
||||
};
|
||||
|
||||
void (*end_cbk)(void) = NULL;
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 设备格式化初始化(手机客户端发指令)
|
||||
@param
|
||||
@return 格式化完成回调
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void rcsp_dev_format_init(void (*end_callback)(void))
|
||||
{
|
||||
end_cbk = end_callback;
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 设备格式化退出
|
||||
@param
|
||||
@return 格式化完成回调
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void dev_format_close(void)
|
||||
{
|
||||
if (end_cbk) {
|
||||
end_cbk();
|
||||
}
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 设备格式化处理响应(手机客户端发指令)
|
||||
@param
|
||||
@return 格式化完成回调
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void rcsp_dev_format_start(u8 OpCode_SN, u8 *data, u16 len)
|
||||
{
|
||||
u8 reason = DEV_FORMAT_ERR_NONE;
|
||||
u32 dev_handle = READ_BIG_U32(data);
|
||||
char *logo = rcsp_browser_dev_remap(dev_handle);
|
||||
if (logo == NULL) {
|
||||
reason = DEV_FORMAT_ERR_FAIL ;
|
||||
JL_CMD_response_send(JL_OPCODE_DEVICE_FORMAT, JL_PRO_STATUS_FAIL, OpCode_SN, &reason, 1, 0, NULL);
|
||||
dev_format_close();
|
||||
return ;
|
||||
}
|
||||
|
||||
char *root_path = dev_manager_get_root_path_by_logo(logo);
|
||||
if (root_path) {
|
||||
|
||||
wdt_disable();
|
||||
int err = f_format(root_path, "fat", 0);
|
||||
wdt_enable();
|
||||
if (err) {
|
||||
reason = DEV_FORMAT_ERR_FAIL ;
|
||||
JL_CMD_response_send(JL_OPCODE_DEVICE_FORMAT, JL_PRO_STATUS_FAIL, OpCode_SN, &reason, 1, 0, NULL);
|
||||
} else {
|
||||
printf("dev format ok\n");
|
||||
JL_CMD_response_send(JL_OPCODE_DEVICE_FORMAT, JL_PRO_STATUS_SUCCESS, OpCode_SN, &reason, 1, 0, NULL);
|
||||
dev_format_close();
|
||||
return ;
|
||||
}
|
||||
} else {
|
||||
reason = DEV_FORMAT_ERR_OFFLINE ;
|
||||
JL_CMD_response_send(JL_OPCODE_DEVICE_FORMAT, JL_PRO_STATUS_FAIL, OpCode_SN, &reason, 1, 0, NULL);
|
||||
}
|
||||
dev_format_close();
|
||||
printf("dev format fail\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
|
||||
#ifndef __DEV_FORMAT_H__
|
||||
#define __DEV_FORMAT_H__
|
||||
|
||||
#include "typedef.h"
|
||||
#include "app_config.h"
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 设备格式化初始化(手机客户端发指令)
|
||||
@param
|
||||
@return 格式化完成回调
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void rcsp_dev_format_init(void (*end_callback)(void));
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 设备格式化处理响应(手机客户端发指令)
|
||||
@param
|
||||
@return 格式化完成回调
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void rcsp_dev_format_start(u8 OpCode_SN, u8 *data, u16 len);
|
||||
|
||||
#endif//__DEV_FORMAT_H__
|
||||
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".file_bluk_trans_prepare.data.bss")
|
||||
#pragma data_seg(".file_bluk_trans_prepare.data")
|
||||
#pragma const_seg(".file_bluk_trans_prepare.text.const")
|
||||
#pragma code_seg(".file_bluk_trans_prepare.text")
|
||||
#endif
|
||||
#include "file_bluk_trans_prepare.h"
|
||||
#include "rcsp.h"
|
||||
#include "system/includes.h"
|
||||
#include "file_operate/file_manager.h"
|
||||
|
||||
#if (RCSP_MODE && TCFG_DEV_MANAGER_ENABLE)
|
||||
enum {
|
||||
FILE_BLUK_TRANS_BEGIN,
|
||||
FILE_BLUK_TRANS_END = 0x80,
|
||||
FILE_BLUK_TRANS_CANCEL = 0x81,
|
||||
};
|
||||
|
||||
static void (*g_end_callback)(void);
|
||||
|
||||
//文件流传输准备
|
||||
void rcsp_file_bluk_trans_prepare(void *priv, u8 OpCode_SN, u8 *data, u16 len)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 offset = 0;
|
||||
u8 op = data[offset++];
|
||||
u8 resp_data[2] = {0};
|
||||
resp_data[0] = op;
|
||||
switch (op) {
|
||||
case FILE_BLUK_TRANS_BEGIN:
|
||||
app_rcsp_task_prepare(0, RCSP_TASK_ACTION_BLUK_TRANSFER, OpCode_SN);
|
||||
break;
|
||||
case FILE_BLUK_TRANS_CANCEL:
|
||||
case FILE_BLUK_TRANS_END:
|
||||
rcsp_file_bluk_trans_close(0);
|
||||
break;
|
||||
}
|
||||
JL_CMD_response_send(JL_OPCODE_FILE_BLUK_TRANSFER, JL_PRO_STATUS_SUCCESS, OpCode_SN, resp_data, sizeof(resp_data), 0, NULL);
|
||||
}
|
||||
|
||||
//文件流传输初始化
|
||||
void rcsp_file_bluk_trans_init(void (*end_callback)(void))
|
||||
{
|
||||
g_end_callback = end_callback;
|
||||
}
|
||||
|
||||
//文件流传输关闭
|
||||
void rcsp_file_bluk_trans_close(u8 dire)
|
||||
{
|
||||
if (g_end_callback) {
|
||||
g_end_callback();
|
||||
g_end_callback = NULL;
|
||||
if (dire) {
|
||||
u8 resp_data[2] = {FILE_BLUK_TRANS_CANCEL, 0};
|
||||
JL_CMD_send(JL_OPCODE_FILE_BLUK_TRANSFER, resp_data, sizeof(resp_data), 1, 0, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
#ifndef __FILE_BLUK_TRANS_PREPARE_H__
|
||||
#define __FILE_BLUK_TRANS_PREPARE_H__
|
||||
|
||||
#include "typedef.h"
|
||||
#include "app_config.h"
|
||||
|
||||
//文件流传输准备
|
||||
void rcsp_file_bluk_trans_prepare(void *priv, u8 OpCode_SN, u8 *data, u16 len);
|
||||
//文件流传输初始化
|
||||
void rcsp_file_bluk_trans_init(void (*end_callback)(void));
|
||||
//文件流传输关闭
|
||||
void rcsp_file_bluk_trans_close(u8 dire);
|
||||
|
||||
#endif
|
||||
+433
@@ -0,0 +1,433 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".file_delete.data.bss")
|
||||
#pragma data_seg(".file_delete.data")
|
||||
#pragma const_seg(".file_delete.text.const")
|
||||
#pragma code_seg(".file_delete.text")
|
||||
#endif
|
||||
#include "file_delete.h"
|
||||
#include "rcsp.h"
|
||||
#include "includes.h"
|
||||
#include "fs/fs.h"
|
||||
#include "dev_manager.h"
|
||||
#include "key_event_deal.h"
|
||||
/* #include "app_task.h" */
|
||||
/* #include "app_task.h" */
|
||||
#include "app_msg.h"
|
||||
#include "file_operate/file_manager.h"
|
||||
#include "rcsp_browser.h"
|
||||
#include "music/music_player.h"
|
||||
#include "rcsp_extra_flash_opt.h"
|
||||
|
||||
#if (RCSP_MODE && TCFG_DEV_MANAGER_ENABLE)
|
||||
#include "media/file_decoder.h"
|
||||
|
||||
#define LOG_TAG_CONST RCSP
|
||||
#define LOG_TAG "[file del]"
|
||||
#define LOG_ERROR_ENABLE
|
||||
#define LOG_DEBUG_ENABLE
|
||||
#define LOG_INFO_ENABLE
|
||||
#define LOG_CLI_ENABLE
|
||||
#include "debug.h"
|
||||
|
||||
#define FILE_DELELET_TIMEOUT (10*1000)
|
||||
|
||||
#define FILE_DEL_DEBUG_EN
|
||||
#ifdef FILE_DEL_DEBUG_EN
|
||||
#define file_del_printf log_info
|
||||
#else
|
||||
#define file_del_printf(...)
|
||||
#endif
|
||||
|
||||
struct __file_del {
|
||||
struct __dev *dev;//当前设备节点
|
||||
struct vfscan *fsn;//设备扫描句柄
|
||||
u8 scandisk_break;
|
||||
u8 busy;
|
||||
u16 timerout;
|
||||
void (*end_callback)(void);
|
||||
};
|
||||
|
||||
struct __file_del *file_d = NULL;
|
||||
#define __this file_d
|
||||
|
||||
///播放参数,文件扫描时用,文件后缀等
|
||||
static const char scan_parm[] = "-t"
|
||||
#if (WATCH_FILE_TO_FLASH)
|
||||
"ALL"
|
||||
#else // WATCH_FILE_TO_FLASH
|
||||
#if (TCFG_DEC_MP3_ENABLE)
|
||||
"MP1MP2MP3"
|
||||
#endif
|
||||
#if (TCFG_DEC_WMA_ENABLE)
|
||||
"WMA"
|
||||
#endif
|
||||
#if ( TCFG_DEC_WAV_ENABLE || TCFG_DEC_DTS_ENABLE)
|
||||
"WAVDTS"
|
||||
#endif
|
||||
#if (TCFG_DEC_FLAC_ENABLE)
|
||||
"FLA"
|
||||
#endif
|
||||
#if (TCFG_DEC_APE_ENABLE)
|
||||
"APE"
|
||||
#endif
|
||||
#if (TCFG_DEC_M4A_ENABLE)
|
||||
"M4AAAC"
|
||||
#endif
|
||||
#if (TCFG_DEC_M4A_ENABLE || TCFG_DEC_ALAC_ENABLE)
|
||||
"MP4"
|
||||
#endif
|
||||
#if (TCFG_DEC_AMR_ENABLE)
|
||||
"AMR"
|
||||
#endif
|
||||
#if (TCFG_DEC_DECRYPT_ENABLE)
|
||||
"SMP"
|
||||
#endif
|
||||
#if (TCFG_DEC_MIDI_ENABLE)
|
||||
"MID"
|
||||
#endif
|
||||
"TMP"
|
||||
#endif // WATCH_FILE_TO_FLASH
|
||||
" -sn -r"
|
||||
;
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件删除扫盘匹配文件过程系统消息获取处理接口
|
||||
@param
|
||||
@return 1:中断文件扫描处理, 0:继续扫盘
|
||||
@note 可以在这个函数内相应所需的消息事件
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int file_delete_scandisk_break(void)
|
||||
{
|
||||
///注意:
|
||||
///需要break fsn的事件, 请在这里拦截,
|
||||
int msg[32] = {0};
|
||||
struct sys_event *event = NULL;
|
||||
char *logo = NULL;
|
||||
char *evt_logo = NULL;
|
||||
#if (RCSP_MSG_DISTRIBUTION_VER != RCSP_MSG_DISTRIBUTION_VER_VISUAL_CFG_TOOL)
|
||||
app_task_get_msg(msg, ARRAY_SIZE(msg), 0);
|
||||
switch (msg[0]) {
|
||||
case APP_MSG_SYS_EVENT:
|
||||
event = (struct sys_event *)(&msg[1]);
|
||||
switch (event->type) {
|
||||
case SYS_DEVICE_EVENT:
|
||||
switch ((u32)event->arg) {
|
||||
case DRIVER_EVENT_FROM_SD0:
|
||||
case DRIVER_EVENT_FROM_SD1:
|
||||
case DRIVER_EVENT_FROM_SD2:
|
||||
evt_logo = (char *)event->u.dev.value;
|
||||
case DEVICE_EVENT_FROM_OTG:
|
||||
if ((u32)event->arg == DEVICE_EVENT_FROM_OTG) {
|
||||
evt_logo = (char *)"udisk0";
|
||||
}
|
||||
///设备上下线底层推出的设备逻辑盘符是跟跟音乐设备一致的(音乐/录音设备, 详细看接口注释)
|
||||
logo = dev_manager_get_phy_logo(__this->dev);
|
||||
///响应设备插拔打断
|
||||
if (event->u.dev.event == DEVICE_EVENT_OUT) {
|
||||
log_i("__func__ = %s logo=%s evt_logo=%s \n", __FUNCTION__, logo, evt_logo);
|
||||
if (logo && evt_logo && (0 == strcmp(logo, evt_logo))) {
|
||||
///相同的设备才响应
|
||||
__this->scandisk_break = 1;
|
||||
}
|
||||
} else {
|
||||
///响应新设备上线
|
||||
__this->scandisk_break = 1;
|
||||
}
|
||||
if (__this->scandisk_break == 0) {
|
||||
log_i("__func__ = %s DEVICE_EVENT_OUT TODO\n", __FUNCTION__);
|
||||
#if RCSP_MODE != RCSP_MODE_EARPHONE
|
||||
dev_status_event_filter(event);
|
||||
#endif
|
||||
log_i("__func__ = %s DEVICE_EVENT_OUT OK\n", __FUNCTION__);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SYS_BT_EVENT:
|
||||
if (bt_background_event_handler_filter(event)) {
|
||||
__this->scandisk_break = 1;
|
||||
}
|
||||
break;
|
||||
case SYS_KEY_EVENT:
|
||||
switch (event->u.key.event) {
|
||||
case KEY_CHANGE_MODE:
|
||||
///响应切换模式事件
|
||||
__this->scandisk_break = 1;
|
||||
break;
|
||||
}
|
||||
if (__this->scandisk_break) {
|
||||
app_task_put_key_msg(event->u.key.event, (int)event->u.key.value);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (__this->scandisk_break) {
|
||||
///查询到需要打断的事件, 返回1, 并且重新推送一次该事件,跑主循环处理流程
|
||||
#if (RCSP_MSG_DISTRIBUTION_VER != RCSP_MSG_DISTRIBUTION_VER_VISUAL_CFG_TOOL)
|
||||
file_del_printf("\n--func=%s, line=%d\n", __FUNCTION__, __LINE__);
|
||||
sys_event_notify(event);
|
||||
file_del_printf("scandisk_break!!!!!!\n");
|
||||
#endif
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void scan_enter(struct __dev *dev)
|
||||
{
|
||||
__this->busy = 1;
|
||||
#if (RCSP_MSG_DISTRIBUTION_VER != RCSP_MSG_DISTRIBUTION_VER_VISUAL_CFG_TOOL)
|
||||
clock_add_set(SCAN_DISK_CLK);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void scan_exit(struct __dev *dev)
|
||||
{
|
||||
#if (RCSP_MSG_DISTRIBUTION_VER != RCSP_MSG_DISTRIBUTION_VER_VISUAL_CFG_TOOL)
|
||||
clock_remove_set(SCAN_DISK_CLK);
|
||||
#endif
|
||||
__this->busy = 0;
|
||||
}
|
||||
|
||||
static const struct __scan_callback scan_cb = {
|
||||
.enter = scan_enter,
|
||||
.exit = scan_exit,
|
||||
.scan_break = file_delete_scandisk_break,
|
||||
};
|
||||
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件删除超时处理
|
||||
@param
|
||||
@return
|
||||
@note 这里是等待手机删除命令超时(即没有等到删除命令)
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void file_delete_timeout(void *p)
|
||||
{
|
||||
//批量删除超时, 退出删除流程
|
||||
if (__this && __this->timerout) {
|
||||
file_del_printf("file_delete_timeout !!\n");
|
||||
rcsp_file_delete_end();
|
||||
}
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件删除结束处理
|
||||
@param
|
||||
@return
|
||||
@note 释放资源
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void rcsp_file_delete_end(void)
|
||||
{
|
||||
if (__this) {
|
||||
if (__this->fsn) {
|
||||
fscan_release(__this->fsn);
|
||||
}
|
||||
if (__this->timerout) {
|
||||
sys_timeout_del(__this->timerout);
|
||||
__this->timerout = 0;
|
||||
}
|
||||
if (__this->end_callback) {
|
||||
__this->end_callback();
|
||||
}
|
||||
free(__this);
|
||||
__this = NULL;
|
||||
file_del_printf("rcsp_file_delete_end\n");
|
||||
}
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件删除开始处理
|
||||
@param OpCode_SN:命名包的sn码, 命名回复时用到
|
||||
@return
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void file_transfer_watch_opt(u32 dev_handle, u8 flag)
|
||||
{
|
||||
if (RCSPDevMapFLASH == dev_handle
|
||||
|| RCSPDevMapFLASH_2 == dev_handle) {
|
||||
char *root_path = NULL;
|
||||
if (__this->dev) {
|
||||
root_path = dev_manager_get_root_path(__this->dev);
|
||||
}
|
||||
#if JL_RCSP_EXTRA_FLASH_OPT
|
||||
rcsp_file_transfer_watch_opt(flag, root_path);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static int file_delete_func(FILE *file)
|
||||
{
|
||||
int err = 0;
|
||||
if (NULL == file) {
|
||||
err = -1;
|
||||
goto __file_delete_func_end;
|
||||
}
|
||||
#if (RCSP_MSG_DISTRIBUTION_VER == RCSP_MSG_DISTRIBUTION_VER_VISUAL_CFG_TOOL)
|
||||
// RCSP TODO:
|
||||
log_info("RCSP TODO!!!");
|
||||
#else
|
||||
int music_state = music_player_get_play_status();
|
||||
if (FILE_DEC_STATUS_PLAY == music_state) {
|
||||
app_task_put_key_msg(KEY_MUSIC_PP, 0);
|
||||
}
|
||||
#endif
|
||||
err = fdelete(file);
|
||||
if (err) {
|
||||
log_error("[%s, %d] fail!!, replay cur file\n", __FUNCTION__, __LINE__);
|
||||
err = -1;
|
||||
goto __file_delete_func_end;
|
||||
} else {
|
||||
#if (RCSP_MSG_DISTRIBUTION_VER == RCSP_MSG_DISTRIBUTION_VER_VISUAL_CFG_TOOL)
|
||||
// RCSP TODO:
|
||||
log_info("RCSP TODO!!!");
|
||||
#else
|
||||
log_info("[%s, %d] ok, play next file\n", __FUNCTION__, __LINE__);
|
||||
if (FILE_DEC_STATUS_PLAY == music_state) {
|
||||
err = app_task_put_key_msg(KEY_MUSIC_PP, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
__file_delete_func_end:
|
||||
return err;
|
||||
}
|
||||
|
||||
//文件删除命令处理
|
||||
void rcsp_file_delete_start(u8 OpCode_SN, u8 *data, u16 len)
|
||||
{
|
||||
FILE *file = NULL;
|
||||
u8 reason = 0;
|
||||
u8 last = data[0];
|
||||
u32 dev_handle = READ_BIG_U32(data + 1);
|
||||
u8 type = data[5];
|
||||
u32 sclust = READ_BIG_U32(data + 6);
|
||||
file_del_printf("last = %d,dev_handle = %d,sclust = %d,type = %d,\n", last, dev_handle, sclust, type);
|
||||
|
||||
char *logo = rcsp_browser_dev_remap(dev_handle);
|
||||
if (logo == NULL) {
|
||||
goto __err;
|
||||
}
|
||||
|
||||
if (__this == NULL) {
|
||||
__this = zalloc(sizeof(struct __file_del));
|
||||
if (__this == NULL) {
|
||||
goto __err;
|
||||
}
|
||||
}
|
||||
|
||||
if (__this->timerout) {
|
||||
sys_timeout_del(__this->timerout);
|
||||
__this->timerout = 0;
|
||||
}
|
||||
|
||||
if (__this->fsn == NULL) {
|
||||
__this->dev = dev_manager_find_spec(logo, 0);
|
||||
|
||||
if (!__this->dev) {
|
||||
free(__this);
|
||||
__this = NULL;
|
||||
goto __err;
|
||||
}
|
||||
|
||||
if (__this->dev) {
|
||||
__this->fsn = file_manager_scan_disk(__this->dev, NULL, scan_parm, 0, (struct __scan_callback *)&scan_cb);
|
||||
if (__this->fsn == NULL) {
|
||||
free(__this);
|
||||
__this = NULL;
|
||||
goto __err;
|
||||
}
|
||||
file_del_printf("%s, fscan ok\n", __FUNCTION__);
|
||||
}
|
||||
} else {
|
||||
file_del_printf("%s, fscan aready\n", __FUNCTION__);
|
||||
if (__this->busy) {
|
||||
//正在执行删除, 回复APP繁忙
|
||||
log_error("file delete busy\n");
|
||||
JL_CMD_response_send(JL_OPCODE_FILE_DELETE, JL_PRO_STATUS_BUSY, OpCode_SN, NULL, 0, 0, NULL);
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
||||
file = file_manager_select(__this->dev, __this->fsn, FSEL_BY_SCLUST, sclust, (struct __scan_callback *)&scan_cb);//根据文件簇号查找断点文件
|
||||
if (file) {
|
||||
#if (defined TCFG_CSC_BT_APP) && TCFG_CSC_BT_APP
|
||||
extern void rcsp_common_info_del_wallpaper(FILE * flie);
|
||||
rcsp_common_info_del_wallpaper(file);
|
||||
#endif
|
||||
file_delete_func(file);
|
||||
/* fdelete(file); */
|
||||
file_del_printf("delete file ok!!\n");
|
||||
JL_CMD_response_send(JL_OPCODE_FILE_DELETE, JL_PRO_STATUS_SUCCESS, OpCode_SN, NULL, 0, 0, NULL);
|
||||
if (last == 0) {
|
||||
if (__this->timerout == 0) {
|
||||
__this->timerout = sys_timeout_add(NULL, file_delete_timeout, FILE_DELELET_TIMEOUT);
|
||||
} else {
|
||||
sys_timer_modify(__this->timerout, FILE_DELELET_TIMEOUT);
|
||||
}
|
||||
//批量删除, 还没有删除完毕, 等待继续删除
|
||||
file_del_printf("wait delete file more\n");
|
||||
return;
|
||||
}
|
||||
|
||||
file_transfer_watch_opt(dev_handle, 4);
|
||||
} else {
|
||||
file_del_printf("file delete, no this file\n");
|
||||
JL_CMD_response_send(JL_OPCODE_FILE_DELETE, JL_PRO_STATUS_PARAM_ERR, OpCode_SN, NULL, 0, 0, NULL);
|
||||
}
|
||||
rcsp_file_delete_end();
|
||||
return ;
|
||||
|
||||
__err:
|
||||
JL_CMD_response_send(JL_OPCODE_FILE_DELETE, JL_PRO_STATUS_FAIL, OpCode_SN, NULL, 0, 0, NULL);
|
||||
rcsp_file_delete_end();
|
||||
}
|
||||
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件删除初始化
|
||||
@param end_callback:文件删除结束回调处理
|
||||
@return
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void rcsp_file_delete_init(void (*end_callback)(void))
|
||||
{
|
||||
if (__this) {
|
||||
log_error("rcsp_file_delete_init aready err!!\n");
|
||||
return ;
|
||||
}
|
||||
__this = zalloc(sizeof(struct __file_del));
|
||||
if (__this == NULL) {
|
||||
log_error("rcsp_file_delete_init fail\n");
|
||||
if (end_callback) {
|
||||
end_callback();
|
||||
}
|
||||
return ;
|
||||
}
|
||||
__this->end_callback = end_callback;
|
||||
//启动定时器, 防止APP后续没有发执行删除的命令过来, 可以超时退出
|
||||
__this->timerout = sys_timeout_add(NULL, file_delete_timeout, 2000);
|
||||
}
|
||||
|
||||
#define PHONE_BOOK_PATH "storage/sd1/C/DOWNLOAD/call.txt"
|
||||
void rcsp_file_delete_one_file(u8 OpCode_SN, u8 *data, u16 len)
|
||||
{
|
||||
FILE *file = fopen(PHONE_BOOK_PATH, "r");
|
||||
if (file) {
|
||||
fdelete(file);
|
||||
}
|
||||
JL_CMD_response_send(JL_OPCODE_ONE_FILE_DELETE, JL_PRO_STATUS_SUCCESS, OpCode_SN, NULL, 0, 0, NULL);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
#ifndef __FILE_DELETE_H__
|
||||
#define __FILE_DELETE_H__
|
||||
|
||||
#include "typedef.h"
|
||||
#include "app_config.h"
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件删除初始化
|
||||
@param end_callback:文件删除结束回调处理
|
||||
@return
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void rcsp_file_delete_init(void (*end_callback)(void));
|
||||
//文件删除命令处理
|
||||
void rcsp_file_delete_start(u8 OpCode_SN, u8 *data, u16 len);
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件删除结束处理
|
||||
@param
|
||||
@return
|
||||
@note 释放资源
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void rcsp_file_delete_end(void);
|
||||
// 删除一个文件
|
||||
void rcsp_file_delete_one_file(u8 OpCode_SN, u8 *data, u16 len);
|
||||
|
||||
#endif//__FILE_DELETE_H__
|
||||
|
||||
+415
@@ -0,0 +1,415 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".file_simple_transfer.data.bss")
|
||||
#pragma data_seg(".file_simple_transfer.data")
|
||||
#pragma const_seg(".file_simple_transfer.text.const")
|
||||
#pragma code_seg(".file_simple_transfer.text")
|
||||
#endif
|
||||
#include "rcsp_config.h"
|
||||
#include "file_simple_transfer.h"
|
||||
#include "system/includes.h"
|
||||
#include "fs/fs.h"
|
||||
#include "dev_manager.h"
|
||||
#include "JL_rcsp_protocol.h"
|
||||
|
||||
#if (RCSP_MODE && TCFG_DEV_MANAGER_ENABLE && JL_RCSP_SIMPLE_TRANSFER)
|
||||
|
||||
#define FILE_SIMPLE_TRANSFER_VERSION 0
|
||||
|
||||
static rcsp_simple_trans_opt *g_rcsp_simple_trans_opt = NULL;
|
||||
#define __this g_rcsp_simple_trans_opt
|
||||
|
||||
enum {
|
||||
FILE_SIMPLE_OPT_QUERY,
|
||||
FILE_SIMPLE_OPT_READ,
|
||||
FILE_SIMPLE_OPT_INSERT,
|
||||
FILE_SIMPLE_OPT_UPDATE,
|
||||
FILE_SIMPLE_OPT_DELETE,
|
||||
};
|
||||
|
||||
|
||||
static int file_simple_opt_get_id_table(u8 type, u8 *data[], u8 reserved_len)
|
||||
{
|
||||
int data_len = 0;
|
||||
if (NULL == __this) {
|
||||
printf("err : please specify the simple file opt interface\n");
|
||||
goto __file_simple_opt_get_id_table_end;
|
||||
}
|
||||
if (!__this->get_id_table_len || !__this->get_id_table) {
|
||||
printf("err : get_id_table_len or get_id_table interface is NULL\n");
|
||||
goto __file_simple_opt_get_id_table_end;
|
||||
}
|
||||
|
||||
data_len = __this->get_id_table_len(type);
|
||||
if (!data_len) {
|
||||
printf("err : id table is empty\n");
|
||||
goto __file_simple_opt_get_id_table_end;
|
||||
}
|
||||
|
||||
*data = zalloc(data_len + reserved_len);
|
||||
if (NULL == *data) {
|
||||
printf("%s is no ram\n", __func__);
|
||||
data_len = 0;
|
||||
goto __file_simple_opt_get_id_table_end;
|
||||
}
|
||||
|
||||
if (!__this->get_id_table(type, *data + reserved_len, data_len)) {
|
||||
printf("err : get id table fail\n");
|
||||
data_len = 0;
|
||||
goto __file_simple_opt_get_id_table_end;
|
||||
}
|
||||
|
||||
__file_simple_opt_get_id_table_end:
|
||||
return data_len;
|
||||
}
|
||||
|
||||
static void file_simple_opt_query(void *priv, u8 OpCode_SN, u8 *data, u16 len)
|
||||
{
|
||||
u16 index = 0;
|
||||
u8 file_type = data[0];
|
||||
u8 *resp_data = NULL;
|
||||
|
||||
u16 reserved_len = 2;
|
||||
int resp_len = file_simple_opt_get_id_table(file_type, &resp_data, reserved_len);
|
||||
if (!resp_len) {
|
||||
goto __file_simple_opt_query_end;
|
||||
}
|
||||
|
||||
index = reserved_len;
|
||||
for (u16 i = reserved_len; i < resp_len + reserved_len; i += 4) {
|
||||
if (0 == (resp_data[i + 2] | resp_data[i + 3])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (index != i) {
|
||||
memcpy(resp_data + index, resp_data + i, 4);
|
||||
}
|
||||
|
||||
// id变成大端
|
||||
resp_data[index] ^= resp_data[index + 1];
|
||||
resp_data[index + 1] ^= resp_data[index];
|
||||
resp_data[index] ^= resp_data[index + 1];
|
||||
|
||||
// size变成大端
|
||||
resp_data[index + 2] ^= resp_data[index + 3];
|
||||
resp_data[index + 3] ^= resp_data[index + 2];
|
||||
resp_data[index + 2] ^= resp_data[index + 3];
|
||||
|
||||
index += 4;
|
||||
}
|
||||
|
||||
__file_simple_opt_query_end:
|
||||
if (index > reserved_len) {
|
||||
resp_data[0] = FILE_SIMPLE_OPT_QUERY;
|
||||
resp_data[1] = FILE_SIMPLE_TRANSFER_VERSION;
|
||||
JL_CMD_response_send(JL_OPCODE_SIMPLE_FILE_TRANS, JL_PRO_STATUS_SUCCESS, OpCode_SN, resp_data, index, 0, NULL);
|
||||
} else {
|
||||
// 防止使用resp_data时是空
|
||||
data[0] = FILE_SIMPLE_OPT_QUERY;
|
||||
data[1] = FILE_SIMPLE_TRANSFER_VERSION;
|
||||
JL_CMD_response_send(JL_OPCODE_SIMPLE_FILE_TRANS, JL_PRO_STATUS_SUCCESS, OpCode_SN, data, 2, 0, NULL);
|
||||
}
|
||||
|
||||
if (resp_data) {
|
||||
free(resp_data);
|
||||
}
|
||||
}
|
||||
|
||||
static void file_simple_opt_read(void *priv, u8 OpCode_SN, u8 *data, u16 len)
|
||||
{
|
||||
|
||||
int index = 0;
|
||||
u16 offset = 0;
|
||||
u8 file_type = data[offset + 0];
|
||||
u16 file_id = data[offset + 1] << 8 | data[offset + 2];
|
||||
u16 file_offset = data[offset + 3] << 8 | data[offset + 4];
|
||||
u16 data_len = data[offset + 5] << 8 | data[offset + 6];
|
||||
u8 package_flag = data[offset + 7];
|
||||
static u16 data_crc = 0;
|
||||
// 通过回复把数据返回
|
||||
u8 *resp_data = NULL;
|
||||
int resp_len = 0;
|
||||
if (package_flag) {
|
||||
data_crc = 0;
|
||||
}
|
||||
if (data_len + 1 > (JL_packet_get_tx_max_mtu() - 8)) {
|
||||
printf("err : data_len is bigger then resp_max_len\n");
|
||||
goto __file_simple_opt_read_end;
|
||||
}
|
||||
resp_len = file_simple_opt_get_id_table(file_type, &resp_data, 0);
|
||||
if (0 == resp_len) {
|
||||
goto __file_simple_opt_read_end;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
for (index = 0; index < resp_len / 4; index++) {
|
||||
if (0 == memcmp(resp_data + index * 4, &file_id, sizeof(file_id))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index == resp_len / 4) {
|
||||
printf("file id : %x is vaild\n", file_id);
|
||||
resp_len = 0;
|
||||
goto __file_simple_opt_read_end;
|
||||
}
|
||||
|
||||
if (0 == (resp_data[index * 4 + 2] | resp_data[index * 4 + 3])) {
|
||||
resp_len = 0;
|
||||
printf("file type : %x, file id : %d, file data is empty\n", file_type, file_id);
|
||||
goto __file_simple_opt_read_end;
|
||||
}
|
||||
|
||||
if (__this->read_file_by_id) {
|
||||
resp_len = __this->read_file_by_id(file_type, file_id, file_offset, data + 4, data_len);
|
||||
if (!resp_len) {
|
||||
printf("err : read data fail %d\n", data_len);
|
||||
goto __file_simple_opt_read_end;
|
||||
} else {
|
||||
// 计算crc
|
||||
data_len = resp_len;
|
||||
data_crc = CRC16_with_initval(data + 4, data_len, data_crc);//calc_crc16_with_init_val(data_crc, data + 4, data_len);
|
||||
data[2] = ((u8 *)&data_crc)[1];
|
||||
data[3] = ((u8 *)&data_crc)[0];
|
||||
}
|
||||
}
|
||||
|
||||
__file_simple_opt_read_end:
|
||||
data[0] = FILE_SIMPLE_OPT_READ;
|
||||
if (resp_len) {
|
||||
data[1] = 0;
|
||||
JL_CMD_response_send(JL_OPCODE_SIMPLE_FILE_TRANS, JL_PRO_STATUS_SUCCESS, OpCode_SN, data, data_len + 4, 0, NULL);
|
||||
} else {
|
||||
data[1] = 1;
|
||||
JL_CMD_response_send(JL_OPCODE_SIMPLE_FILE_TRANS, JL_PRO_STATUS_SUCCESS, OpCode_SN, data, 2, 0, NULL);
|
||||
}
|
||||
|
||||
if (resp_data) {
|
||||
free(resp_data);
|
||||
}
|
||||
}
|
||||
|
||||
static void file_simple_opt_insert(void *priv, u8 OpCode_SN, u8 *data, u16 len)
|
||||
{
|
||||
|
||||
int index = 0;
|
||||
u16 offset = 0;
|
||||
u8 file_type = data[offset + 0];
|
||||
u16 file_offset = data[offset + 1] << 8 | data[offset + 2];
|
||||
u16 file_size = data[offset + 3] << 8 | data[offset + 4];
|
||||
u16 verify_crc = data[offset + 5] << 8 | data[offset + 6];
|
||||
|
||||
offset = 7;
|
||||
|
||||
u16 file_id = 0;
|
||||
u8 *file_data = data + offset;
|
||||
u8 *resp_data = NULL;
|
||||
|
||||
static u16 data_crc = 0;
|
||||
if (0 == file_offset) {
|
||||
data_crc = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
data_crc = CRC16_with_initval(file_data, len - offset, data_crc);//calc_crc16_with_init_val(data_crc, file_data, len - offset);
|
||||
if (data_crc != verify_crc) {
|
||||
printf("err : crc verify is err\n");
|
||||
data[1] = 3;
|
||||
goto __file_simple_opt_insert_end;
|
||||
}
|
||||
if (__this->insert_file_by_id) {
|
||||
if (__this->insert_file_by_id(file_type, &file_id, file_offset, file_data, len - offset, file_size)) {
|
||||
printf("err : insert data fail\n");
|
||||
data[1] = 1;
|
||||
goto __file_simple_opt_insert_end;
|
||||
}
|
||||
}
|
||||
|
||||
data[1] = 0;
|
||||
int resp_len = 2;
|
||||
if ((file_offset + len - offset) == file_size) {
|
||||
// 成功且最后一包
|
||||
data[2] = ((u8 *)&file_id)[1];
|
||||
data[3] = ((u8 *)&file_id)[0];
|
||||
resp_len += 2;
|
||||
}
|
||||
|
||||
__file_simple_opt_insert_end:
|
||||
data[0] = FILE_SIMPLE_OPT_INSERT;
|
||||
if (data[1]) {
|
||||
resp_len = 2;
|
||||
}
|
||||
JL_CMD_response_send(JL_OPCODE_SIMPLE_FILE_TRANS, JL_PRO_STATUS_SUCCESS, OpCode_SN, data, resp_len, 0, NULL);
|
||||
if (resp_data) {
|
||||
free(resp_data);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void file_simple_opt_update(void *priv, u8 OpCode_SN, u8 *data, u16 len)
|
||||
{
|
||||
|
||||
int index = 0;
|
||||
u16 offset = 0;
|
||||
u8 file_type = data[offset + 0];
|
||||
u16 file_id = data[offset + 1] << 8 | data[offset + 2];
|
||||
u16 file_offset = data[offset + 3] << 8 | data[offset + 4];
|
||||
u16 file_size = data[offset + 5] << 8 | data[offset + 6];
|
||||
u16 verify_crc = data[offset + 7] << 8 | data[offset + 8];
|
||||
|
||||
offset = 9;
|
||||
|
||||
u8 *file_data = data + offset;
|
||||
u8 *resp_data = NULL;
|
||||
int resp_len = 0;
|
||||
|
||||
static u16 data_crc = 0;
|
||||
if (0 == file_offset) {
|
||||
data_crc = 0;
|
||||
}
|
||||
|
||||
resp_len = file_simple_opt_get_id_table(file_type, &resp_data, 0);
|
||||
|
||||
resp_len /= 4;
|
||||
|
||||
if (0 == resp_len) {
|
||||
goto __file_simple_opt_update_end;
|
||||
}
|
||||
|
||||
for (index = 0; index < resp_len; index++) {
|
||||
if (0 == memcmp(resp_data + index * 4, &file_id, sizeof(file_id))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index == resp_len) {
|
||||
printf("file id : %x is vaild fail\n", file_id);
|
||||
resp_len = 0;
|
||||
goto __file_simple_opt_update_end;
|
||||
}
|
||||
|
||||
if (0 == (resp_data[index * 4 + 2] | resp_data[index * 4 + 3])) {
|
||||
printf("file type : %x, file id : %d, file data is empty\n", file_type, file_id);
|
||||
resp_len = 0;
|
||||
goto __file_simple_opt_update_end;
|
||||
}
|
||||
|
||||
data_crc = CRC16_with_initval(file_data, len - offset, data_crc);//calc_crc16_with_init_val(data_crc, file_data, len - offset);
|
||||
if (data_crc != verify_crc) {
|
||||
printf("err : crc verify is err\n");
|
||||
data[1] = 3;
|
||||
goto __file_simple_opt_update_end;
|
||||
}
|
||||
|
||||
if (__this->update_file_by_id) {
|
||||
if (__this->update_file_by_id(file_type, file_id, file_offset, file_data, len - offset, file_size)) {
|
||||
printf("err : update file fail\n");
|
||||
resp_len = 0;
|
||||
goto __file_simple_opt_update_end;
|
||||
}
|
||||
}
|
||||
|
||||
__file_simple_opt_update_end:
|
||||
data[0] = FILE_SIMPLE_OPT_UPDATE;
|
||||
if (resp_len) {
|
||||
data[1] = 0;
|
||||
} else {
|
||||
data[1] = 1;
|
||||
}
|
||||
JL_CMD_response_send(JL_OPCODE_SIMPLE_FILE_TRANS, JL_PRO_STATUS_SUCCESS, OpCode_SN, data, 2, 0, NULL);
|
||||
if (resp_data) {
|
||||
free(resp_data);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void file_simple_opt_delete(void *priv, u8 OpCode_SN, u8 *data, u16 len)
|
||||
{
|
||||
|
||||
int index = 0;
|
||||
u16 offset = 0;
|
||||
u8 file_type = data[offset + 0];
|
||||
u16 file_id = data[offset + 1] << 8 | data[offset + 2];
|
||||
u8 *resp_data = NULL;
|
||||
int resp_len = 0;
|
||||
resp_len = file_simple_opt_get_id_table(file_type, &resp_data, 0);
|
||||
resp_len /= 4;
|
||||
if (0 == resp_len) {
|
||||
goto __file_simple_opt_delete_end;
|
||||
}
|
||||
for (index = 0; index < resp_len; index++) {
|
||||
if (0 == memcmp(resp_data + index * 4, &file_id, sizeof(file_id))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index == resp_len) {
|
||||
printf("file type : %x, file id : %d, file data is null\n", file_type, file_id);
|
||||
resp_len = 0;
|
||||
goto __file_simple_opt_delete_end;
|
||||
}
|
||||
|
||||
if (0 == (resp_data[index * 4 + 2] | resp_data[index * 4 + 3])) {
|
||||
printf("file type : %x, file id : %d, file data is empty\n", file_type, file_id);
|
||||
resp_len = 0;
|
||||
goto __file_simple_opt_delete_end;
|
||||
}
|
||||
|
||||
if (__this->delete_file_by_id) {
|
||||
if (__this->delete_file_by_id(file_type, file_id)) {
|
||||
printf("err : delete file fail\n");
|
||||
resp_len = 0;
|
||||
goto __file_simple_opt_delete_end;
|
||||
}
|
||||
}
|
||||
|
||||
__file_simple_opt_delete_end:
|
||||
data[0] = FILE_SIMPLE_OPT_DELETE;
|
||||
if (resp_len) {
|
||||
data[1] = 0;
|
||||
} else {
|
||||
data[1] = 1;
|
||||
}
|
||||
JL_CMD_response_send(JL_OPCODE_SIMPLE_FILE_TRANS, JL_PRO_STATUS_SUCCESS, OpCode_SN, data, 2, 0, NULL);
|
||||
if (resp_data) {
|
||||
free(resp_data);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// rcsp小文件传输命令处理
|
||||
void rcsp_file_simple_transfer_for_small_file(void *priv, u8 OpCode_SN, u8 *data, u16 len)
|
||||
{
|
||||
u8 op = data[0];
|
||||
switch (op) {
|
||||
case FILE_SIMPLE_OPT_QUERY:
|
||||
file_simple_opt_query(priv, OpCode_SN, data + 1, len - 1);
|
||||
break;
|
||||
case FILE_SIMPLE_OPT_READ:
|
||||
file_simple_opt_read(priv, OpCode_SN, data + 1, len - 1);
|
||||
break;
|
||||
case FILE_SIMPLE_OPT_INSERT:
|
||||
file_simple_opt_insert(priv, OpCode_SN, data + 1, len - 1);
|
||||
break;
|
||||
case FILE_SIMPLE_OPT_UPDATE:
|
||||
file_simple_opt_update(priv, OpCode_SN, data + 1, len - 1);
|
||||
break;
|
||||
case FILE_SIMPLE_OPT_DELETE:
|
||||
file_simple_opt_delete(priv, OpCode_SN, data + 1, len - 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// rcsp注册小文件传输操作结构体
|
||||
int rcsp_register_file_simple_transfer_interface(rcsp_simple_trans_opt *file_simple_transfer_interface)
|
||||
{
|
||||
g_rcsp_simple_trans_opt = file_simple_transfer_interface;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
#ifndef __FILE_SIMPLE_TRANSFER_H__
|
||||
#define __FILE_SIMPLE_TRANSFER_H__
|
||||
|
||||
#include "typedef.h"
|
||||
#include "app_config.h"
|
||||
|
||||
typedef struct file_simple_transfer_opt {
|
||||
// 返回长度(成功)/0(失败) 根据当前文件类型获取id表长度(传入 文件类型),该接口返回的长度是 [id(2byte) + file_size(没有文件就是0,但都是占2个byte的位置)] * n
|
||||
int (*get_id_table_len)(u8 file_type);
|
||||
// 成功返回长度/失败0 根据类型获取文件id列表(传入 文件类型),table_data用于存放返回数据,返回的数据格式:[id(2byte) + file_size(没有文件就是0,但都是占2个byte的位置)] * n
|
||||
int (*get_id_table)(u8 file_type, u8 *table_data, u16 data_len);
|
||||
// 成功返回数据长度/失败0 读取文件(文件id,数据偏移,数据,数据长度)
|
||||
int (*read_file_by_id)(u8 file_type, u16 id, u32 data_offset, u8 *data, u16 data_len);
|
||||
// 成功返回0/失败非0 新增文件(文件id,数据偏移,数据,数据长度)
|
||||
int (*insert_file_by_id)(u8 file_type, u16 *id, u32 data_offset, u8 *data, u16 data_len, u16 file_total_size);
|
||||
// 成功返回0/失败非0 更新文件(文件id,数据偏移,数据,数据长度)
|
||||
int (*update_file_by_id)(u8 file_type, u16 id, u32 data_offset, u8 *data, u16 data_len, u16 file_total_size);
|
||||
// 成功返回0/失败非0 删除文件(文件id)
|
||||
int (*delete_file_by_id)(u8 file_type, u16 id);
|
||||
} rcsp_simple_trans_opt;
|
||||
|
||||
// rcsp小文件传输命令处理
|
||||
void rcsp_file_simple_transfer_for_small_file(void *priv, u8 OpCode_SN, u8 *data, u16 len);
|
||||
// rcsp注册小文件传输操作结构体
|
||||
int rcsp_register_file_simple_transfer_interface(rcsp_simple_trans_opt *file_simple_transfer_interface);
|
||||
|
||||
#endif
|
||||
+428
@@ -0,0 +1,428 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".file_trans_back.data.bss")
|
||||
#pragma data_seg(".file_trans_back.data")
|
||||
#pragma const_seg(".file_trans_back.text.const")
|
||||
#pragma code_seg(".file_trans_back.text")
|
||||
#endif
|
||||
#include "file_trans_back.h"
|
||||
#include "rcsp.h"
|
||||
#include "system/includes.h"
|
||||
#include "file_operate/file_manager.h"
|
||||
#include "rcsp_browser.h"
|
||||
#include "fs/fs.h"
|
||||
#include "rcsp_manage.h"
|
||||
#include "rcsp_event.h"
|
||||
#include "rcsp_config.h"
|
||||
#include "JL_rcsp_protocol.h"
|
||||
#include "JL_rcsp_packet.h"
|
||||
|
||||
#if (RCSP_MODE && TCFG_DEV_MANAGER_ENABLE)
|
||||
|
||||
#include "dev_status.h"
|
||||
|
||||
#define FTP_DOWNLOAD_FOLDER_NAME "download" //下载目录
|
||||
|
||||
#define FILE_TRANS_BACK_TASK_NAME "ftran_back"
|
||||
|
||||
enum {
|
||||
FILE_TRANS_BACK_BY_NAME,
|
||||
FILE_TRANS_BACK_BY_CLUST,
|
||||
FILE_TRANS_BACK_BY_NAME_2,
|
||||
FILE_TRANS_BACK_FINISH = 0x80,
|
||||
FILE_TRANS_BACK_CANCEL = 0x81,
|
||||
};
|
||||
|
||||
struct __file_trans_back {
|
||||
FILE *file;
|
||||
struct __dev *dev;
|
||||
struct vfscan *fsn;
|
||||
void (*end_callback)(void);
|
||||
u8 OpCode_SN;
|
||||
u8 op;
|
||||
};
|
||||
|
||||
///播放参数,文件扫描时用,文件后缀等
|
||||
static const char scan_parm[] = "-t"
|
||||
#if (WATCH_FILE_TO_FLASH)
|
||||
"ALL"
|
||||
#else // WATCH_FILE_TO_FLASH
|
||||
#if (TCFG_DEC_MP3_ENABLE)
|
||||
"MP1MP2MP3"
|
||||
#endif
|
||||
#if (TCFG_DEC_WMA_ENABLE)
|
||||
"WMA"
|
||||
#endif
|
||||
#if ( TCFG_DEC_WAV_ENABLE || TCFG_DEC_DTS_ENABLE)
|
||||
"WAVDTS"
|
||||
#endif
|
||||
#if (TCFG_DEC_FLAC_ENABLE)
|
||||
"FLA"
|
||||
#endif
|
||||
#if (TCFG_DEC_APE_ENABLE)
|
||||
"APE"
|
||||
#endif
|
||||
#if (TCFG_DEC_M4A_ENABLE)
|
||||
"M4AAAC"
|
||||
#endif
|
||||
#if (TCFG_DEC_M4A_ENABLE || TCFG_DEC_ALAC_ENABLE)
|
||||
"MP4"
|
||||
#endif
|
||||
#if (TCFG_DEC_AMR_ENABLE)
|
||||
"AMR"
|
||||
#endif
|
||||
#if (TCFG_DEC_DECRYPT_ENABLE)
|
||||
"SMP"
|
||||
#endif
|
||||
#if (TCFG_DEC_MIDI_ENABLE)
|
||||
"MID"
|
||||
#endif
|
||||
"TMP"
|
||||
#endif // WATCH_FILE_TO_FLASH
|
||||
" -sn -r"
|
||||
;
|
||||
|
||||
static struct __file_trans_back *trans_back = NULL;
|
||||
|
||||
static u8 g_trans_back_cancel_flag = -1;
|
||||
|
||||
static u32 g_dev_handle = RCSPDevMapSD1;
|
||||
|
||||
extern u8 check_le_pakcet_sent_finish_flag(void);
|
||||
extern bool rcsp_send_list_is_empty(void);
|
||||
extern void file_trans_idle_set(u8 file_trans_idle_flag);
|
||||
|
||||
static int get_file_prepare(u32 dev_handle)
|
||||
{
|
||||
char *logo = rcsp_browser_dev_remap(dev_handle);
|
||||
if (NULL == logo) {
|
||||
printf("trans_back logo is null");
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct __dev *dev = dev_manager_find_spec(logo, 0);
|
||||
if (NULL == dev) {
|
||||
printf("trans_back dev is null");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NULL == trans_back) {
|
||||
trans_back = zalloc(sizeof(struct __file_trans_back));
|
||||
if (NULL == trans_back) {
|
||||
printf("trans_back zalloc err\n");
|
||||
return -1;
|
||||
}
|
||||
trans_back->dev = dev;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void creat_file_path(char *path, char *root_path, const char *folder, u8 *name, u16 name_len)
|
||||
{
|
||||
strcat(path, root_path);
|
||||
if (folder) {
|
||||
strcat(path, folder);
|
||||
strcat(path, "/");
|
||||
}
|
||||
//strcat(path, name);
|
||||
/* memcpy(path + strlen(root_path) + strlen(folder) + 1, name, name_len); */
|
||||
memcpy(path + strlen(path), name, name_len);
|
||||
//printf("path = %s\n", path);
|
||||
}
|
||||
|
||||
static u32 creat_path_len(char *root_path, const char *folder, u8 *name, u16 name_len)
|
||||
{
|
||||
u32 root_path_len = 0, folder_len = 0;
|
||||
if (root_path) {
|
||||
root_path_len = strlen(root_path);
|
||||
}
|
||||
if (folder) {
|
||||
folder_len = strlen(folder);
|
||||
}
|
||||
u32 len = (root_path_len + folder_len + name_len + 1);
|
||||
if (folder) {
|
||||
len += strlen("/");
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
static u8 file_trans_back_response_send(u8 *data, u16 len, u8 dire, u8 OpCode_SN)
|
||||
{
|
||||
u8 ret = 0;
|
||||
switch (dire) {
|
||||
case 0:
|
||||
ret = JL_CMD_response_send(JL_OPCODE_ONE_FILE_TRANS_BACK, JL_PRO_STATUS_SUCCESS, OpCode_SN, data, len, 0, NULL);
|
||||
break;
|
||||
case 1:
|
||||
ret = JL_DATA_send(JL_OPCODE_DATA, JL_OPCODE_ONE_FILE_TRANS_BACK, data, len, JL_NOT_NEED_RESPOND, 0, NULL);
|
||||
break;
|
||||
case 2:
|
||||
ret = JL_CMD_send(JL_OPCODE_ONE_FILE_TRANS_BACK, data, len, JL_NEED_RESPOND, 0, NULL);
|
||||
break;
|
||||
case 0xFF:
|
||||
ret = JL_CMD_response_send(JL_OPCODE_ONE_FILE_TRANS_BACK, JL_PRO_STATUS_FAIL, OpCode_SN, data, len, 0, NULL);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void file_trans_back_task(void *p)
|
||||
{
|
||||
struct RcspModel *rcspModel = (struct RcspModel *)p;
|
||||
// 从文件句柄中获取当前文件的大小
|
||||
struct vfs_attr attr;
|
||||
fget_attrs(trans_back->file, &attr);
|
||||
// 获取文件数据
|
||||
u32 file_size = attr.fsize;
|
||||
|
||||
// 预留 开始头(3byte) + opCode(2byte) + param_len(2byte) + state(1byte) + opCode_SN(1byte) + 结束(1byte)
|
||||
u16 resp_data_len = JL_packet_get_tx_max_mtu() - 10;
|
||||
u8 *resp_data = zalloc(resp_data_len);
|
||||
if (NULL == resp_data) {
|
||||
// 错误
|
||||
file_trans_back_response_send(&trans_back->op, sizeof(trans_back->op), (u8) - 1, trans_back->OpCode_SN);
|
||||
goto __file_trans_back_task_err;
|
||||
}
|
||||
|
||||
// 把大小发送给app
|
||||
resp_data[0] = trans_back->op;
|
||||
resp_data[1] = ((u8 *)&file_size)[3];
|
||||
resp_data[2] = ((u8 *)&file_size)[2];
|
||||
resp_data[3] = ((u8 *)&file_size)[1];
|
||||
resp_data[4] = ((u8 *)&file_size)[0];
|
||||
file_trans_back_response_send(resp_data, sizeof(file_size) + 1, 0, trans_back->OpCode_SN);
|
||||
// 退出sniff
|
||||
file_trans_idle_set(0);
|
||||
|
||||
u16 crc = 0;
|
||||
resp_data_len -= 4;
|
||||
if (FILE_TRANS_BACK_BY_NAME != trans_back->op) {
|
||||
resp_data_len -= 2;
|
||||
}
|
||||
for (u32 offset = 0, data_len = 0, ret = 0; offset < file_size;) {
|
||||
wdt_clear();
|
||||
// 假如当前spp或ble断开连接
|
||||
if (0 == get_rcsp_connect_status()) {
|
||||
goto __file_trans_back_task_err;
|
||||
}
|
||||
if ((u8) - 1 != g_trans_back_cancel_flag) {
|
||||
break;
|
||||
}
|
||||
|
||||
data_len = (file_size - offset) > resp_data_len ? resp_data_len : file_size - offset;
|
||||
fseek(trans_back->file, offset, SEEK_SET);
|
||||
resp_data[0] = ((u8 *)&offset)[3];
|
||||
resp_data[1] = ((u8 *)&offset)[2];
|
||||
resp_data[2] = ((u8 *)&offset)[1];
|
||||
resp_data[3] = ((u8 *)&offset)[0];
|
||||
|
||||
if (FILE_TRANS_BACK_BY_NAME == trans_back->op) {
|
||||
fread(resp_data + 4, data_len, 1, trans_back->file);
|
||||
} else {
|
||||
fread(resp_data + 6, data_len, 1, trans_back->file);
|
||||
// 填充crc
|
||||
if (JL_ERR_NONE == ret) {
|
||||
crc = CRC16_with_initval(resp_data + 6, data_len, crc);
|
||||
}
|
||||
data_len += 2;
|
||||
resp_data[4] = crc >> 8;
|
||||
resp_data[5] = crc & 0xFF;
|
||||
}
|
||||
|
||||
// 发送文件数据
|
||||
ret = file_trans_back_response_send(resp_data, data_len + 4, 1, trans_back->OpCode_SN);
|
||||
if (JL_ERR_SEND_DATA_OVER_LIMIT == ret) {
|
||||
os_time_dly(1);
|
||||
continue;
|
||||
}
|
||||
if (ret) {
|
||||
printf("file data trans err: %d\n", ret);
|
||||
break;
|
||||
}
|
||||
offset += resp_data_len;
|
||||
}
|
||||
|
||||
while (!(rcsp_send_list_is_empty() && check_le_pakcet_sent_finish_flag())) {
|
||||
os_time_dly(10);
|
||||
if (0 == get_rcsp_connect_status()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
memset(resp_data, 0, resp_data_len + 1);
|
||||
if ((u8) - 1 == g_trans_back_cancel_flag) {
|
||||
// 如果传输完成发送结束命令
|
||||
resp_data[0] = FILE_TRANS_BACK_FINISH;
|
||||
file_trans_back_response_send(resp_data, 1 + 4, 2, trans_back->OpCode_SN);
|
||||
} else {
|
||||
// 取消
|
||||
resp_data[0] = FILE_TRANS_BACK_CANCEL;
|
||||
file_trans_back_response_send(resp_data, 1, 0, trans_back->OpCode_SN);
|
||||
}
|
||||
|
||||
__file_trans_back_task_err:
|
||||
if (resp_data) {
|
||||
free(resp_data);
|
||||
}
|
||||
|
||||
file_trans_idle_set(1);
|
||||
rcsp_msg_post(USER_MSG_RCSP_FILE_TRANS_BACK, 1, (int)p);
|
||||
while (1) {
|
||||
os_time_dly(10);
|
||||
}
|
||||
}
|
||||
|
||||
static int get_file_by_name(void *priv, u8 *data, u16 len)
|
||||
{
|
||||
u32 file_offset = data[0] << 24 | data[1] << 16 << data[2] << 8 | data[3];
|
||||
u8 offset = 4;
|
||||
|
||||
u32 param_len = 0;
|
||||
if (FILE_TRANS_BACK_BY_NAME != trans_back->op) {
|
||||
param_len = data[offset];
|
||||
offset++;
|
||||
}
|
||||
u8 *file_name = data + offset;
|
||||
// 拼凑绝对路径
|
||||
char *root_path = dev_manager_get_root_path(trans_back->dev);
|
||||
char *folder = NULL;
|
||||
if (RCSPDevMapFLASH == g_dev_handle ||
|
||||
RCSPDevMapFLASH_2 == g_dev_handle) {
|
||||
if ('/' == file_name[0]) {
|
||||
file_name++;
|
||||
offset++;
|
||||
}
|
||||
} else {
|
||||
folder = FTP_DOWNLOAD_FOLDER_NAME;
|
||||
}
|
||||
char *path = zalloc(creat_path_len(root_path, folder, file_name, len - offset));
|
||||
creat_file_path(path, root_path, folder, file_name, len - offset);
|
||||
|
||||
if (NULL == trans_back->file) {
|
||||
trans_back->file = fopen(path, "r");
|
||||
}
|
||||
|
||||
if (path) {
|
||||
free(path);
|
||||
}
|
||||
|
||||
if (NULL == trans_back->file) {
|
||||
// 文件不存在
|
||||
goto __get_file_file_by_name_err;
|
||||
}
|
||||
|
||||
if (task_create(file_trans_back_task, priv, FILE_TRANS_BACK_TASK_NAME)) {
|
||||
goto __get_file_file_by_name_err;
|
||||
}
|
||||
return 0;
|
||||
|
||||
__get_file_file_by_name_err:
|
||||
rcsp_file_trans_back_close();
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int cancel_file_trans_back(u8 OpCode_SN, u8 *data, u16 len)
|
||||
{
|
||||
int ret = 0;
|
||||
if (trans_back) {
|
||||
trans_back->OpCode_SN = OpCode_SN;
|
||||
trans_back->op = FILE_TRANS_BACK_CANCEL;
|
||||
g_trans_back_cancel_flag = data[0];
|
||||
} else {
|
||||
ret = -1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// 关闭向手机发送文件
|
||||
void rcsp_file_trans_back_close(void)
|
||||
{
|
||||
task_kill(FILE_TRANS_BACK_TASK_NAME);
|
||||
g_trans_back_cancel_flag = -1;
|
||||
|
||||
if (trans_back->fsn) {
|
||||
fscan_release(trans_back->fsn);
|
||||
trans_back->fsn = NULL;
|
||||
}
|
||||
|
||||
// 关闭文件
|
||||
if (trans_back->file) {
|
||||
fclose(trans_back->file);
|
||||
trans_back->file = NULL;
|
||||
}
|
||||
|
||||
if (trans_back) {
|
||||
free(trans_back);
|
||||
trans_back = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int get_file_by_clust(void *priv, u8 *data, u16 len)
|
||||
{
|
||||
u32 file_offset = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
|
||||
u32 cluster = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
|
||||
// find name by cluster
|
||||
if (NULL == trans_back->file) {
|
||||
if (NULL == trans_back->fsn) {
|
||||
trans_back->fsn = file_manager_scan_disk(trans_back->dev, NULL, scan_parm, 0, NULL);
|
||||
}
|
||||
trans_back->file = file_manager_select(trans_back->dev, trans_back->fsn, FSEL_BY_SCLUST, cluster, NULL);
|
||||
}
|
||||
|
||||
if (NULL == trans_back->fsn) {
|
||||
goto __get_file_by_clust_err;
|
||||
}
|
||||
|
||||
if (NULL == trans_back->file) {
|
||||
goto __get_file_by_clust_err;
|
||||
}
|
||||
|
||||
if (task_create(file_trans_back_task, priv, FILE_TRANS_BACK_TASK_NAME)) {
|
||||
goto __get_file_by_clust_err;
|
||||
}
|
||||
return 0;
|
||||
|
||||
__get_file_by_clust_err:
|
||||
rcsp_file_trans_back_close();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 向手机发送文件
|
||||
void rcsp_file_trans_back_opt(void *priv, u8 OpCode_SN, u8 *data, u16 len)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 offset = 0;
|
||||
u8 op = data[0];
|
||||
switch (op) {
|
||||
case FILE_TRANS_BACK_BY_NAME_2:
|
||||
g_dev_handle = data[1] << 24 | data[2] << 16 | data[3] << 8 | data[4];
|
||||
offset = 5;
|
||||
case FILE_TRANS_BACK_BY_NAME:
|
||||
ret = get_file_prepare(g_dev_handle);
|
||||
if (ret) {
|
||||
break;
|
||||
}
|
||||
trans_back->OpCode_SN = OpCode_SN;
|
||||
trans_back->op = op;
|
||||
ret = get_file_by_name(priv, data + offset, len - offset);
|
||||
break;
|
||||
case FILE_TRANS_BACK_BY_CLUST:
|
||||
g_dev_handle = data[1] << 24 | data[2] << 16 | data[3] << 8 | data[4];
|
||||
offset = 5;
|
||||
ret = get_file_prepare(g_dev_handle);
|
||||
if (ret) {
|
||||
break;
|
||||
}
|
||||
trans_back->OpCode_SN = OpCode_SN;
|
||||
trans_back->op = op;
|
||||
ret = get_file_by_clust(priv, data + offset, len - offset);
|
||||
break;
|
||||
case FILE_TRANS_BACK_CANCEL:
|
||||
ret = cancel_file_trans_back(OpCode_SN, data + 1, len - 1);
|
||||
break;
|
||||
}
|
||||
if (ret) {
|
||||
file_trans_back_response_send(&op, sizeof(op), (u8) - 1, OpCode_SN);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
#ifndef __FILE_TRANS_BACK__
|
||||
#define __FILE_TRANS_BACK__
|
||||
|
||||
#include "typedef.h"
|
||||
#include "app_config.h"
|
||||
|
||||
// 向手机发送文件
|
||||
void rcsp_file_trans_back_opt(void *priv, u8 OpCode_SN, u8 *data, u16 len);
|
||||
// 关闭向手机发送文件
|
||||
void rcsp_file_trans_back_close(void);
|
||||
|
||||
#endif
|
||||
+964
@@ -0,0 +1,964 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".file_transfer.data.bss")
|
||||
#pragma data_seg(".file_transfer.data")
|
||||
#pragma const_seg(".file_transfer.text.const")
|
||||
#pragma code_seg(".file_transfer.text")
|
||||
#endif
|
||||
#include "file_transfer.h"
|
||||
#include "system/includes.h"
|
||||
#include "fs/fs.h"
|
||||
#include "dev_manager.h"
|
||||
#include "rcsp_browser.h"
|
||||
#include "rcsp_config.h"
|
||||
|
||||
#include "rcsp_extra_flash_opt.h"
|
||||
#include "JL_rcsp_protocol.h"
|
||||
#include "ascii.h"
|
||||
|
||||
#define LOG_TAG_CONST RCSP
|
||||
#define LOG_TAG "[file trans]"
|
||||
#define LOG_ERROR_ENABLE
|
||||
#define LOG_DEBUG_ENABLE
|
||||
#define LOG_INFO_ENABLE
|
||||
#define LOG_CLI_ENABLE
|
||||
#include "debug.h"
|
||||
|
||||
#if (RCSP_MODE && TCFG_DEV_MANAGER_ENABLE)
|
||||
#define FTP_FILE_DATA_UNIT (512) //(234)//不能超过RCSP协议的MTU大小
|
||||
#define FTP_FILE_DATA_RECIEVE_REMAIN_SIZE (128) //接收缓存预留
|
||||
#define FTP_FILE_DATA_RECIEVE_BUF_MIN_SIZE (FTP_FILE_DATA_UNIT + FTP_FILE_DATA_RECIEVE_REMAIN_SIZE)
|
||||
#define FTP_FILE_DATA_RECIEVE_TIMEOUT (3*1000) //超时拉取数据等待时长, 超时时间到了,自动拉取
|
||||
#define FTP_DOWNLOAD_FOLDER_NAME "download" //下载目录
|
||||
#define FTP_FILE_VAILD_MARK "JL_FTP" //断点续传需要用到的文件内容标记
|
||||
#define FTP_FILE_VAILD_MARK_TIMER_UNIT (10*1000) //单位ms
|
||||
#define FTP_FILE_CRC_CAC_MAX_COUNTER (100) //文件校验一次校验的数据块个数
|
||||
#define FTP_FILE_PACKET_CRC_CHECK_EN 1 //文件内容每一包校验使能
|
||||
#define FTP_FILE_PACKET_CRC_ERR_CONTINUE_EN 0 //出现包crc错之后是否需要继续传输, 如果是测试, 可以设置为0, 会通知APP停止传输
|
||||
|
||||
/* #define FTP_DEBUG_ENABLE */
|
||||
#ifdef FTP_DEBUG_ENABLE
|
||||
#define ftp_printf log_info
|
||||
#else
|
||||
#define ftp_printf(...)
|
||||
#endif//FTP_DEBUG_ENABLE
|
||||
|
||||
enum {
|
||||
FTP_END_REASON_NONE = 0, //没有错误
|
||||
FTP_END_REASON_WRITE_ERR, //写失败
|
||||
FTP_END_REASON_DATA_OVER_LIMIT, //数据超范围
|
||||
FTP_END_REASON_DATA_CRC_ERR, //文件校验失败
|
||||
};
|
||||
|
||||
struct __file_check {
|
||||
u16 crc_tmp;
|
||||
u32 counter;
|
||||
u32 remain;
|
||||
};
|
||||
|
||||
|
||||
struct __ftp_download {
|
||||
u32 file_size;
|
||||
u32 file_offset;
|
||||
u8 win[FTP_FILE_DATA_UNIT];
|
||||
u8 packet_id;
|
||||
u8 packet_id_max;
|
||||
u8 last_packet;
|
||||
u8 packet_crc_err;
|
||||
u8 packet_crc_check;
|
||||
u8 progress;
|
||||
u32 dev_handle;
|
||||
u16 mark_timer;
|
||||
u16 get_timeout;
|
||||
u16 start_timerout;
|
||||
u16 file_crc;
|
||||
struct __file_check check;
|
||||
char *filepath;
|
||||
FILE *file;
|
||||
struct __dev *dev;
|
||||
void (*end_callback)(void);
|
||||
};
|
||||
static struct __ftp_download *ftp_d = NULL;
|
||||
|
||||
static void file_transfer_download_get_data(void);
|
||||
static void __file_transfer_download_file_check_caculate(void *priv);
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 校验分次处理消息发送处理
|
||||
@param
|
||||
@return
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void file_transfer_download_file_check_continue(void)
|
||||
{
|
||||
int msg[4];
|
||||
msg[0] = (int)__file_transfer_download_file_check_caculate;
|
||||
msg[1] = 1;
|
||||
msg[2] = 0;
|
||||
os_taskq_post_type("app_core", Q_CALLBACK, 3, msg);
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件数据块crc校验
|
||||
@param
|
||||
@return
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void __file_transfer_download_file_check_caculate(void *priv)
|
||||
{
|
||||
if (ftp_d == NULL) {
|
||||
return ;
|
||||
}
|
||||
wdt_clear();
|
||||
JL_ERR err = 0;
|
||||
u32 cnt;
|
||||
if (ftp_d->check.counter >= FTP_FILE_CRC_CAC_MAX_COUNTER) {
|
||||
cnt = FTP_FILE_CRC_CAC_MAX_COUNTER;
|
||||
} else {
|
||||
cnt = ftp_d->check.counter;
|
||||
}
|
||||
log_info("cnt = %d, check.counter = %d, crc_tmp = %x\n", cnt, ftp_d->check.counter, ftp_d->check.crc_tmp);
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
fread(ftp_d->win, sizeof(ftp_d->win), 1, ftp_d->file);
|
||||
ftp_d->check.crc_tmp = CRC16_with_initval(ftp_d->win, sizeof(ftp_d->win), ftp_d->check.crc_tmp);
|
||||
}
|
||||
ftp_d->check.counter -= cnt;
|
||||
if (ftp_d->check.counter == 0) {
|
||||
if (ftp_d->check.remain) {
|
||||
fread(ftp_d->win, ftp_d->check.remain, 1, ftp_d->file);
|
||||
log_info("remain\n");
|
||||
log_info_hexdump(ftp_d->win, ftp_d->check.remain);
|
||||
ftp_d->check.crc_tmp = CRC16_with_initval(ftp_d->win, ftp_d->check.remain, ftp_d->check.crc_tmp);
|
||||
}
|
||||
//crc_check end
|
||||
if (ftp_d->check.crc_tmp == ftp_d->file_crc) {
|
||||
log_info("crc check ok!!, start rename\n");
|
||||
fseek(ftp_d->file, ftp_d->file_size, SEEK_SET);
|
||||
//进入重命名流程
|
||||
err = JL_CMD_send(JL_OPCODE_FILE_RENAME, NULL, 0, 1, 0, NULL);
|
||||
if (err) {
|
||||
//命令发送失败, 直接停止
|
||||
rcsp_file_transfer_close();
|
||||
}
|
||||
return ;
|
||||
} else {
|
||||
log_error("crc check fail, crc_tmp = %x, file_crc = %x!!\n", ftp_d->check.crc_tmp, ftp_d->file_crc);
|
||||
u8 reason = FTP_END_REASON_DATA_CRC_ERR;
|
||||
fdelete(ftp_d->file);
|
||||
ftp_d->file = NULL;
|
||||
JL_ERR err = JL_CMD_send(JL_OPCODE_FILE_TRANSFER_END, &reason, 1, 1, 0, NULL);
|
||||
if (err) {
|
||||
//命令发送失败, 直接停止
|
||||
rcsp_file_transfer_close();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
file_transfer_download_file_check_continue();
|
||||
}
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件文件校验处理
|
||||
@param
|
||||
@return
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void file_transfer_download_file_check(void)
|
||||
{
|
||||
ftp_d->check.crc_tmp = 0;
|
||||
ftp_d->check.counter = ftp_d->file_size / sizeof(ftp_d->win);
|
||||
ftp_d->check.remain = ftp_d->file_size % sizeof(ftp_d->win);
|
||||
ftp_d->file_offset = ftp_d->file_size;
|
||||
log_info("crc_tmp = %x, counter = %d, remain = %d\n", ftp_d->check.crc_tmp, ftp_d->check.counter, ftp_d->check.remain);
|
||||
fseek(ftp_d->file, 0, SEEK_SET);
|
||||
file_transfer_download_file_check_continue();
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件传输重命名
|
||||
@param rename:重命名
|
||||
@return
|
||||
@note 此过程接收的数据是实际文件传输的内容
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int file_rename(const char *rename)
|
||||
{
|
||||
if (ftp_d && ftp_d->file) {
|
||||
//rename之前先关闭文件
|
||||
fclose(ftp_d->file);
|
||||
ftp_d->file = NULL;
|
||||
//重新打开文件
|
||||
ftp_printf("ftp_d->filepath:%s, rename:%s\n", ftp_d->filepath, rename);
|
||||
ftp_d->file = fopen(ftp_d->filepath, "r");
|
||||
//free(path);
|
||||
if (ftp_d->file) {
|
||||
//文件打开成功, 重命名
|
||||
int ret = frename(ftp_d->file, rename);
|
||||
if (ret) {
|
||||
log_error("rename fail\n");
|
||||
} else {
|
||||
log_info("rename ok\n");
|
||||
}
|
||||
return ret;
|
||||
} else {
|
||||
log_error("rename file open err!!");
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件重传文件头信息保存处理
|
||||
@param file:文件句柄,win:临时缓存,offset:文件偏移
|
||||
@return
|
||||
@note 文件传输过程, 定时会触发断点续传信息保存处理
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void file_transfer_download_vaild_mark_fill(FILE *file, u8 *win, u32 offset, u8 vaild)
|
||||
{
|
||||
if (file) {
|
||||
fseek(file, 0, SEEK_SET);
|
||||
memset(win, 0, FTP_FILE_DATA_UNIT);
|
||||
memcpy(win, FTP_FILE_VAILD_MARK, strlen(FTP_FILE_VAILD_MARK));
|
||||
memcpy(win + strlen(FTP_FILE_VAILD_MARK), &offset, sizeof(offset));
|
||||
memcpy(win + strlen(FTP_FILE_VAILD_MARK) + sizeof(offset), &vaild, sizeof(vaild));
|
||||
fwrite(win, FTP_FILE_DATA_UNIT, 1, file);
|
||||
fseek(file, offset, SEEK_SET);
|
||||
/* log_info("============================================%s, offset = %d, pos = %d\n", __FUNCTION__, offset, fpos(file)); */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 断点续传信息解析处理
|
||||
@param file:文件句柄, 文件偏移获取指针
|
||||
@return
|
||||
@note 在文件传输开始的时候进行解析, 目的是找到续传文件偏移
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void file_transfer_download_intermittent_parse(FILE *file, u32 *offset)
|
||||
{
|
||||
if (file) {
|
||||
char mark[10] = {0};
|
||||
fseek(file, 0, SEEK_SET);
|
||||
int rlen = fread(mark, strlen(FTP_FILE_VAILD_MARK), 1, file);
|
||||
if (rlen) {
|
||||
if (strcmp(mark, FTP_FILE_VAILD_MARK) == 0) {
|
||||
log_info("find VAILD_MARK !!\n");
|
||||
rlen = fread(offset, sizeof(u32), 1, file);
|
||||
if (rlen) {
|
||||
u8 vaild = 0;
|
||||
rlen = fread(&vaild, 1, 1, file);
|
||||
if (rlen && vaild) {
|
||||
log_info("read offset ok, %d!!\n", *offset);
|
||||
fseek(file, *offset, SEEK_SET);
|
||||
return ;
|
||||
} else {
|
||||
log_error("read offset ok, but not vaild\n");
|
||||
}
|
||||
} else {
|
||||
log_error("read offset fail!!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*offset = 0;
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件下载数据拉取超时处理
|
||||
@param priv:私有参数,
|
||||
@return
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void file_transfer_download_get_timeout(void *priv)
|
||||
{
|
||||
if (ftp_d) {
|
||||
ftp_printf("timeout!!!\n");
|
||||
ftp_d->get_timeout = 0;
|
||||
//在超时时间内没有收完所需要的数据, 重新拉取数据
|
||||
file_transfer_download_get_data();
|
||||
}
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 断点续传定时保存处理
|
||||
@param
|
||||
@return
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void file_transfer_download_vaild_mark_scan(void *priv)
|
||||
{
|
||||
if (ftp_d && ftp_d->file && ftp_d->mark_timer && ftp_d->last_packet == 0) {
|
||||
file_transfer_download_vaild_mark_fill(ftp_d->file, ftp_d->win, ftp_d->file_offset, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件下载数据拉取处理
|
||||
@param 无
|
||||
@return
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void file_transfer_download_get_data(void)
|
||||
{
|
||||
if (ftp_d == NULL || ftp_d->file == NULL) {
|
||||
ftp_printf("file not ready %d!!\n", __LINE__);
|
||||
return;
|
||||
}
|
||||
|
||||
u32 file_remain = 0;
|
||||
u32 file_offset = 0;
|
||||
u16 recieve_max = rcsp_packet_write_alloc_len();
|
||||
if (recieve_max < FTP_FILE_DATA_RECIEVE_BUF_MIN_SIZE) {
|
||||
ftp_printf("not enough buf to recieve!!\n");
|
||||
return;
|
||||
} else {
|
||||
///预留些接收缓存给其他通信使用
|
||||
recieve_max -= FTP_FILE_DATA_RECIEVE_REMAIN_SIZE;
|
||||
}
|
||||
|
||||
ftp_d->packet_id = 0;
|
||||
ftp_d->packet_id_max = recieve_max / FTP_FILE_DATA_UNIT;
|
||||
recieve_max = ftp_d->packet_id_max * FTP_FILE_DATA_UNIT;
|
||||
|
||||
file_remain = ftp_d->file_size - ftp_d->file_offset;
|
||||
if ((file_remain) < recieve_max) {
|
||||
ftp_d->packet_id_max = file_remain / FTP_FILE_DATA_UNIT;
|
||||
if (file_remain % FTP_FILE_DATA_UNIT) {
|
||||
ftp_d->packet_id_max ++;
|
||||
}
|
||||
}
|
||||
|
||||
if (ftp_d->last_packet) {
|
||||
recieve_max = FTP_FILE_DATA_UNIT;
|
||||
file_offset = 0;
|
||||
} else {
|
||||
file_offset = ftp_d->file_offset;
|
||||
}
|
||||
log_info("[get]recieve_max:%d, file_offset %d\n", recieve_max, file_offset);
|
||||
u8 parm[7] = {0};
|
||||
parm[0] = 0;
|
||||
WRITE_BIG_U16(parm + 1, recieve_max);
|
||||
WRITE_BIG_U32(parm + 3, file_offset);
|
||||
JL_ERR err = JL_CMD_send(JL_OPCODE_FILE_TRANSFER, parm, sizeof(parm), 0, 0, NULL);
|
||||
if (err) {
|
||||
ftp_printf("%s fail!!! %d\n", __FUNCTION__, err);
|
||||
return;
|
||||
}
|
||||
if (ftp_d->get_timeout == 0) {
|
||||
ftp_d->get_timeout = sys_timeout_add(NULL, file_transfer_download_get_timeout, FTP_FILE_DATA_RECIEVE_TIMEOUT);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件路径长度统计
|
||||
@param root_path:根目录, folder:文件夹,filename:文件名
|
||||
@return 文件路径长度
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static u32 creat_path_len(char *root_path, const char *folder, u8 *name, u16 name_len)
|
||||
{
|
||||
u32 len = (strlen(root_path) + name_len + 1);
|
||||
if (folder) {
|
||||
len += strlen(folder);
|
||||
len += strlen("/");
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件路径组装处理
|
||||
@param
|
||||
@return
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void creat_file_path(char *path, char *root_path, const char *folder, u8 *name, u16 name_len)
|
||||
{
|
||||
strcat(path, root_path);
|
||||
if (folder) {
|
||||
strcat(path, folder);
|
||||
strcat(path, "/");
|
||||
}
|
||||
//strcat(path, name);
|
||||
memcpy(path + strlen(path), name, name_len);
|
||||
//log_info("path = %s\n", path);
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件下载拓展参数配置
|
||||
@param OpCode_SN:数据包序列号,data:数据, len:数据长度
|
||||
@return 文件路径长度
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void rcsp_file_transfer_download_parm_extra(u8 OpCode_SN, u8 *data, u16 len)
|
||||
{
|
||||
u8 resp[2] = {0};
|
||||
u8 status = 0;
|
||||
|
||||
resp[0] = data[0];//op
|
||||
|
||||
if (ftp_d) {
|
||||
data += 1;
|
||||
ftp_d->dev_handle = READ_BIG_U32(data);//占用4byte
|
||||
u8 en = *(data + 4);
|
||||
if (FTP_FILE_PACKET_CRC_CHECK_EN && en) {
|
||||
log_info("packet_crc_check enable !!!!!\n");
|
||||
ftp_d->packet_crc_check = 1;
|
||||
} else {
|
||||
log_info("packet_crc_check disable !!!!!\n");
|
||||
ftp_d->packet_crc_check = 0;
|
||||
}
|
||||
resp[1] = ftp_d->packet_crc_check;
|
||||
status = JL_PRO_STATUS_SUCCESS;
|
||||
} else {
|
||||
status = JL_PRO_STATUS_FAIL;
|
||||
}
|
||||
JL_CMD_response_send(JL_OPCODE_DEVICE_PARM_EXTRA, status, OpCode_SN, resp, sizeof(resp), 0, NULL);
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件下载开始
|
||||
@param OpCode_SN:数据包序列号,data:数据, len:数据长度
|
||||
@return 文件路径长度
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int file_transfer_watch_opt(u8 flag, u8 OpCode_SN)
|
||||
{
|
||||
int ret = 0;
|
||||
// 假如当前是大文件传输表盘:
|
||||
if (RCSPDevMapFLASH == ftp_d->dev_handle
|
||||
|| RCSPDevMapFLASH_2 == ftp_d->dev_handle) {
|
||||
// 获取当前root_path
|
||||
char *root_path = NULL;
|
||||
if (ftp_d->dev) {
|
||||
root_path = dev_manager_get_root_path(ftp_d->dev);
|
||||
}
|
||||
#if JL_RCSP_EXTRA_FLASH_OPT
|
||||
ret = rcsp_file_transfer_watch_opt(flag, root_path);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
u16 reason = READ_BIG_U16(&ret);
|
||||
if (3 != flag) {
|
||||
rcsp_file_transfer_close();
|
||||
}
|
||||
JL_CMD_response_send(JL_OPCODE_FILE_TRANSFER_START, JL_PRO_STATUS_FAIL, OpCode_SN, (u8 *)&reason, sizeof(reason), 0, NULL);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// rcsp文件下载开始命令处理
|
||||
void rcsp_file_transfer_download_start(void *priv, u8 OpCode_SN, u8 *data, u16 len)
|
||||
{
|
||||
struct RcspModel *rcspModel = (struct RcspModel *)priv;
|
||||
if (rcspModel == NULL) {
|
||||
return ;
|
||||
}
|
||||
if (ftp_d) {
|
||||
//收到了文件传输开始命令, 停止启动超时处理
|
||||
if (ftp_d->start_timerout) {
|
||||
/* sys_timeout_del(ftp_d->start_timerout); */
|
||||
/* sys_timer_re_run(ftp_d->start_timerout); */
|
||||
sys_timer_modify(ftp_d->start_timerout, FTP_FILE_DATA_RECIEVE_TIMEOUT * 2);
|
||||
/* ftp_d->start_timerout = 0; */
|
||||
}
|
||||
}
|
||||
|
||||
JL_ERR err = 0;
|
||||
///创建文件
|
||||
u32 file_size = READ_BIG_U32(data);//占用4byte
|
||||
u16 file_crc = READ_BIG_U16(data + 4);//占用2byte
|
||||
u8 *file_name = data + 4 + 2;
|
||||
u16 file_name_len = len - 6;
|
||||
if (ftp_d == NULL) {
|
||||
ftp_d = zalloc(sizeof(struct __ftp_download));
|
||||
if (NULL == ftp_d) {
|
||||
log_info("%s, no mem\n", __FUNCTION__);
|
||||
JL_CMD_response_send(JL_OPCODE_FILE_TRANSFER_START, JL_PRO_STATUS_FAIL, OpCode_SN, NULL, 0, 0, NULL);
|
||||
return ;
|
||||
}
|
||||
ftp_d->dev_handle = (u32) - 1;
|
||||
}
|
||||
|
||||
ftp_printf("file_size = %d, file_crc = %x\n", file_size, file_crc);
|
||||
struct __dev *dev = NULL;
|
||||
if (ftp_d->dev_handle == (u32) - 1) {
|
||||
dev = dev_manager_find_spec("sd1", 0);
|
||||
} else {
|
||||
dev = dev_manager_find_spec(rcsp_browser_dev_remap(ftp_d->dev_handle), 0);
|
||||
}
|
||||
if (!dev) {
|
||||
rcsp_file_transfer_close();
|
||||
ftp_printf("no dev online !!\n");
|
||||
JL_CMD_response_send(JL_OPCODE_FILE_TRANSFER_START, JL_PRO_STATUS_FAIL, OpCode_SN, NULL, 0, 0, NULL);
|
||||
return ;
|
||||
}
|
||||
char *root_path = dev_manager_get_root_path(dev);
|
||||
|
||||
ASSERT(root_path);
|
||||
|
||||
|
||||
char *folder = NULL;
|
||||
if (RCSPDevMapSD1 == ftp_d->dev_handle
|
||||
|| RCSPDevMapSD0 == ftp_d->dev_handle) {
|
||||
folder = FTP_DOWNLOAD_FOLDER_NAME;
|
||||
}
|
||||
char *path = zalloc(creat_path_len(root_path, folder, file_name, file_name_len));
|
||||
|
||||
u8 new_file = 0;
|
||||
ASSERT(path);
|
||||
creat_file_path(path, root_path, folder, file_name, file_name_len);
|
||||
ftp_d->dev = dev;
|
||||
ftp_d->file = fopen(path, "r");
|
||||
if (ftp_d->file) {
|
||||
log_info("file exist\n");
|
||||
new_file = 0;
|
||||
fclose(ftp_d->file);
|
||||
ftp_d->file = NULL;
|
||||
} else {
|
||||
log_info("file new\n");
|
||||
new_file = 1;
|
||||
}
|
||||
|
||||
ftp_d->filepath = path;
|
||||
if (file_transfer_watch_opt(new_file, OpCode_SN)) {
|
||||
return;
|
||||
}
|
||||
ftp_d->file = fopen(path, "w+");
|
||||
//free(path);
|
||||
if (ftp_d->file == NULL) {
|
||||
ftp_printf("file create err\n");
|
||||
rcsp_file_transfer_close();
|
||||
///文件打开失败, 回复APP文件传输失败
|
||||
JL_CMD_response_send(JL_OPCODE_FILE_TRANSFER_START, JL_PRO_STATUS_FAIL, OpCode_SN, NULL, 0, 0, NULL);
|
||||
return ;
|
||||
}
|
||||
ftp_d->file_offset = 0;
|
||||
ftp_d->progress = 0;
|
||||
ftp_d->file_crc = file_crc;
|
||||
ftp_d->last_packet = 0;
|
||||
ftp_d->file_size = file_size;
|
||||
if (ftp_d->file_size > sizeof(ftp_d->win)) {
|
||||
if (new_file == 0) {
|
||||
///解析断点续传的文件偏移
|
||||
file_transfer_download_intermittent_parse(ftp_d->file, &ftp_d->file_offset);
|
||||
}
|
||||
if (ftp_d->file_offset == 0 || ftp_d->file_offset > file_size) {
|
||||
log_error("file offset err !! reset offset \n");
|
||||
ftp_d->file_offset = sizeof(ftp_d->win);
|
||||
file_transfer_download_vaild_mark_fill(ftp_d->file, ftp_d->win, ftp_d->file_offset, 0);
|
||||
} else if (ftp_d->file_offset == file_size) {
|
||||
//上次文件已经收完, 进入校验流程
|
||||
log_info("file aready download end \n");
|
||||
file_transfer_download_file_check();
|
||||
return ;
|
||||
}
|
||||
} else {
|
||||
ftp_d->last_packet = 1;
|
||||
}
|
||||
///回复APP文件传输准备就绪
|
||||
u16 file_data_unit = 0;
|
||||
WRITE_BIG_U16(&file_data_unit, FTP_FILE_DATA_UNIT);
|
||||
err = JL_CMD_response_send(JL_OPCODE_FILE_TRANSFER_START, JL_PRO_STATUS_SUCCESS, OpCode_SN, (u8 *)&file_data_unit, sizeof(u16), 0, NULL);
|
||||
if (err == 0) {
|
||||
log_info("%s ok!! file_offset: %d, data unit = %d\n", __FUNCTION__, ftp_d->file_offset, FTP_FILE_DATA_UNIT);
|
||||
///回复启动成功之后,启动数据拉取操作(这里是第一次)
|
||||
//fseek(ftp_d->file, ftp_d->file_offset, SEEK_SET);//重定位下文件位置
|
||||
file_transfer_download_get_data();
|
||||
ftp_d->mark_timer = sys_timer_add(NULL, file_transfer_download_vaild_mark_scan, FTP_FILE_VAILD_MARK_TIMER_UNIT);
|
||||
return ;
|
||||
} else {
|
||||
ftp_printf("%s resp fail!!\n", __FUNCTION__);
|
||||
rcsp_file_transfer_close();
|
||||
ftp_d = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件传输, 重命名处理
|
||||
@param
|
||||
@return
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void rcsp_file_transfer_file_rename(u8 status, u8 *data, u16 len)
|
||||
{
|
||||
if (ftp_d) {
|
||||
if (status == JL_PRO_STATUS_SUCCESS) {
|
||||
log_info("%s !!, %d\n", __FUNCTION__, __LINE__);
|
||||
log_info_hexdump(data, len);
|
||||
file_transfer_watch_opt(-1, 0);
|
||||
//重命名
|
||||
if (file_rename((const char *)data) == 0) {
|
||||
u8 reason = FTP_END_REASON_NONE;
|
||||
int err = JL_CMD_send(JL_OPCODE_FILE_TRANSFER_END, &reason, 1, 1, 0, NULL);
|
||||
if (err) {
|
||||
rcsp_file_transfer_close();
|
||||
}
|
||||
dev_manager_set_valid(ftp_d->dev, 1);
|
||||
file_transfer_watch_opt(2, 0);
|
||||
} else {
|
||||
//有重名的, 重新获取新名称, 如:“xxx_n.mp3”,n为数字
|
||||
int err = JL_CMD_send(JL_OPCODE_FILE_RENAME, NULL, 0, 1, 0, NULL);
|
||||
if (err) {
|
||||
rcsp_file_transfer_close();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ftp_printf("%s fail!! %d\n", __FUNCTION__, status);
|
||||
if (ftp_d->file) {
|
||||
//重命名失败,删除文件
|
||||
log_error("rename file fail, delete file\n");
|
||||
fdelete(ftp_d->file);
|
||||
ftp_d->file = NULL;
|
||||
}
|
||||
rcsp_file_transfer_close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件下载结束(F->A的回复处理)
|
||||
@param status:命令执行状态,data:数据, len:数据长度
|
||||
@return
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void rcsp_file_transfer_download_end(u8 status, u8 *data, u16 len)
|
||||
{
|
||||
if (ftp_d) {
|
||||
ftp_printf("%s status %d\n", __FUNCTION__, status);
|
||||
rcsp_file_transfer_close();
|
||||
}
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件传输,最后一包数据接收处理
|
||||
@param data:数据内容 len:数据长度
|
||||
@return
|
||||
@note 文件传输流程是最后才写文件第一包数据
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void rcsp_file_transfer_download_doing_last_packet(u8 *data, u16 len)
|
||||
{
|
||||
u8 reason = FTP_END_REASON_NONE;
|
||||
JL_ERR err = 0;
|
||||
if (len > FTP_FILE_DATA_UNIT) {
|
||||
log_error("last packet data len err!!\n");
|
||||
reason = FTP_END_REASON_DATA_OVER_LIMIT;
|
||||
err = JL_CMD_send(JL_OPCODE_FILE_TRANSFER_END, &reason, 1, 1, 0, NULL);
|
||||
if (err) {
|
||||
//命令发送失败, 直接停止
|
||||
rcsp_file_transfer_close();
|
||||
}
|
||||
return ;
|
||||
}
|
||||
if (ftp_d->get_timeout) {
|
||||
sys_timeout_del(ftp_d->get_timeout);
|
||||
ftp_d->get_timeout = 0;
|
||||
}
|
||||
log_info("get last packet ok\n");
|
||||
fseek(ftp_d->file, 0, SEEK_SET);
|
||||
int wlen = fwrite(data, len, 1, ftp_d->file);
|
||||
if (wlen != len) {
|
||||
ftp_printf("%s err !! %d\n", __FUNCTION__, wlen);
|
||||
reason = FTP_END_REASON_WRITE_ERR;//文件写异常
|
||||
err = JL_CMD_send(JL_OPCODE_FILE_TRANSFER_END, &reason, 1, 1, 0, NULL);
|
||||
if (err) {
|
||||
//命令发送失败, 直接停止
|
||||
rcsp_file_transfer_close();
|
||||
}
|
||||
} else {
|
||||
//文件接收完成,文件校验
|
||||
file_transfer_download_file_check();
|
||||
}
|
||||
//fseek(ftp_d->file, ftp_d->file_offset, SEEK_SET);
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件传输过程处理(A->F)
|
||||
@param data:数据, len:数据长度
|
||||
@return
|
||||
@note 此过程接收的数据是实际文件传输的内容
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void rcsp_file_transfer_download_doing(u8 *data, u16 len)
|
||||
{
|
||||
if (ftp_d && ftp_d->file) {
|
||||
log_info("id = %d, len = %d\n", data[0], len - 1);
|
||||
|
||||
if (ftp_d->start_timerout) {
|
||||
sys_timer_re_run(ftp_d->start_timerout);
|
||||
}
|
||||
|
||||
if (ftp_d->packet_id != data[0]) {
|
||||
ftp_printf("warning !! packet_id err %d, %d\n", ftp_d->packet_id, data[0]);
|
||||
return ;
|
||||
}
|
||||
|
||||
ftp_d->packet_id ++;
|
||||
|
||||
len -= 1;
|
||||
data += 1;
|
||||
if (ftp_d->packet_crc_check) {
|
||||
u16 packet_crc = READ_BIG_U16(data);//占用2byte
|
||||
len -= 2;
|
||||
data += 2;
|
||||
if (packet_crc != CRC16(data, len)) {
|
||||
log_error("packet crc err !!!!!!!!!!!!!!!!!!!!!\n");
|
||||
ftp_d->packet_crc_err = 1;
|
||||
}
|
||||
if (ftp_d->packet_crc_err) {
|
||||
if (ftp_d->packet_id >= ftp_d->packet_id_max) {
|
||||
ftp_d->packet_crc_err = 0;
|
||||
#if (FTP_FILE_PACKET_CRC_ERR_CONTINUE_EN)
|
||||
//重新拉
|
||||
file_transfer_download_get_data();
|
||||
#else
|
||||
//通知APP停止文件传输, 方便排查问题
|
||||
rcsp_file_transfer_download_active_cancel();
|
||||
#endif//FTP_FILE_PACKET_CRC_ERR_CONTINUE_EN
|
||||
}
|
||||
return ;
|
||||
}
|
||||
ftp_printf("packet crc check done\n");
|
||||
}
|
||||
|
||||
u8 reason = FTP_END_REASON_NONE;
|
||||
int wlen = 0;
|
||||
JL_ERR err = 0;
|
||||
|
||||
if (ftp_d->last_packet) {
|
||||
rcsp_file_transfer_download_doing_last_packet(data, len);
|
||||
return ;
|
||||
}
|
||||
|
||||
if (ftp_d->file_offset >= ftp_d->file_size) {
|
||||
log_error("err, file data is over limit!!\n");
|
||||
reason = FTP_END_REASON_DATA_OVER_LIMIT;//数据超范围
|
||||
err = JL_CMD_send(JL_OPCODE_FILE_TRANSFER_END, &reason, 1, 1, 0, NULL);
|
||||
if (err) {
|
||||
//命令发送失败, 直接停止
|
||||
rcsp_file_transfer_close();
|
||||
}
|
||||
return ;
|
||||
}
|
||||
wdt_clear();
|
||||
wlen = fwrite(data, len, 1, ftp_d->file);
|
||||
if (wlen != len) {
|
||||
ftp_printf("%s err !! %d\n", __FUNCTION__, wlen);
|
||||
reason = FTP_END_REASON_WRITE_ERR;//文件写异常
|
||||
err = JL_CMD_send(JL_OPCODE_FILE_TRANSFER_END, &reason, 1, 1, 0, NULL);
|
||||
if (err) {
|
||||
//命令发送失败, 直接停止
|
||||
rcsp_file_transfer_close();
|
||||
}
|
||||
} else {
|
||||
if (len != FTP_FILE_DATA_UNIT) {
|
||||
ftp_printf("data is not a normal unit !!\n");
|
||||
}
|
||||
ftp_d->file_offset += len;
|
||||
ftp_printf("ftp_d->file_offset:%d, ftp_d->file_size:%d, len:%d\n", ftp_d->file_offset, ftp_d->file_size, len);
|
||||
int cur_progress = ftp_d->file_offset * 100 / ftp_d->file_size;
|
||||
if (ftp_d->progress != cur_progress) {
|
||||
ftp_d->progress = cur_progress;
|
||||
UI_MSG_POST("upgrade:process=%4", cur_progress);
|
||||
}
|
||||
if (ftp_d->file_offset >= ftp_d->file_size) {
|
||||
ftp_printf("file recieve end!! get file first packet\n");
|
||||
if (ftp_d->mark_timer) {
|
||||
sys_timer_del(ftp_d->mark_timer);
|
||||
ftp_d->mark_timer = 0;
|
||||
}
|
||||
ftp_d->last_packet = 1;
|
||||
file_transfer_download_get_data();
|
||||
return;
|
||||
}
|
||||
ftp_d->last_packet = 0;
|
||||
if (ftp_d->get_timeout) {
|
||||
//接收数据成功,重置一下超时
|
||||
ftp_printf("reset timeout!!\n");
|
||||
sys_timer_modify(ftp_d->get_timeout, FTP_FILE_DATA_RECIEVE_TIMEOUT);
|
||||
}
|
||||
if (ftp_d->packet_id >= ftp_d->packet_id_max) {
|
||||
//该次数据包已经收完,拉取新的数据
|
||||
ftp_printf("get more!!\n");
|
||||
file_transfer_download_get_data();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief rcsp_file_transfer_download_progress 文件传输进度
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
int rcsp_file_transfer_download_progress()
|
||||
{
|
||||
if (!ftp_d) {
|
||||
return 0;
|
||||
}
|
||||
int progress = ftp_d->file_offset * 100 / ftp_d->file_size;
|
||||
log_info("%s :%d", __func__, progress);
|
||||
return progress;
|
||||
}
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件传输,被动取消处理
|
||||
@param OpCode_SN:数据包sn码, 回复的时候用的
|
||||
@return
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void rcsp_file_transfer_download_passive_cancel(u8 OpCode_SN, u8 *data, u16 len)
|
||||
{
|
||||
rcsp_file_transfer_close();
|
||||
log_info("passive_cancel answer\n");
|
||||
JL_CMD_response_send(JL_OPCODE_FILE_TRANSFER_CANCEL, JL_PRO_STATUS_SUCCESS, OpCode_SN, NULL, 0, 0, NULL);
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件传输,主动取消处理
|
||||
@param
|
||||
@return
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void rcsp_file_transfer_download_active_cancel(void)
|
||||
{
|
||||
if (ftp_d) {
|
||||
rcsp_file_transfer_close();
|
||||
JL_CMD_send(JL_OPCODE_FILE_TRANSFER_CANCEL, NULL, 0, 1, 0, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件传输,主动取消处理回复处理
|
||||
@param
|
||||
@return
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void rcsp_file_transfer_download_active_cancel_response(u8 status, u8 *data, u16 len)
|
||||
{
|
||||
if (status == JL_PRO_STATUS_SUCCESS) {
|
||||
log_info("active_cancel_response ok!!");
|
||||
}
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件传输关闭处理
|
||||
@param
|
||||
@return
|
||||
@note 主要是做一些资源释放处理
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void rcsp_file_transfer_close(void)
|
||||
{
|
||||
if (ftp_d) {
|
||||
if (ftp_d->check.counter) {
|
||||
log_error("crc caculating !! close err\n");
|
||||
return ;
|
||||
}
|
||||
if (ftp_d->start_timerout) {
|
||||
sys_timeout_del(ftp_d->start_timerout);
|
||||
ftp_d->start_timerout = 0;
|
||||
}
|
||||
if (ftp_d->get_timeout) {
|
||||
sys_timeout_del(ftp_d->get_timeout);
|
||||
ftp_d->get_timeout = 0;
|
||||
}
|
||||
if (ftp_d->mark_timer) {
|
||||
sys_timer_del(ftp_d->mark_timer);
|
||||
ftp_d->mark_timer = 0;
|
||||
}
|
||||
if (ftp_d->file) {
|
||||
if (ftp_d->last_packet == 0) {
|
||||
//文件没有传输完, 如果不是直接断电, 有机会执行更新断点续传的文件偏移信息
|
||||
file_transfer_download_vaild_mark_fill(ftp_d->file, ftp_d->win, ftp_d->file_offset, 1);
|
||||
}
|
||||
fclose(ftp_d->file);
|
||||
ftp_d->file = NULL;
|
||||
}
|
||||
if (ftp_d->filepath) {
|
||||
free(ftp_d->filepath);
|
||||
}
|
||||
|
||||
file_transfer_watch_opt(3, 0);
|
||||
|
||||
if (ftp_d->end_callback) {
|
||||
ftp_d->end_callback();
|
||||
}
|
||||
free(ftp_d);
|
||||
ftp_d = NULL;
|
||||
log_info("rcsp_file_transfer_close!!!!!!\n");
|
||||
}
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件传输启动超时处理
|
||||
@param
|
||||
@return
|
||||
@note 响应app预处理,之后在设定时间内没有发文件传输开始命令过来触发超时
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void file_transfer_start_timeout(void *priv)
|
||||
{
|
||||
log_info("%s\n", __FUNCTION__);
|
||||
rcsp_file_transfer_close();
|
||||
}
|
||||
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件传输初始化处理
|
||||
@param end_callback:文件传输结束处理回调
|
||||
@return
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void rcsp_file_transfer_init(void (*end_callback)(void))
|
||||
{
|
||||
if (ftp_d) {
|
||||
ftp_printf("file downloading err %d!!\n", __LINE__);
|
||||
return ;
|
||||
}
|
||||
ftp_d = zalloc(sizeof(struct __ftp_download));
|
||||
if (ftp_d == NULL) {
|
||||
if (end_callback) {
|
||||
end_callback();
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
//默认不使能每一包文件数据都校验
|
||||
//如果APP有特意发命令过来, 会根据配置打开
|
||||
ftp_d->packet_crc_check = 0;
|
||||
//默认不设置设备, 获取默认最新活动设备
|
||||
ftp_d->dev_handle = (u32) - 1;
|
||||
|
||||
ftp_d->end_callback = end_callback;
|
||||
//如果在超时时间内都没有发文件传输开始命令, 退出文件传输流程
|
||||
ftp_d->start_timerout = sys_timeout_add(NULL, file_transfer_start_timeout, 2000);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
#ifndef __FILE_TRANSFER_H__
|
||||
#define __FILE_TRANSFER_H__
|
||||
|
||||
#include "typedef.h"
|
||||
#include "app_config.h"
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件传输初始化处理
|
||||
@param end_callback:文件传输结束处理回调
|
||||
@return
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void rcsp_file_transfer_init(void (*end_callback)(void));
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件下载拓展参数配置
|
||||
@param OpCode_SN:数据包序列号,data:数据, len:数据长度
|
||||
@return 文件路径长度
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void rcsp_file_transfer_download_parm_extra(u8 OpCode_SN, u8 *data, u16 len);
|
||||
// rcsp文件下载开始命令处理
|
||||
void rcsp_file_transfer_download_start(void *priv, u8 OpCode_SN, u8 *data, u16 len);
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件下载结束(F->A的回复处理)
|
||||
@param status:命令执行状态,data:数据, len:数据长度
|
||||
@return
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void rcsp_file_transfer_download_end(u8 status, u8 *data, u16 len);
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件传输过程处理(A->F)
|
||||
@param data:数据, len:数据长度
|
||||
@return
|
||||
@note 此过程接收的数据是实际文件传输的内容
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void rcsp_file_transfer_download_doing(u8 *data, u16 len);
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件传输,被动取消处理
|
||||
@param OpCode_SN:数据包sn码, 回复的时候用的
|
||||
@return
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void rcsp_file_transfer_download_passive_cancel(u8 OpCode_SN, u8 *data, u16 len);
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件传输,主动取消处理
|
||||
@param
|
||||
@return
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void rcsp_file_transfer_download_active_cancel(void);
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件传输,主动取消处理回复处理
|
||||
@param
|
||||
@return
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void rcsp_file_transfer_download_active_cancel_response(u8 status, u8 *data, u16 len);
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件传输, 重命名处理
|
||||
@param
|
||||
@return
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void rcsp_file_transfer_file_rename(u8 status, u8 *data, u16 len);
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief 文件传输关闭处理
|
||||
@param
|
||||
@return
|
||||
@note 主要是做一些资源释放处理
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void rcsp_file_transfer_close(void);
|
||||
|
||||
#endif//__FILE_TRANSFER_H__
|
||||
|
||||
+978
@@ -0,0 +1,978 @@
|
||||
#include "file_transfer.h"
|
||||
#include "file_delete.h"
|
||||
#include "file_trans_back.h"
|
||||
#include "dev_format.h"
|
||||
#include "btstack/avctp_user.h"
|
||||
#include "app_action.h"
|
||||
#include "fs.h"
|
||||
#include "file_bluk_trans_prepare.h"
|
||||
#include "sensors_data_opt.h"
|
||||
#include "file_simple_transfer.h"
|
||||
#include "custom_cfg.h"
|
||||
#include "JL_rcsp_api.h"
|
||||
#include "mass_data.h"
|
||||
#include "JL_rcsp_packet.h"
|
||||
#include "JL_rcsp_protocol.h"
|
||||
#include "timer.h"
|
||||
|
||||
|
||||
#if (RCSP_MODE)
|
||||
|
||||
#if TCFG_PSRAM_DEV_ENABLE
|
||||
#define MASS_MEMORY_USE_PSRAM 1 // 使用psram保存数据
|
||||
#else
|
||||
#define MASS_MEMORY_USE_PSRAM 0
|
||||
#endif
|
||||
|
||||
|
||||
#define MASS_DATA_OP_PARAM 0 // 参数
|
||||
#define MASS_DATA_OP_DATA 1 // 数据
|
||||
|
||||
#define MASS_DATA_WAY_READ 0 // 获取数据
|
||||
#define MASS_DATA_WAY_WRITE 1 // 发送数据
|
||||
|
||||
#define MASS_DATA_ERR_NO 0 // 成功
|
||||
#define MASS_DATA_ERR_CRC 1 // CRC检验失败
|
||||
#define MASS_DATA_ERR_SEQ 2 // SEQ不对
|
||||
#define MASS_DATA_ERR_TYPE 3 // 数据类型不支持
|
||||
#define MASS_DATA_ERR_WAY 4 // 传输方式不支持
|
||||
#define MASS_DATA_ERR_TOTAL_LEN 5 // 数据长度超范围
|
||||
#define MASS_DATA_ERR_WRITE 6 // 写数据失败
|
||||
#define MASS_DATA_ERR_NO_PARAM 7 // 没有配置参数
|
||||
#define MASS_DATA_ERR_OTHER 0xff // 其他类型错误
|
||||
|
||||
#define MASS_DATA_OP_DATA_SEQ_END BIT(15) // 结束包标识
|
||||
|
||||
#define MASS_DATA_VERSION 0 // 版本号
|
||||
|
||||
// JL_packet_get_tx_max_mtu() - sizeof(JL_PACKET) - 4 - sizeof(struct _MASSDATA_OP_DATA)
|
||||
// JL_packet_get_tx_max_mtu() 通过 set_jl_mtu_send() 配置
|
||||
#define MASS_DATA_DATA_LIMIT 200 // 数据长度限制
|
||||
|
||||
#define MASS_DATA_SEND_TIMEOUT_MS 5000 // 发送超时
|
||||
|
||||
#if 0
|
||||
#define DEBUG_PUT_BUF put_buf
|
||||
#else
|
||||
#define DEBUG_PUT_BUF(...)
|
||||
#endif
|
||||
|
||||
#pragma pack(1)
|
||||
// OP-PARAM
|
||||
struct _MASSDATA_OP_PARAM {
|
||||
u8 way;
|
||||
u8 type;
|
||||
u8 version;
|
||||
u8 dat[0];
|
||||
};
|
||||
|
||||
struct _MASSDATA_OP_PARAM_READ {
|
||||
u16 send_data_limit;
|
||||
u16 recv_data_limit;
|
||||
};
|
||||
|
||||
struct _MASSDATA_OP_PARAM_WRITE {
|
||||
u32 data_len;
|
||||
u16 crc;
|
||||
u16 send_data_limit;
|
||||
u16 recv_data_limit;
|
||||
};
|
||||
|
||||
// OP-PARAM 回复
|
||||
struct _MASSDATA_OP_PARAM_RESPOND {
|
||||
u8 way;
|
||||
u8 type;
|
||||
u8 version;
|
||||
u8 dat[0];
|
||||
};
|
||||
|
||||
struct _MASSDATA_OP_PARAM_RESPOND_READ {
|
||||
u8 result;
|
||||
u32 data_len;
|
||||
u16 crc;
|
||||
u16 send_data_limit;
|
||||
u16 recv_data_limit;
|
||||
};
|
||||
|
||||
struct _MASSDATA_OP_PARAM_RESPOND_WRITE {
|
||||
u8 result;
|
||||
u16 send_data_limit;
|
||||
u16 recv_data_limit;
|
||||
};
|
||||
|
||||
// OP-DATA
|
||||
struct _MASSDATA_OP_DATA {
|
||||
u8 type;
|
||||
u16 seq;
|
||||
u16 crc;
|
||||
u32 offset;
|
||||
u16 len;
|
||||
u8 dat[0];
|
||||
};
|
||||
|
||||
// OP-DATA 回复
|
||||
struct _MASSDATA_OP_DATA_RESPOND {
|
||||
u8 type;
|
||||
u16 seq;
|
||||
u8 result;
|
||||
u8 dat[0];
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
|
||||
// recv
|
||||
struct _MASSDATA_RECV {
|
||||
u32 total_len;
|
||||
u16 crc;
|
||||
u16 seq;
|
||||
u32 w;
|
||||
u8 dat[0];
|
||||
};
|
||||
|
||||
// send
|
||||
struct _MASSDATA_SEND {
|
||||
u8 result;
|
||||
volatile u8 tx_flag : 1; // 1-发送中。0-完成
|
||||
volatile u8 asyn : 1; // 1-异步
|
||||
u16 send_limit;
|
||||
u16 seq;
|
||||
u16 tm;
|
||||
u16 resend_tm;
|
||||
void (*evt_cb)(void *priv, int event);
|
||||
void *evt_cb_priv;
|
||||
u8 *pkt_buf;
|
||||
u16 pkt_len;
|
||||
u16 offset;
|
||||
u16 dat_len;
|
||||
u8 dat[0];
|
||||
};
|
||||
|
||||
|
||||
static struct _MASSDATA_RECV *massdat_rx[MASS_DATA_TYPE_MAX] = {0};
|
||||
static struct _MASSDATA_RECV_CB rx_cb[MASS_DATA_TYPE_MAX] = {0};
|
||||
|
||||
static struct _MASSDATA_SEND *massdat_tx[MASS_DATA_TYPE_MAX] = {0};
|
||||
|
||||
static void mass_data_asyn_send_ready_data(u8 type);
|
||||
static int mass_data_asyn_send_no_wait(u8 type);
|
||||
static void mass_data_asyn_send_release(u8 type, int event);
|
||||
|
||||
extern u8 get_rcsp_connect_status(void);
|
||||
|
||||
#if MASS_MEMORY_USE_PSRAM
|
||||
#include "asm/psram_api.h"
|
||||
#define MASS_MALLOC malloc_psram
|
||||
/* #define MASS_ZALLOC zalloc */
|
||||
#define MASS_FREE free_psram
|
||||
static inline void *MASS_ZALLOC(size_t size)
|
||||
{
|
||||
void *ptr = MASS_MALLOC(size);
|
||||
if (ptr) {
|
||||
memset(ptr, 0, size);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
#else
|
||||
#define MASS_MALLOC malloc
|
||||
#define MASS_ZALLOC zalloc
|
||||
#define MASS_FREE free
|
||||
#endif
|
||||
|
||||
void mass_data_recieve(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len)
|
||||
{
|
||||
u8 *pkt_buf;
|
||||
u16 res_len;
|
||||
u8 result = 0;
|
||||
u8 offset = 0;
|
||||
u8 op = data[offset++];
|
||||
struct _MASSDATA_RECV *p_md_rx;
|
||||
|
||||
log_i("%s, op:%d \n", __func__, op);
|
||||
DEBUG_PUT_BUF(data, len);
|
||||
|
||||
if (op == MASS_DATA_OP_PARAM) {
|
||||
struct _MASSDATA_OP_PARAM op_param;
|
||||
struct _MASSDATA_OP_PARAM_RESPOND *p_respond;
|
||||
struct _MASSDATA_OP_PARAM_RESPOND_READ *p_respond_read;
|
||||
struct _MASSDATA_OP_PARAM_RESPOND_WRITE *p_respond_write;
|
||||
|
||||
memcpy(&op_param, &data[offset], sizeof(struct _MASSDATA_OP_PARAM));
|
||||
offset += sizeof(struct _MASSDATA_OP_PARAM);
|
||||
|
||||
if (op_param.type >= MASS_DATA_TYPE_MAX) {
|
||||
// 不支持数据类型
|
||||
log_e("no support way:%d \n", op_param.type);
|
||||
result = MASS_DATA_ERR_TYPE;
|
||||
goto __op_param_end;
|
||||
}
|
||||
if (op_param.way != MASS_DATA_WAY_WRITE) {
|
||||
// 不支持拉取
|
||||
log_e("no support way:%d \n", op_param.way);
|
||||
result = MASS_DATA_ERR_WAY;
|
||||
goto __op_param_end;
|
||||
}
|
||||
if (massdat_rx[op_param.type]) {
|
||||
MASS_FREE(massdat_rx[op_param.type]);
|
||||
massdat_rx[op_param.type] = NULL;
|
||||
}
|
||||
struct _MASSDATA_OP_PARAM_WRITE op_w;
|
||||
memcpy(&op_w, &data[offset], sizeof(struct _MASSDATA_OP_PARAM_WRITE));
|
||||
offset += sizeof(struct _MASSDATA_OP_PARAM_WRITE);
|
||||
op_w.data_len = READ_BIG_U32(&op_w.data_len);
|
||||
op_w.crc = READ_BIG_U16(&op_w.crc);
|
||||
op_w.send_data_limit = READ_BIG_U16(&op_w.send_data_limit);
|
||||
op_w.recv_data_limit = READ_BIG_U16(&op_w.recv_data_limit);
|
||||
|
||||
log_i("massdat_rx[%d]:%d, crc:0x%x \n", op_param.type, op_w.data_len, op_w.crc);
|
||||
|
||||
if (rx_cb[op_param.type].part_cb) {
|
||||
massdat_rx[op_param.type] = MASS_ZALLOC(sizeof(struct _MASSDATA_RECV));
|
||||
} else {
|
||||
massdat_rx[op_param.type] = MASS_ZALLOC(sizeof(struct _MASSDATA_RECV) + op_w.data_len);
|
||||
}
|
||||
ASSERT(massdat_rx[op_param.type]);
|
||||
massdat_rx[op_param.type]->total_len = op_w.data_len;
|
||||
massdat_rx[op_param.type]->crc = op_w.crc;
|
||||
|
||||
result = 0;
|
||||
/* goto __op_param_end; */
|
||||
|
||||
__op_param_end:
|
||||
log_e("result:%d \n", result);
|
||||
if (op_param.way == MASS_DATA_WAY_READ) {
|
||||
res_len = 1 + sizeof(struct _MASSDATA_OP_PARAM_RESPOND) + sizeof(struct _MASSDATA_OP_PARAM_RESPOND_READ);
|
||||
pkt_buf = MASS_ZALLOC(res_len);
|
||||
ASSERT(pkt_buf);
|
||||
p_respond = (struct _MASSDATA_OP_PARAM_RESPOND *)(pkt_buf + 1);
|
||||
p_respond_read = (struct _MASSDATA_OP_PARAM_RESPOND_READ *)p_respond->dat;
|
||||
p_respond_read->result = result;
|
||||
WRITE_BIG_U16(&p_respond_read->send_data_limit, MASS_DATA_DATA_LIMIT);
|
||||
WRITE_BIG_U16(&p_respond_read->recv_data_limit, MASS_DATA_DATA_LIMIT);
|
||||
} else {
|
||||
res_len = 1 + sizeof(struct _MASSDATA_OP_PARAM_RESPOND) + sizeof(struct _MASSDATA_OP_PARAM_RESPOND_WRITE);
|
||||
pkt_buf = MASS_ZALLOC(res_len);
|
||||
ASSERT(pkt_buf);
|
||||
p_respond = (struct _MASSDATA_OP_PARAM_RESPOND *)(pkt_buf + 1);
|
||||
p_respond_write = (struct _MASSDATA_OP_PARAM_RESPOND_WRITE *)p_respond->dat;
|
||||
p_respond_write->result = result;
|
||||
WRITE_BIG_U16(&p_respond_write->send_data_limit, MASS_DATA_DATA_LIMIT);
|
||||
WRITE_BIG_U16(&p_respond_write->recv_data_limit, MASS_DATA_DATA_LIMIT);
|
||||
}
|
||||
p_respond->way = op_param.way;
|
||||
p_respond->type = op_param.type;
|
||||
p_respond->version = op_param.version;
|
||||
pkt_buf[0] = MASS_DATA_OP_PARAM;
|
||||
|
||||
JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, (u8 *)pkt_buf, res_len, 0, NULL);
|
||||
MASS_FREE(pkt_buf);
|
||||
return ;
|
||||
} else if (op == MASS_DATA_OP_DATA) {
|
||||
struct _MASSDATA_OP_DATA op_data;
|
||||
struct _MASSDATA_OP_DATA_RESPOND *p_data_respond;
|
||||
|
||||
memcpy(&op_data, &data[offset], sizeof(struct _MASSDATA_OP_DATA));
|
||||
offset += sizeof(struct _MASSDATA_OP_DATA);
|
||||
op_data.seq = READ_BIG_U16(&op_data.seq);
|
||||
op_data.crc = READ_BIG_U16(&op_data.crc);
|
||||
op_data.offset = READ_BIG_U16(&op_data.offset);
|
||||
op_data.len = READ_BIG_U16(&op_data.len);
|
||||
|
||||
if (op_data.type >= MASS_DATA_TYPE_MAX) {
|
||||
// 不支持数据类型
|
||||
log_e("no support way:%d \n", op_data.type);
|
||||
result = MASS_DATA_ERR_TYPE;
|
||||
goto __op_data_end;
|
||||
}
|
||||
|
||||
if (massdat_rx[op_data.type] == NULL) {
|
||||
// 没有配置参数
|
||||
result = MASS_DATA_ERR_NO_PARAM;
|
||||
goto __op_data_end;
|
||||
}
|
||||
p_md_rx = massdat_rx[op_data.type];
|
||||
u16 seq = op_data.seq & ~MASS_DATA_OP_DATA_SEQ_END;
|
||||
if (seq != p_md_rx->seq) {
|
||||
// 序列号错误
|
||||
log_e("err seq:%d, %d \n", seq, p_md_rx->seq);
|
||||
result = MASS_DATA_ERR_SEQ;
|
||||
goto __op_data_end;
|
||||
}
|
||||
if ((p_md_rx->w + op_data.len) > p_md_rx->total_len) {
|
||||
// 长度错误
|
||||
log_e("err len0:%d, %d, %d \n", p_md_rx->w, op_data.len, p_md_rx->total_len);
|
||||
result = MASS_DATA_ERR_TOTAL_LEN;
|
||||
goto __op_data_end;
|
||||
}
|
||||
u16 crc = CRC16(&data[offset], op_data.len);
|
||||
if (op_data.crc != crc) {
|
||||
// CRC错误
|
||||
log_e("err crc0:%x, %x \n", op_data.crc, crc);
|
||||
result = MASS_DATA_ERR_CRC;
|
||||
goto __op_data_end;
|
||||
}
|
||||
if (rx_cb[op_data.type].part_cb) {
|
||||
u8 *tmp_buf = (u8 *)MASS_ZALLOC(op_data.len + sizeof(op_data.len));
|
||||
memcpy(tmp_buf, &op_data.len, sizeof(op_data.len));
|
||||
memcpy(tmp_buf + sizeof(op_data.len), &data[offset], op_data.len);
|
||||
|
||||
if (rx_cb[op_data.type].cb) {
|
||||
rx_cb[op_data.type].cb(rx_cb[op_data.type].cb_priv, tmp_buf, p_md_rx->total_len);
|
||||
if (((u8 *)(rx_cb[op_data.type].cb_priv))[0]) {
|
||||
result = MASS_DATA_ERR_WRITE;
|
||||
goto __op_data_end;
|
||||
}
|
||||
}
|
||||
MASS_FREE(tmp_buf);
|
||||
} else {
|
||||
memcpy(&p_md_rx->dat[p_md_rx->w], &data[offset], op_data.len);
|
||||
}
|
||||
p_md_rx->w += op_data.len;
|
||||
p_md_rx->seq = op_data.seq + 1;
|
||||
if (op_data.seq & MASS_DATA_OP_DATA_SEQ_END) {
|
||||
// 结束
|
||||
if (p_md_rx->w != p_md_rx->total_len) {
|
||||
// 长度错误
|
||||
log_e("err len1:%d, %d \n", p_md_rx->w, p_md_rx->total_len);
|
||||
result = MASS_DATA_ERR_TOTAL_LEN;
|
||||
goto __op_data_end;
|
||||
}
|
||||
if (!rx_cb[op_data.type].part_cb) {
|
||||
crc = CRC16(p_md_rx->dat, p_md_rx->total_len);
|
||||
if (p_md_rx->crc != crc) {
|
||||
// CRC错误
|
||||
log_e("err crc1:%x, %x \n", op_data.crc, crc);
|
||||
result = MASS_DATA_ERR_CRC;
|
||||
goto __op_data_end;
|
||||
}
|
||||
}
|
||||
|
||||
log_i("datlen[%d]:%d \n", op_data.type, p_md_rx->total_len);
|
||||
DEBUG_PUT_BUF(p_md_rx->dat, p_md_rx->total_len);
|
||||
|
||||
// 回调处理
|
||||
if ((rx_cb[op_data.type].cb) && (!rx_cb[op_data.type].part_cb)) {
|
||||
rx_cb[op_data.type].cb(rx_cb[op_data.type].cb_priv, p_md_rx->dat, p_md_rx->total_len);
|
||||
}
|
||||
|
||||
// 清除本次传输
|
||||
MASS_FREE(massdat_rx[op_data.type]);
|
||||
massdat_rx[op_data.type] = NULL;
|
||||
}
|
||||
result = 0;
|
||||
/* goto __op_param_end; */
|
||||
|
||||
__op_data_end:
|
||||
log_e("result:%d \n", result);
|
||||
|
||||
if ((rx_cb[op_data.type].part_cb) && (rx_cb[op_data.type].evt_cb)) {
|
||||
// post 失败/成功消息
|
||||
if (op_data.seq & MASS_DATA_OP_DATA_SEQ_END) {
|
||||
rx_cb[op_data.type].evt_cb(rx_cb[op_data.type].cb_priv, MASS_DATA_RECV_EVENT_OK, (void *)&result);
|
||||
} else {
|
||||
if (result) {
|
||||
rx_cb[op_data.type].evt_cb(rx_cb[op_data.type].cb_priv, MASS_DATA_RECV_EVENT_ERROR, (void *)&result);
|
||||
}
|
||||
}
|
||||
}
|
||||
res_len = 1 + sizeof(struct _MASSDATA_OP_DATA_RESPOND) + 4;
|
||||
pkt_buf = MASS_ZALLOC(res_len);
|
||||
ASSERT(pkt_buf);
|
||||
p_data_respond = (struct _MASSDATA_OP_DATA_RESPOND *)(pkt_buf + 1);
|
||||
p_data_respond->type = op_data.type;
|
||||
p_data_respond->seq = op_data.seq;
|
||||
p_data_respond->result = result;
|
||||
WRITE_BIG_U16(&p_data_respond->seq, op_data.seq);
|
||||
pkt_buf[0] = MASS_DATA_OP_DATA;
|
||||
|
||||
JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, (u8 *)pkt_buf, res_len, 0, NULL);
|
||||
MASS_FREE(pkt_buf);
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
||||
void mass_data_respone(void *priv, u8 OpCode, u8 status, u8 *data, u16 len)
|
||||
{
|
||||
u8 offset = 0;
|
||||
u8 op = data[offset++];
|
||||
|
||||
log_i("%s, op:%d \n", __func__, op);
|
||||
DEBUG_PUT_BUF(data, len);
|
||||
|
||||
if (op == MASS_DATA_OP_PARAM) {
|
||||
struct _MASSDATA_OP_PARAM_RESPOND op_param_respond;
|
||||
memcpy(&op_param_respond, &data[offset], sizeof(struct _MASSDATA_OP_PARAM_RESPOND));
|
||||
offset += sizeof(struct _MASSDATA_OP_PARAM_RESPOND);
|
||||
|
||||
if (op_param_respond.way == MASS_DATA_WAY_WRITE) {
|
||||
struct _MASSDATA_OP_PARAM_RESPOND_WRITE op_w;
|
||||
memcpy(&op_w, &data[offset], sizeof(struct _MASSDATA_OP_PARAM_RESPOND_WRITE));
|
||||
offset += sizeof(struct _MASSDATA_OP_PARAM_RESPOND_WRITE);
|
||||
|
||||
u16 send_limit = READ_BIG_U16(&op_w.send_data_limit);
|
||||
u16 recv_limit = READ_BIG_U16(&op_w.recv_data_limit);
|
||||
|
||||
log_i("write[%d] result:%d, limit:%d,%d \n", op_param_respond.type, op_w.result, send_limit, recv_limit);
|
||||
|
||||
if (op_param_respond.type >= MASS_DATA_TYPE_MAX) {
|
||||
log_e("no support type:%d \n", op_param_respond.type);
|
||||
return ;
|
||||
}
|
||||
u8 asyn = 0;
|
||||
local_irq_disable();
|
||||
if (massdat_tx[op_param_respond.type]) {
|
||||
if (send_limit && (massdat_tx[op_param_respond.type]->send_limit > send_limit)) {
|
||||
massdat_tx[op_param_respond.type]->send_limit = send_limit;
|
||||
}
|
||||
massdat_tx[op_param_respond.type]->result = op_w.result;
|
||||
massdat_tx[op_param_respond.type]->tx_flag = 0;
|
||||
if (massdat_tx[op_param_respond.type]->asyn) {
|
||||
asyn = 1;
|
||||
}
|
||||
}
|
||||
local_irq_enable();
|
||||
if (asyn) {
|
||||
if (op_w.result) {
|
||||
mass_data_asyn_send_release(op_param_respond.type, MASS_DATA_SEND_EVENT_RESPOND);
|
||||
} else {
|
||||
mass_data_asyn_send_ready_data(op_param_respond.type);
|
||||
mass_data_asyn_send_no_wait(op_param_respond.type);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log_e("err way:%d \n", op_param_respond.way);
|
||||
}
|
||||
} else if (op == MASS_DATA_OP_DATA) {
|
||||
struct _MASSDATA_OP_DATA_RESPOND op_data_respond;
|
||||
memcpy(&op_data_respond, &data[offset], sizeof(struct _MASSDATA_OP_DATA_RESPOND));
|
||||
offset += sizeof(struct _MASSDATA_OP_DATA_RESPOND);
|
||||
|
||||
u16 seq = READ_BIG_U16(&op_data_respond.seq);
|
||||
log_i("data[%d] result:%d, seq:%d \n", op_data_respond.type, op_data_respond.result, seq);
|
||||
|
||||
if (op_data_respond.type >= MASS_DATA_TYPE_MAX) {
|
||||
log_e("no support type:%d \n", op_data_respond.type);
|
||||
return ;
|
||||
}
|
||||
|
||||
u8 asyn = 0;
|
||||
local_irq_disable();
|
||||
if (massdat_tx[op_data_respond.type]) {
|
||||
massdat_tx[op_data_respond.type]->result = op_data_respond.result;
|
||||
massdat_tx[op_data_respond.type]->tx_flag = 0;
|
||||
if (massdat_tx[op_data_respond.type]->asyn) {
|
||||
asyn = 1;
|
||||
}
|
||||
}
|
||||
local_irq_enable();
|
||||
if (asyn) {
|
||||
if (op_data_respond.result) {
|
||||
mass_data_asyn_send_release(op_data_respond.type, MASS_DATA_SEND_EVENT_RESPOND);
|
||||
} else {
|
||||
massdat_tx[op_data_respond.type]->seq++;
|
||||
massdat_tx[op_data_respond.type]->offset += (massdat_tx[op_data_respond.type]->pkt_len - (1 + sizeof(struct _MASSDATA_OP_DATA)));
|
||||
if (massdat_tx[op_data_respond.type]->offset >= massdat_tx[op_data_respond.type]->dat_len) {
|
||||
mass_data_asyn_send_release(op_data_respond.type, MASS_DATA_SEND_EVENT_OK);
|
||||
} else {
|
||||
mass_data_asyn_send_ready_data(op_data_respond.type);
|
||||
mass_data_asyn_send_no_wait(op_data_respond.type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int mass_data_send_wait(u8 type, u8 *data, u16 len)
|
||||
{
|
||||
int to = 0;
|
||||
massdat_tx[type]->tx_flag = 1;
|
||||
|
||||
log_i("%s, type:%d, len:%d \n", __func__, type, len);
|
||||
DEBUG_PUT_BUF(data, len);
|
||||
|
||||
int result;
|
||||
|
||||
__send:
|
||||
result = JL_CMD_send(JL_OPCODE_MASS_DATA, data, len, JL_NEED_RESPOND, 0, NULL);
|
||||
if (result) {
|
||||
if (result == JL_ERR_SEND_BUSY) {
|
||||
if (to > MASS_DATA_SEND_TIMEOUT_MS) {
|
||||
log_e("send timeout\n");
|
||||
return false;
|
||||
}
|
||||
log_i("send busy \n");
|
||||
os_time_dly(1);
|
||||
to += 10;
|
||||
goto __send;
|
||||
}
|
||||
log_e("send err:%d \n", result);
|
||||
return false;
|
||||
}
|
||||
|
||||
to = 0;
|
||||
#if 0
|
||||
while (!(rcsp_send_list_is_empty() && check_le_pakcet_sent_finish_flag())) {
|
||||
if (!get_rcsp_connect_status()) {
|
||||
// rcsp断开
|
||||
log_e("rcsp disconnect\n");
|
||||
return false;
|
||||
}
|
||||
if (to > MASS_DATA_SEND_TIMEOUT_MS) {
|
||||
log_e("send timeout\n");
|
||||
return false;
|
||||
}
|
||||
os_time_dly(1);
|
||||
to += 10;
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
while (massdat_tx[type]->tx_flag) {
|
||||
if (!get_rcsp_connect_status()) {
|
||||
// rcsp断开
|
||||
log_e("rcsp disconnect\n");
|
||||
return false;
|
||||
}
|
||||
if (to > MASS_DATA_SEND_TIMEOUT_MS) {
|
||||
log_e("send timeout\n");
|
||||
return false;
|
||||
}
|
||||
os_time_dly(1);
|
||||
to += 10;
|
||||
}
|
||||
return massdat_tx[type]->result ? false : true;
|
||||
#endif
|
||||
}
|
||||
|
||||
int mass_data_blocking_send(u8 type, u8 *data, u16 len)
|
||||
{
|
||||
log_i("%s, task:%s, type:%d,len:%d \n", __func__, os_current_task(), type, len);
|
||||
DEBUG_PUT_BUF(data, len);
|
||||
|
||||
if (type >= MASS_DATA_TYPE_MAX) {
|
||||
return false;
|
||||
}
|
||||
local_irq_disable();
|
||||
if (massdat_tx[type]) {
|
||||
local_irq_enable();
|
||||
log_e("why massdat_tx[%d]:0x%x \n", type, massdat_tx[type]);
|
||||
return false;
|
||||
}
|
||||
struct _MASSDATA_SEND *tx_hdl = MASS_ZALLOC(sizeof(struct _MASSDATA_SEND));
|
||||
ASSERT(tx_hdl);
|
||||
massdat_tx[type] = tx_hdl;
|
||||
local_irq_enable();
|
||||
|
||||
int result;
|
||||
int offset = 0;
|
||||
u16 pkt_len = 1 + sizeof(struct _MASSDATA_OP_PARAM) + sizeof(struct _MASSDATA_OP_PARAM_WRITE);
|
||||
u8 *pkt_buf = MASS_ZALLOC(pkt_len);
|
||||
ASSERT(pkt_buf);
|
||||
struct _MASSDATA_OP_PARAM *p_op_param = (struct _MASSDATA_OP_PARAM *)(pkt_buf + 1);
|
||||
struct _MASSDATA_OP_PARAM_WRITE *p_op_w;
|
||||
p_op_w = (struct _MASSDATA_OP_PARAM_WRITE *)p_op_param->dat;
|
||||
|
||||
pkt_buf[0] = MASS_DATA_OP_PARAM;
|
||||
|
||||
p_op_param->way = MASS_DATA_WAY_WRITE;
|
||||
p_op_param->type = type;
|
||||
p_op_param->version = MASS_DATA_VERSION;
|
||||
|
||||
WRITE_BIG_U32(&p_op_w->data_len, len);
|
||||
WRITE_BIG_U16(&p_op_w->crc, CRC16(data, len));
|
||||
WRITE_BIG_U16(&p_op_w->send_data_limit, MASS_DATA_DATA_LIMIT);
|
||||
WRITE_BIG_U16(&p_op_w->recv_data_limit, MASS_DATA_DATA_LIMIT);
|
||||
|
||||
massdat_tx[type]->send_limit = MASS_DATA_DATA_LIMIT;
|
||||
|
||||
result = mass_data_send_wait(type, pkt_buf, pkt_len);
|
||||
MASS_FREE(pkt_buf);
|
||||
if (result == false) {
|
||||
local_irq_disable();
|
||||
MASS_FREE(massdat_tx[type]);
|
||||
massdat_tx[type] = NULL;
|
||||
local_irq_enable();
|
||||
return false;
|
||||
}
|
||||
u16 limit_len = massdat_tx[type]->send_limit;
|
||||
|
||||
pkt_len = 1 + sizeof(struct _MASSDATA_OP_DATA) + limit_len;
|
||||
pkt_buf = MASS_ZALLOC(pkt_len);
|
||||
ASSERT(pkt_buf);
|
||||
struct _MASSDATA_OP_DATA *p_op_data = (struct _MASSDATA_OP_DATA *)(pkt_buf + 1);
|
||||
|
||||
u16 seq = 0;
|
||||
p_op_data->type = type;
|
||||
pkt_buf[0] = MASS_DATA_OP_DATA;
|
||||
|
||||
while (offset < len) {
|
||||
u16 send_len = len - offset;
|
||||
if (send_len > limit_len) {
|
||||
send_len = limit_len;
|
||||
} else {
|
||||
seq |= MASS_DATA_OP_DATA_SEQ_END;
|
||||
}
|
||||
WRITE_BIG_U16(&p_op_data->seq, seq);
|
||||
WRITE_BIG_U16(&p_op_data->crc, CRC16(&data[offset], send_len));
|
||||
WRITE_BIG_U32(&p_op_data->offset, offset);
|
||||
WRITE_BIG_U16(&p_op_data->len, send_len);
|
||||
memcpy(p_op_data->dat, &data[offset], send_len);
|
||||
result = mass_data_send_wait(type, pkt_buf, 1 + sizeof(struct _MASSDATA_OP_DATA) + send_len);
|
||||
if (result == false) {
|
||||
break;
|
||||
}
|
||||
|
||||
seq ++;
|
||||
offset += send_len;
|
||||
}
|
||||
|
||||
MASS_FREE(pkt_buf);
|
||||
|
||||
local_irq_disable();
|
||||
MASS_FREE(massdat_tx[type]);
|
||||
massdat_tx[type] = NULL;
|
||||
local_irq_enable();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void mass_data_asyn_send_release(u8 type, int event)
|
||||
{
|
||||
int evt_func = 0;
|
||||
void *evt_priv;
|
||||
local_irq_disable();
|
||||
if (massdat_tx[type]) {
|
||||
evt_func = (int)massdat_tx[type]->evt_cb;
|
||||
evt_priv = massdat_tx[type]->evt_cb_priv;
|
||||
if (massdat_tx[type]->resend_tm) {
|
||||
sys_timeout_del(massdat_tx[type]->resend_tm);
|
||||
massdat_tx[type]->resend_tm = 0;
|
||||
}
|
||||
if (massdat_tx[type]->tm) {
|
||||
sys_timeout_del(massdat_tx[type]->tm);
|
||||
massdat_tx[type]->tm = 0;
|
||||
}
|
||||
if (massdat_tx[type]->pkt_buf) {
|
||||
MASS_FREE(massdat_tx[type]->pkt_buf);
|
||||
massdat_tx[type]->pkt_buf = NULL;
|
||||
}
|
||||
MASS_FREE(massdat_tx[type]);
|
||||
massdat_tx[type] = NULL;
|
||||
}
|
||||
local_irq_enable();
|
||||
|
||||
log_i("send[%d] relese evt:%d \n", type, event);
|
||||
|
||||
if (evt_func) {
|
||||
((void (*)(void *, int))evt_func)(evt_priv, event);
|
||||
}
|
||||
}
|
||||
|
||||
static void mass_data_asyn_send_to(void *priv)
|
||||
{
|
||||
u8 *type_ptr = (u8 *)priv;
|
||||
u8 type = *type_ptr;
|
||||
if (type >= MASS_DATA_TYPE_MAX) {
|
||||
return ;
|
||||
}
|
||||
log_e("send[%d] timeout\n", type);
|
||||
|
||||
mass_data_asyn_send_release(type, MASS_DATA_SEND_EVENT_TO);
|
||||
}
|
||||
|
||||
static void mass_data_asyn_resend_no_wait(void *priv)
|
||||
{
|
||||
u8 *type_ptr = (u8 *)priv;
|
||||
u8 type = *type_ptr;
|
||||
if (type >= MASS_DATA_TYPE_MAX) {
|
||||
return ;
|
||||
}
|
||||
log_i("resend \n");
|
||||
if (massdat_tx[type]->resend_tm) {
|
||||
sys_timeout_del(massdat_tx[type]->resend_tm);
|
||||
massdat_tx[type]->resend_tm = 0;
|
||||
}
|
||||
int result = mass_data_asyn_send_no_wait(type);
|
||||
if (result == false) {
|
||||
mass_data_asyn_send_release(type, MASS_DATA_SEND_EVENT_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
static void mass_data_asyn_send_ready_param(u8 type)
|
||||
{
|
||||
if (massdat_tx[type]->pkt_buf) {
|
||||
MASS_FREE(massdat_tx[type]->pkt_buf);
|
||||
massdat_tx[type]->pkt_buf = NULL;
|
||||
}
|
||||
massdat_tx[type]->pkt_len = 1 + sizeof(struct _MASSDATA_OP_PARAM) + sizeof(struct _MASSDATA_OP_PARAM_WRITE);
|
||||
massdat_tx[type]->pkt_buf = MASS_ZALLOC(massdat_tx[type]->pkt_len);
|
||||
ASSERT(massdat_tx[type]->pkt_buf);
|
||||
struct _MASSDATA_OP_PARAM *p_op_param = (struct _MASSDATA_OP_PARAM *)(massdat_tx[type]->pkt_buf + 1);
|
||||
struct _MASSDATA_OP_PARAM_WRITE *p_op_w;
|
||||
p_op_w = (struct _MASSDATA_OP_PARAM_WRITE *)p_op_param->dat;
|
||||
|
||||
massdat_tx[type]->pkt_buf[0] = MASS_DATA_OP_PARAM;
|
||||
|
||||
p_op_param->way = MASS_DATA_WAY_WRITE;
|
||||
p_op_param->type = type;
|
||||
p_op_param->version = MASS_DATA_VERSION;
|
||||
|
||||
WRITE_BIG_U32(&p_op_w->data_len, massdat_tx[type]->dat_len);
|
||||
WRITE_BIG_U16(&p_op_w->crc, CRC16(massdat_tx[type]->dat, massdat_tx[type]->dat_len));
|
||||
WRITE_BIG_U16(&p_op_w->send_data_limit, MASS_DATA_DATA_LIMIT);
|
||||
WRITE_BIG_U16(&p_op_w->recv_data_limit, MASS_DATA_DATA_LIMIT);
|
||||
|
||||
massdat_tx[type]->send_limit = MASS_DATA_DATA_LIMIT;
|
||||
|
||||
massdat_tx[type]->tm = sys_timeout_add((void *)&type, mass_data_asyn_send_to, MASS_DATA_SEND_TIMEOUT_MS);
|
||||
}
|
||||
|
||||
static void mass_data_asyn_send_ready_data(u8 type)
|
||||
{
|
||||
if (massdat_tx[type]->pkt_buf) {
|
||||
MASS_FREE(massdat_tx[type]->pkt_buf);
|
||||
massdat_tx[type]->pkt_buf = NULL;
|
||||
}
|
||||
u16 limit_len = massdat_tx[type]->send_limit;
|
||||
|
||||
massdat_tx[type]->pkt_len = 1 + sizeof(struct _MASSDATA_OP_DATA) + limit_len;
|
||||
massdat_tx[type]->pkt_buf = MASS_ZALLOC(massdat_tx[type]->pkt_len);
|
||||
ASSERT(massdat_tx[type]->pkt_buf);
|
||||
struct _MASSDATA_OP_DATA *p_op_data = (struct _MASSDATA_OP_DATA *)(massdat_tx[type]->pkt_buf + 1);
|
||||
|
||||
u16 seq = massdat_tx[type]->seq;
|
||||
p_op_data->type = type;
|
||||
massdat_tx[type]->pkt_buf[0] = MASS_DATA_OP_DATA;
|
||||
|
||||
u16 send_len = massdat_tx[type]->dat_len - massdat_tx[type]->offset;
|
||||
if (send_len > limit_len) {
|
||||
send_len = limit_len;
|
||||
} else {
|
||||
seq |= MASS_DATA_OP_DATA_SEQ_END;
|
||||
}
|
||||
memcpy(p_op_data->dat, &massdat_tx[type]->dat[massdat_tx[type]->offset], send_len);
|
||||
WRITE_BIG_U16(&p_op_data->seq, seq);
|
||||
WRITE_BIG_U16(&p_op_data->crc, CRC16(p_op_data->dat, send_len));
|
||||
WRITE_BIG_U32(&p_op_data->offset, massdat_tx[type]->offset);
|
||||
WRITE_BIG_U16(&p_op_data->len, send_len);
|
||||
massdat_tx[type]->pkt_len = 1 + sizeof(struct _MASSDATA_OP_DATA) + send_len;
|
||||
|
||||
if (massdat_tx[type]->tm) {
|
||||
sys_timeout_del(massdat_tx[type]->tm);
|
||||
massdat_tx[type]->tm = 0;
|
||||
}
|
||||
massdat_tx[type]->tm = sys_timeout_add((void *)&type, mass_data_asyn_send_to, MASS_DATA_SEND_TIMEOUT_MS);
|
||||
}
|
||||
|
||||
static int mass_data_asyn_send_no_wait(u8 type)
|
||||
{
|
||||
int to = 0;
|
||||
massdat_tx[type]->tx_flag = 1;
|
||||
|
||||
log_i("%s, type:%d, len:%d \n", __func__, type, massdat_tx[type]->pkt_len);
|
||||
DEBUG_PUT_BUF(massdat_tx[type]->pkt_buf, massdat_tx[type]->pkt_len);
|
||||
|
||||
int result = JL_CMD_send(JL_OPCODE_MASS_DATA, massdat_tx[type]->pkt_buf, massdat_tx[type]->pkt_len, JL_NEED_RESPOND, 0, NULL);
|
||||
if (result) {
|
||||
if (result == JL_ERR_SEND_BUSY) {
|
||||
log_i("send busy \n");
|
||||
massdat_tx[type]->resend_tm = sys_timeout_add((void *)&type, mass_data_asyn_resend_no_wait, 20);
|
||||
return true;
|
||||
}
|
||||
log_e("send err:%d \n", result);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int mass_data_asyn_send_ex(u8 type, u8 *head, u16 head_len, u8 *data, u16 len, void *evt_cb_priv, void (*evt_cb)(void *priv, int event))
|
||||
{
|
||||
log_i("%s, task:%s, type:%d,len:%d \n", __func__, os_current_task(), type, len);
|
||||
DEBUG_PUT_BUF(data, len);
|
||||
|
||||
if (type >= MASS_DATA_TYPE_MAX) {
|
||||
return false;
|
||||
}
|
||||
struct _MASSDATA_SEND *tx_hdl = MASS_ZALLOC(sizeof(struct _MASSDATA_SEND) + head_len + len);
|
||||
local_irq_disable();
|
||||
if (massdat_tx[type]) {
|
||||
local_irq_enable();
|
||||
MASS_FREE(tx_hdl);
|
||||
log_e("why massdat_tx[%d]:0x%x \n", type, massdat_tx[type]);
|
||||
return false;
|
||||
}
|
||||
ASSERT(tx_hdl);
|
||||
massdat_tx[type] = tx_hdl;
|
||||
massdat_tx[type]->asyn = 1;
|
||||
massdat_tx[type]->dat_len = head_len + len;
|
||||
massdat_tx[type]->evt_cb = evt_cb;
|
||||
massdat_tx[type]->evt_cb_priv = evt_cb_priv;
|
||||
local_irq_enable();
|
||||
|
||||
u8 *dat = massdat_tx[type]->dat;
|
||||
if (head_len) {
|
||||
memcpy(dat, head, head_len);
|
||||
dat += head_len;
|
||||
}
|
||||
memcpy(dat, data, len);
|
||||
|
||||
mass_data_asyn_send_ready_param(type);
|
||||
int result = mass_data_asyn_send_no_wait(type);
|
||||
if (result == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int mass_data_asyn_send(u8 type, u8 *data, u16 len, void *evt_cb_priv, void (*evt_cb)(void *priv, int event))
|
||||
{
|
||||
return mass_data_asyn_send_ex(type, NULL, 0, data, len, evt_cb_priv, evt_cb);
|
||||
}
|
||||
|
||||
void mass_data_recv_register(u8 type, void *cb_priv, void (*cb)(void *priv, u8 *data, int len))
|
||||
{
|
||||
if (type < MASS_DATA_TYPE_MAX) {
|
||||
rx_cb[type].cb_priv = cb_priv;
|
||||
rx_cb[type].cb = cb;
|
||||
}
|
||||
}
|
||||
|
||||
void mass_data_recv_register_ext(u8 type, struct _MASSDATA_RECV_CB *recv_cb)
|
||||
{
|
||||
if (type < MASS_DATA_TYPE_MAX) {
|
||||
memcpy(&rx_cb[type], recv_cb, sizeof(struct _MASSDATA_RECV_CB));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void aliyun_bt_recv_register(void *cb_priv, void (*cb)(void *priv, u8 *data, int len))
|
||||
{
|
||||
mass_data_recv_register(MASS_DATA_TYPE_ALIYUN, cb_priv, cb);
|
||||
}
|
||||
|
||||
int aliyun_bt_data_send(u8 *data, u16 len)
|
||||
{
|
||||
/* return mass_data_blocking_send(MASS_DATA_TYPE_ALIYUN, data, len); */
|
||||
return mass_data_asyn_send(MASS_DATA_TYPE_ALIYUN, data, len, NULL, NULL);
|
||||
}
|
||||
|
||||
int rcsp_overflow_mass_data_send(u8 *data, u16 len)
|
||||
{
|
||||
return mass_data_asyn_send(MASS_DATA_TYPE_RCSP_DATA, data, len, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
#if TCFG_CAT1_MODULE_UPDATE_ENABLE
|
||||
int mass_data_init(void)
|
||||
{
|
||||
rx_cb[MASS_DATA_TYPE_CAT1_UPDATE].part_cb = 1;
|
||||
return 0;
|
||||
}
|
||||
platform_initcall(mass_data_init);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
|
||||
#define TEST_ASYN 1
|
||||
|
||||
static u16 aliyun_test_len;
|
||||
static u8 *aliyun_test_buf = NULL;
|
||||
|
||||
static void test_tm(void *priv)
|
||||
{
|
||||
printf("test_tm \n");
|
||||
aliyun_test_len = rand32() % 4000 + 50;
|
||||
if (aliyun_test_buf) {
|
||||
MASS_FREE(aliyun_test_buf);
|
||||
}
|
||||
aliyun_test_buf = MASS_MALLOC(aliyun_test_len);
|
||||
ASSERT(aliyun_test_buf);
|
||||
|
||||
for (int i = 0; i < aliyun_test_len; i++) {
|
||||
aliyun_test_buf[i] = aliyun_test_len + i;
|
||||
}
|
||||
#if TEST_ASYN
|
||||
mass_data_asyn_send(MASS_DATA_TYPE_ALIYUN, aliyun_test_buf, aliyun_test_len, NULL, NULL);
|
||||
#else
|
||||
mass_data_blocking_send(MASS_DATA_TYPE_ALIYUN, aliyun_test_buf, aliyun_test_len);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int aliyun_test_do(int priv)
|
||||
{
|
||||
sys_timeout_add(NULL, test_tm, 5000);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void test_cb(void *priv, u8 *data, int len)
|
||||
{
|
||||
printf("test_cb:%d \n", len);
|
||||
/* put_buf(data, len); */
|
||||
if (len != aliyun_test_len) {
|
||||
printf("aliyun_test_len:%d \n", aliyun_test_len);
|
||||
while (1);
|
||||
}
|
||||
for (int i = 0; i < aliyun_test_len; i++) {
|
||||
if ((u8)data[i] != (u8)(aliyun_test_buf[i] + 1)) {
|
||||
printf("err i:%d, 0x%x, 0x%x, 0x%x \n", i, data[i], aliyun_test_buf[i], aliyun_test_buf[i] + 1);
|
||||
put_buf(aliyun_test_buf, aliyun_test_len);
|
||||
while (1);
|
||||
}
|
||||
}
|
||||
|
||||
#if TEST_ASYN
|
||||
aliyun_test_do(0);
|
||||
#else
|
||||
// 阻塞发送,不能在蓝牙和app_core任务中
|
||||
if (!strcmp(os_current_task(), "ui")) {
|
||||
aliyun_test_do(0);
|
||||
} else {
|
||||
int msg[3] = {0};
|
||||
msg[0] = (int)aliyun_test_do;
|
||||
msg[1] = 1;
|
||||
do {
|
||||
int os_err = os_taskq_post_type("ui", Q_CALLBACK, 3, msg);
|
||||
if (os_err == OS_ERR_NONE) {
|
||||
break;
|
||||
}
|
||||
if (os_err != OS_Q_FULL) {
|
||||
return ;
|
||||
}
|
||||
os_time_dly(1);
|
||||
} while (1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void aliyun_bt_test(void)
|
||||
{
|
||||
aliyun_bt_recv_register(NULL, test_cb);
|
||||
|
||||
#if TEST_ASYN
|
||||
aliyun_test_do(0);
|
||||
#else
|
||||
// 阻塞发送,不能在蓝牙和app_core任务中
|
||||
if (!strcmp(os_current_task(), "ui")) {
|
||||
aliyun_test_do(0);
|
||||
} else {
|
||||
int msg[3] = {0};
|
||||
msg[0] = (int)aliyun_test_do;
|
||||
msg[1] = 1;
|
||||
do {
|
||||
int os_err = os_taskq_post_type("ui", Q_CALLBACK, 3, msg);
|
||||
if (os_err == OS_ERR_NONE) {
|
||||
break;
|
||||
}
|
||||
if (os_err != OS_Q_FULL) {
|
||||
return ;
|
||||
}
|
||||
os_time_dly(1);
|
||||
} while (1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif//SMART_BOX_EN
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
#ifndef __MASS_DATA_H__
|
||||
#define __MASS_DATA_H__
|
||||
|
||||
#include "typedef.h"
|
||||
#include "app_config.h"
|
||||
|
||||
#define MASS_DATA_TYPE_ORIGINAL 0 // 原始数据
|
||||
#define MASS_DATA_TYPE_ALIYUN 1 // 阿里云
|
||||
#define MASS_DATA_TYPE_RCSP_DATA 2 // RCSP
|
||||
#define MASS_DATA_TYPE_AI_TEXT 3 // AI
|
||||
#define MASS_DATA_TYPE_TTS 4 // TTS
|
||||
#define MASS_DATA_TYPE_VERIFY 5 // 平台接口认证信息
|
||||
#define MASS_DATA_TYPE_ESIM 6 // esim卡
|
||||
#define MASS_DATA_TYPE_CAT1_UPDATE 7 // 4G模块升级数据
|
||||
#define MASS_DATA_TYPE_MAX 8
|
||||
|
||||
#define MASS_DATA_SEND_EVENT_OK 0 // OK
|
||||
#define MASS_DATA_SEND_EVENT_TO 1 // 超时
|
||||
#define MASS_DATA_SEND_EVENT_ERR 2 // 发送失败
|
||||
#define MASS_DATA_SEND_EVENT_RESPOND 3 // 回复出错
|
||||
|
||||
#define MASS_DATA_RECV_EVENT_OK 0 // 完成
|
||||
#define MASS_DATA_RECV_EVENT_ERROR 1 // 出错
|
||||
#define MASS_DATA_RECV_EVENT_TO 2 // 超时
|
||||
|
||||
struct _MASSDATA_RECV_CB {
|
||||
u8 part_cb; // 收到一部分数据后就返回,不等全部收完
|
||||
void (*cb)(void *priv, u8 *data, int len);
|
||||
void *cb_priv;
|
||||
void (*evt_cb)(void *priv, int event, void *evt_param);
|
||||
};
|
||||
|
||||
// 注册收数回调
|
||||
void mass_data_recv_register(u8 type, void *cb_priv, void (*cb)(void *priv, u8 *data, int len));
|
||||
void mass_data_recv_register_ext(u8 type, struct _MASSDATA_RECV_CB *recv_cb);
|
||||
// 非阻塞式发送
|
||||
int mass_data_asyn_send(u8 type, u8 *data, u16 len, void *evt_cb_priv, void (*evt_cb)(void *priv, int event));
|
||||
// 非阻塞式发送。数据与头部分开填数
|
||||
int mass_data_asyn_send_ex(u8 type, u8 *head, u16 head_len, u8 *data, u16 len, void *evt_cb_priv, void (*evt_cb)(void *priv, int event));
|
||||
|
||||
// 阻塞式发送 // 不能在app_core和蓝牙相关任务中调用
|
||||
int mass_data_blocking_send(u8 type, u8 *data, u16 len);
|
||||
|
||||
#endif//__MASS_DATA_H__
|
||||
|
||||
+369
@@ -0,0 +1,369 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".rcsp_adv_bluetooth.data.bss")
|
||||
#pragma data_seg(".rcsp_adv_bluetooth.data")
|
||||
#pragma const_seg(".rcsp_adv_bluetooth.text.const")
|
||||
#pragma code_seg(".rcsp_adv_bluetooth.text")
|
||||
#endif
|
||||
#include "rcsp_config.h"
|
||||
#include "ble_rcsp_server.h"
|
||||
#include "rcsp_adv_bluetooth.h"
|
||||
#include "rcsp_setting_opt.h"
|
||||
#include "rcsp_setting_sync.h"
|
||||
#include "custom_cfg.h"
|
||||
#include "btstack/avctp_user.h"
|
||||
#include "rcsp_manage.h"
|
||||
#include "rcsp_music_info_setting.h"
|
||||
#include "rcsp_bt_manage.h"
|
||||
#include "ble_rcsp_adv.h"
|
||||
#include "JL_rcsp_api.h"
|
||||
#include "JL_rcsp_protocol.h"
|
||||
#include "JL_rcsp_attr.h"
|
||||
|
||||
#if (RCSP_MODE && 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) put_buf(x,len)
|
||||
#else
|
||||
#define rcsp_putchar(...)
|
||||
#define rcsp_printf(...)
|
||||
#define rcsp_printf_buf(...)
|
||||
#endif
|
||||
|
||||
#define JL_OPCODE_SET_DEVICE_REBOOT 0xE7
|
||||
|
||||
extern int get_bt_tws_connect_status();
|
||||
|
||||
static u8 adv_setting_result = 0;
|
||||
static u8 adv_set_deal_one_attr(u8 *buf, u8 size, u8 offset)
|
||||
{
|
||||
u8 rlen = buf[offset];
|
||||
if ((offset + rlen + 1) > (size - offset)) {
|
||||
rcsp_printf("\n\ndeal attr end!\n\n");
|
||||
return rlen;
|
||||
}
|
||||
u8 type = buf[offset + 1];
|
||||
u8 *pbuf = &buf[offset + 2];
|
||||
u8 dlen = rlen - 1;
|
||||
adv_setting_result = 0;
|
||||
|
||||
RCSP_SETTING_OPT *setting_opt_hdl = get_rcsp_setting_opt_hdl(type);
|
||||
if (setting_opt_hdl) {
|
||||
adv_setting_result = set_setting_extra_handle(setting_opt_hdl, pbuf, &dlen);
|
||||
}
|
||||
if (!adv_setting_result) {
|
||||
set_rcsp_opt_setting(setting_opt_hdl, NULL);
|
||||
}
|
||||
|
||||
return rlen + 1;
|
||||
}
|
||||
|
||||
static u32 JL_opcode_set_adv_info(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr)
|
||||
{
|
||||
rcsp_printf("JL_opcode_set_adv_info:\n");
|
||||
rcsp_printf_buf(data, len);
|
||||
u8 offset = 0;
|
||||
while (offset < len) {
|
||||
offset += adv_set_deal_one_attr(data, len, offset);
|
||||
}
|
||||
u8 ret = 0;
|
||||
if (adv_setting_result) {
|
||||
ret = adv_setting_result;
|
||||
JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, &ret, 1, ble_con_handle, spp_remote_addr);
|
||||
} else {
|
||||
JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, &ret, 1, ble_con_handle, spp_remote_addr);
|
||||
}
|
||||
#if TCFG_RCSP_DUAL_CONN_ENABLE
|
||||
// 一拖二则需要手机重新拉取C0设置的设备信息
|
||||
u8 adv_cmd = 0x0;
|
||||
adv_info_device_request(&adv_cmd, sizeof(adv_cmd));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u8 rcsp_adv_get_and_fill_adv_info(u8 *buf, u16 max_len, u8 offset, u8 type)
|
||||
{
|
||||
u8 *adv_data = NULL;
|
||||
RCSP_SETTING_OPT *setting_opt_hdl = get_rcsp_setting_opt_hdl(type);
|
||||
u8 size = get_setting_extra_handle(setting_opt_hdl, &adv_data, NULL);
|
||||
if (size && adv_data) {
|
||||
size = add_one_attr(buf, max_len, offset, type, (void *)adv_data, size);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
extern void bt_adv_get_bat(u8 *buf);
|
||||
static u32 JL_opcode_get_adv_info(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr)
|
||||
{
|
||||
u8 buf[256];
|
||||
u8 offset = 0;
|
||||
|
||||
u32 ret = 0;
|
||||
u32 mask = READ_BIG_U32(data);
|
||||
rcsp_printf("FEATURE MASK : %x\n", mask);
|
||||
/* #define ATTR_TYPE_BAT_VALUE (0) */
|
||||
/* #define ATTR_TYPE_EDR_NAME (1) */
|
||||
//get version
|
||||
if (mask & BIT(ATTR_TYPE_BAT_VALUE)) {
|
||||
rcsp_printf("ATTR_TYPE_BAT_VALUE\n");
|
||||
u8 bat[3];
|
||||
bt_adv_get_bat(bat);
|
||||
offset += add_one_attr(buf, sizeof(buf), offset, ATTR_TYPE_BAT_VALUE, bat, 3);
|
||||
}
|
||||
|
||||
#if RCSP_ADV_NAME_SET_ENABLE
|
||||
if (mask & BIT(ATTR_TYPE_EDR_NAME)) {
|
||||
rcsp_printf("ATTR_TYPE_EDR_NAME\n");
|
||||
offset += rcsp_adv_get_and_fill_adv_info(buf, sizeof(buf), offset, ATTR_TYPE_EDR_NAME);
|
||||
}
|
||||
#endif // RCSP_ADV_NAME_SET_ENABLE
|
||||
|
||||
#if RCSP_ADV_KEY_SET_ENABLE
|
||||
if (mask & BIT(ATTR_TYPE_KEY_SETTING)) {
|
||||
rcsp_printf("ATTR_TYPE_KEY_SETTING\n");
|
||||
offset += rcsp_adv_get_and_fill_adv_info(buf, sizeof(buf), offset, ATTR_TYPE_KEY_SETTING);
|
||||
}
|
||||
if (mask & BIT(ATTR_TYPE_ANC_VOICE_KEY)) {
|
||||
rcsp_printf("ATTR_TYPE_ANC_VOICE_KEY\n");
|
||||
offset += rcsp_adv_get_and_fill_adv_info(buf, sizeof(buf), offset, ATTR_TYPE_ANC_VOICE_KEY);
|
||||
}
|
||||
#endif // RCSP_ADV_KEY_SET_ENABLE
|
||||
|
||||
#if RCSP_ADV_LED_SET_ENABLE
|
||||
if (mask & BIT(ATTR_TYPE_LED_SETTING)) {
|
||||
rcsp_printf("ATTR_TYPE_LED_SETTING\n");
|
||||
offset += rcsp_adv_get_and_fill_adv_info(buf, sizeof(buf), offset, ATTR_TYPE_LED_SETTING);
|
||||
}
|
||||
#endif // RCSP_ADV_LED_SET_ENABLE
|
||||
|
||||
#if RCSP_ADV_MIC_SET_ENABLE
|
||||
if (mask & BIT(ATTR_TYPE_MIC_SETTING)) {
|
||||
rcsp_printf("ATTR_TYPE_MIC_SETTING\n");
|
||||
offset += rcsp_adv_get_and_fill_adv_info(buf, sizeof(buf), offset, ATTR_TYPE_MIC_SETTING);
|
||||
}
|
||||
#endif // RCSP_ADV_MIC_SET_ENABLE
|
||||
|
||||
#if RCSP_ADV_WORK_SET_ENABLE
|
||||
if (mask & BIT(ATTR_TYPE_WORK_MODE)) {
|
||||
rcsp_printf("ATTR_TYPE_WORK_MODE\n");
|
||||
offset += rcsp_adv_get_and_fill_adv_info(buf, sizeof(buf), offset, ATTR_TYPE_WORK_MODE);
|
||||
}
|
||||
#endif // RCSP_ADV_WORK_SET_ENABLE
|
||||
|
||||
#if RCSP_ADV_PRODUCT_MSG_ENABLE
|
||||
if (mask & BIT(ATTR_TYPE_PRODUCT_MESSAGE)) {
|
||||
rcsp_printf("ATTR_TYPE_PRODUCT_MESSAGE\n");
|
||||
u16 vid = get_vid_pid_ver_from_cfg_file(GET_VID_FROM_EX_CFG);
|
||||
u16 pid = get_vid_pid_ver_from_cfg_file(GET_PID_FROM_EX_CFG);
|
||||
u8 tversion[6];
|
||||
tversion[0] = 0x05;
|
||||
tversion[1] = 0xD6;
|
||||
tversion[3] = vid & 0xFF;
|
||||
tversion[2] = vid >> 8;
|
||||
tversion[5] = pid & 0xFF;
|
||||
tversion[4] = pid >> 8;
|
||||
offset += add_one_attr(buf, sizeof(buf), offset, ATTR_TYPE_PRODUCT_MESSAGE, (void *)tversion, 6);
|
||||
}
|
||||
#endif // RCSP_ADV_PRODUCT_MSG_ENABLE
|
||||
|
||||
rcsp_printf_buf(buf, offset);
|
||||
|
||||
ret = JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, buf, offset, ble_con_handle, spp_remote_addr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
u8 adv_info_notify(u8 *buf, u16 len)
|
||||
{
|
||||
return JL_CMD_send(JL_OPCODE_ADV_DEVICE_NOTIFY, buf, len, JL_NOT_NEED_RESPOND, 0, NULL);
|
||||
}
|
||||
|
||||
u8 adv_info_device_request(u8 *buf, u16 len)
|
||||
{
|
||||
printf("JL_OPCODE_ADV_DEVICE_REQUEST\n");
|
||||
return JL_CMD_send(JL_OPCODE_ADV_DEVICE_REQUEST, buf, len, JL_NEED_RESPOND, 0, NULL);
|
||||
}
|
||||
|
||||
int JL_rcsp_adv_cmd_resp(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr)
|
||||
{
|
||||
rcsp_printf("JL_rcsp_adv_cmd_resp\n");
|
||||
switch (OpCode) {
|
||||
case JL_OPCODE_SET_ADV:
|
||||
rcsp_printf(" JL_OPCODE_SET_ADV\n");
|
||||
JL_opcode_set_adv_info(priv, OpCode, OpCode_SN, data, len, ble_con_handle, spp_remote_addr);
|
||||
break;
|
||||
case JL_OPCODE_GET_ADV:
|
||||
rcsp_printf(" JL_OPCODE_GET_ADV\n");
|
||||
JL_opcode_get_adv_info(priv, OpCode, OpCode_SN, data, len, ble_con_handle, spp_remote_addr);
|
||||
break;
|
||||
case JL_OPCODE_ADV_NOTIFY_SETTING:
|
||||
rcsp_printf(" JL_OPCODE_ADV_NOTIFY_SETTING\n");
|
||||
bt_ble_adv_ioctl(BT_ADV_SET_NOTIFY_EN, *((u8 *)data), 1);
|
||||
JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, NULL, 0, ble_con_handle, spp_remote_addr);
|
||||
break;
|
||||
case JL_OPCODE_ADV_DEVICE_REQUEST:
|
||||
rcsp_printf("JL_OPCODE_ADV_DEVICE_REQUEST\n");
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rcsp_wait_reboot_dev(void *priv)
|
||||
{
|
||||
if (NULL == priv && !rcsp_send_list_is_empty()) {
|
||||
return;
|
||||
}
|
||||
bt_cmd_prepare(USER_CTRL_POWER_OFF, 0, NULL);
|
||||
ble_module_enable(0);
|
||||
cpu_reset();
|
||||
}
|
||||
|
||||
static void rcsp_rcsp_reboot_dev(void)
|
||||
{
|
||||
extern void adv_edr_name_change_now(void);
|
||||
adv_edr_name_change_now();
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if (get_bt_tws_connect_status()) {
|
||||
modify_bt_name_and_reset(500);
|
||||
} else {
|
||||
if (sys_timer_add(NULL, rcsp_wait_reboot_dev, 500) == 0) {
|
||||
rcsp_wait_reboot_dev((void *)1);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (sys_timer_add(NULL, rcsp_wait_reboot_dev, 500) == 0) {
|
||||
rcsp_wait_reboot_dev((void *)1);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
int JL_rcsp_adv_event_handler(struct rcsp_event *rcsp)
|
||||
{
|
||||
switch (rcsp->event) {
|
||||
case MSG_JL_REBOOT_DEV:
|
||||
rcsp_rcsp_reboot_dev();
|
||||
break;
|
||||
case MSG_JL_UPDATE_SEQ:
|
||||
printf("MSG_JL_UPDATE_SEQ\n");
|
||||
adv_seq_vaule_sync();
|
||||
break;
|
||||
case MSG_JL_UPDAET_ADV_STATE_INFO:
|
||||
/* if (get_rcsp_connect_status()) { */
|
||||
/* JL_rcsp_set_auth_flag(rcsp->args[0]); */
|
||||
/* bt_ble_adv_ioctl(BT_ADV_SET_NOTIFY_EN, rcsp->args[1], 1); */
|
||||
/* } */
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 获取当前已连接spp数目
|
||||
extern u8 bt_rcsp_spp_conn_num(void);
|
||||
// 下面是弹窗的其他设置
|
||||
int app_core_data_for_send(u8 *packet, u16 size)
|
||||
{
|
||||
//printf("for app send size %d\n", size);
|
||||
|
||||
if (JL_rcsp_get_auth_flag()) {
|
||||
*packet = 1;
|
||||
} else {
|
||||
*packet = 0;
|
||||
}
|
||||
|
||||
if (bt_rcsp_spp_conn_num() > 0) {
|
||||
if (get_ble_adv_notify()) {
|
||||
*(packet + 1) = 1;
|
||||
} else {
|
||||
*(packet + 1) = 0;
|
||||
}
|
||||
|
||||
#if RCSP_ADV_MUSIC_INFO_ENABLE
|
||||
if (get_player_time_en()) {
|
||||
*(packet + 2) = 1;
|
||||
} else {
|
||||
*(packet + 2) = 0;
|
||||
}
|
||||
#else
|
||||
*(packet + 2) = 0;
|
||||
#endif
|
||||
|
||||
*(packet + 3) = get_connect_flag();
|
||||
}
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
#define TWS_FUNC_ID_RCSP_APP_CORE_DATA \
|
||||
(((u8)('R' + 'C' + 'S' + 'P') << (3 * 8)) | \
|
||||
((u8)('A' + 'P' + 'P') << (2 * 8)) | \
|
||||
((u8)('C' + 'O' + 'R' + 'E') << (1 * 8)) | \
|
||||
((u8)('D' + 'A' + 'T' + 'A') << (0 * 8)))
|
||||
|
||||
void app_core_data_for_set(u8 *packet, u16 size);
|
||||
static void rcsp_app_core_data_in_irq(void *_data, u16 len, bool rx)
|
||||
{
|
||||
if (rx) {
|
||||
u8 *data = (u8 *)_data;
|
||||
app_core_data_for_set(data, len);
|
||||
}
|
||||
}
|
||||
|
||||
REGISTER_TWS_FUNC_STUB(tws_rcsp_spp_status) = {
|
||||
.func_id = TWS_FUNC_ID_RCSP_APP_CORE_DATA,
|
||||
.func = rcsp_app_core_data_in_irq,
|
||||
};
|
||||
#endif
|
||||
|
||||
void app_core_data_for_set(u8 *packet, u16 size)
|
||||
{
|
||||
printf("%s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__);
|
||||
/* u8 rcsp_auth_flag = *packet; */
|
||||
u8 ble_adv_notify = *(packet + 1);
|
||||
u8 player_time_en = *(packet + 2);
|
||||
u8 connect_flag = *(packet + 3);
|
||||
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
// 通知从机同步状态
|
||||
if (get_bt_tws_connect_status() && TWS_ROLE_MASTER == tws_api_get_role()) {
|
||||
tws_api_send_data_to_sibling((void *)packet, size, TWS_FUNC_ID_RCSP_APP_CORE_DATA);
|
||||
}
|
||||
#endif
|
||||
set_ble_adv_notify(ble_adv_notify);
|
||||
#if RCSP_ADV_MUSIC_INFO_ENABLE
|
||||
set_player_time_en(player_time_en);
|
||||
#endif
|
||||
set_connect_flag(connect_flag);
|
||||
}
|
||||
|
||||
#elif (defined TCFG_CSC_BT_APP) && TCFG_CSC_BT_APP
|
||||
u8 adv_info_notify(u8 *buf, u16 len)
|
||||
{
|
||||
return JL_CMD_send(JL_OPCODE_ADV_DEVICE_NOTIFY, buf, len, JL_NOT_NEED_RESPOND, 0, NULL);
|
||||
}
|
||||
|
||||
u8 adv_info_device_request(u8 *buf, u16 len)
|
||||
{
|
||||
printf("error!!! %s %d", __func__, __LINE__);
|
||||
return 0;
|
||||
}
|
||||
#else // (RCSP_MODE && RCSP_ADV_EN)
|
||||
|
||||
u8 adv_info_notify(u8 *buf, u16 len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8 adv_info_device_request(u8 *buf, u16 len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
#ifndef __RCSP_ADV_BLUETOOTH__
|
||||
#define __RCSP_ADV_BLUETOOTH__
|
||||
#include "typedef.h"
|
||||
#include "system/event.h"
|
||||
|
||||
|
||||
int JL_rcsp_adv_event_handler(struct rcsp_event *rcsp);
|
||||
int JL_rcsp_adv_cmd_resp(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr);
|
||||
|
||||
/**
|
||||
* @brief 请求手机tws操作C4
|
||||
*/
|
||||
u8 adv_info_device_request(u8 *buf, u16 len);
|
||||
|
||||
#endif
|
||||
+204
@@ -0,0 +1,204 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".rcsp_adv_bluetooth.data.bss")
|
||||
#pragma data_seg(".rcsp_adv_bluetooth.data")
|
||||
#pragma const_seg(".rcsp_adv_bluetooth.text.const")
|
||||
#pragma code_seg(".rcsp_adv_bluetooth.text")
|
||||
#endif
|
||||
#include "rcsp_config.h"
|
||||
#include "ble_rcsp_server.h"
|
||||
#include "rcsp_adv_bluetooth.h"
|
||||
#include "rcsp_setting_opt.h"
|
||||
#include "rcsp_setting_sync.h"
|
||||
#include "custom_cfg.h"
|
||||
#include "btstack/avctp_user.h"
|
||||
#include "rcsp_manage.h"
|
||||
#include "rcsp_music_info_setting.h"
|
||||
#include "rcsp_bt_manage.h"
|
||||
#include "ble_rcsp_adv.h"
|
||||
#include "JL_rcsp_api.h"
|
||||
#include "JL_rcsp_protocol.h"
|
||||
#include "JL_rcsp_attr.h"
|
||||
|
||||
|
||||
#if RCSP_MODE && (!RCSP_ADV_EN)
|
||||
#if (defined TCFG_CSC_BT_APP) && TCFG_CSC_BT_APP
|
||||
|
||||
#define RCSP_DEBUG_EN
|
||||
#ifdef RCSP_DEBUG_EN
|
||||
#define rcsp_putchar(x) putchar(x)
|
||||
#define rcsp_printf printf
|
||||
#define rcsp_printf_buf(x,len) put_buf(x,len)
|
||||
#else
|
||||
#define rcsp_putchar(...)
|
||||
#define rcsp_printf(...)
|
||||
#define rcsp_printf_buf(...)
|
||||
#endif
|
||||
|
||||
|
||||
static u8 adv_setting_result = 0;
|
||||
|
||||
static u8 adv_set_deal_one_attr(u8 *buf, u8 size, u8 offset)
|
||||
{
|
||||
u8 rlen = buf[offset];
|
||||
if ((offset + rlen + 1) > (size - offset)) {
|
||||
rcsp_printf("\n\ndeal attr end!\n\n");
|
||||
return rlen;
|
||||
}
|
||||
u8 type = buf[offset + 1];
|
||||
u8 *pbuf = &buf[offset + 2];
|
||||
u8 dlen = rlen - 1;
|
||||
adv_setting_result = 0;
|
||||
|
||||
RCSP_SETTING_OPT *setting_opt_hdl = get_rcsp_setting_opt_hdl(type);
|
||||
if (setting_opt_hdl) {
|
||||
adv_setting_result = set_setting_extra_handle(setting_opt_hdl, pbuf, &dlen);
|
||||
}
|
||||
if (!adv_setting_result) {
|
||||
set_rcsp_opt_setting(setting_opt_hdl, NULL);
|
||||
}
|
||||
|
||||
return rlen + 1;
|
||||
}
|
||||
|
||||
|
||||
static u32 JL_opcode_set_adv_info(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr)
|
||||
{
|
||||
rcsp_printf("JL_opcode_set_adv_info:\n");
|
||||
rcsp_printf_buf(data, len);
|
||||
u8 offset = 0;
|
||||
while (offset < len) {
|
||||
offset += adv_set_deal_one_attr(data, len, offset);
|
||||
}
|
||||
u8 ret = 0;
|
||||
if (adv_setting_result) {
|
||||
ret = adv_setting_result;
|
||||
JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, &ret, 1, ble_con_handle, spp_remote_addr);
|
||||
} else {
|
||||
JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, &ret, 1, ble_con_handle, spp_remote_addr);
|
||||
}
|
||||
#if TCFG_RCSP_DUAL_CONN_ENABLE
|
||||
// 一拖二则需要手机重新拉取C0设置的设备信息
|
||||
u8 adv_cmd = 0x0;
|
||||
adv_info_device_request(&adv_cmd, sizeof(adv_cmd));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static u8 rcsp_adv_get_and_fill_adv_info(u8 *buf, u16 max_len, u8 offset, u8 type)
|
||||
{
|
||||
u8 *adv_data = NULL;
|
||||
RCSP_SETTING_OPT *setting_opt_hdl = get_rcsp_setting_opt_hdl(type);
|
||||
u8 size = get_setting_extra_handle(setting_opt_hdl, &adv_data, NULL);
|
||||
if (size && adv_data) {
|
||||
size = add_one_attr(buf, max_len, offset, type, (void *)adv_data, size);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
static u32 JL_opcode_get_adv_info(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr)
|
||||
{
|
||||
u8 buf[256] = {0};
|
||||
u8 offset = 0;
|
||||
|
||||
u32 ret = 0;
|
||||
u32 mask = READ_BIG_U32(data);
|
||||
rcsp_printf("FEATURE MASK : %x\n", mask);
|
||||
/* #define ATTR_TYPE_BAT_VALUE (0) */
|
||||
/* #define ATTR_TYPE_EDR_NAME (1) */
|
||||
//get version
|
||||
if (mask & BIT(ATTR_TYPE_BAT_VALUE)) {
|
||||
rcsp_printf("ATTR_TYPE_BAT_VALUE\n");
|
||||
u8 bat[3];
|
||||
void bt_adv_get_bat(u8 * buf);
|
||||
bt_adv_get_bat(bat);
|
||||
offset += add_one_attr(buf, sizeof(buf), offset, ATTR_TYPE_BAT_VALUE, bat, 3);
|
||||
}
|
||||
|
||||
#if RCSP_ADV_NAME_SET_ENABLE
|
||||
if (mask & BIT(ATTR_TYPE_EDR_NAME)) {
|
||||
rcsp_printf("ATTR_TYPE_EDR_NAME\n");
|
||||
offset += rcsp_adv_get_and_fill_adv_info(buf, sizeof(buf), offset, ATTR_TYPE_EDR_NAME);
|
||||
}
|
||||
#endif // RCSP_ADV_NAME_SET_ENABLE
|
||||
|
||||
#if RCSP_ADV_KEY_SET_ENABLE
|
||||
if (mask & BIT(ATTR_TYPE_KEY_SETTING)) {
|
||||
rcsp_printf("ATTR_TYPE_KEY_SETTING\n");
|
||||
offset += rcsp_adv_get_and_fill_adv_info(buf, sizeof(buf), offset, ATTR_TYPE_KEY_SETTING);
|
||||
}
|
||||
if (mask & BIT(ATTR_TYPE_ANC_VOICE_KEY)) {
|
||||
rcsp_printf("ATTR_TYPE_ANC_VOICE_KEY\n");
|
||||
offset += rcsp_adv_get_and_fill_adv_info(buf, sizeof(buf), offset, ATTR_TYPE_ANC_VOICE_KEY);
|
||||
}
|
||||
#endif // RCSP_ADV_KEY_SET_ENABLE
|
||||
|
||||
#if RCSP_ADV_LED_SET_ENABLE
|
||||
if (mask & BIT(ATTR_TYPE_LED_SETTING)) {
|
||||
rcsp_printf("ATTR_TYPE_LED_SETTING\n");
|
||||
offset += rcsp_adv_get_and_fill_adv_info(buf, sizeof(buf), offset, ATTR_TYPE_LED_SETTING);
|
||||
}
|
||||
#endif // RCSP_ADV_LED_SET_ENABLE
|
||||
|
||||
#if RCSP_ADV_MIC_SET_ENABLE
|
||||
if (mask & BIT(ATTR_TYPE_MIC_SETTING)) {
|
||||
rcsp_printf("ATTR_TYPE_MIC_SETTING\n");
|
||||
offset += rcsp_adv_get_and_fill_adv_info(buf, sizeof(buf), offset, ATTR_TYPE_MIC_SETTING);
|
||||
}
|
||||
#endif // RCSP_ADV_MIC_SET_ENABLE
|
||||
|
||||
#if RCSP_ADV_WORK_SET_ENABLE
|
||||
if (mask & BIT(ATTR_TYPE_WORK_MODE)) {
|
||||
rcsp_printf("ATTR_TYPE_WORK_MODE\n");
|
||||
offset += rcsp_adv_get_and_fill_adv_info(buf, sizeof(buf), offset, ATTR_TYPE_WORK_MODE);
|
||||
}
|
||||
#endif // RCSP_ADV_WORK_SET_ENABLE
|
||||
|
||||
#if RCSP_ADV_PRODUCT_MSG_ENABLE
|
||||
if (mask & BIT(ATTR_TYPE_PRODUCT_MESSAGE)) {
|
||||
rcsp_printf("ATTR_TYPE_PRODUCT_MESSAGE\n");
|
||||
u16 vid = get_vid_pid_ver_from_cfg_file(GET_VID_FROM_EX_CFG);
|
||||
u16 pid = get_vid_pid_ver_from_cfg_file(GET_PID_FROM_EX_CFG);
|
||||
u8 tversion[6];
|
||||
tversion[0] = 0x05;
|
||||
tversion[1] = 0xD6;
|
||||
tversion[3] = vid & 0xFF;
|
||||
tversion[2] = vid >> 8;
|
||||
tversion[5] = pid & 0xFF;
|
||||
tversion[4] = pid >> 8;
|
||||
offset += add_one_attr(buf, sizeof(buf), offset, ATTR_TYPE_PRODUCT_MESSAGE, (void *)tversion, 6);
|
||||
}
|
||||
#endif // RCSP_ADV_PRODUCT_MSG_ENABLE
|
||||
|
||||
rcsp_printf_buf(buf, offset);
|
||||
|
||||
ret = JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, buf, offset, ble_con_handle, spp_remote_addr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int JL_rcsp_adv_cmd_resp(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr)
|
||||
{
|
||||
rcsp_printf("JL_rcsp_adv_cmd_resp\n");
|
||||
switch (OpCode) {
|
||||
case JL_OPCODE_SET_ADV:
|
||||
rcsp_printf(" JL_OPCODE_SET_ADV\n");
|
||||
JL_opcode_set_adv_info(priv, OpCode, OpCode_SN, data, len, ble_con_handle, spp_remote_addr);
|
||||
break;
|
||||
case JL_OPCODE_GET_ADV:
|
||||
rcsp_printf(" JL_OPCODE_GET_ADV\n");
|
||||
JL_opcode_get_adv_info(priv, OpCode, OpCode_SN, data, len, ble_con_handle, spp_remote_addr);
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+259
@@ -0,0 +1,259 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".rcsp_setting_opt.data.bss")
|
||||
#pragma data_seg(".rcsp_setting_opt.data")
|
||||
#pragma const_seg(".rcsp_setting_opt.text.const")
|
||||
#pragma code_seg(".rcsp_setting_opt.text")
|
||||
#endif
|
||||
#include "rcsp_config.h"
|
||||
#include "rcsp_setting_opt.h"
|
||||
#include "rcsp_setting_sync.h"
|
||||
#include "rcsp_manage.h"
|
||||
#include "btstack/avctp_user.h"
|
||||
#include "bt_tws.h"
|
||||
#include "rcsp_bt_manage.h"
|
||||
|
||||
|
||||
#if (RCSP_MODE)
|
||||
|
||||
static RCSP_SETTING_OPT *g_opt_link_head = NULL;
|
||||
static u32 g_opt_total_size = 0;
|
||||
|
||||
int register_rcsp_setting_opt_setting(void *opt_param)
|
||||
{
|
||||
RCSP_SETTING_OPT *opt = g_opt_link_head;
|
||||
RCSP_SETTING_OPT *item = (RCSP_SETTING_OPT *)opt_param;
|
||||
while (opt && item) {
|
||||
if (opt->setting_type == item->setting_type) {
|
||||
return 0;
|
||||
}
|
||||
opt = opt->next;
|
||||
}
|
||||
|
||||
if (item) {
|
||||
item->next = g_opt_link_head;
|
||||
g_opt_link_head = item;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static u8 deal_setting_string_item(u8 *des, u8 *src, u8 src_len, u8 type)
|
||||
{
|
||||
u8 offset = 0;
|
||||
if (src_len) {
|
||||
des[offset++] = type;
|
||||
memcpy(des + offset, src, src_len);
|
||||
offset += src_len;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
u8 rcsp_read_data_from_vm(u8 syscfg_id, u8 *buf, u8 buf_len)
|
||||
{
|
||||
/* printf("%s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__); */
|
||||
int len = 0;
|
||||
|
||||
len = syscfg_read(syscfg_id, buf, buf_len);
|
||||
/* if (buf) { */
|
||||
/* put_buf(buf, buf_len); */
|
||||
/* } */
|
||||
|
||||
if (len > 0) {
|
||||
for (int i = 0; i < buf_len; i++) {
|
||||
if (buf[i] != 0xff) {
|
||||
return (buf_len == len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rcsp_setting_init(void)
|
||||
{
|
||||
RCSP_SETTING_OPT *opt = g_opt_link_head;
|
||||
u32 opt_total_size = 0;
|
||||
while (opt) {
|
||||
u8 *data = NULL;
|
||||
if (opt->data_len) {
|
||||
data = zalloc(opt->data_len);
|
||||
}
|
||||
if (opt->custom_setting_init) {
|
||||
opt->custom_setting_init();
|
||||
} else if (rcsp_read_data_from_vm(opt->syscfg_id, data, opt->data_len)) {
|
||||
if (opt->set_setting && opt->deal_opt_setting) {
|
||||
opt->set_setting(data);
|
||||
opt->deal_opt_setting(NULL, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (data) {
|
||||
free(data);
|
||||
}
|
||||
if (opt->data_len) {
|
||||
opt_total_size += (opt->data_len + 1);
|
||||
}
|
||||
opt = opt->next;
|
||||
}
|
||||
|
||||
if (opt_total_size) {
|
||||
g_opt_total_size = opt_total_size + 2;
|
||||
}
|
||||
}
|
||||
|
||||
void update_rcsp_setting(u8 type)
|
||||
{
|
||||
u16 offset = sizeof(u16);
|
||||
u8 *setting_to_sync = NULL;
|
||||
if (g_opt_total_size) {
|
||||
setting_to_sync = zalloc(g_opt_total_size);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
RCSP_SETTING_OPT *opt = g_opt_link_head;
|
||||
|
||||
while (opt) {
|
||||
if (((u8) - 1 == type) || (type == opt->setting_type)) {
|
||||
u8 *data = NULL;
|
||||
if (opt->data_len) {
|
||||
data = zalloc(opt->data_len);
|
||||
}
|
||||
if (opt->custom_setting_update) {
|
||||
opt->custom_setting_update(data);
|
||||
} else if (opt->get_setting && (opt->data_len > 0)) {
|
||||
opt->get_setting(data);
|
||||
}
|
||||
offset += deal_setting_string_item(setting_to_sync + offset, data, opt->data_len, opt->setting_type);
|
||||
if (data) {
|
||||
free(data);
|
||||
}
|
||||
}
|
||||
opt = opt->next;
|
||||
}
|
||||
|
||||
if (offset > sizeof(u16)) {
|
||||
memcpy(setting_to_sync, &offset, sizeof(offset));
|
||||
if (((u8) - 1) == type) {
|
||||
tws_api_send_data_to_sibling(setting_to_sync, offset, TWS_FUNC_ID_ADV_SETTING_SYNC);
|
||||
tws_api_sync_call_by_uuid(TWS_FUNC_APP_OPT_UUID, APP_OPT_SYNC_CMD_APP_RESET_LED_UI, 300);
|
||||
} else {
|
||||
if (tws_api_get_role() == TWS_ROLE_MASTER) {
|
||||
tws_api_send_data_to_sibling(setting_to_sync, offset, TWS_FUNC_ID_ADV_SETTING_SYNC);
|
||||
tws_api_sync_call_by_uuid(TWS_FUNC_APP_OPT_UUID, APP_OPT_SYNC_CMD_APP_RESET_LED_UI, 300);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (setting_to_sync) {
|
||||
free(setting_to_sync);
|
||||
}
|
||||
}
|
||||
|
||||
void deal_sibling_setting(u8 *buf)
|
||||
{
|
||||
u8 type;
|
||||
u16 len = 0;
|
||||
memcpy(&len, buf, sizeof(len));
|
||||
u16 offset = sizeof(len);
|
||||
u8 *data;
|
||||
while (offset < len) {
|
||||
type = buf[offset++];
|
||||
data = buf + offset;
|
||||
RCSP_SETTING_OPT *opt = g_opt_link_head;
|
||||
while (opt) {
|
||||
if (type == opt->setting_type) {
|
||||
if (opt->custom_sibling_setting_deal) {
|
||||
opt->custom_sibling_setting_deal(data);
|
||||
} else if (opt->set_setting) {
|
||||
opt->set_setting(data);
|
||||
}
|
||||
offset += opt->data_len;
|
||||
opt->need_opt = true;
|
||||
break;
|
||||
}
|
||||
opt = opt->next;
|
||||
}
|
||||
}
|
||||
// 发送事件
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_ADV_SETTING_UPDATE, NULL, 0);
|
||||
}
|
||||
|
||||
void update_info_from_vm_info(void)
|
||||
{
|
||||
RCSP_SETTING_OPT *opt = g_opt_link_head;
|
||||
while (opt) {
|
||||
if (opt->need_opt) {
|
||||
if (opt->custom_vm_info_update) {
|
||||
opt->custom_vm_info_update();
|
||||
} else if (opt->deal_opt_setting) {
|
||||
opt->deal_opt_setting(NULL, 1, 0);
|
||||
}
|
||||
opt->need_opt = false;
|
||||
}
|
||||
opt = opt->next;
|
||||
}
|
||||
}
|
||||
|
||||
RCSP_SETTING_OPT *get_rcsp_setting_opt_hdl(u16 setting_type)
|
||||
{
|
||||
RCSP_SETTING_OPT *opt = g_opt_link_head;
|
||||
while (opt) {
|
||||
if (opt->setting_type == setting_type) {
|
||||
return opt;
|
||||
}
|
||||
opt = opt->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void set_rcsp_opt_setting(RCSP_SETTING_OPT *setting_opt_hdl, u8 *data)
|
||||
{
|
||||
if (setting_opt_hdl && setting_opt_hdl->deal_opt_setting) {
|
||||
setting_opt_hdl->deal_opt_setting(data, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
int get_rcsp_opt_setting(RCSP_SETTING_OPT *setting_opt_hdl, u8 *data)
|
||||
{
|
||||
if (setting_opt_hdl && setting_opt_hdl->get_setting) {
|
||||
return setting_opt_hdl->get_setting(data);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_setting_extra_handle(RCSP_SETTING_OPT *setting_opt_hdl, void *data, void *data_len)
|
||||
{
|
||||
if (setting_opt_hdl && setting_opt_hdl->set_setting_extra_handle) {
|
||||
return setting_opt_hdl->set_setting_extra_handle(data, data_len);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int get_setting_extra_handle(RCSP_SETTING_OPT *setting_opt_hdl, void *setting_data, void *setting_data_len)
|
||||
{
|
||||
if (setting_opt_hdl && setting_opt_hdl->get_setting_extra_handle) {
|
||||
return setting_opt_hdl->get_setting_extra_handle(setting_data, setting_data_len);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rcsp_opt_release(void)
|
||||
{
|
||||
RCSP_SETTING_OPT *opt = g_opt_link_head;
|
||||
while (opt) {
|
||||
if (opt->custom_setting_release) {
|
||||
opt->custom_setting_release();
|
||||
}
|
||||
opt = opt->next;
|
||||
}
|
||||
}
|
||||
|
||||
#if RCSP_ADV_EN
|
||||
void modify_bt_name_and_reset(u32 msec)
|
||||
{
|
||||
tws_api_sync_call_by_uuid(TWS_FUNC_ID_ADV_RESET_SYNC, 0, msec);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
#ifndef __RCSP_SETTING_OPT_H__
|
||||
#define __RCSP_SETTING_OPT_H__
|
||||
|
||||
#include "system/includes.h"
|
||||
|
||||
#define REGISTER_APP_SETTING_OPT(rcsp_opt) \
|
||||
int rcsp_opt##_setting_init(void) {\
|
||||
return register_rcsp_setting_opt_setting(&rcsp_opt);\
|
||||
}\
|
||||
late_initcall(rcsp_opt##_setting_init);
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct _RCSP_SETTING_OPT {
|
||||
struct _RCSP_SETTING_OPT *next;
|
||||
bool need_opt;
|
||||
u32 data_len;
|
||||
int setting_type;
|
||||
int syscfg_id;
|
||||
int (*get_setting)(u8 *setting_data);
|
||||
void (*set_setting)(u8 *setting_data);
|
||||
void (*deal_opt_setting)(u8 *setting_data, u8 write_vm, u8 tws_sync);
|
||||
|
||||
// 上面是必填,下面是选填
|
||||
int (*custom_setting_init)(void);
|
||||
int (*custom_vm_info_update)(void);
|
||||
int (*custom_setting_update)(u8 *setting_data);
|
||||
int (*custom_sibling_setting_deal)(u8 *setting_data);
|
||||
int (*custom_setting_release)(void);
|
||||
int (*set_setting_extra_handle)(void *setting_data, void *setting_data_len);
|
||||
int (*get_setting_extra_handle)(void *setting_data, void *setting_data_len);
|
||||
} RCSP_SETTING_OPT;
|
||||
#pragma pack()
|
||||
|
||||
void deal_sibling_setting(u8 *buf);
|
||||
u8 rcsp_read_data_from_vm(u8 syscfg_id, u8 *buf, u8 buf_len);
|
||||
int register_rcsp_setting_opt_setting(void *opt_param);
|
||||
|
||||
RCSP_SETTING_OPT *get_rcsp_setting_opt_hdl(u16 setting_type);
|
||||
void set_rcsp_opt_setting(RCSP_SETTING_OPT *setting_opt, u8 *data);
|
||||
int get_rcsp_opt_setting(RCSP_SETTING_OPT *setting_opt, u8 *data);
|
||||
int set_setting_extra_handle(RCSP_SETTING_OPT *setting_opt_hdl, void *setting_data, void *setting_data_len);
|
||||
int get_setting_extra_handle(RCSP_SETTING_OPT *setting_opt_hdl, void *setting_data, void *setting_data_len);
|
||||
|
||||
void rcsp_setting_init(void);
|
||||
void update_rcsp_setting(u8 type);
|
||||
void update_info_from_vm_info(void);
|
||||
void rcsp_opt_release(void);
|
||||
|
||||
//属于弹窗
|
||||
void modify_bt_name_and_reset(u32 msec);
|
||||
#endif
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".rcsp_setting_sync.data.bss")
|
||||
#pragma data_seg(".rcsp_setting_sync.data")
|
||||
#pragma const_seg(".rcsp_setting_sync.text.const")
|
||||
#pragma code_seg(".rcsp_setting_sync.text")
|
||||
#endif
|
||||
#include "app_config.h"
|
||||
#include "rcsp_setting_sync.h"
|
||||
#include "rcsp_setting_opt.h"
|
||||
#include "adv_time_stamp_setting.h"
|
||||
#include "rcsp_bt_manage.h"
|
||||
#include "rcsp_manage.h"
|
||||
|
||||
#if (RCSP_MODE && TCFG_USER_TWS_ENABLE)
|
||||
#include "btstack/avctp_user.h"
|
||||
#include "bt_tws.h"
|
||||
#include "system/event.h"
|
||||
#include "app_msg.h"
|
||||
|
||||
|
||||
static u16 g_curr_get_adv_sync_tws_len = 0;
|
||||
|
||||
static void rcsp_sync_tws_func_t(void *data, u16 len, bool rx)
|
||||
{
|
||||
if (rx) {
|
||||
g_curr_get_adv_sync_tws_len = len;
|
||||
deal_sibling_setting((u8 *)data);
|
||||
}
|
||||
}
|
||||
|
||||
REGISTER_TWS_FUNC_STUB(adv_tws_sync) = {
|
||||
.func_id = TWS_FUNC_ID_ADV_SETTING_SYNC,
|
||||
.func = rcsp_sync_tws_func_t,
|
||||
};
|
||||
|
||||
static void tws_app_opt_sync_call_fun(int cmd, int err)
|
||||
{
|
||||
struct bt_event bt_e;
|
||||
bt_e.event = APP_OPT_TWS_EVENT_SYNC_FUN_CMD;
|
||||
bt_e.args[0] = 0;
|
||||
bt_e.args[1] = 0;
|
||||
bt_e.args[2] = cmd;
|
||||
struct bt_event *bt_e_p = &bt_e;
|
||||
app_send_message_from(MSG_FROM_RCSP_BT, sizeof(*bt_e_p), (int *)bt_e_p);
|
||||
}
|
||||
|
||||
TWS_SYNC_CALL_REGISTER(tws_tone_sync) = {
|
||||
.uuid = TWS_FUNC_APP_OPT_UUID,
|
||||
.func = tws_app_opt_sync_call_fun,
|
||||
};
|
||||
|
||||
#if RCSP_ADV_EN
|
||||
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,
|
||||
};
|
||||
|
||||
|
||||
static void adv_sync_reset_sync_func_t(int args, int err)
|
||||
{
|
||||
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,
|
||||
};
|
||||
|
||||
static void adv_find_dev_sync_func_t(int args, int err)
|
||||
{
|
||||
/* printf("rcsp_find %s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__); */
|
||||
/* put_buf((u8 *)&args, sizeof(int)); */
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_FIND_DEVICE_RESUME, (u8 *)&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)
|
||||
{
|
||||
/* printf("rcsp_find %s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__); */
|
||||
/* put_buf(param, 3); */
|
||||
int priv = 0;
|
||||
if (TWS_ROLE_MASTER == tws_api_get_role()) {
|
||||
memcpy(&priv, param, 3);
|
||||
/* printf("rcsp_find %s, %s, %d, priv:%d\n", __FILE__, __FUNCTION__, __LINE__, priv); */
|
||||
tws_api_sync_call_by_uuid(TWS_FUNC_ID_ADV_FIND_DEV_SYNC, priv, msec);
|
||||
}
|
||||
}
|
||||
|
||||
static void adv_find_dev_stop_sync_timer_func_t(int args, int err)
|
||||
{
|
||||
/* printf("rcsp_find %s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__); */
|
||||
/* put_buf((u8 *)&args, sizeof(int)); */
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_FIND_DEVICE_STOP, (u8 *)&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,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
void find_device_stop_timer(u8 *param, u32 msec)
|
||||
{
|
||||
/* printf("rcsp_find %s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__); */
|
||||
/* put_buf(param, 3); */
|
||||
int priv = 0;
|
||||
if (TWS_ROLE_MASTER == tws_api_get_role()) {
|
||||
memcpy(&priv, param, 3);
|
||||
/* printf("rcsp_find %s, %s, %d, priv:%d\n", __FILE__, __FUNCTION__, __LINE__, priv); */
|
||||
/* put_buf((u8 *)&priv, sizeof(int)); */
|
||||
tws_api_sync_call_by_uuid(TWS_FUNC_ID_ADV_FIND_DEV_STOP_TIMER_SYNC, priv, msec);
|
||||
}
|
||||
}
|
||||
|
||||
u16 get_adv_sync_tws_len(void)
|
||||
{
|
||||
return (g_curr_get_adv_sync_tws_len > 2) ? (g_curr_get_adv_sync_tws_len - 2) : g_curr_get_adv_sync_tws_len;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
#ifndef __RCSP_SETTING_SYNC_H__
|
||||
#define __RCSP_SETTING_SYNC_H__
|
||||
|
||||
#include "classic/tws_api.h"
|
||||
|
||||
#define TWS_FUNC_ID_ADV_SETTING_SYNC \
|
||||
TWS_FUNC_ID('R', 'C', 'S', 'P')
|
||||
|
||||
#define TWS_FUNC_APP_OPT_UUID \
|
||||
TWS_FUNC_ID('A' + 'P' + 'P', \
|
||||
'O' + 'P' + 'T', \
|
||||
'T' + 'W' + 'S', \
|
||||
'U' + 'U' + 'I' + 'D')
|
||||
|
||||
#define SYS_BT_EVENT_FROM_APP_OPT_TWS \
|
||||
TWS_FUNC_ID('A' + 'P' + 'P', \
|
||||
'O' + 'P' + 'T', \
|
||||
'T' + 'S' + 'S', \
|
||||
'E' + 'V' + 'E' + 'N' + 'T')
|
||||
// ----属于弹窗----
|
||||
#define TWS_FUNC_ID_TIME_STAMP_SYNC \
|
||||
TWS_FUNC_ID('T' + 'W' + 'S', \
|
||||
'A' + 'D' + 'V', \
|
||||
'T' + 'I' + 'M' + 'E', \
|
||||
'S' + 'T' + 'A' + 'M' + 'P')
|
||||
|
||||
#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)))
|
||||
|
||||
#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)))
|
||||
|
||||
#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)))
|
||||
|
||||
#endif
|
||||
// ---------------
|
||||
|
||||
enum {
|
||||
APP_OPT_TWS_EVENT_SYNC_FUN_CMD,
|
||||
};
|
||||
|
||||
enum {
|
||||
APP_OPT_SYNC_CMD_APP_RESET_LED_UI,
|
||||
APP_OPT_SYNC_CMD_MUSIC_INFO,
|
||||
APP_OPT_SYNC_CMD_MUSIC_PLAYER_STATE,
|
||||
APP_OPT_SYNC_CMD_MUSIC_PLAYER_TIEM_EN,
|
||||
};
|
||||
+382
@@ -0,0 +1,382 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".adv_1t2_setting.data.bss")
|
||||
#pragma data_seg(".adv_1t2_setting.data")
|
||||
#pragma const_seg(".adv_1t2_setting.text.const")
|
||||
#pragma code_seg(".adv_1t2_setting.text")
|
||||
#endif
|
||||
#include "adv_1t2_setting.h"
|
||||
#include "app_config.h"
|
||||
#include "rcsp_manage.h"
|
||||
#include "rcsp_bt_manage.h"
|
||||
#include "rcsp_define.h"
|
||||
#include "JL_rcsp_protocol.h"
|
||||
#include "ble_rcsp_server.h"
|
||||
#include "app_ble_spp_api.h"
|
||||
|
||||
#if RCSP_MODE && TCFG_RCSP_DUAL_CONN_ENABLE
|
||||
|
||||
#if RCSP_MODE == RCSP_MODE_EARPHONE
|
||||
#include "earphone.h"
|
||||
#endif
|
||||
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
#include "bt_tws.h"
|
||||
#include "classic/tws_api.h"
|
||||
#endif
|
||||
|
||||
#define DEVICE_NAME_LEN 32 // 缓存设备名长度为32,不可更改该值
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct _rcsp_device_edr_info {
|
||||
u8 is_bind;
|
||||
u8 addr[6];
|
||||
u8 name_len;
|
||||
u8 name[DEVICE_NAME_LEN];
|
||||
u16 ble_con_handle; // 通过协议绑定ble_con_handle
|
||||
} JL_rcsp_device_edr_info;
|
||||
#pragma pack()
|
||||
|
||||
static JL_rcsp_device_edr_info device_edr_info = {0};
|
||||
static JL_rcsp_device_edr_info device_edr_info1 = {0};
|
||||
|
||||
void rcsp_device_edr_info_dump()
|
||||
{
|
||||
return;
|
||||
printf("%s, %d, a isbind:%d, name_len:%d, ble_con_handle:%d\n", __FUNCTION__, __LINE__, device_edr_info.is_bind, device_edr_info.name_len, device_edr_info.ble_con_handle);
|
||||
put_buf(device_edr_info.addr, 6);
|
||||
put_buf(device_edr_info.name, device_edr_info.name_len);
|
||||
printf("%s, %d, b isbind:%d, name_len:%d, ble_con_handle:%d\n", __FUNCTION__, __LINE__, device_edr_info1.is_bind, device_edr_info1.name_len, device_edr_info1.ble_con_handle);
|
||||
put_buf(device_edr_info1.addr, 6);
|
||||
put_buf(device_edr_info1.name, device_edr_info1.name_len);
|
||||
}
|
||||
|
||||
extern u8 bt_rcsp_device_conn_num(void);
|
||||
|
||||
// 获取ble hdl对应的地址
|
||||
extern u8 *rcsp_get_ble_hdl_remote_mac_addr(u16 ble_con_handle);
|
||||
|
||||
/**
|
||||
* @brief 获取rcsp_1t2开关
|
||||
*
|
||||
* @result bool
|
||||
*/
|
||||
bool rcsp_get_1t2_switch()
|
||||
{
|
||||
#if RCSP_MODE == RCSP_MODE_EARPHONE
|
||||
if (get_bt_dual_config() == DUAL_CONN_SET_TWO) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置rcsp_1t2开关
|
||||
*
|
||||
* @param mode_switch 开关
|
||||
*/
|
||||
void rcsp_set_1t2_switch(bool switch_1t2, u16 ble_con_handle, u8 *spp_remote_addr)
|
||||
{
|
||||
printf("%s, switch:%d, ble_con_handle:%d, spp_remote_addr:\n", __FUNCTION__, switch_1t2, ble_con_handle);
|
||||
put_buf(spp_remote_addr, 6);
|
||||
rcsp_device_edr_info_dump();
|
||||
u8 *local_addr = spp_remote_addr;
|
||||
u8 _addr_temp[6] = {0};
|
||||
if (ble_con_handle && !memcmp(spp_remote_addr, _addr_temp, 6)) {
|
||||
// 如果手机没有绑定自己的mac地址,则通过下述api去获取ble的地址,
|
||||
// 此时ble与edr的地址可能相同则该逻辑正确,如果不相同的话则有无法处理的bug
|
||||
local_addr = rcsp_get_ble_hdl_remote_mac_addr(ble_con_handle);
|
||||
}
|
||||
printf("%s, local_addr:", __FUNCTION__);
|
||||
put_buf(local_addr, 6);
|
||||
#if RCSP_MODE == RCSP_MODE_EARPHONE
|
||||
// 断开edr
|
||||
set_dual_conn_config(local_addr, switch_1t2 ? 1 : 0);
|
||||
#else
|
||||
ASSERT(0, "current sdk type is not support 1t2setting!");
|
||||
#endif
|
||||
// 断开ble
|
||||
rcsp_disconn_other_ble(ble_con_handle);
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_1T2_SETTING, NULL, 0);
|
||||
// 根据设置重新判断是否开启蓝牙广播
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if ((tws_api_get_tws_state() & TWS_STA_SIBLING_CONNECTED)) {
|
||||
if (tws_api_get_role() == TWS_ROLE_MASTER) {
|
||||
rcsp_ble_adv_enable_with_con_dev();
|
||||
}
|
||||
}
|
||||
#else
|
||||
rcsp_ble_adv_enable_with_con_dev();
|
||||
#endif
|
||||
}
|
||||
|
||||
void rcsp_1t2_set_edr_info(u8 *addr, u8 *device_name)
|
||||
{
|
||||
if (!addr) {
|
||||
return;
|
||||
}
|
||||
printf("%s, %s, %d, device_name:%s\n", __FILE__, __FUNCTION__, __LINE__, device_name);
|
||||
put_buf(addr, 6);
|
||||
if (memcmp(device_edr_info.addr, addr, 6) && memcmp(device_edr_info1.addr, addr, 6)) {
|
||||
u8 _addr_temp[6] = {0};
|
||||
if (!memcmp(device_edr_info.addr, _addr_temp, 6)) {
|
||||
printf("%s, %d\n", __FUNCTION__, __LINE__);
|
||||
memcpy(device_edr_info.addr, addr, 6);
|
||||
put_buf(device_edr_info.addr, 6);
|
||||
device_edr_info.name_len = strlen((const char *)device_name);
|
||||
if (device_edr_info.name_len) {
|
||||
memcpy(device_edr_info.name, device_name, device_edr_info.name_len);
|
||||
}
|
||||
} else if (!memcmp(device_edr_info1.addr, _addr_temp, 6)) {
|
||||
printf("%s, %d\n", __FUNCTION__, __LINE__);
|
||||
memcpy(device_edr_info1.addr, addr, 6);
|
||||
device_edr_info1.name_len = strlen((const char *)device_name);
|
||||
if (device_edr_info1.name_len) {
|
||||
memcpy(device_edr_info1.name, device_name, device_edr_info1.name_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bt_rcsp_device_conn_num() > 0) {
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if (get_bt_tws_connect_status() && TWS_ROLE_MASTER == tws_api_get_role()) {
|
||||
rcsp_notify_1t2_bt_device_name_list();
|
||||
}
|
||||
#else
|
||||
rcsp_notify_1t2_bt_device_name_list();
|
||||
#endif
|
||||
}
|
||||
rcsp_device_edr_info_dump();
|
||||
rcsp_1t2_setting_tws_sync();
|
||||
}
|
||||
|
||||
void rcsp_1t2_reset_edr_info_for_ble_disconn(u16 ble_con_handle)
|
||||
{
|
||||
if (device_edr_info.ble_con_handle == ble_con_handle) {
|
||||
device_edr_info.is_bind = 0;
|
||||
device_edr_info.ble_con_handle = 0;
|
||||
}
|
||||
if (device_edr_info1.ble_con_handle == ble_con_handle) {
|
||||
device_edr_info1.is_bind = 0;
|
||||
device_edr_info1.ble_con_handle = 0;
|
||||
}
|
||||
rcsp_1t2_setting_tws_sync();
|
||||
rcsp_notify_1t2_bt_device_name_list();
|
||||
/* printf("%s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__); */
|
||||
rcsp_device_edr_info_dump();
|
||||
}
|
||||
|
||||
void rcsp_1t2_reset_edr_info_for_edr_disconn(u8 *addr)
|
||||
{
|
||||
if (!addr) {
|
||||
return;
|
||||
}
|
||||
/* printf("%s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__); */
|
||||
/* put_buf(addr, 6); */
|
||||
u8 _addr_temp[6] = {0};
|
||||
if (memcmp(device_edr_info.addr, _addr_temp, 6)) {
|
||||
/* printf("%s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__); */
|
||||
/* put_buf(device_edr_info.addr, 6); */
|
||||
if (!memcmp(device_edr_info.addr, addr, 6)) {
|
||||
/* printf("%s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__); */
|
||||
rcsp_disconn_designated_ble(device_edr_info.ble_con_handle);
|
||||
memset(&device_edr_info, 0, sizeof(JL_rcsp_device_edr_info));
|
||||
}
|
||||
}
|
||||
if (memcmp(device_edr_info1.addr, _addr_temp, 6)) {
|
||||
/* printf("%s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__); */
|
||||
/* put_buf(device_edr_info1.addr, 6); */
|
||||
if (!memcmp(device_edr_info1.addr, addr, 6)) {
|
||||
/* printf("%s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__); */
|
||||
rcsp_disconn_designated_ble(device_edr_info1.ble_con_handle);
|
||||
memset(&device_edr_info1, 0, sizeof(JL_rcsp_device_edr_info));
|
||||
}
|
||||
}
|
||||
rcsp_1t2_setting_tws_sync();
|
||||
rcsp_notify_1t2_bt_device_name_list();
|
||||
rcsp_device_edr_info_dump();
|
||||
}
|
||||
|
||||
void rcsp_1t2_setting_reset()
|
||||
{
|
||||
/* printf("%s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__); */
|
||||
memset(&device_edr_info, 0, sizeof(JL_rcsp_device_edr_info));
|
||||
memset(&device_edr_info1, 0, sizeof(JL_rcsp_device_edr_info));
|
||||
}
|
||||
|
||||
void rcsp_get_1t2_bt_device_name_list(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr)
|
||||
{
|
||||
/* printf("%s, %d\n", __FUNCTION__, __LINE__); */
|
||||
/* put_buf(data, len); */
|
||||
/* printf("%s, %d, ble_con_handle:%d\n", __FUNCTION__, __LINE__, ble_con_handle); */
|
||||
/* put_buf(spp_remote_addr, 6); */
|
||||
rcsp_device_edr_info_dump();
|
||||
|
||||
u8 is_bind = 0;
|
||||
if (len > 0) {
|
||||
is_bind = data[0];
|
||||
}
|
||||
/* printf("%s, %d, is_bind:%d\n", __FUNCTION__, __LINE__, is_bind); */
|
||||
u8 _addr_temp[6] = {0};
|
||||
bool need_notify = false;
|
||||
if (is_bind) {
|
||||
need_notify = true;
|
||||
// 已绑定信息,更新本地缓存edr信息
|
||||
u8 *phone_addr = data + 1;
|
||||
u8 phone_name_len = data[7];
|
||||
if (!memcmp(device_edr_info.addr, phone_addr, 6)) {
|
||||
/* printf("%s, %d\n", __FUNCTION__, __LINE__); */
|
||||
device_edr_info.is_bind = 1;
|
||||
if (phone_name_len) {
|
||||
memset(device_edr_info.name, 0, DEVICE_NAME_LEN);
|
||||
memcpy(device_edr_info.name, data + 8, phone_name_len);
|
||||
}
|
||||
// iOS绑定ble_con_handle
|
||||
if (ble_con_handle) {
|
||||
device_edr_info.ble_con_handle = ble_con_handle;
|
||||
} else {
|
||||
device_edr_info.ble_con_handle = 0;
|
||||
}
|
||||
}
|
||||
if (!memcmp(device_edr_info1.addr, phone_addr, 6)) {
|
||||
/* printf("%s, %d\n", __FUNCTION__, __LINE__); */
|
||||
device_edr_info1.is_bind = 1;
|
||||
if (phone_name_len) {
|
||||
memset(device_edr_info1.name, 0, DEVICE_NAME_LEN);
|
||||
memcpy(device_edr_info1.name, data + 8, phone_name_len);
|
||||
}
|
||||
// iOS绑定ble_con_handle
|
||||
if (ble_con_handle) {
|
||||
device_edr_info1.ble_con_handle = ble_con_handle;
|
||||
} else {
|
||||
device_edr_info1.ble_con_handle = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// do nothing
|
||||
// 未绑定信息,直接发送本地缓存edr信息
|
||||
}
|
||||
|
||||
// 返回已连接手机列表
|
||||
// device_count + (is_bind + phone_addr + phone_name_len + phone_name) + (...)
|
||||
u8 total_buf_len = 1;
|
||||
u8 device_count = 0;
|
||||
if (memcmp(device_edr_info.addr, _addr_temp, 6)) {
|
||||
device_count++;
|
||||
// 详细见rcsp协议文档C031相关命令
|
||||
total_buf_len += (1 + 6 + 1 + device_edr_info.name_len);
|
||||
}
|
||||
if (memcmp(device_edr_info1.addr, _addr_temp, 6)) {
|
||||
device_count++;
|
||||
total_buf_len += (1 + 6 + 1 + device_edr_info1.name_len);
|
||||
}
|
||||
|
||||
if (device_count == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
u8 *resp = zalloc(total_buf_len);
|
||||
ASSERT(resp, "func = %s, line = %d, no ram!!\n", __FUNCTION__, __LINE__);
|
||||
memcpy(resp, (u8 *)&device_count, 1);
|
||||
u8 buf_index = 1;
|
||||
if (memcmp(device_edr_info.addr, _addr_temp, 6)) {
|
||||
/* printf("%s, %d\n", __FUNCTION__, __LINE__); */
|
||||
memcpy(resp + buf_index, (u8 *)&device_edr_info.is_bind, 1);
|
||||
buf_index += 1;
|
||||
memcpy(resp + buf_index, device_edr_info.addr, 6);
|
||||
buf_index += 6;
|
||||
memcpy(resp + buf_index, (u8 *)&device_edr_info.name_len, 1);
|
||||
buf_index += 1;
|
||||
memcpy(resp + buf_index, device_edr_info.name, device_edr_info.name_len);
|
||||
buf_index += device_edr_info.name_len;
|
||||
}
|
||||
if (memcmp(device_edr_info1.addr, _addr_temp, 6)) {
|
||||
/* printf("%s, %d\n", __FUNCTION__, __LINE__); */
|
||||
memcpy(resp + buf_index, (u8 *)&device_edr_info1.is_bind, 1);
|
||||
buf_index += 1;
|
||||
memcpy(resp + buf_index, device_edr_info1.addr, 6);
|
||||
buf_index += 6;
|
||||
memcpy(resp + buf_index, (u8 *)&device_edr_info1.name_len, 1);
|
||||
buf_index += 1;
|
||||
memcpy(resp + buf_index, device_edr_info1.name, device_edr_info1.name_len);
|
||||
}
|
||||
/* printf("%s, %d\n", __FUNCTION__, __LINE__); */
|
||||
/* put_buf(resp, total_buf_len); */
|
||||
|
||||
if (OpCode == JL_OPCODE_1T2_DEVICE_EDR_INFO_LIST) {
|
||||
/* printf("%s, %d\n", __FUNCTION__, __LINE__); */
|
||||
// 回复
|
||||
JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, resp, total_buf_len, ble_con_handle, spp_remote_addr);
|
||||
} else {
|
||||
/* printf("%s, %d\n", __FUNCTION__, __LINE__); */
|
||||
// 通知
|
||||
JL_CMD_send(JL_OPCODE_1T2_DEVICE_EDR_INFO_LIST, resp, total_buf_len, JL_NOT_NEED_RESPOND, 0, NULL);
|
||||
}
|
||||
if (need_notify) {
|
||||
/* printf("%s, %d\n", __FUNCTION__, __LINE__); */
|
||||
JL_CMD_send(JL_OPCODE_1T2_DEVICE_EDR_INFO_LIST, resp, total_buf_len, JL_NOT_NEED_RESPOND, 0, NULL);
|
||||
}
|
||||
free(resp);
|
||||
|
||||
rcsp_1t2_setting_tws_sync();
|
||||
}
|
||||
|
||||
void rcsp_notify_1t2_bt_device_name_list()
|
||||
{
|
||||
rcsp_get_1t2_bt_device_name_list(NULL, 0, 0, NULL, 0, 0, NULL);
|
||||
}
|
||||
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
#define TWS_FUNC_ID_RCSP_1T2_SETTING \
|
||||
(((u8)('R' + 'C' + 'S' + 'P') << (3 * 8)) | \
|
||||
((u8)('1' + 'T' + '2') << (2 * 8)) | \
|
||||
((u8)('T' + 'W' + 'S') << (1 * 8)) | \
|
||||
((u8)('S' + 'Y' + 'N' + 'C') << (0 * 8)))
|
||||
|
||||
static void rcsp_1t2_setting_tws_sync_in_irq(void *_data, u16 len, bool rx)
|
||||
{
|
||||
if (rx) {
|
||||
u16 info_size = sizeof(JL_rcsp_device_edr_info);
|
||||
memcpy((void *)&device_edr_info, _data, info_size);
|
||||
memcpy((void *)&device_edr_info1, _data + info_size, info_size);
|
||||
/* printf("1t2setting %s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__); */
|
||||
/* put_buf((void *)&device_edr_info, info_size); */
|
||||
/* printf("1t2setting %s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__); */
|
||||
/* put_buf((void *)&device_edr_info1, info_size); */
|
||||
}
|
||||
}
|
||||
|
||||
REGISTER_TWS_FUNC_STUB(tws_rcsp_1t2_setting_sync) = {
|
||||
.func_id = TWS_FUNC_ID_RCSP_1T2_SETTING,
|
||||
.func = rcsp_1t2_setting_tws_sync_in_irq,
|
||||
};
|
||||
|
||||
// tws同步1t2缓存信息
|
||||
void rcsp_1t2_setting_tws_sync(void)
|
||||
{
|
||||
if (get_bt_tws_connect_status() && TWS_ROLE_MASTER == tws_api_get_role()) {
|
||||
u16 info_size = sizeof(JL_rcsp_device_edr_info);
|
||||
u8 buf[sizeof(JL_rcsp_device_edr_info) * 2] = {0};
|
||||
memcpy(buf, (void *)&device_edr_info, info_size);
|
||||
memcpy(buf + info_size, (void *)&device_edr_info1, info_size);
|
||||
/* printf("1t2setting %s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__); */
|
||||
/* put_buf((void *)&device_edr_info, info_size); */
|
||||
/* printf("1t2setting %s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__); */
|
||||
/* put_buf((void *)&device_edr_info1, info_size); */
|
||||
/* printf("1t2setting %s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__); */
|
||||
/* put_buf(buf, sizeof(buf)); */
|
||||
|
||||
tws_api_send_data_to_sibling(buf, sizeof(buf), TWS_FUNC_ID_RCSP_1T2_SETTING);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// tws同步1t2缓存信息
|
||||
void rcsp_1t2_setting_tws_sync(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // TCFG_RCSP_DUAL_CONN_ENABLE
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
#ifndef __ADV_1T2_SETTING_H__
|
||||
#define __ADV_1T2_SETTING_H__
|
||||
|
||||
#include "system/includes.h"
|
||||
|
||||
/**
|
||||
* @brief 获取rcsp_1t2开关
|
||||
*
|
||||
* @result bool
|
||||
*/
|
||||
bool rcsp_get_1t2_switch();
|
||||
|
||||
/**
|
||||
* @brief 设置rcsp_1t2开关
|
||||
*
|
||||
* @param mode_switch 开关
|
||||
*/
|
||||
void rcsp_set_1t2_switch(bool mode_switch, u16 ble_con_handle, u8 *spp_remote_addr);
|
||||
|
||||
/**
|
||||
* @brief edr连接的时候记录地址与手机名
|
||||
*
|
||||
* @param addr
|
||||
* @param device_name // 最长32bytes
|
||||
*/
|
||||
void rcsp_1t2_set_edr_info(u8 *addr, u8 *device_name);
|
||||
|
||||
/**
|
||||
* @brief edr断开连接的时候记录地址与手机名
|
||||
*
|
||||
* @param addr
|
||||
*/
|
||||
void rcsp_1t2_reset_edr_info_for_edr_disconn(u8 *addr);
|
||||
|
||||
/**
|
||||
* @brief edr断开连接的时候记录地址与手机名
|
||||
*
|
||||
* @param addr
|
||||
*/
|
||||
void rcsp_1t2_reset_edr_info_for_ble_disconn(u16 ble_con_handle);
|
||||
|
||||
// 初始化内部buf
|
||||
void rcsp_1t2_setting_reset();
|
||||
|
||||
/**
|
||||
* @brief 获取rcsp_1t2已连接蓝牙设备主机(如手机)名列表
|
||||
*/
|
||||
void rcsp_get_1t2_bt_device_name_list(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr);
|
||||
|
||||
/**
|
||||
* @brief 通知rcsp_1t2已连接蓝牙设备主机(如手机)名列表
|
||||
*/
|
||||
void rcsp_notify_1t2_bt_device_name_list();
|
||||
|
||||
/**
|
||||
* @brief 1t2信息同步到从机
|
||||
*/
|
||||
void rcsp_1t2_setting_tws_sync(void);
|
||||
|
||||
#endif
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".adv_adaptive_noise_reduction.data.bss")
|
||||
#pragma data_seg(".adv_adaptive_noise_reduction.data")
|
||||
#pragma const_seg(".adv_adaptive_noise_reduction.text.const")
|
||||
#pragma code_seg(".adv_adaptive_noise_reduction.text")
|
||||
#endif
|
||||
#include "adv_adaptive_noise_reduction.h"
|
||||
#include "syscfg_id.h"
|
||||
#include "user_cfg_id.h"
|
||||
#include "app_config.h"
|
||||
#include "rcsp_adv_bluetooth.h"
|
||||
|
||||
#if (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
|
||||
|
||||
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
#ifndef __ADV_ADAPTIVE_NOISE_REDUCTION_H__
|
||||
#define __ADV_ADAPTIVE_NOISE_REDUCTION_H__
|
||||
|
||||
#include "system/includes.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
|
||||
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".adv_ai_no_pick.data.bss")
|
||||
#pragma data_seg(".adv_ai_no_pick.data")
|
||||
#pragma const_seg(".adv_ai_no_pick.text.const")
|
||||
#pragma code_seg(".adv_ai_no_pick.text")
|
||||
#endif
|
||||
#include "adv_ai_no_pick.h"
|
||||
#include "app_config.h"
|
||||
#include "rcsp_adv_bluetooth.h"
|
||||
|
||||
#if RCSP_ADV_AI_NO_PICK
|
||||
|
||||
/**
|
||||
* @brief 获取智能免摘开关
|
||||
*
|
||||
* @result bool
|
||||
*/
|
||||
bool get_ai_no_pick_switch()
|
||||
{
|
||||
printf("===%s===", __FUNCTION__);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 开启智能免摘
|
||||
*/
|
||||
void set_ai_no_pick_switch(bool p_switch)
|
||||
{
|
||||
printf("%s, switch:%d", __FUNCTION__, p_switch);
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_AI_NO_PICK, NULL, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取智能免摘敏感度
|
||||
*
|
||||
* @result RCSP_AI_NO_PICK_SENSITIVITY
|
||||
*/
|
||||
RCSP_AI_NO_PICK_SENSITIVITY get_ai_no_pick_sensitivity()
|
||||
{
|
||||
printf("===%s===", __FUNCTION__);
|
||||
return RCSP_AI_NO_PICK_SENSITIVITY_HIGH;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置智能免摘敏感度
|
||||
*/
|
||||
void set_ai_no_pick_sensitivity(RCSP_AI_NO_PICK_SENSITIVITY sensitivity)
|
||||
{
|
||||
switch (sensitivity) {
|
||||
case RCSP_AI_NO_PICK_SENSITIVITY_HIGH:
|
||||
case RCSP_AI_NO_PICK_SENSITIVITY_LOW:
|
||||
default:
|
||||
printf("%s, sensitivity:%d", __FUNCTION__, sensitivity);
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_AI_NO_PICK, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取智能免摘自动关闭时间
|
||||
*
|
||||
* @result RCSP_AI_NO_PICK_AUTO_CLOSE_TIME
|
||||
*/
|
||||
RCSP_AI_NO_PICK_AUTO_CLOSE_TIME get_ai_no_pick_auto_close_time()
|
||||
{
|
||||
printf("===%s===", __FUNCTION__);
|
||||
return RCSP_AI_NO_PICK_AUTO_CLOSE_TIME_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置智能免摘自动关闭时间
|
||||
*/
|
||||
void set_ai_no_pick_auto_close_time(RCSP_AI_NO_PICK_AUTO_CLOSE_TIME time_type)
|
||||
{
|
||||
switch (time_type) {
|
||||
case RCSP_AI_NO_PICK_AUTO_CLOSE_TIME_NONE:
|
||||
case RCSP_AI_NO_PICK_AUTO_CLOSE_TIME_5s:
|
||||
case RCSP_AI_NO_PICK_AUTO_CLOSE_TIME_15s:
|
||||
case RCSP_AI_NO_PICK_AUTO_CLOSE_TIME_30s:
|
||||
default:
|
||||
printf("%s, type:%d", __FUNCTION__, time_type);
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_AI_NO_PICK, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+54
@@ -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__
|
||||
+668
@@ -0,0 +1,668 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".adv_anc_voice.data.bss")
|
||||
#pragma data_seg(".adv_anc_voice.data")
|
||||
#pragma const_seg(".adv_anc_voice.text.const")
|
||||
#pragma code_seg(".adv_anc_voice.text")
|
||||
#endif
|
||||
#include "app_config.h"
|
||||
#include "syscfg_id.h"
|
||||
#include "user_cfg_id.h"
|
||||
#include "ble_rcsp_server.h"
|
||||
#include "smartbox_user_app.h"
|
||||
#include "adv_anc_voice.h"
|
||||
#include "rcsp_setting_sync.h"
|
||||
#include "rcsp_setting_opt.h"
|
||||
#include "rcsp_manage.h"
|
||||
#include "rcsp_bt_manage.h"
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
#include "bt_tws.h"
|
||||
#endif
|
||||
|
||||
|
||||
#define LOG_TAG_CONST APP
|
||||
#define LOG_TAG "[RCSP-ANC]"
|
||||
#define LOG_ERROR_ENABLE
|
||||
#define LOG_DEBUG_ENABLE
|
||||
#define LOG_INFO_ENABLE
|
||||
#define LOG_DUMP_ENABLE
|
||||
#define LOG_CHAR_ENABLE
|
||||
#include "debug.h"
|
||||
|
||||
#if (RCSP_MODE && 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 u8 rcsp_adv_anc_event_flag = 0x0;
|
||||
|
||||
static void enable_adv_anc_event(void)
|
||||
{
|
||||
rcsp_adv_anc_event_flag = 1;
|
||||
}
|
||||
|
||||
static u8 get_adv_anc_event_status(void)
|
||||
{
|
||||
return rcsp_adv_anc_event_flag;
|
||||
}
|
||||
|
||||
static void disable_adv_anc_event(void)
|
||||
{
|
||||
rcsp_adv_anc_event_flag = 0;
|
||||
}
|
||||
|
||||
static bool check_pos_neg(u8 mode)
|
||||
{
|
||||
bool ret = false;
|
||||
u8 offset = 1 + mode * 8;
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if ('R' == bt_tws_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;
|
||||
}
|
||||
|
||||
int get_anc_voice_info(u8 *anc_info)
|
||||
{
|
||||
memcpy(anc_info, g_anc_info, sizeof(g_anc_info));
|
||||
return 0;
|
||||
}
|
||||
|
||||
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)); */
|
||||
update_rcsp_setting(ATTR_TYPE_ANC_VOICE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static u8 count_the_num_of_positions(u16 value)
|
||||
{
|
||||
u8 cnt;
|
||||
for (cnt = 0; value; value = value & (value - 1), cnt++);
|
||||
return cnt;
|
||||
}
|
||||
|
||||
static void anc_voice_effect_set(u8 *anc_setting, u8 mode, s16 value)
|
||||
{
|
||||
static s16 value_old = -1;
|
||||
#if TCFG_AUDIO_ANC_ENABLE
|
||||
if (value != value_old) {
|
||||
extern void audio_anc_fade_gain_set(int gain);
|
||||
audio_anc_fade_gain_set(value);
|
||||
}
|
||||
if (anc_setting) {
|
||||
if (-1 == value_old) {
|
||||
anc_mode_switch(mode + 1, 0);
|
||||
} else {
|
||||
anc_mode_switch(mode + 1, 1);
|
||||
}
|
||||
} else {
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if ((-1 == value_old) || (get_bt_tws_connect_status() && (count_the_num_of_positions(get_adv_anc_event_status()) > 1))) {
|
||||
#else
|
||||
if (-1 == value_old) {
|
||||
#endif
|
||||
anc_mode_switch(mode + 1, 0);
|
||||
} else {
|
||||
anc_mode_switch(mode + 1, 1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
value_old = value;
|
||||
}
|
||||
|
||||
static void anc_voice_state_update(u8 *anc_setting)
|
||||
{
|
||||
u8 offset = 0;
|
||||
u8 mode = g_anc_info[offset];
|
||||
offset++;
|
||||
offset += mode * 8;
|
||||
s16 left_max = g_anc_info[offset] << 8 | g_anc_info[offset + 1];
|
||||
s16 right_max = g_anc_info[offset + 2] << 8 | g_anc_info[offset + 3];
|
||||
s16 left_val = g_anc_info[offset + 4] << 8 | g_anc_info[offset + 5];
|
||||
s16 right_val = g_anc_info[offset + 6] << 8 | g_anc_info[offset + 7];
|
||||
offset += 8;
|
||||
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if ('R' == bt_tws_get_local_channel()) {
|
||||
if (check_pos_neg(mode) && right_val >= right_max) {
|
||||
anc_voice_effect_set(anc_setting, mode, right_val);
|
||||
} else if (right_max >= right_val) {
|
||||
anc_voice_effect_set(anc_setting, mode, right_val);
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (check_pos_neg(mode) && left_val >= left_max) {
|
||||
anc_voice_effect_set(anc_setting, mode, left_val);
|
||||
} else if (left_max >= left_val) {
|
||||
anc_voice_effect_set(anc_setting, mode, left_val);
|
||||
}
|
||||
}
|
||||
|
||||
void deal_anc_voice(u8 *anc_setting, u8 write_vm, u8 tws_sync)
|
||||
{
|
||||
/* printf("%s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__); */
|
||||
/* extern void tws_api_role_switch(); */
|
||||
/* tws_api_role_switch(); */
|
||||
/* return; */
|
||||
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);
|
||||
}
|
||||
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if (get_bt_tws_connect_status()) {
|
||||
if (TWS_ROLE_MASTER == tws_api_get_role()) {
|
||||
anc_voice_state_update(anc_info);
|
||||
} else if (0 == tws_sync) {
|
||||
anc_voice_state_update(anc_info);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
anc_voice_state_update(anc_info);
|
||||
}
|
||||
// 更新状态
|
||||
enable_adv_anc_event();
|
||||
}
|
||||
|
||||
#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' == bt_tws_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);
|
||||
}
|
||||
|
||||
// ==================================================
|
||||
#define AUDIO_ANC_MODE_OFF 1
|
||||
#define AUDIO_ANC_MODE_ON 2
|
||||
#define AUDIO_ANC_MODE_TRANSPARENCY 3
|
||||
static const u8 g_audio_anc_mode[] = {
|
||||
AUDIO_ANC_MODE_OFF,
|
||||
AUDIO_ANC_MODE_ON,
|
||||
AUDIO_ANC_MODE_TRANSPARENCY
|
||||
};
|
||||
// ==================================================
|
||||
// mode - 模式,0 - 关闭模式,1 - 降噪模式,2 - 通透模式
|
||||
// type - 类型,0 - 左耳,1 - 右耳
|
||||
// buf - 获取对应值的buffer
|
||||
// 返回值:返回数据,0是失败
|
||||
u16 rcsp_adv_anc_voice_value_get(u8 mode)
|
||||
{
|
||||
u8 cur_app_mode;
|
||||
for (cur_app_mode = 0; cur_app_mode < sizeof(g_audio_anc_mode); cur_app_mode++) {
|
||||
if (mode == g_audio_anc_mode[cur_app_mode]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
u8 anc_vm_info[24] = {0};
|
||||
if (sizeof(anc_vm_info) != syscfg_read(CFG_RCSP_ADV_ANC_VOICE, anc_vm_info, sizeof(anc_vm_info))) {
|
||||
return 16384;
|
||||
}
|
||||
/* u8 *anc_ptr = anc_vm_info + cur_app_mode * 8 + 4; */
|
||||
u8 *anc_ptr = anc_vm_info + cur_app_mode * 8;
|
||||
u8 type = 0;
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
type = ('R' == bt_tws_get_local_channel()) ? 1 : 0;
|
||||
#endif/*TCFG_USER_TWS_ENABLE*/
|
||||
switch (type) {
|
||||
case 1:
|
||||
// 右耳
|
||||
anc_ptr += 2;
|
||||
case 0:
|
||||
// 左耳
|
||||
break;
|
||||
default:
|
||||
return 16384;
|
||||
}
|
||||
return (anc_ptr[0] << 8 | anc_ptr[1]);
|
||||
}
|
||||
|
||||
int anc_voice_setting_sync()
|
||||
{
|
||||
int ret = 0;
|
||||
u8 anc_info[8] = {0};
|
||||
#if (TCFG_AUDIO_ANC_ENABLE)
|
||||
#ifdef CONFIG_CPU_BR30
|
||||
u16 noise_reduction = (u16)audio_anc_fade_gain_get(); // 调用接口获取降噪最大值
|
||||
u16 transparent = (u16)audio_anc_fade_gain_get(); // 调用接口获取通透最大值
|
||||
#else
|
||||
u16 noise_reduction = 16384;
|
||||
u16 transparent = 16384;
|
||||
#endif
|
||||
#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' == bt_tws_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;
|
||||
} else {
|
||||
u8 anc_voice_setting[25] = {0};
|
||||
if (rcsp_read_data_from_vm(CFG_RCSP_ADV_ANC_VOICE_MODE, anc_voice_setting, 1)) {
|
||||
if (rcsp_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);
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
static RCSP_SETTING_OPT anc_voice_opt = {
|
||||
.data_len = 25,
|
||||
.setting_type = ATTR_TYPE_ANC_VOICE,
|
||||
.syscfg_id = CFG_RCSP_ADV_ANC_VOICE,
|
||||
.deal_opt_setting = deal_anc_voice,
|
||||
.set_setting = set_anc_voice_info,
|
||||
.get_setting = get_anc_voice_info,
|
||||
.custom_setting_init = anc_voice_setting_init,
|
||||
.custom_vm_info_update = NULL,
|
||||
.custom_setting_update = NULL,
|
||||
.custom_sibling_setting_deal = NULL,
|
||||
.custom_setting_release = NULL,
|
||||
.set_setting_extra_handle = NULL,
|
||||
.get_setting_extra_handle = NULL,
|
||||
};
|
||||
REGISTER_APP_SETTING_OPT(anc_voice_opt);
|
||||
|
||||
#elif (defined TCFG_CSC_BT_APP) && TCFG_CSC_BT_APP && RCSP_MODE
|
||||
|
||||
#include "smartbox_info_manager.h"
|
||||
/*note: 目前 anc信息 只用到mode */
|
||||
|
||||
|
||||
// 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};
|
||||
|
||||
|
||||
int get_anc_voice_info(u8 *anc_info)
|
||||
{
|
||||
memcpy(anc_info, g_anc_info, sizeof(g_anc_info));
|
||||
return 0;
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
static bool check_pos_neg(u8 mode)
|
||||
{
|
||||
bool ret = false;
|
||||
u8 offset = 1 + mode * 8;
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if ('R' == bt_tws_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;
|
||||
}
|
||||
|
||||
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 == 1)) {
|
||||
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 == (sizeof(anc_vm_info) - 1))) {
|
||||
syscfg_write(CFG_RCSP_ADV_ANC_VOICE, anc_info + 1, sizeof(anc_vm_info) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
u8 anc_voice_info_get(u8 *data, u16 len)
|
||||
{
|
||||
u8 offset = 0;
|
||||
u8 mode = g_anc_info[0];
|
||||
|
||||
if ((!data) || (len < 9)) {
|
||||
log_error("%s param error", __func__);
|
||||
}
|
||||
|
||||
data[offset++] = mode;
|
||||
memcpy(data + offset, g_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;
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
log_info("%s %d %d anc_mode:%d", __func__, write_vm, tws_sync, anc_info[0]);
|
||||
if (write_vm) {
|
||||
update_anc_voice_vm_value(anc_info);
|
||||
}
|
||||
|
||||
/*rcsp协议 和 仓与耳机ble协议 模式值定义不一样,这里加1保持一致*/
|
||||
u8 send_anc_mode = g_anc_info[0] + 1;
|
||||
sbox_anc_mode_set(send_anc_mode);
|
||||
|
||||
if (tws_sync) {
|
||||
custom_client_send_anc_mode(send_anc_mode);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
u8 anc_voice_info_fetch_all_get(u8 *data, u16 len)
|
||||
{
|
||||
u8 mode = 0;
|
||||
u8 offset = 1;
|
||||
for (u8 resp_offset = 1; offset < sizeof(g_anc_info); offset += 8) {
|
||||
data[resp_offset++] = mode;
|
||||
memcpy(data + resp_offset, g_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);
|
||||
|
||||
//anc设置完,得再通知app
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_ANC_VOICE, NULL, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//anc配置 写入vm和通知app
|
||||
void anc_ui_set_mode_rcsp_vm(u8 mode)
|
||||
{
|
||||
u8 anc_info[25] = {0};
|
||||
anc_info[0] = (mode - 1);
|
||||
deal_anc_voice(anc_info, 1, 0);
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_ANC_VOICE, NULL, 0);
|
||||
}
|
||||
|
||||
int anc_voice_setting_init(void)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 anc_mode = -1;
|
||||
|
||||
ret = syscfg_read(CFG_RCSP_ADV_ANC_VOICE_MODE, &anc_mode, sizeof(anc_mode));
|
||||
|
||||
if (ret != sizeof(anc_mode)) {
|
||||
anc_mode = 0;
|
||||
syscfg_write(CFG_RCSP_ADV_ANC_VOICE_MODE, &anc_mode, sizeof(anc_mode));
|
||||
}
|
||||
log_info("%s anc_mode:%d", __func__, anc_mode);
|
||||
|
||||
g_anc_info[0] = anc_mode;
|
||||
sbox_anc_mode_set(anc_mode + 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static RCSP_SETTING_OPT anc_voice_opt = {
|
||||
.data_len = 25,
|
||||
.setting_type = ATTR_TYPE_ANC_VOICE,
|
||||
.syscfg_id = CFG_RCSP_ADV_ANC_VOICE,
|
||||
.deal_opt_setting = NULL,
|
||||
.set_setting = NULL,
|
||||
.get_setting = get_anc_voice_info,
|
||||
.custom_setting_init = anc_voice_setting_init,
|
||||
.custom_vm_info_update = NULL,
|
||||
.custom_setting_update = NULL,
|
||||
.custom_sibling_setting_deal = NULL,
|
||||
.custom_setting_release = NULL,
|
||||
.set_setting_extra_handle = NULL,
|
||||
.get_setting_extra_handle = NULL,
|
||||
};
|
||||
REGISTER_APP_SETTING_OPT(anc_voice_opt);
|
||||
#else
|
||||
void anc_ui_set_mode_rcsp_vm(u8 mode)
|
||||
{
|
||||
printf("%s is NULL error!!!", __func__);
|
||||
}
|
||||
|
||||
#endif
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
#ifndef __ADV_ANS_VOICE_H__
|
||||
#define __ADV_ANS_VOICE_H__
|
||||
|
||||
#define ANC_VOICE_TYPE_MAX 3
|
||||
|
||||
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);
|
||||
int 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);
|
||||
void anc_ui_set_mode_rcsp_vm(u8 mode);
|
||||
|
||||
// mode - 模式,0 - 关闭模式,1 - 降噪模式,2 - 通透模式
|
||||
// // type - 类型,0 - 左耳,1 - 右耳
|
||||
// // buf - 获取对应值的buffer
|
||||
// // 返回值:返回数据,0是失败
|
||||
u16 rcsp_adv_anc_voice_value_get(u8 mode);
|
||||
|
||||
#endif
|
||||
+239
@@ -0,0 +1,239 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".adv_anc_voice_key.data.bss")
|
||||
#pragma data_seg(".adv_anc_voice_key.data")
|
||||
#pragma const_seg(".adv_anc_voice_key.text.const")
|
||||
#pragma code_seg(".adv_anc_voice_key.text")
|
||||
#endif
|
||||
#include "app_config.h"
|
||||
#include "syscfg_id.h"
|
||||
#include "user_cfg_id.h"
|
||||
|
||||
#include "ble_rcsp_server.h"
|
||||
#include "rcsp_setting_sync.h"
|
||||
#include "rcsp_setting_opt.h"
|
||||
#include "adv_anc_voice_key.h"
|
||||
|
||||
#include "adv_anc_voice.h"
|
||||
#include "rcsp_setting_opt.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"
|
||||
|
||||
static u8 g_anc_voice_key_mode[4] = {0, 0, 0, BIT(ANC_VOICE_TYPE_MAX) - 1};
|
||||
|
||||
extern int get_bt_tws_connect_status();
|
||||
|
||||
static 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));
|
||||
}
|
||||
|
||||
static int get_anc_voice_key_mode(u8 *anc_voice_mode)
|
||||
{
|
||||
memcpy(anc_voice_mode, g_anc_voice_key_mode, sizeof(g_anc_voice_key_mode));
|
||||
return 0;
|
||||
}
|
||||
|
||||
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_rcsp_setting(ATTR_TYPE_ANC_VOICE_KEY);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static 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;
|
||||
}
|
||||
|
||||
static int anc_voice_key_set_setting_extra_handle(void *setting_data, void *setting_data_len)
|
||||
{
|
||||
//u8 dlen = *((u8 *)setting_data_len);
|
||||
u8 *key_setting_data = (u8 *)setting_data;
|
||||
set_anc_voice_key_mode(key_setting_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int anc_voice_key_get_setting_extra_handle(void *setting_data, void *setting_data_len)
|
||||
{
|
||||
int **setting_data_ptr = (int **)setting_data;
|
||||
*setting_data_ptr = (int *)g_anc_voice_key_mode;
|
||||
return sizeof(g_anc_voice_key_mode);
|
||||
}
|
||||
|
||||
static RCSP_SETTING_OPT adv_anc_voice_key_opt = {
|
||||
.data_len = 4,
|
||||
.setting_type = ATTR_TYPE_ANC_VOICE_KEY,
|
||||
.syscfg_id = CFG_RCSP_ADV_ANC_VOICE_KEY,
|
||||
.deal_opt_setting = deal_anc_voice_key_setting,
|
||||
.set_setting = set_anc_voice_key_mode,
|
||||
.get_setting = get_anc_voice_key_mode,
|
||||
.custom_setting_init = NULL,
|
||||
.custom_vm_info_update = NULL,
|
||||
.custom_setting_update = NULL,
|
||||
.custom_sibling_setting_deal = NULL,
|
||||
.custom_setting_release = NULL,
|
||||
.set_setting_extra_handle = anc_voice_key_set_setting_extra_handle,
|
||||
.get_setting_extra_handle = anc_voice_key_get_setting_extra_handle,
|
||||
};
|
||||
REGISTER_APP_SETTING_OPT(adv_anc_voice_key_opt);
|
||||
|
||||
#endif
|
||||
#elif (defined TCFG_CSC_BT_APP) && TCFG_CSC_BT_APP
|
||||
#if (RCSP_ADV_KEY_SET_ENABLE)
|
||||
|
||||
#include "audio_anc.h"
|
||||
|
||||
|
||||
static u8 g_anc_voice_key_mode[4] = {0, 0, 0, BIT(ANC_VOICE_TYPE_MAX) - 1};
|
||||
|
||||
extern int get_bt_tws_connect_status();
|
||||
|
||||
static 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));
|
||||
}
|
||||
|
||||
static int get_anc_voice_key_mode(u8 *anc_voice_mode)
|
||||
{
|
||||
memcpy(anc_voice_mode, g_anc_voice_key_mode, sizeof(g_anc_voice_key_mode));
|
||||
return 0;
|
||||
}
|
||||
|
||||
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_rcsp_setting(ATTR_TYPE_ANC_VOICE_KEY);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static 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;
|
||||
}
|
||||
|
||||
static int anc_voice_key_set_setting_extra_handle(void *setting_data, void *setting_data_len)
|
||||
{
|
||||
//u8 dlen = *((u8 *)setting_data_len);
|
||||
u8 *key_setting_data = (u8 *)setting_data;
|
||||
set_anc_voice_key_mode(key_setting_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int anc_voice_key_get_setting_extra_handle(void *setting_data, void *setting_data_len)
|
||||
{
|
||||
int **setting_data_ptr = (int **)setting_data;
|
||||
*setting_data_ptr = (int *)g_anc_voice_key_mode;
|
||||
return sizeof(g_anc_voice_key_mode);
|
||||
}
|
||||
|
||||
static RCSP_SETTING_OPT adv_anc_voice_key_opt = {
|
||||
.data_len = 4,
|
||||
.setting_type = ATTR_TYPE_ANC_VOICE_KEY,
|
||||
.syscfg_id = CFG_RCSP_ADV_ANC_VOICE_KEY,
|
||||
.deal_opt_setting = deal_anc_voice_key_setting,
|
||||
.set_setting = set_anc_voice_key_mode,
|
||||
.get_setting = get_anc_voice_key_mode,
|
||||
.custom_setting_init = NULL,
|
||||
.custom_vm_info_update = NULL,
|
||||
.custom_setting_update = NULL,
|
||||
.custom_sibling_setting_deal = NULL,
|
||||
.custom_setting_release = NULL,
|
||||
.set_setting_extra_handle = anc_voice_key_set_setting_extra_handle,
|
||||
.get_setting_extra_handle = anc_voice_key_get_setting_extra_handle,
|
||||
};
|
||||
REGISTER_APP_SETTING_OPT(adv_anc_voice_key_opt);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
#ifndef __ADV_ANC_VOICE_KEY_H__
|
||||
#define __ADV_ANC_VOICE_KEY_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
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".adv_bt_name_setting.data.bss")
|
||||
#pragma data_seg(".adv_bt_name_setting.data")
|
||||
#pragma const_seg(".adv_bt_name_setting.text.const")
|
||||
#pragma code_seg(".adv_bt_name_setting.text")
|
||||
#endif
|
||||
#include "app_config.h"
|
||||
#include "user_cfg.h"
|
||||
#include "syscfg_id.h"
|
||||
#include "ble_rcsp_server.h"
|
||||
|
||||
#include "rcsp_setting_opt.h"
|
||||
|
||||
#if (RCSP_MODE && RCSP_ADV_EN && RCSP_ADV_NAME_SET_ENABLE)
|
||||
|
||||
static u8 g_edr_name[32] = {0};
|
||||
|
||||
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, g_edr_name, LOCAL_NAME_LEN);
|
||||
lmp_hci_write_local_name(bt_get_local_name());
|
||||
}
|
||||
|
||||
static void set_bt_name_setting(u8 *bt_name_setting)
|
||||
{
|
||||
memcpy(g_edr_name, bt_name_setting, 32);
|
||||
}
|
||||
|
||||
static int get_bt_name_setting(u8 *bt_name_setting)
|
||||
{
|
||||
memcpy(bt_name_setting, g_edr_name, 32);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 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_rcsp_setting(ATTR_TYPE_EDR_NAME);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void deal_bt_name_setting(u8 *bt_name_setting, u8 write_vm, u8 tws_sync)
|
||||
{
|
||||
if (!bt_name_setting) {
|
||||
get_bt_name_setting(g_edr_name);
|
||||
} else {
|
||||
memcpy(g_edr_name, bt_name_setting, 32);
|
||||
}
|
||||
if (write_vm) {
|
||||
update_bt_name_vm_value(g_edr_name);
|
||||
}
|
||||
if (tws_sync) {
|
||||
bt_name_sync(g_edr_name);
|
||||
}
|
||||
}
|
||||
|
||||
static int bt_name_set_setting_extra_handle(void *setting_data, void *setting_data_len)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 dlen = *((u8 *)setting_data_len);
|
||||
u8 *bt_name_setting_data = (u8 *) setting_data;
|
||||
u8 bt_name[32] = {0};
|
||||
if (dlen > 20) {
|
||||
ret = 2;
|
||||
} else {
|
||||
memcpy(bt_name, bt_name_setting_data, dlen);
|
||||
bt_name[dlen] = '\0';
|
||||
memcpy(g_edr_name, bt_name, sizeof(bt_name));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bt_name_get_setting_extra_handle(void *setting_data, void *setting_data_len)
|
||||
{
|
||||
int **setting_data_ptr = (int **)setting_data;
|
||||
*setting_data_ptr = (int *)g_edr_name;
|
||||
return strlen((const char *)g_edr_name);
|
||||
}
|
||||
|
||||
static RCSP_SETTING_OPT adv_bt_name_opt = {
|
||||
.data_len = 32,
|
||||
.setting_type = ATTR_TYPE_EDR_NAME,
|
||||
.syscfg_id = CFG_BT_NAME,
|
||||
.deal_opt_setting = deal_bt_name_setting,
|
||||
.set_setting = set_bt_name_setting,
|
||||
.get_setting = get_bt_name_setting,
|
||||
.custom_setting_init = NULL,
|
||||
.custom_vm_info_update = NULL,
|
||||
.custom_setting_update = NULL,
|
||||
.custom_sibling_setting_deal = NULL,
|
||||
.custom_setting_release = NULL,
|
||||
.set_setting_extra_handle = bt_name_set_setting_extra_handle,
|
||||
.get_setting_extra_handle = bt_name_get_setting_extra_handle,
|
||||
};
|
||||
|
||||
REGISTER_APP_SETTING_OPT(adv_bt_name_opt);
|
||||
|
||||
#else
|
||||
|
||||
void adv_edr_name_change_now(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
+323
@@ -0,0 +1,323 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".adv_hearing_aid_setting.data.bss")
|
||||
#pragma data_seg(".adv_hearing_aid_setting.data")
|
||||
#pragma const_seg(".adv_hearing_aid_setting.text.const")
|
||||
#pragma code_seg(".adv_hearing_aid_setting.text")
|
||||
#endif
|
||||
#include "adv_hearing_aid_setting.h"
|
||||
#include "spp_user.h"
|
||||
|
||||
#include "rcsp_setting_sync.h"
|
||||
#include "rcsp_setting_opt.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 get_bt_tws_connect_status();
|
||||
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);
|
||||
extern void set_hearing_aid_operating_flag();
|
||||
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)); */
|
||||
update_rcsp_setting(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, RCSP_DEVICE_STATUS_ATTR_TYPE_ASSISTED_HEARING, data, data_len);
|
||||
|
||||
ret = JL_CMD_send(JL_OPCODE_SYS_INFO_AUTO_UPDATE, buf, data_len + 1, JL_NOT_NEED_RESPOND, 0, NULL);
|
||||
|
||||
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, 0, NULL);
|
||||
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
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
#ifndef __ADV_HEARING_AID_SETTING_H__
|
||||
#define __ADV_HEARING_AID_SETTING_H__
|
||||
|
||||
#include "app_config.h"
|
||||
|
||||
#if RCSP_ADV_ASSISTED_HEARING
|
||||
|
||||
#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 // RCSP_ADV_ASSISTED_HEARING
|
||||
|
||||
#endif
|
||||
+547
@@ -0,0 +1,547 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".adv_key_setting.data.bss")
|
||||
#pragma data_seg(".adv_key_setting.data")
|
||||
#pragma const_seg(".adv_key_setting.text.const")
|
||||
#pragma code_seg(".adv_key_setting.text")
|
||||
#endif
|
||||
#include "app_config.h"
|
||||
#include "syscfg_id.h"
|
||||
#include "key_event_deal.h"
|
||||
#include "ble_rcsp_server.h"
|
||||
|
||||
#include "rcsp_setting_sync.h"
|
||||
#include "rcsp_setting_opt.h"
|
||||
#include "adv_anc_voice_key.h"
|
||||
#include "app_msg.h"
|
||||
#include "key_driver.h"
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
#include "bt_tws.h"
|
||||
#endif
|
||||
|
||||
#define LOG_TAG_CONST APP
|
||||
#define LOG_TAG "[RCSP-KEY-SET]"
|
||||
#define LOG_ERROR_ENABLE
|
||||
#define LOG_DEBUG_ENABLE
|
||||
#define LOG_INFO_ENABLE
|
||||
#define LOG_DUMP_ENABLE
|
||||
#define LOG_CHAR_ENABLE
|
||||
#include "debug.h"
|
||||
|
||||
#if (RCSP_MODE && RCSP_ADV_EN)
|
||||
#if RCSP_ADV_KEY_SET_ENABLE
|
||||
|
||||
extern int get_bt_tws_connect_status();
|
||||
static u8 rcsp_adv_key_event_flag = 0x0;
|
||||
|
||||
#define ADV_POWER_ON_OFF 0
|
||||
enum RCSP_KEY_TYPE {
|
||||
RCSP_KEY_TYPE_NULL = 0x00,
|
||||
#if ADV_POWER_ON_OFF
|
||||
RCSP_KEY_TYPE_POWER_ON,
|
||||
RCSP_KEY_TYPE_POWER_OFF,
|
||||
#endif
|
||||
RCSP_KEY_TYPE_PREV = 0x03,
|
||||
RCSP_KEY_TYPE_NEXT,
|
||||
RCSP_KEY_TYPE_PP,
|
||||
RCSP_KEY_TYPE_ANSWER_CALL,
|
||||
RCSP_KEY_TYPE_HANG_UP,
|
||||
RCSP_KEY_TYPE_CALL_BACK,
|
||||
RCSP_KEY_TYPE_INC_VOICE,
|
||||
RCSP_KEY_TYPE_DESC_VOICE,
|
||||
RCSP_KEY_TYPE_TAKE_PHOTO,
|
||||
RCSP_KEY_TYPE_ANC_VOICE = 0xFF,
|
||||
};
|
||||
|
||||
enum RCSP_EAR_CHANNEL {
|
||||
RCSP_EAR_CHANNEL_LEFT = 0x01,
|
||||
RCSP_EAR_CHANNEL_RIGHT = 0x02,
|
||||
};
|
||||
|
||||
enum RCSP_KEY_ACTION {
|
||||
RCSP_KEY_ACTION_CLICK = 0x01,
|
||||
RCSP_KEY_ACTION_DOUBLE_CLICK = 0x02,
|
||||
};
|
||||
|
||||
static u8 g_key_setting[12] = {
|
||||
RCSP_EAR_CHANNEL_LEFT, RCSP_KEY_ACTION_CLICK, RCSP_KEY_TYPE_PP, \
|
||||
RCSP_EAR_CHANNEL_RIGHT, RCSP_KEY_ACTION_CLICK, RCSP_KEY_TYPE_PP, \
|
||||
RCSP_EAR_CHANNEL_LEFT, RCSP_KEY_ACTION_DOUBLE_CLICK, RCSP_KEY_TYPE_ANSWER_CALL, \
|
||||
RCSP_EAR_CHANNEL_RIGHT, RCSP_KEY_ACTION_DOUBLE_CLICK, RCSP_KEY_TYPE_ANSWER_CALL
|
||||
};
|
||||
// 按键缓存
|
||||
// 第一列 | 第二列 | 第三列
|
||||
// 01 左耳| 01 单击| 按键功能
|
||||
// 02 右耳| 02 双击| 按键功能
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static void set_key_setting(u8 *key_setting_info)
|
||||
{
|
||||
// 设置左耳短按功能
|
||||
g_key_setting[3 * 0 + 2] = key_setting_info[0];
|
||||
// 设置左耳长按功能
|
||||
g_key_setting[3 * 2 + 2] = key_setting_info[1];
|
||||
// 设置右耳短按功能
|
||||
g_key_setting[3 * 1 + 2] = key_setting_info[2];
|
||||
// 设置右耳长按功能
|
||||
g_key_setting[3 * 3 + 2] = key_setting_info[3];
|
||||
}
|
||||
|
||||
static int get_key_setting(u8 *key_setting_info)
|
||||
{
|
||||
// 获取左耳短按功能
|
||||
key_setting_info[0] = g_key_setting[3 * 0 + 2];
|
||||
// 获取左耳长按功能
|
||||
key_setting_info[1] = g_key_setting[3 * 2 + 2];
|
||||
// 获取右耳短按功能
|
||||
key_setting_info[2] = g_key_setting[3 * 1 + 2];
|
||||
// 获取右耳长按功能
|
||||
key_setting_info[3] = g_key_setting[3 * 3 + 2];
|
||||
return 0;
|
||||
}
|
||||
|
||||
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_rcsp_setting(ATTR_TYPE_KEY_SETTING);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static 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();
|
||||
}
|
||||
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
static void rcsp_key_msg_in_task(u8 *_data, u16 len)
|
||||
{
|
||||
u8 *data = (u8 *)_data;
|
||||
u8 key_opt = *data;
|
||||
switch (key_opt) {
|
||||
case RCSP_KEY_TYPE_ANC_VOICE:
|
||||
update_anc_voice_key_opt();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
free(_data);
|
||||
}
|
||||
|
||||
static void rcsp_key_tws_func_t(void *data, u16 len, bool rx)
|
||||
{
|
||||
if (rx) {
|
||||
int msg[4];
|
||||
if (!data || (len == 0)) {
|
||||
ASSERT(0, "this must have key msg buf");
|
||||
}
|
||||
u8 *buf = malloc(len);
|
||||
if (!buf) {
|
||||
return;
|
||||
}
|
||||
memcpy(buf, data, len);
|
||||
|
||||
msg[0] = (int)rcsp_key_msg_in_task;
|
||||
msg[1] = 2;
|
||||
msg[2] = (int)buf;
|
||||
msg[3] = (int)len;
|
||||
os_taskq_post_type("app_core", Q_CALLBACK, sizeof(msg) / sizeof(int), msg);
|
||||
}
|
||||
}
|
||||
|
||||
#define TWS_FUNC_ID_RCSP_KEY_SYNC \
|
||||
(((u8)('R' + 'C' + 'S' + 'P') << (3 * 8)) | \
|
||||
((u8)('K' + 'E' + 'Y') << (2 * 8)) | \
|
||||
((u8)('M' + 'S' + 'G') << (1 * 8)) | \
|
||||
((u8)('S' + 'Y' + 'N' + 'C') << (0 * 8)))
|
||||
|
||||
REGISTER_TWS_FUNC_STUB(adv_key_sync) = {
|
||||
.func_id = TWS_FUNC_ID_RCSP_KEY_SYNC,
|
||||
.func = rcsp_key_tws_func_t,
|
||||
};
|
||||
#endif
|
||||
|
||||
static u8 get_adv_key_opt(u8 key_action, u8 channel)
|
||||
{
|
||||
u8 opt;
|
||||
for (opt = 0; opt < sizeof(g_key_setting); opt += 3) {
|
||||
if (g_key_setting[opt] == channel &&
|
||||
g_key_setting[opt + 1] == key_action) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sizeof(g_key_setting) == opt) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (g_key_setting[opt + 2]) {
|
||||
case RCSP_KEY_TYPE_NULL:
|
||||
opt = RCSP_KEY_TYPE_NULL;
|
||||
break;
|
||||
#if ADV_POWER_ON_OFF
|
||||
case RCSP_KEY_TYPE_POWER_ON:
|
||||
opt = APP_MSG_POWER_ON;
|
||||
break;
|
||||
case RCSP_KEY_TYPE_POWER_OFF:
|
||||
opt = APP_MSG_POWER_OFF;
|
||||
break;
|
||||
#endif
|
||||
case RCSP_KEY_TYPE_PREV:
|
||||
opt = APP_MSG_MUSIC_PREV;
|
||||
break;
|
||||
case RCSP_KEY_TYPE_NEXT:
|
||||
opt = APP_MSG_MUSIC_NEXT;
|
||||
break;
|
||||
case RCSP_KEY_TYPE_PP:
|
||||
opt = APP_MSG_MUSIC_PP;
|
||||
break;
|
||||
case RCSP_KEY_TYPE_ANSWER_CALL:
|
||||
opt = APP_MSG_CALL_ANSWER;
|
||||
break;
|
||||
case RCSP_KEY_TYPE_HANG_UP:
|
||||
opt = APP_MSG_CALL_HANGUP;
|
||||
break;
|
||||
case RCSP_KEY_TYPE_CALL_BACK:
|
||||
opt = APP_MSG_CALL_LAST_NO;
|
||||
break;
|
||||
case RCSP_KEY_TYPE_INC_VOICE:
|
||||
opt = APP_MSG_VOL_UP;
|
||||
break;
|
||||
case RCSP_KEY_TYPE_DESC_VOICE:
|
||||
opt = APP_MSG_VOL_DOWN;
|
||||
break;
|
||||
case RCSP_KEY_TYPE_TAKE_PHOTO:
|
||||
opt = APP_MSG_HID_CONTROL;
|
||||
break;
|
||||
case RCSP_KEY_TYPE_ANC_VOICE:
|
||||
#if (RCSP_ADV_EN && RCSP_ADV_ANC_VOICE)
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if (get_bt_tws_connect_status() && TWS_ROLE_SLAVE == tws_api_get_role()) {
|
||||
u8 val = RCSP_KEY_TYPE_ANC_VOICE;
|
||||
tws_api_send_data_to_sibling((void *)&val, 1, TWS_FUNC_ID_RCSP_KEY_SYNC);
|
||||
} else {
|
||||
update_anc_voice_key_opt();
|
||||
}
|
||||
#else
|
||||
update_anc_voice_key_opt();
|
||||
#endif
|
||||
|
||||
#endif
|
||||
opt = RCSP_KEY_TYPE_NULL;
|
||||
break;
|
||||
}
|
||||
return opt;
|
||||
}
|
||||
|
||||
/**
|
||||
* rcsp按键配置转换
|
||||
*
|
||||
* @param value 按键功能
|
||||
* @param msg 按键消息
|
||||
*
|
||||
* @return 是否拦截消息
|
||||
*/
|
||||
int rcsp_key_event_remap(int *msg)
|
||||
{
|
||||
int key_action = APP_MSG_KEY_ACTION(msg[0]);
|
||||
|
||||
g_printf("key_remap: 0x%x, 0x%x, 0x%x, key_value:%x\n", msg[0], msg[1], APP_KEY_MSG_FROM_TWS);
|
||||
|
||||
switch (key_action) {
|
||||
case KEY_ACTION_CLICK:
|
||||
// 单击
|
||||
key_action = RCSP_KEY_ACTION_CLICK;
|
||||
break;
|
||||
case KEY_ACTION_DOUBLE_CLICK:
|
||||
// 双击
|
||||
key_action = RCSP_KEY_ACTION_DOUBLE_CLICK;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if (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 = (msg[1] == APP_KEY_MSG_FROM_TWS) ? RCSP_EAR_CHANNEL_RIGHT : RCSP_EAR_CHANNEL_LEFT;
|
||||
break;
|
||||
case 'R':
|
||||
channel = (msg[1] == APP_KEY_MSG_FROM_TWS) ? RCSP_EAR_CHANNEL_LEFT : RCSP_EAR_CHANNEL_RIGHT;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _msg = get_adv_key_opt(key_action, channel);
|
||||
if (_msg == RCSP_KEY_TYPE_NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (_msg != -1) {
|
||||
msg[0] = _msg;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int key_set_setting_extra_handle(void *setting_data, void *setting_data_len)
|
||||
{
|
||||
u8 dlen = *((u8 *)setting_data_len);
|
||||
u8 *key_setting_data = (u8 *)setting_data;
|
||||
while (dlen >= 3) {
|
||||
if (key_setting_data[0] == RCSP_EAR_CHANNEL_LEFT) {
|
||||
if (key_setting_data[1] == RCSP_KEY_ACTION_CLICK) {
|
||||
g_key_setting[2] = key_setting_data[2];
|
||||
} else if (key_setting_data[1] == RCSP_KEY_ACTION_DOUBLE_CLICK) {
|
||||
g_key_setting[8] = key_setting_data[2];
|
||||
}
|
||||
} else if (key_setting_data[0] == RCSP_EAR_CHANNEL_RIGHT) {
|
||||
if (key_setting_data[1] == RCSP_KEY_ACTION_CLICK) {
|
||||
g_key_setting[5] = key_setting_data[2];
|
||||
} else if (key_setting_data[1] == RCSP_KEY_ACTION_DOUBLE_CLICK) {
|
||||
g_key_setting[11] = key_setting_data[2];
|
||||
}
|
||||
}
|
||||
dlen -= 3;
|
||||
key_setting_data += 3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int key_get_setting_extra_handle(void *setting_data, void *setting_data_len)
|
||||
{
|
||||
int **setting_data_ptr = (int **)setting_data;
|
||||
*setting_data_ptr = (int *)g_key_setting;
|
||||
return sizeof(g_key_setting);
|
||||
}
|
||||
|
||||
static RCSP_SETTING_OPT adv_key_opt = {
|
||||
.data_len = 4,
|
||||
.setting_type = ATTR_TYPE_KEY_SETTING,
|
||||
.syscfg_id = CFG_RCSP_ADV_KEY_SETTING,
|
||||
.deal_opt_setting = deal_key_setting,
|
||||
.set_setting = set_key_setting,
|
||||
.get_setting = get_key_setting,
|
||||
.custom_setting_init = NULL,
|
||||
.custom_vm_info_update = NULL,
|
||||
.custom_setting_update = NULL,
|
||||
.custom_sibling_setting_deal = NULL,
|
||||
.custom_setting_release = NULL,
|
||||
.set_setting_extra_handle = key_set_setting_extra_handle,
|
||||
.get_setting_extra_handle = key_get_setting_extra_handle,
|
||||
};
|
||||
REGISTER_APP_SETTING_OPT(adv_key_opt);
|
||||
|
||||
extern int app_default_msg_handler(int *msg);
|
||||
int rcsp_key_msg_handler(int *msg)
|
||||
{
|
||||
if (!APP_MSG_FROM_KEY(msg[0])) {
|
||||
return 0;
|
||||
}
|
||||
if (0 == get_adv_key_event_status()) {
|
||||
return 0;
|
||||
}
|
||||
g_printf("rcsp key msg receive:0x%x\n", msg[0]);
|
||||
return rcsp_key_event_remap(msg);
|
||||
}
|
||||
|
||||
APP_MSG_PROB_HANDLER(rcsp_key_msg_entry) = {
|
||||
.owner = 0xff,
|
||||
.from = MSG_FROM_APP,
|
||||
.handler = rcsp_key_msg_handler,
|
||||
};
|
||||
|
||||
#endif
|
||||
#elif (defined TCFG_CSC_BT_APP) && TCFG_CSC_BT_APP
|
||||
#if RCSP_ADV_KEY_SET_ENABLE
|
||||
|
||||
enum RCSP_EAR_CHANNEL {
|
||||
RCSP_EAR_CHANNEL_LEFT = 0x01,
|
||||
RCSP_EAR_CHANNEL_RIGHT = 0x02,
|
||||
};
|
||||
|
||||
enum RCSP_KEY_ACTION {
|
||||
RCSP_KEY_ACTION_CLICK = 0x01,
|
||||
RCSP_KEY_ACTION_DOUBLE_CLICK = 0x02,
|
||||
};
|
||||
|
||||
enum RCSP_KEY_TYPE {
|
||||
RCSP_KEY_TYPE_NULL = 0x00,
|
||||
#if ADV_POWER_ON_OFF
|
||||
RCSP_KEY_TYPE_POWER_ON,
|
||||
RCSP_KEY_TYPE_POWER_OFF,
|
||||
#endif
|
||||
RCSP_KEY_TYPE_PREV = 0x03,
|
||||
RCSP_KEY_TYPE_NEXT,
|
||||
RCSP_KEY_TYPE_PP,
|
||||
RCSP_KEY_TYPE_ANSWER_CALL,
|
||||
RCSP_KEY_TYPE_HANG_UP,
|
||||
RCSP_KEY_TYPE_CALL_BACK,
|
||||
RCSP_KEY_TYPE_INC_VOICE,
|
||||
RCSP_KEY_TYPE_DESC_VOICE,
|
||||
RCSP_KEY_TYPE_TAKE_PHOTO,
|
||||
RCSP_KEY_TYPE_ANC_VOICE = 0xFF,
|
||||
};
|
||||
|
||||
static u8 g_key_setting[12] = {
|
||||
RCSP_EAR_CHANNEL_LEFT, RCSP_KEY_ACTION_CLICK, RCSP_KEY_TYPE_PP, \
|
||||
RCSP_EAR_CHANNEL_RIGHT, RCSP_KEY_ACTION_CLICK, RCSP_KEY_TYPE_PP, \
|
||||
RCSP_EAR_CHANNEL_LEFT, RCSP_KEY_ACTION_DOUBLE_CLICK, RCSP_KEY_TYPE_ANSWER_CALL, \
|
||||
RCSP_EAR_CHANNEL_RIGHT, RCSP_KEY_ACTION_DOUBLE_CLICK, RCSP_KEY_TYPE_ANSWER_CALL
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
static int get_key_setting(u8 *key_setting_info)
|
||||
{
|
||||
// 获取左耳短按功能
|
||||
key_setting_info[0] = g_key_setting[3 * 0 + 2];
|
||||
// 获取左耳长按功能
|
||||
key_setting_info[1] = g_key_setting[3 * 2 + 2];
|
||||
// 获取右耳短按功能
|
||||
key_setting_info[2] = g_key_setting[3 * 1 + 2];
|
||||
// 获取右耳长按功能
|
||||
key_setting_info[3] = g_key_setting[3 * 3 + 2];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void set_key_setting(u8 *key_setting_info)
|
||||
{
|
||||
// 设置左耳短按功能
|
||||
g_key_setting[3 * 0 + 2] = key_setting_info[0];
|
||||
// 设置左耳长按功能
|
||||
g_key_setting[3 * 2 + 2] = key_setting_info[1];
|
||||
// 设置右耳短按功能
|
||||
g_key_setting[3 * 1 + 2] = key_setting_info[2];
|
||||
// 设置右耳长按功能
|
||||
g_key_setting[3 * 3 + 2] = key_setting_info[3];
|
||||
}
|
||||
|
||||
static void update_key_setting_vm_value(u8 *key_setting_info)
|
||||
{
|
||||
syscfg_write(CFG_RCSP_ADV_KEY_SETTING, key_setting_info, 4);
|
||||
}
|
||||
|
||||
static 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();
|
||||
}
|
||||
|
||||
static int key_set_setting_extra_handle(void *setting_data, void *setting_data_len)
|
||||
{
|
||||
u8 dlen = *((u8 *)setting_data_len);
|
||||
u8 *key_setting_data = (u8 *)setting_data;
|
||||
|
||||
if (!key_setting_data) {
|
||||
log_error("%s key_setting_data is NULL", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (dlen >= 3) {
|
||||
if (key_setting_data[0] == RCSP_EAR_CHANNEL_LEFT) {
|
||||
if (key_setting_data[1] == RCSP_KEY_ACTION_CLICK) {
|
||||
g_key_setting[2] = key_setting_data[2];
|
||||
} else if (key_setting_data[1] == RCSP_KEY_ACTION_DOUBLE_CLICK) {
|
||||
g_key_setting[8] = key_setting_data[2];
|
||||
}
|
||||
} else if (key_setting_data[0] == RCSP_EAR_CHANNEL_RIGHT) {
|
||||
if (key_setting_data[1] == RCSP_KEY_ACTION_CLICK) {
|
||||
g_key_setting[5] = key_setting_data[2];
|
||||
} else if (key_setting_data[1] == RCSP_KEY_ACTION_DOUBLE_CLICK) {
|
||||
g_key_setting[11] = key_setting_data[2];
|
||||
}
|
||||
}
|
||||
dlen -= 3;
|
||||
key_setting_data += 3;
|
||||
}
|
||||
deal_key_setting(NULL, 1, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int key_get_setting_extra_handle(void *setting_data, void *setting_data_len)
|
||||
{
|
||||
int **setting_data_ptr = (int **)setting_data;
|
||||
*setting_data_ptr = (int *)g_key_setting;
|
||||
return sizeof(g_key_setting);
|
||||
}
|
||||
|
||||
static RCSP_SETTING_OPT adv_key_opt = {
|
||||
.data_len = 4,
|
||||
.setting_type = ATTR_TYPE_KEY_SETTING,
|
||||
.syscfg_id = CFG_RCSP_ADV_KEY_SETTING,
|
||||
.deal_opt_setting = deal_key_setting,
|
||||
.set_setting = set_key_setting,
|
||||
.get_setting = get_key_setting,
|
||||
.custom_setting_init = NULL,
|
||||
.custom_vm_info_update = NULL,
|
||||
.custom_setting_update = NULL,
|
||||
.custom_sibling_setting_deal = NULL,
|
||||
.custom_setting_release = NULL,
|
||||
.set_setting_extra_handle = key_set_setting_extra_handle,
|
||||
.get_setting_extra_handle = key_get_setting_extra_handle,
|
||||
};
|
||||
REGISTER_APP_SETTING_OPT(adv_key_opt);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+231
@@ -0,0 +1,231 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".adv_led_setting.data.bss")
|
||||
#pragma data_seg(".adv_led_setting.data")
|
||||
#pragma const_seg(".adv_led_setting.text.const")
|
||||
#pragma code_seg(".adv_led_setting.text")
|
||||
#endif
|
||||
#include "app_config.h"
|
||||
#include "syscfg_id.h"
|
||||
#include "user_cfg.h"
|
||||
#include "ble_rcsp_server.h"
|
||||
|
||||
#include "rcsp_setting_sync.h"
|
||||
#include "rcsp_setting_opt.h"
|
||||
|
||||
#if (RCSP_MODE && RCSP_ADV_EN)
|
||||
#if RCSP_ADV_LED_SET_ENABLE
|
||||
|
||||
#include "asm/pwm_led_hw.h"
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
static u8 g_led_status[14] = {
|
||||
0x01, 0x06, \
|
||||
0x02, 0x05, \
|
||||
0x03, 0x04, \
|
||||
0x04, 0x00, \
|
||||
0x05, 0x00, \
|
||||
0x06, 0x00, \
|
||||
0x07, 0x00
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static void set_led_setting(u8 *led_setting_info)
|
||||
{
|
||||
g_led_status[2 * 0 + 1] = led_setting_info[0];
|
||||
g_led_status[2 * 1 + 1] = led_setting_info[1];
|
||||
g_led_status[2 * 2 + 1] = led_setting_info[2];
|
||||
g_led_status[2 * 3 + 1] = led_setting_info[3];
|
||||
g_led_status[2 * 4 + 1] = led_setting_info[4];
|
||||
g_led_status[2 * 5 + 1] = led_setting_info[5];
|
||||
g_led_status[2 * 6 + 1] = led_setting_info[6];
|
||||
}
|
||||
|
||||
static int get_led_setting(u8 *led_setting_info)
|
||||
{
|
||||
led_setting_info[0] = g_led_status[2 * 0 + 1];
|
||||
led_setting_info[1] = g_led_status[2 * 1 + 1];
|
||||
led_setting_info[2] = g_led_status[2 * 2 + 1];
|
||||
led_setting_info[3] = g_led_status[2 * 3 + 1];
|
||||
led_setting_info[4] = g_led_status[2 * 4 + 1];
|
||||
led_setting_info[5] = g_led_status[2 * 5 + 1];
|
||||
led_setting_info[6] = g_led_status[2 * 6 + 1];
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 1、写入VM
|
||||
static void update_led_setting_vm_value(u8 *led_setting_info)
|
||||
{
|
||||
syscfg_write(CFG_RCSP_ADV_LED_SETTING, led_setting_info, 7);
|
||||
}
|
||||
// 2、同步对端
|
||||
static void led_setting_sync(u8 *led_setting_info)
|
||||
{
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if (get_bt_tws_connect_status()) {
|
||||
update_rcsp_setting(ATTR_TYPE_LED_SETTING);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
// 3、更新状态
|
||||
void update_led_setting_state(void)
|
||||
{
|
||||
u8 led_setting_info[7];
|
||||
get_led_setting(led_setting_info);
|
||||
|
||||
// 直接修改led表
|
||||
LED_REMAP_STATUS *p_led = led_get_remap_t();
|
||||
// 未配对
|
||||
p_led->bt_init_ok = 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]);
|
||||
// 断开连接
|
||||
p_led->bt_disconnect = adv_led_value_conversion(led_setting_info[1]);
|
||||
// 音乐模式播放音乐
|
||||
p_led->music_play = adv_led_value_conversion(led_setting_info[3]);
|
||||
// 音乐模式停止播放
|
||||
p_led->music_pause = adv_led_value_conversion(led_setting_info[4]);
|
||||
// Linein模式播放音乐
|
||||
p_led->linein_play = adv_led_value_conversion(led_setting_info[5]);
|
||||
// Linein模式静音
|
||||
p_led->linein_mute = adv_led_value_conversion(led_setting_info[6]);
|
||||
|
||||
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;
|
||||
case STATUS_MUSIC_MODE:
|
||||
case STATUS_MUSIC_PLAY:
|
||||
ui_update_status(STATUS_MUSIC_PLAY);
|
||||
break;
|
||||
case STATUS_MUSIC_PAUSE:
|
||||
ui_update_status(STATUS_MUSIC_PAUSE);
|
||||
break;
|
||||
case STATUS_LINEIN_MODE:
|
||||
case STATUS_LINEIN_PLAY:
|
||||
ui_update_status(STATUS_LINEIN_PLAY);
|
||||
break;
|
||||
case STATUS_LINEIN_PAUSE:
|
||||
ui_update_status(STATUS_LINEIN_PAUSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void deal_led_setting(u8 *led_setting_info, u8 write_vm, u8 tws_sync)
|
||||
{
|
||||
u8 led_setting[7];
|
||||
if (!led_setting_info) {
|
||||
get_led_setting(led_setting);
|
||||
} else {
|
||||
memcpy(led_setting, led_setting_info, 7);
|
||||
set_led_setting(led_setting_info);
|
||||
}
|
||||
if (write_vm) {
|
||||
update_led_setting_vm_value(led_setting);
|
||||
}
|
||||
if (tws_sync) {
|
||||
led_setting_sync(led_setting);
|
||||
}
|
||||
update_led_setting_state();
|
||||
}
|
||||
|
||||
static int led_set_setting_extra_handle(void *setting_data, void *setting_data_len)
|
||||
{
|
||||
u8 dlen = *((u8 *)setting_data_len);
|
||||
u8 *led_setting_data = (u8 *) setting_data;
|
||||
while (dlen >= 2) {
|
||||
if (led_setting_data[0] == 0 || led_setting_data[0] > 7) {
|
||||
return -1;
|
||||
} else {
|
||||
g_led_status[2 * (led_setting_data[0] - 1) + 1] = led_setting_data[1];
|
||||
}
|
||||
dlen -= 2;
|
||||
led_setting_data += 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int led_get_setting_extra_handle(void *setting_data, void *setting_data_len)
|
||||
{
|
||||
int **setting_data_ptr = (int **)setting_data;
|
||||
*setting_data_ptr = g_led_status;
|
||||
return sizeof(g_led_status);
|
||||
}
|
||||
|
||||
static RCSP_SETTING_OPT adv_led_opt = {
|
||||
.data_len = 7,
|
||||
.setting_type = ATTR_TYPE_LED_SETTING,
|
||||
.syscfg_id = CFG_RCSP_ADV_LED_SETTING,
|
||||
.deal_opt_setting = deal_led_setting,
|
||||
.set_setting = set_led_setting,
|
||||
.get_setting = get_led_setting,
|
||||
.custom_setting_init = NULL,
|
||||
.custom_vm_info_update = NULL,
|
||||
.custom_setting_update = NULL,
|
||||
.custom_sibling_setting_deal = NULL,
|
||||
.custom_setting_release = NULL,
|
||||
.set_setting_extra_handle = led_set_setting_extra_handle,
|
||||
.get_setting_extra_handle = led_get_setting_extra_handle,
|
||||
};
|
||||
REGISTER_APP_SETTING_OPT(adv_led_opt);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
+189
@@ -0,0 +1,189 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".adv_mic_setting.data.bss")
|
||||
#pragma data_seg(".adv_mic_setting.data")
|
||||
#pragma const_seg(".adv_mic_setting.text.const")
|
||||
#pragma code_seg(".adv_mic_setting.text")
|
||||
#endif
|
||||
#include "app_config.h"
|
||||
#include "syscfg_id.h"
|
||||
#include "ble_rcsp_server.h"
|
||||
|
||||
#include "adv_mic_setting.h"
|
||||
#include "rcsp_setting_sync.h"
|
||||
#include "rcsp_setting_opt.h"
|
||||
#include "classic/tws_api.h"
|
||||
#include "bt_tws.h"
|
||||
|
||||
#if (RCSP_MODE && RCSP_ADV_EN)
|
||||
#if RCSP_ADV_MIC_SET_ENABLE
|
||||
|
||||
enum RCSP_MIC_MODE {
|
||||
RCSP_MIC_MODE_AUTO = 1, // 自动切换
|
||||
RCSP_MIC_MODE_LEFT = 2, // 始终左耳
|
||||
RCSP_MIC_MODE_RIGHT = 3, // 始终右耳
|
||||
};
|
||||
|
||||
static u8 g_mic_mode = RCSP_MIC_MODE_LEFT;
|
||||
|
||||
static void mic_setting_info_deal(u8 *mic_info_data)
|
||||
{
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
u8 channel = tws_api_get_local_channel();
|
||||
printf("%s, channel:%c\n", __FUNCTION__, channel);
|
||||
|
||||
if (tws_api_get_role() == TWS_ROLE_MASTER) {
|
||||
printf("-----master-----\n");
|
||||
} else {
|
||||
printf("-----role-----\n");
|
||||
}
|
||||
switch (*mic_info_data) {
|
||||
case RCSP_MIC_MODE_AUTO:
|
||||
if (get_bt_tws_connect_status()) {
|
||||
printf("-------auto--------\n");
|
||||
tws_api_auto_role_switch_enable();
|
||||
}
|
||||
break;
|
||||
case RCSP_MIC_MODE_LEFT:
|
||||
if (get_bt_tws_connect_status()) {
|
||||
if (channel != 'L') {
|
||||
printf("-------!L--------\n");
|
||||
tws_api_auto_role_switch_disable();
|
||||
tws_api_role_switch();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RCSP_MIC_MODE_RIGHT:
|
||||
if (get_bt_tws_connect_status()) {
|
||||
if (channel != 'R') {
|
||||
printf("-------!R--------\n");
|
||||
tws_api_auto_role_switch_disable();
|
||||
tws_api_role_switch();
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void set_mic_setting(u8 *mic_setting_info)
|
||||
{
|
||||
g_mic_mode = *mic_setting_info;
|
||||
}
|
||||
|
||||
static int get_mic_setting(u8 *mic_setting_info)
|
||||
{
|
||||
*mic_setting_info = g_mic_mode;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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_rcsp_setting(ATTR_TYPE_MIC_SETTING);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void deal_mic_setting(u8 *mic_setting_info, u8 write_vm, u8 tws_sync)
|
||||
{
|
||||
if (!mic_setting_info) {
|
||||
} else {
|
||||
set_mic_setting(mic_setting_info);
|
||||
}
|
||||
if (write_vm) {
|
||||
update_mic_setting_vm_value(&g_mic_mode);
|
||||
}
|
||||
if (tws_sync) {
|
||||
adv_mic_setting_sync(&g_mic_mode);
|
||||
}
|
||||
mic_setting_info_deal(&g_mic_mode);
|
||||
}
|
||||
|
||||
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
//通话时,根据esco state,固定mic的位置
|
||||
void rcsp_user_mic_fixed_deal()
|
||||
{
|
||||
u8 channel = tws_api_get_local_channel();
|
||||
|
||||
if (!get_bt_tws_connect_status()) {
|
||||
return;
|
||||
}
|
||||
|
||||
u8 adv_mic_setting = 0;
|
||||
get_mic_setting(&adv_mic_setting);
|
||||
if ((tws_api_get_role() == TWS_ROLE_MASTER)
|
||||
&& (tws_api_get_tws_state() | TWS_STA_ESCO_OPEN)) {
|
||||
|
||||
switch (adv_mic_setting) {
|
||||
case RCSP_MIC_MODE_LEFT:
|
||||
if (get_bt_tws_connect_status()) {
|
||||
if (channel != 'L') {
|
||||
printf("mic_sw_l\n");
|
||||
tws_api_role_switch();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case RCSP_MIC_MODE_RIGHT:
|
||||
if (get_bt_tws_connect_status()) {
|
||||
if (channel != 'R') {
|
||||
printf("mic_sw_r\n");
|
||||
tws_api_role_switch();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("mic_sw_auto\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int mic_set_setting_extra_handle(void *setting_data, void *setting_data_len)
|
||||
{
|
||||
u8 dlen = *((u8 *)setting_data_len);
|
||||
u8 *mic_setting_data = (u8 *)setting_data;
|
||||
memcpy(&g_mic_mode, mic_setting_data, dlen);
|
||||
printf("mic_set_setting_extra_handle mode:%d", g_mic_mode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mic_get_setting_extra_handle(void *setting_data, void *setting_data_len)
|
||||
{
|
||||
int **setting_data_ptr = (int **)setting_data;
|
||||
*setting_data_ptr = (int *)&g_mic_mode;
|
||||
return sizeof(g_mic_mode);
|
||||
}
|
||||
|
||||
static RCSP_SETTING_OPT adv_mic_opt = {
|
||||
.data_len = 1,
|
||||
.setting_type = ATTR_TYPE_MIC_SETTING,
|
||||
.syscfg_id = CFG_RCSP_ADV_MIC_SETTING,
|
||||
.deal_opt_setting = deal_mic_setting,
|
||||
.set_setting = set_mic_setting,
|
||||
.get_setting = get_mic_setting,
|
||||
.custom_setting_init = NULL,
|
||||
.custom_vm_info_update = NULL,
|
||||
.custom_setting_update = NULL,
|
||||
.custom_sibling_setting_deal = NULL,
|
||||
.custom_setting_release = NULL,
|
||||
.set_setting_extra_handle = mic_set_setting_extra_handle,
|
||||
.get_setting_extra_handle = mic_get_setting_extra_handle,
|
||||
};
|
||||
REGISTER_APP_SETTING_OPT(adv_mic_opt);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
#ifndef __ADV_MIC_SETTING_H__
|
||||
#define __ADV_MIC_SETTING_H__
|
||||
|
||||
void rcsp_user_mic_fixed_deal();
|
||||
|
||||
#endif
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".adv_scene_noise_reduction.data.bss")
|
||||
#pragma data_seg(".adv_scene_noise_reduction.data")
|
||||
#pragma const_seg(".adv_scene_noise_reduction.text.const")
|
||||
#pragma code_seg(".adv_scene_noise_reduction.text")
|
||||
#endif
|
||||
#include "adv_scene_noise_reduction.h"
|
||||
#include "app_config.h"
|
||||
#include "rcsp_adv_bluetooth.h"
|
||||
|
||||
#if (RCSP_ADV_ANC_VOICE && RCSP_ADV_SCENE_NOISE_REDUCTION)
|
||||
|
||||
/**
|
||||
* @brief 获取场景降噪类型
|
||||
*
|
||||
* @result RCSP_SCENE_NOISE_REDUCTION_TYPE
|
||||
*/
|
||||
RCSP_SCENE_NOISE_REDUCTION_TYPE get_scene_noise_reduction_type()
|
||||
{
|
||||
printf("===%s===", __FUNCTION__);
|
||||
return RCSP_SCENE_NOISE_REDUCTION_TYPE_INTELLIGENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置场景降噪类型
|
||||
*/
|
||||
void set_scene_noise_reduction_type(RCSP_SCENE_NOISE_REDUCTION_TYPE type)
|
||||
{
|
||||
switch (type) {
|
||||
case RCSP_SCENE_NOISE_REDUCTION_TYPE_INTELLIGENT:
|
||||
case RCSP_SCENE_NOISE_REDUCTION_TYPE_MILD:
|
||||
case RCSP_SCENE_NOISE_REDUCTION_TYPE_BALANCE:
|
||||
case RCSP_SCENE_NOISE_REDUCTION_TYPE_DEEPNESS:
|
||||
default:
|
||||
printf("%s, type:%d", __FUNCTION__, type);
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_SCENE_NOISE_REDUCTION, NULL, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
+27
@@ -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__
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".adv_time_stamp_setting.data.bss")
|
||||
#pragma data_seg(".adv_time_stamp_setting.data")
|
||||
#pragma const_seg(".adv_time_stamp_setting.text.const")
|
||||
#pragma code_seg(".adv_time_stamp_setting.text")
|
||||
#endif
|
||||
#include "rcsp_config.h"
|
||||
#include "syscfg_id.h"
|
||||
#include "ble_rcsp_server.h"
|
||||
|
||||
#include "adv_time_stamp_setting.h"
|
||||
#include "rcsp_setting_sync.h"
|
||||
#include "rcsp_setting_opt.h"
|
||||
#include "rcsp_adv_bluetooth.h"
|
||||
|
||||
#include "rcsp_manage.h"
|
||||
#include "rcsp_bt_manage.h"
|
||||
|
||||
#if (RCSP_MODE && RCSP_ADV_EN)
|
||||
extern int get_bt_tws_connect_status();
|
||||
static u32 adv_time_stamp = 0;
|
||||
static int get_adv_time_stamp(u8 *time_stamp)
|
||||
{
|
||||
memcpy(time_stamp, (u8 *)&adv_time_stamp, sizeof(adv_time_stamp));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void set_adv_time_stamp(u8 *time_stamp)
|
||||
{
|
||||
memcpy((u8 *)&adv_time_stamp, time_stamp, sizeof(adv_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(u8 *time_stamp)
|
||||
{
|
||||
syscfg_write(CFG_RCSP_ADV_TIME_STAMP, time_stamp, 4);
|
||||
}
|
||||
// 2、同步对端
|
||||
static void adv_time_stamp_sync(u8 *time_stamp)
|
||||
{
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if (get_bt_tws_connect_status()) {
|
||||
update_rcsp_setting(ATTR_TYPE_TIME_STAMP);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void deal_time_stamp_setting(u8 *time_stamp, u8 write_vm, u8 tws_sync)
|
||||
{
|
||||
if (time_stamp) {
|
||||
set_adv_time_stamp(time_stamp);
|
||||
}
|
||||
if (write_vm) {
|
||||
update_time_stamp_vm_value((u8 *)&adv_time_stamp);
|
||||
}
|
||||
if (tws_sync) {
|
||||
adv_time_stamp_sync((u8 *)&adv_time_stamp);
|
||||
}
|
||||
}
|
||||
|
||||
static int adv_time_stamp_sibling_settting_deal(u8 *setting_data)
|
||||
{
|
||||
u32 time_stamp = (setting_data[0] | (setting_data[1] << 8) | (setting_data[2] << 16) | (setting_data[3] << 24));
|
||||
set_adv_time_stamp((u8 *)&time_stamp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int time_stamp_set_setting_extra_handle(void *setting_data, void *setting_data_len)
|
||||
{
|
||||
u8 dlen = *((u8 *)setting_data_len);
|
||||
u8 *time_stamp_setting_data = (u8 *) setting_data;
|
||||
adv_time_stamp = (((time_stamp_setting_data[0] << 8) | time_stamp_setting_data[1]) << 8 | time_stamp_setting_data[2]) << 8 | time_stamp_setting_data[3];
|
||||
|
||||
u8 bt_name[32] = {0};
|
||||
syscfg_read(CFG_BT_NAME, bt_name, sizeof(bt_name));
|
||||
RCSP_SETTING_OPT *setting_opt_hdl = get_rcsp_setting_opt_hdl(ATTR_TYPE_EDR_NAME);
|
||||
if (setting_opt_hdl && setting_opt_hdl->set_setting) {
|
||||
setting_opt_hdl->set_setting(bt_name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static RCSP_SETTING_OPT adv_time_stamp_opt = {
|
||||
.data_len = 4,
|
||||
.setting_type = ATTR_TYPE_TIME_STAMP,
|
||||
.syscfg_id = CFG_RCSP_ADV_TIME_STAMP,
|
||||
.deal_opt_setting = deal_time_stamp_setting,
|
||||
.set_setting = set_adv_time_stamp,
|
||||
.get_setting = get_adv_time_stamp,
|
||||
.custom_setting_init = NULL,
|
||||
.custom_vm_info_update = NULL,
|
||||
.custom_setting_update = NULL,
|
||||
.custom_sibling_setting_deal = adv_time_stamp_sibling_settting_deal,
|
||||
.custom_setting_release = NULL,
|
||||
.set_setting_extra_handle = time_stamp_set_setting_extra_handle,
|
||||
.get_setting_extra_handle = NULL,
|
||||
};
|
||||
REGISTER_APP_SETTING_OPT(adv_time_stamp_opt);
|
||||
|
||||
#endif
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
#ifndef __ADV_TIME_STAMP_SETTING_H__
|
||||
#define __ADV_TIME_STAMP_SETTING_H__
|
||||
|
||||
//void set_adv_time_stamp(u8 *time_stamp);
|
||||
//void get_adv_time_stamp(u8 *time_stamp);
|
||||
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
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".adv_voice_enhancement_mode.data.bss")
|
||||
#pragma data_seg(".adv_voice_enhancement_mode.data")
|
||||
#pragma const_seg(".adv_voice_enhancement_mode.text.const")
|
||||
#pragma code_seg(".adv_voice_enhancement_mode.text")
|
||||
#endif
|
||||
#include "adv_voice_enhancement_mode.h"
|
||||
#include "app_config.h"
|
||||
#include "rcsp_adv_bluetooth.h"
|
||||
|
||||
#if (RCSP_ADV_ANC_VOICE && RCSP_ADV_WIND_NOISE_DETECTION)
|
||||
|
||||
/**
|
||||
* @brief 获取人声增强模式开关
|
||||
*
|
||||
* @result bool
|
||||
*/
|
||||
bool get_voice_enhancement_mode_switch()
|
||||
{
|
||||
printf("===%s===", __FUNCTION__);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置人声增强模式开关
|
||||
*/
|
||||
void set_voice_enhancement_mode_switch(bool mode_switch)
|
||||
{
|
||||
printf("%s, switch:%d\n", __FUNCTION__, mode_switch);
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_VOICE_ENHANCEMENT_MODE, NULL, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
+18
@@ -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__
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".adv_wind_noise_detection.data.bss")
|
||||
#pragma data_seg(".adv_wind_noise_detection.data")
|
||||
#pragma const_seg(".adv_wind_noise_detection.text.const")
|
||||
#pragma code_seg(".adv_wind_noise_detection.text")
|
||||
#endif
|
||||
#include "adv_wind_noise_detection.h"
|
||||
#include "app_config.h"
|
||||
#include "rcsp_adv_bluetooth.h"
|
||||
|
||||
#if (RCSP_ADV_ANC_VOICE && RCSP_ADV_WIND_NOISE_DETECTION)
|
||||
|
||||
|
||||
/**
|
||||
* @brief 获取风噪检测开关
|
||||
*
|
||||
* @result bool
|
||||
*/
|
||||
bool get_wind_noise_detection_switch()
|
||||
{
|
||||
printf("===%s===", __FUNCTION__);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置风噪检测开关
|
||||
*/
|
||||
void set_wind_noise_detection_switch(bool detection_switch)
|
||||
{
|
||||
printf("%s, switch:%d\n", __FUNCTION__, detection_switch);
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_WIND_NOISE_DETECTION, NULL, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
+18
@@ -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__
|
||||
+171
@@ -0,0 +1,171 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".adv_work_setting.data.bss")
|
||||
#pragma data_seg(".adv_work_setting.data")
|
||||
#pragma const_seg(".adv_work_setting.text.const")
|
||||
#pragma code_seg(".adv_work_setting.text")
|
||||
#endif
|
||||
#include "app_config.h"
|
||||
#include "adv_work_setting.h"
|
||||
#include "syscfg_id.h"
|
||||
#include "ble_rcsp_server.h"
|
||||
#include "rcsp_adv_bluetooth.h"
|
||||
|
||||
#include "rcsp_setting_sync.h"
|
||||
#include "rcsp_setting_opt.h"
|
||||
#include "os/os_api.h"
|
||||
#include "btstack/avctp_user.h"
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
#include "bt_tws.h"
|
||||
#endif
|
||||
|
||||
#if (RCSP_MODE && RCSP_ADV_EN)
|
||||
#if RCSP_ADV_WORK_SET_ENABLE
|
||||
|
||||
static u8 g_work_mode = RCSPWorkModeNormal;
|
||||
|
||||
extern void bt_set_low_latency_mode(int enable, u8 tone_play_enable, int delay_ms);
|
||||
static void set_work_setting(u8 *work_setting_info)
|
||||
{
|
||||
g_work_mode = *work_setting_info;
|
||||
/* printf("rcsp_work %s, %s, %d, mode:%d\n", __FILE__, __FUNCTION__, __LINE__, g_work_mode); */
|
||||
}
|
||||
|
||||
static int get_work_setting(u8 *work_setting_info)
|
||||
{
|
||||
/* printf("rcsp_work %s, %s, %d, mode:%d\n", __FILE__, __FUNCTION__, __LINE__, g_work_mode); */
|
||||
*work_setting_info = g_work_mode;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void adv_work_setting_vm_value(u8 *work_setting_info)
|
||||
{
|
||||
syscfg_write(CFG_RCSP_ADV_WORK_SETTING, work_setting_info, sizeof(u8));
|
||||
}
|
||||
|
||||
static void adv_work_setting_sync(u8 *work_setting_info)
|
||||
{
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if (get_bt_tws_connect_status()) {
|
||||
update_rcsp_setting(ATTR_TYPE_WORK_MODE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __rcsp_work_set_call(void)
|
||||
{
|
||||
/* printf("__rcsp_work_set_call\n"); */
|
||||
if (RCSPWorkModeNormal == g_work_mode) {
|
||||
bt_set_low_latency_mode(0, 1, 300);
|
||||
} else if (RCSPWorkModeGame == g_work_mode) {
|
||||
bt_set_low_latency_mode(1, 1, 300);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
/* printf("%s, err %x\n", __FUNCTION__, err); */
|
||||
}
|
||||
|
||||
static void update_work_setting_state(void)
|
||||
{
|
||||
/* printf("%s, set deal\n", __FUNCTION__); */
|
||||
rcsp_work_set_deal();
|
||||
}
|
||||
|
||||
static void deal_work_setting(u8 *work_setting_info, u8 write_vm, u8 tws_sync)
|
||||
{
|
||||
/* printf("rcsp_work %s, %s, %d, work_setting_info:%d\n", __FILE__, __FUNCTION__, __LINE__, *work_setting_info); */
|
||||
if (work_setting_info) {
|
||||
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();
|
||||
}
|
||||
|
||||
void rcsp_set_work_mode(RCSPWorkMode work_mode)
|
||||
{
|
||||
u8 _work_mode = work_mode;
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if (get_bt_tws_connect_status()) {
|
||||
if (TWS_ROLE_MASTER == tws_api_get_role()) {
|
||||
deal_work_setting(&_work_mode, 1, 1);
|
||||
}
|
||||
} else {
|
||||
deal_work_setting(&_work_mode, 1, 1);
|
||||
}
|
||||
#else
|
||||
deal_work_setting(&_work_mode, 1, 1);
|
||||
#endif
|
||||
u8 adv_cmd = 0x0;
|
||||
adv_info_device_request(&adv_cmd, sizeof(adv_cmd));
|
||||
}
|
||||
|
||||
int ble_vendor_is_slow_state(void)
|
||||
{
|
||||
if ((BT_STATUS_PLAYING_MUSIC == bt_get_connect_status()) && (RCSPWorkModeGame == g_work_mode)) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int adv_work_opt_init(void)
|
||||
{
|
||||
u8 work_setting_info = RCSPWorkModeNormal;
|
||||
if (rcsp_read_data_from_vm(CFG_RCSP_ADV_WORK_SETTING, &work_setting_info, sizeof(work_setting_info))) {
|
||||
if (work_setting_info != RCSPWorkModeNormal && work_setting_info != RCSPWorkModeGame) {
|
||||
work_setting_info = RCSPWorkModeNormal;
|
||||
}
|
||||
set_work_setting(&work_setting_info);
|
||||
__rcsp_work_set_call();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int work_set_setting_extra_handle(void *setting_data, void *setting_data_len)
|
||||
{
|
||||
u8 dlen = *((u8 *)setting_data_len);
|
||||
u8 *work_mode_setting_data = (u8 *)setting_data;
|
||||
memcpy(&g_work_mode, work_mode_setting_data, dlen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int work_get_setting_extra_handle(void *setting_data, void *setting_data_len)
|
||||
{
|
||||
u8 **setting_data_ptr = (u8 **)setting_data;
|
||||
*setting_data_ptr = &g_work_mode;
|
||||
return sizeof(g_work_mode);
|
||||
}
|
||||
|
||||
static RCSP_SETTING_OPT adv_work_opt = {
|
||||
.data_len = 1,
|
||||
.setting_type = ATTR_TYPE_WORK_MODE,
|
||||
.syscfg_id = CFG_RCSP_ADV_WORK_SETTING,
|
||||
.deal_opt_setting = deal_work_setting,
|
||||
.set_setting = set_work_setting,
|
||||
.get_setting = get_work_setting,
|
||||
.custom_setting_init = adv_work_opt_init,
|
||||
.custom_vm_info_update = NULL,
|
||||
.custom_setting_update = NULL,
|
||||
.custom_sibling_setting_deal = NULL,
|
||||
.custom_setting_release = NULL,
|
||||
.set_setting_extra_handle = work_set_setting_extra_handle,
|
||||
.get_setting_extra_handle = work_get_setting_extra_handle,
|
||||
};
|
||||
|
||||
REGISTER_APP_SETTING_OPT(adv_work_opt);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
#ifndef __ADV_WORK_SETTING_H__
|
||||
#define __ADV_WORK_SETTING_H__
|
||||
|
||||
typedef enum {
|
||||
RCSPWorkModeNone = 0,
|
||||
RCSPWorkModeNormal = 1,
|
||||
RCSPWorkModeGame = 2,
|
||||
} RCSPWorkMode;
|
||||
|
||||
// 设置工作模式
|
||||
void rcsp_set_work_mode(RCSPWorkMode work_mode);
|
||||
|
||||
#endif
|
||||
+226
@@ -0,0 +1,226 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".rcsp_color_led_setting.data.bss")
|
||||
#pragma data_seg(".rcsp_color_led_setting.data")
|
||||
#pragma const_seg(".rcsp_color_led_setting.text.const")
|
||||
#pragma code_seg(".rcsp_color_led_setting.text")
|
||||
#endif
|
||||
#include "rcsp_color_led_setting.h"
|
||||
#if (RCSP_MODE && RCSP_ADV_COLOR_LED_SET_ENABLE)
|
||||
#include "syscfg_id.h"
|
||||
#include "user_cfg.h"
|
||||
|
||||
#include "rcsp_setting_sync.h"
|
||||
#include "rcsp_setting_opt.h"
|
||||
|
||||
#include "ui_manage.h"
|
||||
#include "asm/pwm_led.h"
|
||||
#include "color_led_app.h"
|
||||
#define IS_COLOR_LED_LEGAL(color_led) \
|
||||
((color_led.open_status <= 2) && \
|
||||
(color_led.mode <= 2) && \
|
||||
(color_led.fre_mode <= 3))
|
||||
|
||||
enum {
|
||||
OPEN_STATUS_CLOSE = 0,
|
||||
OPEN_STATUS_OPEN = 1,
|
||||
OPEN_STATUS_SETTING = 2,
|
||||
};
|
||||
enum {
|
||||
MODE_LIGHT = 0,
|
||||
MODE_TWINKLE = 1,
|
||||
MODE_USER = 2,
|
||||
};
|
||||
const u32 twinkle_color_table[] = {
|
||||
COLOR_RED,
|
||||
COLOR_ORANGE,
|
||||
COLOR_YELLOW,
|
||||
COLOR_GREEN,
|
||||
COLOR_CYAN,
|
||||
COLOR_BLUE,
|
||||
COLOR_PURPLE,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
u8 open_status : 2;//0:关闭 1:打开 2:设置模式
|
||||
u8 mode : 3;//0:彩色 2:闪烁 3:情景模式
|
||||
u8 reseved : 3;
|
||||
u8 red;
|
||||
u8 green;
|
||||
u8 blue;
|
||||
u8 twinkle_mode;
|
||||
u8 fre_mode;
|
||||
u8 user_mode;
|
||||
u16 hue;
|
||||
u8 saturation;
|
||||
u8 lightness;
|
||||
} __attribute__((packed)) color_led_t;
|
||||
static color_led_t color_led;
|
||||
|
||||
#define COLOR_LED_PROTOCOL_DATA_LEN (sizeof(color_led_t))
|
||||
|
||||
u32 rcsp_get_color_led_setting_data_len(void)
|
||||
{
|
||||
return COLOR_LED_PROTOCOL_DATA_LEN;
|
||||
}
|
||||
|
||||
static void set_color_led_setting(u8 *color_led_setting_info)
|
||||
{
|
||||
/* printf("%s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__); */
|
||||
/* put_buf(color_led_setting_info, COLOR_LED_PROTOCOL_DATA_LEN); */
|
||||
color_led_t color_led_cur;
|
||||
memcpy((u8 *)&color_led_cur, color_led_setting_info, sizeof(color_led_t));
|
||||
if ((color_led_cur.open_status == 0) || (color_led_cur.open_status == 1)) {
|
||||
//switch active,not set other_status
|
||||
color_led.open_status = color_led_cur.open_status;
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy((u8 *)&color_led, color_led_setting_info, sizeof(color_led_t));
|
||||
}
|
||||
|
||||
static int get_color_led_setting(u8 *color_led_setting_info)
|
||||
{
|
||||
color_led_t color_led_cur;
|
||||
int len = syscfg_read(VM_COLOR_LED_SETTING, color_led_setting_info, COLOR_LED_PROTOCOL_DATA_LEN);
|
||||
|
||||
if (len != COLOR_LED_PROTOCOL_DATA_LEN) {
|
||||
printf("!!!!!!!!color led data read error !!!!!!!!!!!!!!! \n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 1、写入VM
|
||||
static void update_color_led_setting_vm_value(u8 *color_led_setting_info)
|
||||
{
|
||||
color_led_t color_led_cur;
|
||||
memcpy((u8 *)&color_led_cur, color_led_setting_info, sizeof(color_led_t));
|
||||
if ((color_led_cur.open_status == 0) || (color_led_cur.open_status == 1)) {
|
||||
//switch active,not set other_status
|
||||
u8 open_status = color_led_cur.open_status;
|
||||
int len = syscfg_read(VM_COLOR_LED_SETTING, (u8 *)&color_led_cur, COLOR_LED_PROTOCOL_DATA_LEN);
|
||||
color_led_cur.open_status = open_status;
|
||||
syscfg_write(VM_COLOR_LED_SETTING, (u8 *)&color_led_cur, COLOR_LED_PROTOCOL_DATA_LEN);
|
||||
return;
|
||||
}
|
||||
|
||||
syscfg_write(VM_COLOR_LED_SETTING, color_led_setting_info, COLOR_LED_PROTOCOL_DATA_LEN);
|
||||
}
|
||||
// 2、同步对端
|
||||
static void color_led_setting_sync(u8 *color_led_setting_info)
|
||||
{
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
extern int get_bt_tws_connect_status();
|
||||
if (get_bt_tws_connect_status()) {
|
||||
update_rcsp_setting(ATTR_TYPE_COLOR_LED_SETTING);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void color_led_flash(void)
|
||||
{
|
||||
|
||||
color_led_t color_led_cur;
|
||||
get_color_led_setting((u8 *)&color_led_cur);
|
||||
if (!IS_COLOR_LED_LEGAL(color_led_cur)) {
|
||||
printf("color led illegal data \n");
|
||||
return;
|
||||
}
|
||||
|
||||
u8 mode = 0;
|
||||
u8 fre_mode = 0;
|
||||
u32 color = 0;
|
||||
|
||||
if (color_led_cur.open_status == OPEN_STATUS_CLOSE) {
|
||||
mode = COLOR_LED_MODE_LIGHT;
|
||||
color = COLOR_BLACK;
|
||||
color_led_set_api(mode, fre_mode, color);
|
||||
return;
|
||||
}
|
||||
|
||||
fre_mode = color_led_cur.fre_mode;
|
||||
color = color_led_cur.red + ((int)color_led_cur.green << 8) + ((int)color_led_cur.blue << 16);
|
||||
switch (color_led_cur.mode) {
|
||||
case MODE_LIGHT:
|
||||
mode = COLOR_LED_MODE_LIGHT;
|
||||
break;
|
||||
case MODE_TWINKLE:
|
||||
if (color_led_cur.twinkle_mode == 0) {
|
||||
mode = COLOR_LED_MODE_COLORFUL_TWINKLE;
|
||||
} else {
|
||||
mode = COLOR_LED_MODE_TWINKLE;
|
||||
color = twinkle_color_table[color_led_cur.twinkle_mode - 1];
|
||||
}
|
||||
break;
|
||||
case MODE_USER:
|
||||
mode = COLOR_LED_MODE_RAINBOW + color_led_cur.user_mode;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
printf("mode:%d fre_mode:%d color:0x%x \n", mode, fre_mode, color);
|
||||
color_led_set_api(mode, fre_mode, color);
|
||||
}
|
||||
|
||||
static void deal_color_led_setting(u8 *color_led_setting_info, u8 write_vm, u8 tws_sync)
|
||||
{
|
||||
u8 led_setting[COLOR_LED_PROTOCOL_DATA_LEN];
|
||||
if (!color_led_setting_info) {
|
||||
get_color_led_setting(led_setting);
|
||||
} else {
|
||||
memcpy(led_setting, color_led_setting_info, COLOR_LED_PROTOCOL_DATA_LEN);
|
||||
set_color_led_setting(color_led_setting_info);
|
||||
}
|
||||
if (write_vm) {
|
||||
update_color_led_setting_vm_value(led_setting);
|
||||
}
|
||||
if (tws_sync) {
|
||||
color_led_setting_sync(led_setting);
|
||||
}
|
||||
|
||||
color_led_flash();
|
||||
}
|
||||
|
||||
static int rcsp_color_led_init(void)
|
||||
{
|
||||
color_led_t color_led_cur;
|
||||
int len = syscfg_read(VM_COLOR_LED_SETTING, (u8 *)&color_led_cur, COLOR_LED_PROTOCOL_DATA_LEN);
|
||||
|
||||
if ((!IS_COLOR_LED_LEGAL(color_led)) || (len != COLOR_LED_PROTOCOL_DATA_LEN)) {
|
||||
printf("first time start device,reset color led data \n");
|
||||
memset((u8 *)&color_led_cur, 0x00, sizeof(color_led_cur));
|
||||
color_led_cur.open_status = OPEN_STATUS_SETTING;
|
||||
color_led_cur.mode = MODE_USER;
|
||||
color_led_cur.red = 64;
|
||||
color_led_cur.green = 191;
|
||||
color_led_cur.blue = 191;
|
||||
color_led_cur.hue = 180;
|
||||
color_led_cur.saturation = 50;
|
||||
color_led_cur.lightness = 50;
|
||||
color_led_set_api(COLOR_LED_MODE_RAINBOW + color_led_cur.user_mode, 0, 0);
|
||||
syscfg_write(VM_COLOR_LED_SETTING, (u8 *)&color_led_cur, COLOR_LED_PROTOCOL_DATA_LEN);
|
||||
color_led = color_led_cur;
|
||||
}
|
||||
|
||||
set_color_led_setting((u8 *)&color_led_cur);
|
||||
deal_color_led_setting(NULL, 0, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static RCSP_SETTING_OPT adv_color_led_opt = {
|
||||
.data_len = COLOR_LED_PROTOCOL_DATA_LEN,
|
||||
.setting_type = ATTR_TYPE_COLOR_LED_SETTING,
|
||||
.syscfg_id = VM_COLOR_LED_SETTING,
|
||||
.deal_opt_setting = deal_color_led_setting,
|
||||
.set_setting = set_color_led_setting,
|
||||
.get_setting = get_color_led_setting,
|
||||
.custom_setting_init = rcsp_color_led_init,
|
||||
.custom_vm_info_update = NULL,
|
||||
.custom_setting_update = NULL,
|
||||
.custom_sibling_setting_deal = NULL,
|
||||
.custom_setting_release = NULL,
|
||||
};
|
||||
REGISTER_APP_SETTING_OPT(adv_color_led_opt);
|
||||
|
||||
#endif
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
#ifndef __RCSP_MUSIC_INFO_SETTING_H__
|
||||
#define __RCSP_MUSIC_INFO_SETTING_H__
|
||||
|
||||
#include "system/includes.h"
|
||||
#include "app_config.h"
|
||||
|
||||
// 获取彩灯配置的数据长度
|
||||
u32 rcsp_get_color_led_setting_data_len(void);
|
||||
|
||||
#endif
|
||||
+444
@@ -0,0 +1,444 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".rcsp_eq_setting.data.bss")
|
||||
#pragma data_seg(".rcsp_eq_setting.data")
|
||||
#pragma const_seg(".rcsp_eq_setting.text.const")
|
||||
#pragma code_seg(".rcsp_eq_setting.text")
|
||||
#endif
|
||||
#include "app_config.h"
|
||||
#include "syscfg_id.h"
|
||||
#include "ble_rcsp_server.h"
|
||||
#include "smartbox_user_app.h"
|
||||
#include "rcsp_setting_sync.h"
|
||||
#include "rcsp_setting_opt.h"
|
||||
#include "rcsp_manage.h"
|
||||
#include "rcsp_bt_manage.h"
|
||||
|
||||
#define LOG_TAG_CONST APP
|
||||
#define LOG_TAG "[RCSP-EQ]"
|
||||
#define LOG_ERROR_ENABLE
|
||||
#define LOG_DEBUG_ENABLE
|
||||
#define LOG_INFO_ENABLE
|
||||
#define LOG_DUMP_ENABLE
|
||||
#define LOG_CHAR_ENABLE
|
||||
#include "debug.h"
|
||||
|
||||
#if (defined(TCFG_EQ_ENABLE) && TCFG_EQ_ENABLE && RCSP_MODE && RCSP_ADV_EQ_SET_ENABLE)
|
||||
|
||||
#if RCSP_MODE == RCSP_MODE_EARPHONE
|
||||
#include "media/effects/audio_eq.h"
|
||||
#include "media/effects/eq_config.h"
|
||||
#else
|
||||
#ifndef CONFIG_MEDIA_NEW_ENABLE
|
||||
#include "media/eq_config.h"
|
||||
#else
|
||||
#include "effects/audio_eq.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#include "clock_manager/clock_manager.h"
|
||||
|
||||
extern int get_bt_tws_connect_status();
|
||||
|
||||
__attribute__((weak))
|
||||
u8 eq_get_table_nsection(EQ_MODE mode)
|
||||
{
|
||||
return EQ_SECTION_MAX;
|
||||
}
|
||||
|
||||
static u8 g_eq_setting_info[11] = {0};
|
||||
|
||||
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) {
|
||||
clock_refurbish();
|
||||
eq_mode_set(mode);
|
||||
} else {
|
||||
// 自定义修改EQ参数
|
||||
if (EQ_MODE_CUSTOM == mode) {
|
||||
clock_refurbish();
|
||||
if (status != 0x7F) {
|
||||
u8 i;
|
||||
for (i = 0; i < eq_get_table_nsection(0); 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void set_eq_setting(u8 *eq_setting)
|
||||
{
|
||||
memcpy(g_eq_setting_info, eq_setting, 11);
|
||||
}
|
||||
|
||||
static int get_eq_setting(u8 *eq_setting)
|
||||
{
|
||||
memcpy(eq_setting, g_eq_setting_info, 11);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 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_rcsp_setting(ATTR_TYPE_EQ_SETTING);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static 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 {
|
||||
g_eq_setting_info[0] = eq_setting[0];
|
||||
get_eq_setting(eq_info);
|
||||
}
|
||||
} else {
|
||||
memcpy(eq_info, eq_setting, 11);
|
||||
g_eq_setting_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);
|
||||
}
|
||||
|
||||
|
||||
static 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_get_table_nsection(0)) {
|
||||
// 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_get_table_nsection(0);
|
||||
data_len++;
|
||||
for (i = 0; i < eq_get_table_nsection(0); 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;
|
||||
}
|
||||
|
||||
static u8 app_get_eq_all_info(u8 *get_eq_info)
|
||||
{
|
||||
u16 i;
|
||||
u8 mode = EQ_MODE_NORMAL;
|
||||
get_eq_info[0] = eq_get_table_nsection(0);
|
||||
u8 data_len = 1;
|
||||
// get freq
|
||||
for (i = 0; i < eq_get_table_nsection(0); 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_get_table_nsection(0)) {
|
||||
get_eq_info[data_len] |= (1 << 7);
|
||||
}
|
||||
data_len++;
|
||||
for (i = 0; i < eq_get_table_nsection(0); 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_get_table_nsection(0)) {
|
||||
get_eq_info[data_len] |= (1 << 7);
|
||||
}
|
||||
data_len++;
|
||||
for (i = 0; i < eq_get_table_nsection(0); i++) {
|
||||
if (10 == eq_get_table_nsection(0)) {
|
||||
get_eq_info[data_len] = g_eq_setting_info[i + 1];
|
||||
} else {
|
||||
get_eq_info[data_len] = g_eq_setting_info[i + 2];
|
||||
}
|
||||
data_len++;
|
||||
}
|
||||
|
||||
return data_len;
|
||||
}
|
||||
|
||||
static int eq_opt_init(void)
|
||||
{
|
||||
u8 eq_setting_vm_info[11] = {0};
|
||||
u8 eq_setting_info[10] = {0};
|
||||
u8 eq_setting_mode = 0;
|
||||
u8 i;
|
||||
if (rcsp_read_data_from_vm(CFG_RCSP_ADV_EQ_DATA_SETTING, eq_setting_info, sizeof(eq_setting_info))) {
|
||||
if (rcsp_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, 10);
|
||||
set_eq_setting(eq_setting_vm_info);
|
||||
deal_eq_setting(NULL, 0, 0);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int eq_get_setting_extra_handle(void *setting_data, void *setting_data_len)
|
||||
{
|
||||
u16 data_len = *((u16 *) setting_data_len);
|
||||
if (data_len > sizeof(g_eq_setting_info)) {
|
||||
data_len = app_get_eq_all_info(setting_data);
|
||||
} else {
|
||||
data_len = app_get_eq_info(setting_data);
|
||||
}
|
||||
return data_len;
|
||||
}
|
||||
|
||||
static RCSP_SETTING_OPT eq_opt = {
|
||||
.data_len = 11,
|
||||
.setting_type = ATTR_TYPE_EQ_SETTING,
|
||||
.syscfg_id = CFG_RCSP_ADV_EQ_DATA_SETTING,
|
||||
.deal_opt_setting = deal_eq_setting,
|
||||
.set_setting = set_eq_setting,
|
||||
.get_setting = get_eq_setting,
|
||||
.custom_setting_init = eq_opt_init,
|
||||
.custom_vm_info_update = NULL,
|
||||
.custom_setting_update = NULL,
|
||||
.custom_sibling_setting_deal = NULL,
|
||||
.custom_setting_release = NULL,
|
||||
.set_setting_extra_handle = NULL,
|
||||
.get_setting_extra_handle = eq_get_setting_extra_handle,
|
||||
};
|
||||
REGISTER_APP_SETTING_OPT(eq_opt);
|
||||
|
||||
#elif ((!TCFG_EQ_ENABLE) && RCSP_MODE && RCSP_ADV_EQ_SET_ENABLE && (defined TCFG_CSC_BT_APP) && TCFG_CSC_BT_APP)
|
||||
|
||||
#if RCSP_MODE == RCSP_MODE_EARPHONE
|
||||
#include "media/effects/audio_eq.h"
|
||||
#include "media/effects/eq_config.h"
|
||||
#else
|
||||
#ifndef CONFIG_MEDIA_NEW_ENABLE
|
||||
#include "media/eq_config.h"
|
||||
#else
|
||||
#include "effects/audio_eq.h"
|
||||
#endif
|
||||
#endif
|
||||
#include "clock_manager/clock_manager.h"
|
||||
#include "smartbox_info_manager.h"
|
||||
|
||||
|
||||
static u8 g_eq_setting_info[11];
|
||||
|
||||
|
||||
static void set_eq_setting(u8 *eq_setting)
|
||||
{
|
||||
memcpy(g_eq_setting_info, eq_setting, 11);
|
||||
}
|
||||
|
||||
static int get_eq_setting(u8 *eq_setting)
|
||||
{
|
||||
memcpy(eq_setting, g_eq_setting_info, 11);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//eq配置 写入vm和通知app
|
||||
void eq_ui_set_rcsp_vm(u8 mode)
|
||||
{
|
||||
u8 eq_info[11] = {0};
|
||||
get_eq_setting(eq_info);
|
||||
eq_info[0] = mode;
|
||||
set_eq_setting(eq_info);
|
||||
update_eq_vm_value(eq_info);
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_EQ, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
static 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 {
|
||||
g_eq_setting_info[0] = eq_setting[0];
|
||||
get_eq_setting(eq_info);
|
||||
}
|
||||
} else {
|
||||
memcpy(eq_info, eq_setting, 11);
|
||||
g_eq_setting_info[0] = eq_setting[0];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (write_vm) {
|
||||
update_eq_vm_value(eq_info);
|
||||
}
|
||||
|
||||
log_info("%s %d %d eq_mode:%d", __func__, write_vm, tws_sync, eq_info[0]);
|
||||
sbox_equalizer_mode_set(eq_info[0]);
|
||||
|
||||
if (tws_sync) {
|
||||
custom_client_send_eq_mode(eq_info[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int eq_get_setting_extra_handle(void *setting_data, void *setting_data_len)
|
||||
{
|
||||
u16 data_len = *((u16 *) setting_data_len);
|
||||
// if (data_len > sizeof(g_eq_setting_info)) {
|
||||
// data_len = app_get_eq_all_info(setting_data);
|
||||
// } else {
|
||||
// data_len = app_get_eq_info(setting_data);
|
||||
// }
|
||||
|
||||
if (data_len > sizeof(g_eq_setting_info)) {
|
||||
data_len = sizeof(g_eq_setting_info);
|
||||
memcpy(setting_data, g_eq_setting_info, data_len);
|
||||
} else {
|
||||
memcpy(setting_data, g_eq_setting_info, data_len);
|
||||
}
|
||||
|
||||
return data_len;
|
||||
}
|
||||
|
||||
static int eq_opt_init(void)
|
||||
{
|
||||
u8 eq_setting_vm_info[11] = {0};
|
||||
u8 eq_setting_info[10] = {0};
|
||||
u8 eq_setting_mode = 0;
|
||||
u8 i;
|
||||
int ret;
|
||||
|
||||
log_info("%s", __func__);
|
||||
ret = rcsp_read_data_from_vm(CFG_RCSP_ADV_EQ_DATA_SETTING, eq_setting_info, sizeof(eq_setting_info));
|
||||
if (ret == sizeof(eq_setting_info)) {
|
||||
memcpy(&eq_setting_vm_info[1], eq_setting_info, 10);
|
||||
}
|
||||
|
||||
ret = rcsp_read_data_from_vm(CFG_RCSP_ADV_EQ_MODE_SETTING, &eq_setting_mode, sizeof(eq_setting_mode));
|
||||
if (ret == sizeof(eq_setting_mode)) {
|
||||
eq_setting_vm_info[0] = eq_setting_mode;
|
||||
}
|
||||
|
||||
set_eq_setting(eq_setting_vm_info);
|
||||
deal_eq_setting(NULL, 0, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static RCSP_SETTING_OPT eq_opt = {
|
||||
.data_len = 11,
|
||||
.setting_type = ATTR_TYPE_EQ_SETTING,
|
||||
.syscfg_id = CFG_RCSP_ADV_EQ_DATA_SETTING,
|
||||
.deal_opt_setting = deal_eq_setting,
|
||||
.set_setting = set_eq_setting,
|
||||
.get_setting = get_eq_setting,
|
||||
.custom_setting_init = eq_opt_init,
|
||||
.custom_vm_info_update = NULL,
|
||||
.custom_setting_update = NULL,
|
||||
.custom_sibling_setting_deal = NULL,
|
||||
.custom_setting_release = NULL,
|
||||
.set_setting_extra_handle = NULL,
|
||||
.get_setting_extra_handle = eq_get_setting_extra_handle,
|
||||
};
|
||||
REGISTER_APP_SETTING_OPT(eq_opt);
|
||||
#else
|
||||
void eq_ui_set_rcsp_vm(u8 mode)
|
||||
{
|
||||
printf("%s is NULL warn!!!", __func__);
|
||||
}
|
||||
#endif
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".rcsp_high_low_vol_setting.data.bss")
|
||||
#pragma data_seg(".rcsp_high_low_vol_setting.data")
|
||||
#pragma const_seg(".rcsp_high_low_vol_setting.text.const")
|
||||
#pragma code_seg(".rcsp_high_low_vol_setting.text")
|
||||
#endif
|
||||
#include "app_config.h"
|
||||
#include "syscfg_id.h"
|
||||
|
||||
#include "rcsp_setting_sync.h"
|
||||
#include "rcsp_setting_opt.h"
|
||||
#include "ble_rcsp_server.h"
|
||||
|
||||
#include "JL_rcsp_protocol.h"
|
||||
#include "effects/audio_bass_treble_eq.h"
|
||||
|
||||
#if (RCSP_MODE && RCSP_ADV_HIGH_LOW_SET && TCFG_BASS_TREBLE_NODE_ENABLE)
|
||||
|
||||
struct _HIGH_LOW_VOL {
|
||||
int low_vol;
|
||||
int high_vol;
|
||||
};
|
||||
|
||||
static struct _HIGH_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);
|
||||
|
||||
static int get_high_low_vol_info(u8 *vol_gain_param)
|
||||
{
|
||||
memcpy(vol_gain_param, &high_low_vol, sizeof(struct _HIGH_LOW_VOL));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void set_high_low_vol_info(u8 *vol_gain_param)
|
||||
{
|
||||
memcpy(&high_low_vol, vol_gain_param, sizeof(struct _HIGH_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 _HIGH_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_rcsp_setting(ATTR_TYPE_HIGH_LOW_VOL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void high_low_vol_state_update(void)
|
||||
{
|
||||
static int low_vol = 0;
|
||||
static int high_vol = 0;
|
||||
struct high_bass param = {0};
|
||||
if (low_vol != high_low_vol.low_vol) {
|
||||
param.gain = high_low_vol.low_vol - 12;
|
||||
mix_out_high_bass(AUDIO_EQ_BASS, ¶m);
|
||||
low_vol = high_low_vol.low_vol;
|
||||
}
|
||||
if (high_vol != high_low_vol.high_vol) {
|
||||
param.gain = high_low_vol.high_vol - 12;
|
||||
mix_out_high_bass(AUDIO_EQ_HIGH, ¶m);
|
||||
high_vol = high_low_vol.high_vol;
|
||||
}
|
||||
}
|
||||
|
||||
static void deal_high_low_vol(u8 *vol_gain_data, u8 write_vm, u8 tws_sync)
|
||||
{
|
||||
if (vol_gain_data) {
|
||||
set_high_low_vol_info(vol_gain_data);
|
||||
printf("low %d, high %d\n", high_low_vol.low_vol, high_low_vol.high_vol);
|
||||
}
|
||||
if (write_vm) {
|
||||
update_high_low_vol_vm_value((u8 *)&high_low_vol);
|
||||
}
|
||||
if (tws_sync) {
|
||||
high_low_vol_setting_sync((u8 *)&high_low_vol);
|
||||
}
|
||||
high_low_vol_state_update();
|
||||
}
|
||||
|
||||
static int high_low_set_setting_extra_handle(void *setting_data, void *setting_data_len)
|
||||
{
|
||||
high_low_vol.low_vol = READ_BIG_U32(setting_data) + 12;
|
||||
high_low_vol.high_vol = READ_BIG_U32(setting_data + 4) + 12;
|
||||
high_low_vol.low_vol = high_low_vol.low_vol > 24 ? 24 : high_low_vol.low_vol;
|
||||
high_low_vol.low_vol = high_low_vol.low_vol < 0 ? 0 : high_low_vol.low_vol;
|
||||
high_low_vol.high_vol = high_low_vol.high_vol > 24 ? 24 : high_low_vol.high_vol;
|
||||
high_low_vol.high_vol = high_low_vol.high_vol < 0 ? 0 : high_low_vol.high_vol;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int high_low_get_setting_extra_handle(void *setting_data, void *setting_data_len)
|
||||
{
|
||||
struct _HIGH_LOW_VOL gain_param = {0};
|
||||
gain_param.low_vol = high_low_vol.low_vol < 0 ? 0 : high_low_vol.low_vol;
|
||||
gain_param.low_vol = high_low_vol.low_vol > 24 ? 24 : high_low_vol.low_vol;
|
||||
gain_param.high_vol = high_low_vol.high_vol < 0 ? 0 : high_low_vol.high_vol;
|
||||
gain_param.high_vol = high_low_vol.high_vol > 24 ? 24 : high_low_vol.high_vol;
|
||||
gain_param.low_vol -= 12;
|
||||
gain_param.high_vol -= 12;
|
||||
gain_param.low_vol = READ_BIG_U32((u8 *)&gain_param.low_vol);
|
||||
gain_param.high_vol = READ_BIG_U32((u8 *)&gain_param.high_vol);
|
||||
memcpy(setting_data, &gain_param, sizeof(gain_param));
|
||||
return sizeof(gain_param);
|
||||
}
|
||||
|
||||
static RCSP_SETTING_OPT high_low_vol_opt = {
|
||||
.data_len = 8,
|
||||
.setting_type = ATTR_TYPE_HIGH_LOW_VOL,
|
||||
.syscfg_id = CFG_RCSP_ADV_HIGH_LOW_VOL,
|
||||
.deal_opt_setting = deal_high_low_vol,
|
||||
.set_setting = set_high_low_vol_info,
|
||||
.get_setting = get_high_low_vol_info,
|
||||
.custom_setting_init = NULL,
|
||||
.custom_setting_release = NULL,
|
||||
.custom_vm_info_update = NULL,
|
||||
.custom_setting_update = NULL,
|
||||
.custom_sibling_setting_deal = NULL,
|
||||
.set_setting_extra_handle = high_low_set_setting_extra_handle,
|
||||
.get_setting_extra_handle = high_low_get_setting_extra_handle,
|
||||
};
|
||||
REGISTER_APP_SETTING_OPT(high_low_vol_opt);
|
||||
|
||||
#endif
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".rcsp_karaoke_eq_setting.data.bss")
|
||||
#pragma data_seg(".rcsp_karaoke_eq_setting.data")
|
||||
#pragma const_seg(".rcsp_karaoke_eq_setting.text.const")
|
||||
#pragma code_seg(".rcsp_karaoke_eq_setting.text")
|
||||
#endif
|
||||
#include "app_config.h"
|
||||
#include "syscfg_id.h"
|
||||
#include "ble_rcsp_server.h"
|
||||
|
||||
#include "rcsp_setting_sync.h"
|
||||
#include "rcsp_setting_opt.h"
|
||||
|
||||
#if (defined(TCFG_EQ_ENABLE) && MIC_EFFECT_EQ_EN && RCSP_MODE && RCSP_ADV_KARAOKE_EQ_SET_ENABLE && RCSP_ADV_KARAOKE_SET_ENABLE)
|
||||
|
||||
#include "effect_cfg.h"
|
||||
#include "effect_tool.h"
|
||||
#include "mic_effect.h"
|
||||
|
||||
static u8 g_karaoke_setting_info[9] = {EFFECT_EQ_SECTION_MAX, 0};
|
||||
|
||||
static void update_eq_setting_info(u8 *eq_info_data)
|
||||
{
|
||||
// 更新卡拉ok的EQ值
|
||||
struct eq_seg_info *eq_info = NULL;
|
||||
for (u8 i = 0; i < EFFECT_EQ_SECTION_MAX; i++) {
|
||||
eq_info = mic_eq_get_info(i);
|
||||
if (eq_info->gain != g_karaoke_setting_info[i + 1]) {
|
||||
eq_info->gain = g_karaoke_setting_info[i + 1];
|
||||
mic_eq_set_info(eq_info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void set_karaoke_eq_setting(u8 *eq_setting)
|
||||
{
|
||||
memcpy(g_karaoke_setting_info, eq_setting, sizeof(g_karaoke_setting_info));
|
||||
}
|
||||
|
||||
static int get_karaoke_eq_setting(u8 *eq_setting)
|
||||
{
|
||||
memcpy(eq_setting, g_karaoke_setting_info, sizeof(g_karaoke_setting_info));
|
||||
return sizeof(g_karaoke_setting_info);
|
||||
}
|
||||
|
||||
// 1、写入VM
|
||||
static void update_karaoke_eq_vm_value(u8 *eq_setting)
|
||||
{
|
||||
syscfg_write(VM_KARAOKE_EQ_SETTING, g_karaoke_setting_info, 9);
|
||||
}
|
||||
|
||||
// 2、同步对端
|
||||
static void karaoke_eq_sync(u8 *eq_setting)
|
||||
{
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if (get_bt_tws_connect_status()) {
|
||||
update_rcsp_setting(ATTR_TYPE_KARAOKE_EQ_SETTING);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void deal_karaoke_eq_setting(u8 *eq_setting, u8 write_vm, u8 tws_sync)
|
||||
{
|
||||
if (eq_setting) {
|
||||
set_karaoke_eq_setting(eq_setting);
|
||||
}
|
||||
if (write_vm) {
|
||||
update_karaoke_eq_vm_value(eq_setting);
|
||||
}
|
||||
if (tws_sync) {
|
||||
karaoke_eq_sync(eq_setting);
|
||||
}
|
||||
update_eq_setting_info(eq_setting);
|
||||
}
|
||||
|
||||
// 0 - gain
|
||||
// 1 - freq
|
||||
static u8 get_karaoke_eq_info(u8 *get_eq_info, u8 type)
|
||||
{
|
||||
u8 i;
|
||||
u8 data_len = 1;
|
||||
struct eq_seg_info *eq_info = NULL;
|
||||
get_eq_info[0] = EFFECT_EQ_SECTION_MAX;
|
||||
for (i = 0; i < EFFECT_EQ_SECTION_MAX; i++) {
|
||||
eq_info = mic_eq_get_info(i);
|
||||
if (type) {
|
||||
u16 eq_freq = eq_info->freq;
|
||||
eq_freq = ((((u8 *)&eq_freq)[0] << 8) + ((u8 *)&eq_freq)[1]);
|
||||
memcpy(get_eq_info + data_len, &eq_freq, sizeof(eq_freq));
|
||||
data_len += sizeof(eq_freq);
|
||||
} else {
|
||||
u8 eq_gain = (eq_info->gain >> 20) & 0xFF;
|
||||
memcpy(get_eq_info + data_len, &eq_gain, sizeof(eq_gain));
|
||||
data_len += sizeof(eq_gain);
|
||||
}
|
||||
}
|
||||
|
||||
return data_len;
|
||||
}
|
||||
|
||||
static u8 get_karaoke_eq_all_freq_info(u8 *get_eq_info)
|
||||
{
|
||||
return get_karaoke_eq_info(get_eq_info, 1);
|
||||
}
|
||||
|
||||
static u8 get_karoke_eq_all_gain_info(u8 *get_eq_info)
|
||||
{
|
||||
return get_karaoke_eq_info(get_eq_info, 0);
|
||||
}
|
||||
|
||||
static int karaoke_eq_get_setting_extra_handle(void *setting_data, void *setting_data_len)
|
||||
{
|
||||
u16 data_len = *((u16 *) setting_data_len);
|
||||
if (data_len > sizeof(g_karaoke_setting_info)) {
|
||||
data_len = get_karaoke_eq_all_freq_info(setting_data);
|
||||
} else {
|
||||
data_len = get_karaoke_eq_setting(setting_data);
|
||||
}
|
||||
return data_len;
|
||||
}
|
||||
|
||||
static RCSP_SETTING_OPT karaoke_eq_opt = {
|
||||
.data_len = 9,
|
||||
.setting_type = ATTR_TYPE_KARAOKE_EQ_SETTING,
|
||||
.syscfg_id = VM_KARAOKE_EQ_SETTING,
|
||||
.deal_opt_setting = deal_karaoke_eq_setting,
|
||||
.set_setting = set_karaoke_eq_setting,
|
||||
.get_setting = get_karaoke_eq_setting,
|
||||
.custom_vm_info_update = NULL,
|
||||
.custom_setting_update = NULL,
|
||||
.custom_sibling_setting_deal = NULL,
|
||||
.custom_setting_release = NULL,
|
||||
.set_setting_extra_handle = NULL,
|
||||
.get_setting_extra_handle = karaoke_eq_get_setting_extra_handle,
|
||||
};
|
||||
REGISTER_APP_SETTING_OPT(karaoke_eq_opt);
|
||||
|
||||
#endif
|
||||
+608
@@ -0,0 +1,608 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".rcsp_karaoke_setting.data.bss")
|
||||
#pragma data_seg(".rcsp_karaoke_setting.data")
|
||||
#pragma const_seg(".rcsp_karaoke_setting.text.const")
|
||||
#pragma code_seg(".rcsp_karaoke_setting.text")
|
||||
#endif
|
||||
#include "rcsp_config.h"
|
||||
#include "syscfg_id.h"
|
||||
#include "ble_rcsp_server.h"
|
||||
|
||||
#include "rcsp_setting_sync.h"
|
||||
#include "rcsp_setting_opt.h"
|
||||
#include "rcsp_device_status.h"
|
||||
|
||||
#if (SOUNDCARD_ENABLE && RCSP_MODE && RCSP_ADV_KARAOKE_SET_ENABLE)
|
||||
|
||||
#include "key_event_deal.h"
|
||||
#include "mic_effect.h"
|
||||
#include "JL_rcsp_packet.h"
|
||||
#include "soundcard/soundcard.h"
|
||||
|
||||
// mask : 8byte
|
||||
// 音效 : index(1byte) + value(2byte)
|
||||
// 气氛 : index(1byte) + value(2byte)
|
||||
// 参数 : [index(1byte) + value(2byte)] * 7
|
||||
#define KARAOKE_SETTING_SIZE (8 + ((1 + 2) * 2) + ((1 + 2) * 7))
|
||||
#define KARAOKE_SETTING_ATMOSPHERE_TYPE_SET 0
|
||||
|
||||
enum karaoke_setting_index {
|
||||
// 音效
|
||||
KARAOKE_SETTING_SOUND_EFFECT_NORMAL = 0,
|
||||
KARAOKE_SETTING_SOUND_EFFECT_BOY = 1,
|
||||
KARAOKE_SETTING_SOUND_EFFECT_GRIL = 2,
|
||||
KARAOKE_SETTING_SOUND_EFFECT_KIDS = 3,
|
||||
KARAOKE_SETTING_SOUND_EFFECT_MAGIC = 4,
|
||||
KARAOKE_SETTING_SOUND_EFFECT_ELECTRIC_A_MAJOR = 5,
|
||||
KARAOKE_SETTING_SOUND_EFFECT_ELECTRIC_Ashop_MAJOR = 6,
|
||||
KARAOKE_SETTING_SOUND_EFFECT_ELECTRIC_B_MAJOR = 7,
|
||||
KARAOKE_SETTING_SOUND_EFFECT_ELECTRIC_C_MAJOR = 8,
|
||||
KARAOKE_SETTING_SOUND_EFFECT_ELECTRIC_Cshop_MAJOR = 9,
|
||||
KARAOKE_SETTING_SOUND_EFFECT_ELECTRIC_D_MAJOR = 10,
|
||||
KARAOKE_SETTING_SOUND_EFFECT_ELECTRIC_Dshop_MAJOR = 11,
|
||||
KARAOKE_SETTING_SOUND_EFFECT_ELECTRIC_E_MAJOR = 12,
|
||||
KARAOKE_SETTING_SOUND_EFFECT_ELECTRIC_F_MAJOR = 13,
|
||||
KARAOKE_SETTING_SOUND_EFFECT_ELECTRIC_Fshop_MAJOR = 14,
|
||||
KARAOKE_SETTING_SOUND_EFFECT_ELECTRIC_G_MAJOR = 15,
|
||||
KARAOKE_SETTING_SOUND_EFFECT_ELECTRIC_Gshop_MAJOR = 16,
|
||||
// 气氛
|
||||
KARAOKE_SETTING_ATMOSPHERE_CHEERS = 17,
|
||||
KARAOKE_SETTING_ATMOSPHERE_EMBARRASSED = 18,
|
||||
KARAOKE_SETTING_ATMOSPHERE_GUNFIRE = 19,
|
||||
KARAOKE_SETTING_ATMOSPHERE_DESPISE = 20,
|
||||
KARAOKE_SETTING_ATMOSPHERE_OPEN = 21,
|
||||
KARAOKE_SETTING_ATMOSPHERE_KISS = 22,
|
||||
KARAOKE_SETTING_ATMOSPHERE_LAUGHTER = 23,
|
||||
KARAOKE_SETTING_ATMOSPHERE_APPLAUSE = 24,
|
||||
KARAOKE_SETTING_ATMOSPHERE_PAY_ATTENTION_TO = 25,
|
||||
KARAOKE_SETTING_ATMOSPHERE_MUA = 26,
|
||||
KARAOKE_SETTING_ATMOSPHERE_A_THIEF = 27,
|
||||
KARAOKE_SETTING_ATMOSPHERE_IF_YOU_ARE_THE_ONE = 28,
|
||||
// 参数
|
||||
KARAOKE_SETTING_MIC_PARAM_MIC_VOL = 29,
|
||||
KARAOKE_SETTING_MIC_PARAM_RECORD_VOL = 30,
|
||||
KARAOKE_SETTING_MIC_PARAM_REVERBERATION = 31,
|
||||
KARAOKE_SETTING_MIC_PARAM_HIGH = 32,
|
||||
KARAOKE_SETTING_MIC_PARAM_BASS = 33,
|
||||
KARAOKE_SETTING_MIC_PARAM_ACCOMPANIMENT_VOL = 34,
|
||||
KARAOKE_SETTING_MIC_PARAM_MONITOR_VOL = 35,
|
||||
// 其他
|
||||
KARAOKE_SETTING_OTHER_EFFECT_POPPING = 36,
|
||||
KARAOKE_SETTING_OTHER_EFFECT_SHOUT = 37,
|
||||
KARAOKE_SETTING_OTHER_EFFECT_DODGE = 38,
|
||||
|
||||
KARAOKE_SETTING_INDEX_END,
|
||||
};
|
||||
|
||||
enum {
|
||||
APP_PITCH_NONE = 0,
|
||||
APP_PITCH_BOY,
|
||||
APP_PITCH_GIRL,
|
||||
APP_PITCH_KIDS,
|
||||
APP_PITCH_MAGIC,
|
||||
/* 电音 */
|
||||
APP_SOUNDCARD_MODE_ELECTRIC_A_MAJOR,
|
||||
APP_SOUNDCARD_MODE_ELECTRIC_Ashop_MAJOR,
|
||||
APP_SOUNDCARD_MODE_ELECTRIC_B_MAJOR,
|
||||
APP_SOUNDCARD_MODE_ELECTRIC_C_MAJOR,
|
||||
APP_SOUNDCARD_MODE_ELECTRIC_Cshop_MAJOR,
|
||||
APP_SOUNDCARD_MODE_ELECTRIC_D_MAJOR,
|
||||
APP_SOUNDCARD_MODE_ELECTRIC_Dshop_MAJOR,
|
||||
APP_SOUNDCARD_MODE_ELECTRIC_E_MAJOR,
|
||||
APP_SOUNDCARD_MODE_ELECTRIC_F_MAJOR,
|
||||
APP_SOUNDCARD_MODE_ELECTRIC_Fshop_MAJOR,
|
||||
APP_SOUNDCARD_MODE_ELECTRIC_G_MAJOR,
|
||||
APP_SOUNDCARD_MODE_ELECTRIC_Gshop_MAJOR,
|
||||
|
||||
APP_SOUNDCARD_MODE_BOOM, // 爆音
|
||||
APP_SOUNDCARD_MODE_SHOUTING_WHEAT, // 喊麦
|
||||
APP_SOUNDCARD_MODE_DODGE, // 闪避
|
||||
};
|
||||
|
||||
const static u8 g_mutex_type_table[] = {
|
||||
KARAOKE_SETTING_SOUND_EFFECT_NORMAL,
|
||||
KARAOKE_SETTING_SOUND_EFFECT_BOY,
|
||||
KARAOKE_SETTING_SOUND_EFFECT_GRIL,
|
||||
KARAOKE_SETTING_SOUND_EFFECT_KIDS,
|
||||
KARAOKE_SETTING_SOUND_EFFECT_MAGIC,
|
||||
KARAOKE_SETTING_SOUND_EFFECT_ELECTRIC_A_MAJOR,
|
||||
KARAOKE_SETTING_SOUND_EFFECT_ELECTRIC_Ashop_MAJOR,
|
||||
KARAOKE_SETTING_SOUND_EFFECT_ELECTRIC_B_MAJOR,
|
||||
KARAOKE_SETTING_SOUND_EFFECT_ELECTRIC_C_MAJOR,
|
||||
KARAOKE_SETTING_SOUND_EFFECT_ELECTRIC_Cshop_MAJOR,
|
||||
KARAOKE_SETTING_SOUND_EFFECT_ELECTRIC_D_MAJOR,
|
||||
KARAOKE_SETTING_SOUND_EFFECT_ELECTRIC_Dshop_MAJOR,
|
||||
KARAOKE_SETTING_SOUND_EFFECT_ELECTRIC_E_MAJOR,
|
||||
KARAOKE_SETTING_SOUND_EFFECT_ELECTRIC_F_MAJOR,
|
||||
KARAOKE_SETTING_SOUND_EFFECT_ELECTRIC_Fshop_MAJOR,
|
||||
KARAOKE_SETTING_SOUND_EFFECT_ELECTRIC_G_MAJOR,
|
||||
KARAOKE_SETTING_SOUND_EFFECT_ELECTRIC_Gshop_MAJOR,
|
||||
KARAOKE_SETTING_OTHER_EFFECT_POPPING,
|
||||
KARAOKE_SETTING_OTHER_EFFECT_SHOUT
|
||||
};
|
||||
|
||||
const static u8 g_atmosphere_type_table[] = {
|
||||
KARAOKE_SETTING_ATMOSPHERE_CHEERS,
|
||||
KARAOKE_SETTING_ATMOSPHERE_EMBARRASSED,
|
||||
KARAOKE_SETTING_ATMOSPHERE_GUNFIRE,
|
||||
KARAOKE_SETTING_ATMOSPHERE_DESPISE,
|
||||
KARAOKE_SETTING_ATMOSPHERE_OPEN,
|
||||
KARAOKE_SETTING_ATMOSPHERE_KISS,
|
||||
KARAOKE_SETTING_ATMOSPHERE_LAUGHTER,
|
||||
KARAOKE_SETTING_ATMOSPHERE_APPLAUSE,
|
||||
KARAOKE_SETTING_ATMOSPHERE_PAY_ATTENTION_TO,
|
||||
KARAOKE_SETTING_ATMOSPHERE_MUA,
|
||||
KARAOKE_SETTING_ATMOSPHERE_A_THIEF,
|
||||
KARAOKE_SETTING_ATMOSPHERE_IF_YOU_ARE_THE_ONE
|
||||
};
|
||||
|
||||
const static u8 g_common_type_table[] = {
|
||||
KARAOKE_SETTING_OTHER_EFFECT_DODGE
|
||||
};
|
||||
|
||||
const static u8 g_value_type_table[] = {
|
||||
KARAOKE_SETTING_MIC_PARAM_MIC_VOL,
|
||||
KARAOKE_SETTING_MIC_PARAM_RECORD_VOL,
|
||||
KARAOKE_SETTING_MIC_PARAM_REVERBERATION,
|
||||
KARAOKE_SETTING_MIC_PARAM_HIGH,
|
||||
KARAOKE_SETTING_MIC_PARAM_BASS,
|
||||
KARAOKE_SETTING_MIC_PARAM_ACCOMPANIMENT_VOL,
|
||||
KARAOKE_SETTING_MIC_PARAM_MONITOR_VOL
|
||||
};
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct {
|
||||
u8 mask[8];
|
||||
u8 mic_vol_index;
|
||||
u16 mic_vol_value;
|
||||
u8 mic_record_index;
|
||||
u16 mic_record_value;
|
||||
u8 mic_reververation_index;
|
||||
u16 mic_reververation_value;
|
||||
u8 mic_high_index;
|
||||
u16 mic_high_value;
|
||||
u8 mic_low_index;
|
||||
u16 mic_low_value;
|
||||
u8 mic_accompaniment_index;
|
||||
u16 mic_accompaniment_value;
|
||||
u8 mic_moitor_index;
|
||||
u16 mic_moitor_value;
|
||||
} karaoke_setting;
|
||||
#pragma pack()
|
||||
|
||||
static u8 g_update_index_record = -1;
|
||||
static karaoke_setting g_karaoke_setting = {0};
|
||||
|
||||
extern u8 get_curr_soundcard_pitch_by_value(void);
|
||||
extern u8 get_curr_soundcard_pitch(void);
|
||||
extern u8 curr_soundcard_mode_is_normal(void);
|
||||
|
||||
static void karaoke_setting_mask_set_bit(u8 *mask, u8 index, u8 type)
|
||||
{
|
||||
if (type) {
|
||||
mask[index / 8] |= BIT(index % 8);
|
||||
} else {
|
||||
mask[index / 8] &= ~BIT(index % 8);
|
||||
}
|
||||
}
|
||||
|
||||
static int karaoke_setting_setting_init(void)
|
||||
{
|
||||
// 不读VM
|
||||
// 需要从接口获取初始值并填充
|
||||
// mic_vol_index
|
||||
g_karaoke_setting.mic_vol_index = KARAOKE_SETTING_MIC_PARAM_MIC_VOL;
|
||||
g_karaoke_setting.mic_vol_value = soundcard_get_mic_vol();
|
||||
|
||||
// mic_record_index
|
||||
g_karaoke_setting.mic_record_index = KARAOKE_SETTING_MIC_PARAM_RECORD_VOL;
|
||||
g_karaoke_setting.mic_record_value = soundcard_get_rec_vol();
|
||||
|
||||
// mic_reververation_index
|
||||
g_karaoke_setting.mic_reververation_index = KARAOKE_SETTING_MIC_PARAM_REVERBERATION;
|
||||
g_karaoke_setting.mic_reververation_value = soundcard_get_reverb_wet_vol();
|
||||
|
||||
// mic_high_index
|
||||
g_karaoke_setting.mic_high_index = KARAOKE_SETTING_MIC_PARAM_HIGH;
|
||||
g_karaoke_setting.mic_high_value = soundcard_get_high_sound_vol();
|
||||
|
||||
// mic_low_index
|
||||
g_karaoke_setting.mic_low_index = KARAOKE_SETTING_MIC_PARAM_BASS;
|
||||
g_karaoke_setting.mic_low_value = soundcard_get_low_sound_vol();
|
||||
|
||||
// mic_accompaniment_index
|
||||
g_karaoke_setting.mic_accompaniment_index = KARAOKE_SETTING_MIC_PARAM_ACCOMPANIMENT_VOL;
|
||||
g_karaoke_setting.mic_accompaniment_value = soundcard_get_music_vol();
|
||||
|
||||
// mic_moitor_index
|
||||
g_karaoke_setting.mic_moitor_index = KARAOKE_SETTING_MIC_PARAM_MONITOR_VOL;
|
||||
g_karaoke_setting.mic_moitor_value = soundcard_get_earphone_vol();
|
||||
|
||||
// effect_index
|
||||
karaoke_setting_mask_set_bit(g_karaoke_setting.mask, KARAOKE_SETTING_SOUND_EFFECT_NORMAL, 1);
|
||||
|
||||
// atomsphere_index
|
||||
#if KARAOKE_SETTING_ATMOSPHERE_TYPE_SET
|
||||
karaoke_setting_mask_set_bit(g_karaoke_setting.mask, KARAOKE_SETTING_ATMOSPHERE_CHEERS, 1);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void set_karaoke_setting_setting(u8 *karaoke_setting)
|
||||
{
|
||||
memcpy(&g_karaoke_setting, karaoke_setting, sizeof(g_karaoke_setting));
|
||||
}
|
||||
|
||||
static int get_karaoke_setting_setting(u8 *karaoke_setting)
|
||||
{
|
||||
memcpy(karaoke_setting, &g_karaoke_setting, sizeof(g_karaoke_setting));
|
||||
return sizeof(g_karaoke_setting);
|
||||
}
|
||||
|
||||
static int karaoke_setting_set_value(u8 *data, u8 index, u16 value)
|
||||
{
|
||||
int offset = 0;
|
||||
data[offset++] = index;
|
||||
data[offset++] = ((u8 *)&value)[1];
|
||||
data[offset++] = ((u8 *)&value)[0];
|
||||
return offset;
|
||||
}
|
||||
|
||||
static int karaoke_get_setting_extra_handle(void *setting_data, void *setting_data_len)
|
||||
{
|
||||
// 全局变量g_karaoke_setting已经把值都存好,只需要进行大小端转化即可
|
||||
int offset = 0;
|
||||
u8 *data = (u8 *)setting_data;
|
||||
for (; offset < sizeof(g_karaoke_setting.mask); offset ++) {
|
||||
data[sizeof(g_karaoke_setting.mask) - offset - 1] = g_karaoke_setting.mask[offset];
|
||||
}
|
||||
|
||||
if ((u8) - 1 == g_update_index_record) {
|
||||
// mic_vol_value
|
||||
offset += karaoke_setting_set_value(data + offset, g_karaoke_setting.mic_vol_index, g_karaoke_setting.mic_vol_value);
|
||||
// mic_record_value
|
||||
offset += karaoke_setting_set_value(data + offset, g_karaoke_setting.mic_record_index, g_karaoke_setting.mic_record_value);
|
||||
// mic_reververation_value
|
||||
offset += karaoke_setting_set_value(data + offset, g_karaoke_setting.mic_reververation_index, g_karaoke_setting.mic_reververation_value);
|
||||
// mic_high_value
|
||||
offset += karaoke_setting_set_value(data + offset, g_karaoke_setting.mic_high_index, g_karaoke_setting.mic_high_value);
|
||||
// mic_low_value
|
||||
offset += karaoke_setting_set_value(data + offset, g_karaoke_setting.mic_low_index, g_karaoke_setting.mic_low_value);
|
||||
// mic_accompaniment_value
|
||||
offset += karaoke_setting_set_value(data + offset, g_karaoke_setting.mic_accompaniment_index, g_karaoke_setting.mic_accompaniment_value);
|
||||
// mic_moitor_value
|
||||
offset += karaoke_setting_set_value(data + offset, g_karaoke_setting.mic_moitor_index, g_karaoke_setting.mic_moitor_value);
|
||||
} else {
|
||||
switch (g_update_index_record) {
|
||||
case KARAOKE_SETTING_MIC_PARAM_MIC_VOL:
|
||||
offset += karaoke_setting_set_value(data + offset, g_update_index_record, g_karaoke_setting.mic_vol_value);
|
||||
break;
|
||||
case KARAOKE_SETTING_MIC_PARAM_RECORD_VOL:
|
||||
offset += karaoke_setting_set_value(data + offset, g_update_index_record, g_karaoke_setting.mic_record_value);
|
||||
break;
|
||||
case KARAOKE_SETTING_MIC_PARAM_REVERBERATION:
|
||||
offset += karaoke_setting_set_value(data + offset, g_update_index_record, g_karaoke_setting.mic_reververation_value);
|
||||
break;
|
||||
case KARAOKE_SETTING_MIC_PARAM_HIGH:
|
||||
offset += karaoke_setting_set_value(data + offset, g_update_index_record, g_karaoke_setting.mic_high_value);
|
||||
break;
|
||||
case KARAOKE_SETTING_MIC_PARAM_BASS:
|
||||
offset += karaoke_setting_set_value(data + offset, g_update_index_record, g_karaoke_setting.mic_low_value);
|
||||
break;
|
||||
case KARAOKE_SETTING_MIC_PARAM_ACCOMPANIMENT_VOL:
|
||||
offset += karaoke_setting_set_value(data + offset, g_update_index_record, g_karaoke_setting.mic_accompaniment_value);
|
||||
break;
|
||||
case KARAOKE_SETTING_MIC_PARAM_MONITOR_VOL:
|
||||
offset += karaoke_setting_set_value(data + offset, g_update_index_record, g_karaoke_setting.mic_moitor_value);
|
||||
break;
|
||||
}
|
||||
g_update_index_record = -1;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
static bool karaoke_setting_table_check(u8 index, u8 *table, u8 table_len)
|
||||
{
|
||||
for (u8 i = 0; i < table_len; i++) {
|
||||
if (index == table[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool karaoke_setting_mask_set(u8 index, u8 *table, u8 table_len)
|
||||
{
|
||||
if (karaoke_setting_table_check(index, table, table_len)) {
|
||||
for (u8 i = 0; i < table_len; i++) {
|
||||
karaoke_setting_mask_set_bit(g_karaoke_setting.mask, table[i], 0);
|
||||
}
|
||||
karaoke_setting_mask_set_bit(g_karaoke_setting.mask, index, 1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int karaoke_set_setting_extra_handle(void *setting_data, void *setting_data_len)
|
||||
{
|
||||
u16 data_len = *((u16 *) setting_data_len) - 1;
|
||||
u8 *data = (u8 *) setting_data;
|
||||
u8 i = 0;
|
||||
while (i < data_len) {
|
||||
u8 index = data[i++];
|
||||
u16 value = data[i++] << 8 | data[i++];
|
||||
karaoke_setting_mask_set(index, g_mutex_type_table, sizeof(g_mutex_type_table));
|
||||
#if KARAOKE_SETTING_ATMOSPHERE_TYPE_SET
|
||||
karaoke_setting_mask_set(index, g_atmosphere_type_table, sizeof(g_atmosphere_type_table));
|
||||
#endif
|
||||
if (karaoke_setting_table_check(index, g_common_type_table, sizeof(g_common_type_table))) {
|
||||
karaoke_setting_mask_set_bit(g_karaoke_setting.mask, index, 1);
|
||||
}
|
||||
karaoke_setting_mask_set(index, g_value_type_table, sizeof(g_value_type_table));
|
||||
g_update_index_record = index;
|
||||
switch (index) {
|
||||
case KARAOKE_SETTING_MIC_PARAM_MIC_VOL:
|
||||
g_karaoke_setting.mic_vol_index = index;
|
||||
g_karaoke_setting.mic_vol_value = value;
|
||||
break;
|
||||
case KARAOKE_SETTING_MIC_PARAM_RECORD_VOL:
|
||||
g_karaoke_setting.mic_record_index = index;
|
||||
g_karaoke_setting.mic_record_value = value;
|
||||
break;
|
||||
case KARAOKE_SETTING_MIC_PARAM_REVERBERATION:
|
||||
g_karaoke_setting.mic_reververation_index = index;
|
||||
g_karaoke_setting.mic_reververation_value = value;
|
||||
break;
|
||||
case KARAOKE_SETTING_MIC_PARAM_HIGH:
|
||||
g_karaoke_setting.mic_high_index = index;
|
||||
g_karaoke_setting.mic_high_value = value;
|
||||
break;
|
||||
case KARAOKE_SETTING_MIC_PARAM_BASS:
|
||||
g_karaoke_setting.mic_low_index = index;
|
||||
g_karaoke_setting.mic_low_value = value;
|
||||
break;
|
||||
case KARAOKE_SETTING_MIC_PARAM_ACCOMPANIMENT_VOL:
|
||||
g_karaoke_setting.mic_accompaniment_index = index;
|
||||
g_karaoke_setting.mic_accompaniment_value = value;
|
||||
break;
|
||||
case KARAOKE_SETTING_MIC_PARAM_MONITOR_VOL:
|
||||
g_karaoke_setting.mic_moitor_index = index;
|
||||
g_karaoke_setting.mic_moitor_value = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void update_karaoke_setting_vm_value(u8 *karaoke_setting)
|
||||
{
|
||||
// 不写VM
|
||||
}
|
||||
|
||||
static void karaoke_setting_sync(u8 *color_led_setting_info)
|
||||
{
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if (get_bt_tws_connect_status()) {
|
||||
update_rcsp_setting(ATTR_TYPE_KARAOKE_SETTING);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void karaoke_setting_update(void)
|
||||
{
|
||||
switch (g_update_index_record) {
|
||||
case KARAOKE_SETTING_MIC_PARAM_MIC_VOL:
|
||||
app_task_put_key_msg(KEY_SOUNDCARD_SLIDE_MIC, g_karaoke_setting.mic_vol_value);
|
||||
break;
|
||||
case KARAOKE_SETTING_MIC_PARAM_RECORD_VOL:
|
||||
app_task_put_key_msg(KEY_SOUNDCARD_SLIDE_RECORD_VOL, g_karaoke_setting.mic_record_value);
|
||||
break;
|
||||
case KARAOKE_SETTING_MIC_PARAM_REVERBERATION:
|
||||
app_task_put_key_msg(KEY_SOUNDCARD_SLIDE_WET_GAIN, g_karaoke_setting.mic_reververation_value);
|
||||
break;
|
||||
case KARAOKE_SETTING_MIC_PARAM_HIGH:
|
||||
app_task_put_key_msg(KEY_SOUNDCARD_SLIDE_HIGH_SOUND, g_karaoke_setting.mic_high_value);
|
||||
break;
|
||||
case KARAOKE_SETTING_MIC_PARAM_BASS:
|
||||
app_task_put_key_msg(KEY_SOUNDCARD_SLIDE_LOW_SOUND, g_karaoke_setting.mic_low_value);
|
||||
break;
|
||||
case KARAOKE_SETTING_MIC_PARAM_ACCOMPANIMENT_VOL:
|
||||
app_task_put_key_msg(KEY_SOUNDCARD_SLIDE_MUSIC_VOL, g_karaoke_setting.mic_accompaniment_value);
|
||||
break;
|
||||
case KARAOKE_SETTING_MIC_PARAM_MONITOR_VOL:
|
||||
app_task_put_key_msg(KEY_SOUNDCARD_SLIDE_EARPHONE_VOL, g_karaoke_setting.mic_moitor_value);
|
||||
break;
|
||||
case KARAOKE_SETTING_OTHER_EFFECT_POPPING:
|
||||
app_task_put_key_msg(KEY_SOUNDCARD_MODE_BOOM, 0);
|
||||
break;
|
||||
case KARAOKE_SETTING_SOUND_EFFECT_MAGIC:
|
||||
app_task_put_key_msg(KEY_SOUNDCARD_MODE_MAGIC, 0);
|
||||
break;
|
||||
case KARAOKE_SETTING_OTHER_EFFECT_SHOUT:
|
||||
app_task_put_key_msg(KEY_SOUNDCARD_MODE_SHOUTING_WHEAT, 0);
|
||||
break;
|
||||
case KARAOKE_SETTING_OTHER_EFFECT_DODGE:
|
||||
app_task_put_key_msg(KEY_SOUNDCARD_MODE_DODGE, 0);
|
||||
break;
|
||||
default:
|
||||
if (karaoke_setting_table_check(g_update_index_record, g_mutex_type_table, sizeof(g_mutex_type_table))) {
|
||||
app_task_put_key_msg(KEY_SOUNDCARD_MODE_PITCH_BY_VALUE, g_update_index_record);
|
||||
break;
|
||||
} else if (karaoke_setting_table_check(g_update_index_record, g_atmosphere_type_table, sizeof(g_atmosphere_type_table))) {
|
||||
app_task_put_key_msg(KEY_SOUNDCARD_MAKE_NOISE0 + g_update_index_record - KARAOKE_SETTING_ATMOSPHERE_CHEERS, 0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* g_update_index_record = -1; */
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void deal_karaoke_setting(u8 *karaoke_setting, u8 write_vm, u8 tws_sync)
|
||||
{
|
||||
if (karaoke_setting) {
|
||||
set_karaoke_setting_setting(karaoke_setting);
|
||||
}
|
||||
if (write_vm) {
|
||||
update_karaoke_setting_vm_value(karaoke_setting);
|
||||
}
|
||||
if (tws_sync) {
|
||||
karaoke_setting_sync(karaoke_setting);
|
||||
}
|
||||
karaoke_setting_update();
|
||||
}
|
||||
|
||||
static int karaoke_setting_key_event_update(int event, void *param)
|
||||
{
|
||||
int ret = false;
|
||||
struct RcspModel *rcspModel = rcsp_handle_get();
|
||||
if (rcspModel == NULL || 0 == JL_rcsp_get_auth_flag()) {
|
||||
return ret;
|
||||
}
|
||||
switch (event) {
|
||||
case KEY_SOUNDCARD_MAKE_NOISE0:
|
||||
case KEY_SOUNDCARD_MAKE_NOISE1:
|
||||
case KEY_SOUNDCARD_MAKE_NOISE2:
|
||||
case KEY_SOUNDCARD_MAKE_NOISE3:
|
||||
case KEY_SOUNDCARD_MAKE_NOISE4:
|
||||
case KEY_SOUNDCARD_MAKE_NOISE5:
|
||||
case KEY_SOUNDCARD_MAKE_NOISE6:
|
||||
case KEY_SOUNDCARD_MAKE_NOISE7:
|
||||
case KEY_SOUNDCARD_MAKE_NOISE8:
|
||||
case KEY_SOUNDCARD_MAKE_NOISE9:
|
||||
case KEY_SOUNDCARD_MAKE_NOISE10:
|
||||
case KEY_SOUNDCARD_MAKE_NOISE11:
|
||||
g_update_index_record = KARAOKE_SETTING_ATMOSPHERE_CHEERS + event - KEY_SOUNDCARD_MAKE_NOISE0;
|
||||
#if KARAOKE_SETTING_ATMOSPHERE_TYPE_SET
|
||||
karaoke_setting_mask_set(g_update_index_record, g_atmosphere_type_table, sizeof(g_atmosphere_type_table));
|
||||
#endif
|
||||
ret = true;
|
||||
break;
|
||||
case KEY_SOUNDCARD_MODE_PITCH:
|
||||
g_update_index_record = get_curr_soundcard_pitch();
|
||||
karaoke_setting_mask_set(g_update_index_record, g_mutex_type_table, sizeof(g_mutex_type_table));
|
||||
ret = true;
|
||||
break;
|
||||
case KEY_SOUNDCARD_MODE_PITCH_BY_VALUE:
|
||||
g_update_index_record = get_curr_soundcard_pitch_by_value();
|
||||
switch (g_update_index_record) {
|
||||
case APP_SOUNDCARD_MODE_BOOM:
|
||||
karaoke_setting_mask_set(KARAOKE_SETTING_OTHER_EFFECT_POPPING, g_mutex_type_table, sizeof(g_mutex_type_table));
|
||||
break;
|
||||
case APP_SOUNDCARD_MODE_SHOUTING_WHEAT:
|
||||
karaoke_setting_mask_set(KARAOKE_SETTING_OTHER_EFFECT_SHOUT, g_mutex_type_table, sizeof(g_mutex_type_table));
|
||||
break;
|
||||
default:
|
||||
if (g_update_index_record >= APP_SOUNDCARD_MODE_ELECTRIC_A_MAJOR && g_update_index_record <= APP_SOUNDCARD_MODE_ELECTRIC_Gshop_MAJOR) {
|
||||
karaoke_setting_mask_set(g_update_index_record - APP_SOUNDCARD_MODE_ELECTRIC_A_MAJOR + KARAOKE_SETTING_SOUND_EFFECT_ELECTRIC_A_MAJOR, g_mutex_type_table, sizeof(g_mutex_type_table));
|
||||
break;
|
||||
}
|
||||
karaoke_setting_mask_set(g_update_index_record, g_mutex_type_table, sizeof(g_mutex_type_table));
|
||||
break;
|
||||
}
|
||||
ret = true;
|
||||
break;
|
||||
case KEY_SOUNDCARD_MODE_BOOM:
|
||||
g_update_index_record = KARAOKE_SETTING_OTHER_EFFECT_POPPING;
|
||||
karaoke_setting_mask_set(g_update_index_record, g_mutex_type_table, sizeof(g_mutex_type_table));
|
||||
if (curr_soundcard_mode_is_normal()) {
|
||||
karaoke_setting_mask_set_bit(g_karaoke_setting.mask, g_update_index_record, 0);
|
||||
}
|
||||
ret = true;
|
||||
break;
|
||||
case KEY_SOUNDCARD_MODE_SHOUTING_WHEAT:
|
||||
g_update_index_record = KARAOKE_SETTING_OTHER_EFFECT_SHOUT;
|
||||
karaoke_setting_mask_set(g_update_index_record, g_mutex_type_table, sizeof(g_mutex_type_table));
|
||||
if (curr_soundcard_mode_is_normal()) {
|
||||
karaoke_setting_mask_set_bit(g_karaoke_setting.mask, g_update_index_record, 0);
|
||||
}
|
||||
ret = true;
|
||||
case KEY_SOUNDCARD_MODE_DODGE:
|
||||
g_update_index_record = KARAOKE_SETTING_OTHER_EFFECT_DODGE;
|
||||
if (mic_dodge_get_status()) {
|
||||
karaoke_setting_mask_set_bit(g_karaoke_setting.mask, g_update_index_record, 1);
|
||||
} else {
|
||||
karaoke_setting_mask_set_bit(g_karaoke_setting.mask, g_update_index_record, 0);
|
||||
}
|
||||
ret = true;
|
||||
break;
|
||||
case KEY_SOUNDCARD_MODE_ELECTRIC:
|
||||
g_update_index_record = get_curr_soundcard_pitch_by_value();
|
||||
karaoke_setting_mask_set(g_update_index_record, g_mutex_type_table, sizeof(g_mutex_type_table));
|
||||
ret = true;
|
||||
break;
|
||||
case KEY_SOUNDCARD_MODE_MAGIC:
|
||||
g_update_index_record = KARAOKE_SETTING_SOUND_EFFECT_MAGIC;
|
||||
karaoke_setting_mask_set(g_update_index_record, g_mutex_type_table, sizeof(g_mutex_type_table));
|
||||
if (curr_soundcard_mode_is_normal()) {
|
||||
karaoke_setting_mask_set_bit(g_karaoke_setting.mask, g_update_index_record, 0);
|
||||
}
|
||||
ret = true;
|
||||
break;
|
||||
case KEY_SOUNDCARD_SLIDE_MIC:
|
||||
g_update_index_record = KARAOKE_SETTING_MIC_PARAM_MIC_VOL;
|
||||
g_karaoke_setting.mic_vol_value = soundcard_get_mic_vol();
|
||||
ret = true;
|
||||
break;
|
||||
case KEY_SOUNDCARD_SLIDE_LOW_SOUND:
|
||||
g_update_index_record = KARAOKE_SETTING_MIC_PARAM_BASS;
|
||||
// 更新对应全局变量
|
||||
g_karaoke_setting.mic_low_value = soundcard_get_low_sound_vol();
|
||||
ret = true;
|
||||
break;
|
||||
case KEY_SOUNDCARD_SLIDE_HIGH_SOUND:
|
||||
g_update_index_record = KARAOKE_SETTING_MIC_PARAM_HIGH;
|
||||
// 更新对应全局变量
|
||||
g_karaoke_setting.mic_high_value = soundcard_get_high_sound_vol();
|
||||
ret = true;
|
||||
break;
|
||||
case KEY_SOUNDCARD_SLIDE_WET_GAIN:
|
||||
g_update_index_record = KARAOKE_SETTING_MIC_PARAM_REVERBERATION;
|
||||
g_karaoke_setting.mic_reververation_value = soundcard_get_reverb_wet_vol();
|
||||
ret = true;
|
||||
break;
|
||||
case KEY_SOUNDCARD_SLIDE_RECORD_VOL:
|
||||
g_update_index_record = KARAOKE_SETTING_MIC_PARAM_RECORD_VOL;
|
||||
// 更新对应全局变量
|
||||
g_karaoke_setting.mic_record_value = soundcard_get_rec_vol();
|
||||
ret = true;
|
||||
break;
|
||||
case KEY_SOUNDCARD_SLIDE_MUSIC_VOL:
|
||||
g_update_index_record = KARAOKE_SETTING_MIC_PARAM_ACCOMPANIMENT_VOL;
|
||||
// 更新对应全局变量
|
||||
g_karaoke_setting.mic_accompaniment_value = soundcard_get_music_vol();
|
||||
ret = true;
|
||||
break;
|
||||
case KEY_SOUNDCARD_SLIDE_EARPHONE_VOL:
|
||||
g_update_index_record = KARAOKE_SETTING_MIC_PARAM_MONITOR_VOL;
|
||||
// 更新对应全局变量
|
||||
g_karaoke_setting.mic_moitor_value = soundcard_get_earphone_vol();
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
if (ret) {
|
||||
RCSP_UPDATE(COMMON_FUNCTION, BIT(RCSP_DEVICE_STATUS_ATTR_TYPE_KARAOKE_SETTING_INFO));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static RCSP_SETTING_OPT karaoke_setting_opt = {
|
||||
.data_len = KARAOKE_SETTING_SIZE,
|
||||
.setting_type = ATTR_TYPE_KARAOKE_SETTING,
|
||||
.deal_opt_setting = deal_karaoke_setting,
|
||||
.set_setting = set_karaoke_setting_setting,
|
||||
.get_setting = get_karaoke_setting_setting,
|
||||
.custom_setting_init = karaoke_setting_setting_init,
|
||||
.set_setting_extra_handle = karaoke_set_setting_extra_handle,
|
||||
.get_setting_extra_handle = karaoke_get_setting_extra_handle,
|
||||
.custom_setting_key_event_update = karaoke_setting_key_event_update,
|
||||
};
|
||||
REGISTER_APP_SETTING_OPT(karaoke_setting_opt);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".rcsp_misc_drc_setting.data.bss")
|
||||
#pragma data_seg(".rcsp_misc_drc_setting.data")
|
||||
#pragma const_seg(".rcsp_misc_drc_setting.text.const")
|
||||
#pragma code_seg(".rcsp_misc_drc_setting.text")
|
||||
#endif
|
||||
#include "app_config.h"
|
||||
#include "syscfg_id.h"
|
||||
|
||||
#include "rcsp_misc_setting.h"
|
||||
#include "ble_rcsp_server.h"
|
||||
|
||||
#if (RCSP_MODE && RCSP_DRC_VAL_SETTING && TCFG_AUDIO_OUT_EQ_ENABLE && TCFG_DRC_ENABLE && TCFG_AUDIO_OUT_DRC_ENABLE && RCSP_ADV_EQ_SET_ENABLE)
|
||||
#include "audio_dec.h"
|
||||
|
||||
extern int high_bass_drc_set_filter_info(int th);
|
||||
|
||||
static s16 drc_val = 0;
|
||||
|
||||
static int drc_setting_set(u8 *misc_setting, u8 is_conversion)
|
||||
{
|
||||
u32 offset = 0;
|
||||
if (is_conversion) {
|
||||
drc_val = misc_setting[offset++] << 8 | misc_setting[offset++];
|
||||
drc_val = drc_val < 0 ? (drc_val + 61) : drc_val;
|
||||
} else {
|
||||
memcpy((u8 *)&drc_val, misc_setting, sizeof(drc_val));
|
||||
offset += 2;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
static int drc_setting_get(u8 *misc_setting, u8 is_conversion)
|
||||
{
|
||||
u32 offset = 0;
|
||||
if (is_conversion) {
|
||||
drc_val = drc_val > 0 ? (drc_val - 61) : drc_val;
|
||||
misc_setting[offset++] = (drc_val >> 8) & 0xFF;
|
||||
misc_setting[offset++] = (drc_val) & 0xFF;
|
||||
} else {
|
||||
memcpy(misc_setting, (u8 *)&drc_val, sizeof(drc_val));
|
||||
offset += 2;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
static int drc_state_update(u8 *misc_setting)
|
||||
{
|
||||
// 值不相同才设置
|
||||
static s16 prev_drc_val = -1;
|
||||
if (-1 == prev_drc_val || prev_drc_val != drc_val) {
|
||||
high_bass_drc_set_filter_info(drc_val > 0 ? drc_val - 61 : drc_val);
|
||||
prev_drc_val = drc_val;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static RCSP_MISC_SETTING_OPT drc_setting_opt = {
|
||||
.misc_data_len = 2,
|
||||
.misc_setting_type = MISC_SETTING_DRC_VAL,
|
||||
.misc_syscfg_id = CFG_RCSP_MISC_DRC_SETTING,
|
||||
.misc_set_setting = drc_setting_set,
|
||||
.misc_get_setting = drc_setting_get,
|
||||
.misc_state_update = drc_state_update,
|
||||
.misc_custom_setting_init = NULL,
|
||||
.misc_custom_write_vm = NULL,
|
||||
};
|
||||
REGISTER_APP_MISC_SETTING_OPT(drc_setting_opt);
|
||||
|
||||
#endif
|
||||
+158
@@ -0,0 +1,158 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".rcsp_misc_reverbration_setting.data.bss")
|
||||
#pragma data_seg(".rcsp_misc_reverbration_setting.data")
|
||||
#pragma const_seg(".rcsp_misc_reverbration_setting.text.const")
|
||||
#pragma code_seg(".rcsp_misc_reverbration_setting.text")
|
||||
#endif
|
||||
#include "rcsp_misc_setting.h"
|
||||
#include "app_config.h"
|
||||
|
||||
#if (RCSP_MODE && RCSP_REVERBERATION_SETTING && TCFG_MIC_EFFECT_ENABLE && RCSP_ADV_EQ_SET_ENABLE)
|
||||
|
||||
#include "syscfg_id.h"
|
||||
#include "rcsp_setting_opt.h"
|
||||
#include "ble_rcsp_server.h"
|
||||
#include "mic_effect.h"
|
||||
#include "key_event_deal.h"
|
||||
|
||||
extern void mic_effect_set_echo_delay(u32 delay);
|
||||
extern u32 mic_effect_get_echo_delay(void);
|
||||
extern void mic_effect_set_echo_decay(u32 decay);
|
||||
extern u32 mic_effect_get_echo_decay(void);
|
||||
extern u8 mic_effect_get_status(void);
|
||||
|
||||
#pragma pack(1)
|
||||
struct t_reverbration {
|
||||
u8 state;
|
||||
u16 depth_val;
|
||||
u16 strength_val;
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
static struct t_reverbration reverbration;
|
||||
|
||||
static int reverbration_setting_set(u8 *misc_setting, u8 is_conversion)
|
||||
{
|
||||
u32 offset = 0;
|
||||
reverbration.state = misc_setting[offset++];
|
||||
|
||||
if (is_conversion) {
|
||||
reverbration.depth_val = misc_setting[offset++] << 8 | misc_setting[offset++];
|
||||
reverbration.strength_val = misc_setting[offset++] << 8 | misc_setting[offset++];
|
||||
} else {
|
||||
memcpy((u8 *)&reverbration.depth_val, misc_setting + offset, sizeof(reverbration.depth_val));
|
||||
offset += 2;
|
||||
memcpy((u8 *)&reverbration.strength_val, misc_setting + offset, sizeof(reverbration.strength_val));
|
||||
offset += 2;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
static int reverbration_setting_get(u8 *misc_setting, u8 is_conversion)
|
||||
{
|
||||
u32 offset = 0;
|
||||
misc_setting[offset++] = reverbration.state;
|
||||
if (is_conversion) {
|
||||
misc_setting[offset++] = (reverbration.depth_val >> 8) & 0xFF;
|
||||
misc_setting[offset++] = (reverbration.depth_val) & 0xFF;
|
||||
misc_setting[offset++] = (reverbration.strength_val >> 8) & 0xFF;
|
||||
misc_setting[offset++] = (reverbration.strength_val) & 0xFF;
|
||||
} else {
|
||||
memcpy(misc_setting + offset, (u8 *)&reverbration.depth_val, sizeof(reverbration.depth_val));
|
||||
offset += 2;
|
||||
memcpy(misc_setting + offset, (u8 *)&reverbration.strength_val, sizeof(reverbration.strength_val));
|
||||
offset += 2;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
static int reverbration_write_vm(u8 *misc_setting)
|
||||
{
|
||||
u8 reverbration_state = 0;
|
||||
syscfg_read(CFG_RCSP_MISC_REVERB_ON_OFF, &reverbration_state, sizeof(reverbration_state));
|
||||
if (reverbration_state != reverbration.state) {
|
||||
syscfg_write(CFG_RCSP_MISC_REVERB_ON_OFF, &reverbration.state, sizeof(reverbration.state));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int reverbration_state_update(u8 *misc_setting)
|
||||
{
|
||||
// 值不相同才设置
|
||||
static u16 prev_depth_val = -1;
|
||||
static u16 prev_strength_val = -1;
|
||||
if (reverbration.state != mic_effect_get_status()) {
|
||||
app_task_put_key_msg(KEY_REVERB_OPEN, 0);
|
||||
}
|
||||
|
||||
if (mic_effect_get_status() && (-1 == prev_depth_val || reverbration.depth_val != prev_depth_val)) {
|
||||
mic_effect_set_echo_delay(reverbration.depth_val * 2);
|
||||
prev_depth_val = reverbration.depth_val;
|
||||
}
|
||||
|
||||
if (mic_effect_get_status() && (-1 == prev_strength_val || reverbration.strength_val != prev_strength_val)) {
|
||||
mic_effect_set_echo_decay(reverbration.strength_val * 70 / 100);
|
||||
prev_strength_val = reverbration.strength_val;
|
||||
}
|
||||
|
||||
if (0 == mic_effect_get_status()) {
|
||||
prev_depth_val = -1;
|
||||
prev_strength_val = -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int reverbration_custom_setting_init(void)
|
||||
{
|
||||
u8 reverbration_state = 0;
|
||||
if (sizeof(reverbration_state) == syscfg_read(CFG_RCSP_MISC_REVERB_ON_OFF, &reverbration_state, sizeof(reverbration_state))) {
|
||||
reverbration.state = reverbration_state;
|
||||
} else {
|
||||
reverbration.state = mic_effect_get_status();
|
||||
}
|
||||
reverbration.depth_val = mic_effect_get_echo_delay() / 2;
|
||||
reverbration.strength_val = mic_effect_get_echo_decay() * 100 / 70;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int reverbartion_key_event_callback_deal(u32 event, void *param)
|
||||
{
|
||||
int ret = false;
|
||||
switch (event) {
|
||||
case KEY_REVERB_OPEN:
|
||||
reverbration.state = mic_effect_get_status();
|
||||
reverbration_write_vm(NULL);
|
||||
reverbration_state_update(NULL);
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static RCSP_MISC_SETTING_OPT reverbration_setting_opt = {
|
||||
.misc_data_len = 5,
|
||||
.misc_syscfg_id = CFG_RCSP_MISC_REVERB_ON_OFF,
|
||||
.misc_setting_type = MISC_SETTING_REVERBERATION,
|
||||
.misc_set_setting = reverbration_setting_set,
|
||||
.misc_get_setting = reverbration_setting_get,
|
||||
.misc_state_update = reverbration_state_update,
|
||||
.misc_custom_setting_init = reverbration_custom_setting_init,
|
||||
.misc_custom_write_vm = reverbration_write_vm,
|
||||
.misc_custom_key_event_callback_deal = reverbartion_key_event_callback_deal,
|
||||
};
|
||||
REGISTER_APP_MISC_SETTING_OPT(reverbration_setting_opt);
|
||||
|
||||
void rcsp_close_reverbrateion_state_and_update(void)
|
||||
{
|
||||
if (reverbration.state) {
|
||||
app_task_put_key_msg(KEY_REVERB_OPEN, 0);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void rcsp_close_reverbrateion_state_and_update(void)
|
||||
{
|
||||
|
||||
}
|
||||
#endif
|
||||
+264
@@ -0,0 +1,264 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".rcsp_misc_setting.data.bss")
|
||||
#pragma data_seg(".rcsp_misc_setting.data")
|
||||
#pragma const_seg(".rcsp_misc_setting.text.const")
|
||||
#pragma code_seg(".rcsp_misc_setting.text")
|
||||
#endif
|
||||
#include "rcsp_misc_setting.h"
|
||||
#include "app_config.h"
|
||||
|
||||
#if (RCSP_MODE && RCSP_REVERBERATION_SETTING && TCFG_MIC_EFFECT_ENABLE && RCSP_ADV_EQ_SET_ENABLE)
|
||||
#include "syscfg_id.h"
|
||||
#include "rcsp_setting_sync.h"
|
||||
#include "rcsp_setting_opt.h"
|
||||
#include "ble_rcsp_server.h"
|
||||
|
||||
#include "rcsp_config.h"
|
||||
#include "rcsp_device_status.h"
|
||||
|
||||
extern int get_bt_tws_connect_status();
|
||||
|
||||
static int misc_setting_init(void);
|
||||
static int get_misc_setting_info(u8 *misc_setting);
|
||||
static int set_misc_setting_extra_handle(void *setting_data, void *param);
|
||||
static void set_misc_setting_info(u8 *misc_setting);
|
||||
static void deal_misc_setting(u8 *misc_setting, u8 write_vm, u8 tws_sync);
|
||||
|
||||
static RCSP_SETTING_OPT misc_setting_opt = {
|
||||
.data_len = 0,
|
||||
.setting_type = ATTR_TYPE_MISC_SETTING,
|
||||
.deal_opt_setting = deal_misc_setting,
|
||||
.set_setting = set_misc_setting_info,
|
||||
.get_setting = get_misc_setting_info,
|
||||
.custom_setting_init = misc_setting_init,
|
||||
.set_setting_extra_handle = set_misc_setting_extra_handle,
|
||||
};
|
||||
REGISTER_APP_SETTING_OPT(misc_setting_opt);
|
||||
|
||||
static RCSP_MISC_SETTING_OPT *g_misc_opt_link_head = NULL;
|
||||
static u32 g_misc_setting_update_type = -1;
|
||||
|
||||
int rcsp_register_setting_misc_setting(void *misc_setting)
|
||||
{
|
||||
// 需要排序
|
||||
RCSP_MISC_SETTING_OPT *misc_opt = g_misc_opt_link_head;
|
||||
RCSP_MISC_SETTING_OPT *item = (RCSP_MISC_SETTING_OPT *)misc_setting;
|
||||
RCSP_MISC_SETTING_OPT *existed_item = NULL;
|
||||
while (misc_opt && item) {
|
||||
if (misc_opt->misc_setting_type == item->misc_setting_type) {
|
||||
return 0;
|
||||
} else if (item->misc_setting_type > misc_opt->misc_setting_type) {
|
||||
existed_item = misc_opt;
|
||||
}
|
||||
misc_opt = misc_opt->next;
|
||||
}
|
||||
|
||||
if (!g_misc_opt_link_head) {
|
||||
item->next = g_misc_opt_link_head;
|
||||
g_misc_opt_link_head = item;
|
||||
return 0;
|
||||
} else if (item && existed_item) {
|
||||
item->next = existed_item->next;
|
||||
existed_item->next = item;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int misc_setting_init(void)
|
||||
{
|
||||
u32 total_len = sizeof(u32); // 1个mask的长度
|
||||
RCSP_MISC_SETTING_OPT *misc_opt = g_misc_opt_link_head;
|
||||
while (misc_opt) {
|
||||
u8 *data = zalloc(misc_opt->misc_data_len);
|
||||
if (misc_opt->misc_custom_setting_init) {
|
||||
misc_opt->misc_custom_setting_init();
|
||||
} else if (rcsp_read_data_from_vm(misc_opt->misc_syscfg_id, data, misc_opt->misc_data_len)) {
|
||||
if (misc_opt->misc_set_setting) {
|
||||
misc_opt->misc_set_setting(data, 0);
|
||||
}
|
||||
}
|
||||
if (data) {
|
||||
free(data);
|
||||
}
|
||||
total_len += misc_opt->misc_data_len;
|
||||
misc_opt = misc_opt->next;
|
||||
}
|
||||
if (g_misc_opt_link_head && g_misc_opt_link_head != misc_opt) {
|
||||
misc_setting_opt.data_len = total_len;
|
||||
deal_misc_setting(NULL, 0, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_misc_setting_info(u8 *misc_setting)
|
||||
{
|
||||
u32 mask = 0;
|
||||
u32 offset = sizeof(mask);
|
||||
RCSP_MISC_SETTING_OPT *misc_opt = g_misc_opt_link_head;
|
||||
u32 update_mics_setting_type = g_misc_setting_update_type;
|
||||
g_misc_setting_update_type = -1;
|
||||
while (misc_opt) {
|
||||
if (update_mics_setting_type & BIT(misc_opt->misc_setting_type)) {
|
||||
if (misc_opt->misc_get_setting) {
|
||||
misc_opt->misc_get_setting(misc_setting + offset, 1);
|
||||
}
|
||||
offset += misc_opt->misc_data_len;
|
||||
mask |= BIT(misc_opt->misc_setting_type);
|
||||
}
|
||||
misc_opt = misc_opt->next;
|
||||
}
|
||||
|
||||
misc_setting[0] = (mask >> 24) & 0xFF;
|
||||
misc_setting[1] = (mask >> 16) & 0xFF;
|
||||
misc_setting[2] = (mask >> 8) & 0xFF;
|
||||
misc_setting[3] = (mask) & 0xFF;
|
||||
return offset;
|
||||
}
|
||||
|
||||
static int set_misc_setting_extra_handle(void *setting_data, void *param)
|
||||
{
|
||||
u8 *misc_setting = (u8 *)setting_data;
|
||||
u32 mask = (misc_setting[0] << 24 | misc_setting[1] << 16 | misc_setting[2] << 8 | misc_setting[3]);
|
||||
if (0 == mask) {
|
||||
return -1;
|
||||
}
|
||||
RCSP_MISC_SETTING_OPT *misc_opt = g_misc_opt_link_head;
|
||||
u32 update_mics_setting_type = 0;
|
||||
while (misc_opt) {
|
||||
if (mask & BIT(misc_opt->misc_setting_type) && misc_opt->be_notify_app) {
|
||||
update_mics_setting_type |= BIT(misc_opt->misc_setting_type);
|
||||
}
|
||||
misc_opt = misc_opt->next;
|
||||
}
|
||||
if (!param && update_mics_setting_type) {
|
||||
g_misc_setting_update_type = update_mics_setting_type;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 g_set_mask = -1;
|
||||
static void set_misc_setting_info(u8 *misc_setting)
|
||||
{
|
||||
u32 offset = 4;
|
||||
g_set_mask = (misc_setting[0] << 24 | misc_setting[1] << 16 | misc_setting[2] << 8 | misc_setting[3]);
|
||||
RCSP_MISC_SETTING_OPT *misc_opt = g_misc_opt_link_head;
|
||||
while (misc_opt) {
|
||||
if (g_set_mask & BIT(misc_opt->misc_setting_type)) {
|
||||
if (misc_opt->misc_set_setting) {
|
||||
misc_opt->misc_set_setting(misc_setting + offset, 1);
|
||||
}
|
||||
offset += misc_opt->misc_data_len;
|
||||
}
|
||||
misc_opt = misc_opt->next;
|
||||
}
|
||||
}
|
||||
|
||||
static int write_misc_setting_vm_value(int syscfg_id, u8 *data, u32 data_len)
|
||||
{
|
||||
if (!data_len) {
|
||||
goto end;
|
||||
}
|
||||
u8 *vm_data = zalloc(data_len);
|
||||
syscfg_read(syscfg_id, vm_data, data_len);
|
||||
if (memcmp(vm_data, data, data_len)) {
|
||||
syscfg_write(syscfg_id, data, data_len);
|
||||
}
|
||||
if (vm_data) {
|
||||
free(vm_data);
|
||||
}
|
||||
end:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void update_misc_setting_vm_value(u8 *misc_setting)
|
||||
{
|
||||
RCSP_MISC_SETTING_OPT *misc_opt = g_misc_opt_link_head;
|
||||
while (misc_opt) {
|
||||
if (g_set_mask & BIT(misc_opt->misc_setting_type)) {
|
||||
if (misc_opt->misc_custom_write_vm) {
|
||||
misc_opt->misc_custom_write_vm(misc_setting);
|
||||
} else if (misc_opt->misc_syscfg_id && misc_opt->misc_get_setting) {
|
||||
u8 *data = zalloc(misc_opt->misc_data_len);
|
||||
misc_opt->misc_get_setting(data, 0);
|
||||
write_misc_setting_vm_value(misc_opt->misc_syscfg_id, data, misc_opt->misc_data_len);
|
||||
if (data) {
|
||||
free(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
misc_opt = misc_opt->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void misc_setting_sync(u8 *misc_setting)
|
||||
{
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if (get_bt_tws_connect_status()) {
|
||||
update_rcsp_setting(ATTR_TYPE_MISC_SETTING);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void misc_setting_state_update(u8 *misc_setting)
|
||||
{
|
||||
RCSP_MISC_SETTING_OPT *misc_opt = g_misc_opt_link_head;
|
||||
while (misc_opt) {
|
||||
if (g_set_mask & BIT(misc_opt->misc_setting_type)) {
|
||||
if (misc_opt->misc_state_update) {
|
||||
misc_opt->misc_state_update(misc_setting);
|
||||
}
|
||||
}
|
||||
misc_opt = misc_opt->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void deal_misc_setting(u8 *misc_setting, u8 write_vm, u8 tws_sync)
|
||||
{
|
||||
if (misc_setting) {
|
||||
set_misc_setting_info(misc_setting);
|
||||
}
|
||||
if (write_vm) {
|
||||
update_misc_setting_vm_value(misc_setting);
|
||||
}
|
||||
if (tws_sync) {
|
||||
misc_setting_sync(misc_setting);
|
||||
}
|
||||
misc_setting_state_update(misc_setting);
|
||||
}
|
||||
|
||||
u32 rcsp_get_misc_setting_data_len(void)
|
||||
{
|
||||
return misc_setting_opt.data_len;
|
||||
}
|
||||
|
||||
int rcsp_misc_event_deal(u32 event, void *param)
|
||||
{
|
||||
RCSP_MISC_SETTING_OPT *misc_opt = g_misc_opt_link_head;
|
||||
while (misc_opt) {
|
||||
if (misc_opt->misc_custom_key_event_callback_deal && misc_opt->misc_custom_key_event_callback_deal(event, param)) {
|
||||
if (misc_opt->be_notify_app) {
|
||||
RCSP_UPDATE(COMMON_FUNCTION, BIT(RCSP_DEVICE_STATUS_ATTR_TYPE_MISC_SETTING_INFO));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
misc_opt = misc_opt->next;
|
||||
}
|
||||
g_misc_setting_update_type = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
u32 rcsp_get_misc_setting_data_len(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rcsp_misc_event_deal(u32 event, void *param)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
#ifndef __RCSP_MISC_SETTING__
|
||||
#define __RCSP_MISC_SETTING__
|
||||
|
||||
#include "system/includes.h"
|
||||
|
||||
#define REGISTER_APP_MISC_SETTING_OPT(rcsp_misc_opt) \
|
||||
int rcsp_misc_opt##_setting_init(void) {\
|
||||
return rcsp_register_setting_misc_setting(&rcsp_misc_opt);\
|
||||
}\
|
||||
late_initcall(rcsp_misc_opt##_setting_init);
|
||||
|
||||
enum {
|
||||
MISC_SETTING_REVERBERATION = 0,
|
||||
MISC_SETTING_DRC_VAL = 1,
|
||||
MISC_SETTING_KARAOKE_SOUND_EFFECT = 2,
|
||||
MISC_SETTING_KARAOKE_ATMOSPHERE = 3,
|
||||
MISC_SETTING_KARAOKE_SOUND_PARAM = 4,
|
||||
MISC_SETTING_MASK_MAX = 32, // 最多只支持32个
|
||||
};
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct _RCSP_MISC_SETTING_OPT {
|
||||
struct _RCSP_MISC_SETTING_OPT *next;
|
||||
bool be_notify_app; // 接收到数据并更新效果完后是否需要通知app, 如果需要通知app则置1
|
||||
u32 misc_data_len;
|
||||
int misc_setting_type;
|
||||
int misc_syscfg_id;
|
||||
|
||||
// misc_set_setting函数参数:
|
||||
// misc_setting : 传入数据
|
||||
// is_conversion : 1 - 需要转换,从大端转为小端
|
||||
// 0 - 不需要转换
|
||||
int (*misc_set_setting)(u8 *misc_setting, u8 is_conversion);
|
||||
|
||||
// misc_get_setting函数参数:
|
||||
// misc_setting : 传出数据
|
||||
// is_conversion : 1 - 需要转换,从小端转为大端
|
||||
// 0 - 不需要转换
|
||||
int (*misc_get_setting)(u8 *misc_setting, u8 is_conversion);
|
||||
int (*misc_state_update)(u8 *misc_setting); // 参数用于判断当前更新是设置状态(非空)还是初始化/同步(未空)
|
||||
|
||||
// 上面是必填,下面是选填
|
||||
int (*misc_custom_setting_init)(void);
|
||||
int (*misc_custom_write_vm)(u8 *misc_setting);
|
||||
int (*misc_custom_key_event_callback_deal)(u32 event, void *param);
|
||||
} RCSP_MISC_SETTING_OPT;
|
||||
#pragma pack()
|
||||
|
||||
int rcsp_register_setting_misc_setting(void *misc_setting);
|
||||
int rcsp_misc_event_deal(u32 event, void *param);
|
||||
// 获取混响数据的长度
|
||||
u32 rcsp_get_misc_setting_data_len(void);
|
||||
|
||||
#endif
|
||||
+573
@@ -0,0 +1,573 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".rcsp_music_info_setting.data.bss")
|
||||
#pragma data_seg(".rcsp_music_info_setting.data")
|
||||
#pragma const_seg(".rcsp_music_info_setting.text.const")
|
||||
#pragma code_seg(".rcsp_music_info_setting.text")
|
||||
#endif
|
||||
#include "rcsp_music_info_setting.h"
|
||||
#include "rcsp_config.h"
|
||||
#include "syscfg_id.h"
|
||||
#include "ble_rcsp_server.h"
|
||||
#include "rcsp_adv_bluetooth.h"
|
||||
|
||||
#include "rcsp_setting_sync.h"
|
||||
#include "rcsp_setting_opt.h"
|
||||
#include "rcsp_bt_manage.h"
|
||||
#include "btstack/avctp_user.h"
|
||||
#include "bt_tws.h"
|
||||
#include "rcsp_functions/rcsp_config.h"
|
||||
|
||||
|
||||
|
||||
#if (RCSP_MODE && 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;
|
||||
};
|
||||
|
||||
static struct music_info_t music_info;
|
||||
void JL_rcsp_event_to_user(u32 type, u8 event, u8 *msg, u8 size);
|
||||
static u8 rcsp_adv_music_info_vaild(void);
|
||||
|
||||
|
||||
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 TCFG_USER_TWS_ENABLE
|
||||
// 通知从机同步状态
|
||||
if (get_bt_tws_connect_status() && TWS_ROLE_MASTER != tws_api_get_role()) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (BT_STATUS_PLAYING_MUSIC == bt_get_connect_status()) {
|
||||
bt_cmd_prepare(USER_CTRL_AVCTP_OPID_GET_PLAY_TIME, 0, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void get_music_info(void)
|
||||
{
|
||||
bt_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(TWS_FUNC_APP_OPT_UUID, APP_OPT_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)
|
||||
{
|
||||
struct RcspModel *rcspModel = rcsp_handle_get();
|
||||
if (1 == rcspModel->A_platform && rcsp_adv_music_info_vaild()) {
|
||||
return;
|
||||
}
|
||||
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(TWS_FUNC_APP_OPT_UUID, APP_OPT_SYNC_CMD_MUSIC_PLAYER_STATE, 300);
|
||||
} else {
|
||||
tws_api_sync_call_by_uuid(TWS_FUNC_APP_OPT_UUID, APP_OPT_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;
|
||||
}
|
||||
}
|
||||
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
#define TWS_FUNC_ID_RCSP_MUSIC_EN \
|
||||
(((u8)('R' + 'C' + 'S' + 'P') << (3 * 8)) | \
|
||||
((u8)('A' + 'P' + 'I') << (2 * 8)) | \
|
||||
((u8)('M' + 'U') << (1 * 8)) | \
|
||||
((u8)('E' + 'N') << (0 * 8)))
|
||||
|
||||
static void deal_music_en_in_task(void *_data, u16 len)
|
||||
{
|
||||
u8 *data = (u8 *)_data;
|
||||
u8 en = *data;
|
||||
/* printf("music_en===================:%d\n", en); */
|
||||
music_player_time_timer_deal(en);
|
||||
free(data);
|
||||
}
|
||||
|
||||
static void rcsp_music_en_in_irq(void *_data, u16 len, bool rx)
|
||||
{
|
||||
if (rx) {
|
||||
u8 *buf = malloc(len);
|
||||
ASSERT(buf, "rcsp_music_en_in_irq malloc err!\n");
|
||||
int msg[] = {(int)deal_music_en_in_task, 2, (int)buf, len};
|
||||
memcpy(buf, _data, len);
|
||||
os_taskq_post_type("app_core", Q_CALLBACK, ARRAY_SIZE(msg), msg);
|
||||
}
|
||||
}
|
||||
|
||||
REGISTER_TWS_FUNC_STUB(tws_rcsp_music_en) = {
|
||||
.func_id = TWS_FUNC_ID_RCSP_MUSIC_EN,
|
||||
.func = rcsp_music_en_in_irq,
|
||||
};
|
||||
#endif
|
||||
|
||||
void music_player_time_timer_deal(u8 en)
|
||||
{
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
// 通知从机同步状态
|
||||
if (get_bt_tws_connect_status() && TWS_ROLE_MASTER == tws_api_get_role()) {
|
||||
tws_api_send_data_to_sibling((void *)&en, 1, TWS_FUNC_ID_RCSP_MUSIC_EN);
|
||||
}
|
||||
#endif
|
||||
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:
|
||||
bt_cmd_prepare(USER_CTRL_AVCTP_OPID_PLAY, 0, NULL);
|
||||
break;
|
||||
|
||||
case 0x02:
|
||||
bt_cmd_prepare(USER_CTRL_AVCTP_OPID_PREV, 0, NULL);
|
||||
break;
|
||||
|
||||
case 0x03:
|
||||
bt_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, u16 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;
|
||||
|
||||
}
|
||||
|
||||
static void rcsp_adv_update_music_info(void *priv)
|
||||
{
|
||||
u8 i;
|
||||
u32 type = *((u32 *)priv);
|
||||
if (music_info.player_time_en) {
|
||||
for (i = 0; i < (sizeof(type) * 8); i++) {
|
||||
if (type & BIT(i)) {
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_MUSIC_INFO, &i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static u8 music_info_state = 0;
|
||||
static void rcsp_adv_music_info_state(void *priv)
|
||||
{
|
||||
music_info_state = *((u8 *)priv);
|
||||
}
|
||||
|
||||
static u8 rcsp_adv_music_info_vaild(void)
|
||||
{
|
||||
return music_info_state == 0;
|
||||
}
|
||||
|
||||
void rcsp_adv_music_info_set_state(u8 state, u32 time)
|
||||
{
|
||||
static u8 cur_state = 0;
|
||||
cur_state = state;
|
||||
sys_timeout_add(&cur_state, rcsp_adv_music_info_state, time);
|
||||
}
|
||||
|
||||
void rcsp_adv_music_info_deal(u8 type, u32 time, u8 *info, u16 len)
|
||||
{
|
||||
//printf("info len \n");
|
||||
//put_buf(info,len);
|
||||
struct RcspModel *rcspModel = rcsp_handle_get();
|
||||
if (1 == rcspModel->A_platform && rcsp_adv_music_info_vaild()) {
|
||||
return;
|
||||
}
|
||||
#if RCSP_ADV_FIND_DEVICE_ENABLE
|
||||
extern u8 rcsp_find_device_key_flag_get(void);
|
||||
if (rcsp_find_device_key_flag_get()) {
|
||||
return ;
|
||||
}
|
||||
#endif
|
||||
static u32 deal_type = 0;
|
||||
static u32 final_type = 0;
|
||||
switch (type) {
|
||||
case 0:
|
||||
if (time && 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)) {
|
||||
if (len > 64) {
|
||||
len = 64;
|
||||
}
|
||||
if (len) {
|
||||
music_info.title_len = len;
|
||||
memcpy(music_info.title, info, len);
|
||||
} else {
|
||||
music_info.title[0] = 0;
|
||||
music_info.title_len = 1;
|
||||
}
|
||||
deal_type |= BIT(type);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if ((info)) {
|
||||
if (len > 64) {
|
||||
len = 64;
|
||||
}
|
||||
if (len) {
|
||||
music_info.artist_len = len;
|
||||
memcpy(music_info.artist, info, len);
|
||||
} else {
|
||||
music_info.artist[0] = 0;
|
||||
music_info.artist_len = 1;
|
||||
}
|
||||
deal_type |= BIT(type);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if ((info)) {
|
||||
if (len > 64) {
|
||||
len = 64;
|
||||
}
|
||||
if (len) {
|
||||
music_info.album_len = len;
|
||||
memcpy(music_info.album, info, len);
|
||||
} else {
|
||||
music_info.album[0] = 0;
|
||||
music_info.album_len = 1;
|
||||
}
|
||||
deal_type |= BIT(type);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if ((info)) {
|
||||
len = 1;
|
||||
music_info.num_len = len;
|
||||
memcpy(&music_info.number, info, len);
|
||||
deal_type |= BIT(type);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
if ((info)) {
|
||||
len = 2;
|
||||
music_info.total_len = len;
|
||||
memcpy(music_info.total, info, len);
|
||||
deal_type |= BIT(type);
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
if ((info)) {
|
||||
if (len > 16) {
|
||||
len = 16;
|
||||
}
|
||||
music_info.genre_len = len;
|
||||
memcpy(music_info.genre, info, len);
|
||||
deal_type |= BIT(type);
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
if ((info)) {
|
||||
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);
|
||||
deal_type |= BIT(type);
|
||||
final_type = deal_type;
|
||||
if (0 == music_info.player_time_en) {
|
||||
sys_timeout_add(&final_type, rcsp_adv_update_music_info, 500);
|
||||
}
|
||||
deal_type = 0;
|
||||
}
|
||||
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); */
|
||||
}
|
||||
|
||||
void avrcp_element_attr_rsp_ext_process(u8 type, u32 time, u8 *info, u16 len)
|
||||
{
|
||||
/* printf("music info len2: \n"); */
|
||||
/* put_buf(info, len); */
|
||||
if (0 == len) {
|
||||
rcsp_adv_music_info_deal(type, time, info, len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
u8 get_player_time_en(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
#ifndef __RCSP_MUSIC_INFO_SETTING_H__
|
||||
#define __RCSP_MUSIC_INFO_SETTING_H__
|
||||
|
||||
#include "app_config.h"
|
||||
#include "generic/typedef.h"
|
||||
|
||||
#if (RCSP_MODE && 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
|
||||
+259
@@ -0,0 +1,259 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".rcsp_vol_setting.data.bss")
|
||||
#pragma data_seg(".rcsp_vol_setting.data")
|
||||
#pragma const_seg(".rcsp_vol_setting.text.const")
|
||||
#pragma code_seg(".rcsp_vol_setting.text")
|
||||
#endif
|
||||
#include "rcsp_config.h"
|
||||
|
||||
#include "syscfg_id.h"
|
||||
|
||||
#include "rcsp_setting_sync.h"
|
||||
#include "rcsp_setting_opt.h"
|
||||
#include "ble_rcsp_server.h"
|
||||
#include "rcsp_device_status.h"
|
||||
|
||||
#include "key_event_deal.h"
|
||||
#include "audio_config.h"
|
||||
#include "rcsp_functions/rcsp_config.h"
|
||||
|
||||
#if (RCSP_MODE && RCSP_ADV_EQ_SET_ENABLE)
|
||||
|
||||
#include "vol_sync.h"
|
||||
|
||||
static u8 vol_setting[1] = {0};
|
||||
extern int get_bt_tws_connect_status();
|
||||
|
||||
bool rcsp_set_device_volume(int volume)
|
||||
{
|
||||
struct RcspModel *rcspModel = rcsp_handle_get();
|
||||
if (rcspModel == NULL) {
|
||||
return false;
|
||||
}
|
||||
if (0 == rcspModel->dev_vol_sync) {
|
||||
return false;
|
||||
}
|
||||
if (0 == rcspModel->A_platform) {
|
||||
set_music_device_volume(volume);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rcsp_set_volume(s8 volume)
|
||||
{
|
||||
static u8 cur_flag = 0;
|
||||
struct RcspModel *rcspModel = rcsp_handle_get();
|
||||
if (cur_flag || rcspModel == NULL) {
|
||||
cur_flag = 0;
|
||||
return false;
|
||||
}
|
||||
if (0 == rcspModel->dev_vol_sync) {
|
||||
return false;
|
||||
}
|
||||
#if TCFG_APP_LINEIN_EN
|
||||
if (LINEIN_FUNCTION == rcspModel->cur_app_mode) {
|
||||
cur_flag = 1;
|
||||
extern int linein_volume_set(u8 vol);
|
||||
linein_volume_set(volume);
|
||||
cur_flag = 0;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
bool rcsp_key_volume_down(u8 value)
|
||||
{
|
||||
struct RcspModel *rcspModel = rcsp_handle_get();
|
||||
if (rcspModel == NULL) {
|
||||
return false;
|
||||
}
|
||||
if (0 == rcspModel->dev_vol_sync) {
|
||||
return false;
|
||||
}
|
||||
#if TCFG_APP_LINEIN_EN
|
||||
if (LINEIN_FUNCTION == rcspModel->cur_app_mode) {
|
||||
extern void linein_key_vol_down();
|
||||
linein_key_vol_down();
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
bool rcsp_key_volume_up(u8 value)
|
||||
{
|
||||
struct RcspModel *rcspModel = rcsp_handle_get();
|
||||
if (rcspModel == NULL) {
|
||||
return false;
|
||||
}
|
||||
if (0 == rcspModel->dev_vol_sync) {
|
||||
return false;
|
||||
}
|
||||
#if TCFG_APP_LINEIN_EN
|
||||
if (LINEIN_FUNCTION == rcspModel->cur_app_mode) {
|
||||
extern void linein_key_vol_up();
|
||||
linein_key_vol_up();
|
||||
true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
void rcsp_get_max_vol_info(u8 *vol_info)
|
||||
{
|
||||
*vol_info = app_audio_volume_max_query(AppVol_BT_MUSIC);
|
||||
}
|
||||
|
||||
void rcsp_get_cur_dev_vol_info(u8 *vol_info)
|
||||
{
|
||||
*vol_info = app_audio_get_volume(APP_AUDIO_CURRENT_STATE);
|
||||
}
|
||||
|
||||
void rcsp_set_vol_for_find_device(u8 vol_flag)
|
||||
{
|
||||
static u8 vol = 0;
|
||||
static u8 state = 0;
|
||||
if (state == vol_flag) {
|
||||
return ;
|
||||
}
|
||||
if (vol_flag) {
|
||||
// 停止媒体
|
||||
vol = app_audio_get_volume(APP_AUDIO_CURRENT_STATE);
|
||||
// 最大声
|
||||
app_audio_set_volume(app_audio_get_state(), app_audio_volume_max_query(AppVol_BT_MUSIC), 1);
|
||||
|
||||
} else {
|
||||
// 恢复
|
||||
app_audio_set_volume(app_audio_get_state(), vol, 1);
|
||||
}
|
||||
|
||||
rcsp_device_status_update(COMMON_FUNCTION, BIT(RCSP_DEVICE_STATUS_ATTR_TYPE_VOL));
|
||||
state = vol_flag;
|
||||
}
|
||||
|
||||
static int rcsp_get_vol_info(u8 *vol_info)
|
||||
{
|
||||
*vol_info = app_audio_get_volume(APP_AUDIO_CURRENT_STATE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void set_vol_info(u8 *vol_info)
|
||||
{
|
||||
memcpy(vol_setting, vol_info, sizeof(vol_setting));
|
||||
}
|
||||
|
||||
static void update_vol_vm_value(u8 *vol_info)
|
||||
{
|
||||
// 不需要写vm操作,5s后会自动保持音量值
|
||||
//syscfg_write(CFG_MUSIC_VOL, vol_setting, sizeof(vol_setting));
|
||||
}
|
||||
|
||||
static void vol_setting_sync(u8 *vol_info)
|
||||
{
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if (get_bt_tws_connect_status()) {
|
||||
update_rcsp_setting(ATTR_TYPE_VOL_SETTING);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void vol_state_update(void)
|
||||
{
|
||||
// 更新操作,包含写vm操作
|
||||
struct RcspModel *rcspModel = rcsp_handle_get();
|
||||
if (rcspModel == NULL) {
|
||||
return ;
|
||||
}
|
||||
u8 vol = vol_setting[0];
|
||||
if (LINEIN_FUNCTION == rcspModel->cur_app_mode) {
|
||||
#if TCFG_APP_LINEIN_EN
|
||||
extern int linein_volume_set(u8 vol);
|
||||
linein_volume_set(vol);
|
||||
#endif
|
||||
} else {
|
||||
app_audio_set_volume(app_audio_get_state(), vol, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void deal_vol_setting(u8 *vol_info, u8 write_vm, u8 tws_sync)
|
||||
{
|
||||
if (vol_info) {
|
||||
set_vol_info(vol_info);
|
||||
}
|
||||
if (write_vm) {
|
||||
update_vol_vm_value(vol_setting);
|
||||
}
|
||||
if (tws_sync) {
|
||||
vol_setting_sync(vol_setting);
|
||||
}
|
||||
vol_state_update();
|
||||
}
|
||||
|
||||
static int vol_setting_init(void)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 cur_vol = app_audio_get_volume(APP_AUDIO_CURRENT_STATE);
|
||||
set_vol_info(&cur_vol);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static RCSP_SETTING_OPT vol_setting_opt = {
|
||||
.data_len = 1,
|
||||
.setting_type = ATTR_TYPE_VOL_SETTING,
|
||||
.syscfg_id = CFG_MUSIC_VOL,
|
||||
.deal_opt_setting = deal_vol_setting,
|
||||
.set_setting = set_vol_info,
|
||||
.get_setting = rcsp_get_vol_info,
|
||||
.custom_setting_init = vol_setting_init, // 初始化不需要vm操作,所以重新实现
|
||||
.custom_setting_release = NULL,
|
||||
.custom_vm_info_update = NULL,
|
||||
.custom_setting_update = NULL,
|
||||
.custom_sibling_setting_deal = NULL,
|
||||
};
|
||||
REGISTER_APP_SETTING_OPT(vol_setting_opt);
|
||||
|
||||
#else
|
||||
|
||||
void rcsp_set_vol_for_find_device(u8 vol_flag)
|
||||
{
|
||||
#if 0
|
||||
static u8 vol = 0;
|
||||
static u8 state = 0;
|
||||
if (state == vol_flag) {
|
||||
return ;
|
||||
}
|
||||
if (vol_flag) {
|
||||
// 停止媒体
|
||||
vol = app_audio_get_volume(APP_AUDIO_CURRENT_STATE);
|
||||
// 最大声
|
||||
app_audio_set_volume(app_audio_get_state(), app_audio_volume_max_query(AppVol_BT_MUSIC), 1);
|
||||
|
||||
} else {
|
||||
// 恢复
|
||||
app_audio_set_volume(app_audio_get_state(), vol, 1);
|
||||
}
|
||||
|
||||
rcsp_device_status_update(COMMON_FUNCTION, BIT(RCSP_DEVICE_STATUS_ATTR_TYPE_VOL));
|
||||
state = vol_flag;
|
||||
#endif //end of 0
|
||||
}
|
||||
|
||||
bool rcsp_set_device_volume(int volume)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void rcsp_get_max_vol_info(u8 *vol_info)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void rcsp_get_cur_dev_vol_info(u8 *vol_info)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
#ifndef __RCSP_VOL_SETTING_H__
|
||||
#define __RCSP_VOL_SETTING_H__
|
||||
|
||||
#include "app_config.h"
|
||||
|
||||
/**
|
||||
* @brief 获取当前设备音量
|
||||
*
|
||||
* @param vol_info 当前设备音量大小
|
||||
*/
|
||||
void rcsp_get_cur_dev_vol_info(u8 *vol_info);
|
||||
/**
|
||||
* @brief 获取当前设备最大音量
|
||||
*
|
||||
* @param vol_info 当前设备最大音量
|
||||
*/
|
||||
void rcsp_get_max_vol_info(u8 *vol_info);
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,167 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".rcsp_switch_device.data.bss")
|
||||
#pragma data_seg(".rcsp_switch_device.data")
|
||||
#pragma const_seg(".rcsp_switch_device.text.const")
|
||||
#pragma code_seg(".rcsp_switch_device.text")
|
||||
#endif
|
||||
|
||||
#include "rcsp_functions/rcsp_config.h"
|
||||
#include "rcsp_config.h"
|
||||
#include "rcsp_device_feature.h"
|
||||
#include "btstack/avctp_user.h"
|
||||
#include "rcsp_event.h"
|
||||
#include "rcsp_manage.h"
|
||||
#include "rcsp_bt_manage.h"
|
||||
#include "rcsp_update.h"
|
||||
#include "JL_rcsp_protocol.h"
|
||||
#include "app_ble_spp_api.h"
|
||||
|
||||
#include "app_main.h"
|
||||
|
||||
#define LOG_TAG_CONST RCSP
|
||||
#define LOG_TAG "[switch_device]"
|
||||
#define LOG_ERROR_ENABLE
|
||||
#define LOG_DEBUG_ENABLE
|
||||
#define LOG_INFO_ENABLE
|
||||
#define LOG_CLI_ENABLE
|
||||
#include "debug.h"
|
||||
|
||||
#if (RCSP_MODE)
|
||||
|
||||
/* #define RCSP_DEBUG_EN */
|
||||
|
||||
#ifdef RCSP_DEBUG_EN
|
||||
#define rcsp_putchar(x) log_char(x)
|
||||
#define rcsp_printf log_info
|
||||
#define rcsp_printf_buf(x,len) log_info_hexdump(x,len)
|
||||
#else
|
||||
#define rcsp_putchar(...)
|
||||
#define rcsp_printf(...)
|
||||
#define rcsp_printf_buf(...)
|
||||
#endif
|
||||
|
||||
extern void *rcsp_server_ble_hdl;
|
||||
extern void *rcsp_server_ble_hdl1;
|
||||
|
||||
static u8 g_new_reconn_flag = 0;
|
||||
|
||||
static u16 g_ble_con_handle = 0; // ble手机发切换通讯方式时不为空
|
||||
static bool g_is_switching = false;
|
||||
static u8 g_is_switch_to_spp = 0; // 0:BLE; 1:SPP
|
||||
|
||||
|
||||
#if TCFG_EDR_SCAN_CONN_CTRL
|
||||
/* 用于区分一键连接时候,ble断连原因 */
|
||||
static u8 ble_disconnect_by_app_flag = 0; /* 1:一键连接时候,app发命令断连ble */
|
||||
|
||||
u8 rcsp_get_ble_disconnect_by_app_flag(void)
|
||||
{
|
||||
return ble_disconnect_by_app_flag;
|
||||
}
|
||||
|
||||
void rcsp_set_ble_disconnect_by_app_flag(u8 flag)
|
||||
{
|
||||
printf("%s flag:%d", __func__, flag);
|
||||
ble_disconnect_by_app_flag = flag;
|
||||
}
|
||||
#endif
|
||||
|
||||
extern void ble_app_disconnect(void);
|
||||
extern u8 check_le_pakcet_sent_finish_flag(void);
|
||||
static void wait_response_and_disconn_ble(void *priv)
|
||||
{
|
||||
static u16 wait_response_timeout = 0;
|
||||
static u8 wait_cnt = 0;
|
||||
// ble切换spp:前一个条件开始不满足,之后满足; 后一个条件开始满足,之后不满足; 超时10次后自动断开ble
|
||||
if (wait_response_timeout || (g_ble_con_handle && (1 == g_is_switch_to_spp))) {
|
||||
if ((10 == wait_cnt) || (rcsp_send_list_is_empty() && check_le_pakcet_sent_finish_flag())) {
|
||||
if (wait_response_timeout) {
|
||||
sys_timeout_del(wait_response_timeout);
|
||||
wait_response_timeout = 0;
|
||||
}
|
||||
wait_cnt = 0;
|
||||
#if TCFG_EDR_SCAN_CONN_CTRL
|
||||
rcsp_set_ble_disconnect_by_app_flag(1);
|
||||
#endif
|
||||
ble_app_disconnect();
|
||||
/* u16 ble_con_handle = app_ble_get_hdl_con_handle(rcsp_server_ble_hdl); */
|
||||
/* if (g_ble_con_handle == ble_con_handle) { */
|
||||
/* app_ble_disconnect(rcsp_server_ble_hdl); */
|
||||
/* } */
|
||||
/* #if TCFG_RCSP_DUAL_CONN_ENABLE */
|
||||
/* u16 ble_con_handle1 = app_ble_get_hdl_con_handle(rcsp_server_ble_hdl1); */
|
||||
/* if (g_ble_con_handle == ble_con_handle1) { */
|
||||
/* app_ble_disconnect(rcsp_server_ble_hdl1); */
|
||||
/* } */
|
||||
/* #endif */
|
||||
g_is_switching = false;
|
||||
} else {
|
||||
wait_cnt++;
|
||||
wait_response_timeout = sys_timeout_add(NULL, wait_response_and_disconn_ble, 100);
|
||||
}
|
||||
} else {
|
||||
g_is_switching = false;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef RCSP_UPDATE_EN
|
||||
static void wait_disconn_spp_timeout(void *priv)
|
||||
{
|
||||
static u8 wait_cnt = 0;
|
||||
if (wait_cnt++ >= 20) {
|
||||
log_info("wait spp disconnect timeout\n");
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_DEV_DISCONNECT, NULL, 0);
|
||||
} else {
|
||||
sys_timeout_add(NULL, wait_disconn_spp_timeout, 100);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
u8 get_rcsp_support_new_reconn_flag(void)
|
||||
{
|
||||
return g_new_reconn_flag;
|
||||
}
|
||||
|
||||
void switch_device(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr)
|
||||
{
|
||||
struct RcspModel *rcspModel = (struct RcspModel *)priv;
|
||||
if (rcspModel == NULL) {
|
||||
return ;
|
||||
}
|
||||
if (g_is_switching) {
|
||||
JL_CMD_response_send(OpCode, JL_PRO_STATUS_BUSY, OpCode_SN, NULL, 0, ble_con_handle, spp_remote_addr);
|
||||
return;
|
||||
}
|
||||
rcspModel->trans_chl = data[0];//指spp还是ble
|
||||
log_info("rcspModel->trans_chl:%x\n", rcspModel->trans_chl);
|
||||
if (len > 1) {
|
||||
g_new_reconn_flag = data[1];
|
||||
JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, &g_new_reconn_flag, 1, ble_con_handle, spp_remote_addr);
|
||||
} else {
|
||||
JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, NULL, 0, ble_con_handle, spp_remote_addr);
|
||||
}
|
||||
g_is_switch_to_spp = data[0];
|
||||
g_is_switching = true;
|
||||
g_ble_con_handle = ble_con_handle;
|
||||
#if RCSP_UPDATE_EN
|
||||
if (get_jl_update_flag()) {
|
||||
if (ble_con_handle) {
|
||||
rcsp_printf("BLE_ CON START DISCON\n");
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_DEV_DISCONNECT, NULL, 0);
|
||||
g_is_switching = false;
|
||||
} else {
|
||||
rcsp_printf("WAIT_FOR_SPP_DISCON\n");
|
||||
wait_disconn_spp_timeout(NULL);
|
||||
g_is_switching = false;
|
||||
}
|
||||
} else {
|
||||
wait_response_and_disconn_ble(NULL);
|
||||
}
|
||||
#else
|
||||
wait_response_and_disconn_ble(NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif//RCSP_MODE
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef __RCSP_SWITCH_DEVICE_H__
|
||||
#define __RCSP_SWITCH_DEVICE_H__
|
||||
|
||||
#include "typedef.h"
|
||||
#include "app_config.h"
|
||||
|
||||
void switch_device(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr);
|
||||
u8 get_rcsp_support_new_reconn_flag(void);
|
||||
|
||||
#endif // __RCSP_SWITCH_DEVICE_H__
|
||||
|
||||
+587
@@ -0,0 +1,587 @@
|
||||
#include "jiffies.h"
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".rcsp_ch_loader_download.data.bss")
|
||||
#pragma data_seg(".rcsp_ch_loader_download.data")
|
||||
#pragma const_seg(".rcsp_ch_loader_download.text.const")
|
||||
#pragma code_seg(".rcsp_ch_loader_download.text")
|
||||
#endif
|
||||
//#include "update_lib.h"
|
||||
#include "app_config.h"
|
||||
#include "update.h"
|
||||
#include "uart.h"
|
||||
#include "update_loader_download.h"
|
||||
#include "rcsp_update.h"
|
||||
#include "JL_rcsp_protocol.h"
|
||||
#include "classic/tws_api.h"
|
||||
#include "os/os_api.h"
|
||||
#include "ble_rcsp_server.h"
|
||||
#include "clock_manager/clock_manager.h"
|
||||
#include "btstack/avctp_user.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "rcsp_update_tws.h"
|
||||
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
#include "bt_tws.h"
|
||||
#endif
|
||||
|
||||
#if (RCSP_MODE && RCSP_UPDATE_EN && !RCSP_BLE_MASTER && TCFG_APP_UPDATE_EN)
|
||||
|
||||
#include "fs/fs.h"
|
||||
|
||||
#if TCFG_RCSP_DUAL_CONN_ENABLE
|
||||
#include "adv_1t2_setting.h"
|
||||
#endif
|
||||
|
||||
#define LOG_TAG "[RCSP-UPDATE]"
|
||||
#define LOG_INFO_ENABLE
|
||||
#define LOG_ERROR_ENABLE
|
||||
#include "debug.h"
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
u16 ble_con_handle;
|
||||
u8 *spp_remote_addr;
|
||||
} rcsp_update_param_t;
|
||||
|
||||
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;
|
||||
|
||||
static u8 g_rcsp_ancs_state_flag = 0;
|
||||
|
||||
//NOTE:测试盒的定义和本sdk文件系统的seek_type定义不一样;
|
||||
enum {
|
||||
BT_SEEK_SET = 0x01,
|
||||
BT_SEEK_CUR = 0x02,
|
||||
|
||||
BT_SEEK_TYPE_UPDATE_LEN = 0x10,
|
||||
};
|
||||
|
||||
// 断开连接时,需要清空正在升级的bthdl
|
||||
void rcsp_clean_update_hdl_for_end_update(u16 ble_con_handle, u8 *spp_remote_addr)
|
||||
{
|
||||
if (ble_con_handle == __this->ble_con_handle) {
|
||||
__this->ble_con_handle = 0;
|
||||
__this->spp_remote_addr = NULL;
|
||||
}
|
||||
if (__this->spp_remote_addr && spp_remote_addr && !memcmp(spp_remote_addr, __this->spp_remote_addr, 6)) {
|
||||
__this->ble_con_handle = 0;
|
||||
__this->spp_remote_addr = NULL;
|
||||
}
|
||||
if (!ble_con_handle && !spp_remote_addr) {
|
||||
__this->ble_con_handle = 0;
|
||||
__this->spp_remote_addr = NULL;
|
||||
}
|
||||
/* if (__this->spp_remote_addr) { */
|
||||
/* printf("%s, %d\n", __FUNCTION__, __LINE__); */
|
||||
/* put_buf(__this->spp_remote_addr, 6); */
|
||||
/* } */
|
||||
}
|
||||
|
||||
// 升级前需要设置正在升级的bthdl,防止1t2手机继续升级
|
||||
void rcsp_set_update_hdl(u16 ble_con_handle, u8 *spp_remote_addr)
|
||||
{
|
||||
if (ble_con_handle) {
|
||||
__this->ble_con_handle = ble_con_handle;
|
||||
__this->spp_remote_addr = NULL;
|
||||
} else {
|
||||
__this->spp_remote_addr = spp_remote_addr;
|
||||
__this->ble_con_handle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 获取当前升级的上位机信息
|
||||
void rcsp_get_update_hdl(u16 *ble_con_handle, u8 *spp_remote_addr)
|
||||
{
|
||||
/* if (__this->spp_remote_addr) { */
|
||||
/* printf("%s, %d\n", __FUNCTION__, __LINE__); */
|
||||
/* put_buf(__this->spp_remote_addr, 6); */
|
||||
/* } */
|
||||
*ble_con_handle = __this->ble_con_handle;
|
||||
if (__this->spp_remote_addr) {
|
||||
memcpy(spp_remote_addr, __this->spp_remote_addr, 6);
|
||||
} else {
|
||||
u8 _addr_temp[6] = {0};
|
||||
memcpy(spp_remote_addr, _addr_temp, 6);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
#if((OTA_TWS_SAME_TIME_ENABLE && (RCSP_MODE == RCSP_MODE_SOUNDBOX)))
|
||||
if ((tws_ota_control(OTA_TYPE_GET) == OTA_TWS) &&
|
||||
(tws_api_get_tws_state() & TWS_STA_SIBLING_DISCONNECTED)) {
|
||||
//假如TWS一起升级,TWS断开了,返回失败
|
||||
r_printf("tws disconn, stop update");
|
||||
rcsp_f_stop(DEVICE_UPDATE_STA_FAIL);
|
||||
return (u16) - 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (get_rcsp_connect_status()) {
|
||||
__this->data_send_hdl(fp, __this->file_offset, len);
|
||||
}
|
||||
|
||||
__RETRY:
|
||||
if (!get_rcsp_connect_status() || g_rcsp_ancs_state_flag) { //如果已经断开连接直接返回-1
|
||||
return -1;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
log_info(">>>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;
|
||||
}
|
||||
|
||||
enum {
|
||||
BT_UPDATE_OVER = 0,
|
||||
BT_UPDATE_KEY_ERR,
|
||||
BT_UPDATE_CONNECT_ERR,
|
||||
};
|
||||
|
||||
static u8 update_result_handle(u8 err)
|
||||
{
|
||||
u8 res = 0;
|
||||
if (0 == support_dual_bank_update_en) {
|
||||
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;
|
||||
case UPDATE_RESULT_EX_DSP_UPDATE_ERR:
|
||||
res = UPDATE_RESULT_EX_DSP_UPDATE_ERR;
|
||||
break;
|
||||
default:
|
||||
res = err;
|
||||
break;
|
||||
|
||||
}
|
||||
} else if (UPDATE_RESULT_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 (UPDATE_RESULT_BT_UPDATE_KEY_ERR == err) {
|
||||
res = DEVICE_UPDATE_STA_KEY_ERR;
|
||||
} else {
|
||||
res = DEVICE_UPDATE_STA_FAIL;
|
||||
}
|
||||
|
||||
#if CONFIG_REUSABLE_RESERVE
|
||||
extern u8 reusable_update_app_flag_handle(u8 state, u8 opt);
|
||||
if ((UPDATE_RESULT_ERR_NONE == err) && (3 == reusable_update_app_flag_handle(0, 0))) {
|
||||
res = DEVICE_UPDATE_STA_SUCCESS;
|
||||
}
|
||||
#elif CONFIG_RESFS_UPDATE_ENABLE
|
||||
extern u8 resfs_update_app_flag_handle(u8 state, u8 opt);
|
||||
if ((UPDATE_RESULT_ERR_NONE == err) && (3 == resfs_update_app_flag_handle(0, 0))) {
|
||||
res = DEVICE_UPDATE_STA_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
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);
|
||||
log_info(">>>rcsp_stop\n");
|
||||
__this->state = UPDATA_STOP;
|
||||
|
||||
if (!get_rcsp_connect_status() || g_rcsp_ancs_state_flag) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#if((OTA_TWS_SAME_TIME_ENABLE && (RCSP_MODE)))
|
||||
void db_update_notify_fail_to_phone()
|
||||
{
|
||||
if (get_rcsp_connect_status()) {
|
||||
rcsp_f_stop(DEVICE_UPDATE_STA_FAIL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
__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];
|
||||
|
||||
if (!get_rcsp_connect_status()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
WRITE_BIG_U32(data, size);
|
||||
|
||||
user_change_ble_conn_param(0);
|
||||
|
||||
log_info("send content_size:%x\n", size);
|
||||
err = JL_CMD_send(JL_OPCODE_NOTIFY_UPDATE_CONENT_SIZE, data, sizeof(data), JL_NEED_RESPOND, __this->ble_con_handle, __this->spp_remote_addr);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void rcsp_update_handle(u8 state, void *buf, int len)
|
||||
{
|
||||
/* log_info("R"); */
|
||||
if (state != __this->state) {
|
||||
log_error(">>>rcsp state err\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!get_rcsp_connect_status() || g_rcsp_ancs_state_flag) {
|
||||
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;
|
||||
}
|
||||
|
||||
static int rcsp_update_request_null(void)
|
||||
{
|
||||
u8 buff[8];
|
||||
if (__this->resume_hdl == NULL || __this->sleep_hdl == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
rcsp_f_seek(NULL, SEEK_SET, 0);
|
||||
rcsp_f_read(NULL, buff, sizeof(buff));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rcsp_update_delay_ms(u32 ms)
|
||||
{
|
||||
int ret = 0;
|
||||
u32 t_start;
|
||||
u32 tick;
|
||||
u32 keep_time = 0;
|
||||
|
||||
tick = ms;
|
||||
t_start = jiffies_msec();
|
||||
while (tick--) {
|
||||
os_time_dly(1);
|
||||
ret = rcsp_update_request_null();
|
||||
if (ret) {
|
||||
log_error("al fail\n");
|
||||
break;
|
||||
}
|
||||
keep_time = jiffies_msec() - t_start;
|
||||
if (keep_time >= ms) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
log_info("rcsp update delay %dms\n", keep_time);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void rcsp_ch_update_init(void (*resume_hdl)(void *priv), int (*sleep_hdl)(void *priv))
|
||||
{
|
||||
log_info("------------rcsp_ch_update_init\n");
|
||||
|
||||
g_rcsp_ancs_state_flag = 0;
|
||||
rcsp_update_resume_hdl_register(resume_hdl, sleep_hdl);
|
||||
//register_receive_fw_update_block_handle(rcsp_updata_handle);
|
||||
|
||||
/* fix ble disconnect */
|
||||
rcsp_update_delay_ms(2000);
|
||||
}
|
||||
|
||||
void rcsp_update_ancs_disconn_handler(void)
|
||||
{
|
||||
g_rcsp_ancs_state_flag = 1;
|
||||
rcsp_resume();
|
||||
}
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
extern void set_jl_update_flag(u8 flag);
|
||||
extern u8 *rcsp_get_ble_hdl_remote_mac_addr(u16 ble_con_handle);
|
||||
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) {
|
||||
log_info("state:%x, update result code:%x\n", ret_code->stu, ret_code->err_code);
|
||||
}
|
||||
switch (state) {
|
||||
case UPDATE_CH_INIT:
|
||||
#if TCFG_RCSP_DUAL_CONN_ENABLE
|
||||
/* // 踢掉另一个连接的设备,并关闭广播 */
|
||||
/* u8 *remote_addr = __this->spp_remote_addr; */
|
||||
/* if (__this->ble_con_handle) { */
|
||||
/* remote_addr = rcsp_get_ble_hdl_remote_mac_addr(__this->ble_con_handle); */
|
||||
/* } */
|
||||
/* u8 *other_conn_addr = btstack_get_other_dev_addr(remote_addr); */
|
||||
/* if (other_conn_addr) { */
|
||||
/* btstack_device_detach(btstack_get_conn_device(other_conn_addr)); */
|
||||
/* } */
|
||||
/* rcsp_disconn_other_ble(__this->ble_con_handle); */
|
||||
rcsp_bt_ble_adv_enable(0);
|
||||
#endif
|
||||
// 如果是ble,则设置连接参数,提高传输效率
|
||||
if (0 == get_curr_device_type()) {
|
||||
clock_refurbish();
|
||||
notify_update_connect_parameter(3);
|
||||
}
|
||||
break;
|
||||
case UPDATE_CH_EXIT:
|
||||
if (UPDATE_DUAL_BANK_IS_SUPPORT()) {
|
||||
if ((0 == ret_code->stu) && (UPDATE_RESULT_ERR_NONE == ret_code->err_code || UPDATE_RESULT_BT_UPDATE_OVER == ret_code->err_code)) {
|
||||
set_jl_update_flag(1);
|
||||
log_info(">>>rcsp update succ\n");
|
||||
update_result_set(UPDATA_SUCC);
|
||||
|
||||
} else {
|
||||
update_result_set(UPDATA_DEV_ERR);
|
||||
log_info(">>>rcsp update err\n");
|
||||
}
|
||||
} else {
|
||||
if ((0 == ret_code->stu) && (UPDATE_RESULT_ERR_NONE == ret_code->err_code || UPDATE_RESULT_BT_UPDATE_OVER == ret_code->err_code)) {
|
||||
set_jl_update_flag(1);
|
||||
}
|
||||
}
|
||||
// 如果是ble,则设置连接参数,还原传输效率
|
||||
if (0 == get_curr_device_type()) {
|
||||
notify_update_connect_parameter(-1);
|
||||
}
|
||||
#if TCFG_RCSP_DUAL_CONN_ENABLE
|
||||
rcsp_clean_update_hdl_for_end_update(0, NULL);
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if ((tws_api_get_tws_state() & TWS_STA_SIBLING_CONNECTED)) {
|
||||
if (tws_api_get_role() == TWS_ROLE_MASTER) {
|
||||
rcsp_ble_adv_enable_with_con_dev();
|
||||
}
|
||||
} else {
|
||||
rcsp_ble_adv_enable_with_con_dev();
|
||||
}
|
||||
#else
|
||||
rcsp_ble_adv_enable_with_con_dev();
|
||||
#endif
|
||||
#endif
|
||||
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);
|
||||
}
|
||||
|
||||
#else // (RCSP_MODE && RCSP_UPDATE_EN && !RCSP_BLE_MASTER && TCFG_APP_UPDATE_EN)
|
||||
|
||||
// 断开连接时,需要清空正在升级的bthdl
|
||||
void rcsp_clean_update_hdl_for_end_update(u16 ble_con_handle, u8 *spp_remote_addr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void db_update_notify_fail_to_phone()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void rcsp_resume(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endif // (RCSP_MODE && RCSP_UPDATE_EN && !RCSP_BLE_MASTER && TCFG_APP_UPDATE_EN)
|
||||
|
||||
+938
@@ -0,0 +1,938 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".rcsp_update.data.bss")
|
||||
#pragma data_seg(".rcsp_update.data")
|
||||
#pragma const_seg(".rcsp_update.text.const")
|
||||
#pragma code_seg(".rcsp_update.text")
|
||||
#endif
|
||||
#include "app_config.h"
|
||||
#include "rcsp_update.h"
|
||||
#if (RCSP_MODE && RCSP_UPDATE_EN && !RCSP_BLE_MASTER && TCFG_APP_UPDATE_EN)
|
||||
#include "uart.h"
|
||||
#include "system/timer.h"
|
||||
#include "update.h"
|
||||
#include "custom_cfg.h"
|
||||
#include "btstack/avctp_user.h"
|
||||
#include "ble_rcsp_server.h"
|
||||
#include "rcsp_manage.h"
|
||||
#include "rcsp_bt_manage.h"
|
||||
#include "update_loader_download.h"
|
||||
#include "ble_rcsp_server.h"
|
||||
#include "classic/tws_api.h"
|
||||
#include "rcsp_task.h"
|
||||
#include "rcsp_config.h"
|
||||
#include "syscfg_id.h"
|
||||
#include "rcsp_device_status.h"
|
||||
#include "JL_rcsp_protocol.h"
|
||||
#include "rcsp_config.h"
|
||||
#include "rcsp_functions/rcsp_config.h"
|
||||
#if RCSP_ADV_EN
|
||||
#include "rcsp_setting_opt.h"
|
||||
#endif
|
||||
|
||||
#if (RCSP_MODE == RCSP_MODE_EARPHONE)
|
||||
#include "bt_tws.h"
|
||||
#endif
|
||||
|
||||
#if (RCSP_MODE == RCSP_MODE_WATCH)
|
||||
#include "rcsp_extra_flash_opt.h"
|
||||
#endif
|
||||
|
||||
#if (RCSP_MODE == RCSP_MODE_SOUNDBOX)
|
||||
#include "rcsp_misc_setting.h"
|
||||
#endif
|
||||
|
||||
|
||||
#define RCSP_DEBUG_EN
|
||||
#ifdef RCSP_DEBUG_EN
|
||||
#define rcsp_putchar(x) putchar(x)
|
||||
#define rcsp_printf printf
|
||||
#define rcsp_put_buf(x,len) put_buf(x,len)
|
||||
#else
|
||||
#define rcsp_putchar(...)
|
||||
#define rcsp_printf(...)
|
||||
#define rcsp_put_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;
|
||||
|
||||
static update_file_ext_id_t update_file_id_info = {
|
||||
.update_file_id_info.ver[0] = 0xff,
|
||||
.update_file_id_info.ver[1] = 0xff,
|
||||
};
|
||||
extern u8 get_charge_online_flag(void);
|
||||
extern u8 get_self_battery_level(void);
|
||||
extern const int support_dual_bank_update_en;
|
||||
extern void ble_app_disconnect(void);
|
||||
extern void updata_parm_set(UPDATA_TYPE up_type, void *priv, u32 len);
|
||||
extern u8 check_le_pakcet_sent_finish_flag(void);
|
||||
// 获取rcsp已连接设备
|
||||
extern u8 bt_rcsp_device_conn_num(void);
|
||||
// 获取当前ble连接设备的mac地址
|
||||
u8 *rcsp_get_ble_hdl_remote_mac_addr(u16 ble_con_handle);
|
||||
|
||||
static u8 update_flag = 0;
|
||||
static u8 tws_need_update = 0; //标志耳机是否需要强制升级
|
||||
|
||||
#if RCSP_MODE == RCSP_MODE_EARPHONE
|
||||
static u8 tws_need_role_switch = 0; //用于tws连接之后版本号不匹配进行role_switch,低版本号的作为主机进行强制升级
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
enum {
|
||||
UPDATE_FLAG_OK,
|
||||
UPDATE_FLAG_LOW_POWER,
|
||||
UPDATE_FLAG_FW_INFO_ERR,
|
||||
UPDATE_FLAG_FW_INFO_CONSISTENT,
|
||||
UPDATE_FLAG_TWS_DISCONNECT,
|
||||
UPDATE_FLAG_TWS_NOT_IN_CHARGESTORE,
|
||||
UPDATE_FLAG_ALREADY, //已有升级任务
|
||||
UPDATE_FLAG_MULTI_CONN_DEVICE, //多个蓝牙连接设备不允许升级
|
||||
};
|
||||
|
||||
|
||||
|
||||
static void rcsp_update_change_mtu(u16 new_mtu);
|
||||
|
||||
static void rcsp_update_prepare()
|
||||
{
|
||||
///升级前可以选择关闭需要关闭的模块
|
||||
#if RCSP_DEVICE_STATUS_ENABLE
|
||||
rcsp_device_status_setting_stop();
|
||||
#endif
|
||||
|
||||
#if (RCSP_MODE != RCSP_MODE_SOUNDBOX)
|
||||
// 关闭混响
|
||||
extern void rcsp_close_reverbrateion_state_and_update(void);
|
||||
rcsp_close_reverbrateion_state_and_update();
|
||||
#endif
|
||||
|
||||
#if (SOUNDCARD_ENABLE)
|
||||
extern void soundcard_close(void);
|
||||
soundcard_close();
|
||||
return ;
|
||||
#endif
|
||||
|
||||
#if (TCFG_MIC_EFFECT_ENABLE && (0 == RCSP_REVERBERATION_SETTING))
|
||||
mic_effect_stop();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static void rcsp_update_fail_and_resume(void)
|
||||
{
|
||||
#if (TCFG_MIC_EFFECT_ENABLE)
|
||||
mic_effect_start();
|
||||
#endif
|
||||
|
||||
#if (SOUNDCARD_ENABLE)
|
||||
extern void soundcard_start(void);
|
||||
soundcard_start();
|
||||
#endif
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @abstract 获取当前连接设备类型
|
||||
*
|
||||
* @return 0:ble,1:spp
|
||||
*/
|
||||
static u8 device_type = 0;
|
||||
static void set_curr_update_type(u8 type)
|
||||
{
|
||||
device_type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @abstract 获取当前连接设备类型
|
||||
*
|
||||
* @return 0:ble,1:spp
|
||||
*/
|
||||
u8 get_curr_device_type(void)
|
||||
{
|
||||
return device_type;
|
||||
}
|
||||
|
||||
#if (RCSP_MODE == RCSP_MODE_WATCH)
|
||||
|
||||
void set_update_ex_flash_flag(u8 update_flag)
|
||||
{
|
||||
// 读取vm,如果相同不设置,如果不同设置vm
|
||||
u8 tmp_flag = 0;
|
||||
syscfg_read(VM_RESET_EX_FLASH_FLAG, &tmp_flag, sizeof(tmp_flag));
|
||||
if (tmp_flag != update_flag) {
|
||||
syscfg_write(VM_RESET_EX_FLASH_FLAG, &update_flag, sizeof(update_flag));
|
||||
}
|
||||
}
|
||||
|
||||
u8 get_update_ex_flash_flag(void)
|
||||
{
|
||||
// 从vm中获取标志位
|
||||
u8 update_flag = 0;
|
||||
u8 tmp_flag = -1;
|
||||
if (sizeof(tmp_flag) ==
|
||||
syscfg_read(VM_RESET_EX_FLASH_FLAG, &tmp_flag, sizeof(tmp_flag))) {
|
||||
update_flag = tmp_flag;
|
||||
}
|
||||
return update_flag;
|
||||
}
|
||||
|
||||
#endif // (RCSP_MODE == RCSP_MODE_WATCH)
|
||||
|
||||
typedef struct _update_mode_t {
|
||||
u8 opcode;
|
||||
u8 opcode_sn;
|
||||
u16 ble_con_handle;
|
||||
u8 spp_remote_addr[6];
|
||||
|
||||
} update_mode_t;
|
||||
|
||||
static update_mode_t update_record_info;
|
||||
|
||||
#if (RCSP_MODE == RCSP_MODE_SOUNDBOX)
|
||||
|
||||
#define RCSP_UPDATE_WAIT_SPP_DISCONN_TIME (1000)
|
||||
static bool check_edr_is_disconnct(void);
|
||||
static void rcsp_update_private_param_fill(UPDATA_PARM *p);
|
||||
static void rcsp_update_before_jump_handle(int type);
|
||||
static void wait_response_and_disconn_spp(void *priv)
|
||||
{
|
||||
static u32 wait_time = 0;
|
||||
if (check_edr_is_disconnct()) {
|
||||
rcsp_printf("b");
|
||||
if (wait_time > RCSP_UPDATE_WAIT_SPP_DISCONN_TIME) {
|
||||
wait_time = 0;
|
||||
bt_cmd_prepare(USER_CTRL_POWER_OFF, 0, NULL);
|
||||
} else {
|
||||
wait_time += 100;
|
||||
}
|
||||
sys_timeout_add(NULL, wait_response_and_disconn_spp, 100);
|
||||
return;
|
||||
}
|
||||
|
||||
wait_time = 0;
|
||||
rcsp_printf("BLE_APP_UPDATE\n");
|
||||
update_mode_api_v2(BLE_APP_UPDATA,
|
||||
rcsp_update_private_param_fill,
|
||||
rcsp_update_before_jump_handle);
|
||||
}
|
||||
#endif // (RCSP_MODE == RCSP_MODE_SOUNDBOX)
|
||||
|
||||
static void JL_controller_save_curr_cmd_para(u8 OpCode, u8 OpCode_SN)
|
||||
{
|
||||
update_record_info.opcode = OpCode;
|
||||
update_record_info.opcode_sn = OpCode_SN;
|
||||
}
|
||||
|
||||
static 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, void *buf, int len) = NULL;
|
||||
static void register_receive_fw_update_block_handle(void (*handle)(u8 state, void *buf, int 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);
|
||||
}
|
||||
|
||||
static u16 wait_response_timeout;
|
||||
static void wait_response_and_disconn_ble(void *priv)
|
||||
{
|
||||
rcsp_printf("W");
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_DEV_DISCONNECT, NULL, 0);
|
||||
}
|
||||
|
||||
static void rcsp_update_before_jump_handle(int type)
|
||||
{
|
||||
#if CONFIG_UPDATE_JUMP_TO_MASK
|
||||
void latch_reset();
|
||||
latch_reset();
|
||||
#else
|
||||
cpu_reset();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void rcsp_wait_reboot_dev(void *priv)
|
||||
{
|
||||
if (NULL == priv && !rcsp_send_list_is_empty()) {
|
||||
return;
|
||||
}
|
||||
bt_cmd_prepare(USER_CTRL_POWER_OFF, 0, NULL);
|
||||
extern void ble_module_enable(u8 en);
|
||||
ble_module_enable(0);
|
||||
#if CONFIG_UPDATE_JUMP_TO_MASK
|
||||
void latch_reset();
|
||||
latch_reset();
|
||||
#else
|
||||
cpu_reset();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void rcsp_rcsp_reboot_dev(void)
|
||||
{
|
||||
extern void adv_edr_name_change_now(void);
|
||||
adv_edr_name_change_now();
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if (get_bt_tws_connect_status()) {
|
||||
#if RCSP_ADV_EN
|
||||
modify_bt_name_and_reset(500);
|
||||
#endif
|
||||
} else {
|
||||
if (sys_timer_add(NULL, rcsp_wait_reboot_dev, 500) == 0) {
|
||||
rcsp_wait_reboot_dev((void *)1);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (sys_timer_add(NULL, rcsp_wait_reboot_dev, 500) == 0) {
|
||||
rcsp_wait_reboot_dev((void *)1);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
extern void rcsp_set_update_hdl(u16 ble_con_handle, u8 *spp_remote_addr);
|
||||
extern void rcsp_get_update_hdl(u16 *ble_con_handle, u8 *spp_remote_addr);
|
||||
void rcsp_loader_download_result_handle(void *priv, u8 type, u8 cmd);
|
||||
u32 rcsp_update_status_response(void *priv, u8 status);
|
||||
u32 rcsp_update_data_read(void *priv, u32 offset_addr, u16 len);
|
||||
extern void rcsp_update_handle(u8 state, void *buf, int 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 bt_set_low_latency_mode(int enable);
|
||||
extern void bt_ble_rcsp_adv_disable(void);
|
||||
void JL_resp_inquire_device_if_can_update(u8 OpCode, u8 OpCode_SN, u8 update_sta, u16 ble_con_handle, u8 *spp_remote_addr);
|
||||
void JL_rcsp_resp_dev_update_file_info_offest(u8 OpCode, u8 OpCode_SN, u16 ble_con_handle, u8 *spp_remote_addr);
|
||||
int JL_rcsp_update_cmd_resp(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr)
|
||||
{
|
||||
if ((OpCode >= JL_OPCODE_GET_DEVICE_UPDATE_FILE_INFO_OFFSET) && \
|
||||
(OpCode <= JL_OPCODE_SET_DEVICE_REBOOT)) {
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if (tws_api_get_role() == TWS_ROLE_SLAVE) {
|
||||
if (!(support_dual_bank_update_en && (OTA_TWS_SAME_TIME_ENABLE == 0))) { //如果双备份且没有打开TWS_SAME_TIME_ENABLE还是需要监听,应该是需要打开TWS_SAME_TIME_ENABEL,不然BLE传输只能升级一边
|
||||
putchar('&');
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
int ret = 0;
|
||||
u8 msg[5];
|
||||
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");
|
||||
JL_rcsp_resp_dev_update_file_info_offest(OpCode, OpCode_SN, ble_con_handle, spp_remote_addr);
|
||||
|
||||
} 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) {
|
||||
u8 can_update_flag = UPDATE_FLAG_FW_INFO_ERR;
|
||||
set_curr_update_type(data[0]);
|
||||
#if (TCFG_USER_TWS_ENABLE && 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 // (TCFG_USER_TWS_ENABLE && OTA_TWS_SAME_TIME_ENABLE)
|
||||
|
||||
// 1t2判断是否已有升级任务
|
||||
u8 cur_con_dev = bt_rcsp_device_conn_num();
|
||||
if (cur_con_dev > 1) {
|
||||
can_update_flag = UPDATE_FLAG_MULTI_CONN_DEVICE;
|
||||
}
|
||||
if (UPDATE_FLAG_OK == can_update_flag) {
|
||||
u8 max_con_dev = rcsp_max_support_con_dev_num();
|
||||
if (max_con_dev > 1) {
|
||||
u16 current_update_ble_con_hdl = 0;
|
||||
u8 current_update_spp_addr[6] = {0};
|
||||
u8 _addr_temp[6] = {0};
|
||||
rcsp_get_update_hdl(¤t_update_ble_con_hdl, current_update_spp_addr);
|
||||
if (current_update_ble_con_hdl || memcmp(current_update_spp_addr, _addr_temp, 6)) {
|
||||
can_update_flag = UPDATE_FLAG_ALREADY;
|
||||
}
|
||||
}
|
||||
}
|
||||
//低电逻辑处理
|
||||
struct RcspModel *rcsp_hd = rcsp_handle_get();
|
||||
if ((0 == get_charge_online_flag()) && rcsp_hd->low_battery_level && (get_self_battery_level() <= (rcsp_hd->low_battery_level % 10))) { // 防止设置low_battery_level大于10
|
||||
can_update_flag = UPDATE_FLAG_LOW_POWER;
|
||||
}
|
||||
//todo;judge voltage
|
||||
JL_resp_inquire_device_if_can_update(OpCode, OpCode_SN, can_update_flag, ble_con_handle, spp_remote_addr);
|
||||
|
||||
if (UPDATE_FLAG_OK != can_update_flag) {
|
||||
break;
|
||||
}
|
||||
rcsp_set_update_hdl(ble_con_handle, spp_remote_addr);
|
||||
rcsp_update_prepare();
|
||||
|
||||
if (0 == support_dual_bank_update_en) {
|
||||
#if RCSP_MODE == RCSP_MODE_EARPHONE
|
||||
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_USE_SPP == get_curr_device_type()) {
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
tws_api_detach(TWS_DETACH_BY_LOCAL, 5000); //单备份升级断开tws
|
||||
tws_cancle_all_noconn();
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#if (TCFG_USER_TWS_ENABLE == 1)
|
||||
if (!tws_api_get_role()) {
|
||||
#else
|
||||
if (1) {
|
||||
#endif
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_LOADER_DOWNLOAD_START, NULL, 0);
|
||||
} else {
|
||||
tws_need_update = 1; //置上该标志位APP重新连接的时候强制进入升级
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
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");
|
||||
bt_set_low_latency_mode(0);
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if (support_dual_bank_update_en && !tws_api_get_role()) {
|
||||
#else
|
||||
if (support_dual_bank_update_en) {
|
||||
#endif
|
||||
u8 status = 0;
|
||||
#if JL_RCSP_EXTRA_FLASH_OPT
|
||||
if (!get_update_ex_flash_flag()) {
|
||||
register_user_chip_update_handle(NULL);
|
||||
if (rcsp_eflash_update_flag_get()) {
|
||||
extern void app_rcsp_task_disable_opt(void);
|
||||
app_rcsp_task_disable_opt();
|
||||
app_rcsp_task_prepare(0, RCSP_TASK_ACTION_WATCH_TRANSFER, 0);
|
||||
}
|
||||
} else if (0 == get_curr_platform()) {
|
||||
#if UPDATE_EX_FALSH_USE_4K_BUF
|
||||
/* u32 update_once_req_size = rcsp_packet_write_alloc_len() / 256 * 256; */
|
||||
u32 update_once_req_size = 4096;
|
||||
extern void ex_flash_update_once_req_size_set(u32 pack_size);
|
||||
ex_flash_update_once_req_size_set(update_once_req_size);
|
||||
set_jl_mtu_resv(rcsp_packet_write_alloc_len());
|
||||
rcsp_update_change_mtu(rcsp_packet_write_alloc_len());
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, &status, 1, ble_con_handle, spp_remote_addr);
|
||||
rcsp_update_data_api_register(rcsp_update_data_read, rcsp_update_status_response);
|
||||
register_receive_fw_update_block_handle(rcsp_update_handle);
|
||||
printf("rcsp_update_loader_download_init %d\n", __LINE__);
|
||||
rcsp_update_loader_download_init(DUAL_BANK_UPDATA, rcsp_loader_download_result_handle);
|
||||
}
|
||||
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");
|
||||
JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, NULL, 0, ble_con_handle, spp_remote_addr);
|
||||
rcsp_rcsp_reboot_dev();
|
||||
|
||||
break;
|
||||
#if 0//TCFG_RCSP_DUAL_CONN_ENABLE
|
||||
case JL_OPCODE_CHECK_DEVICE_CONN_NUM:
|
||||
rcsp_printf("JL_OPCODE_CHECK_DEVICE_CONN_NUM\n");
|
||||
u8 cur_con_dev = bt_rcsp_device_conn_num();
|
||||
if (cur_con_dev > 1) {
|
||||
// 踢掉另一个连接的设备
|
||||
u8 first_flag = data[0];
|
||||
if (first_flag) {
|
||||
u8 *remote_addr = spp_remote_addr;
|
||||
if (ble_con_handle) {
|
||||
remote_addr = rcsp_get_ble_hdl_remote_mac_addr(ble_con_handle);
|
||||
}
|
||||
u8 *other_conn_addr = btstack_get_other_dev_addr(remote_addr);
|
||||
if (other_conn_addr) {
|
||||
btstack_device_detach(btstack_get_conn_device(other_conn_addr));
|
||||
}
|
||||
rcsp_disconn_other_ble(ble_con_handle);
|
||||
}
|
||||
JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, &cur_con_dev, 1, ble_con_handle, spp_remote_addr);
|
||||
} else {
|
||||
// 通知手机可以进入升级了
|
||||
JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, &cur_con_dev, 1, ble_con_handle, spp_remote_addr);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void JL_rcsp_resp_dev_update_file_info_offest(u8 OpCode, u8 OpCode_SN, u16 ble_con_handle, u8 *spp_remote_addr)
|
||||
{
|
||||
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), ble_con_handle, spp_remote_addr);
|
||||
}
|
||||
|
||||
static void JL_resp_inquire_device_if_can_update(u8 OpCode, u8 OpCode_SN, u8 update_sta, u16 ble_con_handle, u8 *spp_remote_addr)
|
||||
{
|
||||
u8 data[1];
|
||||
data[0] = update_sta;
|
||||
JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, data, sizeof(data), ble_con_handle, spp_remote_addr);
|
||||
}
|
||||
|
||||
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 (bt_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);
|
||||
u16 current_update_ble_con_hdl = 0;
|
||||
u8 current_update_spp_addr[6] = {0};
|
||||
rcsp_get_update_hdl(¤t_update_ble_con_hdl, current_update_spp_addr);
|
||||
/* printf("%s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__); */
|
||||
/* u8 _addr_temp[6] = {0}; */
|
||||
/* if (memcmp(current_update_spp_addr, _addr_temp, 6)) { */
|
||||
/* put_buf(current_update_spp_addr, 6); */
|
||||
/* } */
|
||||
err = JL_CMD_send(JL_OPCODE_SEND_FW_UPDATE_BLOCK, data, sizeof(data), JL_NEED_RESPOND, current_update_ble_con_hdl, current_update_spp_addr);
|
||||
|
||||
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;
|
||||
u16 current_update_ble_con_hdl = 0;
|
||||
u8 current_update_spp_addr[6] = {0};
|
||||
rcsp_get_update_hdl(¤t_update_ble_con_hdl, current_update_spp_addr);
|
||||
send_err = JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, data, sizeof(data), current_update_ble_con_hdl, current_update_spp_addr);
|
||||
|
||||
return send_err;
|
||||
}
|
||||
|
||||
static 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int JL_rcsp_update_cmd_receive_resp(void *priv, u8 OpCode, u8 status, u8 *data, u16 len)
|
||||
{
|
||||
int ret = 0;
|
||||
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:
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
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(">>>rcsp update succ\n");
|
||||
update_result_set(UPDATA_SUCC);
|
||||
}
|
||||
} else {
|
||||
rcsp_printf(">>>update loader err\n");
|
||||
#if 1//(RCSP_MODE == RCSP_MODE_SOUNDBOX)
|
||||
rcsp_update_fail_and_resume();
|
||||
#endif
|
||||
/* #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 u32 ex_cfg_fill_content_api(void);
|
||||
static void rcsp_update_private_param_fill(UPDATA_PARM *p)
|
||||
{
|
||||
u32 exif_addr = ex_cfg_fill_content_api();
|
||||
memcpy(p->parm_priv, (u8 *)&exif_addr, sizeof(exif_addr));
|
||||
}
|
||||
|
||||
static void rcsp_update_change_mtu(u16 new_mtu)
|
||||
{
|
||||
u8 buf[2] = {0};
|
||||
buf[0] = ((u8 *)&new_mtu)[1];
|
||||
buf[1] = ((u8 *)&new_mtu)[0];
|
||||
u16 current_update_ble_con_hdl = 0;
|
||||
u8 current_update_spp_addr[6] = {0};
|
||||
rcsp_get_update_hdl(¤t_update_ble_con_hdl, current_update_spp_addr);
|
||||
JL_CMD_send(JL_OPCODE_NOTIFY_MTU, (u8 *)buf, sizeof(buf), JL_NOT_NEED_RESPOND, current_update_ble_con_hdl, current_update_spp_addr);
|
||||
}
|
||||
|
||||
extern void register_user_chip_update_handle(const user_chip_update_t *user_update_ins);
|
||||
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_enable(void);
|
||||
extern u32 ex_cfg_fill_content_api(void);
|
||||
extern void update_param_priv_fill(UPDATA_PARM *p, void *priv, u16 priv_len);
|
||||
|
||||
#if RCSP_MODE == RCSP_MODE_EARPHONE
|
||||
|
||||
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 *priv)
|
||||
{
|
||||
r_printf("slave reopen adv...\n");
|
||||
ble_module_enable(1);
|
||||
bt_ble_rcsp_adv_enable();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int JL_rcsp_update_msg_deal(void *hdl, u8 event, u8 *msg)
|
||||
{
|
||||
int ret = 0;
|
||||
u16 remote_file_version;
|
||||
u8 can_update_flag = UPDATE_FLAG_FW_INFO_ERR;
|
||||
static int wait_edr_count = 0;
|
||||
|
||||
printf("---%s --- %d %d\n", __func__, __LINE__, event);
|
||||
switch (event) {
|
||||
case MSG_JL_DEV_DISCONNECT:
|
||||
if (rcsp_send_list_is_empty() && check_ble_all_packet_sent()) {
|
||||
rcsp_printf("MSG_JL_DEV_DISCONNECT\n");
|
||||
ble_app_disconnect();
|
||||
if (check_edr_is_disconnct()) {
|
||||
puts("-need discon edr\n");
|
||||
bt_cmd_prepare(USER_CTRL_POWER_OFF, 0, NULL);
|
||||
}
|
||||
if (RCSP_USE_BLE == get_curr_device_type()) {
|
||||
ble_discon_timeout = sys_timeout_add(NULL, ble_discon_timeout_handle, 1000);
|
||||
}
|
||||
} else {
|
||||
wait_response_timeout = sys_timeout_add(NULL, wait_response_and_disconn_ble, 100);
|
||||
}
|
||||
break;
|
||||
|
||||
case MSG_JL_LOADER_DOWNLOAD_START:
|
||||
printf("---%s --- %d\n", __func__, __LINE__);
|
||||
rcsp_update_data_api_register(rcsp_update_data_read, rcsp_update_status_response);
|
||||
register_receive_fw_update_block_handle(rcsp_update_handle);
|
||||
#if (RCSP_MODE == RCSP_MODE_WATCH)
|
||||
u32 update_once_req_size = 4096;
|
||||
extern void ex_flash_update_once_req_size_set(u32 pack_size);
|
||||
ex_flash_update_once_req_size_set(update_once_req_size);
|
||||
set_jl_mtu_resv(rcsp_packet_write_alloc_len());
|
||||
rcsp_update_change_mtu(rcsp_packet_write_alloc_len());
|
||||
#endif
|
||||
if (RCSP_USE_BLE == get_curr_device_type()) {
|
||||
printf("rcsp_update_loader_download_init %d\n", __LINE__);
|
||||
rcsp_update_loader_download_init(BLE_APP_UPDATA, rcsp_loader_download_result_handle);
|
||||
} else if (RCSP_USE_SPP == get_curr_device_type()) {
|
||||
printf("rcsp_update_loader_download_init %d\n", __LINE__);
|
||||
rcsp_update_loader_download_init(SPP_APP_UPDATA, rcsp_loader_download_result_handle);
|
||||
}
|
||||
break;
|
||||
|
||||
case MSG_JL_UPDATE_START:
|
||||
// loader加载完成,开始进入loader升级
|
||||
if (check_edr_is_disconnct() && wait_edr_count < 20) {
|
||||
rcsp_printf("b");
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_START, NULL, 0);
|
||||
wait_edr_count++;
|
||||
break;
|
||||
}
|
||||
wait_edr_count = 0;
|
||||
// 单备份的loader都是使用ble
|
||||
rcsp_printf("BLE_APP_UPDATE\n");
|
||||
update_mode_api_v2(BLE_APP_UPDATA,
|
||||
rcsp_update_private_param_fill,
|
||||
rcsp_update_before_jump_handle);
|
||||
/* sys_timeout_add(NULL, wait_response_and_disconn_spp, 100); */
|
||||
|
||||
break;
|
||||
default:
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
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 (bt_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 !TCFG_USER_TWS_ENABLE
|
||||
bt_cmd_prepare(USER_CTRL_WRITE_SCAN_DISABLE, 0, NULL);
|
||||
bt_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 (bt_get_total_connect_dev() == 0) {
|
||||
sys_auto_shut_down_enable();
|
||||
}
|
||||
}
|
||||
/* cpu_reset(); //升级失败直接复位 */
|
||||
}
|
||||
|
||||
#else // (RCSP_MODE && RCSP_UPDATE_EN && !RCSP_BLE_MASTER && TCFG_APP_UPDATE_EN)
|
||||
|
||||
//以下函数是为了编译通过
|
||||
int JL_rcsp_update_msg_deal(void *hdl, u8 event, u8 *msg)
|
||||
{
|
||||
printf("%s:NULL", __func__);
|
||||
return 0;
|
||||
}
|
||||
void set_jl_update_flag(u8 flag)
|
||||
{
|
||||
printf("%s:NULL", __func__);
|
||||
}
|
||||
void update_slave_adv_reopen(void *priv)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
u8 get_update_ex_flash_flag(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void set_update_ex_flash_flag(u8 update_flag)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int JL_rcsp_update_cmd_receive_resp(void *priv, u8 OpCode, u8 status, u8 *data, u16 len)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int JL_rcsp_update_cmd_resp(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif // (RCSP_MODE && RCSP_UPDATE_EN && !RCSP_BLE_MASTER && TCFG_APP_UPDATE_EN)
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
#ifndef _RCSP_UPDATE_H_
|
||||
#define _RCSP_UPDATE_H_
|
||||
|
||||
//#include "rcsp_protocol.h"
|
||||
//#include "rcsp_packet.h"
|
||||
#include "typedef.h"
|
||||
|
||||
int JL_rcsp_update_cmd_resp(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr);
|
||||
int JL_rcsp_update_msg_deal(void *hdl, u8 event, u8 *msg);
|
||||
|
||||
int 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);
|
||||
void update_slave_adv_reopen(void *priv);
|
||||
u8 rcsp_update_get_role_switch(void);
|
||||
|
||||
#endif
|
||||
|
||||
+759
@@ -0,0 +1,759 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".rcsp_update_tws.data.bss")
|
||||
#pragma data_seg(".rcsp_update_tws.data")
|
||||
#pragma const_seg(".rcsp_update_tws.text.const")
|
||||
#pragma code_seg(".rcsp_update_tws.text")
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "generic/circular_buf.h"
|
||||
#include "os/os_api.h"
|
||||
#include "update_loader_download.h"
|
||||
#include "system/task.h"
|
||||
#include "system/timer.h"
|
||||
#include "init.h"
|
||||
#include "rcsp_update_tws.h"
|
||||
#include "dual_bank_updata_api.h"
|
||||
#include "bt_tws.h"
|
||||
#include "app_config.h"
|
||||
#include "btstack/avctp_user.h"
|
||||
#include "update.h"
|
||||
#include "app_main.h"
|
||||
|
||||
#if ((RCSP_MODE == RCSP_MODE_SOUNDBOX) && OTA_TWS_SAME_TIME_ENABLE)
|
||||
|
||||
//#define LOG_TAG_CONST EARPHONE
|
||||
#define LOG_TAG "[UPDATE_TWS]"
|
||||
#define log_errorOR_ENABLE
|
||||
#define LOG_DEBUG_ENABLE
|
||||
#define LOG_INFO_ENABLE
|
||||
/* #define LOG_DUMP_ENABLE */
|
||||
#define LOG_CLI_ENABLE
|
||||
#include "debug.h"
|
||||
|
||||
#define THIS_TASK_NAME "tws_ota"
|
||||
#define SLAVE_REV_BUF_LEN 1024*2
|
||||
|
||||
enum {
|
||||
TWS_UPDATE_START,
|
||||
TWS_UPDATE_RESULT_EXCHANGE,
|
||||
TWS_UPDATE_RESULT_EXCHANGE_RES,
|
||||
TWS_UPDATE_OVER,
|
||||
TWS_UPDATE_OVER_CONFIRM,
|
||||
TWS_UPDATE_OVER_CONFIRM_REQ,
|
||||
TWS_UPDATE_OVER_CONFIRM_RES,
|
||||
TWS_UPDATE_VERIFY,
|
||||
};
|
||||
|
||||
extern void sys_enter_soft_poweroff(void *priv);
|
||||
|
||||
void db_update_notify_fail_to_phone();
|
||||
|
||||
struct __tws_ota_var {
|
||||
OS_SEM master_sem;
|
||||
OS_SEM slave_sem;
|
||||
OS_SEM confirm_sem;
|
||||
struct __tws_ota_para para;
|
||||
u8 ota_type;
|
||||
u8 ota_status;
|
||||
u8 ota_remote_status;
|
||||
u8 ota_result;
|
||||
volatile u32 ota_data_len;
|
||||
u16 ota_timer_id;
|
||||
u8 ota_verify_cnt;
|
||||
volatile u32 ota_confirm;
|
||||
cbuffer_t cbuffer;
|
||||
u8 *slave_r_buf;
|
||||
};
|
||||
struct __tws_ota_var tws_ota_var;
|
||||
#define __this (&tws_ota_var)
|
||||
|
||||
void tws_ota_event_post(u32 type, u8 event)
|
||||
{
|
||||
struct sys_event e;
|
||||
e.type = SYS_BT_EVENT;
|
||||
e.arg = (void *)type;
|
||||
e.u.bt.event = event;
|
||||
sys_event_notify(&e);
|
||||
}
|
||||
|
||||
u8 tws_ota_control(int type, ...)
|
||||
{
|
||||
int ret = 0;
|
||||
int role = 0;
|
||||
int value = 0;
|
||||
|
||||
va_list argptr;
|
||||
va_start(argptr, type);
|
||||
|
||||
switch (type) {
|
||||
case OTA_TYPE_SET:
|
||||
value = va_arg(argptr, int);
|
||||
__this->ota_type = value;
|
||||
break;
|
||||
case OTA_TYPE_GET:
|
||||
ret = __this->ota_type;
|
||||
break;
|
||||
case OTA_STATUS_SET:
|
||||
value = va_arg(argptr, int);
|
||||
__this->ota_status = value;
|
||||
break;
|
||||
case OTA_STATUS_GET:
|
||||
ret = __this->ota_status;
|
||||
break;
|
||||
case OTA_REMOTE_STATUS_SET:
|
||||
value = va_arg(argptr, int);
|
||||
__this->ota_remote_status = value;
|
||||
break;
|
||||
case OTA_REMOTE_STATUS_GET:
|
||||
ret = __this->ota_remote_status;
|
||||
break;
|
||||
case OTA_RESULT_SET:
|
||||
value = va_arg(argptr, int);
|
||||
role = va_arg(argptr, int);
|
||||
if (value == 1) {
|
||||
__this->ota_result |= BIT(role);
|
||||
} else {
|
||||
__this->ota_result &= ~BIT(role);
|
||||
}
|
||||
break;
|
||||
case OTA_RESULT_GET:
|
||||
ret = __this->ota_result;
|
||||
break;
|
||||
}
|
||||
|
||||
va_end(argptr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tws_ota_init(void)
|
||||
{
|
||||
memset((u8 *)__this, 0, sizeof(struct __tws_ota_var));
|
||||
__this->ota_status = OTA_INIT;
|
||||
__this->ota_type = OTA_TWS;
|
||||
|
||||
if (a2dp_get_status() == BT_MUSIC_STATUS_STARTING) {
|
||||
/* log_info("try pause a2dp music"); */
|
||||
user_send_cmd_prepare(USER_CTRL_AVCTP_OPID_PAUSE, 0, NULL);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define TWS_FUNC_ID_OTA_SYNC TWS_FUNC_ID('O', 'T', 'A', 'S')
|
||||
static void tws_ota_data_read_s_from_m(void *_data, u16 len, bool rx)
|
||||
{
|
||||
if (rx && __this->ota_status == OTA_START && __this->slave_r_buf) {
|
||||
/* r_log_info("Offset:%x r_len:%d\n",__this->ota_data_len,len); */
|
||||
/* put_buf(_data, len); */
|
||||
__this->ota_data_len += len;
|
||||
if (cbuf_is_write_able(&(__this->cbuffer), len)) {
|
||||
cbuf_write(&(__this->cbuffer), _data, len);
|
||||
} else {
|
||||
log_info("ota cbuf write err\n");
|
||||
}
|
||||
os_sem_post(&__this->slave_sem);
|
||||
}
|
||||
}
|
||||
|
||||
REGISTER_TWS_FUNC_STUB(app_ota_sync_stub) = {
|
||||
.func_id = TWS_FUNC_ID_OTA_SYNC,
|
||||
.func = tws_ota_data_read_s_from_m,
|
||||
};
|
||||
|
||||
int tws_ota_data_send_m_to_s(u8 *buf, u16 len)
|
||||
{
|
||||
if (!(tws_api_get_tws_state() & TWS_STA_SIBLING_CONNECTED)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (tws_api_get_role() == TWS_ROLE_SLAVE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ret = tws_api_send_data_to_slave(buf, len, TWS_FUNC_ID_OTA_SYNC);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tws_ota_err_callback(u8 reason)
|
||||
{
|
||||
tws_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS, OTA_UPDATE_ERR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tws_ota_update_loop(void *priv)
|
||||
{
|
||||
u32 total_len = 0;
|
||||
u32 len = 0;
|
||||
u8 *tmp_buf = NULL;
|
||||
int ret = 0;
|
||||
|
||||
u8 sniff_wait_exit_timeout = 30;//3s
|
||||
|
||||
log_info("tws_ota_update_loop\n");
|
||||
|
||||
while (1) {
|
||||
os_sem_pend(&__this->slave_sem, 0);
|
||||
|
||||
if (sniff_wait_exit_timeout) {
|
||||
//wait slave exit sniff
|
||||
extern u8 btstcak_get_bt_mode(void);
|
||||
while (btstcak_get_bt_mode() && sniff_wait_exit_timeout--) {
|
||||
log_info("wait sniff exit \n");
|
||||
os_time_dly(10);
|
||||
}
|
||||
log_info(">>>>>>>sniff timeout:%d \n", sniff_wait_exit_timeout);
|
||||
|
||||
if (!sniff_wait_exit_timeout) {
|
||||
log_info(">>>>>>wait sniff exit timeout !!!! \n");
|
||||
}
|
||||
sniff_wait_exit_timeout = 0;
|
||||
dual_bank_passive_update_init(__this->para.fm_crc16, __this->para.fm_size, __this->para.max_pkt_len, NULL);
|
||||
ret = dual_bank_update_allow_check(__this->para.fm_size);
|
||||
if (ret) {
|
||||
log_info("fm_size:%x can't update\n", __this->para.fm_size);
|
||||
tws_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS, OTA_UPDATE_ERR);
|
||||
continue;
|
||||
}
|
||||
tws_api_sync_call_by_uuid(0xA2E22223, SYNC_CMD_START_UPDATE, 400);
|
||||
continue;
|
||||
}
|
||||
|
||||
total_len = cbuf_get_data_size(&(__this->cbuffer));
|
||||
/* log_info("total_len : %d\n",total_len); */
|
||||
while (total_len) {
|
||||
if (total_len > get_dual_bank_passive_update_max_buf()) {
|
||||
len = get_dual_bank_passive_update_max_buf();
|
||||
} else {
|
||||
len = total_len;
|
||||
}
|
||||
|
||||
if (!len) {
|
||||
continue;
|
||||
}
|
||||
tmp_buf = malloc(len);
|
||||
if (tmp_buf) {
|
||||
if (cbuf_read(&(__this->cbuffer), tmp_buf, len) == len) {
|
||||
putchar('D');
|
||||
dual_bank_update_write(tmp_buf, len, NULL);
|
||||
} else {
|
||||
log_error("read err\n");
|
||||
}
|
||||
free(tmp_buf);
|
||||
} else {
|
||||
log_error("malloc err\n");
|
||||
}
|
||||
total_len -= len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ota_finish_confirm(void *priv)
|
||||
{
|
||||
log_info("ota_finish_confirm:%d\n", __this->ota_confirm);
|
||||
if (!__this->ota_confirm) {
|
||||
//ota tws confirm err,earse boot info
|
||||
flash_update_clr_boot_info(CLEAR_APP_UPDATE_BANK);
|
||||
/* ASSERT(0, "ota tws confirm err\n"); */
|
||||
}
|
||||
tws_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS, OTA_UPDATE_SUCC);
|
||||
|
||||
}
|
||||
|
||||
u16 tws_ota_enter_verify(void *priv)
|
||||
{
|
||||
if (tws_api_get_tws_state() & TWS_STA_SIBLING_DISCONNECTED) {
|
||||
log_info("tws_disconn in verify\n");
|
||||
db_update_notify_fail_to_phone();
|
||||
return -1;
|
||||
}
|
||||
tws_ota_send_data_to_sibling(TWS_UPDATE_VERIFY, NULL, 0);
|
||||
os_sem_pend(&__this->master_sem, 1000);
|
||||
//这里pend完,要做超时的准备
|
||||
if (__this->ota_status == OTA_VERIFY_ING) {
|
||||
return 0;
|
||||
} else {
|
||||
db_update_notify_fail_to_phone();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
u16 tws_ota_exit_verify(u8 *res, u8 *up_flg)
|
||||
{
|
||||
//not updata boot info in lib
|
||||
*up_flg = 1;
|
||||
|
||||
u8 tws_ota_result[2];
|
||||
u8 master_result = *res;
|
||||
u8 result = 0;
|
||||
tws_ota_control(OTA_STATUS_SET, OTA_VERIFY_END);
|
||||
tws_ota_control(OTA_RESULT_SET, !master_result, TWS_ROLE_MASTER);
|
||||
__RESTART:
|
||||
if (tws_api_get_tws_state() & TWS_STA_SIBLING_DISCONNECTED) {
|
||||
db_update_notify_fail_to_phone();
|
||||
return 0;
|
||||
}
|
||||
result = tws_ota_control(OTA_RESULT_GET);
|
||||
tws_ota_result[0] = result;
|
||||
tws_ota_result[1] = tws_ota_control(OTA_STATUS_GET);
|
||||
tws_ota_send_data_to_sibling(TWS_UPDATE_RESULT_EXCHANGE, (u8 *)&tws_ota_result, 2);
|
||||
|
||||
if ((result & BIT(TWS_ROLE_SLAVE)) && (result & BIT(TWS_ROLE_SLAVE))) {
|
||||
log_info("tws already ota succ1\n");
|
||||
os_sem_set(&__this->master_sem, 0);
|
||||
tws_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS, OTA_UPDATE_OVER);
|
||||
return 1;
|
||||
} else if (__this->ota_remote_status == OTA_VERIFY_END || __this->ota_remote_status == OTA_OVER) {
|
||||
tws_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS, OTA_UPDATE_ERR);
|
||||
return 0;
|
||||
} else {
|
||||
os_sem_pend(&__this->master_sem, 200);
|
||||
goto __RESTART;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
u16 tws_ota_updata_boot_info_over(void *priv)
|
||||
{
|
||||
log_info("master update_burn_boot_info succ\n");
|
||||
if (tws_api_get_tws_state() & TWS_STA_SIBLING_DISCONNECTED) {
|
||||
log_info("tws_disconn, ota open fail");
|
||||
db_update_notify_fail_to_phone();
|
||||
return -1;
|
||||
}
|
||||
|
||||
//等待从机更新完成
|
||||
log_info("1------pend in");
|
||||
os_sem_pend(&__this->confirm_sem, 300);
|
||||
log_info("1------pend out");
|
||||
|
||||
log_info("-------mz01");
|
||||
if (__this->ota_confirm) {
|
||||
log_info("-------mz02");
|
||||
os_sem_set(&__this->confirm_sem, 0);
|
||||
tws_ota_send_data_to_sibling(TWS_UPDATE_OVER_CONFIRM_REQ, NULL, 0);
|
||||
log_info("2------pend in");
|
||||
if (OS_TIMEOUT == os_sem_pend(&__this->confirm_sem, 300)) {
|
||||
__this->ota_confirm = 0;
|
||||
}
|
||||
log_info("2------pend out");
|
||||
}
|
||||
|
||||
if (!__this->ota_confirm) {
|
||||
log_info("-------mz03");
|
||||
//ota tws confirm err,earse boot info
|
||||
flash_update_clr_boot_info(CLEAR_APP_UPDATE_BANK);
|
||||
/* ASSERT(0, "ota tws confirm err\n"); */
|
||||
return -1;
|
||||
}
|
||||
/* tws_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS,OTA_UPDATE_SUCC); //主机等手机发重启命令*/
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int tws_ota_open(struct __tws_ota_para *para)
|
||||
{
|
||||
int ret = 0;
|
||||
log_info("tws_ota_open\n");
|
||||
|
||||
if (tws_api_get_tws_state() & TWS_STA_SIBLING_DISCONNECTED) {
|
||||
log_info("tws_disconn, ota open fail");
|
||||
db_update_notify_fail_to_phone();
|
||||
return -1;
|
||||
}
|
||||
|
||||
os_sem_create(&__this->master_sem, 0);
|
||||
os_sem_create(&__this->slave_sem, 0);
|
||||
os_sem_create(&__this->confirm_sem, 0);
|
||||
|
||||
if (tws_api_get_role() == TWS_ROLE_MASTER) {
|
||||
extern void bt_check_exit_sniff();
|
||||
bt_check_exit_sniff();
|
||||
//master 发命令给slave启动升级
|
||||
|
||||
|
||||
log_info("master updata info: crc16:%x size:%x max_pkt_len:%d\n", para->fm_crc16, para->fm_size, para->max_pkt_len);
|
||||
if (__this->ota_type == OTA_TWS) {
|
||||
tws_ota_send_data_to_sibling(TWS_UPDATE_START, (u8 *)para, sizeof(struct __tws_ota_para));
|
||||
log_info("sem pend in ...");
|
||||
os_sem_pend(&__this->master_sem, 600);
|
||||
log_info("sem pend out ...");
|
||||
//判断对耳状态
|
||||
if (__this->ota_status == OTA_START) {
|
||||
log_info("slave has ready");
|
||||
ret = 0;
|
||||
} else {
|
||||
log_info("slave answer timeout");
|
||||
db_update_notify_fail_to_phone();
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log_info("slave updata info: crc16:%x size:%x max_pkt_len:%d\n", para->fm_crc16, para->fm_size, para->max_pkt_len);
|
||||
|
||||
/* tws_api_sync_call_by_uuid('T', SYNC_CMD_START_UPDATE, 100); */
|
||||
tws_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS, OTA_START_UPDATE_READY);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tws_ota_close(void)
|
||||
{
|
||||
int ret = 0;
|
||||
log_info("%s", __func__);
|
||||
if (__this->slave_r_buf) {
|
||||
free(__this->slave_r_buf);
|
||||
__this->slave_r_buf = 0;
|
||||
task_kill(THIS_TASK_NAME);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ota_verify_timeout(void *priv)
|
||||
{
|
||||
log_info("ota_verify_timeout:%x %x\n", __this->para.fm_size, __this->ota_data_len);
|
||||
if (__this->ota_data_len == __this->para.fm_size) {
|
||||
/* tws_api_sync_call_by_uuid('T', SYNC_CMD_START_VERIFY, 100); */
|
||||
tws_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS, OTA_START_VERIFY);
|
||||
return;
|
||||
}
|
||||
|
||||
if (__this->ota_verify_cnt > 4) {
|
||||
log_info("code len err\n");
|
||||
tws_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS, OTA_UPDATE_ERR);
|
||||
sys_timeout_del(__this->ota_timer_id);
|
||||
__this->ota_timer_id = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
__this->ota_verify_cnt ++;
|
||||
__this->ota_timer_id = 0;
|
||||
__this->ota_timer_id = sys_timeout_add(NULL, ota_verify_timeout, 500);
|
||||
}
|
||||
|
||||
int tws_ota_get_data_from_sibling(u8 opcode, u8 *data, u8 len)
|
||||
{
|
||||
u8 tws_ota_result[2];
|
||||
switch (opcode) {
|
||||
//master->slave
|
||||
case TWS_UPDATE_START:
|
||||
log_info("TWS_AI_START_UPDATE:%d\n", opcode);
|
||||
if (tws_api_get_role() == TWS_ROLE_SLAVE) {
|
||||
if (__this->slave_r_buf) {
|
||||
tws_ota_close();
|
||||
}
|
||||
tws_ota_init();
|
||||
memcpy((u8 *) & (__this->para), data, len);
|
||||
tws_ota_open(&(__this->para));
|
||||
}
|
||||
break;
|
||||
|
||||
//master->slave
|
||||
case TWS_UPDATE_RESULT_EXCHANGE:
|
||||
log_info("TWS_UPDATE_RESULT_EXCHANGE:%d %d\n", data[0], data[1]);
|
||||
__this->ota_remote_status = data[1];
|
||||
tws_ota_control(OTA_RESULT_SET, (data[0] & BIT(TWS_ROLE_MASTER) ? 1 : 0), TWS_ROLE_MASTER);
|
||||
|
||||
tws_ota_result[0] = __this->ota_result;
|
||||
tws_ota_result[1] = __this->ota_status;
|
||||
tws_ota_send_data_to_sibling(TWS_UPDATE_RESULT_EXCHANGE_RES, (u8 *)tws_ota_result, 2);
|
||||
log_info("master ota result:%x %d\n", tws_ota_control(OTA_RESULT_GET), __this->ota_status);
|
||||
break;
|
||||
|
||||
//slave->master
|
||||
case TWS_UPDATE_RESULT_EXCHANGE_RES:
|
||||
log_info("TWS_UPDATE_RESULT_EXCHANGE_RES:%d %d\n", data[0], data[1]);
|
||||
__this->ota_remote_status = data[1];
|
||||
tws_ota_control(OTA_RESULT_SET, (data[0] & BIT(TWS_ROLE_SLAVE) ? 1 : 0), TWS_ROLE_SLAVE);
|
||||
log_info("slave ota result:%x %d\n", tws_ota_control(OTA_RESULT_GET), __this->ota_status);
|
||||
|
||||
if (tws_ota_control(OTA_RESULT_GET) & BIT(TWS_ROLE_SLAVE)) {
|
||||
os_sem_post(&__this->master_sem);
|
||||
}
|
||||
break;
|
||||
|
||||
//master->slave
|
||||
case TWS_UPDATE_VERIFY:
|
||||
log_info("TWS_UPDATE_VERIFY\n");
|
||||
tws_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS, OTA_START_VERIFY);
|
||||
break;
|
||||
|
||||
case TWS_UPDATE_OVER:
|
||||
log_info("TWS_AI_UPDATE_OVER:%d\n", opcode);
|
||||
__this->ota_status = OTA_OVER;
|
||||
break;
|
||||
|
||||
//slave to master
|
||||
case TWS_UPDATE_OVER_CONFIRM:
|
||||
log_info("TWS_UPDATE_OVER_CONFIRM\n");
|
||||
__this->ota_confirm = 1;
|
||||
if (tws_api_get_role() == TWS_ROLE_MASTER) {
|
||||
log_info("1------post");
|
||||
os_sem_post(&__this->confirm_sem);
|
||||
}
|
||||
break;
|
||||
//master->slave
|
||||
case TWS_UPDATE_OVER_CONFIRM_REQ:
|
||||
log_info("TWS_UPDATE_OVER_CONFIRM_REQ\n");
|
||||
if (tws_api_get_role() == TWS_ROLE_SLAVE) {
|
||||
__this->ota_confirm = 1;
|
||||
tws_ota_send_data_to_sibling(TWS_UPDATE_OVER_CONFIRM_RES, NULL, 0);
|
||||
log_info("2------post");
|
||||
os_sem_post(&__this->confirm_sem);
|
||||
}
|
||||
break;
|
||||
//slave->master
|
||||
case TWS_UPDATE_OVER_CONFIRM_RES:
|
||||
log_info("TWS_UPDATE_OVER_CONFIRM_RES\n");
|
||||
if (tws_api_get_role() == TWS_ROLE_MASTER) {
|
||||
log_info("3------post");
|
||||
os_sem_post(&__this->confirm_sem);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tws_ota_send_data_to_sibling(u8 opcode, u8 *data, u8 len)
|
||||
{
|
||||
extern void tws_data_to_sibling_send(u8 opcode, u8 * data, u8 len);
|
||||
tws_data_to_sibling_send(opcode, data, len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
u8 dual_bank_update_burn_boot_info_callback(u8 ret)
|
||||
{
|
||||
if (ret) {
|
||||
log_info("update_burn_boot_info err\n");
|
||||
} else {
|
||||
log_info("slave update_burn_boot_info succ\n");
|
||||
tws_ota_send_data_to_sibling(TWS_UPDATE_OVER_CONFIRM, NULL, 0);
|
||||
|
||||
//not recive master confirm
|
||||
log_info("3------pend in");
|
||||
os_sem_pend(&__this->confirm_sem, 300);
|
||||
log_info("3------pend out");
|
||||
|
||||
if (!__this->ota_confirm) {
|
||||
//ota tws confirm err,earse boot info
|
||||
flash_update_clr_boot_info(CLEAR_APP_UPDATE_BANK);
|
||||
/* ASSERT(0, "ota tws confirm err\n"); */
|
||||
return 0;
|
||||
}
|
||||
|
||||
//确保从机的回复命令送达到主机
|
||||
os_time_dly(50);
|
||||
|
||||
tws_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS, OTA_UPDATE_SUCC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//slave ota result
|
||||
static sint32_t gma_ota_slave_result(int crc_res)
|
||||
{
|
||||
u8 ret = crc_res;
|
||||
|
||||
tws_ota_control(OTA_STATUS_SET, OTA_VERIFY_END);
|
||||
|
||||
tws_ota_control(OTA_RESULT_SET, crc_res, TWS_ROLE_SLAVE);
|
||||
|
||||
log_info("gma_ota_slave_result:%d %d\n", crc_res, tws_ota_control(OTA_STATUS_GET));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tws_ota_sync_cmd(int reason)
|
||||
{
|
||||
int ret = 1;
|
||||
|
||||
switch (reason) {
|
||||
//slave request
|
||||
case SYNC_CMD_START_UPDATE:
|
||||
log_info("SYNC_CMD_START_UPDATE\n");
|
||||
|
||||
if (__this->ota_status != OTA_INIT) {
|
||||
log_info("tws ota no init");
|
||||
break;
|
||||
}
|
||||
__this->ota_status = OTA_START;
|
||||
__this->ota_data_len = 0;
|
||||
__this->ota_remote_status = OTA_START;
|
||||
if (tws_api_get_role() == TWS_ROLE_MASTER) {
|
||||
os_sem_post(&__this->master_sem);
|
||||
} else {
|
||||
}
|
||||
break;
|
||||
|
||||
//slave request
|
||||
case SYNC_CMD_START_VERIFY:
|
||||
log_info("SYNC_CMD_START_VERIFY\n");
|
||||
__this->ota_status = OTA_VERIFY_ING;
|
||||
__this->ota_remote_status = OTA_VERIFY_ING;
|
||||
|
||||
if (tws_api_get_role() == TWS_ROLE_MASTER) {
|
||||
os_sem_post(&__this->master_sem);
|
||||
} else {
|
||||
dual_bank_update_verify(NULL, NULL, gma_ota_slave_result);
|
||||
}
|
||||
break;
|
||||
|
||||
//master request
|
||||
case SYNC_CMD_UPDATE_OVER:
|
||||
log_info("SYNC_CMD_UPDATE_OVER\n");
|
||||
|
||||
__this->ota_status = OTA_OVER;
|
||||
__this->ota_remote_status = OTA_OVER;
|
||||
if ((__this->ota_result & BIT(TWS_ROLE_MASTER)) && (__this->ota_result & BIT(TWS_ROLE_SLAVE))) {
|
||||
log_info("OTA SUCCESS\n");
|
||||
//update boot info
|
||||
if (tws_api_get_role() == TWS_ROLE_SLAVE) {
|
||||
dual_bank_update_burn_boot_info(dual_bank_update_burn_boot_info_callback);
|
||||
}
|
||||
} else {
|
||||
log_info("OTA ERR\n");
|
||||
/* tws_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS,OTA_UPDATE_SUCC); */
|
||||
}
|
||||
break;
|
||||
|
||||
//slave request
|
||||
case SYNC_CMD_UPDATE_ERR:
|
||||
log_info("SYNC_CMD_UPDATE_ERR\n");
|
||||
if (tws_api_get_role() == TWS_ROLE_MASTER) {
|
||||
} else {
|
||||
tws_ota_stop(OTA_STOP_UPDATE_OVER_ERR);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void tws_ota_app_event_deal(u8 event)
|
||||
{
|
||||
if (__this->ota_status == OTA_OVER) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (event) {
|
||||
case TWS_EVENT_CONNECTION_DETACH:
|
||||
/* case TWS_EVENT_PHONE_LINK_DETACH: */
|
||||
case TWS_EVENT_REMOVE_PAIRS:
|
||||
log_info("stop ota : %d --1\n", event);
|
||||
tws_ota_stop(OTA_STOP_LINK_DISCONNECT);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void tws_ota_stop(u8 reason)
|
||||
{
|
||||
log_info("%s", __func__);
|
||||
|
||||
if (__this->ota_status != OTA_OVER) {
|
||||
|
||||
//reconnect hfp when start err
|
||||
if (reason == OTA_STOP_APP_DISCONNECT || reason == OTA_STOP_UPDATE_OVER_ERR) {
|
||||
//在更新信息的时候,手机app断开
|
||||
|
||||
/* if(tws_api_get_role() == TWS_ROLE_MASTER) { */
|
||||
/* extern void user_post_key_msg(u8 user_msg); */
|
||||
/* user_post_key_msg(USER_TWS_OTA_RESUME); */
|
||||
/* } */
|
||||
}
|
||||
|
||||
__this->ota_status = OTA_OVER;
|
||||
if (__this->ota_timer_id) {
|
||||
sys_timeout_del(__this->ota_timer_id);
|
||||
__this->ota_timer_id = 0;
|
||||
}
|
||||
|
||||
tws_ota_close();
|
||||
dual_bank_passive_update_exit(NULL);
|
||||
extern void rcsp_db_update_fail_deal(); //双备份升级失败处理
|
||||
rcsp_db_update_fail_deal();
|
||||
}
|
||||
}
|
||||
|
||||
int bt_ota_event_handler(struct bt_event *bt)
|
||||
{
|
||||
int ret = 0;
|
||||
switch (bt->event) {
|
||||
case OTA_START_UPDATE:
|
||||
log_info("OTA_START_UPDATE\n");
|
||||
tws_api_sync_call_by_uuid(0xA2E22223, SYNC_CMD_START_UPDATE, 400);
|
||||
break;
|
||||
case OTA_START_UPDATE_READY:
|
||||
log_info("OTA_START_UPDATE_READY:%x %x %d\n", __this->para.fm_crc16, __this->para.fm_size, __this->para.max_pkt_len);
|
||||
extern void rcsp_before_enter_db_update_mode();
|
||||
rcsp_before_enter_db_update_mode();
|
||||
if (__this->slave_r_buf) {
|
||||
ASSERT(0, "tws_ota_update_loop already exit\n");
|
||||
}
|
||||
task_create(tws_ota_update_loop, NULL, THIS_TASK_NAME);
|
||||
__this->slave_r_buf = malloc(SLAVE_REV_BUF_LEN);
|
||||
ASSERT(__this->slave_r_buf, "slave_r_buf malloc err\n");
|
||||
cbuf_init(&(__this->cbuffer), __this->slave_r_buf, SLAVE_REV_BUF_LEN);
|
||||
|
||||
os_sem_post(&__this->slave_sem);
|
||||
/* tws_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS,OTA_START_UPDATE); */
|
||||
break;
|
||||
case OTA_START_VERIFY:
|
||||
log_info("OTA_START_VERIFY\n");
|
||||
if (__this->ota_data_len == __this->para.fm_size) {
|
||||
tws_api_sync_call_by_uuid(0xA2E22223, SYNC_CMD_START_VERIFY, 1000);
|
||||
} else {
|
||||
if (__this->ota_timer_id) {
|
||||
sys_timeout_del(__this->ota_timer_id);
|
||||
__this->ota_timer_id = 0;
|
||||
}
|
||||
__this->ota_timer_id = sys_timeout_add(NULL, ota_verify_timeout, 500);
|
||||
}
|
||||
break;
|
||||
case OTA_UPDATE_OVER:
|
||||
log_info("OTA_UPDATE_OVER\n");
|
||||
tws_api_sync_call_by_uuid(0xA2E22223, SYNC_CMD_UPDATE_OVER, 400);
|
||||
break;
|
||||
case OTA_UPDATE_ERR:
|
||||
log_info("OTA_UPDATE_ERR\n");
|
||||
tws_api_sync_call_by_uuid(0xA2E22223, SYNC_CMD_UPDATE_ERR, 400);
|
||||
break;
|
||||
case OTA_UPDATE_SUCC:
|
||||
log_info("OTA_UPDATE_SUCC\n");
|
||||
update_result_set(UPDATA_SUCC);
|
||||
dual_bank_passive_update_exit(NULL);
|
||||
|
||||
/* update_result_set(UPDATA_SUCC); */
|
||||
/* extern void cpu_reset(); */
|
||||
/* cpu_reset(); */
|
||||
//user_ctl.shutdown_need_adv = 0;
|
||||
sys_enter_soft_poweroff((void *)1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rcsp_tws_ota_sync_handler(int reason, int err)
|
||||
{
|
||||
tws_ota_sync_cmd(reason);
|
||||
}
|
||||
|
||||
TWS_SYNC_CALL_REGISTER(rcsp_tws_ota_sync) = {
|
||||
.uuid = 0xA2E22223,
|
||||
.task_name = "app_core",
|
||||
.func = rcsp_tws_ota_sync_handler,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
#ifndef RCSP_UPDATE_TWS_H
|
||||
#define RCSP_UPDATE_TWS_H
|
||||
|
||||
#include "app_config.h"
|
||||
|
||||
#if ((RCSP_MODE == RCSP_MODE_SOUNDBOX) && OTA_TWS_SAME_TIME_ENABLE)
|
||||
|
||||
#define SYS_BT_OTA_EVENT_TYPE_STATUS (('O' << 24) | ('T' << 16) | ('A' << 8) | '\0')
|
||||
|
||||
#include "system/event.h"
|
||||
#include "update_loader_download.h"
|
||||
|
||||
typedef int sint32_t;
|
||||
|
||||
enum {
|
||||
OTA_OVER = 0,
|
||||
OTA_INIT,
|
||||
OTA_START,
|
||||
OTA_VERIFY_ING,
|
||||
OTA_VERIFY_END,
|
||||
OTA_SUCC,
|
||||
};
|
||||
|
||||
enum {
|
||||
OTA_SINGLE_EARPHONE,
|
||||
OTA_TWS,
|
||||
};
|
||||
|
||||
enum {
|
||||
OTA_START_UPDATE = 0,
|
||||
OTA_START_UPDATE_READY,
|
||||
OTA_START_VERIFY,
|
||||
OTA_UPDATE_OVER,
|
||||
OTA_UPDATE_ERR,
|
||||
OTA_UPDATE_SUCC,
|
||||
};
|
||||
|
||||
enum {
|
||||
OTA_TYPE_SET = 0,
|
||||
OTA_TYPE_GET,
|
||||
OTA_STATUS_SET,
|
||||
OTA_STATUS_GET,
|
||||
OTA_REMOTE_STATUS_SET,
|
||||
OTA_REMOTE_STATUS_GET,
|
||||
OTA_RESULT_SET,
|
||||
OTA_RESULT_GET,
|
||||
};
|
||||
|
||||
|
||||
enum {
|
||||
OTA_STOP_APP_DISCONNECT,
|
||||
OTA_STOP_LINK_DISCONNECT,
|
||||
OTA_STOP_UPDATE_OVER_SUCC,
|
||||
OTA_STOP_UPDATE_OVER_ERR,
|
||||
OTA_STOP_PHONE,
|
||||
};
|
||||
|
||||
enum {
|
||||
SYNC_CMD_START_UPDATE,
|
||||
SYNC_CMD_START_VERIFY,
|
||||
SYNC_CMD_UPDATE_OVER,
|
||||
SYNC_CMD_UPDATE_ERR,
|
||||
};
|
||||
|
||||
int tws_ota_init(void);
|
||||
int tws_ota_close(void);
|
||||
|
||||
int tws_ota_open(struct __tws_ota_para *para);
|
||||
void tws_ota_stop(u8 reason);
|
||||
|
||||
u16 tws_ota_enter_verify(void *priv);
|
||||
u16 tws_ota_exit_verify(u8 *res, u8 *up_flg);
|
||||
u16 tws_ota_updata_boot_info_over(void *priv);
|
||||
|
||||
int tws_ota_err_callback(u8 reason);
|
||||
|
||||
int tws_ota_data_send_m_to_s(u8 *buf, u16 len);
|
||||
int tws_ota_sync_cmd(int reason);
|
||||
void tws_ota_app_event_deal(u8 event);
|
||||
u8 dual_bank_update_burn_boot_info_callback(u8 ret);
|
||||
int bt_ota_event_handler(struct bt_event *bt);
|
||||
void tws_ota_event_post(u32 type, u8 event);
|
||||
|
||||
u8 tws_ota_control(int type, ...);
|
||||
|
||||
void tws_ota_send_data_to_sibling(u8 opcode, u8 *data, u8 len);
|
||||
int tws_ota_get_data_from_sibling(u8 opcode, u8 *data, u8 len);
|
||||
|
||||
#endif // ((RCSP_MODE == RCSP_MODE_SOUNDBOX) && OTA_TWS_SAME_TIME_ENABLE)
|
||||
|
||||
#endif // RCSP_UPDATE_TWS_H
|
||||
|
||||
+871
@@ -0,0 +1,871 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".nfc_data_opt.data.bss")
|
||||
#pragma data_seg(".nfc_data_opt.data")
|
||||
#pragma const_seg(".nfc_data_opt.text.const")
|
||||
#pragma code_seg(".nfc_data_opt.text")
|
||||
#endif
|
||||
#include "rcsp_config.h"
|
||||
#include "nfc_data_opt.h"
|
||||
#include "rcsp_browser.h"
|
||||
#include "rcsp_event.h"
|
||||
|
||||
#if (RCSP_MODE && JL_RCSP_SENSORS_DATA_OPT && JL_RCSP_NFC_DATA_OPT)
|
||||
|
||||
#define FTP_DOWNLOAD_FOLDER_NAME "download" //下载目录
|
||||
|
||||
#define WATCH_NFC_MSG_TRANS_BACK "w_nfc_back"
|
||||
|
||||
#define WATCH_NFC_ID_MAX 10
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct nfc_msg_head_t {
|
||||
u16 nfc_file_id;
|
||||
u16 reserver;
|
||||
u32 dev_hanlder;
|
||||
u32 update_time;
|
||||
u8 nfc_file_name[6];
|
||||
u8 nfc_nick_name[24];
|
||||
u16 data_len; // crc + nfc_unique_id
|
||||
u16 crc;
|
||||
} nfc_msg_head;
|
||||
#pragma pack()
|
||||
|
||||
enum {
|
||||
NFC_DATA_INFO_SYNC_BEGIN,
|
||||
NFC_DATA_INFO_SYNC_END,
|
||||
NFC_DATA_INFO_MODIFY,
|
||||
NFC_DATA_INFO_DELETE,
|
||||
NFC_DATA_INFO_UPDATE,
|
||||
NFC_DATA_INFO_DEFAULT_ID,
|
||||
NFC_DATA_INFO_INSERT,
|
||||
NFC_DATA_INFO_INSERT_FINISH,
|
||||
};
|
||||
|
||||
enum {
|
||||
NFC_DATA_INFO_MODIFY_TIME,
|
||||
NFC_DATA_INFO_MODIFY_NICE_NAME,
|
||||
};
|
||||
|
||||
enum {
|
||||
NFC_DATA_INFO_DEFAULT_ID_GET,
|
||||
NFC_DATA_INFO_DEFAULT_ID_SET,
|
||||
NFC_DATA_INFO_DEFAULT_ID_NOTIFY,
|
||||
};
|
||||
|
||||
struct __nfc_file_msg {
|
||||
struct __dev *dev;
|
||||
u32 handler;
|
||||
u8 OpCode_SN;
|
||||
u8 op;
|
||||
};
|
||||
|
||||
static struct __nfc_file_msg *g_nfc_file_msg = NULL;
|
||||
static u32 g_nfc_file_index_record = 0;
|
||||
|
||||
static int get_nfc_file_prepare(u32 dev_handle)
|
||||
{
|
||||
char *logo = rcsp_browser_dev_remap(dev_handle);
|
||||
if (NULL == logo) {
|
||||
printf("g_nfc_file_msg logo is null");
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct __dev *dev = dev_manager_find_spec(logo, 0);
|
||||
if (NULL == dev) {
|
||||
printf("g_nfc_file_msg dev is null");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NULL == g_nfc_file_msg) {
|
||||
g_nfc_file_msg = zalloc(sizeof(struct __nfc_file_msg));
|
||||
if (NULL == g_nfc_file_msg) {
|
||||
printf("g_nfc_file_msg zalloc err\n");
|
||||
return -1;
|
||||
}
|
||||
g_nfc_file_msg->dev = dev;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nfc_id_default_get_from_vm(u8 *data, u16 data_len)
|
||||
{
|
||||
if (data_len != syscfg_read(VM_WATCH_DEFAULT_NFC_ID, data, data_len)) {
|
||||
printf("%s, read vm fail\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nfc_id_default_set_to_vm(u8 *data, u16 data_len)
|
||||
{
|
||||
u8 *tmp_data = zalloc(data_len);
|
||||
if (NULL == tmp_data) {
|
||||
printf("%s, no enough memory!!\n", __func__);
|
||||
goto __nfc_id_default_set_to_vm_end;
|
||||
}
|
||||
if (nfc_id_default_get_from_vm(tmp_data, data_len)) {
|
||||
memset(tmp_data, 0xff, data_len);
|
||||
}
|
||||
if (0 == memcmp(data, tmp_data, data_len)) {
|
||||
goto __nfc_id_default_set_to_vm_end;
|
||||
}
|
||||
syscfg_write(VM_WATCH_DEFAULT_NFC_ID, data, data_len);
|
||||
|
||||
__nfc_id_default_set_to_vm_end:
|
||||
if (tmp_data) {
|
||||
free(tmp_data);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void creat_file_path(char *path, char *root_path, const char *folder, u8 *name, u16 name_len)
|
||||
{
|
||||
strcat(path, root_path);
|
||||
if (folder) {
|
||||
strcat(path, folder);
|
||||
strcat(path, "/");
|
||||
}
|
||||
if (name) {
|
||||
memcpy(path + strlen(path), name, name_len);
|
||||
}
|
||||
}
|
||||
|
||||
static u32 creat_path_len(char *root_path, const char *folder, u8 *name, u16 name_len)
|
||||
{
|
||||
u32 len = (strlen(root_path) + strlen(folder) + name_len + 1);
|
||||
if (folder) {
|
||||
len += strlen("/");
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
static int get_nfc_file_path(u8 *path[], u8 file_index, u8 *file_name)
|
||||
{
|
||||
if (NULL == g_nfc_file_msg) {
|
||||
printf("%s, g_nfc_file_msg is null\n", __func__);
|
||||
goto __get_nfc_file_path_err;
|
||||
}
|
||||
|
||||
char *root_path = dev_manager_get_root_path(g_nfc_file_msg->dev);
|
||||
char *folder = NULL;
|
||||
if (RCSPDevMapSD1 == g_nfc_file_msg->handler) {
|
||||
folder = FTP_DOWNLOAD_FOLDER_NAME;
|
||||
}
|
||||
char tmp_name[] = "00.nfc";
|
||||
|
||||
if (*path) {
|
||||
free(*path);
|
||||
*path = NULL;
|
||||
}
|
||||
|
||||
if (NULL == *path) {
|
||||
if (file_name) {
|
||||
*path = zalloc(creat_path_len(root_path, folder, file_name, strlen(file_name) + 1));
|
||||
} else {
|
||||
*path = zalloc(creat_path_len(root_path, folder, tmp_name, strlen(tmp_name) + 1));
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL == *path) {
|
||||
printf("%s, no enough memory!!\n", __func__);
|
||||
goto __get_nfc_file_path_err;
|
||||
}
|
||||
if (file_index) {
|
||||
tmp_name[0] = (file_index / 10) + '0';
|
||||
tmp_name[1] = (file_index % 10) + '0';
|
||||
}
|
||||
|
||||
if (file_name) {
|
||||
creat_file_path(*path, root_path, folder, file_name, strlen(file_name));
|
||||
} else {
|
||||
creat_file_path(*path, root_path, folder, tmp_name, strlen(tmp_name));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
__get_nfc_file_path_err:
|
||||
if (*path) {
|
||||
free(*path);
|
||||
*path = NULL;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static u8 file_trans_back_response_send(u8 *data, u16 len, u8 dire, u8 OpCode_SN)
|
||||
{
|
||||
u8 ret = 0;
|
||||
switch (dire) {
|
||||
case 0:
|
||||
ret = JL_CMD_response_send(JL_OPCODE_SENSOR_NFC_FUNCTION_OPT, JL_PRO_STATUS_SUCCESS, OpCode_SN, data, len, 0, NULL);
|
||||
break;
|
||||
case 1:
|
||||
ret = JL_DATA_send(JL_OPCODE_DATA, JL_OPCODE_SENSOR_NFC_FUNCTION_OPT, data, len, JL_NOT_NEED_RESPOND, 0, NULL);
|
||||
break;
|
||||
case 2:
|
||||
ret = JL_CMD_send(JL_OPCODE_SENSOR_NFC_FUNCTION_OPT, data, len, JL_NOT_NEED_RESPOND, 0, NULL);
|
||||
break;
|
||||
case 0xFF:
|
||||
ret = JL_CMD_response_send(JL_OPCODE_SENSOR_NFC_FUNCTION_OPT, JL_PRO_STATUS_FAIL, OpCode_SN, data, len, 0, NULL);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nfc_file_read(char *path, u8 *buffer, u16 buffer_size, u8 offset, u8 *reason, u8 *file_index_record)
|
||||
{
|
||||
u8 ret = 0;
|
||||
FILE *file = fopen(path, "r");
|
||||
if (NULL == file) {
|
||||
printf("%s, file open fail\n", __func__);
|
||||
goto __nfc_file_read_end;
|
||||
}
|
||||
|
||||
u32 nfc_data_len = sizeof(nfc_msg_head) - 2;
|
||||
|
||||
if (nfc_data_len > buffer_size - offset) {
|
||||
ret = file_trans_back_response_send(buffer, offset, 1, g_nfc_file_msg->op);
|
||||
offset = 0;
|
||||
if (ret) {
|
||||
// 错误
|
||||
printf("%s, send data err : %d, %d", __func__, ret, offset);
|
||||
*reason = ret;
|
||||
goto __nfc_file_read_end;
|
||||
}
|
||||
}
|
||||
|
||||
nfc_msg_head *nfc_msg = (nfc_msg_head *)(buffer + offset);
|
||||
offset += fread(file, buffer + offset, nfc_data_len);
|
||||
|
||||
u8 crc_uuid_len = ((u8 *)&nfc_msg->data_len)[0] << 8 | ((u8 *)&nfc_msg->data_len)[1];
|
||||
|
||||
if (crc_uuid_len > buffer_size - offset) {
|
||||
ret = file_trans_back_response_send(buffer, offset, 1, g_nfc_file_msg->op);
|
||||
offset = 0;
|
||||
if (ret) {
|
||||
// 错误
|
||||
printf("%s, send data err : %d, %d", __func__, ret, offset);
|
||||
*reason = ret;
|
||||
goto __nfc_file_read_end;
|
||||
}
|
||||
}
|
||||
fseek(file, nfc_data_len, SEEK_SET);
|
||||
offset += fread(file, buffer + offset, crc_uuid_len);
|
||||
*file_index_record = 1;
|
||||
|
||||
__nfc_file_read_end:
|
||||
if (file) {
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
static void nfc_rcsp_file_trans_back_close(void)
|
||||
{
|
||||
task_kill(WATCH_NFC_MSG_TRANS_BACK);
|
||||
|
||||
if (g_nfc_file_msg) {
|
||||
free(g_nfc_file_msg);
|
||||
g_nfc_file_msg = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// 返回大于0是有默认值,等于0是没有默认值,-1是错误
|
||||
static u16 nfc_file_exist_check(u8 *file_index_record, u16 record_len)
|
||||
{
|
||||
// 读出nfc_id,如果读取失败则返回
|
||||
u16 tmp_nfc_id = 0;
|
||||
if (nfc_id_default_get_from_vm(&tmp_nfc_id, sizeof(tmp_nfc_id))) {
|
||||
return -1;
|
||||
}
|
||||
// 这种情况不可能也不应该出现
|
||||
if (tmp_nfc_id >= record_len) {
|
||||
printf("err : %s vaild !!\n");
|
||||
return -1;
|
||||
}
|
||||
// 判断file_index_record对用nfc_id的位置有没有值,有则返回
|
||||
if (file_index_record[tmp_nfc_id]) {
|
||||
return tmp_nfc_id + 1;
|
||||
}
|
||||
// 如果没有值,取最接近的上一个
|
||||
for (u16 i = tmp_nfc_id; i > 0; i--) {
|
||||
u16 tmp_index = i - 1;
|
||||
if (file_index_record[tmp_index]) {
|
||||
nfc_id_default_set_to_vm(&tmp_index, sizeof(tmp_index));
|
||||
return tmp_index + 1;
|
||||
}
|
||||
}
|
||||
// 如果还是没有,取最接近的下一个
|
||||
for (u16 i = tmp_nfc_id + 1; i < record_len; i++) {
|
||||
if (file_index_record[i]) {
|
||||
nfc_id_default_set_to_vm(&i, sizeof(i));
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
// 如果file_index_record里的值是全0,则把nfc_id对应的vm值设置为0
|
||||
tmp_nfc_id = 0;
|
||||
nfc_id_default_set_to_vm(&tmp_nfc_id, sizeof(tmp_nfc_id));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nfc_file_trans_back_task(void *p)
|
||||
{
|
||||
u8 ret = 0;
|
||||
u8 reason = 0;
|
||||
u8 offset = 0;
|
||||
u8 *path = NULL;
|
||||
// 回复当前命令
|
||||
u16 resp_data_len = JL_packet_get_tx_max_mtu() - 6;
|
||||
u8 *resp_data = zalloc(resp_data_len);
|
||||
u8 *file_index_record = zalloc(WATCH_NFC_ID_MAX);
|
||||
|
||||
if (NULL == resp_data || NULL == file_index_record) {
|
||||
reason = -1;
|
||||
file_trans_back_response_send(NULL, 0, (u8) - 1, g_nfc_file_msg->OpCode_SN);
|
||||
goto __nfc_file_trans_back_task_err;
|
||||
}
|
||||
|
||||
file_trans_back_response_send(&ret, sizeof(ret), 0, g_nfc_file_msg->OpCode_SN);
|
||||
|
||||
g_nfc_file_index_record = 0;
|
||||
for (u8 i = 0; i < WATCH_NFC_ID_MAX; i++) {
|
||||
// 读取文件:01~09.nfc
|
||||
if (get_nfc_file_path(&path, i, NULL)) {
|
||||
reason = -1;
|
||||
break;
|
||||
}
|
||||
offset = nfc_file_read(path, resp_data, resp_data_len, offset, &reason, file_index_record + i);
|
||||
if (reason) {
|
||||
break;
|
||||
}
|
||||
if (file_index_record[i]) {
|
||||
g_nfc_file_index_record |= BIT(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (offset) {
|
||||
// 发送
|
||||
if (file_trans_back_response_send(resp_data, offset, 1, g_nfc_file_msg->op)) {
|
||||
printf("%s, send data err : %d, %d", __func__, ret, offset);
|
||||
reason = -1;
|
||||
}
|
||||
}
|
||||
|
||||
nfc_file_exist_check(file_index_record, WATCH_NFC_ID_MAX);
|
||||
|
||||
__nfc_file_trans_back_task_err:
|
||||
if (path) {
|
||||
free(path);
|
||||
}
|
||||
|
||||
if (resp_data) {
|
||||
free(resp_data);
|
||||
}
|
||||
|
||||
if (file_index_record) {
|
||||
free(file_index_record);
|
||||
}
|
||||
|
||||
// 发送事件结束
|
||||
rcsp_msg_post(
|
||||
USER_MSG_RCSP_NFC_FILE_TRANS_BACK,
|
||||
5,
|
||||
(int)p,
|
||||
(int)g_nfc_file_msg->handler,
|
||||
NFC_DATA_INFO_SYNC_BEGIN,
|
||||
(int)reason, 0);
|
||||
|
||||
while (1) {
|
||||
os_time_dly(10);
|
||||
}
|
||||
}
|
||||
|
||||
static int nfc_data_msg_modify(void *priv, u8 *data, u16 len)
|
||||
{
|
||||
u8 ret = 0;
|
||||
u8 offset = 0;
|
||||
u8 *path = NULL;
|
||||
FILE *file = NULL;
|
||||
u8 file_index = data[offset++] * 10 + data[offset++];
|
||||
if (get_nfc_file_path(&path, file_index, NULL)) {
|
||||
ret = -1;
|
||||
goto __nfc_data_msg_modify_end;
|
||||
}
|
||||
file = fopen(path, "r");
|
||||
if (file) {
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
} else {
|
||||
ret = -1;
|
||||
printf("%s, file open err\n", __func__);
|
||||
goto __nfc_data_msg_modify_end;
|
||||
}
|
||||
|
||||
file = fopen(path, "w+");
|
||||
if (NULL == file) {
|
||||
ret = -1;
|
||||
printf("%s, file open err\n", __func__);
|
||||
goto __nfc_data_msg_modify_end;
|
||||
}
|
||||
|
||||
nfc_msg_head nfc_msg = {0};
|
||||
fread(file, &nfc_msg, sizeof(nfc_msg));
|
||||
|
||||
u32 mask = data[offset++] << 24 | data[offset++] << 16 | data[offset++] << 8 | data[offset++];
|
||||
|
||||
// 假如是时间戳
|
||||
if (mask & BIT(NFC_DATA_INFO_MODIFY_TIME)) {
|
||||
memcpy(&nfc_msg.update_time, data + offset, sizeof(nfc_msg.update_time));
|
||||
offset += sizeof(nfc_msg.update_time);
|
||||
}
|
||||
|
||||
// 假如是别名
|
||||
if (mask & BIT(NFC_DATA_INFO_MODIFY_NICE_NAME)) {
|
||||
if (len - offset > sizeof(nfc_msg.nfc_nick_name)) {
|
||||
printf("err : remote nick name len is vaild\n");
|
||||
ret = -1;
|
||||
goto __nfc_data_msg_modify_end;
|
||||
}
|
||||
memset(nfc_msg.nfc_nick_name, 0, sizeof(nfc_msg.nfc_nick_name));
|
||||
memcpy(nfc_msg.nfc_nick_name, data + offset, len - offset);
|
||||
}
|
||||
|
||||
int nfc_total_len = flen(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
fwrite(file, &nfc_msg, sizeof(nfc_msg));
|
||||
fseek(file, nfc_total_len, SEEK_SET);
|
||||
|
||||
__nfc_data_msg_modify_end:
|
||||
if (path) {
|
||||
free(path);
|
||||
path = NULL;
|
||||
}
|
||||
|
||||
if (file) {
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
}
|
||||
|
||||
rcsp_msg_post(
|
||||
USER_MSG_RCSP_NFC_FILE_TRANS_BACK,
|
||||
5,
|
||||
(int)priv,
|
||||
(int)g_nfc_file_msg->handler,
|
||||
NFC_DATA_INFO_MODIFY,
|
||||
(int)ret,
|
||||
(int)file_index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nfc_data_msg_default_id_get(u16 *default_nfc_id)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 *file_index_record = zalloc(WATCH_NFC_ID_MAX);
|
||||
if (NULL == file_index_record) {
|
||||
printf("%s, no enough memory!!\n", __func__);
|
||||
ret = -1;
|
||||
goto __nfc_data_msg_default_id_get_end;
|
||||
}
|
||||
|
||||
for (u8 i = 0; i < WATCH_NFC_ID_MAX && i < sizeof(g_nfc_file_index_record); i++) {
|
||||
file_index_record[i] = !!(g_nfc_file_index_record & BIT(i));
|
||||
}
|
||||
u16 tmp_nfc_id = nfc_file_exist_check(file_index_record, WATCH_NFC_ID_MAX);
|
||||
if (0 == tmp_nfc_id || (u16) - 1 == tmp_nfc_id) {
|
||||
ret = -1;
|
||||
goto __nfc_data_msg_default_id_get_end;
|
||||
}
|
||||
*default_nfc_id = tmp_nfc_id - 1;
|
||||
|
||||
__nfc_data_msg_default_id_get_end:
|
||||
if (file_index_record) {
|
||||
free(file_index_record);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nfc_data_msg_delete(void *priv, u8 *data, u16 len)
|
||||
{
|
||||
u8 ret = 0;
|
||||
u8 offset = 0;
|
||||
u8 file_index = data[offset++] * 10 + data[offset++];
|
||||
u8 *path = NULL;
|
||||
FILE *file = NULL;
|
||||
if (get_nfc_file_path(&path, file_index, NULL)) {
|
||||
ret = -1;
|
||||
goto __nfc_data_msg_delete_end;
|
||||
}
|
||||
|
||||
if ((file = fopen(path, "r"))) {
|
||||
if (fdelete(file)) {
|
||||
//错误
|
||||
printf("%s, delete fail\n", __func__);
|
||||
ret = -1;
|
||||
goto __nfc_data_msg_delete_end;
|
||||
}
|
||||
file = NULL;
|
||||
g_nfc_file_index_record &= ~BIT(file_index);
|
||||
}
|
||||
|
||||
__nfc_data_msg_delete_end:
|
||||
if (path) {
|
||||
free(path);
|
||||
path = NULL;
|
||||
}
|
||||
|
||||
if (file) {
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
}
|
||||
|
||||
rcsp_msg_post(
|
||||
USER_MSG_RCSP_NFC_FILE_TRANS_BACK,
|
||||
5,
|
||||
(int)priv,
|
||||
(int)g_nfc_file_msg->handler,
|
||||
NFC_DATA_INFO_DELETE,
|
||||
(int)ret,
|
||||
(int)file_index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nfc_data_msg_insert(void *priv, u8 *data, u16 len)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 offset = 0;
|
||||
u8 *path = NULL;
|
||||
FILE *file = NULL;
|
||||
u8 file_index = 0;
|
||||
// 可以用于判断FLASH/SD卡容量是否足够
|
||||
u32 file_size = data[offset++] << 24 | data[offset++] << 16 | data[offset++] << 8 | data[offset++];
|
||||
u8 *nfc_file_name = zalloc(len - offset + 1);
|
||||
if (NULL == nfc_file_name) {
|
||||
printf("%s, no enough memory!!\n", __func__);
|
||||
ret = -1;
|
||||
goto __nfc_data_msg_insert_end;
|
||||
}
|
||||
memcpy(nfc_file_name, data + offset, len - offset);
|
||||
file_index = (nfc_file_name[0] - '0') * 10 + nfc_file_name[1] - '0';
|
||||
ret = get_nfc_file_path(&path, 0, nfc_file_name);
|
||||
if (ret) {
|
||||
goto __nfc_data_msg_insert_end;
|
||||
}
|
||||
|
||||
if ((file = fopen(path, "r"))) {
|
||||
if (fdelete(file)) {
|
||||
printf("%s, delete fail\n", __func__);
|
||||
ret = -1;
|
||||
goto __nfc_data_msg_insert_end;
|
||||
}
|
||||
file = NULL;
|
||||
}
|
||||
|
||||
__nfc_data_msg_insert_end:
|
||||
if (file) {
|
||||
fclose(file);
|
||||
}
|
||||
if (path) {
|
||||
free(path);
|
||||
}
|
||||
if (nfc_file_name) {
|
||||
free(nfc_file_name);
|
||||
}
|
||||
|
||||
rcsp_msg_post(
|
||||
USER_MSG_RCSP_NFC_FILE_TRANS_BACK,
|
||||
5,
|
||||
(int)priv,
|
||||
(int)g_nfc_file_msg->handler,
|
||||
NFC_DATA_INFO_INSERT,
|
||||
(int)ret,
|
||||
(int)file_index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nfc_data_msg_insert_finish(void *priv, u8 *data, u16 len)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 *path = NULL;
|
||||
FILE *file = NULL;
|
||||
u16 nfc_id = 0;
|
||||
u8 *nfc_file_name = zalloc(len + 1);
|
||||
if (NULL == nfc_file_name) {
|
||||
printf("%s, no enough memory!!\n", __func__);
|
||||
ret = -1;
|
||||
goto __nfc_data_msg_insert_finish_end;
|
||||
}
|
||||
memcpy(nfc_file_name, data, len);
|
||||
ret = get_nfc_file_path(&path, 0, nfc_file_name);
|
||||
if (ret) {
|
||||
goto __nfc_data_msg_insert_finish_end;
|
||||
}
|
||||
|
||||
nfc_id = (nfc_file_name[0] - '0') * 10 + (nfc_file_name[1] - '0');
|
||||
if ((file = fopen(path, "r"))) {
|
||||
// 读出数据
|
||||
// 把数据写给nfc外设
|
||||
g_nfc_file_index_record |= BIT(nfc_id);
|
||||
}
|
||||
|
||||
__nfc_data_msg_insert_finish_end:
|
||||
if (file) {
|
||||
fclose(file);
|
||||
}
|
||||
if (path) {
|
||||
free(path);
|
||||
}
|
||||
if (nfc_file_name) {
|
||||
free(nfc_file_name);
|
||||
}
|
||||
rcsp_msg_post(
|
||||
USER_MSG_RCSP_NFC_FILE_TRANS_BACK,
|
||||
5,
|
||||
(int)priv,
|
||||
(int)g_nfc_file_msg->handler,
|
||||
NFC_DATA_INFO_INSERT_FINISH,
|
||||
(int)ret,
|
||||
(int)nfc_id);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nfc_id_default_opt(void *priv, u8 *data, u16 len, u8 OpCode_SN)
|
||||
{
|
||||
u8 offset = 0;
|
||||
u8 flag = data[offset++];
|
||||
u8 resp_data[3] = {0};
|
||||
u8 resp_data_len = 0;
|
||||
u8 file_index = 0;
|
||||
u8 op = NFC_DATA_INFO_DEFAULT_ID;
|
||||
memcpy(resp_data + 1, data + offset, 2);
|
||||
switch (flag) {
|
||||
case NFC_DATA_INFO_DEFAULT_ID_GET:
|
||||
printf("NFC_DATA_INFO_DEFAULT_ID_GET\n");
|
||||
// 把id写入vm
|
||||
u16 default_nfc_id = 0;
|
||||
if (nfc_id_default_get_from_vm(&default_nfc_id, sizeof(default_nfc_id))) {
|
||||
resp_data[0] = -1;
|
||||
break;
|
||||
}
|
||||
resp_data[1] = ((u8 *)&default_nfc_id)[1];
|
||||
resp_data[2] = ((u8 *)&default_nfc_id)[0];
|
||||
resp_data_len = 3;
|
||||
op = -1;
|
||||
file_trans_back_response_send(resp_data, resp_data_len, 0, OpCode_SN);
|
||||
break;
|
||||
case NFC_DATA_INFO_DEFAULT_ID_SET:
|
||||
printf("NFC_DATA_INFO_DEFAULT_ID_SET\n");
|
||||
u16 nfc_id = data[offset++] << 8 | data[offset++];
|
||||
if (nfc_id > WATCH_NFC_ID_MAX - 1) {
|
||||
printf("%s, nfc id is vaild\n", __func__);
|
||||
resp_data[0] = -1;
|
||||
}
|
||||
nfc_id_default_set_to_vm(&nfc_id, sizeof(nfc_id));
|
||||
resp_data_len = 1;
|
||||
file_index = nfc_id;
|
||||
break;
|
||||
}
|
||||
rcsp_msg_post(
|
||||
USER_MSG_RCSP_NFC_FILE_TRANS_BACK,
|
||||
5,
|
||||
(int)priv,
|
||||
(int)g_nfc_file_msg->handler,
|
||||
op,
|
||||
(int)resp_data[0],
|
||||
(int)file_index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nfc_data_opt_check(u8 OpCode, u8 OpCode_SN, u8 *data, u16 len)
|
||||
{
|
||||
u8 offset = 0;
|
||||
u32 handle = data[offset++] << 24 | data[offset++] << 16 | data[offset++] << 8 | data[offset++];
|
||||
int ret = get_nfc_file_prepare(handle);
|
||||
if (0 == ret) {
|
||||
g_nfc_file_msg->op = OpCode;
|
||||
g_nfc_file_msg->OpCode_SN = OpCode_SN;
|
||||
g_nfc_file_msg->handler = handle;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nfc_data_opt(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len)
|
||||
{
|
||||
u8 op = 0;
|
||||
u8 offset = 0;
|
||||
int ret = nfc_data_opt_check(OpCode, OpCode_SN, data + offset, len - offset);
|
||||
if (ret) {
|
||||
goto __nfc_data_opt_end;
|
||||
}
|
||||
offset += 4;
|
||||
op = data[offset++];
|
||||
switch (op) {
|
||||
case NFC_DATA_INFO_SYNC_BEGIN:
|
||||
if (task_create(nfc_file_trans_back_task, priv, WATCH_NFC_MSG_TRANS_BACK)) {
|
||||
ret = -1;
|
||||
nfc_rcsp_file_trans_back_close();
|
||||
goto __nfc_data_opt_end;
|
||||
}
|
||||
break;
|
||||
case NFC_DATA_INFO_MODIFY:
|
||||
nfc_data_msg_modify(priv, data + offset, len - offset);
|
||||
break;
|
||||
case NFC_DATA_INFO_DELETE:
|
||||
nfc_data_msg_delete(priv, data + offset, len - offset);
|
||||
break;
|
||||
case NFC_DATA_INFO_DEFAULT_ID:
|
||||
nfc_id_default_opt(priv, data + offset, len - offset, OpCode_SN);
|
||||
break;
|
||||
case NFC_DATA_INFO_INSERT:
|
||||
nfc_data_msg_insert(priv, data + offset, len - offset);
|
||||
break;
|
||||
case NFC_DATA_INFO_INSERT_FINISH:
|
||||
nfc_data_msg_insert_finish(priv, data + offset, len - offset);
|
||||
break;
|
||||
}
|
||||
|
||||
__nfc_data_opt_end:
|
||||
if (ret) {
|
||||
JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, (u8 *)&ret, 1, 0, NULL);
|
||||
file_trans_back_response_send(&ret, 1, 0, OpCode_SN);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int nfc_id_default_notify(u32 devHeadler, u16 nfc_id)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 resp_data[] = {((u8 *)&devHeadler)[3], ((u8 *)&devHeadler)[2], ((u8 *)&devHeadler)[1], ((u8 *)&devHeadler)[0], NFC_DATA_INFO_DEFAULT_ID, NFC_DATA_INFO_DEFAULT_ID_NOTIFY, ((u8 *)&nfc_id)[1], ((u8 *)&nfc_id)[0]};
|
||||
if (nfc_id > WATCH_NFC_ID_MAX - 1) {
|
||||
ret = -1;
|
||||
goto __nfc_id_default_notify_end;
|
||||
}
|
||||
|
||||
// 从vm中读取nfc_id
|
||||
u16 default_nfc_id = -1;
|
||||
ret = file_trans_back_response_send(resp_data, sizeof(resp_data), 2, 0);
|
||||
nfc_id_default_set_to_vm(&nfc_id, sizeof(nfc_id));
|
||||
__nfc_id_default_notify_end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void nfc_peripherals_deal(u32 handler, u8 file_index)
|
||||
{
|
||||
u8 *path = NULL;
|
||||
u8 *nfc_data = NULL;
|
||||
FILE *file = NULL;
|
||||
if (get_nfc_file_path(&path, file_index, NULL)) {
|
||||
goto __nfc_peripherals_deal_end;
|
||||
}
|
||||
file = fopen(path, "r");
|
||||
if (NULL == file) {
|
||||
printf("%s, file open fail\n", __func__);
|
||||
goto __nfc_peripherals_deal_end;
|
||||
}
|
||||
// 获取当前文件对应的数据
|
||||
nfc_msg_head nfc_msg = {0};
|
||||
fread(file, (u8 *)&nfc_msg, sizeof(nfc_msg));
|
||||
int nfc_id_crc_len = ((u8 *)&nfc_msg.data_len)[0] << 8 | ((u8 *)&nfc_msg.data_len)[1];
|
||||
int nfc_data_len = flen(file);
|
||||
nfc_data_len = nfc_data_len - (sizeof(nfc_msg) - 2) - nfc_id_crc_len;
|
||||
if (nfc_data_len <= 0) {
|
||||
goto __nfc_peripherals_deal_end;
|
||||
}
|
||||
|
||||
nfc_data = zalloc(nfc_data_len);
|
||||
if (NULL == nfc_data) {
|
||||
printf("%s, file open fail\n", __func__);
|
||||
goto __nfc_peripherals_deal_end;
|
||||
}
|
||||
|
||||
fseek(file, (sizeof(nfc_msg) - 2) + nfc_id_crc_len, SEEK_SET);
|
||||
fread(file, nfc_data, nfc_data_len);
|
||||
// 把数据写到nfc外设中
|
||||
|
||||
__nfc_peripherals_deal_end:
|
||||
if (path) {
|
||||
free(path);
|
||||
}
|
||||
if (nfc_data) {
|
||||
free(nfc_data);
|
||||
}
|
||||
if (file) {
|
||||
fclose(file);
|
||||
}
|
||||
}
|
||||
|
||||
void nfc_file_trans_back_end(void *priv, u32 handler, u8 op, int result, int param)
|
||||
{
|
||||
u8 ret = (u8)result;
|
||||
u8 file_index = (u8) param;
|
||||
if (NFC_DATA_INFO_SYNC_BEGIN != op && (u8) - 1 != op) {
|
||||
file_trans_back_response_send(&ret, sizeof(ret), 0, g_nfc_file_msg->OpCode_SN);
|
||||
}
|
||||
|
||||
switch (op) {
|
||||
case NFC_DATA_INFO_SYNC_BEGIN:
|
||||
printf("NFC_DATA_INFO_SYNC_BEGIN end\n");
|
||||
u8 resp_data[2] = {NFC_DATA_INFO_SYNC_END, ret};
|
||||
file_trans_back_response_send(resp_data, sizeof(resp_data), 2, 0);
|
||||
break;
|
||||
case NFC_DATA_INFO_MODIFY:
|
||||
printf("NFC_DATA_INFO_MODIFY end\n");
|
||||
break;
|
||||
case NFC_DATA_INFO_DELETE:
|
||||
printf("NFC_DATA_INFO_DELETE end\n");
|
||||
// 获取默认id
|
||||
u16 default_nfc_id = 0;
|
||||
if (0 == ret && 0 == nfc_data_msg_default_id_get(&default_nfc_id)) {
|
||||
nfc_id_default_notify(handler, default_nfc_id);
|
||||
}
|
||||
break;
|
||||
case NFC_DATA_INFO_DEFAULT_ID:
|
||||
printf("NFC_DATA_INFO_DEFAULT_ID end\n");
|
||||
if (0 == ret) {
|
||||
// 写入外设
|
||||
nfc_peripherals_deal(handler, file_index);
|
||||
}
|
||||
break;
|
||||
case NFC_DATA_INFO_INSERT:
|
||||
printf("NFC_DATA_INFO_INSERT end\n");
|
||||
// 插入开始,可以做对应得初始化动作
|
||||
break;
|
||||
case NFC_DATA_INFO_INSERT_FINISH:
|
||||
printf("NFC_DATA_INFO_INSERT_FINISH end\n");
|
||||
// 插入结束,这个时候已经存在文件,可以读出来写入外设
|
||||
if (0 == ret) {
|
||||
// 写入外设
|
||||
}
|
||||
break;
|
||||
}
|
||||
nfc_rcsp_file_trans_back_close();
|
||||
}
|
||||
|
||||
int JL_rcsp_nfc_data_funciton(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len)
|
||||
{
|
||||
int ret = -1;
|
||||
switch (OpCode) {
|
||||
case JL_OPCODE_SENSOR_NFC_FUNCTION_OPT:
|
||||
ret = 0;
|
||||
nfc_data_opt(priv, OpCode, OpCode_SN, data, len);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int JL_rcsp_nfc_data_funciton(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
void nfc_file_trans_back_end(void *priv, u32 handler, u8 op, int result, int param)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int nfc_id_default_notify(u32 devHeadler, u16 nfc_id)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
#ifndef __RCSP_NFC_DATA_FUNC_H__
|
||||
#define __RCSP_NFC_DATA_FUNC_H__
|
||||
|
||||
#include "typedef.h"
|
||||
#include "app_config.h"
|
||||
|
||||
int JL_rcsp_nfc_data_funciton(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len);
|
||||
int nfc_id_default_notify(u32 devHeadler, u16 nfc_id);
|
||||
void nfc_file_trans_back_end(void *priv, u32 handler, u8 op, int result, int param);
|
||||
|
||||
#endif
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".sensor_log_notify.data.bss")
|
||||
#pragma data_seg(".sensor_log_notify.data")
|
||||
#pragma const_seg(".sensor_log_notify.text.const")
|
||||
#pragma code_seg(".sensor_log_notify.text")
|
||||
#endif
|
||||
#include "rcsp_functions/rcsp_config.h"
|
||||
#include "sensor_log_notify.h"
|
||||
#include "JL_rcsp_api.h"
|
||||
#include "JL_rcsp_protocol.h"
|
||||
|
||||
#if (RCSP_MODE && JL_RCSP_SENSORS_DATA_OPT)
|
||||
#define FUNCTION_UPDATE_MAX_LEN (256)
|
||||
|
||||
static int pedometer_data_get(u8 *data, u16 max_len)
|
||||
{
|
||||
int rlen = 0;
|
||||
#if TCFG_GSENSOR_ENABLE
|
||||
extern int gSensor_read_data(u8 * buf[]);
|
||||
u8 *tmp_data = NULL;
|
||||
rlen = gSensor_read_data(&tmp_data);
|
||||
if (rlen > max_len) {
|
||||
rlen = 0;
|
||||
} else {
|
||||
memcpy(data, tmp_data, rlen);
|
||||
}
|
||||
#endif
|
||||
return rlen;
|
||||
}
|
||||
|
||||
static void sensors_log_nofity_trigger(void *priv, u8 OpCode, u8 *data, u16 len)
|
||||
{
|
||||
u8 ret = 0;
|
||||
u32 mask = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
|
||||
u8 *resp_data = zalloc(FUNCTION_UPDATE_MAX_LEN);
|
||||
if (NULL == resp_data) {
|
||||
ret = -1;
|
||||
printf("%s, no ram err !!!\n", __func__);
|
||||
goto __sensors_log_nofity_trigger_end;
|
||||
}
|
||||
|
||||
if (mask & BIT(SENSOR_LOG_ACCELERATION)) {
|
||||
// 触发加速度
|
||||
u16 data_len = 0;
|
||||
resp_data[data_len++] = 0xa5;
|
||||
watch_sensor_log_notify(SENSOR_LOG_ACCELERATION, resp_data, data_len);
|
||||
}
|
||||
|
||||
if (mask & BIT(SENSOR_LOG_HEART_RATE_BLOOD_OXYGEN)) {
|
||||
// 触发血氧
|
||||
u16 data_len = 0;
|
||||
resp_data[data_len++] = 0x5a;
|
||||
watch_sensor_log_notify(SENSOR_LOG_HEART_RATE_BLOOD_OXYGEN, resp_data, data_len);
|
||||
}
|
||||
|
||||
if (mask & BIT(SENSOR_LOG_PEDOMETER)) {
|
||||
u16 data_len = 0;
|
||||
data_len = pedometer_data_get(resp_data, len);
|
||||
watch_sensor_log_notify(SENSOR_LOG_PEDOMETER, resp_data, data_len);
|
||||
}
|
||||
|
||||
__sensors_log_nofity_trigger_end:
|
||||
if (resp_data) {
|
||||
free(resp_data);
|
||||
}
|
||||
}
|
||||
|
||||
int JL_rcsp_sensors_log_notify(void *priv, u8 OpCode, u8 *data, u16 len)
|
||||
{
|
||||
int ret = -1;
|
||||
switch (OpCode) {
|
||||
case JL_OPCODE_SENSOR_LOG_DATA_AUTO_UPDATE:
|
||||
ret = 0;
|
||||
sensors_log_nofity_trigger(priv, OpCode, data, len);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void watch_sensor_log_notify(u8 type, u8 *data, u16 data_len)
|
||||
{
|
||||
struct RcspModel *rcspModel = rcsp_handle_get();
|
||||
if (rcspModel == NULL || 0 == JL_rcsp_get_auth_flag()) {
|
||||
return ;
|
||||
}
|
||||
|
||||
u8 *resp_data = zalloc(FUNCTION_UPDATE_MAX_LEN);
|
||||
if (NULL == resp_data) {
|
||||
printf("%s, no ram err !!!\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
for (u16 offset = 0, rlen = 0; offset < data_len; offset += FUNCTION_UPDATE_MAX_LEN - 1) {
|
||||
rlen = (data_len - offset) > (FUNCTION_UPDATE_MAX_LEN - 1) ? (FUNCTION_UPDATE_MAX_LEN - 1) : (data_len - offset);
|
||||
u32 mask = BIT(type);
|
||||
resp_data[0] = ((u8 *)&mask)[3];
|
||||
resp_data[1] = ((u8 *)&mask)[2];
|
||||
resp_data[2] = ((u8 *)&mask)[1];
|
||||
resp_data[3] = ((u8 *)&mask)[0];
|
||||
memcpy(resp_data + 4, data + offset, rlen);
|
||||
if (JL_CMD_send(JL_OPCODE_SENSOR_LOG_DATA_AUTO_UPDATE, resp_data, rlen + 4, JL_NOT_NEED_RESPOND, 0, NULL)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (resp_data) {
|
||||
free(resp_data);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int JL_rcsp_sensors_log_notify(void *priv, u8 OpCode, u8 *data, u16 len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void watch_sensor_log_notify(u8 type, u8 *data, u16 data_len)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
#ifndef __RCSP_SENSOR_LOG_NOTIFY_H__
|
||||
#define __RCSP_SENSOR_LOG_NOTIFY_H__
|
||||
|
||||
#include "typedef.h"
|
||||
#include "app_config.h"
|
||||
|
||||
enum {
|
||||
SENSOR_LOG_ACCELERATION,
|
||||
SENSOR_LOG_HEART_RATE_BLOOD_OXYGEN,
|
||||
SENSOR_LOG_PEDOMETER,
|
||||
};
|
||||
|
||||
void watch_sensor_log_notify(u8 type, u8 *data, u16 data_len);
|
||||
int JL_rcsp_sensors_log_notify(void *priv, u8 OpCode, u8 *data, u16 len);
|
||||
|
||||
#endif
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".sensors_data_opt.data.bss")
|
||||
#pragma data_seg(".sensors_data_opt.data")
|
||||
#pragma const_seg(".sensors_data_opt.text.const")
|
||||
#pragma code_seg(".sensors_data_opt.text")
|
||||
#endif
|
||||
#include "sensors_data_opt.h"
|
||||
#include "sport_data_func.h"
|
||||
#include "sport_info_sync.h"
|
||||
#include "nfc_data_opt.h"
|
||||
#include "sport_info_opt.h"
|
||||
|
||||
#if (RCSP_MODE && JL_RCSP_SENSORS_DATA_OPT)
|
||||
int JL_rcsp_sensors_data_opt(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len)
|
||||
{
|
||||
if (0 == JL_rcsp_sports_data_funciton(priv, OpCode, OpCode_SN, data, len)) {
|
||||
return 0;
|
||||
}
|
||||
if (0 == JL_rcsp_nfc_data_funciton(priv, OpCode, OpCode_SN, data, len)) {
|
||||
return 0;
|
||||
}
|
||||
if (0 == JL_rcsp_sports_info_funciton(priv, OpCode, OpCode_SN, data, len)) {
|
||||
return 0;
|
||||
}
|
||||
if (0 == JL_rcsp_sports_info_sync_funciton(priv, OpCode, OpCode_SN, data, len)) {
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
#ifndef __RCSP_SENSORS_DATA_OPT_H__
|
||||
#define __RCSP_SENSORS_DATA_OPT_H__
|
||||
|
||||
#include "typedef.h"
|
||||
#include "app_config.h"
|
||||
|
||||
int JL_rcsp_sensors_data_opt(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len);
|
||||
|
||||
#endif
|
||||
+431
@@ -0,0 +1,431 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".sport_data_func.data.bss")
|
||||
#pragma data_seg(".sport_data_func.data")
|
||||
#pragma const_seg(".sport_data_func.text.const")
|
||||
#pragma code_seg(".sport_data_func.text")
|
||||
#endif
|
||||
#include "rcsp_config.h"
|
||||
#include "sport_data_func.h"
|
||||
#include "rcsp_event.h"
|
||||
#include "rcsp_manage.h"
|
||||
#include "rcsp_extra_flash_opt.h"
|
||||
#include "JL_rcsp_protocol.h"
|
||||
#include "JL_rcsp_api.h"
|
||||
|
||||
#if (RCSP_MODE && JL_RCSP_SENSORS_DATA_OPT)
|
||||
#define SPROT_DATA_PROTOCOL_VERSION 0
|
||||
#define FUNCTION_UPDATE_MAX_LEN (256 - 32) // 预留32个byte放别的突发的命令
|
||||
|
||||
//#define SPORT_DATA_TIMED_NOFIFYCATION_TIME (5 * 60 * 1000) // 5min
|
||||
#define SPORT_DATA_TIMED_NOFIFYCATION_TIME 0 // 默认关闭连上app后定时发送运动数据
|
||||
|
||||
#define ASSET_CMD_DATA_LEN(len, limit) \
|
||||
do{ \
|
||||
if(len >= limit){ \
|
||||
}else{ \
|
||||
return ; \
|
||||
}\
|
||||
}while(0);
|
||||
|
||||
|
||||
static rcsp_sport_data_opt_t *g_rcsp_sport_data_opt = NULL;
|
||||
#define __this g_rcsp_sport_data_opt
|
||||
|
||||
static OS_SEM g_sport_data_get_sem;
|
||||
static int sport_data_func_multi_pack_update(void *priv, u8 *resp_pack, u16 resp_pack_len, sport_resp_data *sport_data, u16 sport_data_len);
|
||||
extern u8 get_ota_status();
|
||||
extern u8 rcsp_eflash_update_flag_get(void);
|
||||
static u32 rcsp_sport_data_function_get(void *priv, u32 mask, u8 *sub_mask, u8 *buf, u16 buf_size)
|
||||
{
|
||||
printf("rcsp_sport_data_function_get, mask = %x\n", mask);
|
||||
struct RcspModel *rcspModel = (struct RcspModel *)priv;
|
||||
u32 offset = 0;
|
||||
u32 record_len = 0;
|
||||
sport_attr_get_func func = NULL;
|
||||
sport_resp_data *resp_data = (sport_resp_data *)zalloc(SPORTS_DATA_FUNC_ATTR_TYPE_GET_MAX * sizeof(sport_resp_data));
|
||||
for (u8 i = 0, j = 0; i < SPORTS_DATA_FUNC_ATTR_TYPE_GET_MAX; i++) {
|
||||
if (mask & BIT(i)) {
|
||||
rcspModel->priv = (void *)(resp_data + i);
|
||||
if (i >= __this->sport_data_get_tab_num) {
|
||||
continue;
|
||||
}
|
||||
func = __this->sport_data_get_tab[i];
|
||||
if (func) {
|
||||
offset += func(priv, i, sub_mask[j++], buf, buf_size, offset);
|
||||
}
|
||||
if (resp_data[i].resp_data_len) {
|
||||
record_len += resp_data[i].resp_data_len + 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rcspModel->err_code) {
|
||||
sport_data_func_multi_pack_update(priv, buf, buf_size, resp_data, record_len);
|
||||
offset = 0;
|
||||
}
|
||||
for (u8 i = 0; i < SPORTS_DATA_FUNC_ATTR_TYPE_GET_MAX; i++) {
|
||||
if (resp_data[i].call_back) {
|
||||
resp_data[i].call_back(resp_data[i].priv);
|
||||
}
|
||||
}
|
||||
if (resp_data) {
|
||||
free(resp_data);
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
static bool rcsp_data_function_set(void *priv, u8 function, u8 *data, u16 len)
|
||||
{
|
||||
printf("rcsp_data_function_set\n");
|
||||
struct RcspModel *rcspModel = (struct RcspModel *)priv;
|
||||
if (rcspModel == NULL) {
|
||||
return false;
|
||||
}
|
||||
put_buf(data, len);
|
||||
if (function >= __this->sport_data_set_tab_num) {
|
||||
return false;
|
||||
}
|
||||
attr_set_func func = __this->sport_data_set_tab[function];
|
||||
if (func) {
|
||||
func(priv, function, data, len, 0, NULL);
|
||||
}
|
||||
if (rcspModel->err_code) {
|
||||
rcspModel->err_code = 0;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void get_sport_data_info(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len)
|
||||
{
|
||||
struct RcspModel *rcspModel = (struct RcspModel *)priv;
|
||||
if (rcspModel == NULL) {
|
||||
return;
|
||||
}
|
||||
// 加锁
|
||||
/* sport_data_func_get_prepare_deal(); */
|
||||
rcspModel->OpCode_record = OpCode;
|
||||
rcspModel->OpCode_SN_record = OpCode_SN;
|
||||
u8 offset = 0;
|
||||
u32 mask = data[offset + 0] << 24 | data[offset + 1] << 16 | data[offset + 2] << 8 | data[offset + 3];
|
||||
offset += 4;
|
||||
u8 version = data[offset++];
|
||||
u8 *sub_mask = data + offset;
|
||||
u8 *resp = zalloc(TARGET_FEATURE_RESP_BUF_SIZE);
|
||||
u32 rlen = rcsp_sport_data_function_get(priv, mask, sub_mask, resp + 2, TARGET_FEATURE_RESP_BUF_SIZE - 2);
|
||||
resp[0] = (rlen == 0);
|
||||
resp[1] = 1; // 附带response data
|
||||
if (rcspModel->err_code) {
|
||||
rcspModel->err_code = 0;
|
||||
} else {
|
||||
JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, resp, (u16)rlen + 2, 0, NULL);
|
||||
}
|
||||
if (resp) {
|
||||
free(resp);
|
||||
}
|
||||
/* sport_data_func_get_finish_deal(); */
|
||||
}
|
||||
|
||||
static void set_sport_data_info(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len)
|
||||
{
|
||||
u8 offset = 0;
|
||||
u8 function = data[offset++];
|
||||
u8 version = data[offset++];
|
||||
bool ret = rcsp_data_function_set(priv, function, data + offset, len - offset);
|
||||
u8 resp_data[2] = {function, ret};
|
||||
JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, resp_data, sizeof(resp_data), 0, NULL);
|
||||
}
|
||||
|
||||
void sport_data_func_update(u32 mask, u8 *sub_mask)
|
||||
{
|
||||
struct RcspModel *rcspModel = rcsp_handle_get();
|
||||
//ota不响应运动数据
|
||||
if (rcspModel == NULL || 0 == JL_rcsp_get_auth_flag() || rcsp_eflash_update_flag_get() || get_ota_status()) {
|
||||
return ;
|
||||
}
|
||||
// 加锁
|
||||
/* sport_data_func_get_prepare_deal(); */
|
||||
u32 rlen = 0;
|
||||
u8 *buf = zalloc(FUNCTION_UPDATE_MAX_LEN);
|
||||
if (NULL == buf) {
|
||||
printf("%s, no ram err!!\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
buf[0] = SPROT_DATA_PROTOCOL_VERSION; // version
|
||||
buf[1] = 1; // package count
|
||||
buf[2] = 0; // package id
|
||||
|
||||
rcspModel->OpCode_record = JL_OPCODE_SPORTS_DATA_INFO_AUTO_UPDATE;
|
||||
rlen = rcsp_sport_data_function_get((void *)rcspModel, mask, sub_mask, buf + 3, FUNCTION_UPDATE_MAX_LEN - 3);
|
||||
|
||||
if (rlen) {
|
||||
JL_CMD_send(JL_OPCODE_SPORTS_DATA_INFO_AUTO_UPDATE, buf, rlen + 3, JL_NOT_NEED_RESPOND, 0, NULL);
|
||||
}
|
||||
|
||||
if (buf) {
|
||||
free(buf);
|
||||
}
|
||||
/* sport_data_func_get_finish_deal(); */
|
||||
}
|
||||
|
||||
int JL_rcsp_sports_data_funciton(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len)
|
||||
{
|
||||
int ret = -1;
|
||||
if (!__this) {
|
||||
return ret;
|
||||
}
|
||||
switch (OpCode) {
|
||||
case JL_OPCODE_SPORTS_DATA_INFO_GET:
|
||||
ret = 0;
|
||||
//ota不响应运动数据
|
||||
if (get_ota_status()) {
|
||||
JL_CMD_response_send(OpCode, JL_PRO_STATUS_FAIL, OpCode_SN, NULL, 0, 0, NULL);
|
||||
break;
|
||||
}
|
||||
get_sport_data_info(priv, OpCode, OpCode_SN, data, len);
|
||||
break;
|
||||
case JL_OPCODE_SPORTS_DATA_INFO_SET:
|
||||
ret = 0;
|
||||
//ota不响应运动数据
|
||||
if (get_ota_status()) {
|
||||
JL_CMD_response_send(OpCode, JL_PRO_STATUS_FAIL, OpCode_SN, NULL, 0, 0, NULL);
|
||||
break;
|
||||
}
|
||||
set_sport_data_info(priv, OpCode, OpCode_SN, data, len);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// 处理多包的情况
|
||||
static u16 sport_data_func_multi_pack_detailed_update(u8 *resp_pack, u16 resp_pack_len, sport_resp_data *sport_data, u16 offset)
|
||||
{
|
||||
u8 *resp_data = resp_pack + 3;
|
||||
u8 resp_data_len = resp_pack_len - 3;
|
||||
|
||||
if (!sport_data->resp_data_len) {
|
||||
return offset;
|
||||
}
|
||||
|
||||
u16 data_len = sport_data->resp_data_len + 2;
|
||||
if (offset + 2 > resp_data_len) {
|
||||
resp_data[offset++] = ((u8 *)&data_len)[1];
|
||||
JL_CMD_send(JL_OPCODE_SPORTS_DATA_INFO_AUTO_UPDATE, resp_pack, resp_pack_len, JL_NOT_NEED_RESPOND, 0, NULL);
|
||||
resp_pack[2]++;
|
||||
offset = 0;
|
||||
resp_data[offset++] = ((u8 *)&data_len)[0];
|
||||
} else if (offset + 3 > resp_data_len) {
|
||||
resp_data[offset++] = ((u8 *)&data_len)[1];
|
||||
resp_data[offset++] = ((u8 *)&data_len)[0];
|
||||
JL_CMD_send(JL_OPCODE_SPORTS_DATA_INFO_AUTO_UPDATE, resp_pack, resp_pack_len, JL_NOT_NEED_RESPOND, 0, NULL);
|
||||
resp_pack[2]++;
|
||||
offset = 0;
|
||||
} else {
|
||||
resp_data[offset++] = ((u8 *)&data_len)[1];
|
||||
resp_data[offset++] = ((u8 *)&data_len)[0];
|
||||
}
|
||||
resp_data[offset++] = sport_data->resp_mask;
|
||||
resp_data[offset++] = sport_data->resp_sub_mask;
|
||||
for (data_len = 0; data_len < sport_data->resp_data_len;) {
|
||||
u16 len = 0;
|
||||
if (resp_data_len - offset > sport_data->resp_data_len - data_len) {
|
||||
len = sport_data->resp_data_len - data_len;
|
||||
memcpy(resp_data + offset, sport_data->resp_data + data_len, len);
|
||||
offset += len;
|
||||
} else {
|
||||
len = resp_data_len - offset;
|
||||
memcpy(resp_data + offset, sport_data->resp_data + data_len, len);
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
if (offset) {
|
||||
break;
|
||||
} else {
|
||||
JL_CMD_send(JL_OPCODE_SPORTS_DATA_INFO_AUTO_UPDATE, resp_pack, resp_pack_len, JL_NOT_NEED_RESPOND, 0, NULL);
|
||||
resp_pack[2]++;
|
||||
}
|
||||
|
||||
data_len += len;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
static int sport_data_func_multi_pack_update(void *priv, u8 *resp_pack, u16 resp_pack_len, sport_resp_data *sport_data, u16 sport_data_len)
|
||||
{
|
||||
struct RcspModel *rcspModel = (struct RcspModel *)priv;
|
||||
if (rcspModel == NULL) {
|
||||
return false;
|
||||
}
|
||||
// 假如rcspModel->err_code为0,则是普通推送
|
||||
if (JL_OPCODE_SPORTS_DATA_INFO_AUTO_UPDATE != rcspModel->OpCode_record) {
|
||||
// 假如不是主动推送,先回复命令
|
||||
resp_pack[0] = 0;
|
||||
resp_pack[1] = 0; // 不带response data
|
||||
JL_CMD_response_send(rcspModel->OpCode_record, JL_PRO_STATUS_SUCCESS, rcspModel->OpCode_SN_record, resp_pack, 2, 0, NULL);
|
||||
}
|
||||
|
||||
// 组装数据并发送
|
||||
resp_pack[0] = SPROT_DATA_PROTOCOL_VERSION;
|
||||
resp_pack[1] = sport_data_len / resp_pack_len + !!(sport_data_len % resp_pack_len);
|
||||
resp_pack[2] = 0;
|
||||
u16 offset = 0;
|
||||
for (u8 i = 0; i < SPORTS_DATA_FUNC_ATTR_TYPE_GET_MAX; i++) {
|
||||
offset = sport_data_func_multi_pack_detailed_update(resp_pack, resp_pack_len, sport_data + i, offset);
|
||||
}
|
||||
if (offset) {
|
||||
JL_CMD_send(JL_OPCODE_SPORTS_DATA_INFO_AUTO_UPDATE, resp_pack, offset + 3, JL_NOT_NEED_RESPOND, 0, NULL);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sport_data_global_var_callback(void *priv)
|
||||
{
|
||||
if (NULL == priv) {
|
||||
return 0;
|
||||
}
|
||||
u8 **data = (u8 **)priv;
|
||||
if (*data) {
|
||||
free(*data);
|
||||
*data = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
u16 add_one_attr_with_submask_huge(u8 *buf, u16 max_len, u8 offset, u8 type, u8 sub_mask, u8 *data, u16 size)
|
||||
{
|
||||
if (offset + size + 4 > max_len) {
|
||||
/* printf("\n\nadd attr err!\n\n"); */
|
||||
return 0;
|
||||
}
|
||||
|
||||
u16 data_len = size + 2;
|
||||
buf[offset] = ((u8 *)&data_len)[1];
|
||||
buf[offset + 1] = ((u8 *)&data_len)[0];
|
||||
buf[offset + 2] = type;
|
||||
buf[offset + 3] = sub_mask;
|
||||
memcpy(&buf[offset + 4], data, size);
|
||||
return size + 4;
|
||||
}
|
||||
|
||||
void sport_data_global_var_deal(void *priv, u8 type, u8 sub_mask, u8 *data, u16 data_len, u8 result_len, void *callback_param)
|
||||
{
|
||||
struct RcspModel *rcspModel = (struct RcspModel *)priv;
|
||||
sport_resp_data *resp_data = (sport_resp_data *)rcspModel->priv;
|
||||
resp_data->resp_mask = type;
|
||||
resp_data->resp_sub_mask = sub_mask;
|
||||
resp_data->resp_data_len = data_len;
|
||||
resp_data->resp_data = data;
|
||||
resp_data->call_back = sport_data_global_var_callback;
|
||||
resp_data->priv = callback_param;
|
||||
if (!result_len) {
|
||||
rcspModel->err_code = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void sport_data_regular_update(void *priv)
|
||||
{
|
||||
// 隔一段时间向app推送运动数据,这里以获取心率统计值为例子
|
||||
#if JL_RCSP_EXTRA_FLASH_OPT
|
||||
if (!rcsp_eflash_update_flag_get()) {
|
||||
u32 mask = BIT(SPORTS_DATA_FUNC_ATTR_TYPE_HEART_RATE) | BIT(SPORTS_DATA_FUNC_ATTR_TYPE_BLOOD_OXYGEN) | BIT(SPORTS_DATA_FUNC_ATTR_TYPE_ALTITUDE) | BIT(SPORTS_DATA_FUNC_ATTR_TYPE_AIR_PRESSURE) | BIT(SPORTS_DATA_FUNC_ATTR_TYPE_ALTITUDE) | BIT(SPORTS_DATA_FUNC_ATTR_TYPE_EXERCISE_STEPS);
|
||||
u8 sub_mask[5] = {0};
|
||||
sub_mask[0] = 0x01;
|
||||
sub_mask[1] = 0x01;
|
||||
sub_mask[2] = 0x01;
|
||||
sub_mask[3] = 0x01;
|
||||
sub_mask[4] = 0x01;
|
||||
sport_data_func_update(mask, sub_mask);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void sport_data_func_event(void *priv, u8 flag)
|
||||
{
|
||||
struct RcspModel *rcspModel = (struct RcspModel *)priv;
|
||||
static u16 sport_data_update_timer = 0;
|
||||
if (flag) {
|
||||
// 连上
|
||||
if (SPORT_DATA_TIMED_NOFIFYCATION_TIME && 0 == sport_data_update_timer) {
|
||||
sport_data_update_timer = sys_timer_add(NULL, sport_data_regular_update, SPORT_DATA_TIMED_NOFIFYCATION_TIME);
|
||||
}
|
||||
} else {
|
||||
// 断开
|
||||
if (sport_data_update_timer) {
|
||||
sys_timer_del(sport_data_update_timer);
|
||||
sport_data_update_timer = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sport_data_func_init(void)
|
||||
{
|
||||
struct RcspModel *rcspModel = rcsp_handle_get();
|
||||
rcsp_msg_post(USER_MSG_RCSP_SPORT_DATA_EVENT, 2, (int)rcspModel, 1);
|
||||
if (!os_sem_valid(&g_sport_data_get_sem)) {
|
||||
os_sem_create(&g_sport_data_get_sem, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void sport_data_func_release(void)
|
||||
{
|
||||
struct RcspModel *rcspModel = rcsp_handle_get();
|
||||
/* if (os_sem_valid(&g_sport_data_get_sem)) { */
|
||||
/* os_sem_del(&g_sport_data_get_sem, 0); */
|
||||
/* } */
|
||||
rcsp_msg_post(USER_MSG_RCSP_SPORT_DATA_EVENT, 2, (int)rcspModel, 0);
|
||||
}
|
||||
|
||||
void sport_data_func_get_prepare_deal(void)
|
||||
{
|
||||
if (get_rcsp_connect_status()) {
|
||||
os_sem_pend(&g_sport_data_get_sem, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void sport_data_func_get_finish_deal(void)
|
||||
{
|
||||
if (get_rcsp_connect_status()) {
|
||||
os_sem_post(&g_sport_data_get_sem);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int rcsp_register_sport_data_opt_interface(rcsp_sport_data_opt_t *rcsp_sport_data_opt_interface)
|
||||
{
|
||||
g_rcsp_sport_data_opt = rcsp_sport_data_opt_interface;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void sport_data_func_update(u32 mask, u8 *sub_mask)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void sport_data_func_init(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void sport_data_func_release(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void sport_data_func_event(void *priv, u8 flag)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void sport_data_func_get_prepare_deal(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void sport_data_func_get_finish_deal(void)
|
||||
{
|
||||
|
||||
}
|
||||
#endif
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
#ifndef __RCSP_SPORT_DATA_FUNC_H__
|
||||
#define __RCSP_SPORT_DATA_FUNC_H__
|
||||
|
||||
#include "typedef.h"
|
||||
#include "JL_rcsp_attr.h"
|
||||
|
||||
enum {
|
||||
SPORTS_DATA_FUNC_ATTR_TYPE_HEART_RATE,
|
||||
SPORTS_DATA_FUNC_ATTR_TYPE_AIR_PRESSURE,
|
||||
SPORTS_DATA_FUNC_ATTR_TYPE_ALTITUDE,
|
||||
SPORTS_DATA_FUNC_ATTR_TYPE_EXERCISE_STEPS,
|
||||
SPORTS_DATA_FUNC_ATTR_TYPE_PRESSURE_DETECTION,
|
||||
SPORTS_DATA_FUNC_ATTR_TYPE_BLOOD_OXYGEN,
|
||||
SPORTS_DATA_FUNC_ATTR_TYPE_TRAINING_LOAD,
|
||||
SPORTS_DATA_FUNC_ATTR_TYPE_MAX_OXYGEN_UPTAKE,
|
||||
SPORTS_DATA_FUNC_ATTR_TYPE_EXERCISE_RECOVERY_TIME,
|
||||
SPORTS_DATA_FUNC_ATTR_TYPE_SPORTS_INFORMATION,
|
||||
SPORTS_DATA_FUNC_ATTR_TYPE_GET_MAX,
|
||||
};
|
||||
|
||||
enum {
|
||||
DATA_FUNC_ATTR_TYPE_LOCATION,
|
||||
DATA_FUNC_ATTR_TYPE_WEATHER,
|
||||
DATA_FUNC_ATTR_TYPE_NOTICE,
|
||||
DATA_FUNC_ATTR_TYPE_NOTICE_REMOVE,
|
||||
DATA_FUNC_ATTR_TYPE_SET_MAX,
|
||||
};
|
||||
|
||||
typedef struct sport_resp_data_t {
|
||||
u16 resp_data_len;
|
||||
u8 resp_mask;
|
||||
u8 resp_sub_mask;
|
||||
u8 *resp_data;
|
||||
int (*call_back)(void *priv);
|
||||
void *priv;
|
||||
} sport_resp_data;
|
||||
|
||||
typedef u32(*sport_attr_get_func)(void *priv, u8 attr, u8 type, u8 *buf, u16 buf_size, u32 offset);
|
||||
|
||||
typedef struct rcsp_sport_data_opt {
|
||||
const sport_attr_get_func *sport_data_get_tab;
|
||||
int sport_data_get_tab_num;
|
||||
const attr_set_func *sport_data_set_tab;
|
||||
int sport_data_set_tab_num;
|
||||
} rcsp_sport_data_opt_t;
|
||||
|
||||
int JL_rcsp_sports_data_funciton(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len);
|
||||
void sport_data_func_update(u32 mask, u8 *sub_mask);
|
||||
void sport_data_global_var_deal(void *priv, u8 type, u8 sub_mask, u8 *data, u16 data_len, u8 result_len, void *callback_param);
|
||||
u16 add_one_attr_with_submask_huge(u8 *buf, u16 max_len, u8 offset, u8 type, u8 sub_mask, u8 *data, u16 size);
|
||||
void sport_data_func_get_prepare_deal(void);
|
||||
void sport_data_func_get_finish_deal(void);
|
||||
int rcsp_register_sport_data_opt_interface(rcsp_sport_data_opt_t *rcsp_sport_data_opt_interface);
|
||||
|
||||
// #if (RCSP_MODE)
|
||||
// #define RCSP_UPDATE sport_data_func_update
|
||||
// #else
|
||||
// #define RCSP_UPDATE(...)
|
||||
// #endif
|
||||
|
||||
#endif
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".sport_info_opt.data.bss")
|
||||
#pragma data_seg(".sport_info_opt.data")
|
||||
#pragma const_seg(".sport_info_opt.text.const")
|
||||
#pragma code_seg(".sport_info_opt.text")
|
||||
#endif
|
||||
#include "rcsp_config.h"
|
||||
#include "JL_rcsp_attr.h"
|
||||
#include "sport_info_opt.h"
|
||||
#include "rcsp_event.h"
|
||||
#include "rcsp_manage.h"
|
||||
#include "JL_rcsp_protocol.h"
|
||||
#include "JL_rcsp_api.h"
|
||||
|
||||
#if (RCSP_MODE && JL_RCSP_SENSORS_DATA_OPT)
|
||||
|
||||
#define FUNCTION_UPDATE_MAX_LEN (256)
|
||||
|
||||
#define ASSET_CMD_DATA_LEN(len, limit) \
|
||||
do{ \
|
||||
if(len >= limit){ \
|
||||
}else{ \
|
||||
return ; \
|
||||
}\
|
||||
}while(0);
|
||||
|
||||
enum {
|
||||
SPORTS_INFO_OPT_GET,
|
||||
SPORTS_INFO_OPT_SET,
|
||||
SPORTS_INFO_OPT_NOTIFY,
|
||||
};
|
||||
|
||||
static rcsp_sport_info_opt_t *g_rcsp_sport_info_opt = NULL;
|
||||
#define __this g_rcsp_sport_info_opt
|
||||
|
||||
static void get_sport_info(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len)
|
||||
{
|
||||
printf("get_sport_info\n");
|
||||
u32 rlen = 0;
|
||||
u32 mask = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
|
||||
u8 *resp = zalloc(TARGET_FEATURE_RESP_BUF_SIZE);
|
||||
if (NULL == resp) {
|
||||
printf("%s, %d, no ram!!\n", __func__, __LINE__);
|
||||
goto __get_sport_info_end;
|
||||
}
|
||||
|
||||
rlen = attr_get(priv, resp, TARGET_FEATURE_RESP_BUF_SIZE, __this->sport_info_get_tab, __this->sport_info_get_tab_num, mask);
|
||||
|
||||
__get_sport_info_end:
|
||||
if (0 == rlen) {
|
||||
JL_CMD_response_send(OpCode, JL_PRO_STATUS_FAIL, OpCode_SN, NULL, 0, 0, NULL);
|
||||
} else {
|
||||
JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, resp, (u16)rlen, 0, NULL);
|
||||
}
|
||||
|
||||
if (resp) {
|
||||
free(resp);
|
||||
}
|
||||
}
|
||||
|
||||
static void set_sport_info(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len)
|
||||
{
|
||||
printf("set_sport_info\n");
|
||||
struct RcspModel *rcspModel = (struct RcspModel *)priv;
|
||||
if (rcspModel == NULL) {
|
||||
return;
|
||||
}
|
||||
put_buf(data, len);
|
||||
attr_set(priv, data, len, __this->sport_info_set_tab, __this->sport_info_set_tab_num, 0, NULL);
|
||||
if (rcspModel->err_code) {
|
||||
rcspModel->err_code = 0;
|
||||
JL_CMD_response_send(OpCode, JL_PRO_STATUS_FAIL, OpCode_SN, NULL, 0, 0, NULL);
|
||||
} else {
|
||||
JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, NULL, 0, 0, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void sport_info_opt_update(u32 mask)
|
||||
{
|
||||
struct RcspModel *rcspModel = rcsp_handle_get();
|
||||
if (rcspModel == NULL || 0 == JL_rcsp_get_auth_flag()) {
|
||||
return ;
|
||||
}
|
||||
u32 rlen = 0;
|
||||
u8 *buf = zalloc(FUNCTION_UPDATE_MAX_LEN);
|
||||
if (buf == NULL) {
|
||||
printf("no ram err\n");
|
||||
return;
|
||||
}
|
||||
buf[0] = SPORTS_INFO_OPT_NOTIFY;
|
||||
|
||||
rlen = attr_get((void *)rcspModel, buf + 1, FUNCTION_UPDATE_MAX_LEN - 1, __this->sport_info_get_tab, __this->sport_info_get_tab_num, mask);
|
||||
if (rlen) {
|
||||
JL_CMD_send(JL_OPCODE_SPORTS_DATA_INFO_OPT, buf, (u16)rlen + 1, JL_NOT_NEED_RESPOND, 0, NULL);
|
||||
}
|
||||
if (buf) {
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
|
||||
int JL_rcsp_sports_info_funciton(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len)
|
||||
{
|
||||
int ret = -1;
|
||||
if (!__this) {
|
||||
return ret;
|
||||
}
|
||||
if (JL_OPCODE_SPORTS_DATA_INFO_OPT == OpCode) {
|
||||
u8 op = data[0];
|
||||
switch (op) {
|
||||
case SPORTS_INFO_OPT_GET:
|
||||
get_sport_info(priv, OpCode, OpCode_SN, data + 1, len - 1);
|
||||
break;
|
||||
case SPORTS_INFO_OPT_SET:
|
||||
set_sport_info(priv, OpCode, OpCode_SN, data + 1, len - 1);
|
||||
break;
|
||||
case SPORTS_INFO_OPT_NOTIFY:
|
||||
break;
|
||||
}
|
||||
ret = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int rcsp_register_sport_info_opt_interface(rcsp_sport_info_opt_t *rcsp_sport_info_opt_interface)
|
||||
{
|
||||
g_rcsp_sport_info_opt = rcsp_sport_info_opt_interface;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void sport_info_opt_update(u32 mask)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
#ifndef __RCSP_SPORT_INFO_OPT_H__
|
||||
#define __RCSP_SPORT_INFO_OPT_H__
|
||||
|
||||
#include "typedef.h"
|
||||
#include "JL_rcsp_attr.h"
|
||||
|
||||
enum {
|
||||
SPORTS_INFO_OPT_FUNC_ATTR_TYPE_RESERVE,
|
||||
SPORTS_INFO_OPT_FUNC_ATTR_TYPE_SENSOR_OPT,
|
||||
SPORTS_INFO_OPT_FUNC_ATTR_TYPE_SEDENTARY,
|
||||
SPORTS_INFO_OPT_FUNC_ATTR_TYPE_CONTINUOUS_HEART_RATE,
|
||||
SPORTS_INFO_OPT_FUNC_ATTR_TYPE_EXERCISE_HEART_RATE,
|
||||
SPORTS_INFO_OPT_FUNC_ATTR_TYPE_PRESSURE_DETECTION,
|
||||
SPORTS_INFO_OPT_FUNC_ATTR_TYPE_SLEEP_DETECTION,
|
||||
SPORTS_INFO_OPT_FUNC_ATTR_TYPE_FALL_DETECTION,
|
||||
SPORTS_INFO_OPT_FUNC_ATTR_TYPE_RAISE_WRIST,
|
||||
SPORTS_INFO_OPT_FUNC_ATTR_TYPE_PERSONAL_INFO,
|
||||
SPORTS_INFO_OPT_FUNC_ATTR_TYPE_BT_DISCONN,
|
||||
SPORTS_INFO_OPT_FUNC_ATTR_TYPE_MAX,
|
||||
};
|
||||
|
||||
// 开关
|
||||
enum {
|
||||
SPORT_INFO_SWTICH_TYPE_SENSOR,
|
||||
// 传感器功能
|
||||
SPORT_INFO_SWTICH_TYPE_SENSOR_PEDOMETER,
|
||||
SPORT_INFO_SWTICH_TYPE_SENSOR_PEDOMETER_RECORD,
|
||||
SPORT_INFO_SWTICH_TYPE_SENSOR_HEART_RATE,
|
||||
SPORT_INFO_SWTICH_TYPE_SENSOR_HEART_RATE_RECORD,
|
||||
SPORT_INFO_SWTICH_TYPE_SENSOR_BLOOD_OXYGEN,
|
||||
SPORT_INFO_SWTICH_TYPE_SENSOR_BLOOD_OXYGEN_RECORD,
|
||||
SPORT_INFO_SWTICH_TYPE_SENSOR_ALTITUDE,
|
||||
|
||||
SPORT_INFO_SWTICH_TYPE_SENSOR_ALTITUDE_RECORD,//8
|
||||
// 久坐提醒
|
||||
SPORT_INFO_SWTICH_TYPE_SEDENTARY,
|
||||
// 连续测量心率
|
||||
SPORT_INFO_SWTICH_TYPE_CONTINUOUS_HEART_RATE,
|
||||
// 运动心率
|
||||
SPORT_INFO_SWTICH_TYPE_EXERCISE_HEART_RATE,
|
||||
// 压力自动检测
|
||||
SPORT_INFO_SWTICH_TYPE_PRESSURE_DETECTION,
|
||||
// 睡眠检测
|
||||
SPORT_INFO_SWTICH_TYPE_SLEEP_DETECTION,
|
||||
// 跌倒检测
|
||||
SPORT_INFO_SWTICH_TYPE_FALL_DETECTION,
|
||||
// 抬腕检测
|
||||
SPORT_INFO_SWTICH_TYPE_RAISE_WRIST,
|
||||
// 蓝牙断开提示
|
||||
SPORT_INFO_SWTICH_TYPE_BT_DISCONN,
|
||||
// 当前最大值
|
||||
SPORT_INFO_SWITCH_TYPE_END,
|
||||
};
|
||||
|
||||
// 开关类型扩展
|
||||
enum SPORT_INFO_SWITCH_EXPAND_TYPE {
|
||||
// 睡眠检测 - 自定义时间段
|
||||
SPORT_INFO_SWTICH_TYPE_SLEEP_DETECTION_CUSTOMIZE = SPORT_INFO_SWITCH_TYPE_END,
|
||||
// 抬腕检测 - 自定义时间段
|
||||
SPORT_INFO_SWTICH_TYPE_RAISE_WRIST_CUSTOMIZE,
|
||||
// 最大值,不超过31
|
||||
SPORT_INFO_SWTICH_TYPE_MAX,
|
||||
};
|
||||
|
||||
// 模式
|
||||
enum {
|
||||
// 久坐提醒
|
||||
SPORT_INFO_MODE_TYPE_SEDENTARY,
|
||||
// 连续心率
|
||||
SPORT_INFO_MODE_TYPE_CONTINUOUS_HEART_RATE,
|
||||
// 压力检测
|
||||
SPORT_INFO_MODE_TYPE_PRESSURE_DETECTION,
|
||||
// 跌倒检测
|
||||
SPORT_INFO_MODE_TYPE_FALL_DETECTION,
|
||||
// 抬碗检测
|
||||
SPORT_INFO_MODE_TYPE_RAISE_WRIST,
|
||||
// 蓝牙断开提示
|
||||
SPORT_INFO_MODE_TYPE_BT_DISCONN,
|
||||
// 最大值
|
||||
SPORT_INFO_MODE_TYPE_MAX,
|
||||
};
|
||||
|
||||
typedef struct rcsp_sport_info_opt {
|
||||
const attr_get_func *sport_info_get_tab;
|
||||
int sport_info_get_tab_num;
|
||||
const attr_set_func *sport_info_set_tab;
|
||||
int sport_info_set_tab_num;
|
||||
} rcsp_sport_info_opt_t;
|
||||
|
||||
int JL_rcsp_sports_info_funciton(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len);
|
||||
|
||||
void sport_info_opt_update(u32 mask);
|
||||
|
||||
int rcsp_register_sport_info_opt_interface(rcsp_sport_info_opt_t *rcsp_sport_info_opt_interface);
|
||||
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user