|
1 /* |
|
2 * Copyright (c) 2009 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 the License "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: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 #include "bcatoisc.h" |
|
21 #include "bcatoisctrace.h" |
|
22 #include "iscdefinitions.h" |
|
23 #include <cdbcols.h> |
|
24 |
|
25 using namespace BasebandChannelAdaptation; |
|
26 |
|
27 |
|
28 /** |
|
29 * Default constructor to create a CNotifyFlowControlMonitor instance. |
|
30 */ |
|
31 CNotifyFlowControlMonitor::CNotifyFlowControlMonitor(RIscApi& aIscApi) |
|
32 :CActive(EPriorityStandard), |
|
33 iIscApi(aIscApi) |
|
34 { |
|
35 C_TRACE( (_T("CNotifyFlowControlMonitor::CNotifyFlowControlMonitor RIscAapi 0x%x ->"), &aIscApi ) ); |
|
36 |
|
37 CActiveScheduler::Add(this); |
|
38 |
|
39 C_TRACE( (_T("CNotifyFlowControlMonitor::CNotifyFlowControlMonitor <-") ) ); |
|
40 } |
|
41 |
|
42 void CNotifyFlowControlMonitor::NotifyFlowControlStatus() |
|
43 { |
|
44 C_TRACE( (_T("CNotifyFlowControlMonitor::NotifyFlowControlStatus() ->") ) ); |
|
45 |
|
46 ASSERT(!IsActive()); |
|
47 |
|
48 iFlowControlValue = iIscApi.FlowControlStatus(); |
|
49 |
|
50 C_TRACE( (_T("CNotifyFlowControlMonitor::NotifyFlowControlStatus initial iFlowControlValue %d ->"), iFlowControlValue ) ); |
|
51 |
|
52 iIscApi.NotifyFlowControl(iStatus, iFlowControlValue); |
|
53 SetActive(); |
|
54 |
|
55 C_TRACE( (_T("CNotifyFlowControlMonitor::NotifyFlowControlStatus() <-") ) ); |
|
56 } |
|
57 |
|
58 void CNotifyFlowControlMonitor::RequestFlowcontrolChange( TRequestStatus& aStatus ) |
|
59 { |
|
60 C_TRACE( (_T("CNotifyFlowControlMonitor::RequestFlowcontrolChange ->") ) ); |
|
61 |
|
62 iWriteStatus = &aStatus; |
|
63 *iWriteStatus = KRequestPending; |
|
64 |
|
65 |
|
66 C_TRACE( (_T("CNotifyFlowControlMonitor::RequestFlowcontrolChange <-") ) ); |
|
67 } |
|
68 |
|
69 void CNotifyFlowControlMonitor::RunL() |
|
70 { |
|
71 C_TRACE( (_T("CNotifyFlowControlMonitor::RunL() iStatus %d ->"), iStatus.Int() ) ); |
|
72 |
|
73 iFlowControlValue = iIscApi.FlowControlStatus(); |
|
74 |
|
75 |
|
76 C_TRACE( (_T("CNotifyFlowControlMonitor::RunL flow control Value has changed and is now: (%d)"), iFlowControlValue ) ); |
|
77 |
|
78 if( *iWriteStatus == KRequestPending ) |
|
79 { |
|
80 User::RequestComplete(iWriteStatus, KErrNone); |
|
81 } |
|
82 |
|
83 if( iStatus == KErrNone ) |
|
84 { |
|
85 //Check for further flow control status changes |
|
86 iIscApi.NotifyFlowControl(iStatus, iFlowControlValue); |
|
87 SetActive(); |
|
88 } |
|
89 |
|
90 C_TRACE( (_T("CNotifyFlowControlMonitor::RunL() <-") ) ); |
|
91 } |
|
92 |
|
93 TInt CNotifyFlowControlMonitor::GetFlowControlState() |
|
94 { |
|
95 return iFlowControlValue; |
|
96 } |
|
97 |
|
98 void CNotifyFlowControlMonitor::DoCancel() |
|
99 { |
|
100 C_TRACE( (_T("CNotifyFlowControlMonitor::DoCancel() ->") ) ); |
|
101 |
|
102 iIscApi.NotifyFlowControlCancel(); |
|
103 |
|
104 C_TRACE( (_T("CNotifyFlowControlMonitor::DoCancel() <-") ) ); |
|
105 } |
|
106 |
|
107 CNotifyFlowControlMonitor::~CNotifyFlowControlMonitor() |
|
108 { |
|
109 C_TRACE( (_T("CNotifyFlowControlMonitor::~CNotifyFlowControlMonitor() ->") ) ); |
|
110 |
|
111 Cancel(); |
|
112 |
|
113 C_TRACE( (_T("CNotifyFlowControlMonitor::~CNotifyFlowControlMonitor() <-") ) ); |
|
114 } |
|
115 |
|
116 |
|
117 CNotifyWriteStatusMonitor::CNotifyWriteStatusMonitor( CBcaToIsc& aUser, RIscApi& aIscApi ) |
|
118 :CActive(EPriorityHigh), |
|
119 iUser(aUser), |
|
120 iIscApi(aIscApi) |
|
121 { |
|
122 C_TRACE( (_T("CNotifyWriteStatusMonitor::CNotifyWriteStatusMonitor ->") ) ); |
|
123 // iBuf = new TPtr8( NULL, 0, 0 ); |
|
124 CActiveScheduler::Add(this); |
|
125 C_TRACE( (_T("CNotifyWriteStatusMonitor::CNotifyWriteStatusMonitor <-") ) ); |
|
126 } |
|
127 |
|
128 |
|
129 void CNotifyWriteStatusMonitor::Write( TRequestStatus& aStatus, const TDesC8& aBuf ) |
|
130 { |
|
131 |
|
132 iBuf = &aBuf; |
|
133 iClientStatus = &aStatus; |
|
134 *iClientStatus = KRequestPending; |
|
135 |
|
136 if( iUser.iFlowControlMonitor->GetFlowControlState() == EIscFlowControlOff ) |
|
137 { |
|
138 //iIscApi.DataSend( aStatus, aBuf ); |
|
139 SendAndComplete(); |
|
140 } |
|
141 else //flow control on |
|
142 { |
|
143 |
|
144 //iBuf = &aBuf; |
|
145 // iBuf->Set( const_cast<TUint8*>(aBuf.Ptr()), aBuf.Length(), aBuf.Length() ); |
|
146 // iClientStatus = &aStatus; |
|
147 // *iClientStatus = KRequestPending; |
|
148 iUser.iFlowControlMonitor->RequestFlowcontrolChange( iStatus ); |
|
149 SetActive(); |
|
150 } |
|
151 |
|
152 } |
|
153 void CNotifyWriteStatusMonitor::RunL() |
|
154 { |
|
155 C_TRACE( (_T("CNotifyWriteStatusMonitor::RunL() iStatus %d ->"), iStatus.Int() ) ); |
|
156 |
|
157 SendAndComplete(); |
|
158 //iIscApi.DataSend( *iClientStatus, *iBuf ); |
|
159 |
|
160 C_TRACE( (_T("CNotifyWriteStatusMonitor::RunL() <-") ) ); |
|
161 } |
|
162 |
|
163 void CNotifyWriteStatusMonitor::SendAndComplete() |
|
164 { |
|
165 TInt error = KErrGeneral; |
|
166 |
|
167 error = iIscApi.DataSend( *iBuf ); |
|
168 User::RequestComplete(iClientStatus, error); |
|
169 } |
|
170 |
|
171 |
|
172 void CNotifyWriteStatusMonitor::DoCancel() |
|
173 { |
|
174 C_TRACE( (_T("CNotifyWriteStatusMonitor::DoCancel() ->") ) ); |
|
175 |
|
176 if( *iClientStatus == KRequestPending ) |
|
177 { |
|
178 C_TRACE( (_T("CNotifyWriteStatusMonitor::DoCancel completing client request with KErrCancel ->") ) ); |
|
179 //Complete clients request |
|
180 User::RequestComplete( iClientStatus, KErrCancel ); |
|
181 } |
|
182 |
|
183 C_TRACE( (_T("CNotifyWriteStatusMonitor::DoCancel() <-") ) ); |
|
184 } |
|
185 |
|
186 |
|
187 CNotifyWriteStatusMonitor::~CNotifyWriteStatusMonitor() |
|
188 { |
|
189 C_TRACE( (_T("CNotifyWriteStatusMonitor::~CNotifyWriteStatusMonitor() ->") ) ); |
|
190 |
|
191 Cancel(); |
|
192 |
|
193 C_TRACE( (_T("CNotifyWriteStatusMonitor::~CNotifyWriteStatusMonitor() <-") ) ); |
|
194 } |
|
195 |
|
196 |
|
197 |
|
198 /** |
|
199 * Default constructor to create a CBcaToIsc instance. |
|
200 */ |
|
201 CBcaToIsc::CBcaToIsc() : iReadLength(0), iChannelNumber( 0xffff ) |
|
202 { |
|
203 C_TRACE( (_T("CBcaToIsc::CBcaToIsc() ->") ) ); |
|
204 |
|
205 C_TRACE( (_T("CBcaToIsc::CBcaToIsc() <-") ) ); |
|
206 } |
|
207 |
|
208 /** |
|
209 2nd phase of construction: allocates member objects |
|
210 |
|
211 @leave when members cannot be constructed. */ |
|
212 void CBcaToIsc::ConstructL() |
|
213 { |
|
214 C_TRACE( (_T("CBcaToIsc::ConstructL() ->") ) ); |
|
215 __ASSERT_DEBUG(!iFlowControlMonitor, User::Panic(_L("BcaToIsc.dll"), EMonitorAlreadyExists)); |
|
216 __ASSERT_DEBUG(!iWriteStatusMonitor, User::Panic(_L("BcaToIsc.dll"), EMonitorAlreadyExists)); |
|
217 iFlowControlMonitor = new (ELeave)CNotifyFlowControlMonitor(iIscApi); |
|
218 iWriteStatusMonitor = new (ELeave)CNotifyWriteStatusMonitor(*this, iIscApi); |
|
219 C_TRACE( (_T("CBcaToIsc::ConstructL() this 0x%x <-"), this ) ); |
|
220 |
|
221 } |
|
222 |
|
223 /** |
|
224 * Destructor |
|
225 */ |
|
226 CBcaToIsc::~CBcaToIsc() |
|
227 { |
|
228 |
|
229 C_TRACE( (_T("CBcaToIsc::~CBcaToIsc() ->") ) ); |
|
230 if( iFlowControlMonitor ) |
|
231 { |
|
232 delete iFlowControlMonitor; |
|
233 } |
|
234 |
|
235 if( iWriteStatusMonitor ) |
|
236 { |
|
237 delete iWriteStatusMonitor; |
|
238 } |
|
239 iClientShutdownStatus = NULL; |
|
240 C_TRACE( (_T("CBcaToIsc::~CBcaToIsc() <-") ) ); |
|
241 |
|
242 } |
|
243 |
|
244 /** This method deletes the BCA itself.*/ |
|
245 void CBcaToIsc::Release() |
|
246 { |
|
247 |
|
248 C_TRACE( (_T("CBcaToIsc::Release() this 0x%x ->"), this ) ); |
|
249 delete this; |
|
250 C_TRACE( (_T("CBcaToIsc::Release() this 0x%x <-"), this ) ); |
|
251 |
|
252 } |
|
253 |
|
254 |
|
255 /** |
|
256 * Informs that the BCA is required by the client(for instance, Raw IP NIF). |
|
257 |
|
258 * @param aStatus complete status, KErrNone if successful, error code otherwise. |
|
259 * @param aChannelId comm port name. |
|
260 */ |
|
261 void CBcaToIsc::Open(TRequestStatus& aStatus, const TDesC& aChannelId) |
|
262 { |
|
263 |
|
264 C_TRACE( (_T("CBcaToIsc::Open aStatus %d aChannelId descriptor %S ->"), aStatus.Int(), &aChannelId ) ); |
|
265 // Expected form either <XXX>Int_<XX> (i.e. 100Int_3) or Int!!! |
|
266 TUint16 channelid( 0xffff ); |
|
267 TInt error( KErrGeneral ); |
|
268 _LIT(KIntUnderScore, "Int_"); |
|
269 TInt len1 = aChannelId.Find(KIntUnderScore); |
|
270 if( len1 < KErrNone ) |
|
271 { |
|
272 // Int format |
|
273 TLex16 channelParser(aChannelId); |
|
274 error = channelParser.Val(channelid, EDecimal); |
|
275 } |
|
276 else |
|
277 { |
|
278 // <XXX>Int_<XX> format |
|
279 TUint numPos = len1 + KIntUnderScore.iTypeLength; |
|
280 TPtrC digit = aChannelId.Mid(numPos); |
|
281 TLex16 channelParser(digit); |
|
282 error = channelParser.Val(channelid, EDecimal); |
|
283 } |
|
284 ASSERT( KErrNone == error ); |
|
285 if( error == KErrNone ) |
|
286 { |
|
287 error = iIscApi.Loan( channelid ); |
|
288 iChannelNumber = error == KErrNone ? channelid : iChannelNumber; |
|
289 } |
|
290 ASSERT( KErrNone == error ); |
|
291 TRequestStatus* request = &aStatus; |
|
292 User::RequestComplete( request, error ); |
|
293 C_TRACE( (_T("CBcaToIsc::Open <-") ) ); |
|
294 |
|
295 } |
|
296 |
|
297 /** |
|
298 Shuts the BCA channel down in a graceful manner. BCA releases its resources. |
|
299 Cancels all outstanding operations: Writes, Reads and Ioctls. |
|
300 |
|
301 @param aStatus completion status: Always KErrNone. |
|
302 */ |
|
303 void CBcaToIsc::Shutdown(TRequestStatus& aStatus) |
|
304 { |
|
305 |
|
306 C_TRACE( (_T("CBcaToIsc::Shutdown aStatus %d ->"), aStatus.Int() ) ); |
|
307 iClientShutdownStatus = &aStatus; |
|
308 *iClientShutdownStatus = KRequestPending; |
|
309 iWriteStatusMonitor->Cancel(); |
|
310 iFlowControlMonitor->Cancel(); |
|
311 iIscApi.DataReceiveCancel(); |
|
312 iIscApi.ReturnLoan( iChannelNumber ); |
|
313 User::RequestComplete(iClientShutdownStatus, KErrNone); |
|
314 C_TRACE( (_T("CBcaToIsc::Shutdown <-") ) ); |
|
315 |
|
316 } |
|
317 |
|
318 /** |
|
319 * Closes the BCA immediately. BCA releases its resources. |
|
320 * cancels all Writes, Reads and Controls. |
|
321 */ |
|
322 void CBcaToIsc::Close() |
|
323 { |
|
324 |
|
325 C_TRACE( (_T("CBcaToIsc::Close() iChannelNumber=0x%x->"), iChannelNumber ) ); |
|
326 if( iClientShutdownStatus && ( *iClientShutdownStatus == KRequestPending ) ) |
|
327 { |
|
328 C_TRACE( (_T("CBcaToIsc::Close completing client Shutdown request with KErrCancel ->") ) ); |
|
329 User::RequestComplete(iClientShutdownStatus, KErrCancel); |
|
330 } |
|
331 C_TRACE( (_T("CBcaToIsc::Close() iChannelNumber=0x%x 1"), iChannelNumber ) ); |
|
332 iWriteStatusMonitor->Cancel(); |
|
333 C_TRACE( (_T("CBcaToIsc::Close() iChannelNumber=0x%x 2"), iChannelNumber ) ); |
|
334 iFlowControlMonitor->Cancel(); |
|
335 C_TRACE( (_T("CBcaToIsc::Close() iChannelNumber=0x%x 3"), iChannelNumber ) ); |
|
336 iIscApi.DataReceiveCancel(); |
|
337 C_TRACE( (_T("CBcaToIsc::Close() iChannelNumber=0x%x 4"), iChannelNumber ) ); |
|
338 iIscApi.DataSendCancel(); |
|
339 C_TRACE( (_T("CBcaToIsc::Close() iChannelNumber=0x%x 5"), iChannelNumber ) ); |
|
340 iIscApi.ReturnLoan( iChannelNumber ); |
|
341 |
|
342 C_TRACE( (_T("CBcaToIsc::Close() <-") ) ); |
|
343 |
|
344 } |
|
345 |
|
346 /** |
|
347 * Queues a Read. |
|
348 |
|
349 * @param aStatus complete status, KErrNone if successful, error code otherwise. |
|
350 * @param aBuf buffer for data to be read. |
|
351 * @note The buffer is owned by the client. Client must not access / modify the buffer until the Read completes. |
|
352 */ |
|
353 void CBcaToIsc::Read(TRequestStatus& aStatus,TDes8& aBuf) |
|
354 { |
|
355 |
|
356 C_TRACE( (_T("CBcaToIsc::Read aStatus=%d aBuf=0x%x ->"), aStatus.Int(), &aBuf ) ); |
|
357 iIscApi.DataReceive( aStatus, aBuf, iReadLength ); |
|
358 C_TRACE( (_T("CBcaToIsc::Read aStatus=%d aBuf=0x%x <-"), aStatus.Int(), &aBuf ) ); |
|
359 |
|
360 } |
|
361 |
|
362 /** |
|
363 * Queues a Write |
|
364 |
|
365 * @param aStatus the complete status, KErrNone if successful, error code otherwise. |
|
366 * @param aBuf the buffer to sent. |
|
367 * @note The buffer is owned by the client. Client must not access / modify the buffer until the Write completes. |
|
368 */ |
|
369 void CBcaToIsc::Write( TRequestStatus& aStatus, const TDesC8& aBuf ) |
|
370 { |
|
371 C_TRACE( (_T("CBcaToIsc::Write aStatus %d aBuf %S ->"), aStatus.Int(), &aBuf ) ); |
|
372 //write requesti pitää jäädä odottamaan jos flow controlli päälä. |
|
373 |
|
374 iWriteStatusMonitor->Write(aStatus, aBuf); |
|
375 |
|
376 C_TRACE( (_T("CBcaToIsc::Write <-") ) ); |
|
377 } |
|
378 |
|
379 /** |
|
380 Cancels the outstanding Read operation.(best effort operation: the read may have been completed already.) |
|
381 */ |
|
382 void CBcaToIsc::CancelRead() |
|
383 { |
|
384 C_TRACE( (_T("CBcaToIsc::CancelRead() ->") ) ); |
|
385 |
|
386 iIscApi.DataReceiveCancel(); |
|
387 |
|
388 C_TRACE( (_T("CBcaToIsc::CancelRead() <-") ) ); |
|
389 } |
|
390 |
|
391 /** |
|
392 Cancels all Write operations.(best effort attempt: the write may have been completed already.) |
|
393 */ |
|
394 void CBcaToIsc::CancelWrite() |
|
395 { |
|
396 C_TRACE( (_T("CBcaToIsc::CancelWrite() ->") ) ); |
|
397 |
|
398 iWriteStatusMonitor->Cancel(); |
|
399 |
|
400 C_TRACE( (_T("CBcaToIsc::CancelWrite() <-") ) ); |
|
401 } |
|
402 |
|
403 |
|
404 /** |
|
405 * Ioctl: asynchronously controls the BcaToIsc. |
|
406 |
|
407 * @param aStatus complete status, KErrNone if successful, system-wide error code otherwise. |
|
408 * @param aOptLevel option level to be used. |
|
409 * @param aOptName option name to be used. |
|
410 * @param aOpt an optional parameter,holds the option value on return or the option value to be set. |
|
411 */ |
|
412 void CBcaToIsc::Ioctl( |
|
413 TRequestStatus& aStatus, |
|
414 TUint, // aOptLevel, |
|
415 TUint, // aOptName, |
|
416 TDes8& // aOpt |
|
417 ) |
|
418 { |
|
419 |
|
420 C_TRACE( (_T("CBcaToIsc::Ioctl ->") ) ); |
|
421 TRequestStatus* ptrStatus = &aStatus; |
|
422 User::RequestComplete( ptrStatus, KErrNotSupported); |
|
423 C_TRACE( (_T("CBcaToIsc::Ioctl <-") ) ); |
|
424 |
|
425 } |
|
426 |
|
427 /** Cancels an outstanding Ioctl, if any. */ |
|
428 void CBcaToIsc::CancelIoctl() |
|
429 { |
|
430 |
|
431 C_TRACE( (_T("CBcaToIsc::CancelIoctl() ->") ) ); |
|
432 C_TRACE( (_T("CBcaToIsc::CancelIoctl() <-") ) ); |
|
433 |
|
434 } |
|
435 |