设备配置改为外部独立文件: ./settings/0239.hsc ...

This commit is contained in:
gb 2022-08-13 09:29:00 +08:00
parent 0ff688a3cf
commit c3e86e4dbf
10 changed files with 407 additions and 6 deletions

View File

@ -1,6 +1,7 @@
#include "hg_scanner.h" #include "hg_scanner.h"
#include "../wrapper/hg_log.h" #include "../wrapper/hg_log.h"
#include "sane/sane_option_definitions.h" #include "sane/sane_option_definitions.h"
#include "scanner_setting.h"
#if defined(WIN32) || defined(_WIN64) #if defined(WIN32) || defined(_WIN64)
#include "scanner_manager.h" #include "scanner_manager.h"
@ -2010,6 +2011,23 @@ void hg_scanner::init_settings(const char* json_setting_text)
setting_count_ = count; setting_count_ = count;
notify_setting_result_ = true; 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) int hg_scanner::on_scann_error(int err)
{ {
status_ = err; status_ = err;

View File

@ -241,6 +241,7 @@ protected:
BlockingQueue<std::shared_ptr<tiny_buffer>> imgs_; BlockingQueue<std::shared_ptr<tiny_buffer>> imgs_;
void init_settings(const char* json_setting_text); void init_settings(const char* json_setting_text);
int init_settings(int pid);
int on_scann_error(int err); // 返回“0”忽略错误继续执行其它值则停止后续工作 int on_scann_error(int err); // 返回“0”忽略错误继续执行其它值则停止后续工作
int try_third_app_handle_start(bool& handled); int try_third_app_handle_start(bool& handled);
int try_third_app_after_start(int err); int try_third_app_after_start(int err);

View File

@ -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 #ifndef MAPPING_FUNCTION_IN_BASE
init_setting_map(setting_map_, ARRAY_SIZE(setting_map_));//优先初始化 init_setting_map(setting_map_, ARRAY_SIZE(setting_map_));//优先初始化
#endif #endif
init_settings(jsontext.c_str()); if (init_settings(0x200))
init_settings(jsontext.c_str());
printf_devconfig(); printf_devconfig();
} }

View File

@ -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 #ifndef MAPPING_FUNCTION_IN_BASE
init_setting_map(setting_map_, ARRAY_SIZE(setting_map_)); init_setting_map(setting_map_, ARRAY_SIZE(setting_map_));
#endif #endif
init_settings((jsontext1 + jsontext2).c_str()); if (init_settings(0x239))
init_settings((jsontext1 + jsontext2).c_str());
writedown_device_configuration(); // initialize the hardware settings writedown_device_configuration(); // initialize the hardware settings
init_version(); init_version();
} }

View File

@ -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_));//优先初始化 init_setting_map(setting_map_, ARRAY_SIZE(setting_map_));//优先初始化
#endif #endif
init_settings(jsontext.c_str()); if (init_settings(0x300))
init_settings(jsontext.c_str());
printf_devconfig(); printf_devconfig();
} }

View File

@ -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 #ifndef MAPPING_FUNCTION_IN_BASE
init_setting_map(setting_map_, ARRAY_SIZE(setting_map_));//优先初始化 init_setting_map(setting_map_, ARRAY_SIZE(setting_map_));//优先初始化
#endif #endif
init_settings(jsontext.c_str()); if (init_settings(0x400))
init_settings(jsontext.c_str());
printf_devconfig(); printf_devconfig();
} }

View File

@ -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 #ifndef MAPPING_FUNCTION_IN_BASE
init_setting_map(setting_map_, ARRAY_SIZE(setting_map_)); init_setting_map(setting_map_, ARRAY_SIZE(setting_map_));
#endif #endif
init_settings((jsontext + jsontext2).c_str()); if(init_settings(0x402))
init_settings((jsontext + jsontext2).c_str());
writedown_device_configuration(); // initialize the hardware settings writedown_device_configuration(); // initialize the hardware settings
init_version(); init_version();
} }

View File

@ -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 #ifndef MAPPING_FUNCTION_IN_BASE
init_setting_map(setting_map_, ARRAY_SIZE(setting_map_)); init_setting_map(setting_map_, ARRAY_SIZE(setting_map_));
#endif #endif
init_settings(jsontext.c_str()); if (init_settings(0x439))
init_settings(jsontext.c_str());
writedown_device_configuration(); // initialize the hardware settings_439 writedown_device_configuration(); // initialize the hardware settings_439
init_version(); init_version();
} }

View File

@ -0,0 +1,319 @@
#include "scanner_setting.h"
#include <time.h>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 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;
}

View File

@ -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 <string>
#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);