Skip to content

Instantly share code, notes, and snippets.

@werebus
Last active November 10, 2023 21:38
Show Gist options
  • Save werebus/b5e9fd54a1c0845aef43 to your computer and use it in GitHub Desktop.
Save werebus/b5e9fd54a1c0845aef43 to your computer and use it in GitHub Desktop.
Script for making our Novatel 551L connect to Verizon

The following are instructions for setting up a Verizon-provided NovaTel 551L on a Debian-based Linux system. Our target system was an embedded ARM TS-7800, which left us somewhat handicapped when it came to the version of Linux that we were able to use. We were able to install Debian Wheezy (7.7) on this device, but limited to the kernel sources that were provided by the manufacture (2.6.34).

If you have a more modern kernel available to you (>=3.4), look into libqmi and ModemManager, which use the native QMI protocol to communicate with the modem instead of the AT command hacks featured here.

Prerequisites

There aren't too many, but you do need few kernel modules:

  • USB_NET_CDCETHER
  • USB_SERIAL_OPTION

If you have a monolithic kernel, these are probably already built. In our situation, however, we had to build these from source.

You also need udev; probably you're fine.

Prep the Modem

Several things I've read online say that you need to use the Verizon-provided VZAccess Manager software to get the modem connected initially. I'm not sure exactly why this is, but there must be some sort of secret provisioning step happening behind the scenes. Grab you favorite Windows computer, install VZAccess Manager and connect to the network once.

The Driver Package

We started by installing the driver package provided. I've included it here because I can't find the version we were provided elsewhere on the Internet, and it's GPL-licensed. Click here, to download the .deb

dpkg -i novatel_modem_drivers_config_1.2-1.deb

Pay attention to the output of the above command. It will let you know if there's anything wrong with the kernel module prerequisites laid out above, the installation process will let you know.

Fix udev Rules

The driver package provides udev rules, but they use an old rule syntax that's been deprecated for a while and was removed entirely in udev version 174. Replace /etc/udev/rules.d/nvtl_modem.rules with the version in this gist.

Vzwctl

This is a small python script for handling the connecting/disconnecting to the CDMA network. It requires pySerial:

apt-get install python-serial

Put vzwctl.py in /usr/local/bin and make it executable.

Usage:

  • vzwctl.py up -- connect to the CDMA network
  • vzwctl.py down -- disconnect from the CDMA network
  • vzwctl.py status -- Output the current connection status

Configure the Network Interface

Add the "interfaces" snippit below to /etc/network/interfaces. Note that on more modern kernels, the network interface is probably called something like usb0 and not eth1.

