tx-gxx-linux/pc/code_twain/sln/usb_tools/scanner/scanner_handler.h

135 lines
3.8 KiB
C++

// scanner business handler
//
// created on 2023-03-27
//
#pragma once
#include "referer.h"
#include "data.h"
#include "packet.h"
#include "ipc_util.h"
#include <functional>
#include <vector>
#include <algorithm>
#include <map>
class async_usb_host;
struct libusb_device;
class cmd_result : public refer
{
std::function<int(cmd_result*)> call_;
std::function<int(cmd_result*)> clean_;
std::function<dyn_mem_ptr(dyn_mem_ptr, uint32_t*, packet_data_base_ptr*, cmd_result*)> roger_;
MUTEX locker_;
uint32_t id_;
linux_event *wait_;
void* param_;
int err_;
uint32_t to_;
bool over_;
static MUTEX lock_;
static uint32_t pack_id_;
static uint32_t gen_pack_id(void);
public:
cmd_result(std::function<int(cmd_result*)> call,
std::function<int(cmd_result*)> clean,
std::function<dyn_mem_ptr(dyn_mem_ptr, uint32_t*, packet_data_base_ptr*, cmd_result*)> roger,
void* param, uint32_t id = 0);
protected:
~cmd_result();
public:
uint32_t get_id(void);
uint32_t set_timeout(uint32_t timeout = 1000/*WAIT_INFINITE*/); // return previous
void* get_param(void);
void* set_param(void* param); // return previous
bool wait(void);
void trigger(void);
bool is_over(void);
int get_error_code(void);
void set_error_code(int err);
public:
int call(void);
dyn_mem_ptr roger(dyn_mem_ptr data, uint32_t* used, packet_data_base_ptr* more);
int clean(void);
};
class scanner_handler : public refer
{
MUTEX lock_reply_;
std::vector<cmd_result*> reply_;
async_usb_host* usb_;
volatile uint32_t status_;
std::function<void(uint32_t)> status_notify_;
std::function<data_holder_ptr(LPPACKIMAGE, uint64_t)> img_receiver_;
cmd_result* gen_reply(std::function<int(cmd_result*)> call,
std::function<int(cmd_result*)> clean,
std::function<dyn_mem_ptr(dyn_mem_ptr, uint32_t*, packet_data_base_ptr*, cmd_result*)> roger,
void* param, uint32_t id = 0);
cmd_result* take_reply(uint32_t id);
int wait_result(cmd_result* reply);
typedef struct _set_opt_result
{
uint32_t err;
uint8_t after_do;
char val[0];
}SORET, *LPSORET;
public:
scanner_handler(void);
// the json text from device only contains option items, the "group" info is contains in every item.
// this function convert them into normal SANE-OPTION JSON
// the parameter 'groups' is given the sequence of group
static bool reorder_device_config_json(std::string& cont, const std::map<std::string/*name*/, std::string/*title*/>* groups = nullptr);
protected:
~scanner_handler();
// I/O ...
public:
// following methods transferred by EP0
int get_protocol_version(uint8_t* h, uint8_t* l);
int get_scanner_status(LPEP0REPLYSTATUS status);
int restart_peer_bulk(uint32_t timeout = 1000/*ms*/);
// following methods transferred by Bulk, blocked ...
int option_get_all(std::string& json_opts);
int option_value_get(const char* name, void* buf, uint32_t size/*buffer size of 'buf'*/);
int option_value_set(const char* name, uint32_t type, void* buf, uint32_t size/*buffer size of 'buf'*/, uint8_t* after);
int status_get(void);
void set_image_receiver(std::function<data_holder_ptr(LPPACKIMAGE/*NULL when scanning stopped*/, uint64_t/*size in image, error in stopped*/)> img);
void set_status_notifyer(std::function<void(uint32_t)> stntf);
int scan_start(void);
int scan_stop(void);
int file_transfer(const char* local_path, const char* remote_path, bool to_device
, PROGRESS_NOTIFYER progress = PROGRESS_NOTIFYER()
, uint64_t local_off = 0, uint64_t remote_off = 0);
int file_move(const char* rfrom, const char* rto);
int file_delete(const char* remote);
int program_start(const char* remote_pe, const char* param = nullptr, uint64_t* pid = nullptr);
int program_stop(uint64_t pid);
// methods ...
public:
int open_usb_scanner(libusb_device* dev);
int close(void);
int reset_message_que(void);
bool is_scanner_available(void);
};