1. Overview

USB modems are widely used to facilitate internet connectivity in systems, enabling high-speed data transmission over cellular networks. In Linux, communicating with our USB modems enables us to utilise the modems effectively, ensuring reliable and seamless data transmission.

In this tutorial, we’ll see how we can identify, configure, and communicate with our USB modem in a Linux environment.

2. Problem Statement

Traditionally, Linux treats everything, especially the devices we connect to our system, as files and directories to read from and write to. We can find these device files in the /dev directory of our system. Everything from our hard disk drives, USBs, printers, and ports is listed in this directory.

When we connect a device via a USB port to our system, Linux creates a file for that device in the /dev directory.

How can we then utilize this device file to communicate with our modem?

3. Identifying USB Modems in Linux

First, we check to see if our device has been properly loaded into our system. To do this, we use the lsusb command:

$ lsusb
Bus 001 Device 013: ID 058f:6387 Huawei Technologies Co. Ltd. E353/E8221 (Mass storage mode)
Bus 001 Device 023: ID 80ee:0021 VirtualBox USB Tablet
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

The lsusb command displays all the USB buses in the system and all the devices connected to them. We can see that the system lists our modem as Device 013, with a vendorID and productID of 058f and 6387, respectively.

Generally, our system detects the type of device we connect. However, there are cases where this doesn’t happen, and our system reads our USB device incorrectly.

In this case, the system reads our modem as a storage device. This affects our ability to communicate with the device effectively.

Consequently, we have to ensure that our system reads it properly before we can communicate with it.

4. Configuring USB Modems

There are two distinct ways through which we can configure our USB modem so that the system can recognize it. The first way is by manually editing the configuration file of the usb_modeswitch package in the /etc directory.

The usb_modeswitch package is a mode-switching tool for USB devices, providing multiple states or modes. We first open the file as a root user using the sudo command to enable us to write to it:

$ sudo vim /etc/usb_modeswitch.conf

Then, we append the details of our modem to the file:

#Huawei E8221
DefaultVendor = 0x058f
DefaultProduct = 0x6387
TargetVendor = 0x058f
TargetProduct = 0x6387
MessageContent = "555342430000000000000000000000110600000000000000000000000000"

What this does is configure the usb_modeswitch package to target our modem and send a message to test this mode switch.

Consequently, we can go ahead and execute the usb_modeswitch command:

$ sudo usb_modeswitch -c /etc/usb_modeswitch.conf
Look for target devices ...
 Found devices in target mode or class (1)
Look for default devices ...
 Found devices in default mode (1)
Access device 013 on bus 001
Get the current device configuration ...
Current configuration number is 1
...
Looking for active drivers ...
 OK, driver detached
Set up interface 0
Use endpoint 0x01 for message sending ...
Trying to send message 1 to endpoint 0x01 ...
 OK, message successfully sent
...
 Device is gone, skip any further commands
-> Run lsusb to note any changes. Bye!

At this point, the system recognizes our modem in its appropriate mode.

On the other hand, we can use single-line terminal commands to achieve the same result:

$ sudo usb_modeswitch -v 0x058f -p 0x6387 -V 0x058f -P 0x6387 -m "0x01" -M "555342430000000000000000000000110600000000000000000000000000"

If successful, we’ll receive the same output as above. We can verify this change by running the lsusb command again:

$ lsusb
Bus 001 Device 013: ID 058f:6387 Huawei Technologies Co. Ltd. E353/E8221
Bus 001 Device 023: ID 80ee:0021 VirtualBox USB Tablet
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

Our system recognizes the modem in its appropriate mode. Let’s read the device file of our modem using the dmesg command tool:

$ dmesg | grep ttyU*
[   0.000000] console [tty0] enabled
[ 463.367652] usb 1-2 : GSM modem [1-port] converter now attached to ttyUSB0
[ 463.368192] usb 1-2 : GSM modem [1-port] converter now attached to ttyUSB1

The dmesg command is a powerful tool that displays messages from our Linux kernel. In this output, we filtered all messages relating to our USB modem device file creation. We see that the USB modem device file has been created at the serial port ttyUSB0.

Furthermore, we need to grant this device file the necessary read and write permissions:

$ sudo chmod -R a+rwx /dev/ttyUSB0

This grants read, write, and execute permissions to all users on our device file.

Then, we temporarily stop our ModemManager service:

$ sudo systemctl stop ModemManager.service

Finally, we set a baud rate for our specified serial port:

$ sudo stty -F /dev/ttyUSB0 9600

This enables other applications and tools to communicate with the modem using the specified settings.

5. Communicating With USB Modems

Now that we’ve established our USB modem connection and a device file has been created, let’s see how we can communicate with it.

We can test communication with our modem using AT commands or the Hayes command set. This consists of a series of short text strings, which we can combine to produce commands for modem operations.

We want to test both the read and write status of our modem’s device file. Therefore, we’ll make use of two terminal tabs to accomplish this.

In the first tab, we test the read status of the serial port:

$ sudo cat < /dev/ttyUSB0
_

Here, we’re trying to read the contents of the device file. Currently, nothing is displayed, as no command is being written to it yet.

Conversely, we’ll test the write status in the second terminal:

$ sudo echo -e "AT\r" > /dev/ttyUSB0

Here, we’re trying to check communication between our modem and the system by sending an AT command.

If we navigate to our first terminal, we notice a change in the read status:

$ sudo cat < /dev/ttyUSB0

OK

Evidently, we can see that our device and system communicate correctly. If one of the components isn’t working, we obtain an Error message.

6. Conclusion

In this article, we discussed how we can communicate with USB modems in Linux. We explored ways to identify and configure our modem device using the lsusb, usb_modeswitch and dmesg commands. Lastly, we tested communication between our modem and our system using the AT command.

Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.