其实所谓的开关,就是对底层文件节点的设置。
android\system\netd\server\CommandListener.cpp
int CommandListener::InterfaceCmd::restartModem() {
const char* WM_AW4G = "/sys/kernel/ril_api/ril";
const char* WM_DT4G = "/sys/devices/platform/datang_power/datang";
char MODEM_PATH[512] = {0};
// for example:
// echo 0 > /sys/kernel/ril_api/ril
// sleep little time
// echo 1 > /sys/kernel/ril_api/ril
if (!access(WM_AW4G, F_OK)) {
strcpy(MODEM_PATH, WM_AW4G);
ALOGI("Use WM_AW4G, kernel node: %s", MODEM_PATH);
} else if (!access(WM_DT4G, F_OK)) {
strcpy(MODEM_PATH, WM_DT4G);
ALOGI("Use WM_DT4G, kernel node: %s", MODEM_PATH);
} else {
ALOGE("Can't find modem kernel node,so can't restart modem");
return -1;
}
ALOGI("Now restart modem");
int fd = -1;
fd = open(MODEM_PATH, O_WRONLY);
if (fd < 0) {
ALOGE("Failed to open %s: %s", MODEM_PATH, strerror(errno));
return -1;
}
if (write(fd, "0", 1) != 1) {
ALOGE("Failed to write 0 to %s: %s", MODEM_PATH, strerror(errno));
close(fd);
return -1;
}
// os said need sleep 1s
usleep(500*1000);
usleep(500*1000);
if (write(fd, "1", 1) != 1) {
ALOGE("Failed to write 1 to %s: %s", MODEM_PATH, strerror(errno));
close(fd);
return -1;
}
if (fd > 0) close(fd);
ALOGI("Successful to write restart to %s", MODEM_PATH);
return 0;
}
CommandListener::InterfaceCmd::runCommand
{
// 0 1 2
+ // interface restart modem
+ if ((argc == 3) && !strcmp(argv[1], "restart") && !strcmp(argv[2], "modem")) {
+ if (restartModem()) {
+ cli->sendMsg(ResponseCode::CommandOkay,
+ "restartModem() successful", false);
+ } else {
+ cli->sendMsg(ResponseCode::OperationFailed,
+ "restartModem() failed", false);
+ }
+ return 0;
+ }
}
有了底层的修改,就可以通过上层的NetworkManagementService.java中通过接收广播,或者通过逻辑继续控制。
核心代码: mConnector.execute("interface", "restart", "modem");