847 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			847 lines
		
	
	
		
			23 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.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								****************************************************************************/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "iot_pkt.h"
							 | 
						||
| 
								 | 
							
								#include "iot_mem_pool.h"
							 | 
						||
| 
								 | 
							
								#include "iot_module.h"
							 | 
						||
| 
								 | 
							
								#include "iot_errno.h"
							 | 
						||
| 
								 | 
							
								#include "iot_dbglog_api.h"
							 | 
						||
| 
								 | 
							
								#include "iot_dbglog.h"
							 | 
						||
| 
								 | 
							
								#include "iot_config.h"
							 | 
						||
| 
								 | 
							
								#include "iot_io.h"
							 | 
						||
| 
								 | 
							
								#include "iot_system_api.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								typedef struct _iot_pkt_global {
							 | 
						||
| 
								 | 
							
								    uint32_t pool_cnt : 16,
							 | 
						||
| 
								 | 
							
								        req_cnt : 16;
							 | 
						||
| 
								 | 
							
								    iot_pkt_config_t config;
							 | 
						||
| 
								 | 
							
								    iot_mem_pool_t *pool[IOT_PKT_POOL_MAX];
							 | 
						||
| 
								 | 
							
								#if DEBUG_PKT_OVERWRITE
							 | 
						||
| 
								 | 
							
								    os_mutex_h mutex;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								#if PLC_MEM_ALLOC_STAT > 1
							 | 
						||
| 
								 | 
							
								    uint16_t efficiency[IOT_PKT_POOL_MAX];
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								#if IOT_PKT_FREE_CALLBACK_ENABLE
							 | 
						||
| 
								 | 
							
								    os_mutex_h free_callback_lock;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								} iot_pkt_global_t;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static iot_pkt_global_t *p_pkt_glb = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static inline void __iot_pkt_reset(iot_pkt_t* buf, uint32_t size)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    buf->head = (uint8_t*)buf + sizeof(iot_pkt_t);
							 | 
						||
| 
								 | 
							
								    buf->data = buf->head;
							 | 
						||
| 
								 | 
							
								    buf->tail = buf->head;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    buf->end = buf->head + size;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if IOT_PKT_FREE_CALLBACK_ENABLE
							 | 
						||
| 
								 | 
							
								    iot_list_head_t *entry;
							 | 
						||
| 
								 | 
							
								    entry = (iot_list_head_t *)&(buf->entry);
							 | 
						||
| 
								 | 
							
								    iot_list_init(entry);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    buf->free_func = NULL;
							 | 
						||
| 
								 | 
							
								    buf->param = NULL;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if IOT_PKT_INFO_DUMP_DEBUG
							 | 
						||
