Read data from bluetooth - Android, Raspberry Pi Zero, Bluetooth - linux

I have an application in Android which connects with my Raspberry Pi Zero via Bluetooth.
I start connection in my phone and I only confirm a pairing in RPI.
I send a data from my Android to RPi and I know, this data is received in RPi because when I use:
sudo hcidump -a hci0
I see this data
But I don't have idea how can I write a programm (in python for example) which will read this data and run of led or something else with GPIO.
I tried pybluez.service but I have only:
Waiting for connection on channel 2
I tried
sudo rfcomm watch hci0
but I have:
"Can't bind RFCOMM socket : Address already in use
And others,I tried the first 5-10 tutorials in google or youtube and nothing.

The Bluetooth error "Can't bind RFCOMM socket: Address already in use": means that the bind() function used by the command producing the error (in your case, rfcomm) failed because there is another local socket with the same number (in your case, referred to channel 2) already bound by a local application.
A way to solve this problem is to find the local application in your system which is currently binding that socket (maybe another instance of rfcomm on the same channel). Close the socket in that application, or simply terminate it.

Related

BlueZ modify LE CONNECT_REQ Timeout

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?

In PiTooth.py program after pairing from a second terminal, the program in the other terminal is still "waiting for connection"

I followed this tutorial for emulating my Raspberry pi model B as a bluetooth Keyboard. I am able to identify the pi as a keyboard when searching for connection.
The pairing part is working fine also, I am using the following command for pairing:
sudo blue-simple-agent hci0 <mac address>
The tutorial asks to run the PiTooth code in one terminal and it will initialise the required ports (control and interrupt ports), read the SDP record, advertise the sdp record and it will listen for connection in the control and interrupt port. Then open another terminal and use the above command to pair with the client.
It is getting paired but it not reflected in the other terminal, which is still like "waiting for connection. The following is the part of the python code where it is listening for connection and connecting:
class Bluetooth:
HOST = 0 # BT Mac address
PORT = 1 # Bluetooth Port Number...
def listen(self):
# Advertise our service record
self.service_handle = self. service.AddRecord(self.service_record)
print “Service record added”
# Start listening on the server sockets
self.scontrol.listen(1) # Limit of 1 connection
self.sinterrupt.listen(1)
print “Waiting for a connection”
self.ccontrol, self.cinfo = self.scontrol.accept()
print “Got a connection on the control channel from “ + self.cinfo[Bluetooth.HOST]
self.cinterrupt, self.cinfo = self.sinterrupt.accept()
print “Got a connection on the interrupt channel from “ + self.cinfo[Bluetooth.HOST]
The whole code is really big and I don't like to enlarge the question. Please view this google doc for the code:
https://docs.google.com/document/d/1hEyprvN1MyFqyczL9Qh07_-pJjRvBIEkomiJhLHcXiQ/edit?usp=sharing
Can anyone help me solve this issue. Or is there any problem with the code. Is there any alternative ways to listen for connection.
The issue is resolved. It was an out-of-box solution actually. The problem was with the operating power of the pi. The pi was powered from my laptop's USB port and it's voltage was about 4.4V. USB ports usually provide only 500 mA, 5 V. Raspberry pi need a voltage source of about 4.75 to 5.25V and current in range of 700 to 1000 mA for optimum performance. Exactly how much current (mA) the Raspberry Pi requires is dependent on what you connect to it. For reference about power supply. I just changed the source, I fetched power via a 1000 mA 5v adapter and checked the voltage in the pi, it was about 4.64V and it worked fine.

How to switch wifi channel without dropping connection?

We are developing small internet connected device that connects via wifi and does some work. It is controlled via mobile app.
For configuration purposes we use wi-fi module that can work in both STA + AP modes simultaneously via two interfaces wlan0 and wlan1. One of the interfaces works in Master mode. Phone connects to the device via wlan1 and sends command for the device to connect to another network and waits for result. Device in turn connects to another wi-fi network using wlan0 and notifies the phone if connection was successful or not.
But there is one issue. Both interfaces (wlan0 and wlan1) must work on the same channel as we have single hardware module. This causes channel of wlan1 to change in order to match of channel for wlan0.
Here comes the problem. When channel changes phone looses connection with the device. Is there a way to change wi-fi channel but keep connection between the device and mobile phone?
Our wi-fi module is rtl8723bu.
Linux 3.4.103.
Wifi daemons: hostapd v0.8.x_rtw_r7475.20130812_beta, wpa_supplicant v2.3.
UPDATE
Here is more clearly description what is going on on device.
Let's assume that the phone already connected to Device wlan1 interface with essid DeviceAp which is on channel 1. We have a Router with essid RouterAp which is on channel 6. Device interface wlan0 is not configured and not running.
(Step1 on image below).
Then the phone sends a request to the device to connect to RouterAp.
(Step2 on image below).
When wlan0 starts connecting to RouterAp it changes working channel. Because WiFi module can work only on one channel. The channel of wlan1 also changes (maybe in hard way). Therefore Phone lost DeviceAp and starts roaming.
(Step3 on image below).
SO the update question is:
Is there a way to tell the Phone (or other device) about network change? Or perhaps increase the likelihood that the phone is connected back to DeviceAP.
This behavior is very similar to the process of setting up Google Chromecast.
Chromecast also has two wireless interfaces and change the channel, but the Phone does not lose connection with it.
Image:
http://postimg.org/image/soh78vd17/

