thaliproject / Thali_CordovaPlugin

Thali p2p plugin
MIT License
226 stars 44 forks source link

Android O: We are unable to get Bluetooth Mac Address #1956

Closed lesn1kk closed 7 years ago

lesn1kk commented 7 years ago

In Android 6, Google blocked ability to get Bluetooth Mac Address using API. We managed to make it work however by using a 'hole' and by getting Bluetooth Mac Address from Settings using reflection (link). Unfortunately, it looks like in Android O, we are no longer able to do it, we can't get mac address and advertise it. It looks like access to this only have apps with permissions LOCAL_MAC_ADDRESS (link), and this permissions are only granted to system apps because of security reasons.

We need to find a way to get device's bluetooth mac address.

EDIT: Additional links: 1

yaronyg commented 7 years ago

Sigh... we all knew this was inevitable. The question is - can we find another reflection interface to get around this or do we have to switch to bro mode? Or should we just integrate M-87 or Nearby? We know Bluetooth is a disaster on Android so moving away from it seems more reasonable than keeping investing in it.

enricogior commented 7 years ago

@yaronyg why do we pass the MAC address in the custom advertised data instead of just retrieving it from the ScanResult object, given it's available there?

D/org.thaliproject.p2p.btconnectorlib.internal.bluetooth.le.BlePeerDiscoverer: checkScanResult: ScanResult{mDevice=78:00:9E:DE:CB:21, mScanRecord=ScanRecord [mAdvertiseFlags=-1, mServiceUuids=[26db4a19-f04e-4c3d-9e99-a3e81631546f], mManufacturerSpecificData={}, mServiceData={00004a19-0000-1000-8000-00805f9b34fb=[11, 120, 0, -98, -34, -53, 33]}, mTxPowerLevel=-2147483648, mDeviceName=null], mRssi=-46, mTimestampNanos=789861695795}

it's the same value that is later retrieved from the advertised data:

D/org.thaliproject.p2p.btconnectorlib.internal.bluetooth.le.BlePeerDiscoverer: checkScanResult: parsedAdvertisement: [UUID = null, bluetoothMacAddress = 78:00:9E:DE:CB:21, provideBluetoothMacAddressRequestId = nullextra info = 11]

yaronyg commented 7 years ago

I'm drowning in work right now but my guess is that what you are seeing is the Bluetooth address advertised by a remote peer. But how do you get your own Bluetooth address to advertise to other peers? We also need to be careful to distinguish between BLE Mac addresses and Bluetooth Mac Addresses. Unfortunately Android sometimes will talk about Bluetooth when it means BLE. So you have to carefully check which is which.

enricogior commented 7 years ago

But how do you get your own Bluetooth address to advertise to other peers?

We don't need to know our own MAC address in order to start BLE advertising. We pass the local MAC address in the custom data for Thali's sake, but I don't understand why we do it since it doesn't seems necessary in the first place, maybe I'm missing something. I'm going to give it a try and change the logic and see if it works.

yaronyg commented 7 years ago

http://www.goland.org/thalilocalp2psurvivingmarshmallow/

enricogior commented 7 years ago

@yaronyg OK, I was confused by two things:

I've also tried to use the BRO MODE, but it seems it is currently broken, is that the case as far as you know?

yaronyg commented 7 years ago

BRO MODE worked last time we tested it but that was more than a year ago so most likely the code has rotted.

enricogior commented 7 years ago

Good news, I tried an alternative reflection method to get the MAC address and it worked on Android O (it also works on previous versions): https://stackoverflow.com/a/35984808/7098985

Weird thing: initially it worked only on one Nexus 6P and failed on the second device. I uninstall and re-installed the app a couple of times but it was still failing. After resetting the device to its factory settings it started to work, no idea what was the problem.

enricogior commented 7 years ago

This has been fixed https://github.com/thaliproject/Thali_CordovaPlugin_BtLibrary/pull/111