Files
checker_host/base/check_cfg.cpp

574 lines
14 KiB
C++
Raw Normal View History

2023-11-26 23:05:35 +08:00
#include "base/check_cfg.h"
#include "base/mycfg.h"
#include "base/crc.h"
#include "QDir"
// 配置路径
#define CHECK_CFG_FILE_NAME cfg_->def_check_cfg
2023-11-27 14:31:00 +08:00
check_range my_json::json_to_range(QJsonValue v)
{
if (v.type() == QJsonValue::Object)
return check_range(v.toObject());
else
{
qWarning("json not a range object");
return check_range(0, 0);
}
2023-11-26 23:05:35 +08:00
}
2023-11-27 14:31:00 +08:00
check_task my_json::json_to_task(QJsonValue v)
{
if (v.type() == QJsonValue::Object)
return check_task(v.toObject());
else
{
qWarning("json not a task object");
return check_task();
}
2023-11-26 23:05:35 +08:00
}
check_err my_json::json_to_err(QJsonValue v)
{
2023-11-27 14:31:00 +08:00
if (v.type() == QJsonValue::Object)
return check_err(v.toObject());
else
{
qWarning("json not a err object");
return check_err();
}
2023-11-26 23:05:35 +08:00
}
check_suberr my_json::json_to_suberr(QJsonValue v)
{
2023-11-27 14:31:00 +08:00
if (v.type() == QJsonValue::Object)
return check_suberr(v.toObject());
else
{
qWarning("json not a suberr object");
return check_suberr();
}
2023-11-26 23:05:35 +08:00
}
check_cfg::check_cfg()
{
2023-11-27 14:31:00 +08:00
this->cfg_ = syscfg();
this->scheme_ = nullptr;
2023-11-26 23:05:35 +08:00
2023-11-27 14:31:00 +08:00
reload();
2023-11-26 23:05:35 +08:00
}
2023-11-27 14:31:00 +08:00
check_cfg::~check_cfg()
{
if (scheme_ != nullptr)
{
free(scheme_);
scheme_ = nullptr;
}
2023-11-26 23:05:35 +08:00
}
// 把方案转化为结构体
2023-11-27 14:31:00 +08:00
void check_cfg::scheme_json_to_struct()
{
if (scheme_ != nullptr)
{
free(scheme_);
scheme_ = nullptr;
}
scheme_struct_size = sizeof(scheme_def) + sizeof(scheme_task_def) * get_check_task_num();
scheme_ = (scheme_def *)calloc(1, scheme_struct_size);
if (scheme_)
{
scheme_->plan_id = get_plan_id();
scheme_->task_num = get_check_task_num();
scheme_->timeout_m = get_check_time_out();
scheme_->marerr_num = errs.size();
2023-12-02 11:27:25 +08:00
qDebug("scheme,id=%d,task_num=%d", scheme_->plan_id, scheme_->task_num);
2023-11-27 14:31:00 +08:00
for (int i = 0; i < scheme_->task_num; i++)
{
scheme_task_def *st = &scheme_->task[i];
check_task ct = tasks[i];
st->err = ct.get_failed_code();
st->item_num = ct.get_return_num();
st->taskid = ct.get_task_id();
st->taskindex = ct.get_index();
QList<uint8_t> ret_errs = ct.get_ret_failed_code();
QList<check_range> rangs = ct.get_ranges();
int rangs_num = rangs.size();
int err_num = ret_errs.size();
// qDebug("st,err,item_num=%d,taskid=%d,taskindex=%d", st->item_num, st->taskid, st->taskindex);
2023-11-27 14:31:00 +08:00
for (int i = 0; i < st->item_num; i++)
{
// qDebug("\ti=%d", i);
2023-11-27 14:31:00 +08:00
if (rangs_num > i)
{
st->range[i].err = 0;
if (err_num > i)
{
st->range[i].err = ret_errs[i];
}
st->range[i].max = rangs[i].max;
st->range[i].min = rangs[i].min;
2023-11-26 23:05:35 +08:00
}
2023-11-27 14:31:00 +08:00
else
{
st->range[i].err = 0;
st->range[i].max = 65535;
st->range[i].min = 0;
2023-11-26 23:05:35 +08:00
}
2023-11-27 14:31:00 +08:00
}
2023-11-26 23:05:35 +08:00
}
2023-11-27 14:31:00 +08:00
qDebug("tran err list.");
for (int i = 0; i < scheme_->marerr_num; i++)
{
marerr_def *merr = &scheme_->marerr[i];
QList<uint8_t> suberr = errs[i].get_subcodes();
merr->err = errs[i].get_code();
merr->suberr_num = suberr.size();
for (int j = 0; j < merr->suberr_num; j++)
{
merr->suberr[j] = suberr[j];
}
}
qDebug("tran slave array.");
myarray slave_array = scheme_to_byte_array();
uint32_t crc32 = crc::crc32(slave_array);
slave_array.append(crc32 & 0xff);
slave_array.append((crc32 >> 8) & 0xff);
slave_array.append((crc32 >> 16) & 0xff);
slave_array.append((crc32 >> 24) & 0xff);
memcpy(scheme_->slave_data, slave_array.data(), slave_array.size());
qDebug("tran end.");
}
else
{
qWarning("can not calloc.");
}
2023-11-26 23:05:35 +08:00
}
// 升级
bool check_cfg::updata(QString jstring)
{
2023-11-27 14:31:00 +08:00
QFile file;
QJsonDocument json_doc;
QJsonParseError err;
file.setFileName(CHECK_CFG_FILE_NAME);
json_doc = QJsonDocument::fromJson(jstring.toUtf8(), &err);
if (err.error != QJsonParseError::NoError)
{
2023-12-02 11:27:25 +08:00
qWarning("parse json failed:%s", err.errorString().toLocal8Bit().data());
2023-11-27 14:31:00 +08:00
qWarning() << jstring;
return false;
}
if (file.exists())
{
if (file.remove() != true)
qWarning() << "remove file " << file.fileName() << "err";
}
if (!file.exists())
{
file.open(QIODevice::ReadWrite);
QTextStream stream(&file);
stream.setCodec("utf-8");
stream << json_doc.toJson();
file.flush();
file.close();
system((char *)"sync");
}
reload();
return true;
2023-11-26 23:05:35 +08:00
}
void check_cfg::reload()
{
2023-11-27 14:31:00 +08:00
QFile file;
file.setFileName(CHECK_CFG_FILE_NAME);
if (file.exists())
{
file.open(QIODevice::ReadOnly);
QTextStream stream(&file);
stream.setCodec("utf-8");
QString json_str = stream.readAll();
QJsonParseError err;
json_doc = QJsonDocument::fromJson(json_str.toUtf8(), &err);
if (err.error != QJsonParseError::NoError)
2023-11-26 23:05:35 +08:00
{
2023-11-27 14:31:00 +08:00
qWarning() << "parse json failed:" << err.errorString();
qWarning() << json_str;
}
else
{
clear();
my_json m;
QJsonObject json = json_doc.object();
JVALUE_TO_INT(plan_id, json.value("PlanID"));
JVALUE_TO_STR(brief, json.value("PlanBrief"));
m.json_to_list(json, "CheckSoftVersion", slave_soft_versions, &my_json::json_to_u16);
m.json_to_list(json, "CheckHardVersion", slave_hard_versions, &my_json::json_to_u16);
JVALUE_TO_INT(time_out_s, json.value("TimeOutS"));
JVALUE_TO_INT(time_out_m, json.value("TimeOutM"));
JVALUE_TO_U8(task_id_max, json.value("TaskIDMax"));
m.json_to_list(json, "MajorErrInfo", errs, &my_json::json_to_err);
m.json_to_list(json, "SubErrInfo", suberrs, &my_json::json_to_suberr);
m.json_to_list(json, "TaskArray", tasks, &my_json::json_to_task);
m.json_to_list(json, "CheckerRtvName", check_ret_items, &my_json::json_to_str);
// 如果返回参数字段为空,则依次统计
if (check_ret_items.size() == 0)
{
for (int i = 0; i < tasks.size(); i++)
{
check_ret_items.append(tasks[i].get_return_info());
}
}
2023-11-26 23:05:35 +08:00
2023-11-27 14:31:00 +08:00
// task index应该从0开始依次递增
for (int i = 0; i < tasks.size(); i++)
{
if (tasks[i].get_index() != i)
2023-11-26 23:05:35 +08:00
{
2023-11-27 14:31:00 +08:00
qWarning() << "name=" << tasks[i].get_brief() << " task_index!=[i]";
2023-11-26 23:05:35 +08:00
}
2023-11-27 14:31:00 +08:00
}
// 检查子错误与主错误的对应关系
ch_errcode.clear();
for (int i = 0; i < tasks.size(); i++)
{
ch_errcode.append(tasks[i].get_failed_code());
ch_errcode.append(tasks[i].get_ret_failed_code());
}
// 查找子错误是否都有对应的描述
QSet<uint8_t> s = ch_errcode.toSet();
if (s.contains(uint8_t(0)))
s.remove(uint8_t(0));
QList<uint8_t> d = s.toList();
for (int i = 0; i < suberrs.size(); i++)
{
for (int j = 0; j < d.size(); j++)
2023-11-26 23:05:35 +08:00
{
2023-11-27 14:31:00 +08:00
if (suberrs[i] == d[j])
{
d.removeAt(j);
break;
}
2023-11-26 23:05:35 +08:00
}
2023-11-27 14:31:00 +08:00
}
if (!d.isEmpty())
{
qWarning() << "many suberr have not brief." << d;
}
// 匹配主错误
get_ch_merrcode();
// 把剩下的子错误全部添加到优先级最低的主错误中
errs.last().append(ch_errcode);
// 生成方案结构体
scheme_json_to_struct();
}
qInfo() << "check id:" << planid_to_String(0);
file.close();
}
else
{
qWarning() << "check cfg file " << file.fileName() << " had lossed";
}
2023-11-26 23:05:35 +08:00
}
2023-11-27 14:31:00 +08:00
#define TASKS_MAX_SIZE (0x700 - 4)
2023-11-26 23:05:35 +08:00
// 把任务数据转化为字节数组
2023-11-27 14:31:00 +08:00
myarray check_cfg::tasks_to_byte_array()
2023-11-26 23:05:35 +08:00
{
2023-11-27 14:31:00 +08:00
myarray t;
for (int i = 0; i < tasks.size(); i++)
{
t.append(tasks[i].to_byte_array());
}
int size = t.size();
if (size < TASKS_MAX_SIZE)
{
t.append(TASKS_MAX_SIZE - size, char(0xff));
}
else
{
qWarning() << "tasks array size too larg.";
}
return t;
2023-11-26 23:05:35 +08:00
}
2023-11-27 14:31:00 +08:00
#define TASKSID_MAX_SIZE (0x100 - 4)
2023-11-26 23:05:35 +08:00
// 把任务序号转化为数组
2023-11-27 14:31:00 +08:00
myarray check_cfg::tasksid_to_byte_array()
2023-11-26 23:05:35 +08:00
{
2023-11-27 14:31:00 +08:00
myarray t;
t.append(plan_id & 0xff);
t.append((plan_id >> 8) & 0xff);
t.append((plan_id >> 16) & 0xff);
t.append((plan_id >> 24) & 0xff);
for (int i = 0; i < tasks.size(); i++)
{
t.append(tasks[i].get_task_id());
}
int size = t.size();
if (size < TASKSID_MAX_SIZE)
{
t.append(TASKSID_MAX_SIZE - size, char(0xff));
}
else
{
qWarning() << "tasksid array size too larg.";
}
return t;
2023-11-26 23:05:35 +08:00
}
// 方案转化为数组
2023-11-27 14:31:00 +08:00
myarray check_cfg::scheme_to_byte_array()
2023-11-26 23:05:35 +08:00
{
2023-11-27 14:31:00 +08:00
myarray t;
t.append(tasksid_to_byte_array());
t.append(4, char(0xff));
t.append(tasks_to_byte_array());
return t;
2023-11-26 23:05:35 +08:00
}
// 获取检测方案id
int check_cfg::get_plan_id()
{
2023-11-27 14:31:00 +08:00
return plan_id;
2023-11-26 23:05:35 +08:00
}
// 根据方案获取具体信息id为0时填充本机方案
QString check_cfg::planid_to_String(int id)
{
2023-11-27 14:31:00 +08:00
if (id == 0)
id = plan_id;
// 日bit0~bit4 月bit5~bit8 年bit9~bit15
int sid = (id >> 0) & 0x7f;
int modele = (id >> 7) & 0x1f;
int chip = (id >> 12) & 0xf;
int day = (id >> 16) & 0x1f;
int month = (id >> 21) & 0xf;
int year = ((id >> 25) & 0x7f) + 2022;
QString s = "%1-%2-%3 id=%4,modele=%5,chip=%6";
return s.arg(year).arg(month).arg(day).arg(sid).arg(modele).arg(chip);
2023-11-26 23:05:35 +08:00
}
// 获取适配的从机软件版本号
2023-11-27 14:31:00 +08:00
QList<uint16_t> &check_cfg::get_slave_soft_versions()
2023-11-26 23:05:35 +08:00
{
2023-11-27 14:31:00 +08:00
return slave_soft_versions;
2023-11-26 23:05:35 +08:00
}
// 获取适配的从机硬件版本号
2023-11-27 14:31:00 +08:00
QList<uint16_t> &check_cfg::get_slave_hard_versions()
2023-11-26 23:05:35 +08:00
{
2023-11-27 14:31:00 +08:00
return slave_hard_versions;
2023-11-26 23:05:35 +08:00
}
// 获取方案执行最长时间
int check_cfg::get_check_time_out()
{
2023-11-27 14:31:00 +08:00
return time_out_m;
2023-11-26 23:05:35 +08:00
}
// 获取任务id最大值
uint8_t check_cfg::get_task_id_max()
{
2023-11-27 14:31:00 +08:00
return task_id_max;
2023-11-26 23:05:35 +08:00
}
// 根据错误号返回错误字符串
QString check_cfg::get_err_string(int err)
{
2023-11-27 14:31:00 +08:00
QString r;
for (int i = 0; i < errs.size(); i++)
{
if (errs[i] == err)
r = errs[i]();
}
if (!r.isEmpty())
return r;
for (int i = 0; i < suberrs.size(); i++)
{
if (suberrs[i] == err)
r = suberrs[i]();
}
if (!r.isEmpty())
return r;
return QString("未知错误");
2023-11-26 23:05:35 +08:00
}
// 获取检测任务个数
int check_cfg::get_check_task_num()
{
2023-11-27 14:31:00 +08:00
return tasks.size();
2023-11-26 23:05:35 +08:00
}
// 根据序列指获取对应的任务参数
check_task check_cfg::get_task(int index)
{
2023-11-27 14:31:00 +08:00
for (int i = 0; i < tasks.size(); i++)
{
if (tasks[i].get_index() == index)
return tasks[i];
}
return check_task();
// return tasks[index];
2023-11-26 23:05:35 +08:00
}
2023-11-27 14:31:00 +08:00
QJsonObject check_cfg::returns_to_json(myarray data)
2023-11-26 23:05:35 +08:00
{
2023-11-27 14:31:00 +08:00
QJsonObject j;
QJsonArray a;
// 先是8字节错误结果再是8字节执行状态1已执行
myarray d = data.mid(16, data.size() - 16);
// j.insert("PlanID",plan_id);
j.insert("TasksExecuteCode", QString(data.mid(0, 8).toHex().toUpper()));
ch_errcode.clear();
for (int i = 0; i < get_check_task_num();)
{
QJsonObject t;
bool ack = get_return_ack_by_index(data, i);
check_task task = get_task(i);
t = task.returns_to_json(ack, d);
ch_errcode.append(task.get_ch_errcode());
// qDebug()<<"append err code="<<ch_errcode<<endl;
// if(ack==true)
2023-11-26 23:05:35 +08:00
{
2023-11-27 14:31:00 +08:00
d.remove(0, get_task(i).get_return_num() * 2);
i++;
}
// else
// {
// i=get_task(i).get_err_jump();
// }
a.append(t);
}
j.insert("TaskArray", a);
QList<check_err> e = get_ch_merrcode();
// QJsonArray err_code;
// QString err_str;
// for(int i=0;i<e.size();i++)
// {
// err_str=err_str+e[i]()+";";
// err_code.append(e[i].get_code());
// }
// if(err_code.isEmpty()){
// j.insert("ErrInfo","ok");
// err_code.append(0);
// }
// else{
// j.insert("ErrInfo",err_str);
// }
// j.insert("ErrCode",err_code);
if (e.isEmpty())
{
j.insert("ErrInfo", "ok");
j.insert("ErrCode", 0);
}
else
{
j.insert("ErrInfo", e[0]());
j.insert("ErrCode", e[0].get_code());
}
return j;
2023-11-26 23:05:35 +08:00
}
QList<check_err> check_cfg::get_ch_merrcode()
{
2023-11-27 14:31:00 +08:00
QList<check_err> l;
QSet<uint8_t> s = ch_errcode.toSet();
if (s.contains(uint8_t(0)))
s.remove(uint8_t(0));
ch_errcode = s.toList();
// qDebug()<<"mejor errs="<<errs<<endl;
for (int i = 0; i < ch_errcode.size();)
{
if (in_err_range(l, ch_errcode[i]) == true)
2023-11-26 23:05:35 +08:00
{
2023-11-27 14:31:00 +08:00
ch_errcode.removeAt(i);
2023-11-26 23:05:35 +08:00
}
2023-11-27 14:31:00 +08:00
else
{
i++;
}
}
if (!ch_errcode.isEmpty())
{
// 有子错误没找到主错误
2023-12-02 11:27:25 +08:00
qWarning() << "many suberr left.%d" << ch_errcode;
2023-11-27 14:31:00 +08:00
}
return l;
2023-11-26 23:05:35 +08:00
}
2023-11-27 14:31:00 +08:00
bool check_cfg::in_err_range(QList<check_err> &l, uint8_t code)
2023-11-26 23:05:35 +08:00
{
2023-11-27 14:31:00 +08:00
for (int j = 0; j < errs.size(); j++)
{
if (errs[j].in_range(code))
2023-11-26 23:05:35 +08:00
{
2023-11-27 14:31:00 +08:00
// qDebug()<<"find subcode="<<code<<" in mcode="<<errs[j].get_code()<<endl;
l.append(errs[j]);
return true;
2023-11-26 23:05:35 +08:00
}
2023-11-27 14:31:00 +08:00
}
2023-12-02 11:27:25 +08:00
qDebug("can not find mcode,subcode=%d", code);
2023-11-27 14:31:00 +08:00
return false;
2023-11-26 23:05:35 +08:00
}
2023-11-27 14:31:00 +08:00
bool check_cfg::get_return_ack_by_index(myarray data, int index)
2023-11-26 23:05:35 +08:00
{
2023-11-27 14:31:00 +08:00
if (data.size() < 8)
{
qWarning("check values too less.");
return false;
}
if (index < 0 || index >= 64)
{
qWarning("index out of range.");
return false;
}
if ((data[index / 8] & (1 << (index % 8))) != 0)
{
return false;
}
else
{
return true;
}
2023-11-26 23:05:35 +08:00
}
2023-11-27 14:31:00 +08:00
myarray check_cfg::returns_to_paramerr(myarray data)
2023-11-26 23:05:35 +08:00
{
2023-11-27 14:31:00 +08:00
myarray p;
int len = (get_return_num() + 7) / 8;
int index = 0;
p.append(len, char(0xff));
if (data.size() < get_return_num() * 2)
{
qWarning("data too less");
2023-11-26 23:05:35 +08:00
return p;
2023-11-27 14:31:00 +08:00
}
for (int i = 0; i < tasks.size(); i++)
{
QList<check_range> ranges = tasks[i].get_ranges();
for (int j = 0; j < ranges.size(); j++)
{
int temp = data[index * 2] | (data[index * 2 + 1] << 8);
if (temp >= ranges[j].min && temp <= ranges[j].max)
{
p[index / 8] = p[index / 8] & (~(1 << (index % 8)));
}
else
{
p[index / 8] = p[index / 8] | (1 << (index % 8));
}
index++;
}
}
return p;
2023-11-26 23:05:35 +08:00
}
static check_cfg *g_check_cfg;
check_cfg *check_plan()
{
2023-11-27 14:31:00 +08:00
if (g_check_cfg == nullptr)
{
g_check_cfg = new check_cfg();
}
return g_check_cfg;
2023-11-26 23:05:35 +08:00
}