蓝牙配对过程分析(经典蓝牙)

本文详细分析了蓝牙配对的过程,从原生应用设置界面到蓝牙协议栈,涵盖SSP配对方式,包括Numeric Comparison、Passkey Entry、Just Works和Out of Band。讲解了从Android系统的packagesSettings、framework层、aidl文件、Bluetooth包、jini层到hal层的创建绑定调用,以及蓝牙协议栈如何给线程间发送消息和通过HCI向底层发送控制命令。

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

打开手机/手表的蓝牙,就能在列表中看到扫描到的蓝牙,点击就可以实现配对功能。目前手表支持与所有设备的配对,但是仅支持与耳机类型的设备进行连接

安全简易配对SSP(Secure simple pairing),蓝牙2.0之后配对方式,简易安全配对一共有四种,其中Out of Band很少使用到,具体如下:
Numeric Comparison
配对双方都显示一个6位的数字,由用户来核对数字是否一致,并输入Yes/No,两端Yes表示一致即可配对,可以防止中间人攻击。
使用场景:两端设备可以弹出6位十进制数,并且有yes和no按钮。

Passkey Entry
配对目标输入一个在本地设备上显示的6位数字,输入正确即可配对,并可以防止中间人攻击。
使用场景:一端设备可以显示,另一端设备可以输入。

Just Works
不会进行鉴权,不能防止中间人攻击用于配对没有显示没有输入的设备,主动发起连接即可配对,用户看不到配对过程,不可以防止中间人攻击,例如连接蓝牙耳机。
使用场景:用于即不能显示6位随机数,也不能输入的设备。

Out of Band
两设备的通过别的途径交换配对信息,例如一些NFC蓝牙音箱。

一、原生应用设置界面的packages\Settings

目录:android\packages\apps\Settings\src\com\android\settings\bluetooth\BluetoothDevicePreference.java

void onClicked() {
    int bondState = mCachedDevice.getBondState();

    if (mCachedDevice.isConnected()) {
        askDisconnect();//断开连接
    } else if (bondState == BluetoothDevice.BOND_BONDED) {
        mCachedDevice.connect(true);//已经配对了就连接
    } else if (bondState == BluetoothDevice.BOND_NONE) {
        pair();//没有配对的话就去配对
    }
}
private void pair() {
    if (!mCachedDevice.startPairing()) {
        Utils.showError(getContext(), mCachedDevice.getName(),
                R.string.bluetooth_pairing_error_message);
    } else {
        final Context context = getContext();

        SearchIndexableRaw data = new SearchIndexableRaw(context);
        data.className = BluetoothSettings.class.getName();
        data.title = mCachedDevice.getName();
        data.screenTitle = context.getResources().getString(R.string.bluetooth_settings);
        data.iconResId = R.drawable.ic_settings_bluetooth;
        data.enabled = true;

        Index.getInstance(context).updateFromSearchIndexableData(data);
    }
}

Y:\HLOS\frameworks\base\packages\SettingsLib\src\com\android\settingslib\bluetooth\CachedBluetoothDevice.java

public boolean startPairing() {
        // Pairing is unreliable while scanning, so cancel discovery
        if (mLocalAdapter.isDiscovering()) {
            mLocalAdapter.cancelDiscovery();//如果设备正在搜索,就取消搜索
        }

        if (!mDevice.createBond()) {
  //配对
            return false;
        }

        mConnectAfterPairing = true;  // auto-connect after pairing
        return true;
    }
二、framework层配对逻辑

Y:\HLOS\frameworks\base\core\java\android\bluetooth\BluetoothDevice.java

