OS: Android 6.0
Kernel: 3.10.92
之前分析了WiFi的连接,连接上之后会获取ip地址.
自从Android6.0之后,Google引入了一个new DHCP client,它的代码都是融入在JAVA Framework中,而旧的则是以service: /system/bin/dhcpcd的形式存在,代码用C实现.
不知道引入new dchp client带来了什么好处,但是发现部分网友有遇到获取IP address失败的情况。
而是否用new DHCP client可以在Settings中的开发者选项里做切换:
下面是New DHCP Client的代码调用过程:
enter -> WifiStateMachine.java //ObtainingIpState
startDhcp -> //动态获取ip
maybeInitDhcpStateMachine -> //创建dhcp状态机
DhcpClient.makeDhcpStateMachine ->
new DhcpClient ->
createStateMachineCommandIntent //创建“KICK”intent后面用来处理packet
setInitialState(mStoppedState); //默认是mStoppedState状态
client.start ->
smh.completeConstruction //开始DhcpClient的状态运行
mDhcpStateMachine.sendMessage -> //DhcpStateMachine.CMD_START_DHCP
processMessage -> DhcpClient.java //StoppedState
transitionTo(mWaitBeforeStartState) ->
enter -> WaitBeforeStartState没有enter,调用父类DhcpState
initInterface ->
mIface.getHardwareAddress //获得Mac地址
initSockets //ReceiveThread用来读取ipaddress
new ReceiveThread
mReceiveThread.start ->
run //ReceiveThread开始运行
mController.sendMessage(DhcpStateMachine.CMD_PRE_DHCP_ACTION) ->
processMessage -> L2ConnectedState
handlePreDhcpSetup ->
mWifiP2pChannel.sendMessage -> //DhcpStateMachine.CMD_PRE_DHCP_ACTION_COMPLETE
processMessage -> //WaitBeforeStartState的父类WaitBeforeOtherState
transitionTo(mOtherState) -> //mOtherState在WaitBeforeStartState初始化的时候赋值,是DhcpInitState
super.enter ->
enter -> //PacketRetransmittingState
sendMessage(CMD_KICK) ->
processMessage ->
sendPacket ->
sendDiscoverPacket ->
DhcpPacket.buildDiscoverPacket -> //制作一个packet
buildDiscoverPacket ->
new DhcpDiscoverPacket ->
super -> //调用父类构造函数
DhcpPacket
pkt.buildPacket ->
buildPacket -> DhcpDiscoverPacket.java
fillInPacket -> //这个函数没看太明白是如何具体ip address的,貌似和upd协议有关
mClientIp.getAddress
transmitPacket ->
Os.sendto -> //发送给前面一直等待的ReceiveThread
Os.read -> //读取packet
DhcpPacket.decodeFullPacket //解包
sendMessage -> //CMD_RECEIVED_PACKET
processMessage -> //PacketRetransmittingState
receivePacket -> //DhcpInitState
packet.toDhcpResults //获得ipaddress
transitionTo(mDhcpRequestingState) ->
enter -> //又调用了DhcpRequestingState的父类PacketRetransmittingState再发一次CMD_KICK
sendRequestPacket -> 申请此IP
DhcpPacket.buildRequestPacket ->
transmitPacket -> //DhcpRequestingState
...... //中间步骤和上面一样
receivePacket -> //DhcpRequestingState, 确认租用此IP
packet.toDhcpResults
transitionTo(mDhcpBoundState) ->
enter -> //DhcpBoundState
notifySuccess -> //通知wifi状态机完成
mController.sendMessage -> //DhcpStateMachine.CMD_POST_DHCP_ACTION
handlePostDhcpSetup
handleIPv4Success
参考:
The new DHCP Client?How to Fix Wifi Stuck "Obtaining IP Address"
Fix: Cannot connect to Wi-Fi after Marshmallow Update