SipSession.java revision 1aceda35cc607856ec2e960e0c6cfc6aea87ab8e
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 * 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 */
29public 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 the call is being transferred to a new one.
164         *
165         * @hide
166         * @param newSession the new session that the call will be transferred to
167         * @param sessionDescription the new peer's session description
168         */
169        public void onCallTransferring(SipSession newSession,
170                String sessionDescription) {
171        }
172
173        /**
174         * Called when an error occurs during session initialization and
175         * termination.
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 onError(SipSession session, int errorCode,
182                String errorMessage) {
183        }
184
185        /**
186         * Called when an error occurs during session modification negotiation.
187         *
188         * @param session the session object that carries out the transaction
189         * @param errorCode error code defined in {@link SipErrorCode}
190         * @param errorMessage error message
191         */
192        public void onCallChangeFailed(SipSession session, int errorCode,
193                String errorMessage) {
194        }
195
196        /**
197         * Called when a registration request is sent.
198         *
199         * @param session the session object that carries out the transaction
200         */
201        public void onRegistering(SipSession session) {
202        }
203
204        /**
205         * Called when registration is successfully done.
206         *
207         * @param session the session object that carries out the transaction
208         * @param duration duration in second before the registration expires
209         */
210        public void onRegistrationDone(SipSession session, int duration) {
211        }
212
213        /**
214         * Called when the registration fails.
215         *
216         * @param session the session object that carries out the transaction
217         * @param errorCode error code defined in {@link SipErrorCode}
218         * @param errorMessage error message
219         */
220        public void onRegistrationFailed(SipSession session, int errorCode,
221                String errorMessage) {
222        }
223
224        /**
225         * Called when the registration gets timed out.
226         *
227         * @param session the session object that carries out the transaction
228         */
229        public void onRegistrationTimeout(SipSession session) {
230        }
231    }
232
233    private final ISipSession mSession;
234    private Listener mListener;
235
236    SipSession(ISipSession realSession) {
237        mSession = realSession;
238        if (realSession != null) {
239            try {
240                realSession.setListener(createListener());
241            } catch (RemoteException e) {
242                Log.e(TAG, "SipSession.setListener(): " + e);
243            }
244        }
245    }
246
247    SipSession(ISipSession realSession, Listener listener) {
248        this(realSession);
249        setListener(listener);
250    }
251
252    /**
253     * Gets the IP address of the local host on which this SIP session runs.
254     *
255     * @return the IP address of the local host
256     */
257    public String getLocalIp() {
258        try {
259            return mSession.getLocalIp();
260        } catch (RemoteException e) {
261            Log.e(TAG, "getLocalIp(): " + e);
262            return "127.0.0.1";
263        }
264    }
265
266    /**
267     * Gets the SIP profile that this session is associated with.
268     *
269     * @return the SIP profile that this session is associated with
270     */
271    public SipProfile getLocalProfile() {
272        try {
273            return mSession.getLocalProfile();
274        } catch (RemoteException e) {
275            Log.e(TAG, "getLocalProfile(): " + e);
276            return null;
277        }
278    }
279
280    /**
281     * Gets the SIP profile that this session is connected to. Only available
282     * when the session is associated with a SIP dialog.
283     *
284     * @return the SIP profile that this session is connected to
285     */
286    public SipProfile getPeerProfile() {
287        try {
288            return mSession.getPeerProfile();
289        } catch (RemoteException e) {
290            Log.e(TAG, "getPeerProfile(): " + e);
291            return null;
292        }
293    }
294
295    /**
296     * Gets the session state. The value returned must be one of the states in
297     * {@link State}.
298     *
299     * @return the session state
300     */
301    public int getState() {
302        try {
303            return mSession.getState();
304        } catch (RemoteException e) {
305            Log.e(TAG, "getState(): " + e);
306            return State.NOT_DEFINED;
307        }
308    }
309
310    /**
311     * Checks if the session is in a call.
312     *
313     * @return true if the session is in a call
314     */
315    public boolean isInCall() {
316        try {
317            return mSession.isInCall();
318        } catch (RemoteException e) {
319            Log.e(TAG, "isInCall(): " + e);
320            return false;
321        }
322    }
323
324    /**
325     * Gets the call ID of the session.
326     *
327     * @return the call ID
328     */
329    public String getCallId() {
330        try {
331            return mSession.getCallId();
332        } catch (RemoteException e) {
333            Log.e(TAG, "getCallId(): " + e);
334            return null;
335        }
336    }
337
338
339    /**
340     * Sets the listener to listen to the session events. A {@code SipSession}
341     * can only hold one listener at a time. Subsequent calls to this method
342     * override the previous listener.
343     *
344     * @param listener to listen to the session events of this object
345     */
346    public void setListener(Listener listener) {
347        mListener = listener;
348    }
349
350
351    /**
352     * Performs registration to the server specified by the associated local
353     * profile. The session listener is called back upon success or failure of
354     * registration. The method is only valid to call when the session state is
355     * in {@link State#READY_TO_CALL}.
356     *
357     * @param duration duration in second before the registration expires
358     * @see Listener
359     */
360    public void register(int duration) {
361        try {
362            mSession.register(duration);
363        } catch (RemoteException e) {
364            Log.e(TAG, "register(): " + e);
365        }
366    }
367
368    /**
369     * Performs unregistration to the server specified by the associated local
370     * profile. Unregistration is technically the same as registration with zero
371     * expiration duration. The session listener is called back upon success or
372     * failure of unregistration. The method is only valid to call when the
373     * session state is in {@link State#READY_TO_CALL}.
374     *
375     * @see Listener
376     */
377    public void unregister() {
378        try {
379            mSession.unregister();
380        } catch (RemoteException e) {
381            Log.e(TAG, "unregister(): " + e);
382        }
383    }
384
385    /**
386     * Initiates a call to the specified profile. The session listener is called
387     * back upon defined session events. The method is only valid to call when
388     * the session state is in {@link State#READY_TO_CALL}.
389     *
390     * @param callee the SIP profile to make the call to
391     * @param sessionDescription the session description of this call
392     * @param timeout the session will be timed out if the call is not
393     *        established within {@code timeout} seconds. Default value (defined
394     *        by SIP protocol) is used if {@code timeout} is zero or negative.
395     * @see Listener
396     */
397    public void makeCall(SipProfile callee, String sessionDescription,
398            int timeout) {
399        try {
400            mSession.makeCall(callee, sessionDescription, timeout);
401        } catch (RemoteException e) {
402            Log.e(TAG, "makeCall(): " + e);
403        }
404    }
405
406    /**
407     * Answers an incoming call with the specified session description. The
408     * method is only valid to call when the session state is in
409     * {@link State#INCOMING_CALL}.
410     *
411     * @param sessionDescription the session description to answer this call
412     * @param timeout the session will be timed out if the call is not
413     *        established within {@code timeout} seconds. Default value (defined
414     *        by SIP protocol) is used if {@code timeout} is zero or negative.
415     */
416    public void answerCall(String sessionDescription, int timeout) {
417        try {
418            mSession.answerCall(sessionDescription, timeout);
419        } catch (RemoteException e) {
420            Log.e(TAG, "answerCall(): " + e);
421        }
422    }
423
424    /**
425     * Ends an established call, terminates an outgoing call or rejects an
426     * incoming call. The method is only valid to call when the session state is
427     * in {@link State#IN_CALL},
428     * {@link State#INCOMING_CALL},
429     * {@link State#OUTGOING_CALL} or
430     * {@link State#OUTGOING_CALL_RING_BACK}.
431     */
432    public void endCall() {
433        try {
434            mSession.endCall();
435        } catch (RemoteException e) {
436            Log.e(TAG, "endCall(): " + e);
437        }
438    }
439
440    /**
441     * Changes the session description during a call. The method is only valid
442     * to call when the session state is in {@link State#IN_CALL}.
443     *
444     * @param sessionDescription the new session description
445     * @param timeout the session will be timed out if the call is not
446     *        established within {@code timeout} seconds. Default value (defined
447     *        by SIP protocol) is used if {@code timeout} is zero or negative.
448     */
449    public void changeCall(String sessionDescription, int timeout) {
450        try {
451            mSession.changeCall(sessionDescription, timeout);
452        } catch (RemoteException e) {
453            Log.e(TAG, "changeCall(): " + e);
454        }
455    }
456
457    ISipSession getRealSession() {
458        return mSession;
459    }
460
461    private ISipSessionListener createListener() {
462        return new ISipSessionListener.Stub() {
463            public void onCalling(ISipSession session) {
464                if (mListener != null) {
465                    mListener.onCalling(SipSession.this);
466                }
467            }
468
469            public void onRinging(ISipSession session, SipProfile caller,
470                    String sessionDescription) {
471                if (mListener != null) {
472                    mListener.onRinging(SipSession.this, caller,
473                            sessionDescription);
474                }
475            }
476
477            public void onRingingBack(ISipSession session) {
478                if (mListener != null) {
479                    mListener.onRingingBack(SipSession.this);
480                }
481            }
482
483            public void onCallEstablished(ISipSession session,
484                    String sessionDescription) {
485                if (mListener != null) {
486                    mListener.onCallEstablished(SipSession.this,
487                            sessionDescription);
488                }
489            }
490
491            public void onCallEnded(ISipSession session) {
492                if (mListener != null) {
493                    mListener.onCallEnded(SipSession.this);
494                }
495            }
496
497            public void onCallBusy(ISipSession session) {
498                if (mListener != null) {
499                    mListener.onCallBusy(SipSession.this);
500                }
501            }
502
503            public void onCallTransferring(ISipSession session,
504                    String sessionDescription) {
505                if (mListener != null) {
506                    mListener.onCallTransferring(
507                            new SipSession(session, SipSession.this.mListener),
508                            sessionDescription);
509
510                }
511            }
512
513            public void onCallChangeFailed(ISipSession session, int errorCode,
514                    String message) {
515                if (mListener != null) {
516                    mListener.onCallChangeFailed(SipSession.this, errorCode,
517                            message);
518                }
519            }
520
521            public void onError(ISipSession session, int errorCode, String message) {
522                if (mListener != null) {
523                    mListener.onError(SipSession.this, errorCode, message);
524                }
525            }
526
527            public void onRegistering(ISipSession session) {
528                if (mListener != null) {
529                    mListener.onRegistering(SipSession.this);
530                }
531            }
532
533            public void onRegistrationDone(ISipSession session, int duration) {
534                if (mListener != null) {
535                    mListener.onRegistrationDone(SipSession.this, duration);
536                }
537            }
538
539            public void onRegistrationFailed(ISipSession session, int errorCode,
540                    String message) {
541                if (mListener != null) {
542                    mListener.onRegistrationFailed(SipSession.this, errorCode,
543                            message);
544                }
545            }
546
547            public void onRegistrationTimeout(ISipSession session) {
548                if (mListener != null) {
549                    mListener.onRegistrationTimeout(SipSession.this);
550                }
551            }
552        };
553    }
554}
555