基于rk3288平台android5.1系统的wifi流程分析 ---- 作为AP,启动自动分配ip服务流程

   上一篇博客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<String> 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<RouteInfo> routes = new ArrayList<RouteInfo>();
    // 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<RouteInfo> 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();
                }
            }
        }

以上, 分析到此。 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值