192 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			192 lines
		
	
	
		
			5.0 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.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								****************************************************************************/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* os shim includes */
							 | 
						||
| 
								 | 
							
								#include "os_types.h"
							 | 
						||
| 
								 | 
							
								#include "os_mem.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* common includes */
							 | 
						||
| 
								 | 
							
								#include "iot_errno.h"
							 | 
						||
| 
								 | 
							
								#include "iot_module.h"
							 | 
						||
| 
								 | 
							
								#include "iot_mem_pool.h"
							 | 
						||
| 
								 | 
							
								#include "iot_addr_hash_table.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								iot_addr_hash_table_h iot_addr_hash_table_create(module_id_t module,
							 | 
						||
| 
								 | 
							
								    uint16_t entry_cnt, uint16_t entry_size, uint16_t table_size)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t ret;
							 | 
						||
| 
								 | 
							
								    iot_addr_hash_table_t *table = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (table_size > IOT_ADDR_HASH_TABLE_SIZE_MAX)
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    table_size = 1 << table_size;
							 | 
						||
| 
								 | 
							
								    table = os_mem_malloc(module, sizeof(*table));
							 | 
						||
| 
								 | 
							
								    if (table == NULL) {
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    table->hash_ent = os_mem_malloc(module,
							 | 
						||
| 
								 | 
							
								        (table_size * (sizeof(*table->hash_ent))));
							 | 
						||
| 
								 | 
							
								    if (table->hash_ent == NULL) {
							 | 
						||
| 
								 | 
							
								        goto err_table;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ret = iot_mem_pool_new(module, entry_cnt,
							 | 
						||
| 
								 | 
							
								        entry_size, &table->entry_p, 0);
							 | 
						||
| 
								 | 
							
								    if (ret)
							 | 
						||
| 
								 | 
							
								        goto err_pool;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    table->entry_cnt = entry_cnt;
							 | 
						||
| 
								 | 
							
								    table->entry_size = entry_size;
							 | 
						||
| 
								 | 
							
								    table->table_size = table_size;
							 | 
						||
| 
								 | 
							
								    table->meter_flag = 0;
							 | 
						||
| 
								 | 
							
								    goto out;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								err_pool:
							 | 
						||
| 
								 | 
							
								    os_mem_free(table->hash_ent);
							 | 
						||
| 
								 | 
							
								err_table:
							 | 
						||
| 
								 | 
							
								    os_mem_free(table);
							 | 
						||
| 
								 | 
							
								    table = NULL;
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    return table;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void iot_addr_hash_table_delete(iot_addr_hash_table_h handle)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_addr_hash_table_t *table = handle;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (table) {
							 | 
						||
| 
								 | 
							
								        iot_mem_pool_destroy(table->entry_p);
							 | 
						||
| 
								 | 
							
								        os_mem_free(table->hash_ent);
							 | 
						||
| 
								 | 
							
								        os_mem_free(table);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t iot_addr_hash_table_add(iot_addr_hash_table_h handle,
							 | 
						||
| 
								 | 
							
								    iot_addr_hash_entry_t *entry)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t ret = ERR_OK, index;
							 | 
						||
| 
								 | 
							
								    iot_addr_hash_table_t *table = handle;
							 | 
						||
| 
								 | 
							
								    iot_addr_hash_entry_t *tmp;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    index = iot_mac_addr_hash(entry->addr, table->table_size - 1);
							 | 
						||
| 
								 | 
							
								    tmp = table->hash_ent[index];
							 | 
						||
| 
								 | 
							
								    if (tmp == NULL) {
							 | 
						||
| 
								 | 
							
								        table->hash_ent[index] = entry;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        for (;;) {
							 | 
						||
| 
								 | 
							
								            if (iot_mac_addr_cmp(tmp->addr, entry->addr)) {
							 | 
						||
| 
								 | 
							
								                ret = ERR_EXIST;
							 | 
						||
| 
								 | 
							
								                goto out;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            if (tmp->next) {
							 | 
						||
| 
								 | 
							
								                tmp = tmp->next;
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                /* iterate to the end of the list */
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        tmp->next = entry;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    entry->next = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    return ret;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void iot_addr_hash_table_remove(iot_addr_hash_table_h handle,
							 | 
						||
| 
								 | 
							
								    iot_addr_hash_entry_t *entry)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t index;
							 | 
						||
| 
								 | 
							
								    iot_addr_hash_table_t *table = handle;
							 | 
						||
| 
								 | 
							
								    iot_addr_hash_entry_t *curr, *prev = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* search entry */
							 | 
						||
| 
								 | 
							
								    index = iot_mac_addr_hash(entry->addr, table->table_size - 1);
							 | 
						||
| 
								 | 
							
								    curr = table->hash_ent[index];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    while (curr) {
							 | 
						||
| 
								 | 
							
								        if (curr == entry)
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        prev = curr;
							 | 
						||
| 
								 | 
							
								        curr = curr->next;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (curr) {
							 | 
						||
| 
								 | 
							
								        /* remove entry from the hash table */
							 | 
						||
| 
								 | 
							
								        if (prev) {
							 | 
						||
| 
								 | 
							
								            prev->next = curr->next;
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            table->hash_ent[index] = curr->next;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        curr->next = NULL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								iot_addr_hash_entry_t *iot_addr_hash_table_find(iot_addr_hash_table_h handle,
							 | 
						||
| 
								 | 
							
								    uint8_t* addr)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t index;
							 | 
						||
| 
								 | 
							
								    iot_addr_hash_table_t *table = handle;
							 | 
						||
| 
								 | 
							
								    iot_addr_hash_entry_t *entry;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    index = iot_mac_addr_hash(addr, table->table_size - 1);
							 | 
						||
| 
								 | 
							
								    entry = table->hash_ent[index];
							 | 
						||
| 
								 | 
							
								    while (entry) {
							 | 
						||
| 
								 | 
							
								        if (iot_mac_addr_cmp(addr, entry->addr)) {
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        entry = entry->next;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return entry;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void iot_addr_hash_table_loop(iot_addr_hash_table_h handle,
							 | 
						||
| 
								 | 
							
								    iot_addr_hash_loop_func_t func, void *param)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t index = 0;
							 | 
						||
| 
								 | 
							
								    iot_addr_hash_table_t *table = handle;
							 | 
						||
| 
								 | 
							
								    iot_addr_hash_entry_t *entry, *next_entry;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    while (index < table->table_size) {
							 | 
						||
| 
								 | 
							
								        entry = table->hash_ent[index];
							 | 
						||
| 
								 | 
							
								        while (entry) {
							 | 
						||
| 
								 | 
							
								            next_entry = entry->next;
							 | 
						||
| 
								 | 
							
								            func(entry, param);
							 | 
						||
| 
								 | 
							
								            /* caution, after this point, entry pointer is invalid */
							 | 
						||
| 
								 | 
							
								            entry = next_entry;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        index++;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								iot_addr_hash_entry_t *iot_addr_hash_table_alloc(iot_addr_hash_table_h handle)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_addr_hash_table_t *table = handle;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return iot_mem_pool_alloc(table->entry_p);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void iot_addr_hash_table_free(iot_addr_hash_table_h handle,
							 | 
						||
| 
								 | 
							
								    iot_addr_hash_entry_t *entry)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_addr_hash_table_t *table = handle;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    iot_mem_pool_free(table->entry_p, entry);
							 | 
						||
| 
								 | 
							
								}
							 |