best way to read from UsbDeviceConnection in USB host mode - android

To read data from an opened USB connection one uses UsbDeviceConnection bulkTransfer method.
I have the situation that after sending a request the routine should read all incoming data, which can be just 8 bytes or even 300+ bytes.
The problem is that bulkTransfer does not read all the bytes for some reason - it just returns with some bytes while there could be more to come.
Is it better to write a loop around bulkTransfer until there is no more data, or increase the timeout, or possibly there is another approach.
What would be the best way to handle this?
I tried the loop approach and I am surprised that it only reads about 10-20 bytes each time with a timeout of even 1second. I am sure there is more data already available, don't know why it does not read more at a time.
Does it matter which buffersize one uses - many examples have 4096 but how does changing this influence the reading of data?
Many thanks

If the device sends 10 bytes at a time and does so repeatedly to finish the 300+ bytes, you still only get these 10-byte chunks each time you read with bulk transfer.
In other words, the method does not wait to fill up your buffer. It returns as soon as there is something. So if you really want to collect the entire 300+ byte response, you do need to loop.

Related

Android BLE connection breaks when sending many packets with WRITE_TYPE_NO_RESPONSE

I am getting crazy with a project where I need to send firmware files from an Android device to a STM32F4 chip using Bluetooth LE.
I have already implemented BLE on both ends successfully and I am working with it with several characteristics for a long period without any problem.
Now a file transfer ought to be implemented that shall be able to send files in size of about 250K. My implementation seem to work but only in one of 10 cases. It does start sending packets in chunks of 20 bytes but then it
stops communication in 90% of the test cases on an undetermined point. I need to disconnect/reset and restart to get things up again.
Characteristic for file transger on the STM32F4 are defined as:
ret = aci_gatt_add_char(fileServiceHandle,
UUID_TYPE_128, // File xfer UUID
uuid, // Char UUID
FILEIO_RECORD_LEN, // Maximum length of the characteristic value (20)
CHAR_PROP_WRITE|CHAR_PROP_WRITE_WITHOUT_RESP|CHAR_PROP_NOTIFY, // WRITE NOTIFY me
ATTR_PERMISSION_NONE, // Nothing special
GATT_NOTIFY_ATTRIBUTE_WRITE, // The application will be notified when a client writes to this attribute.
// An #ref EVT_BLUE_GATT_ATTRIBUTE_MODIFIED will be issued.
16, // Encryption key size
0, // is fixed length (1== variable size)
&fileRequestHandle); // ReturnValue als handle
In Andoid I am setting the WRITE_TYPE_NO_RESPONSE flag in the service characteristic to
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
... aServiceCharacteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
Writing the packets is done in the onCharacteristicWrite call back function for a FIFO of maximum 8 packets.
Build up to 8 fragments of file data and queue it to a fifo
wrtCharacteristic.setValue(firstQueueItem);
in onCharacteristicWrite call back: if queue not empy { wrtCharacteristic.setValue(nextQueueItem); }
If the last packet is received in the STM32F4, all packets in that group are verified and an acknowledge is send back causing an event in the APP.
The event then triggers sending the next 8 packets.
This looks pretty straight forward to me and seem to work sometimes. It works always though if I am setting the number of consecutive blocks to 1. All other sizes do not complete sending the in files in almost all cases.
There is no evidence of when the transfer is broken, sometimes immediately, sometimes after sending more than 80% of the data.
I have also tried to skip writing the received data on the STM32F4 to the flash storage to avoid SPI interferences without any changes in behavior.
Is there anything that I am missing here? Where could I check for errors. Any help wouldbe very much appreciated.
For unknown reasons, this problem does occur any longer. My implementation has not changed compared to what I stated on top. I tried to request a BLE response for the last packet of each group but that does not seem to make any difference.
I thank everybody who read and commented on this entry.

What's the quickest way to send lots of data over BLE?

If I want to transfer a lot of data (e.g. 1 MB file) over BLE, what's the best way to do it?
I control both sides of the connection, but the client side is iOS/Android so only has access to GATT. I can't do anything with L2CAP.
I also can't wait for Bluetooth 4.1, 6LoWPAN, Connection-Oriented-Channels or anything like that.
I would assume the answer is to have one "request" characteristic that you write a data request to ("Give me 3000 bytes starting at byte 0"), and a "data out" characteristic that sends lots of 20 byte notifications (the maximum characteristic size) containing the data.
Is there a better way?
Yes we are using the approach you have mentioned.
Request data with the last index number(First time the index is 0)
The server send you with data with index no.Store the index no for subsequent format
continue Step 1 and 2 till the time server sends end of data-probably with index -1 or something.
Make sure you transfer the data you required in the most space efficient format.See if you can zip the files and transfer it.
You can update connection interval to small value with smallest 6*1.25 ms in remote BLE device.
Actually, BLE is designed for Low energy, small packet, low data rate.
L2cap data will be transmitted in different data channel with frequency hop. Packets TX/RX happen within each connection interval and max number of packets TX/RX in an event is restricted by specification, finally implemented by manufacture. So we can change connection interval as small as possible to increase data rate.
Refer BT 4.0 spec Vol 2, 7.8.18 LE Connection Update Command.
Try to negotiate a larger MTU than the default.
Then each notification can be larger. Even though it will be fragmented by the L2CAP layer, you will get a slightly larger throughput since the packet header will be smaller.

