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.
Related
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 have begun learning Socket Programming and Issue I faced is. I am unable to connect Sockets when On two different network ( To be specific : I am using Web-host and Cgi programming to create python socket Server and my goal is to connect to that socket using desktop client python application )
My Server Coad : Location Public_html/cgi-bin/serverSocket.py
#!/usr/bin/python
print "Content-type: text/html\n\n";
import cgitb
import socket
cgitb.enable()
def main():
host = 'localhost'
port = 8111
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.bind((host,port))
except socket.error as e:
print(str(e))
s.listen(10)
c,addr = s.accept()
print("Connection From : " + str(addr))
while True:
data = c.recv(1024)
if not data:
break
print ("From Connected user : " + str(data.decode()))
data =str(data.decode()).upper()
print ("sending :" + str(data))
c.send(data.encode())
if __name__ == '__main__':
main()
And Client Program : Location On My Local Computer C:/Desktop
#!/usr/bin/python
print "Content-type: text/html\n\n";
#Client Socket Program
import socket
def main():
host = 'www.mywebsite.com'
port = 8111
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect((host,port))
except socket.error as e:
print(str(e))
message=input("-> ")
while message != 'q':
s.send(message.encode())
print("Sent Message")
data=s.recv(1024)
print('Recieved from server :', str (data.decode()))
message=input("->")
s.close()
if __name__ == '__main__':
main()
| Error Encountered is : [WinError 10060] |
| Python Server uses : Python 2.6.6 |
| Python Client :python 3.4 |
While using This On same system (ie: Local host as Server and client works Fine)
PS: Also link if there is any tutorial on this,Also advice some configuration if must be made.
If you want them to access each other, use public IPs. (Public IP Address) You would also need to port-forward (this is different for every router so I can't explain, look it up). Otherwise, the port you want to access will not be accessible from other networks. When you port-forward, that port on your Public IP Address can then be accessed.
Python 2 and 3 handle sockets differently! See here this question for example. What you could do as a quick workaround is to change your client start line to "#!/usr/bin/env python2.7" to force the client to use python 2 as well, that should fix your problem.
I am trying to build a simple Bluetooth client / server where my Raspberry Pi is the server and my laptop the client.
This is the server code (running on my Raspberry Pi):
#!/usr/bin/python
# -*- coding: utf-8
import wifi, bluetooth
uuid="1e0ca4ea-299d-4335-93eb-27fcfe7fa848"
print "Setting up Bluetooth socket"
try:
sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
sock.bind(("", 0))
sock.listen(1)
except IOError as e:
print str(e)
print "Registering service"
try:
bluetooth.advertise_service(sock, "MyService", uuid)
while True:
print "Waiting for connection..."
client_sock,address = sock.accept()
print "Accepted connection from {0}".format(address)
data = client_sock.recv(1024)
print "Received data: {0}".format(data)
print "Closing client socket."
client_sock.close()
except IOError as e:
print str(e)
This seems to work, the script runs and blocks with Waiting for connection....
Then, my client code:
#!/usr/bin/python
# -*- coding: utf-8
import bluetooth, time
mac = "00:15:83:E5:E2:46"
uuid = "1e0ca4ea-299d-4335-93eb-27fcfe7fa848"
service = []
retry = 1
while len(service) == 0:
print "Looking for service on {0}, try {1}".format(mac, retry)
service = bluetooth.find_service(address=mac, uuid=uuid)
retry = retry + 1
time.sleep(1)
if len(service) == 1:
service = service[0]
print "Service found. Name={0}".format(service["name"])
print "Connecting to service."
sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
try:
sock.connect((mac, service["port"]))
print "Connected to service on {0} on port {1}".format(mac, service["port"])
except bluetooth.btcommon.BluetoothError as e:
print "Connection failed: {0}".format(e)
elif len(service) == 0:
print "No service found on mac {0}.".format(mac)
else:
print "{0} services found for mac/uuid, ignored.".format(len(service))
Also works, up until I try to connect() to the Raspberry Pi. I get the following error:
Connecting to service.
Connection failed: (111, 'Connection refused')
I tried connecting the laptop to the Raspberry Pi (it finds it and says it is "Connected") and searching for more info online, but wasn't able to find anything.
This error occures when u want to connect to not listening port.
U are listening on port "0" .....
Change it to for example 9999 and then client has to connect to that port on the server adress
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")
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"