add file_map; add palt_types.h; fix device_opt

This commit is contained in:
gb 2023-12-09 18:22:26 +08:00
parent 9d9c38aaec
commit 955584c894
18 changed files with 1047 additions and 128 deletions

View File

@ -108,6 +108,10 @@ PACKIMAGE img_receiver::head(void)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// hg_scanner
static std::string device_opt_json[] = {
"{\"tx-prog\":{\"cat\":\"none\",\"group\":\"\\u9ad8\\u7ea7\\u8bbe\\u7f6e\",\"title\":\"\\u6587\\u4ef6\\u4f20\\u8f93\\u8fdb\\u5ea6\",\"desc\":\"\\u4f20\\u8f93\\u6587\\u4ef6\\u5b8c\\u6210\\u767e\\u5206\\u6bd4\",\"type\":\"float\",\"ui-pos\":0,\"auth\":0,\"size\":8,\"ownread\":true,\"cur\":0.000000,\"default\":0.000000}}"
};
hg_scanner::hg_scanner(ONLNSCANNER* dev, imgproc_mgr* imgproc, hguser* user, std::vector<sane_opt_provider*>* constopts)
: dev_(*dev), status_(SCANNER_ERR_OPENED_BY_OTHER_PROCESS)
, msg_(from_default_language("\350\256\276\345\244\207\345\267\262\347\273\217\350\242\253\350\277\233\347\250\213 '%s' \345\215\240\347\224\250"))
@ -142,11 +146,11 @@ hg_scanner::hg_scanner(ONLNSCANNER* dev, imgproc_mgr* imgproc, hguser* user, std
dev_opts_->add(v);
}
#ifdef USE_SAFE_THREAD
auto tf = [this](void*) -> void
auto tf = [this](void) -> void
{
thread_image_processor();
};
imgpr_thread_.start(tf, nullptr, "hg_scanner::thread_image_processor");
imgpr_thread_.start(tf, "hg_scanner::thread_image_processor", NULL);
#else
imgpr_thread_.reset(new std::thread(&hg_scanner::thread_image_processor, this));
#endif
@ -205,6 +209,16 @@ void hg_scanner::init(void)
if (ret == SCANNER_ERR_OK)
{
std::string pc("");
for (auto& v : device_opt_json)
pc += v;
if (pc.length())
pc.erase(0, 1);
if (opts.length())
opts[opts.length() - 1] = ',';
else
opts = "{";
opts += pc;
ret = scanner_->option_get_all(opts);
set_opt_json_text(&opts[0]);
if(user_)
@ -233,6 +247,23 @@ void hg_scanner::thread_image_processor(void)
//processor->release();
}
char* hg_scanner::get_value(const char* name, void* value, size_t* size, int* err)
{
char* ret = nullptr;
if (strcmp(name, "tx-prog") == 0)
{
ret = (char*)malloc(sizeof(double));
*(double*)ret = tx_prg_;
if (size)
*size = sizeof(double);
if (err)
*err = status_;
}
return ret;
}
int hg_scanner::set_value(const char* name, void* val)
{
int type = DATA_TYPE_BOOL,
@ -344,8 +375,11 @@ int hg_scanner::read_image_data(uint8_t* buf, size_t* len)
{
return SCANNER_ERR_OK;
}
int hg_scanner::status(void)
int hg_scanner::status(EP0REPLYSTATUS* ds)
{
if (ds)
scanner_->get_scanner_status(ds);
return status_;
}
std::string hg_scanner::status_message(void)
@ -363,3 +397,25 @@ device_option* hg_scanner::get_device_opt(void)
return dev_opts_;
}
int hg_scanner::file_transfer(const char* local, const char* remote, bool to_remote)
{
auto prog = [this](uint64_t total, uint64_t txed, uint32_t err, void* user) -> int
{
double now = txed;
now /= total;
tx_prg_ = now;
status_ = err;
if (err)
utils::to_log(LOG_LEVEL_WARNING, "File transfer error: %d (at %ld/%ld)\n", err, txed, total);
else if (txed >= total)
utils::to_log(LOG_LEVEL_DEBUG, "File transfer finished(%ld/%ld) with error %d\n", txed, total, err);
return 0;
};
tx_prg_ = .0f;
return scanner_->file_transfer(local, remote, to_remote, prog);
}

View File

@ -81,6 +81,8 @@ class hg_scanner : public sane_opt_provider
scanner_handler *scanner_ = nullptr;
hguser *user_ = nullptr;
double tx_prg_ = .0f; // file transfer progress
volatile bool cancelled_ = false;
volatile bool run_ = true;
safe_fifo<img_receiver*> raw_imgs_;
@ -105,6 +107,7 @@ protected:
// sane_opt_provider
public:
virtual char* get_value(const char* name, void* value, size_t* size, int* err = nullptr) override;
virtual int set_value(const char* name, void* val) override;
// scanner operation ...
@ -115,8 +118,12 @@ public:
int re_connect(void);
int get_image_info(SANE_Parameters* pii);
int read_image_data(uint8_t* buf, size_t* len);
int status(void);
int status(EP0REPLYSTATUS* ds = nullptr);
std::string status_message(void);
bool is_online(void);
// advanced functions ...
public:
device_option* get_device_opt(void);
int file_transfer(const char* local, const char* remote, bool to_remote); // get_value("tx-prog", (double*)percent) to query progress
};

View File

