在一个终端上,可以有多个端点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端口的理解的更多相关文章

  1. c#tcp源端口号和目的端口怎么理解

    在一台机器上,一个进程对应一个端口.端口的作用就是用来唯一标识这个进程.源端口标识发起通信的那个进程,目的端口标识接受通信的那个进程.有了端口号,接受到报文后才能够知道将报文发送到哪个进程.

  2. STP 指定端口 根端口 区别和理解

    不多说,先上图,A为指定端口,B为非指定端口. 看本文的网友应该知道根端口和指定端口的选举,但是对指定端口和根端口的理解不清楚.这里我就略过选举过程,直接描述这两者的区别和存在的意义. 指定端口:转发 ...

  3. 就该这样理解 OSI 七层参考模型、浅谈不同局域网之间的通信

    简介 说到OSI参考模型,理解网络与网络之间的关系,不说太深入难以理解的东西,只求能最大程度上理解与使用. 参考模型是国际标准化组织(ISO)制定的一个用于计算机或通信系统间互联的标准体系,一般称为O ...

  4. 【转】理解Docker容器网络之Linux Network Namespace

    原文:理解Docker容器网络之Linux Network Namespace 由于2016年年中调换工作的原因,对容器网络的研究中断过一段时间.随着当前项目对Kubernetes应用的深入,我感觉之 ...

  5. 服务器开发基础-Tcp/Ip网络模型—完成端口(Completion Port)模型

    本文对于初学网络编程的极为友好,文中所有代码全部基于C语言实现,文中见解仅限于作者对于完成端口的初步认识,由于作者才疏学浅,出现的错误和纰漏,麻烦您一定要指出来,咱们共同进步.谢谢!!! 完成端口(c ...

  6. 从K8S部署示例进一步理解容器化编排技术的强大

    概念 Kubernetes,也称为K8s,生产级别的容器编排系统,是一个用于自动化部署.扩展和管理容器化应用程序的开源系统.K8s是一个go语言开发,docker也是go语言开发,可见go语言的是未来 ...

  7. Socket Programming in C#--Getting Started

    Getting Started You can argue that one can overcome these shortcomings by multithreading meaning tha ...

  8. Android网络编程之Socket

    Socket(套接字)是一种通信机制,可以实现单机或跨网络进行通信,其创建需要明确的区分C(客户端)/S(服务器端),支持多个客户端连接到同一个服务器.有两种传输模式: 1).面向连接的传输:基于TC ...

  9. 两台机子的repcached Memcache 的安装与实验

    安装memcached前先要确定系统是否安装了gcc: 1.解压安装包: tar -zxf memcached-1.2.8-repcached-2.2.tar.gz 2.编译: 系统应安装了libev ...

随机推荐

  1. 04_ switch 练习 _ 你及格了吗

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

  2. spring boot 开始部署报Whitelabel Error Page错解决方法

    因为时刚刚才学spring boot ,第一次碰到的问题,花了半个小时终于明白了,SpringBoot 的application类会自动扫描子包类下的mapping方法,因此application类不 ...

  3. 更为复杂C程序的运行时结构

    运行环境 win 10 企业版 1809 17763.194,MinGW V3.14 32位,Bundled V3.13.2,Bundled GDB V8.2. 在C语言中,栈的方向是从高地址向低地址 ...

  4. 使用vue实现tab栏的点击切换样式

    <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...

  5. 学习ActiveMQ(七):JMS消息的事务管理

    Spring提供了一个JmsTransactionManager用于对JMS ConnectionFactory做事务管理.这将允许JMS应用利用Spring的事务管理特性.JmsTransactio ...

  6. 纯css3实现只适应的正方形

    纯 CSS 实现自适应正方形 Table of Contents 方案一:CSS3 vw 单位 方案二:设置垂直方向的 padding 撑开容器 方案三:利用伪元素的 margin(padding)- ...

  7. Android的SQlite的使用

    Android系统集成了一个轻量级的数据库:SQlite.SQlite不像Oracle.MySQl数据库那样需要安装.启动服务器进程,SQLite数据库只是一个文件 实例1:向数据库里插入数据 主界面 ...

  8. Springboot-001-解决nested exception is org.apache.ibatis.binding.BindingException: Parameter 'env' not found. Available parameters are [arg1, arg0, param1, param2]

    环境:Springboot + Mybatis + MySQL + VUE 场景: 前端发出数据比对请求,在服务后台与数据库交互时,接口提示错误信息如下所示: { "code": ...

  9. @ResponseBody ResponseEntity

    1.产生疑问 我们知道,如果在 Controller 的某个方法上加上 @ResponseBody 注解,那么你就能拿到 json 数据. 如果你只是知道这么用,那么你应该知道 ResponseBod ...

  10. mac环境使用ATS验证

    https://blog.csdn.net/skylin19840101/article/details/53760146 参考的这篇文章,用 /usr/bin/nscurl --ats-diagno ...