606 lines
12 KiB
C
606 lines
12 KiB
C
|
||
#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();
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|