Files
checker_slave/source/task/tran_for_coder2.c
2023-06-15 18:11:28 +08:00

430 lines
9.2 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"
// 这个文件解析跟赋码仪相关的命令
// 从机地址偏移
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_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);
// 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));
tran_set_busy(w->u.p,0);
}
}
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);
}
static void write_del(ucport_def *u)
{
free(u);
}
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;
}
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->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_;
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码
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);
// 生成存储码
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]);
}
// 默认失败
for(int i=0;i<10;i++)
{
u->ack[i*39+0]=i+slave_addr_off();
u->ack[i*39+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,code_creat(8,4,u->item[i].uid_pw_hex));
}
}
}
array_def *a=arr_creat();
arr_append(a,u->addrs_num);
arr_append(a,0);
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)
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;
uint8_t *ack_d=&w->ack[(addr)*6];
ack_d[0]=addr+slave_addr_off();
ack_d[1]=ack;
// TODO: 还有4字节数据
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);
}
}
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_num(a,4,0);
}
emit tran_send_signal(u->u.p,0x81,arr_temp(a));
tran_set_busy(u->u.p,0);
}
static void check_del(ucport_def *u)
{
free(u);
}
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->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,0);
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));
}
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);
}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);
}
return 0;
}
app_init_export(init_live_keeper);