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中的消息缓存实现的更多相关文章

  1. 深入探讨在集群环境中使用 EhCache 缓存系统

    EhCache 缓存系统简介 EhCache 是一个纯 Java 的进程内缓存框架,具有快速.精干等特点,是 Hibernate 中默认的 CacheProvider. 下图是 EhCache 在应用 ...

  2. (转)深入探讨在集群环境中使用 EhCache 缓存系统

    简介: EhCache 是一个纯 Java 的进程内缓存框架,具有快速.精干等特点,是 Hibernate 中默认的 CacheProvider.本文充分的介绍了 EhCache 缓存系统对集群环境的 ...

  3. WebIM(2)---消息缓存

    WebIM系列文章 在一步一步打造WebIM(1)一文中,已经介绍了如何实现一个简单的WebIM,但是,这个WebIM有一个问题,就是每一次添加消息监听器时,都必须访问一次数据库去查询是否有消息,显然 ...

  4. Objective-C中的消息发送总结

    关于OC中的消息发送的实现,在去年也看过一次,当时有点不太理解,但是今年再看却很容易理解. 我想这跟知识体系的构建有关,如果你不认识有砖.水泥等这些建筑的基本组成部分,那么我们应该很难理解建筑是怎么建 ...

  5. linux中的redis缓存服务器

    Linux中的Redis缓存服务器 一.Redis基础部分: 1.redis介绍与安装比mysql快10倍以上 *****************redis适用场合**************** 1 ...

  6. nordic mesh 任务调度实现

    nordic mesh 任务调度实现 nordic mesh的任务调度室基于定时器实现的,有两个链表结构维护任务. 需要注意的是,任务调度的部分接口只能在"bearer event" ...

  7. 《逐梦旅程 WINDOWS游戏编程之从零开始》笔记5——Direct3D中的顶点缓存和索引缓存

    第12章 Direct3D绘制基础 1. 顶点缓存 计算机所描绘的3D图形是通过多边形网格来构成的,网网格勾勒出轮廓,然后在网格轮廓的表面上贴上相应的图片,这样就构成了一个3D模型.三角形网格是构建物 ...

  8. 基于事件驱动机制,在Service Mesh中进行消息传递的探讨

    翻译 | 宋松 原文 | https://www.infoq.com/articles/service-mesh-event-driven-messaging 关键点 当前流行的Service Mes ...

  9. IOS OS X 中集中消息的传递机制

    1 KVO (key-value Observing) 是提供对象属性被改变是的通知机制.KVO的实现实在Foundation中,很多基于 Foundation 的框架都依赖与它.如果只对某一个对象的 ...

随机推荐

  1. Struts2+hibernate 结合,实现登陆校验

    完整的项目在github中,数据库使用postgresql,建表语句见项目文档. 下面我分块介绍一下struts2.hibernate.与页面部分的代码. Struts2 UserAction.jav ...

  2. JAVA揭竿而起总要有名号

    古代揭竿而起总要有个响亮的名号,这可不是随便的哦,比如  苍天已死,黄天当立... 玩JAVA里面形形色色的名字,都是有套路的,至于名字怎么起法,那得问问标识符 标识符 用作给变量.类和方法命名.注意 ...

  3. MySql服务未知原因消失了的解决办法

    一: 5.1及后续版本: 打开计算机命令窗口,切换至mysql安装目录,然后运行bin目录下的mysqld.exe,命令如下: D:\MySQL\bin>mysqld.exe -installS ...

  4. centos7安装ftp

    1.服务器初始化检查 检查selinux,firewall,iptables是否开启 1.查看selinux的运行状态 [root@zeq ~] getenforce Disabled 我的现在是关闭 ...

  5. sort的用法

    早一段时间一直没有理解sort的用法,在早几天终于是研究的明白的,所以就来分享一下,如果你也被这个方法困扰,没懂原理,可以看一下这遍文章,希望有所帮助. 第一种,最简单的排序,纯数字排序: var a ...

  6. 【laravel】同一代码段内,先更新数据,后查询修改的数据,查询结果错误的问题

    如标题所言,是什么意思呢?举个栗子,需求如下: 你是一个电话销售人员,手头有一些待call电话单,每个电话单上有N个不同的电话号码,需要你每打一个电话就标记为”已打“.当一个电话单上的号码都标记为”已 ...

  7. 如何在 EXCEL 2003 插入的方框内打对勾,复选框

    一个方框里带勾的符号是吧第一种:EXCEL里有个插入符号的功能知道吧,打开它在符号那栏(不是特殊符号那栏),下拉字体找到Wingdings字体,在下面的符号中就能找到框中带勾的符号 第二种:在界面点& ...

  8. 『Linux基础 - 2 』操作系统,Linux背景知识和Ubuntu操作系统安装

    这篇笔记记录了以下几个知识点: 1.目前常见的操作系统及分类,虚拟机 2.Linux操作系统背景知识,Windows和Linux两个操作系统的对比 3.在虚拟机中安装Ubuntu系统的详细步骤 OS( ...

  9. Django中ORM简述

    ORM:对象关系映射(Object Relational Mapping,简称ORM) 作用:根据类生成表结构,将对象.列表的操作转换成对象的SQL语句,将SQL语句查询的结果转换为对象或列表 优点: ...

  10. [原创]利用python发送伪造的ARP请求

    #!/usr/bin/env python import socket s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW) s.bind((&qu ...