#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" // 这个文件解析跟赋码仪相关的命令 // 从机地址偏移 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)); //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);