#include "base/check_cfg.h" #include "base/mycfg.h" #include "base/crc.h" #include "QDir" // 配置路径 #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; 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 ret_errs = ct.get_ret_failed_code(); QList 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 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 s = ch_errcode.toSet(); if (s.contains(uint8_t(0))) s.remove(uint8_t(0)); QList 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 &check_cfg::get_slave_soft_versions() { return slave_soft_versions; } // 获取适配的从机硬件版本号 QList &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="< e = get_ch_merrcode(); // QJsonArray err_code; // QString err_str; // for(int i=0;i check_cfg::get_ch_merrcode() { QList l; QSet s = ch_errcode.toSet(); if (s.contains(uint8_t(0))) s.remove(uint8_t(0)); ch_errcode = s.toList(); // qDebug()<<"mejor errs="< &l, uint8_t code) { for (int j = 0; j < errs.size(); j++) { if (errs[j].in_range(code)) { // qDebug()<<"find subcode="<= 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 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; }