|
1 // Copyright (c) 2001-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 #include "CSimPhone.h" |
|
17 #include "CSimDataCall.h" |
|
18 #include "Simlog.h" |
|
19 #include "et_struct.h" |
|
20 |
|
21 _LIT(KCommonCallName,"DataCall%d"); // < Data call name template. |
|
22 const TInt KCallListGranularity=2; // < The granularity of the call list array. |
|
23 |
|
24 /** |
|
25 * @file |
|
26 * |
|
27 * This file contains the implementation of the Similator TSY Data line functionality. |
|
28 * The line classes process the line-based requests made by ETel clients |
|
29 * and passed down to the TSY by the ETel Server. |
|
30 */ |
|
31 |
|
32 CSimDataLine* CSimDataLine::NewL(CSimPhone* aPhone,const TDesC& aName) |
|
33 /** |
|
34 * Standard two phase constructor. |
|
35 * |
|
36 * @param aPhone pointer to the phone object. |
|
37 * @param aName name of the line to be constructed |
|
38 * @return CSimDataLine pointer to the voice line object created |
|
39 * @leave Leaves if no memory or object is not created for any reason |
|
40 */ |
|
41 { |
|
42 CSimDataLine* dataLine=new(ELeave) CSimDataLine(aPhone); |
|
43 TCleanupItem newLineDataClose(CloseLine,dataLine); |
|
44 CleanupStack::PushL(newLineDataClose); |
|
45 dataLine->ConstructL(aName); |
|
46 CleanupStack::Pop(); |
|
47 return dataLine; |
|
48 } |
|
49 |
|
50 CSimDataLine::CSimDataLine(CSimPhone* aPhone) |
|
51 :CSimLine(aPhone) |
|
52 /** |
|
53 * Trivial constructor. Calls CSimLine to initialise its members |
|
54 */ |
|
55 { |
|
56 iICProperty.iCategory = KUidPSSimTsyCategory; |
|
57 iICProperty.iKey = KPSSimTsyIncomingDataCall; |
|
58 iICProperty.iType = KPSSimTsyIncomingDataCallKeyType; |
|
59 |
|
60 iRHProperty.iCategory = KUidPSSimTsyCategory; |
|
61 iRHProperty.iKey = KPSSimTsyRemoteHangup; |
|
62 iRHProperty.iType = KPSSimTsyRemoteHangupKeyType; |
|
63 } |
|
64 |
|
65 void CSimDataLine::ConstructL(const TName& aName) |
|
66 /** |
|
67 * Pre-allocate a pool of data calls and allocate one to be the default to |
|
68 * contain information about an incoming call. |
|
69 * |
|
70 * @param aName name of the voice line to be constructed |
|
71 */ |
|
72 { |
|
73 iCaps=Caps(); |
|
74 CSimLine::ConstructL(aName); |
|
75 iCalls=new(ELeave) CArrayFixFlat<CSimCall*>(KCallListGranularity); |
|
76 TName callName; |
|
77 iSpareCall=CreateNewCallL(callName,ECallTypeSpareCall); |
|
78 iAnswerNextIncomingCall=iSpareCall; |
|
79 } |
|
80 |
|
81 CSimDataLine::~CSimDataLine() |
|
82 /** |
|
83 * Destroy the spare call - all the others will be closed by the client (or server). |
|
84 */ |
|
85 { |
|
86 if ((iAnswerNextIncomingCall!=iSpareCall) && (iAnswerNextIncomingCall)) |
|
87 { |
|
88 iAnswerNextIncomingCall->Close(); |
|
89 } |
|
90 if(iSpareCall) |
|
91 { |
|
92 iSpareCall->Close(); |
|
93 } |
|
94 if(iCalls) |
|
95 { |
|
96 iCalls->Delete(0,iCalls->Count()); |
|
97 delete iCalls; |
|
98 } |
|
99 } |
|
100 |
|
101 CTelObject* CSimDataLine::OpenNewObjectByNameL(const TDesC& aName) |
|
102 /** |
|
103 * Opens a data call by name. |
|
104 * This will be called if the user opens a pre-alloc'ed call by name. |
|
105 * |
|
106 * @param aName name of call to be opened |
|
107 * @return CTelObject pointer to the object opened by name |
|
108 * @leave Leaves if name given does not match the required name |
|
109 */ |
|
110 { |
|
111 LOGDATA1(">>CSimDataLine::OpenNewObjectByNameL"); |
|
112 TInt i; |
|
113 for(i=0;i<iCalls->Count();i++) |
|
114 { |
|
115 if(iCalls->At(i)->iName.MatchF(aName)==0) |
|
116 { |
|
117 (void)iCalls->At(i)->Open(); |
|
118 return iCalls->At(i); |
|
119 } |
|
120 } |
|
121 LOGDATA1("<<CSimDataLine::OpenNewObjectByNameL"); |
|
122 User::Leave(KErrNotFound); |
|
123 return NULL; |
|
124 } |
|
125 |
|
126 CTelObject* CSimDataLine::OpenNewObjectL(TDes& aNewName) |
|
127 /** |
|
128 * Open a data call and return a name. |
|
129 * This function creates a new call object and returns its pointer. |
|
130 * |
|
131 * @param aNewName name of call to be opened |
|
132 * @return CTelObject pointer to the object allocated |
|
133 * @leave Leaves if no memory available |
|
134 */ |
|
135 { |
|
136 return CreateNewCallL(aNewName,ECallTypeNormalCall); |
|
137 } |
|
138 |
|
139 CSimCall* CSimDataLine::CreateNewCallL(TDes& aNewName,TCallType aCallType) |
|
140 { |
|
141 aNewName.Format(KCommonCallName,iCallCnt++); |
|
142 CSimDataCall* newCall=CSimDataCall::NewL(this,aNewName,iPhone); |
|
143 CleanupStack::PushL(newCall); |
|
144 iCalls->AppendL(newCall); |
|
145 if(aCallType!=ECallTypeSpareCall) |
|
146 { |
|
147 HandleNewCallAddedNotification(aNewName); |
|
148 } |
|
149 iNameOfLastCallAdded.Copy(aNewName); |
|
150 LOGDATA2(">>CSimDataLine::CreateNewCallL 0x%08x",newCall); |
|
151 CleanupStack::Pop(newCall); |
|
152 return newCall; |
|
153 } |
|
154 |
|
155 TInt CSimDataLine::ExtFunc(const TTsyReqHandle aTsyReqHandle,const TInt aIpc,const TDataPackage& aPackage) |
|
156 /** |
|
157 * ExtFunc is called by the server when it has a "extended", i.e. non-core ETel request |
|
158 * for the TSY to process |
|
159 * A request handle, request type and request data are passed to the TSY |
|
160 * |
|
161 * @param aTsyReqHandle |
|
162 * @param aIpc IPc number representing the request |
|
163 * @param aPackage data for the request |
|
164 * @return Symbian system wide error code. |
|
165 */ |
|
166 { |
|
167 |
|
168 TAny* dataPtr=aPackage.Ptr1(); |
|
169 |
|
170 // The request data has to extracted from TDataPackage and the TAny* pointers have to |
|
171 // be "cast" to the expected request data type |
|
172 |
|
173 switch (aIpc) |
|
174 { |
|
175 // |
|
176 // No Flow Control OR Multiple Completion |
|
177 // |
|
178 case EMobileLineGetMobileLineStatus: |
|
179 return GetMobileLineStatus(aTsyReqHandle, |
|
180 REINTERPRET_CAST(RMobileCall::TMobileCallStatus*,dataPtr)); |
|
181 |
|
182 // |
|
183 // Multiple Completion Services with Immediate Server Repost |
|
184 // (Usually Notifications) |
|
185 // |
|
186 case EMobileLineNotifyMobileLineStatusChange: |
|
187 return NotifyMobileLineStatusChange(aTsyReqHandle, |
|
188 REINTERPRET_CAST(RMobileCall::TMobileCallStatus*, dataPtr)); |
|
189 |
|
190 default: |
|
191 return KErrNotSupported; |
|
192 } |
|
193 } |
|
194 |
|
195 TInt CSimDataLine::CancelService(const TInt aIpc,const TTsyReqHandle aTsyReqHandle) |
|
196 /** |
|
197 * Cancel an outstanding request. |
|
198 * @param aIpc The IPC number of the request that must be cancelled. Note: this is not the |
|
199 * IPC number of the cancel request itself. |
|
200 * @param aTsyReqHandle The TSY Request Handle of the request to be cancelled. |
|
201 */ |
|
202 { |
|
203 switch(aIpc) |
|
204 { |
|
205 case EEtelLineNotifyStatusChange: |
|
206 return NotifyStatusChangeCancel(aTsyReqHandle); |
|
207 |
|
208 case EEtelLineNotifyIncomingCall: |
|
209 return NotifyIncomingCallCancel(aTsyReqHandle); |
|
210 |
|
211 case EEtelLineNotifyHookChange: |
|
212 return NotifyHookChangeCancel(aTsyReqHandle); |
|
213 |
|
214 case EEtelLineNotifyCallAdded: |
|
215 return NotifyCallAddedCancel(aTsyReqHandle); |
|
216 |
|
217 case EMobileLineNotifyMobileLineStatusChange: |
|
218 return NotifyMobileLineStatusChangeCancel(aTsyReqHandle); |
|
219 |
|
220 default: |
|
221 LOGDATA1("CSimDataLine::CancelService: No IPC match in SIM TSY, defering to core cancelservice function."); |
|
222 break; |
|
223 } |
|
224 |
|
225 return CLineBase::CancelService(aIpc,aTsyReqHandle); |
|
226 } |
|
227 |
|
228 TInt CSimDataLine::EnumerateCall(const TTsyReqHandle aTsyReqHandle,TInt* aParams) |
|
229 /** |
|
230 * Count and return the number of data calls used. |
|
231 * |
|
232 * @param aTsyReqHandle |
|
233 * @return KErrNone |
|
234 * @param aParams pointer to the number of calls used |
|
235 */ |
|
236 { |
|
237 *aParams=iCalls->Count(); |
|
238 ReqCompleted(aTsyReqHandle,KErrNone); |
|
239 return KErrNone; |
|
240 } |
|
241 |
|
242 TInt CSimDataLine::GetCallInfo(const TTsyReqHandle aTsyReqHandle,TCallInfoIndex* aCallInfoIndex) |
|
243 /** |
|
244 * Retrieve the Call Information relevant to the numbered call. |
|
245 * Returns the name, the current call status and the call capabilities |
|
246 * TCallInfoIndex specifies which call info is requested. |
|
247 * |
|
248 * @param aTsyReqHandle |
|
249 * @param aCallInfoIndex pointer to the call info |
|
250 * @return KErrNone |
|
251 */ |
|
252 { |
|
253 TInt& i=aCallInfoIndex->iIndex; |
|
254 if((i<0)||(i>iCalls->Count())) |
|
255 { |
|
256 ReqCompleted(aTsyReqHandle,KErrArgument); |
|
257 return KErrNone; |
|
258 } |
|
259 |
|
260 aCallInfoIndex->iInfo.iCallName.Copy(iCalls->At(i)->iName); |
|
261 aCallInfoIndex->iInfo.iStatus=(RCall::TStatus)iCalls->At(i)->iState; |
|
262 aCallInfoIndex->iInfo.iCallCapsFlags=iCalls->At(i)->Caps(); |
|
263 ReqCompleted(aTsyReqHandle,KErrNone); |
|
264 return KErrNone; |
|
265 } |
|
266 |
|
267 TUint CSimDataLine::Caps() |
|
268 /** |
|
269 * Return the current capabilities of this line. |
|
270 * @return TUint Current line capabilities. |
|
271 */ |
|
272 { |
|
273 TUint caps=RLine::KCapsData; |
|
274 if(iState==RMobileCall::EStatusIdle) |
|
275 caps|=RLine::KCapsEventIncomingCall; |
|
276 return caps; |
|
277 } |
|
278 |
|
279 TInt CSimDataLine::FindActiveCall(CSimCall*& aCall) |
|
280 /** |
|
281 * Find an active voice call. Return KErrNotFound if no voice calls active. |
|
282 * @param aCall Pointer to active voice call. |
|
283 * @return TInt Standard return error. |
|
284 */ |
|
285 { |
|
286 TInt i; |
|
287 for(i=0;i<iCalls->Count();i++) |
|
288 { |
|
289 if(iCalls->At(i)->iState==RMobileCall::EStatusConnected) |
|
290 { |
|
291 aCall=(CSimDataCall*)iCalls->At(i); |
|
292 return KErrNone; |
|
293 } |
|
294 } |
|
295 return KErrNotFound; |
|
296 } |