From c3e86e4dbf698fe0d3397fb31853f5dd8fd2a23f Mon Sep 17 00:00:00 2001 From: gb <741021719@qq.com> Date: Sat, 13 Aug 2022 09:29:00 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=BE=E5=A4=87=E9=85=8D=E7=BD=AE=E6=94=B9?= =?UTF-8?q?=E4=B8=BA=E5=A4=96=E9=83=A8=E7=8B=AC=E7=AB=8B=E6=96=87=E4=BB=B6?= =?UTF-8?q?:=20./settings/0239.hsc=20...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hgdriver/hgdev/hg_scanner.cpp | 18 ++ hgdriver/hgdev/hg_scanner.h | 1 + hgdriver/hgdev/hg_scanner_200.cpp | 3 +- hgdriver/hgdev/hg_scanner_239.cpp | 3 +- hgdriver/hgdev/hg_scanner_300.cpp | 3 +- hgdriver/hgdev/hg_scanner_400.cpp | 3 +- hgdriver/hgdev/hg_scanner_402.cpp | 3 +- hgdriver/hgdev/hg_scanner_439.cpp | 3 +- hgdriver/hgdev/scanner_setting.cpp | 319 +++++++++++++++++++++++++++++ hgdriver/hgdev/scanner_setting.h | 57 ++++++ 10 files changed, 407 insertions(+), 6 deletions(-) create mode 100644 hgdriver/hgdev/scanner_setting.cpp create mode 100644 hgdriver/hgdev/scanner_setting.h diff --git a/hgdriver/hgdev/hg_scanner.cpp b/hgdriver/hgdev/hg_scanner.cpp index bf0d706..035fc81 100644 --- a/hgdriver/hgdev/hg_scanner.cpp +++ b/hgdriver/hgdev/hg_scanner.cpp @@ -1,6 +1,7 @@ #include "hg_scanner.h" #include "../wrapper/hg_log.h" #include "sane/sane_option_definitions.h" +#include "scanner_setting.h" #if defined(WIN32) || defined(_WIN64) #include "scanner_manager.h" @@ -2010,6 +2011,23 @@ void hg_scanner::init_settings(const char* json_setting_text) setting_count_ = count; notify_setting_result_ = true; } +int hg_scanner::init_settings(int pid) +{ + char rel_path[80] = { 0 }; + std::string root(hg_log::get_scanner_path()), jsn(""); + int ret = 0; + + sprintf(rel_path, "%ssettings%s%04x.hsc", PATH_SEPARATOR, PATH_SEPARATOR, pid); + root += rel_path; + ret = load_scanner_setting(root.c_str(), jsn); + VLOG_MINI_2(LOG_LEVEL_WARNING, "Apply '%s' setting: %d\n", root.c_str(), ret); + if (ret) + return SCANNER_ERR_DATA_DAMAGED; + + init_settings(jsn.c_str()); + + return SCANNER_ERR_OK; +} int hg_scanner::on_scann_error(int err) { status_ = err; diff --git a/hgdriver/hgdev/hg_scanner.h b/hgdriver/hgdev/hg_scanner.h index 2accc54..ea1a07d 100644 --- a/hgdriver/hgdev/hg_scanner.h +++ b/hgdriver/hgdev/hg_scanner.h @@ -241,6 +241,7 @@ protected: BlockingQueue> imgs_; void init_settings(const char* json_setting_text); + int init_settings(int pid); int on_scann_error(int err); // 返回“0”忽略错误继续执行,其它值则停止后续工作 int try_third_app_handle_start(bool& handled); int try_third_app_after_start(int err); diff --git a/hgdriver/hgdev/hg_scanner_200.cpp b/hgdriver/hgdev/hg_scanner_200.cpp index 80d69a1..e3b8569 100644 --- a/hgdriver/hgdev/hg_scanner_200.cpp +++ b/hgdriver/hgdev/hg_scanner_200.cpp @@ -219,7 +219,8 @@ hg_scanner_200::hg_scanner_200(const char* dev_name,int pid, usb_io* io) : hg_sc #ifndef MAPPING_FUNCTION_IN_BASE init_setting_map(setting_map_, ARRAY_SIZE(setting_map_));//优先初始化 #endif - init_settings(jsontext.c_str()); + if (init_settings(0x200)) + init_settings(jsontext.c_str()); printf_devconfig(); } diff --git a/hgdriver/hgdev/hg_scanner_239.cpp b/hgdriver/hgdev/hg_scanner_239.cpp index 77b7363..4378da2 100644 --- a/hgdriver/hgdev/hg_scanner_239.cpp +++ b/hgdriver/hgdev/hg_scanner_239.cpp @@ -433,7 +433,8 @@ hg_scanner_239::hg_scanner_239(const char* dev_name, int pid,usb_io* io) : hg_sc #ifndef MAPPING_FUNCTION_IN_BASE init_setting_map(setting_map_, ARRAY_SIZE(setting_map_)); #endif - init_settings((jsontext1 + jsontext2).c_str()); + if (init_settings(0x239)) + init_settings((jsontext1 + jsontext2).c_str()); writedown_device_configuration(); // initialize the hardware settings init_version(); } diff --git a/hgdriver/hgdev/hg_scanner_300.cpp b/hgdriver/hgdev/hg_scanner_300.cpp index f7d1695..a64d64d 100644 --- a/hgdriver/hgdev/hg_scanner_300.cpp +++ b/hgdriver/hgdev/hg_scanner_300.cpp @@ -200,7 +200,8 @@ hg_scanner_300::hg_scanner_300(const char* dev_name,int pid, usb_io* io) : hg_sc init_setting_map(setting_map_, ARRAY_SIZE(setting_map_));//优先初始化 #endif - init_settings(jsontext.c_str()); + if (init_settings(0x300)) + init_settings(jsontext.c_str()); printf_devconfig(); } diff --git a/hgdriver/hgdev/hg_scanner_400.cpp b/hgdriver/hgdev/hg_scanner_400.cpp index e35606b..f8ab1f7 100644 --- a/hgdriver/hgdev/hg_scanner_400.cpp +++ b/hgdriver/hgdev/hg_scanner_400.cpp @@ -198,7 +198,8 @@ hg_scanner_400::hg_scanner_400(const char* dev_name,int pid, usb_io* io) : hg_sc #ifndef MAPPING_FUNCTION_IN_BASE init_setting_map(setting_map_, ARRAY_SIZE(setting_map_));//优先初始化 #endif - init_settings(jsontext.c_str()); + if (init_settings(0x400)) + init_settings(jsontext.c_str()); printf_devconfig(); } diff --git a/hgdriver/hgdev/hg_scanner_402.cpp b/hgdriver/hgdev/hg_scanner_402.cpp index bb0fae4..79602e0 100644 --- a/hgdriver/hgdev/hg_scanner_402.cpp +++ b/hgdriver/hgdev/hg_scanner_402.cpp @@ -425,7 +425,8 @@ hg_scanner_402::hg_scanner_402(const char* dev_name, int pid,usb_io* io) : hg_sc #ifndef MAPPING_FUNCTION_IN_BASE init_setting_map(setting_map_, ARRAY_SIZE(setting_map_)); #endif - init_settings((jsontext + jsontext2).c_str()); + if(init_settings(0x402)) + init_settings((jsontext + jsontext2).c_str()); writedown_device_configuration(); // initialize the hardware settings init_version(); } diff --git a/hgdriver/hgdev/hg_scanner_439.cpp b/hgdriver/hgdev/hg_scanner_439.cpp index 26bcc5c..bd40647 100644 --- a/hgdriver/hgdev/hg_scanner_439.cpp +++ b/hgdriver/hgdev/hg_scanner_439.cpp @@ -419,7 +419,8 @@ hg_scanner_439::hg_scanner_439(const char* dev_name, int pid,usb_io* io) : hg_sc #ifndef MAPPING_FUNCTION_IN_BASE init_setting_map(setting_map_, ARRAY_SIZE(setting_map_)); #endif - init_settings(jsontext.c_str()); + if (init_settings(0x439)) + init_settings(jsontext.c_str()); writedown_device_configuration(); // initialize the hardware settings_439 init_version(); } diff --git a/hgdriver/hgdev/scanner_setting.cpp b/hgdriver/hgdev/scanner_setting.cpp new file mode 100644 index 0000000..7bd5f52 --- /dev/null +++ b/hgdriver/hgdev/scanner_setting.cpp @@ -0,0 +1,319 @@ +#include "scanner_setting.h" +#include + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// DEFINE ... +#define SSFH_VER_MAIN 1 +#define SSFH_VER_MINOR 0 + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// base64 util .. +static char base64_default_table[] = { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" }; + +base64::base64() : padding_char_('=') +{ + base64_ind_[0] = base64_char_[0] = 0; + + initialize_base64_table(base64_default_table); +} +base64::~base64() +{} + +bool base64::is_valid_base64_table(const char* table) +{ + bool valid = false; + + if (table && strlen(table) >= 64) + { + char repeat[4] = { 0 }; + + valid = true; + for (int i = 0; i < 63; ++i) + { + repeat[0] = table[i]; + if (strstr(table + i + 1, repeat)) + { + valid = false; + break; + } + } + } + + return valid; +} +bool base64::initialize_base64_table(const char* table) +{ + if (!table || strlen(table) < 64) + { + if (memcmp(base64_default_table, base64_char_, 64) == 0) + { + return !table; + } + + memcpy(base64_char_, base64_default_table, 64); + } + else + { + if (memcmp(base64_char_, table, 64) == 0) + { + return true; + } + else if (!is_valid_base64_table(table)) + return false; + + memcpy(base64_char_, table, 64); + } + base64_char_[64] = base64_char_[65] = 0; + + // initialize base64_index + memset(base64_ind_, 0, sizeof(base64_ind_)); + for (int i = 0; i < 64; ++i) + { + base64_ind_[base64_char_[i]] = i; + } + + // padding char + padding_char_ = '='; + if (base64_ind_[padding_char_]) + { + for (padding_char_ = 0x21; padding_char_ < 0x7e && base64_ind_[padding_char_] && padding_char_ != base64_char_[0]; ++padding_char_); + } + + return padding_char_ < 0x7e; +} + +bool base64::set_base64_table(const char* table) +{ + return initialize_base64_table(table ? table : base64_default_table); +} +std::string base64::encode(const char* data, size_t bytes, unsigned int line_bytes, bool need_padding) +{ + char* str = (char*)malloc(bytes * 2 + 3); + unsigned char c1 = 0, c2 = 0, c3 = 0; + unsigned long line_len = 0; + unsigned long words = bytes / 3; + int rest = bytes % 3, + pos = 0; + std::string ret(""); + + for (unsigned long i = 0; i < words; ++i) + { + // fetch 3 letters + c1 = *data++; + c2 = *data++; + c3 = *data++; + + // encoding into 4-bytes + str[pos++] = base64_char_[c1 >> 2]; + str[pos++] = base64_char_[((c1 << 4) | (c2 >> 4)) & 0x3f]; + str[pos++] = base64_char_[((c2 << 2) | (c3 >> 6)) & 0x3f]; + str[pos++] = base64_char_[c3 & 0x3f]; + line_len += 4; + + // new line ... + if ((unsigned int)line_len > line_bytes - 4) + { + str[pos++] = '\r'; + str[pos++] = '\n'; + line_len = 0; + } + } + + // rest ... + if (rest == 1) + { + c1 = *data++; + str[pos++] = base64_char_[(c1 & 0xfc) >> 2]; + str[pos++] = base64_char_[((c1 & 0x03) << 4)]; + if (need_padding) + { + str[pos++] = padding_char_; + str[pos++] = padding_char_; + } + } + else if (rest == 2) + { + c1 = *data++; + c2 = *data++; + str[pos++] = base64_char_[(c1 & 0xfc) >> 2]; + str[pos++] = base64_char_[((c1 & 0x03) << 4) | ((c2 & 0xf0) >> 4)]; + str[pos++] = base64_char_[((c2 & 0x0f) << 2)]; + if (need_padding) + { + str[pos++] = padding_char_; + } + } + if (pos > 0) + { + str[pos++] = 0; + ret = std::string(str, pos - 1); + } + free(str); + + return ret; +} +std::string base64::decode(const char* data, size_t bytes) +{ + char* str = (char*)malloc(bytes + 1); + int pos = 0, + shifts = 18, + value = 0; + std::string ret(""); + + for (int i = 0; i < (int)bytes; ++i) + { + if (*data != '\r' && *data != '\n') + { + if (*data == padding_char_) + { + break; + } + + value += base64_ind_[*data] << shifts; + if (shifts == 0) + { + shifts = 18; + str[pos++] = (value >> 16) & 0x0ff; + str[pos++] = (value >> 8) & 0x0ff; + str[pos++] = (value >> 0) & 0x0ff; + value = 0; + } + else + { + shifts -= 6; + } + } + data++; + } + + if (shifts == 12 || shifts == 6) + { + str[pos++] = (value >> 16) & 0x0ff; + } + else if (shifts == 0) + { + str[pos++] = (value >> 16) & 0x0ff; + str[pos++] = (value >> 8) & 0x0ff; + } + + if (pos > 0) + { + str[pos++] = 0; + ret = std::string(str, pos - 1); + } + free(str); + + return ret; +} + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// check sum .. +unsigned int simple_checksum(const char* data, size_t len) +{ + unsigned int chk = -1; + + while (len >= sizeof(chk)) + { + chk ^= *((unsigned int*)data); + data += sizeof(chk); + len -= sizeof(chk); + } + if (len) + { + unsigned int rest = *((unsigned int*)data), mask = (1 << (len * 8)) - 1; + + rest &= mask; + chk ^= rest; + } + + return chk; +} + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// exporting .. +int load_scanner_setting(const char* file, std::string& jsn) +{ + FILE* src = fopen(file, "rb"); + long len = 0; + char* buf = nullptr; + SSFILEH ssfh = { 0 }; + + if (!src) + return errno; + + fseek(src, 0, SEEK_END); + len = ftell(src); + fseek(src, 0, SEEK_SET); + if (len < sizeof(ssfh)) + { + fclose(src); + + return EBADF; + } + + buf = new char[len]; + if (!buf) + { + fclose(src); + + return ENOMEM; + } + + memset(buf, 0, len); + fread(&ssfh, sizeof(ssfh), 1, src); + len -= sizeof(ssfh); + fread(buf, 1, len, src); + fclose(src); + if (ssfh.ver_main != 1 || + ssfh.ver_sub != 0 || + simple_checksum(buf, len) != (ssfh.checksum ^ ssfh.timestamp) || + ssfh.length != len + sizeof(ssfh)) + { + delete[] buf; + + return EBADF; + } + + base64 b64; + jsn = b64.decode(buf, len); + delete[] buf; + + return 0; +} +int save_scanner_setting(const char* file, const std::string& jsn) +{ + SSFILEH ssfh = { 0 }; + base64 b64; + std::string str(b64.encode(jsn.c_str(), jsn.length())); + + ssfh.ver_main = SSFH_VER_MAIN; + ssfh.ver_sub = SSFH_VER_MINOR; + ssfh.length = str.length() + sizeof(ssfh); + ssfh.timestamp = time(NULL); + ssfh.checksum = simple_checksum(str.c_str(), str.length()); + + FILE *dst = fopen(file, "wb"); + + bool ok = false; + if (!dst) + return ENFILE; + + ssfh.checksum ^= ssfh.timestamp; + if (fwrite(&ssfh, sizeof(ssfh), 1, dst) == 1) + ok = fwrite(str.c_str(), 1, str.length(), dst) == str.length(); + fclose(dst); + if (!ok) + { + remove(file); + + return EFAULT; + } + + return 0; +} diff --git a/hgdriver/hgdev/scanner_setting.h b/hgdriver/hgdev/scanner_setting.h new file mode 100644 index 0000000..acbb05e --- /dev/null +++ b/hgdriver/hgdev/scanner_setting.h @@ -0,0 +1,57 @@ +#pragma once + +// For: check and load scanner configuration json +// +// Date: 2022-08-12 +// +// FileName: 0239.hsc +// +// Location: same parent path of scanner component, rel: ./settings +// +// Format: 0: short - 1.2, version of the file format +// +// 2: int - total length of the whole file, include this head +// +// 6: unsigned - checksum of content +// +// 10: BASE64 of the json content + +#include + +#pragma pack(push) +#pragma pack(1) + +typedef struct _scanner_setting_file_head +{ + unsigned char ver_main; + unsigned char ver_sub; + unsigned int length; // whole file length, include this head + unsigned int checksum; // checksum of BASE64 content + unsigned int timestamp; // time(NULL) + char base64_content[0]; +}SSFILEH, *LPSSFILEH; + +#pragma pack(pop) + +class base64 +{ + char base64_ind_[128]; + char base64_char_[80]; + char padding_char_; + + bool is_valid_base64_table(const char* table); + bool initialize_base64_table(const char* table); + +public: + base64(); + ~base64(); + +public: + bool set_base64_table(const char* table = nullptr); + std::string encode(const char* data, size_t bytes, unsigned int line_bytes = -1, bool need_padding = true); + std::string decode(const char* data, size_t bytes); +}; + +// return 0 for success, otherwise error code +int load_scanner_setting(const char* file, std::string& jsn); +int save_scanner_setting(const char* file, const std::string& jsn);