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