ModemManager: new 'iridium' plugin


So, finished developing a new 'iridium' [1] plugin for ModemManager.
Nothing prevents you now from easily connecting to the Internet from
anywhere in the Earth :-) (through the Iridium satellite network). The
plugin works with the "Iridium 9522B Satellite Transceiver" RS232 modem
[2], and should probably work with similar or newer modems. This plugin
is a bit special, as it simulates a GSM modem while it really isn't one.
Most AT commands are the standard ones for GSM modems, but of course we
cannot play with changing bands or trying to enable/disable 3G, and we
are limited to GSM-only-like circuit-switched connections.
Iridium-specific features like SBD (Short Burst Data) are not covered.

Some of the specific things that needed to take care of for this modem
to work:
 * Minor fixes w.r.t how the modem writes the replies, like allowing no
whitespaces before the CPIN? reply, or allowing leading zeroes in
numbers in CREG responses.
 * Customized SMS storage setup, flow control setup, and signal quality
retrieval commands.
 * Allowed mode and Network technology handling, simulating a GSM-only
 * Skipped ICCID/IMSI check, not available in the Iridium SIM cards.
 * Modified the generic implementation so that plugins can specify if
they support PS network, so that all GPRS network registration status
and PDP context handling commands can be skipped.
 * Modified the generic implementation so that plugins can implement
their own Operator name and code retrieval (fixed to "Iridium" and
"90103" respectively in this plugin).
 * Generic initialization fully changed, so that ATZ is sent alone and a
500ms graceful time is given to the modem before sending remaining
initialization commands.
 * Modified both MM and NM so that plugins can specify how much time NM
should wait for the IP setup in pppd. This value is fixed to 20s by
default, but we need a larger value in case of Iridium (200s is given
 * The Iridium modem doesn't seem to like the generic disconnection
process where just port flashing is done once pppd hanged up the call.
Closing and opening again the port after some short time seems to deal
with that issue.

Attached is also a python script that creates a new Iridium connection
in NM (0.8) and tries to enable it. You may want to remove
'ignore-auto-routes', 'ignore-auto-dns' and 'never-default' options in
the IPv4 section, which were added mainly for testing purposes. You
should also be able to create a new connection with
nm-connection-editor: New 'Broadband' connection, set Country as not
listed, manually set provider as 'Iridium' (GSM), and place an empty
APN. Then remove *99# and set the new number to dial: 008816000025.

This development is ready for review in the 'plugin-iridium' branch in
the following Gitorious repository [3]:

The NetworkManager changes needed (just 1 commit) are available in the
'08-mm-ip-timeout' branch in the following Gitorious repository [4]:
This branch is based on NM_0_8, but the commit [5] can be cherry-picked
to git master without conflict.


[1] I wanted to call the plugin 'dysprosium', but jokes that need to be
explained are not funny :-P

#!/bin/env python
# -*- Mode: Python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
# Copyright (C) 2009 Red Hat, Inc.
# Copyright (C) 2011 Aleksander Morgado <aleksander lanedo com>
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

import dbus
import glib
import sys
import posix
import time

uuid = "aabbccddeeffaabbccddeeffaabbccddeeff"

s_con = { 'id':          'Iridium',
          'uuid':        uuid,
          'type':        'gsm',
          'autoconnect': False }

s_gsm = { 'number':     '008816000025' }

s_ip4 = { 'method':             'auto',
          'ignore-auto-routes': True,
          'ignore-auto-dns':    True,
          'never-default':      True }

s_ser = { 'baud':       9600L }

s_ppp = {}

con = { 'connection':   s_con,
        'gsm':          s_gsm,
        'ipv4':         s_ip4,
        'serial':       s_ser,
        'ppp':          s_ppp }

# init dbus
sys_bus = dbus.SystemBus()

ss_proxy = sys_bus.get_object('org.freedesktop.NetworkManagerSystemSettings',
ss_iface = dbus.Interface(ss_proxy, 'org.freedesktop.NetworkManagerSettings')

nm_proxy = sys_bus.get_object('org.freedesktop.NetworkManager',
nm_iface = dbus.Interface(nm_proxy, 'org.freedesktop.NetworkManager')

def find_connection(requested_uuid):
    for c in ss_iface.ListConnections():
        # get the details of the connection
        c_proxy = sys_bus.get_object('org.freedesktop.NetworkManagerSystemSettings', c)
        c_iface = dbus.Interface(c_proxy,'org.freedesktop.NetworkManagerSettings.Connection')
        settings = c_iface.GetSettings()
        if settings['connection']['uuid'] == requested_uuid:
            # found our connection
            return c
    return None

def try_add(connection):
        # Ask the system settings service to create the connection
    except Exception, e:
        print "Can't add connection"
        print e


print "Looking for existing connection..."
con_path = find_connection(uuid)
if not con_path:
    # Try to create the connection, which could fail if we need authorization.
    print "Adding new connection..."

    print "New connection added, exiting"

# Find a GSM device to activate this connection on
print "Looking for device..."
dev_path = None
for dev in nm_iface.GetDevices():
    dev_proxy = sys_bus.get_object('org.freedesktop.NetworkManager', dev)
    dev_props_iface = dbus.Interface(dev_proxy,'org.freedesktop.DBus.Properties')
    props = dev_props_iface.GetAll('org.freedesktop.NetworkManager.Device')
    if props['DeviceType'] == 3:   # gsm
        dev_path = dev

if not dev_path:
    print "No gsm devices available"

# Now ask NM to activate that connection
active_path =nm_iface.ActivateConnection('org.freedesktop.NetworkManagerSystemSettings',
if not active_path:
    print "Couldn't activate connection"

# Wait for the connection to become active
active_proxy = sys_bus.get_object('org.freedesktop.NetworkManager', active_path)
active_props_iface = dbus.Interface(active_proxy,'org.freedesktop.DBus.Properties')

state = 0
while state != 2:  # 2 == activated
    state =active_props_iface.Get('org.freedesktop.NetworkManager.Connection.Active','State')
    if state != 2:
        print "waiting for connection to become active..."

print "activated!"

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]