Files
2025-12-03 11:12:34 +08:00

745 lines
26 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".effects_adj.data.bss")
#pragma data_seg(".effects_adj.data")
#pragma const_seg(".effects_adj.text.const")
#pragma code_seg(".effects_adj.text")
#endif
#include "system/includes.h"
#include "media/includes.h"
#include "app_config.h"
#include "audio_config.h"
#include "jlstream.h"
#include "cfg_tool.h"
#include "volume_node.h"
#include "effects/effects_adj.h"
#include "effects/eq_config.h"
#include "effects/audio_eq.h"
#include "effects/audio_bass_treble_eq.h"
#define LOG_TAG_CONST EFFECTS
#define LOG_TAG "[EFFECTS_ADJ]"
#define LOG_ERROR_ENABLE
#define LOG_INFO_ENABLE
#define LOG_DUMP_ENABLE
#include "debug.h"
#ifdef SUPPORT_MS_EXTENSIONS
#pragma code_seg(".effects_adj.text")
#pragma data_seg(".effects_adj.data")
#pragma const_seg(".effects_adj.text.const")
#endif
#if TCFG_CFG_TOOL_ENABLE
struct eff_mode {
u16 uuid;
u16 mode_num; //模式个数
u16 mode_index; //当前模式序号
} __attribute__((packed));
struct stream_crc {
u16 uuid;
u16 crc;
};
struct eff_struct { //参数结构,节点结构组成uuid name parm_struct
u16 uuid;
u16 reserve;//bit0 是否伪模块,伪模块时发送多个节点数据 bit1:表单类节点是否为手动调节,bit2-7:保留
char data[0];//多节点一起更新时[len +nodedata(struct eff_struct结构) ...]
} __attribute__((packed));
struct eff_online_packet {
int cmd;
struct eff_struct par;
};
struct eq_list_entry {
struct list_head entry;
struct eq_online *tab;
};
struct eff_list_entry {
struct list_head entry;
u32 private_type;//特殊私有类型,当前被mdrc使用
u32 len;
struct eff_online_packet *packet;
};
struct eff_list {
struct list_head head; //链表头
};
static struct eff_list eff_hdl_eq = {0};
static struct eff_list eff_hdl = {0};
static spinlock_t eff_lock[2];
static int eff_list_init(void)
{
INIT_LIST_HEAD(&eff_hdl_eq.head);
INIT_LIST_HEAD(&eff_hdl.head);
spin_lock_init(&eff_lock[0]);
spin_lock_init(&eff_lock[1]);
return 0;
}
__initcall(eff_list_init);
static u32 total_buf = 0;
void effects_adj_printf()
{
log_debug(">>>>>total_buf adj buf %d bytes>>>>>\n", total_buf);
}
/*
*eq调音临时系数更新
* */
void eq_list_entry_update(struct eq_list_entry *hdl, struct eff_online_packet *ep, u32 size, int *ret, int *start, int *end)
{
int *data = (int *)&ep->par.data[16];
if (data[0] == EQ_SPECIAL_CMD) { //type bypass global_gain sen_num
if (data[3] != hdl->tab->seg_num) {
if (hdl->tab) {
int prev_size = sizeof(struct eq_online) + hdl->tab->seg_num * sizeof(struct eq_seg_info);
if (total_buf > prev_size) {
total_buf -= prev_size;
} else {
total_buf = 0;
}
free(hdl->tab);
}
int sizet = sizeof(struct eq_online) + data[3] * sizeof(struct eq_seg_info);
hdl->tab = malloc(sizet);
total_buf += sizet;
}
hdl->tab->is_bypass = data[1];
memcpy(&hdl->tab->global_gain, &data[2], 4);//总增益是浮点
hdl->tab->seg_num = data[3];
hdl->tab->uuid = ep->par.uuid;
memcpy(hdl->tab->name, &ep->par.data, 16);
log_debug("multi hdl->tab->is_bypass %d\n", hdl->tab->is_bypass);
log_debug("multi hdl->tab->global_gain %x\n", *(int *)&hdl->tab->global_gain);
log_debug("multi hdl->tab->seg_num %d\n", hdl->tab->seg_num);
*ret = EQ_SPECIAL_CMD;
return;
} else if (data[0] == EQ_SPECIAL_SEG_CMD) { //type seg[n]
hdl->tab->uuid = ep->par.uuid;
memcpy(hdl->tab->name, &ep->par.data, 16);
struct eq_seg_info *src_seg = (struct eq_seg_info *)&data[1];
int tar_size = size - 8 - 16; ////减去cmd uuid name
*start = src_seg[0].index;
for (int i = 0; i < hdl->tab->seg_num; i++) {
if (tar_size >= sizeof(struct eq_seg_info)) {
memcpy(&hdl->tab->seg[src_seg[i].index], &src_seg[i], sizeof(struct eq_seg_info));
struct eq_seg_info *seg = (struct eq_seg_info *)&hdl->tab->seg[src_seg[i].index];
/* log_debug("multi soure idx:%d, iir:%d, freq:%d, gain:0x%08x, q:0x%08x ", seg->index, seg->iir_type, seg->freq, *(int *)&seg->gain, *(int *)&seg->q); */
tar_size -= sizeof(struct eq_seg_info);
*end = src_seg[i].index;
}
}
*ret = EQ_SPECIAL_SEG_CMD;
return;
}
struct eq_adj eq = {0};
memcpy(&eq, &ep->par.data[16], size - 8 - 16);//减去cmd uuid name
if (eq.type == EQ_IS_BYPASS_CMD) {
hdl->tab->is_bypass = eq.param.is_bypass;
log_debug("tab->is_bypass %d\n", hdl->tab->is_bypass);
} else if (eq.type == EQ_GLOBAL_GAIN_CMD) {
hdl->tab->global_gain = eq.param.global_gain;
log_debug("hdl->tab->global_gain %x\n", *(int *)&hdl->tab->global_gain);
} else if (eq.type == EQ_SEG_NUM_CMD) {
if (eq.param.seg_num != hdl->tab->seg_num) {
float global_gain = hdl->tab->global_gain;
int is_bypass = hdl->tab->is_bypass;
if (hdl->tab) {
int prev_size = sizeof(struct eq_online) + hdl->tab->seg_num * sizeof(struct eq_seg_info);
if (total_buf > prev_size) {
total_buf -= prev_size;
} else {
total_buf = 0;
}
free(hdl->tab);
}
int sizet = sizeof(struct eq_online) + eq.param.seg_num * sizeof(struct eq_seg_info);
hdl->tab = malloc(sizet);
total_buf += sizet;
hdl->tab->global_gain = global_gain;
hdl->tab->is_bypass = is_bypass;
log_debug("hdl->tab->is_bypass %d\n", hdl->tab->is_bypass);
log_debug("hdl->tab->global_gain %x\n", *(int *)&hdl->tab->global_gain);
}
hdl->tab->seg_num = eq.param.seg_num;
log_debug("hdl->tab->seg_num %d\n", hdl->tab->seg_num);
} else if (eq.type == EQ_SEG_CMD) {
memcpy(&hdl->tab->seg[eq.param.seg.index], &eq.param.seg, sizeof(struct eq_seg_info));
struct eq_seg_info *seg = (struct eq_seg_info *)&hdl->tab->seg[eq.param.seg.index];
log_debug("soure idx:%d, iir:%d, freq:%d, gain:0x%08x, q:0x%08x ", seg->index, seg->iir_type, seg->freq, *(int *)&seg->gain, *(int *)&seg->q);
}
hdl->tab->uuid = ep->par.uuid;
memcpy(hdl->tab->name, &ep->par.data, 16);
}
/*
*通用音效临时参数更新
* */
void eff_list_entry_update(struct eff_list_entry *hdl, struct eff_online_packet *ep, u32 size)
{
if (size != hdl->len) {
if (hdl->packet) {
if (total_buf > hdl->len) {
total_buf -= hdl->len;
} else {
total_buf = 0;
}
free(hdl->packet);
}
hdl->len = size;
hdl->packet = malloc(size);
total_buf += size;
}
hdl->packet->cmd = ep->cmd;
hdl->packet->par.uuid = ep->par.uuid;
memcpy(&hdl->packet->par, &ep->par, size - 4);
}
/*
*获取特殊类型节点(mdrc)参数名字后的第一个int,协议见Mdrc调试
* */
int eff_get_privete_type(struct eff_online_packet *ep)
{
int private_type = 0;
memcpy(&private_type, &ep->par.data[16], 4);
return private_type;
}
/*
*获取参数链表成员的名字
* */
void eff_get_node_name(struct eff_list_entry *hdl, char *name)
{
memcpy(name, hdl->packet->par.data, 16);
}
/*
*检测mdrc子模块的类型
*return false:私有类型不匹配, true:私有类型匹配
* */
int eff_check_mdrc_private_type(struct eff_list_entry *hdl, u16 uuid, int private_type)
{
if ((uuid == NODE_UUID_MDRC) && private_type && (private_type != hdl->private_type)) {//mdrc需要加多一个cmd的判断
return false;
}
return true;
}
/*
*把在线调试的参数建立到链表内,方便节点切歌时,获取当前已经调试的参数
* */
void eff_entry_add(void *packet, u32 size, int *ret, int *start, int *end)
{
struct eff_online_packet *ep = (struct eff_online_packet *)packet;
int private_type = 0;
char name[16];
char src_name[16];
memcpy(name, ep->par.data, sizeof(name));
if (!strlen(name)) { //节点名字未填写,不做记录
return;
}
if ((ep->par.uuid != NODE_UUID_EQ) && (ep->par.uuid != NODE_UUID_SOF_EQ)) {
spin_lock(&eff_lock[0]);
if (ep->par.uuid == NODE_UUID_MDRC) {// 特殊类型,通过cmd记录差异点
private_type = eff_get_privete_type(ep);
}
if (!list_empty(&eff_hdl.head)) {
struct eff_list_entry *hdl;
list_for_each_entry(hdl, &eff_hdl.head, entry) {
eff_get_node_name(hdl, src_name);
log_debug("cmd 0x%x hdl->hdl->packet->cmd 0x%x", ep->cmd, hdl->packet->cmd);
if ((hdl->packet->par.uuid == ep->par.uuid) && !strncmp(src_name, name, strlen(name))) { //查询已存在,更新参数
if (!eff_check_mdrc_private_type(hdl, ep->par.uuid, private_type)) {
continue;
}
eff_list_entry_update(hdl, ep, size);
log_debug("node update %x\n", ep->par.uuid);
spin_unlock(&eff_lock[0]);
return;
}
}
}
//查询未存在,记录参数,并add到链表
int sizet = sizeof(struct eff_list_entry);
struct eff_list_entry *hdl = zalloc(sizet);
total_buf += sizet;
hdl->private_type = private_type;
eff_list_entry_update(hdl, ep, size);
list_add(&hdl->entry, &eff_hdl.head);
log_debug("node add %x\n", ep->par.uuid);
spin_unlock(&eff_lock[0]);
} else {
spin_lock(&eff_lock[1]);
if (!list_empty(&eff_hdl_eq.head)) { //非空
struct eq_list_entry *hdl;
list_for_each_entry(hdl, &eff_hdl_eq.head, entry) {
if ((hdl->tab->uuid == ep->par.uuid) && !strncmp(hdl->tab->name, name, 16)) { //查询已存在,更新参数
eq_list_entry_update(hdl, ep, size, ret, start, end);
log_debug("eq_list upadate\n");
spin_unlock(&eff_lock[1]);
return;
}
}
}
//查询未存在,记录参数,并add到链表
int sizet = sizeof(struct eq_list_entry);
struct eq_list_entry *hdl = zalloc(sizet);
total_buf += sizet;
int default_section = 10;
sizet = sizeof(struct eq_online) + default_section * sizeof(struct eq_seg_info);
hdl->tab = malloc(sizet);
total_buf += sizet;
hdl->tab->seg_num = default_section;
eq_list_entry_update(hdl, ep, size, ret, start, end);
list_add(&hdl->entry, &eff_hdl_eq.head);
log_debug("eq_list add\n");
spin_unlock(&eff_lock[1]);
}
}
/*
*节点通过uuid 与name获取在线调试音效的参数
* */
int get_eff_online_param(u32 _uuid, char *name, void *packet)
{
int ret = 0;
char src_name[16];
u16 uuid = _uuid & 0xffff;
int private_type = ((_uuid & 0xffff0000) >> 16);//复用uuid变量高16bit记录mdrc type
if ((uuid != NODE_UUID_EQ) && (uuid != NODE_UUID_SOF_EQ)) {
spin_lock(&eff_lock[0]);
if (!list_empty(&eff_hdl.head)) { //非空
struct eff_list_entry *hdl;
list_for_each_entry(hdl, &eff_hdl.head, entry) {
eff_get_node_name(hdl, src_name);
if ((hdl->packet->par.uuid == uuid) && !strncmp(src_name, name, strlen(name))) {
if (!eff_check_mdrc_private_type(hdl, uuid, private_type)) {
continue;
}
int len = 0;
char *ptr = (char *)packet;//结构:uuid name param
char *src = (char *)&hdl->packet->par;
memcpy(&len, &ptr[4 + 16], 4); //4byte uuid + 16byte name
int cp_len = hdl->len - 4 - 20;// 4byte 是减去cmd的长度, 20是 uuid reserve name 长度
if (cp_len > len) {
log_error("=====node online param err %s %d %d=====\n", name, len, cp_len);
cp_len = len;
}
memcpy(&ptr[20 + 4], &src[20], cp_len);
ret = 1;
break;
}
}
}
spin_unlock(&eff_lock[0]);
} else {
spin_lock(&eff_lock[1]);
if (!list_empty(&eff_hdl_eq.head)) { //非空
struct eq_list_entry *hdl;
list_for_each_entry(hdl, &eff_hdl_eq.head, entry) {
if ((hdl->tab->uuid == uuid) && !strncmp(hdl->tab->name, name, 16)) {
struct eq_online *tar = (struct eq_online *)packet;
tar->is_bypass = hdl->tab->is_bypass;
tar->global_gain = hdl->tab->global_gain;
tar->seg_num = hdl->tab->seg_num;
memcpy(tar->seg, hdl->tab->seg, sizeof(struct eq_seg_info)*hdl->tab->seg_num);
/* log_debug("tar seg %x\n", (int)tar->seg); */
/* for (int i = 0; i < tar->seg_num; i++) { */
/* struct eq_seg_info *seg = (struct eq_seg_info *)&hdl->tab->seg[i]; */
/* log_debug("source idx:%d, iir:%d, freq:%d, gain:0x%08x, q:0x%08x ", seg->index, seg->iir_type, seg->freq, *(int *)&seg->gain, *(int *)&seg->q); */
/* } */
ret = 1;
break;
}
}
}
spin_unlock(&eff_lock[1]);
}
return ret;
}
/*
*接收上位机发来的模式信息,小机可用于播放相应模式提示音
* */
void eff_mode_switch(void *priv)
{
struct eff_mode *param = (struct eff_mode *)priv;
log_debug("uuid 0x%x\n", param->uuid);
log_debug("mode_num %d\n", param->mode_num);
log_debug("mode_index %d\n", param->mode_index);
}
/*
*在线调音开始时会检查,界面框图流程的crc与stream.bin的crc是否一致
*不一致时,需要重新更新stream.bin并编译下载代码
* */
int eff_stream_crc_check(void *priv)
{
struct stream_crc *check = (struct stream_crc *)priv;
u16 crc = jlstream_read_stream_crc();
if (crc == check->crc) {
return true;
} else {
log_error("check stream crc fail, please update stream.bin and re-download \n");
}
return false;
}
int indicator_get_param(struct eff_online_packet *ep, u8 sq)
{
struct indicator_private_cmd {
u16 uuid;
u8 subid;
u8 reserve;
char name[16];
};
struct indicator_private_cmd *indator = (struct indicator_private_cmd *)&ep->par;
struct indicator_upload_data indicator_data = {0};
int res = jlstream_get_node_param(ep->par.uuid, indator->name, &indicator_data, sizeof(indicator_data));
if (res == sizeof(indicator_data)) {
eff_node_send_packet(REPLY_TO_TOOL, sq, (u8 *)&indicator_data, sizeof(indicator_data));
res = ERR_ACCEPTABLE;
} else {
res = ERR_COMM;
}
return res;
}
/*
*高低音获取当前gain并上传
* */
static int bass_treble_get_node_param(struct eff_online_packet *ep, u8 sq)
{
int res = ERR_COMM;
struct bass_treble_private_cmd { //协议相关
u16 uuid;
char name[16];
char mark[16];
} __attribute__((packed));
struct seg_gain gain = {0};
struct bass_treble_private_cmd *get_param = (struct bass_treble_private_cmd *)&ep->par;
if (!strcmp("low", get_param->mark)) {
gain.index = 0;
} else if (!strcmp("mid", get_param->mark)) {
gain.index = 1;
} else if (!strcmp("hig", get_param->mark)) {
gain.index = 2;
}
res = jlstream_get_node_param(get_param->uuid, get_param->name, &gain, sizeof(gain));//获取当前增益
if (res == sizeof(gain)) {
struct bass_treb_upload { //协议相关
u8 len;
u8 type;
float cur_gain;
} __attribute__((packed));
struct bass_treb_upload upload_param;
upload_param.len = sizeof(struct bass_treb_upload) - 1;
upload_param.type = 0x1;//数据类型 0u32 1:float
upload_param.cur_gain = gain.gain;
log_debug("bass treble idx : %d, gain: 0x%x\n", gain.index, *(int *)&gain.gain);
eff_node_send_packet(REPLY_TO_TOOL, sq, (u8 *)&upload_param, sizeof(upload_param));//上传当前增益
res = ERR_ACCEPTABLE;
}
return res;
}
/*
*获取当前音量并上传
* */
static int volume_get_node_param(struct eff_online_packet *ep, u8 sq)
{
int res = ERR_COMM;
struct volume_private_cmd { //协议相关
u16 uuid;
char name[16];
char mark[16];
} __attribute__((packed));
struct volume_cfg cfg = {0};
struct volume_private_cmd *get_param = (struct volume_private_cmd *)&ep->par;
if (!strcmp("volume", get_param->mark)) {
res = jlstream_get_node_param(get_param->uuid, get_param->name, &cfg, sizeof(cfg));//获取当前增益
if (res == sizeof(cfg)) {
struct volume_upload { //协议相关
u8 len;
u8 type;
int cur_vol;
} __attribute__((packed));
struct volume_upload upload_param;
upload_param.len = sizeof(struct volume_upload) - 1;
upload_param.type = 0x0;//数据类型 0u32 1:float
upload_param.cur_vol = cfg.cur_vol;
log_debug("volume get cur_vol %d\n", cfg.cur_vol);
eff_node_send_packet(REPLY_TO_TOOL, sq, (u8 *)&upload_param, sizeof(upload_param));//上传当前增益
res = ERR_ACCEPTABLE;
}
}
return res;
}
/*
*表单节点获取当前值
* */
static int form_node_get_parm(struct eff_online_packet *ep, u8 sq)
{
int res = ERR_COMM;
switch (ep->par.uuid) {
case NODE_UUID_BASS_TREBLE:
res = bass_treble_get_node_param(ep, sq);
break;
case NODE_UUID_VOLUME_CTRLER:
res = volume_get_node_param(ep, sq);
break;
default:
//do smt
break;
}
return res;
}
/*
*工具获取支持在线调试的节点列表
* */
static int check_eff_node_online_support(struct eff_online_packet *ep, u8 sq)
{
int res = ERR_ACCEPTABLE;
u16 cnt = 0;
struct effects_online_adjust *p;
list_for_online_adjust_target(p) {
/* printf("uuid %x\n", p->uuid); */
cnt++;
}
eff_node_send_packet(REPLY_TO_TOOL, sq, (u8 *)effects_online_adjust_begin, (int)(cnt * sizeof(u16)));
return res;
}
/*
*工具同步界面全部参数下来时,快速更新数据给节点
* */
static void eq_fast_update(char *name, u8 type, int start, int end, u16 uuid)
{
struct eq_tool *tab = NULL;
struct eq_online *online_parm = zalloc(sizeof(struct eq_online) + sizeof(struct eq_seg_info) * AUDIO_EQ_MAX_SECTION);
if (online_parm) {
online_parm->uuid = uuid;
memcpy(online_parm->name, name, strlen(name));
int online_ret = jlstream_event_notify(STREAM_EVENT_GET_EFF_ONLINE_PARM, (int)online_parm);
if (online_ret) {
int seg_size = sizeof(struct eq_seg_info) * online_parm->seg_num;
int sizet = sizeof(struct eq_tool) + seg_size;
tab = zalloc(sizet);
tab->is_bypass = online_parm->is_bypass;
tab->global_gain = online_parm->global_gain;
tab->seg_num = online_parm->seg_num;
memcpy(tab->seg, online_parm->seg, sizeof(struct eq_seg_info)*tab->seg_num);
}
free(online_parm);
}
if (!tab) {
return;
}
struct eq_adj eff = {0};
if (type == EQ_SPECIAL_CMD) {
//运行时,直接设置更新
eff.type = EQ_SEG_NUM_CMD;
eff.param.seg_num = tab->seg_num;
jlstream_set_node_param(uuid, name, &eff, sizeof(eff));//更新滤波器段数
eff.type = EQ_IS_BYPASS_CMD;
eff.param.is_bypass = tab->is_bypass;
jlstream_set_node_param(uuid, name, &eff, sizeof(eff));//更新bypass状态
eff.type = EQ_GLOBAL_GAIN_CMD;
eff.param.global_gain = tab->global_gain;
jlstream_set_node_param(uuid, name, &eff, sizeof(eff));//更新总增益
} else if (type == EQ_SPECIAL_SEG_CMD) {
for (int i = start; i <= end; i++) {
eff.type = EQ_SEG_CMD;
memcpy(&eff.param.seg, &tab->seg[i], sizeof(struct eq_seg_info));
jlstream_set_node_param(uuid, name, &eff, sizeof(eff));//更新滤波器系数
}
}
free(tab);
}
static s32 eff_online_update_base(void *packet, u32 size, u8 sq)
{
int eq_ret = 0;
int start = 0;
int end = 0;
int res = ERR_ACCEPTABLE;
char name[16];
struct eff_online_packet *ep = (struct eff_online_packet *)packet;
log_debug("cmd %x\n", ep->cmd);
switch (ep->cmd) {
case EFF_ADJ_CMD:
memcpy(name, ep->par.data, sizeof(name));
log_debug("uuid:0x%x name %s\n", ep->par.uuid, name);
if (ep->par.uuid == NODE_UUID_VOLUME_CTRLER) {
log_debug("effects.adj.c %d,%x\n", __LINE__, (int)(ep->par.reserve & EFF_MANUAL_ADJ_NODE));
int res = ERR_COMM;
if (!(int)(ep->par.reserve & EFF_MANUAL_ADJ_NODE)) { //点开节点下发的音量
struct volume_cfg cfg = {0};
res = jlstream_get_node_param(NODE_UUID_VOLUME_CTRLER, name, &cfg, sizeof(cfg));//获取当前增益
struct volume_cfg *temp_vol_cfg = (struct volume_cfg *)(&ep->par.data[16]);
temp_vol_cfg->cur_vol = cfg.cur_vol;
log_debug("effects.adj.c%d,%d\n", __LINE__, cfg.cur_vol);
}
}
eff_entry_add(packet, size, (int *)&eq_ret, &start, &end);
if (eq_ret == EQ_SPECIAL_CMD) {
res = ERR_NONE;
eq_fast_update(name, eq_ret, start, end, ep->par.uuid);
break;
}
if (eq_ret == EQ_SPECIAL_SEG_CMD) {
res = ERR_NONE;
eq_fast_update(name, eq_ret, start, end, ep->par.uuid);
break;
}
res = jlstream_set_node_param(ep->par.uuid, name, &ep->par.data[16], size - sizeof(ep->cmd) - sizeof(ep->par.uuid) - sizeof(ep->par.reserve) - 16); //减去cmd 减uuid 减revere 减name
effects_adj_printf();
break;
case EFF_MODE_CMD:
eff_mode_switch((void *)&ep->par);
res = ERR_NONE;
break;
case EFF_CRC_CMD:
if (eff_stream_crc_check((void *)&ep->par)) {
res = ERR_NONE;
} else {
res = EFF_ERR_CRC;
}
break;
#ifdef TCFG_INDICATOR_NODE_ENABLE
case EFF_INDICATOR_CMD:
res = indicator_get_param(ep, sq);
break;
#endif
case EFF_FORM_CMD:
res = form_node_get_parm(ep, sq);
break;
case EFF_ONLINE_CMD:
res = check_eff_node_online_support(ep, sq);
break;
default:
break;
}
return res;
}
static s32 eff_online_update(void *packet, u32 size, u8 sq)
{
int res = ERR_ACCEPTABLE;
struct eff_online_packet *ep = (struct eff_online_packet *)packet;
switch (ep->cmd) {
case EFF_ADJ_CMD:
if (ep->par.reserve & EFF_NODE_MERGE_UPDATE) { //多节点数据一次更新
struct eff_online_packet *new_ep = NULL;
u8 *next_node = (u8 *)ep->par.data;
u16 offset = 0;
u16 eff_struct_len = 0;
size = size - 4 - 2 - 2;//4cmd 2uuid 2reserve
/* printf("start %x, end:%x\n", (u32)ep->par.data, (u32)ep->par.data + size); */
while (offset < size && ((u32)next_node < (u32)((u32)ep->par.data + size))) {
memcpy(&eff_struct_len, next_node, 2);
if (!eff_struct_len) {
log_error("eff_struct_len error offset %d size %d\n", offset, size);
break;
}
new_ep = (struct eff_online_packet *)malloc(eff_struct_len + 4);//struct eff_struct结构长度 + cmd长度
if (new_ep) {//重组packet并做更新
/* printf("offset %d ,size %d, eff_struct_len %d\n", offset, size, eff_struct_len); */
new_ep->cmd = EFF_ADJ_CMD;
memcpy((void *)&new_ep->par, &next_node[2], eff_struct_len);
eff_online_update_base((void *)new_ep, eff_struct_len + 4, sq);
free(new_ep);
new_ep = NULL;
next_node = &next_node[eff_struct_len + 2]; //取下一个节点的数据地址
offset += (eff_struct_len + 2);//struct eff_struct长度+ 2byte len
} else {
log_error("alloc new_packet error\n");
break;
}
}
res = ERR_NONE;
} else {
res = eff_online_update_base(ep, size, sq);
}
break;
default:
res = eff_online_update_base(ep, size, sq);
break;
}
return res;
}
static void eff_send_packet(u32 id, u8 sq, u8 *packet, int size)
{
all_assemble_package_send_to_pc(id, sq, packet, size);
}
void eff_node_send_packet(u32 id, u8 sq, u8 *packet, int size)
{
all_assemble_package_send_to_pc(id, sq, packet, size);
}
static void effect_tool_callback(u8 *packet, u32 size)
{
int res = 0;
u8 id = packet[0];
u8 sq = packet[1];
u8 *eff_packet = (u8 *)&packet[2];
ASSERT(((int)eff_packet & 0x3) == 0, "packet %x size %d\n", (unsigned int)eff_packet, size - 2);
res = eff_online_update((void *)&packet[2], size - 2, sq);
switch (res) {
case EFF_ERR_TYPE_PTR_NULL:
log_debug("buf err");
eff_send_packet(REPLY_TO_TOOL, sq, (u8 *)"ER_FLOW_OPEN_BUF", strlen("ER_FLOW_OPEN_BUF"));
break;
case EFF_ERR_TYPE_ALGORITHM_NULL:
log_debug("algorithm err");
eff_send_packet(REPLY_TO_TOOL, sq, (u8 *)"ER_FLOW_OPEN_ALGORITHM", strlen("ER_FLOW_OPEN_ALGORITHM"));
break;
case ERR_COMM:
log_debug("Nack");
eff_send_packet(REPLY_TO_TOOL, sq, (u8 *)"ER", strlen("ER"));
break;
case EFF_ERR_CRC:
log_debug("crc err");
eff_send_packet(REPLY_TO_TOOL, sq, (u8 *)"ER_FLOW_CRC", strlen("ER_FLOW_CRC"));
break;
case ERR_ACCEPTABLE:
//可接受的错误,由case内部处理,返回内部数据
log_debug("accept");
break;
default:
log_debug("Ack");
eff_send_packet(REPLY_TO_TOOL, sq, (u8 *)"OK", strlen("OK"));
break;
}
}
REGISTER_DETECT_TARGET(eff_adj_target) = {
.id = EFF_CONFIG_ID,
.tool_message_deal = effect_tool_callback,
};
#endif