settings app中点击使能Tether的开关进入到如下函数:
TetherSettings.java:
- private
void setUsbTethering(boolean enabled) { -
ConnectivityManager cm = -
(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE); -
if (cm.setUsbTethering(enabled) != ConnectivityManager.TETHER_ERROR_NO_ERROR) { -
mUsbTether.setChecked(false); -
mUsbTether.setSummary(R.string.usb_tethering_errored_subtext); -
return; -
} -
mUsbTether.setSummary(""); - }
ConnectivityManager cm远程调用
- public
int setUsbTethering(boolean enable) { -
enforceTetherAccessPermi ssion(); -
if (isTetheringSupported()) { -
return mTethering.setUsbTethering(enable); -
} else { -
return ConnectivityManager.TETHER_ERROR_UNSUPPORTED; -
} - }
其中mTethering是一个Tethering对象。
--Tethering.java:
- 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); -
} -
} else { -
tetherUsb(false); -
if (mRndisEnabled) { -
usbManager.setCurrentFunction(null, false); -
} -
mUsbTetherRequested = false; -
} -
} -
return ConnectivityManager.TETHER_ERROR_NO_ERROR; - }
mRndisEnabled表示驱动中USB Tether设备是否成功加载。该变量在以下函数中更新:
- private
class StateReceiver extends BroadcastReceiver { -
public void onReceive(Context content, Intent intent) { -
String action = intent.getAction(); -
if (action.equals(UsbManager.ACTION_USB_STATE)) { -
synchronized (Tethering.this.mPublicSync) { -
boolean usbConnected = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false); -
boolean usbMass = intent.getBooleanExtra(UsbManager.USB_FUNCTION_MASS_STORAGE, false); -
mRndisEnabled = intent.getBooleanExtra(UsbManager.USB_FUNCTION_RNDIS, false); -
-
// start tethering if we have a request pending -
if (usbConnected && mRndisEnabled && mUsbTetherRequested) { -
tetherUsb(true); -
} else if (!usbConnected ) { -
Log.d(TAG, "usb disconnected ,try Tethering down"); -
tetherUsb(false); -
} -
mUsbTetherRequested = false; -
} -
} else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) { -
if (VDBG) Log.d(TAG, "Tethering got CONNECTIVITY_ACTION"); -
mTetherMasterSM.sendMessage(TetherMasterSM.CMD_UPSTREAM_CHANGED); -
} -
} -
}
据实际分析,在USB DeviceManager中发送
代码参考;
- private
void updateUsbState() { -
// send a sticky broadcast containing current USB state -
Intent intent = new Intent(UsbManager.ACTION_USB_STATE); -
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); -
intent.putExtra(UsbManager.USB_CONNECTED, mConnected); -
intent.putExtra(UsbManager.USB_CONFIGURED, mConfigured); -
-
if (mCurrentFunctions != null) { -
String[] functions = mCurrentFunctions.split(","); -
for (int i = 0; i < functions.length; i++) { -
intent.putExtra(functions[i], true); -
} -
} -
-
mContext.sendStickyBroadcast(intent); - }
下面执行到 tetherUsb(true);
- private
void tetherUsb(boolean enable) { -
if (VDBG) Log.d(TAG, "tetherUsb " + enable); -
-
String[] ifaces = new String[0]; -
try { -
ifaces = mNMService.listInterfaces(); -
} catch (Exception e) { -
Log.e(TAG, "Error listing Interfaces", e); -
return; -
} -
for (String iface : ifaces) { -
if (VDBG) Log.d(TAG, "iface = " + iface); -
if (isUsb(iface)) { -
int result = (enable ? tether(iface) : untether(iface)); -
if (result == ConnectivityManager.TETHER_ERROR_NO_ERROR) { -
return; -
} -
} -
} -
Log.e(TAG, "unable start or stop USB tethering"); -
}
ListInterfaces函数会通过socket发送一个
继续执行到
- public
int tether(String iface) { -
if (DBG) Log.d(TAG, "Tethering " + iface); -
TetherInterfaceSM sm = null; -
synchronized (mPublicSync) { -
sm = mIfaces.get(iface); -
-
//add by kondy -
if (sm == null) { -
if (DBG) Log.d(TAG, "try add " + iface); -
interfaceAdded(iface); -
sm = mIfaces.get(iface); -
} -
-
} -
if (sm == null) { -
Log.e(TAG, "Tried to Tether an unknown iface :" + iface + ", ignoring"); -
return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE; -
} -
if (!sm.isAvailable() && !sm.isErrored()) { -
Log.e(TAG, "Tried to Tether an unavailable iface :" + iface + ", ignoring"); -
return ConnectivityManager.TETHER_ERROR_UNAVAIL_IFACE; -
} -
sm.sendMessage(TetherInterfaceSM.CMD_TETHER_REQUESTED); -
return ConnectivityManager.TETHER_ERROR_NO_ERROR; - }
mIfaces记录了netd主动上发了接口
随后应该去看看CMD_TETHER_REQUEST的消息处理了:
- case
CMD_TETHER_REQUESTED: -
setLastError(ConnectivityManager.TETHER_ERROR_NO_ERROR); -
mTetherMasterSM.sendMessage(TetherMasterSM.CMD_TETHER_MODE_REQUESTED, -
TetherInterfaceSM.this); -
transitionTo(mStartingState); -
break;
上面的代码通过transitionTo函数让当前Tether状态从init转换到starting,android的状态机的实现使能执行该函数时会自动释放前一状态使用的资源,并且执行下一个状态的初始化过程。
MstartingState的定义是一个State变量,但是实际是一个子类对象,让SmHandle通过多态进行管理
- mStartingState
= new StartingState(); -
addState(mStartingState);
transitionTo会自动条用
- 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; -
} -
} -
sendTetherStateChangedBr oadcast(); -
-
// Skipping StartingState -
transitionTo(mTetheredState); -
}
enter中通过函数
- 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); -
sendTetherStateChangedBr oadcast(); -
}
其中调用了tetherInterface便是真正执行tether操作的函数了。我们去networkManagerService.java中看看这个函数:
果然!通过发送命令
在netd的CommandListener中会处理这个消息。
CommandListenner.c TetherCmd::runCommand函数中有如下定义:
- else
if (!strcmp(argv[1], "interface")) { -
if (!strcmp(argv[2], "add")) { -
rc = sTetherCtrl->tetherInterface(argv[3]); -
} else if (!strcmp(argv[2], "remove")) { -
rc = sTetherCtrl->untetherInterface(argv[3]); -
} else if (!strcmp(argv[2], "list")) { -
InterfaceCollection *ilist = sTetherCtrl->getTetheredInterfaceList (); -
InterfaceCollection::iterator it; -
-
for (it = ilist->begin(); it != ilist->end(); ++it) { -
cli->sendMsg(ResponseCode::TetherInterfaceListResul t, *it, false); -
} -
} else { -
cli->sendMsg(ResponseCode::CommandParameterError, -
"Unknown tether interface operation", false); -
return 0; -
} -
}
如果命令是add ,则会执行 TetherController 中的
- int
TetherController::tetherInterface(const char *interface) { -
LOGD("tetherInterface [%s]", interface); -
-
//add by kondy -
if (!strcmp(interface, USB_TETHER_INTERFACE)) { -
enableRNDIS(true); -
} -
-
mInterfaces->push_back(strdup(interface)); -
return 0; - }
该函数将参数表示的接口添加进一个队列。注意移植本程序时需要在这个函数中真正开启Tether功能。至于开启的方法则与驱动有关。此处通过调用
至于驱动程序,应该将device模拟成一个USB网卡。网上应该有相关源码,ubuntu可以自动加载驱动,erwindows需要下载一个inf文件手动加载驱动。
至此,从app-> framework ->Native ->驱动接口流程便走通了,至于tether的其他操作莫不遵循此条主线。