/**************************************************************************** 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. ****************************************************************************/ /* os shim includes */ #include "os_types_api.h" #include "os_mem_api.h" /* common includes */ #include "iot_utils_api.h" #include "iot_errno_api.h" #include "iot_bitmap_api.h" /* smart grid internal includes */ #include "proto_crc16.h" #include "proto_1662.h" #define PROTO_1662_HDR_CHAR_LEN 3 const uint8_t proto_1662_hdr_char[PROTO_1662_HDR_CHAR_LEN] = { PROTO_1662_START_END_CHAR, PROTO_1662_ADDR_CHAR, PROTO_1662_CTRL_CHAR }; const uint8_t proto_1662_read_addr_msg[] = {0x7E, 0xFF, 0x03, 0x00, 0x22, 0x00, 0x03, 0xC0, 0x05, 0x80, 0xDF, 0xD7, 0x7E}; proto_1662_header_t *proto_1662_format_check(uint8_t *data, uint32_t len) { uint8_t *data_tmp = NULL; uint16_t fcs, fcs_len, info_len; uint32_t len_tmp, i, total_len; proto_1662_header_t *head; proto_1662_tailer_t *tail; for (i = 0, len_tmp = len; i < len; i++) { if (!os_mem_cmp(proto_1662_hdr_char, &data[i], PROTO_1662_HDR_CHAR_LEN)) { data_tmp = data + i; break; } len_tmp--; } if ((len_tmp < sizeof(*head)) || (data_tmp == NULL)) { goto drop; } head = (proto_1662_header_t *)data_tmp; info_len = iot_bytes_to_uint16(head->info_len, 1); total_len = sizeof(*head) + info_len - sizeof(head->cmd) + sizeof(*tail); if (len_tmp < total_len) { goto drop; } tail = (proto_1662_tailer_t*)(data_tmp + sizeof(*head) + info_len - sizeof(head->cmd)); fcs = tail->fcs[0]; fcs = (fcs << 8) + tail->fcs[1]; fcs_len = (uint16_t)(total_len - PROTO_1662_START_END_CHAR_LEN - PROTO_1662_FCS_LEN); if (fcs != proto_fcs16_get_check_sum(data_tmp + 1, fcs_len)) { goto drop; } goto out; drop: head = NULL; out: return head; } iot_pkt_t *proto_1662_build_ra_msg(void) { uint8_t *data; iot_pkt_t *pkt; pkt = iot_pkt_alloc(sizeof(proto_1662_read_addr_msg), IOT_SMART_GRID_MID); if (!pkt) return NULL; data = iot_pkt_put(pkt, sizeof(proto_1662_read_addr_msg)); os_mem_cpy(data, proto_1662_read_addr_msg, sizeof(proto_1662_read_addr_msg)); return pkt; } iot_pkt_t *proto_1662_build_trans_msg(uint8_t *data, uint16_t len) { uint8_t *data_tmp; uint16_t fcs, fcs_len, info_len; uint32_t total_len; iot_pkt_t *pkt; proto_1662_header_t *head; proto_1662_tailer_t *tail; total_len = sizeof(*head) + len + sizeof(*tail); pkt = iot_pkt_alloc(total_len, IOT_SMART_GRID_MID); if (!pkt) return NULL; data_tmp = iot_pkt_put(pkt, total_len); head = (proto_1662_header_t*)data_tmp; head->start_char = PROTO_1662_START_END_CHAR; head->addr = PROTO_1662_ADDR_CHAR; head->ctrl = PROTO_1662_CTRL_CHAR; head->rssi = PROTO_1662_DEF_RSSI; head->proto_type = PROTO_1662_PROTO_TRANS; info_len = len + sizeof(head->cmd); iot_uint16_to_bytes(info_len, head->info_len, 1); head->cmd = PROTO_1662_CMD_TRANS; os_mem_cpy(head->data, data, len); tail = (proto_1662_tailer_t*)(data_tmp + sizeof(*head) + len); fcs_len = (uint16_t)(total_len - PROTO_1662_START_END_CHAR_LEN - PROTO_1662_FCS_LEN); fcs = proto_fcs16_get_check_sum(data_tmp + 1, fcs_len); tail->fcs[0] = (uint8_t)(fcs >> 8); tail->fcs[1] = (uint8_t)fcs; tail->end_char = PROTO_1662_START_END_CHAR; return pkt; } uint8_t proto_1662_ascii_to_hex(uint8_t ascii) { uint8_t hex = PROTO_1662_HEX_INVALID; if ((ascii >= 0x30) && (ascii <= 0x39)) { hex = ascii - 0x30; } else if((ascii >= 0x41) && (ascii <= 0x46)) { hex = ascii - 0x37; } else if((ascii >= 0x61) && (ascii <= 0x66)) { hex = ascii - 0x57; } return hex; }