I'm making an Android application getting data from a USB device (mode USB host). I read the document at https://developer.android.com/index.html and also some posts in stackoverflow and I found that they use sometimes bulkTransfer(), sometimes controlTransfer() but I can't find out the difference between two method and when do we use each one? Could anyone please give me some suggestion?
Control Transfer is mainly used for sending commands or receiving a device descriptor. It is normally used when setting up a device. The typical packet length is 8 bytes for low speed devices and 8, 16, 32 or 64 bytes for high speed devices. Data which is transferred via this method is formatted into three packets:
Packet 1 – Setup: The packet which contains the address and endpoint number
Packet 2 – Data: The data being sent
Packet 3 – Status: Where the device acknowledges whether the setup packet has been received and read correctly without errors.
Bulk Transfer is used for sending large packets of data to your target device. Printers and Scanners generally follow this transfer protocol. Bulk transfer has built in error correction to ensure that data is transferred and received without error. The process is considered complete when the amount of data obtained is equal to the amount of data requested. This transfer method is not ideal for time sensitive applications since there is no latency guarantee.
Related
My app is sending some data via bluetooth socket using Serial Port Profile, and the other device is Microchip's BM78 module.
Everything is working fine except one very particular case when testing with Huawei NEM-L21 phone. The data delivered correctly right after connection is made, or if data frames are sent frequently. But if there's a pause of 5-10 seconds between transfers, then the next transfer will get the beginning of the data blob altered. The first two blocks of approximately 650 bytes each is swapped, like if it was buffered before sending, and the second buffer gets transferred before the first one. The rest of the blob is ok.
I have no explanation for that. I've excluded BM78 issues, it's working totally ok with windows (virtual com port for bluetooth), and with a bunch of other android devices. It's only this particular phone that shows this issue.
So, is that just a bug in the phone's firmware, or there's something about bluetooth that's missed my attention? Like maybe power management options I can tweak in the phone? Anything related to Bluetooth in general?
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.
I am new to the BLE development. I want to send some large amount of data over a BLE connection with maximum throughput.
I have a GATT server, which is running on Linux, and a client which is running as an app on Android. I have created a custom characteristic with the maximum allowed size(512 bytes). I am requesting it from the app with a read operation. Every time I receive a call for reading on the server side I change it's value until I am finished with all the data(I know this isn't the best way but that's not the problem for now).
As for the connection parameters using android's requestConnectionPriority(CONNECTION_PRIORITY_HIGH) i can see that they are trying to negotiate a connection interval of 7.5ms but for some reason, it changes to 15ms and it remains there. Maybe my phone doesn't support it but I don't think so.
The next thing and the main problem is the MTU. Using hcidump, I can see that they are starting to negotiate the MTU as I can see an MTU Request from the client with a value of 517(by default) and a server Response with the same value. But when I trigger the data exchange I can see(using Wireshark) that the packets are containing only 32 bytes of payload. I don't know if it's a restriction with my Bluetooth adapter.
An MTU packet can consist of many radio packets and the 32byte radio packet payload is probably a restriction in your bluetooth adapter. No phone supports 7.5ms connection intervals at this point in time. You should also enable Data Length Extention if your phone and device supports it. This will allow you to transmit multiple MTUs throughout the connection event.
I have been searching through stackoverflow; however, I seem to have found various conflicting answer's to questions regarding this. Given Android 5.1.1 and iOS 8.4.1 what is the maximum amount of bytes that can be sent through a connectionless BLE service to one another. It is my base understanding that it should be 20 bytes from BLE Specficiation(actually 23); however, I have seen queries where iOS was able to push 512 and android was able to increase it's MTU.
Also if it is possible to send more than 20 bytes in a connection would they all be recognized correctly at the scanners on iOS and android with a cross-platform application when it is receiving the packet's without direct connection?
Per Apple's Best Practices for Setting Up Your Local Device as a Peripheral:
Although advertising packets in general can hold a variety of
information about the peripheral device, you may advertise only your
device’s local name and the UUIDs of any services you want to
advertise. That is, when you create your advertising dictionary, you
may specify only the following two keys:
CBAdvertisementDataLocalNameKey and
CBAdvertisementDataServiceUUIDsKey. You receive an error if you
specify any other keys.
There are also limits as to how much space you can use when
advertising data. When your app is in the foreground, it can use up to
28 bytes of space in the initial advertisement data for any
combination of the two supported advertising data keys. If this space
is used up, there are an additional 10 bytes of space in the scan
response that can be used only for the local name. Any service UUIDs
that do not fit in the allotted space are added to a special
“overflow” area; they can be discovered only by an iOS device that is
explicitly scanning for them. While your app is in the background, the
local name is not advertised and all service UUIDs are place in the
overflow area.
Note: These sizes do not include the 2 bytes of header information
that are required for each new data type. The exact format of
advertising and response data is defined in the Bluetooth 4.0
specification, Volume 3, Part C, Section 11
If you use an unregistered 16 byte service UUID, I think that's going to give you about 12 bytes of data.
Available bytes in an advertising packet will differ from available bytes in a payload packet.
Something is troubling me for years.
I work with a lot of bluetooth and lately wifi streams (spp). Those streams always connect to specific devices and communication happens via simple byte commands.
Some of the devices (their microcontrollers) i program myself and there i have to always check if the signal on the wire is what i expect, send and check for crcs.
Somehow i want to do the same on my smartphone because i access my streams with "readByte" and read byte by byte and i am always wondering if it is actually possible that
a) one byte from a message can be missing
b) messages arrive mixed or "out of sequence"
I have no idea how much the underlying hardware does. Does it check every message with crc and requests the message again if it was corrupted ? Or does it blindly pass every byte through to my "readByte" method ?
If the device sends message a and then b, is it possible that the receiver receives b before a and passes my code b before a or even mix up the bytes like a zipper and give me a[0] then b[0] then a[1] and so on.
How much trust in those streams should i have ? Some clarification would be appreciated
I think you can sleep well. WiFi and Bluetooth based on packet switch network, each packet comes with crc, and physical layer has built-in congestion and link quality control - so, aside from ultra rare firmware bugs, it is actually more reliable than wired serial connection.
In other words - error correction occurs at lower level than you are using..
Answer to question about packet arrival order: point to point protocols aren't affected by this problem. Packet reordering occurs when they travel by different routes, thus no problem when there are no other routes.
You will get same bytes in same order if you are using byte oriented streams over those protocols, because they are designed with this goal in mind. Packet access, on the other hand, is not, but Android doesn't provide you means to use it.
I feel like If you ever learnt about Computer Network OSI Model, you will understand what I am talking about better.
First, TCP/IP has nothing in common with Bluetooth. TCP is a transport level protocol whereas Bluetooth would be a lower level protocol. Thus you could use TCP or UDP on top of Bluetooth just as you use TCP and UDP on top of Ethernet.
Second, When data transferred through bluetooth devices, TCP protocol would be used. The TCP use congestion recovery algorithms to ensure data is transferred exactly. Modern implementations of TCP include four intertwined algorithms for flow control: slow start, congestion avoidance, fast retransmit, and fast recovery. So, If you want to know more about this, you may search the internet. Because they would rather be more theoretical than programmatic.
Well of data corruption i don't have any good idea.
But "mix up the bytes like a zipper and give me a[0] then b[0] then a[1] " should not happen.
I built app that parses nmea messages form external bluetooth gps. I don't check anything and some how my app works stable.