BlueTooth流程

2020-06-28 11:15

一、写在前面的话

近来由于项目需求需要搞蓝牙这一块,之前在上家公司带LC(本地连接)组时也做过一点蓝牙,在Android系统中也解过一些bug,但是不够系统,现在正好比较系统的学习蓝牙。

二、蓝牙的协议框架

A2dp Handset opp Hid Health Pan Map Dun... | | |...

CORE Stack Specification |

Host Controller Interface | chip

三、Android 4.4(Kitkat)上蓝牙的启动流程

1.服务启动

系统启动时在SystemServer中注册蓝牙服务管理BluetoothManagerService服务:

if (SystemProperties.get(\ Slog.i(TAG, \

} else if (factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { Slog.i(TAG, \

} else if (!context.getPackageManager().hasSystemFeature (PackageManager.FEATURE_BLUETOOTH)) {

Slog.i(TAG, \ } else if (disableBluetooth) {

Slog.i(TAG, \ } else {

Slog.i(TAG, \

bluetooth = new BluetoothManagerService(context); ServiceManager.addService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE, bluetooth); }

其它进程通过binder机制调用该服务,该服务属于综合服务管理类,包括AdapterService的启动、蓝牙适配器Adapter的管理等。

2.蓝牙启动模式

在4.4上蓝牙的启动模式分两种:QuietEnableMode和普通从“设置”里打开两种方式,前一中方式主要是为了NFC的Handover功能——在传递媒体大文件时nfc会打开蓝牙传送。

3.蓝牙关键服务启动和回调处理

下面就以在“设置”中打开为例描述下蓝牙的启动流程:

1)蓝牙所有的profiles位于上层代码中/packages/apps/Bluetooth目录下,常用的几个profiles包括A2dp、HeadSet、Opp、Hid、Pan等,并且Android 4.4上蓝牙协议栈采用的是BRCM和Google共同开发的bluedroid;

2)启动流程涉及代码结构Settings -> Bluetooth -> framework -> bluedroid -> hci -> chip,启动过程是先启动AdapterService并初始化bluedroid,然后启动所有的profile service(A2dpService、HeadsetService等),

成功加载所支持的profiles后使能bluedroid给蓝牙上电,蓝牙上电成功后回bluedroid回调类com_android_bluetooth_btservice_AdapterService.cpp的接口static void adapter_state_change_callback(bt_state_t status),通过JNI回调通知AdapterStateMachine更新Adapter状态,并且通知注册到AdapterService上回调: void updateAdapterState(int prevState, int newState){ if (mCallbacks !=null) {

int n=mCallbacks.beginBroadcast();

Log.d(TAG,\ for (int i=0; i

mCallbacks.getBroadcastItem(i).onBluetoothStateChange(prevState,newState); } catch (RemoteException e) {

Log.e(TAG, \ } }

mCallbacks.finishBroadcast(); } }

mCallbacks该回调是BluetoothManagerService在成功bind到AdapterService时注册的回调mBluetoothCallback:

case MESSAGE_BLUETOOTH_SERVICE_CONNECTED: {

if (DBG) Log.d(TAG,\

mIsBluetoothServiceConnected = true;

IBinder service = (IBinder) msg.obj; synchronized(mConnection) {

if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {

mBluetoothGatt = IBluetoothGatt.Stub.asInterface(service); break;

} // else must be SERVICE_IBLUETOOTH

//Remove timeout

mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);

mBinding = false;

mBluetooth = IBluetooth.Stub.asInterface(service);

try {

boolean enableHciSnoopLog = (Settings.Secure.getInt(mContentResolver, Settings.Secure.BLUETOOTH_HCI_LOG, 0) == 1);

if (!mBluetooth.configHciSnoopLog(enableHciSnoopLog)) { Log.e(TAG,\ }

} catch (RemoteException e) {

Log.e(TAG,\ }

if (mConnection.isGetNameAddressOnly()) { //Request GET NAME AND ADDRESS Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS); mHandler.sendMessage(getMsg); if (!mEnable) return; }

mConnection.setGetNameAddressOnly(false); //Register callback object try {

mBluetooth.registerCallback(mBluetoothCallback); //注册Adapter状态变更的callback

} catch (RemoteException re) {

Log.e(TAG, \ } ...

而BluetoothManagerService注册该callback的目的是通知系统所有支持的profiles蓝牙的开启状态,用于更新每个profile和对应profile服务的bind,如通知BluetoothHeadset bind到HeadsetService上,通过binder机制获取HeadsetService的句柄进行相关操作: BluetoothHeadset.java

final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback = new IBluetoothStateChangeCallback.Stub() {

public void onBluetoothStateChange(boolean up) {

if (DBG) Log.d(TAG, \ if (!up) {

if (VDBG) Log.d(TAG,\ synchronized (mConnection) {

try {

mService = null;

mContext.unbindService(mConnection); } catch (Exception re) { Log.e(TAG,\ } } } else {

synchronized (mConnection) { try {

if (mService == null) {

if (VDBG) Log.d(TAG,\ doBind();//绑定到HeadsetService }

} catch (Exception re) { Log.e(TAG,\ } } } } };

那么既然profile要去bind到对应的service上,这些profile对应的Sercice又是什么时候注册的呢?

这个很关键,其实在我们使能蓝牙过程中,AdapaterStateMachine处于OffState状态,处理 msg.what == USER_TURN_ON case USER_TURN_ON:

if (DBG) Log.d(TAG,\ notifyAdapterStateChange(BluetoothAdapter.STATE_TURNING_ON); mPendingCommandState.setTurningOn(true); transitionTo(mPendingCommandState);

sendMessageDelayed(START_TIMEOUT, START_TIMEOUT_DELAY);

adapterService.processStart();//启动系统支持的所有profiles的services

对应调用AdapterService的接口:

void processStart() {

if (DBG) debugLog(\

Class[] supportedProfileServices = Config.getSupportedProfiles(); //Initialize data objects

for (int i=0; i < supportedProfileServices.length;i++) {

mProfileServicesState.put(supportedProfileServices[i].getName(),BluetoothAdapter.STATE_OFF); }

mRemoteDevices = new RemoteDevices(mPowerManager, this); mAdapterProperties.init(mRemoteDevices);

if (DBG) {debugLog(\ mBondStateMachine = BondStateMachine.make(this, mAdapterProperties, mRemoteDevices);

mJniCallbacks.init(mBondStateMachine,mRemoteDevices);

//FIXME: Set static instance here??? setAdapterService(this);

//Start profile services

if (!mProfilesStarted && supportedProfileServices.length >0) { //Startup all profile services

setProfileServiceState(supportedProfileServices,BluetoothAdapter.STATE_ON); }else {

if (DBG) {debugLog(\

mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.STARTED)); } }

以上就是profiles对应服务的注册。

3)BluetoothManagerService中处理两个callback:一个是来自BluetoothAdapter实例化时注册的回调mManagerCallback并添加到BluetoothManagerService类private final RemoteCallbackList mCallbacks中,该callback主要用于当BluetoothManagerService成功bind到AdapterService时BluetoothDevice获取AdapterService的句柄(BluetoothDevice获取的过程也是向BluetoothAdapter注册回调的机制);另一个来自于各个profile实现类如BluetoothHeadset注册的callback添加到BluetoothManagerService类private final RemoteCallbackList mStateChangeCallbacks中,用户通知每个profile adapter状态的变化如TURNING_ON、TURN_ON、TURNING_OFF、TURN_OFF等;

4)Bluetooth中采用的回调机的地方太多,从Settings中显示部分就多处采用回调来更新UI显示,如BluetoothSettings父类DeviceListPreferenceFragment在onResume()时向LocalBluetoothEventManager中注册callback: @Override

public void onResume() { super.onResume();

if (mLocalManager == null) return;


BlueTooth流程.doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:霍尔式点火电路最完整解说 - 图文

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: