上一篇博客https://blog.csdn.net/ballack_linux/article/details/78112977 分析到开启热点成功了, 虽然可以搜索的到这个热点,但是没法连接上,因为自动分配ip的服务没有启动,这里继续分析该流程。
上一篇结束的时候是处在SoftApStartedState状态下 :
//-------------frameworksopt/net/wifi/service/java/com/android/server/wifi/WifiStateMachine.java-----------------
class SoftApStartingState extends State {
public boolean processMessage(Message message) {
switch(message.what) {
case CMD_START_AP_SUCCESS:
setWifiApState(WIFI_AP_STATE_ENABLED);
transitionTo(mSoftApStartedState);
break;
}
}
}
-> {
class SoftApStartedState extends State {
public boolean processMessage(Message message) {
switch(message.what) {
case CMD_TETHER_STATE_CHANGE:
TetherStateChange stateChange = (TetherStateChange) message.obj;
if (startTethering(stateChange.available)) {
transitionTo(mTetheringState);
}
break;
}
}
}
}
接下来执行startTethering动作:
private boolean startTethering(ArrayList available) {
// wifiRegexs就是支持AP的wlan interface, 在此平台只有一个,即wlan0
String[] wifiRegexs = mCm.getTetherableWifiRegexs();
for (String intf : available) {
for (String regex : wifiRegexs) {
if (intf.matches(regex)) {
InterfaceConfiguration ifcg = null;
try {
ifcg = mNwService.getInterfaceConfig(intf);
if (ifcg != null) {
// 这里就是设置自动分配ip的网段和子网掩码!!!
/* IP/netmask: 192.168.43.1/255.255.255.0 */
ifcg.setLinkAddress(new LinkAddress(
NetworkUtils.numericToInetAddress("192.168.43.1"), 24));
ifcg.setInterfaceUp();
mNwService.setInterfaceConfig(intf, ifcg);
}
} catch (Exception e) {
loge("Error configuring interface " + intf + ", :" + e);
return false;
}
if(mCm.tether(intf) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
loge("Error tethering on " + intf);
return false;
}
mTetherInterfaceName = intf;
return true;
}
}
}
// We found no interfaces to tether
return false;
}
这里执行ConnectivityManager的tether函数:
//-----------frameworks/base/core/java/android/net/ConnectivityManager.java----------
public int tether(String iface) {
try {
return mService.tether(iface);
} catch (RemoteException e) {
return TETHER_ERROR_SERVICE_UNAVAIL;
}
}
//---------frameworks/base/services/core/java/com/android/server/ConnectivityService.java---------
public int tether(String iface) {
ConnectivityManager.enforceTetherChangePermission(mContext);
if (isTetheringSupported()) {
return mTethering.tether(iface);
} else {
return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
}
}
//---------frameworks/base/services/core/java/com/android/server/connectivity/Tethering.java----------
public int tether(String iface) {
if (DBG) Log.d(TAG, "Tethering " + iface);
TetherInterfaceSM sm = null;
synchronized (mPublicSync) {
sm = mIfaces.get(iface);
}
sm.sendMessage(TetherInterfaceSM.CMD_TETHER_REQUESTED);
}
看一下TetherInterfaceSM 状态机 :
//---------frameworks/base/services/core/java/com/android/server/connectivity/Tethering.java---------
TetherInterfaceSM(String name, Looper looper, boolean usb) {
mInitialState = new InitialState();
setInitialState(mInitialState);
}
class InitialState extends State {
public void enter() {
setAvailable(true);
setTethered(false);
sendTetherStateChangedBroadcast();
}
public boolean processMessage(Message message) {
if (DBG) Log.d(TAG, "InitialState.processMessage what=" + message.what);
boolean retValue = true;
switch (message.what) {
case CMD_TETHER_REQUESTED:
setLastError(ConnectivityManager.TETHER_ERROR_NO_ERROR);
// 注意!这里是给mTetherMasterSM发CMD_TETHER_MODE_REQUESTED消息!!!!
mTetherMasterSM.sendMessage(TetherMasterSM.CMD_TETHER_MODE_REQUESTED,
TetherInterfaceSM.this);
transitionTo(mStartingState);
break;
case CMD_INTERFACE_DOWN:
transitionTo(mUnavailableState);
break;
default:
retValue = false;
break;
}
return retValue;
}
}
那么TetherMasterSM如何启动的?
//---------frameworks/base/services/java/com/android/server/SystemServer.java---------
-> startOtherServices
-> {
try {
Slog.i(TAG, "Connectivity Service");
connectivity = new ConnectivityService(
context, networkManagement, networkStats, networkPolicy);
ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);
networkStats.bindConnectivityManager(connectivity);
networkPolicy.bindConnectivityManager(connectivity);
} catch (Throwable e) {
reportWtf("starting Connectivity Service", e);
}
}
//---------frameworks/base/services/core/java/com/android/server/ConnectivityService.java---------
public class ConnectivityService extends IConnectivityManager.Stub
implements PendingIntent.OnFinished {
public ConnectivityService(Context context, INetworkManagementService netManager,
INetworkStatsService statsService, INetworkPolicyManager policyManager) {
mTethering = new Tethering(mContext, mNetd, statsService, mHandler.getLooper());
}
}
//---------frameworks/base/services/core/java/com/android/server/connectivity/Tethering.java---------
public Tethering(Context context, INetworkManagementService nmService,
INetworkStatsService statsService, Looper looper) {
// make our own thread so we don't anr the system
mLooper = IoThread.get().getLooper();
mTetherMasterSM = new TetherMasterSM("TetherMaster", mLooper);
mTetherMasterSM.start();
}
class TetherMasterSM extends StateMachine { TetherMasterSM(String name, Looper looper) {
mInitialState = new InitialState();
setInitialState(mInitialState);
}
可以看到TetherMasterSM状态机初始状态是在mInitialState的 , 那么上面发送的CMD_TETHER_MODE_REQUESTED消息就由它来处理 :
//---------frameworks/base/services/core/java/com/android/server/connectivity/Tethering.java---------
class InitialState extends TetherMasterUtilState {
public boolean processMessage(Message message) {
switch (message.what) {
case CMD_TETHER_MODE_REQUESTED:
TetherInterfaceSM who = (TetherInterfaceSM)message.obj;
if (VDBG) Log.d(TAG, "Tether Mode requested by " + who);
mNotifyList.add(who);
transitionTo(mTetherModeAliveState);
break;
}
}
}
class TetherModeAliveState extends TetherMasterUtilState {
public void enter() {
turnOnMasterTetherSettings(); // may transition us out
startListeningForSimChanges();
mTryCell = !WAIT_FOR_NETWORK_TO_SETTLE; // better try something first pass
// or crazy tests cases will fain
chooseUpstreamType(mTryCell);
mTryCell = !mTryCell;
}
}
-> {
protected boolean turnOnMasterTetherSettings() {
try {
mNMService.setIpForwardingEnabled(true);
} catch (Exception e) {
transitionTo(mSetIpForwardingEnabledErrorState);
return false;
}
try {
mNMService.startTethering(mDhcpRange);
} catch (Exception e) {
try {
mNMService.stopTethering();
mNMService.startTethering(mDhcpRange);
} catch (Exception ee) {
transitionTo(mStartTetheringErrorState);
return false;
}
}
return true;
}
}
这里的mDhcpRange定义如下:
mDhcpRange = context.getResources().getStringArray(
com.android.internal.R.array.config_tether_dhcp_range);
if ((mDhcpRange.length == 0) || (mDhcpRange.length % 2 ==1)) {
mDhcpRange = DHCP_DEFAULT_RANGE;
}
其中:
private static final String[] DHCP_DEFAULT_RANGE = {
"192.168.42.2", "192.168.42.254", "192.168.43.2", "192.168.43.254",
"192.168.44.2", "192.168.44.254", "192.168.45.2", "192.168.45.254",
"192.168.46.2", "192.168.46.254", "192.168.47.2", "192.168.47.254",
"192.168.48.2", "192.168.48.254", "192.168.49.2", "192.168.49.254",
};
好, 接着看:
//---------frameworks/base/services/core/java/com/android/server/NetworkManagementService.java---------
public void setIpForwardingEnabled(boolean enable) {
mConnector.execute("ipfwd", enable ? "enable" : "disable");
}
public void startTethering(String[] dhcpRange) {
final Command cmd = new Command("tether", "start");
for (String d : dhcpRange) {
cmd.appendArg(d);
}
mConnector.execute(cmd);
}
//---------system/netd/server/CommandListener.cpp ---------
int CommandListener::IpFwdCmd::runCommand(SocketClient *cli,
int argc, char **argv) {
if (!strcmp(argv[1], "enable")) {
rc = sTetherCtrl->setIpFwdEnabled(true);
}
}
int CommandListener::TetherCmd::runCommand(SocketClient *cli,
int argc, char **argv) {
if (!strcmp(argv[1], "start")) {
rc = sTetherCtrl->startTethering(num_addrs, addrs);
}
}
//---------system/netd/server/TetherController.cpp ---------
int TetherController::setIpFwdEnabled(bool enable) {
ALOGD("Setting IP forward enable = %d", enable);
int fd = open("/proc/sys/net/ipv4/ip_forward", O_WRONLY); // 允许数据包转发
write(fd, (enable ? "1" : "0"), 1);
}
int TetherController::startTethering(int num_addrs, struct in_addr* addrs) {
ALOGD("Starting tethering services");
pid = fork();
if (!pid) {
int num_processed_args = TETHER_START_CONST_ARG + (num_addrs/2) + 1;
char **args = (char **)malloc(sizeof(char *) * num_processed_args);
args[num_processed_args - 1] = NULL;
args[0] = (char *)"/system/bin/dnsmasq"; // 这里可以看到是在这里执行的dnsmasq!!!
args[1] = (char *)"--keep-in-foreground"; // 这里带了很多参数,都是固定的!!
args[2] = (char *)"--no-resolv";
args[3] = (char *)"--no-poll";
args[4] = (char *)"--dhcp-authoritative";
// TODO: pipe through metered status from ConnService
args[5] = (char *)"--dhcp-option-force=43,ANDROID_METERED";
args[6] = (char *)"--pid-file";
args[7] = (char *)"";
}
int nextArg = TETHER_START_CONST_ARG;
for (int addrIndex=0; addrIndex < num_addrs;) {
char *start = strdup(inet_ntoa(addrs[addrIndex++]));
char *end = strdup(inet_ntoa(addrs[addrIndex++]));
asprintf(&(args[nextArg++]),"--dhcp-range=%s,%s,1h", start, end);
}
execv(args[0], args); // 调用exec函数族替代子进程, 执行dnsmasq进程!!
}
启动这个服务之后, 有设备来连接, 就可以正常分配ip了!!!
接着继续TetherInterfaceSM的 transitionTo(mStartingState);的流程:
//---------frameworks/base/services/core/java/com/android/server/connectivity/Tethering.java---------
class StartingState extends State {
public void enter() {
setAvailable(false);
if (mUsb) {
if (!Tethering.this.configureUsbIface(true)) {
mTetherMasterSM.sendMessage(TetherMasterSM.CMD_TETHER_MODE_UNREQUESTED,
TetherInterfaceSM.this);
setLastError(ConnectivityManager.TETHER_ERROR_IFACE_CFG_ERROR);
transitionTo(mInitialState);
return;
}
}
sendTetherStateChangedBroadcast();
// Skipping StartingState
transitionTo(mTetheredState); // 直接跳转到mTetheredState状态
}
}
class TetheredState extends State {
@Override
public void enter() {
try {
mNMService.tetherInterface(mIfaceName);
} catch (Exception e) {
Log.e(TAG, "Error Tethering: " + e.toString());
setLastError(ConnectivityManager.TETHER_ERROR_TETHER_IFACE_ERROR);
transitionTo(mInitialState);
return;
}
if (DBG) Log.d(TAG, "Tethered " + mIfaceName);
setAvailable(false);
setTethered(true);
sendTetherStateChangedBroadcast();
}
}
//---------frameworks/base/services/core/java/com/android/server/NetworkManagementService.java---------
public void tetherInterface(String iface) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
try {
mConnector.execute("tether", "interface", "add", iface); // 添加接口
} catch (NativeDaemonConnectorException e) {
throw e.rethrowAsParcelableException();
}
List routes = new ArrayList();
// The RouteInfo constructor truncates the LinkAddress to a network prefix, thus making it
// suitable to use as a route destination.
routes.add(new RouteInfo(getInterfaceConfig(iface).getLinkAddress(), null, iface)); // 添加路由表项
addInterfaceToLocalNetwork(iface, routes); // 将接口添加到本地网络
}
-> {
public void addInterfaceToLocalNetwork(String iface, List routes) {
modifyInterfaceInNetwork("add", "local", iface);
for (RouteInfo route : routes) {
if (!route.isDefaultRoute()) {
modifyRoute("add", "local", route);
}
}
}
}
-> {
private void modifyInterfaceInNetwork(String action, String netId, String iface) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
try {
mConnector.execute("network", "interface", action, netId, iface);
} catch (NativeDaemonConnectorException e) {
throw e.rethrowAsParcelableException();
}
}
}
以上, 分析到此。