|
1 /* |
|
2 * Copyright (c) 2002-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 "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: Implements functions for LAN interface |
|
15 * |
|
16 */ |
|
17 |
|
18 /* |
|
19 * %version: 24 % |
|
20 */ |
|
21 |
|
22 #include <f32file.h> |
|
23 #include <e32std.h> // for TTime |
|
24 #include <nifvar.h> |
|
25 #include <nifutl.h> |
|
26 #include <es_mbuf.h> |
|
27 #include <nifmbuf.h> |
|
28 #include <comms-infras/nifprvar.h> |
|
29 #include <comms-infras/connectionsettings.h> // for KSlashChar |
|
30 #include <commdb.h> |
|
31 #include "WlanProto.h" |
|
32 #include "carddrv.h" |
|
33 #include <in_sock.h> // Header is retained, but in_sock.h is modified for ipv6 |
|
34 #include "CLanIp4Bearer.h" |
|
35 #include "CLanIp6Bearer.h" |
|
36 #include <cdbcols.h> |
|
37 #include <cdblen.h> |
|
38 #include "CLanxBearer.h" |
|
39 #include "WlanProvision.h" |
|
40 #include <comms-infras/ss_metaconnprov.h> // for SAccessPointConfig |
|
41 #include <comms-infras/linkmessages.h> |
|
42 #include <elements/nm_messages_base.h> |
|
43 #include <elements/nm_messages_child.h> |
|
44 |
|
45 // From old wlan implementation |
|
46 #include <ip4_hdr.h> |
|
47 #include <ip6_hdr.h> |
|
48 #include <centralrepository.h> |
|
49 #include "am_debug.h" |
|
50 #include "EtherCardApi.h" |
|
51 #include "wlandevicesettingsinternalcrkeys.h" |
|
52 #include "NifWLMServerIf.h" |
|
53 |
|
54 |
|
55 using namespace ESock; |
|
56 using namespace Messages; |
|
57 |
|
58 _LIT8(KDescIp, "ip"); |
|
59 _LIT8(KDescIcmp, "icmp"); |
|
60 _LIT8(KDescIp6, "ip6"); |
|
61 |
|
62 const TInt KLanxBearerPtrArrayGranularity = 2; |
|
63 const TInt KContinueSending = 1; |
|
64 const TInt KMaxDSCPValues = 64; |
|
65 |
|
66 /** |
|
67 * Mapping of user priority values to the corresponding access classes. |
|
68 */ |
|
69 const TWlmAccessClass KUPtoAC[E8021DUserPriorityMax] = |
|
70 { |
|
71 EWlmAccessClassBestEffort, // E8021DUserPriorityBE |
|
72 EWlmAccessClassBackground, // E8021DUserPriorityBK1 |
|
73 EWlmAccessClassBackground, // E8021DUserPriorityBK2 |
|
74 EWlmAccessClassBestEffort, // E8021DUserPriorityEE |
|
75 EWlmAccessClassVideo, // E8021DUserPriorityCL |
|
76 EWlmAccessClassVideo, // E8021DUserPriorityVI |
|
77 EWlmAccessClassVoice, // E8021DUserPriorityVO |
|
78 EWlmAccessClassVoice, // E8021DUserPriorityNC |
|
79 }; |
|
80 |
|
81 /** |
|
82 * Mapping of access class transitions on packet downgrade. |
|
83 */ |
|
84 const TWlmAccessClass KNextAC[EWlmAccessClassMax] = |
|
85 { |
|
86 EWlmAccessClassBackground, // EWlmAccessClassBestEffort -> EWlmAccessClassBackground |
|
87 EWlmAccessClassMax, // EWlmAccessClassBackground -> EWlmAccessClassMax |
|
88 EWlmAccessClassBestEffort, // EWlmAccessClassVideo -> EWlmAccessClassBestEffort |
|
89 EWlmAccessClassVideo // EWlmAccessClassVoice -> EWlmAccessClassVideo |
|
90 }; |
|
91 |
|
92 /** |
|
93 * Mapping of IP TOS (DSCP) bits to the corresponding user priority values. |
|
94 */ |
|
95 const T8021DPriority KDSCPtoUP[KMaxDSCPValues] = |
|
96 { |
|
97 /* DSCP bits as binary format, DSCP byte in IPv4 packet as HEX */ |
|
98 |
|
99 /* 000000, 0x00 */E8021DUserPriorityBE, /* 000001, 0x04 */E8021DUserPriorityBE, |
|
100 /* 000010, 0x08 */E8021DUserPriorityBE, /* 000011, 0x0C */E8021DUserPriorityBE, |
|
101 /* 000100, 0x10 */E8021DUserPriorityBE, /* 000101, 0x14 */E8021DUserPriorityBE, |
|
102 /* 000110, 0x18 */E8021DUserPriorityBE, /* 000111, 0x1C */E8021DUserPriorityBE, |
|
103 /* 001000, 0x20 */E8021DUserPriorityBK1, /* 001001, 0x24 */E8021DUserPriorityBK1, |
|
104 /* 001010, 0x28 */E8021DUserPriorityEE, /* 001011, 0x2C */E8021DUserPriorityEE, |
|
105 /* 001100, 0x30 */E8021DUserPriorityEE, /* 001101, 0x34 */E8021DUserPriorityEE, |
|
106 /* 001110, 0x38 */E8021DUserPriorityEE, /* 001111, 0x3C */E8021DUserPriorityEE, |
|
107 |
|
108 /* 010000, 0x40 */E8021DUserPriorityEE, /* 010001, 0x44 */E8021DUserPriorityEE, |
|
109 /* 010010, 0x48 */E8021DUserPriorityEE, /* 010011, 0x4C */E8021DUserPriorityEE, |
|
110 /* 010100, 0x50 */E8021DUserPriorityEE, /* 010101, 0x54 */E8021DUserPriorityEE, |
|
111 /* 010110, 0x58 */E8021DUserPriorityEE, /* 010111, 0x5C */E8021DUserPriorityEE, |
|
112 /* 011000, 0x60 */E8021DUserPriorityVI, /* 011001, 0x64 */E8021DUserPriorityVI, |
|
113 /* 011010, 0x68 */E8021DUserPriorityVI, /* 011011, 0x6C */E8021DUserPriorityVI, |
|
114 /* 011100, 0x70 */E8021DUserPriorityVI, /* 011101, 0x74 */E8021DUserPriorityVI, |
|
115 /* 011110, 0x78 */E8021DUserPriorityVI, /* 011111, 0x7C */E8021DUserPriorityVI, |
|
116 |
|
117 /* 100000, 0x80 */E8021DUserPriorityVI, /* 100001, 0x84 */E8021DUserPriorityVI, |
|
118 /* 100010, 0x88 */E8021DUserPriorityVI, /* 100011, 0x8C */E8021DUserPriorityVI, |
|
119 /* 100100, 0x90 */E8021DUserPriorityVI, /* 100101, 0x94 */E8021DUserPriorityVI, |
|
120 /* 100110, 0x98 */E8021DUserPriorityVI, /* 100111, 0x9C */E8021DUserPriorityVI, |
|
121 /* 101000, 0xA0 */E8021DUserPriorityCL, /* 101001, 0xA4 */E8021DUserPriorityCL, |
|
122 /* 101010, 0xA8 */E8021DUserPriorityCL, /* 101011, 0xAC */E8021DUserPriorityCL, |
|
123 /* 101100, 0xB0 */E8021DUserPriorityCL, /* 101101, 0xB4 */E8021DUserPriorityCL, |
|
124 /* 101110, 0xB8 */E8021DUserPriorityVO, /* 101111, 0xBC */E8021DUserPriorityVO, |
|
125 |
|
126 /* 110000, 0xC0 */E8021DUserPriorityNC, /* 110001, 0xC4 */E8021DUserPriorityNC, |
|
127 /* 110010, 0xC8 */E8021DUserPriorityNC, /* 110011, 0xCC */E8021DUserPriorityNC, |
|
128 /* 110100, 0xD0 */E8021DUserPriorityNC, /* 110101, 0xD4 */E8021DUserPriorityNC, |
|
129 /* 110110, 0xD8 */E8021DUserPriorityNC, /* 110111, 0xDC */E8021DUserPriorityNC, |
|
130 /* 111000, 0xE0 */E8021DUserPriorityNC, /* 111001, 0xE4 */E8021DUserPriorityNC, |
|
131 /* 111010, 0xE8 */E8021DUserPriorityNC, /* 111011, 0xEC */E8021DUserPriorityNC, |
|
132 /* 111100, 0xF0 */E8021DUserPriorityNC, /* 111101, 0xF4 */E8021DUserPriorityNC, |
|
133 /* 111110, 0xF8 */E8021DUserPriorityNC, /* 111111, 0xFC */E8021DUserPriorityNC |
|
134 }; |
|
135 |
|
136 /** |
|
137 * Inactivity timeouts per access class. |
|
138 */ |
|
139 const TUint KTsInactivityTime[EWlmAccessClassMax] = |
|
140 { |
|
141 600000000, // 600 seconds for EWlmAccessClassBestEffort |
|
142 600000000, // 600 seconds for EWlmAccessClassBackground |
|
143 120000000, // 120 seconds for EWlmAccessClassVideo |
|
144 30000000, // 30 seconds for EWlmAccessClassVoice |
|
145 }; |
|
146 |
|
147 EXPORT_C CLANLinkCommon::CLANLinkCommon(CSubConnectionFlowFactoryBase& aFactory, const TNodeId& aSubConnId, CProtocolIntfBase* aProtocolIntf) |
|
148 : CSubConnectionFlowBase(aFactory, aSubConnId, aProtocolIntf), iMMState(EStopped) |
|
149 { |
|
150 DEBUG("CLANLinkCommon::CLANLinkCommon()"); |
|
151 LOG_NODE_CREATE(KWlanLog, CLANLinkCommon); |
|
152 } |
|
153 |
|
154 |
|
155 // ----------------------------------------------------------------------------- |
|
156 // CLANLinkCommon::LoadPacketDriverL |
|
157 // ----------------------------------------------------------------------------- |
|
158 // |
|
159 void CLANLinkCommon::LoadPacketDriverL() |
|
160 { |
|
161 DEBUG("CLANLinkCommon::LoadPacketDriverL() - Creates only new class instance"); |
|
162 |
|
163 iPktDrv = CPcCardPktDrv::NewL( this ); |
|
164 } |
|
165 |
|
166 // ----------------------------------------------------------------------------- |
|
167 // CLANLinkCommon::NewL |
|
168 // ----------------------------------------------------------------------------- |
|
169 // |
|
170 EXPORT_C CLANLinkCommon* CLANLinkCommon::NewL(CSubConnectionFlowFactoryBase& aFactory, const TNodeId& aSubConnId, CProtocolIntfBase* aProtocolIntf) |
|
171 { |
|
172 DEBUG("CLANLinkCommon::NewL()"); |
|
173 |
|
174 CLANLinkCommon* s=new (ELeave) CLANLinkCommon(aFactory, aSubConnId, aProtocolIntf); |
|
175 CleanupStack::PushL(s); |
|
176 s->ConstructL(); |
|
177 CleanupStack::Pop(s); |
|
178 return s; |
|
179 } |
|
180 |
|
181 // ----------------------------------------------------------------------------- |
|
182 // CLANLinkCommon::ReadMACSettings |
|
183 // ----------------------------------------------------------------------------- |
|
184 // |
|
185 TBool CLANLinkCommon::ReadMACSettings() |
|
186 { |
|
187 DEBUG("CLANLinkCommon::ReadMACSettings()"); |
|
188 |
|
189 TBuf8<KMACByteLength> drvMacAddr; |
|
190 TUint8* config=iPktDrv->GetInterfaceAddress(); |
|
191 drvMacAddr.Append(&config[0],KMACByteLength); // First 3 bytes of config not part of address |
|
192 iMacAddr.Copy(drvMacAddr); // update Ethints copy of the MAC address |
|
193 TUint bearerLim = iBearers->Count(); |
|
194 for(TUint index=0;index<bearerLim;index++) |
|
195 { |
|
196 CLanxBearer* bearer=(*iBearers)[index]; |
|
197 bearer->UpdateMACAddr(); |
|
198 } |
|
199 |
|
200 // check that the macaddress has been passed and is not 0; |
|
201 return CheckMac(iMacAddr); // wrong. |
|
202 } |
|
203 |
|
204 // ----------------------------------------------------------------------------- |
|
205 // CLANLinkCommon::Mtu |
|
206 // ----------------------------------------------------------------------------- |
|
207 // |
|
208 TUint CLANLinkCommon::Mtu() const |
|
209 { |
|
210 DEBUG("CLanLinkCommon::Mtu()"); |
|
211 |
|
212 TInt err = KErrNone; |
|
213 CRepository* repository = NULL; |
|
214 TRAP( err, repository = CRepository::NewL( KCRUidWlanDeviceSettingsRegistryId ) ); |
|
215 if( err != KErrNone ) |
|
216 { |
|
217 DEBUG1( "Could not access repository (%d), using default value for mtu(1500)", err ); |
|
218 return KEtherMaxDataLen; |
|
219 } |
|
220 // No need to use CleanupStack because no possibility to leave |
|
221 |
|
222 TInt temp = 0; |
|
223 err = repository->Get( KWlanMTU, temp ); |
|
224 if( err == KErrNone ) |
|
225 { |
|
226 delete repository; |
|
227 DEBUG1("MTU value from cenrep is:%d", temp); |
|
228 if( temp > KEtherMaxDataLen || temp <= 0 ) |
|
229 { |
|
230 DEBUG("MTU from cenrep is out of range 1-1500, setting it to 1500"); |
|
231 temp = KEtherMaxDataLen; |
|
232 } |
|
233 return temp; |
|
234 } |
|
235 else |
|
236 { |
|
237 DEBUG1( "Could not access repository (%d), using default value for mtu(1500)", err ); |
|
238 delete repository; |
|
239 return KEtherMaxDataLen; |
|
240 } |
|
241 } |
|
242 |
|
243 // ----------------------------------------------------------------------------- |
|
244 // CLANLinkCommon::ConstructL |
|
245 // ----------------------------------------------------------------------------- |
|
246 // |
|
247 EXPORT_C void CLANLinkCommon::ConstructL() |
|
248 { |
|
249 DEBUG("CLANLinkCommon::ConstructL()"); |
|
250 |
|
251 // Initialise class members that do not need to be read from the database |
|
252 iBearers = new (ELeave) CLanxBearerPtrArray(KLanxBearerPtrArrayGranularity); |
|
253 iEtherType = EStandardEthernet; |
|
254 |
|
255 iOnlyThisBearer = NULL; |
|
256 } |
|
257 |
|
258 // ----------------------------------------------------------------------------- |
|
259 // CLANLinkCommon::~CLANLinkCommon |
|
260 // ----------------------------------------------------------------------------- |
|
261 // |
|
262 EXPORT_C CLANLinkCommon::~CLANLinkCommon() |
|
263 { |
|
264 DEBUG("CLANLinkCommon::~CLANLinkCommon()"); |
|
265 |
|
266 delete iPktDrv; |
|
267 ASSERT(0 == iBearers->Count()); |
|
268 delete iBearers; |
|
269 delete iPeriodic; |
|
270 delete iWLMServerCommon; |
|
271 for( TUint idx( 0 ); idx < EWlmAccessClassMax; ++idx ) |
|
272 { |
|
273 delete iAcArray[idx]; |
|
274 } |
|
275 |
|
276 LOG_NODE_DESTROY(KWlanLog, CLANLinkCommon); |
|
277 } |
|
278 |
|
279 // ----------------------------------------------------------------------------- |
|
280 // CLANLinkCommon::CheckMac |
|
281 // ----------------------------------------------------------------------------- |
|
282 // |
|
283 TBool CLANLinkCommon::CheckMac(TDes8& aMacAddr) |
|
284 { |
|
285 DEBUG("CLANLinkCommon::CheckMac()"); |
|
286 |
|
287 TUint MacBytes = 6; |
|
288 for (TUint i=0;i<MacBytes;i++) |
|
289 { |
|
290 if (aMacAddr[i] != 0) |
|
291 { |
|
292 return ETrue; |
|
293 } |
|
294 } |
|
295 return EFalse; |
|
296 } |
|
297 |
|
298 // ----------------------------------------------------------------------------- |
|
299 // CLANLinkCommon::AcTrafficModeChanged |
|
300 // ----------------------------------------------------------------------------- |
|
301 // |
|
302 void CLANLinkCommon::AcTrafficModeChanged( |
|
303 TWlmAccessClass aAccessClass, |
|
304 TWlmAcTrafficMode aMode ) |
|
305 { |
|
306 DEBUG( "CLANLinkCommon::AcTrafficModeChanged()" ); |
|
307 |
|
308 iAcArray[aAccessClass]->SetTrafficMode( aMode ); |
|
309 } |
|
310 |
|
311 // ----------------------------------------------------------------------------- |
|
312 // CLANLinkCommon::AcTrafficModeChanged |
|
313 // ----------------------------------------------------------------------------- |
|
314 // |
|
315 void CLANLinkCommon::AcTrafficStatusChanged( |
|
316 TWlmAccessClass aAccessClass, |
|
317 TWlmAcTrafficStatus aStatus ) |
|
318 { |
|
319 DEBUG( "CLANLinkCommon::AcTrafficStatusChanged()" ); |
|
320 |
|
321 iAcArray[aAccessClass]->SetTrafficStatus( aStatus ); |
|
322 } |
|
323 |
|
324 // ----------------------------------------------------------------------------- |
|
325 // CLANLinkCommon::LinkLayerUp |
|
326 // ----------------------------------------------------------------------------- |
|
327 // |
|
328 /** |
|
329 Link Layer Up |
|
330 Called by the packet driver when it is happy |
|
331 */ |
|
332 EXPORT_C void CLANLinkCommon::LinkLayerUp() |
|
333 { |
|
334 DEBUG("CLANLinkCommon::LinkLayerUp()"); |
|
335 |
|
336 //some drivers have a valid MAC only after negotiation finishes |
|
337 iValidMacAddr = ReadMACSettings(); |
|
338 PostDataClientStartedMessage(); |
|
339 |
|
340 /** |
|
341 * With the new comms framework, this KLinkLayerOpen always sent and then will be caught and swallowed |
|
342 * at the ipproto layer if a netcfgext is being used. |
|
343 */ |
|
344 |
|
345 /** |
|
346 * We are forced to signal link layer open from here even though there may not |
|
347 * be a configured IP address. This is a dirty fix because of politics... |
|
348 */ |
|
349 PostProgressMessage(KLinkLayerOpen, KErrNone); |
|
350 |
|
351 TUint bearerLim = iBearers->Count(); |
|
352 for(TUint index=0;index<bearerLim;index++) |
|
353 { |
|
354 CLanxBearer *bearer=(*iBearers)[index]; |
|
355 bearer->StartSending((CProtocolBase*)this); |
|
356 } |
|
357 |
|
358 // Get current traffic status for access classes. |
|
359 TWlmAcTrafficStatusArray acArray; |
|
360 TInt ret = iWLMServerCommon->GetAcTrafficStatus( acArray ); |
|
361 if( ret != KErrNone ) |
|
362 { |
|
363 DEBUG1( "CLANLinkCommon::LinkLayerUp() - RWLMServer::GetAcTrafficStatus() failed with %d", |
|
364 ret ); |
|
365 |
|
366 // Assume all access classes are admitted. |
|
367 for( TUint idx( 0 ); idx < EWlmAccessClassMax; ++idx ) |
|
368 { |
|
369 iAcArray[idx]->SetTrafficStatus( EWlmAcTrafficStatusAdmitted ); |
|
370 } |
|
371 } |
|
372 else |
|
373 { |
|
374 // Update access class instances with the current status. |
|
375 for( TUint idx( 0 ); idx < EWlmAccessClassMax; ++idx ) |
|
376 { |
|
377 iAcArray[idx]->SetTrafficStatus( acArray[idx] ); |
|
378 } |
|
379 } |
|
380 } |
|
381 |
|
382 // ----------------------------------------------------------------------------- |
|
383 // CLANLinkCommon::LinkLayerDown |
|
384 // ----------------------------------------------------------------------------- |
|
385 // |
|
386 EXPORT_C void CLANLinkCommon::LinkLayerDown(TInt aError, TAction aAction) |
|
387 /** |
|
388 Link Layer Down |
|
389 Called by the packet driver when the link has gone down |
|
390 |
|
391 @param aError error code |
|
392 @param aAction whether a reconnect is required or not |
|
393 */ |
|
394 { |
|
395 DEBUG("CLANLinkCommon::LinkLayerDown()"); |
|
396 |
|
397 // If a stop was requested from the SCpr then this LinkLayerDown() |
|
398 // was expected. This also means the SCpr has already been sent a |
|
399 // TDataClientStopped and the packet driver has been stopped. |
|
400 // If on the other hand the stop was not requested a TDataClientGoneDown |
|
401 // message needs to be sent to the SCpr and the packet driver still |
|
402 // needs a StopInterface call - usually this would mean that aAction |
|
403 // is EReconnect |
|
404 if (iStopRequested == EFalse && iMMState == EStarted) |
|
405 { |
|
406 PostProgressMessage(KLinkLayerClosed, aError); |
|
407 PostFlowGoingDownMessage(aError, (aAction == EReconnect) ? MNifIfNotify::EReconnect : MNifIfNotify::EDisconnect); |
|
408 iPktDrv->StopInterface(); |
|
409 MaybePostDataClientIdle(); |
|
410 iMMState = EStopped; |
|
411 } |
|
412 } |
|
413 |
|
414 // ----------------------------------------------------------------------------- |
|
415 // CLANLinkCommon::StopCb |
|
416 // ----------------------------------------------------------------------------- |
|
417 // |
|
418 TInt CLANLinkCommon::StopCb(TAny* aThisPtr) |
|
419 { |
|
420 DEBUG("CLANLinkCommon::StopCb()"); |
|
421 |
|
422 CLANLinkCommon* self = static_cast<CLANLinkCommon*>(aThisPtr); |
|
423 self->StopInterface(); |
|
424 return KErrNone; |
|
425 } |
|
426 |
|
427 // ----------------------------------------------------------------------------- |
|
428 // CLANLinkCommon::StopInterface |
|
429 // ----------------------------------------------------------------------------- |
|
430 // |
|
431 void CLANLinkCommon::StopInterface() |
|
432 { |
|
433 DEBUG("CLANLinkCommon::StopInterface()"); |
|
434 |
|
435 if(iPeriodic) |
|
436 { |
|
437 iPeriodic->Cancel(); |
|
438 delete iPeriodic; |
|
439 iPeriodic = NULL; |
|
440 } |
|
441 |
|
442 iPktDrv->StopInterface(); |
|
443 PostProgressMessage(KLinkLayerClosed, iError); |
|
444 PostFlowDownMessage(iError); |
|
445 |
|
446 MaybePostDataClientIdle(); |
|
447 } |
|
448 |
|
449 // ----------------------------------------------------------------------------- |
|
450 // CLANLinkCommon::EtherFrame |
|
451 // ----------------------------------------------------------------------------- |
|
452 // |
|
453 TInt CLANLinkCommon::EtherFrame(RMBufChain &aPdu, TDesC8& aDestAddr, TUint16 aType, TUint8& aDscp) |
|
454 { |
|
455 RMBufChain ethHdr; |
|
456 TUint etherHeaderSize = (iEtherType==EStandardEthernet) ? |
|
457 KEtherHeaderSize : KEtherLLCHeaderSize; |
|
458 |
|
459 TRAPD(ret, ethHdr.AllocL(etherHeaderSize)); |
|
460 if(ret != KErrNone) |
|
461 { |
|
462 return ret; |
|
463 } |
|
464 |
|
465 TEtherLLCFrame *hdrBuf = reinterpret_cast<TEtherLLCFrame*>(ethHdr.First()->Buffer()); |
|
466 |
|
467 //Get the packet info: |
|
468 RMBufPktInfo* info = RMBufPacket::PeekInfoInChain(aPdu); |
|
469 |
|
470 // Fill in the dest, src Mac addresses: |
|
471 hdrBuf->SetDestAddr(aDestAddr); |
|
472 hdrBuf->SetSrcAddr(iMacAddr); |
|
473 |
|
474 switch(iEtherType) |
|
475 { |
|
476 case EStandardEthernet: |
|
477 BigEndian::Put16((TUint8*)&hdrBuf->iType,aType); |
|
478 break; |
|
479 case ELLCEthernet: |
|
480 // Several fields to fill in. According to nifmbuf.h, |
|
481 // info->iLength gives the actual length of the packet. |
|
482 BigEndian::Put16((TUint8*)&hdrBuf->iLen,static_cast<TInt16>(info->iLength)); |
|
483 hdrBuf->iDSAP=KLLC_SNAP_DSAP; |
|
484 hdrBuf->iSSAP=KLLC_SNAP_SSAP; |
|
485 hdrBuf->iCtrl=KLLC_SNAP_CTRL; |
|
486 hdrBuf->SetOUI(0); |
|
487 hdrBuf->SetType(aType); |
|
488 break; |
|
489 default: |
|
490 // Can't handle any other kind of Ethernet header. |
|
491 return KErrGeneral; |
|
492 } |
|
493 |
|
494 //Remove the original first Packet - by trimming the info from the packet. |
|
495 aPdu.TrimStart(aPdu.Length() - info->iLength); // At this point, info becomes invalid. |
|
496 |
|
497 //Extract the DSCP value as aPdu points to IP packet now |
|
498 if (KIPFrameType == aType) |
|
499 { |
|
500 TInet6HeaderIP4 *ipv4hdr = (TInet6HeaderIP4 *)aPdu.First()->Ptr(); |
|
501 TUint8 TOS = ipv4hdr->TOS(); |
|
502 aDscp = (TOS >> 2) & 0xff; |
|
503 DEBUG2( "CLanLinkCommon::EtherFrame() - DSCP of the IPv4 packet: 0x%02X (%u)", |
|
504 aDscp, aDscp ); |
|
505 } |
|
506 else if (KIP6FrameType == aType) |
|
507 { |
|
508 TInet6HeaderIP *ipv6hdr = (TInet6HeaderIP *)aPdu.First()->Ptr(); |
|
509 TUint8 TrafficClass = ipv6hdr->TrafficClass(); |
|
510 aDscp = (TrafficClass >> 2) & 0xff; |
|
511 DEBUG2( "CLanLinkCommon::EtherFrame() - DSCP of the IPv6 packet: 0x%02X (%u)", |
|
512 aDscp, aDscp ); |
|
513 } |
|
514 |
|
515 //Finally, add the saved packet buffer to the mac header |
|
516 aPdu.Prepend(ethHdr); |
|
517 return KErrNone; |
|
518 } |
|
519 |
|
520 // ----------------------------------------------------------------------------- |
|
521 // CLANLinkCommon::FrameSend |
|
522 // ----------------------------------------------------------------------------- |
|
523 // |
|
524 TInt CLANLinkCommon::FrameSend( |
|
525 RMBufChain& aPdu, |
|
526 TDesC8& aDestAddr, |
|
527 TUint16 aType ) |
|
528 { |
|
529 // Call down from the Protocol |
|
530 // The data begins in the second MBuf - because the first one |
|
531 // is the info. The upper layer must have filled in the destination |
|
532 // and source Mac addresses before this method is called and must |
|
533 // supply the ether header type in aType. |
|
534 // EtherFrame strips off the info and replaces it by the proper |
|
535 // ether header. |
|
536 |
|
537 TUint8 dscp( 0 ); |
|
538 TInt err = EtherFrame( aPdu, aDestAddr, aType, dscp ); |
|
539 if( err != KErrNone ) |
|
540 { |
|
541 // drop the packet but _don't_ return an error (if we return |
|
542 // an error from here, the stack thinks it is fatal...) |
|
543 aPdu.Free(); |
|
544 return KContinueSending; |
|
545 } |
|
546 |
|
547 // Map DSCP values to desired access class and user priority values. |
|
548 T8021DPriority userPriority( KDSCPtoUP[dscp] ); |
|
549 TWlmAccessClass accessClass( KUPtoAC[userPriority] ); |
|
550 TBool dropPacket( EFalse ); |
|
551 |
|
552 // ARP packets are treated as Voice traffic. |
|
553 if( aType == KArpFrameType ) |
|
554 { |
|
555 DEBUG( "CLanLinkCommon::FrameSend() - ARP packet" ); |
|
556 |
|
557 userPriority = E8021DUserPriorityNC; |
|
558 accessClass = EWlmAccessClassVoice; |
|
559 } |
|
560 |
|
561 if( iAcArray[accessClass]->IsAdmitted() ) |
|
562 { |
|
563 DEBUG1( "CLanLinkCommon::FrameSend() - traffic admitted on AC %u", |
|
564 accessClass ); |
|
565 } |
|
566 else |
|
567 { |
|
568 DEBUG1( "CLanLinkCommon::FrameSend() - traffic NOT admitted on AC %u", |
|
569 accessClass ); |
|
570 |
|
571 // Find an admitted access class. |
|
572 DownGradePacket( userPriority, dropPacket ); |
|
573 } |
|
574 |
|
575 if( !dropPacket ) |
|
576 { |
|
577 //Prepend UP value to the packet |
|
578 RMBufChain UPBuf; |
|
579 TRAPD( allocRet, UPBuf.AllocL( sizeof(TUint8) ) ); |
|
580 if( allocRet != KErrNone ) |
|
581 { |
|
582 // drop the packet but _don't_ return an error (if we return |
|
583 // an error from here, the stack thinks it is fatal...) |
|
584 aPdu.Free(); |
|
585 return KContinueSending; |
|
586 } |
|
587 |
|
588 (UPBuf.First())->Put((TUint8)userPriority); |
|
589 aPdu.Prepend( UPBuf ); |
|
590 |
|
591 DEBUG2( "CLanLinkCommon::FrameSend() - sending packet on AC %u with UP %u", |
|
592 KUPtoAC[userPriority], |
|
593 userPriority ); |
|
594 TInt ret = iPktDrv->Send( aPdu ); |
|
595 |
|
596 // ARP packets will never triggers traffic stream creation. |
|
597 if( aType == KArpFrameType ) |
|
598 { |
|
599 return ret; |
|
600 } |
|
601 |
|
602 // Notify the per-AC handler. |
|
603 iAcArray[accessClass]->OnFrameSend(); |
|
604 |
|
605 if( ret != KContinueSending ) |
|
606 { |
|
607 // Suspend inactivity timer for all ACs if NIF Queue is full. |
|
608 for( TUint idx( 0 ); idx < EWlmAccessClassMax; ++idx ) |
|
609 { |
|
610 iAcArray[idx]->SuspendInactivityTimer(); |
|
611 } |
|
612 } |
|
613 |
|
614 return ret; |
|
615 } |
|
616 else |
|
617 { |
|
618 DEBUG( "CLanLinkCommon::FrameSend() - no ACs admitted, dropping packet" ); |
|
619 |
|
620 aPdu.Free(); |
|
621 |
|
622 return KContinueSending; |
|
623 } |
|
624 } |
|
625 |
|
626 // ----------------------------------------------------------------------------- |
|
627 // CLANLinkCommon::DownGradePacket |
|
628 // ----------------------------------------------------------------------------- |
|
629 // |
|
630 void CLANLinkCommon::DownGradePacket( |
|
631 T8021DPriority& aUP, |
|
632 TBool& aDrop ) |
|
633 { |
|
634 DEBUG1( "CLanLinkCommon::DownGradePacket() - UP before downgrade: %u", |
|
635 aUP ); |
|
636 |
|
637 /** |
|
638 * This method wouldn't be called if downgrade wasn't needed, |
|
639 * so we don't have to check Voice priority at all. |
|
640 */ |
|
641 TWlmAccessClass accessClass( KNextAC[KUPtoAC[aUP]] ); |
|
642 while( accessClass != EWlmAccessClassMax ) |
|
643 { |
|
644 if( iAcArray[accessClass]->IsAdmitted() ) |
|
645 { |
|
646 aUP = KACtoUP[accessClass]; |
|
647 aDrop = EFalse; |
|
648 |
|
649 DEBUG1( "CLanLinkCommon::DownGradePacket() - UP after downgrade: %u", |
|
650 aUP ); |
|
651 |
|
652 return; |
|
653 } |
|
654 |
|
655 accessClass = KNextAC[accessClass]; |
|
656 } |
|
657 |
|
658 DEBUG( "CLanLinkCommon::DownGradePacket() - packet will be dropped" ); |
|
659 |
|
660 aDrop = ETrue; |
|
661 } |
|
662 |
|
663 // ----------------------------------------------------------------------------- |
|
664 // CLANLinkCommon::GetProtocolType |
|
665 // ----------------------------------------------------------------------------- |
|
666 // |
|
667 TInt CLANLinkCommon::GetProtocolType( |
|
668 TUint8* aEtherHeader, |
|
669 TUint16& aEtherType ) |
|
670 { |
|
671 TEtherFrame* etherFrame = reinterpret_cast<TEtherFrame*>(aEtherHeader); |
|
672 TUint16 etherType = etherFrame->GetType(); |
|
673 |
|
674 if( etherType >= KMinEtherType) |
|
675 { |
|
676 // type/length field >= 1536, this is Ethernet II frame |
|
677 aEtherType = etherType; |
|
678 } |
|
679 else |
|
680 { |
|
681 // type/length field is something between KEtherLLCMaxLengthFieldValue |
|
682 // and KMinEtherType, this shouldn't happen... |
|
683 //__ASSERT_DEBUG(EFalse, User::Panic(_L("wlannif"), KErrGeneral)); |
|
684 return KErrNotSupported; |
|
685 } |
|
686 return KErrNone; |
|
687 } |
|
688 |
|
689 // ----------------------------------------------------------------------------- |
|
690 // CLANLinkCommon::Process |
|
691 // ----------------------------------------------------------------------------- |
|
692 // |
|
693 void CLANLinkCommon::Process( |
|
694 RMBufChain& aPdu, |
|
695 TUint8* aEtherHeader, |
|
696 TUint8 aUPValue ) |
|
697 { |
|
698 TUint16 etherCode(0); |
|
699 TBool packetProcessed(EFalse); |
|
700 TInt ret=GetProtocolType( aEtherHeader, etherCode ); |
|
701 if( ret==KErrNone ) |
|
702 { // It's an ethernet packet of some kind. |
|
703 DEBUG2("CLANLinkCommon::Process() - UP: %u, ethertype: 0x%04X", |
|
704 aUPValue, etherCode ); |
|
705 |
|
706 TUint bearerLim = iBearers->Count(); |
|
707 for( TUint index=0;index<bearerLim && !packetProcessed; index++ ) |
|
708 { |
|
709 CLanxBearer *bearer=(*iBearers)[index]; |
|
710 |
|
711 if( bearer->WantsProtocol( |
|
712 etherCode, aPdu.First()->Next()->Buffer()) ) |
|
713 { |
|
714 bearer->Process( aPdu ); |
|
715 packetProcessed=ETrue; |
|
716 } |
|
717 } |
|
718 } |
|
719 if( ret!=KErrNone || !packetProcessed ) |
|
720 { |
|
721 aPdu.Free(); // Something strange about the packet - bin it |
|
722 } |
|
723 else |
|
724 { |
|
725 // Notify the per-AC handler. |
|
726 iAcArray[KUPtoAC[aUPValue]]->OnFrameReceive(); |
|
727 } |
|
728 } |
|
729 |
|
730 // ----------------------------------------------------------------------------- |
|
731 // CLANLinkCommon::ResumeSending |
|
732 // ----------------------------------------------------------------------------- |
|
733 // |
|
734 EXPORT_C void CLANLinkCommon::ResumeSending() |
|
735 { |
|
736 DEBUG( "CLanLinkCommon::ResumeSending()" ); |
|
737 |
|
738 TUint bearerLim = iBearers->Count(); |
|
739 for( TUint index=0;index<bearerLim;index++ ) |
|
740 { |
|
741 CLanxBearer *bearer=(*iBearers)[index]; |
|
742 bearer->StartSending( (CProtocolBase*)this ); |
|
743 } |
|
744 |
|
745 for( TUint idx( 0 ); idx < EWlmAccessClassMax; ++idx ) |
|
746 { |
|
747 iAcArray[idx]->ResumeInactivityTimer(); |
|
748 } |
|
749 } |
|
750 |
|
751 /** |
|
752 |
|
753 */ |
|
754 EXPORT_C TInt CLANLinkCommon::ReadInt(const TDesC& /*aField*/, TUint32& /*aValue*/) |
|
755 { |
|
756 return KErrNotSupported; |
|
757 } |
|
758 |
|
759 /** |
|
760 |
|
761 */ |
|
762 EXPORT_C TInt CLANLinkCommon::WriteInt(const TDesC& /*aField*/, TUint32 /*aValue*/) |
|
763 { |
|
764 return KErrNotSupported; |
|
765 } |
|
766 |
|
767 /** |
|
768 |
|
769 */ |
|
770 EXPORT_C TInt CLANLinkCommon::ReadDes(const TDesC& /*aField*/, TDes8& /*aValue*/) |
|
771 { |
|
772 return KErrNotSupported; |
|
773 } |
|
774 |
|
775 /** |
|
776 |
|
777 */ |
|
778 EXPORT_C TInt CLANLinkCommon::ReadDes(const TDesC& /*aField*/, TDes16& /*aValue*/) |
|
779 { |
|
780 return KErrNotSupported; |
|
781 |
|
782 } |
|
783 |
|
784 /** |
|
785 |
|
786 */ |
|
787 EXPORT_C TInt CLANLinkCommon::WriteDes(const TDesC& /*aField*/, const TDesC8& /*aValue*/) |
|
788 { |
|
789 return KErrNotSupported; |
|
790 } |
|
791 |
|
792 /** |
|
793 |
|
794 */ |
|
795 EXPORT_C TInt CLANLinkCommon::WriteDes(const TDesC& /*aField*/, const TDesC16& /*aValue*/) |
|
796 { |
|
797 return KErrNotSupported; |
|
798 } |
|
799 |
|
800 /** |
|
801 |
|
802 */ |
|
803 EXPORT_C TInt CLANLinkCommon::ReadBool(const TDesC& /*aField*/, TBool& /*aValue*/) |
|
804 { |
|
805 return KErrNotSupported; |
|
806 } |
|
807 |
|
808 /** |
|
809 |
|
810 */ |
|
811 EXPORT_C TInt CLANLinkCommon::WriteBool(const TDesC& /*aField*/, TBool /*aValue*/) |
|
812 { |
|
813 return KErrNotSupported; |
|
814 } |
|
815 |
|
816 /** |
|
817 |
|
818 */ |
|
819 EXPORT_C void CLANLinkCommon::IfProgress(TInt aStage, TInt aError) |
|
820 { |
|
821 PostProgressMessage(aStage, aError); |
|
822 } |
|
823 |
|
824 /** |
|
825 |
|
826 */ |
|
827 EXPORT_C void CLANLinkCommon::IfProgress(TSubConnectionUniqueId /*aSubConnectionUniqueId*/, TInt aStage, TInt aError) |
|
828 { |
|
829 // Not quite correct - there is no subconnection id specific progress message. |
|
830 IfProgress(aStage, aError); |
|
831 } |
|
832 |
|
833 /** |
|
834 |
|
835 */ |
|
836 EXPORT_C void CLANLinkCommon::NifEvent(TNetworkAdaptorEventType /*aEventType*/, TUint /*aEvent*/, const TDesC8& /*aEventData*/, TAny* /*aSource*/) |
|
837 { |
|
838 } |
|
839 |
|
840 // ====================================================================================== |
|
841 // |
|
842 // from MFlowBinderControl |
|
843 |
|
844 // ----------------------------------------------------------------------------- |
|
845 // CLANLinkCommon::GetControlL |
|
846 // ----------------------------------------------------------------------------- |
|
847 // |
|
848 EXPORT_C MLowerControl* CLANLinkCommon::GetControlL(const TDesC8& aName) |
|
849 /** |
|
850 Request from upper CFProtocol to retrieve our MLowerControl class. |
|
851 |
|
852 @param aName Protocol Name. Presently, only "ip" and "ip6" are supported. |
|
853 @return pointer to our MLowerControl class instance. We leave on an error, hence this routine should |
|
854 never return NULL. |
|
855 */ |
|
856 { |
|
857 DEBUG("CLANLinkCommon::GetControlL()"); |
|
858 |
|
859 CLanxBearer* bearer=NULL; |
|
860 if (aName.CompareF(KDescIp6) == 0) |
|
861 { |
|
862 bearer = new(ELeave) CLanIp6Bearer(this); |
|
863 } |
|
864 else if (aName.CompareF(KDescIp) == 0 || aName.CompareF(KDescIcmp) == 0) |
|
865 { |
|
866 bearer = new(ELeave) CLanIp4Bearer(this); |
|
867 } |
|
868 else |
|
869 { |
|
870 User::Leave(KErrNotSupported); |
|
871 } |
|
872 |
|
873 CleanupStack::PushL(bearer); |
|
874 bearer->ConstructL(); |
|
875 |
|
876 iBearers->AppendL(bearer); |
|
877 ProvisionBearerConfigL(aName); |
|
878 CleanupStack::Pop(); |
|
879 return bearer; |
|
880 } |
|
881 |
|
882 |
|
883 // ----------------------------------------------------------------------------- |
|
884 // CLANLinkCommon::BindL |
|
885 // ----------------------------------------------------------------------------- |
|
886 // |
|
887 EXPORT_C MLowerDataSender* CLANLinkCommon::BindL(const TDesC8& aProtocol, MUpperDataReceiver* aReceiver, MUpperControl* aControl) |
|
888 /** |
|
889 Request from upper CFProtocol to bind to this module. |
|
890 |
|
891 @param aProtocol protocol name (e.g. "ip", "ip6" etc). |
|
892 @param aReceiver pointer to MUpperDataReceiver instance of upper CFProtocol |
|
893 @param aControl pointer to MUpperControl instance of upper CFProtocol |
|
894 @return pointer to our MLowerDataSender instance (eventually passed to the upper CFProtocol) |
|
895 */ |
|
896 { |
|
897 DEBUG("CLANLinkCommon::BindL()"); |
|
898 |
|
899 TInt index = 0; |
|
900 CLanxBearer* bearer = FindBearerByProtocolName(aProtocol, index); |
|
901 if (bearer) |
|
902 { |
|
903 bearer->SetUpperPointers(aReceiver, aControl); |
|
904 if (iValidMacAddr) |
|
905 { |
|
906 aControl->StartSending(); |
|
907 } |
|
908 } |
|
909 else |
|
910 { |
|
911 User::Leave(KErrNotSupported); |
|
912 } |
|
913 iSubConnectionProvider.RNodeInterface::PostMessage(Id(), TCFControlProvider::TActive().CRef()); |
|
914 return bearer; |
|
915 } |
|
916 |
|
917 |
|
918 // ----------------------------------------------------------------------------- |
|
919 // CLANLinkCommon::Unbind |
|
920 // ----------------------------------------------------------------------------- |
|
921 // |
|
922 EXPORT_C void CLANLinkCommon::Unbind(MUpperDataReceiver* /*aReceiver*/, MUpperControl* aControl) |
|
923 /** |
|
924 Request from upper CFProtocol to unbind from this module. |
|
925 |
|
926 @param aReceiver pointer to data receiver class of upper CFProtocol (originally passed to it in downward BindL() request) |
|
927 @param aControl pointer to control class of upper CFProtocol (originally passed to it in downward BindL() request) |
|
928 */ |
|
929 |
|
930 { |
|
931 DEBUG("CLANLinkCommon::Unbind()"); |
|
932 |
|
933 TInt index = 0; |
|
934 CLanxBearer* bearer = FindBearerByUpperControl(aControl, index); |
|
935 ASSERT(bearer); |
|
936 iBearers->Delete(index); |
|
937 delete bearer; |
|
938 |
|
939 // If no-one remains bound to us, signal data client idle to SCPR |
|
940 MaybePostDataClientIdle(); |
|
941 } |
|
942 |
|
943 |
|
944 // |
|
945 // Utilities |
|
946 // |
|
947 |
|
948 // ----------------------------------------------------------------------------- |
|
949 // CLANLinkCommon::FindBearerByProtocolName |
|
950 // ----------------------------------------------------------------------------- |
|
951 // |
|
952 CLanxBearer* CLANLinkCommon::FindBearerByProtocolName(const TDesC8& aProtocol, TInt& aIndex) const |
|
953 /** |
|
954 Search the iBearers array searching for a match by protocol name. |
|
955 |
|
956 @param aProtocol name of protocol (in) |
|
957 @param aIndex on success, index of found entry (>=0), else -1. |
|
958 @return pointer to CLanxBearer entry on success else NULL. |
|
959 */ |
|
960 { |
|
961 DEBUG("CLANLinkCommon::FindBearerByProtocolName()"); |
|
962 |
|
963 TInt count = iBearers->Count(); |
|
964 for (TInt i = 0 ; i < count ; ++i) |
|
965 { |
|
966 CLanxBearer* bearer = iBearers->At(i); |
|
967 if (bearer->ProtocolName() == aProtocol) |
|
968 { |
|
969 aIndex = i; |
|
970 return bearer; |
|
971 } |
|
972 } |
|
973 aIndex = -1; |
|
974 return NULL; |
|
975 } |
|
976 |
|
977 |
|
978 // ----------------------------------------------------------------------------- |
|
979 // CLANLinkCommon::FindBearerByUpperControl |
|
980 // ----------------------------------------------------------------------------- |
|
981 // |
|
982 CLanxBearer* CLANLinkCommon::FindBearerByUpperControl(const MUpperControl* aUpperControl, TInt& aIndex) const |
|
983 /** |
|
984 Search the iBearers array searching for a match by protocol name. |
|
985 |
|
986 @param aProtocol name of protocol (in) |
|
987 @param aIndex on success, index of found entry (>=0), else -1. |
|
988 @return pointer to CLanxBearer entry on success else NULL. |
|
989 */ |
|
990 { |
|
991 DEBUG("CLANLinkCommon::FindBearerByUpperControl()"); |
|
992 |
|
993 TInt count = iBearers->Count(); |
|
994 for (TInt i = 0 ; i < count ; ++i) |
|
995 { |
|
996 CLanxBearer* bearer = iBearers->At(i); |
|
997 if (bearer->MatchesUpperControl(aUpperControl)) |
|
998 { |
|
999 aIndex = i; |
|
1000 return bearer; |
|
1001 } |
|
1002 } |
|
1003 aIndex = -1; |
|
1004 return NULL; |
|
1005 } |
|
1006 |
|
1007 // ===================================================================================== |
|
1008 // |
|
1009 // MCFNode |
|
1010 |
|
1011 // ----------------------------------------------------------------------------- |
|
1012 // CLANLinkCommon::ReceivedL |
|
1013 // ----------------------------------------------------------------------------- |
|
1014 // |
|
1015 EXPORT_C void CLANLinkCommon::ReceivedL(const TRuntimeCtxId& aSender, const TNodeId& aRecipient, TSignatureBase& aMessage) |
|
1016 /** |
|
1017 Routine called on an incoming message from SCPR |
|
1018 |
|
1019 @param aCFMessage incoming message |
|
1020 @return KErrNone, else a system wide error code. |
|
1021 */ |
|
1022 { |
|
1023 DEBUG1("CLANLinkCommon::ReceivedL(), aCFMessage=%d", aMessage.MessageId().MessageId()); |
|
1024 |
|
1025 CSubConnectionFlowBase::ReceivedL(aSender, aRecipient, aMessage); |
|
1026 |
|
1027 if (TEBase::ERealmId == aMessage.MessageId().Realm()) |
|
1028 { |
|
1029 switch (aMessage.MessageId().MessageId()) |
|
1030 { |
|
1031 case TEBase::TError::EId : |
|
1032 SubConnectionError(static_cast<TEBase::TError&>(aMessage).iValue); |
|
1033 break; |
|
1034 case TEBase::TCancel::EId : |
|
1035 CancelStartFlow(); |
|
1036 break; |
|
1037 default: |
|
1038 ASSERT(EFalse); |
|
1039 } |
|
1040 } |
|
1041 else if (TEChild::ERealmId == aMessage.MessageId().Realm()) |
|
1042 { |
|
1043 switch (aMessage.MessageId().MessageId()) |
|
1044 { |
|
1045 case TEChild::TDestroy::EId : |
|
1046 Destroy(); |
|
1047 break; |
|
1048 default: |
|
1049 ASSERT(EFalse); |
|
1050 } |
|
1051 } |
|
1052 else if (TCFDataClient::ERealmId == aMessage.MessageId().Realm()) |
|
1053 { |
|
1054 switch (aMessage.MessageId().MessageId()) |
|
1055 { |
|
1056 case TCFDataClient::TStart::EId : |
|
1057 StartFlowL(); |
|
1058 break; |
|
1059 case TCFDataClient::TProvisionConfig::EId: |
|
1060 ProvisionConfig(static_cast<TCFDataClient::TProvisionConfig&>(aMessage).iConfig); |
|
1061 break; |
|
1062 case TCFDataClient::TStop::EId : |
|
1063 StopFlow(static_cast<TCFDataClient::TStop&>(aMessage).iValue); |
|
1064 break; |
|
1065 case TCFDataClient::TBindTo::EId : |
|
1066 { |
|
1067 TCFDataClient::TBindTo& bindToReq = message_cast<TCFDataClient::TBindTo>(aMessage); |
|
1068 if (!bindToReq.iNodeId.IsNull()) |
|
1069 { |
|
1070 User::Leave(KErrNotSupported); |
|
1071 } |
|
1072 RClientInterface::OpenPostMessageClose(Id(), aSender, TCFDataClient::TBindToComplete().CRef()); |
|
1073 break; |
|
1074 } |
|
1075 default: |
|
1076 ASSERT(EFalse); |
|
1077 } |
|
1078 } |
|
1079 else if (TLinkMessage::ERealmId == aMessage.MessageId().Realm()) |
|
1080 { |
|
1081 switch (aMessage.MessageId().MessageId()) |
|
1082 { |
|
1083 case TLinkMessage::TAgentToFlowNotification::EId: |
|
1084 { |
|
1085 TLinkMessage::TAgentToFlowNotification& msg = message_cast<TLinkMessage::TAgentToFlowNotification>(aMessage); |
|
1086 if(msg.iValue != EAgentToNifEventVendorSpecific) |
|
1087 { |
|
1088 User::Leave(KErrNotSupported); |
|
1089 } |
|
1090 else //EAgentToNifEventVendorSpecific |
|
1091 { |
|
1092 //User::LeaveIfError((iPktDrv) ? iPktDrv->Notification( |
|
1093 // static_cast<TAgentToNifEventType>(msg.iValue), NULL) : KErrNotSupported); |
|
1094 DEBUG("CLANLinkCommon::ReceivedL(), rcvd disconnect notification from Agent"); |
|
1095 iError = KErrDisconnected; |
|
1096 StopInterface(); |
|
1097 } |
|
1098 } |
|
1099 break; |
|
1100 default: |
|
1101 ASSERT(EFalse); |
|
1102 }; //endswitch |
|
1103 } |
|
1104 else |
|
1105 { |
|
1106 ASSERT(EFalse); |
|
1107 } |
|
1108 } |
|
1109 |
|
1110 // |
|
1111 // Methods for handling incoming SCPR messages |
|
1112 // |
|
1113 |
|
1114 // ----------------------------------------------------------------------------- |
|
1115 // CLANLinkCommon::StartFlowL |
|
1116 // ----------------------------------------------------------------------------- |
|
1117 // |
|
1118 void CLANLinkCommon::StartFlowL() |
|
1119 { |
|
1120 DEBUG("CLANLinkCommon::StartFlowL()"); |
|
1121 |
|
1122 if ( !iPktDrv ) |
|
1123 LoadPacketDriverL(); |
|
1124 |
|
1125 iStopRequested = EFalse; |
|
1126 |
|
1127 ASSERT(iMMState == EStopped); |
|
1128 |
|
1129 if (iSavedError != KErrNone) |
|
1130 { |
|
1131 // If there were errors during prior processing of the TProvisionConfig message, |
|
1132 // leave here and cause a TError response to TDataClientStart. |
|
1133 User::Leave(iSavedError); |
|
1134 } |
|
1135 |
|
1136 iValidMacAddr = ReadMACSettings(); |
|
1137 |
|
1138 iMMState = EStarting; |
|
1139 User::LeaveIfError(iPktDrv->StartInterface()); |
|
1140 } |
|
1141 |
|
1142 |
|
1143 // ----------------------------------------------------------------------------- |
|
1144 // CLANLinkCommon::CancelStartFlow |
|
1145 // ----------------------------------------------------------------------------- |
|
1146 // |
|
1147 void CLANLinkCommon::CancelStartFlow() |
|
1148 { |
|
1149 if (iMMState == EStarting) |
|
1150 { |
|
1151 iStopRequested = ETrue; |
|
1152 |
|
1153 iPktDrv->StopInterface(); |
|
1154 PostProgressMessage(KLinkLayerClosed, KErrCancel); |
|
1155 PostFlowDownMessage(KErrCancel); |
|
1156 |
|
1157 MaybePostDataClientIdle(); |
|
1158 } |
|
1159 } |
|
1160 |
|
1161 |
|
1162 // half a second should be enough for sending DHCPRELEASE |
|
1163 static const TInt KDhcpReleaseDelay = 500000; |
|
1164 |
|
1165 // ----------------------------------------------------------------------------- |
|
1166 // CLANLinkCommon::StopFlow |
|
1167 // ----------------------------------------------------------------------------- |
|
1168 // |
|
1169 void CLANLinkCommon::StopFlow(TInt aError) |
|
1170 { |
|
1171 DEBUG("CLANLinkCommon::StopFlow()"); |
|
1172 |
|
1173 iStopRequested = ETrue; |
|
1174 |
|
1175 iMMState = EStopping; |
|
1176 |
|
1177 iError = aError; |
|
1178 |
|
1179 TCallBack callback(StopCb, this); |
|
1180 TRAPD(err, iPeriodic = CPeriodic::NewL(CActive::EPriorityStandard)); |
|
1181 if(err == KErrNone) |
|
1182 { |
|
1183 // Call the callback after KDhcpReleaseDelay. This is done only once, |
|
1184 // but we need to put something (KMaxTInt) to CPeriodic's interval. |
|
1185 iPeriodic->Start(TTimeIntervalMicroSeconds32(KDhcpReleaseDelay), TTimeIntervalMicroSeconds32(KMaxTInt), callback); |
|
1186 } |
|
1187 else |
|
1188 { |
|
1189 iPeriodic = NULL; |
|
1190 } |
|
1191 } |
|
1192 |
|
1193 |
|
1194 // ----------------------------------------------------------------------------- |
|
1195 // CLANLinkCommon::SubConnectionGoingDown |
|
1196 // ----------------------------------------------------------------------------- |
|
1197 // |
|
1198 void CLANLinkCommon::SubConnectionGoingDown() |
|
1199 { |
|
1200 } |
|
1201 |
|
1202 // ----------------------------------------------------------------------------- |
|
1203 // CLANLinkCommon::SubConnectionError |
|
1204 // ----------------------------------------------------------------------------- |
|
1205 // |
|
1206 void CLANLinkCommon::SubConnectionError(TInt /*aError*/) |
|
1207 { |
|
1208 } |
|
1209 |
|
1210 |
|
1211 /* |
|
1212 Provisioning description for Ethernet CFProtocol Flow: |
|
1213 |
|
1214 - on receipt of the TProvisionConfig message, the pointer contained within is stored |
|
1215 in iAccessPointConfig and the provisioning information contained within the AccessPointConfig |
|
1216 array is validated: |
|
1217 - at least one of TLanIp4Provision or TLanIp6Provision must be present. They are added by the EtherMCPr and |
|
1218 populated from CommsDat. |
|
1219 |
|
1220 - the packet driver is loaded. |
|
1221 |
|
1222 - if any of the above steps fail, the resulting error is saved in iSaveError so that when TDataClientStart message is |
|
1223 subsequently received, a TError message can be sent in response (there is no response to TProvisionConfig message). |
|
1224 */ |
|
1225 |
|
1226 // ----------------------------------------------------------------------------- |
|
1227 // CLANLinkCommon::ProvisionConfig |
|
1228 // ----------------------------------------------------------------------------- |
|
1229 // |
|
1230 void CLANLinkCommon::ProvisionConfig( const RMetaExtensionContainerC& aConfigData ) |
|
1231 { |
|
1232 DEBUG("CLANLinkCommon::ProvisionConfig()"); |
|
1233 |
|
1234 iSavedError = KErrNone; |
|
1235 |
|
1236 AccessPointConfig().Close(); |
|
1237 AccessPointConfig().Open(aConfigData); |
|
1238 |
|
1239 iLanIp4Provision = static_cast<const TLanIp4Provision*>(AccessPointConfig().FindExtension(STypeId::CreateSTypeId(TLanIp4Provision::EUid, TLanIp4Provision::ETypeId))); |
|
1240 if (iLanIp4Provision) |
|
1241 { |
|
1242 DEBUG("CLANLinkCommon::ProvisionConfig() - IP4 config to be provisioned"); |
|
1243 } |
|
1244 |
|
1245 iLanIp6Provision = static_cast<const TLanIp6Provision*>(AccessPointConfig().FindExtension(STypeId::CreateSTypeId(TLanIp6Provision::EUid, TLanIp6Provision::ETypeId))); |
|
1246 if (iLanIp6Provision) |
|
1247 { |
|
1248 DEBUG("CLANLinkCommon::ProvisionConfig() - IP6 config to be provisioned"); |
|
1249 } |
|
1250 |
|
1251 if (iLanIp4Provision == NULL && iLanIp6Provision == NULL) |
|
1252 { |
|
1253 // At least one set of IP4/6 provisioning information must be present |
|
1254 iSavedError = KErrCorrupt; |
|
1255 return; |
|
1256 } |
|
1257 |
|
1258 TRAPD(err, ProvisionConfigL()); |
|
1259 if (err != KErrNone) |
|
1260 { |
|
1261 iSavedError = err; |
|
1262 } |
|
1263 } |
|
1264 |
|
1265 // ----------------------------------------------------------------------------- |
|
1266 // CLANLinkCommon::ProvisionConfigL |
|
1267 // ----------------------------------------------------------------------------- |
|
1268 // |
|
1269 void CLANLinkCommon::ProvisionConfigL() |
|
1270 { |
|
1271 DEBUG("CLANLinkCommon::ProvisionConfigL()"); |
|
1272 |
|
1273 // Provision Bearers |
|
1274 if (iBearers->Count()) |
|
1275 { |
|
1276 ProvisionBearerConfigL(KDescIp()); |
|
1277 ProvisionBearerConfigL(KDescIp6()); |
|
1278 } |
|
1279 |
|
1280 iWLMServerCommon = new (ELeave) CLANNifWLMServerCommon(this); |
|
1281 iWLMServerCommon->ConstructL(); |
|
1282 |
|
1283 TBool isAutomaticMgmt( ETrue ); |
|
1284 CRepository* repository = NULL; |
|
1285 TRAP_IGNORE( repository = CRepository::NewL( KCRUidWlanDeviceSettingsRegistryId ) ); |
|
1286 if( repository ) |
|
1287 { |
|
1288 TInt temp( 0 ); |
|
1289 TInt ret = repository->Get( KWlanAutomaticTrafficStreamMgmt, temp ); |
|
1290 if( ret == KErrNone && |
|
1291 !temp ) |
|
1292 { |
|
1293 isAutomaticMgmt = EFalse; |
|
1294 } |
|
1295 |
|
1296 delete repository; |
|
1297 repository = NULL; |
|
1298 } |
|
1299 |
|
1300 for( TUint idx( 0 ); idx < EWlmAccessClassMax; ++idx ) |
|
1301 { |
|
1302 iAcArray[idx] = CLANNifWLMServerPerAC::NewL( |
|
1303 static_cast<TWlmAccessClass>( idx ), |
|
1304 KTsInactivityTime[idx], |
|
1305 isAutomaticMgmt ); |
|
1306 } |
|
1307 } |
|
1308 |
|
1309 // ----------------------------------------------------------------------------- |
|
1310 // CLANLinkCommon::Destroy |
|
1311 // ----------------------------------------------------------------------------- |
|
1312 // |
|
1313 void CLANLinkCommon::Destroy() |
|
1314 { |
|
1315 DEBUG("CLANLinkCommon::Destroy()"); |
|
1316 |
|
1317 ASSERT(iMMState==EStopped); |
|
1318 DeleteThisFlow(); |
|
1319 } |
|
1320 |
|
1321 // Utility functions |
|
1322 |
|
1323 void CLANLinkCommon::ProvisionBearerConfigL(const TDesC8& aName) |
|
1324 { |
|
1325 DEBUG("CLANLinkCommon::ProvisionBearerConfigL()"); |
|
1326 |
|
1327 TInt index = -1; |
|
1328 CLanxBearer* bearer = FindBearerByProtocolName(aName, index); |
|
1329 if (bearer) |
|
1330 { |
|
1331 if (aName.CompareF(KDescIp) == 0) |
|
1332 { |
|
1333 if (iLanIp4Provision) |
|
1334 { |
|
1335 bearer->SetProvisionL(iLanIp4Provision); // CLanIp4Bearer |
|
1336 } |
|
1337 } |
|
1338 else if (aName.CompareF(KDescIp6) == 0) |
|
1339 { |
|
1340 if (iLanIp6Provision) |
|
1341 { |
|
1342 bearer->SetProvisionL(iLanIp6Provision); // CLanIp6Bearer |
|
1343 } |
|
1344 } |
|
1345 } |
|
1346 } |
|
1347 |
|
1348 |
|
1349 // ----------------------------------------------------------------------------- |
|
1350 // CLANLinkCommon::PostProgressMessage |
|
1351 // ----------------------------------------------------------------------------- |
|
1352 // |
|
1353 void CLANLinkCommon::PostProgressMessage(TInt aStage, TInt aError) |
|
1354 { |
|
1355 DEBUG("CLANLinkCommon::PostProgressMessage()"); |
|
1356 |
|
1357 //Be careful when sending TStateChange message as RNodeChannelInterface will override the activity id |
|
1358 iSubConnectionProvider.RNodeInterface::PostMessage(Id(), TCFMessage::TStateChange( Elements::TStateChange( aStage, aError) ).CRef()); |
|
1359 } |
|
1360 |
|
1361 // ----------------------------------------------------------------------------- |
|
1362 // CLANLinkCommon::SetAllowedBearer |
|
1363 // ----------------------------------------------------------------------------- |
|
1364 // |
|
1365 void CLANLinkCommon::SetAllowedBearer(CLanxBearer* aBearer) |
|
1366 { |
|
1367 iOnlyThisBearer = aBearer; |
|
1368 } |
|
1369 |
|
1370 // ----------------------------------------------------------------------------- |
|
1371 // CLANLinkCommon::BearereIsActive |
|
1372 // ----------------------------------------------------------------------------- |
|
1373 // |
|
1374 TBool CLANLinkCommon::BearerIsActive(CLanxBearer* aBearer) |
|
1375 { |
|
1376 if (!iOnlyThisBearer || |
|
1377 aBearer == iOnlyThisBearer) |
|
1378 { |
|
1379 return ETrue; |
|
1380 } |
|
1381 return EFalse; |
|
1382 } |
|
1383 |
|
1384 // ----------------------------------------------------------------------------- |
|
1385 // CLANLinkCommon::PostFlowDownMessage |
|
1386 // ----------------------------------------------------------------------------- |
|
1387 // |
|
1388 void CLANLinkCommon::PostFlowDownMessage(TInt aError) |
|
1389 { |
|
1390 DEBUG("CLANLinkCommon::PostFlowDownMessage()"); |
|
1391 |
|
1392 if (iMMState == EStopping) |
|
1393 { |
|
1394 iSubConnectionProvider.PostMessage(Id(), TCFDataClient::TStopped(aError).CRef()); |
|
1395 } |
|
1396 else if (iMMState == EStarting) |
|
1397 { |
|
1398 iSubConnectionProvider.PostMessage(Id(), TEBase::TError(TCFDataClient::TStart::Id(), aError).CRef()); |
|
1399 } |
|
1400 else if (iMMState == EStarted) |
|
1401 { |
|
1402 iSubConnectionProvider.PostMessage(Id(), TCFControlProvider::TDataClientGoneDown(aError).CRef()); |
|
1403 } |
|
1404 iMMState = EStopped; |
|
1405 } |
|
1406 |
|
1407 |
|
1408 // ----------------------------------------------------------------------------- |
|
1409 // CLANLinkCommon::PostFlowGoingDownMessage |
|
1410 // ----------------------------------------------------------------------------- |
|
1411 // |
|
1412 void CLANLinkCommon::PostFlowGoingDownMessage(TInt aError, MNifIfNotify::TAction /*aAction*/) |
|
1413 { |
|
1414 DEBUG("CLANLinkCommon::PostFlowGoingDownMessage()"); |
|
1415 |
|
1416 // TDataClientGoneDown only makes sense if the flow was actually started |
|
1417 ASSERT(iMMState == EStarted); |
|
1418 iMMState = EStopped; |
|
1419 iSubConnectionProvider.PostMessage(Id(), TCFControlProvider::TDataClientGoneDown(aError).CRef()); |
|
1420 } |
|
1421 |
|
1422 |
|
1423 // ----------------------------------------------------------------------------- |
|
1424 // CLANLinkCommon::PostDataClientStartedMessage |
|
1425 // ----------------------------------------------------------------------------- |
|
1426 // |
|
1427 void CLANLinkCommon::PostDataClientStartedMessage() |
|
1428 { |
|
1429 DEBUG("CLANLinkCommon::PostDataClientStartedMessage()"); |
|
1430 |
|
1431 iMMState = EStarted; |
|
1432 iSubConnectionProvider.PostMessage(Id(), TCFDataClient::TStarted().CRef()); |
|
1433 } |
|
1434 |
|
1435 |
|
1436 // ----------------------------------------------------------------------------- |
|
1437 // CLANLinkCommon::MaybePostDataClientIdle |
|
1438 // ----------------------------------------------------------------------------- |
|
1439 // |
|
1440 void CLANLinkCommon::MaybePostDataClientIdle() |
|
1441 { |
|
1442 DEBUG("CLANLinkCommon::MaybePostDataClientIdle()"); |
|
1443 |
|
1444 if (iBearers->Count() == 0 && iMMState == EStopped) |
|
1445 { |
|
1446 iSubConnectionProvider.PostMessage(Id(), TCFControlProvider::TIdle().CRef()); |
|
1447 } |
|
1448 } |
|
1449 |
|
1450 |
|
1451 void TEtherLLCFrame::SetDestAddr( TDesC8& aDest) |
|
1452 { |
|
1453 DEBUG("TEtherLLCFrame::SetDestAddr()"); |
|
1454 |
|
1455 Mem::Copy(iDestAddr, aDest.Ptr(), KMACByteLength); |
|
1456 } |
|
1457 |
|
1458 // ----------------------------------------------------------------------------- |
|
1459 // CLANLinkCommon::SetSrcAddr |
|
1460 // ----------------------------------------------------------------------------- |
|
1461 // |
|
1462 void TEtherLLCFrame::SetSrcAddr(TDesC8& aSrc) |
|
1463 { |
|
1464 DEBUG("TEtherLLCFrame::SetSrcAddr()"); |
|
1465 |
|
1466 Mem::Copy(iSrcAddr, aSrc.Ptr(), KMACByteLength); |
|
1467 } |
|
1468 |
|
1469 // ----------------------------------------------------------------------------- |
|
1470 // CLANLinkCommon::SetOUI |
|
1471 // ----------------------------------------------------------------------------- |
|
1472 // |
|
1473 void TEtherLLCFrame::SetOUI(TUint32 aOUI) |
|
1474 { |
|
1475 DEBUG("TEtherLLCFrame::SetOUI()"); |
|
1476 |
|
1477 //aOUI is in native order, but the result is |
|
1478 //always stored in network byte order. |
|
1479 //Can't use the bigendian methods, because |
|
1480 //they only work for 16 and 32 -bit items. |
|
1481 OUI[0] = (TUint8)((aOUI>>16)&0xff); |
|
1482 OUI[1] = (TUint8)((aOUI>>8)&0xff); |
|
1483 OUI[2] = (TUint8)(aOUI&0xff); |
|
1484 } |