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