补充图像源事件交互, THUNK数据传输

This commit is contained in:
gb 2022-12-29 16:46:27 +08:00
parent e4e880c7ee
commit 8a08984470
11 changed files with 313 additions and 91 deletions

View File

@ -6,6 +6,8 @@
// //
#include "referer.h" #include "referer.h"
#include "packet.h"
#include <thread> #include <thread>
#include <memory> #include <memory>
@ -40,17 +42,15 @@ enum scanner_event
SCANNER_EVENT_IMAGE_PROC_ERR, SCANNER_EVENT_IMAGE_PROC_ERR,
// 4 - resource // 4 - resource
SCANNER_EVENT_RESOURCE_LOW_MEM = 300, SCANNER_EVENT_RESOURCE_LOW_MEM = 300, // on_event(, (bool*)low_mem, (bool)local_display)
SCANNER_EVENT_RESOURCE_LOW_DISK, SCANNER_EVENT_RESOURCE_LOW_DISK, // on_event(, (bool*)low_disk, (bool)local_display)
SCANNER_EVENT_RESOURCE_HIGH_CPU, SCANNER_EVENT_RESOURCE_HIGH_CPU, // on_event(, (bool*)high_cpu, (bool)local_display)
}; };
typedef struct _img_data typedef struct _img_data
{ {
uint32_t new_img : 1; // 0 - partial data; 1 - new image data LPPACKIMAGE info;
uint32_t img_over : 1; // 0 - has data yet; 1 - END for the image uint8_t* data;
uint32_t reserve : 30;
uint8_t* buf;
}IMGD, *LPIMGD; }IMGD, *LPIMGD;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -5,11 +5,16 @@
// created on 2022-12-06 // created on 2022-12-06
// //
#include <bits/stdint-uintn.h> #include <bits/stdint-uintn.h>
#include <string.h>
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// definitions ... // definitions ...
#define CONFIG_NAME_MAX_LEN 32 // max bytes of configuration name #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 !!! // 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 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 // 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::data - {"os":"linux", "ver":"4.4.194", ...} 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::data - {"firmware":"G2393A1234", "CIS":"CIS-123", ...} 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::data - {"serial":"20221206001"} 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::data - {"serial":"20221206001"}, [out] PACK_BASE 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::data - {"mac":"12:34:56:78:9a:bc"} 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::data - {"ipv4":"192.168.1.123", "ipv6":"::1"} 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::data - {"CPU":"ARM x86", "mem":"16GB", ...} 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::data - {"history-count":12345, ...} 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::data - {"roller-count":2345} 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::data - {"roller-count":2345}, [out] PACK_BASE PACK_CMD_ATTR_ROLLER_COUNT_SET, // set roller count, [in]: PACK_BASE::payload - {"roller-count":2345}, [out] PACK_BASE
// configuration get/set // 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 = 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::data - LPCFGVAL, [out]: PACK_BASE::data - LPCFGVAL 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::data - LPCFGVAL, [out]: PACK_BASE on OK or PACK_BASE::data - 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 PACK_CMD_SETTING_RESTORE, // restore given settings, [in]: PACK_BASE, [out]: PACK_BASE
// status management // status management
@ -42,25 +47,26 @@ enum packet_cmd
// scan command // scan command
PACK_CMD_SCAN_START = 100, // start scanning, [in]: PACK_BASE, [out]: PACK_BASE 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_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_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::data - LPPACKIMAGE 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 PACK_CMD_SCAN_IMG_POP, // discard first image, [in]: PACK_BASE, [out]: PACK_BASE
// file operation // 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_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::data - (char*)file-path, [out] PACK_BASE::data - file content 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::data - LPFILEINFO, [out] PACK_BASE::data - (char*)path-file. should receive whole data even if fails 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::data - LPFILEINFO, [out] same data as in 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::data - (char*)file-path, [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 // process operation
PACK_CMD_PROCESS_REBOOT = 200, // reboot system, [in]: PACK_BASE, [out]: PACK_BASE 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_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::data - (char*)process-id, [out]: PACK_BASE 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::data - (char*)command string, [out]: PACK_BASE::data - (char*)execute result. popen(), fgets ... 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::data - (char*)process-id(-1 for all), [out]: LPPROCINFO 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 enum scanner_status
@ -68,14 +74,16 @@ enum scanner_status
SCANNER_STATUS_READY = 0, SCANNER_STATUS_READY = 0,
SCANNER_STATUS_START_SCANNING, // start ok, but scanning-thread not working SCANNER_STATUS_START_SCANNING, // start ok, but scanning-thread not working
SCANNER_STATUS_WORKING, // start ok, and scanning-thread is working SCANNER_STATUS_WORKING, // start ok, and scanning-thread is working
SCANNER_STATUS_PAUSING,
SCANNER_STATUS_COVER_OPENNED, SCANNER_STATUS_COVER_OPENNED,
SCANNER_STATUS_SLEEPING,
SCANNER_STATUS_COUNT_MODE, SCANNER_STATUS_COUNT_MODE,
SCANNER_STATUS_DOUBLE_FEEDED, SCANNER_STATUS_DOUBLE_FEEDED,
SCANNER_STATUS_PAPER_JAMMED, SCANNER_STATUS_PAPER_JAMMED,
SCANNER_STATUS_PAPER_ASKEW, SCANNER_STATUS_PAPER_ASKEW,
SCANNER_STATUS_FEED_FAILED, SCANNER_STATUS_FEED_FAILED,
SCANNER_STATUS_NO_PAPER, SCANNER_STATUS_NO_PAPER,
SCANNER_STATUS_CFG_CHANGED, // PACK_BASE::data - LPCFGVAL SCANNER_STATUS_CFG_CHANGED, // PACK_BASE::payload - LPCFGVAL
}; };
enum img_format enum img_format
@ -119,6 +127,23 @@ enum data_type
DATA_TYPE_CUSTOM, 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(push)
#pragma pack(1) #pragma pack(1)
typedef struct _pack_base // A piece of data has only one header typedef struct _pack_base // A piece of data has only one header
@ -130,6 +155,8 @@ typedef struct _pack_base // A piece of data has only one header
uint32_t cmd; // packet_cmd on initiator side uint32_t cmd; // packet_cmd on initiator side
uint32_t result; // command result(error code) on roger side uint32_t result; // command result(error code) on roger side
char payload[0]; // payloads, according to 'cmd', LPTHUNKD if 'thunk' was 1 char payload[0]; // payloads, according to 'cmd', LPTHUNKD if 'thunk' was 1
STRUCT_CONSTRUCTOR(_pack_base)
}PACK_BASE, * LPPACK_BASE; }PACK_BASE, * LPPACK_BASE;
typedef struct _thunk_data typedef struct _thunk_data
@ -151,30 +178,37 @@ typedef struct _cfg_val
typedef struct _img_pos typedef struct _img_pos
{ {
uint64_t paper_ind : 32; // paper index in this turn/start, based ZERO uint64_t paper_ind : 32; // paper index in this turn/start, based ZERO. (image-collector set)
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 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 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 multiout_ind : 4; // index of multi-out
uint64_t channel_ind : 4; // index of color channel, based ZERO, 0x0f for all channels uint64_t reserved : 6; // reserved
uint64_t status : 4; // img_status
uint64_t reserved : 12; // reserved STRUCT_CONSTRUCTOR(_img_pos)
}IMGPOS, * LPIMGPOS; }IMGPOS, * LPIMGPOS;
typedef struct _pack_img typedef struct _pack_img
{ {
IMGPOS pos; // image pos info ... IMGPOS pos; // image pos info ...
uint32_t width; // image width in pixel uint32_t width; // image width in pixel. (image-collector set)
uint32_t height; // image height in pixel uint32_t height; // image height in pixel. (image-collector set)
uint32_t resolution_x; // image horizontal reolution uint32_t resolution_x; // image horizontal reolution. (image-collector set)
uint32_t resolution_y; // image vertical reolution uint32_t resolution_y; // image vertical reolution. (image-collector set)
uint32_t channels : 6; // image channels per pixel uint32_t channels : 6; // image channels per pixel. (image-collector set)
uint32_t format : 6; // image format, see 'img_format' uint32_t format : 6; // image format, see 'img_format'. (image-collector set)
uint32_t bpp : 6; // bits per pixel 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 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' uint32_t compression : 6; // image data compression, see 'img_compression'. (image-collector set)
uint32_t reserve : 2; // unused now 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 ... 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 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) char data[0]; // two parts: image info (info_size) + image data (data_size)
STRUCT_CONSTRUCTOR(_pack_img)
}PACKIMAGE, * LPPACKIMAGE; }PACKIMAGE, * LPPACKIMAGE;
typedef struct _oper_token typedef struct _oper_token
@ -193,6 +227,8 @@ typedef struct _file_info
uint16_t version_len; // bytes of version string 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) 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' // or 5 parts in command PACK_CMD_FILE_WRITE, add content at the last part of bytes 'size'
STRUCT_CONSTRUCTOR(_file_info)
}FILEINFO, * LPFILEINFO; }FILEINFO, * LPFILEINFO;
typedef struct _proc_info typedef struct _proc_info
@ -209,6 +245,15 @@ typedef struct _proc_info
uint64_t cpu_clk; // cpu clock uint64_t cpu_clk; // cpu clock
char path_name[4]; char path_name[4];
}proc[1]; }proc[1];
STRUCT_CONSTRUCTOR(_proc_info)
}PROCINFO, * LPPROCINFO; }PROCINFO, * LPPROCINFO;
#pragma pack(pop) #pragma pack(pop)
////////////////////////////////////////////////////////////////////////////////////////////////
// configurations ...
//
// 1 - App has whole set, group definitions
//
// 2 - device provides sub-set, or a customizing item
//

