Bug 23310 - CBCentralManager does not scan for peripherals with service UUID
Summary: CBCentralManager does not scan for peripherals with service UUID
Alias: None
Product: iOS
Classification: Xamarin
Component: XI runtime ()
Version: XI 8.0.0
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
Depends on:
Reported: 2014-09-23 16:54 UTC by praveen.jh@globallogic.com
Modified: 2014-10-02 09:02 UTC (History)
3 users (show)

Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description praveen.jh@globallogic.com 2014-09-23 16:54:29 UTC
I am working on a BLE iOS mobile app where I am trying to scan for peripherals with specific service UUID. As per iOS SDK I need to call "scanForPeripheralsWithServices" method for that.

I don't feel this method is implemented correctly in Xamarin.ios.

Below is the code that I call to start scanning for peripherals having the service UUID that my app is interested in. "DiscoveredPeripheral" callback method in NOT invoked in this case. However, if I pass null CBUUID array to ScanForPeripherals then it discovers all the devices correctly (i.e. DiscoveredPeripheral is called for all devices but in this case my program has to loop through all the discovered device and check if it has the required service).

public override void UpdatedState(CBCentralManager central)
	if (central.State != CBCentralManagerState.PoweredOn) return;

	if (central.State == CBCentralManagerState.PoweredOn)
		var serviceUUID = "C31A8CED-04DE-4126-A818-67436BF7AF5C";

		CBUUID[] serviceGuids = new CBUUID[]{CBUUID.FromString(serviceUUID)};

		//var serviceGuids = new []{ Guid.Parse (testUUID)};
	Console.WriteLine("UpdatedState :" + central.State.ToString());

It would be nice to scan for peripherals that has the requested service.
Let me know if my implementation is not correct.
Comment 1 Rolf Bjarne Kvinge [MSFT] 2014-09-24 05:33:41 UTC
Can you try this way of calling ScanForPeripherals instead? This is exactly how it would be done in Objective-C, bypassing any bindings in Xamarin.iOS.

	IntPtr uuid = Messaging.IntPtr_objc_msgSend_IntPtr (Class.GetHandle (typeof (CBUUID)), Selector.GetHandle ("UUIDWithString:"), new NSString (serviceUUID).Handle);
	IntPtr serviceGuids = Messaging.IntPtr_objc_msgSend_IntPtr (Class.GetHandle (typeof (NSArray)), Selector.GetHandle ("arrayWithObject:"), uuid);

	Messaging.void_objc_msgSend_IntPtr_IntPtr (central.Handle, Selector.GetHandle ("scanForPeripheralsWithServices:options:"), serviceGuids, IntPtr.Zero);
	Messaging.void_objc_msgSend (serviceGuids, Selector.GetHandle ("release"));
	Messaging.void_objc_msgSend (uuid, Selector.GetHandle ("release"));
Comment 2 praveen.jh@globallogic.com 2014-09-24 21:10:27 UTC
That did not work. DiscoveredPeripheral callback method is not invoked even after doing it exactly the Objective-C way as suggested. 
This makes me curious, does it work in iOS? I don't know native iOS programming to verify for myself. I have seen documentation and people commenting that it works. 

If I pass the first parameter as null array of CBUUID, then all peripherals are discovered and I can search for service with my UUID in it.
Comment 3 Rolf Bjarne Kvinge [MSFT] 2014-09-25 10:48:54 UTC
Could it be that the service UUID is wrong? You're not supposed to pass the uuid for a particular device, but the uuid for a service the device implements.

Another idea is to check if you can scan for any of the other services the device implements (if it implements more than one) to see if that works.
Comment 4 Firoz Khan 2014-10-01 22:51:23 UTC
No, it is not working. I have tried your suggested idea. "scanForPeripheralsWithServices" we require for background mode. Background mode only support to scanForPeripheralsWithServices. We can not search all the devices in background mode, it is recommend by IOS Core Bluetooth development guide.

So, Please suggest the way how we achieve in background.
Comment 5 Rolf Bjarne Kvinge [MSFT] 2014-10-02 09:02:25 UTC
I'm closing this bug report since this is most likely not a bug in Xamarin.iOS.

If you're not sure how to use the API, please ask on our forums or stackoverflow, you'll get much more visibility there, someone will likely know the answer.

If you're certain it's a problem in Xamarin.iOS, please provide an Xcode project that works (it is trivial to create an Xcode project that listens for Bluetooth devices in a few lines of code) since we can't reproduce it (because custom hardware is required).