|
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 // Ethernet and 802.3 protocol suite common link layer (interface) code |
|
15 // |
|
16 // |
|
17 |
|
18 /** |
|
19 @file |
|
20 */ |
|
21 |
|
22 #include <f32file.h> |
|
23 #include <e32std.h> // for TTime |
|
24 #include <nifman.h> |
|
25 #include <nifvar.h> |
|
26 #include <nifutl.h> |
|
27 #include <es_mbuf.h> |
|
28 #include <nifmbuf.h> |
|
29 #include <comms-infras/nifprvar.h> |
|
30 #include <comms-infras/connectionsettings.h> // for KSlashChar |
|
31 #include <commdb.h> |
|
32 #include "EthProto.h" |
|
33 #include "PKTDRV.H" |
|
34 #include <in_sock.h> // Header is retained, but in_sock.h is modified for ipv6 |
|
35 #include <d32ethernet.h> |
|
36 #include "CLanIp4Bearer.h" |
|
37 #include "CLanIp6Bearer.h" |
|
38 #include "eth_log.h" |
|
39 #include <cdbcols.h> |
|
40 #include <cdblen.h> |
|
41 #include "CLanxBearer.h" |
|
42 #include "eth_log.h" |
|
43 #include "EthProvision.h" |
|
44 #include <comms-infras/ss_metaconnprov.h> // for SAccessPointConfig |
|
45 #include <comms-infras/ss_log.h> |
|
46 #include <comms-infras/linkmessages.h> |
|
47 #include <elements/nm_messages_base.h> |
|
48 #include <elements/nm_messages_child.h> |
|
49 |
|
50 using namespace Messages; |
|
51 using namespace MeshMachine; |
|
52 using namespace ESock; |
|
53 using namespace Elements; |
|
54 |
|
55 _LIT8(KDescIp, "ip"); |
|
56 _LIT8(KDescIcmp, "icmp"); |
|
57 _LIT8(KDescIp6, "ip6"); |
|
58 |
|
59 /** |
|
60 Constant supports Broadcasting or Multicasting |
|
61 @internalComponent |
|
62 */ |
|
63 |
|
64 /** |
|
65 Packet driver Function Pointer |
|
66 @internalComponent |
|
67 */ |
|
68 typedef CPktDrvFactory* (*TPktDrvFactoryNewL)(); |
|
69 |
|
70 EXPORT_C CLANLinkCommon::CLANLinkCommon(CSubConnectionFlowFactoryBase& aFactory, const TNodeId& aSubConnId, CProtocolIntfBase* aProtocolIntf) |
|
71 : CSubConnectionFlowBase(aFactory, aSubConnId, aProtocolIntf), iMMState(EStopped) |
|
72 { |
|
73 LOG_NODE_CREATE(KEthLogTag2, CLANLinkCommon); |
|
74 } |
|
75 |
|
76 /** |
|
77 Loads, creates and starts the packet driver. |
|
78 The packet driver's name is found from the LAN service table in commdb. |
|
79 The name then has '.drv' appended and its driver factory is found using DoFindDriverFactoryL. |
|
80 If found, the packet driver is created using the factory's NewDriverL method and the driver state is set to EDrvStarted. |
|
81 @note Should be called from the ConstructL phase of the CLANLinkCommon initialisation. |
|
82 */ |
|
83 void CLANLinkCommon::LoadPacketDriverL() |
|
84 { |
|
85 TBuf<KCommsDbSvrDefaultTextFieldLength+4> drvName; // plus 4 is for the filename extension added below |
|
86 |
|
87 ASSERT(iLanLinkProvision); |
|
88 |
|
89 if (LinkProvision().PacketDriverName().Length() == 0) |
|
90 { |
|
91 __FLOG_STATIC(KEther802LogTag1,KEthLogTag2, _L("Empty packet driver name - is .cfg file up-to-date? See ether802.ini for information on required fields in commdb.")); |
|
92 User::Leave(KErrArgument); |
|
93 } |
|
94 |
|
95 drvName.Copy(LinkProvision().PacketDriverName()); |
|
96 |
|
97 if(!(drvName.Right(4)==KPacketDriverFileExtension())) // no != for comparing strings, so a bit of laboured logic |
|
98 { |
|
99 drvName.Append(KPacketDriverFileExtension); |
|
100 } |
|
101 |
|
102 // Ref counted library ownership to ensure the library is not unloaded prematurely |
|
103 CPktDrvFactory* pktFactory = (CPktDrvFactory *)DoCreateDriverFactoryL(TUid::Uid(KUidNifmanPktDrv), drvName); |
|
104 CleanupStack::PushL(pktFactory); |
|
105 iPktDrvOwner = new(ELeave)CPacketDriverOwner(pktFactory); |
|
106 CleanupStack::Pop(); |
|
107 iPktDrvOwner->Open(); |
|
108 |
|
109 iPktDrv=pktFactory->NewDriverL(this); |
|
110 } |
|
111 |
|
112 EXPORT_C CLANLinkCommon* CLANLinkCommon::NewL(CSubConnectionFlowFactoryBase& aFactory, const TNodeId& aSubConnId, CProtocolIntfBase* aProtocolIntf) |
|
113 { |
|
114 CLANLinkCommon* s=new (ELeave) CLANLinkCommon(aFactory, aSubConnId, aProtocolIntf); |
|
115 CleanupStack::PushL(s); |
|
116 s->ConstructL(); |
|
117 CleanupStack::Pop(); |
|
118 return s; |
|
119 } |
|
120 |
|
121 /** Ethernet Type - Encapsulation |
|
122 @internalComponent |
|
123 */ |
|
124 _LIT(KEtherType,"encapsulation"); |
|
125 |
|
126 /** |
|
127 Reads the Link layer Ethernet settings in Ether802.ini. Currently this is just the ethernet |
|
128 encapsulation type, stored in parameter encapsulation in section [ethernet], sets iEtherType |
|
129 on the basis of the encapsulation type: ELLCEthernet, if the encapsulation parameter = 1, or |
|
130 EStandardEthernet otherwise. |
|
131 */ |
|
132 void CLANLinkCommon::ReadEthintSettingsL() |
|
133 { |
|
134 CESockIniData* ini = CESockIniData::NewL(ETHER802_CONFIG_FILENAME); |
|
135 CleanupStack::PushL(ini); |
|
136 TInt encapType = 0; |
|
137 ini->FindVar(KEthernetSection,KEtherType,encapType); |
|
138 |
|
139 CleanupStack::PopAndDestroy(); |
|
140 |
|
141 switch(encapType) |
|
142 { |
|
143 case 0 : |
|
144 __FLOG_STATIC(KEther802LogTag1, KEthLogTag2, _L("Framing type set to Ethernet II")); |
|
145 iEtherType=EStandardEthernet; |
|
146 break; |
|
147 case 1 : |
|
148 __FLOG_STATIC(KEther802LogTag1, KEthLogTag2, _L("Framing type set to IEEE802.3 LLC-SNAP")); |
|
149 iEtherType=ELLCEthernet; |
|
150 break; |
|
151 default : |
|
152 __FLOG_STATIC(KEther802LogTag1, KEthLogTag2, _L("Unrecognised or no framing type in config file - framing type set to Ethernet II")); |
|
153 iEtherType=EStandardEthernet; // not a valid type |
|
154 } |
|
155 } |
|
156 |
|
157 /** |
|
158 Implementation of the pure virtual from CLANLinkBase, for use by the bearers. Returns the |
|
159 hardware interface obtained from the packet layer in the aBuffer descriptor in a 6 byte binary |
|
160 Big-endian format. |
|
161 @return ETrue if the hardware address was non-zero, EFalse otherwise. |
|
162 */ |
|
163 TBool CLANLinkCommon::ReadMACSettings() |
|
164 { |
|
165 TBuf8<KMACByteLength> drvMacAddr; |
|
166 TUint8* config=iPktDrv->GetInterfaceAddress(); |
|
167 drvMacAddr.Append(&config[0],KMACByteLength); // First 3 bytes of config not part of address |
|
168 iMacAddr.Copy(drvMacAddr); // update Ethints copy of the MAC address |
|
169 TUint bearerLim = iBearers->Count(); |
|
170 for(TUint index=0;index<bearerLim;index++) |
|
171 { |
|
172 CLanxBearer* bearer=(*iBearers)[index]; |
|
173 bearer->UpdateMACAddr(); |
|
174 } |
|
175 |
|
176 // check that the macaddress has been passed and is not 0; |
|
177 return CheckMac(iMacAddr); // wrong. |
|
178 } |
|
179 |
|
180 |
|
181 TUint CLANLinkCommon::Mtu() const |
|
182 { |
|
183 if(iEtherType==ELLCEthernet) |
|
184 { |
|
185 __FLOG_STATIC(KEther802LogTag1, KEthLogTag2, _L("MTU - value for LLC frames")); |
|
186 return KEtherMaxFrame; |
|
187 } |
|
188 __FLOG_STATIC(KEther802LogTag1, KEthLogTag2, _L("MTU - default setting")); |
|
189 return KDefaultMtuSetting; |
|
190 } |
|
191 |
|
192 /** |
|
193 The CLANLinkCommon::ConstructL performs all the memory allocating initialisations. It's |
|
194 iContainer is allocated, using NewL; its iPktDriverFactories is created using its |
|
195 iContainer->CreateL. A dynamic array of 16 iBearers are created. |
|
196 @param TDesC Unused |
|
197 */ |
|
198 EXPORT_C void CLANLinkCommon::ConstructL() |
|
199 { |
|
200 __FLOG_STATIC(KEther802LogTag1,KEthLogTag2, _L("Ethint started")); |
|
201 |
|
202 // Initialise class members that do not need to be read from the database |
|
203 iBearers = new (ELeave) CLanxBearerPtrArray(16); |
|
204 iOnlyThisBearer = NULL; |
|
205 |
|
206 __FLOG_STATIC(KEther802LogTag1, KEthLogTag2, _L("Reading Ethint settings")); |
|
207 ReadEthintSettingsL(); |
|
208 |
|
209 #ifdef TCPDUMP_LOGGING |
|
210 __FLOG_STATIC(KEther802LogTag1, KEthLogTag2, _L("Libpcap format logging enabled")); |
|
211 iLogger = CEthLog::NewL(); |
|
212 iLogger->DumpTcpDumpFileHeader(); |
|
213 #endif // TCPDUMP_LOGGING |
|
214 } |
|
215 |
|
216 /** |
|
217 Destructor. If there are any iPktDrvFactories, these are deleted first, by closing each Factory's |
|
218 RLibrary iLib handle and then deleting the object. Then all the bearers are deleted . Finally, |
|
219 the packet driver, the logical device driver and the physical device driver are freed and then |
|
220 the packet driver is deleted. |
|
221 */ |
|
222 EXPORT_C CLANLinkCommon::~CLANLinkCommon() |
|
223 { |
|
224 #ifdef TCPDUMP_LOGGING |
|
225 delete iLogger; |
|
226 #endif // TCPDUMP_LOGGING |
|
227 |
|
228 delete iPktDrv; |
|
229 if(iPktDrvOwner != NULL ) // iPktDrvOwner may not be created if leave occurs while loading the driver. |
|
230 { |
|
231 iPktDrvOwner->Close(); |
|
232 } |
|
233 ASSERT(0 == iBearers->Count()); |
|
234 delete iBearers; |
|
235 |
|
236 LOG_NODE_DESTROY(KEthLogTag2, CLANLinkCommon); |
|
237 } |
|
238 |
|
239 /** |
|
240 Checks the descriptor for a valid (non-zero) MAC address. |
|
241 @param aMacAddr A reference to a the descriptor containing the new MAC |
|
242 @return ETrue if the MAC address was non-zero, EFalse otherwise. |
|
243 */ |
|
244 TBool CLANLinkCommon::CheckMac(TDes8& aMacAddr) |
|
245 { |
|
246 for (TUint i=0;i<=5;i++) |
|
247 { |
|
248 if (aMacAddr[i] != 0) |
|
249 return ETrue; |
|
250 } |
|
251 return EFalse; |
|
252 } |
|
253 |
|
254 /** |
|
255 This method is intended for use when a device does not have the correct MAC address when ARP is started |
|
256 (e.g. IRLAN). It must be called by the packet driver as soon as an interface address is available. |
|
257 It should be called before the packet driver sends LinkLayerUp to nifman,otherwise packets could |
|
258 be sent with an invalid hardware address. |
|
259 */ |
|
260 EXPORT_C void CLANLinkCommon::FoundMACAddrL() |
|
261 { |
|
262 iValidMacAddr = ReadMACSettings(); |
|
263 } |
|
264 |
|
265 /** |
|
266 Link Layer Up |
|
267 Called by the packet driver when it is happy |
|
268 @internalTechnology |
|
269 */ |
|
270 EXPORT_C void CLANLinkCommon::LinkLayerUp() |
|
271 { |
|
272 //some drivers have a valid MAC only after negotiation finishes |
|
273 iValidMacAddr = ReadMACSettings(); |
|
274 PostDataClientStartedMessage(); |
|
275 |
|
276 __FLOG_STATIC(KEther802LogTag1, KEthLogTag2, _L ("CLANLinkCommon::LinkLayerUp()")); |
|
277 |
|
278 /** |
|
279 With the new comms framework, this KLinkLayerOpen always sent and then will be caught and swallowed |
|
280 at the ipproto layer if a netcfgext is being used. */ |
|
281 #ifndef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
282 if (LinkProvision().ConfigDaemonName().Length() == 0) |
|
283 { |
|
284 #endif |
|
285 |
|
286 #ifndef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
287 } |
|
288 #endif |
|
289 |
|
290 TUint bearerLim = iBearers->Count(); |
|
291 for(TUint index=0;index<bearerLim;index++) |
|
292 { |
|
293 CLanxBearer *bearer=(*iBearers)[index]; |
|
294 bearer->StartSending((CProtocolBase*)this); |
|
295 } |
|
296 } |
|
297 |
|
298 EXPORT_C void CLANLinkCommon::LinkLayerDown(TInt aError, TAction aAction) // Notify the Protocol that the line is down |
|
299 /** |
|
300 Link Layer Down |
|
301 Called by the packet driver when the link has gone down |
|
302 |
|
303 @param aError error code |
|
304 @param aAction whether a reconnect is required or not |
|
305 @internalTechnology |
|
306 */ |
|
307 { |
|
308 // If a stop was requested from the SCpr then this LinkLayerDown() |
|
309 // was expected. This also means the SCpr has already been sent a |
|
310 // TCFDataClient::TStopped and the packet driver has been stopped. |
|
311 // If on the other hand the stop was not requested a TDataClientGoneDown |
|
312 // message needs to be sent to the SCpr and the packet driver still |
|
313 // needs a StopInterface call - usually this would mean that aAction |
|
314 // is EReconnect |
|
315 if (iStopRequested == EFalse && iMMState == EStarted) |
|
316 { |
|
317 |
|
318 PostFlowGoingDownMessage(aError, (aAction == EReconnect) ? MNifIfNotify::EReconnect : MNifIfNotify::EDisconnect); |
|
319 iPktDrv->StopInterface(); |
|
320 iMMState = EStopped; |
|
321 } |
|
322 } |
|
323 |
|
324 /** |
|
325 Given the RMBufChain &aPdu, which contains a PktInfo at the start, Convert the PktInfo into |
|
326 an ether frame header. The source and dest address is already assumed to be filled, i.e. |
|
327 multi-cast or whatever. aPdu is returned modified. |
|
328 @param aPdu Contains a PktInfo. |
|
329 @param aType The Ether type for the packet, |
|
330 @return An error code, KErrNone if the Ethernet header could be prepended, or KErrGeneral |
|
331 if it could not. |
|
332 */ |
|
333 TInt CLANLinkCommon::EtherFrame(RMBufChain &aPdu, TUint16 aType) |
|
334 { |
|
335 TInt ret; |
|
336 //To start with, we need a buffer for the ethernet header, |
|
337 //and the packet info. |
|
338 |
|
339 //Create an ether header |
|
340 RMBufChain ethHdr; |
|
341 TUint etherHeaderSize = (iEtherType==EStandardEthernet) ? |
|
342 KEtherHeaderSize : KEtherLLCHeaderSize; |
|
343 TRAP(ret, ethHdr.AllocL(etherHeaderSize)); |
|
344 if (ret != KErrNone) |
|
345 { |
|
346 return ret; |
|
347 } |
|
348 TEtherLLCFrame *hdrBuf=(TEtherLLCFrame*)ethHdr.First()->Buffer(); |
|
349 |
|
350 //Get the packet info: |
|
351 RMBufPktInfo* info = RMBufPacket::PeekInfoInChain(aPdu); |
|
352 |
|
353 // Fill in the dest, src Mac addresses: |
|
354 hdrBuf->SetDestAddr(info->iDstAddr); |
|
355 hdrBuf->SetSrcAddr(iMacAddr); |
|
356 switch(iEtherType) |
|
357 { |
|
358 case EStandardEthernet: |
|
359 BigEndian::Put16((TUint8*)&hdrBuf->iTypeLen,aType); |
|
360 break; |
|
361 case ELLCEthernet: |
|
362 // Several fields to fill in. According to nifmbuf.h, |
|
363 // info->iLength gives the actual length of the packet. |
|
364 BigEndian::Put16((TUint8*)&hdrBuf->iTypeLen,static_cast<TInt16>(info->iLength)); |
|
365 hdrBuf->iDSAP=KLLC_SNAP_DSAP; |
|
366 hdrBuf->iSSAP=KLLC_SNAP_SSAP; |
|
367 hdrBuf->iCtrl=KLLC_SNAP_CTRL; |
|
368 hdrBuf->SetOUI(0); |
|
369 hdrBuf->SetType(aType); |
|
370 break; |
|
371 default: |
|
372 // Can't handle any other kind of Ethernet header. |
|
373 return KErrGeneral; |
|
374 } |
|
375 //Remove the original first Packet - by trimming the info from the packet. |
|
376 TUint dummyLength=aPdu.Length(); // At this point, info becomes invalid. |
|
377 aPdu.TrimStart(dummyLength-info->iLength); |
|
378 //Finally, add the saved packet buffer to the mac header |
|
379 aPdu.Prepend(ethHdr); |
|
380 return KErrNone; |
|
381 } |
|
382 |
|
383 /** |
|
384 FrameSend frames the aPdu packet, giving it a type field defined by aType and then sends it via |
|
385 the packet driver's Send method, returning its return value. If there is an error framing the |
|
386 packet, the packet is dropped and KErrGeneral is returned. |
|
387 @param aPdu The Packet to be sent (actually an RMBufPkt). |
|
388 @param aProtocol A pointer to the protocol which sent the packet (ignored) |
|
389 @param aType The Type field in the Ethernet header when framing. For iEtherFrame== EStandardEthernet, |
|
390 this is stored in the iType field, for ELLCEthernet, this is stored in the |
|
391 iTypeHi:iTypeLo fields. |
|
392 @return 0 Tells the higher layer to send no more data else |
|
393 1 Tells higher layer that it can send more data |
|
394 */ |
|
395 TInt CLANLinkCommon::FrameSend(RMBufChain& aPdu,TAny* /*aProtocol*/, TUint16 aType) |
|
396 { |
|
397 // Call down from the Protocol |
|
398 // The data begins in the second MBuf - because the first one |
|
399 // is the info. The upper layer must have filled in the destination |
|
400 // and source Mac addresses before this method is called and must |
|
401 // supply the ether header type in aType. |
|
402 // EtherFrame strips off the info and replaces it by the proper |
|
403 // ether header. |
|
404 |
|
405 // Caller Flow controls off if the return to this method is <= 0 |
|
406 if(EtherFrame(aPdu,aType)==KErrNone) |
|
407 { |
|
408 // Dump it to the log in pcap format |
|
409 #ifdef TCPDUMP_LOGGING |
|
410 //Find absolute time now |
|
411 TTime timeNow; |
|
412 timeNow.HomeTime(); |
|
413 |
|
414 iLogger->DumpFrame(timeNow,aPdu); |
|
415 #endif |
|
416 |
|
417 return iPktDrv->Send(aPdu); |
|
418 } |
|
419 else |
|
420 { // drop the packet and return an error - incorrectly formatted. |
|
421 // which error though? |
|
422 aPdu.Free(); |
|
423 } |
|
424 return KErrGeneral; // Should be a better error code though. |
|
425 } |
|
426 |
|
427 |
|
428 /** |
|
429 GetProtocolType extracts protocol header information from an ethernet packet and is called |
|
430 when processing a packet. |
|
431 @param aPdu An Ethernet packet (actually, it is really an RMBufPkt with a packed |
|
432 info, not an RMBufChain) |
|
433 @param aEtherType The Ether type for the packet, which is the type field for the packet, |
|
434 for example: KIPFrameType (=0x800) or KIP6FrameType (0x8dd). Note: |
|
435 GetProtocolType makes no restrictions on valid EtherTypes, since |
|
436 this is handled by the bearers. |
|
437 @param aPayloadPtr A pointer to the beginning of the actual payload after the Ethernet |
|
438 header (or the Ethernet LLC header). |
|
439 @param aEtherHeaderSize The size of the Ethernet header, either the standard ethernet header |
|
440 size (KEtherHeaderSize==14), or the LLC header size (KEtherLLCHeaderSize= standard+8). |
|
441 @return An error code, KErrNone, if a valid procol type could be extracted, or KErrNotSupported otherwise. |
|
442 */ |
|
443 TInt CLANLinkCommon::GetProtocolType(RMBufChain& aPdu, |
|
444 TUint16& aEtherType, TUint8*& aPayloadPtr, |
|
445 TUint& aEtherHeaderSize) const |
|
446 { |
|
447 RMBuf* chnptr=aPdu.First(); // Start of received packet |
|
448 // Start of actual packet data (Ethernet II) |
|
449 TEtherFrame *etherFrame=(TEtherFrame*)(chnptr->Next()->Ptr()); |
|
450 |
|
451 if ((aEtherType=etherFrame->GetType())>=1536) |
|
452 { // Standard Ethernet type |
|
453 __ASSERT_DEBUG(chnptr->Next()->Length() >= KEtherHeaderSize, Panic(EIeee802AddrBadMBuf)); |
|
454 __FLOG_STATIC(KEther802LogTag1, KEthLogTag2, _L ("CLANLinkCommon::GetProtocolType () Got Ethernet-II-type frame")); |
|
455 |
|
456 if (chnptr->Next()->Length() == KEtherHeaderSize) |
|
457 { |
|
458 aPayloadPtr = chnptr->Next()->Ptr(); |
|
459 } |
|
460 else |
|
461 { |
|
462 aPayloadPtr = etherFrame->iData; |
|
463 } |
|
464 aEtherHeaderSize=KEtherHeaderSize; |
|
465 } |
|
466 else // It's an LLC Ethernet frame (802.3) |
|
467 { |
|
468 if(chnptr->Next()->Length() >= KEtherLLCHeaderSize) |
|
469 { |
|
470 TEtherLLCFrame *etherLLCFrame = (TEtherLLCFrame*)etherFrame; |
|
471 if(etherLLCFrame->iDSAP==KLLC_SNAP_DSAP && |
|
472 etherLLCFrame->iSSAP==KLLC_SNAP_SSAP && |
|
473 etherLLCFrame->iCtrl==KLLC_SNAP_CTRL) |
|
474 { // Valid LLC-SNAP Frame. |
|
475 __FLOG_STATIC(KEther802LogTag1, KEthLogTag2, _L ("CLANLinkCommon::GetProtocolType () Got 802.3-type frame, with LLC and SNAP headers")); |
|
476 aEtherType=etherLLCFrame->GetType(); // Standard Ethernet type. |
|
477 aPayloadPtr=etherLLCFrame->iData; |
|
478 aEtherHeaderSize=KEtherLLCHeaderSize; |
|
479 } |
|
480 else |
|
481 { |
|
482 __FLOG_STATIC(KEther802LogTag1, KEthLogTag2, _L ("CLANLinkCommon::GetProtocolType () Got what initially looked like a 802.3-type frame, but no SNAP header")); |
|
483 aEtherType=0; |
|
484 aPayloadPtr=0; |
|
485 aEtherHeaderSize=0; |
|
486 return KErrNotSupported; |
|
487 } |
|
488 } |
|
489 else |
|
490 { |
|
491 return KErrCorrupt; |
|
492 } |
|
493 } |
|
494 return KErrNone; |
|
495 } |
|
496 |
|
497 /** |
|
498 Process processes a packet received from the packet driver. |
|
499 @param aPdu The Packet to be sent (actually an RMBufPkt). |
|
500 @param aLLC Unclear. |
|
501 */ |
|
502 EXPORT_C void CLANLinkCommon::Process(RMBufChain& aPdu, TAny* /*aLLC*/) |
|
503 { |
|
504 TUint16 etherCode; |
|
505 TUint8* etherPtr; |
|
506 TUint etherHeaderSize; |
|
507 TBool packetProcessed=EFalse; |
|
508 TInt ret=GetProtocolType(aPdu,etherCode,etherPtr,etherHeaderSize); |
|
509 if (ret==KErrNone) |
|
510 { // It's an ethernet packet of some kind. |
|
511 |
|
512 // Dump it to the log in pcap format |
|
513 #ifdef TCPDUMP_LOGGING |
|
514 //Find absolute time now |
|
515 TTime timeNow; |
|
516 timeNow.HomeTime(); |
|
517 |
|
518 RMBufPacket& pkt = (RMBufPacket&)aPdu; |
|
519 pkt.Unpack(); |
|
520 iLogger->DumpFrame(timeNow,aPdu); |
|
521 pkt.Pack(); |
|
522 #endif |
|
523 |
|
524 TUint bearerLim = iBearers->Count(); |
|
525 for(TUint index=0;index<bearerLim && !packetProcessed;index++) |
|
526 { |
|
527 CLanxBearer* bearer=(*iBearers)[index]; |
|
528 if (BearerIsActive(bearer)) |
|
529 { |
|
530 if(bearer->WantsProtocol(etherCode,etherPtr)) |
|
531 { |
|
532 RMBufPacket& pkt = (RMBufPacket&)aPdu; |
|
533 pkt.Unpack(); |
|
534 pkt.TrimStart(etherHeaderSize); |
|
535 pkt.Pack(); |
|
536 bearer->Process(aPdu, (TAny*)(TUint32)etherCode); // process expects ether type, but fixed function definition... |
|
537 packetProcessed=ETrue; |
|
538 } |
|
539 } |
|
540 } |
|
541 } |
|
542 if (ret!=KErrNone || !packetProcessed) |
|
543 { |
|
544 __FLOG_STATIC(KEther802LogTag1, KEthLogTag2, _L ("CLANLinkCommon::Process() - dropping packet - unrecognised type")); |
|
545 aPdu.Free(); // Something strange about the packet - bin it |
|
546 } |
|
547 } |
|
548 |
|
549 /** |
|
550 Implementation of pure virtual from CLANLinkBase for use by the packet driver. |
|
551 Resume Sending is a notification call into NIF from the lower layer telling the NIF that a |
|
552 previous sending congestion situation has been cleared and it can accept more downstack data. |
|
553 NIF subsequently calls all the bearers' StartSending() methods directly. |
|
554 */ |
|
555 EXPORT_C void CLANLinkCommon::ResumeSending() |
|
556 { |
|
557 TUint bearerLim = iBearers->Count(); |
|
558 for(TUint index=0;index<bearerLim;index++) |
|
559 { |
|
560 CLanxBearer* bearer=(*iBearers)[index]; |
|
561 bearer->StartSending((CProtocolBase*)this); |
|
562 } |
|
563 } |
|
564 |
|
565 /** |
|
566 |
|
567 */ |
|
568 EXPORT_C TInt CLANLinkCommon::ReadInt(const TDesC& /*aField*/, TUint32& /*aValue*/) |
|
569 { |
|
570 return KErrNotSupported; |
|
571 } |
|
572 |
|
573 /** |
|
574 |
|
575 */ |
|
576 EXPORT_C TInt CLANLinkCommon::WriteInt(const TDesC& /*aField*/, TUint32 /*aValue*/) |
|
577 { |
|
578 return KErrNotSupported; |
|
579 } |
|
580 |
|
581 /** |
|
582 |
|
583 */ |
|
584 EXPORT_C TInt CLANLinkCommon::ReadDes(const TDesC& /*aField*/, TDes8& /*aValue*/) |
|
585 { |
|
586 return KErrNotSupported; |
|
587 } |
|
588 |
|
589 /** |
|
590 |
|
591 */ |
|
592 EXPORT_C TInt CLANLinkCommon::ReadDes(const TDesC& aField, TDes16& aValue) |
|
593 { |
|
594 // Emulate reading of following parameters only: |
|
595 // LAN_BEARER\LAN_BEARER_LDD_FILENAME |
|
596 // LAN_BEARER\LAN_BEARER_LDD_NAME |
|
597 // LAN_BEARER\LAN_BEARER_PDD_FILENAME |
|
598 // LAN_BEARER\LAN_BEARER_PDD_NAME |
|
599 |
|
600 _LIT(KLanBearer, "LANBearer\\"); |
|
601 const TInt KLanBearerTokenSize = 10; |
|
602 |
|
603 TPtrC field(aField.Left(KLanBearerTokenSize)); // "LANBearer" |
|
604 |
|
605 if (field.Compare(KLanBearer()) == 0) |
|
606 { |
|
607 _LIT(KLanBearerLddFilename, "LDDFilename"); |
|
608 _LIT(KLanBearerLddName, "LDDName"); |
|
609 _LIT(KLanBearerPddFilename, "PDDFilename"); |
|
610 _LIT(KLanBearerPddName, "PDDName"); |
|
611 |
|
612 field.Set(aField.Mid(KLanBearerTokenSize)); // skip "LANBearer\\" |
|
613 if (field.CompareF(KLanBearerLddFilename) == 0) |
|
614 { |
|
615 aValue.Copy(LinkProvision().LddFilename()); |
|
616 } |
|
617 else |
|
618 if (field.CompareF(KLanBearerLddName) == 0) |
|
619 { |
|
620 aValue.Copy(LinkProvision().LddName()); |
|
621 } |
|
622 else |
|
623 if (field.CompareF(KLanBearerPddFilename) == 0) |
|
624 { |
|
625 aValue.Copy(LinkProvision().PddFilename()); |
|
626 } |
|
627 else |
|
628 if (field.CompareF(KLanBearerPddName) == 0) |
|
629 { |
|
630 aValue.Copy(LinkProvision().PddName()); |
|
631 } |
|
632 else |
|
633 { |
|
634 return KErrNotSupported; |
|
635 } |
|
636 return KErrNone; |
|
637 } |
|
638 else |
|
639 { |
|
640 return KErrNotSupported; |
|
641 } |
|
642 } |
|
643 |
|
644 /** |
|
645 |
|
646 */ |
|
647 EXPORT_C TInt CLANLinkCommon::WriteDes(const TDesC& /*aField*/, const TDesC8& /*aValue*/) |
|
648 { |
|
649 return KErrNotSupported; |
|
650 } |
|
651 |
|
652 /** |
|
653 |
|
654 */ |
|
655 EXPORT_C TInt CLANLinkCommon::WriteDes(const TDesC& /*aField*/, const TDesC16& /*aValue*/) |
|
656 { |
|
657 return KErrNotSupported; |
|
658 } |
|
659 |
|
660 /** |
|
661 |
|
662 */ |
|
663 EXPORT_C TInt CLANLinkCommon::ReadBool(const TDesC& /*aField*/, TBool& /*aValue*/) |
|
664 { |
|
665 return KErrNotSupported; |
|
666 } |
|
667 |
|
668 /** |
|
669 |
|
670 */ |
|
671 EXPORT_C TInt CLANLinkCommon::WriteBool(const TDesC& /*aField*/, TBool /*aValue*/) |
|
672 { |
|
673 return KErrNotSupported; |
|
674 } |
|
675 |
|
676 /** |
|
677 |
|
678 */ |
|
679 EXPORT_C void CLANLinkCommon::IfProgress(TInt aStage, TInt aError) |
|
680 { |
|
681 PostProgressMessage(aStage, aError); |
|
682 } |
|
683 |
|
684 /** |
|
685 |
|
686 */ |
|
687 EXPORT_C void CLANLinkCommon::NifEvent(TNetworkAdaptorEventType /*aEventType*/, TUint /*aEvent*/, const TDesC8& /*aEventData*/, TAny* /*aSource*/) |
|
688 { |
|
689 } |
|
690 |
|
691 |
|
692 /** |
|
693 Load a factory and check the Uid etc |
|
694 function always opens factory CObject if successful |
|
695 */ |
|
696 CPktDrvFactory* CLANLinkCommon::DoCreateDriverFactoryL(TUid aUid2,const TDesC& aFilename) |
|
697 { |
|
698 TParse parse; |
|
699 User::LeaveIfError(parse.Set(aFilename,0,0)); |
|
700 |
|
701 CPktDrvFactory* f=0; |
|
702 |
|
703 TAutoClose<RLibrary> lib; |
|
704 User::LeaveIfError(lib.iObj.Load(aFilename)); |
|
705 lib.PushL(); |
|
706 // The Uid check |
|
707 if(lib.iObj.Type()[1]!=aUid2) |
|
708 User::Leave(KErrBadLibraryEntryPoint); |
|
709 |
|
710 TPktDrvFactoryNewL libEntry=(TPktDrvFactoryNewL)lib.iObj.Lookup(1); |
|
711 if (libEntry==NULL) |
|
712 User::Leave(KErrNoMemory); |
|
713 |
|
714 f =(*libEntry)(); // Opens CObject (can leave) |
|
715 |
|
716 CleanupStack::PushL(f); |
|
717 f->Install(lib.iObj); // Transfers the library object if successful |
|
718 |
|
719 // Can pop the library now - auto close will have no effect because handle is null |
|
720 CleanupStack::Pop(); |
|
721 lib.Pop(); |
|
722 |
|
723 return f; |
|
724 } |
|
725 |
|
726 |
|
727 // ====================================================================================== |
|
728 // |
|
729 // from MFlowBinderControl |
|
730 |
|
731 EXPORT_C MLowerControl* CLANLinkCommon::GetControlL(const TDesC8& aName) |
|
732 /** |
|
733 Request from upper CFProtocol to retrieve our MLowerControl class. |
|
734 |
|
735 @param aName Protocol Name. Presently, only "ip" and "ip6" are supported. |
|
736 @return pointer to our MLowerControl class instance. We leave on an error, hence this routine should |
|
737 never return NULL. |
|
738 */ |
|
739 { |
|
740 CLanxBearer* bearer=NULL; |
|
741 if (aName.CompareF(KDescIp6) == 0) |
|
742 { |
|
743 bearer = new(ELeave) CLanIp6Bearer(this); |
|
744 } |
|
745 else if (aName.CompareF(KDescIp) == 0 || aName.CompareF(KDescIcmp) == 0) |
|
746 { |
|
747 bearer = new(ELeave) CLanIp4Bearer(this); |
|
748 } |
|
749 else |
|
750 { |
|
751 User::Leave(KErrNotSupported); |
|
752 } |
|
753 |
|
754 CleanupStack::PushL(bearer); |
|
755 bearer->ConstructL(); |
|
756 |
|
757 // Must have provisioning information to operate |
|
758 ASSERT(iLanLinkProvision); |
|
759 iBearers->AppendL(bearer); |
|
760 ProvisionBearerConfigL(aName); |
|
761 CleanupStack::Pop(); |
|
762 return bearer; |
|
763 } |
|
764 |
|
765 EXPORT_C MLowerDataSender* CLANLinkCommon::BindL(const TDesC8& aProtocol, MUpperDataReceiver* aReceiver, MUpperControl* aControl) |
|
766 /** |
|
767 Request from upper CFProtocol to bind to this module. |
|
768 |
|
769 @param aProtocol protocol name (e.g. "ip", "ip6" etc). |
|
770 @param aReceiver pointer to MUpperDataReceiver instance of upper CFProtocol |
|
771 @param aControl pointer to MUpperControl instance of upper CFProtocol |
|
772 @return pointer to our MLowerDataSender instance (eventually passed to the upper CFProtocol) |
|
773 */ |
|
774 { |
|
775 TInt index = 0; |
|
776 CLanxBearer* bearer = FindBearerByProtocolName(aProtocol, index); |
|
777 if (bearer) |
|
778 { |
|
779 bearer->SetUpperPointers(aReceiver, aControl); |
|
780 if (iValidMacAddr) |
|
781 { |
|
782 aControl->StartSending(); |
|
783 } |
|
784 } |
|
785 else |
|
786 { |
|
787 User::Leave(KErrNotSupported); |
|
788 } |
|
789 |
|
790 iSubConnectionProvider.RNodeInterface::PostMessage(Id(), TCFControlProvider::TActive().CRef()); |
|
791 return bearer; |
|
792 } |
|
793 |
|
794 EXPORT_C void CLANLinkCommon::Unbind(MUpperDataReceiver* /*aReceiver*/, MUpperControl* aControl) |
|
795 /** |
|
796 Request from upper CFProtocol to unbind from this module. |
|
797 |
|
798 @param aReceiver pointer to data receiver class of upper CFProtocol (originally passed to it in downward BindL() request) |
|
799 @param aControl pointer to control class of upper CFProtocol (originally passed to it in downward BindL() request) |
|
800 */ |
|
801 |
|
802 { |
|
803 TInt index = 0; |
|
804 CLanxBearer* bearer = FindBearerByUpperControl(aControl, index); |
|
805 ASSERT(bearer); |
|
806 iBearers->Delete(index); |
|
807 delete bearer; |
|
808 |
|
809 // If no-one remains bound to us, signal data client idle to SCPR |
|
810 MaybePostDataClientIdle(); |
|
811 } |
|
812 |
|
813 |
|
814 // |
|
815 // Utilities |
|
816 // |
|
817 |
|
818 CLanxBearer* CLANLinkCommon::FindBearerByProtocolName(const TDesC8& aProtocol, TInt& aIndex) const |
|
819 /** |
|
820 Search the iBearers array searching for a match by protocol name. |
|
821 |
|
822 @param aProtocol name of protocol (in) |
|
823 @param aIndex on success, index of found entry (>=0), else -1. |
|
824 @return pointer to CLanxBearer entry on success else NULL. |
|
825 */ |
|
826 { |
|
827 TInt count = iBearers->Count(); |
|
828 for (TInt i = 0 ; i < count ; ++i) |
|
829 { |
|
830 CLanxBearer* bearer = iBearers->At(i); |
|
831 if (bearer->ProtocolName() == aProtocol) |
|
832 { |
|
833 aIndex = i; |
|
834 return bearer; |
|
835 } |
|
836 } |
|
837 aIndex = -1; |
|
838 return NULL; |
|
839 } |
|
840 |
|
841 CLanxBearer* CLANLinkCommon::FindBearerByUpperControl(const MUpperControl* aUpperControl, TInt& aIndex) const |
|
842 /** |
|
843 Search the iBearers array searching for a match by protocol name. |
|
844 |
|
845 @param aProtocol name of protocol (in) |
|
846 @param aIndex on success, index of found entry (>=0), else -1. |
|
847 @return pointer to CLanxBearer entry on success else NULL. |
|
848 */ |
|
849 { |
|
850 TInt count = iBearers->Count(); |
|
851 for (TInt i = 0 ; i < count ; ++i) |
|
852 { |
|
853 CLanxBearer* bearer = iBearers->At(i); |
|
854 if (bearer->MatchesUpperControl(aUpperControl)) |
|
855 { |
|
856 aIndex = i; |
|
857 return bearer; |
|
858 } |
|
859 } |
|
860 aIndex = -1; |
|
861 return NULL; |
|
862 } |
|
863 |
|
864 // ===================================================================================== |
|
865 // |
|
866 // Messages::ANode |
|
867 |
|
868 EXPORT_C void CLANLinkCommon::ReceivedL(const TRuntimeCtxId& aSender, const TNodeId& aRecipient, TSignatureBase& aMessage) |
|
869 /** |
|
870 Routine called on an incoming message from SCPR |
|
871 |
|
872 @param aCFMessage incoming message |
|
873 @return KErrNone, else a system wide error code. |
|
874 */ |
|
875 { |
|
876 CSubConnectionFlowBase::ReceivedL(aSender, aRecipient, aMessage); |
|
877 if (TEBase::ERealmId == aMessage.MessageId().Realm()) |
|
878 { |
|
879 switch (aMessage.MessageId().MessageId()) |
|
880 { |
|
881 case TEBase::TError::EId : |
|
882 SubConnectionError(static_cast<TEBase::TError&>(aMessage).iValue); |
|
883 break; |
|
884 case TEBase::TCancel::EId : |
|
885 CancelStartFlow(); |
|
886 break; |
|
887 default: |
|
888 ASSERT(EFalse); |
|
889 } |
|
890 } |
|
891 else if (TEChild::ERealmId == aMessage.MessageId().Realm()) |
|
892 { |
|
893 switch (aMessage.MessageId().MessageId()) |
|
894 { |
|
895 case TEChild::TDestroy::EId : |
|
896 Destroy(); |
|
897 break; |
|
898 default: |
|
899 ASSERT(EFalse); |
|
900 } |
|
901 } |
|
902 else if (TCFDataClient::ERealmId == aMessage.MessageId().Realm()) |
|
903 { |
|
904 switch (aMessage.MessageId().MessageId()) |
|
905 { |
|
906 case TCFDataClient::TStart::EId : |
|
907 StartFlowL(); |
|
908 break; |
|
909 case TCFDataClient::TProvisionConfig::EId : |
|
910 ProvisionConfig(static_cast<TCFDataClient::TProvisionConfig&>(aMessage).iConfig); |
|
911 break; |
|
912 case TCFDataClient::TStop::EId : |
|
913 StopFlow(static_cast<TCFDataClient::TStop&>(aMessage).iValue); |
|
914 break; |
|
915 case TCFDataClient::TBindTo::EId : |
|
916 { |
|
917 TCFDataClient::TBindTo& bindToReq = message_cast<TCFDataClient::TBindTo>(aMessage); |
|
918 if (!bindToReq.iNodeId.IsNull()) |
|
919 { |
|
920 User::Leave(KErrNotSupported); |
|
921 } |
|
922 RClientInterface::OpenPostMessageClose(Id(), aSender, TCFDataClient::TBindToComplete().CRef()); |
|
923 } |
|
924 break; |
|
925 default: |
|
926 ASSERT(EFalse); |
|
927 } |
|
928 } |
|
929 else if (TLinkMessage::ERealmId == aMessage.MessageId().Realm()) |
|
930 { |
|
931 switch (aMessage.MessageId().MessageId()) |
|
932 { |
|
933 case TLinkMessage::TAgentToFlowNotification::EId: |
|
934 { |
|
935 TLinkMessage::TAgentToFlowNotification& msg = message_cast<TLinkMessage::TAgentToFlowNotification>(aMessage); |
|
936 if(msg.iValue < KVendorSpecificNotificationStart) |
|
937 { |
|
938 User::Leave(KErrNotSupported); |
|
939 } |
|
940 else |
|
941 { |
|
942 User::LeaveIfError((iPktDrv) ? iPktDrv->Notification( |
|
943 static_cast<TAgentToNifEventType>(msg.iValue), NULL) : KErrNotSupported); |
|
944 } |
|
945 } |
|
946 break; |
|
947 default: |
|
948 ASSERT(EFalse); |
|
949 }; //endswitch |
|
950 } |
|
951 else // (message and realm not recognised within this domain) |
|
952 { |
|
953 ASSERT(EFalse); |
|
954 } |
|
955 } |
|
956 |
|
957 // |
|
958 // Methods for handling incoming SCPR messages |
|
959 // |
|
960 |
|
961 void CLANLinkCommon::StartFlowL() |
|
962 { |
|
963 iStopRequested = EFalse; |
|
964 |
|
965 ASSERT(iMMState == EStopped); |
|
966 |
|
967 if (iSavedError != KErrNone) |
|
968 { |
|
969 // If there were errors during prior processing of the TProvisionConfig message, |
|
970 // leave here and cause a TError response to TCFDataClient::TStart. |
|
971 User::Leave(iSavedError); |
|
972 } |
|
973 |
|
974 iValidMacAddr = ReadMACSettings(); |
|
975 |
|
976 __FLOG_STATIC(KEther802LogTag1, KEthLogTag2, _L("Starting Interface")); |
|
977 iMMState = EStarting; |
|
978 User::LeaveIfError(iPktDrv->StartInterface()); |
|
979 } |
|
980 |
|
981 |
|
982 void CLANLinkCommon::CancelStartFlow() |
|
983 { |
|
984 if (iMMState == EStarting) |
|
985 { |
|
986 iStopRequested = ETrue; |
|
987 |
|
988 iPktDrv->StopInterface(); |
|
989 PostFlowDownMessage(KErrCancel); |
|
990 } |
|
991 } |
|
992 |
|
993 void CLANLinkCommon::StopFlow(TInt aError) |
|
994 { |
|
995 iStopRequested = ETrue; |
|
996 iMMState = EStopping; |
|
997 |
|
998 iPktDrv->StopInterface(); |
|
999 PostFlowDownMessage(aError); |
|
1000 } |
|
1001 |
|
1002 void CLANLinkCommon::SubConnectionGoingDown() |
|
1003 { |
|
1004 } |
|
1005 |
|
1006 void CLANLinkCommon::SubConnectionError(TInt /*aError*/) |
|
1007 { |
|
1008 } |
|
1009 |
|
1010 |
|
1011 /* |
|
1012 Provisioning description for Ethernet CFProtocol Flow: |
|
1013 |
|
1014 - on receipt of the TProvisionConfig message, the pointer contained within is stored |
|
1015 in iAccessPointConfig and the provisioning information contained within the AccessPointConfig |
|
1016 array is validated: |
|
1017 - TLanLinkProvision must be present. It is added by the EtherMCPr and populated from CommsDat. A pointer to it |
|
1018 is stored in iLanLinkProvision. |
|
1019 - at least one of TLanIp4Provision or TLanIp6Provision must be present. They are added by the EtherMCPr and |
|
1020 populated from CommsDat. |
|
1021 |
|
1022 - the packet driver is loaded. |
|
1023 |
|
1024 - if any of the above steps fail, the resulting error is saved in iSaveError so that when TCFDataClient::TStart message is |
|
1025 subsequently received, a TError message can be sent in response (there is no response to TProvisionConfig message). |
|
1026 */ |
|
1027 |
|
1028 void CLANLinkCommon::ProvisionConfig(const RMetaExtensionContainerC& aConfigData) |
|
1029 { |
|
1030 __FLOG_STATIC(KEther802LogTag1,KEthLogTag2,_L("CLANLinkCommon:\tProvisionConfig message received")); |
|
1031 |
|
1032 AccessPointConfig().Close(); |
|
1033 AccessPointConfig().Open(aConfigData); |
|
1034 |
|
1035 ASSERT(iLanLinkProvision == NULL); // Should only happen once |
|
1036 |
|
1037 iLanLinkProvision = static_cast<const TLanLinkProvision*>(AccessPointConfig().FindExtension(STypeId::CreateSTypeId(TLanLinkProvision::EUid, TLanLinkProvision::ETypeId))); |
|
1038 if (iLanLinkProvision == NULL) |
|
1039 { |
|
1040 __FLOG_STATIC(KEther802LogTag1,KEthLogTag2,_L("CLANLinkCommon:\tProvisionConfig() - no Ethernet Link configuration")); |
|
1041 iSavedError = KErrCorrupt; |
|
1042 return; |
|
1043 } |
|
1044 |
|
1045 iLanIp4Provision = static_cast<const TLanIp4Provision*>(AccessPointConfig().FindExtension(STypeId::CreateSTypeId(TLanIp4Provision::EUid, TLanIp4Provision::ETypeId))); |
|
1046 if (iLanIp4Provision == NULL) |
|
1047 { |
|
1048 __FLOG_STATIC(KEther802LogTag1,KEthLogTag2,_L("CLANLinkCommon:\tProvisionConfig() - no IP4 configuration")); |
|
1049 } |
|
1050 |
|
1051 iLanIp6Provision = static_cast<const TLanIp6Provision*>(AccessPointConfig().FindExtension(STypeId::CreateSTypeId(TLanIp6Provision::EUid, TLanIp6Provision::ETypeId))); |
|
1052 if (iLanIp6Provision == NULL) |
|
1053 { |
|
1054 __FLOG_STATIC(KEther802LogTag1,KEthLogTag2,_L("CLANLinkCommon:\tProvisionConfig() - no IP6 config provisioned")); |
|
1055 } |
|
1056 |
|
1057 if (iLanIp4Provision == NULL && iLanIp6Provision == NULL) |
|
1058 { |
|
1059 // At least one set of IP4/6 provisioning information must be present |
|
1060 iSavedError = KErrCorrupt; |
|
1061 return; |
|
1062 } |
|
1063 |
|
1064 TRAPD(err, ProvisionConfigL()); |
|
1065 if (err != KErrNone) |
|
1066 { |
|
1067 iSavedError = err; |
|
1068 } |
|
1069 } |
|
1070 |
|
1071 |
|
1072 void CLANLinkCommon::ProvisionConfigL() |
|
1073 { |
|
1074 // Provision Bearers |
|
1075 if (iBearers->Count()) |
|
1076 { |
|
1077 ProvisionBearerConfigL(KDescIp()); |
|
1078 ProvisionBearerConfigL(KDescIp6()); |
|
1079 } |
|
1080 |
|
1081 __FLOG_STATIC(KEther802LogTag1, KEthLogTag2, _L("Loading packet driver")); |
|
1082 LoadPacketDriverL(); |
|
1083 } |
|
1084 |
|
1085 void CLANLinkCommon::Destroy() |
|
1086 { |
|
1087 ASSERT(iMMState==EStopped); |
|
1088 DeleteThisFlow(); |
|
1089 } |
|
1090 |
|
1091 // Utility functions |
|
1092 |
|
1093 void CLANLinkCommon::ProvisionBearerConfigL(const TDesC8& aName) |
|
1094 { |
|
1095 TInt index = -1; |
|
1096 CLanxBearer* bearer = FindBearerByProtocolName(aName, index); |
|
1097 if (bearer) |
|
1098 { |
|
1099 if (aName.CompareF(KDescIp) == 0) |
|
1100 { |
|
1101 if (iLanIp4Provision) |
|
1102 { |
|
1103 bearer->SetProvisionL(iLanIp4Provision); // CLanIp4Bearer |
|
1104 } |
|
1105 } |
|
1106 else if (aName.CompareF(KDescIp6) == 0) |
|
1107 { |
|
1108 if (iLanIp6Provision) |
|
1109 { |
|
1110 bearer->SetProvisionL(iLanIp6Provision); // CLanIp6Bearer |
|
1111 } |
|
1112 } |
|
1113 } |
|
1114 } |
|
1115 |
|
1116 void CLANLinkCommon::PostProgressMessage(TInt aStage, TInt aError) |
|
1117 { |
|
1118 //Be careful when sending TStateChange message as RNodeChannelInterface will override the activity id |
|
1119 iSubConnectionProvider.RNodeInterface::PostMessage(Id(), TCFMessage::TStateChange(TStateChange( aStage, aError)).CRef()); |
|
1120 } |
|
1121 |
|
1122 void CLANLinkCommon::PostFlowDownMessage(TInt aError) |
|
1123 { |
|
1124 if (iMMState == EStopping) |
|
1125 { |
|
1126 iLastRequestOriginator.ReplyTo(Id(), TCFDataClient::TStopped(aError).CRef()); |
|
1127 } |
|
1128 else if (iMMState == EStarting) |
|
1129 { |
|
1130 iLastRequestOriginator.ReplyTo(Id(), TEBase::TError(TCFDataClient::TStart::Id(), aError).CRef()); |
|
1131 } |
|
1132 else if (iMMState == EStarted) |
|
1133 { |
|
1134 iSubConnectionProvider.PostMessage(Id(), TCFControlProvider::TDataClientGoneDown(aError).CRef()); |
|
1135 } |
|
1136 iMMState = EStopped; |
|
1137 } |
|
1138 |
|
1139 void CLANLinkCommon::PostFlowGoingDownMessage(TInt aError, MNifIfNotify::TAction aAction) |
|
1140 { |
|
1141 // TDataClientGoneDown only makes sense if the flow was actually started |
|
1142 ASSERT(iMMState == EStarted); |
|
1143 iMMState = EStopped; |
|
1144 iSubConnectionProvider.PostMessage(Id(), TCFControlProvider::TDataClientGoneDown(aError, aAction).CRef()); |
|
1145 } |
|
1146 |
|
1147 void CLANLinkCommon::PostDataClientStartedMessage() |
|
1148 { |
|
1149 iMMState = EStarted; |
|
1150 iLastRequestOriginator.ReplyTo(Id(), TCFDataClient::TStarted().CRef()); |
|
1151 } |
|
1152 |
|
1153 void CLANLinkCommon::MaybePostDataClientIdle() |
|
1154 { |
|
1155 if (iBearers->Count() == 0) |
|
1156 { |
|
1157 iSubConnectionProvider.PostMessage(Id(), TCFControlProvider::TIdle().CRef()); |
|
1158 } |
|
1159 } |
|
1160 |
|
1161 |
|
1162 /** |
|
1163 Sets the BigEndian 32-bit value at iDstAddr to aDestAddr |
|
1164 Support methods for TEtherLLCFrame. |
|
1165 Note: These Methods should really go in a file for themselves. |
|
1166 @param aDest The destination IP address. |
|
1167 */ |
|
1168 void TEtherLLCFrame::SetDestAddr( TDesC8& aDest) |
|
1169 { |
|
1170 // copied a word at a time, remember BigEndian portability. |
|
1171 for(TUint ix=0; ix<3; ix++) |
|
1172 { |
|
1173 BigEndian::Put16((TUint8*)&iDestAddr[ix],(TUint16)(((aDest[ix*2]<<8)|aDest[ix*2+1])&0xffff)); |
|
1174 } |
|
1175 } |
|
1176 |
|
1177 /** |
|
1178 Sets the BigEndian 32-bit value at iSrcAddr to aSrcAddr. |
|
1179 @param aSrc The source IP address. |
|
1180 */ |
|
1181 void TEtherLLCFrame::SetSrcAddr(TDesC8& aSrc) |
|
1182 { |
|
1183 for(TUint ix=0; ix<3; ix++) |
|
1184 { |
|
1185 BigEndian::Put16((TUint8*)&iSrcAddr[ix],(TUint16)(((aSrc[ix*2]<<8)|aSrc[ix*2+1])&0xffff)); |
|
1186 } |
|
1187 } |
|
1188 |
|
1189 /** |
|
1190 aOUI is in native order, but the result is always stored in network byte order. |
|
1191 Can't use the bigendian methods, because they only work for 16 and 32 -bit items. |
|
1192 @param aOUI Byte order. |
|
1193 */ |
|
1194 void TEtherLLCFrame::SetOUI(TUint32 aOUI) |
|
1195 { |
|
1196 //aOUI is in native order, but the result is |
|
1197 //always stored in network byte order. |
|
1198 //Can't use the bigendian methods, because |
|
1199 //they only work for 16 and 32 -bit items. |
|
1200 OUI[0] = (TUint8)((aOUI>>16)&0xff); |
|
1201 OUI[1] = (TUint8)((aOUI>>8)&0xff); |
|
1202 OUI[2] = (TUint8)(aOUI&0xff); |
|
1203 } |
|
1204 |
|
1205 const TLanLinkProvision& CLANLinkCommon::LinkProvision() |
|
1206 { |
|
1207 return *iLanLinkProvision; |
|
1208 } |
|
1209 |
|
1210 void CLANLinkCommon::SetAllowedBearer(CLanxBearer* aBearer) |
|
1211 { |
|
1212 iOnlyThisBearer = aBearer; |
|
1213 } |
|
1214 TBool CLANLinkCommon::BearerIsActive(CLanxBearer* aBearer) |
|
1215 { |
|
1216 if (!iOnlyThisBearer || |
|
1217 aBearer == iOnlyThisBearer) |
|
1218 { |
|
1219 return ETrue; |
|
1220 } |
|
1221 return EFalse; |
|
1222 } |
|
1223 |