View File

@ -91,7 +91,7 @@ public:
// EINVAL - if paramter 'len' was nullptr // EINVAL - if paramter 'len' was nullptr
// ENOMEM - if size of 'buf' was too small, the minimum size needed is stored in 'len' // 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 // 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' // Function: set value of configuration named 'cfg_name'
// //
@ -106,7 +106,7 @@ public:
// EINVAL - parameter was invalid. 'cfg_name' was nullptr // EINVAL - parameter was invalid. 'cfg_name' was nullptr
// ENOENT - configuration 'cfg_name' was not found // 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' // 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 <string> #include <string>

View File

@ -28,10 +28,11 @@ int32_t image_collector::trigger_event(int32_t ev, void* data, size_t data_len)
return ENODEV; return ENODEV;
} }
int image_collector::stop(void) int32_t image_collector::uninit(void)
{ {
if (handler_) if (handler_)
handler_->release(); handler_->release();
handler_ = nullptr; handler_ = nullptr;
return 0; return 0;

View File

@ -30,9 +30,11 @@ public:
static image_collector* create_image_collector(event_handler* handler); static image_collector* create_image_collector(event_handler* handler);
public: public:
virtual int re_init(void) = 0; // can be called many times // virtual int32_t re_init(void) = 0; // can be called many times
virtual int start(void) = 0; virtual int32_t start(void) = 0; // start capture
virtual int stop(void); // class derives from this should call me ! virtual int32_t pause(void) = 0; // pause capturing - pause after taking full image
virtual int uninit(void) = 0; virtual int32_t resume(void) = 0; // resume capture
virtual int32_t stop(void) = 0; // stop capture
virtual int32_t uninit(void);
}; };