how much size of data can be send in tidtcpclient in delphi xe7

I'm using Delphi XE7 for developing mobile application. And I'm using TIdtcpClient component to interact with the Server application. And I need to know for Android mobile & iOs mobile app, what is maximum size of data which I can send at a time to server. Or it depends on the speed of the internet. Please help me in this
TCP sockets are data streams, the length of the transmitted data is unlimited. For data with fixed length, client and server have to know when the stream ends, either by sending length information first before sending the actual data, or by using a end-of-data symbol / terminator sequence. You can also send an 'endless' stream, for example live audio / video data, which continues until one side disconnects.
There is no theoretical size limit to data that you can sent. Limitations are because of system resources/processing power, bandwidth availability and of course time that it takes to send.
System resources in the case of mobile devices will be memory, cpu power and data availability (cost per data) as it will most probably be for other platforms as well. Another resource that influences performance is the developer; the worst he writes the app the worst it will perform.
Bandwidth availability will determine how fast that chunk of data can be sent which directly influences the time it takes. Who wants to wait forever, right?
One more thing that is important, is the recipient. How patient the recipient is and how much resources he has also influences how much data you can send him.
So if you have plenty of time and resources then you will be able to send large amounts of data.
The Indy suite which TidTCPClient is part of, uses TidBytes as a memory data container into which an array of bytes is stored (the bytes that make up your data). Those TidBytes arrays are used to hold the data that you send or the data that you receive. They are handed to TidTCPClient when sending or receiving. The size of TidBytes arrays are once again limited by resources of the sender/receiver. If that causes an issue then you can break the data into smaller chunks then send them one-after-the-other. As long as you indicate to the recipient how big each chunk is, as mentioned by mjm and in the case of segmented sends you must also indicate which segment goes where in the complete data stream. A way of indicating to the recipient is to prefix the size of the data as either a byte, word or integer to the start of the entire package that you will send and as long as the server knows to either read the first byte, word or integer he will know how much data will follow that indicator and thus know how much data to expect as actual usable data.
Seeing that you might not know how much resources the recipient has it is wise to always break large amounts of data up into smaller chunks. This unfortunately is something that you will have to test to figure out how large. Also keep in mind the technology that will be used to send it across. For example Ethernet has certain packet sizes and if data is broken up into too small sizes it might cause too much overhead. The trick is to try and find the balance. Do not worry about that too much but do read up on it.

Android bluetooth chunk size

I'm experiencing a strange behavior of bluetooth socket (in my opinion), and I would like know if anybody can clarify it to me.
The situation:
I have two Android applications connected together by a Bluetooth socket:
The first makes a simple write(byte[] message) on the output stream.
The second makes a simple read(byte[] buffer) on the input stream.
On the reader side I use a buffer of 1024 bytes. The sender send a message a little bit larger than the receiver buffer size: 1024 + 108 bytes (always the same message).
Ok now the behavior:
On the reader app I receive the most often a first chunk of 1024 bytes which fills up the buffer (as expected) and then a second one of 108 bytes.
But really often (maybe 40% of the time) I receive a first chunk of 1008 bytes and then a second one of 124 bytes.
I really would like to understand this because I'm affraid to miss an important bluetooth concept. At first I was thinking to compare the count of byte read with the buffer size to know if the entire message had been received but this experimentation shows that it's maybe not a good idea.
Is anybody can explain to me this behavior?
Thanks in advance.
For the record, I now use Google Guava methods for read/write on streams and all works fine.
I'm finding the same thing- it seems to be because Bluetooth sends data over as a stream instead of packets.
So if I send 4 500 byte packets, it might end up sending a 1600 byte one and a 400 byte one, or the way I sent it. Over stack overflow questions say to use some random value in the byte array to tell when a message is finished (How to read all bytes together via Bluetooth?).
There should be a better way, but I plan to use a very unlikely character set to try to find the end of the message- and pad it onto the end of each of my messages going out. Some of the other stack overflow questions suggest using '\n', but I might end up using several to make it more unlikely, such as: "\t~\t"- something that should never be typed in my game (or hopefully not extracted from the enormous amount of other stuff going on).
Hope that helps!

How to correctly stream data via Bluetooth to Android

I'm in the process of developing an application which reads data from a DAQ that streams its data over Bluetooth. The packet sizes can change, as can the sampling rate (1Hz - 512Hz), and I'm able to loop through and read the data off the device using a buffer.
My question is, how do I correctly process the data when there is such a variable of packet size and sampling rate? How do I determine the buffer size?
Currently I'm simply opening a socket, opening an input stream, and then using a while loop (while the socket is open == true) to read from the stream, and process the data (simple decoding, not an extraneous task).
As an example, there are 23 bytes in a packet, and I have the sampling rate very low at the moment at 1Hz. I have a buffer of 256 bytes, which means that it wont accommodate a full packet at the end of the buffer, and I've written code for it to run over onto the next buffer. Once the data is read grab one packet from the buffer, decode and store it, do the next one, etc.
How should I be streaming, and manipulating the data correctly? Eventually I'll be grabbing something in the region of 44 packets at 512Hz, right at Bluetooths transfer limit, and I want to be able to process it as effective as possible, and display errors when a packet is dropped in the process, etc.
TL;DR: how do I correctly stream data using buffers and/or interrupts.

Categories

Resources