1. 程式人生 > >nordic mesh中的消息緩存實現

nordic mesh中的消息緩存實現

協議 entry message 轉發 [] exists whether 遍歷 PE

nordic mesh中的消息緩存實現

代碼文件msg_cache.hmsg_cache.c

接口定義

頭文件中定義了四個接口,供mesh協議棧調用,四個接口如下所示,接口的實現代碼在msg_cache.c文件中。

@file:msg_cache.h

// 消息緩存初始化
void msg_cache_init(void);

// 檢查消息是否存在
bool msg_cache_entry_exists(uint16_t src_addr, uint32_t sequence_number);

// 添加消息到緩存
void msg_cache_entry_add(uint16_t src, uint32_t
seq); // 消息緩存清空 void msg_cache_clear(void);

實現代碼

消息緩存用靜態全局變量的一個數組m_msg_cache[]實現,該數組長度為32,數組每個元素表示消息。m_msg_cache_head表示新消息加入的位置,通過對m_msg_cache_head的控制實現一個環形的消息緩存。

其結構定義如下:

typedef struct
{
    bool allocated;  /**< Whether the entry is in use. */
    uint16_t src;    /**< Source address from packet header. */
uint32_t seq; /**< Sequence number from the packet header. */ } msg_cache_entry_t; /** Message cache buffer */ static msg_cache_entry_t m_msg_cache[MSG_CACHE_ENTRY_COUNT]; /** Message cache head index * 新消息的加入位置 */ static uint32_t m_msg_cache_head = 0;

由緩存結構可知,消息緩存結構只是保存了消息的源地址及其序列號。收到消息時,先在消息緩存中檢查是否已有該消息,若不存在則添加進去,否則忽略消息。

由於藍牙mesh是基於泛洪管理網絡的,所以某個節點會收到多條相同的消息(每個節點會中繼轉發消息),消息緩存主要用判斷是否已收到該消息,用來避免消息擁塞。

msg_cache_init()

消息緩存初始化代碼如下,就是將消息緩存數組的各元素設置為可用狀態。


void msg_cache_init(void)
{
    for (uint32_t i = 0; i < MSG_CACHE_ENTRY_COUNT; ++i)
    {
        m_msg_cache[i].src = NRF_MESH_ADDR_UNASSIGNED;
        m_msg_cache[i].seq = 0;
        m_msg_cache[i].allocated = 0;
    }

    m_msg_cache_head = 0;
}

msg_cache_entry_exists()

判斷消息是否已經存在,從m_msg_cache_head的位置開始逆序遍歷整個消息緩存數組,逐個對比源地址及序列號


bool msg_cache_entry_exists(uint16_t src_addr, uint32_t sequence_number)
{
    /* Search backwards from head */
    uint32_t entry_index = m_msg_cache_head;
    for (uint32_t i = 0; i < MSG_CACHE_ENTRY_COUNT; ++i)
    {
        if (entry_index-- == 0) /* compare before subtraction */
        {
            entry_index = MSG_CACHE_ENTRY_COUNT - 1;
        }

        if (!m_msg_cache[entry_index].allocated)
        {
            return false; /* Gone past the last valid entry. */
        }

        if (m_msg_cache[entry_index].src == src_addr &&
            m_msg_cache[entry_index].seq == sequence_number)
        {
            return true;
        }
    }

    return false;
}

msg_cache_entry_add()

消息添加到緩存

void msg_cache_entry_add(uint16_t src, uint32_t seq)
{
    m_msg_cache[m_msg_cache_head].src = src;
    m_msg_cache[m_msg_cache_head].seq = seq;
    m_msg_cache[m_msg_cache_head].allocated = true;

    if ((++m_msg_cache_head) == MSG_CACHE_ENTRY_COUNT)
    {
        m_msg_cache_head = 0;
    }
}

msg_cache_clear()

清空消息緩存

void msg_cache_clear(void)
{
    for (uint32_t i = 0; i < MSG_CACHE_ENTRY_COUNT; ++i)
    {
        m_msg_cache[i].allocated = 0;
    }
}

nordic mesh中的消息緩存實現