132 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			132 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/****************************************************************************
 | 
						|
 | 
						|
Copyright(c) 2024 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 ship includes */
 | 
						|
#include "os_mem_api.h"
 | 
						|
 | 
						|
/* common includes */
 | 
						|
#include "iot_config_api.h"
 | 
						|
#include "iot_errno_api.h"
 | 
						|
#include "iot_ntoh_api.h"
 | 
						|
 | 
						|
/* protocol includes */
 | 
						|
#include "proto_crc16.h"
 | 
						|
#include "proto_wapper.h"
 | 
						|
 | 
						|
/* smart grid internal header files */
 | 
						|
#include "iot_sg_fr.h"
 | 
						|
 | 
						|
proto_wapper_user_data_t *proto_wapper_user_data_check(uint8_t *data,
 | 
						|
    uint32_t len)
 | 
						|
{
 | 
						|
    uint32_t len_t, i = 0x0, data_len;
 | 
						|
    uint16_t id_domain;
 | 
						|
    uint8_t *data_s = NULL;
 | 
						|
    proto_wapper_user_data_t *user_data;
 | 
						|
 | 
						|
    if (!len) {
 | 
						|
        goto drop;
 | 
						|
    }
 | 
						|
    for (i = 0x0, len_t = len; i < len - 1; i++) {
 | 
						|
        id_domain = iot_bytes_to_uint16(data + i, 1);
 | 
						|
        if (id_domain == PROTO_WAPPER_ID_DOMAIN) {
 | 
						|
            data_s = data + i;
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        len_t--;
 | 
						|
    }
 | 
						|
    if (data_s == NULL || len_t < sizeof(*user_data)) {
 | 
						|
        goto drop;
 | 
						|
    }
 | 
						|
    user_data = (proto_wapper_user_data_t *)data_s;
 | 
						|
    data_len = iot_bytes_to_uint16(user_data->len, 1);
 | 
						|
    len_t -= (sizeof(user_data->id_domain) + sizeof(user_data->src_addr) +
 | 
						|
        sizeof(user_data->dest_addr) + sizeof(user_data->len));
 | 
						|
    if (data_len > len_t) {
 | 
						|
        goto drop;
 | 
						|
    }
 | 
						|
    goto out;
 | 
						|
drop:
 | 
						|
    data_s = NULL;
 | 
						|
out:
 | 
						|
    return (proto_wapper_user_data_t *)data_s;
 | 
						|
}
 | 
						|
 | 
						|
proto_wapper_head_t *proto_wapper_format_check(uint8_t *data, uint32_t len)
 | 
						|
{
 | 
						|
    proto_wapper_head_t *head;
 | 
						|
    uint32_t len_t, data_len, i = 0x0;
 | 
						|
    uint16_t info_len;
 | 
						|
    uint8_t *data_s = NULL;
 | 
						|
 | 
						|
    for (i = 0x0, len_t = len; i < len; i++) {
 | 
						|
        if (data[i] == PROTO_WAPPER_START_CHAR) {
 | 
						|
            data_s = data + i;
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        len_t--;
 | 
						|
    }
 | 
						|
    if (data_s == NULL || len_t < (sizeof(proto_wapper_head_t) +
 | 
						|
        sizeof(proto_wapper_tail_t))) {
 | 
						|
        goto drop;
 | 
						|
    }
 | 
						|
    head = (proto_wapper_head_t *)data_s;
 | 
						|
    /* Command len + User Data len + tail len */
 | 
						|
    info_len = iot_bytes_to_uint16(head->len, 1);
 | 
						|
    if (info_len < sizeof(head->cmd) + sizeof(proto_wapper_tail_t)) {
 | 
						|
        goto drop;
 | 
						|
    }
 | 
						|
    len_t -= (sizeof(*head) + sizeof(proto_wapper_tail_t));
 | 
						|
    data_len = info_len - sizeof(head->cmd) - sizeof(proto_wapper_tail_t);
 | 
						|
    if (data_len > len_t) {
 | 
						|
        goto drop;
 | 
						|
    }
 | 
						|
    if (!proto_wapper_user_data_check(head->user_data, data_len)) {
 | 
						|
        goto drop;
 | 
						|
    }
 | 
						|
    if (proto_fcs16_check(data_s + 1, PROTO_WAPPER_HEAD_LEN_NUM + info_len)) {
 | 
						|
        goto drop;
 | 
						|
    }
 | 
						|
    goto out;
 | 
						|
drop:
 | 
						|
    data_s = NULL;
 | 
						|
out:
 | 
						|
    return (proto_wapper_head_t *)data_s;
 | 
						|
}
 | 
						|
 | 
						|
iot_pkt_t *proto_wapper_format_build(uint8_t *user_data, uint32_t len,
 | 
						|
    uint8_t cmd)
 | 
						|
{
 | 
						|
    uint32_t total_len;
 | 
						|
    proto_wapper_head_t *head;
 | 
						|
    proto_wapper_tail_t *tail;
 | 
						|
    iot_pkt_t *pkt;
 | 
						|
 | 
						|
    total_len = sizeof(*head) + len + sizeof(*tail);
 | 
						|
    pkt = iot_pkt_alloc(total_len, IOT_SMART_GRID_MID);
 | 
						|
    if (!pkt) {
 | 
						|
        return NULL;
 | 
						|
    }
 | 
						|
    head = (proto_wapper_head_t *)iot_pkt_put(pkt, total_len);
 | 
						|
    head->start_char = PROTO_WAPPER_START_CHAR;
 | 
						|
    iot_uint16_to_bytes((uint16_t)(sizeof(head->cmd) + len +
 | 
						|
        sizeof(*tail)), head->len, 1);
 | 
						|
    head->cmd = cmd;
 | 
						|
    os_mem_cpy(head->user_data, user_data, len);
 | 
						|
    tail = (proto_wapper_tail_t *)(head->user_data + len);
 | 
						|
    tail->fcs = proto_fcs16_get_check_sum(iot_pkt_data(pkt) + 1,
 | 
						|
        (uint16_t)(total_len - sizeof(*tail) - sizeof(head->start_char)));
 | 
						|
    return pkt;
 | 
						|
} |