| 
								 | 
							
								void iot_pkt_dump_info(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t toltal_cnt, buf_size, free_cnt, i;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for (i = 0; i < p_pkt_glb->pool_cnt; i++) {
							 | 
						||
| 
								 | 
							
								        toltal_cnt = p_pkt_glb->config.pool_cfg[i].count;
							 | 
						||
| 
								 | 
							
								        buf_size = p_pkt_glb->config.pool_cfg[i].size;
							 | 
						||
| 
								 | 
							
								        free_cnt = iot_mem_pool_get_freenum(p_pkt_glb->pool[i]);
							 | 
						||
| 
								 | 
							
								        iot_printf("PKT:%d-%d/%d. ", buf_size, free_cnt, toltal_cnt);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    iot_printf("\n");
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* according to MID, get the pool owner mask */
							 | 
						||
| 
								 | 
							
								static inline uint32_t iot_pkt_get_target_owner(module_id_t module_id)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t owner = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (IOT_CLI_MID == module_id)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        owner= PKT_OWNER_IOT;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else if ((module_id >= PLC_MID_BASE) && (module_id < NB_MID_BASE))
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        owner = PKT_OWNER_PLC;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else if ((module_id >= NB_MID_BASE) && (module_id < OS_RISCV_BASE))
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        owner = PKT_OWNER_NB;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        owner = PKT_OWNER_PLC;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return owner;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void iot_pkt_init(const iot_pkt_config_t *cfg)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint16_t size, count;
							 | 
						||
| 
								 | 
							
								    uint32_t i, j, owner;
							 | 
						||
| 
								 | 
							
								    iot_mem_pool_t *tmp_pool;
							 | 
						||
| 
								 | 
							
								    iot_pkt_config_t *config;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    p_pkt_glb = os_mem_malloc(IOT_PKT_MID, sizeof(*p_pkt_glb));
							 | 
						||
| 
								 | 
							
								    IOT_ASSERT(p_pkt_glb);
							 | 
						||
| 
								 | 
							
								#if DEBUG_PKT_OVERWRITE
							 | 
						||
| 
								 | 
							
								    if (NULL == (p_pkt_glb->mutex = os_create_mutex(IOT_PKT_MID))) {
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if IOT_PKT_FREE_CALLBACK_ENABLE
							 | 
						||
| 
								 | 
							
								    if (NULL ==
							 | 
						||
| 
								 | 
							
								        (p_pkt_glb->free_callback_lock = os_create_mutex(IOT_PKT_MID))) {
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								    config = &p_pkt_glb->config;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for (i = 0; i < IOT_PKT_POOL_MAX; i++) {
							 | 
						||
| 
								 | 
							
								        if (cfg->pool_cfg[i].count == 0)
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        config->pool_cfg[i].size = cfg->pool_cfg[i].size;
							 | 
						||
| 
								 | 
							
								        config->pool_cfg[i].count = cfg->pool_cfg[i].count;
							 | 
						||
| 
								 | 
							
								        config->pool_cfg[i].owner = cfg->pool_cfg[i].owner;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    p_pkt_glb->pool_cnt = i;
							 | 
						||
| 
								 | 
							
								    IOT_ASSERT(p_pkt_glb->pool_cnt);
							 | 
						||
| 
								 | 
							
								    p_pkt_glb->req_cnt = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for (i = 0; i < p_pkt_glb->pool_cnt; i++) {
							 | 
						||
| 
								 | 
							
								        if (config->pool_cfg[i].count) {
							 | 
						||
| 
								 | 
							
								            iot_mem_pool_new(IOT_PKT_MID, config->pool_cfg[i].count,
							 | 
						||
| 
								 | 
							
								                 sizeof(iot_pkt_t) + config->pool_cfg[i].size,
							 | 
						||
| 
								 | 
							
								                 &p_pkt_glb->pool[i], 1);
							 | 
						||
| 
								 | 
							
								            IOT_ASSERT(p_pkt_glb->pool[i]);
							 | 
						||
| 
								 | 
							
								#if PLC_MEM_ALLOC_STAT
							 | 
						||
| 
								 | 
							
								            iot_printf("data buf: %d, num %d x size %d = %d bytes, owner = 0x%X, "
							 | 
						||
| 
								 | 
							
								                    "@0x%x, align_size:%d\n", \
							 | 
						||
| 
								 | 
							
								            i, config->pool_cfg[i].count, \
							 | 
						||
| 
								 | 
							
								                sizeof(iot_pkt_t) + config->pool_cfg[i].size,
							 | 
						||
| 
								 | 
							
								                config->pool_cfg[i].count * \
							 | 
						||
| 
								 | 
							
								                (sizeof(iot_pkt_t) + config->pool_cfg[i].size),
							 | 
						||
| 
								 | 
							
								                config->pool_cfg[i].owner, p_pkt_glb->pool[i],\
							 | 
						||
| 
								 | 
							
								                iot_mem_pool_get_align_size(p_pkt_glb->pool[i]));
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* sort the pkt size pool from least to largest */
							 | 
						||
| 
								 | 
							
								    for (i = 0; i < p_pkt_glb->pool_cnt; i++) {
							 | 
						||
| 
								 | 
							
								        for (j = i + 1; j < p_pkt_glb->pool_cnt; j++) {
							 | 
						||
| 
								 | 
							
								            if (config->pool_cfg[i].size > config->pool_cfg[j].size) {
							 | 
						||
| 
								 | 
							
								                size = config->pool_cfg[i].size;
							 | 
						||
| 
								 | 
							
								                count = config->pool_cfg[i].count;
							 | 
						||
| 
								 | 
							
								                owner = config->pool_cfg[i].owner;
							 | 
						||
| 
								 | 
							
								                tmp_pool = p_pkt_glb->pool[i];
							 | 
						||
| 
								 | 
							
								                config->pool_cfg[i].size = config->pool_cfg[j].size;
							 | 
						||
| 
								 | 
							
								                config->pool_cfg[i].count = config->pool_cfg[j].count;
							 | 
						||
| 
								 | 
							
								                config->pool_cfg[i].owner = config->pool_cfg[j].owner;
							 | 
						||
| 
								 | 
							
								                p_pkt_glb->pool[i] = p_pkt_glb->pool[j];
							 | 
						||
| 
								 | 
							
								                config->pool_cfg[j].size = size;
							 | 
						||
| 
								 | 
							
								                config->pool_cfg[j].count = count;
							 | 
						||
| 
								 | 
							
								                config->pool_cfg[j].owner = owner;
							 | 
						||
| 
								 | 
							
								                p_pkt_glb->pool[j] = tmp_pool;
							 | 
						||
| 
								 | 
							
								            } else if (config->pool_cfg[i].size == config->pool_cfg[j].size) {
							 | 
						||
| 
								 | 
							
								                IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if IOT_PKT_DEBUG
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								iot_pkt_t* iot_pkt_mem_alloc(uint32_t size, module_id_t module_id,
							 | 
						||
| 
								 | 
							
								    uint8_t init_mem, const char *file_name, uint32_t line_num)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t i, n, next, module_owner;
							 | 
						||
| 
								 | 
							
								    iot_pkt_t* result = NULL;
							 | 
						||
| 
								 | 
							
								    iot_pkt_t* printf_buf = NULL;
							 | 
						||
| 
								 | 
							
								    iot_mem_pool_entry_t* p_entry = NULL;
							 | 
						||
| 
								 | 
							
								    if (size == 0) {
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    module_owner = iot_pkt_get_target_owner(module_id);
							 | 
						||
| 
								 | 
							
								    for (i = 0; i < p_pkt_glb->pool_cnt; i++) {
							 | 
						||
| 
								 | 
							
								        if (size <= p_pkt_glb->config.pool_cfg[i].size) {
							 | 
						||
| 
								 | 
							
								            if (p_pkt_glb->config.pool_cfg[i].owner & module_owner)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                result = iot_mem_pool_alloc(p_pkt_glb->pool[i]);
							 | 
						||
| 
								 | 
							
								                if (result) {
							 | 
						||
| 
								 | 
							
								                    result->file_name = file_name;
							 | 
						||
| 
								 | 
							
								                    result->line_num = line_num;
							 | 
						||
| 
								 | 
							
								                    __iot_pkt_reset(result, p_pkt_glb->config.pool_cfg[i].size);
							 | 
						||
| 
								 | 
							
								                    if (init_mem) {
							 | 
						||
| 
								 | 
							
								                        os_mem_set(result->head, 0,
							 | 
						||
| 
								 | 
							
								                            (result->end - result->head));
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                    goto out;
							 | 
						||
| 
								 | 
							
								                } else {
							 | 
						||
| 
								 | 
							
								                    iot_printf("%s in Line %d ----buf_size:%d, pool_size:%d, "
							 | 
						||
| 
								 | 
							
								                        "this pool use up\n", file_name, line_num, size,
							 | 
						||
| 
								 | 
							
								                        p_pkt_glb->config.pool_cfg[i].size);
							 | 
						||
| 
								 | 
							
								                    p_entry = p_pkt_glb->pool[i]->entries;
							 | 
						||
| 
								 | 
							
								                    next = p_pkt_glb->pool[i]->align_block_word_size;
							 | 
						||
| 
								 | 
							
								                    if (p_entry != NULL) {
							 | 
						||
| 
								 | 
							
								                        for (n = 0; n < p_pkt_glb->pool[i]->num; n++) {
							 | 
						||
| 
								 | 
							
								                            printf_buf = (iot_pkt_t*)p_entry;
							 | 
						||
| 
								 | 
							
								                            iot_printf("%s in Line %d ----pool_size:%d, "
							 | 
						||
| 
								 | 
							
								                                "addr = [0x%08X]\n", printf_buf->file_name,
							 | 
						||
| 
								 | 
							
								                                printf_buf->line_num,
							 | 
						||
| 
								 | 
							
								                                p_pkt_glb->config.pool_cfg[i].size, printf_buf);
							 | 
						||
| 
								 | 
							
								                            p_entry = p_entry + next;
							 | 
						||
| 
								 | 
							
								                        }
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    return result;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#else /* IOT_PKT_DEBUG */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								iot_pkt_t* iot_pkt_mem_alloc(uint32_t size, module_id_t module_id,
							 | 
						||
| 
								 | 
							
								    uint8_t init_mem)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t i = 0, module_owner;
							 | 
						||
| 
								 | 
							
								    iot_pkt_t* result = NULL;
							 | 
						||
| 
								 | 
							
								#if DEBUG_PKT_OVERWRITE
							 | 
						||
| 
								 | 
							
								    uint32_t ast_ra = 0;
							 | 
						||
| 
								 | 
							
								    RISC_GET_REG_RA(ast_ra);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (size == 0) {
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    module_owner = iot_pkt_get_target_owner(module_id);
							 | 
						||
| 
								 | 
							
								    for (i = 0; i < p_pkt_glb->pool_cnt; i++) {
							 | 
						||
| 
								 | 
							
								        if (size <= p_pkt_glb->config.pool_cfg[i].size) {
							 | 
						||
| 
								 | 
							
								            if ( p_pkt_glb->config.pool_cfg[i].owner & module_owner) {
							 | 
						||
| 
								 | 
							
								                result = iot_mem_pool_alloc(p_pkt_glb->pool[i]);
							 | 
						||
| 
								 | 
							
								                if (result) {
							 | 
						||
| 
								 | 
							
								                    __iot_pkt_reset(result,
							 | 
						||
| 
								 | 
							
								                        p_pkt_glb->config.pool_cfg[i].size);
							 | 
						||
| 
								 | 
							
								#if DEBUG_PKT_OVERWRITE
							 | 
						||
| 
								 | 
							
								                    iot_printf("pkt_alloc:@%x,ra:0x%x\n", \
							 | 
						||
| 
								 | 
							
								                        (uint32_t)result, ast_ra);
							 | 
						||
| 
								 | 
							
								                    os_acquire_mutex(p_pkt_glb->mutex);
							 | 
						||
| 
								 | 
							
								                    iot_pkt_check_end_overwrite(result);
							 | 
						||
| 
								 | 
							
								                    os_release_mutex(p_pkt_glb->mutex);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								                    if (init_mem) {
							 | 
						||
| 
								 | 
							
								                        os_mem_set(result->head, 0,
							 | 
						||
| 
								 | 
							
								                            (result->end - result->head));
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								#if PLC_MEM_ALLOC_STAT > 1
							 | 
						||
| 
								 | 
							
								                    /* 1/8 avg efficiency contribution for this time */
							 | 
						||
| 
								 | 
							
								                    p_pkt_glb->efficiency[i] = \
							 | 
						||
| 
								 | 
							
								                        (p_pkt_glb->efficiency[i] - \
							 | 
						||
| 
								 | 
							
								                            (p_pkt_glb->efficiency[i] >> 3)) + \
							 | 
						||
| 
								 | 
							
								                            ((size & 0xffff) >> 3);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								                    goto out;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								#if PLC_MEM_ALLOC_STAT > 1
							 | 
						||
| 
								 | 
							
								    if ((++p_pkt_glb->req_cnt & IOTPKT_STAT_DISPLAY_FREQ) \
							 | 
						||
| 
								 | 
							
								        == IOTPKT_STAT_DISPLAY_FREQ)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        for (i = 0; i < p_pkt_glb->pool_cnt; i++) {
							 | 
						||
| 
								 | 
							
								            iot_printf("pu%dpm%d/%d:e%d/%d;",
							 | 
						||
| 
								 | 
							
								            p_pkt_glb->pool[i]->num - p_pkt_glb->pool[i]->free_num,
							 | 
						||
| 
								 | 
							
								            p_pkt_glb->pool[i]->max_num,
							 | 
						||
| 
								 | 
							
								            p_pkt_glb->pool[i]->num, p_pkt_glb->efficiency[i],
							 | 
						||
| 
								 | 
							
								            (p_pkt_glb->pool[i]->align_block_word_size << 2));
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        iot_printf("\n");
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								    return result;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif /* IOT_PKT_DEBUG */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t iot_pkt_set_free_callback(iot_pkt_t *buf,
							 | 
						||
| 
								 | 
							
								    iot_pkt_free_func_t free_callback, void *param)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								#if IOT_PKT_FREE_CALLBACK_ENABLE
							 | 
						||
| 
								 | 
							
								    if (buf) {
							 | 
						||
| 
								 | 
							
								        buf->free_func = free_callback;
							 | 
						||
| 
								 | 
							
								        buf->param = param;
							 | 
						||
| 
								 | 
							
								        return ERR_OK;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								    (void)buf;
							 | 
						||
| 
								 | 
							
								    (void)free_callback;
							 | 
						||
| 
								 | 
							
								    (void)param;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								    return ERR_FAIL;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void iot_pkt_get_free_callback(iot_pkt_t *buf,
							 | 
						||
| 
								 | 
							
								    iot_pkt_free_func_t *free_callback, void **param)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if IOT_PKT_FREE_CALLBACK_ENABLE
							 | 
						||
| 
								 | 
							
								    if (buf && buf->free_func) {
							 | 
						||
| 
								 | 
							
								        *free_callback = buf->free_func;
							 | 
						||
| 
								 | 
							
								        *param = buf->param;
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								    (void)buf;
							 | 
						||
| 
								 | 
							
								    *free_callback = NULL;
							 | 
						||
| 
								 | 
							
								    *param = NULL;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_pkt_exe_free_callback(iot_pkt_t *buf, uint8_t state)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								#if IOT_PKT_FREE_CALLBACK_ENABLE
							 | 
						||
| 
								 | 
							
								    uint32_t ret;
							 | 
						||
| 
								 | 
							
								    iot_list_head_t *entry = (iot_list_head_t *)&(buf->entry);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    os_acquire_mutex(p_pkt_glb->free_callback_lock);
							 | 
						||
| 
								 | 
							
								    ret = iot_list_empty(entry);
							 | 
						||
| 
								 | 
							
								    if (!ret) {
							 | 
						||
| 
								 | 
							
								        iot_list_del(entry);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    os_release_mutex(p_pkt_glb->free_callback_lock);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (ret && buf->free_func) {
							 | 
						||
| 
								 | 
							
								        buf->free_func(buf->param, state);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								    (void)buf;
							 | 
						||
| 
								 | 
							
								    (void)state;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void iot_pkt_free(iot_pkt_t* buf)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_pkt_free_tx_done(buf, IOT_PKT_STATE_UNKNOWN);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void iot_pkt_free_tx_done(iot_pkt_t* buf, uint8_t state)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t i, buf_len;
							 | 
						||
| 
								 | 
							
								#if DEBUG_PKT_OVERWRITE
							 | 
						||
| 
								 | 
							
								    uint32_t ast_ra = 0;
							 | 
						||
| 
								 | 
							
								    RISC_GET_REG_RA(ast_ra);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (buf == NULL) {
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    buf_len = iot_pkt_block_len(buf, IOT_PKT_BLOCK_ALL);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for (i = 0; i < p_pkt_glb->pool_cnt; i++) {
							 | 
						||
| 
								 | 
							
								        if (buf_len == p_pkt_glb->config.pool_cfg[i].size) {
							 | 
						||
| 
								 | 
							
								            iot_pkt_exe_free_callback(buf, state);
							 | 
						||
| 
								 | 
							
								#if DEBUG_PKT_OVERWRITE
							 | 
						||
| 
								 | 
							
								            iot_printf("pkt_free@%x,ra:0x%x\n", (uint32_t)buf, ast_ra);
							 | 
						||
| 
								 | 
							
								            os_acquire_mutex(p_pkt_glb->mutex);
							 | 
						||
| 
								 | 
							
								            iot_pkt_check_end_overwrite(buf);
							 | 
						||
| 
								 | 
							
								            /* init the tail and end value for debug. */
							 | 
						||
| 
								 | 
							
								            buf->tail = NULL;
							 | 
						||
| 
								 | 
							
								            buf->end = NULL;
							 | 
						||
| 
								 | 
							
								            iot_mem_pool_free(p_pkt_glb->pool[i], buf);
							 | 
						||
| 
								 | 
							
								            os_release_mutex(p_pkt_glb->mutex);
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								            iot_mem_pool_free(p_pkt_glb->pool[i], buf);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (i >= p_pkt_glb->pool_cnt) {
							 | 
						||
| 
								 | 
							
								        uint32_t ret;
							 | 
						||
| 
								 | 
							
								        /* buffer corrupted */
							 | 
						||
| 
								 | 
							
								        iot_printf("pkt 0x%x not found with len %d\n", buf, buf_len);
							 | 
						||
| 
								 | 
							
								        iot_pkt_exe_free_callback(buf, state);
							 | 
						||
| 
								 | 
							
								        for (i = 0; i < p_pkt_glb->pool_cnt; i++) {
							 | 
						||
| 
								 | 
							
								            ret = iot_mem_pool_force_free(p_pkt_glb->pool[i], buf);
							 | 
						||
| 
								 | 
							
								            if (ret == ERR_OK) {
							 | 
						||
| 
								 | 
							
								                goto out;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    return;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint8_t** iot_pkt_dataptr_addr(iot_pkt_t* buf)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (buf) {
							 | 
						||
| 
								 | 
							
								        return (&buf->data);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return NULL;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint8_t* iot_pkt_reserve(iot_pkt_t* buf, uint32_t size)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (buf->data == (uint8_t*)IOT_MEM_POOL_POISON) {
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (buf && buf->tail + size <= buf->end) {
							 | 
						||
| 
								 | 
							
								        buf->data += size;
							 | 
						||
| 
								 | 
							
								        buf->tail += size;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return buf->data;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								    return NULL;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint8_t* iot_pkt_put(iot_pkt_t* buf, uint32_t size)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (buf->data == (uint8_t*)IOT_MEM_POOL_POISON) {
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (buf && buf->tail + size <= buf->end) {
							 | 
						||
| 
								 | 
							
								        buf->tail += size;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return buf->data;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return NULL;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint8_t* iot_pkt_shrink(iot_pkt_t* buf, uint32_t size)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (buf->data == (uint8_t*)IOT_MEM_POOL_POISON) {
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (buf && buf->tail - size >= buf->data) {
							 | 
						||
| 
								 | 
							
								        buf->tail -= size;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return buf->data;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return NULL;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint8_t* iot_pkt_push(iot_pkt_t* buf, uint32_t size)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (buf->data == (uint8_t*)IOT_MEM_POOL_POISON) {
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (buf && buf->data - size >= buf->head) {
							 | 
						||
| 
								 | 
							
								        buf->data -= size;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return buf->data;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return NULL;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint8_t* iot_pkt_pull(iot_pkt_t* buf, uint32_t size)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (buf->data == (uint8_t*)IOT_MEM_POOL_POISON) {
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (buf && buf->data + size <= buf->tail) {
							 | 
						||
| 
								 | 
							
								        buf->data += size;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return buf->data;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return NULL;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint8_t* IRAM_ATTR iot_pkt_set_data(iot_pkt_t* buf, void* new_data)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (buf->data == (uint8_t*)IOT_MEM_POOL_POISON) {
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (buf && (uint8_t*)new_data >= buf->head
							 | 
						||
| 
								 | 
							
								        && (uint8_t*)new_data <= buf->tail) {
							 | 
						||
| 
								 | 
							
								        buf->data = (uint8_t*)new_data;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return buf->data;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return NULL;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint8_t* IRAM_ATTR iot_pkt_set_tail(iot_pkt_t* buf, void* new_tail)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (buf->data == (uint8_t*)IOT_MEM_POOL_POISON) {
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (buf && (uint8_t*)new_tail >= buf->data
							 | 
						||
| 
								 | 
							
								                && (uint8_t*)new_tail <= buf->end) {
							 | 
						||
| 
								 | 
							
								        buf->tail = (uint8_t*)new_tail;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return buf->data;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return NULL;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint8_t* IRAM_ATTR iot_pkt_block_ptr(iot_pkt_t* buf, uint8_t block_type)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (buf == NULL) {
							 | 
						||
| 
								 | 
							
								        return 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    void* result = NULL;
							 | 
						||
| 
								 | 
							
								    switch (block_type)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								    case IOT_PKT_BLOCK_ALL:
							 | 
						||
| 
								 | 
							
								    case IOT_PKT_BLOCK_HEAD:
							 | 
						||
| 
								 | 
							
								        result = buf->head;
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    case IOT_PKT_BLOCK_DATA:
							 | 
						||
| 
								 | 
							
								        result = buf->data;
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    case IOT_PKT_BLOCK_TAIL:
							 | 
						||
| 
								 | 
							
								        result = buf->tail;
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    case IOT_PKT_BLOCK_END:
							 | 
						||
| 
								 | 
							
								        result = buf->end;
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    default:
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return result;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t IRAM_ATTR iot_pkt_block_len(iot_pkt_t* buf, uint8_t block_type)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (buf == NULL) {
							 | 
						||
| 
								 | 
							
								        return 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    uint32_t len = 0;
							 | 
						||
| 
								 | 
							
								    switch (block_type)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								    case IOT_PKT_BLOCK_ALL:
							 | 
						||
| 
								 | 
							
								        len = buf->end - buf->head;
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    case IOT_PKT_BLOCK_HEAD:
							 | 
						||
| 
								 | 
							
								        len = buf->data - buf->head;
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    case IOT_PKT_BLOCK_DATA:
							 | 
						||
| 
								 | 
							
								        len = buf->tail - buf->data;
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    case IOT_PKT_BLOCK_TAIL:
							 | 
						||
| 
								 | 
							
								        len = buf->end - buf->tail;
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    default:
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return len;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void iot_pkt_reset(iot_pkt_t *buf)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    os_mem_set(buf->head, 0, (buf->end - buf->head));
							 | 
						||
| 
								 | 
							
								    buf->data = buf->tail = buf->head;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void iot_pkt_cpy(iot_pkt_t *dst, iot_pkt_t *src)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if ((dst->end - dst->head) < (src->tail - src->head)) {
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        dst->data = dst->head + (src->data - src->head);
							 | 
						||
| 
								 | 
							
								        dst->tail = dst->data + (src->tail - src->data);
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(dst->data, src->data, (src->tail - src->data));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if IOT_PKT_FREE_CALLBACK_ENABLE
							 | 
						||
| 
								 | 
							
								        iot_list_head_t *src_entry, *dst_entry;
							 | 
						||
| 
								 | 
							
								        src_entry = (iot_list_head_t *)&(src->entry);
							 | 
						||
| 
								 | 
							
								        dst_entry = (iot_list_head_t *)&(dst->entry);
							 | 
						||
| 
								 | 
							
								        os_acquire_mutex(p_pkt_glb->free_callback_lock);
							 | 
						||
| 
								 | 
							
								        iot_list_add(dst_entry, src_entry);
							 | 
						||
| 
								 | 
							
								        os_release_mutex(p_pkt_glb->free_callback_lock);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (src->free_func) {
							 | 
						||
| 
								 | 
							
								            dst->free_func = src->free_func;
							 | 
						||
| 
								 | 
							
								            dst->param = src->param;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void iot_pkt_cpy_with_head(iot_pkt_t *dst, iot_pkt_t *src)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_pkt_cpy(dst, src);
							 | 
						||
| 
								 | 
							
								    os_mem_cpy(dst->head, src->head, (src->data - src->head));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t iot_pkt_list_block_data_len(iot_pkt_ls *pkt_list)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t toltal_len = 0;
							 | 
						||
| 
								 | 
							
								    iot_pkt_ls *lst = pkt_list;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    while(lst)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if(lst->pkt)
							 | 
						||
| 
								 | 
							
								            toltal_len += iot_pkt_block_len(lst->pkt, IOT_PKT_BLOCK_DATA);
							 | 
						||
| 
								 | 
							
								        lst = lst->next;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return toltal_len;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t iot_pkt_list_item_count(iot_pkt_ls *pkt_list)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t cnt = 0;
							 | 
						||
| 
								 | 
							
								    iot_pkt_ls *lst = pkt_list;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    while(lst)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        cnt ++;
							 | 
						||
| 
								 | 
							
								        lst = lst->next;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return cnt;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void iot_pkt_list_free_every_pkt_mem(iot_pkt_ls *pkt_list)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_pkt_ls *lst = pkt_list;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    while(lst)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if(lst->pkt)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            iot_pkt_free(lst->pkt);
							 | 
						||
| 
								 | 
							
								            lst->pkt = NULL;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t iot_pkt_pktpool_status(uint8_t pool_idx, uint32_t* bufsz, \
							 | 
						||
| 
								 | 
							
								    uint32_t* freenum, uint32_t* totalnum)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if ((pool_idx >= IOT_PKT_POOL_MAX) || (bufsz == NULL) ||
							 | 
						||
| 
								 | 
							
								        (freenum == NULL) || (totalnum == NULL))
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								           return ERR_INVAL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    *bufsz =  p_pkt_glb->config.pool_cfg[pool_idx].size;
							 | 
						||
| 
								 | 
							
								    *freenum = iot_mem_pool_get_freenum(p_pkt_glb->pool[pool_idx]);
							 | 
						||
| 
								 | 
							
								    *totalnum = p_pkt_glb->config.pool_cfg[pool_idx].count;
							 | 
						||
| 
								 | 
							
								    return ERR_OK;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void mem_dump(uint32_t *word_ptr, uint32_t word_cnt)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    for (uint32_t j = 0; j < (word_cnt >> 2); j++) {
							 | 
						||
| 
								 | 
							
								        iot_printf("0x%08x:", word_ptr + (j << 2));
							 | 
						||
| 
								 | 
							
								        for (uint32_t i = 0; i < 4; i++)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            iot_printf("0x%08x ", *(word_ptr + (j << 2) + i));
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        iot_printf("\n");
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void mem_dump_byte(uint8_t *byte_ptr, uint32_t byte_cnt)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t i, j;
							 | 
						||
| 
								 | 
							
								    for (i = 0; i < byte_cnt; ) {
							 | 
						||
| 
								 | 
							
								        iot_printf("0x%08x:", (uint32_t)byte_ptr + i);
							 | 
						||
| 
								 | 
							
								        for (j = 0; j < 8; j++) {
							 | 
						||
| 
								 | 
							
								            if ((i + j) >= byte_cnt) {
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            iot_printf("0x%02x ", byte_ptr[i + j]);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        iot_printf("\n");
							 | 
						||
| 
								 | 
							
								        i += j;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t iot_pkt_validation(iot_pkt_t *pkt)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (!iot_data_addr_legal(
							 | 
						||
| 
								 | 
							
								             (uint32_t) iot_pkt_block_ptr(pkt,
							 | 
						||
| 
								 | 
							
								                 IOT_PKT_BLOCK_HEAD))
							 | 
						||
| 
								 | 
							
								        || !iot_data_addr_legal(
							 | 
						||
| 
								 | 
							
								             (uint32_t) iot_pkt_block_ptr(pkt,
							 | 
						||
| 
								 | 
							
								                 IOT_PKT_BLOCK_DATA))
							 | 
						||
| 
								 | 
							
								        || !iot_data_addr_legal(
							 | 
						||
| 
								 | 
							
								             (uint32_t) iot_pkt_block_ptr(pkt,
							 | 
						||
| 
								 | 
							
								                 IOT_PKT_BLOCK_TAIL))
							 | 
						||
| 
								 | 
							
								        || !iot_data_addr_legal(
							 | 
						||
| 
								 | 
							
								             (uint32_t) iot_pkt_block_ptr(pkt,
							 | 
						||
| 
								 | 
							
								                 IOT_PKT_BLOCK_END)))
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        iot_printf("iot_pkt overwrite found @0x%x, "
							 | 
						||
| 
								 | 
							
								            "4 pointers' are: 0x%x, 0x%x, 0x%x, 0x%x\n",
							 | 
						||
| 
								 | 
							
								            pkt,
							 | 
						||
| 
								 | 
							
								            iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_HEAD),
							 | 
						||
| 
								 | 
							
								            iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_DATA),
							 | 
						||
| 
								 | 
							
								            iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_TAIL),
							 | 
						||
| 
								 | 
							
								            iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_END));
							 | 
						||
| 
								 | 
							
								        iot_dbglog_input(PLC_MAC_RX_HW_MID, DBGLOG_ERR,
							 | 
						||
| 
								 | 
							
								            IOT_MAC_RX_OVERWRITE_ID, 5, pkt,
							 | 
						||
| 
								 | 
							
								            iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_HEAD),
							 | 
						||
| 
								 | 
							
								            iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_DATA),
							 | 
						||
| 
								 | 
							
								            iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_TAIL),
							 | 
						||
| 
								 | 
							
								            iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_END));
							 | 
						||
| 
								 | 
							
								        return ERR_INVAL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return ERR_OK;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if DEBUG_PKT_OVERWRITE
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t iot_pkt_check_end_overwrite(iot_pkt_t *buf)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t align_size = 0;
							 | 
						||
| 
								 | 
							
								    uint32_t pool_num, size, count;
							 | 
						||
| 
								 | 
							
								    uint32_t head_addr, data_addr, tail_addr, end_addr;
							 | 
						||
| 
								 | 
							
								    uint32_t last_pkt_addr;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (!buf) {
							 | 
						||
| 
								 | 
							
								        iot_printf("pkt_check invalid\n");
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								        return ERR_INVAL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    size = iot_pkt_block_len(buf, IOT_PKT_BLOCK_ALL);
							 | 
						||
| 
								 | 
							
								    for (pool_num = 0; pool_num < p_pkt_glb->pool_cnt; ) {
							 | 
						||
| 
								 | 
							
								        if (size == p_pkt_glb->config.pool_cfg[pool_num].size) {
							 | 
						||
| 
								 | 
							
								            align_size = iot_mem_pool_get_align_size(p_pkt_glb->pool[pool_num]);
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        ++pool_num;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (align_size == 0) {
							 | 
						||
| 
								 | 
							
								        iot_printf("pkt_check not found pool\n");
							 | 
						||
| 
								 | 
							
								        return ERR_INVAL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* calculation the actual next pkt */
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *pkt = (iot_pkt_t *)((uint32_t)buf + align_size);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    size = iot_mem_pool_get_align_size(p_pkt_glb->pool[pool_num]);
							 | 
						||
| 
								 | 
							
								    count = p_pkt_glb->config.pool_cfg[pool_num].count;
							 | 
						||
| 
								 | 
							
								    /* get this pool last pkt addr */
							 | 
						||
| 
								 | 
							
								    last_pkt_addr = (uint32_t)p_pkt_glb->pool[pool_num]->entries \
							 | 
						||
| 
								 | 
							
								        + (size * (count - 1));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* the next pkt is the next pool first pkt.
							 | 
						||
| 
								 | 
							
								     * but each pool address is discontinuous.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    if ((uint32_t)pkt > last_pkt_addr) {
							 | 
						||
| 
								 | 
							
								        pool_num++; // set pool to next pool num
							 | 
						||
| 
								 | 
							
								        /* next pool's pkt size = 0, means current pool is last pool.
							 | 
						||
| 
								 | 
							
								         * don't need to check the next pkt. */
							 | 
						||
| 
								 | 
							
								        if (0 == p_pkt_glb->config.pool_cfg[pool_num].size) {
							 | 
						||
| 
								 | 
							
								            return ERR_OK;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        pkt = (iot_pkt_t *)p_pkt_glb->pool[pool_num]->entries;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (!pkt) {
							 | 
						||
| 
								 | 
							
								        iot_printf("pkt_check buf=0x%x, last=0x%x\n",
							 | 
						||
| 
								 | 
							
								            (uint32_t)buf, (uint32_t)last_pkt_addr);
							 | 
						||
| 
								 | 
							
								        //align_size * 2 / 4
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT_DUMP(0, (uint32_t *)buf, align_size >> 1);
							 | 
						||
| 
								 | 
							
								        return ERR_INVAL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* get this pkt's head/data/tail/end address */
							 | 
						||
| 
								 | 
							
								    head_addr = (uint32_t)iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_HEAD);
							 | 
						||
| 
								 | 
							
								    data_addr = (uint32_t)iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_DATA);
							 | 
						||
| 
								 | 
							
								    tail_addr = (uint32_t)iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_TAIL);
							 | 
						||
| 
								 | 
							
								    end_addr = (uint32_t)iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_END);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (((0 == head_addr) || iot_data_addr_legal(head_addr))
							 | 
						||
| 
								 | 
							
								        && ((uint32_t)IOT_MEM_POOL_POISON == data_addr)
							 | 
						||
| 
								 | 
							
								        && !tail_addr
							 | 
						||
| 
								 | 
							
								        && !end_addr) {
							 | 
						||
| 
								 | 
							
								        /* the next pkt not allocated ,not need check.
							 | 
						||
| 
								 | 
							
								         * for the not allocated pkt:
							 | 
						||
| 
								 | 
							
								         * pkt->head is the pool block's head, the value is NULL or
							 | 
						||
| 
								 | 
							
								         *      next_pool_block_ptr.
							 | 
						||
| 
								 | 
							
								         * pkt->data must be IOT_MEM_POOL_POISON
							 | 
						||
| 
								 | 
							
								         * pkt->tail and pkt->end must be NULL
							 | 
						||
| 
								 | 
							
								         * for the allocated pkt, the head/data/tail/end must be valid address.
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								        return ERR_OK;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* next pkt */
							 | 
						||
| 
								 | 
							
								    if (ERR_OK != iot_pkt_validation(pkt)) {
							 | 
						||
| 
								 | 
							
								        //align_size * 2 / 4
							 | 
						||
| 
								 | 
							
								        iot_printf("pkt_end_overwrite:0x%x-0x%x\n",
							 | 
						||
| 
								 | 
							
								            (uint32_t)buf, (uint32_t)pkt);
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT_DUMP(0, (uint32_t *)buf, align_size >> 1);
							 | 
						||
| 
								 | 
							
								        return ERR_INVAL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return ERR_OK;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#else /* DEBUG_PKT_OVERWRITE */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t iot_pkt_check_end_overwrite(iot_pkt_t *buf)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    (void)buf;
							 | 
						||
| 
								 | 
							
								    return ERR_OK;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif /* DEBUG_PKT_OVERWRITE */
							 | 
						||
| 
								 | 
							
								
							 |