[Xamarin.Forms] CoreBluetooth Peripheral disconnects after 1 minute

WorldOfBasti 136 Reputation points
2021-11-01T15:15:07.333+00:00

Hello, I am trying to develop two applications for Bluetooth LE with CoreBluetooth in Xamarin.Forms. I am using my Mac as peripheral and my iPhone as central. My aim is that I want to send messages from the central to the peripheral. Everything works as expected, but when I don't send any messages for 1 minute, the peripheral disconnects, with this error on the central: Error Domain=CBErrorDomain Code=7 "The specified device has disconnected from us." UserInfo={NSLocalizedDescription=The specified device has disconnected from us.}.
If I send messages every 10 seconds it would work, but I don't know if this is the right solution.. so my question is: Is there any time limit, etc. or is something wrong with my implementation?

Here is my peripheral interface:

private CBPeripheralManager manager;

private CBUUID ServiceUUID = CBUUID.FromString("4DF91029-B356-463E-9F48-BAB077BF3EF5");
private CBUUID WriteCharacteristicUUID = CBUUID.FromString("4DF91030-B356-463E-9F48-BAB077BF3EF5");

public void StartService()
{
    manager = new CBPeripheralManager(this, null);
}

public override void StateUpdated(CBPeripheralManager peripheral)
{
    if (peripheral.State == CBPeripheralManagerState.PoweredOn)
    {
        if (peripheral.Advertising)
            peripheral.StopAdvertising();

        var service = new CBMutableService(ServiceUUID, true);
        var writeCharacteristic = new CBMutableCharacteristic(WriteCharacteristicUUID, CBCharacteristicProperties.WriteWithoutResponse, null, CBAttributePermissions.Writeable);
        service.Characteristics = new CBMutableCharacteristic[] { writeCharacteristic };
        manager.AddService(service);

        var advertisingData = new StartAdvertisingOptions { ServicesUUID = new CBUUID[] { ServiceUUID }, LocalName = "myService" };
        manager?.StartAdvertising(advertisingData);
    }
    else
    {
        Debug.WriteLine($"Handle other states: {peripheral.State}");
    }
}

public override void WriteRequestsReceived(CBPeripheralManager peripheral, CBATTRequest[] requests)
{
    foreach (var request in requests)
    {
        Debug.WriteLine(request.Value.ToString());
    }
}

And here is my central interface:

private CBCentralManager manager;

public void Connect()
{
    manager = new CBCentralManager(this, null);
}

public override void DisconnectedPeripheral(CBCentralManager central, CBPeripheral peripheral, NSError error)
{
    Debug.WriteLine($"Disconnect: {error.Description}");
}



public override void UpdatedState(CBCentralManager central)
{
    if (central.State == CBCentralManagerState.PoweredOn)
    {
        central.ScanForPeripherals(new CBUUID[] { }, new NSDictionary());
    }
}

public override void DiscoveredPeripheral(CBCentralManager central, CBPeripheral peripheral, NSDictionary advertisementData, NSNumber RSSI)
{
    Debug.WriteLine(peripheral.Name);

    if (peripheral.Name == "myService")
    {
        manager.StopScan();
        manager.ConnectPeripheral(peripheral);
    }
}

public override void ConnectedPeripheral(CBCentralManager central, CBPeripheral peripheral)
{
    peripheral.DiscoveredService += ServicesDiscovered;
    peripheral.DiscoveredCharacteristic += CharacteristicsDiscovered;
    peripheral.DiscoverServices();
}

private void ServicesDiscovered(object sender, NSErrorEventArgs args)
{
    var peripheral = (CBPeripheral)sender;

    var service = peripheral.Services.Where(x => x.UUID == CBUUID.FromString("4DF91029-B356-463E-9F48-BAB077BF3EF5")).FirstOrDefault();
    if (service != null)
        peripheral.DiscoverCharacteristics(service);
}

private void CharacteristicsDiscovered(object sender, CBServiceEventArgs args)
{
    var peripheral = (CBPeripheral)sender;
    var writeCharacteristic = args.Service.Characteristics.Where(x => x.UUID == CBUUID.FromString("4DF91030-B356-463E-9F48-BAB077BF3EF5")).FirstOrDefault();

    peripheral.WriteValue("someData", writeCharacteristic, CBCharacteristicWriteType.WithoutResponse);
}

Thanks in advance

Developer technologies | .NET | Xamarin
0 comments No comments
{count} votes

Accepted answer
  1. Bruce (SqlWork.com) 78,006 Reputation points Volunteer Moderator
    2021-11-01T20:20:07.303+00:00

    the timeout is normal. Bluetooth devices discount if no traffic to save battery.

    1 person found this answer helpful.

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.