Central:ペアリング

自動でペアリングについて

obniz.jsにはペアリングを自動で行う仕組みが入っています。

characterisicsやdescriptorを読み書きする際に、認証エラーが帰ってきた場合、obniz.jsは自動でペアリングを行おうと試みます。自動で行うので、設定は不要です。その代わり、passkey入力やbonding(鍵情報の保存)を行うことはできません

自動ペアリング時の設定はこちらのようになっています

  • IO capability: NoInputNoOutput
  • OOB data: Authentication data not present
  • Authentication requirement: Bonding - No MITM
  • Max encryption key size: 16octet

これ以外の設定(passkeyを入力したいなど)の場合は、マニュアルのペアリングを実行してください。

ペアリングの流れ

ペアリングはペリフェラルが必要だと判断したときにペリフェラルの方から要求されます。つまりいつ行われるかはペリフェラルによります。また、ペアリングはセントラルから意図的に行うこともできます。

ペリフェラルによっては接続時からペアリングが必要となります。通常はそのまま処理されますが、passkeyが必要だったり、LTKを保存したい場合、またはエラーを取得したい場合はconnectWait()関数のオプションとしてペアリングに関する設定が必要です。

pairingOptionで指定する関数はペアリングが必要になったときにのみ呼び出されます。
つまりconnectWait()自体は接続に成功するとすぐに完了となり、任意のタイミングでpairingOption内の関数が呼び出されます。

passkey

いくつかのペリフェラルでペアリング時にpasskey(PINコード)の入力が求められることがあります。obniz.jsではpasskeyCallbackを指定することでpasskeyに対応することができます。

// Javascript Example
await obniz.ble.initWait({});
obniz.ble.scan.onfind = async function(peripheral){
  if(peripheral.localName == "my peripheral"){
    await peripheral.connectWait({
      pairingOption: {
        passkeyCallback: async () => {
          return 012345;
        },
        onPairedCallback: (keys) => {
          console.log(`paired ${keys}`)
        },
        onPairingFailed: () => {
          console.log(`pairing failed`);
        }
      },
    });
  }
}
await obniz.ble.scan.startWait();

LTKを取得

ペアリングした結果のキーはonPairedCallbackで受け取れます。

// Javascript Example
await obniz.ble.initWait({});
obniz.ble.scan.onfind = async function(peripheral){
  if(peripheral.localName == "my peripheral"){
    await peripheral.connectWait({
      pairingOption: {
        passkeyCallback: async () => {
          return 012345;
        },
        onPairedCallback: (keys) => {
          console.log(`paired ${keys}`)
        },
        onPairingFailed: () => {
          console.log(`pairing failed`);
        }
      },
    });
  }
}
await obniz.ble.scan.startWait();

保存されたLTKでのペアリングは以下のように行います。
失敗した場合はonPairingFailed()が呼び出されます。
ただし、成功した場合はonPairedCallback()は呼び出されません。

// Javascript Example
await obniz.ble.initWait({});
obniz.ble.scan.onfind = async function(peripheral){
  if(peripheral.localName == "my peripheral"){
    const keys = '*****';
    await peripheral.connectWait({
      pairingOption: {
        keys,
        onPairingFailed: () => {
          console.log(`pairing failed`);
        }
      },
    });
  }
}
await obniz.ble.scan.startWait();

または、ペリフェラルが接続時にペアリングを必要としない場合はpairingWait()を利用します。

// Javascript Example
const keys =  "xxxxxx"; 
await obniz.ble.initWait({});
obniz.ble.scan.onfind = async function(peripheral){
  if(peripheral.localName == "my peripheral"){
      await peripheral.connectWait();
      console.log("connected");
      await peripheral.pairingWait({ keys });
      console.log("paired");
   }
}
await obniz.ble.scan.startWait();

セントラル側からペアリングを行う

セントラル側から意図的にペアリングを行う場合は、peripheral.pairingWait関数を使用します。

// Javascript Example
await obniz.ble.initWait({});
obniz.ble.scan.onfind = async function(peripheral){
  if(peripheral.localName == "my peripheral"){
      await peripheral.connectWait();
      console.log("success");
      const keys = await peripheral.pairingWait({
        onPairedCallback: (keys) => {
          console.log(`paired ${keys}`)
        },
        onPairingFailed: () => {
          console.log(`pairing failed`);
        }
      });
      // Please store `keys` if you want to bond.
   }
}
await obniz.ble.scan.startWait();

関連の質問