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