android4.4 dhcp莫名断网

现象

在客户反馈网络问题的时候,发现一个很奇怪的,DHCP情况下,莫名其妙的断网,日志如下

D/dhcp    ( 1767): ===========DHCP stop===interface:eth0=======daemon_cmd:dhcpcd_eth0
D/dhcp    ( 1767): ====func:dhcp_do_request=====
D/dhcp    ( 1767): ===========DHCP==========daemon_cmd:dhcpcd_eth0:-f /system/etc/dhcpcd/dhcpcd.conf -h android-ba7b6b8cf5f0b590 eth0
D/dhcp    ( 1767): ===========DHCP==========daemon_prop_name:init.svc.dhcpcd_eth0, desired_status:running
D/dhcp    ( 1767): 1====DHCP=====Timed out waiting for dhcpcd to start
D/NetUtils( 1767): dhcp_do_request failed : eth0 (new)
E/Ethernet( 1767): DHCP request error:Timed out waiting for dhcpcd to start


D/dhcp    ( 1767): ===========DHCP stop===interface:eth0=======daemon_cmd:dhcpcd_eth0
D/dhcp    ( 1767): ====func:dhcp_do_request=====
D/dhcp    ( 1767): ===========DHCP==========daemon_cmd:dhcpcd_eth0:-f /system/etc/dhcpcd/dhcpcd.conf -h android-ba7b6b8cf5f0b590 eth0
D/dhcp    ( 1767): ===========DHCP==========daemon_prop_name:init.svc.dhcpcd_eth0, desired_status:running
D/dhcp    ( 1767): 1====DHCP=====Timed out waiting for dhcpcd to start
D/NetUtils( 1767): dhcp_do_request failed : eth0 (new)
E/Ethernet( 1767): DHCP request error:Timed out waiting for dhcpcd to start


D/dhcp    ( 1767): ===========DHCP stop===interface:eth0=======daemon_cmd:dhcpcd_eth0

D/dhcp    ( 1767): ====func:dhcp_do_request=====
D/dhcp    ( 1767): ===========DHCP==========daemon_cmd:dhcpcd_eth0:-f /system/etc/dhcpcd/dhcpcd.conf -h android-ba7b6b8cf5f0b590 eth0
D/dhcp    ( 1767): ===========DHCP==========daemon_prop_name:init.svc.dhcpcd_eth0, desired_status:running

超时之后,无论如何网络都不正常,郁闷了好久,最后只能硬着硬皮翻看framework代码,详细的代码分析可以参考别人的博客

https://blog.csdn.net/iampisfan/article/details/51043151
https://blog.csdn.net/IT_xiao_bai0516/article/details/123132036
https://blog.csdn.net/luzze__123/article/details/120826232
https://www.cnblogs.com/schips/p/android_api-property_get-and-property_set.html

我只是总结一下
1 android framework负责在开关网络是启动或者关闭dhcpcd程序,这个程序是开源程序,他的作用就是用来跟dhcp服务器交互的。
2 通信的结果是通过prop机制来通信的,用getprop | grep dhcp 就可以看到他们的通信结果。
3 framework 跟dhcpcd通信是单向的,单向的,单向的!

于是这样就会在某些网络里出现出现奇奇怪怪的问题:
1 dhcpcd 超时退出了,这个为什么出现不太清楚,是在客户环境里出现的,
可以这样确认

shell@sabresd_6dq:/ # ps | grep "dhcp"
dhcp      2222  2221  1032   476   c0141530 402178c4 S /system/bin/dhcpcd

这是正常的样子,我当时没有这个dhcpcd程序了,继续抓日志

130|shell@sabresd_6dq:/ # logcat -s dhcpcd -v time
--------- beginning of /dev/log/system
--------- beginning of /dev/log/main
I/dhcpcd  ( 2160): dhcpcd[2162]: timed out
I/dhcpcd  ( 2160): dhcpcd terminated by exit(1)
I/dhcpcd  ( 3032): dhcpcd[3033]: version 5.5.6 starting
I/dhcpcd  ( 3032): dhcpcd[3033]: eth0: broadcasting for a lease
I/dhcpcd  ( 3032): dhcpcd[3033]: timed out
I/dhcpcd  ( 3032): dhcpcd terminated by exit(1)
I/dhcpcd  ( 3799): dhcpcd[3800]: version 5.5.6 starting
I/dhcpcd  ( 3799): dhcpcd[3800]: eth0: broadcasting for a lease
I/dhcpcd  ( 3799): dhcpcd[3800]: eth0: offered 192.168.1.201 from 192.168.1.1
I/dhcpcd  ( 3799): dhcpcd[3800]: eth0: acknowledged 192.168.1.201 from 192.168.1.1
I/dhcpcd  ( 3799): dhcpcd[3800]: eth0: leased 192.168.1.201 for 300 seconds


I/dhcpcd  ( 4657): dhcpcd[4658]: version 5.5.6 starting
I/dhcpcd  ( 4657): dhcpcd[4658]: eth0: rebinding lease of 192.168.1.201
I/dhcpcd  ( 4657): dhcpcd[4658]: eth0: broadcasting for a lease
I/dhcpcd  ( 4657): dhcpcd[4658]: timed out
I/dhcpcd  ( 4657): dhcpcd terminated by exit(1)

可以看到是超时退出,我只能先解决掉超时的问题,解决方案如下,修改超时时间
vi device/fsl/imx6/etc/init.rc

service dhcpcd_eth0 /system/bin/logwrapper /system/bin/dhcpcd -ABKL -t 0

-t 0 代表了永远不超时
这样一改,就不用超时退出了。

2 但是这样修改之后,所有的网络信息都是正常的,网络通信也是正常的,但是上层页面看不到网络信息,WTF!客户很急的,最后修改framework文件
vi ./frameworks/base/core/java/android/net/EthernetDataTracker.java

//add by wgd 20220727
import android.os.Build;
import java.lang.reflect.Method;
import java.util.Timer;
import java.util.TimerTask;
//end
//txr 20220727 check dhcp need update

private String getDevicePrep(String prep) throws Exception {
 String serial = "unknown";
 Class<?> clazz = Class.forName("android.os.Build");
 Class<?> paraTypes = Class.forName("java.lang.String");
 Method method = clazz.getDeclaredMethod("getString", paraTypes);
 if (!method.isAccessible()) {
     method.setAccessible(true);
 }
 serial = (String) method.invoke(new Build(), prep);
 return serial;
}


private String  lastPropVal = "" ;
private Timer dhcpTimer;

public void  openDhcpCheckTimer(){
 if (dhcpTimer == null){
     dhcpTimer = new Timer();
 }else {
     stopDhcpCheckTimer();
     dhcpTimer = new Timer();
 }
 dhcpTimer.schedule(new TimerTask() {
     @Override
     public void run() {
         Log.d(TAG ,"the timer is run<------------");
         String propVal = "";
         try{
             String propName = "dhcp."+mIface+".result" ;
             propVal = getDevicePrep(propName);
             Log.d(TAG, "**************checkDhcpUpdate propName " + propName + " " + "lastPropVal "  +  lastPropVal + " " + "propVal " + propVal);
                 if( !(lastPropVal.equals("ok"))&& propVal.equals("ok") && !(mNetworkInfo.getDetailedState().equals(DetailedState.CONNECTED)) ){
                    Log.d(TAG, "**************update dhcp " + mIface);
                    mNetworkInfo.setIsAvailable(true);
                    mLinkProperties.setInterfaceName(mIface);
                    mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, mHwAddr);
                    Message msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
                    msg.sendToTarget();
                    sendEthStateChangedBroadcast(ETHER_STATE_CONNECTED);
                }
                lastPropVal = propVal ;
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    },10,10000);
}

private void stopDhcpCheckTimer(){
    if(dhcpTimer!=null){
        dhcpTimer.cancel();
        dhcpTimer = null;
    }
}

//txr end 

public boolean teardown() {
         mTeardownRequested.set(true);
         NetworkUtils.stopDhcp(mIface);
         //txr 20220728 stop check dhcp update
         stopDhcpCheckTimer();
         return true;
     }
     
     
public boolean reconnect() {
         if (mLinkUp) {
             int iface_state = getEthernetIfaceState();
             int carrier_state = getEthernetCarrierState();
             if((iface_state == ETHER_IFACE_STATE_UP) &&
                     (carrier_state == 1)){
                 mTeardownRequested.set(false);
                 runDhcp();
                 //txr add check hdcp update
                 openDhcpCheckTimer();
                }
         }
         return mLinkUp;
     }

先添加一个定时器,去看dhcp.eth0.result是不是变化了,如果变化了 ,就强制上报一个网络信息。

虽然这样问题暂时解决了,但是还是想不通为什么在我们的dhcp环境下没什么问题,但是在客户环境里,竟然30s都获取不到dhcp的ip,郁闷,看各位有什么更好的方案?

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值