On my Linux (Angstrom distro on BeagleBone Black) I have a USB dongle which presents as a serial port and per default is available as /dev/ttyUSB0
I want to start a daemon, which will connect to the serial port and make it available as a socket. I have the code for this USB-to-socket bridge and it works when started by hand.
I want it to start automatically whenever the system boots, supposing the USB dongle is plugged in. How should I do this?
Attempts so far:
systemd: I created a systemd service with conditions After: remote-fs.target and After:syslog.target , but (it seems) the USB dongle is not ready at that point and the startup of the daemon fails.
Are there other systemd targets or services to condition to, so that the daemon is started only when the udev has finished installing devices and the network is ready?
udev: I created a udev rule like
KERNEL=="ttyUSB?", RUN+="/path/to/daemon.sh"
which executes successfully. But the daemon (which is started as a background process with a "&" within that script) seems not to execute. Also it seems to be frowned upon, to fork long running processes from udev rules.
What is the correct way to do it?
Create a udev rule like
# cat /etc/udev/rules.d/95-serialdaemon.rules
KERNEL=="ttyUSB0", TAG+="systemd", ENV{SYSTEMD_WANTS}="serialdaemon.service"
Create a systemd service like
# cat /lib/systemd/system/serialdaemon.service
[Unit]
Description=USB serial to socket bridge
After=remote-fs.target
After=syslog.target
[Service]
ExecStart=/mnt/serialdaemon.sh
Create the executable file
# cat /mnt/serialdaemon.sh
#!/bin/sh
date +%F-%T >> /var/log/serialdaemon.log
/usr/local/serialdaemon/serialdaemon -serial /dev/ttyUSB0 -port 15789 -baud 38400 >> /var/log/serialdaemon.log 2>&1
date +%F-%T >> /var/log/serialdaemon.log
Since the link in my further comment seems to solve this problem, here is the solution for using udev for starting a daemon when a certain usb device is plugged in:
Proper(-ish) way to start long-running systemd service on udev event (device hotplug)
Related
I have a connection that seems to work to an RS232 serial device to Ethernet server (hardware device). I want to make it persistent. What is the best way to do that? I'm using this command now:
sudo socat pty,link=/dev/ttySx udp:192.168.1.50:23
I would like to make that stay open all the time, including after reboots, so I can talk to the device /dev/ttySx but I'm not sure the best way to do that.
Edit: I am running this on Ubuntu 18.04
You could try setting up a systemd service. Create a file such as /etc/systemd/system/myttySx.service holding for example:
[Unit]
Description=socat ttySx to udp
After=network-online.target
[Service]
Restart=restart-always
RestartSec=10
ExecStart=/usr/bin/socat pty,link=/dev/ttySx udp:192.168.1.50:23
[Install]
WantedBy=multi-user.target
and enable it and start it (once only) as root with:
systemctl daemon-reload
systemctl enable myttySx
systemctl start myttySx
systemd on Ubuntu 18.04 is a bit old, so this may not be correct for that version. Check with systemctl status myttySx. Post each problem in a new question so others may answer.
I'm trying to enable serial-getty#ttyS0.service to output getty to serial console as well as tty0.
I have tried running systemctl enable serial-getty#ttyS0 but I suspect that systemd might not be running when late_command is running.
Then I tried making the symlink manually with ln -s /lib/systemd/system/serial-getty#.service /etc/systemd/system/getty.target.wants/serial-getty#ttyS0.service and after the install getty.target.wants only contains getty#tty1.service.
I can't use console=tty0 console=ttyS0,115200n8 kernel parameter because then messages from the init system and the system logger will only appear on the first serial port and I want them to appear on tty0.
Does anyone have any experience or any idea on how to enable services in preseed config?
Thanks.
I'm trying to automatically call a program at boot that uses Bluetooth. However, the program is being called before Bluetooth is configured and running.
I've tried calling the program in two ways:
Using a script in init.d and registered with update-rc.d with this line in the init: # Required-Start: $all
Calling it from /etc/rc.local
Neither of these work as desired. They both start the program, but before Bluetooth is configured and running.
What is the best way to force a script or program to run after Bluetooth?
Below are some select lines from the boot sequence so you can see the issue I'm having:
[ OK ] Started Login Service.
[ OK ] Started Getty on tty1.
**Where my program is currently executing**
[ OK ] Started Configure Bluetooth Modems connected by UART.
[ OK ] Reached Target Bluetooth
**Where I want my program to be executing**
Raspbian GNU/Linux 8 tty1
login:
The new init system for Debian 8 "Jessie" is systemd. The old way in Debian 7 "Wheezy" was Sysv with runlevels and /etc/inittab. A drawback of using crontab to run your program will be, if the script execution crashes, it dies forever. Restarting a script automatically if its ends is called "respawn".
As you can see, the Bluetooth Service is running and prints that a "Target" is reached. To create your own service, which runs after bluetooth startup, and respawns with systemd just create a file in /etc/systemd/system/ i.e. my_program.service
[Unit]
Desription=my_program with systemd, respawn, after bluetooth
After=bluetooth.target
[Service]
ExecStart=node /home/pi/workspace/my_program
Restart=always
[Install]
WantedBy=multi-user.target
and activate it
systemctl enable my_program.service
reboot or start it manually
systemctl daemon-reload
systemctl start my_program.service
If one kills the process or reboots, my_program will be restarted automatically some seconds later.
For anyone running Raspbian 9 (stretch)
I tried out #andpei's answer and my application still wasn't waiting for bluetooth to start up. I was able to solve this by adding "Requires".
[Unit]
Desription=my_program with systemd, respawn, after bluetooth
After=bluetooth.target
Requires=bluetooth.target
Using crontab, I was able to make it work with the following line:
#reboot sleep 5 && node /home/pi/workspace/my_program
Not ideal but it works for now. I'm open to any better answers.
I'm relatively new to the Raspberry Pi and am trying to receive data via Bluetooth on my Raspberry Pi. I've opted to use obexpushd and have installed all the bluetooth packages needed. However, when I run the command
obexpushd -B -n
to initialize obexpushd and have it listen to any incoming Bluetooth messages, it gives me this error message:
Listening on bluetooth/[00:00:00:00:00:00]:9
SDP session setup failed, disabling bluetooth
net_init() failed
I'm pretty sure that I've paired and connected the Raspberry Pi and device correctly so I'm at a loss for why it's not working.
You have an issues with your bluetooth sdp. Try stopping it
$ sudo service bluetooth stop
And restart it
$ sudo bluetoothd --compat
I had the same issue and it worked for me.
Subert's Answer Worked for me, I was wondering that hci was not discoverable.
In addition of Subert's Answer:
service bluetooth stop
bluetoothd --compat &
obexpushd -B -n &
For me the hciconfig was down, so i started it as:
hciconfig hci0 up
Now every thing is fine,
Thanks for subert's Answer.
Though #Subert is correct, a better way to run the daemon in compat mode is to extend the systemd script. This solution allows you to use the start/stop scripts and will survive any updates.
Create the file /etc/systemd/system/bluetooth.service.d/compat.conf with the following:
[Service]
ExecStart=/usr/lib/bluetooth/bluetoothd —compat
I decided to name the file compat.conf but you can name it whatever you want.
Reload & restart the daemon, and you're done!
$ sudo systemctl daemon-reload
$ sudo service bluetooth restart
I didn't have to run the hciconfig command but do have to run obexpushd as root (using sudo) until I figure out a better way.
I have got 2 Raspberry Pis, running Raspbian, up-to-date. Each Pi has exactly one Bluetooth USB dongle. I can make them communicate via RFCOMM using this.
Now, I would like to establish a proper IP layer over the Bluetooth physical link. As far as I understand, I have to use PAN (Personal Area Network), that should create a network interface I could manage with ifconfig. I am trying to adapt this tutorial, but I am stuck at an invalid exchange error.
On RPi0, I run
$ sudo pand --nodetach --listen --master --role=NAP
pand[2313]: Bluetooth PAN daemon version 4.99
On RPi1, I run
$ pand --nodetach --connect 00:1A:7D:DA:71:16
pand[2323]: Bluetooth PAN daemon version 4.99
pand[2323]: Connecting to 00:1A:7D:DA:71:16
pand[2323]: Connect to 00:1A:7D:DA:71:16 failed. Invalid exchange(52)
I cannot find any relevant information about this error code. Any idea how I could solve this ? Or am I mistaken and should I use something else instead of PAN ?
Thanks in advance !
EDIT:
When specifying the Bluetooth device I want to listen on, I get another error message. It doesn't really make sense either, since I do not run any other Bluetooth server.
$ sudo pand -i 00:1A:7D:DA:71:16 --nodetach --listen --role=NAP
pand[2582]: Bluetooth PAN daemon version 4.99
pand[2582]: Bind failed. Address already in use(98)
So things seem to have changed quite a lot recently and the Pi comes with Bluez 5.23 in 2016.
Having just spent two days, these steps have solved it for my pi but might help for any Debian Jessie install. I hope so. Tested on a new pi, running jessie with fresh install just now. This will give a bluetooth pan bridged to your eth0 network (and thus use your existing dhcp/dns server etc). This is my first post, so please forgive stupidity around the various conventions here. I hope this helps someone and saves you a little time.
This is prbably not an optimal solution (I'm no guru), and I'd love to hear about some improvements.
Install some things (python stuff will help with scritps):
sudo apt-get install bridge-utils bluez python-dbus python-gobject
Download two very cool python scripts, put them in /usr/local/bin and chmod both perhaps to 755 depending on who needs access to execute...
blueagent5
and bt-pan. Many thanks and homage to their respective authors. Gosh this kind of thing saves so much time and misery.
Now, we need a bridge. Add the following to the end of /etc/network/interfaces
auto pan0
iface pan0 inet dhcp
bridge_stp off
bridge_ports eth0
I rebooted at about this time to make sure all was as it would be normally.
sudo reboot
Log back in and we issue
modprobe bnep
hciconfig hci0 lm master,accept
ip link set pan0 up
If you don't want pin prompt, don't do this next step. To ensure we get a PIN prompt, issue this...
hciconfig hci0 sspmode 0
Start PAN using the special magic in the bt-pan script. It doesn't return, so add an ampersand at the end.
bt-pan server pan0 &
Start the bluetooth security agent with wonderful ease and confidence. Optionally set a pin (it defaults to 0000).
blueagent5 --pin 4321 &
Okay, one last thing. Forward the network. This will only work if there is no fancy authentication at the router/dhcp, if there is, you may need to look further to solve this issue.
sysctl -w net.ipv4.ip_forward=1
iptables -A INPUT -i pan0 -j ACCEPT
iptables -A FORWARD -i pan0 -j ACCEPT
Once done, you may need to save these iptables settings and reinstate them each time the system boots.
Tiptoe over to your tablet or whatever you are trying to connect to the internet. Open Bluetooth in your settings. Pair with 4321 as your pin, and connect to the local network.
But you didn't need to tiptoe after all, it all seems quite robust to me. Enjoy!
After a lot of struggle, this is how I got it working. Let's hope it can help someone else. Long story short, edit /etc/bluetooth/main.conf to include this line:
DisablePlugins = network
Restart the bluetooth service.
sudo service bluetooth restart
FYI, here is my command for the "server" :
sudo pand -i 00:1A:7D:DA:71:14 --listen --master --role=NAP
And for the "client":
sudo pand --nodetach --connect 00:1A:7D:DA:71:14
Then you can just use ifconfig, ping, ssh... usual stuff. You might want to take a look here, it was useful to me.
A bluez-tools package is available on raspbian with the same functionality as the aforementioned python scripts. original answer
Here's how you can setup a bluetooth pan on Raspbian.
This answer uses systemd/networkd but you could do something similar with an interfaces file and dnsmasq if you wanted.
Run:
sudo apt-get install bluez-tools
Create the following files:
/etc/systemd/network/pan0.netdev
[NetDev]
Name=pan0
Kind=bridge
/etc/systemd/network/pan0.network
[Match]
Name=pan0
[Network]
Address=172.20.1.1/24
DHCPServer=yes
/etc/systemd/system/bt-agent.service
[Unit]
Description=Bluetooth Auth Agent
[Service]
ExecStart=/usr/bin/bt-agent -c NoInputNoOutput
Type=simple
[Install]
WantedBy=multi-user.target
/etc/systemd/system/bt-network.service
[Unit]
Description=Bluetooth NEP PAN
After=pan0.network
[Service]
ExecStart=/usr/bin/bt-network -s nap pan0
Type=simple
[Install]
WantedBy=multi-user.target
Then run
sudo systemctl enable systemd-networkd
sudo systemctl enable bt-agent
sudo systemctl enable bt-network
sudo systemctl start systemd-networkd
sudo systemctl start bt-agent
sudo systemctl start bt-network
Finally to pair, run:
sudo bt-adapter --set Discoverable 1
Then, on the other device pair it and connect the network. Hopefully everything should just work after that.
#cowswithguns
Your solution works almost flawlessly except for
bt-pan server pan &
it should be
bt-pan server pan0 &
Works great with rpi3 and bluez5.X
Only caveat it still uses somehow the wifi. I am trying to ssh to rpi3 via bluetooth while rpi3 is associated with a device that provide its own AP for a one-to-one connection and this cuts off the bluetooth communication. Works only if the rpi3 is associated to a wifi AP.