I'm trying to connect to a BTLE device from Linux from C++ with BlueZ.
Connecting to most devices works fine, but there is a special device which times out with 90% probability. From a standard Android smartphone the connection to this particular device works as intended.
For #Emil's advice in my other question (thanks!) I've setup a Link Layer sniffer tool for further investigation.
During the sniff period I tried connecting to the device(Destination) from both device(Good) and device(Bad).
Device(Good) is working perfectly - it connected
Device(Bad) is not working - timed out
Now I have a Link Layer data of both device connection trials and there is one significant difference between their trials:
Device(Good)'s LL Data for its CONNECT_REQ uses 500 for Timeout value (which is 625ms) while Device(Bad)'s LL Data in CONNECT_REQ uses 42 (which is 52.5ms).
I think Device(Destination)'s response is normally (mostly) arriving between those two, ie after 52.5ms and below 625ms, but sometimes it arrives in less than 52.5ms, and then also BlueZ can connect to it finally.
Is there any possibility to change this Timeout property for CONNECT_REQ in BlueZ? Maybe with setsockopt by any chance?
Or this is something hardcoded into kernel, even for bluetooth adapters attached to USB?
Related
First post! Full disclosure, I have a very limited programming / pi background.
I'm working on a project to communicate with a Chroma Bi-Directional power supply (Model #: 62180D-1200) using LXI / SCPI communication. There's more I hope to do in the future, but for the time being I'm simply trying to establish a working communication channel using the "*IDN?" identify command. I have a raspberry pi connected to the same network as the power supply, which I am using to communicate to the 62180D.
Before beginning any of this testing, I have been able to establish that I can communicate with the device via http (web browser). The web page for the device even includes an scpi query tool -- which works!
Successful HTTP communication
To query the device from the pi I have used PuTty to log in to my pi and issue the following command:
lxi scpi -a <device ip address> "*IDN?"
I am expecting to see the same result as shown in the image above (Model No. , Serial No., Firmware Version), but instead I'm receiving the following:
Error: Read error (timeout)
Error: Failed to receive message
I was under the impression that this protocol is fairly plug and play. I have other LXI enabled devices on the same network that I am able to communicate with them using this same approach. Is there some obvious thing I'm missing here?
I am using a BeagleBone Black board (kernel 4.14.108-ti-r104) to create USB gadget using configfs/functionfs. I compose my gadget (using gadgettool) providing details about device configuration (function, vendor id, product id and ton of other params), run my userspace program that writes descriptors and strings to ep0 and connect the device to host. All works fine, I get BIND (when binding device to UDC) and ENABLE (when actually host is connected) events and my device can read from ep2 and write to ep1. Using wireshark I see the communication looks good, device and configuration descriptors as well as strings are exchanged.
The problem starts when I connect the device to another host. Unfortunately I have almost no control over that host, in particular I cannot run wireshark there, I don't even know the OS. The only thing I can do is to plug/unplug device, optionally see a message that device was detected and optionally a restart. What I see on the gadget side is that following BIND and ENABLE events I immediately get SUSPEND event and read on ep2 fails with 108 (ESHUTDOWN). Now the question is how to track the problem down.
I tried usbmon, but it seems it does not listen to traffic when device is in gadget mode. I have also seen https://github.com/torvalds/linux/blob/master/drivers/usb/gadget/udc/trace.h file which seems to define some udc trace points, but I am not really sure how they can be used.
So the final question is simple: how do I get any information about traffic on USB bus having access only to gadget side? I don't need full trace, but al least some information which packets were exchanged would be super useful. Did it fail while exchanging device descriptors, configuration/interface/endpoint descriptors or strings or something totally different?
Small update:
The whole thing is about Android Open Accessory Protocol and I am trying to write a gadget that would connect to this accessory.
I have changed my gadget composition somewhat and now I know the gadget is being identified by host (it displays manufacturer/model) so I suppose the issue is not in device descriptor and strings. I have used two additional flags in descriptors (FUNCTIONFS_ALL_CTRL_RECIP | FUNCTIONFS_CONFIG0_SETUP) and when connecting to my computer I get setup event (request 51 as expected), but when connecting to my accessory I still get SUSPEND/ESHUTDOWN. This time though it looks like the time between ENABLE and SUSPEND is much greater (over 10 seconds) which looks to me as if the host send some message, but this message was not processed by my gadget and then the host timeout out and disabled usb device. Still don't know how to find out if the accessory sent anything to gadget and what it was...
It`s possible to establish two connections( or more) between Pc and other device? When I try to do that I have got exception: 10048 -> ex.Message = "A connect request was made on an already connected socket xxxxxxxxxxxx:0000110100001000800000805f9b34fb". If not, there is some workaround? I used 32feet libary to wrote application.
i just connected 4 devices (spp) simultanously and transfering data periodically.
so it is definitely possible.
if one device is disconnected the other connection can't get data anymore, but i guess this is just a bug in my code.
it would be very interesting if anyone else has tried this.
I guess its not possible. There can exist one connection between a master and slave. A master can be simultaneously connected to as much as 7 active slaves.
And most probably the other device that you are using might support only one connection.
In your case it is possible to connect up to 7 device to your pc.
This an RFCOMM limitation, not a limitation of the lower levels of the Bluetooth stack. See a workaround described in the 32feet.NET documentation https://32feet.codeplex.com/wikipage?title=General%20Bluetooth%20Data%20Connections
Notes
[1] The one RFCOMM connection is a protocol limitation. TCP/IP has port numbers on source and destination ends and thus can support multiple connections, RFCOMM has only the remote channel number so only can support one connection.
If you need multiple connection and are in control of the 'server' device then have the service listen on two (or more) RFCOMM channels so the client can connect to different channel numbers.
I want to clear of my basics before I Jump into more complicated matter of bluetooth. I have following basic question.
If there is two bluetooth devices(A phone and a bluetooth display). Is it that bluetooth connection is initiated only by the phone.
Suppose there would be lot of bluetooth communication happening from a phone to bluetooth display.Both devices can send messages to any other devices at any time. What is usual design approach of communication. Is it that the phone creates a Socket Connection to the bluetooth display through RFCOMM first time by sending a connect request to the Bluetooth device and this connection is maintained all the time or for every message the Socket connection is made and then socket is closed, after that again reopened and closed for next message.
If the connection is opened till the devices are in nearby range what are the consequences.
What is normal way of communication in case of phone and headset.
Can I get any reference so that i can get some knowledge about that.
1) In general, bluetooth connections can be initiated by either device. For example, with a phone and computer, you could start a connection from either side. With a phone and a display or headset, there may be no input interface on one device, so you would initiate connections from the phone. Devices can also auto-negotiate role switches such that they swap master/slave roles.
2) If you have continuous data to exchange, or require low latency, the connection would typically be left up. If you only have rare messages to exchange, tearing down the connection would save power because the devices are maintaining the connection synchronization by exchanging null packets.
3) You can't maintain a connection with devices out of range. If they can't communicate for some timeout period (on the order of seconds) then they lose sync and kill the connection.
4) Note that phone/headset are not using RFCOMM connections, rather the HSP (headset profile). Connections for isochronous voice data are inherently different than a sporadic data connection like RFCOMM.
5) A good way to see how "real" devices are communicating is to use tools like hcidump, as part of the linux blueZ stack. This lets you fully sniff the protocol messages that happen as you connect devices.
I have an issue where i have connected my linux server to a serial port. There is a continous flow of data from serial port which comes through epabx.
In Minicom i get first call's data and from second call it goes offline.
I dont see any data.
Can some one help me on this.
Thanks for all the help given by you. Finally i have got the error solved.
God knows how i started getting the data.
But still i am listing the steps i performed to get correct data.
Sometimes data from serial port wont be capturing in the processing form application.
It may be because of the following issues.
1.Serial port not connected properly.
2.Serial port cable not working.
3.Some pins on serial port are damaged or connection lost.
Note: For above all reasons contact the client person or person in charge of epabx systems.
4.Data not getting displayed on hypertiminal.
This is a common issue in linux which uses minicom as hyperterminal.
Sol: Check the version of the minicom before running it on linux. If the version is minocom 2.1 then some process would be blocking the incoming data.
Uninstall minicom 2.1 and reinstall minicom 2.0
It is said that gate 8 process would block the incoming data.
minicom may be responding to control characters in your data. I'd recommend something simple but effective like
od -t x1 -t a /dev/ttySomething
to dump your data in both hex and as text.
You should also check that your port settings are correct i.e. bitrate, parity, stop bits, flow-control. Sometimes, when your settings are not correct, you will end up with weird results. Also, you need to check that your protocol is only sending texts as Carl mentioned.