|
1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 /** |
|
17 @file |
|
18 @internalComponent |
|
19 */ |
|
20 |
|
21 #include "mbmsengine.h" |
|
22 #include "pdpservices.h" |
|
23 #include <commsdattypesv1_1.h> |
|
24 |
|
25 using namespace ESock; |
|
26 using namespace ConnectionServ; |
|
27 using namespace CommsDat; |
|
28 using namespace Messages; |
|
29 |
|
30 //This function retrieves the phone information. |
|
31 void GetPhoneInfoL(RTelServer& aTelServer, const TDesC& aLoadedTsyName, RTelServer::TPhoneInfo& aInfo); |
|
32 |
|
33 //Constructor for CMBMSEngine |
|
34 CMBMSEngine::CMBMSEngine(const TNodeId& aMbmsTMCommsId, MPacketServiceNotifier& aPacketServiceNotifier) |
|
35 :CActive(EPriorityStandard), |
|
36 iMbmsTMCommsId(aMbmsTMCommsId), |
|
37 iPacketServiceNotifier(aPacketServiceNotifier) |
|
38 { |
|
39 CActiveScheduler::Add(this); |
|
40 } |
|
41 |
|
42 /** |
|
43 The NewL factory function for CMBMSEngine. |
|
44 @param aMBMSTMCommsId comms Id. |
|
45 @param aClientId Node Channel Id. |
|
46 @param aRequestType Message Id |
|
47 @param aRequestBundleOwner Parameter Bundle. |
|
48 @return CMBMSEngine* |
|
49 */ |
|
50 CMBMSEngine* CMBMSEngine::NewL(const TNodeId& aMbmsTMCommsId, MPacketServiceNotifier& aPacketServiceNotifier) |
|
51 { |
|
52 CMBMSEngine* self = new(ELeave) CMBMSEngine(aMbmsTMCommsId, aPacketServiceNotifier); |
|
53 CleanupStack::PushL(self); |
|
54 self->ConstructL(); |
|
55 CleanupStack::Pop(self); |
|
56 return self; |
|
57 } |
|
58 |
|
59 /** |
|
60 Destructor for CMBMSEngine. |
|
61 */ |
|
62 CMBMSEngine::~CMBMSEngine() |
|
63 { |
|
64 iPacketService.Close(); |
|
65 iPhone.Close(); |
|
66 iTelServer.Close(); |
|
67 |
|
68 iMBMSRequestList.ResetAndDestroy(); |
|
69 } |
|
70 /** |
|
71 ConstructL for CMBMSEngine. |
|
72 */ |
|
73 void CMBMSEngine::ConstructL() |
|
74 { |
|
75 InitialisePhoneL(); |
|
76 iPendingRequests = EFalse; |
|
77 } |
|
78 /** |
|
79 This function is used to find the MBMS request from the list based on the client Id. |
|
80 @param aClientId The reference to TCFNodeChannelId |
|
81 @return TUint |
|
82 */ |
|
83 TUint CMBMSEngine::GetRequestElementL(const TRuntimeCtxId& aNodeCtxId) |
|
84 { |
|
85 TBool findMBMSRequest = EFalse; |
|
86 TInt index = 0; |
|
87 for (;index < iMBMSRequestList.Count(); index++) |
|
88 { |
|
89 if(aNodeCtxId == iMBMSRequestList[index]->GetClientId()) |
|
90 { |
|
91 findMBMSRequest = ETrue; |
|
92 break; |
|
93 } |
|
94 } |
|
95 if(!findMBMSRequest) |
|
96 User::Leave(KErrNotFound); |
|
97 |
|
98 return index; |
|
99 } |
|
100 |
|
101 /** |
|
102 This function is used to remove requests from the list. |
|
103 @param aClientId The reference to TCFNodeChannelId |
|
104 @return void |
|
105 */ |
|
106 void CMBMSEngine::RemoveFromRequestListL(const Messages::TRuntimeCtxId& aNodeCtxId) |
|
107 { |
|
108 TUint index = GetRequestElementL(aNodeCtxId); |
|
109 DeleteIndexElement(index); |
|
110 } |
|
111 /** |
|
112 This function is used to delete the request object fron the indexed list. |
|
113 @param aIndex TUint |
|
114 @return void |
|
115 */ |
|
116 void CMBMSEngine::DeleteIndexElement(TUint aIndex) |
|
117 { |
|
118 delete iMBMSRequestList[aIndex]; |
|
119 iMBMSRequestList[aIndex] = NULL; |
|
120 iMBMSRequestList.Remove(aIndex); |
|
121 iMBMSRequestList.Compress(); |
|
122 |
|
123 //check for any pending requests |
|
124 CheckPendingRequests(); |
|
125 } |
|
126 |
|
127 /** |
|
128 This function is used to cancel any outstanding request and remove it from the list. |
|
129 @param aClientId The reference to TCFNodeChannelId |
|
130 @return void |
|
131 */ |
|
132 void CMBMSEngine::CancelAndRemoveFromRequestListL(const Messages::TRuntimeCtxId& aNodeCtxId) |
|
133 { |
|
134 TUint index = GetRequestElementL(aNodeCtxId); |
|
135 iMBMSRequestList[index]->CancelMessage(KErrCancel); |
|
136 DeleteIndexElement(index); |
|
137 } |
|
138 |
|
139 /** |
|
140 This function is used to check whether any outstanding requests are there or not. |
|
141 In case if any outstanding requests are there,active the requests at the head of the list. |
|
142 @return void |
|
143 */ |
|
144 void CMBMSEngine::CheckPendingRequests() |
|
145 { |
|
146 if((iMBMSRequestList.Count() > 0) && (!iMBMSRequestList[0]->IsActive())) |
|
147 { |
|
148 //activate the requests at the head of the list. |
|
149 iMBMSRequestList[0]->StartRequest(); |
|
150 } |
|
151 } |
|
152 |
|
153 /** |
|
154 This function is used to check whether the MBMS query is valid or not.If valid, |
|
155 create an object of CMBMSServiceRequest and store in a list for later use. |
|
156 @param aCFMessage The reference to Messages::TSignatureBase |
|
157 @return void |
|
158 */ |
|
159 void CMBMSEngine::AddToRequestListL( |
|
160 Messages::RNodeInterface* aNodeInterface, |
|
161 const Messages::TRuntimeCtxId& aNodeCtxId, |
|
162 const Messages::TNodeSignal::TMessageId& aRequestType, |
|
163 CRefCountOwnedParameterBundle* aRequestBundleOwner |
|
164 ) |
|
165 { |
|
166 TUint mbmsQueryCount = 0; |
|
167 //the below enums are initialised to EBearerAvailability to avoid Armv5 warnings. |
|
168 XMBMSServiceQuerySet::TQueryType previousQuery = XMBMSServiceQuerySet::EBearerAvailability ; |
|
169 XMBMSServiceQuerySet::TQueryType currentQuery = XMBMSServiceQuerySet::EBearerAvailability; |
|
170 |
|
171 const ConnectionServ::CConnectionServParameterBundle* mbmsParamsBundle1 = static_cast<const CConnectionServParameterBundle*>(aRequestBundleOwner->Ptr()); |
|
172 if(!mbmsParamsBundle1) |
|
173 User::Leave(KErrNotFound); |
|
174 |
|
175 ConnectionServ::CConnectionServParameterBundle* mbmsParamsBundle = const_cast<CConnectionServParameterBundle *>(mbmsParamsBundle1); |
|
176 |
|
177 //get the cout of Containers |
|
178 TUint containerCount = mbmsParamsBundle->CountParamSetContainers(); |
|
179 |
|
180 //leave if Container is empty |
|
181 if (containerCount == 0) |
|
182 { |
|
183 User::Leave(KErrArgument); |
|
184 } |
|
185 |
|
186 TBool checkMBMSQuery = EFalse; |
|
187 for(TUint i = 0; i < containerCount; i++) |
|
188 { |
|
189 CParameterSetContainer* objectPSC = mbmsParamsBundle->GetParamSetContainer(i); |
|
190 XMBMSServiceQuerySet* queryMBMS = XMBMSServiceQuerySet::FindInParamSetContainer(*objectPSC); |
|
191 |
|
192 //pick only MBMS Query Types. |
|
193 if(!queryMBMS) |
|
194 continue; |
|
195 |
|
196 if(queryMBMS) |
|
197 checkMBMSQuery = ETrue; |
|
198 |
|
199 //leave if there are more than one type of MBMS query in the bundle. |
|
200 currentQuery = queryMBMS->GetQueryType(); |
|
201 //leave if query is not set. |
|
202 if(currentQuery<0) |
|
203 User::Leave(KErrArgument); |
|
204 |
|
205 //check whether the bundle has got only MBMS queries. |
|
206 if(mbmsQueryCount>0) |
|
207 { |
|
208 if(currentQuery != previousQuery) |
|
209 { |
|
210 User::Leave(KErrArgument); |
|
211 } |
|
212 } |
|
213 previousQuery = currentQuery; |
|
214 mbmsQueryCount++; |
|
215 } |
|
216 //leave if no MBMS query found. |
|
217 if(!checkMBMSQuery) |
|
218 User::Leave(KErrArgument); |
|
219 |
|
220 //store the CMBMSServiceRequest in a list. |
|
221 CMBMSServiceRequest* newServiceRequest = CMBMSServiceRequest::NewL( |
|
222 *this, |
|
223 iMbmsTMCommsId, |
|
224 aNodeInterface, |
|
225 aNodeCtxId, |
|
226 aRequestType, |
|
227 aRequestBundleOwner, |
|
228 currentQuery |
|
229 ); |
|
230 CleanupStack::PushL(newServiceRequest); |
|
231 iMBMSRequestList.AppendL(newServiceRequest); |
|
232 CleanupStack::Pop(newServiceRequest); |
|
233 |
|
234 //start the requests if none of the requests are pending. |
|
235 CheckPendingRequests(); |
|
236 } |
|
237 /** |
|
238 Function to initialize the phone settings |
|
239 @return TBool |
|
240 */ |
|
241 TBool CMBMSEngine::InitialisePhoneL() |
|
242 { |
|
243 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
244 CMDBSession* dbSession = CMDBSession::NewL(KCDVersion1_2); |
|
245 #else |
|
246 CMDBSession* dbSession = CMDBSession::NewL(KCDVersion1_1); |
|
247 #endif |
|
248 CleanupStack::PushL(dbSession); |
|
249 |
|
250 CMDBRecordSet<CCDGlobalSettingsRecord> globalSettingsRecord(KCDTIdGlobalSettingsRecord); |
|
251 TRAPD(err, globalSettingsRecord.LoadL(*dbSession)); |
|
252 if(err != KErrNone) |
|
253 { |
|
254 User::Leave(KErrNotFound); |
|
255 } |
|
256 |
|
257 CCDModemBearerRecord *modemBearerRecord = static_cast<CCDModemBearerRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdModemBearerRecord)); |
|
258 CleanupStack::PushL(modemBearerRecord); |
|
259 |
|
260 modemBearerRecord->SetRecordId(((CCDGlobalSettingsRecord*)globalSettingsRecord.iRecords[0])->iModemForPhoneServicesAndSMS); |
|
261 TRAPD(err1,modemBearerRecord->LoadL(*dbSession)); |
|
262 |
|
263 if(err1 != KErrNone) |
|
264 { |
|
265 User::Leave(KErrNotFound); |
|
266 } |
|
267 |
|
268 TName tsyName; |
|
269 tsyName = modemBearerRecord->iTsyName; |
|
270 //leave if not able to read Tsy name. |
|
271 if(tsyName.Length() == 0) |
|
272 { |
|
273 User::Leave(KErrNotFound); |
|
274 } |
|
275 |
|
276 CleanupStack::PopAndDestroy(modemBearerRecord); |
|
277 CleanupStack::PopAndDestroy(dbSession); |
|
278 |
|
279 User::LeaveIfError(iTelServer.Connect()); |
|
280 User::LeaveIfError(iTelServer.LoadPhoneModule(tsyName)); |
|
281 User::LeaveIfError(iTelServer.SetExtendedErrorGranularity(RTelServer::EErrorExtended)); |
|
282 |
|
283 //Open telephony server |
|
284 GetPhoneInfoL(iTelServer,tsyName,iPhoneInfo); |
|
285 |
|
286 //Open phone |
|
287 User::LeaveIfError(iPhone.Open(iTelServer,iPhoneInfo.iName)); |
|
288 //Get phone status |
|
289 iPhone.GetStatus(iPhoneStatus); |
|
290 |
|
291 SetActive(); |
|
292 iPhoneState = EInitialising; |
|
293 |
|
294 TRequestStatus* status = &iStatus; |
|
295 User::RequestComplete(status, KErrNone); |
|
296 |
|
297 return ETrue; |
|
298 } |
|
299 |
|
300 /** |
|
301 This is CActive overloaded function.Cancel all outstanding requests. |
|
302 @param None |
|
303 @return Void |
|
304 */ |
|
305 void CMBMSEngine::DoCancel() |
|
306 { |
|
307 iPhone.InitialiseCancel(); |
|
308 } |
|
309 |
|
310 /** |
|
311 This is CActive overloaded function. |
|
312 @param None |
|
313 @return TInt |
|
314 */ |
|
315 TInt CMBMSEngine::RunError(TInt /*aError*/) |
|
316 { |
|
317 Cancel(); |
|
318 return KErrNone; |
|
319 } |
|
320 |
|
321 /** |
|
322 This is CActive overloaded function. |
|
323 @param None |
|
324 @return Void |
|
325 */ |
|
326 void CMBMSEngine::RunL() |
|
327 { |
|
328 TRequestStatus* status = &iStatus; |
|
329 if (iStatus == KErrNone) |
|
330 { |
|
331 switch(iPhoneState) |
|
332 { |
|
333 case EInitialising: |
|
334 if(iPhoneStatus.iMode==RPhone::EModeUnknown) |
|
335 { |
|
336 iPhone.Initialise(iStatus); |
|
337 } |
|
338 else |
|
339 { |
|
340 User::RequestComplete(status, KErrNone); |
|
341 } |
|
342 SetActive(); |
|
343 iPhoneState = ESetAttachMode; |
|
344 break; |
|
345 case ESetAttachMode: |
|
346 //Open packet service |
|
347 User::LeaveIfError(iPacketService.Open(iPhone)); |
|
348 |
|
349 //Put phone is attachwhenpossible mode. |
|
350 //In this mode, the phone will try to attach to the gprs network whenever it can. |
|
351 iPacketService.SetAttachMode(iStatus, RPacketService::EAttachWhenNeeded); |
|
352 iPhoneState = EAttachModeComplete; |
|
353 SetActive(); |
|
354 break; |
|
355 case EAttachModeComplete: |
|
356 iPacketServiceNotifier.PacketServiceAttachedCallbackL(); |
|
357 break; |
|
358 } |
|
359 } |
|
360 } |
|
361 |
|
362 /** |
|
363 Function to retrieve the RPacketService Instance |
|
364 @return RPacketService& |
|
365 */ |
|
366 RPacketService& CMBMSEngine::GetRPacketService() |
|
367 { |
|
368 return iPacketService; |
|
369 } |