414 lines
16 KiB
C
414 lines
16 KiB
C
/****************************************************************************
|
|
|
|
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
|
|
|
|
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
|
|
be copied by any method or incorporated into another program without
|
|
the express written consent of Aerospace C.Power. This Information or any portion
|
|
thereof remains the property of Aerospace C.Power. The Information contained herein
|
|
is believed to be accurate and Aerospace C.Power assumes no responsibility or
|
|
liability for its use in any way and conveys no license or title under
|
|
any patent or copyright and makes no representation or warranty that this
|
|
Information is free from patent or copyright infringement.
|
|
|
|
****************************************************************************/
|
|
|
|
#ifndef PROTO_QSXJ_H
|
|
#define PROTO_QSXJ_H
|
|
|
|
#include "os_types_api.h"
|
|
#include "iot_utils_api.h"
|
|
#include "iot_pkt_api.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/* pack for the structures in the whole file */
|
|
#pragma pack(push) /* save the pack status */
|
|
#pragma pack(1) /* 1 byte align */
|
|
|
|
/* definition frame start char */
|
|
#define PROTO_QSXJ_START_CHAR 0x02
|
|
/* definition frame start char length */
|
|
#define PROTO_QSXJ_START_CHAR_LEN 1
|
|
/* definition crc16 length */
|
|
#define PROTO_QSXJ_CRC16_LEN 2
|
|
/* definition length of length structure */
|
|
#define PROTO_QSXJ_LEN_STRUCTURE_LEN 2
|
|
/* definition length of di */
|
|
#define PROTO_QSXJ_DI_LEN 2
|
|
/* definition length of command */
|
|
#define PROTO_QSXJ_COMMAND_LEN 1
|
|
|
|
/* definition protocol version */
|
|
/* Version before January 1, 2021 */
|
|
#define PROTO_QSXJ_VER_SX_V04 0
|
|
/* Version after January 1, 2021 */
|
|
#define PROTO_QSXJ_VER_SX_V28 1
|
|
|
|
/* definition protocol channel number */
|
|
/* channel from module to DCU */
|
|
#define PROTO_QSXJ_CHANNEL_NUM0 0
|
|
/* channel from module to CIU */
|
|
#define PROTO_QSXJ_CHANNEL_NUM1 1
|
|
|
|
/* definition protocol command */
|
|
#define PROTO_QSXJ_COMMAND_CONF_REQ 0xa1
|
|
#define PROTO_QSXJ_COMMAND_CONF_RESP 0xa0
|
|
#define PROTO_QSXJ_COMMAND_SET_REQ 0x22
|
|
#define PROTO_QSXJ_COMMAND_SET_RESP 0x33
|
|
#define PROTO_QSXJ_COMMAND_TRANS_REQ 0x55
|
|
#define PROTO_QSXJ_COMMAND_TRANS_RESP 0x66
|
|
#define PROTO_QSXJ_COMMAND_EVT_RPT_REQ 0x77
|
|
#define PROTO_QSXJ_COMMAND_EVT_RPT_RESP 0x88
|
|
#define PROTO_QSXJ_COMMAND_RESET_REQ 0x99
|
|
#define PROTO_QSXJ_COMMAND_RESET_RESP 0xaa
|
|
#define PROTO_QSXJ_COMMAND_BROADCAST 0xff
|
|
#define PROTO_QSXJ_COMMAND_FWD_REQ 0xbb
|
|
#define PROTO_QSXJ_COMMAND_FWD_RESP 0xcc
|
|
#define PROTO_QSXJ_COMMAND_SET_ID_REQ 0x80
|
|
#define PROTO_QSXJ_COMMAND_SET_ID_RESP 0x8c
|
|
#define PROTO_QSXJ_COMMAND_GET_PARAM_REQ 0xc0
|
|
#define PROTO_QSXJ_COMMAND_GET_PARAM_RESP 0xc4
|
|
#define PROTO_QSXJ_COMMAND_OFF_RPT_REQ 0xc1
|
|
#define PROTO_QSXJ_COMMAND_OFF_RPT_RESP 0xc9
|
|
#define PROTO_QSXJ_COMMAND_UPGRADE_REQ 0xb0
|
|
#define PROTO_QSXJ_COMMAND_UPGRADE_RESP 0xb8
|
|
#define PROTO_QSXJ_COMMAND_GET_UPDATA_REQ 0xd0
|
|
#define PROTO_QSXJ_COMMAND_GET_UPDATA_RESP 0xd8
|
|
|
|
/* definition protocol general di */
|
|
#define PROTO_QSXJ_DI_SUCCESS 0x0000
|
|
#define PROTO_QSXJ_DI_FAILED 0x0001
|
|
#define PROTO_QSXJ_DI_MODULE_TYPE 0x0005
|
|
#define PROTO_QSXJ_DI_HARDWARE_VER 0x0006
|
|
#define PROTO_QSXJ_DI_SOFTWARE_VER 0x0007
|
|
#define PROTO_QSXJ_DI_VENDOR_TYPE 0x0008
|
|
#define PROTO_QSXJ_DI_MODULE_STATE 0x000a
|
|
#define PROTO_QSXJ_DI_METER_NUM 0x000b
|
|
#define PROTO_QSXJ_DI_BUFFER_LEN 0x000c
|
|
#define PROTO_QSXJ_DI_PROTO_VER 0x000d
|
|
#define PROTO_QSXJ_DI_MODULE_ID 0x000e
|
|
#define PROTO_QSXJ_DI_CLOSE_TIME 0x000f
|
|
#define PROTO_QSXJ_DI_RPT_TIMEOUT 0x0010
|
|
|
|
/* definition protocol hplc di */
|
|
#define PROTO_QSXJ_DI_CCO_MAC 0x8001
|
|
#define PROTO_QSXJ_DI_SNR 0x8002
|
|
#define PROTO_QSXJ_DI_MI_PSK 0x8003
|
|
#define PROTO_QSXJ_DI_BLACKLIST_TIME 0x8004
|
|
#define PROTO_QSXJ_DI_MI_PSK_ID 0x8005
|
|
#define PROTO_QSXJ_DI_FUTURE_MI_PSK_ID 0x8006
|
|
#define PROTO_QSXJ_DI_FUTURE_MI_PSK 0x8007
|
|
#define PROTO_QSXJ_DI_FUTURE_MI_PSK_TIME 0x8008
|
|
#define PROTO_QSXJ_DI_PWR_DOWN_RPT_RAND 0x8009
|
|
|
|
/* definition heartbeat data max length */
|
|
#define PROTO_QSXJ_HEARTBEAT_DATA_LEN_MAX 17
|
|
|
|
/* definition network state, 0 1 2 3 7 reserved for future */
|
|
#define PROTO_QSXJ_NET_STATE_ON_LINE 0x04
|
|
#define PROTO_QSXJ_NET_STATE_OFF_LINE 0x05
|
|
#define PROTO_QSXJ_NET_STATE_JOINING 0x06
|
|
|
|
/* definition upgrade state, 0 reserved for future */
|
|
#define PROTO_QSXJ_UPGRADE_STATE_SUCCESS 0x20
|
|
#define PROTO_QSXJ_UPGRADE_STATE_UPGRADING 0x40
|
|
#define PROTO_QSXJ_UPGRADE_STATE_VER_FAIL 0x60
|
|
#define PROTO_QSXJ_UPGRADE_STATE_FILE_FAIL 0x80
|
|
|
|
/* definition module information length */
|
|
#define PROTO_QSXJ_MODE_INFO_LEN_HW_VER 4
|
|
#define PROTO_QSXJ_MODE_INFO_LEN_SW_VER_FIX 22
|
|
#define PROTO_QSXJ_MODE_INFO_LEN_SW_VER_FILL 5
|
|
#define PROTO_QSXJ_MODE_INFO_LEN_PROTO_VER 6
|
|
|
|
/* definition module type */
|
|
#define PROTO_QSXJ_MODE_TYPE_HPLC 19
|
|
/* definition vendor type */
|
|
#define PROTO_QSXJ_VENDOR_TYPE_WQ 13
|
|
|
|
/* definition module id max len */
|
|
#define PROTO_QSXJ_MODULE_ID_MAX_LEN 32
|
|
|
|
/* definition qsxj di data len */
|
|
#define PROTO_QSXJ_DI_MODULE_STATE_DATA_LEN 1
|
|
#define PROTO_QSXJ_DI_BUFFER_LEN_DATA_LEN 2
|
|
#define PROTO_QSXJ_DI_CLOSE_TIME_DATA_LEN 1
|
|
#define PROTO_QSXJ_DI_RPT_TIMEOUT_DATA_LEN 1
|
|
#define PROTO_QSXJ_DI_SNR_DATA_LEN 1
|
|
#define PROTO_QSXJ_DI_MI_PSK_DATA_LEN 32
|
|
#define PROTO_QSXJ_DI_BL_TIME_DATA_LEN 4
|
|
#define PROTO_QSXJ_DI_MI_PSK_ID_DATA_LEN 15
|
|
#define PROTO_QSXJ_DI_FMI_PSK_ID_DATA_LEN 15
|
|
#define PROTO_QSXJ_DI_FMI_PSK_DATA_LEN 32
|
|
#define PROTO_QSXJ_DI_FMI_PSK_TIME_DATA_LEN 12
|
|
#define PROTO_QSXJ_DI_PWR_DOWN_RPT_RAND_DATA_LEN 2
|
|
|
|
/* definition meter upgrade info len */
|
|
#define PROTO_QSXJ_UPGRADE_CNT_LEN 2
|
|
#define PROTO_QSXJ_UPGRADE_IDX_LEN 4
|
|
#define PROTO_QSXJ_UPGRADE_DL_LEN 2
|
|
|
|
/* fixed version, E.ME18-PH99-999.HT.V1. */
|
|
static const uint8_t fixed_ver[] = {0x45, 0x2E, 0x4D, 0x45, 0x31, 0x38, 0x2D,
|
|
0x50, 0x48, 0x39, 0x39, 0x2D, 0x39, 0x39, 0x39, 0x2E, 0x48, 0x54, 0x2E,
|
|
0x56, 0x31, 0x2E};
|
|
|
|
typedef struct _proto_qsxj_head {
|
|
/* start char, see PROTO_QSXJ_START_CHAR */
|
|
uint8_t start_char;
|
|
/* three higher bit in length, length from command to crc16 */
|
|
uint8_t length_h : 3,
|
|
/* protocol version, see PROTO_QSXJ_VER_SX_XXX */
|
|
ver : 2,
|
|
/* flag of following frame, 0 means there is no following frame, */
|
|
/* 1 means there is following frame */
|
|
flag_follow : 1,
|
|
/* channel number, see PROTO_QSXJ_CHANNEL_XXX */
|
|
channel_num : 2;
|
|
/* eight lower bit in length, length from command to crc16 */
|
|
uint8_t length_l;
|
|
/* command, see PROTO_QSXJ_COMMAND_XXX */
|
|
uint8_t command;
|
|
/* data */
|
|
uint8_t data[0];
|
|
} proto_qsxj_head_t;
|
|
|
|
/* frame tail info of qsxj protocol link layer frame */
|
|
typedef struct _proto_qsxj_tailer {
|
|
/* crc16, from length to data */
|
|
uint8_t crc[PROTO_QSXJ_CRC16_LEN];
|
|
} proto_qsxj_tailer_t;
|
|
|
|
/* structure of qsxj protocol link layer frame
|
|
-------------
|
|
|----02H-------------| start of frame, 0x02.
|
|
|----Length----------| 2 byte of length. Include length(11 bit),
|
|
| | version(2 bit), channel number(2 bit) and flag of
|
|
| | following frame(1 bit).
|
|
|----command---------| 1 byte of command.
|
|
|----user data-------| user data
|
|
|----crc16-----------| 2 byte of crc16. from length to user data.
|
|
-------------
|
|
*/
|
|
|
|
/* structure of user data, for fixed length. only for version SX_V04 */
|
|
typedef struct _proto_qsxj_fixed_data {
|
|
/* data identification, see PROTO_QSXJ_DI_XXX. big endian */
|
|
uint8_t di[PROTO_QSXJ_DI_LEN];
|
|
/* data */
|
|
uint8_t data[0];
|
|
} proto_qsxj_fixed_data_t;
|
|
|
|
/* structure of user data */
|
|
typedef struct _proto_qsxj_data {
|
|
/* data identification, see PROTO_QSXJ_DI_XXX. big endian */
|
|
uint8_t di[PROTO_QSXJ_DI_LEN];
|
|
/* length of data */
|
|
uint8_t len;
|
|
/* data */
|
|
uint8_t data[0];
|
|
} proto_qsxj_data_t;
|
|
|
|
/* structure of module type, fixed data */
|
|
typedef struct _proto_qsxj_mode_type {
|
|
/* module type */
|
|
uint8_t mod_type;
|
|
} proto_qsxj_mode_type_t;
|
|
|
|
/* structure of hardware version */
|
|
typedef struct _proto_qsxj_hw_ver {
|
|
/* hardware version */
|
|
uint8_t hw_ver[PROTO_QSXJ_MODE_INFO_LEN_HW_VER];
|
|
} proto_qsxj_hw_ver_t;
|
|
|
|
/* structure of software version */
|
|
typedef struct _proto_qsxj_sw_ver {
|
|
/* fixed software version */
|
|
uint8_t ver_fix[PROTO_QSXJ_MODE_INFO_LEN_SW_VER_FIX];
|
|
/* filled software version */
|
|
uint8_t ver_fill[PROTO_QSXJ_MODE_INFO_LEN_SW_VER_FILL];
|
|
} proto_qsxj_sw_ver_t;
|
|
|
|
/* structure of vendor type, fixed data */
|
|
typedef struct _proto_qsxj_vendor_type {
|
|
/* vendor type */
|
|
uint8_t vendor_type;
|
|
} proto_qsxj_vendor_type_t;
|
|
|
|
/* structure of protocol version, fixed data */
|
|
typedef struct _proto_qsxj_proto_ver {
|
|
/* protocol version */
|
|
uint8_t proto_ver[PROTO_QSXJ_MODE_INFO_LEN_PROTO_VER];
|
|
} proto_qsxj_proto_ver_t;
|
|
|
|
/* structure of protocol upgrade */
|
|
typedef struct _proto_qsxj_proto_upgrade {
|
|
/* total count */
|
|
uint8_t total_cnt[PROTO_QSXJ_UPGRADE_CNT_LEN];
|
|
/* upgrade segment index, index start from 0 */
|
|
uint8_t seg_index[PROTO_QSXJ_UPGRADE_IDX_LEN];
|
|
/* upgrade data len */
|
|
uint8_t data_len[PROTO_QSXJ_UPGRADE_DL_LEN];
|
|
/* data */
|
|
uint8_t data[0];
|
|
} proto_qsxj_proto_upgrade_t;
|
|
|
|
#pragma pack(pop) /* restore the pack status */
|
|
|
|
#define proto_qsxj_len_get(head) (((head)->length_h << 8) | (head)->length_l)
|
|
|
|
#define proto_qsxj_len_fill(head, len) \
|
|
do { \
|
|
(head)->length_h = (uint8_t)((len >> 8) & 0x07); \
|
|
(head)->length_l = (uint8_t)(len & 0xff); \
|
|
} while(0)
|
|
|
|
#define proto_qsxj_di_to_byte(di, ptr) \
|
|
do { \
|
|
((uint8_t *)(ptr))[0] = (uint8_t)((di) >> 8); \
|
|
((uint8_t *)(ptr))[1] = (uint8_t)((di) & 0xff); \
|
|
} while(0)
|
|
|
|
/**
|
|
* @brief proto_qsxj_sanity_check - check if a protocol qsxj03.04.177-2021
|
|
* packet is a valid.
|
|
* @param data: packet data
|
|
* @param len: length of the packet data
|
|
* @param frame_len: pointer to length cache buffer.
|
|
* @retval: NULL -- Incorrect protocol format.
|
|
* @retval: otherwise -- pointer to the qsxj03.04.177-2021 protocol header
|
|
*/
|
|
proto_qsxj_head_t *proto_qsxj_sanity_check(uint8_t* data,
|
|
uint16_t len);
|
|
|
|
/**
|
|
* @brief proto_qsxj_frame_find - find a complete qsxj03.04.177-2021 data frame
|
|
* in buffer.
|
|
* @param data: buffer data
|
|
* @param len: length of the buffer data
|
|
* @param frame_len: pointer to length cache buffer.
|
|
* @retval: NULL -- Incorrect protocol format.
|
|
* @retval: otherwise -- pointer to the qsxj03.04.177-2021 protocol header
|
|
*/
|
|
proto_qsxj_head_t *proto_qsxj_frame_find(uint8_t *data,
|
|
uint16_t len);
|
|
|
|
/**
|
|
* @brief proto_qsxj_check_frame_handler() - check whether the frame
|
|
* is legitimate.
|
|
* @param buffer: the buffer containing data.
|
|
* @param buffer_len: len of the buffer.
|
|
* @param is_frame: false: the frame isn't legitimate.
|
|
* true: the frame is legitimate.
|
|
*/
|
|
void proto_qsxj_check_frame_handler(uint8_t* buffer, uint32_t buffer_len,
|
|
bool_t* is_frame);
|
|
|
|
/**
|
|
* @brief proto_qsxj_build_msg - build a qsxj03.04.177-2021 protocol message.
|
|
* @param data: buffer data
|
|
* @param data_len: length of the buffer data
|
|
* @param command: message command, see PROTO_QSXJ_COMMAND_XXX.
|
|
* @param ver: qsxj03.04.177-2021 protocol version, see PROTO_QSXJ_VER_XXX
|
|
* @param flag_follow: flag of following frame, 0 means there is no following
|
|
* frame, 1 means there is following frame.
|
|
* @param channel: channel number, see PROTO_QSXJ_CHANNEL_XXX.
|
|
* @retval: NULL -- for failure case.
|
|
* @retval: pkt -- the iot pkt buffer for to the qsxj03.04.177-2021
|
|
* protocol message.
|
|
*/
|
|
iot_pkt_t *proto_qsxj_build_msg(uint8_t *data, uint16_t data_len,
|
|
uint8_t command, uint8_t ver, uint8_t flag_follow, uint8_t channel);
|
|
|
|
/**
|
|
* @brief proto_qsxj_build_heartbeat_msg - build a heartbeat message.
|
|
* @param ver: qsxj03.04.177-2021 protocol version, see PROTO_QSXJ_VER_XXX.
|
|
* @param state: current module state.
|
|
* @param cco_addr: pointer to the cco address buffer, big endian.
|
|
* @param snr: the net snr, only used when cco_addr isn't NULL.
|
|
* @retval: NULL -- for failure case.
|
|
* @retval: pkt -- the iot pkt buffer for to the qsxj03.04.177-2021
|
|
* protocol message.
|
|
*/
|
|
iot_pkt_t *proto_qsxj_build_heartbeat_msg(uint8_t ver,
|
|
uint8_t state, uint8_t *cco_addr, int8_t snr);
|
|
|
|
/**
|
|
* @brief proto_qsxj_build_trans_msg - build a transmission message.
|
|
* @param ver: qsxj03.04.177-2021 protocol version, see PROTO_QSXJ_VER_XXX.
|
|
* @param data: data to be transmitted.
|
|
* @param data_len: length of data.
|
|
* @retval: NULL -- for failure case.
|
|
* @retval: pkt -- the iot pkt buffer for to the qsxj03.04.177-2021
|
|
* protocol message.
|
|
*/
|
|
iot_pkt_t *proto_qsxj_build_trans_msg(uint8_t ver,
|
|
uint8_t *data, uint16_t data_len);
|
|
|
|
/**
|
|
* @brief proto_qsxj_build_broadcast_msg - build a broadcast message.
|
|
* @param ver: qsxj03.04.177-2021 protocol version, see PROTO_QSXJ_VER_XXX.
|
|
* @param data: broadcast data.
|
|
* @param data_len: length of data.
|
|
* @retval: NULL -- for failure case.
|
|
* @retval: pkt -- the iot pkt buffer for to the qsxj03.04.177-2021
|
|
* protocol message.
|
|
*/
|
|
iot_pkt_t *proto_qsxj_build_broadcast_msg(uint8_t ver,
|
|
uint8_t *data, uint16_t data_len);
|
|
|
|
/**
|
|
* @brief proto_qsxj_build_upgrade_msg - build a upgrade message.
|
|
* @param ver: qsxj03.04.177-2021 protocol version, see PROTO_QSXJ_VER_XXX.
|
|
* @param data: data to be transmitted.
|
|
* @param data_len: length of data.
|
|
* @retval: NULL -- for failure case.
|
|
* @retval: pkt -- the iot pkt buffer for to the qsxj03.04.177-2021
|
|
* protocol message.
|
|
*/
|
|
iot_pkt_t *proto_qsxj_build_upgrade_msg(uint8_t ver,
|
|
uint8_t *data, uint16_t data_len);
|
|
|
|
/**
|
|
* @brief proto_qsxj_build_ack - build a ack or nack message.
|
|
* @param ver: qsxj03.04.177-2021 protocol version, see PROTO_QSXJ_VER_XXX.
|
|
* @param command: message command, see PROTO_QSXJ_COMMAND_XXX.
|
|
* @param flag_nack: flag of nack.
|
|
* @retval: NULL -- for failure case.
|
|
* @retval: pkt -- the iot pkt buffer for to the qsxj03.04.177-2021
|
|
* protocol message.
|
|
*/
|
|
iot_pkt_t *proto_qsxj_build_ack(uint8_t ver, uint8_t command,
|
|
uint8_t flag_nack);
|
|
|
|
/**
|
|
* @brief proto_qsxj_build_get_meter_info - build a get meter info message.
|
|
* @param ver: qsxj03.04.177-2021 protocol version, see PROTO_QSXJ_VER_XXX.
|
|
* @param flag_follow: flag of following frame, 0 means there is no following
|
|
* frame, 1 means there is following frame.
|
|
* @retval: NULL -- for failure case.
|
|
* @retval: pkt -- the iot pkt buffer for to the qsxj03.04.177-2021
|
|
* protocol message.
|
|
*/
|
|
iot_pkt_t *proto_qsxj_build_get_meter_info(uint8_t ver, uint8_t flag_follow);
|
|
|
|
/**
|
|
* @brief proto_qsxj_di_data_len_get - qsxj di data le get.
|
|
* @param di: qsxj protocol di.
|
|
* @param data_len: qsxj di data len, function output.
|
|
* @param fixed: 1 is di data len is fixed, function output.
|
|
* @retval: ERR_OK - data len get successfully.
|
|
* @retval: otherwise - error code. see ERR_XXX
|
|
*/
|
|
uint32_t proto_qsxj_di_data_len_get(uint16_t di, uint8_t *data_len,
|
|
uint8_t *fixed);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* PROTO_QSXJ_H */
|