411 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			411 lines
		
	
	
		
			10 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 "mac_peer.h"
							 | 
						||
| 
								 | 
							
								#include "plc_peer_api.h"
							 | 
						||
| 
								 | 
							
								#include "mac_pdev.h"
							 | 
						||
| 
								 | 
							
								#include "mac_vdev.h"
							 | 
						||
| 
								 | 
							
								#include "mac_desc_engine.h"
							 | 
						||
| 
								 | 
							
								#include "iot_errno.h"
							 | 
						||
| 
								 | 
							
								#include "mac_stream.h"
							 | 
						||
| 
								 | 
							
								#include "iot_queue.h"
							 | 
						||
| 
								 | 
							
								#include "hash_table.h"
							 | 
						||
| 
								 | 
							
								#include "rate_control.h"
							 | 
						||
| 
								 | 
							
								#include "plc_protocol.h"
							 | 
						||
| 
								 | 
							
								#include "iot_io.h"
							 | 
						||
| 
								 | 
							
								#include "os_utils_api.h"
							 | 
						||
| 
								 | 
							
								#include "rf_rate_control.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								mac_peer_t *peer_hash_tbl[peer_tbl_sz] = { 0 };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t plc_create_peer(pdevid_t pid, vdevid_t vid, tei_t tei)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    (void)pid;
							 | 
						||
| 
								 | 
							
								    (void)vid;
							 | 
						||
| 
								 | 
							
								    (void)tei;
							 | 
						||
| 
								 | 
							
								    return 0;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t plc_free_peer(pdevid_t pid, vdevid_t vid, tei_t tei)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    (void)pid;
							 | 
						||
| 
								 | 
							
								    (void)vid;
							 | 
						||
| 
								 | 
							
								    (void)tei;
							 | 
						||
| 
								 | 
							
								    return 0;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t mac_peer_alloc(mac_vdev_t *vdev, tei_t tei,
							 | 
						||
| 
								 | 
							
								    uint32_t is_self, uint32_t is_direct_conn, \
							 | 
						||
| 
								 | 
							
								    uint32_t is_sub_peer, uint32_t is_proxy_peer, mac_peer_t **peer)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    mac_peer_t *tmp;
							 | 
						||
| 
								 | 
							
								    (void)is_direct_conn;
							 | 
						||
| 
								 | 
							
								    uint32_t ret = mac_desc_get(&g_mac_desc_eng, \
							 | 
						||
| 
								 | 
							
								        PLC_MAC_PEER_POOL, (void **)&tmp);
							 | 
						||
