web-dev-qa-db-fra.com

Couplage basse consommation Bluetooth Android

Comment coupler un périphérique Bluetooth Low Energy (BLE) avec Android pour lire des données cryptées.

À l'aide des informations de la page Android BLE , je suis en mesure de découvrir l'appareil, de me connecter, de découvrir des services et de lire des caractéristiques non chiffrées.

Lorsque j'essaie de lire une caractéristique chiffrée (qui oblige iOS à afficher une fenêtre contextuelle demandant d'apparier puis de terminer la lecture), je reçois un code d'erreur 5 correspondant à Authentification insuffisante

Je ne suis pas sûr que comment faire pour que le périphérique soit apparié ou comment fournir les informations d'authentification pour que la lecture se termine}. 

J'ai manipulé BluetoothGattCharacteristics en essayant d'ajouter des descripteurs, mais cela n'a pas fonctionné non plus.
Toute aide est appréciée!

32
Zomb

Lorsque vous obtenez l'erreur GATT_INSUFFICIENT_AUTHENTICATION, le système lance le processus de liaison pour vous. Dans l'exemple ci-dessous, j'essaie d'activer les notifications et les indications sur le moniteur de glycémie. J'active d'abord les notifications sur la caractéristique de mesure du glucose, ce qui peut entraîner l'apparition de l'erreur.

@Override
    public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
        if (status == BluetoothGatt.GATT_SUCCESS) {
            if (GM_CHARACTERISTIC.equals(descriptor.getCharacteristic().getUuid())) {
                mCallbacks.onGlucoseMeasurementNotificationEnabled();

                if (mGlucoseMeasurementContextCharacteristic != null) {
                    enableGlucoseMeasurementContextNotification(gatt);
                } else {
                    enableRecordAccessControlPointIndication(gatt);
                }
            }

            if (GM_CONTEXT_CHARACTERISTIC.equals(descriptor.getCharacteristic().getUuid())) {
                mCallbacks.onGlucoseMeasurementContextNotificationEnabled();
                enableRecordAccessControlPointIndication(gatt);
            }

            if (RACP_CHARACTERISTIC.equals(descriptor.getCharacteristic().getUuid())) {
                mCallbacks.onRecordAccessControlPointIndicationsEnabled();
            }
        } else if (status == BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION) {
            // this is where the tricky part comes

            if (gatt.getDevice().getBondState() == BluetoothDevice.BOND_NONE) {
                mCallbacks.onBondingRequired();

                // I'm starting the Broadcast Receiver that will listen for bonding process changes

                final IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
                mContext.registerReceiver(mBondingBroadcastReceiver, filter);
            } else {
                // this situation happens when you try to connect for the second time to already bonded device
                // it should never happen, in my opinion
                Logger.e(TAG, "The phone is trying to read from paired device without encryption. Android Bug?");
                // I don't know what to do here
                // This error was found on Nexus 7 with KRT16S build of Andorid 4.4. It does not appear on Samsung S4 with Andorid 4.3.
            }
        } else {
            mCallbacks.onError(ERROR_WRITE_DESCRIPTOR, status);
        }
    };

Où le récepteur mBondingBroadcast est:

private BroadcastReceiver mBondingBroadcastReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(final Context context, final Intent intent) {
        final BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
        final int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, -1);
        final int previousBondState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, -1);

        Logger.d(TAG, "Bond state changed for: " + device.getAddress() + " new state: " + bondState + " previous: " + previousBondState);

        // skip other devices
        if (!device.getAddress().equals(mBluetoothGatt.getDevice().getAddress()))
            return;

        if (bondState == BluetoothDevice.BOND_BONDED) {
            // Continue to do what you've started before
            enableGlucoseMeasurementNotification(mBluetoothGatt);

            mContext.unregisterReceiver(this);
            mCallbacks.onBonded();
        }
    }
};

N'oubliez pas de désenregistrer le récepteur de diffusion lorsque vous quittez l'activité. Il se peut que le receveur lui-même ne l'ait pas enregistré.

24
philips77

je pense que le nouvel Android 4.4 fournit la méthode d'appariement. Je rencontre déjà le même problème, alors attendez la mise à jour et espérez que la méthode createBond () soit résolue.

http://developer.Android.com/reference/Android/bluetooth/BluetoothDevice.html#setPairingConfirmation%28boolean%29

1
mcd

Vous aurez peut-être besoin de vérifier le fichier kernel smp.c, quelle méthode pour l'appeler appelle pour l'appariement. 1) clé de passe 2) juste travailler ou etc. J'imagine que s'il est possible d'appeler le niveau de sécurité MIMT et le mot de passe, il n'y aura pas de problème d'authentification. Assurez-vous que tous les indicateurs sont définis pour invoquer les méthodes de clé de passe SMP. suivre en mettant un peu d'impression dans le fichier smp.c.

Une solution qui fonctionne dans ICS: avec l'outil btmgmt sous Android et en le raccordant à des API de chiffrement. avec mot de passe ou toute autre méthode. Ça marche. Vous devrez peut-être ajouter les API de clé de passe dans btmgmt à partir du dernier code bluez.

0
RobinSingh