From d1e617afd3e9c1e249eea850f71921fb0d3c6885 Mon Sep 17 00:00:00 2001 From: ranchuan Date: Thu, 21 Dec 2023 18:51:58 +0800 Subject: [PATCH] =?UTF-8?q?=20=20=E5=AE=9E=E7=8E=B0=E8=B5=8B=E7=A0=81?= =?UTF-8?q?=E4=BB=AA=E5=91=BD=E4=BB=A4=20=20=20=E5=8D=87=E7=BA=A7=E5=B0=8F?= =?UTF-8?q?=E6=9D=BF=E7=A8=8B=E5=BA=8F=E5=A4=B1=E8=B4=A5=E6=97=B6=E5=81=9C?= =?UTF-8?q?=E6=AD=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ReadMe.txt | 3 + checker_host.pro | 8 ++ complier_info.h | 2 +- elec/JQ_PSDGenerate.cpp | 86 ++++++++++++++ elec/JQ_PSDGenerate.h | 12 ++ elec/JQ_UIDGenerate.cpp | 250 +++++++++++++++++++++++++++++++++++++++ elec/JQ_UIDGenerate.h | 37 ++++++ elec/PSDGenerate.cpp | 60 ++++++++++ elec/PSDGenerate.h | 13 +++ elec/coder_lib.cpp | 251 ++++++++++++++++++++++++++++++++++++++++ elec/coder_lib.h | 41 +++++++ elec/elec_judge.cpp | 2 +- info.json | 2 +- interface/if_can.cpp | 4 +- prot/prot_cmdline.cpp | 68 +++++++++-- prot/prot_cmdline.h | 6 + prot_cmd/cmd_coder.cpp | 174 +++++++++++++++++++++++++--- prot_cmd/cmd_coder.h | 59 +++++++++- prot_cmd/cmd_pc.cpp | 187 +++++++++++++++++++++++++++++- prot_cmd/cmd_pc.h | 36 +++++- prot_cmd/cmd_slave.cpp | 31 ++++- prot_cmd/cmd_slave.h | 2 + 22 files changed, 1291 insertions(+), 43 deletions(-) create mode 100644 elec/JQ_PSDGenerate.cpp create mode 100644 elec/JQ_PSDGenerate.h create mode 100644 elec/JQ_UIDGenerate.cpp create mode 100644 elec/JQ_UIDGenerate.h create mode 100644 elec/PSDGenerate.cpp create mode 100644 elec/PSDGenerate.h create mode 100644 elec/coder_lib.cpp create mode 100644 elec/coder_lib.h diff --git a/ReadMe.txt b/ReadMe.txt index 962a74c..0e77c1b 100644 --- a/ReadMe.txt +++ b/ReadMe.txt @@ -22,4 +22,7 @@ 制定任务执行命令 2023.12.20 任务执行命令验证写入电阻校准值成功 +2023.12.21 + 实现赋码仪命令 + 升级小板程序失败时停止 diff --git a/checker_host.pro b/checker_host.pro index dc35b3b..6a7eddb 100644 --- a/checker_host.pro +++ b/checker_host.pro @@ -26,6 +26,10 @@ SOURCES += \ base/crc.cpp \ base/debug.cpp \ base/mycfg.cpp \ + elec/JQ_PSDGenerate.cpp \ + elec/JQ_UIDGenerate.cpp \ + elec/PSDGenerate.cpp \ + elec/coder_lib.cpp \ elec/elec_judge.cpp \ elec/mystring.cpp \ interface/codec.cpp \ @@ -56,6 +60,10 @@ HEADERS += \ base/debug.h \ base/file.h \ base/mycfg.h \ + elec/JQ_PSDGenerate.h \ + elec/JQ_UIDGenerate.h \ + elec/PSDGenerate.h \ + elec/coder_lib.h \ elec/elec_judge.h \ elec/mystring.h \ interface/codec.h \ diff --git a/complier_info.h b/complier_info.h index 6bd4d7e..ba45e65 100644 --- a/complier_info.h +++ b/complier_info.h @@ -6,7 +6,7 @@ -#define BUILD_DATE "2023-12-20 17:13:21" +#define BUILD_DATE "2023-12-21 18:29:22" diff --git a/elec/JQ_PSDGenerate.cpp b/elec/JQ_PSDGenerate.cpp new file mode 100644 index 0000000..d43d15a --- /dev/null +++ b/elec/JQ_PSDGenerate.cpp @@ -0,0 +1,86 @@ +#include "JQ_PSDGenerate.h" + +/******************************************************************************************************************** + * 新版密码支持BCD码 * +********************************************************************************************************************/ +static uint32_t GetSpecialCodeIndex(uint8_t ucSpecialCode) +{ + if (ucSpecialCode >= '0' && ucSpecialCode <= '9') + { + return ucSpecialCode - 0x30; + } + else if (ucSpecialCode >= 'A' && ucSpecialCode <= 'Z') + { + return ucSpecialCode - 'A' + 10; + } + else if (ucSpecialCode >= 'a' && ucSpecialCode <= 'z') + { + return ucSpecialCode - 'a' + 36; + } + else + return 63; +} + +static uint32_t GetiDateInfo(uint8_t *ucpDate) +{ + uint8_t ucMonth = ucpDate[0]*10 + ucpDate[1]; + uint8_t ucDay = ucpDate[2]*10 + ucpDate[3]; + + return ucMonth << 5 | ucDay; +} + +//public static string GetPasswordByShellCode(string shellcode) +//{ +// string ssp = shellcode.Substring(7, 1); +// string sdate = shellcode.Substring(3, 4); +// string sindex = shellcode.Substring(8, 5); + +// UInt32 u32BCD = (UInt32)(((GetiDateInfo(sdate) & 0x1FF) << 23) | +// ((GetSpecialCodeIndex(ssp) & 0x3F) << 17) | +// (GetiIndex(sindex) & 0x1FFFF)); + +// return U32tohexstr(u32BCD); + +//} + +uint8_t JQ_GetPasswordByUidCode(const uint8_t *uidcode,uint8_t* psd) +{ + uint8_t ucSpecialCode = 0; + uint8_t usaDate[4] = {0}; + uint32_t ulIndex = 0; + uint32_t ulBCDPsd = 0; + uint8_t i=0; + + + //581900230A12345 + ucSpecialCode = uidcode[9]; + for(i=5;i<9;i++) + usaDate[i-5] = uidcode[i]-0x30; + + for(i=10;i<15;i++) + { + ulIndex *= 10; + ulIndex += (uidcode[i]-0x30); + } + + ulBCDPsd = (GetiDateInfo(usaDate) & 0x1FF) << 23 | + (GetSpecialCodeIndex(ucSpecialCode) & 0x3F) << 17 | + ulIndex & 0x1FFFF; + +// psd[0] = (ulBCDPsd&0xFF000000)>>24; +// psd[1] = (ulBCDPsd&0x00FF0000)>>16; +// psd[2] = (ulBCDPsd&0x0000FF00)>>8; +// psd[3] = ulBCDPsd&0x000000FF; + // 反序 + psd[3] = (ulBCDPsd&0xFF000000)>>24; + psd[2] = (ulBCDPsd&0x00FF0000)>>16; + psd[1] = (ulBCDPsd&0x0000FF00)>>8; + psd[0] = ulBCDPsd&0x000000FF; + return 0; +} + + + + + + diff --git a/elec/JQ_PSDGenerate.h b/elec/JQ_PSDGenerate.h new file mode 100644 index 0000000..f3b311f --- /dev/null +++ b/elec/JQ_PSDGenerate.h @@ -0,0 +1,12 @@ +#ifndef __JQ_PSDGENERATE_H__ +#define __JQ_PSDGENERATE_H__ +#include +#include +#include "stdint-gcc.h" + + +uint8_t JQ_GetPasswordByUidCode(const uint8_t *uidcode,uint8_t* psd); + + + +#endif diff --git a/elec/JQ_UIDGenerate.cpp b/elec/JQ_UIDGenerate.cpp new file mode 100644 index 0000000..d166075 --- /dev/null +++ b/elec/JQ_UIDGenerate.cpp @@ -0,0 +1,250 @@ +#include "JQ_UIDGenerate.h" +#include "stdint-gcc.h" +#include "string.h" +//#include "Common.h" + + +static uint32_t UINT32_ENDIAN_CHANGE(uint32_t val); + +static bool YMUid_Valid_check(uint8_t *u8ArrayYMUid); + +static uint8_t _CalcCrc8(uint8_t *Ptr,uint8_t num); + + +bool UidCode_JQ2YM(const PST_JQUID_TYPEDEF pstJQUID,PST_YMUID_TYPEDEF pstYMUID) +{ + UNION_VALUE_CHANGE_TYPEDEF stDate; + UNION_VALUE_CHANGE_TYPEDEF stSerialCode ; + uint8_t i=0; + uint16_t u16Year = 0; + uint16_t u16Month = 0; + uint8_t u8Day = 0; + uint16_t u16Date =0; + ST_JQUID_TYPEDEF _stJQUID; + + uint16_t sum=0; + + for(i=0;i<8;i++) + { + sum=sum+pstJQUID->u8ArrayJQUidCode[i]; + _stJQUID.u8ArrayJQUidCode[7-i]=pstJQUID->u8ArrayJQUidCode[i]; //逆序detid + } + memcpy(pstJQUID->u8ArrayJQUidCode,_stJQUID.u8ArrayJQUidCode,8); + + if(sum == 0) //全0时,CRC码也为0,所以需要避免这种情况 + return 0; + + + if(pstJQUID->u8ArrayJQUidCode[7] != _CalcCrc8(pstJQUID->u8ArrayJQUidCode,7)) + return false; + + pstYMUID->ucArrayYMUidCode[0] = pstJQUID->u8ArrayJQUidCode[0]/10+0x30; + pstYMUID->ucArrayYMUidCode[1] = pstJQUID->u8ArrayJQUidCode[0]%10+0x30; + + + + pstYMUID->ucArrayYMUidCode[4] = pstJQUID->u8ArrayJQUidCode[1];//特征码 + + u16Date = pstJQUID->u8ArrayJQUidCode[2]; + u16Date = u16Date<<8 | pstJQUID->u8ArrayJQUidCode[3]; + + u16Year = (u16Date>>9)&0x7F; + u16Month = (u16Date>>5)&0x0F; + u8Day = u16Date&0x1F; + + pstYMUID->ucArrayYMUidCode[2] = u16Year/10+0x30; + pstYMUID->ucArrayYMUidCode[3] = u16Year%10+0x30; + + pstYMUID->ucArrayYMUidCode[5] = u16Month/10+0x30; + pstYMUID->ucArrayYMUidCode[6] = u16Month%10+0x30; + + pstYMUID->ucArrayYMUidCode[7] = u8Day/10+0x30; + pstYMUID->ucArrayYMUidCode[8] = u8Day%10+0x30; + + + memcpy(stSerialCode.u8Val+1,pstJQUID->u8ArrayJQUidCode+4,3); + stSerialCode.u32Value = UINT32_ENDIAN_CHANGE( stSerialCode.u32Value); + + pstYMUID->ucArrayYMUidCode[DEF_YM_SPECIALCODE_INDEX] = (stSerialCode.u32Value>>17) & 0x7F; + stSerialCode.u32Value = stSerialCode.u32Value&0x1FFFF; + + for(i=14;i>=10;i--) + { + pstYMUID->ucArrayYMUidCode[i] = (stSerialCode.u32Value%10+0x30); + stSerialCode.u32Value = stSerialCode.u32Value/10; + + } + + + if(!YMUid_Valid_check(pstYMUID->ucArrayYMUidCode)) + return false; + + return true; +} + +bool UidCode_JQ2YM_NoBackwardSequence(const PST_JQUID_TYPEDEF pstJQUID,PST_YMUID_TYPEDEF pstYMUID) +{ + UNION_VALUE_CHANGE_TYPEDEF stDate; + UNION_VALUE_CHANGE_TYPEDEF stSerialCode ; + uint8_t i=0; + uint16_t u16Year = 0; + uint16_t u16Month = 0; + uint8_t u8Day = 0; + uint16_t u16Date =0; + + if(pstJQUID->u8ArrayJQUidCode[7] != _CalcCrc8(pstJQUID->u8ArrayJQUidCode,7)) + return false; + + pstYMUID->ucArrayYMUidCode[0] = pstJQUID->u8ArrayJQUidCode[0]/10+0x30; + pstYMUID->ucArrayYMUidCode[1] = pstJQUID->u8ArrayJQUidCode[0]%10+0x30; + + + + pstYMUID->ucArrayYMUidCode[4] = pstJQUID->u8ArrayJQUidCode[1];//特征码 + + u16Date = pstJQUID->u8ArrayJQUidCode[2]; + u16Date = u16Date<<8 | pstJQUID->u8ArrayJQUidCode[3]; + + u16Year = (u16Date>>9)&0x7F; + u16Month = (u16Date>>5)&0x0F; + u8Day = u16Date&0x1F; + + pstYMUID->ucArrayYMUidCode[2] = u16Year/10+0x30; + pstYMUID->ucArrayYMUidCode[3] = u16Year%10+0x30; + + pstYMUID->ucArrayYMUidCode[5] = u16Month/10+0x30; + pstYMUID->ucArrayYMUidCode[6] = u16Month%10+0x30; + + pstYMUID->ucArrayYMUidCode[7] = u8Day/10+0x30; + pstYMUID->ucArrayYMUidCode[8] = u8Day%10+0x30; + + + memcpy(stSerialCode.u8Val+1,pstJQUID->u8ArrayJQUidCode+4,3); + stSerialCode.u32Value = UINT32_ENDIAN_CHANGE( stSerialCode.u32Value); + + pstYMUID->ucArrayYMUidCode[DEF_YM_SPECIALCODE_INDEX] = (stSerialCode.u32Value>>17) & 0x7F; + stSerialCode.u32Value = stSerialCode.u32Value&0x1FFFF; + + for(i=14;i>=10;i--) + { + pstYMUID->ucArrayYMUidCode[i] = (stSerialCode.u32Value%10+0x30); + stSerialCode.u32Value = stSerialCode.u32Value/10; + + } + + + if(!YMUid_Valid_check(pstYMUID->ucArrayYMUidCode)) + return false; + + return true; +} + + + +bool UidCode_YM2JQ(PST_JQUID_TYPEDEF pstJQUID,const PST_YMUID_TYPEDEF pstYMUID) +{ + UNION_VALUE_CHANGE_TYPEDEF stSerialCode ; + uint8_t i=0; + uint16_t u16Year = 0; + uint16_t u16Month = 0; + uint8_t u8Day = 0; + uint16_t u16Date =0; + + if(!YMUid_Valid_check(pstYMUID->ucArrayYMUidCode)) + return false; + + + + stSerialCode.u32Value = 0; + + pstJQUID->u8ArrayJQUidCode[0] = (pstYMUID->ucArrayYMUidCode[0]-0x30)*10 + (pstYMUID->ucArrayYMUidCode[1]-0x30);//企业代码 + pstJQUID->u8ArrayJQUidCode[1] = pstYMUID->ucArrayYMUidCode[4];//特征码 + + u16Year = (pstYMUID->ucArrayYMUidCode[2]-0x30)*10 + (pstYMUID->ucArrayYMUidCode[3]-0x30); + u16Month = (pstYMUID->ucArrayYMUidCode[5]-0x30)*10 + (pstYMUID->ucArrayYMUidCode[6]-0x30); + u8Day = (pstYMUID->ucArrayYMUidCode[7]-0x30)*10 + (pstYMUID->ucArrayYMUidCode[8]-0x30); + u16Date = (u16Year&0x7F)<<9|(u16Month&0x0F)<<5|(u8Day&0x1F); + pstJQUID->u8ArrayJQUidCode[2] = (u16Date&0xFF00)>>8; + pstJQUID->u8ArrayJQUidCode[3] = (u16Date&0x00FF); + + + for(i=10;i<15;i++) + { + stSerialCode.u32Value = stSerialCode.u32Value*10 + (pstYMUID->ucArrayYMUidCode[i]-0x30); + } + + stSerialCode.u32Value |= pstYMUID->ucArrayYMUidCode[DEF_YM_SPECIALCODE_INDEX]<<17; + stSerialCode.u32Value = UINT32_ENDIAN_CHANGE(stSerialCode.u32Value);; + + memcpy(pstJQUID->u8ArrayJQUidCode+4,stSerialCode.u8Val+1,3); + + pstJQUID->u8ArrayJQUidCode[7] = _CalcCrc8(pstJQUID->u8ArrayJQUidCode,7); + + return true; +} + + + +//============================================================================// +//8位CRC效验计算,只计算缓存区前6个字节 +//输入参数:需要计算数据缓存区头指针 +//返 回 值:效验值 +//============================================================================// +static uint8_t _CalcCrc8(uint8_t *Ptr,uint8_t num) +{ + uint8_t i,j,crc = 0; + + for (j = 0; j < num; j++) + { + crc ^= *(Ptr+j); + for ( i = 0; i < 8; i++) + { + if ((crc & 0x01) != 0) + { + crc >>= 1; + crc ^= 0x8c; + } + else + { + crc >>= 1; + } + } + } + return crc; +} + +static bool YMUid_Valid_check(uint8_t *u8ArrayYMUid) +{ + uint8_t i=0; + uint8_t u8ValidDataCounter = 0; + + for(i=0;i<15;i++) + { + if(u8ArrayYMUid[i] >= '0' && u8ArrayYMUid[i] <= '9') + { + u8ValidDataCounter++; + continue; + } + if(u8ArrayYMUid[i] >= 'A' && u8ArrayYMUid[i] <= 'Z') + { + u8ValidDataCounter++; + continue; + } + if(u8ArrayYMUid[i] >= 'a' && u8ArrayYMUid[i] <= 'z') + { + u8ValidDataCounter++; + continue; + } + } + + if(u8ValidDataCounter < 7) + return false; + return true; +} + +static uint32_t UINT32_ENDIAN_CHANGE(uint32_t val) +{ + + return ((( val & 0x000000ff)<< 24 ) | ( ( val & 0x0000ff00 ) << 8 ) | ( ( val & 0x00ff0000 ) >> 8 ) | ( ( val & 0xff000000 ) >> 24 )); +} + diff --git a/elec/JQ_UIDGenerate.h b/elec/JQ_UIDGenerate.h new file mode 100644 index 0000000..f2a7053 --- /dev/null +++ b/elec/JQ_UIDGenerate.h @@ -0,0 +1,37 @@ +#ifndef __JQ_UIDGENERATE_H__ +#define __JQ_UIDGENERATE_H__ +#include +#include +#include "stdint-gcc.h" + + + +#define DEF_YM_SPECIALCODE_INDEX 9 + +#pragma pack(1) +typedef struct +{ + unsigned char ucArrayYMUidCode[15]; +}ST_YMUID_TYPEDEF,*PST_YMUID_TYPEDEF; + +typedef struct +{ + uint8_t u8ArrayJQUidCode[8]; +}ST_JQUID_TYPEDEF,*PST_JQUID_TYPEDEF; + +typedef union +{ + uint32_t u32Value; + uint8_t u8Val[4]; +}UNION_VALUE_CHANGE_TYPEDEF,*PST_VALUE_CHANGE_TYPEDEF; + +#pragma pack() + +bool UidCode_YM2JQ(PST_JQUID_TYPEDEF pstJQUID,const PST_YMUID_TYPEDEF pstYMUID); + +bool UidCode_JQ2YM(const PST_JQUID_TYPEDEF pstJQUID,PST_YMUID_TYPEDEF pstYMUID); + +bool UidCode_JQ2YM_NoBackwardSequence(const PST_JQUID_TYPEDEF pstJQUID,PST_YMUID_TYPEDEF pstYMUID); + +#endif + diff --git a/elec/PSDGenerate.cpp b/elec/PSDGenerate.cpp new file mode 100644 index 0000000..8a9eea6 --- /dev/null +++ b/elec/PSDGenerate.cpp @@ -0,0 +1,60 @@ +#include "PSDGenerate.h" + +/******************************************************************************************************************** + * 新版密码支持BCD码 * +********************************************************************************************************************/ + +uint64_t Scramble(uint64_t number, uint64_t max) +{ + int i = 0; + // some random values + uint64_t scramblers[] = { 3, 5, 7, 31, 343, 2348, 89897 }; + number += (max / 7) + 6; + number %= max; + // shuffle according to divisibility + for (i = 0; i < 7; i++) + { + if (scramblers[i] >= max / 3) break; + number = ((number * scramblers[i]) % max) + + ((number * scramblers[i]) / max); + } + + + return number % max; +} + +int GetPasswordByUidCode(const uint8_t *uidcode,uint8_t* psd) +{ + uint64_t val = 0,val1 = 0; + int i= 0; + uint64_t ulBCDPsd = 0; + + for(i=2;i<10;i++) + { + val *=10; + val += uidcode[i]-0x30; + } + val += uidcode[10]; + + for(i=11;i<16;i++) + { + val1 *=10; + val1 += uidcode[i]-0x30; + } + val = val + val1; + ulBCDPsd = Scramble(val, 0xFFFFFFFF); + + + psd[0] = (ulBCDPsd&0xFF000000)>>24; + psd[1] = (ulBCDPsd&0x00FF0000)>>16; + psd[2] = (ulBCDPsd&0x0000FF00)>>8; + psd[3] = ulBCDPsd&0x000000FF; + + return 0; +} + + + + + + diff --git a/elec/PSDGenerate.h b/elec/PSDGenerate.h new file mode 100644 index 0000000..969b613 --- /dev/null +++ b/elec/PSDGenerate.h @@ -0,0 +1,13 @@ +#ifndef __PSDGENERATE_H__ +#define __PSDGENERATE_H__ +#include +#include +#include "stdint.h" + + + +int GetPasswordByUidCode(const uint8_t *uidcode,uint8_t* psd); + + + +#endif diff --git a/elec/coder_lib.cpp b/elec/coder_lib.cpp new file mode 100644 index 0000000..2c64f62 --- /dev/null +++ b/elec/coder_lib.cpp @@ -0,0 +1,251 @@ +#include "coder_lib.h" +#include "string.h" +#include "elec/mystring.h" +#include "stdio.h" +#include "base/crc.h" + + +/* ++-----------------------------------------------------------------------+ +| 管壳码格式(ascii) | ++-----------------------------------------------------------------------+ +| 13byte | ++-----------------------------------------------------------------------+ +| 雷管厂代号 | 生产年份 | 生产月份 | 生产日 | 特征号 | 流水号 | ++------------+------------+------------+----------+----------+----------+ +| 2byte | 1byte | 2byte | 2byte | 1byte | 5byte | ++-----------------------------------------------------------------------+ + + + ++-----------------------------------------------------------------------+ +| UID码格式(ascii) | ++-----------------------------------------------------------------------+ +| 16byte | ++-----------------------------------------------------------------------+ +| 芯片厂代号 | 生产年份 | 雷管厂代号 | 月 | 日 | 特征码 | 盒号 | 序号 | ++------------+----------+------------+-----+-----+--------+------+------+ +| 2byte | 2byte | 2byte |2byte|2byte| 1byte | 3byte| 2byte| ++-----------------------------------------------------------------------+ + + + ++-----------------------------------------------------------------------+ +| UID码存储格式(hex) | ++-----------------------------------------------------------------------+ +| 8byte | ++-----------------------------------------------------------------------+ +| 芯片厂代号 | 雷管厂代号 | 年月日 | 特征码盒号序号 | crc8 | ++------------+------------+------------------+-------------------+------+ +| 1byte | 1byte | 2byte(大端) | 3byte(大端) | 1byte| ++-----------------------------------------------------------------------+ + + + +年月日(ascii)->年月日(hex) +年(y),月(m),日(d) +time=((((y[0]-'0')*10)+(y[1]-'0'))<<9)|\ + ((((m[0]-'0')*10)+(m[1]-'0'))<<5)|\ + (((d[0]-'0')*10)+(d[1]-'0')) + +特征码盒号序号(ascii)->特征码盒号序号(hex) +特征码(c),盒号(b),序号(i) +code=c*10000+((b[0]-'0')*100+(b[1]-'0')*10+(b[2]-'0'))*100+\ + ((i[1]-'0')*10+(i[2]-'0')) + + +*/ + + + + + +// 根据管壳码和年份信息生成uid的年份信息 +static int coder_calc_year(const char *year,const char shell_year,char *uid_year) +{ + int y=0; + for(int i=0;i<4;i++) + { + y*=10;y+=year[i]-'0'; + } + // year是实时数据,鉴于12月31生产的雷管,year可能不同 + // 此时year-1来保证与uid码上的相同 +// if(year[3]!=shell_year) +// y--; + for(int i=0;i<10;i++){ + if((y%10)!=(shell_year-'0')) + y--; + else + break; + } + uid_year[0]=y%100/10+'0'; + uid_year[1]=y%10+'0'; + if(uid_year[1]==shell_year) + return 0; + else + return -1; +} + +// 返回1则shell_code有效 +int check_shell_code(const char *shell_code) +{ + for(int i=0;i<13;i++) + { + if(shell_code[i]==0) + return 0; + } + if(strncmp("0000000000000",shell_code,13)==0) + return 0; + return 1; +} + +// 管壳码转uid码 +int coder_shell_to_uid(const char *year,const char *shell_code,char *uid_code) +{ + int ret=0; + memset(uid_code,0,16); + // 添加芯片企业代号(2byte) + memcpy(&uid_code[0],"AD",2); + // 添加年份(2y=byte) + ret=coder_calc_year(year,shell_code[2],&uid_code[2]); + // 添加雷管厂代号(2byte) + memcpy(&uid_code[4],&shell_code[0],2); + // 添加月日特征码流水号 + memcpy(&uid_code[6], &shell_code[3],10); + + if(ret){ + memset(uid_code,0,16); + } + return ret; +} + + + + + + +// JQ管壳码转uid码 +int coder_shell_to_uid_jq(const char *year,const char *shell_code,char *uid_code) +{ + int ret=0; + memset(uid_code,0,16); + // 添加雷管厂代号(2byte) + memcpy(&uid_code[0],&shell_code[0],2); + // 添加年份(2y=byte) + ret=coder_calc_year(year,shell_code[2],&uid_code[2]); + // 添加0(1byte) + memcpy(&uid_code[4],"0",1); + // 添加月日特征码流水号 + memcpy(&uid_code[5], &shell_code[3],10); + if(ret){ + memset(uid_code,0,16); + } + return ret; +} + + + + + + +// 转换hex字符串为一个byte +static int coder_strhex_to_byte(const char *str_hex) +{ + char buff[3]={0}; + buff[0]=str_hex[0]; + buff[1]=str_hex[1]; + return str_ahextoi(buff); +} +// 转换int字符串为一个整形 +static int coder_strint_to_byte(const char *str_int,int len) +{ + char buff[10]={0}; + if(len>10) return 0; + memcpy(buff,str_int,len); + return str_atoi(buff); +} + +// uid码转存储码 +int coder_uid_to_save(const char *uid_code,uint8_t *save_code) +{ + uint16_t ymd=0; + uint32_t feature=0; + save_code[0]=coder_strhex_to_byte(&uid_code[0]); + save_code[1]=coder_strhex_to_byte(&uid_code[4]); + ymd=coder_strint_to_byte(&uid_code[2],2)<<9; + ymd|=coder_strint_to_byte(&uid_code[6],2)<<5; + ymd|=coder_strint_to_byte(&uid_code[8],2); + save_code[2]=ymd>>8; + save_code[3]=ymd&0xff; + // 文档 YM-UID设计V1.2 - 2023.xlsx 规定*10000,实际是*100000 + feature=uid_code[10]*100000; + feature+=coder_strint_to_byte(&uid_code[11],3)*100; + feature+=coder_strint_to_byte(&uid_code[14],2); + save_code[4]=feature>>16; + save_code[5]=feature>>8; + save_code[6]=feature&0xff; + save_code[7]=crc::crc8(save_code,7); + return 0; +} + +// 转换byte为hex字符串 +static int coder_byte_to_strhex(const uint8_t byte,char *str_hex) +{ + char buff[10]={0}; + sprintf(buff,"%02X",byte); + str_hex[0]=buff[0]; + str_hex[1]=buff[1]; + return 0; +} +// 转换int为int字符串 +static int coder_int_to_strint(const int n,char *str_int,int len) +{ + char buff[10]={0}; + sprintf(buff,"%05d",n); + memcpy(str_int,buff+(strlen(buff)-len),len); + return 0; +} + +// 存储码转uid +int coder_save_to_uid(const uint8_t *save_code,char *uid_code) +{ + uint16_t ymd=0; + uint32_t feature=0; + int ret=0; + if(save_code[7]!=crc::crc8((uint8_t *)save_code,7)) + { + return -1; + } + ret|=coder_byte_to_strhex(save_code[0],&uid_code[0]); + ret|=coder_byte_to_strhex(save_code[1],&uid_code[4]); + ymd=(save_code[2]<<8)|save_code[3]; + feature=(save_code[4]<<16)|(save_code[5]<<8)|(save_code[6]); + ret|=coder_int_to_strint(ymd>>9,&uid_code[2],2); + ret|=coder_int_to_strint((ymd>>5)&0x0f,&uid_code[6],2); + ret|=coder_int_to_strint((ymd)&0x1f,&uid_code[8],2); + uid_code[10]=feature/100000; + ret|=coder_int_to_strint(feature%100000/100,&uid_code[11],3); + ret|=coder_int_to_strint(feature%100,&uid_code[14],2); + return ret; +} + + + +// uid码转管壳码 +int coder_uid_to_shell(const char *uid_code,char *shell_code) +{ + memset(shell_code,0,13); + // 添加雷管厂代号 + memcpy(&shell_code[0],&uid_code[4],2); + // 添加生产年份 + memcpy(&shell_code[2],&uid_code[3],1); + // 添加月日特征码流水号 + memcpy(&shell_code[3],&uid_code[6],10); + + return 0; +} + + + + + diff --git a/elec/coder_lib.h b/elec/coder_lib.h new file mode 100644 index 0000000..0702121 --- /dev/null +++ b/elec/coder_lib.h @@ -0,0 +1,41 @@ +#ifndef coder_lib_h__ +#define coder_lib_h__ + + +#include "stdint.h" + + + + + + + +// 返回1则shell_code有效 +int check_shell_code(const char *shell_code); + + +// 管壳码转uid码 +int coder_shell_to_uid(const char *year,const char *shell_code,char *uid_code); + +// uid码转存储码 +int coder_uid_to_save(const char *uid_code,uint8_t *save_code); + +// 存储码转uid +int coder_save_to_uid(const uint8_t *save_code,char *uid_code); + +// uid码转管壳码 +int coder_uid_to_shell(const char *uid_code,char *shell_code); + + +int coder_shell_to_uid_jq(const char *year,const char *shell_code,char *uid_code); + + + + + + + + + +#endif + diff --git a/elec/elec_judge.cpp b/elec/elec_judge.cpp index 8b77a86..0b5a2db 100644 --- a/elec/elec_judge.cpp +++ b/elec/elec_judge.cpp @@ -392,7 +392,7 @@ int elec_extract_chip(int id) // 找到异常代码序号 int elec_report_err(elec_judge_def *e) { - static const uint8_t pro_table[]={1,3,7,8,2,4,5,6,20,0}; + static const uint8_t pro_table[]={1,3,7,8,2,4,5,6,9,20,0}; uint8_t index=0; for (int i=0;ilocal_ip).toLocal8Bit().data()); - str = "route add default gw %1"; - system(str.arg(cfg_->gateway_ip).toLocal8Bit().data()); - } if (socket_ == nullptr) { socket_ = new QUdpSocket(this); @@ -65,8 +79,46 @@ void command::init_cb() qInfo() << "udp command start."; qInfo() << "cmd port=" << cfg_->cmd_port; } + if(timer_==nullptr) + { + timer_=new QTimer(); + connect(timer_,&QTimer::timeout,this,&command::timer_cb); + timer_->start(3000); + } } +void command::timer_cb() +{ + mycfg *cfg_ = syscfg(); + // qDebug("command timer cb."); + if(CheckNetInfo()==true){ + if(networt_state==0){ + qDebug("network connected."); + networt_state=1; + } + if (get_local_ip().isEmpty()) + { + qDebug()<<"modify local ip addr."<local_ip); + system(str.toLocal8Bit().data()); + qDebug()<gateway_ip); + system(str.toLocal8Bit().data()); + qDebug()< #include +#include "QTimer" // using namespace std; // using namespace std::placeholders; @@ -41,6 +42,8 @@ public: command() { socket_ = nullptr; + timer_=nullptr; + networt_state=0; } virtual ~command() { @@ -49,6 +52,7 @@ public: } void send(QByteArray data); void init_cb(); + void timer_cb(); void ready_read_cb(); private: @@ -56,6 +60,8 @@ private: QByteArray recv_data; QHostAddress host_addr; quint16 port; + QTimer *timer_; + int networt_state; }; diff --git a/prot_cmd/cmd_coder.cpp b/prot_cmd/cmd_coder.cpp index 1996069..22ff795 100644 --- a/prot_cmd/cmd_coder.cpp +++ b/prot_cmd/cmd_coder.cpp @@ -1,8 +1,10 @@ #include "cmd_coder.h" #include "QDebug" - - - +#include "elec/elec_judge.h" +#include "elec/coder_lib.h" +#include "elec/JQ_PSDGenerate.h" +#include "elec/JQ_UIDGenerate.h" +#include "elec/PSDGenerate.h" @@ -47,6 +49,8 @@ static const task_def g_ew_task_table[]={ {"读MTP",35,5,2,8}, {"写MTP",36,5,10,0}, {"设置电阻校准值",37,1,1,0}, +{"读取流水号",38,5,2,2}, +{"写入流水号",39,5,2,0}, {nullptr,0,0,0,0}, }; @@ -100,6 +104,8 @@ static const task_def g_jq_task_table[]={ {"配置三码数据到小板",41,1,10,0}, {"任务插槽",42,1,1,0}, {"设置电阻校准值",43,1,1,0}, +{"写入流水号",44,5,2,0}, +{"读取流水号",45,5,2,2}, {nullptr,0,0,0,0}, }; @@ -123,8 +129,13 @@ const task_def *coder_find_task(const char *str) { int chip=elec_extract_chip(check_plan()->get_plan_id()); const task_def *table=nullptr; + + qDebug("find task in ext_table."); table=g_ext_task_table; for(int i=0;i<100;i++){ + if(table[i].name==nullptr){ + break; + } if(qstrcmp(str,table[i].name)==0){ return &table[i]; } @@ -132,14 +143,20 @@ const task_def *coder_find_task(const char *str) table=nullptr; if(chip==0){ table=g_jq_task_table; + qDebug("find task in jq_table."); }else if(chip==2){ table=g_ew_task_table; + qDebug("find task in ew_table."); } if(table==nullptr){ return nullptr; } for(int i=0;i<100;i++){ + if(table[i].name==nullptr){ + break; + } if(qstrcmp(str,table[i].name)==0){ + qDebug("find task index=%d.",i); return &table[i]; } } @@ -167,7 +184,11 @@ int coder_add_task(myarray &d,const char *name,int slot_index,int task_index,uin const task_def *task=nullptr; task=coder_find_task(name); if(task==nullptr){ + qWarning("can not find task with %s.",name); return -1; + }else{ + qDebug("task_name:%s,task_id=%d,par_count=%d,ret_count=%d,err=%d",name,task->task_id, + task->par_count,task->ret_count,task->errcode); } char *par=(char *)params; d.append(uint8_t(slot_index)); @@ -176,7 +197,9 @@ int coder_add_task(myarray &d,const char *name,int slot_index,int task_index,uin d.append(uint8_t(task->ret_count)); d.append(uint8_t(task->errcode)); d.append(uint8_t(task_index)); - d.append(par,task->par_count*2); + if(task->par_count*2>0){ + d.append(par,task->par_count*2); + } return 0; } @@ -192,6 +215,18 @@ int coder_slave_pack(myarray &d,int addr) } +// 找到指定任务序号的数据 +myarray coder_slave_find_ret_data(myarray data,int task_index) +{ + for(int i=0;i data) myarray &sdata=data[i]; int addr=i+syscfg()->slave_addr_start; r.append(uint8_t(addr)); - r.append(sdata[0]); + if(sdata.size()>0){ + r.append(sdata[0]); + }else{ + r.append(uint8_t(0xd0)); + } r.append(4,uint8_t(0)); } return r; @@ -274,7 +311,21 @@ myarray cmd_coder_check2::ret_slave_to_pc(QList data) r.append(uint8_t(coder_chip_type())); for (int i=0;islave_addr_start; + myarray sret=coder_slave_find_ret_data(sdata.mid(1),1); + r.append(uint8_t(addr)); + if(sdata.size()==0){ + r.append(uint8_t(0xd0)); + r.append(8,uint8_t(0)); + }else{ + r.append(sdata[0]); + if(sret.size()<4){ + sret.append(4-sret.size(),uint8_t(0)); + } + r.append(sret.left(4)); + r.append(4,uint8_t(0)); + } } return r; } @@ -300,31 +351,73 @@ myarray cmd_coder_code::cmd_pc_to_slave(myarray data) myarray ret; const task_def *table=nullptr; uint16_t params[10]={0}; + chip_mode=elec_extract_chip(check_plan()->get_plan_id()); + char year[10]={0}; + memcpy(year,data.mid(1,4).data(),4); + qDebug("tran pc data to slave"); for (int i=0;i data) { myarray r; - r.append(uint8_t(addrs&0xff)); - r.append(uint8_t((addrs>>8)&0xff)); - r.append(uint8_t((addrs>>16)&0xff)); - r.append(uint8_t(coder_chip_type())); + r.append(uint8_t(addrs)); for (int i=0;islave_addr_start; + r.append(uint8_t(addr)); + if(sdata.size()>0){ + r.append(sdata[0]); + }else{ + r.append(uint8_t(0xd0)); + } + r.append(uid_codes[i].shell,13); + if(chip_mode==0){ + r.append(uid_codes[i].uid,15); + }else{ + r.append(uid_codes[i].uid,16); + } + r.append(uid_codes[i].psw,8); } return r; } @@ -383,5 +476,50 @@ protpc_export(0x41, get_coder_setrtv); +// 批检仪检测并写入流水号 +myarray cmd_checker_check::cmd_pc_to_slave(myarray data) +{ + myarray ret; + const task_def *table=nullptr; + uint16_t params[10]={0}; + int len=data.size(); + for(int i=0;i data) +{ + myarray r; + r.append(char(0)); + for(int i=0;i data); protected: int addrs; + int chip_mode; + QList uid_codes; }; @@ -262,6 +269,56 @@ protected: +// 批检仪检测并设置模块流水号 +class cmd_checker_check : public selfdev_runtask +{ + Q_OBJECT +public: + cmd_checker_check():selfdev_runtask(){ + } + // pc指令转从机 + myarray cmd_pc_to_slave(myarray data); + // pc指令生成从机列表 + QList cmd_pc_to_addrs(myarray data){ + QList addr_list; + addrs=0; + int len=data.size(); + for(int i=0;i data); +protected: + int addrs; + int mode; +}; + + + + + + #endif // CMD_CODER_H diff --git a/prot_cmd/cmd_pc.cpp b/prot_cmd/cmd_pc.cpp index cecbad0..48123a3 100644 --- a/prot_cmd/cmd_pc.cpp +++ b/prot_cmd/cmd_pc.cpp @@ -117,7 +117,7 @@ void selfdev_check::timeout() } // 把小板的返回数据转化为自研批检仪上位机的格式 -static myarray tran_slave_to_selfdev_check(myarray &data) +myarray tran_slave_to_selfdev_check(myarray &data) { check_cfg *ccfg_=check_plan(); // 返回值个数 @@ -126,13 +126,14 @@ static myarray tran_slave_to_selfdev_check(myarray &data) int paramerr_num=(return_num+7)/8; // 每个通道占用的长度 int len_for_each=1+8+paramerr_num+return_num*2; - // 去掉应答位 - data.remove(0,1); myarray r; if(data.size()<17){ + // 无返回则填充为异常 r.append(char(208)); r.append((len_for_each-1),char(0xff)); }else{ + // 去掉应答位 + data.remove(0,1); myarray paramerr=ccfg_->returns_to_paramerr(data.right(return_num*2)); r=data.left(8)+paramerr+data.right(return_num*2); uint8_t marerr=0,suberr=0; @@ -818,8 +819,8 @@ int selfdev_runtask::dolater(int cmd, myarray data) mycfg *cfg_=syscfg(); busy=1; // 这里开始检测 - qDebug("set_rescv."); - emit send_data_signal(cmd,myarray(1,0)); + qDebug("runtask."); + // emit send_data_signal(cmd,myarray(1,0)); HandleBoardCast *b=new slave_cmd(); addrs=cmd_pc_to_addrs(data); bool ack=slave->set_boardcast_handle(addrs,b); @@ -868,3 +869,179 @@ void selfdev_runtask::slave_end_slot(int addr,int ack, slave_data data) +#pragma pack(1) +typedef struct{ + char devicetype[12]; + char hostif[8]; + uint8_t localip[4]; + uint8_t hostip[4]; + uint16_t hostport; + uint8_t localid; + int uartbsp; + uint8_t coder_return_mode; + uint8_t slave_addr_start; +}paraminfo_def; +#pragma pack() + +static void ip_fill(QString str,uint8_t *ip){ + QStringList snums = str.split('.'); + for(int i=0;idevicetype,cfg_->device_type.toLocal8Bit(),cfg_->device_type.size()+1); + if(cfg_->tcp_enable==true){ + memcpy(p->hostif,"utcp",5); + }else{ + memcpy(p->hostif,"uart4",6); + } + ip_fill(cfg_->local_ip,p->localip); + ip_fill(cfg_->server_ip,p->hostip); + p->hostport=cfg_->server_port; + p->localid=cfg_->local_id; + p->uartbsp=cfg_->uart_bsp; + p->coder_return_mode=cfg_->coder_return_mode; + p->slave_addr_start=cfg_->slave_addr_start; +} + +// 保存配置项 +static int paraminfo_save(paraminfo_def *p) +{ + int ret=0; + mycfg *cfg_=syscfg(); + uint8_t ip_zero[4]={0,0,0,0}; + if(strcmp("coder",p->devicetype)==0||strcmp("checker",p->devicetype)==0) + cfg_->device_type=QString(p->devicetype); + else { + qWarning()<<"devicetype param must be \"coder\" or \"checker\"."<devicetype; + ret=1;return ret;} + if(strcmp("utcp",p->hostif)==0){ + cfg_->tcp_enable=true; + }else{ + cfg_->tcp_enable=false; + } + if(memcmp(p->localip,ip_zero,4)!=0){ + cfg_->local_ip=QString("%1.%2.%3.%4").arg(p->localip[0]).arg(p->localip[1]).arg(p->localip[2]).arg(p->localip[3]); + }else { + qWarning()<<"localip param must not be all zero"; + ret=3;return ret;} + if(memcmp(p->hostip,ip_zero,4)!=0){ + cfg_->server_ip=QString("%1.%2.%3.%4").arg(p->hostip[0]).arg(p->hostip[1]).arg(p->hostip[2]).arg(p->hostip[3]); + }else { + qWarning()<<"hostip param must not be all zero"; + ret=4;return ret;} + cfg_->server_port=p->hostport; + cfg_->local_id=p->localid; + if(p->uartbsp==115200||p->uartbsp==9600) + cfg_->uart_bsp=p->uartbsp; + else { + qWarning()<<"uartbsp param must be 115200 or 9600"; + ret=5;return ret;} + if(p->coder_return_mode==0||p->coder_return_mode==1) + cfg_->coder_return_mode=p->coder_return_mode; + else { + qWarning()<<"coder_return_mode param must be 0 or 1"; + ret=6;return ret;} + if(p->slave_addr_start==0||p->slave_addr_start==1) + cfg_->slave_addr_start=p->slave_addr_start; + else { + qWarning()<<"slave_addr_start param must be 0 or 1"; + ret=7;return ret;} + cfg_->save(); + return ret; +} + +// 赋码仪配置参数 +int coder_sysparam::dolater(int cmd, myarray data) +{ + uint8_t op=data[1]; + paraminfo_def par={{0},{0},{0},{0},{0},{0},{0},{0},{0}}; + // 1是写,0是读 + if(op==0) + { + paraminfo_fill(&par); + uint8_t *d=(uint8_t *)(&par); + QByteArray arr; + // 赋码仪添加通道数 + arr.append(data[0]); + // 赋码仪添加读写位 + arr.append(op); + arr.append(uint8_t(0)); + QByteArray temp=QByteArray::fromRawData((const char *)d,sizeof(paraminfo_def)); + arr.append(temp); + emit send_data_signal(cmd,arr); + }else if(op==1) + { + QByteArray arr; + // 赋码仪添加通道数 + arr.append(data[0]); + // 赋码仪添加读写位 + arr.append(op); + + if(data.size()<1+1+sizeof(paraminfo_def)){ + arr.append(uint8_t(0xff)); + emit send_data_signal(cmd,arr); + }else{ + qDebug()<<"param:"<slave_num)); + r.append(char(0)); + r+=bootinfo_fill_local(); + for(int i=0;i slave_acked; int slave_acked_num; @@ -294,6 +299,35 @@ signals: +// 赋码仪配置参数 +class coder_sysparam : public HandlePc +{ + Q_OBJECT +public: + coder_sysparam() : HandlePc() { + } + ~coder_sysparam() { + } + int dolater(int cmd, myarray data); + void timeout(); +}; + + + + + +// 赋码仪基本信息 +class coder_bootinfo : public selfdev_bootinfo +{ + Q_OBJECT +public: + coder_bootinfo() : selfdev_bootinfo() { + } + ~coder_bootinfo() { + } + void slave_end_slot(int addr,int ack, slave_data data); +}; + diff --git a/prot_cmd/cmd_slave.cpp b/prot_cmd/cmd_slave.cpp index 816657a..ec35b8d 100644 --- a/prot_cmd/cmd_slave.cpp +++ b/prot_cmd/cmd_slave.cpp @@ -280,6 +280,16 @@ int boardcast_updata::start(myarray data) int boardcast_updata::dolater(int cmd, myarray data) { + for(int i=0;iget_check_time_out()*1000; + step=0; + // 执行模式不为3时使用方案中的超时时间 + if(data[0]!=3){ + timeout=check_plan()->get_check_time_out()*1000; + } qDebug("addr %d start ,timeout=%d",addr,timeout); this->data=data; send_pack_num=0; @@ -531,10 +545,17 @@ int slave_cmd::dolater(int cmd, myarray data) timeout_stop_retry(); if(cmd==this->cmd){ if(send_next()==true){ - qDebug("cmd end success."); - busy=0; - end(0,ret_data); - timeout_stop(); + if(step==0){ + qDebug("cmd send success."); + step=1; + addr_response=0; + ret_data.clear(); + }else{ + qDebug("cmd end success."); + busy=0; + end(0,ret_data); + timeout_stop(); + } } }else{ qWarning("cmd:%02x err.",cmd); diff --git a/prot_cmd/cmd_slave.h b/prot_cmd/cmd_slave.h index d773dea..df0fb9f 100644 --- a/prot_cmd/cmd_slave.h +++ b/prot_cmd/cmd_slave.h @@ -153,6 +153,7 @@ public: slave_cmd():HandleBoardCast(){ send_bytes=0; send_pack_num=0; + step=0; } int start(myarray data); int dolater(int cmd, myarray data); @@ -162,6 +163,7 @@ protected: int send_bytes; int send_pack_num; myarray data; + int step; };