|
1 /* |
|
2 * Copyright (c) 2002-2006 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: Packet probe hook |
|
15 * |
|
16 */ |
|
17 |
|
18 #include "sap.h" |
|
19 |
|
20 |
|
21 CProviderProbe::CProviderProbe(CProtocolProbe* aProtocol) : iProtocol(aProtocol) |
|
22 { |
|
23 // __DECLARE_NAME(_S("CProviderProbe")); |
|
24 iQueueLimit = 8000; |
|
25 } |
|
26 |
|
27 CProviderProbe::~CProviderProbe() |
|
28 { |
|
29 if (iProtocol) |
|
30 iProtocol->CancelSAP(this); |
|
31 } |
|
32 |
|
33 void CProviderProbe::Start() |
|
34 { |
|
35 } |
|
36 |
|
37 TInt CProviderProbe::GetOption(TUint /*aLevel*/, TUint /*aName*/, TDes8& /*aOption*/) const |
|
38 { |
|
39 return KErrNotSupported; |
|
40 } |
|
41 |
|
42 TInt CProviderProbe::SetOption(TUint /*aLevel*/, TUint /*aName*/, const TDesC8& /*aOption*/) |
|
43 { |
|
44 // return KErrNotSupported; |
|
45 return KErrNone; |
|
46 } |
|
47 |
|
48 void CProviderProbe::Ioctl(TUint /*level*/,TUint /*name*/,TDes8* /*anOption*/) |
|
49 { |
|
50 Panic(EProbePanic_NotSupported); |
|
51 } |
|
52 |
|
53 void CProviderProbe::CancelIoctl(TUint /*aLevel*/,TUint /*aName*/) |
|
54 { |
|
55 Panic(EProbePanic_NotSupported); |
|
56 } |
|
57 |
|
58 |
|
59 TUint CProviderProbe::Write(const TDesC8 &/*aDesc*/, TUint /*aOptions*/, TSockAddr* /*aAddr*/) |
|
60 { |
|
61 // For now, Write does nothing on probe socket |
|
62 return 1; |
|
63 } |
|
64 |
|
65 void CProviderProbe::Shutdown(TCloseType /*option*/,const TDesC8& /*aDisconnectionData*/) |
|
66 { |
|
67 Panic(EProbePanic_NotSupported); |
|
68 } |
|
69 |
|
70 void CProviderProbe::Shutdown(TCloseType aOption) |
|
71 { |
|
72 switch(aOption) |
|
73 { |
|
74 case EStopInput: |
|
75 iInputStopped = ETrue; |
|
76 iRecvQ.Free(); |
|
77 iSocket->Error(KErrNone,MSocketNotify::EErrorClose); // Complete KErrNone |
|
78 break; |
|
79 |
|
80 case EStopOutput: |
|
81 iSocket->Error(KErrNone,MSocketNotify::EErrorClose); // Complete KErrNone |
|
82 break; |
|
83 |
|
84 default: |
|
85 if (aOption != EImmediate) |
|
86 iSocket->CanClose(); |
|
87 } |
|
88 } |
|
89 |
|
90 TInt CProviderProbe::SetLocalName(TSockAddr &/*aAddr*/) |
|
91 { |
|
92 return 0; // Ignore silently |
|
93 } |
|
94 |
|
95 void CProviderProbe::AutoBind() |
|
96 { |
|
97 // Ignore silently |
|
98 } |
|
99 |
|
100 // CProviderProbe::Error |
|
101 // ********************* |
|
102 // Soft errors are not immediately reported to the socket server. |
|
103 // A soft error is indicated by a zero aOperationMask. |
|
104 // |
|
105 // The socket error can be cleared by calling this routing with |
|
106 // aError == KErrNone. |
|
107 // |
|
108 void CProviderProbe::Error(TInt aError, TUint aOperationMask) |
|
109 { |
|
110 if (aError <= KErrNone && !FatalState()) |
|
111 { |
|
112 if (aError == KErrNone) |
|
113 iErrorMask = aOperationMask; |
|
114 else |
|
115 iErrorMask |= aOperationMask; |
|
116 if (iSocket && aOperationMask) |
|
117 iSocket->Error(aError, aOperationMask); |
|
118 } |
|
119 } |
|
120 |
|
121 // |
|
122 // CProviderProbe::Process() |
|
123 // ************************* |
|
124 // Process incoming data from the protocol object. |
|
125 // |
|
126 void CProviderProbe::Process(RMBufChain& aPacket, CProtocolBase * /*aSourceProtocol*/) |
|
127 { |
|
128 // iInputStopped is set at ShutDown() and no packets should be coming |
|
129 // from the protocol after that. However, without knowing the exact |
|
130 // details of the process model/threads, it could be possible that |
|
131 // a Process() call has been initiated by the protocol and interrupted |
|
132 // before the shutdown, thus there may be a need for this iInputStopped |
|
133 // flag, although I would prefer to do without... NEED TO VERIFY IF |
|
134 // iInputStopped is really needed!!! -- msa |
|
135 // |
|
136 if(!(iInputStopped || |
|
137 (iErrorMask & (MSocketNotify::EErrorFatal|MSocketNotify::EErrorConnect|MSocketNotify::EErrorRecv)))) |
|
138 { |
|
139 iQueueLimit -= RMBufPacketBase::PeekInfoInChain(aPacket)->iLength; |
|
140 iRecvQ.Append(aPacket); |
|
141 iSocket->NewData(1); |
|
142 } |
|
143 else |
|
144 aPacket.Free(); |
|
145 } |
|
146 |
|
147 // CProviderProbe::IsReceiving |
|
148 // *************************** |
|
149 // |
|
150 TBool CProviderProbe::IsReceiving(const RMBufPktInfo & /*aInfo*/) |
|
151 { |
|
152 if (iQueueLimit < 0) |
|
153 { |
|
154 // Receive Queue limit is full, cannot receive this packet |
|
155 iPacketsDropped++; |
|
156 return FALSE; |
|
157 } |
|
158 return TRUE; |
|
159 } |
|
160 |
|
161 |
|
162 // CProviderProbe::GetData |
|
163 // *********************** |
|
164 void CProviderProbe::GetData(TDes8 &aDesc, TUint aOptions, TSockAddr *anAddr) |
|
165 { |
|
166 RMBufPacketBase packet; |
|
167 if (!iRecvQ.Remove(packet)) |
|
168 Panic(EProbePanic_NoData); |
|
169 |
|
170 const RMBufPktInfo *const info = packet.Unpack(); |
|
171 |
|
172 packet.CopyOut(aDesc, 0); |
|
173 |
|
174 if (anAddr!=NULL) |
|
175 *anAddr = info->iSrcAddr; |
|
176 |
|
177 if (aOptions & KSockReadPeek) |
|
178 { |
|
179 packet.Pack(); |
|
180 iRecvQ.Prepend(packet); |
|
181 iSocket->NewData(1); |
|
182 } |
|
183 else |
|
184 { |
|
185 iQueueLimit += info->iLength; // Allow more packets in.. |
|
186 packet.Free(); |
|
187 } |
|
188 } |