Files
kunlun/app/smart_grid/inc/proto_qsxj.h
2024-09-28 14:24:04 +08:00

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 */