|
1 // Copyright (c) 1997-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 "PPPBASE.H" |
|
17 |
|
18 // Options are based on aligned MBuf Chains. |
|
19 // Steps are taken to guarantee that the first 128 bytes |
|
20 // of an option are held in the first MBuf |
|
21 |
|
22 RPppOption::RPppOption() |
|
23 { |
|
24 } |
|
25 |
|
26 RPppOption::RPppOption(RMBufChain& aChain) |
|
27 // |
|
28 // Note: this empties the original chain |
|
29 // |
|
30 { |
|
31 Assign(aChain); |
|
32 Align(KMBufSmallSize); |
|
33 } |
|
34 |
|
35 void RPppOption::SetL(TUint8 aType, const TAny* aPtr, TInt aLen) |
|
36 { |
|
37 |
|
38 aLen += 2; |
|
39 |
|
40 if (aLen>MaxLength()) |
|
41 { |
|
42 Free(); |
|
43 AllocL(aLen); |
|
44 } |
|
45 else |
|
46 SetLength(aLen); |
|
47 |
|
48 First()->Put(aType, 0); |
|
49 First()->Put((TUint8)aLen, 1); |
|
50 if (aLen>0) |
|
51 CopyIn(TPtrC8((TUint8*)aPtr, aLen-2), 2); |
|
52 } |
|
53 |
|
54 void RPppOption::SetValueLength(TInt aLen) |
|
55 { |
|
56 aLen += 2; |
|
57 ASSERT(aLen<=KMBufSmallSize); |
|
58 First()->Put((TUint8)aLen, 1); |
|
59 First()->SetLength(aLen); |
|
60 } |
|
61 |
|
62 TUint8 RPppOption::OptType() const |
|
63 { |
|
64 return First()->Get(0); |
|
65 } |
|
66 |
|
67 void RPppOption::SetType(const TUint8 aType) |
|
68 { |
|
69 TUint8* Ptr; |
|
70 |
|
71 Ptr = First()->Ptr(); |
|
72 *Ptr = aType; |
|
73 } |
|
74 |
|
75 TInt RPppOption::ValueLength() const |
|
76 { |
|
77 return First()->Get(1)-2; |
|
78 } |
|
79 |
|
80 TUint8* RPppOption::ValuePtr() |
|
81 { |
|
82 return First()->Ptr()+2; |
|
83 } |
|
84 |
|
85 const TUint8* RPppOption::ValuePtr() const |
|
86 { |
|
87 return First()->Ptr()+2; |
|
88 } |
|
89 |
|
90 /** |
|
91 Re-aligns the underlying storage in an MBuf chain |
|
92 droppng any MBufs that are no longer needed |
|
93 DOES NOT preserve data. |
|
94 */ |
|
95 TInt RPppOption::SetLength(TInt aLength) |
|
96 { |
|
97 RMBuf* p = NULL; |
|
98 RMBuf* m = First(); |
|
99 while (m!=NULL && aLength>0) |
|
100 { |
|
101 TInt n = m->Size(); |
|
102 aLength -= n; |
|
103 m->SetData(0, n); |
|
104 if (aLength<0) |
|
105 m->AdjustEnd(aLength); |
|
106 p = m; |
|
107 m = m->Next(); |
|
108 } |
|
109 if (m!=NULL && p!=NULL) |
|
110 { |
|
111 p->Unlink(); |
|
112 m->Free(); |
|
113 } |
|
114 if (aLength>0) |
|
115 return KErrGeneral; |
|
116 return KErrNone; |
|
117 } |
|
118 |
|
119 /** |
|
120 Return the size of underlying storage in an MBuf chain |
|
121 */ |
|
122 TInt RPppOption::MaxLength() const |
|
123 { |
|
124 TInt len = 0; |
|
125 const RMBuf* m = First(); |
|
126 while (m!=NULL) |
|
127 { |
|
128 len += m->Size(); |
|
129 m = m->Next(); |
|
130 } |
|
131 return len; |
|
132 } |
|
133 |
|
134 void RPppOptionList::SetL(RMBufChain& aPacket, TInt aLength) |
|
135 { |
|
136 CleanupStack::PushL(*this); |
|
137 CleanupStack::PushL(aPacket); |
|
138 |
|
139 if (aLength==0) |
|
140 aLength = aPacket.Length(); |
|
141 |
|
142 RMBufChain tmp; |
|
143 while (aLength>=2) |
|
144 { |
|
145 aPacket.Align(2); |
|
146 TInt len = aPacket.First()->Get(1); |
|
147 |
|
148 // Carlson97 (p.41) suggests that option length of 0 or 1 |
|
149 // should be treated as 2 for the sake of verifying |
|
150 // the packet integrity when doing the length checks: |
|
151 // |
|
152 // "If, however, and option has an improper Len field for that |
|
153 // type of option, but all of the lengths otherwise add up correctly, then |
|
154 // the option should, according to the RFC 1661, be included in a Configure Nak message |
|
155 // with the Len field changed to the proper length. (Dealing with a Len field set to 00 or 01 is a grey |
|
156 // area in the standard. I recommend treating this as as though it had been 02 for the sake of verifying |
|
157 // the packet integrity when doing the length checks; if these checks succeed, a Configure Nak should be |
|
158 // returned with the correct Len field for those options. ...)" |
|
159 // |
|
160 // This targets cases where the option fields have correct length, but the option Len value is incorrect. |
|
161 // That is, the packet can be correctly parsed. |
|
162 // Setting option len to 2 may result in either overruning the packet length during parsing, |
|
163 // or in parsing the packet incorrectly (incorrect option ID, values, etc). Both cases are checked for later. |
|
164 if (len < 2) |
|
165 len = 2; |
|
166 |
|
167 if (len > aLength) // The option extends beyond the end of the packet. |
|
168 User::Leave(KErrCorrupt); |
|
169 |
|
170 aPacket.SplitL(len, tmp); |
|
171 Append(aPacket); |
|
172 aPacket.Assign(tmp); |
|
173 aLength -= len; |
|
174 } |
|
175 // If there is anything left over, then the list and packet |
|
176 // are discarded as we probably have a truncated option. |
|
177 if (aLength>0) |
|
178 User::Leave(KErrCorrupt); |
|
179 |
|
180 CleanupStack::Pop(2); |
|
181 } |
|
182 |
|
183 TBool RPppOptionList::IsSubsetOf(RPppOptionList& aList) |
|
184 /** |
|
185 Check if the current option list is a subset of the OptionsList presented (aList). |
|
186 |
|
187 All the options in the current list must be contained and must be in the same order as the options in aList |
|
188 All the option arguments must also be identical |
|
189 |
|
190 @param aList option list to compare against. |
|
191 @return ETrue if option lists match, else EFalse |
|
192 */ |
|
193 { |
|
194 TMBufPktQIter iter1(*this); |
|
195 TMBufPktQIter iter2(aList); |
|
196 |
|
197 RPppOption opt1; |
|
198 RPppOption opt2; |
|
199 |
|
200 opt1 = iter1++; |
|
201 opt2 = iter2++; |
|
202 |
|
203 while (!opt1.IsEmpty()) |
|
204 { |
|
205 if (opt2.IsEmpty()) |
|
206 { |
|
207 return EFalse; |
|
208 } |
|
209 if (opt1.OptType() == opt2.OptType()) |
|
210 { |
|
211 if (opt1.ValueLength() == opt2.ValueLength() && |
|
212 Mem::Compare(opt1.ValuePtr(), opt1.ValueLength(), opt2.ValuePtr(), opt2.ValueLength()) == 0) //Arguments are the same |
|
213 { |
|
214 opt1 = iter1++; //We can move on to the next option aList is incremented later |
|
215 } |
|
216 else |
|
217 { |
|
218 return EFalse; //option arguemts are different therefore comparison fails |
|
219 } |
|
220 //if the option types are different then we move on to the next option in aList |
|
221 } |
|
222 opt2 = iter2++; |
|
223 } |
|
224 return ETrue; |
|
225 } |
|
226 |
|
227 TBool RPppOptionList::EqualTo(RPppOptionList& aList) |
|
228 /** |
|
229 Check if the current option list exactly matches that of the option list specified as argument. |
|
230 |
|
231 The options in each list must have the same type in the same order and have the same value. |
|
232 If one option list has extra options at the end, then this also counts as a mismatch. |
|
233 Note that aList should really be a const, but this would require propagation of the constness |
|
234 to several related classes. |
|
235 |
|
236 @param aList option list to compare against. |
|
237 @return ETrue if option lists match, else EFalse |
|
238 */ |
|
239 { |
|
240 TMBufPktQIter iter1(*this); |
|
241 TMBufPktQIter iter2(aList); |
|
242 |
|
243 RPppOption opt1; |
|
244 RPppOption opt2; |
|
245 |
|
246 opt1 = iter1++; |
|
247 opt2 = iter2++; |
|
248 |
|
249 while (!opt1.IsEmpty() && !opt2.IsEmpty()) |
|
250 { |
|
251 if (opt1.OptType() != opt2.OptType() || opt1.ValueLength() != opt2.ValueLength() || |
|
252 Mem::Compare(opt1.ValuePtr(), opt1.ValueLength(), opt2.ValuePtr(), opt2.ValueLength()) != 0) |
|
253 { |
|
254 return EFalse; |
|
255 } |
|
256 opt1 = iter1++; |
|
257 opt2 = iter2++; |
|
258 } |
|
259 |
|
260 // finally, check for the case where one option list has extra options |
|
261 |
|
262 return (opt1.IsEmpty() && opt2.IsEmpty()); |
|
263 } |
|
264 |
|
265 /** |
|
266 Build an MBuf chain by copying the underlying packet queue, |
|
267 leaving space on the front for a protocol header. |
|
268 */ |
|
269 TInt RPppOptionList::CopyL(RMBufChain& aPacket, TInt aHdrSize) const |
|
270 { |
|
271 __ASSERT_ALWAYS(aHdrSize<KMBufSmallSize, PppPanic(EPppPanic_PacketHeaderTooBig)); |
|
272 |
|
273 RMBufChain i; |
|
274 |
|
275 // Get total length of chain needed |
|
276 TInt pktlen, len = 0; |
|
277 i = First(); |
|
278 while (!i.IsEmpty()) |
|
279 { |
|
280 len += i.Length(); |
|
281 i = i.Next(); |
|
282 } |
|
283 |
|
284 // Allocate the chain |
|
285 pktlen = len+aHdrSize; |
|
286 aPacket.AllocL(pktlen); |
|
287 |
|
288 // Do the copy |
|
289 TInt n, n1, n2; |
|
290 TUint8* p1, * p2; |
|
291 RMBuf* m1, * m2; |
|
292 |
|
293 i = First(); |
|
294 m1 = i.First(); |
|
295 p1 = m1->Ptr(); |
|
296 n1 = m1->Length(); |
|
297 |
|
298 m2 = aPacket.First(); |
|
299 p2 = m2->Ptr(); |
|
300 n2 = m2->Length(); |
|
301 |
|
302 if (aHdrSize>0) |
|
303 { |
|
304 if (aHdrSize==KMBufSmallSize) |
|
305 { |
|
306 m2 = m2->Next(); |
|
307 p2 = m2->Ptr(); |
|
308 n2 = m2->Length(); |
|
309 } |
|
310 else |
|
311 { |
|
312 p2 += aHdrSize; |
|
313 n2 -= aHdrSize; |
|
314 } |
|
315 } |
|
316 |
|
317 while (len>0) |
|
318 { |
|
319 n = n1<n2 ? n1 : n2; |
|
320 Mem::Copy(p2, p1, n); |
|
321 if (n1 -= n, n1==0) |
|
322 { |
|
323 if (m1 = m1->Next(), m1==NULL) |
|
324 { |
|
325 i = i.Next(); |
|
326 m1 = i.First(); |
|
327 } |
|
328 if (m1!=NULL) |
|
329 { |
|
330 p1 = m1->Ptr(); |
|
331 n1 = m1->Length(); |
|
332 } |
|
333 } |
|
334 else |
|
335 p1 += n; |
|
336 if (n2 -= n, n2==0) |
|
337 { |
|
338 if (m2 = m2->Next(), m2!=NULL) |
|
339 { |
|
340 p2 = m2->Ptr(); |
|
341 n2 = m2->Length(); |
|
342 } |
|
343 } |
|
344 else |
|
345 p2 += n; |
|
346 len -= n; |
|
347 } |
|
348 |
|
349 return pktlen; |
|
350 } |
|
351 |
|
352 /** |
|
353 For each option in aReplaceList, delete the original in this list |
|
354 and replace it with the given one. |
|
355 */ |
|
356 TInt RPppOptionList::ReplaceOptions(RPppOptionList& aReplaceList) |
|
357 { |
|
358 RPppOption opt; |
|
359 while (aReplaceList.Remove(opt)) |
|
360 { |
|
361 TInt err; |
|
362 if (err = ReplaceOption(opt), err!=KErrNone) |
|
363 return err; |
|
364 } |
|
365 return KErrNone; |
|
366 } |
|
367 |
|
368 /** |
|
369 For each option in aRejectList, delete the original in this list |
|
370 */ |
|
371 TInt RPppOptionList::RemoveOptions(RPppOptionList& aRejectList) |
|
372 { |
|
373 RPppOption opt; |
|
374 while (aRejectList.Remove(opt)) |
|
375 { |
|
376 TInt err; |
|
377 if (err = RemoveOption(opt), err!=KErrNone) |
|
378 return err; |
|
379 opt.Free(); |
|
380 } |
|
381 return KErrNone; |
|
382 } |
|
383 |
|
384 TInt RPppOptionList::ReplaceOption(RPppOption& aOption) |
|
385 // |
|
386 // |
|
387 // |
|
388 { |
|
389 TMBufPktQIter iter(*this); |
|
390 RPppOption opt; |
|
391 while (opt = iter++, !opt.IsEmpty()) |
|
392 { |
|
393 if (opt.OptType()==aOption.OptType()) |
|
394 { |
|
395 opt.SetValueLength(aOption.ValueLength()); |
|
396 Mem::Copy(opt.ValuePtr(), aOption.ValuePtr(), aOption.ValueLength()); |
|
397 return KErrNone; |
|
398 } |
|
399 } |
|
400 return KErrNotFound; |
|
401 } |
|
402 |
|
403 |
|
404 TInt RPppOptionList::RemoveOption(RPppOption& aOption) |
|
405 // |
|
406 // |
|
407 // |
|
408 { |
|
409 TMBufPktQIter iter(*this); |
|
410 RPppOption opt; |
|
411 while (opt = iter.Current(), !opt.IsEmpty()) |
|
412 { |
|
413 if (opt.OptType()==aOption.OptType()) |
|
414 { |
|
415 opt.Init(); |
|
416 iter.Remove(opt); |
|
417 opt.Free(); |
|
418 return KErrNone; |
|
419 } |
|
420 iter++; |
|
421 } |
|
422 return KErrNotFound; |
|
423 } |
|
424 |
|
425 |
|
426 /** |
|
427 Calculate the FCS of an Option list |
|
428 Used for detecting non-convergence |
|
429 */ |
|
430 void RPppOptionList::Crc32(TPppFcs32& aFcs, TBool aInitFcs) |
|
431 { |
|
432 if (aInitFcs) |
|
433 aFcs.Init(); |
|
434 |
|
435 RPppOption opt; |
|
436 TMBufPktQIter iter(*this); |
|
437 |
|
438 while (opt = iter++, !opt.IsEmpty()) |
|
439 { |
|
440 RMBuf* m = opt.First(); |
|
441 while (m!=NULL) |
|
442 { |
|
443 aFcs.Calc(m->Ptr(), m->EndPtr()); |
|
444 m = m->Next(); |
|
445 } |
|
446 } |
|
447 } |
|
448 |
|
449 /** |
|
450 Creates an options packet from an options list |
|
451 |
|
452 @param aPacket Return value for the constructed packet |
|
453 @param aPppId Protocol (e.g. LCP, IPCP etc). |
|
454 @param aType Type field of packet (e.g. Config-Request etc). |
|
455 @param aId Id field of packet |
|
456 @param aCreateEmptyPacket Set to ETrue if an empty packet is required. |
|
457 @see RFC1661, 5. |
|
458 @see MPppFsm::NewPacket |
|
459 */ |
|
460 void RPppOptionList::CreatePacketL(RMBufPacket& aPacket, TUint aPppId, TUint8 aType, TUint8 aId, TBool aCreateEmptyPacket) |
|
461 { |
|
462 RMBufPktInfo* info=NULL; |
|
463 TInt len; |
|
464 |
|
465 CleanupStack::PushL(aPacket); |
|
466 if (aCreateEmptyPacket) |
|
467 { |
|
468 // An empty packet contains just a header (Type (1) + Id (1) + Length (2)) |
|
469 len = 4; |
|
470 aPacket.AllocL(len); |
|
471 } |
|
472 else |
|
473 { |
|
474 len = CopyL(aPacket, 4); |
|
475 } |
|
476 info = aPacket.NewInfoL(); |
|
477 CleanupStack::Pop(); |
|
478 |
|
479 info->iLength = len; |
|
480 TPppAddr::Cast(info->iDstAddr).SetProtocol(aPppId); |
|
481 TUint8* ptr = aPacket.First()->Ptr(); |
|
482 *ptr++ = aType; |
|
483 *ptr++ = aId; |
|
484 BigEndian::Put16(ptr, (TUint16)len); |
|
485 aPacket.Pack(); |
|
486 } |
|
487 |
|
488 void RPppOptionList::CreateAndAddL(TUint8 aType) |
|
489 { |
|
490 RPppOption opt; |
|
491 opt.SetL(aType, NULL, 0); |
|
492 Append(opt); |
|
493 } |
|
494 |
|
495 void RPppOptionList::CreateAndAddL(TUint8 aType, TUint8 aValue) |
|
496 { |
|
497 RPppOption opt; |
|
498 opt.SetL(aType, &aValue, sizeof(aValue)); |
|
499 Append(opt); |
|
500 } |
|
501 |
|
502 void RPppOptionList::CreateAndAddL(TUint8 aType, TUint16 aValue) |
|
503 { |
|
504 RPppOption opt; |
|
505 TUint8 swapped[2]; |
|
506 // swap the byte order if necessary |
|
507 BigEndian::Put16(swapped, aValue); |
|
508 opt.SetL(aType, swapped, sizeof(swapped)); |
|
509 Append(opt); |
|
510 } |
|
511 |
|
512 void RPppOptionList::CreateAndAddL(TUint8 aType, TUint32 aValue) |
|
513 { |
|
514 RPppOption opt; |
|
515 TUint8 swapped[4]; |
|
516 // swap the byte order if necessary |
|
517 BigEndian::Put32(swapped, aValue); |
|
518 opt.SetL(aType, swapped, sizeof(swapped)); |
|
519 Append(opt); |
|
520 } |
|
521 |
|
522 void RPppOptionList::CreateAndAddL(TUint8 aType, const TUint8 * aBuf, TInt aLen ) |
|
523 { |
|
524 RPppOption opt; |
|
525 opt.SetL(aType, aBuf, aLen); |
|
526 Append(opt); |
|
527 } |
|
528 |
|
529 void RPppOptionList::CreateAndAddL(TUint8 aType, TPtrC8& aValue ) |
|
530 { |
|
531 RPppOption opt; |
|
532 opt.SetL(aType, aValue.Ptr(), aValue.Length()); |
|
533 Append(opt); |
|
534 } |
|
535 |
|
536 |
|
537 |
|
538 MPppOptionsExtender::MPppOptionsExtender() |
|
539 { |
|
540 iExtOptHandlerList.SetOffset(_FOFF(MPppOptionHandler, iOptHandlerLink)); |
|
541 } |
|
542 |
|
543 void MPppOptionsExtender::ExtOptRegister(MPppOptionHandler* aHandler) |
|
544 { |
|
545 iExtOptHandlerList.AddLast(*aHandler); |
|
546 } |
|
547 |
|
548 void MPppOptionsExtender::ExtOptDeregister(MPppOptionHandler* aHandler) |
|
549 { |
|
550 aHandler->iOptHandlerLink.Deque(); |
|
551 } |
|
552 |
|
553 void MPppOptionsExtender::ExtOptNegotiationStarted() |
|
554 { |
|
555 TDblQueIter<MPppOptionHandler> iter(iExtOptHandlerList); |
|
556 MPppOptionHandler* handler; |
|
557 |
|
558 while (handler = iter++, handler!=NULL) |
|
559 handler->OptNegotiationStarted(); |
|
560 } |
|
561 |
|
562 void MPppOptionsExtender::ExtOptNegotiationAborted() |
|
563 { |
|
564 TDblQueIter<MPppOptionHandler> iter(iExtOptHandlerList); |
|
565 MPppOptionHandler* handler; |
|
566 |
|
567 while (handler = iter++, handler!=NULL) |
|
568 handler->OptNegotiationAborted(); |
|
569 } |
|
570 |
|
571 void MPppOptionsExtender::ExtOptNegotiationComplete() |
|
572 { |
|
573 TDblQueIter<MPppOptionHandler> iter(iExtOptHandlerList); |
|
574 MPppOptionHandler* handler; |
|
575 |
|
576 while (handler = iter++, handler!=NULL) |
|
577 handler->OptNegotiationComplete(); |
|
578 } |
|
579 |
|
580 void MPppOptionsExtender::ExtOptFillinConfigRequestL(RPppOptionList& aRequestList) |
|
581 { |
|
582 TDblQueIter<MPppOptionHandler> iter(iExtOptHandlerList); |
|
583 MPppOptionHandler* handler; |
|
584 while (handler = iter++, handler!=NULL) |
|
585 handler->OptFillinConfigRequestL(aRequestList); |
|
586 } |
|
587 |
|
588 void MPppOptionsExtender::ExtOptCheckConfigRequest(RPppOption& aOption, RPppOptionList &aAckList, RPppOptionList &aNakList, RPppOptionList &aRejList) |
|
589 { |
|
590 MPppOptionHandler* handler = ExtOptLookup(aOption.OptType()); |
|
591 TPppOptResponse res = (handler==NULL) ? EPppOptReject : handler->OptCheckConfigRequest(aOption); |
|
592 switch (res) |
|
593 { |
|
594 case EPppOptAck: |
|
595 aAckList.Append(aOption); |
|
596 break; |
|
597 case EPppOptNak: |
|
598 aNakList.Append(aOption); |
|
599 break; |
|
600 case EPppOptReject: |
|
601 aRejList.Append(aOption); |
|
602 break; |
|
603 } |
|
604 } |
|
605 |
|
606 void MPppOptionsExtender::ExtOptApplyConfigRequest(RPppOption& aOption) |
|
607 { |
|
608 MPppOptionHandler* handler = ExtOptLookup(aOption.OptType()); |
|
609 if (handler!=NULL) |
|
610 handler->OptApplyConfigRequest(aOption); |
|
611 } |
|
612 |
|
613 void MPppOptionsExtender::ExtOptRecvConfigAck(RPppOption& aOption) |
|
614 { |
|
615 MPppOptionHandler* handler = ExtOptLookup(aOption.OptType()); |
|
616 if (handler!=NULL) |
|
617 handler->OptRecvConfigAck(aOption); |
|
618 } |
|
619 |
|
620 void MPppOptionsExtender::ExtOptRecvConfigNak(RPppOption& aOption, RPppOptionList& aReqList) |
|
621 { |
|
622 MPppOptionHandler* handler = ExtOptLookup(aOption.OptType()); |
|
623 if (handler!=NULL) |
|
624 handler->OptRecvConfigNak(aOption, aReqList); |
|
625 } |
|
626 |
|
627 void MPppOptionsExtender::ExtOptRecvConfigReject(RPppOption& aOption, RPppOptionList& aReqList) |
|
628 { |
|
629 MPppOptionHandler* handler = ExtOptLookup(aOption.OptType()); |
|
630 if (handler!=NULL) |
|
631 handler->OptRecvConfigReject(aOption, aReqList); |
|
632 } |
|
633 |
|
634 MPppOptionHandler* MPppOptionsExtender::ExtOptLookup(TUint8 aOptId) |
|
635 { |
|
636 TDblQueIter<MPppOptionHandler> iter(iExtOptHandlerList); |
|
637 MPppOptionHandler* handler; |
|
638 |
|
639 while (handler = iter++, handler!=NULL) |
|
640 { |
|
641 TInt i; |
|
642 for (i=0; i<handler->iNumOptions; i++) |
|
643 { |
|
644 if (handler->iOptionList[i]==aOptId) |
|
645 return handler; |
|
646 } |
|
647 } |
|
648 return NULL; |
|
649 } |
|
650 |
|
651 MPppOptionHandler::MPppOptionHandler() |
|
652 { |
|
653 iNumOptions = 0; |
|
654 iOptionList = NULL; |
|
655 } |
|
656 |
|
657 void MPppOptionHandler::OptRegister(MPppOptionsExtender* aExtender, const TUint8* aOptList, TInt aNumOpts) |
|
658 { |
|
659 iNumOptions = aNumOpts; |
|
660 iOptionList = aOptList; |
|
661 aExtender->ExtOptRegister(this); |
|
662 } |
|
663 |
|
664 // Default Implementations of option handler functions |
|
665 |
|
666 void MPppOptionHandler::OptNegotiationStarted() |
|
667 { |
|
668 return; |
|
669 } |
|
670 |
|
671 void MPppOptionHandler::OptNegotiationAborted() |
|
672 { |
|
673 return; |
|
674 } |
|
675 |
|
676 void MPppOptionHandler::OptNegotiationComplete() |
|
677 { |
|
678 return; |
|
679 } |
|
680 |
|
681 void MPppOptionHandler::OptFillinConfigRequestL(RPppOptionList& /*aRequestList*/) |
|
682 { |
|
683 return; |
|
684 } |
|
685 |
|
686 TPppOptResponse MPppOptionHandler::OptCheckConfigRequest(RPppOption& /*aOption*/) |
|
687 { |
|
688 return EPppOptReject; |
|
689 } |
|
690 |
|
691 void MPppOptionHandler::OptApplyConfigRequest(RPppOption& /*aOption*/) |
|
692 { |
|
693 return; |
|
694 } |
|
695 |
|
696 void MPppOptionHandler::OptRecvConfigAck(RPppOption& /*aOption*/) |
|
697 { |
|
698 return; |
|
699 } |
|
700 |
|
701 void MPppOptionHandler::OptRecvConfigNak(RPppOption& aOption, RPppOptionList& aReqList) |
|
702 { |
|
703 aReqList.ReplaceOption(aOption); |
|
704 } |
|
705 |
|
706 void MPppOptionHandler::OptRecvConfigReject(RPppOption& aOption, RPppOptionList& aReqList) |
|
707 { |
|
708 aReqList.RemoveOption(aOption); |
|
709 } |