Android USB Tethering的实现以及代码流程

本文深入分析了USB连接如何影响网络适配器的状态变化,详细介绍了从用户界面到核心内核层的交互过程,包括函数调用、配置更改以及与Android系统的整合。阐述了如何通过sysfs接口调整USB设备的功能,以及如何通过内核的android.c文件实现设备启用和禁用。文章进一步解释了如何在Android系统中将USB连接状态与网络接口状态关联,以及如何通过Netd服务接收和处理网络接口事件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

分析还不是很全,kernel层的代码还在看,同步更新吧


 

直接略过界面层,界面一系列处理后调用Tethering.java的setUsbTethering函数。

public int setUsbTethering(boolean enable) {
    if (VDBG) Log.d(TAG, "setUsbTethering(" + enable + ")");
        UsbManager usbManager = (UsbManager)mContext.getSystemService(Context.USB_SERVICE);
 
    synchronized (mPublicSync) {
        if (enable) {
            if (mRndisEnabled) {
                tetherUsb(true);
            } else {
                mUsbTetherRequested = true;
                usbManager.setCurrentFunction(UsbManager.USB_FUNCTION_RNDIS, false);//一开始因为rndis还没有enable,所以会先设置function
            }
        } else {
            tetherUsb(false);
            if (mRndisEnabled) {
                usbManager.setCurrentFunction(null, false);
            }
            mUsbTetherRequested = false;
        }
    }
        return ConnectivityManager.TETHER_ERROR_NO_ERROR;
}


Java层改变usbfunction,其实就是设置内核提供的接口文件进行操作的

具体可以在init.usbmode.sh里面看到

echo 0 > /sys/class/android_usb/android0/enable
echo ${VENDOR_ID} > /sys/class/android_usb/android0/idVendor
 
if [ ${ENG_PROP} -eq 1 ] ; then
  set_engpid ${USB_FUNCTION}
fi
 
echo ${PID} > /sys/class/android_usb/android0/idProduct
/system/bin/log -t ${TAG} -p i "usb product id: ${PID}"
 
echo 0 > /sys/class/android_usb/android0/bDeviceClass
echo 0 > /sys/class/android_usb/android0/bDeviceSubClass
echo 0 > /sys/class/android_usb/android0/bDeviceProtocol
 
echo ${USB_FUNCTION} > /sys/class/android_usb/android0/functions
/system/bin/log -t ${TAG} -p i "enabled usb functions: ${USB_FUNCTION}"
 
echo 1 > /sys/class/android_usb/android0/enable


首先设置enable0,即断开,然后设置functions等,最后再 将enable设为1,也就是代表连接上了USB。设置enable会调用android.c的enable_store函数,设置fucntions会调用functions_store函数。

android.c里面的代码:

static DEVICE_ATTR(functions, S_IRUGO | S_IWUSR, functions_show, functions_store);
static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, enable_show, enable_store);

functions_store只是把enablefunction存储到一个enabled_list里面。

重点是enable_store函数

static ssize_t enable_store(struct device *pdev, struct device_attribute *attr,
    const char *buff, size_t size)
{
struct android_dev *dev = dev_get_drvdata(pdev);
struct usb_composite_dev *cdev = dev->cdev;
struct android_usb_function *f;
struct android_configuration *conf;
int enabled = 0;
static DEFINE_RATELIMIT_STATE(rl, 10*HZ, 1);
 
if (!cdev)
return -ENODEV;
 
mutex_lock(&dev->mutex);
 
sscanf(buff, "%d", &enabled);
if (enabled && !dev->enabled) {  //enable从0设置为1时进入这个分支
/*
 * Update values in composite driver's copy of
 * device descriptor.
 */
cdev->desc.idVendor = device_desc.idVendor;
cdev->desc.idProduct = device_desc.idProduct;
cdev->desc.bcdDevice = device_desc.bcdDevice;
cdev->desc.bDeviceClass = device_desc.bDeviceClass;
cdev->desc.bDeviceSubClass = device_desc.bDeviceSubClass;
cdev->desc.bDeviceProtocol = device_desc.bDeviceProtocol;
list_for_each_entry(conf, &dev->configs, list_item)
list_for_each_entry(f, &conf->enabled_functions,
enabled_list) {
if (f->enable)
f->enable(f);
}
android_enable(dev);
dev->enabled = true;
} else if (!enabled && dev->enabled) {
android_disable(dev);
list_for_each_entry(conf, &dev->configs, list_item)
list_for_each_entry(f, &conf->enabled_functions,
enabled_list) {
if (f->disable)
f->disable(f);
}
dev->enabled = false;
} else if (__ratelimit(&rl)) {
pr_err("android_usb: already %s\n",
dev->enabled ? "enabled" : "disabled");
}
 
mutex_unlock(&dev->mutex);
 
return size;
}