Connecting to BT LE device using org.bluez.Adapter.CreateDevice fails with org.bluez.Error.Failed: Operation canceled Error

I'm trying to set up a connection to a Bluetooth 4.0 LE device on Linux using the BlueZ 4.X DBus interface.
To test this I use the following command:
dbus-send --system --dest=org.bluez --print-reply /org/bluez/<PID of bluetoothd>/hci0 org.bluez.Adapter.CreateDevice string:<MAC of BT device>
This command seems to work most times, giving a result like:
method return sender=:1.238 -> dest=:1.262 reply_serial=2
object path "/org/bluez/9652/hci1/dev_BC_6A_29_26_C2_1C"
and enabling me to interact with the device DBus object.
However, starting from yesterday, this seems to fail very frequently returning the following error:
Error org.bluez.Error.Failed: Operation canceled
When debugging the bluetooth daemon, (using bluetoothd -n -d) I notice the following things when executing the method call:
bluetoothd[340]: src/adapter.c:create_device() BC:6A:29:26:C2:1C
bluetoothd[340]: src/adapter.c:adapter_create_device() BC:6A:29:26:C2:1C
bluetoothd[340]: src/device.c:device_create() Creating device /org/bluez/340/hci0/dev_BC_6A_29_26_C2_1C
bluetoothd[340]: src/device.c:btd_device_ref() 0xb7ad8: ref=1
bluetoothd[340]: src/device.c:device_set_temporary() temporary 1
bluetoothd[340]: src/device.c:btd_device_ref() 0xb7ad8: ref=2
bluetoothd[340]: plugins/mgmtops.c:mgmt_event() cond 1
bluetoothd[340]: plugins/mgmtops.c:mgmt_event() Received 14 bytes from management socket
bluetoothd[340]: plugins/mgmtops.c:mgmt_connect_failed() hci0 BC:6A:29:26:C2:1C status 4
bluetoothd[340]: src/event.c:btd_event_conn_failed() status 0x04
bluetoothd[340]: src/device.c:device_remove() Removing device /org/bluez/340/hci0/dev_BC_6A_29_26_C2_1C
bluetoothd[340]: src/device.c:device_set_temporary() temporary 1
bluetoothd[340]: src/device.c:btd_device_unref() 0xb7ad8: ref=1
bluetoothd[340]: src/device.c:btd_device_unref() 0xb7ad8: ref=0
bluetoothd[340]: src/device.c:device_free() 0xb7ad8
As far as I can see, my Bluetooth dongle sends me an error event (status 4) when I try to connect to the device.
However, when I use hcitool ot gatttool to connect to the device, everything works perfectly.
I found that this happens mostly after I try to connect to the device using a different program (i.e cinnamon-settings), and cancel the connection prematurely. I also noticed this with other programs like bluetooth-properties on Angstrom.
My guess is that Bluez sends the wrong HCI commands to my bluetooth dongle in certain conditions. I think this is because the gui programs try to pair with the device instead of just connecting to it, which may cause BlueZ to think my device is a Bluetooth 2.0 device.
Thus far I seemed to be able to resolve this problem by connecting to my BT device using a gui application, waiting till it fails, and restarting my computer. However, the problem seems to reoccur occasionally, making this very painful.
I have seen this problem on systems running both BlueZ version 4.99 and 4.101.
Does anyone know how I can solve this correctly?
It seems like my predictions where more or less correct. After many hours of debugging the Bluetooth daemon I discovered that connecting to BT LE devices without a preliminary scan causes the daemon to try to connect to the device as a BR/EDR device. This is because the daemon's "internal cache" is filled with the EIR information at the time the device is discovered. If this information is not available when connecting to a LE device the CreateDevice method will fail.
A simple solution is to always make sure to discover devices before connecting to them.
The BlueZ 5 API introduction and porting guide also describes this problem, and how it is solved in BlueZ 5:
Bluetooth Low Energy essentially extended Bluetooth addresses with one extra bit, requiring one to always know whether an address is “random” or “public”. This caused issues with the BlueZ 4 API where the address was given to BlueZ in the CreateDevice and CreatePairedDevice calls. Since the parameter didn’t contain any of this extra random/public information bluetoothd had to maintain an internal cache to look up the necessary info. Another complication to the matter is that the BlueZ D-Bus API doesn’t differentiate between traditional BR/EDR devices and LE devices so there are essentially three possible address types: BR/EDR, LE public and LE random.

Bluetooth -> Winapi/32feet. Two connection from Pc to one device using Spp

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.

Resources