Files
checker_gen1/source/task/tran_for_coder2.c
2023-08-08 13:24:47 +08:00

552 lines
12 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "tran_for_coder2.h"
#include "debug.h"
#include "mymisc.h"
#include "mystdlib.h"
#include "board.h"
#include "dev_flash.h"
#include "tcp.h"
#include "prot_uc.h"
#include "handle_for_coder.h"
#include "handle_for_checker.h"
#include "coder_lib.h"
#include "PSDGenerate.h"
#include "mystring.h"
#include "coder_judge.h"
// 这个文件解析跟赋码仪相关的命令
typedef struct{
int step;// 检测注码顺序
}self_def;
static self_def g_self;
// 从机地址偏移
static inline int slave_addr_off(void)
{
if(sys_param()->slave_addr_start)
return 1;
else
return 0;
}
typedef struct{
ucport_def u;
uint8_t addrs_num;
char year[10];
struct{
char shell_code[20];
char uid_code[20];
char password[10];
uint8_t uid_pw_hex[15];
}item[10];
uint8_t ack[390];
uint8_t ack_num;
void (*doexert)(ucport_def *u);
}write_uid_def;
// 上报注码结果
static void write_uid_upmit(write_uid_def *w)
{
array_def *a=arr_creat();
arr_append(a,w->addrs_num);
// arr_appends(a,w->ack,390);
for(int i=0;i<10;i++)
{
uint8_t *d=&w->ack[i*39];
if(sys_param()->coder_ret_mode)
{
// 完整模式
arr_appends(a,d,39);
}
else{
// 精简模式
arr_appends(a,d,2);
d+=2+13+16;
arr_appends(a,d,8);
}
}
emit tran_send_signal(w->u.p,0x82,arr_temp(a));
g_self.step=0;
// 把命令字改为0x82用于接收主机应答
tran_set_busy(w->u.p,0);
w->u.cmd=0x82;
}
// 填充注码结果
static void write_uid_fillret(write_uid_def *w,int addr,int ack)
{
addr-=1;
uint8_t *d=&w->ack[(addr)*39];
w->ack_num++;
d[0]=addr+slave_addr_off();
d[1]=(ack==0xff)?0xff:(ack+0xc0);
memcpy(&d[2],w->item[addr].shell_code,13);
memcpy(&d[2+13],w->item[addr].uid_code,16);
memcpy(&d[2+13+16],w->item[addr].password,8);
if(w->ack_num>=10)
{
write_uid_upmit(w);
}
}
// 注码完成
static void write_uid_end(ucport_def *u,port_mcu *src,void *data,int ack,char *err_str)
{
write_uid_def *w=(write_uid_def *)u;
uint8_t addr=port_get_addr(src);
if(addr<=0||addr>10){
DBG_WARN("addr err:%d",addr);
return;
}
write_uid_fillret(w,addr,ack);
}
static void write_uid_return_ok(void *p)
{
write_uid_def *u=p;
array_def *a=arr_creat();
arr_append(a,u->addrs_num);
for(int i=0;i<10;i++)
{
arr_append(a,i+slave_addr_off());
arr_append(a,0);
arr_append_num(a,37,'0');
}
emit tran_send_signal(u->u.p,0x82,arr_temp(a));
tran_set_busy(u->u.p,0);
g_self.step=0;
}
static void write_del(ucport_def *u)
{
free(u);
}
static int write_uid_dolater(ucport_def *u,uint8_t cmd,array_def *data,char *err_str)
{
DBG_LOG("recv write_uid end signal.");
tran_set_busy(u->p,0);
return 0;
}
static ucport_def *write_uid(tran_def *t, uint8_t cmd,array_def *data)
{
if(arr_length(data)<140+4+1){
DBG_WARN("cmd format err.");
return 0;
}
int ret=0;
write_uid_def *u=calloc(1,sizeof(write_uid_def));
u->u.p=t;
u->u.del=write_del;
u->u.doend=write_uid_end;
u->u.dolater=write_uid_dolater;
u->addrs_num=arr_get(data,0);
memcpy(u->year,arr_data(data)+1,4);
DBG_LOG("coder, year=%s",u->year);
// 数据固定140字节如果不检测某通道则该通道填充占位符
uint8_t *d_off=arr_data(data)+4+1;
uint8_t *d_;
tran_set_busy(t,1);
for(int i=0;i<10;i++)
{
memcpy(u->item[i].shell_code,d_off+i*14+1,13);
DBG_LOG("slave:%d, shell=%s",i,u->item[i].shell_code);
// 生成uid码
ret|=coder_shell_to_uid(u->year,u->item[i].shell_code,u->item[i].uid_code);
DBG_LOG("slave:%d, uid=%s",i,u->item[i].uid_code);
// 生成存储码
ret|=coder_uid_to_save(u->item[i].uid_code,u->item[i].uid_pw_hex);
// 生成密码
GetPasswordByUidCode((uint8_t *)u->item[i].uid_code,&u->item[i].uid_pw_hex[8]);
d_=u->item[i].uid_pw_hex;
DBG_LOG("slave:%d, uid_pw=%02X %02X %02X %02X %02X %02X %02X %02X "
"%02X %02X %02X %02X ",i,d_[0],d_[1],d_[2],d_[3],d_[4],d_[5],d_[6],d_[7],
d_[8],d_[9],d_[10],d_[11]);
// 生成密码字符串
sprintf(u->item[i].password,"%02X%02X%02X%02X",u->item[i].uid_pw_hex[8],
u->item[i].uid_pw_hex[9],u->item[i].uid_pw_hex[10],u->item[i].uid_pw_hex[11]);
// 默认失败
u->ack[i*39+0]=i+slave_addr_off();
u->ack[i*39+1]=1;
if(1){
port_mcu *mcu=tran_get_portm(u->u.p,i);
// 这里打开赋码操作
if(mcu){
if(check_shell_code(u->item[i].shell_code)){
port_start(mcu,code_creat(8,4,u->item[i].uid_pw_hex));
}else{
// 管壳码无效,不注码,此时默认已ack
write_uid_fillret(u,i+1,0xff);
}
}
}
}
array_def *a=arr_creat();
arr_append(a,u->addrs_num);
if(g_self.step==1){
if(ret==0)
arr_append(a,TRAN_ERR_NONE);
else
arr_append(a,TRAN_ERR_PARAM);
}else{
arr_append(a,TRAN_ERR_STEP);
}
emit tran_reply_signal(u->u.p,arr_temp(a));
// test:稍后返回成功
//later_execute(write_uid_return_ok,u,500);
return (ucport_def *)u;
}
transmit_export(ym_checker,0x02,write_uid)
// 复检完成
static void write_uid2_end(ucport_def *u,port_mcu *src,void *data,int ack,char *err_str)
{
write_uid_def *w=(write_uid_def *)u;
uint8_t addr=port_get_addr(src);
if(addr<=0||addr>10){
DBG_WARN("addr err:%d",addr);
return;
}
addr-=1;
uint8_t *d=&w->ack[(addr)*39];
w->ack_num++;
d[0]=addr+slave_addr_off();
d[1]=ack;
memcpy(&d[2],w->item[addr].shell_code,13);
memcpy(&d[2+13],w->item[addr].uid_code,16);
memcpy(&d[2+13+16],w->item[addr].password,8);
if(w->ack_num>=10)
{
array_def *a=arr_creat();
arr_append(a,w->addrs_num);
for(int i=0;i<10;i++)
{
uint8_t *d=&w->ack[i*39];
arr_appends(a,d,2);
}
emit tran_send_signal(w->u.p,0x83,arr_temp(a));
tran_set_busy(w->u.p,0);
}
}
static ucport_def *write_uid2(tran_def *t, uint8_t cmd,array_def *data)
{
write_uid_def *u=(write_uid_def *)write_uid(t,cmd,data);
if(u)
{
u->u.doend=write_uid2_end;
}
return (ucport_def *)u;
}
// 复检,与注码动作相同,但返回值不同
transmit_export(ym_checker,0x03,write_uid2)
// 判断检测数据错误码
// 返回 errcode,1=param/0=execute,taskindex,paramindex
static uint32_t in_range_err(const uint8_t *src_data,const uint8_t *errbit)
{
const scheme_def *s=check_scheme();
const scheme_task_def *t;
int temp;
int index=0;
uint32_t ret=0;
for(int i=0;i<s->task_num;i++)
{
t=&s->task[i];
if((errbit[i/8]&(1<<(i%8)))!=0)
{
ret=(t->err&0xff)|(i<<16);
return ret;
}
for(int j=0;j<t->item_num;j++)
{
temp=src_data[index*2]|(src_data[index*2+1]<<8);
if(temp>=t->range[j].min&&temp<=t->range[j].max){
// 正常
}else{
ret=(t->range[j].err&0xff)|(1<<8)|(i<<16)|(j<<24);
return ret;
}
index++;
}
}
return ret;
}
typedef struct{
ucport_def u;
uint8_t addrs_num;
uint8_t type;
uint8_t ack[(6)*10];
uint8_t ack_num;
void (*doexert)(ucport_def *u);
}check_def;
// 检测完成
static void check_end(ucport_def *u,port_mcu *src,void *data,int ack,char *err_str)
{
check_def *w=(check_def *)u;
uint8_t addr=port_get_addr(src);
if(addr<=0||addr>10){
DBG_WARN("addr err:%d",addr);
return;
}
addr-=1;
uint32_t errcode=0;
uint8_t *ack_d=&w->ack[(addr)*6];
ack_d[0]=addr+slave_addr_off();
if(ack==-1) ack_d[1]=208; // 208表示通信超时
else ack_d[1]=ack==0?0:209;// 209表示小板返回了命令失败
// TODO: 还有4字节数据
if(data)
{
errcode=in_range_err(arr_data(data)+8+8,arr_data(data));
ack_d[2]=errcode&0xff;
ack_d[3]=(errcode>>8)&0xff;
ack_d[4]=(errcode>>16)&0xff;
ack_d[5]=(errcode>>24)&0xff;
if(ack_d[1]==0){
// 先判断主要错误,如果没有主要错误,则填充为子错误
ack_d[1]=coder_judge(arr_data(data));
if(ack_d[1]==0){
ack_d[1]=ack_d[2];
}
}
}else{
}
w->ack_num++;
if(w->ack_num>=10)
{
array_def *a=arr_creat();
arr_append(a,w->addrs_num);
arr_append(a,w->type);
arr_appends(a,w->ack,(6)*10);
emit tran_send_signal(w->u.p,0x81,arr_temp(a));
tran_set_busy(w->u.p,0);
// 把命令字改为0x81用于接收主机应答
w->u.cmd=0x81;
g_self.step=1;
}
}
static void check_return_ok(void *p)
{
check_def *u=p;
array_def *a=arr_creat();
arr_append(a,u->addrs_num);
arr_append(a,u->type);
// 固定返回6*10个字节如果不检测某通道则该通道填充占位符
for(int i=0;i<10;i++){
arr_append(a,i+slave_addr_off());
arr_append(a,0);// 成功
arr_append(a,i+1);// 返回真是序号
arr_append_num(a,3,0);
}
emit tran_send_signal(u->u.p,0x81,arr_temp(a));
tran_set_busy(u->u.p,0);
g_self.step=1;
}
static void check_del(ucport_def *u)
{
free(u);
}
static int check_dolater(ucport_def *u,uint8_t cmd,array_def *data,char *err_str)
{
DBG_LOG("recv check end signal.");
tran_set_busy(u->p,0);
return 0;
}
static ucport_def *check(tran_def *t, uint8_t cmd,array_def *data)
{
if(arr_length(data)<2){
DBG_WARN("cmd format err.");
return 0;
}
check_def *u=calloc(1,sizeof(check_def));
u->u.p=t;
u->u.del=check_del;
u->u.doend=check_end;
u->u.dolater=check_dolater;
u->addrs_num=arr_get(data,0);
u->type=arr_get(data,0);
// 默认失败
for(int i=0;i<10;i++)
{
u->ack[i*6+0]=i+slave_addr_off();
u->ack[i*6+1]=1;
}
tran_set_busy(t,1);
for(int i=0;i<10;i++)
{
if(1){
port_mcu *mcu=tran_get_portm(u->u.p,i);
// 这里打开检测
if(mcu){
port_start(mcu,check_creat(check_scheme()));
}
}
}
array_def *a=arr_creat();
arr_append(a,u->addrs_num);
arr_append(a,u->type);
arr_append(a,TRAN_ERR_NONE);
emit tran_reply_signal(u->u.p,arr_temp(a));
// test:稍后返回成功
//later_execute(check_return_ok,u,500);
return (ucport_def *)u;
}
transmit_export(ym_checker,0x01,check)
typedef struct{
rt_timer_t timer;
}live_keeper_def;
static void live_connect(live_keeper_def *t)
{
rt_tick_t tick=0;
tick=rt_tick_from_millisecond(1000);
rt_timer_control(t->timer,RT_TIMER_CTRL_SET_TIME,&tick);
rt_timer_start(t->timer);
}
static void live_recv(live_keeper_def *t)
{
rt_tick_t tick=0;
tick=rt_tick_from_millisecond(5000);
rt_timer_control(t->timer,RT_TIMER_CTRL_SET_TIME,&tick);
rt_timer_start(t->timer);
}
// cmd=0x8a
static void live_send(void *p)
{
const sys_param_def *par=sys_param();
tran_def *t=app_variable("tran",0,0);
uint16_t slave_online=0;
if(t)
slave_online=tran_get_slave_online(t);
array_def *d=arr_creat();
arr_append(d,0);
arr_append(d,0xff);
arr_append(d,0x03);
arr_append(d,par->local_id&0xff);
arr_append(d,slave_online&0xff);// 在线的小板
arr_append(d,(slave_online>>8)&0xff);
emit coder2_live_send_signal(p,0x8a,arr_temp(d));
//DBG_LOG("tcp liver:%s",str_temp(arr_string(d)));
}
static void init_for_tcp(void *t)
{
void *tcp=app_variable("tcp",0,0);
void *protu=app_variable("protu",0,0);
if(tcp&&protu){
live_keeper_def *live=calloc(1,sizeof(live_keeper_def));
live->timer=rt_timer_create("live_t",live_send,live,
rt_tick_from_millisecond(1000),
RT_TIMER_FLAG_PERIODIC|RT_TIMER_FLAG_SOFT_TIMER);
protu_codec_set(protu,protu_find_codec("ym_checker"));
connect(tcp,tcp_connect_signal,0,live,live_connect);
connect(tcp,tcp_recv_signal,0,live,live_recv);
connect(live,coder2_live_send_signal,0,protu,protu_send_call);
DBG_LOG("tcp liver created");
}else{
DBG_WARN("can not fond variable \"tcp\" or/and \"protu\"");
}
}
// 如果本机为赋码仪并且连接类型为tcp
// 初始化心跳
static int init_live_keeper(void)
{
const sys_param_def *par=sys_param();
if((strcmp(par->device_type,"coder")==0)&&(strcmp(par->host_if,"utcp")==0))
{
app_valid_call("protu",init_for_tcp,0);
}else{
DBG_LOG("tcp liver not created");
}
return 0;
}
app_init_export(init_live_keeper);