I tried to write a simple Bluetooth Server socket on the raspberry pi, according to the example of pybluez: https://github.com/karulis/pybluez/blob/master/examples/simple/rfcomm-server.py
I tried to connect from within an Android app.
When I run my Android app, I can't connect to the Server socket. When I Display the UUIDs seen by Android I get the following list, not containing my actual Service on the PI:
08-05 22:11:33.806 13510-13510/ch.erni.btlintilla D/DevName﹕ RichPi
08-05 22:11:33.806 13510-13510/ch.erni.btlintilla D/UUID﹕ 0000112d-0000-1000-8000-00805f9b34fb
08-05 22:11:33.806 13510-13510/ch.erni.btlintilla D/UUID﹕ 0000110e-0000-1000-8000-00805f9b34fb
08-05 22:11:33.806 13510-13510/ch.erni.btlintilla D/UUID﹕ 00001112-0000-1000-8000-00805f9b34fb
08-05 22:11:33.806 13510-13510/ch.erni.btlintilla D/UUID﹕ 0000111f-0000-1000-8000-00805f9b34fb
08-05 22:11:33.806 13510-13510/ch.erni.btlintilla D/UUID﹕ 00000000-0000-1000-8000-00805f9b34fb
08-05 22:11:33.806 13510-13510/ch.erni.btlintilla D/UUID﹕ 00000000-0000-1000-8000-00805f9b34fb
I then ran sdptool browse on the PI and didn't discover any devices.
I have already tried different Solutions mentioned in similar threads (DisablePlugins = pnat, Pairing Prior to starting the Service). Any help appreciated.
Below the sample code used to create the Server socket on the py.
# file: rfcomm-server.py
# auth: Albert Huang <albert#csail.mit.edu>
# desc: simple demonstration of a server application that uses RFCOMM sockets
#
# $Id: rfcomm-server.py 518 2007-08-10 07:20:07Z albert $
from bluetooth import *
server_sock=BluetoothSocket( RFCOMM )
server_sock.bind(("",PORT_ANY))
server_sock.listen(1)
port = server_sock.getsockname()[1]
uuid = "94f39d29-7d6d-437d-973b-fba39e49d4ee"
advertise_service( server_sock, "SampleServer",
service_id = uuid,
service_classes = [ uuid, SERIAL_PORT_CLASS ],
profiles = [ SERIAL_PORT_PROFILE ],
# protocols = [ OBEX_UUID ]
)
print("Waiting for connection on RFCOMM channel %d" % port)
client_sock, client_info = server_sock.accept()
print("Accepted connection from ", client_info)
try:
while True:
data = client_sock.recv(1024)
if len(data) == 0: break
print("received [%s]" % data)
except IOError:
pass
print("disconnected")
client_sock.close()
server_sock.close()
print("all done")
Related
I have an ESP32 board which sends data via bluetooth. I can receive data on PC using this python code:
from bluetooth import *
import sys
def input_and_send():
while True:
data = input()
if len(data) == 0: break
sock.send(data)
sock.send("\n")
def rx_and_echo():
sock.send("\nsend anything\n")
while True:
data = sock.recv(buf_size)
if data:
print(data.decode('utf-8'))
sock.send(data)
addr = "XX:XX:XX:XX:XX:XX"
service_matches = find_service( address = addr )
buf_size = 1024
if len(service_matches) == 0:
print("couldn't find the SampleServer service =(")
sys.exit(0)
for s in range(len(service_matches)):
print("\nservice_matches: [" + str(s) + "]:")
print(service_matches[s])
first_match = service_matches[0]
port = first_match["port"]
name = first_match["name"]
host = first_match["host"]
port = 1
print("connecting to \"%s\" on %s, port %s" % (name, host, port))
sock = BluetoothSocket(RFCOMM)
sock.connect((host, port))
print("connected")
# input_and_send()
rx_and_echo()
sock.close()
Data.append(data.decode('utf-8'))
Now, I want to get data on android phone. I wrote a python program using kivy, but bluetooth package does not work on android. I tried bleak and jnius packages, but they did not work. Is there another packages which can use bluetooth of phone properly? I see, some persons advise using jnius package for android, but I could not get data using "BluetoothReceive" function.
Any help is appreciated.
I understood how to receive data using python on android. I used jnius package, and tried to look errors using this code on android phone.
I found theBufferReader should be used instead of getInputStream(), and readLine() instead of readline(). You can receive data using the below code:
from jnius import autoclass
BluetoothAdapter = autoclass('android.bluetooth.BluetoothAdapter')
BluetoothDevice = autoclass('android.bluetooth.BluetoothDevice')
BluetoothSocket = autoclass('android.bluetooth.BluetoothSocket')
UUID = autoclass('java.util.UUID')
BufferReader = autoclass('java.io.BufferedReader')
InputStream = autoclass('java.io.InputStreamReader')
paired_devices = BluetoothAdapter.getDefaultAdapter().getBondedDevices().toArray()
socket = None
for device in paired_devices:
if device.getName() == 'ESP32':
socket = device.createRfcommSocketToServiceRecord(
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"))
recv_stream = BufferReader(InputStream(socket.getInputStream()))
break
socket.connect()
Serial_Data = recv_stream.readLine()
Add this bluetooth permision to your buildozer.spec file.
android.permissions = BLUETOOTH, BLUETOOTH_ADMIN, ACCESS_FINE_LOCATION
Since jnius package does not work on PC (Windows or Linux), I hope there be another way to debug the python code directly, without making application and testing it on android phone.
I have 3 devices -> 2*PC and 1 Raspberry Pi. 2 PCs are only for the sake of testing. 2PC = 2 Laptops with Windows 10.
On raspberry pi I have Bluetooth service(Py 2.7 but 3.5 should also work if print()):
import bluetooth
try:
server_sock=bluetooth.BluetoothSocket( bluetooth.RFCOMM )
server_sock.bind(("",0))
server_sock.listen(100)
bluetooth.advertise_service( server_sock, "MyService",
service_classes = [ bluetooth.SERIAL_PORT_CLASS ],
profiles = [ bluetooth.SERIAL_PORT_PROFILE ] )
client_sock, client_info = server_sock.accept()
print("Accepted connection from ", client_info)
client_sock.send('Hello')
data = client_sock.recv(1024)
print("received [%s]" % data)
client_sock.close()
server_sock.close()
except:
client_sock.close()
server_sock.close()
On Laptops I have client
import sys
from bluetooth import *
try:
service_matches = find_service(name="MyService",
uuid = SERIAL_PORT_CLASS )
print(service_matches)
if len(service_matches) == 0:
print('Found nothing')
sys.exit(0)
for i in service_matches:
print(i)
first_match = service_matches[0]
port = first_match["port"]
name = first_match["name"]
host = first_match["host"]
print "connecting to ", host
sock=BluetoothSocket( RFCOMM )
sock.connect((host, port))
data = sock.recv(1024)
sock.send("hello!!")
print(data)
sock.close()
except Exception as e:
print(e)
sock.close()
Everything works just fine, however, with one laptop I can repeat the proces between listening and connecting forever. With other Laptot I am able to connect 2-3 times and then I am receiving this error:
in <module>
uuid = SERIAL_PORT_CLASS )
File "C:\Python27\lib\site-packages\bluetooth\msbt.py", line 204, in find_service
addresses = discover_devices (lookup_names = False)
File "C:\Python27\lib\site-packages\bluetooth\msbt.py", line 15, in discover_devices
devices = bt.discover_devices(duration=duration, flush_cache=flush_cache)
IOError: No more data is available.
That means the error happened inside the pybluez function find_service. Interesting is that this happens when it cannot find a device. On the other laptop where this error is never triggered(always connects) but there are no devices ends up always with:
print('Found nothing')
When the error starts to happen after 2-3 succesful connections, I need to restart Raspberry pi to be able to connect again.
Thanks for any help
I am trying an example code in python which works as a bluetooth server. This code gives following error..
Traceback (most recent call last):
File "/var/lib/cloud9/examples/Sa/rfcomm-server_py", line 7, in
from bluetooth import *
File "/var/lib/cloud9/examples/Sa/bluetooth/init.py", line 43, in
from .bluez import *
File "/var/lib/cloud9/examples/Sa/bluetooth/bluez.py", line 6, in
import _bluetooth as _bt
ImportError: No module named _bluetooth
I am using beaglebone green wireless board in cloud9 IDE
# file: rfcomm-server.py
# auth: Albert Huang <albert#csail.mit.edu>
# desc: simple demonstration of a server application that uses RFCOMM sockets
# $Id: rfcomm-server.py 518 2007-08-10 07:20:07Z albert $
from bluetooth import *
server_sock=BluetoothSocket( RFCOMM )
server_sock.bind(("",PORT_ANY))
server_sock.listen(1)
port = server_sock.getsockname()[1]
uuid = "94f39d29-7d6d-437d-973b-fba39e49d4ee"
advertise_service( server_sock, "SampleServer",
service_id = uuid,
service_classes = [ uuid, SERIAL_PORT_CLASS ],
profiles = [ SERIAL_PORT_PROFILE ],
# protocols = [ OBEX_UUID ]
)
print("Waiting for connection on RFCOMM channel %d" % port)
client_sock, client_info = server_sock.accept()
print("Accepted connection from ", client_info)
try:
while True:
data = client_sock.recv(1024)
if len(data) == 0: break
print("received [%s]" % data)
except IOError:
pass
print("disconnected")
client_sock.close()
server_sock.close()
print("all done")
I didn't turn on the bluetooth on Beaglebone green wireless board, but after running the following command, the code above worked perfectly:
$ bb-wl18xx-bluetooth
I am trying to create an RFCOMM server process with Python that can be used without the need for pairing. Initially, I grabbed the two example scripts from the PyBluez documentation:
Server:
# file: rfcomm-server.py
# auth: Albert Huang <albert#csail.mit.edu>
# desc: simple demonstration of a server application that uses RFCOMM sockets
#
# $Id: rfcomm-server.py 518 2007-08-10 07:20:07Z albert $
from bluetooth import *
server_sock=BluetoothSocket( RFCOMM )
server_sock.bind(("",PORT_ANY))
server_sock.listen(1)
port = server_sock.getsockname()[1]
uuid = "94f39d29-7d6d-437d-973b-fba39e49d4ee"
advertise_service( server_sock, "SampleServer",
service_id = uuid,
service_classes = [ uuid, SERIAL_PORT_CLASS ],
profiles = [ SERIAL_PORT_PROFILE ],
# protocols = [ OBEX_UUID ]
)
print "Waiting for connection on RFCOMM channel %d" % port
client_sock, client_info = server_sock.accept()
print "Accepted connection from ", client_info
try:
while True:
data = client_sock.recv(1024)
if len(data) == 0: break
print "received [%s]" % data
except IOError:
pass
print "disconnected"
client_sock.close()
server_sock.close()
print "all done"
Client:
# file: rfcomm-client.py
# auth: Albert Huang <albert#csail.mit.edu>
# desc: simple demonstration of a client application that uses RFCOMM sockets
# intended for use with rfcomm-server
#
# $Id: rfcomm-client.py 424 2006-08-24 03:35:54Z albert $
from bluetooth import *
import sys
addr = None
if len(sys.argv) < 2:
print "no device specified. Searching all nearby bluetooth devices for"
print "the SampleServer service"
else:
addr = sys.argv[1]
print "Searching for SampleServer on %s" % addr
# search for the SampleServer service
uuid = "94f39d29-7d6d-437d-973b-fba39e49d4ee"
service_matches = find_service( uuid = uuid, address = addr )
if len(service_matches) == 0:
print "couldn't find the SampleServer service =("
sys.exit(0)
first_match = service_matches[0]
port = first_match["port"]
name = first_match["name"]
host = first_match["host"]
print "connecting to \"%s\" on %s" % (name, host)
# Create the client socket
sock=BluetoothSocket( RFCOMM )
sock.connect((host, port))
print "connected. type stuff"
while True:
data = raw_input()
if len(data) == 0: break
sock.send(data)
sock.close()
When I ran the server script on Windows everything worked just how I had hoped - no pairing was necessary. At this stage everything was looking very promising.
However, I need the server process to run under Debian Squeeze. When I test on Debian the client connection is refused. In the syslog there are messages from bluetoothd for a failed link key request and PIN request.
Version information:
PyBluez 0.18
Python 2.6
Bluez 4.66
Bluetooth v2.0 hardware on both ends of the connection
This discussion seems to suggest that if I can adjust the security level on the server socket then pairing will be disabled and everything will just work as expected. It is not apparent to me how to do this with PyBluez though, or even if it is possible.
I have experimented with calls to setsockopt() using various BT_SECURITY* constants, as well as grabbing the last PyBluez and calling setl2capsecurity() but have not been able to make any progress.
Is this going to be achievable with PyBluez?
This turned out to be a problem with the Debian Squeeze bluez default configuration.
If anyone else hits this problem, disable the pnat plugin by editing /etc/bluetooth/main.conf:
DisablePlugins = pnat
Then restart bluetoothd.
$ sudo invoke-rc.d bluetooth restart
No changes were required to the PyBluez code.
I have a script that loads a Firmware on an embedded device over a serial port. The script takes the /dev/xxx adress of the serial port as an argument.
I have a special setup, where I do this over Bluetooth.
I managed to connect via bluetooth to the module in python. However I just can't find any example/information on how to register the local socket in a serial device like /dev/rfcomm0.
####### ORCA Bluetooth uploader Script #######
#As an input argument the script needs the BT Adress of the racer.
#if none is given, the script looks for nearby devices.
import bluetooth
import subprocess
import sys
import os
#Check if we received a BT ADDR
if sys.argv[-1] != 'bt_comm.py':
#Define the Pin for binding and the connection Port
#Our Pin is 0000
pin = "0000"
#The Bootoader is listening on Port 1 for a connection
port = 1
rfcomm_port = 0
#The BT Addr we get from the command line input
#TAG:TODO:Check the input for sanity
addr = sys.argv[-1]
#Build the Firmware image
subprocess.call("python ./px_mkfw.py --image ../../Firmware_orca/Images/px4fmu.bin > orca_fw",shell=True)
#Create an RFCOMM Socket
server_sock=bluetooth.BluetoothSocket( bluetooth.RFCOMM )
#Connect to the device
server_sock.connect((addr, port))
print "Connected to ",addr
Here I need some way to register server_sock at /dev/rfcomm0
#Call the px_uploader script
subprocess.call("python ./px_uploader.py --port /dev/rfcomm%d orca_fw" % rfcomm_port,shell=True)
#Close the connection
server_sock.close()
else:
#Look for BT Devices and print them
discovered_devices = bluetooth.discover_devices(lookup_names = True, flush_cache = True, duration = 20)
if discovered_devices is not None:
for addr in discovered_devices:
print "Found bluetooth device: ", addr
else:
print "Could not find any bluetooth device nearby"