Files
coder_stm32f1/source/task/tran_for_coder2ch.c

407 lines
8.6 KiB
C
Raw Normal View History

#include "tran_for_coder2.h"
#include "tran_for_coder2ch.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 "JQ_PSDGenerate.h"
#include "mystring.h"
#include "coder_judge.h"
#include "JQ_UIDGenerate.h"
// JQ模块在检测时注码
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)
{
int ack=0;
array_def *a=arr_creat();
arr_append(a,w->addrs_num);
// arr_appends(a,w->ack,390);
for(int i=0;i<w->addrs_num;i++)
{
uint8_t *d=&w->ack[i*38];
ack|=d[1];
if(sys_param()->coder_ret_mode)
{
// 完整模式
arr_appends(a,d,38);
}
else{
// 精简模式
arr_appends(a,d,2);
d+=2+13+15;
arr_appends(a,d,8);
}
}
// emit tran_send_signal(w->u.p,0x82,arr_temp(a));
// 发送赋码结束信号
emit code2_end_signal(w->u.p,ack,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)*38];
w->ack_num++;
d[0]=addr+slave_addr_off();
//d[1]=((ack==0xff)||(ack==0x00))?ack:(ack+0xc0);
d[1]=ack;
memcpy(&d[2],w->item[addr].shell_code,13);
memcpy(&d[2+13],w->item[addr].uid_code,15);
memcpy(&d[2+13+15],w->item[addr].password,8);
if(w->ack_num>=w->addrs_num)
{
write_uid_upmit(w);
}
}
// 判断检测数据错误码
// 返回 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;
}
// 注码完成
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>w->addrs_num){
DBG_WARN("addr err:%d",addr);
return;
}
uint32_t errcode=0;
if(ack==0)
{
if(data)
{
errcode=in_range_err(arr_data(data)+8+8,arr_data(data));
ack=coder_judge_jq(arr_data(data));
if(ack==0){
ack=errcode&0xff;
}
}else{
ack=0xd0;
DBG_WARN("check return data is none.");
}
}else{
ack=0xd0;// 通信超时
}
DBG_LOG("addr=%d,errcode=%d",addr,ack);
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<u->addrs_num;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)<14+4+1){
DBG_WARN("cmd format err.");
DBG_WARN("data=%s",str_temp(arr_string(data)));
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<u->addrs_num;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_jq(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);
UidCode_YM2JQ((PST_JQUID_TYPEDEF)u->item[i].uid_pw_hex,(PST_YMUID_TYPEDEF)u->item[i].uid_code);
// 生成密码
JQ_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*38+0]=i+slave_addr_off();
u->ack[i*38+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,code2_creat(8,4,u->item[i].uid_pw_hex));
}else{
// 管壳码无效,不注码,此时默认已ack
// 管壳码无效不视为失败
ret=0;
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);
// 发送注码开始信号
emit code2_start_signal(u->u.p);
return (ucport_def *)u;
}
transmit_export(ym_checker,0x02,write_uid)
typedef struct{
rt_timer_t timer;
void *protu;
}live_keeper_def;
static void live_start(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);
//rt_timer_stop(t->timer);
}
// cmd=0x8a
static void live_send(void *p)
{
live_keeper_def *live=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);
}
//protu_codec_set(live->protu,protu_find_codec("ym_checker"));
array_def *d=arr_creat();
arr_append(d,coder_extract_chip(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("send liver data.");
}
static void init_for_coder2ch(void *t)
{
void *protu=app_variable("protu",0,0);
if(protu){
live_keeper_def *live=calloc(1,sizeof(live_keeper_def));
live->protu=protu;
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(protu,protu_recv_signal,0,live,live_recv);
connect(live,coder2_live_send_signal,0,protu,protu_send_call);
DBG_LOG("coder2ch liver created");
live_start(live);
}else{
DBG_WARN("can not fond variable \"protu\"");
}
}
// 如果本机为赋码仪并且连接类型为tcp
// 初始化心跳
static int init_live_keeper(void)
{
const sys_param_def *par=sys_param();
app_valid_call("protu",init_for_coder2ch,0);
return 0;
}
app_init_export(init_live_keeper);