160 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			160 lines
		
	
	
		
			5.4 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_DLMS_HDLC_H
							 | 
						||
| 
								 | 
							
								#define PROTO_DLMS_HDLC_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 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* default baud rate for GB/T 17215.646 */
							 | 
						||
| 
								 | 
							
								#define PROTO_DLMS_HDLC_DEFAULT_BAUD         9600
							 | 
						||
| 
								 | 
							
								#define PROTO_DLMS_HDLC_START_BYTE           0x7e
							 | 
						||
| 
								 | 
							
								#define PROTO_DLMS_HDLC_END_BYTE             0x7e
							 | 
						||
| 
								 | 
							
								#define PROTO_DLMS_HDLC_FRAME_HDLC           0x0a
							 | 
						||
| 
								 | 
							
								#define PROTO_DLMS_HDLC_START_END_LEN        (2)
							 | 
						||
| 
								 | 
							
								#define PROTO_DLMS_HDLC_CHECKSUM_LEN         (2)
							 | 
						||
| 
								 | 
							
								#define PROTO_DLMS_HDLC_ADD_TYPE_1           (1)
							 | 
						||
| 
								 | 
							
								#define PROTO_DLMS_HDLC_ADD_TYPE_2           (2)
							 | 
						||
| 
								 | 
							
								#define PROTO_DLMS_HDLC_ADD_TYPE_4           (4)
							 | 
						||
| 
								 | 
							
								#define PROTO_DLMS_HDLC_ADD_MAX_LEN          (2)
							 | 
						||
| 
								 | 
							
								#define PROTO_DLMS_HDLC_CTRL_LEN             (1)
							 | 
						||
| 
								 | 
							
								#define PROTO_DLMS_LLC_D_LSAP                0xe6
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								union proto_dlms_hdlc_format
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    struct {
							 | 
						||
| 
								 | 
							
								        /* frame length except start and end byte */
							 | 
						||
| 
								 | 
							
								        uint16_t len:       11,
							 | 
						||
| 
								 | 
							
								        /* segmentation of frame, rules of using the
							 | 
						||
| 
								 | 
							
								         * segmentation bit are defined in GB/T 17215.646
							 | 
						||
| 
								 | 
							
								         * 6.4.4.4.3.6.
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								                 seg:       1,
							 | 
						||
| 
								 | 
							
								        /* type of the frame, see PROTO_DLMS_HDLC_FRAME_HDLC */
							 | 
						||
| 
								 | 
							
								                 frame_type:4;
							 | 
						||
| 
								 | 
							
								    } bit;
							 | 
						||
| 
								 | 
							
								    uint16_t value;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* frame head info of DLMS HDLC protocol link layer frame */
							 | 
						||
| 
								 | 
							
								typedef struct _proto_dlms_hdlc_head {
							 | 
						||
| 
								 | 
							
								    /* start char, see PROTO_DLMS_HDLC_START_BYTE */
							 | 
						||
| 
								 | 
							
								    uint8_t                      start_char;
							 | 
						||
| 
								 | 
							
								    /* frame format */
							 | 
						||
| 
								 | 
							
								    union proto_dlms_hdlc_format frame_format;
							 | 
						||
| 
								 | 
							
								    /* server address and client address */
							 | 
						||
| 
								 | 
							
								    uint8_t                      sa_and_ca[0];
							 | 
						||
| 
								 | 
							
								} proto_dlms_hdlc_head_t;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* frame llc info of DLMS HDLC protocol link layer frame */
							 | 
						||
| 
								 | 
							
								typedef struct _proto_dlms_llc_info {
							 | 
						||
| 
								 | 
							
								    /* destination (remote) Lsap, see PROTO_DLMS_LLC_D_LSAP */
							 | 
						||
| 
								 | 
							
								    uint8_t dest_lsap;
							 | 
						||
| 
								 | 
							
								    /* source (local) Lsap */
							 | 
						||
| 
								 | 
							
								    uint8_t source_lsap;
							 | 
						||
| 
								 | 
							
								    /* the byte is reserved for future
							 | 
						||
| 
								 | 
							
								     * use and its value must always be 0x00
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    uint8_t reserved;
							 | 
						||
| 
								 | 
							
								    /* data */
							 | 
						||
| 
								 | 
							
								    uint8_t data[0];
							 | 
						||
| 
								 | 
							
								} proto_dlms_llc_info_t;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* frame tail info of DLMS HDLC protocol link layer frame */
							 | 
						||
| 
								 | 
							
								typedef struct _proto_dlms_hdlc_tailer {
							 | 
						||
| 
								 | 
							
								     /* check sum */
							 | 
						||
| 
								 | 
							
								     uint8_t     fcs[PROTO_DLMS_HDLC_CHECKSUM_LEN];
							 | 
						||
| 
								 | 
							
								     /* end char. see PROTO_DLMS_HDLC_END_BYTE */
							 | 
						||
| 
								 | 
							
								     uint8_t     end_char;
							 | 
						||
| 
								 | 
							
								} proto_dlms_hdlc_tailer_t;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* structure of DLMS HDLC link layer frame
							 | 
						||
