Cellular modems (Quectel EM05/EM06/EM12, Sierra EM7565, ...) expose
GPS data as NMEA on a dedicated USB serial interface. Until now we
relied on ModemManager's --location-enable-gps-nmea, which makes MM
hold the NMEA port and parse the stream itself — useful for mmcli
but a dead end for the rest of the system. The result was that
modem GPS was visible only via 'show modem' and could not act as an
NTP fallback time source on devices without dedicated GPS hardware.
This commit reroutes the NMEA stream into the existing
gpsd → chronyd pipeline so cellular modems behave just like any
other NMEA-over-USB GPS dongle. No changes to gpsd, chronyd, or
the ietf-hardware:gps component — the user activates it the same
way as for a dedicated receiver, by adding a 'gps' hardware
component that references /dev/gpsN.
This is Phase 2 of the modem GPS / location integration plan
(.notes/modem-gps-plan.md).
udev (src/modemd/77-mm-modem-gps.rules):
- For known vendor:product:interface tuples, set ID_MM_PORT_IGNORE
so ModemManager keeps off the NMEA port, and add
SYMLINK+="gps%n" so gpsd's existing udev hook picks up the
device automatically.
- Interface-number match uses ENV{ID_USB_INTERFACE_NUM} rather
than ATTRS{bInterfaceNumber}: udev requires all ATTRS{} matches
in a rule to share one parent, but idVendor/idProduct live on
the USB device while bInterfaceNumber lives on the USB
interface. ENV{} matching has no parent constraint and udev
already populates ID_USB_INTERFACE_NUM from bInterfaceNumber.
- Initial entries: Quectel EM05 (2c7c:0125), EM06-E (2c7c:0306),
EM12-G (2c7c:0512), Sierra Wireless EM7565 (1199:9091).
Easy to extend.
modemd (modemd/__init__.py):
- GPS_AT_COMMANDS table maps manufacturer -> (enable, disable) AT
command pair. prepare_location() issues the vendor AT command
via 'mmcli --command=AT+QGPS=1' (or AT+CGPS=1 for Sierra)
instead of --location-enable-gps-{nmea,raw}. Vendor lookup is
substring-based ('Quectel' matches both 'Quectel' and 'Quectel
Incorporated') because ModemManager normalises differently
across firmware revisions. For unrecognised vendors the
high-level MM path is still used as a fallback, so nothing
regresses for hardware not yet in the table.
- The AT path runs based on the udev/vendor table, not on MM's
--location-status capabilities. Setting ID_MM_PORT_IGNORE on
the NMEA port removes 'gps' from MM's capability list even
though the GPS hardware is still there, so a capability gate
would mistakenly skip GPS for the very modems we're targeting.
- _location_capabilities() filters MM-managed sources so a single
unsupported flag (e.g. CDMA on an LTE-only modem) doesn't fail
the whole batched call. Sources the modem doesn't support are
silently skipped; a warning is logged only if the user's YANG
config explicitly lists one.
- Subprocess fan-out collapsed: agps-msa, agps-msb, 3gpp and cdma
flags share a single batched mmcli invocation.
prepare_location() drops from 5 subprocess calls to 1 (unknown
vendor) or 2 (known vendor, AT + batched MM).
- Stringly-typed if/elif source dispatch replaced with a
dict-driven table (LOCATION_MM_FLAGS).
- Two helpers eliminate the ['mmcli', '-m', self.path, ...]
boilerplate at ~30 ModemThread call sites:
self._mmcli(*args, check=True) # runcmd wrapper
self._mmclij(*args) # runcmdj wrapper
build (package/feature-modem/Config.in):
- Select BR2_PACKAGE_MODEM_MANAGER_ATVIADBUS so ModemManager
accepts raw AT commands over D-Bus without being started in
--debug mode. Required by the AT path above; without it
'mmcli --command' is rejected with MM_CORE_ERROR_UNAUTHORIZED.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Turn any ARM or x86 device into a powerful, manageable network appliance in minutes. From $35 Raspberry Pi boards to enterprise switches — deploy routers, IoT gateways, edge devices, or custom network solutions that just work.
Our Values
🔒 Immutable
Your system never breaks. Read-only filesystem with atomic upgrades
means no configuration drift, no corrupted updates, and instant rollback
if something goes wrong. Deploy once, trust forever.
🤝 Friendly
Actually easy to use. Auto-generated CLI from standard YANG models comes
with built-in help for every command — just hit ? or
TAB for context-aware assistance.
Familiar NETCONF & RESTCONF APIs and comprehensive documentation mean you're never stuck. Whether you're learning networking or managing enterprise infrastructure.
🛡️ Secure
Built with security as a foundation, not an afterthought. Minimal
attack surface, separation between system and data, and container
isolation. Sleep better knowing your infrastructure is protected.
Why Choose Infix
Hardware Flexibility: Start with a $35 Raspberry Pi, scale to enterprise switching hardware. Same OS, same tools, same reliability.
Standards-Based: Built around YANG models and IETF standards. Learn once, use everywhere - no vendor lock-in.
Container Ready: Run your applications alongside networking functions. GPIO access, dedicated Ethernet ports, custom protocols — your device, your rules.
Use Cases
- Home Labs & Hobbyists:
Transform a Raspberry Pi into a full-featured router with WiFi - IoT & Edge Computing:
Bridge devices to the cloud with reliable, updatable gateways - Small Business Networks:
Enterprise-grade features without the complexity or cost - Developers & Makers:
Test networking concepts, prototype IoT solutions, or build custom appliances - Network Professionals:
Consistent tooling from development to production deployment.
How about a digital twin using raw Qemu or GNS3!
Quick Example
Configure an interface in seconds - the CLI guides you with built-in help:
admin@infix-12-34-56:/> configure
admin@infix-12-34-56:/config/> edit interface eth0
admin@infix-12-34-56:/config/interface/eth0/> set ipv4 TAB
address autoconf bind-ni-name dhcp
enabled forwarding mtu neighbor
admin@infix-12-34-56:/config/interface/eth0/> set ipv4 address 192.168.2.200 prefix-length 24
admin@infix-12-34-56:/config/interface/eth0/> show
type ethernet;
ipv4 {
address 192.168.2.200 {
prefix-length 24;
}
}
admin@infix-12-34-56:/config/interface/eth0/> diff
interfaces {
interface eth0 {
+ ipv4 {
+ address 192.168.2.200 {
+ prefix-length 24;
+ }
+ }
}
}
admin@infix-12-34-56:/config/interface/eth0/> leave
admin@infix-12-34-56:/> show interfaces
INTERFACE PROTOCOL STATE DATA
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
eth0 ethernet UP 52:54:00:12:34:56
ipv4 192.168.2.200/24 (static)
ipv6 fe80::5054:ff:fe12:3456/64 (link-layer)
admin@infix-12-34-56:/> copy running startup
Notice how TAB completion shows available options, show
displays current config, and diff shows exactly what changed before
you commit your changes with the leave command.
For more information, see CLI documentation.
Get Started
Get pre-built images for your hardware. Use the CLI, web
interface, or standard NETCONF/RESTCONF tools, e.g., curl. Add
containers for any custom functionality you need.
Supported Platforms
- Raspberry Pi 2B/3B/4B/CM4 - Perfect for home labs, learning, and prototyping
- Banana Pi-R3 - Your next home router and gateway
- NanoPi R2S - Compact dual-port router in a tiny package
- x86_64 - Run in VMs or on mini PCs for development and testing
- Marvell CN9130 CRB, EspressoBIN - High-performance ARM64 platforms
- Microchip SparX-5i - Enterprise switching capabilities
- Microchip SAMA7G54-EK - ARM Cortex-A7
- NXP i.MX8MP EVK - Highly capable ARM64 SoC
- StarFive VisionFive2 - RISC-V architecture support
Why start with Raspberry Pi? It's affordable, widely available, has built-in WiFi + Ethernet, and runs the exact same Infix OS you'd deploy in production. Perfect for learning, prototyping, or even small-scale deployments.
Technical Details
Built on proven open-source foundations: Linux, Buildroot, and sysrepo — for reliability you can trust:
- Immutable OS: Read-only filesystem, atomic updates, instant rollback
- YANG Configuration: Industry-standard models with auto-generated tooling
- Hardware Acceleration: Linux switchdev support for wire-speed packet processing
- Container Integration: Docker support with flexible network and hardware access
- Memory Efficient: Runs comfortably on devices with as little as 256 MB RAM
- Code Signing: Releases are cryptographically signed for integrity verification
Perfect for everything from resource-constrained edge devices to high-throughput network appliances.
With the entire system modeled in YANG, scalability is no longer an issue, be it in development, testing, or end users deploying and monitoring their devices. All knobs and dials are accessible from the CLI (console/SSH), or remotely using the native NETCONF or RESTCONF APIs.
Check the Latest Build for bleeding-edge features.