diff options
author | Simon Busch <morphis@gravedo.de> | 2012-02-07 17:22:55 +0100 |
---|---|---|
committer | Simon Busch <morphis@gravedo.de> | 2012-02-09 17:08:04 +0100 |
commit | ddf9e70273df6e4374e4f549208e61a218de4491 (patch) | |
tree | c67286288b58840f11b0ae5ee00832d6e957e170 | |
parent | 118dfd0f0c0000cef24476918c6ff0a3a3fe939a (diff) | |
download | cornucopia-morphis/connman.tar.gz cornucopia-morphis/connman.tar.bz2 cornucopia-morphis/connman.zip |
fsogsmd: connman: ongoing rework to get connman plugin in a usable statemorphis/connman
-rw-r--r-- | fsogsmd/src/connman/modemhandler.vala | 278 | ||||
-rw-r--r-- | fsogsmd/src/connman/plugin.vala | 7 | ||||
-rw-r--r-- | fsogsmd/vapi/connman.vapi | 1 |
3 files changed, 159 insertions, 127 deletions
diff --git a/fsogsmd/src/connman/modemhandler.vala b/fsogsmd/src/connman/modemhandler.vala index e8083980..d7e8fe20 100644 --- a/fsogsmd/src/connman/modemhandler.vala +++ b/fsogsmd/src/connman/modemhandler.vala @@ -18,7 +18,6 @@ **/ using GLib; -using Posix; public class FsoGsm.ModemHandler : FsoFramework.AbstractObject { @@ -32,25 +31,26 @@ public class FsoGsm.ModemHandler : FsoFramework.AbstractObject private FreeSmartphone.Data.World world_service; /* these are the parts we need as interface to the connman core */ - private Connman.Device? network_device; + private Connman.Device? modem_device; private Connman.Network? network; private Connman.IpAddress ipaddr; - /* local informations about the modem state */ - private FreeSmartphone.GSM.DeviceStatus modem_status; + /* local informations about the modem state */ private bool initialized; - private bool available; + private bool resource_locked; private bool supports_gprs; + private bool connected = false; private int signal_strength; private string operator_name; private string mccmnc; + private uint watch = 0; /** * Reset internal data structure **/ private void reset_internal_data() { - available = false; + resource_locked = false; signal_strength = 0; supports_gprs = false; operator_name = ""; @@ -64,44 +64,20 @@ public class FsoGsm.ModemHandler : FsoFramework.AbstractObject { if ( name == "GSM" ) { - if ( availability && !available ) + if ( availability && !resource_locked ) { - on_gsm_resource_available(); + request_resource(); } - else + else if ( !availability && resource_locked ) { - available = false; + assert( logger.debug( @"GSM resource has gone; releasing modem device ..." ) ); + release_modem_device(); + resource_locked = false; } } } /** - * Retrieve a dbus proxy for the supplied interface defintion from the FSO - * GSM message bus. - **/ - private T get_service<T>() throws GLib.Error - { - return Bus.get_proxy_sync<T>( BusType.SYSTEM, FsoFramework.GSM.ServiceDBusName, - FsoFramework.GSM.DeviceServicePath, DBusProxyFlags.NONE ); - } - - /** - * Try to find out if the modem supports gprs data connections. - **/ - private async void check_gprs_support() - { - try - { - var features = yield device_service.get_features(); - supports_gprs = ( features.lookup( "pdp" ) != null ); - } - catch ( Error err ) - { - logger.error( @"Cannot check if modem supports gprs" ); - } - } - - /** * Check modem for correct registration status **/ private async void check_registration() @@ -110,12 +86,7 @@ public class FsoGsm.ModemHandler : FsoFramework.AbstractObject { var device_status = yield device_service.get_device_status(); if ( device_status <= FreeSmartphone.GSM.DeviceStatus.ALIVE_SIM_READY ) - { - logger.info( @"Modem is not yet in ALIVE_REGISTERED state; aborting registration check ..." ); return; - } - - logger.debug( @"Modem is in ALIVE_REGISTERED state now; we can register our network device now" ); if ( network != null ) { @@ -123,11 +94,11 @@ public class FsoGsm.ModemHandler : FsoFramework.AbstractObject return; } - string imsi = network_device.get_ident(); + string imsi = modem_device.get_ident(); network = new Connman.Network( imsi, Connman.NetworkType.CELLULAR ); if ( network == null ) { - logger.error( @"Could not create network provided by our current device" ); + logger.error( @"Could not create a new network for our current device" ); return; } @@ -141,9 +112,9 @@ public class FsoGsm.ModemHandler : FsoFramework.AbstractObject network.set_string( "Operator", operator_name ); network.set_strength( (uint8) signal_strength ); - network_device.add_network( network ); + modem_device.add_network( network ); - logger.info( @"Successfully provided the network to the device" ); + assert( logger.debug( @"Successfully create a new network for our cellular device" ) ); } catch ( Error err ) { @@ -155,42 +126,38 @@ public class FsoGsm.ModemHandler : FsoFramework.AbstractObject * Create a new default device and register it to the internal connman core. * The device can later identified by the IMSI supplied by the modem. **/ - private async bool create_device() + private async bool create_modem_device() { string imsi = DEFAUTL_IMSI; bool result = true; + int rc = 0; + + if ( modem_device != null ) + return false; try { var info = yield sim_service.get_sim_info(); imsi = info.lookup( "imsi" ) as string; - if ( imsi == null ) - { - imsi = DEFAUTL_IMSI; - } + imsi = ( imsi == null ) ? DEFAUTL_IMSI : imsi; - // if we already have a network device registered with then unregister it - // first before we create our new one - if ( network_device != null ) - { - network_device.unregister(); - network_device = null; - } - - network_device = new Connman.Device( imsi, Connman.DeviceType.CELLULAR ); - if ( network_device == null ) + modem_device = new Connman.Device( imsi, Connman.DeviceType.CELLULAR ); + if ( modem_device == null ) { + logger.error( @"Failed to create a new cellular device instance" ); return false; } - // FIXME why do we have to set the identifier twice? (this is the way how it - // is done in the ofono plugin) - network_device.set_ident( imsi ); + modem_device.set_ident( imsi ); - if ( network_device.register() != 0 ) + if ( ( rc = modem_device.register() ) != 0 ) { - network_device = null; + logger.error( @"Failed to register our cellular device with connmand (rc = $(rc))" ); + modem_device = null; + return false; } + + assert( logger.debug( @"Created a new network device successfully" ) ); } catch ( Error err ) { @@ -198,12 +165,39 @@ public class FsoGsm.ModemHandler : FsoFramework.AbstractObject result = false; } - check_registration(); - check_gprs_support(); - return result; } + private void release_modem_device() + { + if ( modem_device == null ) + return; + + if ( network != null ) + { + modem_device.remove_network( network ); + network = null; + } + + modem_device.unregister(); + modem_device = null; + + assert( logger.debug( @"Successfully released modem device from connman" ) ); + } + + private T value_from_variant<T>(Variant? vt, VariantType type, T alternative) + { + if ( vt == null || !vt.is_of_type( type ) ) + return alternative; + + if ( type == VariantType.STRING ) + return (T) vt.get_string(); + else if ( type == VariantType.INT32 ) + return (T) vt.get_int32(); + + return alternative; + } + /** * When network status has changed extract relevant information and supply * it the our network object. @@ -211,16 +205,13 @@ public class FsoGsm.ModemHandler : FsoFramework.AbstractObject private async void on_modem_network_status_changed( HashTable<string,Variant> status ) { Variant? v0 = status.lookup( "provider" ); - operator_name = ( v0 == null ? "unknown" : v0.get_string() ); + operator_name = value_from_variant<string>( v0, VariantType.STRING, "unknown" ); -#if 0 Variant? v1 = status.lookup( "strength" ); - logger.debug( @"$(v1.classify())" ); - signal_strength = ( v1 == null ? 0 : v1.get_int32() ); -#endif + signal_strength = value_from_variant<int>( v1, VariantType.INT32, 0 ); Variant? v2 = status.lookup( "code" ); - mccmnc = ( v2 == null ? "" : v2.get_string() ); + mccmnc = value_from_variant( v2, VariantType.STRING, "" ); if ( network != null ) { @@ -233,63 +224,106 @@ public class FsoGsm.ModemHandler : FsoFramework.AbstractObject * When device status has changed we have to register/remove our network * object from the connman core. **/ - private async void on_modem_device_status_changed( FreeSmartphone.GSM.DeviceStatus status ) + private void on_modem_device_status_changed( FreeSmartphone.GSM.DeviceStatus status ) { - logger.debug( @"Got modem status $(status)" ); + assert( logger.debug( @"Got modem status $(status)" ) ); - if ( status < modem_status && - status < FreeSmartphone.GSM.DeviceStatus.ALIVE_SIM_READY ) + if ( status == FreeSmartphone.GSM.DeviceStatus.ALIVE_REGISTERED ) { - logger.debug( @"Removing network as modem is not ready anymore" ); - return; + check_registration(); } - - switch ( status ) + else if ( status != FreeSmartphone.GSM.DeviceStatus.ALIVE_REGISTERED && + status != FreeSmartphone.GSM.DeviceStatus.SUSPENDING && + status != FreeSmartphone.GSM.DeviceStatus.RESUMING && + network != null ) { - case FreeSmartphone.GSM.DeviceStatus.ALIVE_SIM_READY: - if ( network_device == null ) - { - create_device(); - } - break; - case FreeSmartphone.GSM.DeviceStatus.ALIVE_REGISTERED: - check_registration(); - break; + modem_device.remove_network( network ); + network = null; } + } + + private void on_modem_sim_auth_status_changed( FreeSmartphone.GSM.SIMAuthStatus status ) + { + assert( logger.debug( @"Got SIM auth status $(status)" ) ); - modem_status = status; + if ( status == FreeSmartphone.GSM.SIMAuthStatus.READY && modem_device != null ) + { + assert( logger.debug( @"SIM card is now ready; creating a device for our modem ..." ) ); + create_modem_device(); + } + else + { + release_modem_device(); + } } - private async void on_gsm_resource_available() + private async void setup_services() { try { - yield usage.request_resource( "GSM" ); - available = true; + device_service = Bus.get_proxy_sync<FreeSmartphone.GSM.Device>( BusType.SYSTEM, FsoFramework.GSM.ServiceDBusName, + FsoFramework.GSM.DeviceServicePath, DBusProxyFlags.NONE ); - device_service = get_service<FreeSmartphone.GSM.Device>(); - sim_service = get_service<FreeSmartphone.GSM.SIM>(); - network_service = get_service<FreeSmartphone.GSM.Network>(); - pdp_service = get_service<FreeSmartphone.GSM.PDP>(); + sim_service = Bus.get_proxy_sync<FreeSmartphone.GSM.SIM>( BusType.SYSTEM, FsoFramework.GSM.ServiceDBusName, + FsoFramework.GSM.DeviceServicePath, DBusProxyFlags.NONE ); + + network_service = Bus.get_proxy_sync<FreeSmartphone.GSM.Network>( BusType.SYSTEM, FsoFramework.GSM.ServiceDBusName, + FsoFramework.GSM.DeviceServicePath, DBusProxyFlags.NONE ); - world_service = Bus.get_proxy_sync<FreeSmartphone.Data.World>( BusType.SYSTEM, FsoFramework.Data.ServiceDBusName, - FsoFramework.Data.WorldServicePath, - DBusProxyFlags.NONE ); + pdp_service = Bus.get_proxy_sync<FreeSmartphone.GSM.PDP>( BusType.SYSTEM, FsoFramework.GSM.ServiceDBusName, + FsoFramework.GSM.DeviceServicePath, DBusProxyFlags.NONE ); + sim_service.auth_status.connect( on_modem_sim_auth_status_changed ); device_service.device_status.connect( on_modem_device_status_changed ); network_service.status.connect( on_modem_network_status_changed ); - logger.info( @"Successfully registered with GSM resource" ); - - var device_status = yield device_service.get_device_status(); - if ( device_status >= FreeSmartphone.GSM.DeviceStatus.ALIVE_SIM_READY ) + var sim_auth_status = yield sim_service.get_auth_status(); + assert( logger.debug( @"sim_auth_status = $(sim_auth_status)" ) ); + if ( sim_auth_status == FreeSmartphone.GSM.SIMAuthStatus.READY ) { - create_device(); + assert( logger.debug( @"SIM card is READY; creating device for our modem ..." ) ); + create_modem_device(); } + + assert( logger.debug( @"Setup of relevant services is done" ) ); + } + catch ( GLib.Error err ) + { + logger.error( @"Failed to setup necessary GSM services" ); + } + } + + private async void request_resource() + { + try + { + yield usage.request_resource( "GSM" ); + resource_locked = true; + yield setup_services(); + + if ( watch > 0 ) + GLib.Source.remove( watch ); + + assert( logger.debug( @"Successfully requested GSM resource" ) ); + } + catch ( Error err ) + { + logger.error( @"Could not request GSM resource from usage system; trying again in five seconds ..." ); + watch = Timeout.add_seconds( 5, () => { request_resource(); return false; } ); + } + } + + private async void release_resource() + { + try + { + release_modem_device(); + yield usage.release_resource( "GSM" ); + resource_locked = false; } catch ( Error err ) { - logger.error( @"Can't setup for using GSM resource: $(err.message)" ); + logger.error( @"Failed to release GSM resource: $(err.message)" ); } } @@ -327,14 +361,7 @@ public class FsoGsm.ModemHandler : FsoFramework.AbstractObject DBusProxyFlags.NONE ); usage.resource_available.connect( on_resource_available ); - resources = yield usage.list_resources(); - - // if gsm resource is already available we can request it right now. Otherwise - // we have to wait until the resource arrives on the bus. - if ( "GSM" in resources ) - { - on_gsm_resource_available(); - } + yield request_resource(); } catch ( GLib.Error err ) { @@ -354,7 +381,7 @@ public class FsoGsm.ModemHandler : FsoFramework.AbstractObject if ( mccmnc.length == 0 ) { logger.error( "We don't have mcc and mnc to retrieve correct APN for PDP connection" ); - return -EINVAL; + return -Posix.EINVAL; } try @@ -364,7 +391,7 @@ public class FsoGsm.ModemHandler : FsoFramework.AbstractObject if ( apns.length == 0 ) { logger.error( "Invalid mcc and mnc wihtout context information!" ); - return -EINVAL; + return -Posix.EINVAL; } var apn = apns[0]; @@ -381,6 +408,7 @@ public class FsoGsm.ModemHandler : FsoFramework.AbstractObject // FIXME set ipaddr, method ... network.set_connected( true ); + connected = true; return 0; } @@ -403,6 +431,7 @@ public class FsoGsm.ModemHandler : FsoFramework.AbstractObject } network.set_connected( false ); + connected = false; return 0; } @@ -411,13 +440,18 @@ public class FsoGsm.ModemHandler : FsoFramework.AbstractObject { logger.info( "Shuting down ..." ); - if ( network_device != null ) + if ( connected ) + disconnect_network(); + + if ( modem_device != null ) { - network_device.remove_all_networks(); - network_device.unregister(); - network_device = null; + modem_device.remove_all_networks(); + modem_device.unregister(); + modem_device = null; network = null; } + + release_resource(); } } diff --git a/fsogsmd/src/connman/plugin.vala b/fsogsmd/src/connman/plugin.vala index 4eefa91f..29825039 100644 --- a/fsogsmd/src/connman/plugin.vala +++ b/fsogsmd/src/connman/plugin.vala @@ -28,13 +28,11 @@ FsoGsm.ModemHandler modem; public static int network_probe( Connman.Network network ) { - debug( "network_probe()" ); return 0; } public static int network_remove( Connman.Network network ) { - debug( "network_remove()" ); return 0; } @@ -52,13 +50,11 @@ public static int network_disconnect( Connman.Network network ) public static int modem_probe( Connman.Device device ) { - debug( "modem_probe()" ); return 0; } public static int modem_remove( Connman.Device device ) { - debug( "modem_remove()" ); return 0; } @@ -86,7 +82,6 @@ public int fsogsm_plugin_init() int err; modem = new FsoGsm.ModemHandler(); - modem.initialize(); network_driver = Connman.NetworkDriver() { name = "network", @@ -137,6 +132,8 @@ public int fsogsm_plugin_init() return err; } + modem.initialize(); + return 0; } diff --git a/fsogsmd/vapi/connman.vapi b/fsogsmd/vapi/connman.vapi index f58c57a0..ad88489d 100644 --- a/fsogsmd/vapi/connman.vapi +++ b/fsogsmd/vapi/connman.vapi @@ -268,6 +268,7 @@ namespace Connman public int add_network(Network network); public Network get_network(string identifier); public void remove_all_networks(); + public void remove_network(Network network); public void schedule_scan(); public int register(); public void unregister(); |