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);
 | |
| }
 |