Files
checker_host/base/check_cfg.cpp
2023-11-27 14:31:00 +08:00

581 lines
14 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "base/check_cfg.h"
#include "base/mycfg.h"
#include "base/crc.h"
#include "QDir"
// 配置路径
#define CFG_PATH mystring("/home/root/config/")
#define CHECK_CFG_FILE_NAME cfg_->def_check_cfg
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);
}
}
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();
}
}
check_err my_json::json_to_err(QJsonValue v)
{
if (v.type() == QJsonValue::Object)
return check_err(v.toObject());
else
{
qWarning("json not a err object");
return check_err();
}
}
check_suberr my_json::json_to_suberr(QJsonValue v)
{
if (v.type() == QJsonValue::Object)
return check_suberr(v.toObject());
else
{
qWarning("json not a suberr object");
return check_suberr();
}
}
check_cfg::check_cfg()
{
this->cfg_ = syscfg();
this->scheme_ = nullptr;
QDir path;
if (!path.exists(CFG_PATH))
{
path.mkdir(CFG_PATH);
}
reload();
}
check_cfg::~check_cfg()
{
if (scheme_ != nullptr)
{
free(scheme_);
scheme_ = nullptr;
}
}
// 把方案转化为结构体
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();
qDebug("scheme,id=%d,task_num=%d",scheme_->plan_id,scheme_->task_num);
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);
for (int i = 0; i < st->item_num; i++)
{
qDebug("\ti=%d",i);
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;
}
else
{
st->range[i].err = 0;
st->range[i].max = 65535;
st->range[i].min = 0;
}
}
}
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.");
}
}
// 升级
bool check_cfg::updata(QString jstring)
{
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)
{
qWarning("parse json failed:%s",err.errorString().toLocal8Bit().data());
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;
}
void check_cfg::reload()
{
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)
{
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());
}
}
// task index应该从0开始依次递增
for (int i = 0; i < tasks.size(); i++)
{
if (tasks[i].get_index() != i)
{
qWarning() << "name=" << tasks[i].get_brief() << " task_index!=[i]";
}
}
// 检查子错误与主错误的对应关系
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++)
{
if (suberrs[i] == d[j])
{
d.removeAt(j);
break;
}
}
}
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";
}
}
#define TASKS_MAX_SIZE (0x700 - 4)
// 把任务数据转化为字节数组
myarray check_cfg::tasks_to_byte_array()
{
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;
}
#define TASKSID_MAX_SIZE (0x100 - 4)
// 把任务序号转化为数组
myarray check_cfg::tasksid_to_byte_array()
{
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;
}
// 方案转化为数组
myarray check_cfg::scheme_to_byte_array()
{
myarray t;
t.append(tasksid_to_byte_array());
t.append(4, char(0xff));
t.append(tasks_to_byte_array());
return t;
}
// 获取检测方案id
int check_cfg::get_plan_id()
{
return plan_id;
}
// 根据方案获取具体信息id为0时填充本机方案
QString check_cfg::planid_to_String(int id)
{
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);
}
// 获取适配的从机软件版本号
QList<uint16_t> &check_cfg::get_slave_soft_versions()
{
return slave_soft_versions;
}
// 获取适配的从机硬件版本号
QList<uint16_t> &check_cfg::get_slave_hard_versions()
{
return slave_hard_versions;
}
// 获取方案执行最长时间
int check_cfg::get_check_time_out()
{
return time_out_m;
}
// 获取任务id最大值
uint8_t check_cfg::get_task_id_max()
{
return task_id_max;
}
// 根据错误号返回错误字符串
QString check_cfg::get_err_string(int err)
{
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("未知错误");
}
// 获取检测任务个数
int check_cfg::get_check_task_num()
{
return tasks.size();
}
// 根据序列指获取对应的任务参数
check_task check_cfg::get_task(int index)
{
for (int i = 0; i < tasks.size(); i++)
{
if (tasks[i].get_index() == index)
return tasks[i];
}
return check_task();
// return tasks[index];
}
QJsonObject check_cfg::returns_to_json(myarray data)
{
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)
{
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;
}
QList<check_err> check_cfg::get_ch_merrcode()
{
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)
{
ch_errcode.removeAt(i);
}
else
{
i++;
}
}
if (!ch_errcode.isEmpty())
{
// 有子错误没找到主错误
qWarning()<<"many suberr left.%d"<<ch_errcode;
}
return l;
}
bool check_cfg::in_err_range(QList<check_err> &l, uint8_t code)
{
for (int j = 0; j < errs.size(); j++)
{
if (errs[j].in_range(code))
{
// qDebug()<<"find subcode="<<code<<" in mcode="<<errs[j].get_code()<<endl;
l.append(errs[j]);
return true;
}
}
qDebug("can not find mcode,subcode=%d",code);
return false;
}
bool check_cfg::get_return_ack_by_index(myarray data, int index)
{
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;
}
}
myarray check_cfg::returns_to_paramerr(myarray data)
{
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");
return p;
}
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;
}
static check_cfg *g_check_cfg;
check_cfg *check_plan()
{
if (g_check_cfg == nullptr)
{
g_check_cfg = new check_cfg();
}
return g_check_cfg;
}