#include "installment.h" #include "password.h" #include "fram.h" #include "paras.h" #include "cpuid.h" #include "shell.h" #include "trigger.h" /* */ //------------------------------------------------------------------------------- u32 GetRTCSecond(void) { // RTC_GetCounter // LL_RTC_TIME_GetSecond return 0; } //------------------------------------------------------------------------------- #define INS_SIZE 64 typedef struct { // 0 u8 curmc; // 当前机型,CUR_MACHINE u16 mctype; // 机器类型,MC_TYPE u8 clientId; // 客户代码 u32 cpuId; // 8 u8 lastpswd[24]; // 旧密码 // 32 s32 workableTimer; // 可工作时间计数器,剩余时间计数(分钟为单位) u32 rtcSecondTimer; // 实时时钟计数 // 40 u8 rev[INS_SIZE - 4 - 40]; u32 encount; // 写入有效计数器 } __attribute__ ((packed)) Installment; #define UNLOCK_COUNTER_MIN (S32_MAX - S16_MAX - U16_MAX) // 全解计数(大于此数均为全解) #define UNLOCK_COUNTER_MAX (S32_MAX) #define UNLOCK_COUNTER (UNLOCK_COUNTER_MIN+S16_MAX + (S16_MAX)/2) // 默认全解计数 //------------------------------------------------------------------------------- Installment g_installment; int g_instsel = -1; //------------------------------------------------------------------------------- void TestInstall(char * para1, char * para2); void ResetInstall(void); //------------------------------------------------------------------------------- // 初始化 int InitInstallment(void) { int rslt; u32 cpuid; Installment tmpinstall1, tmpinstall2; rslt = 0; if (g_instsel >= 0) { return 0; } cpuid = 0; { CpuId id; GetCpuID(&id); cpuid += id.dword.dword1; cpuid += id.dword.dword2; cpuid += id.dword.dword3; cpuid += id.dword.dword4; } memset(&g_installment, 0, sizeof(Installment)); // 确定哪个是有效的 ReadFramData(ENC_ADDR, (u8*)&tmpinstall1, sizeof(Installment)); ReadFramData(ENC_ADDR+INS_SIZE, (u8*)&tmpinstall2, sizeof(Installment)); if (1 && tmpinstall1.curmc == CUR_MACHINE && tmpinstall1.mctype == MC_TYPE && tmpinstall1.clientId == CUR_CLINET && tmpinstall1.cpuId == cpuid && 1 ) { if (1 && tmpinstall2.curmc == CUR_MACHINE && tmpinstall2.mctype == MC_TYPE && tmpinstall2.clientId == CUR_CLINET && tmpinstall2.cpuId == cpuid && 1 ) { if (tmpinstall2.encount > tmpinstall1.encount) { g_instsel = 1; } else { g_instsel = 0; } } else { g_instsel = 0; // 将有效的写入无效的缓冲区 WriteFramData(ENC_ADDR+INS_SIZE, (u8*)&tmpinstall1, sizeof(Installment)); } } else { if (1 && tmpinstall2.curmc == CUR_MACHINE && tmpinstall2.mctype == MC_TYPE && tmpinstall2.clientId == CUR_CLINET && tmpinstall2.cpuId == cpuid && 1 ) { g_instsel = 1; // 将有效的写入无效的缓冲区 WriteFramData(ENC_ADDR, (u8*)&tmpinstall2, sizeof(Installment)); } else { // 两个都无效 } } if (g_instsel < 0) { ResetInstall(); } // 重新读入 if (g_instsel == 0) { printf("load enc 0\r\n"); ReadFramData(ENC_ADDR, (u8*)&g_installment, sizeof(Installment)); } else if (g_instsel == 1) { printf("load enc 1\r\n"); ReadFramData(ENC_ADDR+INS_SIZE, (u8*)&g_installment, sizeof(Installment)); } else { printf("load enc error\r\n"); } if (0 || g_installment.curmc != CUR_MACHINE || g_installment.mctype != MC_TYPE || g_installment.clientId != CUR_CLINET || g_installment.cpuId != cpuid || 0 ) { printf("reload enc error\r\n"); ResetInstall(); } else { // 解码验证 int rslt = -1; PswdCtrl pswdctrl; rslt = DecodePswdString(&pswdctrl, (char*)(g_installment.lastpswd), g_installment.clientId); // 解码 if (rslt < 0) { printf("DecodePswdString error, reset ResetInstall\r\n"); // 保存的密码不正确, 或者是没有设置过密码 ResetInstall(); } else { if (pswdctrl.clientId == g_installment.clientId && pswdctrl.cpuId == g_installment.cpuId && 1 ) { s32 thishours = pswdctrl.thishours; if (thishours >= UNLOCK_MIN && thishours <= UNLOCK_MAX) { // 全解 g_installment.workableTimer = UNLOCK_COUNTER; // 设置为最大计数 } else if (thishours < 0) { thishours *= -1; if (thishours >= LOCK_MIN && thishours <= LOCK_MAX) { g_installment.workableTimer = 0; // 全部锁定 } } } else { printf("clientId or cpuId not equ, reset ResetInstall\r\n"); ResetInstall(); } } } // 改变关电过程中的时间 if (g_installment.workableTimer < UNLOCK_COUNTER_MIN) // 有使用限制情况下 { u32 temp; temp = GetRTCSecond(); // 读取现在RTC的值 if (temp >= g_installment.rtcSecondTimer) { temp -= g_installment.rtcSecondTimer; printf("rtc record, close time=%u sec\r\n", temp); temp /= 60; // 关机分钟数 temp++; // 至少减去1分钟 g_installment.workableTimer -= temp; if (g_installment.workableTimer < 0) { g_installment.workableTimer = 0; } if (g_installment.workableTimer >= UNLOCK_COUNTER_MIN) { g_installment.workableTimer = UNLOCK_COUNTER_MIN-1; } rslt = temp - 1; } else { printf("rtc reset\r\n"); // 可能是电池掉电, rtc 复位 } } g_installment.rtcSecondTimer = GetRTCSecond(); // 读取现在RTC的值,重新记录 AddShellCmd("INS", "Install function", TestInstall); return rslt; } void ResetInstall() { Installment tmpinstall; u32 cpuid; cpuid = 0; { CpuId id; GetCpuID(&id); cpuid += id.dword.dword1; cpuid += id.dword.dword2; cpuid += id.dword.dword3; cpuid += id.dword.dword4; } // 初始化两个缓冲区 memset(&tmpinstall, 0, sizeof(Installment)); tmpinstall.curmc = CUR_MACHINE; tmpinstall.mctype = MC_TYPE; tmpinstall.clientId = CUR_CLINET; tmpinstall.cpuId = cpuid; tmpinstall.encount = 100; tmpinstall.workableTimer = 0; // 允许工作时间为0 tmpinstall.rtcSecondTimer = GetRTCSecond(); // 读取现在RTC的值 WriteFramData(ENC_ADDR, (u8*)&tmpinstall, sizeof(Installment)); WriteFramData(ENC_ADDR+INS_SIZE, (u8*)&tmpinstall, sizeof(Installment)); g_instsel = 0; printf("ResetInstall\r\n"); } int SetInstallMent(char * pPswdStr) { int rslt = -1; PswdCtrl pswdctrl; ChangeToUper(pPswdStr); // 转换为大写 do { if (g_instsel >= 0) { rslt = DecodePswdString(&pswdctrl, pPswdStr, g_installment.clientId); // 解码 if (rslt >= 0) { // 6. 验证客户识别码和主板识别码是否符合当前设备。 if (pswdctrl.clientId == g_installment.clientId && pswdctrl.cpuId == g_installment.cpuId && 1 ) { PswdCtrl oldctrl; if (g_installment.lastpswd[0] != 0) // 非第一次设置 { rslt = DecodePswdString(&oldctrl, (char*)(g_installment.lastpswd), g_installment.clientId); // 解码上次密码 if (rslt < 0) { break; } } else { if (pswdctrl.totaltime >= 0 && pswdctrl.totaltime < TIME_MUTI) { oldctrl.nexttotaltime = pswdctrl.totaltime; } else { rslt = -1; // 设置不成功 break; } } // 7.验证上次加密累计时间是否和板卡保存的一致(按小时数验证)。 if (pswdctrl.totaltime == oldctrl.nexttotaltime) { // 8.将新的改变时间加到当前计数时间,并写入计数区域。 s32 thishours = pswdctrl.thishours; if (thishours >= NORMAL_MIN && thishours <= NORMAL_MAX) // 本次是增加时间或新设置加密 { if (g_installment.workableTimer >= UNLOCK_COUNTER_MIN || // 上次是全解 g_installment.workableTimer < 0 ) // 上次是锁定 { g_installment.workableTimer = thishours*60; // 重置为加密状态 } else { g_installment.workableTimer += thishours*60; // 增加时间 if (g_installment.workableTimer < 0) { g_installment.workableTimer = 0; } if (g_installment.workableTimer >= UNLOCK_COUNTER_MIN) { g_installment.workableTimer = UNLOCK_COUNTER_MIN-1; } } } else if (thishours >= UNLOCK_MIN && thishours <= UNLOCK_MAX) // 本次是全解 { // 全解 g_installment.workableTimer = UNLOCK_COUNTER; // 设置为最大计数 } else if (thishours < 0) // 本次是锁定或减少时间 { thishours *= -1; if (thishours >= NORMAL_MIN && thishours <= NORMAL_MAX) // 正常减少时间 { if (g_installment.workableTimer >= UNLOCK_COUNTER_MIN) // 上次是全解 { g_installment.workableTimer = 0; // 全部锁定 } else { g_installment.workableTimer -= thishours*60; // 减少使用时间 if (g_installment.workableTimer < 0) { g_installment.workableTimer = 0; } if (g_installment.workableTimer >= UNLOCK_COUNTER_MIN) { g_installment.workableTimer = UNLOCK_COUNTER_MIN-1; } } } else if (thishours >= LOCK_MIN && thishours <= LOCK_MAX) { g_installment.workableTimer = 0; // 全部锁定 } else { rslt = -1; // 设置不成功 break; } } else { rslt = -1; // 设置不成功 break; } // 9.保存密码串到记录区域。 memcpy(g_installment.lastpswd, pPswdStr, PSWDSTR_LEN); g_installment.lastpswd[PSWDSTR_LEN] = 0; RefWorkableTimer(0); rslt = 0; break; } else { rslt = -1; break; } } else { rslt = -1; break; } } } }while(0); return rslt; } // 得到剩余工作时长,单位为分钟 int GetWorkableTime(void) { if (g_instsel >= 0) { return g_installment.workableTimer; } else { return 0; } } // 更新计数器,单位为分钟 int RefWorkableTimer(s32 val) { if (g_instsel < 0) { g_installment.workableTimer = 0; } else { g_installment.rtcSecondTimer = GetRTCSecond(); // 每隔1分钟,记录rtc的计数值 /* * 20221024 ljs++ * 因界面计算错误,个别情况下所发送的关机时间错误 * 命令代码UCMD_SET_ELAPSED_TIME * 例如,在全解的情况下发送关机时间5000小时,实际并没有关机,只是主控进行了重启 * 所造成的由无时间限制变成了有时间限制,甚至密码到期 * 为解决此问题,增加if条件判断 * 在全解的情况下,不更新计数器 */ if (g_installment.workableTimer < UNLOCK_COUNTER_MIN) // 非全解的情况下 { g_installment.workableTimer += val; } if (g_installment.workableTimer < 0) { g_installment.workableTimer = 0; } else if (g_installment.workableTimer >= UNLOCK_COUNTER_MIN) { g_installment.workableTimer = UNLOCK_COUNTER; } g_installment.encount++; if (g_instsel == 0) { WriteFramData(ENC_ADDR+INS_SIZE, (u8*)&g_installment, sizeof(Installment)); g_instsel = 1; } else { WriteFramData(ENC_ADDR, (u8*)&g_installment, sizeof(Installment)); g_instsel = 0; } } #if (0) // 调试输出 { static u32 timer = 0; u32 gap = 0; u32 temp; temp = GetMsSoftTimer(); if (timer == 0) { gap = 0; } else { gap = temp - timer; } timer = temp; printf("at %d, RefWorkableTimer, gap = %d, ",timer, gap); if (g_installment.workableTimer <= 0) { g_installment.workableTimer = 0; printf("limit use\r\n"); } else if (g_installment.workableTimer >= UNLOCK_COUNTER_MIN) { g_installment.workableTimer = UNLOCK_COUNTER; printf("no limit\r\n"); } else { printf("change workabletimer to %d\r\n", g_installment.workableTimer); } } #endif return g_installment.workableTimer; } // 板卡ID信息 void GetBoardIdInfo(char * boardId) { sprintf(boardId, "CPUID: %u", g_installment.cpuId); } // 加密字符串 void GetLastInstallment(char * installment) { sprintf(installment, "LPSWD: %s", g_installment.lastpswd); } // 读取前一次密码 void GetLastpswd(u8 * lastpswd) { memcpy(lastpswd, g_installment.lastpswd, 24); } void TestInstall(char * para1, char * para2) { int p1, p2; p1 = 0; p2 = 0; if (para1 == NULL || para2 == NULL) { return; } printf("para1=%s, para2=%s\r\n", para1, para2); if (strcmp(para1, "") != 0) { p1 = atoi(para1); } if (strcmp(para2, "") != 0) { p2 = atoi(para2); } if (p1 == p2) { } //-------------------------------- { if (p1 == 0) { char buff[32]; GetBoardIdInfo(buff); // 板卡ID信息 printf("%s\r\n", buff); GetLastInstallment(buff); // 加密字符串 printf("%s\r\n", buff); printf("Workable = %d min\r\n", GetWorkableTime()); } else if (p1 == 1) { SetInstallMent(para2); } else if (p1 == 2) { RefWorkableTimer(p2); } else if (p1 == 100) { ResetInstall(); } } }