|
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 // posthook.h - Base class for post hooks |
|
15 // Base class for post hooks. |
|
16 // |
|
17 |
|
18 |
|
19 |
|
20 /** |
|
21 @file posthook.h |
|
22 @publishedPartner |
|
23 @released |
|
24 */ |
|
25 |
|
26 #ifndef __POSTHOOK_H |
|
27 #define __POSTHOOK_H |
|
28 |
|
29 #include <e32std.h> |
|
30 #include <es_sock.h> |
|
31 |
|
32 #include "in_bind.h" |
|
33 |
|
34 // ***************** |
|
35 // CProtocolPostHook |
|
36 // ***************** |
|
37 |
|
38 class CProtocolPosthook : public CIp6Hook |
|
39 /** |
|
40 * Base class for the hooks between IP and NIF. |
|
41 * |
|
42 * This is the base class for hooks that live between the IP and |
|
43 * NIF layer (post-processing and pre-processing hooks). However, |
|
44 * this is also suitable for the base class of any hook. The class |
|
45 * provides automatic "network service detection", and supports both |
|
46 * <b>binding to</b> and <b>binding from</b> IP6. |
|
47 * |
|
48 * The implementations of CProtocolPosthook::BindL and |
|
49 * CProtocolPosthook::Unbind handle the "chaining" feature of the |
|
50 * post processing hooks. The stack uses a sequence of BindL and |
|
51 * Unbind calls when inserting or removing a protocol. |
|
52 * |
|
53 * Outbound (MIp6Hook::BindPostHook()): |
|
54 @verbatim |
|
55 U ---> IP6 F ---> NIF |
|
56 ..Send.. \ / |
|
57 \ ....P -> |
|
58 \ | |
|
59 H1 --> H2 --> ... --> T |
|
60 ...Send...Send...Send |
|
61 @endverbatim |
|
62 * The MNetworkService::Send passes the packet (P) to the CProtocolBase::Send |
|
63 * of the first post processing hook (H1). It is the responsibility of |
|
64 * H1 to pass the packet to the next post-processing hook (H2). The stack |
|
65 * maintains an internal chain terminator (T), which will pass the packet |
|
66 * to the NIF using the flow context (F) attached to the packet. The |
|
67 * Send does the packet forwarding to the next linked hook automaticly. |
|
68 * |
|
69 * The information block associated with the packet is defined |
|
70 * by RMBufSendPacket , which always includes a reference to the |
|
71 * flow context (F). If a hook before the terminator (T) does |
|
72 * not pass the packet forward in chain, then it must also |
|
73 * take care of releasing the flow context |
|
74 * (RMBufSendInfo::iFlow.Close()). |
|
75 * |
|
76 * The flow context is the only way for the terminator (T) to |
|
77 * know the target NIF. If the packet has not flow context, the |
|
78 * terminator drops the packet. The flow context is detached |
|
79 * from the packet before it is passed to the NIF. |
|
80 * |
|
81 * Inbound (MIp6Hook::BindPreHook()): |
|
82 @verbatim |
|
83 NIF --> IP6 IP6 ---> U |
|
84 ..Process..\ | |
|
85 \ ......P -> | |
|
86 \ src=NIF | |
|
87 H1 --> H2 --> .. --> T |
|
88 ..Process..Process..Process |
|
89 @endverbatim |
|
90 * The MNetworkService::Process passes the incoming packet |
|
91 * to the CProtocolBase::Process of the first pre-processing hook |
|
92 * (H1). It is the responsibility of the H1 to pass the packet |
|
93 * to the next pre-processing hook (H2). The stack maintains |
|
94 * an internal terminator (T), which will pass the packet |
|
95 * upwards in the protocol stack. The CProtocolPosthook::Process |
|
96 * does the packet forwarding to the next linked hook automaticly. |
|
97 * |
|
98 * In the Process chain, the source (CProtocolBase *) is actually |
|
99 * a pointer to the NIF object (CNifIfBase). Upon arriving to the |
|
100 * terminator (T), the source must still be a valid and known to |
|
101 * stack as a NIF (successfully introduced as documented in |
|
102 * @ref nif_binding |
|
103 * at some earlier point). Otherwise packet is not accepted. |
|
104 * The information block is defined by the RMBufPktInfo class. |
|
105 * The information block "changes into" RMBufRecvInfo after the |
|
106 * terminator (T). |
|
107 * |
|
108 * CProtocolPosthook can also be used as a generic base for any hook. |
|
109 * Then the following protocol ids for the BindL will become reserved: |
|
110 * |
|
111 * - MIp6Hook::BindPostHook() (for outbound posthook chaining) |
|
112 * - MIp6Hook::BindPreHook() (for inbound posthook chaining) |
|
113 * - #KProtocolInet6Ip (for the network intance) |
|
114 * - #KProtocolInetIp (for network instance, deprecated) |
|
115 * |
|
116 * ::BindToL implementation handles #KProtocolInet6Ip |
|
117 * and #KProtocolInetIp targets. This does not do automatic CProtcolBase::BindL |
|
118 * to the target (see ::DoBindToL). The hook binds, if needed, should be done |
|
119 * in the ::NetworkAttachedL function. |
|
120 * |
|
121 * @publishedPartner |
|
122 * @released |
|
123 */ |
|
124 { |
|
125 protected: |
|
126 IMPORT_C virtual ~CProtocolPosthook(); |
|
127 public: |
|
128 IMPORT_C virtual void BindToL(CProtocolBase* aProtocol); |
|
129 IMPORT_C virtual void BindL(CProtocolBase* aProtocol, TUint aId); |
|
130 IMPORT_C virtual void Unbind(CProtocolBase* aProtocol, TUint aId); |
|
131 IMPORT_C virtual TInt Send(RMBufChain &aPacket, CProtocolBase* aSrc); |
|
132 IMPORT_C virtual void Process(RMBufChain &aPacket, CProtocolBase* aSrc); |
|
133 TInt ApplyL(RMBufHookPacket & /*aPacket*/, RMBufRecvInfo & /*aInfo*/) |
|
134 /** Default ApplyL. |
|
135 * The default ApplyL does nothing to the packets. |
|
136 * @note |
|
137 * If the only hook binding is post or pre-preprocessing, the ApplyL |
|
138 * is never called. |
|
139 * |
|
140 * @return #KIp6Hook_PASS |
|
141 */ |
|
142 { return KIp6Hook_PASS; } |
|
143 /** |
|
144 * Network layer has been attached. |
|
145 * |
|
146 * This function is called when the network layer is detected and |
|
147 * attached to this protocol object (::NetworkService() returns non-null). |
|
148 * The implementation in the derived class can now |
|
149 * do the hook specific binds and unbinds using: |
|
150 @code |
|
151 // request inbound packets to my Process() |
|
152 NetworkService()->BindL(this, MIp6Hook::BindPreHook()); |
|
153 // request outbound packets to my Send(). |
|
154 NetworkService()->BindL(this, MIp6Hook::BindPostHook()); |
|
155 ... |
|
156 // stop getting inbound packets to my Process() |
|
157 NetworkService()->Unbind(this, MIp6Hook::BindPreHook()); |
|
158 // stop getting outbound packets to my Send() |
|
159 NetworkService()->Unbind(this, MIp6Hook::BindPostHook()); |
|
160 // ..or, to rip off all my hooks |
|
161 NetworkService()->Unbind(this); |
|
162 @endcode |
|
163 */ |
|
164 virtual void NetworkAttachedL() = 0; |
|
165 /** |
|
166 * Network layer is being detached. |
|
167 * |
|
168 * This function is called when the hook is losing |
|
169 * the connection to the network instance (the network |
|
170 * instance has issued Unbind request, because it is |
|
171 * shutting down). |
|
172 * |
|
173 * Derived class does not need to implement this, unless it |
|
174 * caches network layer dependent data internally. Otherwise, |
|
175 * it must implement the function and cleanup all such data. |
|
176 * |
|
177 * During the call ::NetworkService returns the |
|
178 * service instance that is going away. However, it should not |
|
179 * be used for any binding or unbinding. the detach process does |
|
180 * the unbindings automaticly. |
|
181 * |
|
182 * @note |
|
183 * The desctuctor can be called while network is attached. |
|
184 * CProtocolPosthook destructor will unbind this object |
|
185 * automaticly from the network (cancel all binds), and |
|
186 * then detaches withouth calling NetworkDetached. Thus, |
|
187 * the destructor of the derived class must do the cleanup |
|
188 * of cached data, but it does not need to worry about the |
|
189 * binds to the network. |
|
190 */ |
|
191 virtual void NetworkDetached() {}; |
|
192 /** |
|
193 * Gets the network service. |
|
194 * |
|
195 * This returns the network service, if any is currently attached. |
|
196 * The network is attached after ::NetworkAttachedL call until |
|
197 * the next ::NetworkDetached or destruction. Otherwise, network |
|
198 * is not attached and return is always NULL. |
|
199 * |
|
200 * @return The network service or NULL. |
|
201 */ |
|
202 inline MNetworkService *NetworkService() const { return iNetwork; } |
|
203 protected: |
|
204 IMPORT_C TInt DoBindToL(CProtocolBase *aProtocol); |
|
205 private: |
|
206 /** The attached network layer (IP layer). |
|
207 * The CProtocolPosthook::DoBindToL, CProtocolPosthook::BindL |
|
208 * and CProtocolPosthook::Unbind implementations maintain this |
|
209 * pointer. |
|
210 */ |
|
211 MNetworkService *iNetwork; |
|
212 /** Outbound posthook chain. |
|
213 * The next protocol in list. The CProtocolPosthook::BindL and |
|
214 * CProtocolPosthook::Unbind implementions maintain this chain |
|
215 * based on the calls coming from the network layer. The id |
|
216 * reference in the chaining calls is MIp6Hook::BindPostHook(). |
|
217 */ |
|
218 CProtocolBase *iPostHook; |
|
219 /** Inbound posthook chain. |
|
220 * The next protocol in list. The CProtocolPosthook::BindL and |
|
221 * CProtocolPosthook::Unbind implementions maintain this chain |
|
222 * based on the calls coming from the network layer. The id |
|
223 * reference in the chaining calls is MIp6Hook::BindPreHook(). |
|
224 */ |
|
225 CProtocolBase *iInboundHook; |
|
226 /** |
|
227 * The network attachment type. |
|
228 * This base class supports both "bind" and "bindto" attachments |
|
229 * to the network layer. |
|
230 * |
|
231 * - if == 1, <tt>bindto= ip6</tt> is in the "hook" ESK file. |
|
232 * #iNetwork has been set by CProtocolPosthook::DoBindToL. |
|
233 * - if == 0, <tt>bindto= hook</tt> is in the [ip6] section of |
|
234 * the TCPIP6.ESK. #iNetwork has been set by the |
|
235 * CProtocolPosthook::BindL. |
|
236 * |
|
237 * The value is significant only if #iNetwork is non-NULL. |
|
238 */ |
|
239 TUint iBindToNet:1; |
|
240 }; |
|
241 |
|
242 #endif |