Add NETLINK_ROUTE processing to the netlink client code, so that Ethernet
physical-layer up/down events can be tracked. Upper layers will use these events to enable/disable Ethernet connectivity. Change-Id: If07c30c4d79f26cf94eb5597be651ebbf9d072c6
This commit is contained in:
parent
bdd483830d
commit
8418ac8ba5
|
@ -30,17 +30,23 @@ public:
|
|||
const static int NlActionAdd;
|
||||
const static int NlActionRemove;
|
||||
const static int NlActionChange;
|
||||
const static int NlActionLinkDown;
|
||||
const static int NlActionLinkUp;
|
||||
|
||||
NetlinkEvent();
|
||||
virtual ~NetlinkEvent();
|
||||
|
||||
bool decode(char *buffer, int size);
|
||||
bool decode(char *buffer, int size, int format);
|
||||
const char *findParam(const char *paramName);
|
||||
|
||||
const char *getSubsystem() { return mSubsystem; }
|
||||
int getAction() { return mAction; }
|
||||
|
||||
void dump();
|
||||
|
||||
protected:
|
||||
bool parseBinaryNetlinkMessage(char *buffer, int size);
|
||||
bool parseAsciiNetlinkMessage(char *buffer, int size);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -22,9 +22,13 @@ class NetlinkEvent;
|
|||
|
||||
class NetlinkListener : public SocketListener {
|
||||
char mBuffer[64 * 1024];
|
||||
int mFormat;
|
||||
|
||||
public:
|
||||
NetlinkListener(int socket);
|
||||
static const int NETLINK_FORMAT_ASCII = 0;
|
||||
static const int NETLINK_FORMAT_BINARY = 1;
|
||||
|
||||
NetlinkListener(int socket, int format);
|
||||
virtual ~NetlinkListener() {}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -19,12 +19,20 @@
|
|||
#define LOG_TAG "NetlinkEvent"
|
||||
#include <cutils/log.h>
|
||||
|
||||
#include <sysutils/NetlinkListener.h>
|
||||
#include <sysutils/NetlinkEvent.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/if.h>
|
||||
|
||||
const int NetlinkEvent::NlActionUnknown = 0;
|
||||
const int NetlinkEvent::NlActionAdd = 1;
|
||||
const int NetlinkEvent::NlActionRemove = 2;
|
||||
const int NetlinkEvent::NlActionChange = 3;
|
||||
const int NetlinkEvent::NlActionLinkUp = 4;
|
||||
const int NetlinkEvent::NlActionLinkDown = 5;
|
||||
|
||||
NetlinkEvent::NetlinkEvent() {
|
||||
mAction = NlActionUnknown;
|
||||
|
@ -56,7 +64,56 @@ void NetlinkEvent::dump() {
|
|||
}
|
||||
}
|
||||
|
||||
bool NetlinkEvent::decode(char *buffer, int size) {
|
||||
/*
|
||||
* Parse an binary message from a NETLINK_ROUTE netlink socket.
|
||||
*/
|
||||
bool NetlinkEvent::parseBinaryNetlinkMessage(char *buffer, int size) {
|
||||
size_t sz = size;
|
||||
struct nlmsghdr *nh = (struct nlmsghdr *) buffer;
|
||||
|
||||
while (NLMSG_OK(nh, sz) && (nh->nlmsg_type != NLMSG_DONE)) {
|
||||
if (nh->nlmsg_type == RTM_NEWLINK) {
|
||||
int len = nh->nlmsg_len - sizeof(*nh);
|
||||
struct ifinfomsg *ifi;
|
||||
|
||||
if (sizeof(*ifi) <= (size_t) len) {
|
||||
ifi = (ifinfomsg *)NLMSG_DATA(nh);
|
||||
|
||||
if ((ifi->ifi_flags & IFF_LOOPBACK) == 0) {
|
||||
struct rtattr *rta = (struct rtattr *)
|
||||
((char *) ifi + NLMSG_ALIGN(sizeof(*ifi)));
|
||||
len = NLMSG_PAYLOAD(nh, sizeof(*ifi));
|
||||
|
||||
while(RTA_OK(rta, len)) {
|
||||
switch(rta->rta_type) {
|
||||
case IFLA_IFNAME:
|
||||
char buffer[16 + IFNAMSIZ];
|
||||
snprintf(buffer, sizeof(buffer), "INTERFACE=%s",
|
||||
(char *) RTA_DATA(rta));
|
||||
mParams[0] = strdup(buffer);
|
||||
mAction = (ifi->ifi_flags & IFF_LOWER_UP) ?
|
||||
NlActionLinkUp : NlActionLinkDown;
|
||||
mSubsystem = strdup("net");
|
||||
break;
|
||||
}
|
||||
|
||||
rta = RTA_NEXT(rta, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nh = NLMSG_NEXT(nh, size);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse an ASCII-formatted message from a NETLINK_KOBJECT_UEVENT
|
||||
* netlink socket.
|
||||
*/
|
||||
bool NetlinkEvent::parseAsciiNetlinkMessage(char *buffer, int size) {
|
||||
char *s = buffer;
|
||||
char *end;
|
||||
int param_idx = 0;
|
||||
|
@ -92,6 +149,14 @@ bool NetlinkEvent::decode(char *buffer, int size) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool NetlinkEvent::decode(char *buffer, int size, int format) {
|
||||
if (format == NetlinkListener::NETLINK_FORMAT_BINARY) {
|
||||
return parseBinaryNetlinkMessage(buffer, size);
|
||||
} else {
|
||||
return parseAsciiNetlinkMessage(buffer, size);
|
||||
}
|
||||
}
|
||||
|
||||
const char *NetlinkEvent::findParam(const char *paramName) {
|
||||
size_t len = strlen(paramName);
|
||||
for (int i = 0; mParams[i] && i < NL_PARAMS_MAX; ++i) {
|
||||
|
|
|
@ -25,8 +25,9 @@
|
|||
#include <sysutils/NetlinkListener.h>
|
||||
#include <sysutils/NetlinkEvent.h>
|
||||
|
||||
NetlinkListener::NetlinkListener(int socket) :
|
||||
NetlinkListener::NetlinkListener(int socket, int format) :
|
||||
SocketListener(socket, false) {
|
||||
mFormat = format;
|
||||
}
|
||||
|
||||
bool NetlinkListener::onDataAvailable(SocketClient *cli)
|
||||
|
@ -40,13 +41,14 @@ bool NetlinkListener::onDataAvailable(SocketClient *cli)
|
|||
}
|
||||
|
||||
NetlinkEvent *evt = new NetlinkEvent();
|
||||
if (!evt->decode(mBuffer, count)) {
|
||||
int err = evt->decode(mBuffer, count, mFormat);
|
||||
|
||||
if (!err) {
|
||||
SLOGE("Error decoding NetlinkEvent");
|
||||
goto out;
|
||||
} else {
|
||||
onEvent(evt);
|
||||
}
|
||||
|
||||
onEvent(evt);
|
||||
out:
|
||||
delete evt;
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue