zigbee端口的理解
在一个终端上,可以有多个端点endpoint,这个概念是很重要的。
一个节点可以有多个端点,0号endpoint是Zigbee device object(ZDO)用的一个端点,255号是用作广播。我们自己可以定义的是1-240这些端点。每个端点对应一个任务taskid。因此,我们每增加一个端点,就要给它配置一个新任务taskid
举一个列子: 例子一:一个无线节点(radio unit)A上有一个温湿度传感器,有一个空调控制系统;另外一个无线节点B则负责接收A发回的温度数据,并通过一定的算法来控制空调系统。我们不管B如何实现,只研究A如何实现。这种情况的一个很规范的实现方式是:温湿度传感器设置一个endpoint,比如为10号;空调控制系统设置一个endpoint,比如为20号。还要说明的是:还应该为每一个endpoint建立一个任务,这样在注册端点描述符的时候(调用afRegister函数),就会向协议栈底层说明处理这个端点数据的任务是谁。这样:当B想要获取温湿度的时候,他将会发出一个包含A的短地址和10号端点的信息,这个信息到了A,协议栈会将这个消息转给10号端点所对应的task去处理,管理空调的20号端点根本就看不到这个消息;类似地,如果B想要控制空调,他发出的数据包将包含A的短地址和20号端点信息,A收到消息后会发给20号端点的task去处理。(需要注意的是:在网络层面经常会有发给ZDO的消息,这时候信息包的端点号就将是0号)。这种将不同功能分配到不同endpoint上的方法非常有利于任务的划分,是一种很正规的方法。
例子二、一个无线节点(radio uint)A上有4个LED需要被控制,另外一个无线节点B则有4个开关用来控制这4个LED。这种情形的规范实现方式还是要为每一个LED设置一个endpoint(允许的范围内你任意指定,只要不重复),并为每个endpoint建立一个task。这样处理之后,B可以用同样的命令来控制4个LED,而不是每一个led 用不同的命令,这种情况在public profile实际上是必须这么做的。 上面两个例子可能很多同学认为太麻烦,完全可以变通。变通的想法就是我所有的被控对象都落在一个endpoint上,但是我发的数据包内容不同,接收端这个endpoint通过解析数据包的内容来判断具体该做什么,这种方式实际上完全可以实现,不过需要你自己规定一下数据包的格式,即第几个字节表示什么。。。。。虽然这可以实现要求,但是我很不赞成这样,一方面实际上是增加了你程序设计的复杂度,另一方面完全没有了互联的可能,尤其是当你用ZCL的时候,这种方式就行不通了
注册一个应用的端点描述符afRegister( endPointDesc_t *epDesc )
afRegister( endPointDesc_t *epDesc )这个函数用来注册一个新的端点到task,这样当空中有这个端点的数据到来会直接发送到对应的task。
传入参数:
typedef struct
{
byte endPoint;//端点号
byte *task_id; //端点对应的任务号
SimpleDescriptionFormat_t *simpleDesc;//简单描述符
afNetworkLatencyReq_t latencyReq;//必须用noLatencyReqs来填充
} endPointDesc_t;
afStatus_t afRegister( endPointDesc_t *epDesc )
{
epList_t *ep;
// Look for duplicate endpoint
if ( afFindEndPointDescList( epDesc->endPoint ) )
return ( afStatus_INVALID_PARAMETER );
//在端点的链表中搜索新的端点描述符,看看能不能搜到。如果能搜到,则返回错误。
//如果不能搜到,则说明这个端点在此之前没有被注册,则调用afRegisterExtended( epDesc, NULL )函数注册这个端点。
ep = afRegisterExtended( epDesc, NULL );
return ((ep == NULL) ? afStatus_MEM_FAIL : afStatus_SUCCESS);
}
//注册端点描述符
epList_t *afRegisterExtended( endPointDesc_t *epDesc, pDescCB descFn )
{
epList_t *ep;
epList_t *epSearch;
//注册意味着在端点链表中增加一个新的元素,先通过osal_mem_alloc( sizeof ( epList_t ) )申请需要的内存单元
ep = osal_mem_alloc( sizeof ( epList_t ) );
if ( ep ) //如果申请成功
{
// Fill in the new list entry
ep->epDesc = epDesc;
// Default to allow Match Descriptor.
ep->flags = eEP_AllowMatch;
ep->pfnDescCB = descFn;
ep->nextDesc = NULL;
// Does a list exist?
if ( epList == NULL ) //epList为全局epList_t 指针变量,当链表为空时它指向NULL,如果这是创建的第一个链表元素,则 epList = ep
epList = ep; // Make this the first entry
else //如果这不是第一个链表元素,则首先找到链表的首,在首端加入这个新的元素。
{
// Look for the end of the list
epSearch = epList;
while( epSearch->nextDesc != NULL )
epSearch = epSearch->nextDesc;
// Add new entry to end of list
epSearch->nextDesc = ep;
}
}
return ep;
}
typedef struct
{
endPointDesc_t *epDesc;
eEP_Flags flags;
pDescCB pfnDescCB; // Don't use if this function pointer is NULL.
void *nextDesc;
} epList_t;
在实际工作中,afIncomingData( aps_FrameFormat_t *aff, zAddrType_t *SrcAddress, uint16 SrcPanId,NLDE_Signal_t *sig, byte SecurityUse, uint32 timestamp )这个函数从APS层收到数据,在这个函数中判断收到数据对应的端点号在端点链表中能不能找到,如果不能找到则丢掉这包数据,如果能找到则把数据发送的端点对应的task.
通过 afBuildMSGIncoming( aff, epDesc, SrcAddress, SrcPanId, sig, SecurityUse, timestamp )这个函数建立OSAL的数据包到对应的任务,并且置位对应任务的SYS_EVENT_MSG。
zigbee端口的理解的更多相关文章
- c#tcp源端口号和目的端口怎么理解
在一台机器上,一个进程对应一个端口.端口的作用就是用来唯一标识这个进程.源端口标识发起通信的那个进程,目的端口标识接受通信的那个进程.有了端口号,接受到报文后才能够知道将报文发送到哪个进程.
- STP 指定端口 根端口 区别和理解
不多说,先上图,A为指定端口,B为非指定端口. 看本文的网友应该知道根端口和指定端口的选举,但是对指定端口和根端口的理解不清楚.这里我就略过选举过程,直接描述这两者的区别和存在的意义. 指定端口:转发 ...
- 就该这样理解 OSI 七层参考模型、浅谈不同局域网之间的通信
简介 说到OSI参考模型,理解网络与网络之间的关系,不说太深入难以理解的东西,只求能最大程度上理解与使用. 参考模型是国际标准化组织(ISO)制定的一个用于计算机或通信系统间互联的标准体系,一般称为O ...
- 【转】理解Docker容器网络之Linux Network Namespace
原文:理解Docker容器网络之Linux Network Namespace 由于2016年年中调换工作的原因,对容器网络的研究中断过一段时间.随着当前项目对Kubernetes应用的深入,我感觉之 ...
- 服务器开发基础-Tcp/Ip网络模型—完成端口(Completion Port)模型
本文对于初学网络编程的极为友好,文中所有代码全部基于C语言实现,文中见解仅限于作者对于完成端口的初步认识,由于作者才疏学浅,出现的错误和纰漏,麻烦您一定要指出来,咱们共同进步.谢谢!!! 完成端口(c ...
- 从K8S部署示例进一步理解容器化编排技术的强大
概念 Kubernetes,也称为K8s,生产级别的容器编排系统,是一个用于自动化部署.扩展和管理容器化应用程序的开源系统.K8s是一个go语言开发,docker也是go语言开发,可见go语言的是未来 ...
- Socket Programming in C#--Getting Started
Getting Started You can argue that one can overcome these shortcomings by multithreading meaning tha ...
- Android网络编程之Socket
Socket(套接字)是一种通信机制,可以实现单机或跨网络进行通信,其创建需要明确的区分C(客户端)/S(服务器端),支持多个客户端连接到同一个服务器.有两种传输模式: 1).面向连接的传输:基于TC ...
- 两台机子的repcached Memcache 的安装与实验
安装memcached前先要确定系统是否安装了gcc: 1.解压安装包: tar -zxf memcached-1.2.8-repcached-2.2.tar.gz 2.编译: 系统应安装了libev ...
随机推荐
- Ubuntu 安装 Redis和phpredis扩展
服务器Ubuntu16.04 环境php7.0+Apache /****************************开始安装Redis****************************/ 1 ...
- Windows系统maven安装配置
Apache Maven是一个软件项目管理工具,基于项目对象模型(Project Object Model,即POM)的概念,Maven可用来管理项目的依赖.编译.文档等信息.使用Maven管理项目时 ...
- Python 模块定义、导入、优化详解
一.定义 模块:用来从逻辑上组织 python 代码(变量,函数,类, 逻辑:实现一个功能),本质就是 .py 结尾的 python文件(例如:test.py文件,对应的模块名:test) 包:用来从 ...
- pip3更新后install package出现ImportError: cannot import name 'main'
linux下pip3更新后,install包出现main不能导入的情况: bear@bear:~/eclipse-workspace/Python-toolbox$ pip3 install pycr ...
- 学习ActiveMQ(六):JMS消息的确认与重发机制
当我们发送消息的时候,会出现发送失败的情况,此时我们需要用到activemq为我们提供了消息重发机制,进行消息的重新发送.那么我们怎么知道消息有没有发送失败呢?activemq还有消息确认机制,消费者 ...
- PDM:Training Models of Shape from Sets of Examples
这篇论文介绍了一种创建柔性形状模型(Flexible Shape Models)的方法--点分布模型(Point Distribution Model).该方法使用一系列标记点来表示形状,重要的是根据 ...
- python摸爬滚打之day030----进程
1.操作系统了解 现代的计算机系统主要是由一个或者多个处理器,主存,硬盘,键盘,鼠标,显示器,打印机,网络接口及其他输入输出设备组成, 这些都是硬件设备, 而操作系统就是负责调用这些硬件为用户服务的. ...
- 骑士(树形dp)
题意:给你一个基环树森林,每个点有一个权值,一条边上的两个节点不能同时选择.选取任意个节点,求最大权值和 对于每颗基环树:找环→断边→树形dp(没有上司的舞会) #include<iostrea ...
- struct ifreq学习和实例
一.struct ifreq结构体 这个结构定义在/usr/include/net/if.h,用来配置和获取ip地址,掩码,MTU等接口信息的. /* Interface request struct ...
- 【托业】【怪兽】TEST01
101. respectable 值得尊敬的(形容人或事物) respectful 态度恭敬的(形容人) respecting 关于…… respective 各自的 102. hardly 几乎没有 ...