Home | History | Annotate | Download | only in sip
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.net.sip;
     18 
     19 import android.os.RemoteException;
     20 import android.util.Log;
     21 
     22 /**
     23  * Represents a SIP session that is associated with a SIP dialog or a standalone
     24  * transaction not within a dialog.
     25  * <p>You can get a {@link SipSession} from {@link SipManager} with {@link
     26  * SipManager#createSipSession createSipSession()} (when initiating calls) or {@link
     27  * SipManager#getSessionFor getSessionFor()} (when receiving calls).</p>
     28  */
     29 public final class SipSession {
     30     private static final String TAG = "SipSession";
     31 
     32     /**
     33      * Defines SIP session states, such as "registering", "outgoing call", and "in call".
     34      */
     35     public static class State {
     36         /** When session is ready to initiate a call or transaction. */
     37         public static final int READY_TO_CALL = 0;
     38 
     39         /** When the registration request is sent out. */
     40         public static final int REGISTERING = 1;
     41 
     42         /** When the unregistration request is sent out. */
     43         public static final int DEREGISTERING = 2;
     44 
     45         /** When an INVITE request is received. */
     46         public static final int INCOMING_CALL = 3;
     47 
     48         /** When an OK response is sent for the INVITE request received. */
     49         public static final int INCOMING_CALL_ANSWERING = 4;
     50 
     51         /** When an INVITE request is sent. */
     52         public static final int OUTGOING_CALL = 5;
     53 
     54         /** When a RINGING response is received for the INVITE request sent. */
     55         public static final int OUTGOING_CALL_RING_BACK = 6;
     56 
     57         /** When a CANCEL request is sent for the INVITE request sent. */
     58         public static final int OUTGOING_CALL_CANCELING = 7;
     59 
     60         /** When a call is established. */
     61         public static final int IN_CALL = 8;
     62 
     63         /** When an OPTIONS request is sent. */
     64         public static final int PINGING = 9;
     65 
     66         /** Not defined. */
     67         public static final int NOT_DEFINED = 101;
     68 
     69         /**
     70          * Converts the state to string.
     71          */
     72         public static String toString(int state) {
     73             switch (state) {
     74                 case READY_TO_CALL:
     75                     return "READY_TO_CALL";
     76                 case REGISTERING:
     77                     return "REGISTERING";
     78                 case DEREGISTERING:
     79                     return "DEREGISTERING";
     80                 case INCOMING_CALL:
     81                     return "INCOMING_CALL";
     82                 case INCOMING_CALL_ANSWERING:
     83                     return "INCOMING_CALL_ANSWERING";
     84                 case OUTGOING_CALL:
     85                     return "OUTGOING_CALL";
     86                 case OUTGOING_CALL_RING_BACK:
     87                     return "OUTGOING_CALL_RING_BACK";
     88                 case OUTGOING_CALL_CANCELING:
     89                     return "OUTGOING_CALL_CANCELING";
     90                 case IN_CALL:
     91                     return "IN_CALL";
     92                 case PINGING:
     93                     return "PINGING";
     94                 default:
     95                     return "NOT_DEFINED";
     96             }
     97         }
     98 
     99         private State() {
    100         }
    101     }
    102 
    103     /**
    104      * Listener for events relating to a SIP session, such as when a session is being registered
    105      * ("on registering") or a call is outgoing ("on calling").
    106      * <p>Many of these events are also received by {@link SipAudioCall.Listener}.</p>
    107      */
    108     public static class Listener {
    109         /**
    110          * Called when an INVITE request is sent to initiate a new call.
    111          *
    112          * @param session the session object that carries out the transaction
    113          */
    114         public void onCalling(SipSession session) {
    115         }
    116 
    117         /**
    118          * Called when an INVITE request is received.
    119          *
    120          * @param session the session object that carries out the transaction
    121          * @param caller the SIP profile of the caller
    122          * @param sessionDescription the caller's session description
    123          */
    124         public void onRinging(SipSession session, SipProfile caller,
    125                 String sessionDescription) {
    126         }
    127 
    128         /**
    129          * Called when a RINGING response is received for the INVITE request sent
    130          *
    131          * @param session the session object that carries out the transaction
    132          */
    133         public void onRingingBack(SipSession session) {
    134         }
    135 
    136         /**
    137          * Called when the session is established.
    138          *
    139          * @param session the session object that is associated with the dialog
    140          * @param sessionDescription the peer's session description
    141          */
    142         public void onCallEstablished(SipSession session,
    143                 String sessionDescription) {
    144         }
    145 
    146         /**
    147          * Called when the session is terminated.
    148          *
    149          * @param session the session object that is associated with the dialog
    150          */
    151         public void onCallEnded(SipSession session) {
    152         }
    153 
    154         /**
    155          * Called when the peer is busy during session initialization.
    156          *
    157          * @param session the session object that carries out the transaction
    158          */
    159         public void onCallBusy(SipSession session) {
    160         }
    161 
    162         /**
    163          * Called when an error occurs during session initialization and
    164          * termination.
    165          *
    166          * @param session the session object that carries out the transaction
    167          * @param errorCode error code defined in {@link SipErrorCode}
    168          * @param errorMessage error message
    169          */
    170         public void onError(SipSession session, int errorCode,
    171                 String errorMessage) {
    172         }
    173 
    174         /**
    175          * Called when an error occurs during session modification negotiation.
    176          *
    177          * @param session the session object that carries out the transaction
    178          * @param errorCode error code defined in {@link SipErrorCode}
    179          * @param errorMessage error message
    180          */
    181         public void onCallChangeFailed(SipSession session, int errorCode,
    182                 String errorMessage) {
    183         }
    184 
    185         /**
    186          * Called when a registration request is sent.
    187          *
    188          * @param session the session object that carries out the transaction
    189          */
    190         public void onRegistering(SipSession session) {
    191         }
    192 
    193         /**
    194          * Called when registration is successfully done.
    195          *
    196          * @param session the session object that carries out the transaction
    197          * @param duration duration in second before the registration expires
    198          */
    199         public void onRegistrationDone(SipSession session, int duration) {
    200         }
    201 
    202         /**
    203          * Called when the registration fails.
    204          *
    205          * @param session the session object that carries out the transaction
    206          * @param errorCode error code defined in {@link SipErrorCode}
    207          * @param errorMessage error message
    208          */
    209         public void onRegistrationFailed(SipSession session, int errorCode,
    210                 String errorMessage) {
    211         }
    212 
    213         /**
    214          * Called when the registration gets timed out.
    215          *
    216          * @param session the session object that carries out the transaction
    217          */
    218         public void onRegistrationTimeout(SipSession session) {
    219         }
    220     }
    221 
    222     private final ISipSession mSession;
    223     private Listener mListener;
    224 
    225     SipSession(ISipSession realSession) {
    226         mSession = realSession;
    227         if (realSession != null) {
    228             try {
    229                 realSession.setListener(createListener());
    230             } catch (RemoteException e) {
    231                 Log.e(TAG, "SipSession.setListener(): " + e);
    232             }
    233         }
    234     }
    235 
    236     SipSession(ISipSession realSession, Listener listener) {
    237         this(realSession);
    238         setListener(listener);
    239     }
    240 
    241     /**
    242      * Gets the IP address of the local host on which this SIP session runs.
    243      *
    244      * @return the IP address of the local host
    245      */
    246     public String getLocalIp() {
    247         try {
    248             return mSession.getLocalIp();
    249         } catch (RemoteException e) {
    250             Log.e(TAG, "getLocalIp(): " + e);
    251             return "127.0.0.1";
    252         }
    253     }
    254 
    255     /**
    256      * Gets the SIP profile that this session is associated with.
    257      *
    258      * @return the SIP profile that this session is associated with
    259      */
    260     public SipProfile getLocalProfile() {
    261         try {
    262             return mSession.getLocalProfile();
    263         } catch (RemoteException e) {
    264             Log.e(TAG, "getLocalProfile(): " + e);
    265             return null;
    266         }
    267     }
    268 
    269     /**
    270      * Gets the SIP profile that this session is connected to. Only available
    271      * when the session is associated with a SIP dialog.
    272      *
    273      * @return the SIP profile that this session is connected to
    274      */
    275     public SipProfile getPeerProfile() {
    276         try {
    277             return mSession.getPeerProfile();
    278         } catch (RemoteException e) {
    279             Log.e(TAG, "getPeerProfile(): " + e);
    280             return null;
    281         }
    282     }
    283 
    284     /**
    285      * Gets the session state. The value returned must be one of the states in
    286      * {@link State}.
    287      *
    288      * @return the session state
    289      */
    290     public int getState() {
    291         try {
    292             return mSession.getState();
    293         } catch (RemoteException e) {
    294             Log.e(TAG, "getState(): " + e);
    295             return State.NOT_DEFINED;
    296         }
    297     }
    298 
    299     /**
    300      * Checks if the session is in a call.
    301      *
    302      * @return true if the session is in a call
    303      */
    304     public boolean isInCall() {
    305         try {
    306             return mSession.isInCall();
    307         } catch (RemoteException e) {
    308             Log.e(TAG, "isInCall(): " + e);
    309             return false;
    310         }
    311     }
    312 
    313     /**
    314      * Gets the call ID of the session.
    315      *
    316      * @return the call ID
    317      */
    318     public String getCallId() {
    319         try {
    320             return mSession.getCallId();
    321         } catch (RemoteException e) {
    322             Log.e(TAG, "getCallId(): " + e);
    323             return null;
    324         }
    325     }
    326 
    327 
    328     /**
    329      * Sets the listener to listen to the session events. A {@code SipSession}
    330      * can only hold one listener at a time. Subsequent calls to this method
    331      * override the previous listener.
    332      *
    333      * @param listener to listen to the session events of this object
    334      */
    335     public void setListener(Listener listener) {
    336         mListener = listener;
    337     }
    338 
    339 
    340     /**
    341      * Performs registration to the server specified by the associated local
    342      * profile. The session listener is called back upon success or failure of
    343      * registration. The method is only valid to call when the session state is
    344      * in {@link State#READY_TO_CALL}.
    345      *
    346      * @param duration duration in second before the registration expires
    347      * @see Listener
    348      */
    349     public void register(int duration) {
    350         try {
    351             mSession.register(duration);
    352         } catch (RemoteException e) {
    353             Log.e(TAG, "register(): " + e);
    354         }
    355     }
    356 
    357     /**
    358      * Performs unregistration to the server specified by the associated local
    359      * profile. Unregistration is technically the same as registration with zero
    360      * expiration duration. The session listener is called back upon success or
    361      * failure of unregistration. The method is only valid to call when the
    362      * session state is in {@link State#READY_TO_CALL}.
    363      *
    364      * @see Listener
    365      */
    366     public void unregister() {
    367         try {
    368             mSession.unregister();
    369         } catch (RemoteException e) {
    370             Log.e(TAG, "unregister(): " + e);
    371         }
    372     }
    373 
    374     /**
    375      * Initiates a call to the specified profile. The session listener is called
    376      * back upon defined session events. The method is only valid to call when
    377      * the session state is in {@link State#READY_TO_CALL}.
    378      *
    379      * @param callee the SIP profile to make the call to
    380      * @param sessionDescription the session description of this call
    381      * @param timeout the session will be timed out if the call is not
    382      *        established within {@code timeout} seconds. Default value (defined
    383      *        by SIP protocol) is used if {@code timeout} is zero or negative.
    384      * @see Listener
    385      */
    386     public void makeCall(SipProfile callee, String sessionDescription,
    387             int timeout) {
    388         try {
    389             mSession.makeCall(callee, sessionDescription, timeout);
    390         } catch (RemoteException e) {
    391             Log.e(TAG, "makeCall(): " + e);
    392         }
    393     }
    394 
    395     /**
    396      * Answers an incoming call with the specified session description. The
    397      * method is only valid to call when the session state is in
    398      * {@link State#INCOMING_CALL}.
    399      *
    400      * @param sessionDescription the session description to answer this call
    401      * @param timeout the session will be timed out if the call is not
    402      *        established within {@code timeout} seconds. Default value (defined
    403      *        by SIP protocol) is used if {@code timeout} is zero or negative.
    404      */
    405     public void answerCall(String sessionDescription, int timeout) {
    406         try {
    407             mSession.answerCall(sessionDescription, timeout);
    408         } catch (RemoteException e) {
    409             Log.e(TAG, "answerCall(): " + e);
    410         }
    411     }
    412 
    413     /**
    414      * Ends an established call, terminates an outgoing call or rejects an
    415      * incoming call. The method is only valid to call when the session state is
    416      * in {@link State#IN_CALL},
    417      * {@link State#INCOMING_CALL},
    418      * {@link State#OUTGOING_CALL} or
    419      * {@link State#OUTGOING_CALL_RING_BACK}.
    420      */
    421     public void endCall() {
    422         try {
    423             mSession.endCall();
    424         } catch (RemoteException e) {
    425             Log.e(TAG, "endCall(): " + e);
    426         }
    427     }
    428 
    429     /**
    430      * Changes the session description during a call. The method is only valid
    431      * to call when the session state is in {@link State#IN_CALL}.
    432      *
    433      * @param sessionDescription the new session description
    434      * @param timeout the session will be timed out if the call is not
    435      *        established within {@code timeout} seconds. Default value (defined
    436      *        by SIP protocol) is used if {@code timeout} is zero or negative.
    437      */
    438     public void changeCall(String sessionDescription, int timeout) {
    439         try {
    440             mSession.changeCall(sessionDescription, timeout);
    441         } catch (RemoteException e) {
    442             Log.e(TAG, "changeCall(): " + e);
    443         }
    444     }
    445 
    446     ISipSession getRealSession() {
    447         return mSession;
    448     }
    449 
    450     private ISipSessionListener createListener() {
    451         return new ISipSessionListener.Stub() {
    452             public void onCalling(ISipSession session) {
    453                 if (mListener != null) {
    454                     mListener.onCalling(SipSession.this);
    455                 }
    456             }
    457 
    458             public void onRinging(ISipSession session, SipProfile caller,
    459                     String sessionDescription) {
    460                 if (mListener != null) {
    461                     mListener.onRinging(SipSession.this, caller,
    462                             sessionDescription);
    463                 }
    464             }
    465 
    466             public void onRingingBack(ISipSession session) {
    467                 if (mListener != null) {
    468                     mListener.onRingingBack(SipSession.this);
    469                 }
    470             }
    471 
    472             public void onCallEstablished(ISipSession session,
    473                     String sessionDescription) {
    474                 if (mListener != null) {
    475                     mListener.onCallEstablished(SipSession.this,
    476                             sessionDescription);
    477                 }
    478             }
    479 
    480             public void onCallEnded(ISipSession session) {
    481                 if (mListener != null) {
    482                     mListener.onCallEnded(SipSession.this);
    483                 }
    484             }
    485 
    486             public void onCallBusy(ISipSession session) {
    487                 if (mListener != null) {
    488                     mListener.onCallBusy(SipSession.this);
    489                 }
    490             }
    491 
    492             public void onCallChangeFailed(ISipSession session, int errorCode,
    493                     String message) {
    494                 if (mListener != null) {
    495                     mListener.onCallChangeFailed(SipSession.this, errorCode,
    496                             message);
    497                 }
    498             }
    499 
    500             public void onError(ISipSession session, int errorCode, String message) {
    501                 if (mListener != null) {
    502                     mListener.onError(SipSession.this, errorCode, message);
    503                 }
    504             }
    505 
    506             public void onRegistering(ISipSession session) {
    507                 if (mListener != null) {
    508                     mListener.onRegistering(SipSession.this);
    509                 }
    510             }
    511 
    512             public void onRegistrationDone(ISipSession session, int duration) {
    513                 if (mListener != null) {
    514                     mListener.onRegistrationDone(SipSession.this, duration);
    515                 }
    516             }
    517 
    518             public void onRegistrationFailed(ISipSession session, int errorCode,
    519                     String message) {
    520                 if (mListener != null) {
    521                     mListener.onRegistrationFailed(SipSession.this, errorCode,
    522                             message);
    523                 }
    524             }
    525 
    526             public void onRegistrationTimeout(ISipSession session) {
    527                 if (mListener != null) {
    528                     mListener.onRegistrationTimeout(SipSession.this);
    529                 }
    530             }
    531         };
    532     }
    533 }
    534