上一篇我们按照函数的调用流程,完成了由NetlinkManager,NetlinkHandler,NetlinkListener,SocketListener组成的,从kernel到framework的单项消息通路。主要是通过内部的socket实现的通信。通过设置socket监听过滤属性,来接收kernel发出的event,(其中kernel发出的event部分不用了解,可以理解为是自发的)。并通过对于公共库的函数SocketListener的继承,函数重写。实现事件分析,并传递给framework层。
- /
-
dispatchCommand(c, buffer + offset); -
offset = i + 1; -
} -
} -
return true; - }
- void
FrameworkListener::dispatchCommand(SocketClient *cli, char *data) { -
FrameworkCommandCollecti on::iterator i; -
int argc = 0; -
char *argv[FrameworkListener::CMD_ARGS_MAX]; -
char tmp[255]; -
char *p = data; -
char *q = tmp; -
char *qlimit = tmp + sizeof(tmp) - 1; -
bool esc = false; -
bool quote = false; -
int k; -
bool haveCmdNum = !mWithSeq; -
-
memset(argv, 0, sizeof(argv)); -
memset(tmp, 0, sizeof(tmp)); -
while(*p) { -
if (*p == '\\') { //if (*p == '\') -
if (esc) { -
if (q >= qlimit) -
goto overflow; -
*q++ = '\\'; / -
SLOGE("Faking a timeout"); -
goto out; -
} -
//只要是注册进来的命令都会进行调用rumcommand() -
for (i = mCommands->begin(); i != mCommands->end(); ++i) { -
FrameworkCommand *c = *i; -
if (!strcmp(argv[0], c->getCommand())) { - ////////////////////////////////////////////////////////////////////////////
-
if (c->runCommand(cli, argc, argv)) {// runcommand() //// - ////////////////////////////////////////////////////////////////////////////
-
SLOGW("Handler '%s' error (%s)", c->getCommand(), strerror(errno)); -
} -
goto out; -
} -
} -
-
cli->sendMsg(500, "Command not recognized", false); - out:
-
int j; -
for (j = 0; j < argc; j++) -
free(argv[j]); -
return; -
- overflow:
-
LOG_EVENT_INT(78001, cli->getUid()); -
cli->sendMsg(500, "Command too long", false); -
goto out;//错误处理 - }
- //CommandListener::XXXCmd.runCommand()
- int
CommandListener::IpFwdCmd::runCommand(SocketClient *cli, -
int argc, char **argv) { -
int rc = 0; -
-
if (argc < 2) { -
cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); -
return 0; -
} -
-
if (!strcmp(argv[1], "status")) { -
char *tmp = NULL; -
-
asprintf(&tmp, "Forwarding %s", (sTetherCtrl->getIpFwdEnabled() ? "enabled" : "disabled")); -
cli->sendMsg(ResponseCode::IpFwdStatusResult, tmp, false); -
free(tmp); -
return 0; -
} else if (!strcmp(argv[1], "enable")) { -
rc = sTetherCtrl->setIpFwdEnabled(true); -
} else if (!strcmp(argv[1], "disable")) { -
rc = sTetherCtrl->setIpFwdEnabled(false); -
} else { -
cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown ipfwd cmd", false); -
return 0; -
} -
-
if (!rc) { -
cli->sendMsg(ResponseCode::CommandOkay, "ipfwd operation succeeded", false); -
} else { -
cli->sendMsg(ResponseCode::OperationFailed, "ipfwd operation failed", true); -
} -
-
return 0; - }