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 Mux0710Protocol class. |
|
15 // |
|
16 |
|
17 // Mux0710Protocol.cpp |
|
18 |
|
19 /** @file Mux0710Protocol.cpp |
|
20 * |
|
21 */ |
|
22 |
|
23 #include "Mux0710Protocol.h" |
|
24 #include "Portfactory.h" |
|
25 #include "PortC32Interface.h" |
|
26 #include "CsyMsgBufBPFrame.h" |
|
27 #include "ChannelMgrCmdData.h" |
|
28 #include "CommFrameWriterAo.h" |
|
29 #include "CommFrameReaderAo.h" |
|
30 #include "ChannelMgrCtrl.h" |
|
31 #include "CsyDebugLogger.h" |
|
32 |
|
33 // AT Commands |
|
34 _LIT8(KATCmdAttention, "ATE0\r"); |
|
35 _LIT8(KATCmdDisableEcho, "ATE0Q0V1\r"); |
|
36 _LIT8(KATCmdReset, "AT%b\r"); |
|
37 _LIT8(KATCmdSleep, "AT%SLEEP=0\r"); |
|
38 |
|
39 const TInt KRetryCount = 2; |
|
40 |
|
41 CMux0710Protocol* CMux0710Protocol::NewL(CPortFactory& aPortFactory) |
|
42 /** |
|
43 * This static method uses 2-phase construction to create an instance of |
|
44 * this class. |
|
45 * |
|
46 * @return Pointer to the created object |
|
47 */ |
|
48 { |
|
49 _LOG_L4C1("CMux0710Protocol::NewL"); |
|
50 |
|
51 CMux0710Protocol* p = new(ELeave) CMux0710Protocol(aPortFactory); |
|
52 CleanupStack::PushL(p); |
|
53 p->ConstructL(); |
|
54 CleanupStack::Pop(p); |
|
55 return p; |
|
56 } |
|
57 |
|
58 CMux0710Protocol::~CMux0710Protocol() |
|
59 /** |
|
60 * Destructor. |
|
61 */ |
|
62 { |
|
63 _LOG_L4C1("CMux0710Protocol::~CMux0710Protocol"); |
|
64 |
|
65 // Release Free Frame Memory |
|
66 CCsyMsgBufBpFrame* aBpFrame; |
|
67 iFreeFrameBufIter.SetToFirst(); |
|
68 while ((aBpFrame = iFreeFrameBufIter++) != NULL) |
|
69 { |
|
70 iFreeFrameBufList.Remove(*aBpFrame); |
|
71 delete aBpFrame; |
|
72 } |
|
73 |
|
74 delete iTimeouter; |
|
75 } |
|
76 |
|
77 CMux0710Protocol::CMux0710Protocol(CPortFactory& aPortFactory) |
|
78 /** |
|
79 * Constructor. |
|
80 * |
|
81 */ |
|
82 : iPortFactory(aPortFactory), |
|
83 iMuxMgrState(ECsyWaitingForFlushResp), |
|
84 iFreeFrameBufList(_FOFF(CCsyMsgBufBpFrame, iMsgLink)), |
|
85 iFreeFrameBufIter(iFreeFrameBufList), |
|
86 iRetryCount(KRetryCount) |
|
87 {} |
|
88 |
|
89 void CMux0710Protocol::ConstructL() |
|
90 /** |
|
91 * Allocate the memory for the free frames list. |
|
92 */ |
|
93 { |
|
94 _LOG_L4C1("CMux0710Protocol::ConstructL"); |
|
95 |
|
96 iTimeouter = CActiveTimeouter::NewL(*this); |
|
97 |
|
98 // allocate memory for the free frame buffer |
|
99 for (TUint i=0; i < KMaxFreeFrames; i++) |
|
100 { |
|
101 CCsyMsgBufBpFrame* aBpFrame = CCsyMsgBufBpFrame::NewL(); |
|
102 iFreeFrameBufList.AddLast(*aBpFrame); |
|
103 } |
|
104 iFreeFrameCount = KMaxFreeFrames; |
|
105 } |
|
106 |
|
107 CCsyMsgBufBpFrame* CMux0710Protocol::GetFreeFrameBuf(TBool aCheckFlowControlThresholds) |
|
108 /** |
|
109 * Get a free frame buffer and then remove the buffer from |
|
110 * the free list. |
|
111 * |
|
112 * @return - Pointer to a frame buffer or NULL |
|
113 */ |
|
114 { |
|
115 _LOG_L4C2(">>CMux0710Protocol::GetFreeFrameBuf [aCheckFlowControlThresholds=%d]", |
|
116 aCheckFlowControlThresholds); |
|
117 |
|
118 CCsyMsgBufBpFrame* frame = NULL; |
|
119 if (!iFreeFrameBufList.IsEmpty()) |
|
120 { |
|
121 frame = iFreeFrameBufList.First(); |
|
122 if (frame) |
|
123 { |
|
124 iFreeFrameBufList.Remove(*frame); |
|
125 iFreeFrameCount--; |
|
126 _LOG_L4C2("iFreeFrameCount=%d",iFreeFrameCount); |
|
127 |
|
128 if ((aCheckFlowControlThresholds)&&(iFreeFrameCount < KStopDataDlcsThreshold)) |
|
129 { |
|
130 // Need to enforce some flow control |
|
131 iEnforcingFlowControl = ETrue; |
|
132 |
|
133 if (iFreeFrameCount == 1) |
|
134 { |
|
135 // Only one frame free - that can be used to send the MSC command |
|
136 _LOG_L4C1("Drastic action! - 1 frame free"); |
|
137 iPortFactory.StopAnyDlc(); |
|
138 } |
|
139 else |
|
140 { |
|
141 _LOG_L4C2("Less than %d frames free",KStopDataDlcsThreshold); |
|
142 iPortFactory.FindActiveDataDlcToStop(); |
|
143 } |
|
144 } |
|
145 |
|
146 frame->iMsg.Zero(); |
|
147 frame->MsgDlc() = KCtrlChannelDlcNum; |
|
148 frame->CompleteWhenSent() = ETrue; |
|
149 } |
|
150 } |
|
151 |
|
152 _LOG_L4C2("<<CMux0710Protocol::GetFreeFrameBuf [frame=0x%x]",frame); |
|
153 return frame; |
|
154 } |
|
155 |
|
156 void CMux0710Protocol::AddFrameFreeQ(CCsyMsgBufBpFrame* aBpFrame) |
|
157 /** |
|
158 * This method is called to add the specified frame buffer to the |
|
159 * free frame queue. |
|
160 * |
|
161 * @param aBpFrame - Pointer to the frame buffer |
|
162 */ |
|
163 { |
|
164 _LOG_L4C2(">>CMux0710Protocol::AddFrameFreeQ [aBpFrame=0x%x]",aBpFrame); |
|
165 |
|
166 iFreeFrameBufList.AddLast(*aBpFrame); |
|
167 |
|
168 if (iEnforcingFlowControl) |
|
169 { |
|
170 if (iFreeFrameCount >= KStartDataDlcsThreshold) |
|
171 { |
|
172 // Release flow control |
|
173 _LOG_L4C2("More than %d frames free", |
|
174 KStartDataDlcsThreshold); |
|
175 |
|
176 // re-enable a data dlc (note only re-enable one dlc at a time) |
|
177 iEnforcingFlowControl = iPortFactory.FindDlcToEnable(); |
|
178 _LOG_L4C2("iEnforcingFlowControl=%d",iEnforcingFlowControl); |
|
179 } |
|
180 } |
|
181 |
|
182 iFreeFrameCount++; |
|
183 //MAF __ASSERT_DEBUG((iFreeFrameCount <= KMaxFreeFrames),PANIC(KPanicIllegalState)); |
|
184 |
|
185 _LOG_L4C2("<<CMux0710Protocol::AddFrameFreeQ iFreeFrameCount=%d", |
|
186 iFreeFrameCount); |
|
187 } |
|
188 |
|
189 TUint8 CMux0710Protocol::CalcFCS(TUint8* aBuffer, TInt aLen) |
|
190 /** |
|
191 * This method calculates the checkSum for the specified buffer |
|
192 * with the specified length. |
|
193 * |
|
194 * @param aBuffer - Pointer to the data buffer |
|
195 * @param aLen - Length of Number of bytes in the Buffer for which CheckSum to be calculated |
|
196 * @return checksum |
|
197 */ |
|
198 { |
|
199 TUint8 frameCheckSum = 0xFF; |
|
200 aBuffer++; |
|
201 for (TInt i=0; i < aLen; i++ ) |
|
202 { |
|
203 frameCheckSum = crctable[(frameCheckSum ^ (*aBuffer++))]; |
|
204 } |
|
205 |
|
206 // One's Complement |
|
207 frameCheckSum = (TUint8) ((TUint8)(0xFF) - frameCheckSum); |
|
208 |
|
209 return frameCheckSum; |
|
210 } |
|
211 |
|
212 TInt CMux0710Protocol::Create0710DataFrames(TDesC8& aMsgBuf, |
|
213 const TUint8 aDlcNum) |
|
214 /** |
|
215 * This method is called by channel manager objects to fragment |
|
216 * a client message into frames for transmission to the BP. |
|
217 * The length of the client message is determined, the client message is |
|
218 * fragment into 27.010 format, and the formatted frames are added to the |
|
219 * write frame queue. |
|
220 * |
|
221 * @param aMsgBuf - Pointer to the client message |
|
222 * @param aDlcNum - DLC number |
|
223 * @return KErrNone, KErrArgument, or KErrNoMemory |
|
224 */ |
|
225 { |
|
226 _LOG_L4C2(">>CMux0710Protocol::Create0710DataFrames [aDlcNum=%d]", |
|
227 aDlcNum); |
|
228 |
|
229 TInt ret = KErrNone; |
|
230 |
|
231 TInt msgLength = aMsgBuf.Length(); |
|
232 TInt offset = 0; |
|
233 TInt frameLength = 0; |
|
234 TInt maxFrameLength = KMaxFrameSize; |
|
235 |
|
236 TBool beginFlag = ETrue; |
|
237 TBool endFlag = EFalse; |
|
238 |
|
239 _LOG_L4C2("msgLength = %d", msgLength); |
|
240 if (msgLength > 0) |
|
241 { |
|
242 while ((msgLength > 0)&&(ret == KErrNone)) |
|
243 { |
|
244 CCsyMsgBufBpFrame* bpFrame = GetFreeFrameBuf(); |
|
245 if (bpFrame) |
|
246 { |
|
247 // Set up the frame |
|
248 bpFrame->MsgDlc() = aDlcNum; |
|
249 |
|
250 if (msgLength > maxFrameLength) |
|
251 { |
|
252 _LOG_L4C3("Fragmenting (%d > %d)",msgLength,maxFrameLength); |
|
253 |
|
254 frameLength = maxFrameLength; |
|
255 bpFrame->CompleteWhenSent() = EFalse; |
|
256 } |
|
257 else |
|
258 { |
|
259 _LOG_L4C1("No Fragment"); |
|
260 |
|
261 frameLength = msgLength; |
|
262 bpFrame->CompleteWhenSent() = ETrue; |
|
263 endFlag = ETrue; |
|
264 } |
|
265 |
|
266 // Test for convergence layer 4 |
|
267 CPortC32InterfaceBase* port = |
|
268 iPortFactory.FindPortC32Interface(aDlcNum); |
|
269 if (port) |
|
270 { |
|
271 if (port->GetClientType() == CPortFactory::EC32ClientIpNif) |
|
272 { |
|
273 _LOG_L4C1("Layer 4 frame"); |
|
274 |
|
275 Create0710UIHLayer4FrameFromMsg(aMsgBuf, offset, |
|
276 bpFrame, frameLength, aDlcNum, beginFlag, endFlag); |
|
277 |
|
278 // No longer the beginning |
|
279 beginFlag = EFalse; |
|
280 } |
|
281 else |
|
282 { |
|
283 _LOG_L4C1("Normal frame"); |
|
284 |
|
285 Create0710UIHFrameFromMsg( |
|
286 aMsgBuf, offset, bpFrame, frameLength, aDlcNum); |
|
287 } |
|
288 |
|
289 _LOG_L4C1("Writing the frame"); |
|
290 ret = iCommWriter->Write(bpFrame); |
|
291 } |
|
292 else |
|
293 { |
|
294 _LOG_L1C2("** No port defined for aDlcNum=%d", |
|
295 aDlcNum); |
|
296 } |
|
297 } |
|
298 else |
|
299 { |
|
300 // error no free frame available |
|
301 _LOG_L1C1("** No free frame buffer **"); |
|
302 ret = KErrNoMemory; |
|
303 } |
|
304 |
|
305 msgLength -= frameLength; |
|
306 offset += maxFrameLength; |
|
307 } |
|
308 } |
|
309 else |
|
310 { |
|
311 ret = KErrArgument; |
|
312 } |
|
313 |
|
314 _LOG_L4C2("<<CMux0710Protocol::Create0710DataFrames [ret=%d]",ret); |
|
315 return ret; |
|
316 } |
|
317 |
|
318 void CMux0710Protocol::Create0710UIHFrameFromMsg(TDesC8& aMsgBuf, |
|
319 TInt aOffset, |
|
320 CCsyMsgBufBpFrame* aFrameBuf, |
|
321 TInt aLength, |
|
322 TUint8 aDlcNum) |
|
323 /** |
|
324 * This method creates an 27.010 UIH frame from a message. |
|
325 * NOTE: This method assumes that a free frame buffer has been allocated. |
|
326 * |
|
327 * @param aMsgBuf - Pointer to a CSY memory element pointing to a Msg |
|
328 * @param aOffset - Offset from the start of the message to be copied to the frame. |
|
329 * This is needed if the calling method needs to defragment a long message. |
|
330 * @param aFrameBuf - Pointer to a CSY memory elelemt pointing to a Frame |
|
331 * @param aLength - Length of the payload to be copied. |
|
332 * @param aDlcNum - DLC channel number. |
|
333 */ |
|
334 { |
|
335 _LOG_L4C3(">>CMux0710Protocol::Create0710UIHFrameFromMsg [aOffset=%d,aLength=%d]",aOffset,aLength); |
|
336 |
|
337 aFrameBuf->iMsg.Zero(); |
|
338 |
|
339 // set initial length for headers |
|
340 #ifdef _27010ADVANCEOPTION |
|
341 aFrameBuf->iMsg.SetLength(3); |
|
342 #else |
|
343 aFrameBuf->iMsg.SetLength(4); |
|
344 #endif |
|
345 |
|
346 // Octet 0 = Start Flag |
|
347 aFrameBuf->iMsg[0] = KCsy0710StartEndFlag; |
|
348 |
|
349 // Octet 1 = Non-extended Address, Command/Response, DLCI number |
|
350 aFrameBuf->iMsg[1] = (TUint8) ((aDlcNum << 2) | 0x03); // Set the DLCI, EA, C/R |
|
351 |
|
352 // Octet 2 = Control Field = Frame Type (UIH) |
|
353 aFrameBuf->iMsg[2] = (TUint8) KCsy0710CTLUIH; |
|
354 |
|
355 |
|
356 #ifdef _27010ADVANCEOPTION |
|
357 TInt checksumLength = 2; |
|
358 #else |
|
359 // Octet 3 = Length indicator |
|
360 // ASSUME only 1 byte needed for length size |
|
361 // 27.010 supports 7 bits in Octet 3 to indicate a length up to 128 bytes long |
|
362 aFrameBuf->iMsg[3] = (TUint8) ((aLength << 1) | KCsy0710EA); |
|
363 |
|
364 |
|
365 // CRC Frame check : Basic Option -> for Addr, Control, Length Fields only |
|
366 // length = 3 bytes [Addr(1) + Control(1) + Length (1)] |
|
367 TInt checksumLength = 3; |
|
368 #endif |
|
369 TUint8 checksum; |
|
370 checksum = (TUint8) CalcFCS(&aFrameBuf->iMsg[0], checksumLength); |
|
371 |
|
372 // Octet 5-x |
|
373 //CCsyMsgBufClient* csyMsgBufClient = STATIC_CAST(CCsyMsgBufClient*, aMsgBuf); |
|
374 const TUint8* temp = &aMsgBuf[aOffset]; |
|
375 aFrameBuf->iMsg.Append(temp, aLength); |
|
376 TInt tempLength = aFrameBuf->iMsg.Length(); |
|
377 aFrameBuf->iMsg.SetLength(tempLength + 2); |
|
378 aFrameBuf->iMsg[tempLength] = checksum; |
|
379 aFrameBuf->iMsg[tempLength+1] = KCsy0710StartEndFlag; |
|
380 |
|
381 _LOG_L4C1("<<CMux0710Protocol::Create0710UIHFrameFromMsg"); |
|
382 } |
|
383 |
|
384 void CMux0710Protocol::Create0710UIHLayer4FrameFromMsg(TDesC8& aMsgBuf, |
|
385 TInt aOffset, |
|
386 CCsyMsgBufBpFrame* aFrameBuf, |
|
387 TInt aLength, |
|
388 TUint8 aDlcNum, |
|
389 TBool aLayer4Begin, |
|
390 TBool aLayer4End) |
|
391 /** |
|
392 * This method creates an 27.010 UIH frame from a message. |
|
393 * NOTE: This method assumes that a free frame buffer has been allocated. |
|
394 * |
|
395 * @param aMsgBuf - Pointer to a CSY memory element pointing to a Msg |
|
396 * @param aOffset - Offset from the start of the message to be copied to the frame. |
|
397 * This is needed if the calling method needs to defragment a long message. |
|
398 * This method builds the message as a Convergence Layer 4 type, so |
|
399 * only Advanced Option. |
|
400 * @param aFrameBuf - Pointer to a CSY memory elelemt pointing to a Frame |
|
401 * @param aLength - Length of the payload to be copied. |
|
402 * @param aDlcNum - DLC channel number. |
|
403 * @param aLayer4Begin - Beginning of Convergence Layer 4. |
|
404 * @param aLayer4End - End of Convergence Layer 4. |
|
405 */ |
|
406 { |
|
407 _LOG_L4C3(">>CMux0710Protocol::Create0710UIHLayer4FrameFromMsg [aOffset=%d,aLength=%d]",aOffset,aLength); |
|
408 _LOG_L4C3("[aLayer4Begin=%d,aLayer4End=%d]",aLayer4Begin,aLayer4End); |
|
409 |
|
410 //aFrameBuf->iMsg.Zero(); - this is done in GetFreeFrameBuf |
|
411 |
|
412 // set initial length for headers |
|
413 aFrameBuf->iMsg.SetLength(3); |
|
414 |
|
415 // Octet 0 = Start Flag |
|
416 aFrameBuf->iMsg[0] = KCsy0710StartEndFlag; |
|
417 |
|
418 // Octet 1 = Non-extended Address, Command/Response, DLCI number |
|
419 aFrameBuf->iMsg[1] = (TUint8) ((aDlcNum << 2) | 0x03); // Set the DLCI, EA, C/R |
|
420 |
|
421 // Octet 2 = Control Field = Frame Type (UIH) |
|
422 aFrameBuf->iMsg[2] = (TUint8) KCsy0710CTLUIH; |
|
423 |
|
424 TInt checksumLength = 2; |
|
425 TUint8 checksum; |
|
426 checksum = (TUint8) CalcFCS(&aFrameBuf->iMsg[0], checksumLength); |
|
427 |
|
428 // Octet 5-x |
|
429 // Build the Convergence Layer 4 byte |
|
430 TUint8 tempLayer4Byte = 0x01; // Default Middle Frame fragment |
|
431 if (aLayer4Begin && aLayer4End) // Begin and End - Single Frame Message |
|
432 { |
|
433 tempLayer4Byte = 0xC1; // MAF magic numbers |
|
434 } |
|
435 else if (aLayer4Begin) // Begin Frame |
|
436 { |
|
437 tempLayer4Byte = 0x41; |
|
438 } |
|
439 else if (aLayer4End) // End Frame |
|
440 { |
|
441 tempLayer4Byte = 0x81; |
|
442 } |
|
443 aFrameBuf->iMsg.Append(tempLayer4Byte); |
|
444 |
|
445 const TUint8* temp = &aMsgBuf[aOffset]; |
|
446 aFrameBuf->iMsg.Append(temp, aLength); |
|
447 TInt tempLength = aFrameBuf->iMsg.Length(); |
|
448 |
|
449 aFrameBuf->iMsg.SetLength(tempLength + 2); |
|
450 aFrameBuf->iMsg[tempLength] = checksum; |
|
451 aFrameBuf->iMsg[tempLength+1] = KCsy0710StartEndFlag; |
|
452 |
|
453 DumpFrame(aFrameBuf); |
|
454 |
|
455 _LOG_L4C1("<<CMux0710Protocol::Create0710UIHLayer4FrameFromMsg"); |
|
456 } |
|
457 |
|
458 TInt CMux0710Protocol::Create0710ControlFrame(TCsyFrameType aFrameType, |
|
459 TUint8 aDlcNum, |
|
460 TCsyCtrlCommand aType, |
|
461 TUint8 aV24Signals) |
|
462 /** |
|
463 * This method creates an 27.010 control frame using the specified frame type |
|
464 * and DLC number. |
|
465 * NOTE: This method assumes that a free frame buffer has been allocated. |
|
466 * |
|
467 * @param aFrameType - Frame type of the control frame |
|
468 * @param aDlcNum - DLC number of this frame |
|
469 * @return KErrNone or KErrGeneral |
|
470 */ |
|
471 { |
|
472 _LOG_L4C2(">>CMux0710Protocol::Create0710ControlFrame [aDlcNum=%d]",aDlcNum); |
|
473 |
|
474 TInt ret = KErrNone; |
|
475 |
|
476 if (iMaxRetriesReached == EFalse) |
|
477 { |
|
478 |
|
479 #ifdef _27010ADVANCEOPTION |
|
480 TUint8 tempArray[15]; // MAF magic numbers |
|
481 #else |
|
482 TUint8 tempArray[8]; |
|
483 #endif |
|
484 |
|
485 // Octet 0 = Start Flag |
|
486 tempArray[0] = KCsy0710StartEndFlag; |
|
487 |
|
488 // Octet 1 = Non-extended Address, initiating end (Command/Response), DLCI number |
|
489 tempArray[1] = (TUint8) ((aDlcNum << 2) | 0x03); // Set the DLCI, EA, C/R |
|
490 |
|
491 // Octet 2 = Frame Type |
|
492 switch (aFrameType) |
|
493 { |
|
494 case ESABM: |
|
495 _LOG_L3C1("ESABM"); |
|
496 tempArray[2] = (TUint8) KCsy0710CTLSABM; |
|
497 tempArray[2] |= KCsy0710PollFinal; |
|
498 break; |
|
499 case EUA: |
|
500 _LOG_L3C1("EUA"); |
|
501 tempArray[1] = (TUint8) ((aDlcNum << 2) | 0x01); // Set the DLCI, EA |
|
502 tempArray[2] = (TUint8) KCsy0710CTLUA; |
|
503 break; |
|
504 case EDM: |
|
505 _LOG_L3C1("EDM"); |
|
506 tempArray[1] = (TUint8) ((aDlcNum << 2) | 0x01); // Set the DLCI, EA |
|
507 tempArray[2] = (TUint8) KCsy0710CTLDM; |
|
508 break; |
|
509 case EDISC: |
|
510 _LOG_L3C1("EDISC"); |
|
511 tempArray[2] = (TUint8) KCsy0710CTLDISC; |
|
512 tempArray[2] |= KCsy0710PollFinal; |
|
513 break; |
|
514 case EUIH: |
|
515 _LOG_L3C1("EUIH"); |
|
516 tempArray[2] = (TUint8) KCsy0710CTLUIH; |
|
517 tempArray[2] |= KCsy0710PollFinal; // no pollbit |
|
518 break; |
|
519 case EUI: |
|
520 _LOG_L3C1("EUI"); |
|
521 tempArray[2] = (TUint8) KCsy0710CTLUI; |
|
522 break; |
|
523 default: |
|
524 _LOG_L1C2("** Unknown FrameType=%d **",aFrameType); |
|
525 ret = KErrGeneral; |
|
526 break; |
|
527 } |
|
528 |
|
529 #ifndef _27010ADVANCEOPTION |
|
530 |
|
531 (void) aType; //to hide warning. |
|
532 (void) aV24Signals; //to hide warning. |
|
533 |
|
534 // Octet 3 = Length1 indicator octet1 |
|
535 tempArray[3] = (TUint8) 0x01; // zero length and set EA bit |
|
536 |
|
537 // CRC Frame check : Basic Option -> for Addr, Control, Length Fields only |
|
538 // length = 4 bytes [Addr(1) + Control(1) + Length (2)] |
|
539 TInt length = 3; |
|
540 tempArray[4] = (TUint8) CalcFCS(tempArray, length); |
|
541 tempArray[5] = KCsy0710StartEndFlag; |
|
542 |
|
543 // For this call of GetFreeFrameBuf do not check the low frame threshold |
|
544 // since control frame and it could be related to an already occurring flow |
|
545 // control action anyway. |
|
546 CCsyMsgBufBpFrame* ctrlFrame = GetFreeFrameBuf(EFalse); |
|
547 if (ctrlFrame) |
|
548 { |
|
549 ctrlFrame->iMsg.Copy(tempArray, 6); |
|
550 iCommWriter->Write(ctrlFrame); // MAF should be high priority frame |
|
551 } |
|
552 #else |
|
553 |
|
554 if (aFrameType == EUIH) |
|
555 { |
|
556 // Set the DLCI to 0 |
|
557 tempArray[1] = 0x03; // Set the DLCI to 0, EA, C/R |
|
558 } |
|
559 |
|
560 TUint8 checkSum; |
|
561 TInt length = 2; |
|
562 checkSum = (TUint8) CalcFCS(tempArray, length); |
|
563 |
|
564 if (aFrameType == EUIH) |
|
565 { |
|
566 // Only two types of control UIH supported |
|
567 if (aType == EParamNeg) |
|
568 { |
|
569 _LOG_L3C1("Param Negotiate"); |
|
570 |
|
571 tempArray[3] = KCsy0710CTLUIH_DlcParamNegotiate; |
|
572 tempArray[4] = 0x11; // i.e 8 bytes, EA |
|
573 tempArray[5] = aDlcNum; |
|
574 tempArray[6] = (KPNClBits << 4) + KPNFrameType; |
|
575 tempArray[7] = KPNDlcPriority; |
|
576 tempArray[8] = KPNAckTimer; |
|
577 tempArray[9] = KPNMaxFrameSize & 0x00ff; |
|
578 tempArray[10] = KPNMaxFrameSize >> 8; |
|
579 tempArray[11] = KPNMaxRetransmissions; |
|
580 tempArray[12] = KPNWindowSize; |
|
581 tempArray[13] = checkSum; |
|
582 tempArray[14] = KCsy0710StartEndFlag; |
|
583 |
|
584 iParamNegotiateDlcNum = aDlcNum; |
|
585 } |
|
586 else |
|
587 { |
|
588 _LOG_L3C2("MSC aV24Signals=0x%x", aV24Signals); |
|
589 |
|
590 tempArray[3] = KCsy0710CTLUIH_ModemStatusCmd; |
|
591 tempArray[4] = 0x05; // i.e 2 bytes, EA |
|
592 tempArray[5] = (TUint8) ((aDlcNum << 2) | 0x03); // Set the DLCI, EA, 1 |
|
593 tempArray[6] = aV24Signals; |
|
594 tempArray[7] = checkSum; |
|
595 tempArray[8] = KCsy0710StartEndFlag; |
|
596 } |
|
597 } |
|
598 else |
|
599 { |
|
600 tempArray[3] = checkSum; |
|
601 tempArray[4] = KCsy0710StartEndFlag; |
|
602 } |
|
603 |
|
604 CCsyMsgBufBpFrame* ctrlFrame = GetFreeFrameBuf(EFalse); |
|
605 if (ctrlFrame) |
|
606 { |
|
607 #ifdef _27010ADVANCEOPTION |
|
608 if (aFrameType == EUIH) |
|
609 { |
|
610 if (aType == EParamNeg) |
|
611 { |
|
612 ctrlFrame->iMsg.Copy(tempArray, 15); |
|
613 } |
|
614 else |
|
615 { |
|
616 ctrlFrame->iMsg.Copy(tempArray, 9); |
|
617 } |
|
618 } |
|
619 else |
|
620 { |
|
621 ctrlFrame->iMsg.Copy(tempArray, 5); |
|
622 } |
|
623 #else |
|
624 ctrlFrame->iMsg.Copy(tempArray, 5); |
|
625 #endif |
|
626 |
|
627 _LOG_L3C1("Write the frame"); |
|
628 iCommWriter->Write(ctrlFrame); // MAF should be high priority frame |
|
629 } |
|
630 #endif |
|
631 else |
|
632 { // no memory available |
|
633 _LOG_L1C1("** No Memory Available **"); |
|
634 ret = KErrNoMemory; |
|
635 } |
|
636 } |
|
637 else |
|
638 { |
|
639 _LOG_L1C1("** Max Retries Reached **"); |
|
640 ret = KErrTimedOut; |
|
641 } |
|
642 _LOG_L4C2("<<CMux0710Protocol::Create0710ControlFrame [ret=%d]",ret); |
|
643 return ret; |
|
644 } |
|
645 |
|
646 TInt CMux0710Protocol::SwitchToMuxMode() |
|
647 /** |
|
648 * This method is called to switch the baseband to multiplexer mode. |
|
649 * This method formats the AT command the buffer with the AT+CMUX command |
|
650 * and writes to the write FrameBuf List. |
|
651 * |
|
652 * @return KErrNone or KErrNoMemory |
|
653 */ |
|
654 { |
|
655 _LOG_L4C1(">>CMux0710Protocol::SwitchToMuxMode"); |
|
656 |
|
657 #ifdef __CSY_PROTOTYPE__ |
|
658 iMuxMgrState = ECsyMuxEnabled; |
|
659 #else |
|
660 |
|
661 if(iMuxMgrState == ECsyWaitingForFlushResp) |
|
662 { |
|
663 //flush the read queue. |
|
664 iTimeouter->Start(KOneSecond); |
|
665 return KErrNone; |
|
666 } |
|
667 else |
|
668 { |
|
669 iTimeouter->Start(KTwoSeconds); |
|
670 } |
|
671 |
|
672 TInt ret = KErrNone; |
|
673 |
|
674 CCsyMsgBufBpFrame* initBuf = GetFreeFrameBuf(); |
|
675 if (initBuf) |
|
676 { |
|
677 |
|
678 #ifdef USE_TI_CONDAT_STACK |
|
679 if(iMuxMgrState == ECsyWaitingForResetResp) |
|
680 { |
|
681 //when using the TI stack we first attempt to reset the board using at%b. |
|
682 _LOG_L3C1("Sending AT reset command"); |
|
683 TBuf8<16> aBuf(KATCmdReset); |
|
684 initBuf->iMsg.Copy(aBuf); |
|
685 iMuxMgrState = ECsyWaitingForResetResp; |
|
686 } |
|
687 else if(iMuxMgrState == ECsyWaitingForSleepResp) |
|
688 { |
|
689 //Need to ensure that the TI stack will not timeout in the lull between commands |
|
690 _LOG_L3C1("Sending AT sleep command"); |
|
691 TBuf8<16> aBuf(KATCmdSleep); |
|
692 initBuf->iMsg.Copy(aBuf); |
|
693 iMuxMgrState = ECsyWaitingForSleepResp; |
|
694 } |
|
695 else |
|
696 { |
|
697 #endif |
|
698 _LOG_L3C1("Sending AT"); |
|
699 TBuf8<16> aBuf(KATCmdAttention); |
|
700 initBuf->iMsg.Copy(aBuf); |
|
701 iMuxMgrState = ECsyWaitingForAttentionResp; |
|
702 |
|
703 #ifdef USE_TI_CONDAT_STACK |
|
704 } |
|
705 #endif |
|
706 iResponseStr.Zero(); |
|
707 |
|
708 // call comm write to xmit frame |
|
709 // comm writer's RunL will run when frame has been xmitted by LDD |
|
710 // and return the frame buffer to the free list |
|
711 ret = iCommWriter->Write(initBuf); |
|
712 } |
|
713 else |
|
714 { |
|
715 _LOG_L1C1("** No Memory Available **"); |
|
716 ret = KErrNoMemory; |
|
717 } |
|
718 #endif |
|
719 |
|
720 _LOG_L4C2("<<CMux0710Protocol::SwitchToMuxMode [ret=%d]",ret); |
|
721 return ret; |
|
722 } |
|
723 |
|
724 TInt CMux0710Protocol::ParseATResponse(TDes8& aResp) |
|
725 /** |
|
726 * This method parses the specified AT ascii response for the |
|
727 * expected ascii "OK" string. If the string is found then set |
|
728 * the Mux Mode to True. |
|
729 * |
|
730 * @param aResp - Reference to the AT response string to parse |
|
731 * @return KErrNone, KErrGeneral or KErrNotFound |
|
732 */ |
|
733 { |
|
734 _LOG_L4C3(">>CMux0710Protocol::ParseATResponse [iMuxMgrState = %d, aResp=%S]", |
|
735 iMuxMgrState,&aResp); |
|
736 |
|
737 //Response string not always read in one go so concatonate it together to form full response string. |
|
738 TInt appendsize = iResponseStr.MaxSize() - iResponseStr.Length(); |
|
739 iResponseStr.Append(aResp.LeftTPtr(appendsize)); |
|
740 _LOG_L4C2("Result string concatenated = %S",&iResponseStr); |
|
741 |
|
742 if(iMuxMgrState == ECsyWaitingForFlushResp) |
|
743 { |
|
744 _LOG_L4C2("Flushed comm port on opening = %S",&iResponseStr); |
|
745 return KErrNotFound; |
|
746 } |
|
747 |
|
748 #ifdef USE_TI_CONDAT_STACK |
|
749 if(iMuxMgrState == ECsyWaitingForResetResp) |
|
750 { |
|
751 if(iResponseStr.Find(KATInitialised) != KErrNotFound) |
|
752 { |
|
753 //got match - reset Rsp string to enter normal loop handle |
|
754 _LOG_L3C1("Board has successfully been reset."); |
|
755 iResponseStr = _L8("OK"); |
|
756 iRetryCount = 0; // stop retries of the reset |
|
757 } |
|
758 } |
|
759 |
|
760 if(iMuxMgrState == ECsyWaitingForSleepResp) |
|
761 { |
|
762 if(iResponseStr.Find(_L8("OK")) != KErrNotFound) |
|
763 { |
|
764 //got match - sleep acknowledged |
|
765 _LOG_L3C1("Board has had sleep timeout disabled."); |
|
766 iRetryCount = 0; //stop retries of the sleep; |
|
767 } |
|
768 } |
|
769 #endif |
|
770 |
|
771 TInt ret = KErrNone; |
|
772 |
|
773 // all AT responses should contain an "OK" keyword |
|
774 if ((iResponseStr.Find(_L8("OK")) != KErrNotFound) || |
|
775 (iResponseStr.Find(_L8("ERROR")) != KErrNotFound)) |
|
776 { |
|
777 if (iResponseStr.Find(_L8("ERROR")) != KErrNotFound) |
|
778 { |
|
779 #ifdef USE_TI_CONDAT_STACK |
|
780 if(iMuxMgrState == ECsyWaitingForResetResp) |
|
781 { |
|
782 _LOG_L3C1("*******TI Board failed to reset (AT%b) - continue anyway as may already be in a stable state.*******"); |
|
783 iRetryCount--; |
|
784 } |
|
785 else if (iMuxMgrState == ECsyWaitingForSleepResp) |
|
786 { |
|
787 _LOG_L3C1("*******TI Board failed to acknowledge sleep disable (AT%SLEEP=0) - continue anyway as may already be in a stable state.*******"); |
|
788 iRetryCount--; |
|
789 } |
|
790 else |
|
791 { |
|
792 _LOG_L3C1("****************** Received ERROR back ****************"); |
|
793 } |
|
794 #else |
|
795 _LOG_L3C1("****************** Received ERROR back ****************"); |
|
796 #endif |
|
797 } |
|
798 iTimeouter->Stop(); |
|
799 |
|
800 switch (iMuxMgrState) |
|
801 { |
|
802 #ifdef USE_TI_CONDAT_STACK |
|
803 case ECsyWaitingForResetResp: |
|
804 { |
|
805 _LOG_L3C1("ECsyWaitingForResetResp - Start proper init sequence."); |
|
806 if(iRetryCount>0) |
|
807 iMuxMgrState = ECsyWaitingForResetResp; //try reset command again |
|
808 else |
|
809 { |
|
810 iMuxMgrState = ECsyWaitingForSleepResp; |
|
811 iRetryCount = KRetryCount; |
|
812 } |
|
813 SwitchToMuxMode(); |
|
814 } |
|
815 break; |
|
816 |
|
817 case ECsyWaitingForSleepResp: |
|
818 { |
|
819 iResponseStr.Zero(); |
|
820 _LOG_L3C1("ECsyWaitingForSleepResp"); |
|
821 if(iRetryCount>0) |
|
822 iMuxMgrState = ECsyWaitingForSleepResp; |
|
823 else |
|
824 iMuxMgrState = ECsyWaitingForAttentionResp; |
|
825 SwitchToMuxMode(); |
|
826 } |
|
827 break; |
|
828 #endif |
|
829 case ECsyWaitingForAttentionResp: |
|
830 { |
|
831 iResponseStr.Zero(); |
|
832 CCsyMsgBufBpFrame* atCmdBuf = GetFreeFrameBuf(); |
|
833 if (atCmdBuf) |
|
834 { |
|
835 _LOG_L3C1("Writing ATE0 command"); |
|
836 atCmdBuf->iMsg.Copy(KATCmdDisableEcho); |
|
837 iCommWriter->Write(atCmdBuf); |
|
838 iMuxMgrState = ECsyWaitingForEchoDisableResp; |
|
839 } |
|
840 |
|
841 iTimeouter->Start(KTwoSeconds); |
|
842 } |
|
843 break; |
|
844 |
|
845 case ECsyWaitingForEchoDisableResp: |
|
846 { |
|
847 iResponseStr.Zero(); |
|
848 CCsyMsgBufBpFrame* atCmdBuf = GetFreeFrameBuf(); |
|
849 if (atCmdBuf) |
|
850 { |
|
851 _LOG_L3C1("Writing CMUX cmd"); |
|
852 atCmdBuf->iMsg.Copy(KCsyDefaultATEnterMuxModeCmd); |
|
853 iCommWriter->Write(atCmdBuf); |
|
854 iMuxMgrState = ECsyWaitingForCmuxResp; |
|
855 } |
|
856 |
|
857 iTimeouter->Start(KTwoSeconds); |
|
858 } |
|
859 break; |
|
860 |
|
861 case ECsyWaitingForCmuxResp: |
|
862 { |
|
863 iResponseStr.Zero(); |
|
864 _LOG_L3C1("Got CMUX response"); |
|
865 iMuxMgrState = ECsyMuxEnabled; |
|
866 |
|
867 // start the connect process for the control, command & data channels |
|
868 iPortFactory.ConnectControlChannel(); |
|
869 } |
|
870 break; |
|
871 |
|
872 default: |
|
873 _LOG_L3C2("** Invalid Mux Mgr State = %d **", iMuxMgrState); |
|
874 ret = KErrGeneral; |
|
875 break; |
|
876 } |
|
877 } |
|
878 else |
|
879 { |
|
880 ret = KErrNotFound; |
|
881 } |
|
882 |
|
883 _LOG_L4C2("<<CMux0710Protocol::ParseATResponse [ret = %d]",ret); |
|
884 return ret; |
|
885 } |
|
886 |
|
887 void CMux0710Protocol::TimedOut() |
|
888 /** |
|
889 * This resends the AT command required. |
|
890 */ |
|
891 { |
|
892 _LOG_L4C2(">>CMux0710Protocol::TimedOut [iMuxMgrState=%d]",iMuxMgrState); |
|
893 |
|
894 switch (iMuxMgrState) |
|
895 { |
|
896 |
|
897 case ECsyWaitingForFlushResp: |
|
898 { |
|
899 //read queue has just been flushed, now start switch to MUX mode |
|
900 _LOG_L3C1("ECsyWaitingForFlushResp"); |
|
901 #ifdef USE_TI_CONDAT_STACK |
|
902 iMuxMgrState = ECsyWaitingForResetResp; |
|
903 #else |
|
904 iMuxMgrState = ECsyWaitingForAttentionResp; |
|
905 #endif |
|
906 SwitchToMuxMode(); |
|
907 } |
|
908 break; |
|
909 #ifdef USE_TI_CONDAT_STACK |
|
910 case ECsyWaitingForResetResp: |
|
911 { |
|
912 _LOG_L3C1("ECsyWaitingForResetResp"); |
|
913 if(--iRetryCount>0) |
|
914 iMuxMgrState = ECsyWaitingForResetResp; //try reset command again |
|
915 else |
|
916 iMuxMgrState = ECsyWaitingForSleepResp; |
|
917 SwitchToMuxMode(); |
|
918 } |
|
919 break; |
|
920 |
|
921 case ECsyWaitingForSleepResp: |
|
922 { |
|
923 _LOG_L3C1("ECsyWaitingForSleepResp"); |
|
924 if(--iRetryCount>0) |
|
925 iMuxMgrState = ECsyWaitingForSleepResp; //try sleep command again |
|
926 else |
|
927 iMuxMgrState = ECsyWaitingForAttentionResp; |
|
928 SwitchToMuxMode(); |
|
929 } |
|
930 break; |
|
931 #endif |
|
932 case ECsyWaitingForAttentionResp: |
|
933 { |
|
934 if (++iAtResponseTimeout < KAtResponseTimeoutLimit) |
|
935 { |
|
936 _LOG_L3C2("ECsyWaitingForAttentionResp [timeout:%d]",iAtResponseTimeout); |
|
937 SwitchToMuxMode(); |
|
938 } |
|
939 else |
|
940 { |
|
941 _LOG_L3C2("Max retries [%d] reached for At Response", KAtResponseTimeoutLimit); |
|
942 |
|
943 iMaxRetriesReached = ETrue; |
|
944 //call to scheduler DoCancel required here |
|
945 iPortFactory.ChannelCtrlDoCancel(); |
|
946 } |
|
947 } |
|
948 break; |
|
949 |
|
950 case ECsyWaitingForEchoDisableResp: |
|
951 { |
|
952 _LOG_L3C1("ECsyWaitingForEchoDisableResp"); |
|
953 iResponseStr.Zero(); |
|
954 CCsyMsgBufBpFrame* atCmdBuf = NULL; |
|
955 atCmdBuf = GetFreeFrameBuf(); |
|
956 if (atCmdBuf) |
|
957 { |
|
958 TBuf8<16> tempBuf(KATCmdDisableEcho); |
|
959 atCmdBuf->iMsg.Copy(tempBuf); |
|
960 iCommWriter->Write(atCmdBuf); |
|
961 } |
|
962 |
|
963 iTimeouter->Start(KOneSecond); |
|
964 } |
|
965 break; |
|
966 |
|
967 case ECsyWaitingForCmuxResp: |
|
968 { |
|
969 _LOG_L3C1("ECsyWaitingForCmuxResp"); |
|
970 iResponseStr.Zero(); |
|
971 CCsyMsgBufBpFrame* atCmdBuf = GetFreeFrameBuf(); |
|
972 if (atCmdBuf) |
|
973 { |
|
974 _LOG_L3C1("Writing CMUX cmd"); |
|
975 atCmdBuf->iMsg.Copy(KCsyDefaultATEnterMuxModeCmd); |
|
976 iCommWriter->Write(atCmdBuf); |
|
977 iMuxMgrState = ECsyWaitingForCmuxResp; |
|
978 } |
|
979 iTimeouter->Start(KTwoSeconds); |
|
980 } |
|
981 break; |
|
982 |
|
983 default: |
|
984 _LOG_L1C2("** Invalid Mux Mgr State = %d **", iMuxMgrState); |
|
985 break; |
|
986 } |
|
987 |
|
988 _LOG_L4C1("<<CMux0710Protocol::TimedOut"); |
|
989 } |
|
990 |
|
991 void CMux0710Protocol::DumpFrame(CCsyMsgBufBpFrame* aFrameBuf) |
|
992 /** |
|
993 * Logs the packet into the log file. |
|
994 * |
|
995 * @param aPacket The incoming packet |
|
996 */ |
|
997 { |
|
998 _LOG_L4C1(">>CMux0710Protocol::DumpFrame"); |
|
999 |
|
1000 TInt packetLen = aFrameBuf->iMsg.Length(); |
|
1001 _LOG_L4C2("frame length %d",packetLen); |
|
1002 |
|
1003 TBuf8<256> logBuf; |
|
1004 TBuf8<256> logBuf2; |
|
1005 |
|
1006 logBuf.Copy(_L8(" ")); |
|
1007 logBuf2.Copy(_L8(" ")); |
|
1008 _LOG_L4C1(""); |
|
1009 |
|
1010 for (TInt i = 0; i <= packetLen; i++) |
|
1011 { |
|
1012 if (i >= packetLen) |
|
1013 { |
|
1014 logBuf.Append(logBuf2); |
|
1015 _LOG_L4C2("%S",&logBuf); |
|
1016 break; |
|
1017 } |
|
1018 if (((i % 16) == 0) && (i > 0)) |
|
1019 { |
|
1020 logBuf.Append(logBuf2); |
|
1021 _LOG_L4C2("%S",&logBuf); |
|
1022 logBuf.Copy(_L8(" ")); |
|
1023 logBuf2.Copy(_L8(" ")); |
|
1024 } |
|
1025 logBuf.AppendFormat(_L8("%02X "), aFrameBuf->iMsg[i]); |
|
1026 if (TChar(aFrameBuf->iMsg[i]).IsPrint()) |
|
1027 logBuf2.AppendFormat(_L8("%c"), aFrameBuf->iMsg[i]); |
|
1028 else |
|
1029 logBuf2.Append(_L8(".")); |
|
1030 } |
|
1031 |
|
1032 _LOG_L4C1("<<CMux0710Protocol::DumpFrame"); |
|
1033 _LOG_L4C1(""); |
|
1034 } |
|