• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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         /** 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          */
toString(int state)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 
State()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          */
onCalling(SipSession session)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          */
onRinging(SipSession session, SipProfile caller, String sessionDescription)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          */
onRingingBack(SipSession session)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          */
onCallEstablished(SipSession session, String sessionDescription)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          */
onCallEnded(SipSession session)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          */
onCallBusy(SipSession session)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          */
onCallTransferring(SipSession newSession, String sessionDescription)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          */
onError(SipSession session, int errorCode, String errorMessage)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          */
onCallChangeFailed(SipSession session, int errorCode, String errorMessage)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          */
onRegistering(SipSession session)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          */
onRegistrationDone(SipSession session, int duration)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          */
onRegistrationFailed(SipSession session, int errorCode, String errorMessage)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          */
onRegistrationTimeout(SipSession session)232         public void onRegistrationTimeout(SipSession session) {
233         }
234     }
235 
236     private final ISipSession mSession;
237     private Listener mListener;
238 
SipSession(ISipSession realSession)239     SipSession(ISipSession realSession) {
240         mSession = realSession;
241         if (realSession != null) {
242             try {
243                 realSession.setListener(createListener());
244             } catch (RemoteException e) {
245                 Log.e(TAG, "SipSession.setListener(): " + e);
246             }
247         }
248     }
249 
SipSession(ISipSession realSession, Listener listener)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      */
getLocalIp()260     public String getLocalIp() {
261         try {
262             return mSession.getLocalIp();
263         } catch (RemoteException e) {
264             Log.e(TAG, "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      */
getLocalProfile()274     public SipProfile getLocalProfile() {
275         try {
276             return mSession.getLocalProfile();
277         } catch (RemoteException e) {
278             Log.e(TAG, "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      */
getPeerProfile()289     public SipProfile getPeerProfile() {
290         try {
291             return mSession.getPeerProfile();
292         } catch (RemoteException e) {
293             Log.e(TAG, "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      */
getState()304     public int getState() {
305         try {
306             return mSession.getState();
307         } catch (RemoteException e) {
308             Log.e(TAG, "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      */
isInCall()318     public boolean isInCall() {
319         try {
320             return mSession.isInCall();
321         } catch (RemoteException e) {
322             Log.e(TAG, "isInCall(): " + e);
323             return false;
324         }
325     }
326 
327     /**
328      * Gets the call ID of the session.
329      *
330      * @return the call ID
331      */
getCallId()332     public String getCallId() {
333         try {
334             return mSession.getCallId();
335         } catch (RemoteException e) {
336             Log.e(TAG, "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      */
setListener(Listener listener)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      */
register(int duration)363     public void register(int duration) {
364         try {
365             mSession.register(duration);
366         } catch (RemoteException e) {
367             Log.e(TAG, "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      */
unregister()380     public void unregister() {
381         try {
382             mSession.unregister();
383         } catch (RemoteException e) {
384             Log.e(TAG, "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      */
makeCall(SipProfile callee, String sessionDescription, int timeout)400     public void makeCall(SipProfile callee, String sessionDescription,
401             int timeout) {
402         try {
403             mSession.makeCall(callee, sessionDescription, timeout);
404         } catch (RemoteException e) {
405             Log.e(TAG, "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      */
answerCall(String sessionDescription, int timeout)419     public void answerCall(String sessionDescription, int timeout) {
420         try {
421             mSession.answerCall(sessionDescription, timeout);
422         } catch (RemoteException e) {
423             Log.e(TAG, "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      */
endCall()435     public void endCall() {
436         try {
437             mSession.endCall();
438         } catch (RemoteException e) {
439             Log.e(TAG, "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      */
changeCall(String sessionDescription, int timeout)452     public void changeCall(String sessionDescription, int timeout) {
453         try {
454             mSession.changeCall(sessionDescription, timeout);
455         } catch (RemoteException e) {
456             Log.e(TAG, "changeCall(): " + e);
457         }
458     }
459 
getRealSession()460     ISipSession getRealSession() {
461         return mSession;
462     }
463 
createListener()464     private ISipSessionListener createListener() {
465         return new ISipSessionListener.Stub() {
466             public void onCalling(ISipSession session) {
467                 if (mListener != null) {
468                     mListener.onCalling(SipSession.this);
469                 }
470             }
471 
472             public void onRinging(ISipSession session, SipProfile caller,
473                     String sessionDescription) {
474                 if (mListener != null) {
475                     mListener.onRinging(SipSession.this, caller,
476                             sessionDescription);
477                 }
478             }
479 
480             public void onRingingBack(ISipSession session) {
481                 if (mListener != null) {
482                     mListener.onRingingBack(SipSession.this);
483                 }
484             }
485 
486             public void onCallEstablished(ISipSession session,
487                     String sessionDescription) {
488                 if (mListener != null) {
489                     mListener.onCallEstablished(SipSession.this,
490                             sessionDescription);
491                 }
492             }
493 
494             public void onCallEnded(ISipSession session) {
495                 if (mListener != null) {
496                     mListener.onCallEnded(SipSession.this);
497                 }
498             }
499 
500             public void onCallBusy(ISipSession session) {
501                 if (mListener != null) {
502                     mListener.onCallBusy(SipSession.this);
503                 }
504             }
505 
506             public void onCallTransferring(ISipSession session,
507                     String sessionDescription) {
508                 if (mListener != null) {
509                     mListener.onCallTransferring(
510                             new SipSession(session, SipSession.this.mListener),
511                             sessionDescription);
512 
513                 }
514             }
515 
516             public void onCallChangeFailed(ISipSession session, int errorCode,
517                     String message) {
518                 if (mListener != null) {
519                     mListener.onCallChangeFailed(SipSession.this, errorCode,
520                             message);
521                 }
522             }
523 
524             public void onError(ISipSession session, int errorCode, String message) {
525                 if (mListener != null) {
526                     mListener.onError(SipSession.this, errorCode, message);
527                 }
528             }
529 
530             public void onRegistering(ISipSession session) {
531                 if (mListener != null) {
532                     mListener.onRegistering(SipSession.this);
533                 }
534             }
535 
536             public void onRegistrationDone(ISipSession session, int duration) {
537                 if (mListener != null) {
538                     mListener.onRegistrationDone(SipSession.this, duration);
539                 }
540             }
541 
542             public void onRegistrationFailed(ISipSession session, int errorCode,
543                     String message) {
544                 if (mListener != null) {
545                     mListener.onRegistrationFailed(SipSession.this, errorCode,
546                             message);
547                 }
548             }
549 
550             public void onRegistrationTimeout(ISipSession session) {
551                 if (mListener != null) {
552                     mListener.onRegistrationTimeout(SipSession.this);
553                 }
554             }
555         };
556     }
557 }
558