因为rndis_function没有定义enable函数,所以直接执行android_enable(dev)Rndis_function的定义

static struct android_usb_function rndis_function = {
.name = "rndis",
.init = rndis_function_init,
.cleanup = rndis_function_cleanup,
.bind_config = rndis_function_bind_config,
.unbind_config = rndis_function_unbind_config,
.attributes = rndis_function_attributes,
};

接着看android_enable这个函数

static void android_enable(struct android_dev *dev)
{
struct usb_composite_dev *cdev = dev->cdev;
struct android_configuration *conf;
 
if (WARN_ON(!dev->disable_depth))
return;
 
if (--dev->disable_depth == 0) {
 
list_for_each_entry(conf, &dev->configs, list_item)
usb_add_config(cdev, &conf->usb_config,
android_bind_config);
 
usb_gadget_connect(cdev->gadget);//Enables the D+ (or potentially D-) pullup
}
}


主要是执行了usb_add_config函数,并且将android_bind_config传给了一个函数指针。

Usb_add_configcomposite.c里面的函数

int usb_add_config(struct usb_composite_dev *cdev,
struct usb_configuration *config,
int (*bind)(struct usb_configuration *))
{
。。。。。。
status = bind(config);
。。。。。。
}

这里又回到android.c的android_bind_config函数

android_bind_config调用android_bind_enabled_functions,继续调用每个function自己注册的bind_config函数。这里调用的就是rndis的了。看看该函数rndis_function_bind_config。

static int
rndis_function_bind_config(struct android_usb_function *f,
struct usb_configuration *c)
{
int ret;
struct rndis_function_config *rndis = f->config;
 
if (!rndis) {
pr_err("%s: rndis_pdata\n", __func__);
return -1;
}
 
pr_info("%s MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", __func__,
rndis->ethaddr[0], rndis->ethaddr[1], rndis->ethaddr[2],
rndis->ethaddr[3], rndis->ethaddr[4], rndis->ethaddr[5]);
 
    //初始化一个ethernet-over-usb link
ret = gether_setup_name(c->cdev->gadget, rndis->ethaddr, "usb");
if (ret) {
pr_err("%s: gether_setup failed\n", __func__);
return ret;
}
 
if (rndis->wceis) {
/* "Wireless" RNDIS; auto-detected by Windows */
rndis_iad_descriptor.bFunctionClass =
USB_CLASS_WIRELESS_CONTROLLER;
rndis_iad_descriptor.bFunctionSubClass = 0x01;
rndis_iad_descriptor.bFunctionProtocol = 0x03;
rndis_control_intf.bInterfaceClass =
USB_CLASS_WIRELESS_CONTROLLER;
rndis_control_intf.bInterfaceSubClass =  0x01;
rndis_control_intf.bInterfaceProtocol =  0x03;
}
 
return rndis_bind_config_vendor(c, rndis->ethaddr, rndis->vendorID,
   rndis->manufacturer);
}
 


继续回到kernel来,现在走到了U_ether的gether_setup_name函数 这里有个rndis_function_config,他是在UsbDeviceManager初始化的时候通过sysfs赋值的。UsbDeviceManager的构造函数调用了一个叫initRndisAddress的函数。

int gether_setup_name(struct usb_gadget *g, u8 ethaddr[ETH_ALEN],
const char *netname)
{
struct eth_dev *dev;
struct net_device *net;
int status;
 
if (the_dev)
return -EBUSY;
 
net = alloc_etherdev(sizeof *dev);
if (!net)
return -ENOMEM;
 
dev = netdev_priv(net);
spin_lock_init(&dev->lock);
spin_lock_init(&dev->req_lock);
INIT_WORK(&dev->work, eth_work);
INIT_WORK(&dev->rx_work, process_rx_w);
INIT_LIST_HEAD(&dev->tx_reqs);
INIT_LIST_HEAD(&dev->rx_reqs);
 
skb_queue_head_init(&dev->rx_frames);
 
/* network device setup */
dev->net = net;
snprintf(net->name, sizeof(net->name), "%s%%d", netname);
 
if (get_ether_addr(dev_addr, net->dev_addr))
dev_warn(&g->dev,
"using random %s ethernet address\n", "self");
 
if (get_host_ether_addr(host_ethaddr, dev->host_mac))
dev_warn(&g->dev, "using random %s ethernet address\n", "host");
else
dev_warn(&g->dev, "using previous %s ethernet address\n", "host");
 
if (ethaddr)
memcpy(ethaddr, dev->host_mac, ETH_ALEN);
 
net->netdev_ops = ð_netdev_ops;
 
SET_ETHTOOL_OPS(net, &ops);
 
dev->gadget = g;
SET_NETDEV_DEV(net, &g->dev);
SET_NETDEV_DEVTYPE(net, &gadget_type);
 
status = register_netdev(net); //注册网络设备
if (status < 0) {
dev_dbg(&g->dev, "register_netdev failed, %d\n", status);
free_netdev(net);
} else {
INFO(dev, "MAC %pM\n", net->dev_addr);
INFO(dev, "HOST MAC %pM\n", dev->host_mac);
 
the_dev = dev;
 
/* two kinds of host-initiated state changes:
 *  - iff DATA transfer is active, carrier is "on"
 *  - tx queueing enabled if open *and* carrier is "on"
 */
netif_carrier_off(net);
}
 
return status;
}



