【轉】Android4.4(MT8685)源碼藍牙解析--BLE搜索

原文網址:http://blog.csdn.net/u013467735/article/details/41962075java

BLE:全稱爲Bluetooth Low Energy。藍牙規範4.0最重要的一個特性就是低功耗。BLE使得藍牙設備可經過一粒鈕釦電池供電以維持續工做數年之久。很明顯,BLE使得藍牙設備在鐘錶、遠程控制、醫療保健及運動感應器等市場具備極光明的應用場景。android

Google從Android 4.3開始添加了對藍牙4.0的支持。本文一個demo爲入口分析 BLE 搜索的流程。數組

 

[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. package com.dy.ble;  
  2.   
  3. import android.annotation.SuppressLint;  
  4. import android.app.Activity;  
  5. import android.bluetooth.BluetoothAdapter;  
  6. import android.bluetooth.BluetoothDevice;  
  7. import android.os.Bundle;  
  8. import android.util.Log;  
  9. import android.view.View;  
  10. import android.view.View.OnClickListener;  
  11. import android.widget.Button;  
  12.   
  13. public class MainActivity extends Activity {  
  14.     private static final String TAG = "BLE";  
  15.     private Button scanBtn;  
  16.     private BluetoothAdapter bluetoothAdapter;  
  17.       
  18.     @Override  
  19.     protected void onCreate(Bundle savedInstanceState) {  
  20.         super.onCreate(savedInstanceState);  
  21.         setContentView(R.layout.main);  
  22.           
  23.         bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();  
  24.         if(!bluetoothAdapter.isEnabled()){  
  25.             bluetoothAdapter.enable();  
  26.         }  
  27.         scanBtn = (Button) this.findViewById(R.id.btn_scan);  
  28.         scanBtn.setOnClickListener(new OnClickListener(){  
  29.   
  30.             @SuppressLint("NewApi")  
  31.             @Override  
  32.             public void onClick(View arg0) {  
  33.                 if(bluetoothAdapter.isEnabled()){  
  34.                     bluetoothAdapter.startLeScan(callback);  
  35.                 }  
  36.             }  
  37.               
  38.         });  
  39.           
  40.     }  
  41.       
  42.     @SuppressLint("NewApi")  
  43.     private BluetoothAdapter.LeScanCallback callback = new BluetoothAdapter.LeScanCallback(){  
  44.   
  45.         @Override  
  46.         public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {  
  47.             Log.d(TAG, "onLeScan device = " + device + ",rssi = " + rssi + "scanRecord = " + scanRecord);  
  48.         }  
  49.     };  
  50.   
  51. }  

 

 

點擊按鈕就會開始掃描,掃描到設備時,就會觸發onLeScan這個回調方法,而且能夠從參數中獲取掃描到的藍牙設備信息。下面分析BluetoothAdapter中的startLeScan方法。app

 

[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. public boolean startLeScan(LeScanCallback callback) {  
  2.        return startLeScan(null, callback);  
  3.    }  


這裏調用了一個同名的方法,dom

 

 

[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. public boolean startLeScan(UUID[] serviceUuids, LeScanCallback callback) {  
  2.         if (DBG) Log.d(TAG, "startLeScan(): " + serviceUuids);  
  3.   
  4.         if (callback == null) {  
  5.             if (DBG) Log.e(TAG, "startLeScan: null callback");  
  6.             return false;  
  7.         }  
  8.   
  9.         synchronized(mLeScanClients) {  
  10.             if (mLeScanClients.containsKey(callback)) {  
  11.                 if (DBG) Log.e(TAG, "LE Scan has already started");  
  12.                 return false;  
  13.             }  
  14.   
  15.             try {  
  16.                 IBluetoothGatt iGatt = mManagerService.getBluetoothGatt();  
  17.                 if (iGatt == null) {  
  18.                      if (DBG) Log.e("BluetoothAdapterReceiver", "iGatt == null");  
  19.                     // BLE is not supported  
  20.                     return false;  
  21.                 }  
  22.   
  23.                 UUID uuid = UUID.randomUUID();  
  24.                 GattCallbackWrapper wrapper = new GattCallbackWrapper(this, callback, serviceUuids);  
  25.                 iGatt.registerClient(new ParcelUuid(uuid), wrapper);  
  26.                 if (wrapper.scanStarted()) {  
  27.                     if (DBG) Log.e("BluetoothAdapterReceiver", "wrapper.scanStarted()==true");  
  28.                     mLeScanClients.put(callback, wrapper);  
  29.                     return true;  
  30.                 }  
  31.             } catch (RemoteException e) {  
  32.                 Log.e(TAG,"",e);  
  33.             }  
  34.         }  
  35.         return false;  
  36.     }  


這個方法須要BLUETOOTH_ADMIN權限,第一個參數是各類藍牙服務的UUID數組,UUID是「Universally Unique Identifier」的簡稱,通用惟一識別碼的意思。對於藍牙設備,每一個服務都有通用、獨立、惟一的UUID與之對應。也就是說,在同一時間、同一地點,不可能有兩個相同的UUID標識的不一樣服務。第二個參數是前面傳進來的LeScanCallback對象。ide

 

接下來分析下mManagerService,它是一個IBluetoothManager對象,IBluetoothManager是一個AIDL,能夠實現跨進程通訊,其在源碼中的路徑爲:/alps/frameworks/base/core/java/android/bluetooth/IBluetoothManager.aidl。下面來看看mManagerService的實例化,oop

 

[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. BluetoothAdapter(IBluetoothManager managerService) {  
  2.   
  3.        if (managerService == null) {  
  4.            throw new IllegalArgumentException("bluetooth manager service is null");  
  5.        }  
  6.        try {  
  7.            mService = managerService.registerAdapter(mManagerCallback);  
  8.        } catch (RemoteException e) {Log.e(TAG, "", e);}  
  9.        mManagerService = managerService;  
  10.        mLeScanClients = new HashMap<LeScanCallback, GattCallbackWrapper>();  
  11.    }  


直接將BluetoothAdapter構造方法的參數傳給了它,來看看這個參數究竟是什麼?ui

 

 

[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. public static synchronized BluetoothAdapter getDefaultAdapter() {  
  2.         if (sAdapter == null) {  
  3.             IBinder b = ServiceManager.getService(BLUETOOTH_MANAGER_SERVICE);  
  4.             if (b != null) {  
  5.                 IBluetoothManager managerService = IBluetoothManager.Stub.asInterface(b);  
  6.                 sAdapter = new BluetoothAdapter(managerService);  
  7.             } else {  
  8.                 Log.e(TAG, "Bluetooth binder is null");  
  9.             }  
  10.         }  
  11.         return sAdapter;  
  12.     }  


首先經過Binder機制獲取了BLUETOOTH_MANAGER_SERVICE服務的IBinder對象,這個服務是在系統啓動的時候添加進去的,在SystemServer.java中this

 

 

[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. <pre name="code" class="java"> bluetooth = new BluetoothManagerService(context);  
  2.  ServiceManager.addService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE, bluetooth);  

 

 

 

這裏實際就是實例化了一個BluetoothManagerService對象,而後把這個對象經過Binder保存在BLUETOOTH_MANAGER_SERVICE服務中。最後把這個IBinder對象轉化爲IBluetoothManager對象。因此managerService實際就是一個BluetoothManagerService對象。spa

如今回到BluetoothAdapter的startLeScan方法中,

[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. IBluetoothGatt iGatt = mManagerService.getBluetoothGatt();  

這裏實際就是調用BluetoothManagerService中的getBluetoothGatt方法了,咱們進去看看

 

 

[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. public IBluetoothGatt getBluetoothGatt() {  
  2.         // sync protection  
  3.         return mBluetoothGatt;  
  4.     }  


這裏直接返回一個IBluetoothGatt對象,那咱們就來看看這個對象時在哪裏獲得的呢?其實經過對代碼的研究發現, 這個對象是在藍牙開啓的時候獲得的!

 

 

[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. public boolean enable() {  
  2.         if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&  
  3.             (!checkIfCallerIsForegroundUser())) {  
  4.             Log.w(TAG,"enable(): not allowed for non-active and non system user");  
  5.             return false;  
  6.         }  
  7.   
  8.         mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,  
  9.                                                 "Need BLUETOOTH ADMIN permission");  
  10.         if (DBG) {  
  11.             Log.d(TAG,"enable():  mBluetooth =" + mBluetooth +  
  12.                     " mBinding = " + mBinding);  
  13.         }  
  14.         /// M: MoMS permission check @{  
  15.         if(FeatureOption.MTK_MOBILE_MANAGEMENT) {  
  16.             checkEnablePermission();  
  17.             return true;  
  18.         }  
  19.         /// @}  
  20.         synchronized(mReceiver) {  
  21.             mQuietEnableExternal = false;  
  22.             mEnableExternal = true;  
  23.             // waive WRITE_SECURE_SETTINGS permission check  
  24.             long callingIdentity = Binder.clearCallingIdentity();  
  25.             persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);  
  26.             Binder.restoreCallingIdentity(callingIdentity);  
  27.             sendEnableMsg(false);  
  28.         }  
  29.         return true;  
  30.     }  


這是開啓藍牙的代碼,sendEnableMsg(false);這裏看來要發送一個消息,

 

 

[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. private void sendEnableMsg(boolean quietMode) {  
  2.         mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE,  
  3.                              quietMode ? 1 : 0, 0));  
  4.     }  


果真,看看在哪裏接收了

 

 

[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. @Override  
  2.         public void handleMessage(Message msg) {  
  3.             if (DBG) Log.d (TAG, "Message: " + msg.what);  
  4.             switch (msg.what) {  
  5. <span style="white-space:pre">    </span>    case MESSAGE_ENABLE:  
  6.                     if (DBG) {  
  7.                         Log.d(TAG, "MESSAGE_ENABLE: mBluetooth = " + mBluetooth);  
  8.                     }  
  9.                     mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);  
  10.                     mEnable = true;  
  11.                     handleEnable(msg.arg1 == 1);  
  12.                     break;  
[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. <span style="white-space:pre">        </span>}  
  2. }  


進入handleEnable方法看看

 

 

[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. private void handleEnable(boolean quietMode) {  
  2.        mQuietEnable = quietMode;  
  3.   
  4.        synchronized(mConnection) {  
  5.            if (DBG) Log.d(TAG, "handleEnable: mBluetooth = " + mBluetooth +   
  6.                    ", mBinding = " + mBinding + "quietMode = " + quietMode);  
  7.            if ((mBluetooth == null) && (!mBinding)) {  
  8.                if (DBG) Log.d(TAG, "Bind AdapterService");  
  9.                //Start bind timeout and bind  
  10.                Message timeoutMsg=mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);  
  11.                mHandler.sendMessageDelayed(timeoutMsg,TIMEOUT_BIND_MS);  
  12.                mConnection.setGetNameAddressOnly(false);  
  13.                Intent i = new Intent(IBluetooth.class.getName());  
  14.                if (!doBind(i, mConnection,Context.BIND_AUTO_CREATE, UserHandle.CURRENT)) {  
  15.                    mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);  
  16.                    Log.e(TAG, "Fail to bind to: " + IBluetooth.class.getName());  
  17.                } else {  
  18.                    mBinding = true;  
  19.                }  
  20.            } else if (mBluetooth != null) {  
  21.                if (mConnection.isGetNameAddressOnly()) {  
  22.                    // if GetNameAddressOnly is set, we can clear this flag,  
  23.                    // so the service won't be unbind  
  24.                    // after name and address are saved  
  25.                    mConnection.setGetNameAddressOnly(false);  
  26.                    //Register callback object  
  27.                    try {  
  28.                        mBluetooth.registerCallback(mBluetoothCallback);  
  29.                    } catch (RemoteException re) {  
  30.                        Log.e(TAG, "Unable to register BluetoothCallback",re);  
  31.                    }  
  32.                    //Inform BluetoothAdapter instances that service is up  
  33.                    sendBluetoothServiceUpCallback();  
  34.                }  
  35.   
  36.                //Enable bluetooth  
  37.                try {  
  38.                    if (!mQuietEnable) {  
  39.                        if(!mBluetooth.enable()) {  
  40.                            Log.e(TAG,"IBluetooth.enable() returned false");  
  41.                        }  
  42.                    }  
  43.                    else {  
  44.                        if(!mBluetooth.enableNoAutoConnect()) {  
  45.                            Log.e(TAG,"IBluetooth.enableNoAutoConnect() returned false");  
  46.                        }  
  47.                    }  
  48.                } catch (RemoteException e) {  
  49.                    Log.e(TAG,"Unable to call enable()",e);  
  50.                }  
  51.            }  
  52.        }  
  53.    }  


這裏會調用doBinder方法來綁定服務,

 

 

[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. boolean doBind(Intent intent, ServiceConnection conn, int flags, UserHandle user) {  
  2.         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);  
  3.         intent.setComponent(comp);  
  4.         if (comp == null || !mContext.bindServiceAsUser(intent, conn, flags, user)) {  
  5.             Log.e(TAG, "Fail to bind to: " + intent);  
  6.             return false;  
  7.         }  
  8.         return true;  
  9.     }  


這個conn就是mConnection,那麼mConnection是什麼呢?

 

 

[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. private BluetoothServiceConnection mConnection = new BluetoothServiceConnection();  

 

[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. private class BluetoothServiceConnection implements ServiceConnection {  
  2.   
  3.        private boolean mGetNameAddressOnly;  
  4.   
  5.        public void setGetNameAddressOnly(boolean getOnly) {  
  6.            mGetNameAddressOnly = getOnly;  
  7.        }  
  8.   
  9.        public boolean isGetNameAddressOnly() {  
  10.            return mGetNameAddressOnly;  
  11.        }  
  12.   
  13.        public void onServiceConnected(ComponentName className, IBinder service) {  
  14.            if (DBG) Log.d(TAG, "BluetoothServiceConnection: " + className.getClassName());  
  15.            Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED);  
  16.            // TBD if (className.getClassName().equals(IBluetooth.class.getName())) {  
  17.            if (className.getClassName().equals("com.android.bluetooth.btservice.AdapterService")) {  
  18.                msg.arg1 = SERVICE_IBLUETOOTH;  
  19.                // } else if (className.getClassName().equals(IBluetoothGatt.class.getName())) {  
  20.            } else if (className.getClassName().equals("com.android.bluetooth.gatt.GattService")) {  
  21.                msg.arg1 = SERVICE_IBLUETOOTHGATT;  
  22.            } else {  
  23.                Log.e(TAG, "Unknown service connected: " + className.getClassName());  
  24.                return;  
  25.            }  
  26.            msg.obj = service;  
  27.            mHandler.sendMessage(msg);  
  28.        }  
  29.   
  30.        public void onServiceDisconnected(ComponentName className) {  
  31.            // Called if we unexpected disconnected.  
  32.            if (DBG) Log.d(TAG, "BluetoothServiceConnection, disconnected: " +  
  33.                           className.getClassName());  
  34.            Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED);  
  35.            if (className.getClassName().equals("com.android.bluetooth.btservice.AdapterService")) {  
  36.                msg.arg1 = SERVICE_IBLUETOOTH;  
  37.            } else if (className.getClassName().equals("com.android.bluetooth.gatt.GattService")) {  
  38.                msg.arg1 = SERVICE_IBLUETOOTHGATT;  
  39.            } else {  
  40.                Log.e(TAG, "Unknown service disconnected: " + className.getClassName());  
  41.                return;  
  42.            }  
  43.            mHandler.sendMessage(msg);  
  44.        }  
  45.    }  

 

 

如今咱們就知道原來這個mConnection是一個綁定服務的鏈接對象,因此如今BluetoothManagerService綁定了一個IBluetooth的AIDL服務,這時onServiceConnected方法會執行,而且會發送一個MESSAGE_BLUETOOTH_SERVICE_CONNECTED消息,來看接收消息的地方

 

[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. case MESSAGE_BLUETOOTH_SERVICE_CONNECTED:  
  2.                 {  
  3.                     if (DBG) Log.d(TAG,"MESSAGE_BLUETOOTH_SERVICE_CONNECTED: " + msg.arg1);  
  4.   
  5.                     IBinder service = (IBinder) msg.obj;  
  6.                     synchronized(mConnection) {  
  7.                         if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {  
  8.                             mBluetoothGatt = IBluetoothGatt.Stub.asInterface(service);  
  9.                             break;  
  10.                         } // else must be SERVICE_IBLUETOOTH  
  11.   
  12.                         //Remove timeout  
  13.                         mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);  
  14.   
  15.                         mBinding = false;  
  16.                         mBluetooth = IBluetooth.Stub.asInterface(service);  
  17.   
  18.                         try {  
  19.                             boolean enableHciSnoopLog = (Settings.Secure.getInt(mContentResolver,  
  20.                                 Settings.Secure.BLUETOOTH_HCI_LOG, 0) == 1);  
  21.                             if (!mBluetooth.configHciSnoopLog(enableHciSnoopLog)) {  
  22.                                 Log.e(TAG,"IBluetooth.configHciSnoopLog return false");  
  23.                             }  
  24.                         } catch (RemoteException e) {  
  25.                             Log.e(TAG,"Unable to call configHciSnoopLog", e);  
  26.                         }  
  27.   
  28.                         if (mConnection.isGetNameAddressOnly()) {  
  29.                             //Request GET NAME AND ADDRESS  
  30.                             Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);  
  31.                             mHandler.sendMessage(getMsg);  
  32.                             if (!mEnable) return;  
  33.                         }  
  34.   
  35.                         mConnection.setGetNameAddressOnly(false);  
  36.                         //Register callback object  
  37.                         try {  
  38.                             mBluetooth.registerCallback(mBluetoothCallback);  
  39.                         } catch (RemoteException re) {  
  40.                             Log.e(TAG, "Unable to register BluetoothCallback",re);  
  41.                         }  
  42.                         //Inform BluetoothAdapter instances that service is up  
  43.                         sendBluetoothServiceUpCallback();  
  44.   
  45.                         //Do enable request  
  46.                         try {  
  47.                             if (mQuietEnable == false) {  
  48.                                 if(!mBluetooth.enable()) {  
  49.                                     Log.e(TAG,"IBluetooth.enable() returned false");  
  50.                                 }  
  51.                             }  
  52.                             else  
  53.                             {  
  54.                                 if(!mBluetooth.enableNoAutoConnect()) {  
  55.                                     Log.e(TAG,"IBluetooth.enableNoAutoConnect() returned false");  
  56.                                 }  
  57.                             }  
  58.                         } catch (RemoteException e) {  
  59.                             Log.e(TAG,"Unable to call enable()",e);  
  60.                         }  
  61.                     }  
  62.   
  63.                     if (!mEnable) {  
  64.                         waitForOnOff(true, false);  
  65.                         handleDisable();  
  66.                         waitForOnOff(false, false);  
  67.                     }  
  68.                     break;  
  69.                 }  


當msg的參數1爲SERVICE_IBLUETOOTHGATT時,實例化mBluetoothGatt對象,至此咱們就能夠獲得mBluetoothGatt。

 

 

再一次回到BluetoothAdapter的startLeScan方法中,

 

[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. public boolean startLeScan(UUID[] serviceUuids, LeScanCallback callback) {  
  2.         if (DBG) Log.d(TAG, "startLeScan(): " + serviceUuids);  
  3.   
  4.         if (callback == null) {  
  5.             if (DBG) Log.e(TAG, "startLeScan: null callback");  
  6.             return false;  
  7.         }  
  8.   
  9.         synchronized(mLeScanClients) {  
  10.             if (mLeScanClients.containsKey(callback)) {  
  11.                 if (DBG) Log.e(TAG, "LE Scan has already started");  
  12.                 return false;  
  13.             }  
  14.   
  15.             try {  
  16.                 IBluetoothGatt iGatt = mManagerService.getBluetoothGatt();  
  17.                 if (iGatt == null) {  
  18.                      if (DBG) Log.e("BluetoothAdapterReceiver", "iGatt == null");  
  19.                     // BLE is not supported  
  20.                     return false;  
  21.                 }  
  22.   
  23.                 UUID uuid = UUID.randomUUID();  
  24.                 GattCallbackWrapper wrapper = new GattCallbackWrapper(this, callback, serviceUuids);  
  25.                 iGatt.registerClient(new ParcelUuid(uuid), wrapper);  
  26.                 if (wrapper.scanStarted()) {  
  27.                     if (DBG) Log.e("BluetoothAdapterReceiver", "wrapper.scanStarted()==true");  
  28.                     mLeScanClients.put(callback, wrapper);  
  29.                     return true;  
  30.                 }  
  31.             } catch (RemoteException e) {  
  32.                 Log.e(TAG,"",e);  
  33.             }  
  34.         }  
  35.         return false;  
  36.     }  


接着建立了一個GattCallbackWrapper對象,這是個BluetoothAdapter的內部類,主要用於獲取回調信息,而後iGatt註冊一個client,由BluetoothManagerService中的分析可知,iGatt實際是一個GattService內部類BluetoothGattBinder的對象

 

 

[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. public void registerClient(ParcelUuid uuid, IBluetoothGattCallback callback) {  
  2.             GattService service = getService();  
  3.             if (service == null) return;  
  4.             service.registerClient(uuid.getUuid(), callback);  
  5.         }  


這裏仍是調用GattService的registerClient方法

 

 

[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. void registerClient(UUID uuid, IBluetoothGattCallback callback) {  
  2.        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");  
  3.   
  4.        if (DBG) Log.d(TAG, "registerClient() - UUID=" + uuid);  
  5.        mClientMap.add(uuid, callback);  
  6.        gattClientRegisterAppNative(uuid.getLeastSignificantBits(),  
  7.                                    uuid.getMostSignificantBits());  
  8.    }  


這裏面調用了本地方法,對應的JNI文件是Com_android_bluetooth_gatt.cpp,

 

 

[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. static void gattClientRegisterAppNative(JNIEnv* env, jobject object,  
  2.                                         jlong app_uuid_lsb, jlong app_uuid_msb )  
  3. {  
  4.     bt_uuid_t uuid;  
  5.   
  6.     if (!sGattIf) return;  
  7.     set_uuid(uuid.uu, app_uuid_msb, app_uuid_lsb);  
  8.     sGattIf->client->register_client(&uuid);  
  9. }  


分析到這裏其實差很少了,由於這裏系統會調用MTK提供的藍牙庫來實現搜索,源碼咱們沒法看到。

 

 

至此,藍牙BLE搜索分析完畢!

相關文章
相關標籤/搜索