diff --git a/common/event_monitor.h b/common/event_monitor.h index 1211aa9..4584f18 100644 --- a/common/event_monitor.h +++ b/common/event_monitor.h @@ -6,6 +6,8 @@ // #include "referer.h" +#include "packet.h" + #include #include @@ -40,17 +42,15 @@ enum scanner_event SCANNER_EVENT_IMAGE_PROC_ERR, // 4 - resource - SCANNER_EVENT_RESOURCE_LOW_MEM = 300, - SCANNER_EVENT_RESOURCE_LOW_DISK, - SCANNER_EVENT_RESOURCE_HIGH_CPU, + SCANNER_EVENT_RESOURCE_LOW_MEM = 300, // on_event(, (bool*)low_mem, (bool)local_display) + SCANNER_EVENT_RESOURCE_LOW_DISK, // on_event(, (bool*)low_disk, (bool)local_display) + SCANNER_EVENT_RESOURCE_HIGH_CPU, // on_event(, (bool*)high_cpu, (bool)local_display) }; typedef struct _img_data { - uint32_t new_img : 1; // 0 - partial data; 1 - new image data - uint32_t img_over : 1; // 0 - has data yet; 1 - END for the image - uint32_t reserve : 30; - uint8_t* buf; + LPPACKIMAGE info; + uint8_t* data; }IMGD, *LPIMGD; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/common/packet.h b/common/packet.h index febd6d0..c024519 100644 --- a/common/packet.h +++ b/common/packet.h @@ -5,11 +5,16 @@ // created on 2022-12-06 // #include +#include /////////////////////////////////////////////////////////////////////////////// // definitions ... #define CONFIG_NAME_MAX_LEN 32 // max bytes of configuration name - +#define STRUCT_CONSTRUCTOR(st_name) \ + st_name() \ + { \ + memset(this, 0, sizeof(st_name));\ + } // NOTE: All text transmitted by pack cmd is in UTF-8 format !!! @@ -17,22 +22,22 @@ enum packet_cmd { PACK_CMD_HEART_BEAT = 0, // notify peers you are still alive, receiver should reply the same pack - // attributes get/set, all content in PACK_BASE::data should be in JSON style - PACK_CMD_ATTR_SYS_VER_GET = 10, // get system version on device, [in]: PACK_BASE, [out] PACK_BASE::data - {"os":"linux", "ver":"4.4.194", ...} - PACK_CMD_ATTR_FIRMWARE_VER_GET, // get firmware version, [in]: PACK_BASE, [out] PACK_BASE::data - {"firmware":"G2393A1234", "CIS":"CIS-123", ...} - PACK_CMD_ATTR_SERIAL_NUM_GET, // get device serial num, [in]: PACK_BASE, [out] PACK_BASE::data - {"serial":"20221206001"} - PACK_CMD_ATTR_SERIAL_NUM_SET, // set device serial num, [in]: PACK_BASE::data - {"serial":"20221206001"}, [out] PACK_BASE - PACK_CMD_ATTR_MAC_GET, // get mac address, [in]: PACK_BASE, [out] PACK_BASE::data - {"mac":"12:34:56:78:9a:bc"} - PACK_CMD_ATTR_IP_GET, // get ip address, [in]: PACK_BASE, [out] PACK_BASE::data - {"ipv4":"192.168.1.123", "ipv6":"::1"} - PACK_CMD_ATTR_HARDWARE_INFO_GET, // get hardwares information on device, [in]: PACK_BASE, [out] PACK_BASE::data - {"CPU":"ARM x86", "mem":"16GB", ...} - PACK_CMD_ATTR_HISTORY_COUNT_GET, // get history count, [in]: PACK_BASE, [out] PACK_BASE::data - {"history-count":12345, ...} - PACK_CMD_ATTR_ROLLER_COUNT_GET, // get roller count, [in]: PACK_BASE, [out] PACK_BASE::data - {"roller-count":2345} - PACK_CMD_ATTR_ROLLER_COUNT_SET, // set roller count, [in]: PACK_BASE::data - {"roller-count":2345}, [out] PACK_BASE + // attributes get/set, all content in PACK_BASE::payload should be in JSON style + PACK_CMD_ATTR_SYS_VER_GET = 10, // get system version on device, [in]: PACK_BASE, [out] PACK_BASE::payload - {"os":"linux", "ver":"4.4.194", ...} + PACK_CMD_ATTR_FIRMWARE_VER_GET, // get firmware version, [in]: PACK_BASE, [out] PACK_BASE::payload - {"firmware":"G2393A1234", "CIS":"CIS-123", ...} + PACK_CMD_ATTR_SERIAL_NUM_GET, // get device serial num, [in]: PACK_BASE, [out] PACK_BASE::payload - {"serial":"20221206001"} + PACK_CMD_ATTR_SERIAL_NUM_SET, // set device serial num, [in]: PACK_BASE::payload - {"serial":"20221206001"}, [out] PACK_BASE + PACK_CMD_ATTR_MAC_GET, // get mac address, [in]: PACK_BASE, [out] PACK_BASE::payload - {"mac":"12:34:56:78:9a:bc"} + PACK_CMD_ATTR_IP_GET, // get ip address, [in]: PACK_BASE, [out] PACK_BASE::payload - {"ipv4":"192.168.1.123", "ipv6":"::1"} + PACK_CMD_ATTR_HARDWARE_INFO_GET, // get hardwares information on device, [in]: PACK_BASE, [out] PACK_BASE::payload - {"CPU":"ARM x86", "mem":"16GB", ...} + PACK_CMD_ATTR_HISTORY_COUNT_GET, // get history count, [in]: PACK_BASE, [out] PACK_BASE::payload - {"history-count":12345, ...} + PACK_CMD_ATTR_ROLLER_COUNT_GET, // get roller count, [in]: PACK_BASE, [out] PACK_BASE::payload - {"roller-count":2345} + PACK_CMD_ATTR_ROLLER_COUNT_SET, // set roller count, [in]: PACK_BASE::payload - {"roller-count":2345}, [out] PACK_BASE // configuration get/set - PACK_CMD_SETTING_GET = 50, // get all settings supported by the device, [in]: PACK_BASE, [out]: PACK_BASE::data - configuration JSON, see SANE-configuration format - PACK_CMD_SETTING_GET_CUR, // get current value of given setting, [in]: PACK_BASE::data - LPCFGVAL, [out]: PACK_BASE::data - LPCFGVAL - PACK_CMD_SETTING_SET, // set value of given setting, [in]: PACK_BASE::data - LPCFGVAL, [out]: PACK_BASE on OK or PACK_BASE::data - LPCFGVAL + PACK_CMD_SETTING_GET = 50, // get all settings supported by the device, [in]: PACK_BASE, [out]: PACK_BASE::payload - configuration JSON, see SANE-configuration format + PACK_CMD_SETTING_GET_CUR, // get current value of given setting, [in]: PACK_BASE::payload - LPCFGVAL, [out]: PACK_BASE::payload - LPCFGVAL + PACK_CMD_SETTING_SET, // set value of given setting, [in]: PACK_BASE::payload - LPCFGVAL, [out]: PACK_BASE on OK or PACK_BASE::payload - LPCFGVAL PACK_CMD_SETTING_RESTORE, // restore given settings, [in]: PACK_BASE, [out]: PACK_BASE // status management @@ -42,25 +47,26 @@ enum packet_cmd // scan command PACK_CMD_SCAN_START = 100, // start scanning, [in]: PACK_BASE, [out]: PACK_BASE PACK_CMD_SCAN_STOP, // stop scanning, [in]: PACK_BASE, [out]: PACK_BASE - PACK_CMD_SCAN_IMG_SIZE_GET, // get size of the first image, [in]: PACK_BASE, [out]: PACK_BASE::data - (unsigned long long*) - PACK_CMD_SCAN_IMG_READ, // read first image, [in]: PACK_BASE, [out]: PACK_BASE::data - LPPACKIMAGE + PACK_CMD_SCAN_IMG_SIZE_GET, // get size of the first image, [in]: PACK_BASE, [out]: PACK_BASE::payload - (unsigned long long*) + PACK_CMD_SCAN_IMG_READ, // read first image, [in]: PACK_BASE, [out]: PACK_BASE::payload - LPPACKIMAGE PACK_CMD_SCAN_IMG_POP, // discard first image, [in]: PACK_BASE, [out]: PACK_BASE // file operation - PACK_CMD_FILE_QUERY = 150, // query file information, [in]: PACK_BASE::data - (char*)file-path, [out] PACK_BASE::data - LPFILEINFO - PACK_CMD_FILE_READ, // read file content, [in]: PACK_BASE::data - (char*)file-path, [out] PACK_BASE::data - file content - PACK_CMD_FILE_WRITE, // write a file, [in]: PACK_BASE::data - LPFILEINFO, [out] PACK_BASE::data - (char*)path-file. should receive whole data even if fails - PACK_CMD_FILE_MOVE, // move/rename a file, [in]: PACK_BASE::data - LPFILEINFO, [out] same data as in - PACK_CMD_FILE_REMOVE, // delete a file, [in]: PACK_BASE::data - (char*)file-path, [out] same data as in + PACK_CMD_FILE_QUERY = 150, // query file information, [in]: PACK_BASE::payload - (char*)file-path, [out] PACK_BASE::payload - LPFILEINFO + PACK_CMD_FILE_READ, // read file content, [in]: PACK_BASE::payload - (char*)file-path, [out] PACK_BASE::payload - file content + PACK_CMD_FILE_WRITE, // write a file, [in]: PACK_BASE::payload - LPFILEINFO, [out] PACK_BASE::payload - (char*)path-file. should receive whole data even if fails + PACK_CMD_FILE_MOVE, // move/rename a file, [in]: PACK_BASE::payload - LPFILEINFO, [out] same data as in + PACK_CMD_FILE_REMOVE, // delete a file, [in]: PACK_BASE::payload - (char*)file-path, [out] same data as in // process operation PACK_CMD_PROCESS_REBOOT = 200, // reboot system, [in]: PACK_BASE, [out]: PACK_BASE - PACK_CMD_PROCESS_START, // start a program [in]: PACK_BASE::data - (char*)command string, [out]: PACK_BASE::data - (char*)process-id - PACK_CMD_PROCESS_STOP, // kill a process [in]: PACK_BASE::data - (char*)process-id, [out]: PACK_BASE - PACK_CMD_PROCESS_EXEC_RESULT, // get result of a command, [in]: PACK_BASE::data - (char*)command string, [out]: PACK_BASE::data - (char*)execute result. popen(), fgets ... - PACK_CMD_PROCESS_QUERY, // query process information [in]: PACK_BASE::data - (char*)process-id(-1 for all), [out]: LPPROCINFO + PACK_CMD_PROCESS_START, // start a program [in]: PACK_BASE::payload - (char*)command string, [out]: PACK_BASE::payload - (char*)process-id + PACK_CMD_PROCESS_STOP, // kill a process [in]: PACK_BASE::payload - (char*)process-id, [out]: PACK_BASE + PACK_CMD_PROCESS_EXEC_RESULT, // get result of a command, [in]: PACK_BASE::payload - (char*)command string, [out]: PACK_BASE::payload - (char*)execute result. popen(), fgets ... + PACK_CMD_PROCESS_QUERY, // query process information [in]: PACK_BASE::payload - (char*)process-id(-1 for all), [out]: LPPROCINFO - PACK_CMD_TOKEN_GET = 272, // 0x110, Obtain the token of the required command, [in] PACK_BASE, [out] - PACK_BASE::data - LPOPERTOKEN + PACK_CMD_TOKEN_GET = 272, // 0x110, Obtain the token of the required command, [in] PACK_BASE, [out] - PACK_BASE::payload - LPOPERTOKEN + PACK_CMD_INNER_WRITE, // inner command, for invoking IPC write, PACK_BASE::payload is the content to be sent }; enum scanner_status @@ -68,14 +74,16 @@ enum scanner_status SCANNER_STATUS_READY = 0, SCANNER_STATUS_START_SCANNING, // start ok, but scanning-thread not working SCANNER_STATUS_WORKING, // start ok, and scanning-thread is working + SCANNER_STATUS_PAUSING, SCANNER_STATUS_COVER_OPENNED, + SCANNER_STATUS_SLEEPING, SCANNER_STATUS_COUNT_MODE, SCANNER_STATUS_DOUBLE_FEEDED, SCANNER_STATUS_PAPER_JAMMED, SCANNER_STATUS_PAPER_ASKEW, SCANNER_STATUS_FEED_FAILED, SCANNER_STATUS_NO_PAPER, - SCANNER_STATUS_CFG_CHANGED, // PACK_BASE::data - LPCFGVAL + SCANNER_STATUS_CFG_CHANGED, // PACK_BASE::payload - LPCFGVAL }; enum img_format @@ -119,6 +127,23 @@ enum data_type DATA_TYPE_CUSTOM, }; +enum paper_side +{ + PAPER_SIDE_FRONT = 0, // single side, this is front + PAPER_SIDE_BACK, // single side, this is back + PAPER_SIDE_TOP, // VERT-compound sides, and front side is at top + PAPER_SIDE_BOTTOM, // VERT-compound sides, and front side is at bottom + PAPER_SIDE_LEFT, // HORZ-compound sides, and front side is at left + PAPER_SIDE_RIGHT, // HORZ-compound sides, and front side is at right +}; +enum rot_angle +{ + ROT_ANGLE_0 = 0, + ROT_ANGLE_90, + ROT_ANGLE_180, + ROT_ANGLE_270, +}; + #pragma pack(push) #pragma pack(1) typedef struct _pack_base // A piece of data has only one header @@ -130,13 +155,15 @@ typedef struct _pack_base // A piece of data has only one header uint32_t cmd; // packet_cmd on initiator side uint32_t result; // command result(error code) on roger side char payload[0]; // payloads, according to 'cmd', LPTHUNKD if 'thunk' was 1 + + STRUCT_CONSTRUCTOR(_pack_base) }PACK_BASE, * LPPACK_BASE; typedef struct _thunk_data { uint16_t bytes; // bytes in 'data', 0 is end for whole data char data[0]; // data buffer with length 'bytes' -}THUNKD, *LPTHUNKD; +}THUNKD, * LPTHUNKD; typedef struct _cfg_val { @@ -147,41 +174,48 @@ typedef struct _cfg_val uint16_t val_buf_len; // capacity of 'val' char val[2]; // value }vals[1]; -}CFGVAL, *LPCFGVAL; +}CFGVAL, * LPCFGVAL; typedef struct _img_pos { - uint64_t paper_ind : 32; // paper index in this turn/start, based ZERO - uint64_t paper_side : 1; // 0 - front of paper(When scanning multiple sheets, the paper feeding side is the front side), 1 - back of paper + uint64_t paper_ind : 32; // paper index in this turn/start, based ZERO. (image-collector set) + uint64_t new_img : 1; // 0 - partial data; 1 - new image data. (image-collector set) + uint64_t img_over : 1; // 0 - has data yet; 1 - END for the image. (image-collector set) + uint64_t paper_side : 3; // enum paper_side. front of paper(When scanning multiple sheets, the paper feeding side is the front side). (image-collector set) + uint64_t back_rot : 2; // back rotation angle, enum rot_angle. (image-collector set) + uint64_t channel_ind : 4; // index of color channel, based ZERO, 0x0f for all channels. (image-collector set) + uint64_t status : 4; // img_status. (image-collector set) uint64_t split_ind : 7; // splitting order, from left to right and then top to bottom, based ZERO uint64_t multiout_ind : 4; // index of multi-out - uint64_t channel_ind : 4; // index of color channel, based ZERO, 0x0f for all channels - uint64_t status : 4; // img_status - uint64_t reserved : 12; // reserved -}IMGPOS, *LPIMGPOS; + uint64_t reserved : 6; // reserved + + STRUCT_CONSTRUCTOR(_img_pos) +}IMGPOS, * LPIMGPOS; typedef struct _pack_img { IMGPOS pos; // image pos info ... - uint32_t width; // image width in pixel - uint32_t height; // image height in pixel - uint32_t resolution_x; // image horizontal reolution - uint32_t resolution_y; // image vertical reolution - uint32_t channels : 6; // image channels per pixel - uint32_t format : 6; // image format, see 'img_format' - uint32_t bpp : 6; // bits per pixel - uint32_t bppc : 6; // bits per pixel in this channel, equal to 'bpp' if pos.channel_ind == 0x0f - uint32_t compression : 6; // image data compression, see 'img_compression' + uint32_t width; // image width in pixel. (image-collector set) + uint32_t height; // image height in pixel. (image-collector set) + uint32_t resolution_x; // image horizontal reolution. (image-collector set) + uint32_t resolution_y; // image vertical reolution. (image-collector set) + uint32_t channels : 6; // image channels per pixel. (image-collector set) + uint32_t format : 6; // image format, see 'img_format'. (image-collector set) + uint32_t bpp : 6; // bits per pixel. (image-collector set) + uint32_t bppc : 6; // bits per pixel in this channel, equal to 'bpp' if pos.channel_ind == 0x0f. (image-collector set) + uint32_t compression : 6; // image data compression, see 'img_compression'. (image-collector set) uint32_t reserve : 2; // unused now - uint32_t info_size; // image information size in bytes, information part is used for quality of JPEG, pallete of BMP ... - uint64_t data_size; // image data size in bytes + uint32_t info_size; // image information size in bytes, information part is used for quality of JPEG, pallete of BMP .... (image-collector set) + uint64_t data_size; // image data size in bytes. (image-collector set) char data[0]; // two parts: image info (info_size) + image data (data_size) -}PACKIMAGE, *LPPACKIMAGE; + + STRUCT_CONSTRUCTOR(_pack_img) +}PACKIMAGE, * LPPACKIMAGE; typedef struct _oper_token { uint32_t type; // token type char data[128]; // token data -}OPERTOKEN, *LPOPERTOKEN; +}OPERTOKEN, * LPOPERTOKEN; typedef struct _file_info { @@ -193,7 +227,9 @@ typedef struct _file_info uint16_t version_len; // bytes of version string char data[0]; // 4 parts: path-file(name_len) + create-time(create_time_len) + modify-time(modify_time_len) + version(version_len) // or 5 parts in command PACK_CMD_FILE_WRITE, add content at the last part of bytes 'size' -}FILEINFO, *LPFILEINFO; + + STRUCT_CONSTRUCTOR(_file_info) +}FILEINFO, * LPFILEINFO; typedef struct _proc_info { @@ -209,6 +245,15 @@ typedef struct _proc_info uint64_t cpu_clk; // cpu clock char path_name[4]; }proc[1]; -}PROCINFO, *LPPROCINFO; + + STRUCT_CONSTRUCTOR(_proc_info) +}PROCINFO, * LPPROCINFO; #pragma pack(pop) +//////////////////////////////////////////////////////////////////////////////////////////////// +// configurations ... +// +// 1 - App has whole set, group definitions +// +// 2 - device provides sub-set, or a customizing item +// diff --git a/common/referer.h b/common/referer.h index dd0748b..0403079 100644 --- a/common/referer.h +++ b/common/referer.h @@ -91,7 +91,7 @@ public: // EINVAL - if paramter 'len' was nullptr // ENOMEM - if size of 'buf' was too small, the minimum size needed is stored in 'len' // ENOENT - the configuration named 'cfg_name' has not found - virtual int get_config(void* buf, size_t* len, const char* cfg_name = nullptr) = 0; + virtual int32_t get_config(void* buf, size_t* len, const char* cfg_name = nullptr) = 0; // Function: set value of configuration named 'cfg_name' // @@ -106,7 +106,7 @@ public: // EINVAL - parameter was invalid. 'cfg_name' was nullptr // ENOENT - configuration 'cfg_name' was not found // EUCLEAN - content in 'data' was not exact, the exact value is stored in 'data', and bytes in 'len' - virtual int set_config(const char* cfg_name, void* data, size_t* len) = 0; + virtual int32_t set_config(const char* cfg_name, void* data, size_t* len) = 0; }; #include diff --git a/scanner/img_collector/img_collector.cpp b/scanner/img_collector/img_collector.cpp index 5e7d7bf..6806ba3 100644 --- a/scanner/img_collector/img_collector.cpp +++ b/scanner/img_collector/img_collector.cpp @@ -28,10 +28,11 @@ int32_t image_collector::trigger_event(int32_t ev, void* data, size_t data_len) return ENODEV; } -int image_collector::stop(void) +int32_t image_collector::uninit(void) { if (handler_) handler_->release(); + handler_ = nullptr; return 0; diff --git a/scanner/img_collector/img_collector.h b/scanner/img_collector/img_collector.h index 3834f11..d2808a0 100644 --- a/scanner/img_collector/img_collector.h +++ b/scanner/img_collector/img_collector.h @@ -30,9 +30,11 @@ public: static image_collector* create_image_collector(event_handler* handler); public: - virtual int re_init(void) = 0; // can be called many times - virtual int start(void) = 0; - virtual int stop(void); // class derives from this should call me ! - virtual int uninit(void) = 0; +// virtual int32_t re_init(void) = 0; // can be called many times + virtual int32_t start(void) = 0; // start capture + virtual int32_t pause(void) = 0; // pause capturing - pause after taking full image + virtual int32_t resume(void) = 0; // resume capture + virtual int32_t stop(void) = 0; // stop capture + virtual int32_t uninit(void); }; diff --git a/scanner/img_process/img_process.cpp b/scanner/img_process/img_process.cpp index c7a638d..c044958 100644 --- a/scanner/img_process/img_process.cpp +++ b/scanner/img_process/img_process.cpp @@ -216,7 +216,7 @@ img_processor::img_processor(paremeter_get* get, event_handler* h) : param_get_( img_processor::~img_processor() {} -int img_processor::get_config(void* buf, size_t* len, const char* cfg_name) +int32_t img_processor::get_config(void* buf, size_t* len, const char* cfg_name) { int ret = 0; std::string val(""); @@ -249,18 +249,18 @@ int img_processor::get_config(void* buf, size_t* len, const char* cfg_name) return ret; } -int img_processor::set_config(const char* cfg_name, void* data, size_t* len) +int32_t img_processor::set_config(const char* cfg_name, void* data, size_t* len) { int ret = 0; return ret; } -int img_processor::push_image(LPPACKIMAGE img) +int32_t img_processor::push_image(LPPACKIMAGE img, uint8_t* data, size_t len) { return 0; } -int img_processor::stop(void) +int32_t img_processor::stop(void) { if (param_get_) param_get_->release(); @@ -271,3 +271,7 @@ int img_processor::stop(void) return 0; } +int32_t img_processor::set_speed_first(bool first) +{ + return 0; +} diff --git a/scanner/img_process/img_process.h b/scanner/img_process/img_process.h index 98d571e..f38663b 100644 --- a/scanner/img_process/img_process.h +++ b/scanner/img_process/img_process.h @@ -95,11 +95,12 @@ protected: // sane_cfg_provider public: - virtual int get_config(void* buf, size_t* len, const char* cfg_name = nullptr) override; - virtual int set_config(const char* cfg_name, void* data, size_t* len) override; + virtual int32_t get_config(void* buf, size_t* len, const char* cfg_name = nullptr) override; + virtual int32_t set_config(const char* cfg_name, void* data, size_t* len) override; public: - int push_image(LPPACKIMAGE img); - int stop(void); + int32_t push_image(LPPACKIMAGE img, uint8_t* data, size_t len); + int32_t stop(void); + int32_t set_speed_first(bool first); // start as many threads as possible if 'first' was true, or down to ONE thread }; diff --git a/scanner/main/scanner.cpp b/scanner/main/scanner.cpp index 6766bca..5564032 100644 --- a/scanner/main/scanner.cpp +++ b/scanner/main/scanner.cpp @@ -12,8 +12,9 @@ // scanner scanner::scanner(const char* ipc_id) : img_proc_(nullptr), img_src_(nullptr), res_(nullptr), ipc_(nullptr) , exit_(nullptr), run_(true), status_(SCANNER_STATUS_READY), ipc_id_(ipc_id) - , partial_msg_("") + , partial_msg_(""), write_thunk_(false) { + hw_status_.val = 0; exit_ = new linux_event("exit-scanner"); } scanner::~scanner() @@ -48,6 +49,7 @@ int32_t scanner::uninit(void) if (img_src_) { img_src_->stop(); + img_src_->uninit(); img_src_->release(); } if (img_proc_) @@ -77,7 +79,7 @@ int32_t scanner::from_thunk_data(std::string& pack) { LPPACK_BASE pk = (LPPACK_BASE)&pack[0]; - if (pk->thunk) + if (pk->thunk && pk->cmd != PACK_CMD_INNER_WRITE) { std::string d(""); LPTHUNKD pthk = (LPTHUNKD)pk->payload; @@ -88,12 +90,19 @@ int32_t scanner::from_thunk_data(std::string& pack) } pack.erase(sizeof(PACK_BASE)); pack += d; + ((LPPACK_BASE)&pack[0])->thunk = 0; + ((LPPACK_BASE)&pack[0])->total_bytes = d.length(); } return pack.length(); } int32_t scanner::dispatch_ipc_message(LPPACK_BASE pack) { + if (write_thunk_ && pack->cmd != PACK_CMD_INNER_WRITE) + { + return EAGAIN; + } + if (pack->cmd == PACK_CMD_ATTR_HISTORY_COUNT_GET) { @@ -121,36 +130,80 @@ int32_t scanner::dispatch_ipc_message(LPPACK_BASE pack) else if (pack->cmd == PACK_CMD_SETTING_RESTORE) { + } + else if (pack->cmd == PACK_CMD_STATUS_GET) + { + PACK_BASE reply(*pack); + + if (hw_status_.no_paper) + reply.result = SCANNER_STATUS_NO_PAPER; + else if (hw_status_.cover_opened) + reply.result = SCANNER_STATUS_COVER_OPENNED; + else if (hw_status_.sleeping) + reply.result = SCANNER_STATUS_SLEEPING; + else + reply.result = status_; + + size_t len = sizeof(reply); + ipc_->write((char*)&reply, &len, false); } else if (pack->cmd == PACK_CMD_STATUS_RESTORE) { + PACK_BASE reply(*pack); + size_t len = sizeof(reply); + + reply.result = 0; + ipc_->write((char*)&reply, &len, false); } else if (pack->cmd == PACK_CMD_SCAN_START) { + PACK_BASE reply(*pack); + if (hw_status_.no_paper) + reply.result = SCANNER_STATUS_NO_PAPER; + else if (hw_status_.cover_opened) + reply.result = SCANNER_STATUS_COVER_OPENNED; + else if (hw_status_.sleeping) + reply.result = SCANNER_STATUS_SLEEPING; + else if (status_ != SCANNER_STATUS_READY) + reply.result = status_; + else + reply.result = img_src_->start(); + + size_t len = sizeof(reply); + ipc_->write((char*)&reply, &len, false); } else if (pack->cmd == PACK_CMD_SCAN_STOP) { } - else if (pack->cmd == PACK_CMD_SCAN_IMG_SIZE_GET) - { - - } - else if (pack->cmd == PACK_CMD_SCAN_IMG_READ) - { - - } - else if (pack->cmd == PACK_CMD_SCAN_IMG_POP) + //else if (pack->cmd == PACK_CMD_SCAN_IMG_SIZE_GET) + //{ + // + //} + //else if (pack->cmd == PACK_CMD_SCAN_IMG_READ) + //{ + // + //} + //else if (pack->cmd == PACK_CMD_SCAN_IMG_POP) + //{ + // + //} + else if (pack->cmd == PACK_CMD_INNER_WRITE) { + size_t len = pack->total_bytes; + write_thunk_ = pack->thunk; + ipc_->write(pack->payload, &len, false); } return 0; } int32_t scanner::ipc_message_handler(void) { + std::deque task; + while (run_) { std::string msg(""); @@ -159,7 +212,19 @@ int32_t scanner::ipc_message_handler(void) continue; from_thunk_data(msg); - dispatch_ipc_message((LPPACK_BASE)&msg[0]); + if (dispatch_ipc_message((LPPACK_BASE)&msg[0]) == EAGAIN) + { + task.push_back(msg); + } + else if (!write_thunk_) + { + while (task.size()) + { + msg = std::move(task.front()); + task.pop_front(); + dispatch_ipc_message((LPPACK_BASE)&msg[0]); + } + } } return 0; @@ -229,21 +294,93 @@ int32_t scanner::on_event(int32_t ev, void* data, size_t data_len) switch (ev) { - case SCANNER_EVENT_COLLECTOR_WORKING: - status_ = SCANNER_STATUS_WORKING; - break; case SCANNER_EVENT_IPC_DATA_RECEIVED: on_ipc(data, data_len, true); break; case SCANNER_EVENT_IPC_DATA_SENT: on_ipc(data, data_len, false); break; - case SCANNER_EVENT_COLLECTOR_COVER_OPENNED: - status_ = SCANNER_STATUS_COVER_OPENNED; + case SCANNER_EVENT_COLLECTOR_WORKING: + status_ = SCANNER_STATUS_WORKING; + break; + case SCANNER_EVENT_COLLECTOR_IMG_DATA: + if (((LPIMGD)data)->info->pos.new_img && ((LPIMGD)data)->info->pos.img_over) + { + img_proc_->push_image(((LPIMGD)data)->info, ((LPIMGD)data)->data, data_len); + } + else + { + // thunked data, send by IPC immediately + PACK_BASE pk; + LPIMGD src = (LPIMGD)data; + std::string msg(""); + THUNKD thunk; + + pk.cmd = PACK_CMD_INNER_WRITE; + pk.thunk = !((LPIMGD)data)->info->pos.img_over; + if (((LPIMGD)data)->info->pos.new_img) + { + PACK_BASE head; + + memset(&head, 0, sizeof(head)); + head.cmd = PACK_CMD_SCAN_IMG_READ; + head.thunk = 1; + thunk.bytes = sizeof(head) + sizeof(src->info) + data_len; + head.total_bytes = thunk.bytes + sizeof(thunk); + msg = std::string((char*)&pk, sizeof(pk)) + + std::string((char*)&head, sizeof(head)) + + std::string((char*)&thunk, sizeof(thunk)) + + std::string((char*)&src->info, sizeof(src->info)); + } + else + { + thunk.bytes = data_len; + msg = std::string((char*)&pk, sizeof(pk)) + std::string((char*)&thunk, sizeof(thunk)); + } + msg += std::string((char*)src->data, data_len); + if (src->info->pos.img_over) + { + thunk.bytes = 0; // THUNK end flag + msg += std::string((char*)&thunk, sizeof(thunk)); + } + ((LPPACK_BASE)&msg[0])->total_bytes = msg.length() - sizeof(pk); + + msg_que_.save(msg, true); + } break; case SCANNER_EVENT_COLLECTOR_PAPER_ON: + hw_status_.no_paper = !(*(bool*)data); break; - case SCANNER_EVENT_COLLECOTR_GET_BUF: + case SCANNER_EVENT_COLLECTOR_COVER_OPENNED: + hw_status_.cover_opened = *(bool*)data; + break; + case SCANNER_EVENT_COLLECTOR_SLEEPPING: + hw_status_.sleeping = *(bool*)data; + break; + case SCANNER_EVENT_COLLECTOR_ERROR: + break; + case SCANNER_EVENT_COLLECTOR_STOPPED: + status_ = data_len ? (scanner_status)data_len : SCANNER_STATUS_READY; + break; + case SCANNER_EVENT_RESOURCE_LOW_MEM: + case SCANNER_EVENT_RESOURCE_HIGH_CPU: + if (*(bool*)data) // low mem or high cpu + { + if (status_ == SCANNER_STATUS_WORKING) + { + if (img_src_->pause() == 0) + status_ = SCANNER_STATUS_PAUSING; + } + } + else if (status_ == SCANNER_STATUS_PAUSING) + { + if (img_src_->resume() == 0) + status_ = SCANNER_STATUS_WORKING; + } + img_proc_->set_speed_first(!(*(bool*)data)); + break; + case SCANNER_EVENT_RESOURCE_LOW_DISK: + // we have no disk write operations, ignore now break; default: ret = EINVAL; diff --git a/scanner/main/scanner.h b/scanner/main/scanner.h index b1a93a9..fe75e40 100644 --- a/scanner/main/scanner.h +++ b/scanner/main/scanner.h @@ -44,9 +44,21 @@ class scanner : public event_handler, public paremeter_get ipc_wrapper *ipc_; linux_event *exit_; volatile bool run_; + volatile bool write_thunk_; // whether IPC is writing thunk data scanner_status status_; safe_fifo msg_que_; std::string partial_msg_; + union + { + struct + { + uint32_t no_paper : 1; + uint32_t cover_opened : 1; + uint32_t sleeping : 1; + uint32_t reserve : 29; + }; + uint32_t val; + }hw_status_; int32_t init(void); int32_t uninit(void); diff --git a/sln/scanner.vcxproj b/sln/scanner.vcxproj index 7864cb3..38ab361 100644 --- a/sln/scanner.vcxproj +++ b/sln/scanner.vcxproj @@ -43,7 +43,12 @@ + + + + + 16.0 diff --git a/sln/scanner.vcxproj.filters b/sln/scanner.vcxproj.filters index 4fd5711..3d772c3 100644 --- a/sln/scanner.vcxproj.filters +++ b/sln/scanner.vcxproj.filters @@ -95,5 +95,20 @@ + + common + + + img-collector + + + img-proc + + + main + + + res-mon + \ No newline at end of file