I have a Raspberry Pi with a SIM900 GSM add-on board connected. I have managed to establish a GPRS connection with pppd
by following this guide. (It's for a different GSM module but the steps are the same)
I would like to periodically send an AT command (AT+CCLK?
) to the SIM900 to check the clock. I have managed send ad hoc AT commands using screen
but when pppd
is up I can't use screen
to connect to the serial line. It just exits straight away saying [screen is terminating]
. I'm guessing this is because pppd
is using it to connect to the internet.
Q: How do I get the clock time without having to close down pppd?
Looking at part of the user manual it says that the SIM900 has a multiplexer designed to the GSM0710 standard. Would this be useful? If so how would I achieve this?
I will answer this question because it might help someone else too. But I want to start with sharing my experience with multiplexing the UART interface. After I set it all up is seemed like everything was working well. But when I was trying to connect to VPN or transfer some files Raspbian was completely freezing. I'm not sure what is the problem exactly, but it seems to be related to the n_gsm
or the cmux
components. Low bandwidth applications like ping, telnet or SSH seem to work fine though. The n_gsm
module is marked as experimental and should probably not be used in production.
The n_gsm
kernel module is not included in Raspbian by default. To start using a CMUX driver we need to update Raspbian and download the kernel source files, then we can compile the n_gsm
module.
sudo -i
apt update
apt dist-upgrade
apt install bc bison git build-essential flex libssl-dev
rpi-update
sync
reboot
wget -O /usr/bin/rpi-source https://raw.githubusercontent.com/notro/rpi-source/master/rpi-source
chmod +x /usr/bin/rpi-source
/usr/bin/rpi-source -q --tag-update
rpi-source
cd /root/linux/drivers/tty/
make -C /lib/modules/$(uname -r)/build M=$(pwd) -e CONFIG_N_GSM=m modules
cp /root/linux/drivers/tty/n_gsm.ko /lib/modules/`uname -r`/kernel/drivers/tty/
depmod
modprobe n_gsm
You may want to add the module in your /etc/modules as well if you want to load it automatically on boot.
cd /usr/local/src/
git clone https://github.com/Rtone/cmux.git
cd cmux
Usually you need to edit cmux.c
before compiling. Here is the diff that I used for my setup.
diff --git a/cmux.c b/cmux.c
index 1af0f50..f13edfe 100644
--- a/cmux.c
+++ b/cmux.c
@@ -29,6 +29,7 @@
#include <linux/types.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/sysmacros.h>
#include <fcntl.h>
#include <unistd.h>
#include <err.h>
@@ -50,13 +51,13 @@
#endif
/* serial port of the modem */
-#define SERIAL_PORT "/dev/ttyS1"
+#define SERIAL_PORT "/dev/ttyAMA0"
/* line speed */
#define LINE_SPEED B115200
/* maximum transfert unit (MTU), value in bytes */
-#define MTU 512
+#define MTU 1400
/**
* whether or not to create virtual TTYs for the multiplex
@@ -66,7 +67,7 @@
#define CREATE_NODES 1
/* number of virtual TTYs to create (most modems can handle up to 4) */
-#define NUM_NODES 4
+#define NUM_NODES 2
/* name of the virtual TTYs to create */
#define BASENAME_NODES "/dev/ttyGSM"
@@ -313,15 +314,9 @@ int main(void) {
* to fit your modem needs.
* The following matches Quectel M95.
*/
- if (send_at_command(serial_fd, "AT+IFC=2,2\r") == -1)
- errx(EXIT_FAILURE, "AT+IFC=2,2: bad response");
- if (send_at_command(serial_fd, "AT+GMM\r") == -1)
- warnx("AT+GMM: bad response");
if (send_at_command(serial_fd, "AT\r") == -1)
warnx("AT: bad response");
- if (send_at_command(serial_fd, "AT+IPR=115200&w\r") == -1)
- errx(EXIT_FAILURE, "AT+IPR=115200&w: bad response");
- sprintf(atcommand, "AT+CMUX=0,0,5,%d,10,3,30,10,2\r", MTU);
+ sprintf(atcommand, "AT+CMUX=0,0,0,%d,253,3,254,0,0\r", MTU);
if (send_at_command(serial_fd, atcommand) == -1)
errx(EXIT_FAILURE, "Cannot enable modem CMUX");
After making the changes, we should be ready to compile, install and run the multiplexer.
make
cp cmux /usr/bin/cmux
cmux
We should now be able to use the new interfaces. Instead of using /dev/ttyAMA0
we can now use both /dev/ttyGSM1
and /dev/ttyGSM2
. I'm using the first one with pppd and the second one to send AT commands simultaneously. For some reason I was unable to keep using wvdial
, so I dropped that completely and started using pppd
directly. For both cmux
and pppd
I created a systemd service that runs on boot, after each other, so at startup Raspbian is setting up the multiplexer and connecting with the internet over PPP. When the connection is live I'm sending an SMS message (through the secondary mux) to report that the terminal is now online.
I also wrote this post on the Seeed forum to answer a similar question. I'm curious if anyone shares my experience with stability or if anyone is able to share some improvements.