| 
								 | 
							
								    if (ret) {
							 | 
						||
| 
								 | 
							
								        mac_vdev_del_overflow_peer(vdev);
							 | 
						||
| 
								 | 
							
								        ret = mac_desc_get(&g_mac_desc_eng, \
							 | 
						||
| 
								 | 
							
								            PLC_MAC_PEER_POOL, (void **)&tmp);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (ret) {
							 | 
						||
| 
								 | 
							
								        mac_peer_stream_overflow_cnt_dbglog();
							 | 
						||
| 
								 | 
							
								        return ERR_NOMEM;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else {
							 | 
						||
| 
								 | 
							
								        /* init peer */
							 | 
						||
| 
								 | 
							
								        os_mem_set(tmp, 0, sizeof(mac_peer_t));
							 | 
						||
| 
								 | 
							
								        tmp->pdev_id = vdev->ref_pdev_id;
							 | 
						||
| 
								 | 
							
								        tmp->vdev_id = vdev->vdev_id;
							 | 
						||
| 
								 | 
							
								        tmp->tei = tei;
							 | 
						||
| 
								 | 
							
								        tmp->is_self_peer = is_self & 0x1;
							 | 
						||
| 
								 | 
							
								        if (tei == PLC_TEI_BCAST) {
							 | 
						||
| 
								 | 
							
								            /* if bcast, should not be self peer */
							 | 
						||
| 
								 | 
							
								            IOT_ASSERT(is_self == 0);
							 | 
						||
| 
								 | 
							
								            tmp->is_bcast_peer = 1;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        else {
							 | 
						||
| 
								 | 
							
								            tmp->is_bcast_peer = 0;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        tmp->next = NULL;
							 | 
						||
| 
								 | 
							
								        if (mac_tei_map_is_set((mac_tei_map_t *)vdev->sub_peer_bitmap, tei)) {
							 | 
						||
| 
								 | 
							
								            tmp->is_sub_peer = 1;
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            tmp->is_sub_peer = !!is_sub_peer;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        tmp->is_proxy_peer = !!is_proxy_peer;
							 | 
						||
| 
								 | 
							
								        iot_list_init(&tmp->vdev_node);
							 | 
						||
| 
								 | 
							
								        /* add into vdev peer list */
							 | 
						||
| 
								 | 
							
								        vdev_add_peer(vdev, tmp);
							 | 
						||
| 
								 | 
							
								        /* add into peer hash table */
							 | 
						||
| 
								 | 
							
								        peer_hash_tbl_add(tmp);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /* rate info init */
							 | 
						||
| 
								 | 
							
								        mac_rate_ctxt_init(tmp);
							 | 
						||
| 
								 | 
							
								        /* rf rate info init */
							 | 
						||
| 
								 | 
							
								        mac_rf_rate_ctxt_init(tmp);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /* perr cnt ++*/
							 | 
						||
| 
								 | 
							
								        vdev->peer_cnt++;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (tmp->is_proxy_peer) {
							 | 
						||
| 
								 | 
							
								            vdev->proxy_peer_cnt++;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /* return value for the new peer */
							 | 
						||
| 
								 | 
							
								        *peer = tmp;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return ERR_OK;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								mac_peer_t * IRAM_ATTR find_peer(mac_vdev_t *vdev,
							 | 
						||
| 
								 | 
							
								    nid_t nid, tei_t tei)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    mac_peer_t *tmp;
							 | 
						||
| 
								 | 
							
								    peer_hash_src_t hash;
							 | 
						||
| 
								 | 
							
								    hash.vid = vdev->vdev_id;
							 | 
						||
| 
								 | 
							
								    hash.nid = nid;
							 | 
						||
| 
								 | 
							
								    hash.tei = tei;
							 | 
						||
| 
								 | 
							
								    nid_t tmp_nid;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (!vdev->mac_vdev_cfg.is_reduced_vdev
							 | 
						||
| 
								 | 
							
								        && (ERR_OK == vdev_get_nid(vdev, &tmp_nid))) {
							 | 
						||
| 
								 | 
							
								        if (nid != tmp_nid) {
							 | 
						||
| 
								 | 
							
								            return NULL;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        uint32_t hash_code = peer_get_hash(hash);
							 | 
						||
| 
								 | 
							
								        mac_peer_t **tmp_entry_addr = \
							 | 
						||
| 
								 | 
							
								            &peer_hash_tbl[hash_code];
							 | 
						||
| 
								 | 
							
								        for (tmp = *tmp_entry_addr; tmp; tmp = tmp->next)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            if (tmp->tei == tei) {
							 | 
						||
| 
								 | 
							
								                return tmp;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        return vdev->self_peer;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return NULL;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* @return - 0 for successful
							 | 
						||
| 
								 | 
							
								*           other for failed
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								uint32_t peer_hash_tbl_add(mac_peer_t *peer)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    nid_t nid;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (!peer) {
							 | 
						||
| 
								 | 
							
								        return ERR_INVAL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    mac_vdev_t *vdev = get_vdev_ptr(peer->pdev_id, peer->vdev_id);
							 | 
						||
| 
								 | 
							
								    if (!vdev) {
							 | 
						||
| 
								 | 
							
								        return ERR_INVAL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    peer_hash_src_t hash = { 0 };
							 | 
						||
| 
								 | 
							
								    hash.vid = vdev->vdev_id;
							 | 
						||
| 
								 | 
							
								    hash.tei = (tei_t)peer->tei;
							 | 
						||
| 
								 | 
							
								    if (ERR_OK != vdev_get_nid(vdev, &nid)) {
							 | 
						||
| 
								 | 
							
								        if (peer->is_bcast_peer || peer->is_self_peer) {
							 | 
						||
| 
								 | 
							
								            nid = (nid_t)PLC_NID_INVALID;
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								            return ERR_INVAL;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    hash.nid = nid;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (find_peer(vdev, \
							 | 
						||
| 
								 | 
							
								        hash.nid, hash.tei)) {
							 | 
						||
| 
								 | 
							
								        /* if already exist */
							 | 
						||
| 
								 | 
							
								        return ERR_EXIST;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    uint32_t hash_code = peer_get_hash(hash);
							 | 
						||
| 
								 | 
							
								    mac_peer_t **peer_entry = \
							 | 
						||
| 
								 | 
							
								        &peer_hash_tbl[hash_code];
							 | 
						||
| 
								 | 
							
								    if ( *peer_entry == NULL)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        *peer_entry = peer;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else {
							 | 
						||
| 
								 | 
							
								        peer->next = *peer_entry;
							 | 
						||
| 
								 | 
							
								        *peer_entry = peer;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return 0;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t peer_hash_tbl_del(mac_peer_t *peer)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t hash_code;
							 | 
						||
| 
								 | 
							
								    peer_hash_src_t hash = { 0 };
							 | 
						||
| 
								 | 
							
								    mac_vdev_t *vdev = get_vdev_ptr(peer->pdev_id, peer->vdev_id);
							 | 
						||
| 
								 | 
							
								    mac_peer_t *entry = NULL;
							 | 
						||
| 
								 | 
							
								    nid_t nid;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    hash.vid = vdev->vdev_id;
							 | 
						||
| 
								 | 
							
								    hash.tei = (tei_t)peer->tei;
							 | 
						||
| 
								 | 
							
								    if (ERR_OK != vdev_get_nid(vdev, &nid)) {
							 | 
						||
| 
								 | 
							
								        if (peer->is_bcast_peer || peer->is_self_peer) {
							 | 
						||
| 
								 | 
							
								            nid = (nid_t)PLC_NID_INVALID;
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								            return ERR_INVAL;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    hash.nid = nid;
							 | 
						||
| 
								 | 
							
								    hash_code = peer_get_hash(hash);
							 | 
						||
| 
								 | 
							
								    for(mac_peer_t **cur = &peer_hash_tbl[hash_code]; *cur;){
							 | 
						||
| 
								 | 
							
								        entry = *cur;
							 | 
						||
| 
								 | 
							
								        if(peer == entry){
							 | 
						||
| 
								 | 
							
								            *cur = entry->next;
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        else{
							 | 
						||
| 
								 | 
							
								            cur = &entry->next;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if(peer != entry){
							 | 
						||
| 
								 | 
							
								        hash.tei = 0;
							 | 
						||
| 
								 | 
							
								        hash_code = peer_get_hash(hash);
							 | 
						||
| 
								 | 
							
								        for(mac_peer_t **cur = &peer_hash_tbl[hash_code]; *cur;){
							 | 
						||
| 
								 | 
							
								            entry = *cur;
							 | 
						||
| 
								 | 
							
								            if(peer == entry){
							 | 
						||
| 
								 | 
							
								                *cur = entry->next;
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else{
							 | 
						||
| 
								 | 
							
								                cur = &entry->next;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if(peer != entry){
							 | 
						||
| 
								 | 
							
								        hash.tei = 0;
							 | 
						||
| 
								 | 
							
								        hash.nid = 0;
							 | 
						||
| 
								 | 
							
								        hash_code = peer_get_hash(hash);
							 | 
						||
| 
								 | 
							
								        for(mac_peer_t **cur = &peer_hash_tbl[hash_code]; *cur;){
							 | 
						||
| 
								 | 
							
								            entry = *cur;
							 | 
						||
| 
								 | 
							
								            if(peer == entry){
							 | 
						||
| 
								 | 
							
								                *cur = entry->next;
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else{
							 | 
						||
| 
								 | 
							
								                cur = &entry->next;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (peer != entry) {
							 | 
						||
| 
								 | 
							
								        iot_printf("peer:0x%x not found.\n", peer);
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								        return ERR_FAIL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return ERR_OK;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* return 0 for success, else for failed */
							 | 
						||
| 
								 | 
							
								uint32_t peer_add_stream(mac_peer_t *peer, void *stream)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (!peer || !stream)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return ERR_INVAL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    mac_stream_t *str = (mac_stream_t *)stream;
							 | 
						||
| 
								 | 
							
								    if (!str->is_tx) {
							 | 
						||
| 
								 | 
							
								        peer->rate_info.last_rx_ts = os_boot_time32();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    iot_single_list_add(&str->peer_node, &peer->data_stream_list);
							 | 
						||
| 
								 | 
							
								    return ERR_OK;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t peer_del_stream(mac_peer_t *peer, void *stream)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    mac_stream_t *str = (mac_stream_t*)stream;
							 | 
						||
| 
								 | 
							
								    IOT_ASSERT(str->peer == peer);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* delete from peer streamlist */
							 | 
						||
| 
								 | 
							
								    iot_single_list_del(&str->peer_node, &peer->data_stream_list);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return ERR_OK;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t peer_del_all_stream(mac_peer_t *peer, uint32_t del_tx_rx_stream)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t i = 0;
							 | 
						||
| 
								 | 
							
								    mac_stream_t *stream;
							 | 
						||
| 
								 | 
							
								    iot_single_list_head_t *tmp;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								again:
							 | 
						||
| 
								 | 
							
								    tmp = peer->data_stream_list;
							 | 
						||
| 
								 | 
							
								    while (tmp) {
							 | 
						||
| 
								 | 
							
								        stream = iot_list_entry(tmp, mac_stream_t, peer_node);
							 | 
						||
| 
								 | 
							
								        if ((del_tx_rx_stream == DEL_TX_STREAM && !stream->is_tx)
							 | 
						||
| 
								 | 
							
								            || (del_tx_rx_stream == DEL_RX_STREAM && stream->is_tx)) {
							 | 
						||
| 
								 | 
							
								            tmp = tmp->next;
							 | 
						||
| 
								 | 
							
								            continue;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        mac_stream_free(peer, stream);
							 | 
						||
| 
								 | 
							
								        i++;
							 | 
						||
| 
								 | 
							
								        goto again;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return i;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t mac_peer_free(mac_vdev_t *vdev, mac_peer_t *peer)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    mac_peer_t *tmp = peer;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* del peer from vdev */
							 | 
						||
| 
								 | 
							
								    vdev_del_peer(vdev, tmp);
							 | 
						||
| 
								 | 
							
								    /* del peer from hash table */
							 | 
						||
| 
								 | 
							
								    if(tmp->is_self_peer == 0 &&\
							 | 
						||
| 
								 | 
							
								        tmp->is_bcast_peer == 0){
							 | 
						||
| 
								 | 
							
								        /* if not self or bcast peer,
							 | 
						||
| 
								 | 
							
								         * del this peer in hash table
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								        peer_hash_tbl_del(tmp);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    peer_del_all_stream(tmp, DEL_ALL_STREAM);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* destroy peer */
							 | 
						||
| 
								 | 
							
								    if(tmp->is_self_peer == 0 && \
							 | 
						||
| 
								 | 
							
								        tmp->is_bcast_peer == 0){
							 | 
						||
| 
								 | 
							
								        /* if not self or bcast peer
							 | 
						||
| 
								 | 
							
								         * free the peer
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								        mac_desc_free(&g_mac_desc_eng, PLC_MAC_PEER_POOL, tmp);
							 | 
						||
| 
								 | 
							
								        /* peer cnt --*/
							 | 
						||
| 
								 | 
							
								        vdev->peer_cnt--;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (tmp->is_proxy_peer) {
							 | 
						||
| 
								 | 
							
								            vdev->proxy_peer_cnt--;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return ERR_OK;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t is_peer_empty(mac_peer_t *peer)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    mac_stream_t *stream;
							 | 
						||
| 
								 | 
							
								    iot_single_list_head_t *tmp;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    tmp = peer->data_stream_list;
							 | 
						||
| 
								 | 
							
								    while (tmp) {
							 | 
						||
| 
								 | 
							
								        stream = iot_list_entry(tmp, mac_stream_t, peer_node);
							 | 
						||
| 
								 | 
							
								        if (is_stream_empty(stream) == 0) {
							 | 
						||
| 
								 | 
							
								            return 0;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        tmp = tmp->next;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return 1;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t mac_peer_del_temp_peer(mac_peer_t *peer)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    IOT_ASSERT(peer);
							 | 
						||
| 
								 | 
							
								    mac_vdev_t *vdev = get_vdev_ptr(peer->pdev_id, peer->vdev_id);
							 | 
						||
| 
								 | 
							
								    IOT_ASSERT(vdev);
							 | 
						||
| 
								 | 
							
								    if ((mac_vdev_cfg_get_node_role(vdev) != PLC_DEV_ROLE_CCO) && \
							 | 
						||
| 
								 | 
							
								        peer->is_self_peer == 0 && peer->is_bcast_peer == 0 && \
							 | 
						||
| 
								 | 
							
								        peer->is_sub_peer == 0 && peer->is_proxy_peer == 0 && \
							 | 
						||
| 
								 | 
							
								        is_peer_empty(peer) == 1) {
							 | 
						||
| 
								 | 
							
								        iot_printf("DEL none sub peer 0x%x:tei=%d\n", \
							 | 
						||
| 
								 | 
							
								            peer, peer->tei);
							 | 
						||
| 
								 | 
							
								        mac_peer_free(vdev, peer);
							 | 
						||
| 
								 | 
							
								        return 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return 1;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t mac_peer_del_overflow_peer(mac_peer_t *peer)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (!peer) {
							 | 
						||
| 
								 | 
							
								        return ERR_FAIL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    mac_vdev_t *vdev = get_vdev_ptr(peer->pdev_id, peer->vdev_id);
							 | 
						||
| 
								 | 
							
								    IOT_ASSERT(vdev);
							 | 
						||
| 
								 | 
							
								    if ((peer->is_self_peer == 0) && (peer->is_bcast_peer == 0) &&
							 | 
						||
| 
								 | 
							
								        (peer->is_proxy_peer == 0)) {
							 | 
						||
| 
								 | 
							
								        if (peer->is_sub_peer) {
							 | 
						||
| 
								 | 
							
								            mac_add_overflow_peer_del_cnt(PEER_SUB);
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            mac_add_overflow_peer_del_cnt(PEER_TMP);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        mac_peer_free(vdev, peer);
							 | 
						||
| 
								 | 
							
								        return ERR_OK;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return ERR_FAIL;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t mac_peer_rx_ts_update(mac_peer_t *peer, uint32_t cur_ts)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    IOT_ASSERT(peer);
							 | 
						||
| 
								 | 
							
								    if(peer->is_bcast_peer || peer->is_self_peer)
							 | 
						||
| 
								 | 
							
								        return 1;
							 | 
						||
| 
								 | 
							
								    peer->rate_info.last_rx_ts = cur_ts;
							 | 
						||
| 
								 | 
							
								    return 0;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 |