I am attempting to add services to a CBPeripheralManager for IOS using Visual Studio for Mac. However, when I scan for my peripheral using another device, I do not see my added service. The advertising name is correct, but I only see other services (presumably default for iphone).
As a side note, I wrote the program in swift and get the same issue.
My xcode version is 9 and my ios target version is 11.
My code is as follows
CBPeripheralManager _peripheral;
public BLEPeripheral()
{
_peripheral = new CBPeripheralManager();//this, DispatchQueue.CurrentQueue);
_peripheral.CharacteristicSubscribed += (object sender, CBPeripheralManagerSubscriptionEventArgs e) =>
{
Console.WriteLine("Device Subscribed: {0}", e.Central.UUID);
_connectedDevices.Add(e.Central);
ServiceSubscribed(this, e);
};
_peripheral.WriteRequestsReceived += (object sender, CBATTRequestsEventArgs e) => {
Console.WriteLine("Write Request Received");
};
_peripheral.ServiceAdded += (object sender, CBPeripheralManagerServiceEventArgs e) =>
{
Console.WriteLine("Service {0} was added", e.Error);
Console.WriteLine(e.Service.Characteristics.Length.ToString());
Console.WriteLine(e.Service.UUID.ToString());
IsAdvertising = true;
StartAdvertisingOptions advOptions = new StartAdvertisingOptions();
advOptions.LocalName = "myDevice";
_peripheral.StartAdvertising(advOptions);
Console.WriteLine("starting the advertisement");
};
_peripheral.AdvertisingStarted += (object sender, Foundation.NSErrorEventArgs e) =>
{
Console.WriteLine("Advertising did start");
};
_peripheral.StateUpdated += (object sender, EventArgs e) =>
{
Console.WriteLine("UpdatedState: {0}", _peripheral.State);
};
}
My Code for setting up the service is:
public void setupService()
{
txChar = new CBMutableCharacteristic(txCharUUID, CBCharacteristicProperties.Notify, null, CBAttributePermissions.Readable);
var MyServiceUUID = CBUUID.FromString("A66C4FFC-52C6-4C04-B97C-34E5E91DG5BG");
MyService = new CBMutableService(MyServiceUUID, true);
MyService.Characteristics = new CBMutableCharacteristic[] { txChar };
_peripheral.AddService(MyService);
}
The state of the peripheralmanager is PoweredOn. I check this before pressing the button which adds the service and starts advertisement.
Probably the main reason why your solution is not working is that CBPeripheralManager
methods must be used only when it's in State==PoweredOn
. The Apple documentation states this in the Overview.
I can see another minor potential problem in your example. In StartAdvertisingOption
you didn't set the ServiceUUID, so you are not advertising your service. It should be StartAdvertisingOptions advOptions = new StartAdvertisingOptions { LocalName = "myDevice", ServicesUUID = new CBUUID[] { _uuidService } };
Here follows a working solution where I moved all the CBPeripheralManager
logic in the UpdateState
event:
public class BleGattServerManager
{
private CBPeripheralManager _PeripheralManager;
private CBUUID _uuidService = CBUUID.FromString("625D74A2-3E61-4D1E-8949-8BE42DFDC6DA");
public BleGattServerManager()
{
//set up peripheral
_PeripheralManager = new CBPeripheralManager();
_PeripheralManager.StateUpdated += _PeripheralManager_StateUpdated;
_PeripheralManager.AdvertisingStarted += _PeripheralManager_AdvertisingStarted;
_PeripheralManager.ServiceAdded += _PeripheralManager_ServiceAdded;
}
private void _PeripheralManager_ServiceAdded(object sender, CBPeripheralManagerServiceEventArgs e)
{
System.Diagnostics.Debug.WriteLine("Service added");
}
private void _PeripheralManager_AdvertisingStarted(object sender, NSErrorEventArgs e)
{
System.Diagnostics.Debug.WriteLine("Advertising started");
}
private void _PeripheralManager_StateUpdated(object sender, EventArgs e)
{
System.Diagnostics.Debug.WriteLine("State=" + _PeripheralManager.State);
if (_PeripheralManager.State == CBPeripheralManagerState.PoweredOn)
{
//set up the GATT service
CBUUID uuidCharact = CBUUID.FromString("5BDAFB34-DA3F-40AA-8F9C-8AD409CB0063");
NSData readme = NSData.FromString("readme!");
CBMutableCharacteristic _CharacRead = new CBMutableCharacteristic(uuidCharact, CBCharacteristicProperties.Read, readme, CBAttributePermissions.Readable);
CBMutableService service = new CBMutableService(_uuidService, true);
service.Characteristics = new CBMutableCharacteristic[] { _CharacRead };
_PeripheralManager.AddService(service);
StartAdvertisingOptions advData = new StartAdvertisingOptions { LocalName = "my GATT!", ServicesUUID = new CBUUID[] { _uuidService } };
_PeripheralManager.StartAdvertising(advData);
}
}
}