pfSense 4G Modem
August 27, 2023.
Recently, I acquired a computer on which I intend to run a virtualised firewall, for this purpose I installed pfSense
this is an operating system based on FreeBSD with plenty of networking capabilities out of the box.
I also bought a 4G LTE modem card, a Huawei me909-120 along with a SIM card adapter and a
wireless card to use as AP, but wi-fi is beyond the scope of this post.
I noticed some strange behaviour on the 4G modem, and after not finding any solutions on pfSense forums,
I decided to document the fix on a blog post.
In this article, we describe a problem found with a particular 4G modem card and we detail some steps to
troubleshoot and fix it, even if you don’t have this exact problem you can still benefit from the steps
provided in the troubleshooting section.
Table of contents
- Table of contents
- The problem
- Reviewing configuration
- Troubleshooting
- Fixing the problem
- Monitoring uptime
- Closing thoughts
The problem
After configuring Point to Point Protocol (PPP) interface and setting it as the
WAN interface, the card disconnects and reconnects.
This can be seen on the pfSense dashboard, under Status > System Logs > System
ugen0.2: <Huawei Technologies Co., Ltd. HUAWEI Mobile V7R11> at usbus0 (disconnected)
u3g0: at uhub0, port 6, addr 2 (disconnected)
u3g0: detached
ugen0.2: <Huawei Technologies Co., Ltd. HUAWEI Mobile V7R11> at usbus0
u3g0 on uhub0
u3g0: <Huawei Mobile Connect - Modem> on usbus0
u3g0: Found 5 ports.
As you can see on these kernel messages the card is disconnected from the port and then it is found again.
When this happens the serial port device is linked again with an increment of 1.
e.g. If originally the serial port was linked to /dev/cuaU0
after seeing the previous
messages it would now be at /dev/cuaU1
This would result in the following PPP message message under
Status > System Logs > PPP
[wan_link0] MODEM: can't ioctl(TIOCMGET) /dev/cuaU0.0: Device not configured
Since the interface was configured to look for the modem’s serial port under /dev/cuaU0
,
however, the card is now responding to serial commands under /dev/cuaU1
. So one must now reconfigure
the interface to use the new serial port.
Most of the time, this happened so fast the modem did not have a chance to even connect to the mobile network,
making me think the card was flat out fried. But on a few attempts it managed to stay connected up to 5 or 6
minutes, even getting a public IP address, which gave me hope to look for a solution.
Reviewing configuration
The configuration varies depending on the modem model and service provider. Probably the easiest way to know your
Access Point Name (APN) is to plug the SIM card to your phone and connect to the
network. The values should automatically fill in on your phone’s mobile network settings and from there you
can take note of the values you should use.
In this case for the Huawei me909-120 card, I found in some forums I needed to have the following
connection string
&F&C1&D2E0S0=0
Under the PPP interface Advanced configuration. This string represents a few serial AT commands to get
the card in a working state.
Aside from this there is nothing more to be done here, only configuring the interface according to official
docs on PPP
.
Troubleshooting
-
Check the hardware is detected.
You can do this with
dmesg
or withusbconfig
you will need access to a shell for this.
e.g. Using dmesg
:
root# dmesg | grep -iE "modem|card|huawei"
ugen0.2: <Huawei Technologies Co., Ltd. HUAWEI Mobile V7R11> at usbus0
u3g0: <Huawei Mobile Connect - Modem> on usbus0
Dumping device descriptions with usbconfig
you may see multiple devices along with your modem:
root# usbconfig dump_device_desc
...
ugen0.2: <Huawei Technologies Co., Ltd. HUAWEI Mobile V7R11> at usbus0, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=ON (2mA)
bLength = 0x0012
bDescriptorType = 0x0001
bcdUSB = 0x0200
bDeviceClass = 0x0000 <Probed by interface class>
bDeviceSubClass = 0x0000
bDeviceProtocol = 0x00ff
bMaxPacketSize0 = 0x0040
idVendor = 0x12d1
idProduct = 0x15c1
bcdDevice = 0x0102
iManufacturer = 0x0001 <Huawei Technologies Co., Ltd.>
iProduct = 0x0002 <HUAWEI Mobile V7R11>
iSerialNumber = 0x0003 <0123456789ABCDEF>
bNumConfigurations = 0x0003
- Check the modem is responding to serial port
Send a few AT commands to a serial port link, you may have to try different links until you find
the one that works, here I send the command AT and the modem responded with OK
then I send ATCSQ to check signal and this one returned an error.
You may not see your commands echoed back to your terminal, so try to type them and hit enter.
root# cu -l /dev/cuaU0.3 -s 9600 -h
Connected
AT
OK
ATCSQ
ERROR
The fact that I had to use /dev/cuaU0.3
doesn’t necessarily mean I have to use this link on my
interface configuration, in fact I found that my interface only works when I select /dev/cuaU0.0
. But
like this we can verify if the modem works and responds to serial commands.
On one particular port this was printed to my terminal, which is related to various signal metrics
root# cu -l /dev/cuaU0.2 -s 9600 -h
Connected
...
ATA
NO CARRIER
^RSSI: 17
^HCSQ: "LTE",42,33,141,20
^RSSI: 17
^HCSQ: "LTE",43,39,146,30
^RSSI: 16
^HCSQ: "LTE",40,34,106,24
^RSSI: 14
^HCSQ: "LTE",36,26,96,16
^RSSI: 16
^HCSQ: "LTE",41,35,91,28
^RSSI: 15
^HCSQ: "LTE",38,30,106,22
^RSSI: 17
Fixing the problem
So far the card is correctly recognized and it is accepting AT serial commands, yet it is constantly reconnecting
and thus changing serial device link on the pfSense appliance. Since pfSense does not
automatically detect the serial device for a modem, we need a way to always set the same serial device for the
modem.
Reading on a forum about a similar problem, people talked about device quirks, maybe this is a better approach
for this problem, but the solution proposed here is to create a devd configuration.
You can read from man 8 devd
, devd is a system daemon that runs in the background and when
a device is plugged in, it will perform actions according to devd.conf, you can see how this
configuration works by reading man 5 devd.conf
.
An example of its use is visible on some user friendly desktop Linux distributions; when you connect a USB
storage device, devd will usually have a rule to automatically mount the filesystem somewhere on the
system.
We will create a new rule file /etc/devd/modem.rules
with this content:
attach 0 {
device-name "u3g0"; # Find this with: dmesg |grep -i "card brand"
match "vendor" "0x12d1"; # Find this with: usbconfig dump_device_desc
match "product" "0x15c1"; # Find this with: usbconfig dump_device_desc
action "/usr/local/bin/create_links.sh %d"; # A script we will create to map serial ports
};
You can find your device name with dmesg
as shown before, or with sysctl
if you know
your card’s brand name, or you can simply grep for usb and find your card there.
root# sysctl -a | grep -i "huawei"
ugen0.2: <Huawei Technologies Co., Ltd. HUAWEI Mobile V7R11> at usbus0
u3g0: <Huawei Mobile Connect - Modem> on usbus0
dev.u3g.0.%desc: Huawei Mobile Connect - Modem
The last line in the modem.rules file specifies the action, in this case, we will run a custom script to
map the serial ports.
Create the script under /usr/local/bin/create_links.sh
with this content:
#!/bin/sh
device=
serial_ports=$(ls /dev/$device.*)
for port in $serial_ports; do
link_name=$(echo $port | sed 's/.*\.\(.*\)$/\1/')
ln -sf $port /dev/cuaU0.$link_name
done
And grant the script execution rights:
chmod u+x /usr/local/bin/create_links.sh
Monitoring uptime
At this point we can restart the pfSense appliance and verify that the serial device ports are no longer
changing, they should always be linked to /dev/cuaU0.*
After configuring devd rules it can be seen that the interface has no problems staying up.
Closing thoughts
In this post we covered a very specific problem on a 4G modem card. It is not clear if the issue has to do with compatibility, hardware or software, maybe it is related to the modem card’s firmware.
In any case, since the card was properly detected and receiving serial commands it prompted me to search for a simple solution instead of just buying a new card, I must say I did use the help of ChatGPT-3.5 in my troubleshooting and for the creation of the device linking script.