A Go library for parsing and working with ModemManager CLI (mmcli) JSON output. This library provides a simple interface to work with modem information, connection status, signal strength, location data, network time, SMS messaging, and other modem-related functionality.
go get github.com/rescoot/go-mmcli- Parse mmcli JSON output into Go structs
- Get modem connection status
- Monitor signal strength
- Access port information (QMI, AT, NET, etc.)
- Check SIM lock status
- Get current network technology (2G/3G/4G)
- Get operator information
- Monitor unlock attempts
- Check IPv6 support
- Access complete port mapping
- Get and manage location information
- Establish and manage network connections
- Retrieve network time information
- Send and receive SMS messages
The library provides several ways to find modems:
// Get all modem IDs
ids, err := mmcli.GetModemIDs()
// Get full DBus paths
paths, err := mmcli.ListModems()
// Get just the first modem ID (common case)
id, err := mmcli.GetFirstModemID()
// Get details for a specific modem
modem, err := mmcli.GetModemDetails(id)package main
import (
"fmt"
"log"
"github.com/rescoot/go-mmcli"
)
func main() {
// List available modems
ids, err := mmcli.GetModemIDs()
if err != nil {
log.Fatal(err)
}
fmt.Printf("Found %d modems: %v\n", len(ids), ids)
// Get details for first modem
modem, err := mmcli.GetModemDetails(ids[0])
if err != nil {
log.Fatal(err)
}
if modem.IsConnected() {
strength, _ := modem.SignalStrength()
name, code := modem.GetOperatorInfo()
tech := modem.GetCurrentAccessTechnology()
fmt.Printf("Connected to %s (%s)\n", name, code)
fmt.Printf("Technology: %s\n", tech)
fmt.Printf("Signal: %d%%\n", strength)
}
}Parse(data []byte) (*ModemManager, error)- Parse mmcli JSON outputListModems() ([]string, error)- Get full DBus paths of all modemsGetModemIDs() ([]string, error)- Get IDs of all modemsGetFirstModemID() (string, error)- Get ID of first available modemGetModemDetails(id string) (*ModemManager, error)- Get details for specific modemResetModem(modemID string) (bool, error)- Reset a modemGetSIMInfo(simID string) (*SIMInfo, error)- Get SIM card information
IsConnected() bool- Check if modem is connectedSignalStrength() (int, error)- Get signal strength percentageGetPortByType(portType string) string- Get port name by typeIsSimLocked() bool- Check if SIM card is lockedGetCurrentAccessTechnology() string- Get current network technologyGetOperatorInfo() (name string, code string)- Get operator informationRemainingUnlockRetries(lockType string) int- Get remaining unlock attemptsIsIPv6Supported() bool- Check IPv6 supportGetAllPorts() map[string]string- Get all available ports
GetLocationStatus(modemID string) (*LocationStatus, error)- Get location gathering statusGetLocation(modemID string) (*LocationInfo, error)- Get current location informationEnableLocationGathering(modemID string, method string) error- Enable a location gathering methodDisableLocationGathering(modemID string, method string) error- Disable a location gathering methodSetSuplServer(modemID string, address string) error- Set SUPL server address for A-GPSSetGpsRefreshRate(modemID string, rate int) error- Set GPS refresh rateEnableLocationSignals(modemID string) error- Enable location update signalingDisableLocationSignals(modemID string) error- Disable location update signaling
Connect(modemID string, settings ConnectSettings) error- Connect with specific settingsDisconnect(modemID string) error- Disconnect all bearersConnectWithAPN(modemID string, apn string) error- Connect with just an APNConnectWithAuth(modemID string, apn, user, password string) error- Connect with APN, username and password
GetNetworkTime(modemID string) (*TimeInfo, error)- Get current network time informationGetNetworkTimeAsTime(modemID string) (time.Time, error)- Get network time as a time.Time object
GetMessagingStatus(modemID string) (*MessagingStatus, error)- Get messaging support statusListSMS(modemID string) ([]string, error)- List available SMS messagesGetSMSInfo(smsID string) (*SMSInfo, error)- Get information about a specific SMSCreateSMS(modemID string, settings SMSCreateSettings) (string, error)- Create a new SMSSendSMS(smsID string) error- Send an SMSStoreSMS(smsID string) error- Store an SMS in the default storageStoreSMSInStorage(smsID string, storage string) error- Store an SMS in a specific storageDeleteSMS(modemID string, smsID string) error- Delete an SMSCreateAndSendSMS(modemID string, number string, text string) error- Create and send an SMS in one step
package main
import (
"fmt"
"log"
"github.com/rescoot/go-mmcli"
)
func main() {
// List available modems
ids, err := mmcli.GetModemIDs()
if err != nil {
log.Fatal(err)
}
fmt.Printf("Found %d modems: %v\n", len(ids), ids)
// Get details for first modem
modem, err := mmcli.GetModemDetails(ids[0])
if err != nil {
log.Fatal(err)
}
if modem.IsConnected() {
strength, _ := modem.SignalStrength()
name, code := modem.GetOperatorInfo()
tech := modem.GetCurrentAccessTechnology()
fmt.Printf("Connected to %s (%s)\n", name, code)
fmt.Printf("Technology: %s\n", tech)
fmt.Printf("Signal: %d%%\n", strength)
}
}package main
import (
"fmt"
"log"
"github.com/rescoot/go-mmcli"
)
func main() {
// Get first available modem ID
id, err := mmcli.GetFirstModemID()
if err != nil {
log.Fatal("No modem found:", err)
}
// Get location status
status, err := mmcli.GetLocationStatus(id)
if err != nil {
log.Fatal("Failed to get location status:", err)
}
fmt.Printf("Location capabilities: %v\n", status.Capabilities)
fmt.Printf("Enabled methods: %v\n", status.Enabled)
// Enable 3GPP location gathering if not already enabled
for _, method := range status.Capabilities {
if method == "3gpp-lac-ci" {
found := false
for _, enabledMethod := range status.Enabled {
if enabledMethod == "3gpp-lac-ci" {
found = true
break
}
}
if !found {
if err := mmcli.EnableLocationGathering(id, "3gpp"); err != nil {
log.Printf("Failed to enable 3GPP location gathering: %v", err)
}
}
}
}
// Get location information
location, err := mmcli.GetLocation(id)
if err != nil {
log.Fatal("Failed to get location:", err)
}
fmt.Printf("3GPP Location: MCC=%s, MNC=%s, LAC=%s, CID=%s\n",
location.ThreeGPP.MCC, location.ThreeGPP.MNC,
location.ThreeGPP.LAC, location.ThreeGPP.CID)
}package main
import (
"fmt"
"log"
"github.com/rescoot/go-mmcli"
)
func main() {
// Get first available modem ID
id, err := mmcli.GetFirstModemID()
if err != nil {
log.Fatal("No modem found:", err)
}
// Connect with APN
fmt.Println("Connecting to network...")
err = mmcli.ConnectWithAPN(id, "internet")
if err != nil {
log.Fatal("Failed to connect:", err)
}
fmt.Println("Connected successfully!")
// Get modem details to check connection
modem, err := mmcli.GetModemDetails(id)
if err != nil {
log.Fatal("Failed to get modem details:", err)
}
if modem.IsConnected() {
fmt.Println("Modem is connected")
// Disconnect
fmt.Println("Disconnecting...")
err = mmcli.Disconnect(id)
if err != nil {
log.Fatal("Failed to disconnect:", err)
}
fmt.Println("Disconnected successfully!")
}
}package main
import (
"fmt"
"log"
"github.com/rescoot/go-mmcli"
)
func main() {
// Get first available modem ID
id, err := mmcli.GetFirstModemID()
if err != nil {
log.Fatal("No modem found:", err)
}
// Get messaging status
status, err := mmcli.GetMessagingStatus(id)
if err != nil {
log.Fatal("Failed to get messaging status:", err)
}
fmt.Printf("Supported storages: %v\n", status.SupportedStorages)
// List SMS messages
messages, err := mmcli.ListSMS(id)
if err != nil {
log.Fatal("Failed to list SMS messages:", err)
}
fmt.Printf("Found %d SMS messages\n", len(messages))
// Send an SMS
number := "+1234567890" // Replace with actual number
text := "Hello from go-mmcli!"
fmt.Printf("Sending SMS to %s: %s\n", number, text)
err = mmcli.CreateAndSendSMS(id, number, text)
if err != nil {
log.Fatal("Failed to send SMS:", err)
}
fmt.Println("SMS sent successfully!")
}go test -vThe library is designed to be easily extended with new ModemManager functionality. To add support for a new mmcli feature:
- Define appropriate Go structs to represent the data
- Implement functions that call mmcli with the right arguments
- Parse the JSON output into the defined structs
- Add helper methods for common operations
- Add tests for the new functionality
This project is licensed under AGPL 3.0.