|
1 /* |
|
2 * Copyright (c) 2004-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: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #define TRACE_PREFIX "WSOCK: Protocol: " |
|
20 #include "wsock.h" |
|
21 #include "WinsockProtocol.h" |
|
22 #include "WinsockProtocolFamily.h" |
|
23 #include "WinsockHostResolver.h" |
|
24 #include "WinsockServProvider.h" |
|
25 #include "WinsockUtils.h" |
|
26 |
|
27 CWinsockProtocol::CWinsockProtocol(const TWinProtocolDesc* aProtocolDesc) : |
|
28 iProtocolDesc(aProtocolDesc) |
|
29 { |
|
30 TRACE3("[%08X] created %s %S protocol",this, |
|
31 (iProtocolDesc->iAddrFamily == KAfInet6) ? _S("IPv6") : _S("IPv4"), |
|
32 &iProtocolDesc->iName); |
|
33 } |
|
34 |
|
35 CWinsockProtocol::~CWinsockProtocol() |
|
36 { |
|
37 iReadPending.Reset(); |
|
38 if (iIpHlpApi) |
|
39 { |
|
40 BEGIN_WIN32(); |
|
41 FreeLibrary((HMODULE)iIpHlpApi); |
|
42 END_WIN32(); |
|
43 } |
|
44 TRACE2("[%08X] deleted %S protocol",this,&iProtocolDesc->iName); |
|
45 } |
|
46 |
|
47 TBool CWinsockProtocol::IsStreamProtocol() const |
|
48 { |
|
49 return (iProtocolDesc->iSockType == KSockStream); |
|
50 } |
|
51 |
|
52 TBool CWinsockProtocol::IsDatagramProtocol() const |
|
53 { |
|
54 return (iProtocolDesc->iSockType == KSockDatagram); |
|
55 } |
|
56 |
|
57 void CWinsockProtocol::DataSent(TUint aBytes) |
|
58 { |
|
59 if (iWinsockInterface) |
|
60 { |
|
61 iWinsockInterface->DataSent(aBytes); |
|
62 } |
|
63 else if (iIfNotify) |
|
64 { |
|
65 iIfNotify->NotifyDataSent(KNifEntireConnectionSubConnectionId,aBytes); |
|
66 } |
|
67 } |
|
68 |
|
69 void CWinsockProtocol::DataReceived(TUint aBytes) |
|
70 { |
|
71 if (iWinsockInterface) |
|
72 { |
|
73 iWinsockInterface->DataReceived(aBytes); |
|
74 } |
|
75 else if (iIfNotify) |
|
76 { |
|
77 iIfNotify->NotifyDataReceived(KNifEntireConnectionSubConnectionId,aBytes); |
|
78 } |
|
79 } |
|
80 |
|
81 WinsockIpAdapterInfo* CWinsockProtocol::GetAdapterInfo() |
|
82 { |
|
83 if (!iIpHlpApi && iIpHlpApi != INVALID_HANDLE_VALUE) |
|
84 { |
|
85 BEGIN_WIN32(); |
|
86 iIpHlpApi = LoadLibraryA("IPHLPAPI.DLL"); |
|
87 if (iIpHlpApi) |
|
88 { |
|
89 iGetAdapterInfo = (GetAdaptersInfoProc)GetProcAddress((HMODULE) |
|
90 iIpHlpApi, "GetAdaptersInfo"); |
|
91 if (iGetAdapterInfo) |
|
92 { |
|
93 END_WIN32(); |
|
94 } |
|
95 else |
|
96 { |
|
97 FreeLibrary((HMODULE)iIpHlpApi); |
|
98 END_WIN32(); |
|
99 iIpHlpApi = INVALID_HANDLE_VALUE; |
|
100 TRACE("failed to find GetAdaptersInfo in IPHLPAPI.DLL"); |
|
101 } |
|
102 } |
|
103 else |
|
104 { |
|
105 END_WIN32(); |
|
106 iIpHlpApi = INVALID_HANDLE_VALUE; |
|
107 TRACE1("failed to load IPHLPAPI.DLL, err %d",GetLastError()); |
|
108 } |
|
109 } |
|
110 |
|
111 WinsockIpAdapterInfo* info = NULL; |
|
112 if (iGetAdapterInfo) |
|
113 { |
|
114 TUint len = 0; |
|
115 BEGIN_WIN32(); |
|
116 TUint err = iGetAdapterInfo(NULL, &len); |
|
117 END_WIN32(); |
|
118 if (err == ERROR_BUFFER_OVERFLOW && len > 0) |
|
119 { |
|
120 info = (WinsockIpAdapterInfo*)User::Alloc(len); |
|
121 if (info) |
|
122 { |
|
123 BEGIN_WIN32(); |
|
124 err = iGetAdapterInfo(info, &len); |
|
125 END_WIN32(); |
|
126 if (err != ERROR_SUCCESS) |
|
127 { |
|
128 TRACE1("GetAdapterInfo err %d",err); |
|
129 User::Free(info); |
|
130 info = NULL; |
|
131 } |
|
132 } |
|
133 } |
|
134 } |
|
135 return info; |
|
136 } |
|
137 |
|
138 // Notifies CWinsockProtocol that there are unread data in a particular |
|
139 // socket. |
|
140 void CWinsockProtocol::SetReadPending(CWinsockServProvider* aSocket, |
|
141 TBool aPending) |
|
142 { |
|
143 TInt index = iReadPending.FindInAddressOrder(aSocket); |
|
144 if (aPending) |
|
145 { |
|
146 if (index < 0) |
|
147 { |
|
148 iReadPending.InsertInAddressOrder(aSocket); |
|
149 TRACE2("[%08X] %d socket(s) have unread data",this, |
|
150 iReadPending.Count()); |
|
151 } |
|
152 } |
|
153 else |
|
154 { |
|
155 if (index >= 0) |
|
156 { |
|
157 iReadPending.Remove(index); |
|
158 TRACE2("[%08X] %d socket(s) have unread data",this, |
|
159 iReadPending.Count()); |
|
160 } |
|
161 } |
|
162 } |
|
163 |
|
164 // Checks if there are any unread data in any socket associated with this |
|
165 // protocol. |
|
166 TBool CWinsockProtocol::ReadPending() const |
|
167 { |
|
168 return (iReadPending.Count() > 0); |
|
169 } |
|
170 |
|
171 // CProtocolBase |
|
172 CServProviderBase* CWinsockProtocol::NewSAPL(TUint DEBUG_ONLY(aSockType)) |
|
173 { |
|
174 TRACE3("[%08X] NewSAPL(%d) for %S",this,aSockType,&iProtocolDesc->iName); |
|
175 return CWinsockServProvider::NewL(this); |
|
176 } |
|
177 |
|
178 CHostResolvProvdBase* CWinsockProtocol::NewHostResolverL() |
|
179 { |
|
180 return CWinsockHostResolver::NewL(iProtocolDesc); |
|
181 } |
|
182 |
|
183 void CWinsockProtocol::Identify(TServerProtocolDesc* aProtocolDesc) const |
|
184 { |
|
185 *aProtocolDesc = *iProtocolDesc; |
|
186 } |
|
187 |
|
188 TInt CWinsockProtocol::GetOption(TUint aLevel, TUint aName, TDes8& aOption, |
|
189 CProtocolBase* aSourceProtocol) |
|
190 { |
|
191 if(aLevel == KNifOptLevel) |
|
192 { |
|
193 if(aName == KNifOptGetNifIfUser) |
|
194 { |
|
195 TNifIfUser ifuser; |
|
196 ifuser() = this; |
|
197 aOption.Copy(ifuser); |
|
198 return KErrNone; |
|
199 } |
|
200 } |
|
201 return CProtocolBase::GetOption(aLevel, aName, aOption, aSourceProtocol); |
|
202 } |
|
203 |
|
204 // MNifIfUser |
|
205 void CWinsockProtocol::IfUserBindFailure(TInt /*aResult*/, TAny* /*aId*/) |
|
206 { |
|
207 TRACE1("[%08X] IfUserBindFailure",this); |
|
208 } |
|
209 |
|
210 void CWinsockProtocol::IfUserNewInterfaceL(CNifIfBase* aIf, TAny* /*aId*/) |
|
211 { |
|
212 TRACE1("[%08X] IfUserNewInterfaceL",this); |
|
213 ASSERT(aIf && aIf->Notify()); |
|
214 if (aIf) |
|
215 { |
|
216 iWinsockInterface = NULL; |
|
217 iIfNotify = aIf->Notify(); |
|
218 CWinsockInterface* mayBeWinsockInterface = (CWinsockInterface*)aIf; |
|
219 if (mayBeWinsockInterface->Signature() == KWinsockInterfaceSignature) |
|
220 { |
|
221 iWinsockInterface = mayBeWinsockInterface; |
|
222 } |
|
223 } |
|
224 } |
|
225 |
|
226 void CWinsockProtocol::IfUserInterfaceDown(TInt /*aResult*/, |
|
227 CNifIfBase* DEBUG_ONLY(aIf)) |
|
228 { |
|
229 TRACE1("[%08X] IfUserInterfaceDown",this); |
|
230 ASSERT(aIf && iIfNotify && (aIf->Notify() == iIfNotify)); |
|
231 iIfNotify = NULL; |
|
232 iWinsockInterface = NULL; |
|
233 } |
|
234 |
|
235 void CWinsockProtocol::IfUserOpenNetworkLayer() |
|
236 { |
|
237 TRACE1("[%08X] IfUserOpenNetworkLayer",this); |
|
238 Open(); |
|
239 } |
|
240 |
|
241 void CWinsockProtocol::IfUserCloseNetworkLayer() |
|
242 { |
|
243 TRACE1("[%08X] IfUserCloseNetworkLayer",this); |
|
244 Close(); |
|
245 } |
|
246 |
|
247 CProtocolBase* CWinsockProtocol::IfUserProtocol() |
|
248 { |
|
249 return this; |
|
250 } |
|
251 |
|
252 TBool CWinsockProtocol::IfUserIsNetworkLayerActive() |
|
253 { |
|
254 TRACE1("[%08X] IfUserIsNetworkLayerActive",this); |
|
255 return ETrue; |
|
256 } |
|
257 |
|
258 /** |
|
259 * Local Variables: |
|
260 * c-basic-offset: 4 |
|
261 * indent-tabs-mode: nil |
|
262 * End: |
|
263 */ |