View File

@ -216,7 +216,7 @@ img_processor::img_processor(paremeter_get* get, event_handler* h) : param_get_(
img_processor::~img_processor() 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; int ret = 0;
std::string val(""); std::string val("");
@ -249,18 +249,18 @@ int img_processor::get_config(void* buf, size_t* len, const char* cfg_name)
return ret; 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; int ret = 0;
return ret; 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; return 0;
} }
int img_processor::stop(void) int32_t img_processor::stop(void)
{ {
if (param_get_) if (param_get_)
param_get_->release(); param_get_->release();
@ -271,3 +271,7 @@ int img_processor::stop(void)
return 0; return 0;
} }
int32_t img_processor::set_speed_first(bool first)
{
return 0;
}

View File

@ -95,11 +95,12 @@ protected:
// sane_cfg_provider // sane_cfg_provider
public: public:
virtual int get_config(void* buf, size_t* len, const char* cfg_name = nullptr) override; virtual int32_t 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 set_config(const char* cfg_name, void* data, size_t* len) override;
public: public:
int push_image(LPPACKIMAGE img); int32_t push_image(LPPACKIMAGE img, uint8_t* data, size_t len);
int stop(void); 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
}; };

View File

@ -12,8 +12,9 @@
// scanner // scanner
scanner::scanner(const char* ipc_id) : img_proc_(nullptr), img_src_(nullptr), res_(nullptr), ipc_(nullptr) 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) , 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"); exit_ = new linux_event("exit-scanner");
} }
scanner::~scanner() scanner::~scanner()
@ -48,6 +49,7 @@ int32_t scanner::uninit(void)
if (img_src_) if (img_src_)
{ {
img_src_->stop(); img_src_->stop();
img_src_->uninit();
img_src_->release(); img_src_->release();
} }
if (img_proc_) if (img_proc_)
@ -77,7 +79,7 @@ int32_t scanner::from_thunk_data(std::string& pack)
{ {
LPPACK_BASE pk = (LPPACK_BASE)&pack[0]; LPPACK_BASE pk = (LPPACK_BASE)&pack[0];
if (pk->thunk) if (pk->thunk && pk->cmd != PACK_CMD_INNER_WRITE)
{ {
std::string d(""); std::string d("");
LPTHUNKD pthk = (LPTHUNKD)pk->payload; LPTHUNKD pthk = (LPTHUNKD)pk->payload;
@ -88,12 +90,19 @@ int32_t scanner::from_thunk_data(std::string& pack)
} }
pack.erase(sizeof(PACK_BASE)); pack.erase(sizeof(PACK_BASE));
pack += d; pack += d;
((LPPACK_BASE)&pack[0])->thunk = 0;
((LPPACK_BASE)&pack[0])->total_bytes = d.length();
} }
return pack.length(); return pack.length();
} }
int32_t scanner::dispatch_ipc_message(LPPACK_BASE pack) 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) 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_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) 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) 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_STOP)
{ {
} }
else if (pack->cmd == PACK_CMD_SCAN_IMG_SIZE_GET) //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_READ)
{ //{
//
} //}
else if (pack->cmd == PACK_CMD_SCAN_IMG_POP) //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; return 0;
} }
int32_t scanner::ipc_message_handler(void) int32_t scanner::ipc_message_handler(void)
{ {
std::deque<std::string> task;
while (run_) while (run_)
{ {
std::string msg(""); std::string msg("");
@ -159,8 +212,20 @@ int32_t scanner::ipc_message_handler(void)
continue; continue;
from_thunk_data(msg); from_thunk_data(msg);
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]); dispatch_ipc_message((LPPACK_BASE)&msg[0]);
} }
}
}
return 0; return 0;
} }
@ -229,21 +294,93 @@ int32_t scanner::on_event(int32_t ev, void* data, size_t data_len)
switch (ev) switch (ev)
{ {
case SCANNER_EVENT_COLLECTOR_WORKING:
status_ = SCANNER_STATUS_WORKING;
break;
case SCANNER_EVENT_IPC_DATA_RECEIVED: case SCANNER_EVENT_IPC_DATA_RECEIVED:
on_ipc(data, data_len, true); on_ipc(data, data_len, true);
break; break;
case SCANNER_EVENT_IPC_DATA_SENT: case SCANNER_EVENT_IPC_DATA_SENT:
on_ipc(data, data_len, false); on_ipc(data, data_len, false);
break; break;
case SCANNER_EVENT_COLLECTOR_COVER_OPENNED: case SCANNER_EVENT_COLLECTOR_WORKING:
status_ = SCANNER_STATUS_COVER_OPENNED; 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; break;
case SCANNER_EVENT_COLLECTOR_PAPER_ON: case SCANNER_EVENT_COLLECTOR_PAPER_ON:
hw_status_.no_paper = !(*(bool*)data);
break; 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; break;
default: default:
ret = EINVAL; ret = EINVAL;

View File

@ -44,9 +44,21 @@ class scanner : public event_handler, public paremeter_get
ipc_wrapper *ipc_; ipc_wrapper *ipc_;
linux_event *exit_; linux_event *exit_;
volatile bool run_; volatile bool run_;
volatile bool write_thunk_; // whether IPC is writing thunk data
scanner_status status_; scanner_status status_;
safe_fifo<std::string> msg_que_; safe_fifo<std::string> msg_que_;
std::string partial_msg_; 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 init(void);
int32_t uninit(void); int32_t uninit(void);

View File

@ -43,7 +43,12 @@
<ClInclude Include="..\scanner\res_monitor\res_monitor.h" /> <ClInclude Include="..\scanner\res_monitor\res_monitor.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Text Include="..\common\CMakeLists.txt" />
<Text Include="..\scanner\CMakeLists.txt" /> <Text Include="..\scanner\CMakeLists.txt" />
<Text Include="..\scanner\img_collector\CMakeLists.txt" />
<Text Include="..\scanner\img_process\CMakeLists.txt" />
<Text Include="..\scanner\main\CMakeLists.txt" />
<Text Include="..\scanner\res_monitor\CMakeLists.txt" />
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion> <VCProjectVersion>16.0</VCProjectVersion>

View File

@ -95,5 +95,20 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Text Include="..\scanner\CMakeLists.txt" /> <Text Include="..\scanner\CMakeLists.txt" />
<Text Include="..\common\CMakeLists.txt">
<Filter>common</Filter>
</Text>
<Text Include="..\scanner\img_collector\CMakeLists.txt">
<Filter>img-collector</Filter>
</Text>
<Text Include="..\scanner\img_process\CMakeLists.txt">
<Filter>img-proc</Filter>
</Text>
<Text Include="..\scanner\main\CMakeLists.txt">
<Filter>main</Filter>
</Text>
<Text Include="..\scanner\res_monitor\CMakeLists.txt">
<Filter>res-mon</Filter>
</Text>
</ItemGroup> </ItemGroup>
</Project> </Project>