These notes are based on ethaniel's excellent guide. Please read that guide first and then consult these notes on some changes/tweeks I needed to do to get this running on the newest raspberyr pi OS (January 2023) with a Huawei E8372h-320 (2020 model).
Setup SMS forwarding with gammu on debian bullseye on a rasp pi B+ with the HUAWEI E8372h-320 (2020 model)
First and foremost we need to get the huawei into the correct mode. Unfortunately, usb modeswitch did not do this out-of-the-box for me.
Blacklist cdc_ether
by creating a file /etc/modprobe.d/blacklist-huawei-cdc-usb-net.conf
with the following contents:
blacklist cdc_ether
This is not strictly necessary but ensures that no usb0
network interface is created which we will not be using anyway.
For me usb modeswitch had a race condition where, sometimes, just after boot, the huawei stick would automatically switch to a different, incompatible mode, before usb modeswitch had a chance to switch it to the desired target mode (product id 155e
). Sometimes the stick would switch first automatically and sometimes usb modeswitch was faster. Once the stick had switched automatically there was no way to switch out of the incompatible state.
After some online re-search, it turns out that the huawei stick can detect a linux OS on the way it uses SCSI LUNs (whatever that is?!?) when trying to access the mass storage device. When the huawei detects a linux OS, it will switch to the undesired mode. To work around this race condition, we need to tell linux to ignore the mass storage device altogether.
We do this by editing /boot/cmdline.txt
and adding the following boot parameters:
usb-storage.quirks=12d1:1f01:i
the 12d1
:1f01
are the initial vendor/product ids (when the huawei is still in USB mass storage mode). The i
tells linux to ignore the device.
Unfortunately, this is not enough as the default debian installation of usb modeswitch does not correctly switch the huawei stick for me. It switches it yet to another incompatible mode. So, let's first ensure that the stick is not switched to any other mode and just stays in mass storage mode. Do this by disabling automatic running of usb modeswitch by editing /etc/usb_modeswitch.conf
and changing:
DisableSwitching=1
Even with the above, systemd
also installs a udev
rule which will automatically run usb modeswitch. Ensure that this does not happen by deleting the following file sudo rm /usr/lib/udev/rules.d/40-usb_modeswitch.rules
.
Reboot!
With the above change, the huawei stick now stays in mass storage mode (i.e. 12d1:1f01
) so that we have time to switch it to the desired mode. Check lsusb
that the device is indeed in the usb mass storage mode, i.e. vendor/device ids are 12d1:1f01
. If not, the rest of the guide will likely not work for you.
Now that the OS and/or the device does not switch the huawei stick into an incompatible mode, we can now add udev rules to switch it to the correct mode. Create the following udev rule /etc/udev/rules.d/20-huawei-modeswitch.rules
with the following contents:
ACTION=="bind", SUBSYSTEM=="usb", ATTR{idVendor}=="12d1", ATTR{idProduct}=="1f01", RUN+="/usr/sbin/usb_modeswitch -v 12d1 -p 1f01 -V 12d1 -P 155e -X"
Now, usb modeswitch will switch the huawei stick into the correct mode. You can test this by either rebooting or by retriggering udev with the following commands:
sudo udevadm control --reload-rules && sudo udevadm trigger
Check lsusb
is in the correct mode by checking that the vendor/product id is indeed 12d1:155e
. By default, raspberry pi OS contains all the correct drivers (cdc_* and option1 kernel modules) to access the device's serial ports. Double check this by checking that the /dev/ttyUSB0
port is now available. If it is not available then there is something wrong and the rest of the guide will likely not work for you.
Let's install gammu. Add the following to /etc/apt/sources.list
:
deb http://deb.debian.org/debian bullseye-backports main contrib non-free
Then:
sudo apt update
sudo apt install gammu-smsd
By default, systemd will start the gammu daemon during the boot process. However, the huawei stick will not be in the correct mode yet when gammu starts. So we want to stop and disable gammu for now while we ensure that gammu is only started when the huawei stick is in the correct mode. Disable and stop gammu:
sudo systemctl stop gammu-smsd
sudo systemctl disable gammu-smsd
To ensure that gammu is only started when the huawei stick is in the correct mode, add the following rule in /etc/udev/rules.d/21-huawei-start-gammu.rules
to inform systemd about the new device.
ACTION=="bind", DRIVER=="option1", SUBSYSTEM=="usb-serial", GROUP="dialout", TAG+="systemd"
Reboot your device as I could not get the above rule to work by just triggering udev.
As the above udev rule informs systemd about the new device, we can now add systemd dependencies (i.e. services like gammu) to the device (i.e. the /dev/ttyUSB0
device file). This way systemd will automatically start/stop gammu when the device tty appears/disappears respectively. Unfortunately, the device names, that systemd uses, are long and complicated and hard to predict. So we need to find the systemd device name for the /dev/ttyUSB0
port. To figure this out execute the following command:
systemctl list-units --type=device
There will be two entries for each ttyUSB*
, use the shorter one. For me it was:
sys-devices-platform-soc-3f980000.usb-usb1-1\x2d1-1\x2d1.2-1\x2d1.2:1.0-ttyUSB0.device
Now edit the gammu systemd file in /usr/lib/systemd/system/gammu-smsd.service
and modify the WantedBy=
under [Install]
. Change it to the above device, for example:
WantedBy=sys-devices-platform-soc-3f980000.usb-usb1-1\x2d1-1\x2d1.2-1\x2d1.2:1.0-ttyUSB0.device
this ensures that gammu is only loaded when the ttyUSB0 device is available.
By default, debian runs the gammu daemon with root permissions. This is a risk, as gammu is no longer actively maintained and contains many bugs. So I also ensured that gammu
runs under the gammu
user by modifying the [Service]
section as follows:
[Service]
RuntimeDirectory=gammu
EnvironmentFile=-/etc/default/gammu-smsd
User=gammu
Group=gammu
ExecStart=/usr/bin/gammu-smsd --pid=/run/gammu/gammu-smsd.pid --daemon
ExecReload=/bin/kill -HUP $MAINPID
ExecStopPost=/bin/rm -f /run/gammu/gammu-smsd.pid
Type=forking
PIDFile=/run/gammu/gammu-smsd.pid
Note: this is why GROUP="dialout"
is included in the udev rule quoted further above. Without this, the /dev/ttyUSB0
file will not yet have the correct permissions when gammu starts as a non-root user. Interestingly, systemd
will set the group to dialout
even without GROUP="dialout"
, but systemd
seems to do this too late, i.e. after starting the gammu service.
We also need to ensure that the spool
directory has the correct permissions too:
sudo chown -R gammu:gammu /var/spool/gammu
Then replace /etc/gammu-smsdrc
with:
# Configuration file for Gammu SMS Daemon
# Gammu library configuration, see gammurc(5)
[gammu]
port = /dev/ttyUSB0
connection = at
atgen_setCNMI=1,2
# SMSD configuration, see gammu-smsdrc(5)
[smsd]
service = files
logfile = syslog
CheckSecurity = 0
MultipartTimeout=20
debuglevel=0
HangupCalls=1
RunOnReceive=/usr/libexec/smsgateway/gammu.sh
# Paths where messages are stored
inboxpath = /var/spool/gammu/inbox/
outboxpath = /var/spool/gammu/outbox/
sentsmspath = /var/spool/gammu/sent/
errorsmspath = /var/spool/gammu/error
Note that the above atgen_setCNMI=1,2
is super important. Without this line the Huawei E8372h-320 did not work for me. It took me ages to figure this out.
Now create the gammu smsgateway script. First create the directory:
sudo mkdir -p /usr/libexec/smsgateway
Then add the gammu.sh
file:
#!/bin/bash
TOKEN="<YOUR-TELEGRAM-TOKEN>" # you get this from the @BotFather after creating your bot
CHAT_ID="<YOUR-CHAT-ID>" # you get this from @get_id_bot
# no need to change anything below.
URL="https://api.telegram.org/bot${TOKEN}/sendMessage"
CONTENT=`cat "/var/spool/gammu/inbox/${1}"`
eval "curl -s -X POST $URL -d chat_id=\"${CHAT_ID}\" -d text=\"${CONTENT}\""
and adjust permissions:
chown -R root:gammu /usr/libexec/smsgateway
chmod g+x /usr/libexec/smsgateway/gammu.sh
chmod u+x /usr/libexec/smsgateway/gammu.sh
Now reload systemd
sudo systemctl daemon-reload
sudo systemctl enable gammu-smsd
and reboot (or alternatively reload udev with):
sudo udevadm control --reload-rules && sudo udevadm trigger
gammu
should now be running and receiving sms.
Important Note: For me, after every gammu launch, it takes up to 10 minutes for the first text message to arrive after sending it. Subsequent text messages arrived almost instantaneously but the first one seems to take time. This makes debugging issues extremely frustrating and time consuming. Be warned!
Can I use this for Raspberry Pi 3 b+?