28

私は BluetoothLE センサー デバイスに取り組んでいます。このデバイスでは、1 対多のデー​​タ ブロードキャストを形成する必要があります。仕様によると、ペリフェラルは 1 つのマスターしか持つことができず、私が設計しているチップとスタックの制限により、マスターは 3 つのスレーブしか持つことができません。私が理解していることから、Android はとにかく BLE スレーブになることはできないため、デバイスをマスターにすることはできません。

BT4 の仕様と製造元のドキュメントの両方で、ブロードキャスト モードと呼ばれる別の動作モードについて説明しています。ブロードキャスト モードでは、接続は確立されず、アプリケーション データはアドバタイジング パケットの一部として送信されます。多くの Android/iOS 携帯電話が各パケットを同時にスキャンできるため、これは私のニーズにぴったりです。アドバタイジング パケットはバーストで複数回送信されるため、データの受信はほぼ確実であると思われます。パケットがあちこちで失われても、許容できます。

これが興味深いのは、これらのパケットが 10 ~ 20Hz のレートで更新されるライブ センサー データを運ぶことです。Web で見つけた例によると、このモードの BLE は主に、静的データをブロードキャストする「iBeacon」タイプの実装に使用されています。Android スタック内でアドバタイジング パケットがどのようにフィルタリングされるかに関する情報が見つかりません。Bluetooth ハードウェア アドレスごとに 1 つの結果を返すか、アドレスとデータの一意の組み合わせである可能性があります。このアプリケーションでは、2 番目のオプションが有効です。スキャンの開始と停止によってフィルターがリセットされる場合は、何かを機能させることもできます。

Android のドキュメントでは、スキャン メソッドでのデバイス フィルタリングの仕組みについては何も言及されていません。この同じ問題を解決しようとしているネット上の 1 つの投稿を見つけることができましたが、これには未解決の応答があります: BLE: Multiple discovery of the sameperipheral during scan。iOS では、これを可能にするスキャン関数に渡すことができるパラメータがあることを同僚が教えてくれました。

Android ソースの startLeScan() 呼び出しからコードをさかのぼって追跡しようとしましたが、コードは非常に複雑で、抽象化を使用しているため、それを含むオブジェクトの実装を識別するのが困難です。私が得た最も遠いものは、BluetoothManagerService クラス メソッド getBluetoothGatt() から返された IBluetoothGatt オブジェクトです。このオブジェクトは、スキャンの開始要求を受け取ります。github にある現在のリビジョンの BluetoothManagerService.java の 790 行付近でインスタンス化されています。オブジェクトはメッセージの結果からキャストされているため、結果は電話/ドライバー固有のものである可能性があります。これ以上追跡できるかどうかは、私の専門外です。

解決したいもう 1 つの問題は、スキャンのオンとオフをどれだけ迅速に切り替えることができるかということです。スキャンは電力を大量に消費する操作ですが、データのブロードキャストはかなり正確なリアルタイム タイマーで定期的に行われます。その結果、ブロードキャストとスキャンが同期され、残りの 90% 以上の時間はスキャナーがシャットダウンされるように、スキャンのオンとオフを切り替えることができれば、最適化に最適です。これはおそらく実験的にテストする必要があります。

Android用のアクセサリでこれが可能かどうかを確認するために、まだ実現可能性の調査を行っています. 私の現在の電話はまだバージョン 4.3 を実行できないため、これを実験的にテスト/ハッキングする方法がありません。

4

5 に答える 5

15

重複広告レポートに関する Bluetooth 仕様 (Core_v4.1.pdf) の 2535 ~ 2536 ページのテキストは、やや不明確です。ただし、1258 ページのテキストは明確です。HCI_LE_Set_Scan_Enable コマンドに Filter_Duplicates パラメーターを指定します。Android バージョン 4.4 (Kitkat) では、このパラメーターは 0x00 (重複フィルターが無効) です。

Android バージョン 4.4 (Kitkat) の Bluetooth チップでフィルタリングが行われているかどうかを確認する簡単な方法があります。電話を開発者用電話にし、開発者向けオプションを入力して、[Bluetooth HCI スヌープ ログを有効にする] をオンにします。次に、Bluetoothを一度オフにしてからオンにして、設定をバイトにします。これ以降、アプリケーション プロセッサと Bluetooth チップの間のすべての HCI パケットは、電話機の adb pull storage/emulated/legacy/btsnoop_hci.log によってプルされるファイルに保存されます。これはテキスト ファイルではなく、 http://www.fte.com/products/default.aspxからのプログラムが必要です。またはwiresharkでbtsnoop_hci.logを表示します。古いバージョンは BLE をサポートしていないため、Wireshark の場合はかなり新しいバージョンが必要です。私の経験では、Bluetooth チップにはフィルタリングがまったくありません。つまり、Bluetooth チップが受信する ADV_IND および ADV_NONCONN_IND ごとに、HCI イベント「LE Advertising Report Event」が送信されます。これは、Bluetooth チップ Qualcomm/Atheros WCN 3680 および Broadcom BCM 4339 を搭載した電話に当てはまります。

