C# WPF BLE 独自のサービスIDのデバイスにReadValueAsync()で値を取得すると"Access Denied"になる。

YOSHI 0 評価のポイント
2025-07-15T08:12:10.5966667+00:00

Windows11のPCで、BLEセントラルとして動作するアプリをC#WPFで開発しています。

BLEペリフェラルとなるデバイスはArduino Nano 33 Iotで開発しており、サービスID(UUID)は独自のものを定義しています。

このデバイスに対して接続までは成功するのですが、ReadValueAsync()で接続したデバイスから値を取得しようとすると、戻り値が"Access Denied"となり値が取得できません。

デバイスのサービスIDを"180a"など公式で定義されているものに変更した場合、ReadValueAsync()で値の取得に成功します。

独自のサービスIDで値を取得するために確認すべき内容についてご教授いただけないでしょうか。

よろしくお願いいたします。

セントラル側のソースコードは以下の通りです。(UUIDは伏せています)

using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks;
using System.Windows;
using Windows.Devices.Bluetooth;
using Windows.Devices.Bluetooth.Advertisement;
using Windows.Devices.Bluetooth.GenericAttributeProfile;
using Windows.Devices.Enumeration;
namespace BLETESET_dotNET
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        private BluetoothLEAdvertisementWatcher watcher;
        public ObservableCollection<string> Devices { get; set; } = new ObservableCollection<string>();
        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
            watcher = new BluetoothLEAdvertisementWatcher
            {
                ScanningMode = BluetoothLEScanningMode.Active
            };
            watcher.Received += Watcher_Received;
        }
        private async void Watcher_Received(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args)
        {
            var device = await BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress);
            if (device == null) return;
            string name = string.IsNullOrEmpty(device.Name) ? "Unknown" : device.Name;
            string id = device.BluetoothAddress.ToString("X");
            Dispatcher.Invoke(() =>
            {
                string info = $"{name} [{id}]";
                if (!Devices.Contains(info))
                    Devices.Add(info);
            });
        }
        private void StartScan_Click(object sender, RoutedEventArgs e)
        {
            Devices.Clear();
            watcher.Start();
        }
        private void StopScan_Click(object sender, RoutedEventArgs e)
        {
            watcher.Stop();
        }
        private async void PairDevice_Click(object sender, RoutedEventArgs e)
        {
            if (DeviceList.SelectedItem == null)
                return;
            string selected = DeviceList.SelectedItem.ToString();
            string addressHex = selected.Split('[', ']')[1];
            ulong address = Convert.ToUInt64(addressHex, 16);
            try
            {
                var device = await BluetoothLEDevice.FromBluetoothAddressAsync(address);
                var result = await device.GetGattServicesAsync();
                foreach (var service in result.Services)
                {
                    if (service.Uuid == Guid.Parse("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")) // Custom service UUID
                    {
                        var charsResult = await service.GetCharacteristicsAsync();
                        foreach (var chr in charsResult.Characteristics)
                        {
                            if (chr.Uuid == Guid.Parse("yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy"))
                            {
                                if (device.ConnectionStatus == BluetoothConnectionStatus.Connected)
                                {
                                    var readResult = await chr.ReadValueAsync(BluetoothCacheMode.Uncached);
                                    MessageBox.Show($" {readResult.Status}");
                                    
                                    if ( readResult.Status == GattCommunicationStatus.Success)
                                    {
                                        var reader = Windows.Storage.Streams.DataReader.FromBuffer(readResult.Value);
                                        int value = reader.ReadByte();
                                        MessageBox.Show($"読み取った値: {value}");
                                    }
                                }
                            }
                        }
                    }
                }
                device.Dispose();
            }
            catch (Exception ex)
            {
                var result2 = 0;
                MessageBox.Show($"{ex.Message}");
            }
        }
    }
}

開発者テクノロジ | Visual Studio | その他
開発者テクノロジ | Visual Studio | その他

Windows、Web、モバイル デバイス、その他多くのプラットフォーム向けのアプリケーションを構築するための、マイクロソフトが提供する統合開発ツール スイートのファミリーです。 特定のカテゴリに適合しないその他のトピック。


お客様の回答

質問作成者は回答に "承認済み"、モデレーターは "推奨" とマークできます。これにより、ユーザーは作成者の問題が回答によって解決したことを把握できます。