| 
								 | 
							
								 -------------
							 | 
						||
| 
								 | 
							
								 |----7EH-------------|  start of frame, 0x7E.
							 | 
						||
| 
								 | 
							
								 |----frame_format----|  2 byte of frame format. Include length(11 bit),
							 | 
						||
| 
								 | 
							
								 |                    |  segmentation(1 bit) and frame type(4 bit).
							 | 
						||
| 
								 | 
							
								 |----Addr------------|  address field. Include Server address(1 byte or 2 byte
							 | 
						||
| 
								 | 
							
								 |                    |  or 4 byte) and Client address(1 byte).
							 | 
						||
| 
								 | 
							
								 |----Ctrl------------|  1 byte of control.
							 | 
						||
| 
								 | 
							
								 |----HCS-------------|  2 byte of frame header check
							 | 
						||
| 
								 | 
							
								 |----LLC-------------|  3 byte of LLC
							 | 
						||
| 
								 | 
							
								 |----Data------------|  APDU. length is variable
							 | 
						||
| 
								 | 
							
								 |----FCS-------------|  2 byte of frame
							 | 
						||
| 
								 | 
							
								 |----7EH-------------|  end of frame, 0x7E.
							 | 
						||
| 
								 | 
							
								 -------------
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#pragma pack(pop)   /* restore the pack status */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								typedef struct _proto_dlms_hdlc_addr {
							 | 
						||
| 
								 | 
							
								    /* type of address field */
							 | 
						||
| 
								 | 
							
								    uint8_t type;
							 | 
						||
| 
								 | 
							
								    /* length of address field */
							 | 
						||
| 
								 | 
							
								    uint8_t len;
							 | 
						||
| 
								 | 
							
								    /* Upper address */
							 | 
						||
| 
								 | 
							
								    uint16_t u_addr;
							 | 
						||
| 
								 | 
							
								    /* Lower address */
							 | 
						||
| 
								 | 
							
								    uint16_t l_addr;
							 | 
						||
| 
								 | 
							
								} proto_dlms_hdlc_addr_t;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								typedef struct _proto_dlms_hdlc_cache {
							 | 
						||
| 
								 | 
							
								    /* destination address info */
							 | 
						||
| 
								 | 
							
								    proto_dlms_hdlc_addr_t dest_addr;
							 | 
						||
| 
								 | 
							
								    /* source address info */
							 | 
						||
| 
								 | 
							
								    proto_dlms_hdlc_addr_t source_addr;
							 | 
						||
| 
								 | 
							
								    /* control of dlms_hdlc */
							 | 
						||
| 
								 | 
							
								    uint8_t                control;
							 | 
						||
| 
								 | 
							
								    /* pointer to data */
							 | 
						||
| 
								 | 
							
								    uint8_t                *data_ptr;
							 | 
						||
| 
								 | 
							
								    /* length of data */
							 | 
						||
| 
								 | 
							
								    uint16_t               data_len;
							 | 
						||
| 
								 | 
							
								} proto_dlms_hdlc_cache_t;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @brief proto_dlms_hdlc_parse - parse a dlms packet.
							 | 
						||
| 
								 | 
							
								 * @param data:       packet data
							 | 
						||
| 
								 | 
							
								 * @param len:        length of the packet data
							 | 
						||
| 
								 | 
							
								 * @param len:        pointer to cache buffer
							 | 
						||
| 
								 | 
							
								 * @retval:     NULL      -- parse protocol fail.
							 | 
						||
| 
								 | 
							
								 * @retval:     otherwise -- pointer to the dlms protocol header
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								proto_dlms_hdlc_head_t *proto_dlms_hdlc_parse(uint8_t* data,
							 | 
						||
| 
								 | 
							
								    uint16_t len, proto_dlms_hdlc_cache_t *cache);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @brief proto_dlms_hdlc_type_4_addr_to_bcd_addr - convert dlms 4 bytes dest
							 | 
						||
| 
								 | 
							
								 *                                                  addr to 6 byte bcd addr.
							 | 
						||
| 
								 | 
							
								 * @param addr:       6 byte bcd address.
							 | 
						||
| 
								 | 
							
								 * @param hdlc_addr:  pointer to cache buffer.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								void proto_dlms_hdlc_type_4_addr_to_bcd_addr(uint8_t *addr,
							 | 
						||
| 
								 | 
							
								    proto_dlms_hdlc_addr_t *hdlc_addr);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef __cplusplus
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif /* PROTO_DLMS_HDLC_H */
							 |