diff --git a/scanner/async_scanner.cpp b/scanner/async_scanner.cpp index 094e6b6..dfd9e9f 100644 --- a/scanner/async_scanner.cpp +++ b/scanner/async_scanner.cpp @@ -12,6 +12,7 @@ #include #include #include +#include "scanner_const_opts.h" @@ -56,6 +57,9 @@ async_scanner::async_scanner() : usb_(nullptr), cfg_mgr_(nullptr), scan_id_(0) utils::log_info(msg, LOG_LEVEL_DEBUG); }; cfg_mgr_ = new device_option(user, on_log); + const_opts_ = new scanner_const_opts(); + cfg_mgr_->add(const_opts_); + init(); usb_ = new async_usb_gadget(bulk_handle, on_connect); last_err_ = usb_->last_error(); @@ -71,11 +75,13 @@ async_scanner::~async_scanner() if(cfg_mgr_) { cfg_mgr_->clear(); - delete cfg_mgr_; + cfg_mgr_->release(); + cfg_mgr_ = nullptr; } for(auto& v: send_files_) v->release(); send_files_.clear(); + const_opts_->release(); utils::uninit(); } diff --git a/scanner/async_scanner.h b/scanner/async_scanner.h index 3be36a2..1b793c0 100644 --- a/scanner/async_scanner.h +++ b/scanner/async_scanner.h @@ -15,11 +15,13 @@ class device_option; class image_capture; class img_processor; class gb_json; +class scanner_const_opts; class async_scanner : public refer { async_usb_gadget *usb_; device_option *cfg_mgr_; + scanner_const_opts *const_opts_; MUTEX locker_; uint32_t img_cnt_; @@ -30,7 +32,7 @@ class async_scanner : public refer MUTEX fsender_; std::vector send_files_; - + dyn_mem_ptr handle_bulk_cmd(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required); void init(void); diff --git a/scanner/scanner_const_opts.cpp b/scanner/scanner_const_opts.cpp new file mode 100644 index 0000000..1b2cdd7 --- /dev/null +++ b/scanner/scanner_const_opts.cpp @@ -0,0 +1,192 @@ +#include "scanner_const_opts.h" + +#include +#include +#include + + + + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// version ... +#ifndef VER_MAIN +#define VER_MAIN 2 +#define VER_MINOR 0 +#define VER_DATE 20231218 +#define VER_BUILD 4 +#endif + + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// option json: +static std::string device_opt_json[] = { + "{\"dev-vid\":{\"cat\":\"base\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"USB-VID\",\"desc\":\"\\u8bbe\\u5907\\u5236\\u9020\\u5546\\u5728USB\\u7ec4\\u7ec7\\u7684ID\",\"type\":\"string\",\"fix-id\":34898,\"ui-pos\":10,\"auth\":0,\"readonly\":true,\"size\":16,\"auto\":false,\"cur\":\"3072\",\"default\":\"3072\"},\"dev-pid\":{\"cat\":\"base\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"USB-PID\",\"desc\":\"\\u8bbe\\u5907\\u5728USB\\u7ec4\\u7ec7\\u4e2d\\u7684\\u4ea7\\u54c1ID\",\"type\":\"string\",\"fix-id\":34899,\"ui-pos\":11,\"auth\":0,\"readonly\":true,\"size\":16,\"auto\":false,\"cur\":\"0306\",\"default\":\"0306\"},\"dev-name\":{\"cat\":\"base\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"\\u8bbe\\u5907\\u540d\\u79f0\",\"desc\":\"\\u8bbe\\u5907\\u540d\\u79f0\",\"type\":\"string\",\"fix-id\":34900,\"ui-pos\":12,\"auth\":0,\"readonly\":true,\"size\":96,\"auto\":false,\"cur\":\"300NewTx\",\"default\":\"300NewTx\"},\"dev-model\":{\"cat\":\"base\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"\\u4ea7\\u54c1\\u7cfb\\u5217\",\"desc\":\"\\u8bbe\\u5907\\u6240\\u5c5e\\u4ea7\\u54c1\\u7cfb\\u5217\\u540d\\u79f0\",\"type\":\"string\",\"fix-id\":34901,\"ui-pos\":13,\"auth\":0,\"readonly\":true,\"size\":96,\"auto\":false,\"cur\":\"G300\",\"default\":\"G300\"},\"dev-sn\":{\"cat\":\"base\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"\\u5e8f\\u5217\\u53f7\",\"desc\":\"\\u8bbe\\u5907\\u5e8f\\u5217\\u53f7\",\"type\":\"string\",\"fix-id\":34902,\"ui-pos\":14,\"auth\":0,\"readonly\":true,\"size\":32,\"auto\":false,\"ownread\":true,\"cur\":\"GB20231201\",\"default\":\"GB20231201\"},\"fmw-ver\":{\"cat\":\"base\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"\\u56fa\\u4ef6\\u7248\\u672c\",\"desc\":\"\\u8bbe\\u5907\\u56fa\\u4ef6\\u7248\\u672c\\u53f7\",\"type\":\"string\",\"fix-id\":34903,\"ui-pos\":15,\"auth\":0,\"readonly\":true,\"size\":32,\"auto\":false,\"ownread\":true,\"cur\":\"G2393B0500\",\"default\":\"G2393B0500\"},\"roller-life\":{\"cat\":\"base\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"\\u6eda\\u8f74\\u5bff\\u547d\",\"desc\":\"\\u8be5\\u8bbe\\u5907\\u6eda\\u8f74\\u8fc7\\u7eb8\\u7684\\u6700\\u5927\\u5f20\\u6570\",\"type\":\"int\",\"fix-id\":34907,\"ui-pos\":16,\"auth\":0,\"readonly\":true,\"size\":4,\"auto\":false,\"cur\":450000,\"default\":450000},\"ip-addr\":{\"cat\":\"base\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"IP\",\"desc\":\"\\u8bbe\\u5907\\u8054\\u7f51\\u65f6\\u6240\\u5206\\u914d\\u7684IP\\u5730\\u5740\",\"type\":\"string\",\"fix-id\":34904,\"ui-pos\":20,\"auth\":0,\"readonly\":true,\"size\":96,\"auto\":false,\"ownread\":true,\"cur\":\"0\",\"default\":\"0\"},\"mac-addr\":{\"cat\":\"base\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"MAC\",\"desc\":\"\\u8bbe\\u5907\\u7f51\\u5361\\u5730\\u5740\",\"type\":\"string\",\"fix-id\":34905,\"ui-pos\":21,\"auth\":0,\"readonly\":true,\"size\":96,\"auto\":false,\"ownread\":true,\"cur\":\"0\",\"default\":\"0\"}}" +}; + + + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// scanner_const_opts +scanner_const_opts::scanner_const_opts(const char* dev_path) : root_(dev_path) +{ + init(); +} +scanner_const_opts::~scanner_const_opts() +{} + +std::string scanner_const_opts::get_device_content(const char* path) +{ + FILE *src = fopen((root_ + "/" + path).c_str(), "rb"); + char buf[1024] = {0}; + std::string ret(""); + + if(src) + { + int r = 0; + while((r = fread(buf, 1, sizeof(buf), src)) > 0) + ret += std::string(buf, r); + fclose(src); + } + + return std::move(ret); +} +std::string scanner_const_opts::get_ip(void) +{ + std::string val(utils::get_command_result("ifconfig | grep broadcast")); + char buf[80] = {0}; + + sscanf(val.c_str(), " inet %s", buf); + + return buf; +} +std::string scanner_const_opts::get_mac(void) +{ + std::string val(utils::get_command_result("ifconfig | grep ether")); + char buf[80] = {0}; + + sscanf(val.c_str(), " ether %s", buf); + + return buf; +} +void scanner_const_opts::init(void) +{ + std::string text(""); + gb_json *jsn = new gb_json(); + + for(auto& v: device_opt_json) + text += v; + + if(jsn->attach_text(&text[0])) + { + gb_json *child = nullptr; + + text = ""; + jsn->get_value(SANE_STD_OPT_NAME_VID, child); + if(child) + { + std::string val(get_device_content("idVendor")); + size_t pos = val.find("0x"); + uint16_t id = 0; + + if(pos != std::string::npos) + val.erase(0, 2); + if(utils::from_hex_string(val.c_str(), &id)) + { + char str[20] = {0}; + sprintf(str, "%04X", id); + child->set_value("cur", str); + child->set_value("default", str); + } + child->release(); + } + jsn->get_value(SANE_STD_OPT_NAME_PID, child); + if(child) + { + std::string val(get_device_content("idProduct")); + size_t pos = val.find("0x"); + uint16_t id = 0; + + if(pos != std::string::npos) + val.erase(0, 2); + if(utils::from_hex_string(val.c_str(), &id)) + { + char str[20] = {0}; + sprintf(str, "%04X", id); + child->set_value("cur", str); + child->set_value("default", str); + } + child->release(); + } + jsn->get_value(SANE_STD_OPT_NAME_DEVICE_SERIAL_NO, child); + if(child) + { + std::string val(get_device_content("strings/0x409/serialnumber")); + child->set_value("cur", val.c_str()); + child->set_value("default", val.c_str()); + child->release(); + } + jsn->get_value(SANE_STD_OPT_NAME_DEVICE_MAC_ADDR, child); + if(child) + { + std::string val(get_mac()); + + child->set_value("cur", val.c_str()); + child->set_value("default", val.c_str()); + child->release(); + } + jsn->get_value(SANE_STD_OPT_NAME_DEVICE_IP_ADDR, child); + if(child) + { + std::string val(get_ip()); + + child->set_value("cur", val.c_str()); + child->set_value("default", val.c_str()); + child->release(); + } + + text = jsn->to_string(); + set_opt_json_text(&text[0]); + } + jsn->release(); +} + +char* scanner_const_opts::get_value(const char* name, void* value, size_t* size, int* err) +{ + char *ret = nullptr; + std::string val(""); + + if(err) + *err = 0; + + if(strcmp(name, SANE_STD_OPT_NAME_DEVICE_IP_ADDR) == 0) + { + val = get_ip(); + } + else if(strcmp(name, SANE_STD_OPT_NAME_DEVICE_MAC_ADDR) == 0) + { + val = get_mac(); + } + else if(strcmp(name, SANE_STD_OPT_NAME_DEVICE_SERIAL_NO) == 0) + { + val = get_device_content("strings/0x409/serialnumber"); + } + else if(strcmp(name, SANE_STD_OPT_NAME_FIRMWARE_VERSION) == 0) + { + char ver[40] = {0}; + sprintf(ver, "%u.%u.%u%02u", VER_MAIN, VER_MINOR, VER_DATE, VER_BUILD); + val = ver; + } + else if(err) + *err = ENOTSUP; + + if(val.length()) + { + ret = (char*)malloc(val.length() + 1); + memset(ret, 0, val.length() + 1); + strcpy(ret, val.c_str()); + if(size) + *size = val.length(); + } + + return ret; +} \ No newline at end of file diff --git a/scanner/scanner_const_opts.h b/scanner/scanner_const_opts.h new file mode 100644 index 0000000..150eb05 --- /dev/null +++ b/scanner/scanner_const_opts.h @@ -0,0 +1,169 @@ +// scanner const attributes definitions: +// +// Contains: vid, pid, serial-number, ip, mac, firmware-ver, roll-life, name, family +// +// Date: 2023-12-16 + +#include + +class scanner_const_opts : public sane_opt_provider +{ + std::string root_; + + std::string get_device_content(const char* path); + std::string get_ip(void); + std::string get_mac(void); + + void init(void); + +public: + scanner_const_opts(const char* dev_path = "/opt/cfg/usb_gadget/g1"); +protected: + ~scanner_const_opts(); + +public: + // return malloc(), real data size stored in parameter 'size'. invoker should free() the returned value + virtual char* get_value(const char* name, void* value, size_t* size, int* err = nullptr) override; +}; + +// { +// "dev-vid": { +// "cat": "base", +// "group": "关于", +// "title": "USB-VID", +// "desc": "设备制造商在USB组织的ID", +// "type": "int", +// "fix-id": 34898, +// "ui-pos": 10, +// "auth": 0, +// "readonly": true, +// "size": 4, +// "auto": false, +// "cur": 0, +// "default": 0 +// }, +// "dev-pid": { +// "cat": "base", +// "group": "关于", +// "title": "USB-PID", +// "desc": "设备在USB组织中的产品ID", +// "type": "int", +// "fix-id": 34899, +// "ui-pos": 11, +// "auth": 0, +// "readonly": true, +// "size": 4, +// "auto": false, +// "cur": 0, +// "default": 0 +// }, +// "dev-name": { +// "cat": "base", +// "group": "关于", +// "title": "设备名称", +// "desc": "设备名称", +// "type": "string", +// "fix-id": 34900, +// "ui-pos": 12, +// "auth": 0, +// "readonly": true, +// "size": 96, +// "auto": false, +// "cur": "300NewTx", +// "default": "300NewTx" +// }, +// "dev-model": { +// "cat": "base", +// "group": "关于", +// "title": "产品系列", +// "desc": "设备所属产品系列名称", +// "type": "string", +// "fix-id": 34901, +// "ui-pos": 13, +// "auth": 0, +// "readonly": true, +// "size": 96, +// "auto": false, +// "cur": "G300", +// "default": "G300" +// }, +// "dev-sn": { +// "cat": "base", +// "group": "关于", +// "title": "序列号", +// "desc": "设备序列号", +// "type": "string", +// "fix-id": 34902, +// "ui-pos": 14, +// "auth": 0, +// "readonly": true, +// "size": 96, +// "auto": false, +// "ownread": true, +// "cur": "GB20231201", +// "default": "GB20231201" +// }, +// "fmw-ver": { +// "cat": "base", +// "group": "关于", +// "title": "固件版本", +// "desc": "设备固件版本号", +// "type": "string", +// "fix-id": 34903, +// "ui-pos": 15, +// "auth": 0, +// "readonly": true, +// "size": 96, +// "auto": false, +// "ownread": true, +// "cur": "G2393B0500", +// "default": "G2393B0500" +// }, +// "roller-life": { +// "cat": "base", +// "group": "关于", +// "title": "滚轴寿命", +// "desc": "该设备滚轴过纸的最大张数", +// "type": "int", +// "fix-id": 34907, +// "ui-pos": 16, +// "auth": 0, +// "readonly": true, +// "size": 4, +// "auto": false, +// "cur": 0, +// "default": 0 +// }, +// "ip-addr": { +// "cat": "base", +// "group": "关于", +// "title": "IP", +// "desc": "设备联网时所分配的IP地址", +// "type": "string", +// "fix-id": 34904, +// "ui-pos": 20, +// "auth": 0, +// "readonly": true, +// "size": 96, +// "auto": false, +// "ownread": true, +// "cur": "0", +// "default": "0" +// }, +// "mac-addr": { +// "cat": "base", +// "group": "关于", +// "title": "MAC", +// "desc": "设备网卡地址", +// "type": "string", +// "fix-id": 34905, +// "ui-pos": 21, +// "auth": 0, +// "readonly": true, +// "size": 96, +// "auto": false, +// "ownread": true, +// "cur": "0", +// "default": "0" +// } +// } \ No newline at end of file diff --git a/sdk/base/utils.cpp b/sdk/base/utils.cpp index 9a5720e..c6e9944 100644 --- a/sdk/base/utils.cpp +++ b/sdk/base/utils.cpp @@ -857,6 +857,72 @@ namespace utils return str.c_str(); } + bool from_hex_string(const char* hex, uint8_t* val) + { + *val = 0; + if(*hex >= '0' && *hex <= '9') + *val = *hex - '0'; + else if(*hex >= 'a' && *hex <= 'f') + *val = *hex - 'a' + 10; + else if(*hex >= 'A' && *hex <= 'F') + *val = *hex - 'A' + 10; + else + return *hex == 0; + + hex++; + if(*hex) + { + *val <<= 4; + if(*hex >= '0' && *hex <= '9') + *val += *hex - '0'; + else if(*hex >= 'a' && *hex <= 'f') + *val += *hex - 'a' + 10; + else if(*hex >= 'A' && *hex <= 'F') + *val += *hex - 'A' + 10; + else + return false; + } + + return true; + } + bool from_hex_string(const char* hex, uint16_t* val) + { + if(from_hex_string(hex, (uint8_t*)val)) + { + hex += 2; + *val = swap_half(*val); + + return from_hex_string(hex, (uint8_t*)val); + } + else + return false; + } + bool from_hex_string(const char* hex, uint32_t* val) + { + if(from_hex_string(hex, (uint16_t*)val)) + { + hex += 4; + *val = swap_half(*val); + + return from_hex_string(hex, (uint16_t*)val); + } + else + return false; + } + bool from_hex_string(const char* hex, uint64_t* val) + { + if(from_hex_string(hex, (uint32_t*)val)) + { + hex += 8; + *val = swap_half(*val); + + return from_hex_string(hex, (uint32_t*)val); + } + else + return false; + } + + HMODULE load_dll(const char* path_file, int flag) { #if OS_WIN @@ -1103,7 +1169,7 @@ namespace utils if (fn_appendix) file += fn_appendix; file += ".log"; - printf("log file: %s\n", file.c_str()); + printf("log file : %s\n", file.c_str()); } log_cls::instance()->set_log_type(type, &file[0]); diff --git a/sdk/base/utils.h b/sdk/base/utils.h index 811c833..52c53af 100644 --- a/sdk/base/utils.h +++ b/sdk/base/utils.h @@ -52,6 +52,11 @@ namespace utils const char* to_lower(std::string& str); // return str.c_str() const char* trim(std::string& str, const char* sp = "\r\n\t "); // return str.c_str() + bool from_hex_string(const char* hex, uint8_t* val); + bool from_hex_string(const char* hex, uint16_t* val); + bool from_hex_string(const char* hex, uint32_t* val); + bool from_hex_string(const char* hex, uint64_t* val); + HMODULE load_dll(const char* path_file, int flag); bool create_folder(const char* folder); void set_ini_value(const char* seg, const char* key, const char* val, const char* cfg_file); diff --git a/usb/usb_dev.cpp b/usb/usb_dev.cpp index fbb4889..d1f3a37 100644 --- a/usb/usb_dev.cpp +++ b/usb/usb_dev.cpp @@ -741,7 +741,6 @@ int usb_device::pull_down(void) if(l == 1) { utils::to_log(LOG_LEVEL_DEBUG, "pull down device by write '' to '%s' directly success.\n", udc_.c_str()); - std::this_thread::sleep_for(std::chrono::seconds(3)); on_ = false; return 0; }