newtx/sdk/base/packet.h

380 lines
16 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
// packet structures and command
//
// created on 2022-12-06
//
#if !defined(WIN32)
#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)
// NOTE: All text transmitted by pack cmd is in UTF-8 format !!!
enum ep0_req
{
USB_REQ_EP0_GET_PROTO_VER = 100, // get protocol version (PROTOCOL_VER), req = me, ind = 0, val = 0, len = 2
USB_REQ_EP0_GET_STATUS, // 获取各工作线程状态, return EP0REPLYSTATUS. req = me, ind = 0, val = 0, len = sizeof(EP0REPLYSTATUS)
USB_REQ_EP0_RESET_BULK, // 关闭并重新打开BULK端点, return error number (uint32_t). req = me, ind = 0, val = 0, len = sizeof(uint32_t)
USB_REQ_EP0_CANCEL_CMD, // 取消当前指令的继续执行(一般用于中止大数据的传输). req = me, ind = 0, val = 0, len = sizeof(uint32_t) * 2 [(uint32_t)cmd + (uint32_t)pack-id]
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 woker_status
{
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
{
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
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,
};
enum scanner_status
{
SCANNER_STATUS_READY = 0x10000, // status beginning, avoiding conficts with standards/system error code
SCANNER_STATUS_NOT_OPEN,
SCANNER_STATUS_LOST_CONNECT,
SCANNER_STATUS_RESET_BULK,
SCANNER_STATUS_START_SCANNING, // start ok, but scanning-thread not working
SCANNER_STATUS_SCANNING, // start ok, and scanning-thread is working
SCANNER_STATUS_SCAN_FINISHED, // not a persistance status
SCANNER_STATUS_BUSY, // doing task exclude scanning
SCANNER_STATUS_COVER_OPENNED,
SCANNER_STATUS_COVER_CLOSED,
SCANNER_STATUS_SLEEPING,
SCANNER_STATUS_WAKED_UP,
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_PAPER_ON,
SCANNER_STATUS_STAPLE_ON,
SCANNER_STATUS_SIZE_ERR,
SCANNER_STATUS_DOGEAR,
SCANNER_STATUS_CFG_CHANGED, // PACK_BASE::payload - LPCFGVAL
};
// 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;
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
uint8_t after_do; // see SANE_INFO_xxx in sane.h
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
{
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, 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 ...
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 .... (image-collector set)
uint64_t data_size; // image data size in 'data' with bytes. (image-collector set)
// 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
//