add file_map; add palt_types.h; fix device_opt
This commit is contained in:
parent
9d9c38aaec
commit
955584c894
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue