I'm trying to setup a communication channel between two Android phones.
Unfortunately, Google decided to block developer access to Bluetooth adapter MAC address, effectively disabling the entire NFC to Bluetooth handover process (Simple Secure Pairing).
Side note: why? privacy/security gain is minimal to none, especially
if you randomize it! you could simply randomize it when an app requests the MAC and that's it!
This SSP process used to take roughly 1-3 seconds at max and generated great user experience.
Currently, I'm stuck with NearBy which generates a terrible user experience (who's gonna wait 10 seconds just for the initial connection?)
The only options we have left:
Improving NearBy API somehow (~10 seconds average to discover and connect! why Google, why?)
WiFi hotspot - setting an agreed-upon ID as the name, discovering and connecting (~8 seconds average)
Bluetooth - requires a popup to be approved each time, a bit faster but results in bad UX.
Internet - just use the Internet and fall back to local wireless methods (when 4G internet connects much faster than local wireless Android NearBy, you know Google has definitely failed with the implementation).
Is there some secret sauce I can pour onto NearBy to improve it, to be, at least as fast as Apple AirDrop (~4 seconds average)?
Do I have any other options I'm missing?
Thanks!
The definition of absurdity:
Two phones that are 1 meter away from each other with several direct wireless options (Bluetooth/BLE/WiFi) take an average of 10 full seconds just to connect (before data is sent).
Two phones that are 20km away from each other, communicating over cellular data (3G/4G/5G) fully connect after an average of 1.7 seconds! Even after traveling through GSM BTS, proxies, cache, firewalls, BGP routing and other filters.
Google has to do something to fix that (after they disabled the only method to make this faster, using BT SSP, handing over NFC to BT - as they disabled BT MAC address exposure).
My solution right now is to use Internet by default while simultaneously trying to connect via NearBy, as I need a fallback ready to work for some of my clients that don't have a good cellular signal.
Related
I am attempting to connect two Android devices close-range without a 3rd party service to transfer two small json payloads back and forth before closing the connection. Think adding nearby contacts.
I am using the P2P_POINT_TO_POINT Strategy and have both devices advertising and discovering using the code found here: https://developers.google.com/nearby/connections/android/get-started. It consistently works, however it repeatedly takes 10-15 seconds to find the connection and prompt to accept the connection.
Ideally I could get this below 10 seconds.
I read that having one dedicated to advertising another dedicated to discovering helps but it does not work for my use case.
Is there a way to improve the connection rate?
Unfortunately, the best you can do is to try to connect in one direction. That should lower the connection latency to 2~7 seconds. When both devices connect to each other at the same time, that causes thrashing and while we do our best to handle it gracefully, it will cause increased latency.
Stopping discovery before calling request connection would help too, but not by much. We already do it internally during the most sensitive operations.
Our advertising and discovery stack is based off of Bluetooth, and we've experimented with other technologies to compliment it. But they typically have harsher limitations than Bluetooth does (needs a router, needs a very recent Android phone, can't handle simultaneous connections, can't advertise and discover at the same time). Of all the technologies I know of, only mDNS would be faster while still allowing bi-directional connection attempts, and that requires both phones to be connected to the same router (and that the router hasn't disabled mDNS). Typically this means it only works at home. If that's a reasonable limitation for you, then I can pass that on to the team.
I am evaluating Google Nearby connections2.0 more specifically evaluating the synergy effect of it. For this I am evaluating it against Wifi, Bluetooth and BLE in totally offline scenario, without any router.
Scenario
One device is advertising, all others (8 devices in total) are discovering. On successful connection, I am sending simple Files of 20B, 200B and 33KB sizes for 30 secs straight to each connected device.
I am using android Samsung S6 SM-G920F devices with android version: 6.0.1 and playservices version 12.8.74
I have following issues/questions
Q1: First of all at max 3 to 4 devices could be connected simulatenously more than this results into disconnect event of other devices. Even if only 3 devices are connected, and I am continuously sending message for 30seconds, one of them disconnected ? In simpler words, cannot sustain connectivity with any device for more than 45 secs. usually disconnection occur between 25 - 45 secs
Q2: I cannot send message/file continuously for 30 seconds like we can do with the Wifi like this
While(30sec){
bluetoothSocket.outputStream.write(bytes)
}
Because if I try to do this then I got the exception of too much work.I have to wait for the the callback in onTransferPayLoadUpdate()
Q3: If I try to send the file of 1MB or more to other peers, peer received the file successfully in onPayloadReceived callback but server/sender receive the successful status after too much delay. In my case it's between 1 mins to 5 mins after client callback. And I cannot send new file until I got the success callback on server. If I try to send it before getting the callback, nothing happens. Literally nothing. So In essence I can only send file of 1MB once then I have to resent both the devices to send another file.
This should be broken up into 3 separate questions. It helps future developers search easier. So if you get the time to do that, let me know and I'll split up my answer as well. But anyway, let's get into it!
A1: Nearby Connections has 3 separate strategies. The more limited the strategy, the more types of mediums we can use. So with that in mind, and with no router involved, P2P_CLUSTER will only use Bluetooth. It's the most general strategy, so it has the fewest mediums available.
All Android devices use mobile Bluetooth chips, which are unfortunately weak (but small and power sensitive), and that causes them to have a theoretical 7 device limit but a practical 3~4 device limit. To make things worst, that limit is eaten up by smart watches and paired headphones as well. That's why you're running into problems.
P2P_STAR and P2P_POINT_TO_POINT are both much more limited, because you can't connect in any direction. You need to choose who the host is beforehand and have everyone scan for and connect to that host. But you get the added benefit of WiFi hotspots, which have higher bandwidth and a larger number of simultaneous devices supported. I've seen 7 devices happily connected to a Lollipop device.
If you want to go beyond that, into the 10s and 100s, and a router isn't available, you'll have to build a mesh network. I can link you to examples of how to do that if you're interested. We don't offer support for that within Connections, but others have built meshes on top of us so we can point you in the right direction.
A2: Can you include a stack trace of the error you're seeing? Payload.Type.STREAM was built for continuously sending data. The other payload types should also work too, baring some rare but potential issues like BYTE payloads filling up the phones RAM.
A3: Both devices need to wait for onPayloadTransferUpdate(SUCCESS). onPayloadReceived is only a header, and means that there's an incoming file or stream but that the data hasn't been received yet. For byte payloads, we actually send the full byte payload inside the header so that's the only time data is immediately available.
This question follows on from Unity3D -- Send message to other mobile phones in the same vicinity
However, I made mistake of restricting to Unity3D.
So I would like to re-ask the question without that constraint.
Let us say we have 20 mobile phone users in a cave (so no Wi-Fi networks / isGPS)
One user hits a button, and every other user's screen flashes, (within a few milliseconds)
How to accomplish this?
What if everyone is using an iPhone?
What if there is a mix of iPhone and android users?
Finally, is there any solution that would cover a wider range of phones?
You should have some network so that mobiles can share some data. Bluetooth can have maximum of 10 m distance coverage (depends upon devices though). Since, all mobile are running same app they should be linked to a network and communicate. Please Check:
http://developer.android.com/samples/BluetoothLeGatt/index.html
You can create one device as server and communicate among other devices.
https://github.com/polyclef/BluetoothChatMulti
If you have installed the app on all of the devices then in all probability yes, if the device supports push (pretty much any smartphone) then you can use the push service to synchronize the devices based on geofencing (ie, 10m from my location), there are some other discovery routes you could try to (without using the B word) pinging other devices
the app would need to be able to provide some sort of server service if it was to create its own private network based on the IP addresses of the devices it found nearby, as those devices would have to connect to that phone acting as a server. the network interface shouldn't be important, but connecting the satellite devices to the server should be. You could try doing it based on which device can provide data services, aka hotspot. You can easily connect devices to networks programmatically.
at that point your faced with the classic client server problem. There is going to be a huge amount of work to get devices configured, network creation, client server infrastructure if it has to be done without data, packet optimization. Very expensive and very high risk depending on how many restrictions there are.
Search for How to make a html5 group chat and then build on that example.
Possibly send commands to the chat delimited by a / character where a javascript could then execute the command.
Good Luck with your design.
Danny117
i have been reading about proximity security devices through bluetooth, but i am wondering how it works in reality. As far as i have been reading, there are two techniques:
constant scanning from a master. The central device scans the target device every x minutes. When the target is into range, it gives back MAC bluetooth address and RSSI. The negative side is that being constantly into discoverable mode drains the battery, so does the master device that has to be constantly scanning for devices.
Paired and connected. As some product details: "Your laptop locks itself down when you step a certain distance away, and opens again once you're in range". It means that after paring and connected processes, the master can have information when the slave device is out of range, or get inside range again. In bluetooth 4, is going to be even as a profile.
Regarding to the second option, which feature is this? how it works? i mean, maybe you can code a sequence number counter that counts everytime the slave sends a packet through RFCOMM every x milisecs (android or ios), but what i dont understand is how a slave can connect to master again in a transparent way, when normally two bluetooth devices disconnect when they are out of range each other (so you cant send information again from the same bluetooth socket RFCOMM connection).
How proximity devices works in reality? how can you code it?
Bluetooth 4.0 (BT Low Energy) is a whole other animal than traditional Bluetooth. It is designed from the ground up to be good at things like the Proximity profile you describe. Basically a computer and a fob create a connection to periodically communicate at a slow interval, say once every 5 seconds. When you go out of range the connection drops due to a timeout and the PC knows the fob is gone. The PC side isn't power constrained, so it can constantly or periodically scan for the fob when connections are dropped. The fob can advertise its presence using infrequent advertisement packets, which costs only a small amount of power.
Note that there is no RFCOMM in BT LE. Android and other BT stacks currently lack BT LE support because it is too new. Only a few devices exist which actually use BT LE, so getting much real info is hard right now. In a few years this will be much bigger. The new iPhone 4S and new macbooks have the 4.0 BT chips, so you can expect more usage soon.
i am programming for google android and i wonder if the scans for wireless 802.11 networks are done passively or actively? i mean: does the device actually emit a beacon request signal on WifiManager.startScan() or does it just listen for beacons sent periodically by the access points?
Android does passive scans, it listens for beacons. Doing an active scan can create a lot of congestion on the network by sending out probe requests and waiting for probe responses.
Even though this question is 11 years old, it still has relevance today and so I thought I'd give it an up-to-date answer:
Yes, Android devices do search for APs actively. Passive scanning requires for the device to listen for beacons for a longer time, which is energy consuming see this paper by Freudiger for more details
Active scanning only requires sending probe requests and then waiting for the reply on the corresponding channels. This takes less energy as it requires for the radio to be turned on for a much shorter time span. Unfortunately, active scans require for the device to identify itself somehow, and this makes it easily trackable. Mitigations in place are e.g. MAC address randomisation with every burst, randomised MACs during connection with an AP, randomised Sequence Numbers, omission of unnecessary fields and more. It all doesn't seem to be enough as people still find way to optimise their algorithms to improve tracking via Probe Requests. ;-)
Rain Ma replied that Probe Requests contain SSIDs, this is technically not true for all devices anymore. The only reason for SSIDs in Probe Requests is to find hidden networks. In Android devices, newer OS versions don't transmit SSIDs at all anymore, save for when scanning for hidden networks. Up until Android 8, all manually added networks were automatically assumed to be hidden networks. Starting with Android 9, one has to explicitly mark a network to be "hidden" for the device to probe with SSID.
iOS does automatic detection of hidden networks, and they say they don't probe with SSID at all unless they detect a network to be hidden.
The answer is YES
Actually, using omnipeek to capture packages from Android/iOS devices, we can get the result below:
Most Android devices always try to send Probe Request Frame every few minutes. They keep a list of SSID you used to connect, and always try to send probe request frame with SSID to see if they are available now. I guess one of the reason is 802.11 pre-authencation , and some other reason may be: enhance the wifi list display speed.
They are working in a active.
iOS devices seldom do active scan
If you wanna konw more about the rules, you'd better read "802.11 Wireless Networks The Guide"
You can refer to the pciture : Packages captured by omnipeek