# add the following in /etc/network/interfaces
auto eth1
allow-hotplug eth1
iface eth1 inet dhcl
pre-up vzwctl.py up
post-down vzwctl.py down
# place this file in /etc/udev/rules.d/
ACTION=="add", ATTRS{idVendor}=="1410", ENV{vendor}="NVTL"
# When novatel modem appears, configure for it, but ignore the mass storage devices
ACTION=="add", ENV{vendor}=="NVTL", ATTRS{idProduct}!="5???", RUN+="/etc/udev/nvtl_modem.sh"
# symlink the nvtl ports into a separate directory
KERNEL=="ttyUSB[0-9]*", ENV{vendor}=="NVTL", SYMLINK="nvtl/port%n"
# Mapping devices to port maps (which are defined below)
ENV{vendor}=="NVTL", ATTRS{idProduct}=="11??", ENV{technology}="EVDO"
ENV{vendor}=="NVTL", ATTRS{idProduct}=="14??", ENV{technology}="HSPA"
ENV{vendor}=="NVTL", ATTRS{idProduct}=="21??", ENV{technology}="EVDO"
ENV{vendor}=="NVTL", ATTRS{idProduct}=="24??", ENV{technology}="HSPA"
ENV{vendor}=="NVTL", ATTRS{idProduct}=="41??", ENV{technology}="EVDO"
ENV{vendor}=="NVTL", ATTRS{idProduct}=="44??", ENV{technology}="HSPA"
ENV{vendor}=="NVTL", ATTRS{idProduct}=="600?", ENV{technology}="EVDO"
ENV{vendor}=="NVTL", ATTRS{idProduct}=="601?", ENV{technology}="EVDO"
ENV{vendor}=="NVTL", ATTRS{idProduct}=="6020", ENV{technology}="EVDO"
###ENV{vendor}=="NVTL", ATTRS{idProduct}=="6021", ENV{technology}="WIMAX"
ENV{vendor}=="NVTL", ATTRS{idProduct}=="6032", ENV{technology}="INDIAN"
ENV{vendor}=="NVTL", ATTRS{idProduct}=="700?", ENV{technology}="HSPA"
ENV{vendor}=="NVTL", ATTRS{idProduct}=="703?", ENV{technology}="HSPA+"
ENV{vendor}=="NVTL", ATTRS{idProduct}=="704?", ENV{technology}="3G4G"
ENV{vendor}=="NVTL", ATTRS{idProduct}=="800?", ENV{technology}="EVDO"
ENV{vendor}=="NVTL", ATTRS{idProduct}=="900?", ENV{technology}="HSPA"
ENV{vendor}=="NVTL", ATTRS{idProduct}=="901?", ENV{technology}="3G4G"
ENV{vendor}=="NVTL", ATTRS{idProduct}=="a00?", ENV{technology}="GOBI"
###ENV{vendor}=="NVTL", ATTRS{idProduct}=="a01?", ENV{technology}="GOBI"
ENV{vendor}=="NVTL", ATTRS{idProduct}=="a02?", ENV{technology}="GOBI"
ENV{vendor}=="NVTL", ATTRS{idProduct}=="b00?", ENV{technology}="3G4G"
# Port maps - handy shortcuts for different interfaces
# Generic USB HSPA interface ID
KERNEL=="ttyUSB[0-9]*", ENV{technology}=="HSPA", ATTRS{bInterfaceNumber}=="00", SYMLINK+="nvtl/modem"
KERNEL=="ttyUSB[0-9]*", ENV{technology}=="HSPA", ATTRS{bInterfaceNumber}=="01", SYMLINK+="nvtl/status"
KERNEL=="ttyUSB[0-9]*", ENV{technology}=="HSPA", ATTRS{bInterfaceNumber}=="02", SYMLINK+="nvtl/application"
KERNEL=="ttyUSB[0-9]*", ENV{technology}=="HSPA", ATTRS{bInterfaceNumber}=="03", SYMLINK+="nvtl/eapsim"
KERNEL=="ttyUSB[0-9]*", ENV{technology}=="HSPA", ATTRS{bInterfaceNumber}=="04", SYMLINK+="nvtl/gps"
KERNEL=="ttyUSB[0-9]*", ENV{technology}=="HSPA", ATTRS{bInterfaceNumber}=="05", SYMLINK+="nvtl/storage"
# MDM8200 USB HSPA+ interface ID
KERNEL=="ttyUSB[0-9]*", ENV{technology}=="HSPA+", ATTRS{bInterfaceNumber}=="00", SYMLINK+="nvtl/modem"
KERNEL=="ttyUSB[0-9]*", ENV{technology}=="HSPA+", ATTRS{bInterfaceNumber}=="01", SYMLINK+="nvtl/status"
KERNEL=="ttyUSB[0-9]*", ENV{technology}=="HSPA+", ATTRS{bInterfaceNumber}=="02", SYMLINK+="nvtl/application"
KERNEL=="ttyUSB[0-9]*", ENV{technology}=="HSPA+", ATTRS{bInterfaceNumber}=="04", SYMLINK+="nvtl/eapsim"
KERNEL=="ttyUSB[0-9]*", ENV{technology}=="HSPA+", ATTRS{bInterfaceNumber}=="05", SYMLINK+="nvtl/gps"
KERNEL=="ttyUSB[0-9]*", ENV{technology}=="HSPA+", ATTRS{bInterfaceNumber}=="06", SYMLINK+="nvtl/storage"
# Generic USB EVDO interface ID
KERNEL=="ttyUSB[0-9]*", ENV{technology}=="EVDO", ATTRS{bInterfaceNumber}=="00", SYMLINK+="nvtl/modem"
KERNEL=="ttyUSB[0-9]*", ENV{technology}=="EVDO", ATTRS{bInterfaceNumber}=="01", SYMLINK+="nvtl/status"
KERNEL=="ttyUSB[0-9]*", ENV{technology}=="EVDO", ATTRS{bInterfaceNumber}=="02", SYMLINK+="nvtl/application"
KERNEL=="ttyUSB[0-9]*", ENV{technology}=="EVDO", ATTRS{bInterfaceNumber}=="03", SYMLINK+="nvtl/gps"
KERNEL=="ttyUSB[0-9]*", ENV{technology}=="EVDO", ATTRS{bInterfaceNumber}=="04", SYMLINK+="nvtl/storage1"
KERNEL=="ttyUSB[0-9]*", ENV{technology}=="EVDO", ATTRS{bInterfaceNumber}=="06", SYMLINK+="nvtl/storage2"
# INDIAN USB HSPA interface ID (EVDO/WIMAX)
KERNEL=="ttyUSB[0-9]*", ENV{technology}=="INDIAN", ATTRS{bInterfaceNumber}=="00", SYMLINK+="nvtl/modem"
KERNEL=="ttyUSB[0-9]*", ENV{technology}=="INDIAN", ATTRS{bInterfaceNumber}=="01", SYMLINK+="nvtl/status"
KERNEL=="ttyUSB[0-9]*", ENV{technology}=="INDIAN", ATTRS{bInterfaceNumber}=="02", SYMLINK+="nvtl/console"
KERNEL=="ttyUSB[0-9]*", ENV{technology}=="INDIAN", ATTRS{bInterfaceNumber}=="04", SYMLINK+="nvtl/gps"
KERNEL=="ttyUSB[0-9]*", ENV{technology}=="INDIAN", ATTRS{bInterfaceNumber}=="05", SYMLINK+="nvtl/storage"
# GLOBAL USB GOBI interface ID (EVDO/HSPA)
KERNEL=="ttyUSB[0-9]*", ENV{technology}=="GOBI", ATTRS{bInterfaceNumber}=="00", SYMLINK+="nvtl/fwloader"
KERNEL=="ttyUSB[0-9]*", ENV{technology}=="GOBI", ATTRS{bInterfaceNumber}=="01", SYMLINK+="nvtl/composite"
KERNEL=="ttyUSB[0-9]*", ENV{technology}=="GOBI", ATTRS{bInterfaceNumber}=="02", SYMLINK+="nvtl/status"
KERNEL=="ttyUSB[0-9]*", ENV{technology}=="GOBI", ATTRS{bInterfaceNumber}=="03", SYMLINK+="nvtl/gps"
KERNEL=="ttyUSB[0-9]*", ENV{technology}=="GOBI", ATTRS{bInterfaceNumber}=="05", SYMLINK+="nvtl/modem"
# Generic USB 3G/4G interface ID (includes MDM8220-based devices)
KERNEL=="ttyUSB[0-9]*", ENV{technology}=="3G4G", ATTRS{bInterfaceNumber}=="00", SYMLINK+="nvtl/modem"
KERNEL=="ttyUSB[0-9]*", ENV{technology}=="3G4G", ATTRS{bInterfaceNumber}=="01", SYMLINK+="nvtl/status"
KERNEL=="ttyUSB[0-9]*", ENV{technology}=="3G4G", ATTRS{bInterfaceNumber}=="02", SYMLINK+="nvtl/application"
KERNEL=="ttyUSB[0-9]*", ENV{technology}=="3G4G", ATTRS{bInterfaceNumber}=="04", SYMLINK+="nvtl/gps"
#!/usr/bin/env python
import io
import serial
import re
import sys
class VzwModem:
def __init__(self, sport):
self.current_message = ''
self.ser = serial.Serial(sport, 115200)
def wait_for(self, message, timeout = None):
self.ser.timeout = timeout
self.current_message = ''
while not self.current_message.endswith(message):
c = self.ser.read()
if c != '':
self.current_message += c
else:
print "Timeout waiting for " + message
return False
self.ser.flushInput()
return True
def send(self, message):
self.ser.write(message + "\r")
def connect(self):
self.send("AT$NWQMICONNECT=,,,,,,vzwinternet")
self.wait_for("OK", 5)
def disconnect(self):
self.send("AT$NWQMIDISCONNECT")
self.wait_for("OK", 2)
def connected(self):
self.send("AT$NWQMISTATUS")
self.ser.timeout = 2
stat = self.ser.readlines()[2]
return re.search(r": ([A-Z]+)\r\n", stat).group(1) == "CONNECTED"
if __name__ == "__main__":
v = VzwModem('/dev/modem')
if sys.argv[1] == "up":
if not v.connected():
v.connect()
elif sys.argv[1] == "down":
if v.connected():
v.disconnect()
elif sys.argv[1] == "status":
print ("Connected" if v.connected() else "Disconnected")
else:
print "Usage: " + __file__ + " [ up | down | status ]"
sys.exit(1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment