Pairing bluetooth devices with Passkey/Password in python - RFCOMM (Linux) - python

I am working on a Python script to search for bluetooth devices and connect them using RFCOMM. This devices has Passkey/Password. I am using PyBlueZ and, as far as I know, this library cannot handle Passkey/Password connections (Python PyBluez connecting to passkey protected device).
I am able to discover the devices and retrieve their names and addresses:
nearby_devices = bluetooth.discover_devices(duration=4,lookup_names=True,
flush_cache=True, lookup_class=False)
But if tried to connect to a specific device using:
s = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
s.connect((addr,port))
I get an error 'Device or resource busy (16)'.
I tried some bash commands using the hcitool and bluetooth-agent, but I need to do the connection programmatically. I was able to connect to my device using the steps described here: How to pair a bluetooth device from command line on Linux.
I want to ask if someone has connected to a bluetooth device with Passkey/Password using Python. I am thinking about to use the bash commands in Python using subprocess.call(), but I am not sure if it is a good idea.
Thanks for any help.

Finally I am able to connect to a device using PyBlueZ. I hope this answer will help others in the future. I tried the following:
First, import the modules and discover the devices.
import bluetooth, subprocess
nearby_devices = bluetooth.discover_devices(duration=4,lookup_names=True,
flush_cache=True, lookup_class=False)
When you discover the device you want to connect, you need to know port, the address and passkey. With that information do the next:
name = name # Device name
addr = addr # Device Address
port = 1 # RFCOMM port
passkey = "1111" # passkey of the device you want to connect
# kill any "bluetooth-agent" process that is already running
subprocess.call("kill -9 `pidof bluetooth-agent`",shell=True)
# Start a new "bluetooth-agent" process where XXXX is the passkey
status = subprocess.call("bluetooth-agent " + passkey + " &",shell=True)
# Now, connect in the same way as always with PyBlueZ
try:
s = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
s.connect((addr,port))
except bluetooth.btcommon.BluetoothError as err:
# Error handler
pass
Now, you are connected!! You can use your socket for the task you need:
s.recv(1024) # Buffer size
s.send("Hello World!")
Official PyBlueZ documentation is available here

Is there a way to connect two phones via Bluetooth , the script should be running on a Linux host. Any suggestions of using pybluez or any other APIs?
I have seen some examples where a Linux host is used as Client and is connect a phone (which is a server), but here I'm want to use Linux host as just a device to run the script and make two phones connect via Bluetooth.

Related

Unable to view Serial Ports (ComPorts) on android

I installed Octo4A on my android phone.
It installed Alpine linux and python3.
When I run a python script to view the serial ports.
It says no ports are found, but it does find the ports on my windows computer using the same script:
import serial.tools.list_ports as ports
def getAvailablePorts():
availablePorts = list(ports.comports())
return availablePorts
availablePorts = getAvailablePorts()
for port in availablePorts:
print("Available port: " + port.device)
The output on windows:
Available port: COM3
Here are the serials listed in Octo4a:
How can I get a list of the available ports and connect to it on android using python3?
If you look at the code, the way pyserial looks for ports in Linux is by trying to find the following strings:
/dev/ttyS* # built-in serial ports
/dev/ttyUSB* # usb-serial with own driver
/dev/ttyXRUSB* # xr-usb-serial port exar (DELL Edge 3001)
/dev/ttyACM* # usb-serial with CDC-ACM profile
/dev/ttyAMA* # ARM internal port (raspi)
/dev/rfcomm* # BT serial devices
/dev/ttyAP* # Advantech multi-port serial controllers
/dev/ttyGS* # https://www.kernel.org/doc/Documentation/usb/gadget_serial.txt
In Octo4A, serial ports are apparently called /dev/ttyOcto4a so they will not be found by list_ports().
Of course, that does not mean pyserial won't work, you can try to instantiate and open your serial port directly with:
import serial
ser = serial.Serial(port='/dev/ttyOcto4a')
ser.isOpen()
I have not tried this myself, so I can not guarantee it will work.

Get command result from SSH/Telnet via another SSH jump server in Python

I am writing a Python code to SSH or Telnet remote hosts, execute some commands and get the result output. Here we have a jump server, so the code must be "connected" with this server and from it, Telnet or SSH the remote hosts.
All my approaches work fine within the jump server, for example I can get the output of commands inside it. The problem is when I try to remote connect to hosts from it.
import paramiko
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect('IP', 22, username="user", password="pass")
stdin, stdout, stderr = client.exec_command("command")
for line in stdout:
print('... ' + line.strip('\n'))
client.close()
Using the library jumpssh get same results, and I am not will able to Telnet hosts. I tried the follow approach, but get the error
Administratively prohibited.
from jumpssh import SSHSession
gateway_session = SSHSession('jumpserver','user', password='pass').open()
remote_session = gateway_session.get_remote_session('IP',password='pass')
print(gateway_session.get_cmd_output('command'))
In the last company i worked we had a license from an SSH client that supports Python scripts, and worked fine in a more "textual" treatment.
There is any way of accomplish same task natively in Python?
SSHSession is trying to open direct-tcpip port forwarding channel over the gateway_session.
"administratively prohibited" is OpenSSH sshd server message indicating that direct-tcpip port forwarding is disabled.
To enable port forwarding, set AllowTcpForwarding and DisableForwarding directives in sshd_config appropriately.
If you cannot enable the port forwarding on the server, you cannot use jumpssh library.
If you have a shell access to the server, you can use ProxyCommand-like approach instead.
See Paramiko: nest ssh session to another machine while preserving paramiko functionality (ProxyCommand).

Connect to local bluetooth

I am using pybluez to develop a bluetooth application on linux in python. I want to know if it is possible to connect to a "localhost" for bluetooth so I can run the client and server on the same machine (as most people do for web development).
If this is not possible, how to most people develop bluetooth applications? Do they just run the client and server on different devices or is there a more clever way to handle this?
Eventually the server will run on a raspberry pi and the client will be any bluetooth enabled device (cell phone, laptop, etc.) but during development it would be great if I could run both on the same machine.
Here is my server:
import bluetooth as bt
socket = bt.BluetoothSocket(bt.RFCOMM)
host = ""
socket.bind((host, bt.PORT_ANY))
port = socket.getsockname()[1]
print("port: " + str(port))
socket.listen(1)
uuid = "94f39d29-7d6d-437d-973b-fba39e49d4ee"
# bt.advertise_service(socket, "BTServer", uuid)
print("Listening on " + host + ":" + str(port))
client_sock, addr = socket.accept()
print("Connection accepted from " + addr)
data = client_sock.recv(1024)
print(data)
client_sock.close()
socket.close()
And when I call services = bt.find_service(name=None, uuid=None, address="localhost") on the client it cannot find any services.
Through further research I have found that it is not possible to run a bluetooth client and server on the same device with the same bluetooth adapter. For local testing you can either use two bluetooth enabled computers or get a bluetooth dongle.
It is not possible to run a Bluetooth client and server on the same device.
I used the pybluez python module.
When I run bluetooth.discover_devices(lookup_names=True) in the client code on my machine, it returns all other Bluetooth devices around it except my machine.
As we can not discover the machine, we can not connect to it over Bluetooth and can not use it as a Bluetooth Server.

Python alternative to linux bluetooth command "rfcomm connect"

Requirement:
I need to connect to a remote bluetooth device & port and send data using a device file.
1. First scan the nearest bluetooth devices
2. connect to a remote BT addr & channel and communicate using a device file (/dev/rfcomm0)
I'm stuck at the second step. I'm able to do it through linux shell
sudo rfcomm connect /dev/rfcomm0 00:11:22:33:44:55 1 &
This works and then I open my python interpreter and communicate to the remote device using the rfcomm0 device file.
But my requirement is such that the device addr could be changing. So I want to connect and release the connections through python program.
I tried using python subprocess.
But the problem is it returns immediately with a returncode 0 and then the connection is established after certain latency.
import subprocess
host = '00:11:22:33:44:55'
port = "1"
subprocess.call(["rfcomm connect",host,port,"&"],shell=True)
I'm looking if there is any pyBluez or any other python alternative to achieve this.
import subprocess
host = input()
port = 1
cmd = "sudo rfcomm connect /dev/rfcomm0 {} {} &".format(host, port)
conn = subprocess.Popen(cmd, shell=True)
if conn.returncode is None:
print("error in opening connection")
import the subprocess module
Read bluetooth address from the user(host)
port number can also be read as input, I am considering the default port 1
cmd = "sudo rfcomm connect /dev/rfcomm0 {} {} &".format(host, port) will create a command from the given arguments
There are many ways to read the output and errors after the execution of command. Read more about Popen#https://docs.python.org/3/library/subprocess.html
You can you the os module to run Shell commands. You can store the return value like this:
from os import system
Returnedstring = system("Shell command")

Send AT-command through bluetooth from python application

hai guyz,
how can i send AT-command through bluetooth from a python application?
OS:fedora 8
Any one please healp me with the code?
which package i need to import?
from where can i download it?
To get a connection over bluetooth to your IP modem, you want to use the bluetooth
rfcomm driver:
michael#challenger:~> cat /etc/bluetooth/rfcomm.conf
rfcomm0 {
# Automatically bind the device at startup
bind yes;
# Bluetooth address of the device
device 00:1C:CC:XX:XX:XX;
# RFCOMM channel for the connection
channel 1;
# Description of the connection
comment "Blackberry";
}
This is the setup I use for mine - YMMV.
michael#challenger:~> cu -l /dev/rfcomm0
Connected.
ATI
Research in Motion BlackBerry IP Modem
OK
Once you have the rfcomm0 port, you treat the port as a standard serial port and you're good to go.
I think this is better.......
import bluetooth
sockfd = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
sockfd.connect(('00:24:7E:9E:55:0D', 1)) # BT Address
sockfd.send('ATZ\r')
time.sleep(1)
sockfd.send(chr(26))
sockfd.close()

Categories