Provides its own message mechanism in Broadcom, with two message forms: Request/response and Event(event)
request/response Message: the communication between the process is through the SMD, all the messages are sent to the SMD,SMD after receiving the information, if the message is to be SMD to do the corresponding operation, if not, the message route out
Event messages: a process that is interested in certain events can cms_msg_register_event_interest register for this interesting event. When an event occurs, the event information is sent to SMD,SMD and the event information is sent to the process of interest.
1. Realization of the communication between SMD and other processes
SMD Monitoring Messages
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;
}
Other processes connected to Smd:cmsmsg_init
Cmsmsg_init Concrete Implementation
/*
* 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);
}
This establishes the connection of other processes to the SMD, blocking the occurrence of the wait events
/* Pend, waiting for one or more FDS to become ready */
RV = Select (maxfd+1, &readfds, NULL, NULL, &TM);
send and receive messages with Cmsmsg_send cmsmsg_receive, processmessage process Information after an event occurs
2. Communication with the kernel
When the underlying ATM, DSL, and ETH status changes, messages are sent to the SSK,SSK to send the message to the 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 sockets 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 sockets for Kernel Monitor");
Close (KERNELMONITORFD);
KERNELMONITORFD = CMS_INVALID_FD;
return cmsret_internal_error;
}
The KERNELMONITORFD is then added to the select Set, blocking n = Select (Maxfd+1, &readfds, NULL, &errorfds, &TV);
if (Fd_isset (KERNELMONITORFD, &readfds))
{
Processkernelmonitor ();
}
Processkernelmonitor: Polling Information
/* 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. Event Messages
First you need to register an event of interest
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)
{
}
When the dhcp6c changes, send the event information to the 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)
After the SMD receives the event information, find the process of interest to send the information out
Distributeeventmessage
Here cms_msg_dhcp6c_state_changed is registered in SSK, so after Ssk,ssk received the message
#ifdef dmp_x_broadcom_com_ipv6_1/* aka Support_ipv6 */
Case cms_msg_dhcp6c_state_changed:
Processdhcp6cstatechanged (msg);
Break
The message mechanism of Broadcom