the examples I have seen of BLE connection with Delphi / Firemonkey always start with a search for devices, then go to a service discovery to only then do the pairing.
This entire process takes about 5 seconds. I wonder if there is a faster way to connect to an already known device with known services and quickly send a command.
Related
I am using Multipeer Connectivity Framework in my APP and its working absolutely fine but when APP is invoking any API or downloading any file from server then its delaying the response. Sometimes its failed and sometimes I am getting Time out error.
I have also checked "Network" status on xCode debug navigator and found that speed is going up and down instantly and never going beyond 6kb/s and sometimes its showing as 0 kb/s but when I disable Multipeer Connectivity then it works fine and speed going at 70kb/s too.
I have also noticed that if bluetooth is ON then its happening not with the Wifi.
Any suggestion would be really appreciable.
This is happening because when advertising, Multipeer always advertises on the wifi (there's no way to say bluetooth only). The way it advertises is by switching the wifi access mode into adhoc multiple times per second to find other peers, then switching back to AP mode (ie. resuming its connection to your wifi router). Doing this is highly disruptive to large transfers.
You have two options to fix this:
1) as soon as you can, after getting connected, call stopAdvertising(). This will stop the wifi mode from being constantly changed, and your throughput will resume at its normal rate. Warning: you cannot micro-manage this, because it takes up to 30 seconds after calling stopAdvertising() until it takes effect
2) switch from Multipeer to an alternative framework that allows you to specify bluetooth-only, and only use bluetooth. I wrote one called BluePeer which I use in my apps. It is unicast (not multicast) and supports roles like Client/Server (as well as role-less like Multipeer)
I know the default connection interval for CoreBluetooth is 30 ms. I've read couple of articles that claim they can reduce it 30 ms > by changing the min and max of the interval. I didn't see any explanation of how they were changing the parameters of it? I am assuming this is all in the iOS end.
Currently I am working on a project where the iOS device is sending packets to the bluetooth le device. When I was writing without response, there were a lot of packets being dropped so I added a handshake so once the bluetooth device receives a packet the iOS sends the next packet. This is currently taking a long time to upload a file since the connection interval is 30 ms which I am trying to reduce.
Any suggestions would be helpful
td;lr How do I change the connection interval on iOS
Solution So after doing research there is no public API that allows iOS devices to request for a connection interval change request. For Android this is possible.
There is no API on iOS for a app as master (using CBCentralManager) to modify the initial Connection Parameters when connecting to a peripheral.
However, the slave can suggest new connection parameters using a L2CAP Connection Parameter Update Request (see Bluetooth 4.0 specification, Volume 3, Part A, Section 4.20), which iOS will accept if they are reasonable (see Bluetooth Accessory Design Guidelines for Apple Products section 3.6 “Connection Parameters”). Peripherals should do this because different operating systems have different default connection parameters that might not be optimal for a particular peripheral. For example, if you rare implementing your peripheral in iOS or OSX, call -[CBPeripheralManager setDesiredConnectionLatency:forCentral:. Or, if you are using the TI BLE stack to program a CC2540 or the like, call the function L2CAP_ConnParamUpdateReq.
I have been beating my head on the wall with this project. I have an app built to an iPhone 5 that needs to communicate with my mac via bluetooth low-energy, and I want to do it through linux using the bluez protocol. I have my mac dual booted with ubuntu 12.04 and my iPhone app is connectible (acting as a peripheral), which I verified with lightblue. So, my question is, basically, is this possible? Will bluez support this type of connection, or will it only work if I use a dongle?
I have tried many different permutations of bluez. My linux kernel is 3.11.0. I think I am currently running bluez 4.98. I can get the hcitool to sense my app, then I use gatttool -b -I -t random which gives me the [ ][MAC.......][LE]>
then I type connect, I get
[CON][MAC.......][LE]> for about 15 seconds and then the CON goes away. That was the best I could do. Actually, at this point I'm not even getting that anymore. I'm getting any one of 3 errors. Either connection refused (111), could not create connection, or device busy (16).
Anyway, any help is appreciated!
Thanks.
To quickly answer your question, yes BlueZ DOES support pairing with iOS devices. That being said, the way Bluetooth Low Energy works is that you only need pairing if you want to perform an action on a characteristic (i.e. reading, writing, or enabling indications/notifications), and that characteristic requires pairing for that action to be performed. In other words, I think that the errors you are seeing are unrelated to pairing (since they occur before you do anything to the characteristics). I recommend that you try resetting the hci device with the command:
hciconfig hciX reset
Where hciX is the local hci device you are using.
If that doesn't work, try using #hcidump or #btmon to read the raw hci data and possibly get a clearer picture of what exactly might be happening.
If you want to make sure that you have a local hci device (and therefore meaning you wouldn't need a dongle), run the following command
hcitool dev
This should display the local hci devices. If the response is empty, that means that your Linux system is not using Apple's Bluetooth hardware, and that you probably need a dongle.
Also, watch out for other common errors, i.e. are you sure that your peripheral device is connectable, does it have proper implementation of services and characteristics, does the peripheral device have a random address (hence the -t random option?), are you sure you can see it from your linux machine (e.g. with the #hcitool lescan command), and if you are using the gatttool command correctly. There are a couple of good bluez questions on this site that might be beneficial to look at:
Using Bluetooth Low Energy from The Command Line
Bluetooth Low Energy Listening for Notifications/Indications
Raspberry Pi iBeacon Connection Timing Out
Attribute Requires Authentication Before Read/Write
Finally, when it comes to pairing, you have to increase the security level by passing "--sec-level=medium" or "--sec-level=high", e.g.
gatttool --sec-level=high -t random -b <MAC Address> --primary
or
gatttool -l high -t random -b <MAC Address> --primary
This should initiate the pairing process, and then result in a pop-window to appear asking you to accept the pairing request
I hope that this helps,
I'm developing an iOS app that connects to a certain type of BLE device, but I'm writing the code in a room that has 20+ such devices sitting around, powered up. I consistently find that in the morning, I can connect to my personal device just fine, but as the day wears on, it becomes impossible to connect to my device, as if the 20+ other devices have woken up somehow and are blocking my signal. No one is using most of these devices; they're just sitting on tables. Is this a known bug? Is Apple working on it?
Are all the devices Advertising?
If they are advertising with say 20ms then it could be difficult to hear all. There are "only" 3 advertising channels to share between all devices. The connection happens on the same channels (the peripheral listens after it's own advertising to hear if someone want to connect).
It has nothing to do with Apple CoreBluetooth. In my experience CoreBluetooth can handle around 20 devices after connection has succeeded and the activity has moved to the traffic channels.
1) Try using a slower advertising interval. This should work okay if your app is in the foreground.
2) Use a BLE sniffer (TI USB dongle is fine) and see if connections fail on protocol level, then it is not CoreBluetooth's fault.
3) Only advertise with fast interval when needed or you really really need a fast discovery.
As a rule of thumb apple needs up to 55 advertisements in background mode to see a device when it's the only one visible. So if you really need around 1.1second discovery then you might need 20ms advertisement interval, else use 100ms or even more (see Apple advertising interval guidelines for the exact number that will optimise discovery)
100ms gives so much more capacity and not too bad discovery.
1-2s gives a much longer battery lifetime and will be found in 1-2 minutes if your app is in the background. This would be quite fine for eyeBeacons in malls or the like while you might want 100-200ms in smaller areas.
I am trying to build an app for iOS that can connect to computers running macOS or windows, and control a few stuff on those computers. Another application will be installed on those computers so that the app on iOS can connect to them. But at first I need to discover those computers in the network that has my app installed and running. What is a good way of doing that? I thought about using broadcasting, multicasting or bonjour. Are there any other options? Which one is best for my situation?
I am planning on doing two different applications for macOS and windows, one with objective c and other with c#, so the networking stuff should be available for both of those. Thanks in advance
The simplest option by far would be to use IP/UDP broadcast packets. The application on the computers (running whatever OS) can all sit there listening on a predefined UDP port (e.g. 9999), and when the iOS device wants to 'scan' the network, it will send out an IP/UDP broadcast packet with the destination port of 9999. Upon receiving the broadcast packet(s), the application on the computers can respond since it now knows the IP address of the iOS device, and you can take things from there.
The cleanest way to handle a computer leaving the network is for the application that is running on the computer to communicate this fact to the iOS device since it already knows the IP address of the iOS device. But if keeping a current list of computers is crucial, then some sort of a polling mechanism is unavoidable because the computers may crash for whatever reason without having the chance to send the bye-bye message.
Multicasting can be utilized as follows: computers periodically send IGMP joins for a predefined multicast group (e.g. 224.1.1.1), and iOS device sends the multicast UDP packet destined to 224.1.1.1 when it wants to 'scan' the network. The multicast UDP packet(s) will be received by the computers since they have already joined the multicast group of 224.1.1.1, and then the computers can start communicating with the iOS device now that the IP address is known. However, this seems overly complex, and does not really offer any advantages. The whole point of using multicast is to save bandwidth, but the amount of bandwidth saved will be minuscule. Unless you are going to send the same data in substantial quantities from the iOS device to all the computers, there is simply no reason to go down this path.
As for Bonjour, unfortunately I am unable to comment as I have no experience with it, but I would still vote for simple broadcasting to keep things platform independent... well, at least on the computers side. :)