Eth_dev结构体包含了一个usb_gadget结构体和net_device结构体 

 

 

 

 

等待补充更新

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

完成后,kernel会发送一个uevent

Netd接收到并处理

void NetlinkHandler::onEvent(NetlinkEvent *evt) {
    const char *subsys = evt->getSubsystem();
 
    if (!strcmp(subsys, "net")) {
        int action = evt->getAction();
        const char *iface = evt->findParam("INTERFACE");
 
        if (action == evt->NlActionAdd) {
            notifyInterfaceAdded(iface);
        } else if (action == evt->NlActionRemove) {
            notifyInterfaceRemoved(iface);
        } else if (action == evt->NlActionChange) {
            evt->dump();
            notifyInterfaceChanged("nana", true);
        } else if (action == evt->NlActionLinkUp) {
            notifyInterfaceLinkChanged(iface, true);
        } else if (action == evt->NlActionLinkDown) {
            notifyInterfaceLinkChanged(iface, false);
        }

void NetlinkHandler::notifyInterfaceAdded(const char *name) {
    char msg[255];
    snprintf(msg, sizeof(msg), "Iface added %s", name);
 
    mNm->getBroadcaster()->sendBroadcast(ResponseCode::InterfaceChange,
            msg, false);
}


接着就调用interfaceAdded

这里是通过socketclients发送消息,NetworkManagementService.java的NetdCallbackReceiver会收到消息,在onEvent中进行处理

public boolean onEvent(int code, String raw, String[] cooked) {
    switch (code) {
        case NetdResponseCode.InterfaceChange:
             /*
              * a network interface change occured
              * Format: "NNN Iface added <name>"
              *         "NNN Iface removed <name>"
              *         "NNN Iface changed <name> <up/down>"
              *         "NNN Iface linkstatus <name> <up/down>"
              */
             if (cooked.length < 4 || !cooked[1].equals("Iface")) {
                 throw new IllegalStateException(
                     String.format("Invalid event from daemon (%s)", raw));
                 }
                 if (cooked[2].equals("added")) {
                     notifyInterfaceAdded(cooked[3]);
                     return true;
                 } else if (cooked[2].equals("removed")) {
                     notifyInterfaceRemoved(cooked[3]);
                     return true;
                 } else if (cooked[2].equals("changed") && cooked.length == 5) {
                     notifyInterfaceStatusChanged(cooked[3], cooked[4].equals("up"));
                     return true;
                 } else if (cooked[2].equals("linkstate") && cooked.length == 5) {
                     notifyInterfaceLinkStateChanged(cooked[3], cooked[4].equals("up"));
                     return true;
                 }
                 throw new IllegalStateException(
                     String.format("Invalid event from daemon (%s)", raw));
                 // break;

private void notifyInterfaceAdded(String iface) {
    final int length = mObservers.beginBroadcast();
    for (int i = 0; i < length; i++) {
        try {
            mObservers.getBroadcastItem(i).interfaceAdded(iface);
        } catch (RemoteException e) {
        }
    }
    mObservers.finishBroadcast();
}


notifyInterfaceAdded会调用到Tethering.java里面的interfaceAdded函数

具体为什么会调用到tethering.java里的函数,是因为ConnectivityService在初始化的时候将Tethering的对象mTethering register到了INetworkManagementService的实例mNetd

ConnectivityService.java

public ConnectivityService(Context context, INetworkManagementService netManager,
        INetworkStatsService statsService, INetworkPolicyManager policyManager,
        NetworkFactory netFactory) {
。。。。。。。。。。
try {
    mNetd.registerObserver(mTethering);
    mNetd.registerObserver(mDataActivityObserver);
} catch (RemoteException e) {
    loge("Error registering observer :" + e);
}


 registerObserver其实是把mTethering放到一个callbacklist里面,调用的时候会从这个list’里面取出来

 

继续看Tethering.java的interfaceAdded

public void interfaceAdded(String iface) {                                                                                         
    boolean found = false;                                                                   
    boolean usb = false;                                                                     
    synchronized (mPublicSync) {                                                             
        if (isWifi(iface)) {                                                                 
            found = true;                                                                    
        }                                                                                    
        if (isUsb(iface)) {                                                                  
            found = true;                                                                    
            usb = true;                                                                      
        }                                                                                    
        if (isBluetooth(iface)) {                                                            
            found = true;                                                                    
        }                                                                                    
        if (found == false) {                                                                
            if (VDBG) Log.d(TAG, iface + " is not a tetherable iface, ignoring");            
            return;                                                                          
        }                                                                                    
                                                                                             
        TetherInterfaceSM sm = mIfaces.get(iface);                                           
        if (sm != null) {                                                                    
            if (VDBG) Log.d(TAG, "active iface (" + iface + ") reported as added, ignoring");
            return;                                                                          
        }                                                                                    
        sm = new TetherInterfaceSM(iface, mLooper, usb);                                     
        mIfaces.put(iface, sm);                                                              
        sm.start();                                                               
    }                                                                                        
}                                                                                            
 

 

<think>好的,我现在需要回答用户关于Android源码中TetheringManager.java的问题。首先,用户问的是“编出来的是什么”,可能是指这个文件编译后生成的功能或作用。我需要先确认TetheringManager.java在Android系统中的角色。 我记得Android的网络共享功能,比如热点、USB网络共享等,可能由Tethering模块处理。TetheringManager可能是管理这些功能的类。接下来,我需要验证这一点。 查阅相关资料,AndroidTethering功能确实由Tethering模块负责,而TetheringManager.java应该是这个模块的一部分。它可能负责启动和停止网络共享,处理状态变化,管理权限等。 然后,我需要考虑这个类与其他组件的关系。例如,它可能调用底层的网络服务,与ConnectivityManager交互,或者处理来自系统设置应用的请求。同时,可能需要权限检查,确保用户有权启用热点。 还需要注意版本差异,不同Android版本中Tethering实现可能有变化。例如,Android 10之后可能重构了部分网络相关的代码TetheringManager可能属于新的结构。 用户可能需要了解这个类的作用、主要功能和使用场景。比如,当用户打开热点时,系统如何通过TetheringManager来配置和启动共享。还可能涉及错误处理,比如没有移动数据时尝试开启热点会失败,这里TetheringManager如何处理这些情况。 最后,要确保用中文解释清楚,结构清晰,分点说明,避免技术术语过多,但保持准确性。同时,检查是否有LaTeX格式,用户没有要求,所以不需要使用数学公式,但需遵循系统级指令中的格式要求。</think>Android源码中的`TetheringManager.java`是Android系统中负责管理**网络共享(Tethering)功能**的核心类。它属于网络模块的一部分,主要功能是控制设备通过Wi-Fi热点、USB或蓝牙共享移动数据给其他设备的能力。 --- ### 主要功能与作用 1. **网络共享模式管理** 支持以下共享方式: - **Wi-Fi热点**(Soft AP) - **USB网络共享** - **蓝牙网络共享** 通过`startTethering()`和`stopTethering()`方法控制共享的启动与停止。 2. **状态监控与回调** 监听共享状态变化(如启用成功/失败、客户端连接等),通过`TetheringEventCallback`向应用层反馈事件。 3. **权限与策略控制** 验证调用方权限(例如`NETWORK_SETTINGS`或`TETHER_PRIVILEGED`),确保只有系统应用或有权限的第三方应用可操作共享功能。 4. **底层网络配置** 与`ConnectivityService`、`NetworkPolicyManager`等底层服务交互,配置NAT规则、IP地址分配等网络参数。 --- ### 代码结构示例 ```java // 启动Wi-Fi热点 tetheringManager.startTethering( TETHERING_WIFI, executor, new TetheringEventCallback() { @Override public void onTetheringStarted() { // 热点启动成功 } @Override public void onTetheringFailed(int error) { // 处理失败(如硬件不支持、无移动数据等) } } ); // 停止共享 tetheringManager.stopTethering(TETHERING_WIFI); ``` --- ### 典型应用场景 1. **系统设置中的热点开关** 当用户在“设置”中启用Wi-Fi热点时,最终会调用`TetheringManager`的方法。 2. **USB连接共享网络** 设备通过USB连接电脑后,自动触发USB网络共享流程。 3. **运营商策略限制** 根据SIM卡签约信息(如是否允许共享)动态禁用/启用功能。 --- ### 关键依赖 - **底层服务**:依赖`ConnectivityService`实现网络配置。 - **硬件抽象层(HAL)**:通过`wpa_supplicant`或`netd`配置Wi-Fi驱动和防火墙规则。 - **权限系统**:与`PackageManager`协作验证调用方身份。 --- ### 注意事项 - **权限要求**:非系统应用需要用户授权(如通过`Settings.ACTION_TETHER_SETTINGS`界面)。 - **兼容性问题**:不同厂商可能定制实现(如热点最大连接数限制)。 如果需要深入分析具体代码逻辑,建议结合AOSP源码中的`TetheringManager.java`及其测试类`TetheringManagerTest.java`进行调试。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值