|
1 /* |
|
2 * Copyright (c) 2002-2004 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Connection manager |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // Copyright (C) 2002-2004 Nokia |
|
20 |
|
21 // INCLUDE FILES |
|
22 #include <commdbconnpref.h> |
|
23 #include <es_enum.h> |
|
24 #include "rsfwconnectionmanager.h" |
|
25 #include "rsfwcommon.h" |
|
26 #include "mdebug.h" |
|
27 |
|
28 // ============================ MEMBER FUNCTIONS ============================== |
|
29 |
|
30 // ---------------------------------------------------------------------------- |
|
31 // CRsfwConnectionManager::NewL |
|
32 // ---------------------------------------------------------------------------- |
|
33 // |
|
34 EXPORT_C CRsfwConnectionManager* CRsfwConnectionManager::NewL( |
|
35 MRsfwConnectionObserver* aConnectionObserver) |
|
36 { |
|
37 DEBUGSTRING(("CRsfwConnectionManager::NewL")); |
|
38 CRsfwConnectionManager* self = new (ELeave) CRsfwConnectionManager(); |
|
39 CleanupStack::PushL(self); |
|
40 self->ConstructL(aConnectionObserver); |
|
41 CleanupStack::Pop(self); |
|
42 return self; |
|
43 } |
|
44 |
|
45 // ---------------------------------------------------------------------------- |
|
46 // CRsfwConnectionManager::CRsfwConnectionManager |
|
47 // ---------------------------------------------------------------------------- |
|
48 // |
|
49 CRsfwConnectionManager::CRsfwConnectionManager() |
|
50 : CActive( EPriorityStandard ) |
|
51 { |
|
52 } |
|
53 |
|
54 // ---------------------------------------------------------------------------- |
|
55 // CRsfwConnectionManager::ConstructL |
|
56 // ---------------------------------------------------------------------------- |
|
57 // |
|
58 void CRsfwConnectionManager::ConstructL( |
|
59 MRsfwConnectionObserver* aConnectionObserver) |
|
60 { |
|
61 DEBUGSTRING(("CRsfwConnectionManager::ConstructL")); |
|
62 iConnectionObserver = aConnectionObserver; |
|
63 // Connect to the socket server |
|
64 User::LeaveIfError(iSocketServ.Connect()); |
|
65 // Add this to active scheduler |
|
66 CActiveScheduler::Add( this ); |
|
67 |
|
68 iSuspensionTimer = CPeriodic::NewL(CActive::EPriorityLow); |
|
69 } |
|
70 |
|
71 // ---------------------------------------------------------------------------- |
|
72 // CRsfwConnectionManager::~CRsfwConnectionManager |
|
73 // ---------------------------------------------------------------------------- |
|
74 // |
|
75 EXPORT_C CRsfwConnectionManager::~CRsfwConnectionManager() |
|
76 { |
|
77 DEBUGSTRING(("CRsfwConnectionManager::~CRsfwConnectionManager")); |
|
78 Cancel(); |
|
79 iConnection.Close(); |
|
80 iSocketServ.Close(); |
|
81 iIaps.Close(); |
|
82 |
|
83 StopSuspensionTimer(); |
|
84 delete iSuspensionTimer; |
|
85 } |
|
86 |
|
87 // ---------------------------------------------------------------------------- |
|
88 // CRsfwConnectionManager::UseIapL |
|
89 // ---------------------------------------------------------------------------- |
|
90 // |
|
91 EXPORT_C void CRsfwConnectionManager::UseIapL(const TDesC& aIap) |
|
92 { |
|
93 // aIap may contain an IAP name or an IAP Id (or '?'/'*') |
|
94 DEBUGSTRING(("IAP: %S", &aIap)); |
|
95 |
|
96 // Determine IAP selection policy |
|
97 // By default, ask the user |
|
98 iIapSelection = ERsfwIapSelectionAskUser; |
|
99 if (aIap.CompareF(KIapDefaultPreferences) == 0) |
|
100 { |
|
101 // Use static CommDB preferences |
|
102 iIapSelection = ERsfwIapSelectionUseDefaultPreferences; |
|
103 } |
|
104 else if (aIap.CompareF(KIapAskUser) == 0) |
|
105 { |
|
106 // Ask the user |
|
107 } |
|
108 else |
|
109 { |
|
110 // Build a table of acceptable IAPs. |
|
111 // Now the table only contains one entry |
|
112 TIapInfo iapInfo; |
|
113 iapInfo.iId = 0; |
|
114 iapInfo.iName.SetLength(0); |
|
115 // try to retrieve ID or name based on aIap |
|
116 TLex iapLex(aIap); |
|
117 TInt err = iapLex.Val(iapInfo.iId, EDecimal); |
|
118 if (err != KErrNone) |
|
119 { |
|
120 // The IAP name was given |
|
121 iapInfo.iName.Copy(aIap); |
|
122 } |
|
123 if (LoadIapInfoL(iapInfo) == KErrNone) |
|
124 { |
|
125 iIaps.Append(iapInfo); |
|
126 iIapSelection = ERsfwIapSelectionExplicit; |
|
127 } |
|
128 } |
|
129 } |
|
130 |
|
131 // ---------------------------------------------------------------------------- |
|
132 // CRsfwConnectionManager::GetConnection |
|
133 // ---------------------------------------------------------------------------- |
|
134 // |
|
135 EXPORT_C TInt CRsfwConnectionManager::GetConnection(RSocketServ*& aSocketServ, |
|
136 RConnection*& aConnection) |
|
137 { |
|
138 DEBUGSTRING(("Get connection")); |
|
139 TInt err = iConnection.Open(iSocketServ); |
|
140 if (err == KErrNone) |
|
141 { |
|
142 TUint32 iapId = 0; |
|
143 TCommDbDialogPref dialogPreference = ECommDbDialogPrefDoNotPrompt; |
|
144 switch (iIapSelection) |
|
145 { |
|
146 case ERsfwIapSelectionAskUser: |
|
147 iapId = 0; |
|
148 dialogPreference = ECommDbDialogPrefPrompt; |
|
149 break; |
|
150 |
|
151 case ERsfwIapSelectionUseDefaultPreferences: |
|
152 break; |
|
153 |
|
154 case ERsfwIapSelectionExplicit: |
|
155 iapId = iIaps[0].iId; |
|
156 dialogPreference = ECommDbDialogPrefDoNotPrompt; |
|
157 break; |
|
158 |
|
159 default: |
|
160 break; |
|
161 } |
|
162 |
|
163 err = StartConnection(iapId, dialogPreference); |
|
164 if (err == KErrNone) |
|
165 { |
|
166 aSocketServ = &iSocketServ; |
|
167 aConnection = &iConnection; |
|
168 } |
|
169 } |
|
170 DEBUGSTRING(("Get connection returning %d", err)); |
|
171 return err; |
|
172 } |
|
173 |
|
174 // ---------------------------------------------------------------------------- |
|
175 // CRsfwConnectionManager::LoadIapInfoL |
|
176 // ---------------------------------------------------------------------------- |
|
177 // |
|
178 TInt CRsfwConnectionManager::LoadIapInfoL(TIapInfo& aIapInfo) |
|
179 { |
|
180 DEBUGSTRING(("CRsfwConnectionManager::LoadIapInfoL")); |
|
181 // Fetch CommDB data for a matching IAP Id or IAP Name |
|
182 CCommsDatabase* commsDb = CCommsDatabase::NewL(); |
|
183 CleanupStack::PushL(commsDb); |
|
184 CCommsDbTableView* table; |
|
185 if (aIapInfo.iId) |
|
186 { |
|
187 table = commsDb->OpenViewMatchingUintLC(TPtrC(IAP), |
|
188 TPtrC(COMMDB_ID), |
|
189 aIapInfo.iId); |
|
190 } |
|
191 else |
|
192 { |
|
193 table = commsDb->OpenViewMatchingTextLC(TPtrC(IAP), |
|
194 TPtrC(COMMDB_NAME), |
|
195 aIapInfo.iName); |
|
196 } |
|
197 TInt err = table->GotoFirstRecord(); |
|
198 if (err != KErrNone) |
|
199 { |
|
200 DEBUGSTRING16(("Could not find IAP '%S' (id=%d)!", |
|
201 &aIapInfo.iName, |
|
202 aIapInfo.iId)); |
|
203 CleanupStack::PopAndDestroy(2, commsDb); // table, commsDb |
|
204 return KErrNotFound; |
|
205 } |
|
206 |
|
207 // Read IAP information |
|
208 table->ReadUintL(TPtrC(COMMDB_ID), aIapInfo.iId); |
|
209 table->ReadTextL(TPtrC(COMMDB_NAME), aIapInfo.iName); |
|
210 table->ReadTextL(TPtrC(IAP_BEARER_TYPE), aIapInfo.iBearerType); |
|
211 TBuf<KCommsDbSvrMaxColumnNameLength> serviceType; |
|
212 table->ReadTextL(TPtrC(IAP_SERVICE_TYPE), serviceType); |
|
213 TUint32 service; |
|
214 table->ReadUintL(TPtrC(IAP_SERVICE), service); |
|
215 // Find out the network |
|
216 TUint32 networkId; |
|
217 table->ReadUintL(TPtrC(IAP_NETWORK), networkId); |
|
218 CleanupStack::PopAndDestroy(table); // table |
|
219 |
|
220 table = commsDb->OpenViewMatchingUintLC(TPtrC(NETWORK), |
|
221 TPtrC(COMMDB_ID), |
|
222 networkId); |
|
223 err = table->GotoFirstRecord(); |
|
224 if (err == KErrNone) |
|
225 { |
|
226 table->ReadTextL(TPtrC(COMMDB_NAME), aIapInfo.iNetworkName); |
|
227 } |
|
228 else |
|
229 { |
|
230 DEBUGSTRING(("Could not find network for the IAP!")); |
|
231 } |
|
232 CleanupStack::PopAndDestroy(table); // table |
|
233 |
|
234 aIapInfo.iServiceName.Zero(); |
|
235 aIapInfo.iSsId.Zero(); |
|
236 |
|
237 CleanupStack::PopAndDestroy(commsDb); // commsDb |
|
238 |
|
239 |
|
240 aIapInfo.iBearerQuality = ERsfwConnectionQualityStrong; |
|
241 |
|
242 DEBUGSTRING16(("found IAP %S: id=%d, servicetype=%S, service=%d, network=%S, servicename=%S, ssid=%S, bearer=%S, quality=%d", |
|
243 &aIapInfo.iName, |
|
244 aIapInfo.iId, |
|
245 &serviceType, |
|
246 service, |
|
247 &aIapInfo.iNetworkName, |
|
248 &aIapInfo.iServiceName, |
|
249 &aIapInfo.iSsId, |
|
250 &aIapInfo.iBearerType, |
|
251 aIapInfo.iBearerQuality)); |
|
252 |
|
253 return KErrNone; |
|
254 } |
|
255 |
|
256 // ---------------------------------------------------------------------------- |
|
257 // CRsfwConnectionManager::StartConnection |
|
258 // ---------------------------------------------------------------------------- |
|
259 // |
|
260 TInt CRsfwConnectionManager::StartConnection(TUint32 aIapId, |
|
261 TCommDbDialogPref aDialogPreference) |
|
262 { |
|
263 DEBUGSTRING(("CRsfwConnectionManager::StartConnection with id %d", &aIapId)); |
|
264 TCommDbConnPref connectionPref; |
|
265 connectionPref.SetIapId(aIapId); |
|
266 connectionPref.SetDialogPreference(aDialogPreference); |
|
267 connectionPref.SetDirection(ECommDbConnectionDirectionOutgoing); |
|
268 DEBUGSTRING(("Starting connection to IAP %d with pref %d", |
|
269 aIapId, |
|
270 aDialogPreference)); |
|
271 TInt err = iConnection.Start(connectionPref); |
|
272 DEBUGSTRING(("Connection starting returned %d", err)); |
|
273 // start observing the connection, any events will occur in RunL() function |
|
274 if ( !IsActive() ) |
|
275 { |
|
276 iConnection.ProgressNotification(iProgress, iStatus); |
|
277 SetActive(); |
|
278 } |
|
279 else |
|
280 { |
|
281 DEBUGSTRING(("StartConnection called twice!")); |
|
282 err = KErrGeneral; |
|
283 } |
|
284 return err; |
|
285 } |
|
286 |
|
287 // ---------------------------------------------------------------------------- |
|
288 // CRsfwConnectionManager::HandleDisconnectionEventL |
|
289 // ---------------------------------------------------------------------------- |
|
290 // |
|
291 void CRsfwConnectionManager::HandleDisconnectionEventL() |
|
292 { |
|
293 DEBUGSTRING(("CRsfwConnectionManager::HandleDisconnectionEventL")); |
|
294 if (iConnectionObserver) |
|
295 { |
|
296 iConnectionObserver->HandleConnectionEventL( |
|
297 ERsfwConnectionObserverEventConnectionDisconnected, |
|
298 NULL); |
|
299 } |
|
300 } |
|
301 |
|
302 // ---------------------------------------------------------------------------- |
|
303 // CRsfwConnectionManager::StartSuspensionTimer |
|
304 // ---------------------------------------------------------------------------- |
|
305 // |
|
306 void CRsfwConnectionManager::StartSuspensionTimer() |
|
307 { |
|
308 DEBUGSTRING(("CRsfwConnectionManager::StartSuspensionTimer")); |
|
309 if (iSuspensionTimer) |
|
310 { |
|
311 const TInt KRsfwGPRSSuspensionTimeout = 60 * 1000000; // 60 sec |
|
312 |
|
313 DEBUGSTRING(("GPRS suspension timer started (%d us)", |
|
314 KRsfwGPRSSuspensionTimeout)); |
|
315 iSuspensionTimer->Cancel(); |
|
316 TCallBack callBack(CRsfwConnectionManager::SuspensionTimerExpiredL, this); |
|
317 iSuspensionTimer->Start(KRsfwGPRSSuspensionTimeout, |
|
318 KRsfwGPRSSuspensionTimeout, |
|
319 callBack); |
|
320 } |
|
321 } |
|
322 |
|
323 // ---------------------------------------------------------------------------- |
|
324 // CRsfwConnectionManager::StopSuspensionTimer |
|
325 // ---------------------------------------------------------------------------- |
|
326 // |
|
327 void CRsfwConnectionManager::StopSuspensionTimer() |
|
328 { |
|
329 DEBUGSTRING(("CRsfwConnectionManager::StopSuspensionTimer")); |
|
330 if (iSuspensionTimer) |
|
331 { |
|
332 DEBUGSTRING(("GPRS suspension timer stopped")); |
|
333 iSuspensionTimer->Cancel(); |
|
334 } |
|
335 } |
|
336 |
|
337 // ---------------------------------------------------------------------------- |
|
338 // CRsfwConnectionManager::SuspensionTimerExpired |
|
339 // ---------------------------------------------------------------------------- |
|
340 // |
|
341 TInt CRsfwConnectionManager::SuspensionTimerExpiredL(TAny* aArg) |
|
342 { |
|
343 DEBUGSTRING(("GPRS suspension timer expired")); |
|
344 CRsfwConnectionManager* connMan = static_cast<CRsfwConnectionManager*>(aArg); |
|
345 connMan->StopSuspensionTimer(); |
|
346 connMan->HandleDisconnectionEventL(); |
|
347 return KErrNone; |
|
348 } |
|
349 |
|
350 // ---------------------------------------------------------------------------- |
|
351 // CRsfwConnectionManager::RunL |
|
352 // ---------------------------------------------------------------------------- |
|
353 // |
|
354 void CRsfwConnectionManager::RunL() |
|
355 { |
|
356 TInt status = iStatus.Int(); |
|
357 DEBUGSTRING(("CRsfwConnectionManager::RunL %d", &status)); |
|
358 TInt stage = iProgress().iStage; |
|
359 TInt error = iProgress().iError; |
|
360 DEBUGSTRING(("ConnectionManager::RunL - status: %d, stage: %d, error: %d", status, stage, error)); |
|
361 |
|
362 if ( error == KErrConnectionTerminated || error == KErrDisconnected |
|
363 || stage == KLinkLayerClosed || stage == KConnectionClosed ) |
|
364 { |
|
365 // KErrDisconnected occurs if WLAN goes out of range |
|
366 // KErrConnectionTerminated occurs if user cancels connection from "Active connections" menu |
|
367 // stage values KLinkLayerClosed & KConnectionClosed should be generated by GPRS |
|
368 // (however GPRS usually generates KDataTransferTemporarilyBlocked event) |
|
369 HandleDisconnectionEventL(); |
|
370 } |
|
371 else if ( stage == KDataTransferTemporarilyBlocked ) |
|
372 { |
|
373 // KDataTransferTemporarilyBlocked means GPRS 'suspend' event |
|
374 // start timer, when it expires we will disconnect |
|
375 StartSuspensionTimer(); |
|
376 } |
|
377 else if ( stage == KLinkLayerOpen ) |
|
378 { |
|
379 // KLinkLayerOpen may mean GPRS 'resume' event |
|
380 StopSuspensionTimer(); |
|
381 } |
|
382 else |
|
383 { |
|
384 // ignore the event |
|
385 } |
|
386 |
|
387 // request new events if necessary |
|
388 iConnection.ProgressNotification(iProgress, iStatus, KConnProgressDefault); |
|
389 SetActive(); |
|
390 } |
|
391 |
|
392 // ---------------------------------------------------------------------------- |
|
393 // CRsfwConnectionManager::RunError |
|
394 // ---------------------------------------------------------------------------- |
|
395 // |
|
396 #ifdef _DEBUG |
|
397 TInt CRsfwConnectionManager::RunError(TInt aError) |
|
398 #else |
|
399 TInt CRsfwConnectionManager::RunError(TInt /*aError*/) |
|
400 #endif |
|
401 { |
|
402 DEBUGSTRING(("ConnectionManager::RunErrorL - error: %d", aError)); |
|
403 return KErrNone; |
|
404 } |
|
405 |
|
406 // ---------------------------------------------------------------------------- |
|
407 // CRsfwConnectionManager::DoCancel |
|
408 // ---------------------------------------------------------------------------- |
|
409 // |
|
410 void CRsfwConnectionManager::DoCancel() |
|
411 { |
|
412 DEBUGSTRING(("CRsfwConnectionManager::::DoCancel()")); |
|
413 //cancel request issued by ProgressNotification() |
|
414 iConnection.CancelProgressNotification(); |
|
415 } |
|
416 // End of File |