diff options
author | Simon Busch <morphis@gravedo.de> | 2012-07-23 17:53:17 +0200 |
---|---|---|
committer | Simon Busch <morphis@gravedo.de> | 2012-07-30 08:35:42 +0200 |
commit | 7298d0d62a46733f3b7455fd36b5db49d93e6770 (patch) | |
tree | 71fc4bc2919df996a91d06bd8bb21c74f813cd9b /fsogsmd/src/lib | |
parent | 1976427616e0159b31dad4c138077750a101ea1a (diff) | |
download | cornucopia-7298d0d62a46733f3b7455fd36b5db49d93e6770.tar.gz cornucopia-7298d0d62a46733f3b7455fd36b5db49d93e6770.tar.bz2 cornucopia-7298d0d62a46733f3b7455fd36b5db49d93e6770.zip |
fsogsmd: lib: introduce a new call handler implementation
The new call handler tries to put as much logic related to voice calls together and just
delegates single actions (e.g. initiating a call) to a call driver which implements then
the protocol related logic.
Diffstat (limited to 'fsogsmd/src/lib')
-rw-r--r-- | fsogsmd/src/lib/Makefile.am | 3 | ||||
-rw-r--r-- | fsogsmd/src/lib/call.vala | 249 | ||||
-rw-r--r-- | fsogsmd/src/lib/calldriver.vala | 100 | ||||
-rw-r--r-- | fsogsmd/src/lib/callhandler.vala (renamed from fsogsmd/src/lib/at/atcall.vala) | 337 | ||||
-rw-r--r-- | fsogsmd/src/lib/modem.vala | 12 |
5 files changed, 331 insertions, 370 deletions
diff --git a/fsogsmd/src/lib/Makefile.am b/fsogsmd/src/lib/Makefile.am index 84d9f9db..d675d728 100644 --- a/fsogsmd/src/lib/Makefile.am +++ b/fsogsmd/src/lib/Makefile.am @@ -10,7 +10,6 @@ AM_VALAFLAGS = modlibexecdir = $(libdir)/cornucopia/modules/fsogsm modlibexec_LTLIBRARIES = libfsogsm.la libfsogsm_la_SOURCES = \ - at/atcall.vala \ at/atchannel.vala \ at/atcommand.vala \ at/atcommands.vala \ @@ -48,6 +47,8 @@ libfsogsm_la_SOURCES = \ watchdog.vala \ serviceprovider.vala \ mbpi.vala \ + callhandler.vala \ + calldriver.vala \ \ $(top_srcdir)/src/3rdparty/conversions.c \ $(top_srcdir)/src/3rdparty/smsutil.c \ diff --git a/fsogsmd/src/lib/call.vala b/fsogsmd/src/lib/call.vala index 7d3a2543..b0595dd2 100644 --- a/fsogsmd/src/lib/call.vala +++ b/fsogsmd/src/lib/call.vala @@ -119,253 +119,4 @@ public class FsoGsm.CallInfo : GLib.Object public GLib.HashTable<string, GLib.Variant?> cinfo; } -/** - * @interface FsoGsm.CallHandler - **/ -public abstract interface FsoGsm.CallHandler : FsoFramework.AbstractObject -{ - /** - * Call this, when the network has indicated an incoming call. - **/ - public abstract void handleIncomingCall( FsoGsm.CallInfo call_info ); - - /** - * Call this, when the network has indicated an connecting call - **/ - public abstract void handleConnectingCall( FsoGsm.CallInfo call_info ); - - /** - * Call this, when the network has indicated an ending call - **/ - public abstract void handleEndingCall( FsoGsm.CallInfo call_info ); - - /** - * Call this, when the network has indicated a supplementary service indication. - **/ - public abstract void addSupplementaryInformation( string direction, string info ); - - /** - * Call Actions - **/ - public abstract async void activate( int id ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; - public abstract async int initiate( string number, string ctype ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; - public abstract async void hold() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; - public abstract async void release( int id ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; - public abstract async void releaseAll() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; - public abstract async void transfer() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; - public abstract async void deflect( string number ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; - public abstract async void conference( int id ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; - public abstract async void join() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; -} - -/** - * @class FsoGsm.NullCallHandler - **/ -public class FsoGsm.NullCallHandler : FsoGsm.CallHandler, FsoFramework.AbstractObject -{ - public void handleIncomingCall( FsoGsm.CallInfo call_info ) - { - } - - public void handleConnectingCall( FsoGsm.CallInfo call_info ) - { - } - - public void handleEndingCall( FsoGsm.CallInfo call_info ) - { - } - - public void addSupplementaryInformation( string direction, string info ) - { - } - - public async void activate( int id ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error - { - } - - public async int initiate( string number, string ctype ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error - { - return 0; - } - - public async void hold() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error - { - } - - public async void release( int id ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error - { - } - - public async void releaseAll() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error - { - } - - public async void transfer() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error - { - } - - public async void deflect( string number ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error - { - } - - public async void conference( int id ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error - { - } - - public async void join() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error - { - } - - public override string repr() - { - return @"<>"; - } -} - -/** - * @class FsoGsm.AbstractCallHandler - **/ -public abstract class FsoGsm.AbstractCallHandler : FsoGsm.CallHandler, FsoFramework.AbstractObject -{ - protected bool inSyncCallStatus; - protected uint timeout; - protected FsoGsm.Call[] calls; - - protected FsoFramework.Pair<string,string> supplementary; - - protected FsoGsm.Modem modem { get; private set; } - - construct - { - calls = new FsoGsm.Call[Constants.CALL_INDEX_MAX+1] {}; - for ( int i = Constants.CALL_INDEX_MIN; i != Constants.CALL_INDEX_MAX; ++i ) - { - calls[i] = new Call.newFromId( i ); - calls[i].status_changed.connect( ( id, status, properties ) => { - var obj = modem.theDevice<FreeSmartphone.GSM.Call>(); - obj.call_status( id, status, properties ); - } ); - } - } - - // - // protected - // - - protected void validateCallId( int id ) throws FreeSmartphone.Error - { - if ( id < 1 || id > Constants.CALL_INDEX_MAX ) - throw new FreeSmartphone.Error.INVALID_PARAMETER( "Call index needs to be within [ 1, %d ]".printf( (int)Constants.CALL_INDEX_MAX) ); - } - - protected int numberOfBusyCalls() - { - var num = 0; - for ( int i = Constants.CALL_INDEX_MIN; i != Constants.CALL_INDEX_MAX; ++i ) - { - if ( calls[i].detail.status != FreeSmartphone.GSM.CallStatus.RELEASE && calls[i].detail.status != FreeSmartphone.GSM.CallStatus.INCOMING ) - { - num++; - } - } - return num; - } - - protected int numberOfCallsWithStatus( FreeSmartphone.GSM.CallStatus status ) - { - var num = 0; - for ( int i = Constants.CALL_INDEX_MIN; i != Constants.CALL_INDEX_MAX; ++i ) - { - if ( calls[i].detail.status == status ) - { - num++; - } - } - return num; - } - - protected int numberOfCallsWithSpecificStatus( FreeSmartphone.GSM.CallStatus[] status ) - { - var num = 0; - for ( int i = Constants.CALL_INDEX_MIN; i != Constants.CALL_INDEX_MAX; ++i ) - { - if ( calls[i].detail.status in status ) - num++; - } - return num; - } - - protected int lowestOfCallsWithStatus( FreeSmartphone.GSM.CallStatus status ) - { - for ( int i = Constants.CALL_INDEX_MIN; i != Constants.CALL_INDEX_MAX; ++i ) - { - if ( calls[i].detail.status == status ) - { - return i; - } - } - return 0; - } - - protected void startTimeoutIfNecessary() - { - onTimeout(); - if ( timeout == 0 ) - { - timeout = GLib.Timeout.add_seconds( CALL_STATUS_REFRESH_TIMEOUT, onTimeout ); - } - } - - protected bool onTimeout() - { - if ( inSyncCallStatus ) - { - assert( logger.debug( "Synchronizing call status not done yet... ignoring" ) ); - } - else - { - syncCallStatus.begin(); - } - return true; - } - - protected abstract async void syncCallStatus(); - protected abstract async void cancelOutgoingWithId( int id ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; - protected abstract async void rejectIncomingWithId( int id ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; - - // - // public API - // - - public AbstractCallHandler( FsoGsm.Modem modem ) - { - this.modem = modem; - } - - public virtual void handleIncomingCall( FsoGsm.CallInfo call_info ) - { - startTimeoutIfNecessary(); - } - - public virtual void handleConnectingCall( FsoGsm.CallInfo call_info ) - { - } - - public virtual void handleEndingCall( FsoGsm.CallInfo call_info ) - { - } - - public abstract void addSupplementaryInformation( string direction, string info ); - - public abstract async void activate( int id ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; - public abstract async int initiate( string number, string ctype ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; - public abstract async void hold() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; - public abstract async void release( int id ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; - public abstract async void releaseAll() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; - public abstract async void transfer() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; - public abstract async void deflect( string number ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; - public abstract async void conference( int id ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; - public abstract async void join() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; -} - // vim:ts=4:sw=4:expandtab diff --git a/fsogsmd/src/lib/calldriver.vala b/fsogsmd/src/lib/calldriver.vala new file mode 100644 index 00000000..96364d07 --- /dev/null +++ b/fsogsmd/src/lib/calldriver.vala @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2009-2012 Michael 'Mickey' Lauer <mlauer@vanille-media.de> + * 2012 Simon Busch <morphis@gravedo.de> + * + * 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 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * 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 + * + */ + +public interface FsoGsm.ICallDriver : GLib.Object +{ + public abstract async void dial( string number, string type ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; + public abstract async void activate() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; + public abstract async void hangup_active() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; + public abstract async void hangup_all() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; + public abstract async void hold_all_active() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; + public abstract async void release( int id ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; + public abstract async void release_all_held() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; + public abstract async void release_all_active() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; + public abstract async void create_conference() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; + public abstract async void transfer() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; + public abstract async void deflect( string number ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; + public abstract async void join() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; + + public abstract async void cancel_outgoing_with_id( int id ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; + public abstract async void reject_incoming_with_id( int id ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; +} + +public class NullCallDriver : FsoGsm.ICallDriver, GLib.Object +{ + public async void dial( string number, string type ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error + { + } + + public async void activate() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error + { + } + + public async void hangup_active() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error + { + } + + public async void hangup_all() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error + { + } + + public async void hold_all_active() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error + { + } + + public async void release( int id ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error + { + } + + public async void release_all_held() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error + { + } + + public async void release_all_active() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error + { + } + + public async void create_conference() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error + { + } + + public async void transfer() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error + { + } + + public async void deflect( string number ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error + { + } + + public async void join() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error + { + } + + + public async void cancel_outgoing_with_id( int id ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error + { + } + + public async void reject_incoming_with_id( int id ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error + { + } +} + +// vim:ts=4:sw=4:expandtab diff --git a/fsogsmd/src/lib/at/atcall.vala b/fsogsmd/src/lib/callhandler.vala index 4c48cee3..7c68d6cd 100644 --- a/fsogsmd/src/lib/at/atcall.vala +++ b/fsogsmd/src/lib/callhandler.vala @@ -1,5 +1,6 @@ /* * Copyright (C) 2009-2012 Michael 'Mickey' Lauer <mlauer@vanille-media.de> + * 2012 Simon Busch <morphis@gravedo.de> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -17,67 +18,204 @@ * */ -using Gee; -using FsoGsm.Constants; - internal const int CALL_STATUS_REFRESH_TIMEOUT = 3; // in seconds -/** - * @class FsoGsm.GenericAtCallHandler - */ -public class FsoGsm.GenericAtCallHandler : FsoGsm.AbstractCallHandler +public abstract interface FsoGsm.ICallHandler : FsoFramework.AbstractObject +{ + /** + * Call this, when the network has indicated an incoming call. + **/ + public abstract void handleIncomingCall( FsoGsm.CallInfo call_info ); + + /** + * Call this, when the network has indicated an connecting call + **/ + public abstract void handleConnectingCall( FsoGsm.CallInfo call_info ); + + /** + * Call this, when the network has indicated an ending call + **/ + public abstract void handleEndingCall( FsoGsm.CallInfo call_info ); + + /** + * Call this, when the network has indicated a supplementary service indication. + **/ + public abstract void addSupplementaryInformation( string direction, string info ); + + /** + * Call Actions + **/ + public abstract async void activate( int id ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; + public abstract async int initiate( string number, string ctype ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; + public abstract async void hold() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; + public abstract async void release( int id ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; + public abstract async void releaseAll() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; + public abstract async void transfer() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; + public abstract async void deflect( string number ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; + public abstract async void conference( int id ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; + public abstract async void join() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error; +} + +public class FsoGsm.NullCallHandler : FsoGsm.ICallHandler, FsoFramework.AbstractObject { + public void handleIncomingCall( FsoGsm.CallInfo call_info ) + { + } + + public void handleConnectingCall( FsoGsm.CallInfo call_info ) + { + } + + public void handleEndingCall( FsoGsm.CallInfo call_info ) + { + } + + public void addSupplementaryInformation( string direction, string info ) + { + } + + public async void activate( int id ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error + { + } + + public async int initiate( string number, string ctype ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error + { + return 0; + } + + public async void hold() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error + { + } + + public async void release( int id ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error + { + } + + public async void releaseAll() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error + { + } + + public async void transfer() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error + { + } + + public async void deflect( string number ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error + { + } + + public async void conference( int id ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error + { + } + + public async void join() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error + { + } + public override string repr() { - return "<>"; + return @"<>"; + } +} + +public class FsoGsm.CallHandler : FsoGsm.ICallHandler, FsoFramework.AbstractObject +{ + private ICallDriver driver; + private bool inSyncCallStatus; + private uint timeout; + private FsoGsm.Call[] calls; + private FsoFramework.Pair<string,string> supplementary; + private FsoGsm.Modem modem { get; private set; } + + construct + { + calls = new FsoGsm.Call[Constants.CALL_INDEX_MAX+1] {}; + for ( int i = Constants.CALL_INDEX_MIN; i != Constants.CALL_INDEX_MAX; ++i ) + { + calls[i] = new Call.newFromId( i ); + calls[i].status_changed.connect( ( id, status, properties ) => { + var obj = modem.theDevice<FreeSmartphone.GSM.Call>(); + obj.call_status( id, status, properties ); + } ); + } } // - // protected API + // private // - protected override async void cancelOutgoingWithId( int id ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error + private void validateCallId( int id ) throws FreeSmartphone.Error + { + if ( id < 1 || id > Constants.CALL_INDEX_MAX ) + throw new FreeSmartphone.Error.INVALID_PARAMETER( "Call index needs to be within [ 1, %d ]".printf( (int)Constants.CALL_INDEX_MAX) ); + } + + private int numberOfBusyCalls() { - assert( logger.debug( @"Cancelling outgoing call with ID $id" ) ); - var cmd = modem.data().atCommandCancelOutgoing; - if ( cmd != null ) + var num = 0; + for ( int i = Constants.CALL_INDEX_MIN; i != Constants.CALL_INDEX_MAX; ++i ) { - var c1 = new CustomAtCommand(); - var r1 = yield modem.processAtCommandAsync( c1, cmd ); - checkResponseOk( c1, r1 ); + if ( calls[i].detail.status != FreeSmartphone.GSM.CallStatus.RELEASE && calls[i].detail.status != FreeSmartphone.GSM.CallStatus.INCOMING ) + { + num++; + } } - else + return num; + } + + private int numberOfCallsWithStatus( FreeSmartphone.GSM.CallStatus status ) + { + var num = 0; + for ( int i = Constants.CALL_INDEX_MIN; i != Constants.CALL_INDEX_MAX; ++i ) { - var c2 = modem.createAtCommand<V250H>( "H" ); - var r2 = yield modem.processAtCommandAsync( c2, c2.execute() ); - checkResponseOk( c2, r2 ); + if ( calls[i].detail.status == status ) + num++; } + return num; } - protected override async void rejectIncomingWithId( int id ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error + private int numberOfCallsWithSpecificStatus( FreeSmartphone.GSM.CallStatus[] status ) { - assert( logger.debug( @"Rejecting incoming call with ID $id" ) ); - var cmd = modem.data().atCommandRejectIncoming; - if ( cmd != null ) + var num = 0; + for ( int i = Constants.CALL_INDEX_MIN; i != Constants.CALL_INDEX_MAX; ++i ) { - var c1 = new CustomAtCommand(); - var r1 = yield modem.processAtCommandAsync( c1, cmd ); - checkResponseOk( c1, r1 ); + if ( calls[i].detail.status in status ) + num++; } - else + return num; + } + + private int lowestOfCallsWithStatus( FreeSmartphone.GSM.CallStatus status ) + { + for ( int i = Constants.CALL_INDEX_MIN; i != Constants.CALL_INDEX_MAX; ++i ) { - var c2 = modem.createAtCommand<V250H>( "H" ); - var r2 = yield modem.processAtCommandAsync( c2, c2.execute() ); - checkResponseOk( c2, r2 ); + if ( calls[i].detail.status == status ) + return i; } + return 0; } - public override void addSupplementaryInformation( string direction, string info ) + private void startTimeoutIfNecessary() { - supplementary = new FsoFramework.Pair<string,string>( direction, info ); + onTimeout(); + if ( timeout == 0 ) + timeout = GLib.Timeout.add_seconds( CALL_STATUS_REFRESH_TIMEOUT, onTimeout ); + } + + private bool onTimeout() + { + if ( inSyncCallStatus ) + { + assert( logger.debug( "Synchronizing call status not done yet... ignoring" ) ); + } + else + { + syncCallStatus.begin(); + } + + return true; } - protected override async void syncCallStatus() + private async void syncCallStatus() { inSyncCallStatus = true; @@ -138,12 +276,14 @@ public class FsoGsm.GenericAtCallHandler : FsoGsm.AbstractCallHandler new GLib.HashTable<string,GLib.Variant>( str_hash, str_equal ) ); + /* var ceer = modem.createAtCommand<PlusCEER>( "+CEER" ); var result = yield modem.processAtCommandAsync( ceer, ceer.execute() ); if ( ceer.validate( result ) == Constants.AtResponse.VALID ) { detail.properties.insert( "cause", ceer.reason ); } + */ calls[i].update( detail ); } @@ -161,16 +301,12 @@ public class FsoGsm.GenericAtCallHandler : FsoGsm.AbstractCallHandler // public API // - public GenericAtCallHandler( FsoGsm.Modem modem ) + public CallHandler( ICallDriver driver ) { - base( modem ); + this.driver = driver; } - // - // DBus methods, delegated from the Call mediators - // - - public override async void activate( int id ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error + public async void activate( int id ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error { validateCallId( id ); @@ -180,80 +316,59 @@ public class FsoGsm.GenericAtCallHandler : FsoGsm.AbstractCallHandler throw new FreeSmartphone.GSM.Error.CALL_NOT_FOUND( "No suitable call to activate found" ); } - if ( numberOfBusyCalls() == 0 ) // simple case - { - var cmd = modem.createAtCommand<V250D>( "A" ); - var response = yield modem.processAtCommandAsync( cmd, cmd.execute() ); - checkResponseOk( cmd, response ); - } - else - { - // call is present and incoming or held - var cmd2 = modem.createAtCommand<PlusCHLD>( "+CHLD" ); - var response2 = yield modem.processAtCommandAsync( cmd2, cmd2.issue( PlusCHLD.Action.HOLD_ALL_AND_ACCEPT_WAITING_OR_HELD ) ); - checkResponseOk( cmd2, response2 ); - } + if ( numberOfBusyCalls() != 0 ) + throw new FreeSmartphone.GSM.Error.CALL_NOT_FOUND( "System busy" ); + + yield driver.activate(); } - public override async int initiate( string number, string ctype ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error + public async int initiate( string number, string ctype ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error { var num = lowestOfCallsWithStatus( FreeSmartphone.GSM.CallStatus.RELEASE ); if ( num == 0 ) - { throw new FreeSmartphone.GSM.Error.CALL_NOT_FOUND( "System busy" ); - } - var cmd = modem.createAtCommand<V250D>( "D" ); - var response = yield modem.processAtCommandAsync( cmd, cmd.issue( number, ctype == "voice" ) ); - checkResponseOk( cmd, response ); + yield driver.dial( number, ctype ); startTimeoutIfNecessary(); return num; } - public override async void hold() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error + public async void hold() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error { if ( numberOfCallsWithStatus( FreeSmartphone.GSM.CallStatus.ACTIVE ) == 0 ) - { throw new FreeSmartphone.GSM.Error.CALL_NOT_FOUND( "No active call present" ); - } + if ( numberOfCallsWithStatus( FreeSmartphone.GSM.CallStatus.INCOMING ) > 0 ) - { throw new FreeSmartphone.GSM.Error.CALL_NOT_FOUND( "Call incoming. Can't hold active calls without activating" ); - } - var cmd = modem.createAtCommand<PlusCHLD>( "+CHLD" ); - var response = yield modem.processAtCommandAsync( cmd, cmd.issue( PlusCHLD.Action.HOLD_ALL_AND_ACCEPT_WAITING_OR_HELD ) ); - checkResponseOk( cmd, response ); } - public override async void release( int id ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error + public async void release( int id ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error { validateCallId( id ); if ( calls[id].detail.status == FreeSmartphone.GSM.CallStatus.RELEASE ) - { throw new FreeSmartphone.GSM.Error.CALL_NOT_FOUND( "No suitable call to release found" ); - } + if ( calls[id].detail.status == FreeSmartphone.GSM.CallStatus.OUTGOING ) { - yield cancelOutgoingWithId( id ); + yield driver.cancel_outgoing_with_id( id ); return; } + if ( numberOfCallsWithStatus( FreeSmartphone.GSM.CallStatus.INCOMING ) == 1 && calls[id].detail.status == FreeSmartphone.GSM.CallStatus.INCOMING ) { - yield rejectIncomingWithId( id ); + yield driver.reject_incoming_with_id( id ); return; } else { - var cmd = modem.createAtCommand<PlusCHLD>( "+CHLD" ); - var response = yield modem.processAtCommandAsync( cmd, cmd.issue( PlusCHLD.Action.DROP_SPECIFIC_AND_ACCEPT_WAITING_OR_HELD, id ) ); - checkResponseOk( cmd, response ); + yield driver.release( id ); } } - public override async void releaseAll() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error + public async void releaseAll() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error { if ( numberOfCallsWithSpecificStatus( new FreeSmartphone.GSM.CallStatus[] { FreeSmartphone.GSM.CallStatus.INCOMING, FreeSmartphone.GSM.CallStatus.OUTGOING, @@ -262,12 +377,10 @@ public class FsoGsm.GenericAtCallHandler : FsoGsm.AbstractCallHandler throw new FreeSmartphone.GSM.Error.CALL_NOT_FOUND( "No call to release available" ); } - var cmd = modem.createAtCommand<V250H>( "H" ); - yield modem.processAtCommandAsync( cmd, cmd.execute() ); - // no checkResponseOk, this call will always succeed + yield driver.hangup_all(); } - public override async void transfer() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error + public async void transfer() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error { if ( numberOfCallsWithStatus( FreeSmartphone.GSM.CallStatus.ACTIVE ) == 0 && // According to 22.091 section 5.8 it's possible that our network supports @@ -278,16 +391,10 @@ public class FsoGsm.GenericAtCallHandler : FsoGsm.AbstractCallHandler if ( numberOfCallsWithStatus( FreeSmartphone.GSM.CallStatus.HELD ) == 0 ) throw new FreeSmartphone.GSM.Error.CALL_NOT_FOUND( "No held call present" ); - var cmd = modem.createAtCommand<PlusCHLD>( "+CHLD" ); - var response = yield modem.processAtCommandAsync( cmd, cmd.issue( PlusCHLD.Action.DROP_SELF_AND_CONNECT_ACTIVE ) ); - checkResponseOk( cmd, response ); - - // FIXME do we really need to call this here or can we skip it as call state - // polling is always active as long as we have an active call? - startTimeoutIfNecessary(); + yield driver.transfer(); } - public override async void deflect( string number ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error + public async void deflect( string number ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error { if ( numberOfCallsWithStatus( FreeSmartphone.GSM.CallStatus.INCOMING ) == 0 && numberOfCallsWithStatus( FreeSmartphone.GSM.CallStatus.HELD ) == 0 ) @@ -295,16 +402,10 @@ public class FsoGsm.GenericAtCallHandler : FsoGsm.AbstractCallHandler validatePhoneNumber( number ); - var cmd = modem.createAtCommand<PlusCTFR>( "+CTFR" ); - var response = yield modem.processAtCommandAsync( cmd, cmd.issue( number, determinePhoneNumberType( number ) ) ); - checkResponseOk( cmd, response ); - - // FIXME do we really need to call this here or can we skip it as call state - // polling is always active as long as we have an active call? - startTimeoutIfNecessary(); + yield driver.deflect( number ); } - public override async void conference( int id ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error + public async void conference( int id ) throws FreeSmartphone.GSM.Error, FreeSmartphone.Error { if ( numberOfCallsWithStatus( FreeSmartphone.GSM.CallStatus.ACTIVE ) != 0 ) { @@ -319,22 +420,10 @@ public class FsoGsm.GenericAtCallHandler : FsoGsm.AbstractCallHandler throw new FreeSmartphone.GSM.Error.CALL_NOT_FOUND( "Without an active call we can't create a conference call" ); } - // If we deal with an incoming call we have to activate it first and hold our - // current active call. If we deal with an active and an already held call we can - // step through and add both to the conference. - if ( calls[id].detail.status == FreeSmartphone.GSM.CallStatus.INCOMING ) - { - var cmd = modem.createAtCommand<PlusCHLD>( "+CHLD" ); - var response = yield modem.processAtCommandAsync( cmd, cmd.issue( (PlusCHLD.Action) 2 ) ); - checkResponseOk( cmd, response ); - } - - var cmd = modem.createAtCommand<PlusCHLD>( "+CHLD" ); - var response = yield modem.processAtCommandAsync( cmd, cmd.issue( (PlusCHLD.Action) 3 ) ); - checkResponseOk( cmd, response ); + yield driver.create_conference(); } - public override async void join() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error + public async void join() throws FreeSmartphone.GSM.Error, FreeSmartphone.Error { if ( numberOfCallsWithStatus( FreeSmartphone.GSM.CallStatus.ACTIVE ) != 0 && numberOfCallsWithStatus( FreeSmartphone.GSM.CallStatus.HELD ) != 0 ) @@ -342,9 +431,29 @@ public class FsoGsm.GenericAtCallHandler : FsoGsm.AbstractCallHandler throw new FreeSmartphone.GSM.Error.CALL_NOT_FOUND( "No active or hold calls to join" ); } - var cmd = modem.createAtCommand<PlusCHLD>( "+CHLD" ); - var response = yield modem.processAtCommandAsync( cmd, cmd.issue( (PlusCHLD.Action) 4 )); - checkResponseOk( cmd, response ); + yield driver.join(); + } + + public void addSupplementaryInformation( string direction, string info ) + { + } + + public void handleIncomingCall( FsoGsm.CallInfo call_info ) + { + startTimeoutIfNecessary(); + } + + public void handleConnectingCall( FsoGsm.CallInfo call_info ) + { + } + + public void handleEndingCall( FsoGsm.CallInfo call_info ) + { + } + + public override string repr() + { + return @"<>"; } } diff --git a/fsogsmd/src/lib/modem.vala b/fsogsmd/src/lib/modem.vala index 201eeca3..4a712747 100644 --- a/fsogsmd/src/lib/modem.vala +++ b/fsogsmd/src/lib/modem.vala @@ -230,7 +230,7 @@ public abstract interface FsoGsm.Modem : FsoFramework.AbstractObject public abstract T createAtCommand<T>( string command ); public abstract T theDevice<T>(); public abstract IServiceProvider parent { get; set; } // the DBus object - public abstract CallHandler callhandler { get; set; } // the Call handler + public abstract ICallHandler callhandler { get; set; } // the Call handler public abstract SmsHandler smshandler { get; set; } // the Sms handler public abstract PhonebookHandler pbhandler { get; set; } // the Phonebook handler public abstract WatchDog watchdog { get; set; } // the WatchDog @@ -282,7 +282,7 @@ public abstract class FsoGsm.AbstractModem : FsoGsm.Modem, FsoFramework.Abstract protected UnsolicitedResponseHandler urc; public IServiceProvider parent { get; set; } // the DBus object - public CallHandler callhandler { get; set; } // the Call handler + public ICallHandler callhandler { get; set; } // the Call handler public SmsHandler smshandler { get; set; } // the SMS handler public PhonebookHandler pbhandler { get; set; } // the Phonebook handler public WatchDog watchdog { get; set; } // the WatchDog @@ -517,7 +517,7 @@ public abstract class FsoGsm.AbstractModem : FsoGsm.Modem, FsoFramework.Abstract private void registerHandlers() { urc = createUnsolicitedHandler(); - callhandler = createCallHandler(); + callhandler = new CallHandler( createCallDriver() ); smshandler = createSmsHandler(); pbhandler = createPhonebookHandler(); watchdog = createWatchDog(); @@ -629,11 +629,11 @@ public abstract class FsoGsm.AbstractModem : FsoGsm.Modem, FsoFramework.Abstract } /** - * Override this to return a custom type of Call handler to be used for this modem. + * Override this to return a custom type of Call driver to be used for this modem. **/ - protected virtual CallHandler createCallHandler() + protected virtual ICallDriver createCallDriver() { - return new GenericAtCallHandler( this ); + return new NullCallDriver(); } /** |