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.telephony.Rlog;
     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         /** When ending a call. @hide */
     67         public static final int ENDING_CALL = 10;
     68 
     69         /** Not defined. */
     70         public static final int NOT_DEFINED = 101;
     71 
     72         /**
     73          * Converts the state to string.
     74          */
     75         public static String toString(int state) {
     76             switch (state) {
     77                 case READY_TO_CALL:
     78                     return "READY_TO_CALL";
     79                 case REGISTERING:
     80                     return "REGISTERING";
     81                 case DEREGISTERING:
     82                     return "DEREGISTERING";
     83                 case INCOMING_CALL:
     84                     return "INCOMING_CALL";
     85                 case INCOMING_CALL_ANSWERING:
     86                     return "INCOMING_CALL_ANSWERING";
     87                 case OUTGOING_CALL:
     88                     return "OUTGOING_CALL";
     89                 case OUTGOING_CALL_RING_BACK:
     90                     return "OUTGOING_CALL_RING_BACK";
     91                 case OUTGOING_CALL_CANCELING:
     92                     return "OUTGOING_CALL_CANCELING";
     93                 case IN_CALL:
     94                     return "IN_CALL";
     95                 case PINGING:
     96                     return "PINGING";
     97                 default:
     98                     return "NOT_DEFINED";
     99             }
    100         }
    101 
    102         private State() {
    103         }
    104     }
    105 
    106     /**
    107      * Listener for events relating to a SIP session, such as when a session is being registered
    108      * ("on registering") or a call is outgoing ("on calling").
    109      * <p>Many of these events are also received by {@link SipAudioCall.Listener}.</p>
    110      */
    111     public static class Listener {
    112         /**
    113          * Called when an INVITE request is sent to initiate a new call.
    114          *
    115          * @param session the session object that carries out the transaction
    116          */
    117         public void onCalling(SipSession session) {
    118         }
    119 
    120         /**
    121          * Called when an INVITE request is received.
    122          *
    123          * @param session the session object that carries out the transaction
    124          * @param caller the SIP profile of the caller
    125          * @param sessionDescription the caller's session description
    126          */
    127         public void onRinging(SipSession session, SipProfile caller,
    128                 String sessionDescription) {
    129         }
    130 
    131         /**
    132          * Called when a RINGING response is received for the INVITE request sent
    133          *
    134          * @param session the session object that carries out the transaction
    135          */
    136         public void onRingingBack(SipSession session) {
    137         }
    138 
    139         /**
    140          * Called when the session is established.
    141          *
    142          * @param session the session object that is associated with the dialog
    143          * @param sessionDescription the peer's session description
    144          */
    145         public void onCallEstablished(SipSession session,
    146                 String sessionDescription) {
    147         }
    148 
    149         /**
    150          * Called when the session is terminated.
    151          *
    152          * @param session the session object that is associated with the dialog
    153          */
    154         public void onCallEnded(SipSession session) {
    155         }
    156 
    157         /**
    158          * Called when the peer is busy during session initialization.
    159          *
    160          * @param session the session object that carries out the transaction
    161          */
    162         public void onCallBusy(SipSession session) {
    163         }
    164 
    165         /**
    166          * Called when the call is being transferred to a new one.
    167          *
    168          * @hide
    169          * @param newSession the new session that the call will be transferred to
    170          * @param sessionDescription the new peer's session description
    171          */
    172         public void onCallTransferring(SipSession newSession,
    173                 String sessionDescription) {
    174         }
    175 
    176         /**
    177          * Called when an error occurs during session initialization and
    178          * termination.
    179          *
    180          * @param session the session object that carries out the transaction
    181          * @param errorCode error code defined in {@link SipErrorCode}
    182          * @param errorMessage error message
    183          */
    184         public void onError(SipSession session, int errorCode,
    185                 String errorMessage) {
    186         }
    187 
    188         /**
    189          * Called when an error occurs during session modification negotiation.
    190          *
    191          * @param session the session object that carries out the transaction
    192          * @param errorCode error code defined in {@link SipErrorCode}
    193          * @param errorMessage error message
    194          */
    195         public void onCallChangeFailed(SipSession session, int errorCode,
    196                 String errorMessage) {
    197         }
    198 
    199         /**
    200          * Called when a registration request is sent.
    201          *
    202          * @param session the session object that carries out the transaction
    203          */
    204         public void onRegistering(SipSession session) {
    205         }
    206 
    207         /**
    208          * Called when registration is successfully done.
    209          *
    210          * @param session the session object that carries out the transaction
    211          * @param duration duration in second before the registration expires
    212          */
    213         public void onRegistrationDone(SipSession session, int duration) {
    214         }
    215 
    216         /**
    217          * Called when the registration fails.
    218          *
    219          * @param session the session object that carries out the transaction
    220          * @param errorCode error code defined in {@link SipErrorCode}
    221          * @param errorMessage error message
    222          */
    223         public void onRegistrationFailed(SipSession session, int errorCode,
    224                 String errorMessage) {
    225         }
    226 
    227         /**
    228          * Called when the registration gets timed out.
    229          *
    230          * @param session the session object that carries out the transaction
    231          */
    232         public void onRegistrationTimeout(SipSession session) {
    233         }
    234     }
    235 
    236     private final ISipSession mSession;
    237     private Listener mListener;
    238 
    239     SipSession(ISipSession realSession) {
    240         mSession = realSession;
    241         if (realSession != null) {
    242             try {
    243                 realSession.setListener(createListener());
    244             } catch (RemoteException e) {
    245                 loge("SipSession.setListener:", e);
    246             }
    247         }
    248     }
    249 
    250     SipSession(ISipSession realSession, Listener listener) {
    251         this(realSession);
    252         setListener(listener);
    253     }
    254 
    255     /**
    256      * Gets the IP address of the local host on which this SIP session runs.
    257      *
    258      * @return the IP address of the local host
    259      */
    260     public String getLocalIp() {
    261         try {
    262             return mSession.getLocalIp();
    263         } catch (RemoteException e) {
    264             loge("getLocalIp:", e);
    265             return "127.0.0.1";
    266         }
    267     }
    268 
    269     /**
    270      * Gets the SIP profile that this session is associated with.
    271      *
    272      * @return the SIP profile that this session is associated with
    273      */
    274     public SipProfile getLocalProfile() {
    275         try {
    276             return mSession.getLocalProfile();
    277         } catch (RemoteException e) {
    278             loge("getLocalProfile:", e);
    279             return null;
    280         }
    281     }
    282 
    283     /**
    284      * Gets the SIP profile that this session is connected to. Only available
    285      * when the session is associated with a SIP dialog.
    286      *
    287      * @return the SIP profile that this session is connected to
    288      */
    289     public SipProfile getPeerProfile() {
    290         try {
    291             return mSession.getPeerProfile();
    292         } catch (RemoteException e) {
    293             loge("getPeerProfile:", e);
    294             return null;
    295         }
    296     }
    297 
    298     /**
    299      * Gets the session state. The value returned must be one of the states in
    300      * {@link State}.
    301      *
    302      * @return the session state
    303      */
    304     public int getState() {
    305         try {
    306             return mSession.getState();
    307         } catch (RemoteException e) {
    308             loge("getState:", e);
    309             return State.NOT_DEFINED;
    310         }
    311     }
    312 
    313     /**
    314      * Checks if the session is in a call.
    315      *
    316      * @return true if the session is in a call
    317      */
    318     public boolean isInCall() {
    319         try {
    320             return mSession.isInCall();
    321         } catch (RemoteException e) {
    322             loge("isInCall:", e);
    323             return false;
    324         }
    325     }
    326 
    327     /**
    328      * Gets the call ID of the session.
    329      *
    330      * @return the call ID
    331      */
    332     public String getCallId() {
    333         try {
    334             return mSession.getCallId();
    335         } catch (RemoteException e) {
    336             loge("getCallId:", e);
    337             return null;
    338         }
    339     }
    340 
    341 
    342     /**
    343      * Sets the listener to listen to the session events. A {@code SipSession}
    344      * can only hold one listener at a time. Subsequent calls to this method
    345      * override the previous listener.
    346      *
    347      * @param listener to listen to the session events of this object
    348      */
    349     public void setListener(Listener listener) {
    350         mListener = listener;
    351     }
    352 
    353 
    354     /**
    355      * Performs registration to the server specified by the associated local
    356      * profile. The session listener is called back upon success or failure of
    357      * registration. The method is only valid to call when the session state is
    358      * in {@link State#READY_TO_CALL}.
    359      *
    360      * @param duration duration in second before the registration expires
    361      * @see Listener
    362      */
    363     public void register(int duration) {
    364         try {
    365             mSession.register(duration);
    366         } catch (RemoteException e) {
    367             loge("register:", e);
    368         }
    369     }
    370 
    371     /**
    372      * Performs unregistration to the server specified by the associated local
    373      * profile. Unregistration is technically the same as registration with zero
    374      * expiration duration. The session listener is called back upon success or
    375      * failure of unregistration. The method is only valid to call when the
    376      * session state is in {@link State#READY_TO_CALL}.
    377      *
    378      * @see Listener
    379      */
    380     public void unregister() {
    381         try {
    382             mSession.unregister();
    383         } catch (RemoteException e) {
    384             loge("unregister:", e);
    385         }
    386     }
    387 
    388     /**
    389      * Initiates a call to the specified profile. The session listener is called
    390      * back upon defined session events. The method is only valid to call when
    391      * the session state is in {@link State#READY_TO_CALL}.
    392      *
    393      * @param callee the SIP profile to make the call to
    394      * @param sessionDescription the session description of this call
    395      * @param timeout the session will be timed out if the call is not
    396      *        established within {@code timeout} seconds. Default value (defined
    397      *        by SIP protocol) is used if {@code timeout} is zero or negative.
    398      * @see Listener
    399      */
    400     public void makeCall(SipProfile callee, String sessionDescription,
    401             int timeout) {
    402         try {
    403             mSession.makeCall(callee, sessionDescription, timeout);
    404         } catch (RemoteException e) {
    405             loge("makeCall:", e);
    406         }
    407     }
    408 
    409     /**
    410      * Answers an incoming call with the specified session description. The
    411      * method is only valid to call when the session state is in
    412      * {@link State#INCOMING_CALL}.
    413      *
    414      * @param sessionDescription the session description to answer this call
    415      * @param timeout the session will be timed out if the call is not
    416      *        established within {@code timeout} seconds. Default value (defined
    417      *        by SIP protocol) is used if {@code timeout} is zero or negative.
    418      */
    419     public void answerCall(String sessionDescription, int timeout) {
    420         try {
    421             mSession.answerCall(sessionDescription, timeout);
    422         } catch (RemoteException e) {
    423             loge("answerCall:", e);
    424         }
    425     }
    426 
    427     /**
    428      * Ends an established call, terminates an outgoing call or rejects an
    429      * incoming call. The method is only valid to call when the session state is
    430      * in {@link State#IN_CALL},
    431      * {@link State#INCOMING_CALL},
    432      * {@link State#OUTGOING_CALL} or
    433      * {@link State#OUTGOING_CALL_RING_BACK}.
    434      */
    435     public void endCall() {
    436         try {
    437             mSession.endCall();
    438         } catch (RemoteException e) {
    439             loge("endCall:", e);
    440         }
    441     }
    442 
    443     /**
    444      * Changes the session description during a call. The method is only valid
    445      * to call when the session state is in {@link State#IN_CALL}.
    446      *
    447      * @param sessionDescription the new session description
    448      * @param timeout the session will be timed out if the call is not
    449      *        established within {@code timeout} seconds. Default value (defined
    450      *        by SIP protocol) is used if {@code timeout} is zero or negative.
    451      */
    452     public void changeCall(String sessionDescription, int timeout) {
    453         try {
    454             mSession.changeCall(sessionDescription, timeout);
    455         } catch (RemoteException e) {
    456             loge("changeCall:", e);
    457         }
    458     }
    459 
    460     ISipSession getRealSession() {
    461         return mSession;
    462     }
    463 
    464     private ISipSessionListener createListener() {
    465         return new ISipSessionListener.Stub() {
    466             @Override
    467             public void onCalling(ISipSession session) {
    468                 if (mListener != null) {
    469                     mListener.onCalling(SipSession.this);
    470                 }
    471             }
    472 
    473             @Override
    474             public void onRinging(ISipSession session, SipProfile caller,
    475                     String sessionDescription) {
    476                 if (mListener != null) {
    477                     mListener.onRinging(SipSession.this, caller,
    478                             sessionDescription);
    479                 }
    480             }
    481 
    482             @Override
    483             public void onRingingBack(ISipSession session) {
    484                 if (mListener != null) {
    485                     mListener.onRingingBack(SipSession.this);
    486                 }
    487             }
    488 
    489             @Override
    490             public void onCallEstablished(ISipSession session,
    491                     String sessionDescription) {
    492                 if (mListener != null) {
    493                     mListener.onCallEstablished(SipSession.this,
    494                             sessionDescription);
    495                 }
    496             }
    497 
    498             @Override
    499             public void onCallEnded(ISipSession session) {
    500                 if (mListener != null) {
    501                     mListener.onCallEnded(SipSession.this);
    502                 }
    503             }
    504 
    505             @Override
    506             public void onCallBusy(ISipSession session) {
    507                 if (mListener != null) {
    508                     mListener.onCallBusy(SipSession.this);
    509                 }
    510             }
    511 
    512             @Override
    513             public void onCallTransferring(ISipSession session,
    514                     String sessionDescription) {
    515                 if (mListener != null) {
    516                     mListener.onCallTransferring(
    517                             new SipSession(session, SipSession.this.mListener),
    518                             sessionDescription);
    519 
    520                 }
    521             }
    522 
    523             @Override
    524             public void onCallChangeFailed(ISipSession session, int errorCode,
    525                     String message) {
    526                 if (mListener != null) {
    527                     mListener.onCallChangeFailed(SipSession.this, errorCode,
    528                             message);
    529                 }
    530             }
    531 
    532             @Override
    533             public void onError(ISipSession session, int errorCode, String message) {
    534                 if (mListener != null) {
    535                     mListener.onError(SipSession.this, errorCode, message);
    536                 }
    537             }
    538 
    539             @Override
    540             public void onRegistering(ISipSession session) {
    541                 if (mListener != null) {
    542                     mListener.onRegistering(SipSession.this);
    543                 }
    544             }
    545 
    546             @Override
    547             public void onRegistrationDone(ISipSession session, int duration) {
    548                 if (mListener != null) {
    549                     mListener.onRegistrationDone(SipSession.this, duration);
    550                 }
    551             }
    552 
    553             @Override
    554             public void onRegistrationFailed(ISipSession session, int errorCode,
    555                     String message) {
    556                 if (mListener != null) {
    557                     mListener.onRegistrationFailed(SipSession.this, errorCode,
    558                             message);
    559                 }
    560             }
    561 
    562             @Override
    563             public void onRegistrationTimeout(ISipSession session) {
    564                 if (mListener != null) {
    565                     mListener.onRegistrationTimeout(SipSession.this);
    566                 }
    567             }
    568         };
    569     }
    570 
    571     private void loge(String s, Throwable t) {
    572         Rlog.e(TAG, s, t);
    573     }
    574 }
    575