訂正: btsnoop_hci.log へのパスは、電話の製造元によって異なる場合があります。adb shell cat etc/bluetooth/bt_stack.conf |で正しいパスを見つけることができます。grep BtSnoopFileName

于 2014-04-25T10:14:47.233 に答える
8

私は BLE を使用して Android 4.3 (Nexus 4&7) 用のアプリケーションを開発しています。私の観察から、SCAN REQUEST が周辺機器に送り返されなかった場合、スキャンは同じデバイスを複数回返します。

デバイスは、パッシブとアクティブの 2 つの方法でアドバタイズできます。パッシブ モードでは、周辺機器はすべてのデータをアドバタイズするだけで、定期的なパケットを送信した後はリッスンしません。送信、スリープ、送信、スリープ... アクティブ モードでは、センサーもアドバタイズしますが、メッセージはできるだけ短くします。送信後、非常に短い時間リッスンに切り替わります。スキャンがショート メッセージを検出すると、すぐに SCAN REQUEST コマンドを周辺機器に送信し、詳細な応答を取得します。私が見る限り、Android は 1 回のスキャン中に SCAN REQUEST を複数回送信していません。

範囲内に 2 つのデバイスがあるとします。1 つは fe Nordic の nRF Temp センサー (パッシブ広告) で、もう 1 つは接続可能なデバイスです。次のスキャン応答を受け取りました。

11-10 21:32:54.281: D/BluetoothAdapter(13468): startLeScan(): null
11-10 21:32:54.281: D/BluetoothAdapter(13468): onClientRegistered() - status=0 clientIf=4
11-10 21:32:54.321: D/BluetoothAdapter(13468): onScanResult() - Device=CD:61:1A:A8:BC:BE RSSI=-94
11-10 21:32:55.122: D/BluetoothAdapter(13468): onScanResult() - Device=CB:32:81:CF:FD:00 RSSI=-61
11-10 21:32:56.414: D/BluetoothAdapter(13468): onScanResult() - Device=CB:32:81:CF:FD:00 RSSI=-62
11-10 21:32:57.715: D/BluetoothAdapter(13468): onScanResult() - Device=CB:32:81:CF:FD:00 RSSI=-61
11-10 21:32:59.016: D/BluetoothAdapter(13468): onScanResult() - Device=CB:32:81:CF:FD:00 RSSI=-63
11-10 21:33:01.609: D/BluetoothAdapter(13468): onScanResult() - Device=CB:32:81:CF:FD:00 RSSI=-63
11-10 21:33:02.901: D/BluetoothAdapter(13468): onScanResult() - Device=CB:32:81:CF:FD:00 RSSI=-63
11-10 21:33:04.212: D/BluetoothAdapter(13468): onScanResult() - Device=CB:32:81:CF:FD:00 RSSI=-62
11-10 21:33:04.282: D/BluetoothAdapter(13468): stopLeScan()

ご覧のとおり、接続可能なデバイスは 1 回だけ表示され、他のデバイスは 7 回表示されました。

私が解決したいもう 1 つの問題は、スキャンのオンとオフをどれだけ迅速に切り替えることができるかということです。スキャンは電力を大量に消費する操作ですが、データのブロードキャストはかなり正確なリアルタイム タイマーで定期的に行われます。その結果、ブロードキャストとスキャンが同期され、残りの 90% 以上の時間はスキャナーがシャットダウンされるように、スキャンのオンとオフを切り替えることができれば、最適化に最適です。これはおそらく実験的にテストする必要があります。

スキャン頻度はデバイスによって異なります。さらに、広告は通常、37、38、39 の 3 つのチャネルで行われ、発見される可能性が高くなります。ただし、「アクティブな」デバイスからアドバタイジング パケットを複数回取得するには、これは非常に良い考えです。

于 2013-11-10T21:12:56.330 に答える
6

実際のBluetooth仕様は次のように述べています:

重複した広告レポートをホストに送信する必要はありません。 複製されたアドバタイジング レポートは、リンク層がスキャン状態にある間、同じデバイス アドレスに対するアドバタイジング レポートです。広告データは変更される場合があります。広告データまたはスキャン応答データは、重複広告レポートを決定する際に重要とは見なされません。

仕様によると、これはスキャン期間内に適用されます。これを回避する正しい方法は、広告を受信するたびにスキャンを停止して再開することです.

BLE に関する私の経験に基づくと、広告で変数データを送信することはあまり良い考えではないようです。ほとんどすべては、広告からのデータが変更されないことを前提としています。実際に変数データ (温度計の読み取り値など) を送信したい場合は、実際にデバイスに接続し、特性を介して送信する方がはるかに優れています。より信頼性が高く、消費電力がはるかに少なくなります。欠点は、一度に 8 台のデバイスにしか接続できないことです。

アドバタイズメントは、デバイスの存在を検出して識別するためのものです。

于 2014-04-21T01:01:03.227 に答える
0

iOS では、このフラグの名前はCBCentralManagerScanOptionAllowDuplicatesKey. これを scan 関数に渡すと、アドバタイズ パケットごとに通知が発生します。Android で同様のフラグが見つかりませんでした。

于 2013-11-07T11:10:42.637 に答える