3

React Native を使用して Mi Band 3 を認証する方法を見つけるのに数日間苦労しました。接続にはreact-native-ble-plxを使用しています。近くのデバイスを検索したり、バンドに接続したりすることもできますが、何かのサービスや特性を呼び出そうとすると、何かが起こります.

数時間検索したところ、認証に問題がある可能性があることに気付き、それを探し始めましたが、何も見つかりません。これに似た質問を見つけましたが、唯一の答えは「グーグルで検索する」ことでした。

これが私が今持っているものです

const connectToSelectedDevice = async() => {
    try{
        if(selectedDeviceId != 0 ){
            manager.stopDeviceScan()
            manager.connectToDevice(selectedDeviceId).then(async(device)=>{
                const services = await device.discoverAllServicesAndCharacteristics()

                device.monitorCharacteristicForService('0000fee0-0000-1000-8000-00805f9b34fb','0000ff0e-0000-1000-8000-00805f9b34fb',(error, characteristic) => {
                    if (error) {
                        console.error("Error at receiving data from device", error);
                        return
                    }
                    else {
                        console.log('monitor success')
                        console.log('monitor success' + characteristic.value);
                        this.state.messagesRecieved.push(characteristic.value)
                    }
                })

                device.writeCharacteristicWithResponseForService('0000fee0-0000-1000-8000-00805f9b34fb','0000ff0e-0000-1000-8000-00805f9b34fb','AQ==')
                .then(characteristic => {
                    console.log("Successfully sent: " + characteristic.value)
                    return
                })
                .catch(err => {
                    console.log(err)
                })

            })
        }
    }
    catch(error){
        console.log(error);
    }
}
4

1 に答える 1

1

それを考え出した、これが私の解決策です

export const connectToDevice = async(selectedDeviceId,manager,resultFunction) => {  

    manager.stopDeviceScan(), // Since we found the desired device, we stop scanning for devices
    manager.connectToDevice(selectedDeviceId).then(async(device)=>{ //Now we connect to the device

        await device.discoverAllServicesAndCharacteristics() //Before doing anything, we need to discover the device's services and characteristics
        let bluetoothKey = await store.getState().unitInfo.bluetoothKey // This is my 16 bytes key

        device.writeCharacteristicWithoutResponseForService('0000fee1-0000-1000-8000-00805f9b34fb','00000009-0000-3512-2118-0009af100700',btoa('\x01\x00')) // STEP 1 ------ we send \x01\x00, converted to base64
        .catch((e)=>{
            console.log(e);
        })
            
        //Now, we monitor this characteristic, waiting for responses and dealing with them, but Step 2 is below this, because we need to be watching his response
        device.monitorCharacteristicForService('0000fee1-0000-1000-8000-00805f9b34fb', '00000009-0000-3512-2118-0009af100700', (error, characteristic) => { 
            if(error){
                console.log(error);                             
            }
            if(characteristic!= null){                      
                console.log(characteristic) 
                if(characteristic.value == 'EAEB'){         // EAEB means that the band received the key, so we move to the next step and request the band's key
                    requestKey(device)                  
                }
                else if(characteristic.value == 'EAEC'){    // EAEC means the user didn't confirmed the pairing on the band
                    resultFunction(false)
                }
                else if(characteristic.value == 'EAMB'){    // EAMB means the pairing ocurred with success
                    resultFunction(device)  // SUCCESS ------ We store the device object for further use
                }
                else if (characteristic.value == 'EAME'){   // Some error ocurred
                    device.cancelConnection()
                }
                else{ // STEP 4 ------ Happens when the band sends the key we requested
                    sendEncryptedKey(characteristic,bluetoothKey,device)
                }
            }
        })              
                
        let connectionKey = concatArrayAndCommand([1,8],base64ToArrayBuffer(bluetoothKey))              
        device.writeCharacteristicWithoutResponseForService('0000fee1-0000-1000-8000-00805f9b34fb','00000009-0000-3512-2118-0009af100700',arrayToBase64(connectionKey)) // STEP 2 ------ We send \x01\x00 + our key on base64
        .catch((e)=>{
            console.log(e);
        })
        
    }, error => {
        console.log(error)
        resultFunction(false)
    })  
}

const requestKey = (device) =>{ //STEP 3 ------ Requesting band's key, will be watched by our monitor

    device.writeCharacteristicWithoutResponseForService('0000fee1-0000-1000-8000-00805f9b34fb','00000009-0000-3512-2118-0009af100700',btoa('\x02\x00'))     
        .catch((e)=>{
            console.log(e);
        })

}

const sendEncryptedKey = async(characteristic,bluetoothKey,device) => { // STEP 5 ------ One of the most difficult ones, encrypting the band's key, using our key
    let receivedKey = characteristic.value.substring(4) // First we remove the first 4 digits, other result code from the band

    var receivedKeyInBytes = base64ToArrayBuffer(receivedKey)
    var bluetoothKeyInBytes = base64ToArrayBuffer(bluetoothKey)
    
    let encryptor = new aesjs.ModeOfOperation.ecb(bluetoothKeyInBytes);
    let encryptedKeyInBytes = encryptor.encrypt(receivedKeyInBytes);
    let finalValue = concatArrayAndCommand([3,0],encryptedKeyInBytes)

    // After encrypting, we send \x03\x00 + the encoded key 

    device.writeCharacteristicWithoutResponseForService('0000fee1-0000-1000-8000-00805f9b34fb','00000009-0000-3512-2118-0009af100700',arrayToBase64(finalValue))
    .catch((e)=>{
        console.log(e)
    })
}

詳細情報: https://link.medium.com/8cLWEtWlI9

于 2020-09-12T16:35:23.510 に答える