简体   繁体   中英

Receiving BLE advertisement packets on Windows published by iOS device

I'm attempting to communicate between windows and iOS using Bluetooth.

On the iOS side I'm publishing advertisements and on the windows side I'm "watching" for advertisements.

currently upon receiving the advertisements that my iOS device is publishing, these advertisements are... empty. No services, no ManufacturerData, DataSections list contains 1 DataSection with the Data of length 1 (?) local name is null, there's basically nothing in this advertisement packet of any use.

When I call BluetoothLEDevice.FromBluetoothAddressAsync (bluetooth address) I get an object, but with everything empty, no services, an element not found exception when I call GetGattService, DeviceInformation is null... nothing useful as far as I can see.

I don't know if there's something wrong with the advertisement I'm publishing on the iOS side, or if it's how I'm treating it on the Windows side.

Here is the iOS code:

import Foundation
import CoreBluetooth

class BluetoothController : NSObject, CBPeripheralManagerDelegate {
    var delegate : BluetoothControllerDelegate?
    var manager : CBPeripheralManager?

    init(_ delegate : BluetoothControllerDelegate) {
        super.init()
        manager = CBPeripheralManager(delegate: self, queue: nil)
        self.delegate = delegate

        self.delegate?.statusUpdate("init")
    }

    func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager){
        delegate?.statusUpdate("Perepheral did update state : \(peripheral.state)")

        if(peripheral.state == CBManagerState.poweredOn){
            addServices()
        }
    }

    func addServices(){
        let service = CBMutableService(type: CBUUID.init(string: "e1fa36b4-9700-414b-a4e0-382a3e249e56"), primary: true)
 //       service.
        manager?.add(service)
    }

    func peripheralManager(_ peripheral: CBPeripheralManager, didAdd service: CBService, error: Error?){
        delegate?.statusUpdate("Service was added : \(service.uuid)")
        manager?.startAdvertising(getAdvertisementData(service))

    }

    func peripheralManagerDidStartAdvertising(_ peripheral: CBPeripheralManager, error: Error?){
        delegate?.statusUpdate("peripheralManagerDidStartAdvertising : \(peripheral.isAdvertising) : \(error.debugDescription)")
    }


    private func getAdvertisementData(_ service : CBService) -> Dictionary<String, Any>{
        var data : Dictionary<String, Any> = Dictionary<String, Any>()

        data["CBAdvertisementDataLocalNameKey"] = "e1fa36b4-9700-414b-a4e0-382a3e249e56"

        data["CBAdvertisementDataServiceUUIDsKey"] = [service.uuid]

        return data
    }
}

And here is the Windows C# code (a simple console app for the moment) :

    class Program
    {
        static void Main(string[] args)
        {

            BluetoothLEAdvertisementWatcher watcher = new BluetoothLEAdvertisementWatcher();
            watcher.ScanningMode = BluetoothLEScanningMode.Active;
            watcher.Received += Watcher_Received;

            DeviceWatcher devWatcher = DeviceInformation.CreateWatcher();
            devWatcher.Added += DevWatcher_Added;
            devWatcher.Updated += DevWatcher_Updated;

            watcher.Start();
            devWatcher.Start();

            while (true)
            {
            }

        }

        private static void DevWatcher_Updated(DeviceWatcher sender, DeviceInformationUpdate args)
        {
            Console.Write("\nUpdated\n");
        }

        private static void DevWatcher_Added(DeviceWatcher sender, DeviceInformation args)
        {
      //      Console.Write("Added : "+args.Name+"\n");

        }

        static List<ulong> tried = new List<ulong>();

        private static async void Watcher_Received(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args)
        {

            if (tried.Contains(args.BluetoothAddress)) {
                return;
            }

            tried.Add(args.BluetoothAddress);


            Console.Write("Device found =================================================");

            Console.Write("\nDataSections: " + args.Advertisement.DataSections[0].Data);

            //BluetoothLEDevice device =  
            BluetoothLEDevice device = await BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress);
            try
            {
                Console.Write("\n GattServices: " + device.GetGattService(Guid.Parse("e1fa36b4-9700-414b-a4e0-382a3e249e56")).Uuid);
            }catch(Exception e)
            {
                Console.Write(e.ToString());
            }
            if(device.DeviceInformation == null)
            {
                Console.Write("DeviceInformation null");
                return;
            }

            if(device.DeviceInformation.Pairing == null)
            {
                Console.Write("Pairing null");
                return;

            }

            var res = await device.DeviceInformation.Pairing.PairAsync(DevicePairingProtectionLevel.None);

            Console.Write("Pair complete (?) ========================================"+res.Status);

        }
    }

Sorry it's a bit messy...

Thank you in advance for your help, I'm also trying it in the other direction (Windows advertising and iOS watching) it's not going well either, here's another question I've posted on this subject if interested: Listening to and accepting a BLE Connect request in windows

The advertisements are passive so you should change the code from active to passive such as: watcher.ScanningMode = BluetoothLEScanningMode.Passive;

public sealed partial class MainPage : Page
{
    Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementWatcher advertisementWatcher;

    public MainPage()
    {
        this.InitializeComponent();

        advertisementWatcher = new Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementWatcher();

        advertisementWatcher.ScanningMode = Windows.Devices.Bluetooth.Advertisement.BluetoothLEScanningMode.Passive;
        advertisementWatcher.Received += AdvertisementWatcher_Received;

        advertisementWatcher.Start();
    }

    private void AdvertisementWatcher_Received(Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementWatcher sender, Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementReceivedEventArgs args)
    {
        System.Diagnostics.Debug.WriteLine("Address: {0:X}", args.BluetoothAddress);
    }
}

With just the .Received callback you should start seeing data coming such as:

Address: A45E60F3E896 Address: 4BF5661A4EF2 Address: 549F476B5F37 Address: 4CB6DF3019A9 Address: 4BF5661A4EF2 Address: 106070EB42B1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM