blob: d48f94ab81bdae37c1a95ad9a58cf210ad5c002e [file] [log] [blame]
Hung-ying Tyanff0fe662010-06-23 17:26:48 -07001/*
Hung-ying Tyan73f84372010-06-23 18:15:20 -07002 * Copyright (C) 2010 The Android Open Source Project
Hung-ying Tyanff0fe662010-06-23 17:26:48 -07003 *
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 com.android.internal.telephony.sip;
Hung-ying Tyanb8ae93b2010-07-02 18:50:39 -070018
Hung-ying Tyanff0fe662010-06-23 17:26:48 -070019import android.content.Context;
20import android.net.sip.SipAudioCall;
Hung-ying Tyanff0fe662010-06-23 17:26:48 -070021import android.os.Message;
Hung-ying Tyanff0fe662010-06-23 17:26:48 -070022import android.os.Registrant;
23import android.os.SystemClock;
Hung-ying Tyanff0fe662010-06-23 17:26:48 -070024import android.util.Log;
25import android.telephony.PhoneNumberUtils;
26import android.telephony.ServiceState;
27
28import com.android.internal.telephony.*;
29
Hung-ying Tyanfe68ef22010-06-28 23:00:45 -070030abstract class SipConnectionBase extends Connection {
Hung-ying Tyanff0fe662010-06-23 17:26:48 -070031 //***** Event Constants
32 private static final int EVENT_DTMF_DONE = 1;
33 private static final int EVENT_PAUSE_DONE = 2;
34 private static final int EVENT_NEXT_POST_DIAL = 3;
35 private static final int EVENT_WAKE_LOCK_TIMEOUT = 4;
36
37 //***** Constants
38 private static final int PAUSE_DELAY_FIRST_MILLIS = 100;
39 private static final int PAUSE_DELAY_MILLIS = 3 * 1000;
40 private static final int WAKE_LOCK_TIMEOUT_MILLIS = 60*1000;
41
42 private static final String LOG_TAG = "SIP_CONN";
43
Hung-ying Tyanff0fe662010-06-23 17:26:48 -070044 private SipAudioCall mSipAudioCall;
45
Hung-ying Tyanff0fe662010-06-23 17:26:48 -070046 private String dialString; // outgoing calls only
47 private String postDialString; // outgoing calls only
48 private int nextPostDialChar; // index into postDialString
49 private boolean isIncoming;
50 private boolean disconnected;
51
52 int index; // index in SipCallTracker.connections[], -1 if unassigned
53 // The Sip index is 1 + this
54
55 /*
56 * These time/timespan values are based on System.currentTimeMillis(),
57 * i.e., "wall clock" time.
58 */
59 private long createTime;
60 private long connectTime;
61 private long disconnectTime;
62
63 /*
64 * These time/timespan values are based on SystemClock.elapsedRealTime(),
65 * i.e., time since boot. They are appropriate for comparison and
66 * calculating deltas.
67 */
68 private long connectTimeReal;
69 private long duration;
70 private long holdingStartTime; // The time when the Connection last transitioned
71 // into HOLDING
72
73 private DisconnectCause mCause = DisconnectCause.NOT_DISCONNECTED;
74 private PostDialState postDialState = PostDialState.NOT_STARTED;
75
Hung-ying Tyan15364d12010-07-25 00:17:12 -070076 SipConnectionBase(String calleeSipUri) {
Hung-ying Tyanfe68ef22010-06-28 23:00:45 -070077 dialString = calleeSipUri;
78
79 postDialString = PhoneNumberUtils.extractPostDialPortion(dialString);
80
81 isIncoming = false;
82 createTime = System.currentTimeMillis();
83 }
84
Hung-ying Tyan15364d12010-07-25 00:17:12 -070085 protected void setState(Call.State state) {
86 switch (state) {
87 case ACTIVE:
88 connectTimeReal = SystemClock.elapsedRealtime();
89 connectTime = System.currentTimeMillis();
90 break;
91 case DISCONNECTED:
92 duration = SystemClock.elapsedRealtime() - connectTimeReal;
93 disconnectTime = System.currentTimeMillis();
94 break;
95 case HOLDING:
96 holdingStartTime = SystemClock.elapsedRealtime();
97 break;
98 }
99 }
100
Hung-ying Tyanb8ae93b2010-07-02 18:50:39 -0700101 @Override
Hung-ying Tyanff0fe662010-06-23 17:26:48 -0700102 public long getCreateTime() {
103 return createTime;
104 }
105
Hung-ying Tyanb8ae93b2010-07-02 18:50:39 -0700106 @Override
Hung-ying Tyanff0fe662010-06-23 17:26:48 -0700107 public long getConnectTime() {
108 return connectTime;
109 }
110
Hung-ying Tyanb8ae93b2010-07-02 18:50:39 -0700111 @Override
Hung-ying Tyanff0fe662010-06-23 17:26:48 -0700112 public long getDisconnectTime() {
113 return disconnectTime;
114 }
115
Hung-ying Tyanb8ae93b2010-07-02 18:50:39 -0700116 @Override
Hung-ying Tyanff0fe662010-06-23 17:26:48 -0700117 public long getDurationMillis() {
118 if (connectTimeReal == 0) {
119 return 0;
120 } else if (duration == 0) {
121 return SystemClock.elapsedRealtime() - connectTimeReal;
122 } else {
123 return duration;
124 }
125 }
126
Hung-ying Tyanb8ae93b2010-07-02 18:50:39 -0700127 @Override
Hung-ying Tyanff0fe662010-06-23 17:26:48 -0700128 public long getHoldDurationMillis() {
Hung-ying Tyanfe68ef22010-06-28 23:00:45 -0700129 if (getState() != Call.State.HOLDING) {
Hung-ying Tyanff0fe662010-06-23 17:26:48 -0700130 // If not holding, return 0
131 return 0;
132 } else {
133 return SystemClock.elapsedRealtime() - holdingStartTime;
134 }
135 }
136
Hung-ying Tyanb8ae93b2010-07-02 18:50:39 -0700137 @Override
Hung-ying Tyanff0fe662010-06-23 17:26:48 -0700138 public DisconnectCause getDisconnectCause() {
139 return mCause;
140 }
141
142 void setDisconnectCause(DisconnectCause cause) {
143 mCause = cause;
144 }
145
Hung-ying Tyanb8ae93b2010-07-02 18:50:39 -0700146 @Override
Hung-ying Tyanff0fe662010-06-23 17:26:48 -0700147 public PostDialState getPostDialState() {
148 return postDialState;
149 }
150
Hung-ying Tyanb8ae93b2010-07-02 18:50:39 -0700151 @Override
Hung-ying Tyanff0fe662010-06-23 17:26:48 -0700152 public void proceedAfterWaitChar() {
Hung-ying Tyanb8ae93b2010-07-02 18:50:39 -0700153 // TODO
Hung-ying Tyanff0fe662010-06-23 17:26:48 -0700154 }
155
Hung-ying Tyanb8ae93b2010-07-02 18:50:39 -0700156 @Override
Hung-ying Tyanff0fe662010-06-23 17:26:48 -0700157 public void proceedAfterWildChar(String str) {
Hung-ying Tyanb8ae93b2010-07-02 18:50:39 -0700158 // TODO
Hung-ying Tyanff0fe662010-06-23 17:26:48 -0700159 }
160
Hung-ying Tyanb8ae93b2010-07-02 18:50:39 -0700161 @Override
Hung-ying Tyanff0fe662010-06-23 17:26:48 -0700162 public void cancelPostDial() {
Hung-ying Tyanb8ae93b2010-07-02 18:50:39 -0700163 // TODO
Hung-ying Tyanff0fe662010-06-23 17:26:48 -0700164 }
165
Hung-ying Tyanfe68ef22010-06-28 23:00:45 -0700166 protected abstract Phone getPhone();
167
Hung-ying Tyanff0fe662010-06-23 17:26:48 -0700168 DisconnectCause disconnectCauseFromCode(int causeCode) {
169 /**
170 * See 22.001 Annex F.4 for mapping of cause codes
171 * to local tones
172 */
173
174 switch (causeCode) {
175 case CallFailCause.USER_BUSY:
176 return DisconnectCause.BUSY;
177
178 case CallFailCause.NO_CIRCUIT_AVAIL:
179 case CallFailCause.TEMPORARY_FAILURE:
180 case CallFailCause.SWITCHING_CONGESTION:
181 case CallFailCause.CHANNEL_NOT_AVAIL:
182 case CallFailCause.QOS_NOT_AVAIL:
183 case CallFailCause.BEARER_NOT_AVAIL:
184 return DisconnectCause.CONGESTION;
185
186 case CallFailCause.ACM_LIMIT_EXCEEDED:
187 return DisconnectCause.LIMIT_EXCEEDED;
188
189 case CallFailCause.CALL_BARRED:
190 return DisconnectCause.CALL_BARRED;
191
192 case CallFailCause.FDN_BLOCKED:
193 return DisconnectCause.FDN_BLOCKED;
194
195 case CallFailCause.ERROR_UNSPECIFIED:
196 case CallFailCause.NORMAL_CLEARING:
197 default:
Hung-ying Tyanfe68ef22010-06-28 23:00:45 -0700198 Phone phone = getPhone();
Hung-ying Tyanff0fe662010-06-23 17:26:48 -0700199 int serviceState = phone.getServiceState().getState();
200 if (serviceState == ServiceState.STATE_POWER_OFF) {
201 return DisconnectCause.POWER_OFF;
202 } else if (serviceState == ServiceState.STATE_OUT_OF_SERVICE
203 || serviceState == ServiceState.STATE_EMERGENCY_ONLY ) {
204 return DisconnectCause.OUT_OF_SERVICE;
205 } else if (causeCode == CallFailCause.ERROR_UNSPECIFIED) {
206 return DisconnectCause.ERROR_UNSPECIFIED;
207 } else if (causeCode == CallFailCause.NORMAL_CLEARING) {
208 return DisconnectCause.NORMAL;
209 } else {
210 // If nothing else matches, report unknown call drop reason
211 // to app, not NORMAL call end.
212 return DisconnectCause.ERROR_UNSPECIFIED;
213 }
214 }
215 }
216
Hung-ying Tyanb8ae93b2010-07-02 18:50:39 -0700217 @Override
Hung-ying Tyanff0fe662010-06-23 17:26:48 -0700218 public String getRemainingPostDialString() {
219 if (postDialState == PostDialState.CANCELLED
220 || postDialState == PostDialState.COMPLETE
221 || postDialString == null
222 || postDialString.length() <= nextPostDialChar) {
223 return "";
224 }
225
226 return postDialString.substring(nextPostDialChar);
227 }
228
Hung-ying Tyanff0fe662010-06-23 17:26:48 -0700229 private void log(String msg) {
230 Log.d(LOG_TAG, "[SipConn] " + msg);
231 }
232
233 @Override
234 public int getNumberPresentation() {
Hung-ying Tyan15364d12010-07-25 00:17:12 -0700235 // TODO: add PRESENTATION_URL
Hung-ying Tyanff0fe662010-06-23 17:26:48 -0700236 return Connection.PRESENTATION_ALLOWED;
237 }
238
Hung-ying Tyanfe68ef22010-06-28 23:00:45 -0700239 /*
Hung-ying Tyan9ea67392010-06-23 17:58:46 -0700240 @Override
241 public UUSInfo getUUSInfo() {
242 // FIXME: what's this for SIP?
243 return null;
244 }
Hung-ying Tyanfe68ef22010-06-28 23:00:45 -0700245 */
Hung-ying Tyanff0fe662010-06-23 17:26:48 -0700246}