Quantcast
Channel: かずきのBlog@hatena
Viewing all articles
Browse latest Browse all 1387

UWPでBLEのアドバタイジングパケットを拾ってみよう

$
0
0

Windows 10のWindows Runtimeには、BLE関連のAPIがちょろちょろ追加されています。 これを使うと、Windows 8.1の頃にはできなかったBLEのアドバタイジングパケットを受信することが出来ます。

要はiBeaconの電波受信して何かするようなアプリが簡単に組めるっていうことですね。 Windows.Devices.Bluetooth.Advertisement名前空間に各種クラスがあって、ここのBluetoothLEAdvertisementWatcherクラスを使うことでアドバタイジングパケットを受信することが出来ます。

using System;
using System.Linq;
using Windows.Devices.Bluetooth.Advertisement;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;

namespace App29
{
    publicsealedpartialclass MainPage : Page
    {
        private BluetoothLEAdvertisementWatcher watcher;

        public MainPage()
        {
            this.InitializeComponent();

            this.watcher = new BluetoothLEAdvertisementWatcher();

            // CompanyIDとかDataでフィルタリングしたいとき//var md = new BluetoothLEManufacturerData();//// company id 0xFFFF (多分これ https://www.bluetooth.com/specifications/assigned-numbers/company-Identifiers)//md.CompanyId = 0xFFFF; //// data 0x1234//var w = new DataWriter();//w.WriteUInt16(0x1234);//md.Data = w.DetachBuffer();//this.watcher.AdvertisementFilter.Advertisement.ManufacturerData.Add(md);// rssi >= -60のとき受信開始するっぽいthis.watcher.SignalStrengthFilter.InRangeThresholdInDBm = -60;
            // rssi <= -65が2秒続いたら受信終わるっぽいthis.watcher.SignalStrengthFilter.OutOfRangeThresholdInDBm = -65;
            this.watcher.SignalStrengthFilter.OutOfRangeTimeout = TimeSpan.FromMilliseconds(2000);
            this.watcher.Received += this.Watcher_Received;
        }

        private async void Watcher_Received(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args)
        {
            await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
            {
                var md = args.Advertisement.ManufacturerData.FirstOrDefault();
                if (md != null)
                {
                    // ManufactureDataをもとにCompanyIDとったりできる
                }
                this.TextBlockRSSI.Text = $"{args.Timestamp:HH\\:mm\\:ss}, RSSI: {args.RawSignalStrengthInDBm}, Address: {args.BluetoothAddress.ToString("X")}, Type: {args.AdvertisementType}";
            });
        }

        protectedoverridevoid OnNavigatedTo(NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);
            this.watcher.Start();
        }

        protectedoverridevoid OnNavigatedFrom(NavigationEventArgs e)
        {
            base.OnNavigatedFrom(e);
            this.watcher.Stop();
        }
    }
}

InRangeThresholdInDBmとOutOfRangeThresholdInDBmあたりで電波の強度がどれくらいのときに受信するとか指定できるみたいです。あと手持ちのBluetoothの機械だと試せなかったのですがCompanyIDとかでもフィルタリング出来るみたいです。

Receivedイベントでは、イベント引数から各種情報を取得できます。

一応画面のXAMLもはっておきます。TextBlockを置いただけです。

<Pagex:Class="App29.MainPage"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="using:App29"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"mc:Ignorable="d"><Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"><TextBlock x:Name="TextBlockRSSI"Style="{StaticResource HeaderTextBlockStyle}"HorizontalAlignment="Center"VerticalAlignment="Center" /></Grid></Page>

最後に忘れがちなところとして、Package.appxmanifestの機能のタブでBluetoothにチェックを入れておきます。

実行して適当にBluetoothの電波飛ばすデバイスを近づけると以下のように表示されます。

f:id:okazuki:20160214125221p:plain


Viewing all articles
Browse latest Browse all 1387

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>