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