分析还不是很全,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层改变usb的function,其实就是设置内核提供的接口文件进行操作的
具体可以在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
首先设置enable为0,即断开,然后设置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只是把enable的function存储到一个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_config是composite.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
这里是通过socket给clients发送消息,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(); } }