2023-12-01 09:17:09 +00:00
# pragma once
// packet structures and command
//
// created on 2022-12-06
//
2024-02-22 05:55:11 +00:00
# if defined(WIN32)
# include <stdint.h>
# else
2023-12-01 09:17:09 +00:00
# include <bits/stdint-uintn.h>
# endif
# include <string.h>
# define TEMPORARY_API
///////////////////////////////////////////////////////////////////////////////
// definitions ...
# define CONFIG_NAME_MAX_LEN 32 // max bytes of configuration name
# define FLOAT_PRECISION .000001f
# define IS_FLOAT_EQUAL(x, y) (-FLOAT_PRECISION <= (x) - (y) && (x) - (y) <= FLOAT_PRECISION)
# define MAKE_WORD(b0, b1) (((b0) & 0xff) | (((b1) << 8) & 0x0ff00))
# define MAKE_STR(str) #str
# define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
# define ROGER(cmd) cmd##_ROGER
# define PAIR_COMMAND(cmd) \
cmd , \
cmd # # _ROGER
# define RETURN_STR_ENUM(v, e) \
if ( v = = e ) \
return # e ;
# define STRUCT_CONSTRUCTOR(st_name) \
st_name ( ) \
{ \
memset ( this , 0 , sizeof ( st_name ) ) ; \
}
// protocol version, The first thing to do after connecting is to check whether the field is compatible !!!
# define PROTOCOL_VER MAKE_WORD(0, 1)
2024-02-25 05:51:52 +00:00
// resource manager callback
# define CHK_RES_FUNC std::function<bool(int, bool, int)>
# define DECL_CHK_RES_FUNC(where, n) \
auto n = [ where ] ( int task , bool wait , int to_ms ) - > bool
2023-12-01 09:17:09 +00:00
// NOTE: All text transmitted by pack cmd is in UTF-8 format !!!
2023-12-14 06:24:15 +00:00
enum cancel_io
{
CANCEL_IO_CANCEL = 0x0ca0cel ,
} ;
2023-12-01 09:17:09 +00:00
enum ep0_req
{
2023-12-25 09:39:34 +00:00
USB_REQ_EP0_HAND_SHAKE = 100 , // hand-shake[in/out] with data LPPEERCFG, req = me, ind = 0, val = 0, len = sizeof(PEERCFG)
2023-12-26 01:33:05 +00:00
USB_REQ_EP0_GOOD_BYE , // disconnect, req = me, ind = 0, val = 0, len = sizeof(PEERCFG)
2023-12-19 07:27:16 +00:00
USB_REQ_EP0_GET_STATUS , // 获取各工作线程状态, return EP0REPLYSTATUS. req = me, ind = 0, val = bool: whether write log, len = sizeof(EP0REPLYSTATUS)
2023-12-14 06:24:15 +00:00
USB_REQ_EP0_CANCEL_IO , // 设置当前IO数据的有效性. req = me, ind = 0, val = 0, len = sizeof(uint32_t), discard IO data when data is CANCEL_IO_CANCEL
// work-flow: write control with 'CANCEL_IO_CANCEL', write bulk with 1 byte, write control with not 'CANCEL_IO_CANCEL' to restore
2023-12-01 09:17:09 +00:00
USB_REQ_EP0_SET_ENCRYPT , // 设置加密方式, req = me, ind = 0, val = 0, len = sizeof(PACK_BASE)
} ;
2023-12-09 10:21:05 +00:00
enum woker_status
2023-12-01 09:17:09 +00:00
{
2023-12-09 10:21:05 +00:00
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
2023-12-13 06:57:08 +00:00
WORKER_STATUS_WAIT_RESOURCE , // wait resource
2023-12-01 09:17:09 +00:00
} ;
2024-02-25 05:51:52 +00:00
enum _task
{
TASK_NONE = 0 ,
TASK_EP0 ,
TASK_BULK_IN ,
TASK_BULK_OUT ,
TASK_CAPTURER ,
TASK_IMG_PROCESSOR ,
} ;
2023-12-01 09:17:09 +00:00
enum packet_cmd
{
PACK_CMD_NULL ,
PAIR_COMMAND ( PACK_CMD_HEART_BEAT ) , // notify peers you are still alive, receiver should reply the same pack
PAIR_COMMAND ( PACK_CMD_INVALID ) , // reply when received an invalid packet
PAIR_COMMAND ( PACK_CMD_SYNC ) ,
// attributes get/set, all content in PACK_BASE::payload should be in JSON style - all readonly attributes move to readonly SANE-options on 2023-03-20
//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_STATUS_ROGER = 100 , // device -> host. PACK_BASE::result -> status
PAIR_COMMAND ( PACK_CMD_SETTING_GET ) , // get all settings supported by the device, [in]: PACK_BASE, [out]: PACK_BASE::payload - configuration JSON, see SANE-configuration format
PAIR_COMMAND ( PACK_CMD_SETTING_GET_CUR ) , // get current value of given setting, [in]: PACK_BASE::payload - (char*)name, [out]: PACK_BASE::payload - LPCFGVAL
PAIR_COMMAND ( PACK_CMD_SETTING_SET ) , // set value of given setting, [in]: PACK_BASE::payload - LPCFGVAL, [out]: PACK_BASE::payload - LPCFGVAL
PAIR_COMMAND ( PACK_CMD_SETTING_RESTORE ) , // restore given settings, [in]: PACK_BASE::payload - LPCFGVAL, [out]: PACK_BASE::payload - LPCFGVAL
// scan command
PACK_CMD_SCAN_BASE = 200 ,
PAIR_COMMAND ( PACK_CMD_SCAN_START ) , // start scanning, [in]: PACK_BASE, [out]: PACK_BASE
PAIR_COMMAND ( PACK_CMD_SCAN_IMG ) , // device -> host, PACK_BASE::payload - LPPACKIMAGE
PAIR_COMMAND ( PACK_CMD_SCAN_PAPER ) , // device -> host, ONE paper has passed through the CIS. PACK_BASE::data - index of this paper
2024-03-21 09:44:43 +00:00
PACK_CMD_DEBUG_INFO , // device -> host, PACK_BASE::data is (char*)debug-info-text
2023-12-01 09:17:09 +00:00
PACK_CMD_SCAN_FINISHED_ROGER , // device -> host, PACK_BASE::data is scanner_status
PAIR_COMMAND ( PACK_CMD_SCAN_STOP ) , // stop scanning, [in]: PACK_BASE, [out]: PACK_BASE
//PAIR_COMMAND(PACK_CMD_SCAN_IMAGE_REQ), // get image request, [in]: PACK_BASE, [out] PACK_BASE on error, or PACK_BASE::payload - LPPACKIMAGE
//PAIR_COMMAND(PACK_CMD_SCAN_STATUS), // get scanner status, [in]: PACK_BASE, [out] PACK_BASE::result is status code
// file operation
PACK_CMD_FILE_BASE = 300 ,
//PAIR_COMMAND(PACK_CMD_FILE_QUERY), // query file information, [in]: PACK_BASE::payload - (char*)file-path, [out] PACK_BASE::payload - LPFILEINFO
PAIR_COMMAND ( PACK_CMD_FILE_READ_REQ ) , // read file content, [in]: PACK_BASE::payload - LPTXFILE, [out] PACK_BASE::payload - LPTXFILE
PAIR_COMMAND ( PACK_CMD_FILE_WRITE_REQ ) , // write a file, [in]: PACK_BASE::payload - LPTXFILE, [out] PACK_BASE
PAIR_COMMAND ( PACK_CMD_FILE_MOVE ) , // move/rename a file, [in]: PACK_BASE::payload - src\0dst\0\0, [out] PACK_BASE
PAIR_COMMAND ( PACK_CMD_FILE_REMOVE ) , // delete a file, [in]: PACK_BASE::payload - (char*)file-path, [out] PACK_BASE
// process operation
PACK_CMD_PROCESS_BASE = 400 ,
PAIR_COMMAND ( PACK_CMD_PROCESS_START ) , // start a program [in]: PACK_BASE::payload - (char*)pe\0param\0\0, [out]: PACK_BASE::payload - (uint64_t)process-id on success or PACK_BASE on failure
PAIR_COMMAND ( PACK_CMD_PROCESS_STOP ) , // kill a process [in]: PACK_BASE::payload - (char*)process-id, [out]: PACK_BASE
PAIR_COMMAND ( PACK_CMD_PROCESS_REBOOT ) , // reboot system, [in]: PACK_BASE, [out]: PACK_BASE
//PAIR_COMMAND(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 ...
//PAIR_COMMAND(PACK_CMD_PROCESS_QUERY), // query process information [in]: PACK_BASE::payload - (char*)process-id(-1 for all), [out]: LPPROCINFO
PACK_CMD_TOKEN_GET = 900 , // Obtain the token of the required command, [in] PACK_BASE, [out] - PACK_BASE::payload - LPOPERTOKEN
} ;
enum img_cb_type
{
IMG_CB_IMAGE = 0 ,
IMG_CB_STATUS ,
IMG_CB_STOPPED ,
} ;
// option affection if value changed, see SANE_INFO_xxx
enum opt_affect
{
OPT_AFFECT_NONE = 0 ,
OPT_AFFECT_INEXACT = 1 ,
OPT_AFFECT_OTHERS = 2 ,
OPT_AFFECT_IMG_PARAM = 4 ,
} ;
enum img_format
{
IMG_FMT_UNKNOWN = 0 , // unknown format
IMG_FMT_TIFF ,
IMG_FMT_BMP ,
IMG_FMT_JPEG ,
IMG_FMT_PNG ,
IMG_FMT_SVG ,
IMG_FMT_WEBP ,
IMG_FMT_GIF ,
} ;
enum img_compression
{
IMG_COMPRESSION_NONE = 0 ,
IMG_COMPRESSION_GROUP4 ,
IMG_COMPRESSION_RLE4 ,
IMG_COMPRESSION_RLE8 ,
IMG_COMPRESSION_LZW ,
IMG_COMPRESSION_ZIP ,
} ;
enum img_status
{
IMG_STATUS_OK = 0 , // normal
IMG_STATUS_DOUBLE = 1 < < 0 , // double-feeded paper
IMG_STATUS_JAM = 1 < < 1 , // jammed paper
IMG_STATUS_STAPLE = 1 < < 2 , // staples on the paper
IMG_STATUS_SIZE_ERR = 1 < < 3 , // size check failed
IMG_STATUS_DOGEAR = 1 < < 4 , // paper has dogear - common
IMG_STATUS_DOGEAR_PARTIAL = 1 < < 5 , // dogear - scanned partial
IMG_STATUS_BLANK = 1 < < 6 , // blank image
} ;
enum data_type
{
DATA_TYPE_BOOL = 0 , // (bool*)
DATA_TYPE_INT4 , // (uint32_t*)
DATA_TYPE_FLOAT , // (double*)
DATA_TYPE_STRING , // (char*) with max_len space. befor and include me, keep same with SANE_TYPE_BOOL, SANE_TYPE_xxx ...
DATA_TYPE_INT1 , // (uint8_t*)
DATA_TYPE_INT2 , // (uint16_t*)
DATA_TYPE_INT8 , // (uint64_t*)
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
PAPER_SIDE_DSP , // a special type
} ;
enum rot_angle
{
ROT_ANGLE_0 = 0 ,
ROT_ANGLE_90 ,
ROT_ANGLE_180 ,
ROT_ANGLE_270 ,
} ;
enum clr_channel
{
COLOR_CHANNEL_RGB = 0 ,
COLOR_CHANNEL_RGBA ,
COLOR_CHANNEL_GRAY ,
COLOR_CHANNEL_RED ,
COLOR_CHANNEL_GREEN ,
COLOR_CHANNEL_BLUE ,
COLOR_CHANNEL_ALPHA ,
} ;
enum color_mode
{
COLOR_MODE_BW = 0 ,
COLOR_MODE_GRAY ,
COLOR_MODE_RGB ,
} ;
# pragma pack(push)
# pragma pack(1)
typedef struct _ep0_reply
{
uint8_t in_status ; // BULK-IN status, enum bulk_statu
uint8_t out_status ; // BULK-OUT status, enum bulk_statu
uint16_t in_err ; // valid if in_statu == BULK_STATU_ERROR
uint16_t out_err ; // valid if out_statu == BULK_STATU_ERROR
uint16_t task_cnt ; // tasks in command queue
uint32_t task_cmd ; // the cmd of the task thread is doing
uint32_t task_pack_id ; // packet id of the cmd
uint32_t task_required_bytes ; // required byte of this packet
uint32_t packets_to_sent ; // how many packets in sent queue
uint32_t bytes_to_sent ; // how many bytes data is waiting for be sent in one replying packet
} EP0REPLYSTATUS , * LPEP0REPLYSTATUS ;
2023-12-14 06:24:15 +00:00
typedef struct _peer_config
{
2023-12-25 09:39:34 +00:00
uint64_t pid ; // [in] - host pc process id; [out] - usb service process id
2023-12-14 06:24:15 +00:00
uint32_t io_size ; // IO buffer size
2023-12-25 09:39:34 +00:00
uint16_t ver ; // protocol version
2023-12-14 06:24:15 +00:00
} PEERCFG , * LPPEERCFG ;
2023-12-01 09:17:09 +00:00
typedef struct _pack_base // A piece of data has only one header
{
uint32_t enc_cmd : 2 ; // encrypting type, for 'cmd'
uint32_t encrypt : 3 ; // encrypting type, for payload content. the payload must cotains self-check if was encrypted packet
uint32_t enc_data : 5 ; // data for encrypt
uint32_t size : 6 ; // bytes of this structure
uint32_t cmd : 16 ; // packet command
uint32_t data ; // simple data in command packet depends 'cmd', or error code in reply packet
uint32_t pack_id ; // maintain by the initiator, the reply packet use the same id
uint32_t payload_len ; // total bytes of payload of this command packet (the data in the range will sent in ONE 'write'),
// big data can be described in payload and independent communication, and this field should not include them.
// if encrypted packet, this field is the length after encrypting
char payload [ 0 ] ; // payloads, according to 'cmd'
STRUCT_CONSTRUCTOR ( _pack_base )
} PACK_BASE , * LPPACK_BASE ;
# define BASE_PACKET_REPLY(reply, command, id, err) \
( reply ) . encrypt = 0 ; \
( reply ) . enc_data = 0 ; \
( reply ) . size = sizeof ( reply ) ; \
( reply ) . data = err ; \
( reply ) . cmd = command ; \
( reply ) . pack_id = id ; \
( reply ) . payload_len = 0 ;
typedef struct _config_val
{
uint8_t type ; // same as SANE_Value_Type
uint8_t name_off ; // name offset of the option in data, end with '\0'
uint8_t val_off ; // option value offset in data
2023-12-26 03:30:26 +00:00
uint16_t after_do ; // see SCANNER_ERR_RELOAD_xxx in hgscanner_error.h
2023-12-01 09:17:09 +00:00
uint16_t val_size ; // real size of value
uint16_t max_size ; // max size of this option, this value has given in gb_json::size
char data [ 0 ] ; // contains value and name. fetch them according name_off and val_off members.
} CFGVAL , * LPCFGVAL ;
typedef struct _img_pos
{
2024-03-08 07:34:39 +00:00
uint64_t paper_ind : 22 ; // paper index in this turn/start, based ONE. (image-collector set)
uint64_t paper_all : 5 ; // total images of this paper
uint64_t ind_in_paper : 5 ; // image index of this paper, based ZERO
2023-12-01 09:17:09 +00:00
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, enum clr_channel. (image-collector set)
uint64_t status : 7 ; // 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 reserved : 3 ; // reserved
STRUCT_CONSTRUCTOR ( _img_pos )
} IMGPOS , * LPIMGPOS ;
typedef struct _pack_img
{
IMGPOS pos ; // image pos info ...
2024-02-29 07:45:50 +00:00
uint64_t life ; // milliseconds from capturer to final output
2023-12-01 09:17:09 +00:00
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)
2024-03-21 09:44:43 +00:00
uint32_t reserved : 1 ; //
uint32_t prc_last : 1 ; // whether the last image processor
2024-01-23 07:07:17 +00:00
uint32_t prc_stage : 14 ; // position of image processor, 0 is raw from CIS directly
uint32_t prc_time : 18 ; // spent time in milliseconds of image-process prc_stage
2023-12-01 09:17:09 +00:00
uint32_t info_size ; // image information size in bytes, information part is used for quality of JPEG, pallete of BMP .... (image-collector set)
2024-01-23 07:07:17 +00:00
uint32_t data_size ; // image data size in 'data' with bytes. (image-collector set)
2023-12-01 09:17:09 +00:00
// char data[0]; // two parts: image info (info_size) + image data (data_size)
STRUCT_CONSTRUCTOR ( _pack_img )
} PACKIMAGE , * LPPACKIMAGE ;
typedef struct _oper_token
{
uint32_t type ; // token type
char data [ 128 ] ; // token data
} OPERTOKEN , * LPOPERTOKEN ;
typedef struct _tx_file
{
uint64_t size ; // total size
uint64_t offset ; // offset in the file
char path [ 2 ] ; // file full path-name
} TXFILE , * LPTXFILE ;
typedef struct _file_info
{
OPERTOKEN token ; // operation token, returned by command PACK_CMD_TOKEN_GET
uint64_t size ; // file size
uint16_t name_len ; // bytes of file name string
uint16_t create_time_len ; // bytes of create time string: '2022-12-07 12:34:56.789', or target file path in command PACK_CMD_FILE_MOVE
uint16_t modify_time_len ;
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'
STRUCT_CONSTRUCTOR ( _file_info )
} FILEINFO , * LPFILEINFO ;
typedef struct _proc_info
{
OPERTOKEN token ; // operation token, returned by command PACK_CMD_TOKEN_GET
uint32_t count ; // number of elements in array proc
struct _info
{
uint16_t len ; // bytes of this element, include this head
uint64_t pid ; // process id
uint64_t ppid ; // parent process id
uint64_t start ; // started time in ns from 1970-01-01 00:00:00
uint64_t mem ; // memory usage, in bytes
uint64_t cpu_clk ; // cpu clock
char path_name [ 4 ] ;
} proc [ 1 ] ;
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
//