2021年2月16日火曜日

micro:bitの「Bluetooth UIDをアドバタイズ」、NameSpaceとInstanceは32bitのみ設定可能(その2)


 前回の続きとして、EddyStone受信プログラムを作って、送られてくるパケットをダンプして調べて見ることにする。このとき、判別しやすいようにネームスペースは、
写真01


 「551928628100」は、16進数では「0x8081828384」である。ちなみにmicro:bitのブロックエディタは、数値の入力時には、0xを付けた16進数を受け付けるが、表示は10進数になる。インスタンスは、以下のように「1034851382260」(16進数で0xF0F1F2F3F4)とした。


写真02

 プログラム(リスト01)からダンプしてみると、上記の通りだった。つまり、20Bytes来るけど、先頭の2Bytesは、フレームタイプと送信電力で、Googleのドキュメントが間違っているのではないか(あるいは何かのルールが隠れている)のだと思われる。

プログラム01出力

Length: 2
Type:0x01  # Flags data type value
Data:  06
Length: 3
Type:0x03  # Complete list of 16-bit Service UUIDs data type value
Data:  aa fe
Length:21
Type:0x16  # Service Data data type value = EddyStone-UID
Data:  aa fe 00 f6 00 00 00 00 00 00 81 82 83 84 00 00 f1 f2 f3 f4

最後の行がEddyStone UIDのパケット本体で前回の表04 データ構造と同じになっている。これを見ると、ネームスペース、インスタンスともに最後の4Bytes(つまり32bit)にのみデータが入っていて、micro:bit側で指定した5バイトのデータのうち最後の1バイトが抜けている。
 以下がコードである。

リスト01 microbit-dump.cs

using System;
using Windows.Devices.Bluetooth.Advertisement;
namespace MicroBitAdv {
    class Program {
        //private static BluetoothLEAdvertisementWatcher MyWatcher;
        static void Main(string[] args) {
            BluetoothLEAdvertisementWatcher MyWatcher;
            MyWatcher = new BluetoothLEAdvertisementWatcher();
            MyWatcher.SignalStrengthFilter.SamplingInterval = TimeSpan.FromMilliseconds(100);
            MyWatcher.ScanningMode = BluetoothLEScanningMode.Passive;
            MyWatcher.AdvertisementFilter = new BluetoothLEAdvertisementFilter() {
                Advertisement = new BluetoothLEAdvertisement { ServiceUuids = { new Guid("0000FEAA-0000-1000-8000-00805F9B34FB") } } };
            MyWatcher.Received += WatcherReceived;
            MyWatcher.Start();
            Console.ReadKey();
            MyWatcher.Stop();
        }
        private static void WatcherReceived(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args) {
            ulong MyBtAddress = 0xF5E5E7BD08AE; //<- Your MicroBit Bleutooth Address
            if (args.BluetoothAddress != MyBtAddress) { return; }
            foreach (var x in args.Advertisement.DataSections) {
                var dataReader = Windows.Storage.Streams.DataReader.FromBuffer(x.Data);
                var r = new Byte[x.Data.Length];
                Console.WriteLine($"Length:{x.Data.Length+1,2:##}\nType:0x{x.DataType:X2}");
                dataReader.ReadBytes(r);
                Console.Write("Data:  ");
                for (var i= 0;i < x.Data.Length; i++) {
                    Console.Write($"{r[i]:x2} ");
                }
                Console.WriteLine("");   
            }
            Console.WriteLine("--------------\n");
        }
    }
}

micro:bitのBluetoothアドバタイズ

 micro;bitのBluetoothアドバタイズでは以下のようなJavaScriptの関数が呼ばれる。
 
function bluetooth.advertiseUid(ns: number, instance: number, power: number, connectable: boolean): void

しかし、micro:bitでは、すべての変数は32bit(4バイト)のみ。つまり、この関数の形式では、ネームスペース(ns)にもインスタンスにも32bitしか渡らない。
 ということは、micro:bitのBluetoothアドバタイズとは、

ネームスペース(6~9バイト目)」 とは、EddyStoneのNameSpace10Bytesのうち最後の4Bytes(byte6~9。起点はbyte0)に32bit値を設定できる
インスタンス(2~6バイト)」とは、EddyStoneのInstance 6Bytesのうち最後の4Bytes(byte2~5。起点はbyte0)に32bit値を設定できる

という意味になる。

0 件のコメント:

コメントを投稿