public boolean createBond() {
        if (sService == null) {
            Log.e(TAG, "BT not enabled. Cannot create bond to Remote Device");
            return false;
        }
        try {
            Log.i(TAG, "createBond() for device " + getAddress() +
                    " called by pid: " + Process.myPid() +
                    " tid: " + Process.myTid());
            return sService.createBond(this, TRANSPORT_AUTO);//跨进程调用到AdapterService中的方法
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return false;
    }
三、frameworks的aidl文件
private static IBluetooth sService;

HLOS\frameworks\base\core\java\android\bluetooth\IBluetooth.aidl
boolean createBond(in BluetoothDevice device);
这个是属于跨进程通信的方法,通过IBluetooth.aidl文件,调用到AdapterService.java中的createBond方法

四、从framework跨进程调到packages\Bluetooth

Y:\HLOS\packages\apps\Bluetooth\src\com\android\bluetooth\btservice\AdapterService.java

public boolean createBond(BluetoothDevice device, int transport) {
            if (!Utils.checkCallerAllowManagedProfiles(mService)) {
                Log.w(TAG, "createBond() - Not allowed for non-active user");
                return false;
            }

            AdapterService service = getService();
            if (service == null) return false;
            return service.createBond(device, transport, null);//调用本服务的createBond
        }

同在AdapterService文件下

boolean createBond(BluetoothDevice device, int transport, OobData oobData) {
        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
            "Need BLUETOOTH ADMIN permission");
        DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
        if (deviceProp != null && deviceProp.getBondState() != BluetoothDevice.BOND_NONE) {
            return false;
        }
        // Multicast: Do not allow bonding while multcast
        A2dpService a2dpService = A2dpService.getA2dpService();
        if (a2dpService != null &&
            a2dpService.isMulticastFeatureEnabled() &&
            a2dpService.isMulticastOngoing(null)) {
            Log.i(TAG,"A2dp Multicast is ongoing, ignore bonding");
            return false;
        }

        // Pairing is unreliable while scanning, so cancel discovery
        // Note, remove this when native stack improves
        cancelDiscoveryNative();//配对过程,取消扫描

        Message msg = mBondStateMachine.obtainMessage(BondStateMachine.CREATE_BOND);
        msg.
DCNN在医学图像分析,尤其是胃肠道异常检测方面显示出了巨大的潜力。为了深入理解如何使用DCNN进行模式识别,你可以参考《深度学习驱动的胃肠道异常检测:基于DCNN的内窥镜图像分析》这篇文章。该文详细介绍了如何设计和训练一个专门针对内窥镜图像的DCNN模型,以及如何使用Kvasir数据集进行训练和测试,进而实现高精度的胃肠道异常检测。 参考资源链接:[深度学习驱动的胃肠道异常检测:基于DCNN的内窥镜图像分析](https://wenku.youkuaiyun.com/doc/2kaic5eoqt?spm=1055.2569.3001.10343) 首先,你需要准备Kvasir数据集,这是一个公开的医学图像数据集,包含了多种胃肠道疾病相关的内窥镜图像。在准备数据过程中,可能需要进行图像预处理,如调整图像大小、归一化像素值等,以确保输入网络的图像格式统一且适合模型处理。 接下来,设计DCNN架构是关键。你可以采用一个多路径、多分辨率的卷积神经网络架构。这样的设计能够让网络从不同层次学习到更丰富的图像特征,从而提高模型对胃肠道异常的识别能力。例如,使用多个并行的卷积路径,每个路径对应不同的图像分辨率,可以同时捕捉到宏观和微观的异常特征。 在训练过程中,你需要选择合适的损失函数和优化器。通常,在医学图像分类任务中,交叉熵损失函数是一个不错的选择,而Adam优化器则因其快速收敛的特性而被广泛应用。为了防止过拟合,可以使用如dropout或权重衰减的技术。 训练完成后,你可以使用马修斯相关系数(MCC)等指标来评估模型性能。MCC能够全面考虑真阳性、假阳性、真阴性和假阴性,是评估医学图像分类模型性能的一个重要指标。 最后,为了确保模型具有良好的泛化能力,可以在不同的数据集上进行验证,例如Kvasir-Capsule数据集。这样不仅能够评估模型在不同条件下的表现,还能进一步提高医生对模型诊断结果的信任度。 通过这篇资料,你不仅能够学习到如何使用DCNN进行胃肠道异常图像的模式识别,还能了解到如何优化模型结构和参数,以及如何评估模型性能。这对于希望深入医学图像分析领域的研究者或工程师来说是一个宝贵的资源。 参考资源链接:[深度学习驱动的胃肠道异常检测:基于DCNN的内窥镜图像分析](https://wenku.youkuaiyun.com/doc/2kaic5eoqt?spm=1055.2569.3001.10343)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值