|
1 // Copyright (c) 2004-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 // testhook.cpp - Outbound plugin test |
|
15 // When the ip.etesthook.esk is put in c:/system/data this |
|
16 // plugin is bound to the IP. All outgoing messages will pass |
|
17 // through this. The name "ip.etesthook.esk" is important, since this |
|
18 // must be processed before any other ip.*.esk files. |
|
19 // Based on Nokia's exout plugin |
|
20 // |
|
21 // |
|
22 |
|
23 |
|
24 #include <e32svr.h> |
|
25 #include "testhook.h" |
|
26 #include <httpsocketconstants.h> |
|
27 |
|
28 const TUint16 KTestProtocol = 0xfb5; //likewise |
|
29 |
|
30 // |
|
31 // Entrypoint |
|
32 // |
|
33 #ifdef __SECURE_API__ |
|
34 GLDEF_C TInt E32Dll() |
|
35 #else |
|
36 GLDEF_C TInt E32Dll(TDllReason /*aReason*/) |
|
37 #endif |
|
38 { |
|
39 return KErrNone; |
|
40 } |
|
41 |
|
42 class CTestProtocolFamily : public CProtocolFamilyBase |
|
43 { |
|
44 public: |
|
45 CTestProtocolFamily(); |
|
46 ~CTestProtocolFamily(); |
|
47 TInt Install(); |
|
48 TInt Remove(); |
|
49 TUint ProtocolList(TServerProtocolDesc *& aProtocolList); |
|
50 CProtocolBase* NewProtocolL(TUint aSockType, TUint aProtocol); |
|
51 }; |
|
52 |
|
53 extern "C" { IMPORT_C CProtocolFamilyBase* Install(void); } |
|
54 EXPORT_C CProtocolFamilyBase* Install() |
|
55 { |
|
56 return new (ELeave) CTestProtocolFamily; |
|
57 } |
|
58 |
|
59 //---------------------------------------------------------------------- |
|
60 // Dummy protocol family declaration. Required for DLL's |
|
61 // |
|
62 |
|
63 CTestProtocolFamily::CTestProtocolFamily() |
|
64 { |
|
65 __DECLARE_NAME(_S("CTestProtocolFamily")); |
|
66 } |
|
67 |
|
68 CTestProtocolFamily::~CTestProtocolFamily() |
|
69 { |
|
70 } |
|
71 |
|
72 TInt CTestProtocolFamily::Install() |
|
73 { |
|
74 return KErrNone; |
|
75 } |
|
76 |
|
77 TInt CTestProtocolFamily::Remove() |
|
78 { |
|
79 return KErrNone; |
|
80 } |
|
81 |
|
82 TUint CTestProtocolFamily::ProtocolList(TServerProtocolDesc *& aProtocolList) |
|
83 { |
|
84 // This function should be a leaving fn |
|
85 // apparently it is OK for it to leave |
|
86 TServerProtocolDesc *p = new (ELeave) TServerProtocolDesc[1]; // Esock catches this leave |
|
87 |
|
88 CTestProtocol::FillIdentification(p[0]); |
|
89 aProtocolList = p; |
|
90 return 1; |
|
91 } |
|
92 |
|
93 CProtocolBase* CTestProtocolFamily::NewProtocolL(TUint /*aSockType*/, TUint aProtocol) |
|
94 { |
|
95 if (aProtocol != KTestProtocol) |
|
96 { |
|
97 User::Leave(KErrNotSupported); |
|
98 } |
|
99 |
|
100 return new (ELeave) CTestProtocol; |
|
101 } |
|
102 |
|
103 |
|
104 //------------------------------------- |
|
105 |
|
106 const TInt CTestFlowInfo::iOffset = _FOFF(CTestFlowInfo, iDLink); |
|
107 |
|
108 CTestProtocol::CTestProtocol() : iFlowList(CTestFlowInfo::iOffset), iSessionId(KErrNotFound) |
|
109 { |
|
110 } |
|
111 |
|
112 void CTestProtocol::InitL(TDesC& aTag) |
|
113 { |
|
114 CProtocolBase::InitL(aTag); |
|
115 } |
|
116 |
|
117 void CTestProtocol::StartL() |
|
118 { |
|
119 // __ASSERT_DEBUG(iProtocol != NULL, User::Leave(KErrGeneral)); |
|
120 } |
|
121 |
|
122 CTestProtocol::~CTestProtocol() |
|
123 { |
|
124 if (iIPProtocol != NULL) |
|
125 { |
|
126 iIPProtocol->Unbind(this); |
|
127 } |
|
128 } |
|
129 |
|
130 void CTestProtocol::BindL(CProtocolBase* aProtocol, TUint aId) |
|
131 { |
|
132 if ((aId != KProtocolInet6Ip) || (aProtocol == this)) |
|
133 { |
|
134 User::Leave(KErrGeneral); |
|
135 } |
|
136 |
|
137 TUint ourId; |
|
138 TServerProtocolDesc info; |
|
139 Identify(&info); |
|
140 ourId = info.iProtocol; |
|
141 |
|
142 if (aId == ourId) |
|
143 { |
|
144 User::Leave(KErrGeneral); |
|
145 } |
|
146 |
|
147 aProtocol->BindL((CProtocolBase*)this, BindFlowHook()); |
|
148 |
|
149 iIPProtocol = (CProtocolInet6Binder*)aProtocol; |
|
150 } |
|
151 |
|
152 void CTestProtocol::Unbind(CProtocolBase* aProtocol, TUint /*aId*/) |
|
153 { |
|
154 if (iIPProtocol == aProtocol) |
|
155 { |
|
156 iIPProtocol = 0; |
|
157 } |
|
158 |
|
159 // All the FlowContexts in iFlowList must be deleted as well |
|
160 if(!iFlowList.IsEmpty()) |
|
161 { |
|
162 CTestFlowInfo* temp = iFlowList.First(); |
|
163 while (temp != NULL) |
|
164 { |
|
165 temp->iDLink.Deque(); |
|
166 delete temp; |
|
167 temp = iFlowList.First(); |
|
168 } |
|
169 } |
|
170 } |
|
171 |
|
172 void CTestProtocol::FillIdentification(TServerProtocolDesc& anEntry) |
|
173 { |
|
174 anEntry.iName=_S("TestHook"); |
|
175 anEntry.iAddrFamily=KAfInet; |
|
176 anEntry.iSockType=KSockDatagram; |
|
177 anEntry.iProtocol=KTestProtocol; |
|
178 anEntry.iVersion=TVersion(1, 0, 0); |
|
179 anEntry.iByteOrder=EBigEndian; |
|
180 anEntry.iServiceInfo=KSIDatagram | KSIConnectionLess; |
|
181 anEntry.iNamingServices=0; |
|
182 anEntry.iSecurity=KSocketNoSecurity; |
|
183 anEntry.iMessageSize=0xffff; |
|
184 anEntry.iServiceTypeInfo=0; |
|
185 anEntry.iNumSockets=KUnlimitedSockets; |
|
186 } |
|
187 |
|
188 void CTestProtocol::Identify(TServerProtocolDesc *aDesc) const |
|
189 { |
|
190 FillIdentification(*aDesc); |
|
191 } |
|
192 |
|
193 void CTestProtocol::BindToL(CProtocolBase* /*aProtocol*/) |
|
194 { |
|
195 User::Panic(_L("TestHook"), 0); |
|
196 } |
|
197 |
|
198 |
|
199 //---------------------------------------------------------------------- |
|
200 MFlowHook *CTestProtocol::OpenL(TPacketHead& /*aHead*/, CFlowContext* aFlow) |
|
201 { |
|
202 CTestFlowInfo* info = new (ELeave) CTestFlowInfo; |
|
203 info->iMgr = this; |
|
204 iFlowList.AddLast(*info); //Save the flow info for later use |
|
205 |
|
206 if( iSessionId > 0 ) |
|
207 { |
|
208 RDebug::Print(_L("Opening session with id = %i\n"),iSessionId); |
|
209 } |
|
210 |
|
211 info->iFlow = aFlow; |
|
212 |
|
213 return info; |
|
214 } |
|
215 |
|
216 |
|
217 |
|
218 TInt CTestProtocol::SetFlowOption(TUint aLevel, TUint aName, const TDesC8 &aOption, CFlowContext& aFlow) |
|
219 { |
|
220 (void) aFlow; |
|
221 if((aLevel== KSOLHttpSessionInfo) && (aName == KSOHttpSessionId)) |
|
222 { |
|
223 TPckgBuf<TInt> option; |
|
224 option.Copy(aOption); |
|
225 iSessionId = option(); |
|
226 return KErrNone; |
|
227 } |
|
228 return KErrNotSupported; |
|
229 } |
|
230 |
|
231 TInt CTestFlowInfo::ReadyL(TPacketHead& /*aHead*/) |
|
232 { |
|
233 return EFlow_READY; |
|
234 } |
|
235 |
|
236 // |
|
237 // Applies all the remaining modifications needed for every outgoing packet |
|
238 // |
|
239 TInt CTestFlowInfo::ApplyL(RMBufSendPacket& /*aPacket*/, RMBufSendInfo& /*aInfo*/) |
|
240 { |
|
241 return 0; |
|
242 } |
|
243 |
|
244 void CTestFlowInfo::Close() |
|
245 { |
|
246 if (--iRefs < 0) |
|
247 { |
|
248 iDLink.Deque(); |
|
249 delete this; |
|
250 } |
|
251 } |
|
252 |
|
253 void CTestFlowInfo::Open() |
|
254 { |
|
255 iRefs++; |
|
256 } |