在Broadcom中提供了自己的消息机制,有两种消息形式:Request/Response and Event(事件)

Request/Response消息:进程之间的通信都是通过smd,所有的消息都是先发送到smd,smd收到信息后,如果消息目的是smd的就做相应的操作,如果不是,就把这个消息route出去

Event messages :对某些事件感兴趣的进程,可以CMS_MSG_REGISTER_EVENT_INTEREST注册此感兴趣事件。事件发生时,将事件信息发送给smd,smd再将事件信息发送给感兴趣的进程。

1. smd与其他进程的通信的实现

smd监听消息

if ((fd = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0)
{
cmsLog_error("Could not create socket");
return fd;
}

/*
* Bind my server address and listen.
*/
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sun_family = AF_LOCAL;
strncpy(serverAddr.sun_path, SMD_MESSAGE_ADDR, sizeof(serverAddr.sun_path));

rc = bind(fd, (struct sockaddr *) &serverAddr, sizeof(serverAddr));
if (rc != 0)
{
cmsLog_error("bind to %s failed, rc=%d errno=%d", SMD_MESSAGE_ADDR, rc, errno);
close(fd);
return -1;
}

rc = listen(fd, SMD_MESSAGE_BACKLOG);
if (rc != 0)
{
cmsLog_error("listen to %s failed, rc=%d errno=%d", SMD_MESSAGE_ADDR, rc, errno);
close(fd);
return -1;
}

其他进程连接到smd:cmsMsg_init

cmsMsg_init具体实现

/*
* Create a unix domain socket.
*/
handle->commFd = socket(AF_LOCAL, SOCK_STREAM, 0);
if (handle->commFd < 0)
{
cmsLog_error("Could not create socket");
cmsMem_free(handle);
return CMSRET_INTERNAL_ERROR;
}

/*
* Set close-on-exec, even though all apps should close their
* fd's before fork and exec.
*/
if ((rc = fcntl(handle->commFd, F_SETFD, FD_CLOEXEC)) != 0)
{
cmsLog_error("set close-on-exec failed, rc=%d errno=%d", rc, errno);
close(handle->commFd);
cmsMem_free(handle);
return CMSRET_INTERNAL_ERROR;
}

/*
* Connect to smd.
*/
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sun_family = AF_LOCAL;
strncpy(serverAddr.sun_path, SMD_MESSAGE_ADDR, sizeof(serverAddr.sun_path));

rc = connect(handle->commFd, (struct sockaddr *) &serverAddr, sizeof(serverAddr));
if (rc != 0)
{
cmsLog_error("connect to %s failed, rc=%d errno=%d", SMD_MESSAGE_ADDR, rc, errno);
close(handle->commFd);
cmsMem_free(handle);
return CMSRET_INTERNAL_ERROR;
}
else
{
cmsLog_debug("commFd=%d connected to smd", handle->commFd);
}

这样就建立了其他进程与smd的连接,阻塞等待事件的发生

/* pend, waiting for one or more fds to become ready */
rv = select(maxFd+1, &readFds, NULL, NULL, &tm);

用cmsMsg_send cmsMsg_receive发送接收信息,事件发生之后,processMessage处理信息

2. 与kernel的通信

底层 atm, dsl, eth 状态发生改变的时候,会发信息给ssk,ssk再把信息发送给smd

/*
* Initialize special socket to kernel for WAN link-up, link-down events.
* The kernel notification mechanism uses the error channel of some existing fd.
* See webmain in cfm/web.
*/
if ((ret = initKernelMonitorFd()) != CMSRET_SUCCESS)

initKernelMonitorFd:

if ((kernelMonitorFd = socket(AF_NETLINK, SOCK_RAW, NETLINK_BRCM_MONITOR)) < 0)
//if ((kernelMonitorFd = socket(AF_NETLINK, SOCK_RAW, NETLINK_UNUSED)) < 0)
{
cmsLog_error("Could not open netlink socket for kernel monitor");
return CMSRET_INTERNAL_ERROR;
}
else
{
cmsLog_debug("kernelMonitorFd=%d", kernelMonitorFd);
}

addr.nl_family = AF_NETLINK;
addr.nl_pid = getpid();
addr.nl_groups = 0;

if (bind(kernelMonitorFd,(struct sockaddr *)&addr,sizeof(addr))<0)
{
cmsLog_error("Could not bind netlink socket for kernel monitor");
close(kernelMonitorFd);
kernelMonitorFd = CMS_INVALID_FD;
return CMSRET_INTERNAL_ERROR;
}

然后将kernelMonitorFd  加入select集中,阻塞n = select(maxFd+1, &readFds, NULL, &errorFds, &tv);

if (FD_ISSET(kernelMonitorFd, &readFds))
{
processKernelMonitor();
}

processKernelMonitor:轮询信息

/* There can be more than one message per recvmsg */
for(nl_msgHdr = (struct nlmsghdr *) buf; NLMSG_OK (nl_msgHdr, (unsigned int)recvLen);
nl_msgHdr = NLMSG_NEXT (nl_msgHdr, recvLen))

3. 事件消息

首先需要注册感兴趣的事件

msg->type = CMS_MSG_REGISTER_EVENT_INTEREST;
msg->flags_request = 1;
msg->flags_response = 0;
msg->flags_event = 0;
msg->wordData = CMS_MSG_DHCP6C_STATE_CHANGED;
if ((ret = cmsMsg_sendAndGetReply(msgHandle, msg)) != CMSRET_SUCCESS)
{

}

当dhcp6c发生改变的时候,发送事件信息到smd

msg->type = CMS_MSG_DHCP6C_STATE_CHANGED;
msg->src = MAKE_SPECIFIC_EID(getpid(), EID_DHCP6C);
msg->dst = EID_SMD;
msg->flags_event = 1;
msg->dataLength = sizeof(Dhcp6cStateChangedMsgBody);

memcpy(dhcp6cBody, &dhcp6cMsgBody, sizeof(Dhcp6cStateChangedMsgBody));

if ((ret = cmsMsg_send(msgHandle, msg)) != CMSRET_SUCCESS)

smd收到事件信息之后,查找感兴趣的进程将信息发送出去

distributeEventMessage

这里CMS_MSG_DHCP6C_STATE_CHANGED是在ssk注册的,所以到ssk,ssk收到信息之后

#ifdef DMP_X_BROADCOM_COM_IPV6_1 /* aka SUPPORT_IPV6 */
case CMS_MSG_DHCP6C_STATE_CHANGED:
processDhcp6cStateChanged(msg);
break;

Broadcom的消息机制的更多相关文章

  1. iOS开发系列--通知与消息机制

    概述 在多数移动应用中任何时候都只能有一个应用程序处于活跃状态,如果其他应用此刻发生了一些用户感兴趣的那么通过通知机制就可以告诉用户此时发生的事情.iOS中通知机制又叫消息机制,其包括两类:一类是本地 ...

  2. Android消息传递之Handler消息机制

    前言: 无论是现在所做的项目还是以前的项目中,都会遇见线程之间通信.组件之间通信,目前统一采用EventBus来做处理,在总结学习EventBus之前,觉得还是需要学习总结一下最初的实现方式,也算是不 ...

  3. Windows消息机制

    Windows的消息系统是由3个部分组成的: · 消息队列.Windows能够为所有的应用程序维护一个消息队列.应用程序必须从消息队列中获取消息,然后分派给某个窗口.· 消息循环.通过这个循环机制应用 ...

  4. OSG消息机制之事件处理概述

    OSG的消息机制包括好多个头文件预定义及多个类. 首先,消息接收相关的类当属osgGA::GUIEventHandler和osgGA::GUIEventAdapter这两个类了.前者处理OSG程序与用 ...

  5. [转]runtime 消息机制

    原文地址:http://www.jianshu.com/p/f6300eb3ec3d 一.关于runtime 之前在项目中有遇到过用runtime解决改变全局字体的问题,所以再一次感受到了runtim ...

  6. IOS 消息机制(NSNotificationCenter)

    消息机制 NSNotificationCenter 一直都在频繁使用,但是却对其原理不是十分了解.今天就花些时间,把消息机制原理重头到尾好好过一遍. iOS 提供了一种 "同步的" ...

  7. Android之消息机制Handler,Looper,Message解析

    PS:由于感冒原因,本篇写的有点没有主干,大家凑合看吧.. 学习内容: 1.MessageQueue,Looper,MessageQueue的作用. 2.子线程向主线程中发送消息 3.主线程向子线程中 ...

  8. Objective-C总Runtime的那点事儿(一)消息机制

    最近在找工作,Objective-C中的Runtime是经常被问到的一个问题,几乎是面试大公司必问的一个问题.当然还有一些其他问题也几乎必问,例 如:RunLoop,Block,内存管理等.其他的问题 ...

  9. Windows消息机制详解

    消息是指什么?      消息系统对于一个win32程序来说十分重要,它是一个程序运行的动力源泉.一个消息,是系统定义的一个32位的值,他唯一的定义了一个事件,向 Windows发出一个通知,告诉应用 ...

随机推荐

  1. oracle的Hint

    与优化器模式相关的Hint 1 ALl_ROWS   让优化器启用CBO /*+ all_rows */ 2  first_rows(n)     让优化器启用CBO 模式,而且得到目标sql的执行计 ...

  2. powerDesigner的name和comment转化

    name2comment.vbs '****************************************************************************** '* ...

  3. uva12105 Bigger is Better

    更简单的做法:定义状态dp[i][j]表示在已经用了i根火柴的情况下拼出来了剩余部分(是剩余部分,不是已经拼出来了的)为j(需要%m)的最大长度,一个辅助数组p[i][j]表示状态[i][j]的最高位 ...

  4. JavaSE-28 hashCode()方法、equals()方法和==相关概念

    概述 Java中,Object类是所有类的基类:如果一个类没有明确继承其他已定义的类,则默认继承Object类. Object类提供了以下方法,对于其他方法,请参考前期专题描述. hashCode() ...

  5. NET实现谷歌OCR的使用记录(CLOUD VISION API)

    1)购买VPS 2)配置一VPN 建议使用 cisco anycounect  |   ***会连接失败(切记,祭奠浪费的一天)大神可以帮我看下是什么问题 3)进入https://cloud.goog ...

  6. windows cmd 模仿电影黑客

    1.win+R 2.输入cmd 3.按F11进入全屏 4.color a 改变颜色为绿色(可能看起来秀一点) 5.dir/s 查看所有文件,就跑起来了,看起来很酷,但是在懂得人眼里,没什么的(所以只能 ...

  7. Visual Studio 安装VS10x CodeMAP

    最近出差,用的是公司电脑,电脑安装的是Visual Studio 2017 VS10x CodeMap 支持Visual Studio 2010, 2012, 2013, 2015,不支持Visual ...

  8. 计算机网络之TCP拥塞控制

    1. 首先,拥塞控制和流量控制是不一样的. 拥塞控制是防止过多的数据注入到网络中,可以使网络中的路由器或链路不致过载,是一个全局性的过程.  流量控制是点对点通信量的控制,是一个端到端的问题,主要就是 ...

  9. 24. TABLES

    24. TABLES TABLES表提供有关数据库中表的信息. TABLES表有以下列: TABLE_CATALOG :表所属目录的名称.该值始终为def. TABLE_SCHEMA :表所属sche ...

  10. tornado框架基础06-SQLAlchemy连接数据库

    01 ORM 在服务器后台,数据是要存储在数据库的,但是如果项目在开发和部署的时候,是使用的不同的数据库,该怎么办呢?是不是需要把所有的 SQL 语句都再重新写一遍呢? 和数据库相关,不同的数据库需要 ...