|
1 // |
|
2 // * Copyright 2004 Neusoft America Inc. |
|
3 // * All rights reserved. |
|
4 // * This component and the accompanying materials are made available |
|
5 // * under the terms of the 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 // * Contributors: |
|
10 // * Keith Collins (Neusoft America Inc.) original software development and additional code and modifications. |
|
11 // * Thomas Gahagen (Neusoft America Inc.) additional code and modifications. |
|
12 // * Zhen Yuan (Neusoft America Inc.) additional code and modifications. |
|
13 // * |
|
14 // * Description: This file contains the implementation for the CPortC32Interface class. |
|
15 // * This class contains methods which are invoked by C32 when the |
|
16 // * associated client RComm public API is invoked. These methods |
|
17 // * are used to create, configure, read, write, and close logical |
|
18 // * serial ports. Instances of this class are created by the CSY's |
|
19 // * Port Factory. |
|
20 // |
|
21 |
|
22 /** @file PortC32InterfaceIp.cpp |
|
23 * |
|
24 * This file contains the implementation for the CPortC32InterfaceIp class. |
|
25 * This class contains methods which are invoked by C32 when the |
|
26 * associated client RComm public API is invoked. These methods |
|
27 * are used to create, configure, read, write, and close logical |
|
28 * serial ports. Instances of this class are created by the CSY's |
|
29 * Port Factory. |
|
30 * |
|
31 */ |
|
32 |
|
33 #include <cdbcols.h> |
|
34 #include "PortC32InterfaceIp.h" |
|
35 #include "Portfactory.h" |
|
36 #include "Mux0710Protocol.h" |
|
37 #include "CsyMsgBufBPFrame.h" |
|
38 #include "ChannelMgrCmdData.h" |
|
39 #include "CommFrameReaderAo.h" |
|
40 #include "CsyDebugLogger.h" |
|
41 #include "CsyGlobals.h" |
|
42 #include "CommFrameWriterAo.h" |
|
43 |
|
44 CPortC32InterfaceIp* CPortC32InterfaceIp::NewL(CPortFactory& aPortFactory, |
|
45 CPortFactory::TC32PortInfo& aPortInfo) |
|
46 /** |
|
47 * This method uses two phase construction and the cleanup stack to create |
|
48 * an instance of class CPortC32InterfaceIp. |
|
49 * |
|
50 * @param aPortFactory - Reference to the port factory |
|
51 * @param aPortInfo - Reference to the port information |
|
52 * @return Pointer to the created instance |
|
53 */ |
|
54 { |
|
55 _LOG_L4C1("CPortC32InterfaceIp::NewL"); |
|
56 |
|
57 CPortC32InterfaceIp* self = |
|
58 new(ELeave) CPortC32InterfaceIp(aPortFactory, aPortInfo); |
|
59 |
|
60 TCleanupItem closeSelf(CPortFactory::CloseObject, self); |
|
61 CleanupStack::PushL(closeSelf); |
|
62 self->ConstructL(); |
|
63 CleanupStack::Pop(self); |
|
64 |
|
65 return (self); |
|
66 } |
|
67 |
|
68 CPortC32InterfaceIp::~CPortC32InterfaceIp() |
|
69 /** |
|
70 * Destructor. |
|
71 */ |
|
72 { |
|
73 _LOG_L4C1(">>CPortC32InterfaceIp::~CPortC32InterfaceIp"); |
|
74 |
|
75 _LOG_L3C1("Remove port from the port factory"); |
|
76 |
|
77 // let port factory know we are deleted |
|
78 iPortFactory.RemoveC32Port(this); |
|
79 CompleteOutstandingRequest(); |
|
80 |
|
81 _LOG_L3C1("Release any packets going to the C32 client"); |
|
82 |
|
83 // remove all frames to do with the most recent IP packet |
|
84 CCsyMsgBufBpFrame* ipPacketFrame = NULL; |
|
85 iFramesReceivedForIpPacketIter.SetToFirst(); |
|
86 while ((ipPacketFrame = iFramesReceivedForIpPacketIter++) != NULL) |
|
87 { |
|
88 iFramesReceivedForIpPacket.Remove(*ipPacketFrame); |
|
89 delete ipPacketFrame; |
|
90 } |
|
91 |
|
92 _LOG_L4C1("<<CPortC32InterfaceIp::~CPortC32InterfaceIp"); |
|
93 } |
|
94 |
|
95 CPortC32InterfaceIp::CPortC32InterfaceIp(CPortFactory& aPortFactory, |
|
96 CPortFactory::TC32PortInfo& aPortInfo) |
|
97 /** |
|
98 * Constructor. |
|
99 * |
|
100 * @param aPortFactory - Reference to the port factory |
|
101 * @param aPortInfo - Reference to the port information |
|
102 */ |
|
103 : CPortC32InterfaceBase(aPortFactory, aPortInfo), |
|
104 iFramesReceivedForIpPacket(_FOFF(CCsyMsgBufBpFrame, iMsgLink)), |
|
105 iFramesReceivedForIpPacketIter(iFramesReceivedForIpPacket) |
|
106 {} |
|
107 |
|
108 void CPortC32InterfaceIp::ConstructL() |
|
109 /** |
|
110 * Safe constructor |
|
111 */ |
|
112 { |
|
113 _LOG_L4C1(">>CPortC32InterfaceIp::ConstructL"); |
|
114 |
|
115 CPortC32InterfaceBase::ConstructL(); |
|
116 |
|
117 _LOG_L4C1("<<CPortC32InterfaceIp::ConstructL"); |
|
118 } |
|
119 |
|
120 /********************************************************************************/ |
|
121 /* Start of utility methods for CPortC32InterfaceBase */ |
|
122 /********************************************************************************/ |
|
123 |
|
124 TInt CPortC32InterfaceIp::QueryReceiveBuffer(TInt& aLength) const |
|
125 /** |
|
126 * Called by C32 when the client queries the size of the receive buffer, |
|
127 * which returns the number of receive characters available to be read by |
|
128 * the C32 client RComm instance. |
|
129 * |
|
130 * @param aLength - Reference to client's buffer length variable |
|
131 * @return KErrNone |
|
132 */ |
|
133 { |
|
134 _LOG_L4C2("CPortC32InterfaceIp::QueryReceiveBuffer [port=%d]", GetPortNumber()); |
|
135 |
|
136 aLength = 0; |
|
137 |
|
138 // MAF |
|
139 |
|
140 return KErrNone; |
|
141 } |
|
142 |
|
143 void CPortC32InterfaceIp::ResetBuffers(TUint aFlags) |
|
144 /** |
|
145 * Called by C32 when the client requests to reset the buffers, |
|
146 * by removing all receive and/or transmit messages according to |
|
147 * the specified flags. |
|
148 * |
|
149 * @param aFlags Indicate which buffers (receive and/or transmit) should be reset |
|
150 */ |
|
151 { |
|
152 _LOG_L4C3(">>CPortC32InterfaceIp::ResetBuffers [aFlags=%d,port=%d]", |
|
153 aFlags,GetPortNumber()); |
|
154 |
|
155 if (aFlags & KCommResetRx) |
|
156 { |
|
157 _LOG_L4C1("Removing all messages intended for the C32 client"); |
|
158 |
|
159 RemoveWaitingAllFrames(); |
|
160 |
|
161 // remove all frames to do with the most recent IP packet |
|
162 CCsyMsgBufBpFrame* ipPacketFrame = NULL; |
|
163 iFramesReceivedForIpPacketIter.SetToFirst(); |
|
164 while ((ipPacketFrame = iFramesReceivedForIpPacketIter++) != NULL) |
|
165 { |
|
166 iFramesReceivedForIpPacket.Remove(*ipPacketFrame); |
|
167 delete ipPacketFrame; |
|
168 } |
|
169 } |
|
170 |
|
171 if (aFlags & KCommResetTx) |
|
172 { |
|
173 _LOG_L4C1("Removing all messages intended for the modem"); |
|
174 |
|
175 GetMuxChannel()->WriteCancel(); |
|
176 } |
|
177 |
|
178 _LOG_L4C1("<<CPortC32InterfaceIp::ResetBuffers"); |
|
179 } |
|
180 |
|
181 void CPortC32InterfaceIp::PlaceIpPacketFramesOntoFreeList() |
|
182 /** |
|
183 * Place all frames to do with recent IP packet onto free list |
|
184 */ |
|
185 { |
|
186 _LOG_L4C2(">>CPortC32InterfaceIp::PlaceIpPacketFramesOntoFreeList [port=%d]", GetPortNumber()); |
|
187 |
|
188 CCsyMsgBufBpFrame* frame = NULL; |
|
189 iFramesReceivedForIpPacketIter.SetToFirst(); |
|
190 while ((frame = iFramesReceivedForIpPacketIter++) != NULL) |
|
191 { |
|
192 iFramesReceivedForIpPacket.Remove(*frame); |
|
193 iPortFactory.GetMux0710Protocol()->AddFrameFreeQ(frame); |
|
194 } |
|
195 iCurrentIpPacketLength = 0; |
|
196 |
|
197 _LOG_L4C1("<<CPortC32InterfaceIp::PlaceIpPacketFramesOntoFreeList"); |
|
198 } |
|
199 |
|
200 void CPortC32InterfaceIp::PlaceIpPacketFramesOntoReadList() |
|
201 /** |
|
202 * Place all frames to do with recent IP packet onto read list |
|
203 */ |
|
204 { |
|
205 _LOG_L4C2(">>CPortC32InterfaceIp::PlaceIpPacketFramesOntoReadList [port=%d]", GetPortNumber()); |
|
206 |
|
207 CCsyMsgBufBpFrame* frame = NULL; |
|
208 iFramesReceivedForIpPacketIter.SetToFirst(); |
|
209 while ((frame = iFramesReceivedForIpPacketIter++) != NULL) |
|
210 { |
|
211 iFramesReceivedForIpPacket.Remove(*frame); |
|
212 iFramesWaitingToBeReadList.AddLast(*frame); |
|
213 } |
|
214 iCurrentIpPacketLength = 0; |
|
215 iNumberOfPacketsWaiting++; |
|
216 _LOG_L4C2("iNumberOfPacketsWaiting=%d",iNumberOfPacketsWaiting); |
|
217 |
|
218 if (iNumberOfPacketsWaiting == KMaxPacketsOutstandingForC32Client) |
|
219 { |
|
220 _LOG_L2C1("Client appears to be slow at reading"); |
|
221 _LOG_L2C3("iNumberOfPacketsWaiting %d > KMaxPacketsOutstandingForC32Client %d)", |
|
222 iNumberOfPacketsWaiting,KMaxPacketsOutstandingForC32Client); |
|
223 |
|
224 iMuxChannel->SetCsyToModemFlowControl(EFlowControlOn); |
|
225 } |
|
226 |
|
227 _LOG_L4C1("<<CPortC32InterfaceIp::PlaceIpPacketFramesOntoReadList"); |
|
228 } |
|
229 |
|
230 void CPortC32InterfaceIp::SendFrameToClient(CCsyMsgBufBpFrame* aFrame) |
|
231 /** |
|
232 * This method is called by a CSY Channel object when it has a single |
|
233 * frame to send to a C32 client RComm object. |
|
234 * |
|
235 * @param aFrame - Pointer to message to send to client |
|
236 */ |
|
237 { |
|
238 _LOG_L4C2(">>CPortC32InterfaceIp::SendFrameToClient [port=%d]", GetPortNumber()); |
|
239 |
|
240 if (aFrame) |
|
241 { |
|
242 // frame validation |
|
243 if (aFrame->iMsg.Length() <= KAdvOptionNumOfNonDataOctets) |
|
244 { |
|
245 _LOG_L1C1("** Does not appear to be a valid frame - disregarding **"); |
|
246 |
|
247 // Place received frames on the empty list |
|
248 iPortFactory.GetMux0710Protocol()->AddFrameFreeQ(aFrame); |
|
249 PlaceIpPacketFramesOntoFreeList(); |
|
250 |
|
251 _LOG_L4C1("<<CPortC32InterfaceIp::SendFrameToClient - bad frame"); |
|
252 return; |
|
253 } |
|
254 |
|
255 TUint8 framePosition = aFrame->GetType4FrameSequence(); |
|
256 _LOG_L4C2("framePosition = 0x%02x",framePosition); |
|
257 |
|
258 // read buffer validation |
|
259 if (iFramesReceivedForIpPacket.IsEmpty()) |
|
260 { |
|
261 // There is no read buffer allocated for this frame |
|
262 switch (framePosition) |
|
263 { |
|
264 case KSingleFrame: |
|
265 case KStartMultiFrame: |
|
266 { |
|
267 _LOG_L4C1("Starting new IP frame list"); |
|
268 iCurrentIpPacketLength = 0; |
|
269 } |
|
270 break; |
|
271 case KEndMultiFrame: |
|
272 case KMiddleMultiFrame: |
|
273 default: |
|
274 // assumption here is that because no read buffer is allocated then |
|
275 // there cannot have been a valid start frame |
|
276 _LOG_L1C1("** Missed start of packet - disregarding **"); |
|
277 |
|
278 // Place received frame on the empty list |
|
279 iPortFactory.GetMux0710Protocol()->AddFrameFreeQ(aFrame); |
|
280 |
|
281 _LOG_L4C1("<<CPortC32InterfaceIp::SendFrameToClient - no start"); |
|
282 return; |
|
283 } |
|
284 } |
|
285 else if ((framePosition == KSingleFrame)||(framePosition == KStartMultiFrame)) |
|
286 { |
|
287 // There's been a comms error and an end packet has been lost |
|
288 _LOG_L1C1("** Unexpected Start/Single frame - disregarded previous frames **"); |
|
289 |
|
290 // Place received frames on the empty list |
|
291 PlaceIpPacketFramesOntoFreeList(); |
|
292 |
|
293 // Continue processing this frame |
|
294 _LOG_L4C1("Starting new IP frame list"); |
|
295 iCurrentIpPacketLength = 0; |
|
296 } |
|
297 |
|
298 // If have got to here then IP frame list exists |
|
299 |
|
300 TInt length = aFrame->iMsg.Length() - KAdvOptionNumOfNonDataOctets; |
|
301 _LOG_L4C2("length=%d",length); |
|
302 |
|
303 // length validation |
|
304 if ((iCurrentIpPacketLength + length) > KMaxIpPacketSize) |
|
305 { |
|
306 // The length of the data in the new frame would exceed that available |
|
307 // in the read buffer. |
|
308 |
|
309 _LOG_L1C3("** iCurrentIpPacketLength + length %d exceeds max size %d **", |
|
310 (iCurrentIpPacketLength + length),KMaxIpPacketSize); |
|
311 |
|
312 // Place received frames on the empty list |
|
313 iPortFactory.GetMux0710Protocol()->AddFrameFreeQ(aFrame); |
|
314 PlaceIpPacketFramesOntoFreeList(); |
|
315 |
|
316 _LOG_L4C1("<<CPortC32InterfaceIp::SendFrameToClient - frame sized exceeded"); |
|
317 return; |
|
318 } |
|
319 |
|
320 // If have got to here IP frame list exists and length is valid |
|
321 iCurrentIpPacketLength += length; |
|
322 |
|
323 TBool addReadBufferToClientList = EFalse; |
|
324 switch (framePosition) |
|
325 { |
|
326 // Single frame |
|
327 case KSingleFrame: |
|
328 _LOG_L4C1("Only frame"); |
|
329 iFramesReceivedForIpPacket.AddFirst(*aFrame); |
|
330 addReadBufferToClientList = ETrue; |
|
331 break; |
|
332 |
|
333 // Multiframe |
|
334 case KStartMultiFrame: |
|
335 _LOG_L4C1("Start multiframe"); |
|
336 iFramesReceivedForIpPacket.AddFirst(*aFrame); |
|
337 break; |
|
338 |
|
339 case KMiddleMultiFrame: |
|
340 _LOG_L4C1("Middle multiframe"); |
|
341 iFramesReceivedForIpPacket.AddLast(*aFrame); |
|
342 break; |
|
343 |
|
344 case KEndMultiFrame: |
|
345 _LOG_L4C1("Last multiframe"); |
|
346 iFramesReceivedForIpPacket.AddLast(*aFrame); |
|
347 addReadBufferToClientList = ETrue; |
|
348 break; |
|
349 |
|
350 // Unknown |
|
351 default: |
|
352 _LOG_L1C2("** Unknown framePosition %d - ignoring **", |
|
353 framePosition); |
|
354 |
|
355 // Place received frame on the empty list |
|
356 iPortFactory.GetMux0710Protocol()->AddFrameFreeQ(aFrame); |
|
357 PlaceIpPacketFramesOntoFreeList(); |
|
358 |
|
359 _LOG_L4C1("<<CPortC32InterfaceIp::SendFrameToClient - unknown frame pos"); |
|
360 return; |
|
361 } |
|
362 |
|
363 if (addReadBufferToClientList) |
|
364 { |
|
365 // Give iFramesWaitingToBeReadList ownership of the frames making up the IP Packet |
|
366 _LOG_L4C1("Transfer frames to client msg list"); |
|
367 |
|
368 // check if queue is empty |
|
369 TBool trigger = iFramesWaitingToBeReadList.IsEmpty(); |
|
370 |
|
371 PlaceIpPacketFramesOntoReadList(); |
|
372 |
|
373 if (trigger) |
|
374 { |
|
375 _LOG_L4C1("No packets already waiting"); |
|
376 if (iIsReadInProgress) |
|
377 { |
|
378 _LOG_L4C1("A read is outstanding"); |
|
379 ReadFromBufOrQueue(); |
|
380 } |
|
381 } |
|
382 |
|
383 // inform client new data is available |
|
384 SetDataAvailable(); |
|
385 } |
|
386 } |
|
387 else |
|
388 { |
|
389 _LOG_L1C1("** aFrame is null **"); |
|
390 // MAF __ASSERT_DEBUG(EFalse, PANIC(KPanicIllegalState)); |
|
391 } |
|
392 |
|
393 _LOG_L4C1("<<CPortC32InterfaceIp::SendFrameToClient"); |
|
394 } |
|
395 |
|
396 TBool CPortC32InterfaceIp::CreateIpPacketFromFrames() |
|
397 /** |
|
398 * We assume that all validation has been done during SendFrameToClient so only valid |
|
399 * data exists on the iFramesWaitingToBeReadList frame list. |
|
400 * |
|
401 * @return ETrue if packet retrieved successfully |
|
402 */ |
|
403 { |
|
404 _LOG_L4C2(">>CPortC32InterfaceIp::CreateIpPacketFromFrames [port=%d]", GetPortNumber()); |
|
405 |
|
406 iIpPacket.Zero(); |
|
407 |
|
408 TUint8 framePosition = 0; |
|
409 TInt length = 0; |
|
410 TBool packetRetrieved = EFalse; |
|
411 |
|
412 // Remove all frames to do with the same IP Packet from waiting to be read list |
|
413 CCsyMsgBufBpFrame* frame = NULL; |
|
414 iFramesWaitingToBeReadIter.SetToFirst(); |
|
415 while ((frame = iFramesWaitingToBeReadIter++) != NULL) |
|
416 { |
|
417 iFramesWaitingToBeReadList.Remove(*frame); |
|
418 |
|
419 framePosition = frame->GetType4FrameSequence(); |
|
420 _LOG_L4C2("framePosition = 0x%02x",framePosition); |
|
421 |
|
422 length = frame->iMsg.Length() - KAdvOptionNumOfNonDataOctets; |
|
423 _LOG_L4C2("length=%d",length); |
|
424 |
|
425 iIpPacket.Append(&frame->iMsg[KAdvOptionType4StartOfMessageData], length); |
|
426 |
|
427 iPortFactory.GetMux0710Protocol()->AddFrameFreeQ(frame); |
|
428 |
|
429 if ((framePosition == KSingleFrame)||(framePosition == KEndMultiFrame)) |
|
430 { |
|
431 _LOG_L4C1("retrieved packet"); |
|
432 packetRetrieved = ETrue; |
|
433 |
|
434 if (iNumberOfPacketsWaiting == KMaxPacketsOutstandingForC32Client) |
|
435 { |
|
436 _LOG_L2C1("Client appears to be reading again"); |
|
437 |
|
438 // Assume it is okay to set FC to Off even in low free frame |
|
439 // condition since just freed a frame. |
|
440 |
|
441 iMuxChannel->SetCsyToModemFlowControl(EFlowControlOff); |
|
442 } |
|
443 |
|
444 iNumberOfPacketsWaiting--; |
|
445 _LOG_L4C2("iNumberOfPacketsWaiting=%d",iNumberOfPacketsWaiting); |
|
446 break; |
|
447 } |
|
448 } |
|
449 |
|
450 _LOG_L4C2("<<CPortC32InterfaceIp::CreateIpPacketFromFrames [packetRetrieved=%d]",packetRetrieved); |
|
451 return packetRetrieved; |
|
452 } |
|
453 |
|
454 TBool CPortC32InterfaceIp::ReadFromBufOrQueue() |
|
455 /** |
|
456 * This method is called to read from buffer or the frame list |
|
457 * It will read as much as possible. |
|
458 * |
|
459 * @return ETrue if complete the read request |
|
460 */ |
|
461 { |
|
462 _LOG_L4C2(">>CPortC32InterfaceIp::ReadFromBufOrQueue [port=%d]", GetPortNumber()); |
|
463 |
|
464 TBool completedRead = EFalse; |
|
465 TInt ret = KErrNone; |
|
466 |
|
467 _LOG_L4C2("iOneOrMore=%d",iOneOrMore); |
|
468 _LOG_L4C2("iClientLength=%d",iClientLength); |
|
469 |
|
470 while ((CreateIpPacketFromFrames())&&(!ret)) |
|
471 { |
|
472 TInt ipPacketLength = iIpPacket.Length(); |
|
473 TInt length = -1; |
|
474 if (iClientLength - iPos < ipPacketLength) |
|
475 { |
|
476 length = iClientLength - iPos; |
|
477 _LOG_L4C2("length remaining = %d",length); |
|
478 } |
|
479 |
|
480 if ((length > -1) && (ipPacketLength >= length)) |
|
481 { |
|
482 // MAF should partial reads be allowed? |
|
483 _LOG_L2C1("Partial read?"); |
|
484 |
|
485 } |
|
486 else |
|
487 { |
|
488 _LOG_L4C3("read buf %d >= length %d ", ipPacketLength, length); |
|
489 |
|
490 ret = IPCWrite(iClientBuffer, iIpPacket, iPos); |
|
491 if (ret) |
|
492 { |
|
493 _LOG_L1C2("** IPCWrite Error %d **",ret); |
|
494 } |
|
495 |
|
496 _LOG_L4C3("Read: iPos = %d, add %d bytes", iPos, ipPacketLength); |
|
497 |
|
498 iPos += ipPacketLength; |
|
499 } |
|
500 } |
|
501 |
|
502 if (iPos>0) |
|
503 { |
|
504 if (iOneOrMore) |
|
505 { |
|
506 CompleteReadRequest(ret); |
|
507 |
|
508 iPos = 0; |
|
509 completedRead = ETrue; |
|
510 } |
|
511 else |
|
512 { |
|
513 //normal read? and have not filled the buffer yet |
|
514 _LOG_L4C3( "Not filled buffer yet iPos = %d, iClientLength = %d", iPos, iClientLength); |
|
515 } |
|
516 } |
|
517 |
|
518 _LOG_L4C2("<<CPortC32InterfaceIp::ReadFromBufOrQueue [completedRead=%d]", completedRead); |
|
519 return completedRead; |
|
520 } |
|
521 |
|
522 |
|
523 /*** |
|
524 TBool CPortC32InterfaceIp::ReadFromBufOrQueue() |
|
525 ** |
|
526 * This method is called to read from buffer or the frame list |
|
527 * It will read as much as possible. |
|
528 * |
|
529 * @return ETrue if complete the read request |
|
530 * |
|
531 { |
|
532 _LOG_L4C2(">>CPortC32InterfaceIp::ReadFromBufOrQueue [port=%d]", GetPortNumber()); |
|
533 |
|
534 TBool completedRead = EFalse; |
|
535 TInt err = KErrGeneral; |
|
536 TBool cont; |
|
537 do |
|
538 { |
|
539 cont = EFalse; |
|
540 if(iQueuedIpPacket == NULL) |
|
541 { |
|
542 //Read data from the frame list |
|
543 if (!iMsgToClientList.IsEmpty()) |
|
544 { |
|
545 _LOG_L4C1("Set to first item"); |
|
546 iQueuedIpPacket = iMsgToClientList.First(); |
|
547 if (iQueuedIpPacket) |
|
548 { |
|
549 _LOG_L4C1("iQueuedIpPacket not null"); |
|
550 // remove msg buf from client list |
|
551 iMsgToClientList.Remove(*iQueuedIpPacket); |
|
552 } |
|
553 } |
|
554 } |
|
555 if (iQueuedIpPacket) |
|
556 { |
|
557 TInt length = KErrNotFound; // <- yeaks! |
|
558 if (iClientLength - iPos < iQueuedIpPacket->iMsg.Length()) |
|
559 { |
|
560 length = iClientLength - iPos; |
|
561 _LOG_L4C2("length remaining = %d",length); |
|
562 } |
|
563 |
|
564 if (iConfig.iTerminatorCount > 0) |
|
565 { |
|
566 _LOG_L4C2("iTerminatorCount = %d",iConfig.iTerminatorCount); |
|
567 |
|
568 // First find terminator |
|
569 TInt terminatorLoc = KErrNotFound; // <- yeaks! |
|
570 TInt loc; |
|
571 for (TInt i = 0; i < iConfig.iTerminatorCount; i++) |
|
572 { |
|
573 loc = iQueuedIpPacket->iMsg.LocateF(iConfig.iTerminator[i]); |
|
574 if (loc > KErrNotFound) |
|
575 { |
|
576 if (terminatorLoc == KErrNotFound) |
|
577 { |
|
578 terminatorLoc = loc; |
|
579 } |
|
580 else |
|
581 { |
|
582 terminatorLoc = Min(loc,terminatorLoc); |
|
583 } |
|
584 } |
|
585 } |
|
586 if (terminatorLoc > KErrNotFound) |
|
587 { |
|
588 if (length > KErrNotFound) |
|
589 length = Min(terminatorLoc + 1,length); |
|
590 else |
|
591 length = terminatorLoc + 1; |
|
592 } |
|
593 _LOG_L4C2("length = %d",length); |
|
594 } |
|
595 |
|
596 _LOG_L4C2("Read buf length %d",iQueuedIpPacket->iMsg.Length()); |
|
597 |
|
598 if ((iQueuedIpPacket->iMsg.Length() >= length) && (length > KErrNotFound)) |
|
599 { |
|
600 LOGTEXT2(__DEBUGLEVELMAJOR__,"complete partial read: # %d ", length); |
|
601 |
|
602 iPartialReadBuf.Copy(&iQueuedIpPacket->iMsg[0], length); |
|
603 iQueuedIpPacket->iMsg.Delete(0, length); |
|
604 |
|
605 err = IPCWrite(iClientBuffer, iPartialReadBuf, iPos); |
|
606 if (err) |
|
607 { |
|
608 _LOG_L1C2("** IPCWrite Error %d **",err); |
|
609 } |
|
610 |
|
611 CompleteReadRequest(err); |
|
612 err = KErrGeneral; |
|
613 |
|
614 completedRead = ETrue; |
|
615 iPos = 0; |
|
616 |
|
617 if (iQueuedIpPacket->iMsg.Length() == 0) |
|
618 { |
|
619 _LOG_L4C1("All data used - freeing read buffer"); |
|
620 AddToFreeC32BufferQ(iQueuedIpPacket); |
|
621 iQueuedIpPacket = NULL; |
|
622 } |
|
623 } |
|
624 else |
|
625 { |
|
626 LOGTEXT3(__DEBUGLEVELMAJOR__,"read buf %d >= length %d ", iQueuedIpPacket->iMsg.Length(), length); |
|
627 |
|
628 err = IPCWrite(iClientBuffer, iQueuedIpPacket->iMsg, iPos); |
|
629 |
|
630 _LOG_L4C3("Read: iPos = %d, add %d bytes", iPos, iQueuedIpPacket->iMsg.Length()); |
|
631 |
|
632 cont = ETrue; //try read next frame in the list |
|
633 iPos = iPos + iQueuedIpPacket->iMsg.Length(); |
|
634 |
|
635 _LOG_L4C1("Freeing read buffer"); |
|
636 AddToFreeC32BufferQ(iQueuedIpPacket); |
|
637 iQueuedIpPacket = NULL; |
|
638 } |
|
639 } |
|
640 } |
|
641 while (cont); |
|
642 |
|
643 if (iPos>0) |
|
644 { |
|
645 if (iOneOrMore) |
|
646 { |
|
647 if (err) |
|
648 { |
|
649 _LOG_L1C2("** IPCWrite Error %d **",err); |
|
650 } |
|
651 |
|
652 CompleteReadRequest(err); |
|
653 |
|
654 iPos = 0; |
|
655 completedRead = ETrue; |
|
656 } |
|
657 else |
|
658 { |
|
659 //normal read and have not filled the buffer yet |
|
660 _LOG_L4C3( "Not filled buffer yet iPos = %d, iClientLength = %d", iPos, iClientLength); |
|
661 //iToClientMsgQAo->IssueNotificationRequest(); |
|
662 } |
|
663 } |
|
664 |
|
665 _LOG_L4C2("<<CPortC32InterfaceIp::ReadFromBufOrQueue [ret=%d]",completedRead); |
|
666 return completedRead; |
|
667 } |
|
668 ***/ |
|
669 |
|
670 |