SipSession.java revision d012595fd71a41159ec437d072f5dc56db8444a2
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.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 */
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        /** 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