Bug 31200 - The CBCentralManagerDelegate didDiscoverPeripheral callback advertisementData dictionary contains incorrect data types.
Summary: The CBCentralManagerDelegate didDiscoverPeripheral callback advertisementData...
Status: RESOLVED ANSWERED
Alias: None
Product: iOS
Classification: Xamarin
Component: Xamarin.iOS.dll ()
Version: XI 8.10
Hardware: Macintosh Mac OS
: Highest blocker
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2015-06-17 15:25 UTC by Jon Goldberger [MSFT]
Modified: 2015-06-17 15:46 UTC (History)
3 users (show)

Tags:
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:
Status:
RESOLVED ANSWERED

Description Jon Goldberger [MSFT] 2015-06-17 15:25:17 UTC
## Description

First note that I can not test this as I do not have appropriate bluetooth devices to test with, so the following is based on the customer's description.

When implementing the DiscoveredPeripheral(...) method in the CBCentralManagerDelegate, the parameter NSDictionary advertisementData contains incorrect data types. Customer's description:

"I have a device broadcasting the “realUUID” below, obtaining the UUID natively in Objective C works fine. I expect to get a CBUUID object equivalent to the one I construct via string but cannot.

Here is my code:"

[Export("centralManager:didDiscoverPeripheral:advertisementData:RSSI:")]
>public void DiscoveredPeripheral(CBCentralManager central, CBPeripheral peripheral, NSDictionary advertisementData, NSNumber RSSI)
>{
>CBUUID realUUID = CBUUID.FromString("9A8AEA7F-9CF9-4352-8504-84A92E3DB2D7");
>
>Console.WriteLine("Advertisement Data Raw: {0}", advertisementData);
>
>var uuidTypeCheck = advertisementData[CBAdvertisement.DataServiceUUIDsKey];
>Console.WriteLine("Type of this object is {0}", uuidTypeCheck.GetType());
>
>// iOS documentation says this should be an NSArray of CBUUID objects
>NSArray advertisementUUIDs = (NSArray)advertisementData[CBAdvertisement.DataServiceUUIDsKey];
>
>Console.WriteLine("Tyoe of first object in array {0}", advertisementUUIDs.ValueAt(0).GetType());
>
>// try
>// {
>// // Cannot implicitly convery System.IntPtr to CoreBluetooth.CBUUID
>// CBUUID uuid = (CBUUID)advertisementUUIDs.ValueAt(0);
>// Console.WriteLine("UUID value: {0}", uuid.Uuid);
>// Console.WriteLine("The callback UUID {0} the real uuid", realUUID.IsEqual(uuid) ? "is equal to" : "is not equal to");
>// }
>// catch (Exception ex)
>// {
>// Console.WriteLine("Exception getting CBUUID from advertisement data {0}", ex.Message);
>// }
>
>try
>{
>CBUUID uuid = CBUUID.FromCFUUID(theUUID: advertisementUUIDs.ValueAt(0)); // this static initializer takes an IntPtr as a parameter
>Console.WriteLine("UUID value: {0}", uuid.Uuid);
>Console.WriteLine("The callback UUID {0} the real uuid", realUUID.IsEqual(uuid) ? "is equal to" : "is not equal to");
>}
>catch (Exception ex)
>{
>Console.WriteLine("Exception trying to get the uuid from an IntPtr {0}", ex.Message);
>
>}
>}
>

Output to the console from the above code:

>2015-06-16 16:15:17.535 BluetoothScanTest.iOS[6297:1786738] Advertisement Data Raw: {
>kCBAdvDataIsConnectable = 1;
>kCBAdvDataLocalName = MyDev;
>kCBAdvDataServiceUUIDs = (
>"9A8AEA7F-9CF9-4352-8504-84A92E3DB2D7"
>);
>kCBAdvDataTxPowerLevel = 0;
}
>2015-06-16 16:15:17.535 BluetoothScanTest.iOS[6297:1786738] Type of this object is Foundation.NSArray
>2015-06-16 16:15:17.535 BluetoothScanTest.iOS[6297:1786738] Tyoe of first object in array System.IntPtr
>2015-06-16 16:15:17.536 BluetoothScanTest.iOS[6297:1786738] UUID value: 816E850484A2-2E3E-B2D7-0200-000000000000
>2015-06-16 16:15:17.536 BluetoothScanTest.iOS[6297:1786738] The callback UUID is not equal to the real uuid

"The CBUUID.FromCFUUID(IntPtr obj) does not return an equivalent UUID.

If you look closely, you can tell that the UUID is partially present, it is shifted left 16 of the 32 byte value."
Comment 1 Sebastien Pouliot 2015-06-17 15:40:18 UTC
> // iOS documentation says this should be an NSArray of CBUUID objects

and

> CBUUID uuid = CBUUID.FromCFUUID(theUUID: advertisementUUIDs.ValueAt(0));

CBUUID != CFUUID (which is also != NSUUID or System.Guid - but at least the last one is not from Apple).

Try:

CBUUID uuid = Runtime.GetNSObject<CBUUID> (advertisementUUIDs.ValueAt (0));