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