@ -135,6 +135,31 @@ int async_usb_host::start(libusb_device* dev)
bulk_out_.claimed = 1;
}
// check version ...
{
libusb_device_descriptor dd = { 0 };
char product[128] = { 0 };
int ver = 1;
if (libusb_get_device_descriptor(dev, &dd) == LIBUSB_SUCCESS)
{
libusb_get_string_descriptor_ascii(usb_handle_, dd.iProduct, (unsigned char*)product, _countof(product) - 1);
utils::to_log(LOG_LEVEL_DEBUG, "Product: '%s'\n", product);
char* v = strstr(product, "(V");
if (v)
{
ver = atoi(v + 2);
}
}
if (ver < 2)
{
stop();
return EPROTONOSUPPORT;
}
}
run_ = true;
libusb_ref_device(dev);
usb_dev_ = dev;
@ -362,21 +387,21 @@ void async_usb_host::thread_pump_task(void)
void async_usb_host::create_worker_threads(void)
{
#ifdef USE_SAFE_THREAD
auto thread_w = [this](void*) -> void
auto thread_w = [this](void) -> void
{
thread_write_bulk();
};
auto thread_r = [this](void*) -> void
auto thread_r = [this](void) -> void
{
thread_read_bulk();
};
auto thread_p = [this](void*) -> void
auto thread_p = [this](void) -> void
{
thread_pump_task();
};
thread_w_.start(thread_w, nullptr, "async_usb_host::thread_write_bulk");
thread_r_.start(thread_r, nullptr, "async_usb_host::thread_read_bulk");
thread_p_.start(thread_p, nullptr, "async_usb_host::thread_pump_task");
thread_w_.start(thread_w, "async_usb_host::thread_write_bulk");
thread_r_.start(thread_r, "async_usb_host::thread_read_bulk");
thread_p_.start(thread_p, "async_usb_host::thread_pump_task");
#else
thread_w_.reset(new std::thread(&async_usb_host::thread_write_bulk, this));
thread_r_.reset(new std::thread(&async_usb_host::thread_read_bulk, this));
@ -524,6 +549,7 @@ dyn_mem_ptr async_usb_host::handle_data_in(dyn_mem_ptr& data, uint32_t* used, pa
int async_usb_host::get_peer_protocol_version(uint16_t* ver)
{
SIMPLE_LOCK(io_lock_);
uint16_t v = 0;
int err = libusb_control_transfer(usb_handle_, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN
, USB_REQ_EP0_GET_PROTO_VER, 0, 0
@ -537,6 +563,8 @@ int async_usb_host::get_peer_protocol_version(uint16_t* ver)
}
int async_usb_host::get_peer_status(LPEP0REPLYSTATUS status)
{
SIMPLE_LOCK(io_lock_);
return libusb_control_transfer(usb_handle_, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN
, USB_REQ_EP0_GET_STATUS, 0, 0
, (unsigned char*)status, sizeof(*status)
@ -546,17 +574,23 @@ int async_usb_host::restart_peer_bulk(uint32_t timeout)
{
EP0REPLYSTATUS status = { 0 };
chronograph tc;
int ok = 0,
w = 0,
err = 0;
{
SIMPLE_LOCK(io_lock_);
err = libusb_control_transfer(usb_handle_, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN
, USB_REQ_EP0_RESET_BULK, 0, 0
, (unsigned char*)&ok, sizeof(ok)
, 1000);
}
tc.reset();
while ((err = get_peer_status(&status)) == 0 && ok == 0)
{
if (status.in_status == BULK_STATUS_IDLE)
if (status.in_status == WORKER_STATUS_IDLE)
break;
std::this_thread::sleep_for(std::chrono::milliseconds(5));
@ -571,6 +605,8 @@ int async_usb_host::restart_peer_bulk(uint32_t timeout)
}
int async_usb_host::reset_io_buffer_size(unsigned short size)
{
SIMPLE_LOCK(io_lock_);
libusb_control_transfer(usb_handle_, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT
, USB_REQ_EP0_SET_BULK_BUFFER, 0, size
, nullptr, 0
@ -597,9 +633,12 @@ int async_usb_host::set_gadget_encrypting_method(uint32_t cmd_enc, uint32_t payl
pack->enc_cmd = cmd_enc;
pack->encrypt = payload_enc;
pack->enc_data = enc_data;
{
SIMPLE_LOCK(io_lock_);
err = libusb_control_transfer(usb_handle_, LIBUSB_REQUEST_TYPE_VENDOR, USB_REQ_EP0_SET_ENCRYPT, 0, 0
, (unsigned char*)pack, sizeof(*pack)
, 1000);
}
ptr->release();
return err;
@ -861,6 +900,8 @@ int async_usb_host::cancel_write(void)
}
int async_usb_host::raw_control(uint8_t type, uint8_t req, uint16_t ind, uint16_t val, uint16_t len, void* data)
{
SIMPLE_LOCK(io_lock_);
return libusb_control_transfer(usb_handle_, type
, req, val, ind
, (unsigned char*)data, len

View File

@ -39,6 +39,8 @@ class async_usb_host : public refer
libusb_device* usb_dev_;
USBEP bulk_in_;
USBEP bulk_out_;
MUTEX io_lock_;
safe_fifo<dyn_mem_ptr> in_que_;
safe_fifo<data_source_ptr> out_que_;
#ifdef USE_SAFE_THREAD

View File

@ -543,21 +543,18 @@ int scanner_handler::file_transfer(const char* local_path, const char* remote_pa
if (to_device)
{
uint64_t size = 0;
FILE *src = fopen(local_path, "rb");
file_reader *reader = new file_reader();
int err = reader->open(local_path, true, local_off);
if (!src)
return errno;
FSEEK(src, 0, SEEK_END);
size = FTELL(src);
FSEEK(src, local_off, SEEK_SET);
if (size <= local_off)
{
fclose(src);
return EOVERFLOW;
}
size -= local_off;
utils::to_log(LOG_LEVEL_DEBUG, "Send '%s' to '%s' ...\r\n", local_path, remote_path);
if (err)
{
utils::to_log(LOG_LEVEL_FATAL, "Send file failed in open local file '%s': %d\n", local_path, err);
reader->release();
return err;
}
size = reader->get_rest();
reader->set_progress_notify(progress);
auto call = [&](cmd_result* cmd) -> int
{
@ -565,10 +562,10 @@ int scanner_handler::file_transfer(const char* local_path, const char* remote_pa
};
auto clean = [&](cmd_result* cmd) -> int
{
FILE* src = (FILE*)cmd->get_param();
file_reader* reader = (file_reader*)cmd->get_param();
if (src)
fclose(src);
if (reader)
reader->release();
return 0;
};
@ -589,10 +586,8 @@ int scanner_handler::file_transfer(const char* local_path, const char* remote_pa
}
else
{
file_reader_ptr freader = new file_reader();
file_reader_ptr freader = (file_reader_ptr)cmd->set_param(nullptr);
int err = freader->attach((FILE*)cmd->set_param(nullptr));
freader->set_progress_notify(progress);
if (err)
{
// cancel tx-file ...
@ -614,7 +609,7 @@ int scanner_handler::file_transfer(const char* local_path, const char* remote_pa
return ret;
};
WAIT_COMMAND(call, clean, roger, src);
WAIT_COMMAND(call, clean, roger, reader);
}
else
{
@ -630,10 +625,13 @@ int scanner_handler::file_transfer(const char* local_path, const char* remote_pa
{
LPPACK_BASE pack = (LPPACK_BASE)data->ptr();
LPTXFILE pfi = (LPTXFILE)pack->payload;
dyn_mem_ptr reply = dyn_mem::memory(sizeof(PACK_BASE));
*used = sizeof(PACK_BASE) + pack->payload_len;
*more = nullptr;
utils::to_log(LOG_LEVEL_DEBUG, "Receive file - Roger result: %d\r\n", pack->data);
BASE_PACKET_REPLY((*(LPPACK_BASE)reply->ptr()), PACK_CMD_FILE_READ_REQ_ROGER, pack->pack_id, -1);
reply->set_len(sizeof(PACK_BASE));
if (pack->data == 0)
{
if (cmd->is_over())
@ -644,19 +642,21 @@ int scanner_handler::file_transfer(const char* local_path, const char* remote_pa
else
{
file_saver* fsaver = new file_saver();
int err = fsaver->open(local_path, pfi->size);
fsaver->set_progress_notify(progress);
int err = fsaver->open(local_path, pfi->size, true, local_off);
if (err)
{
// cancel tx-file ...
cmd->set_error_code(err);
(*(LPPACK_BASE)reply->ptr()).data = err;
fsaver->release();
reset_message_que();
utils::to_log(LOG_LEVEL_DEBUG, "Receive file - open local file failed: %d\r\n", err);
}
else
{
fsaver->set_progress_notify(progress);
*more = dynamic_cast<packet_data_base_ptr>(fsaver);
(*(LPPACK_BASE)reply->ptr()).data = 0;
status_ = SCANNER_STATUS_BUSY;
utils::to_log(LOG_LEVEL_DEBUG, "Receive file - beginning ...\r\n");
}
@ -664,7 +664,7 @@ int scanner_handler::file_transfer(const char* local_path, const char* remote_pa
}
cmd->trigger();
return nullptr;
return reply;
};
utils::to_log(LOG_LEVEL_DEBUG, "Receive '%s' to '%s' ...\r\n", remote_path, local_path);
@ -805,6 +805,8 @@ int scanner_handler::close(void)
}
int scanner_handler::reset_message_que(void)
{
return 0;
int err = usb_->cancel_write();
status_ = SCANNER_STATUS_RESET_BULK;

View File

@ -19,6 +19,147 @@ void memset(void* buf, unsigned char fill, int len)
}
#endif
#ifdef TEST_HGSCANNER
const char* hg_scanner_err_name(int err, char* buf)
{
RETURN_IF(err, SANE_STATUS_GOOD);
RETURN_IF(err, SANE_STATUS_UNSUPPORTED);
RETURN_IF(err, SANE_STATUS_CANCELLED);
RETURN_IF(err, SANE_STATUS_DEVICE_BUSY);
RETURN_IF(err, SANE_STATUS_INVAL);
RETURN_IF(err, SANE_STATUS_EOF);
RETURN_IF(err, SANE_STATUS_JAMMED);
RETURN_IF(err, SANE_STATUS_NO_DOCS);
RETURN_IF(err, SANE_STATUS_COVER_OPEN);
RETURN_IF(err, SANE_STATUS_IO_ERROR);
RETURN_IF(err, SANE_STATUS_NO_MEM);
RETURN_IF(err, SANE_STATUS_ACCESS_DENIED);
RETURN_IF(err, SCANNER_ERR_INVALID_PARAMETER);
RETURN_IF(err, SCANNER_ERR_USER_CANCELED);
RETURN_IF(err, SCANNER_ERR_INSUFFICIENT_MEMORY);
RETURN_IF(err, SCANNER_ERR_ACCESS_DENIED);
RETURN_IF(err, SCANNER_ERR_IO_PENDING);
RETURN_IF(err, SCANNER_ERR_NOT_EXACT);
RETURN_IF(err, SCANNER_ERR_CONFIGURATION_CHANGED);
RETURN_IF(err, SCANNER_ERR_RELOAD_IMAGE_PARAM);
RETURN_IF(err, SCANNER_ERR_RELOAD_OPT_PARAM);
RETURN_IF(err, SCANNER_ERR_NOT_OPEN);
RETURN_IF(err, SCANNER_ERR_NOT_START);
RETURN_IF(err, SCANNER_ERR_NOT_ANY_MORE);
RETURN_IF(err, SCANNER_ERR_NO_DATA);
RETURN_IF(err, SCANNER_ERR_HAS_DATA_YET);
RETURN_IF(err, SCANNER_ERR_OUT_OF_RANGE);
RETURN_IF(err, SCANNER_ERR_IO);
RETURN_IF(err, SCANNER_ERR_TIMEOUT);
RETURN_IF(err, SCANNER_ERR_OPEN_FILE_FAILED);
RETURN_IF(err, SCANNER_ERR_CREATE_FILE_FAILED);
RETURN_IF(err, SCANNER_ERR_WRITE_FILE_FAILED);
RETURN_IF(err, SCANNER_ERR_DATA_DAMAGED);
RETURN_IF(err, SCANNER_ERR_OPENED_BY_OTHER_PROCESS);
RETURN_IF(err, SCANNER_ERR_USB_INIT_FAILED);
RETURN_IF(err, SCANNER_ERR_USB_REGISTER_PNP_FAILED);
RETURN_IF(err, SCANNER_ERR_USB_CLAIM_INTERFACE_FAILED);
RETURN_IF(err, SCANNER_ERR_DEVICE_NOT_FOUND);
RETURN_IF(err, SCANNER_ERR_DEVICE_NOT_SUPPORT);
RETURN_IF(err, SCANNER_ERR_DEVICE_BUSY);
RETURN_IF(err, SCANNER_ERR_DEVICE_SLEEPING);
RETURN_IF(err, SCANNER_ERR_DEVICE_COUNT_MODE);
RETURN_IF(err, SCANNER_ERR_DEVICE_STOPPED);
RETURN_IF(err, SCANNER_ERR_DEVICE_COVER_OPENNED);
RETURN_IF(err, SCANNER_ERR_DEVICE_NO_PAPER);
RETURN_IF(err, SCANNER_ERR_DEVICE_FEEDING_PAPER);
RETURN_IF(err, SCANNER_ERR_DEVICE_DOUBLE_FEEDING);
RETURN_IF(err, SCANNER_ERR_DEVICE_PAPER_JAMMED);
RETURN_IF(err, SCANNER_ERR_DEVICE_STAPLE_ON);
RETURN_IF(err, SCANNER_ERR_DEVICE_PAPER_SKEW);
RETURN_IF(err, SCANNER_ERR_DEVICE_SIZE_CHECK);
RETURN_IF(err, SCANNER_ERR_DEVICE_DOGEAR);
RETURN_IF(err, SCANNER_ERR_DEVICE_NO_IMAGE);
RETURN_IF(err, SCANNER_ERR_DEVICE_SCANN_ERROR);
RETURN_IF(err, SCANNER_ERR_DEVICE_PC_BUSY);
RETURN_IF(err, SCANNER_ERR_DEVICE_ISLOCK);
RETURN_IF(err, SCANNER_ERR_DEVICE_MAYBE_IS_HOLE);
RETURN_IF(err, SCANNER_ERR_DEVICE_DEVS_BOOTING);
RETURN_IF(err, SCANNER_ERR_DEVICE_UNKNOWN_STATUS);
RETURN_IF(err, SCANNER_ERR_LANG_PAK_LOST);
RETURN_IF(err, SCANNER_ERR_THROW_EXCEPTION);
sprintf(buf, "Unknown error: 0x%X", err);
return buf;
}
const char* hg_scanner_err_description(int err)
{
RETURN_DESC_IF(err, SCANNER_ERR_OK);
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_NOT_SUPPORT);
RETURN_DESC_IF(err, SCANNER_ERR_USER_CANCELED);
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_BUSY);
RETURN_DESC_IF(err, SCANNER_ERR_INVALID_PARAMETER);
RETURN_DESC_IF(err, SCANNER_ERR_NO_DATA);
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_PAPER_JAMMED);
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_NO_PAPER);
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_COVER_OPENNED);
RETURN_DESC_IF(err, SCANNER_ERR_IO);
RETURN_DESC_IF(err, SCANNER_ERR_INSUFFICIENT_MEMORY);
RETURN_DESC_IF(err, SCANNER_ERR_ACCESS_DENIED);
RETURN_DESC_IF(err, SCANNER_ERR_INSUFFICIENT_MEMORY);
RETURN_DESC_IF(err, SCANNER_ERR_ACCESS_DENIED);
RETURN_DESC_IF(err, SCANNER_ERR_IO_PENDING);
RETURN_DESC_IF(err, SCANNER_ERR_NOT_EXACT);
RETURN_DESC_IF(err, SCANNER_ERR_CONFIGURATION_CHANGED);
RETURN_DESC_IF(err, SCANNER_ERR_RELOAD_IMAGE_PARAM);
RETURN_DESC_IF(err, SCANNER_ERR_RELOAD_OPT_PARAM);
RETURN_DESC_IF(err, SCANNER_ERR_NOT_OPEN);
RETURN_DESC_IF(err, SCANNER_ERR_NOT_START);
RETURN_DESC_IF(err, SCANNER_ERR_NOT_ANY_MORE);
RETURN_DESC_IF(err, SCANNER_ERR_NO_DATA);
RETURN_DESC_IF(err, SCANNER_ERR_HAS_DATA_YET);
RETURN_DESC_IF(err, SCANNER_ERR_OUT_OF_RANGE);
RETURN_DESC_IF(err, SCANNER_ERR_IO);
RETURN_DESC_IF(err, SCANNER_ERR_TIMEOUT);
RETURN_DESC_IF(err, SCANNER_ERR_OPEN_FILE_FAILED);
RETURN_DESC_IF(err, SCANNER_ERR_CREATE_FILE_FAILED);
RETURN_DESC_IF(err, SCANNER_ERR_WRITE_FILE_FAILED);
RETURN_DESC_IF(err, SCANNER_ERR_DATA_DAMAGED);
RETURN_DESC_IF(err, SCANNER_ERR_OPENED_BY_OTHER_PROCESS);
RETURN_DESC_IF(err, SCANNER_ERR_USB_INIT_FAILED);
RETURN_DESC_IF(err, SCANNER_ERR_USB_REGISTER_PNP_FAILED);
RETURN_DESC_IF(err, SCANNER_ERR_USB_CLAIM_INTERFACE_FAILED);
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_NOT_FOUND);
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_NOT_SUPPORT);
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_BUSY);
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_SLEEPING);
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_COUNT_MODE);
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_STOPPED);
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_COVER_OPENNED);
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_NO_PAPER);
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_FEEDING_PAPER);
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_DOUBLE_FEEDING);
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_PAPER_JAMMED);
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_STAPLE_ON);
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_PAPER_SKEW);
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_SIZE_CHECK);
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_DOGEAR);
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_NO_IMAGE);
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_SCANN_ERROR);
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_PC_BUSY);
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_ISLOCK);
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_MAYBE_IS_HOLE);
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_DEVS_BOOTING);
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_UNKNOWN_STATUS);
if (err == SCANNER_ERR_LANG_PAK_LOST)
return "SCANNER_ERR_LANG_PAK_LOST";
// NOTE: multi-thread unsafe here
static char g_unk_err[128] = { 0 };
strcpy(g_unk_err, from_default_language(STATU_DESC_SCANNER_ERR_DEVICE_UNKNOWN_ERROR));
sprintf(g_unk_err + strlen(g_unk_err), ":0x%x", err);
return g_unk_err;
}
#endif
usb_manager* usb_manager::inst_ = NULL;
uint8_t usb_manager::uninit_uint8 = 0x0ff;
@ -37,11 +178,11 @@ usb_manager::usb_manager() : run_(true)
wait_pnp_.set_debug_info("Waiting PNP");
#ifdef USE_SAFE_THREAD
auto tf = [this](void*) -> void
auto tf = [this](void) -> void
{
thread_notify_usb_event();
};
usb_notify_thread_.start(tf, nullptr, "usb_manager::thread_notify_usb_event");
usb_notify_thread_.start(tf, "usb_manager::thread_notify_usb_event");
#else
if (!usb_notify_thread_.get())
{
@ -134,11 +275,11 @@ int usb_manager::register_usb_pnp(void)
void usb_manager::init_notify_thread()
{
#ifdef USE_SAFE_THREAD
auto tf = [this](void*) -> void
auto tf = [this](void) -> void
{
thread_trigger_usb_event();
};
usb_monitor_thread_.start(tf, nullptr, "usb_manager::thread_trigger_usb_event");
usb_monitor_thread_.start(tf, "usb_manager::thread_trigger_usb_event");
#else
if(!usb_monitor_thread_.get())
{
@ -804,6 +945,23 @@ void usb_io::init_after_open(void)
close();
last_err_ = err;
}
else
{
libusb_device_descriptor dd = { 0 };
char product[128] = { 0 };
if (libusb_get_device_descriptor(dev_info_.device, &dd) == LIBUSB_SUCCESS)
{
libusb_get_string_descriptor_ascii(handle_, dd.iProduct, (unsigned char*)product, _countof(product) - 1);
utils::to_log(LOG_LEVEL_DEBUG, "Product: %s\n", product);
char* v = strstr(product, "(V");
if (v)
{
ver_ = atoi(v + 2);
}
}
}
}
void usb_io::open(void)
{
@ -1138,6 +1296,10 @@ int usb_io::get_pid(void)
{
return dev_info_.pid;
}
int usb_io::get_ver(void)
{
return ver_;
}
void usb_io::on_disconnected(void)
{

View File

@ -1,7 +1,7 @@
#pragma once
#if defined(WIN32) || defined(_WIN64)
#include "win_usb/win_usb.h"
#include <win_usb/win_usb.h>
#else
#include <libusb-1.0/libusb.h>
@ -158,6 +158,7 @@ class usb_io
int last_err_;
std::string init_err_msg_;
libusb_device *ref_device_;
int ver_ = 1;
// endpoint ports
usb_manager::USBTRANSENDP endpoints_;
@ -197,6 +198,7 @@ public:
libusb_device* get_usb_device(void); // 获取该USB对象
int get_vid(void); // 获取连接到该USB端口上的设备VID
int get_pid(void); // 获取连接到该USB端口上的设备PID
int get_ver(void);
void on_disconnected(void);
std::string init_error_msg(void);

View File

@ -1,8 +1,8 @@
#include "user.h"
#include "../../../sdk/include/huagao/brand.h"
#include "../../../sdk/include/huagao/hgscanner_error.h"
#include "../../../sdk/include/sane/sane_ex.h"
#include <huagao/brand.h>
#include <huagao/hgscanner_error.h>
#include <sane/sane_ex.h>

View File

@ -3,10 +3,11 @@
#include <string.h>
#if defined(WIN32) || defined(_WIN64)
#if OS_WIN
#else
#include <sys/fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -20,7 +21,7 @@ packet_data_base::~packet_data_base()
int packet_data_base::notify_progress(uint64_t total, uint64_t cur_size, uint32_t err)
{
if (progress_notify_)
progress_notify_(total, cur_size, err, user_data_);
return progress_notify_(total, cur_size, err, user_data_);
else
return ENOENT;
}
@ -30,6 +31,10 @@ void packet_data_base::set_packet_param(uint32_t cmd, uint32_t id)
pack_cmd_ = cmd;
pack_id_ = id;
}
void packet_data_base::set_session_id(uint32_t session_id)
{
session_id_ = session_id;
}
int packet_data_base::get_packet_command(void)
{
return pack_cmd_;
@ -38,6 +43,10 @@ int packet_data_base::get_packet_id(void)
{
return pack_id_;
}
uint32_t packet_data_base::get_session_id(void)
{
return session_id_;
}
void packet_data_base::set_progress_notify(PROGRESS_NOTIFYER notify, void* param)
{
@ -52,6 +61,9 @@ data_holder::data_holder()
data_holder::~data_holder()
{}
void data_holder::cancel(void)
{}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -137,11 +149,16 @@ file_saver::file_saver(void) : size_(0), wrote_(0), path_(""), check_(""), dst_(
{}
file_saver::~file_saver()
{
utils::to_log(LOG_LEVEL_DEBUG, "Write file(%s) over(%ld/%ld).\n", path_.c_str(), wrote_, size_);
close();
}
void file_saver::close(void)
{
if (map_)
map_->release();
map_ = nullptr;
if(dst_)
fclose(dst_);
dst_ = nullptr;
@ -150,17 +167,48 @@ void file_saver::close(void)
path_ = check_ = "";
}
int file_saver::open(const char* path, uint64_t size, const char* check)
int file_saver::set_verify_data(const char* data, size_t len)
{
if (data)
check_ = std::string(data, len);
else
check_ = "";
return 0;
}
int file_saver::open(const char* path, uint64_t size, bool in_mem, size_t off)
{
int err = 0;
close();
dst_ = fopen(path, "wb");
if(dst_)
wrote_ = off;
path_ = path;
size_ = size;
if (in_mem)
{
map_ = new file_map();
err = map_->open(path, size, false);
if (err || !map_->map())
{
map_->release();
map_ = nullptr;
}
else
return err;
}
err = utils::make_file_size(path, wrote_);
dst_ = fopen(path, "ab+");
if (dst_)
{
unsigned long long space = 0;
std::string dir(path);
size_t pos = dir.rfind(PATH_SEPARATOR[0]);
err = utils::get_disk_space(path, nullptr, &space, nullptr);
if (pos != std::string::npos)
dir.erase(pos);
err = utils::get_disk_space(dir.c_str(), nullptr, &space, nullptr);
if (err || space < size * 1.5)
{
fclose(dst_);
@ -169,12 +217,6 @@ int file_saver::open(const char* path, uint64_t size, const char* check)
if (err == 0)
err = ENOSPC;
}
else
{
path_ = path;
size_ = size;
check_ = check ? check : "";
}
}
else
{
@ -186,8 +228,22 @@ int file_saver::open(const char* path, uint64_t size, const char* check)
int file_saver::put_data(const void* data, uint32_t* size/*[in] - total bytes of data; [out] - used bytes*/)
{
if(!dst_)
if (!dst_)
{
if (map_)
{
// fix me: we consider whole file is all mapped in memory
int w = *size > size_ - wrote_ ? size_ - wrote_ : *size;
memcpy(map_->buffer() + wrote_, data, w);
*size = w;
wrote_ += w;
notify_progress(size_, wrote_, 0);
return 0;
}
return ENOENT;
}
int w = *size > size_ - wrote_ ? size_ - wrote_ : *size,
real_w = fwrite(data, 1, w, dst_), // should handle error here !
@ -216,7 +272,14 @@ uint32_t file_saver::get_required(void)
{
return size_ - wrote_;
}
void file_saver::cancel(void)
{
std::string discard(path_);
utils::to_log(LOG_LEVEL_DEBUG, "Discard receiving file (%u/%u): '%s'.\n", wrote_, size_, path_.c_str());
close();
remove(discard.c_str());
}
@ -385,12 +448,41 @@ file_reader::~file_reader()
{
if(src_)
fclose(src_);
if (map_)
map_->release();
utils::to_log(LOG_LEVEL_DEBUG, "Read file(%s) over(%ld/%ld).\n", path_.c_str(), consume_, len_);
}
int file_reader::open(const char* file)
int file_reader::open(const char* file, bool in_mem, size_t off)
{
if(src_)
fclose(src_);
src_ = nullptr;
consume_ = off;
if (in_mem)
{
map_ = new file_map();
if (map_->open(file, 0, true) || !map_->map())
{
map_->release();
map_ = nullptr;
}
else
{
if (map_->total_size() <= off)
{
map_->release();
map_ = nullptr;
return EOVERFLOW;
}
path_ = file;
len_ = map_->total_size();
return 0;
}
}
src_ = fopen(file, "rb");
if(!src_)
@ -398,9 +490,15 @@ int file_reader::open(const char* file)
FSEEK(src_, 0, SEEK_END);
len_ = FTELL(src_);
FSEEK(src_, 0, SEEK_SET);
FSEEK(src_, consume_, SEEK_SET);
path_ = file;
consume_ = 0;
if (len_ <= consume_)
{
fclose(src_);
src_ = nullptr;
return EOVERFLOW;
}
return 0;
}
@ -411,6 +509,11 @@ int file_reader::attach(FILE* f)
fclose(src_);
src_ = nullptr;
}
if (map_)
{
map_->release();
map_ = nullptr;
}
uint64_t cur = FTELL(f);
@ -439,7 +542,7 @@ FILE* file_reader::detach(void)
bool file_reader::is_memory_block(void)
{
return false;
return map_ != nullptr;
}
uint32_t file_reader::get_rest(void)
{
@ -449,14 +552,27 @@ uint32_t file_reader::get_rest(void)
// following API valid when is_memory_block() return true
uint8_t* file_reader::ptr(void)
{
return nullptr;
return map_ ? map_->buffer() : nullptr;
}
// following API valid when is_memory_block() return false
int file_reader::fetch_data(void* buf, uint32_t* size)
{
if (!src_)
{
if (map_)
{
if (*size + consume_ >= len_)
*size = len_ - consume_;
memcpy(buf, map_->buffer() + consume_, *size);
consume_ += *size;
notify_progress(len_, consume_, 0);
return 0;
}
return ENODATA;
}
size_t r = fread(buf, 1, *size, src_); // fix me if ERROR occurs !!!
@ -471,3 +587,200 @@ int file_reader::fetch_data(void* buf, uint32_t* size)
return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
file_map::file_map()
{
utils::get_page_size(&os_map_size_);
}
file_map::~file_map()
{
close();
}
void file_map::unmap(void)
{
if (buf_)
#if OS_WIN
UnmapViewOfFile(buf_);
#else
munmap(buf_, map_size_);
#endif
buf_ = nullptr;
map_off_ = map_size_ = off_ = 0;
}
int file_map::open(const char* file, uint64_t size, bool readonly)
{
close();
std::string oper(readonly ? "open" : "create");
#if OS_WIN
HANDLE h = INVALID_HANDLE_VALUE;
DWORD access = PAGE_READONLY;
if (readonly)
{
h = CreateFileA(file, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
}
else
{
access = PAGE_READWRITE;
h = CreateFileA(file, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
}
if (h == INVALID_HANDLE_VALUE)
{
utils::to_log(LOG_LEVEL_WARNING, "FileMapping: %s '%s' failed: %d\n", oper.c_str(), file, GetLastError());
return EFAULT;
}
if (readonly)
{
DWORD* hi = (DWORD*)&size + 1,
* lo = (DWORD*)&size;
*lo = GetFileSize(h, hi);
}
else
{
LONG lo = size & 0x0ffffffff,
hi = size >> 32;
DWORD ret = SetFilePointer(h, lo, &hi, FILE_BEGIN);
if (ret == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
{
CloseHandle(h);
remove(file);
utils::to_log(LOG_LEVEL_WARNING, "FileMapping: no space(%ld) for '%s'.\n", size, file);
return ENOSPC;
}
else
{
// write a byte to ensure map success
SetFilePointer(h, -1, NULL, FILE_CURRENT);
lo = 0;
WriteFile(h, &lo, 1, &ret, NULL);
}
}
map_ = CreateFileMappingA(h, NULL, access, 0, 0, NULL);
access = GetLastError();
CloseHandle(h);
if (!map_)
{
remove(file);
map_ = INVALID_HANDLE_VALUE;
utils::to_log(LOG_LEVEL_WARNING, "FileMapping: create mapping object for '%s' failed: %d.\n", file, access);
return EFAULT;
}
#else
if (readonly)
map_ = (HANDLE)::open(file, O_RDONLY, 0644);
else
{
int err = utils::make_file_size(file, size);
if(err)
{
utils::to_log(LOG_LEVEL_FATAL, "FileMapping: make file(%s) size(%ld) = %d\n", file, size, err);
return err;
}
map_ = (HANDLE)::open(file, O_RDWR, 0666);
utils::to_log(LOG_LEVEL_DEBUG, "FileMapping: open('%s', O_APPEND, 0666) = %p\n", file, map_);
}
if (map_ == INVALID_HANDLE_VALUE)
{
int err = errno;
if(!readonly)
remove(file);
utils::to_log(LOG_LEVEL_WARNING, "FileMapping: create mapping object for '%s' failed: %d.\n", file, err);
return err;
}
#endif
path_file_ = file;
total_ = size;
read_only_ = readonly;
return 0;
}
int file_map::close(void)
{
unmap();
if (map_ != INVALID_HANDLE_VALUE)
#if OS_WIN
CloseHandle(map_);
#else
::close((int)(long)map_);
#endif
map_ = INVALID_HANDLE_VALUE;
total_ = 0;
return 0;
}
uint64_t file_map::total_size(void)
{
return total_;
}
uint8_t* file_map::map(uint64_t off, uint32_t* size)
{
uint32_t len = 0;
unmap();
if (!size)
size = &len;
if (off < total_)
{
DWORD hi = 0,
lo = 0,
cnt = 0;
map_off_ = off / os_map_size_ * os_map_size_;
off_ = off - map_off_;
hi = map_off_ >> 32;
lo = map_off_;
cnt = total_ - map_off_;
if (cnt - off > *size && *size)
{
cnt = ALIGN_TO(*size + off, os_map_size_);
if(cnt > total_ - map_off_)
cnt = total_ - map_off_;
}
map_size_ = cnt;
#if OS_WIN
buf_ = (uint8_t*)MapViewOfFile(map_, read_only_ ? FILE_MAP_READ : FILE_MAP_READ | FILE_MAP_WRITE, hi, lo, map_size_);
#else
int priv = PROT_READ, prot = MAP_PRIVATE;
if (!read_only_)
{
priv |= PROT_WRITE;
prot = MAP_SHARED;
}
buf_ = (uint8_t*)mmap(nullptr, map_size_, priv, prot, (int)(long)map_, map_off_);
if(buf_ == INVALID_HANDLE_VALUE)
buf_ = nullptr;
#endif
if (!buf_)
{
utils::to_log(LOG_LEVEL_WARNING, "FileMapping: request map(%p + %u), real map(%p + %u) failed: %d\n"
, off, *size, map_off_, map_size_, GetLastError());
*size = 0;
}
else
*size = cnt - off;
}
return buf_ ? buf_ + off_ : nullptr;
}
uint8_t* file_map::buffer(void)
{
return buf_ ? buf_ + off_ : nullptr;
}

View File

@ -27,6 +27,7 @@ class packet_data_base : public refer
protected:
uint32_t pack_cmd_;
uint32_t pack_id_;
uint32_t session_id_ = -1;
public:
packet_data_base();
@ -37,12 +38,44 @@ protected:
public:
void set_packet_param(uint32_t cmd, uint32_t id);
void set_session_id(uint32_t session_id);
int get_packet_command(void);
int get_packet_id(void);
uint32_t get_session_id(void);
void set_progress_notify(PROGRESS_NOTIFYER notify = PROGRESS_NOTIFYER(), void* param = nullptr);
};
class file_map : public refer
{
bool read_only_ = false; //
uint32_t os_map_size_ = 0; // desired mapping size of OS
uint64_t total_ = 0; // total size of the whole file
HANDLE map_ = INVALID_HANDLE_VALUE; // handle of the map-object
std::string path_file_; // local file
uint64_t map_off_ = 0; // offset in the file of current mapping buffer
uint32_t map_size_ = 0; // size of current mapping buffer
uint32_t off_ = 0; // offset to align to os_map_size_
uint8_t* buf_ = nullptr; // current mapping buffer
void unmap(void);
public:
file_map();
protected:
~file_map();
public:
int open(const char* file, uint64_t size, bool readonly);
int close(void);
uint64_t total_size(void);
uint8_t* map(uint64_t off = 0, uint32_t* size = 0); // size - in: desired size, 0 is from off to end; out: real size
uint8_t* buffer(void);
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
/* data_holder, used when data is also required for a certain packet
@ -58,6 +91,7 @@ public:
virtual int put_data(const void* data, uint32_t* size/*[in] - total bytes of data; [out] - used bytes*/) = 0; // return error code
virtual bool is_complete(void) = 0;
virtual uint32_t get_required(void) = 0;
virtual void cancel(void);
};
class mem_holder : public data_holder
@ -107,6 +141,7 @@ class file_saver : public data_holder
std::string path_;
std::string check_;
FILE *dst_;
file_map *map_ = nullptr;
uint32_t pack_cmd_;
uint32_t pack_id_;
@ -118,12 +153,14 @@ protected:
~file_saver();
public:
int open(const char* path, uint64_t size, const char* check = nullptr);
int set_verify_data(const char* data, size_t len);
int open(const char* path, uint64_t size, bool in_mem = false, size_t off = 0);
public:
virtual int put_data(const void* data, uint32_t* size/*[in] - total bytes of data; [out] - used bytes*/) override;
virtual bool is_complete(void) override;
virtual uint32_t get_required(void) override;
virtual void cancel(void) override;
};
@ -200,7 +237,8 @@ class file_reader : public data_source
{
size_t len_;
size_t consume_;
FILE *src_;
FILE *src_ = nullptr;
file_map *map_ = nullptr;
std::string path_;
public:
@ -210,7 +248,7 @@ protected:
~file_reader();
public:
int open(const char* file);
int open(const char* file, bool in_mem, size_t off = 0);
int attach(FILE* f);
FILE* detach(void);
@ -225,6 +263,7 @@ public:
virtual int fetch_data(void* buf, uint32_t* size) override;
};
CLS_PTR(packet_data_base);
CLS_PTR(data_holder);
CLS_PTR(mem_holder);

View File

@ -50,13 +50,13 @@ enum ep0_req
USB_REQ_EP0_SET_ENCRYPT, // 设置加密方式, req = me, ind = 0, val = 0, len = sizeof(PACK_BASE)
USB_REQ_EP0_SET_BULK_BUFFER, // 设置bulk缓冲区大小系数 req = me, ind = coef, val = 0, len = 0
};
enum bulk_status
enum woker_status
{
BULK_STATUS_NOT_START = 0, // has not initialized
BULK_STATUS_IDLE, // wait IO
BULK_STATUS_IO, // in reading or writing
BULK_STATUS_ERROR, // error occurs
BULK_STATUS_RESET, // in reset(close and reopen) process
WORKER_STATUS_NOT_START = 0, // has not start
WORKER_STATUS_IDLE, // idle
WORKER_STATUS_BUSY, // in working
WORKER_STATUS_ERROR, // error occurs
WORKER_STATUS_RESET, // in reset(close and reopen) process
};
enum packet_cmd

127
sdk/base/plat_types.h Normal file
View File

@ -0,0 +1,127 @@
#pragma once
#if defined(WIN32) || defined(_WIN64)
#define OS_WIN 1
#else
#define OS_WIN 0
#endif
#define SIZE_KB(n) ((n) * 1024)
#define SIZE_MB(n) SIZE_KB(n * 1024)
#define SIZE_GB(n) SIZE_MB(n * 1024)
#define SEC_2_MS(s) ((s) * 1000)
#define MSEC_2_US(ms) ((ms) * 1000)
#define SEC_2_US(s) MSEC_2_US(SEC_2_MS(s))
#define ALIGN_TO(v, align) (((v) + (align) - 1) / (align) * (align))
#define ALIGN_INT(v) ALIGN_TO(v, sizeof(int))
#define RETURN_ENUM_STR(v, e) \
if(v == e) \
return #e;
#if !OS_WIN // migrate codes from windows to linux ...
#include <unistd.h>
#include <stdint.h>
#include <sys/types.h>
#include <dlfcn.h>
#include <semaphore.h>
#pragma pack(push)
#pragma pack(1)
typedef struct BITMAPFILEHEADER
{
u_int16_t bfType;
u_int32_t bfSize;
u_int16_t bfReserved1;
u_int16_t bfReserved2;
u_int32_t bfOffBits;
}BITMAPFILEHEADER;
typedef struct BITMAPINFOHEADER
{
u_int32_t biSize;
u_int32_t biWidth;
u_int32_t biHeight;
u_int16_t biPlanes;
u_int16_t biBitCount;
u_int32_t biCompression;
u_int32_t biSizeImage;
u_int32_t biXPelsPerMeter;
u_int32_t biYPelsPerMeter;
u_int32_t biClrUsed;
u_int32_t biClrImportant;
}BITMAPINFODEADER;
#pragma pack(pop)
#define BI_RGB 0
#define MAKEWORD(a, b) (((a) & 0x0ff) | (((b) & 0x0ff) << 8))
#define MAKELONG(a, b) (((a) & 0x0ffff) | (((b) & 0x0ffff) << 16))
#define _countof(a) (sizeof(a) / sizeof((a)[0]))
typedef long LONG;
typedef void* HANDLE;
typedef void* HWND;
typedef void* HMODULE;
typedef void* LPVOID;
typedef void* FARPROC;
typedef unsigned int DWORD;
typedef unsigned short WORD;
typedef unsigned short UINT16;
typedef unsigned char BYTE;
typedef int BOOL;
#define TRUE 1
#define FALSE 0
#define MAX_PATH 256
#define huge
#define FAR
#define NEAR
#define LOWORD(v) ((v) & 0x0ffff)
#define HIWORD(v) (((v) >> 16) & 0x0ffff)
#define PASCAL __attribute__((stdcall))
#define _countof(a) (sizeof(a) / sizeof(a[0]))
#define LOAD_WITH_ALTERED_SEARCH_PATH RTLD_NOW
#define FreeLibrary dlclose
#define GetProcAddress dlsym
#define GetPrivateProfileIntW GetPrivateProfileIntA
#define lstrlenA strlen
#define lstrlenW strlen
#define DLL_EXTESION "so"
#define PATH_SEPARATOR "/"
#define STRICMP strcasecmp
#define MKDIR(a, b) mkdir(a, b)
#define STDCALL
#define ERROR_CANCELLED 1223
#define USB_TIMEOUT_INFINITE 0
#define FSEEK fseek
#define FTELL ftell
#define INVALID_HANDLE_VALUE ((HANDLE)(-1))
extern DWORD GetLastError(void);
extern DWORD GetPrivateProfileIntA(const char* app, const char* key, DWORD def, const char* file);
extern DWORD GetPrivateProfileStringA(const char* app, const char* key, const char* init, char* buf, size_t len, const char* file);
extern void Sleep(DWORD milliseconds);
extern int GetModuleFileNameA(HMODULE module, char* buf, size_t len); // NOTE: parameter 'module' is consinder as a part of the module file name
extern uint64_t GetCurrentProcessId(void);
extern uint64_t GetCurrentThreadId(void);
#else
#include <Windows.h>
#define bzero(a, l) memset(a, 0, l)
#define DLL_EXTESION "dll"
#define PATH_SEPARATOR "\\"
#define STRICMP stricmp
#define MKDIR(a, b) mkdir(a)
#define STDCALL __stdcall
#define sem_t HANDLE
#define USB_TIMEOUT_INFINITE -1
#define FSEEK _fseeki64
#define FTELL _ftelli64
#define pid_t int
#endif

View File

@ -1,6 +1,5 @@
#include "utils.h"
#include "huagao/brand.h"
#include "ini_file.h"
@ -71,6 +70,8 @@ int gettimeofday(TIMEV* tv, struct timezone* tz)
#include <sys/shm.h>
#include <sys/mman.h>
#define PRODUCT_VENDOR "HuaGo"
static std::mutex ini_lock_;
static std::map<std::string, simple_ini*> ini_files_;
static std::string debug_cfg_file_ = "";
@ -195,13 +196,13 @@ int GetModuleFileNameA(HMODULE module, char* buf, size_t len)
return len;
}
int GetCurrentThreadId(void)
uint64_t GetCurrentThreadId(void)
{
return pthread_self();
return (uint64_t)pthread_self();
}
int GetCurrentProcessId(void)
uint64_t GetCurrentProcessId(void)
{
return getpid();
return (uint64_t)getpid();
}
#endif
@ -235,7 +236,7 @@ class log_cls
}
else
{
std::string sep("\n\n===================================================================================================================\n");
std::string sep("\n\n========================================================================================================================\n");
fwrite(sep.c_str(), sizeof(sep[0]), sep.length(), file_);
}
@ -548,7 +549,7 @@ namespace utils
}
#endif
std::string get_command_result(const char* cmd, int len)
std::string get_command_result(const char* cmd, int len, int *err)
{
std::string result("");
@ -556,6 +557,8 @@ namespace utils
#else
FILE* src = popen(cmd, "r");
if(err)
*err = 0;
if (src)
{
char buf[128] = { 0 };
@ -572,8 +575,18 @@ namespace utils
}
rv = fread(buf, 1, sizeof(buf) - 1, src);
}
if(rv == -1 && err)
{
*err = errno;
utils::to_log(LOG_LEVEL_DEBUG, "Failed to excute shell command '%s' in read pipe: %d - %s\n", cmd, errno, strerror(errno));
}
pclose(src);
}
else if(err)
{
*err = errno;
utils::to_log(LOG_LEVEL_DEBUG, "Failed to excute shell command '%s' in open pipe: %d - %s\n", cmd, errno, strerror(errno));
}
#endif
return std::move(result);
@ -973,6 +986,36 @@ namespace utils
{
return rename(from, to);
}
int make_file_size(const char* file, uint64_t size)
{
int err = 0;
get_command_result(("fallocate -l " + std::to_string(size) + " " + file).c_str(), -1, &err);
if(err == 0)
{
get_command_result(("truncate -s " + std::to_string(size) + " " + file).c_str(), -1, &err);
if(err == 0)
{
FILE* dst = fopen(file, "rb");
if(dst)
{
uint64_t rs = 0;
FSEEK(dst, 0, SEEK_END);
rs = FTELL(dst);
fclose(dst);
if(rs != size)
err = ENOSPC;
}
else
err = errno;
}
}
if(err)
remove(file);
return err;
}
int get_disk_space(const char* path, unsigned long long* total, unsigned long long* avail, unsigned long long* block)
{
@ -1044,7 +1087,7 @@ namespace utils
return ps;
}
void init_log(log_type type, log_level level, const char* fn_appendix)
std::string init_log(log_type type, log_level level, const char* fn_appendix)
{
std::string file("");
@ -1062,10 +1105,13 @@ namespace utils
if (fn_appendix)
file += fn_appendix;
file += ".log";
printf("log file: %s\n", file.c_str());
}
log_cls::instance()->set_log_type(type, &file[0]);
log_cls::instance()->set_log_level(level);
return std::move(file);
}
void uninit(void)
{
@ -1846,40 +1892,92 @@ int shared_memory::write(const char* data, size_t len)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// safe_thread
safe_thread::safe_thread() : name_("")
{}
safe_thread::safe_thread() : excep_que_("thread-exception")
{
notify_thread_.reset(new std::thread(&safe_thread::thread_notify_exception, this));
}
safe_thread::~safe_thread()
{
if (thread_.get() && thread_->joinable())
thread_->join();
run_ = false;
excep_que_.trigger();
if(notify_thread_->joinable())
notify_thread_->join();
for(auto& v: threads_)
{
if(v.thread.get() && v.thread->joinable())
v.thread->join();
}
threads_.clear();
}
void safe_thread::thread_worker(std::function<void(void*)> func, void* param, std::function<void(void)> on_exception)
void safe_thread::thread_worker(std::function<void(void)> func, std::string name, void* addr)
{
try
{
func(param);
utils::to_log(LOG_LEVEL_DEBUG, "+++ safe_thread of '%s(%p) - %p' is running ...\n", name.c_str(), addr, GetCurrentThreadId());
func();
utils::to_log(LOG_LEVEL_DEBUG, "--- safe_thread of '%s - %p' exited.\n", name.c_str(), GetCurrentThreadId());
return;
}
catch (std::exception e)
{
utils::to_log(LOG_LEVEL_FATAL, "Exception in thread '%s': %s\n", name_.c_str(), e.what());
utils::to_log(LOG_LEVEL_FATAL, "Exception in thread '%p - %s': %s\n", GetCurrentThreadId(), name.c_str(), e.what());
}
catch (...)
{
utils::to_log(LOG_LEVEL_FATAL, "Unknown exception in thread '%s'!\n", name_.c_str());
utils::to_log(LOG_LEVEL_FATAL, "Unknown exception in thread '%p - %s'!\n", GetCurrentThreadId(), name.c_str());
}
excep_que_.save(name, true);
}
void safe_thread::thread_notify_exception(void)
{
while(run_)
{
std::string name("");
if(excep_que_.take(name, true))
{
if(excep_handler_)
excep_handler_(name.c_str());
}
}
if (on_exception)
on_exception();
}
int safe_thread::start(std::function<void(void*)> f, void* param, const char* thread_name, std::function<void(void)> on_exception)
void safe_thread::set_exception_handler(std::function<void(const char*)> on_exception)
{
if (thread_.get() && thread_->joinable())
thread_->join();
excep_handler_ = on_exception;
}
int safe_thread::start(std::function<void(void)> f, const char* thread_name, void* addr)
{
SAFETHRD st;
name_ = thread_name ? thread_name : "";
thread_.reset(new std::thread(&safe_thread::thread_worker, this, f, param, on_exception));
st.name = thread_name ? thread_name : "";
st.thread.reset(new std::thread(&safe_thread::thread_worker, this, f, thread_name, addr));
{
SIMPLE_LOCK(lock_);
threads_.push_back(st);
}
return 0;
}
int safe_thread::stop(const char* thread_name)
{
int ret = ENOENT;
SIMPLE_LOCK(lock_);
for(int i = 0; i < threads_.size(); ++i)
{
if(threads_[i].name == thread_name)
{
if(threads_[i].thread.get() && threads_[i].thread->joinable())
threads_[i].thread->join();
threads_.erase(threads_.begin() + i);
ret = 0;
break;
}
}
return ret;
}

View File

@ -5,7 +5,7 @@
#pragma once
#include <sane/sane_ex.h>
#include "plat_types.h"
#include <string>
#include <memory>
#include <mutex>
@ -37,7 +37,7 @@ namespace utils
std::string utf82ansi(const char* utf8);
std::string ansi2utf8(const char* ansi);
std::string get_command_result(const char* cmd, int len = -1);
std::string get_command_result(const char* cmd, int len = -1, int *err = nullptr);
std::string get_local_data_path(void);
std::string temporary_path(void);
std::string format_current_time(void);
@ -57,11 +57,13 @@ namespace utils
void set_ini_value(const char* seg, const char* key, const char* val, const char* cfg_file);
int enum_file(const char* folder, bool recursive, bool/*return false to stop enumeration*/(STDCALL* found)(const char* path_name, bool dir, void* param), void* param);
int move_file(const char* from, const char* to);
int make_file_size(const char* file, uint64_t size); // truncate or extend file size to 'size', create if not exist
int get_disk_space(const char* path, unsigned long long* total, unsigned long long* avail, unsigned long long* block);
unsigned int get_page_size(unsigned int* map_unit = nullptr);
void init_log(log_type type, log_level level = LOG_LEVEL_ALL, const char* fn_appendix = nullptr/*appendix to default log-file-name*/);
// return logging file path if 'type' was LOG_TYPE_FILE
std::string init_log(log_type type, log_level level = LOG_LEVEL_ALL, const char* fn_appendix = nullptr/*appendix to default log-file-name*/);
void uninit(void);
void log_info(const char* info, int level = LOG_LEVEL_ALL);
void log_mem_info(const char* desc, const void* data, size_t bytes, int level = LOG_LEVEL_ALL); // log as 0x12345678 00 01 02 ...
@ -342,15 +344,27 @@ public:
class safe_thread
{
std::unique_ptr<std::thread> thread_;
std::string name_;
typedef struct _safe_thrd
{
std::string name;
std::shared_ptr<std::thread> thread;
}SAFETHRD;
volatile bool run_ = true;
MUTEX lock_;
std::unique_ptr<std::thread> notify_thread_;
std::vector<SAFETHRD> threads_;
safe_fifo<std::string> excep_que_;
std::function<void(const char*)> excep_handler_ = std::function<void(const char*)>();
void thread_worker(std::function<void(void*)> func, void* param, std::function<void(void)> on_exception);
void thread_worker(std::function<void(void)> func, std::string name, void* addr);
void thread_notify_exception(void);
public:
safe_thread(void);
~safe_thread();
public:
int start(std::function<void(void*)> f, void* param, const char* thread_name, std::function<void(void)> on_exception = std::function<void(void)>());
void set_exception_handler(std::function<void(const char*)> on_exception = std::function<void(const char*)>());
int start(std::function<void(void)> f, const char* thread_name, void* addr = nullptr);
int stop(const char* thread_name);
};

View File

@ -1,7 +1,7 @@
#include "base_opt.h"
#include <json/gb_json.h>
#include "../../../sdk/include/huagao/hgscanner_error.h"
#include <huagao/hgscanner_error.h>
sane_opt_provider::sane_opt_provider()

View File

@ -8,7 +8,6 @@
#include <string>
#include <map>
#include <base/utils.h> // for refer
#include <sane/sane_ex.h>
class sane_opt_provider : public refer
{

View File

@ -1,13 +1,19 @@
#include "device_opt.h"
#include <huagao/hgscanner_error.h>
#include <base/huagaoxxx_warraper_ex.h>
#include "base_opt.h"
#include <lang/app_language.h>
#include <string.h>
#include <algorithm>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
static const char* empty_from_default_language(const char* deflang)
{
return deflang;
}
static const char*(*from_def_lang)(const char*) = empty_from_default_language;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// image-processing jsons ...
@ -380,7 +386,7 @@ bool device_option::is_equal_f(gb_json* opt, void* val, void* v1, void* v2)
}
bool device_option::is_equal_s(gb_json* opt, void* val, void* v1, void* v2)
{
return strcmp((char*)val, from_default_language((char*)v1)) == 0;
return strcmp((char*)val, from_def_lang((char*)v1)) == 0;
}
bool device_option::is_less_b(gb_json* opt, void* val, void* v1, void* v2)
@ -397,7 +403,7 @@ bool device_option::is_less_f(gb_json* opt, void* val, void* v1, void* v2)
}
bool device_option::is_less_s(gb_json* opt, void* val, void* v1, void* v2)
{
return strcmp((char*)val, from_default_language((char*)v1)) < 0;
return strcmp((char*)val, from_def_lang((char*)v1)) < 0;
}
bool device_option::is_great_b(gb_json* opt, void* val, void* v1, void* v2)
@ -414,7 +420,7 @@ bool device_option::is_great_f(gb_json* opt, void* val, void* v1, void* v2)
}
bool device_option::is_great_s(gb_json* opt, void* val, void* v1, void* v2)
{
return strcmp((char*)val, from_default_language((char*)v1)) > 0;
return strcmp((char*)val, from_def_lang((char*)v1)) > 0;
}
bool device_option::is_between_b(gb_json* opt, void* val, void* v1, void* v2)
@ -431,8 +437,8 @@ bool device_option::is_between_f(gb_json* opt, void* val, void* v1, void* v2)
}
bool device_option::is_between_s(gb_json* opt, void* val, void* v1, void* v2)
{
return strcmp((char*)val, from_default_language((char*)v1)) >= 0 &&
strcmp((char*)val, from_default_language((char*)v2)) <= 0;
return strcmp((char*)val, from_def_lang((char*)v1)) >= 0 &&
strcmp((char*)val, from_def_lang((char*)v2)) <= 0;
}
bool device_option::is_opt_enabled(gb_json* opt, void* val, void* v1, void* v2)
@ -1152,13 +1158,42 @@ void device_option::insert_option(gb_json* opt, sane_opt_provider* from, const c
}
else
{
int index = -1;
int index = -1, pos = -1;
if (group)
index = insert_group(group, group);
index = next_group(index + 1);
// insert poisition according to 'ui-pos'
if (!opt->get_value("ui-pos", pos) || pos == -1)
{
index = next_group(index + 1);
}
else
{
for (index++; index < origin_->children(); ++index)
{
gb_json* sib = origin_->child(index);
std::string t("");
int sit = -1;
if (!sib->get_value("type", t) || t == JSON_SANE_TYPE_GROUP)
{
sib->release();
break;
}
if (!sib->get_value("ui-pos", sit) || sit == -1)
{
sib->release();
break;
}
sib->release();
if (pos < sit)
break;
}
}
origin_->insert(index, opt->key().c_str(), opt);
src_[opt->key()] = from;
from->add_ref();
}
@ -1298,13 +1333,30 @@ gb_json* device_option::copy_opt(gb_json* from)
// 1: language changed ... (title, description, string-list)
if (to->get_value("title", val))
to->set_value("title", from_default_language(val.c_str()));
to->set_value("title", from_def_lang(val.c_str()));
if (to->get_value("desc", val))
to->set_value("desc", from_default_language(val.c_str()));
to->set_value("desc", from_def_lang(val.c_str()));
// 2: enabled ...
if (slaver_.count(to->key()))
to->set_value("enabled", slaver_[to->key()]->value(&device_option::calc_simple_logic_expression, this));
{
bool enable = slaver_[to->key()]->value(&device_option::calc_simple_logic_expression, this);
to->set_value("enabled", enable);
if (src_.count(to->key()))
{
src_[to->key()]->enable(to->key().c_str(), enable);
sane_opt_provider* next = src_[to->key()]->get_following(to->key().c_str());
while (next)
{
next->enable(to->key().c_str(), enable);
sane_opt_provider* next1 = next->get_following(to->key().c_str());
next->release();
next = next1;
}
}
}
// 3: default value ...
if (init_value_.count(to->key()))
@ -1409,18 +1461,18 @@ gb_json* device_option::copy_opt(gb_json* from)
for(int i = 0; i < range_value_[to->key()]->count(); ++i)
{
if(!val.empty())
*dst += from_default_language(val.c_str());
*dst += from_def_lang(val.c_str());
val = range_value_[to->key()]->next_value(&device_option::calc_simple_logic_expression, this);
}
}
else
{
val = range_value_[to->key()]->first_value(&device_option::calc_simple_logic_expression, this);
dst->set_value("min", from_default_language(val.c_str()));
dst->set_value("min", from_def_lang(val.c_str()));
val = range_value_[to->key()]->next_value(&device_option::calc_simple_logic_expression, this);
dst->set_value("max", from_default_language(val.c_str()));
dst->set_value("max", from_def_lang(val.c_str()));
val = range_value_[to->key()]->next_value(&device_option::calc_simple_logic_expression, this);
dst->set_value("step", from_default_language(val.c_str()));
dst->set_value("step", from_def_lang(val.c_str()));
}
}
}
@ -1621,6 +1673,10 @@ std::string device_option::get_group(int ind, bool title)
else
return "";
}
void device_option::set_from_default_language_api(const char*(*fdl)(const char*))
{
from_def_lang = fdl ? fdl : empty_from_default_language;
}
void device_option::clear(void)
{

View File

@ -351,6 +351,7 @@ public:
static std::string trans_group(const char* utf8, bool to_title);
static std::string get_group(int ind, bool title);
static void set_from_default_language_api(const char*(*fdl)(const char*));
public:
void clear(void);