|
1 // Copyright (c) 2006-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 // |
|
15 |
|
16 |
|
17 |
|
18 /** |
|
19 @file |
|
20 @internalComponent |
|
21 */ |
|
22 |
|
23 #ifndef L2CAPFECNEGOTIATOR_H |
|
24 #define L2CAPFECNEGOTIATOR_H |
|
25 |
|
26 #include "L2types.h" |
|
27 |
|
28 class TL2CapFecNegotiator; |
|
29 class TL2CapSingleDirectionFecNegotiatorBase; |
|
30 |
|
31 // This encapsulates channel mode dependent FEC option handling behaviors. |
|
32 // Channel mode policy is applied outside of this. |
|
33 NONSHARABLE_CLASS(TModeSpecificFecOptionHandlerBase) |
|
34 { |
|
35 public: |
|
36 // Checks whether the field values are valid (within specification limits). |
|
37 // To be used early, during the parsing of an option received from the peer. |
|
38 // Note: valid doesn't mean acceptable. |
|
39 virtual TBool IsOptionValid(const TRetransmissionAndFlowControlOption& aFecOption) const = 0; |
|
40 virtual TBool IsPeerResponseAcceptable(const TRetransmissionAndFlowControlOption& aPreferred, |
|
41 const TRetransmissionAndFlowControlOption& aPeer) const = 0; |
|
42 // The return value says whether the option needs to be included in ConfigRsp. |
|
43 // [Only enhanced mode positive responses need to be included as they convey new information |
|
44 // on the timers and MPS] |
|
45 virtual TBool BuildPositiveResponse(TRetransmissionAndFlowControlOption& aPreferred, |
|
46 const TRetransmissionAndFlowControlOption& aPeer) const; |
|
47 virtual void BuildNegativeResponse(TRetransmissionAndFlowControlOption& aPreferred, |
|
48 const TRetransmissionAndFlowControlOption& aPeer) const; |
|
49 // In general configuration procedure (spec chapter 7 General Procedures) if the remote accepts |
|
50 // an option from our ConfigReq, it doesn't have to include it in the response. So before |
|
51 // processing the options from a ConfigRsp we've received, we go through the preferred values |
|
52 // we've sent in ConfigReq and pretend that the remote has accepted them without a hitch. Then |
|
53 // options included in the received ConfigRsp are processed. This works well with plain-vanilla |
|
54 // negotiated options, but TRetransmissionAndFlowControl for enhanced modes is different: |
|
55 // request and response semantics are a bit different, and so the request does not contain all |
|
56 // information needed in a response. So we have to take the request we've sent, guess the |
|
57 // missing information, and thus create a fake response. And that's what this method does. |
|
58 virtual void PrepareImplicitPeerResponse(TRetransmissionAndFlowControlOption& aImplicitResponse, |
|
59 const TRetransmissionAndFlowControlOption& aPreferred) const; |
|
60 |
|
61 // Set user-requested MaxTransmit value. The value is given in the enhanced range |
|
62 // 0-255, where 0 means infinity and is only valid for ERTM. Deriving classes are |
|
63 // responsible for the cut-off of the infinity value on 255 if they can't handle it. |
|
64 virtual void SetMaxTransmit(TRetransmissionAndFlowControlOption& aFecOption, TUint8 aMaxTransmit) const; |
|
65 |
|
66 virtual void ZeroUnspecifiedRequestFields(TRetransmissionAndFlowControlOption& aFecOption) const; |
|
67 virtual void ZeroUnspecifiedResponseFields(TRetransmissionAndFlowControlOption& aFecOption) const; |
|
68 }; |
|
69 |
|
70 NONSHARABLE_CLASS(TStreamingFecHandler) : public TModeSpecificFecOptionHandlerBase |
|
71 { |
|
72 public: |
|
73 virtual TBool IsOptionValid(const TRetransmissionAndFlowControlOption& aFecOption) const; |
|
74 virtual TBool IsPeerResponseAcceptable(const TRetransmissionAndFlowControlOption& aPreferred, |
|
75 const TRetransmissionAndFlowControlOption& aPeer) const; |
|
76 virtual TBool BuildPositiveResponse(TRetransmissionAndFlowControlOption& aPreferred, |
|
77 const TRetransmissionAndFlowControlOption& aPeer) const; |
|
78 virtual void BuildNegativeResponse(TRetransmissionAndFlowControlOption& aPreferred, |
|
79 const TRetransmissionAndFlowControlOption& aPeer) const; |
|
80 virtual void ZeroUnspecifiedRequestFields(TRetransmissionAndFlowControlOption& aFecOption) const; |
|
81 virtual void ZeroUnspecifiedResponseFields(TRetransmissionAndFlowControlOption& aFecOption) const; |
|
82 }; |
|
83 |
|
84 NONSHARABLE_CLASS(TErtmFecHandler) : public TModeSpecificFecOptionHandlerBase |
|
85 { |
|
86 public: |
|
87 virtual TBool IsOptionValid(const TRetransmissionAndFlowControlOption& aFecOption) const; |
|
88 virtual TBool IsPeerResponseAcceptable(const TRetransmissionAndFlowControlOption& aPreferred, |
|
89 const TRetransmissionAndFlowControlOption& aPeer) const; |
|
90 virtual TBool BuildPositiveResponse(TRetransmissionAndFlowControlOption& aPreferred, |
|
91 const TRetransmissionAndFlowControlOption& aPeer) const; |
|
92 virtual void BuildNegativeResponse(TRetransmissionAndFlowControlOption& aPreferred, |
|
93 const TRetransmissionAndFlowControlOption& aPeer) const; |
|
94 virtual void PrepareImplicitPeerResponse(TRetransmissionAndFlowControlOption& aImplicitResponse, |
|
95 const TRetransmissionAndFlowControlOption& aPreferred) const; |
|
96 virtual void SetMaxTransmit(TRetransmissionAndFlowControlOption& aFecOption, TUint8 aMaxTransmit) const; |
|
97 virtual void ZeroUnspecifiedRequestFields(TRetransmissionAndFlowControlOption& aFecOption) const; |
|
98 virtual void ZeroUnspecifiedResponseFields(TRetransmissionAndFlowControlOption& aFecOption) const; |
|
99 }; |
|
100 |
|
101 NONSHARABLE_CLASS(TLegacyFecHandler) : public TModeSpecificFecOptionHandlerBase |
|
102 { |
|
103 public: |
|
104 virtual TBool IsOptionValid(const TRetransmissionAndFlowControlOption& aFecOption) const; |
|
105 virtual TBool IsPeerResponseAcceptable(const TRetransmissionAndFlowControlOption& aPreferred, |
|
106 const TRetransmissionAndFlowControlOption& aPeer) const; |
|
107 virtual void SetMaxTransmit(TRetransmissionAndFlowControlOption& aFecOption, TUint8 aMaxTransmit) const; |
|
108 }; |
|
109 |
|
110 NONSHARABLE_CLASS(TBasicFecHandler) : public TModeSpecificFecOptionHandlerBase |
|
111 { |
|
112 public: |
|
113 // Most peers will actually only request Basic implicitly i.e. by not including the FEC |
|
114 // option at all, but we treat implicit/explicit values uniformly and will still execute |
|
115 // these. And a Basic FEC can be explicit if the peer does new modes, but for some |
|
116 // reason doesn't want to use them and has sent us an Unacceptable Params ConfigRsp with |
|
117 // Basic in it. |
|
118 virtual TBool IsOptionValid(const TRetransmissionAndFlowControlOption& aFecOption) const; |
|
119 virtual TBool IsPeerResponseAcceptable(const TRetransmissionAndFlowControlOption& aPreferred, |
|
120 const TRetransmissionAndFlowControlOption& aPeer) const; |
|
121 }; |
|
122 |
|
123 // This groups all mode-specific handlers and provides delegator methods that forward calls to |
|
124 // appropriate FecHandlers. |
|
125 NONSHARABLE_CLASS(TFecOptionHandlerDelegator) |
|
126 { |
|
127 public: |
|
128 inline TBool IsOptionValid(const TRetransmissionAndFlowControlOption& aFecOption) const; |
|
129 inline TBool IsPeerResponseAcceptable(const TRetransmissionAndFlowControlOption& aPreferred, |
|
130 const TRetransmissionAndFlowControlOption& aPeer) const; |
|
131 inline TBool BuildPositiveResponse(TRetransmissionAndFlowControlOption& aPreferred, |
|
132 const TRetransmissionAndFlowControlOption& aPeer) const; |
|
133 inline void BuildNegativeResponse(TRetransmissionAndFlowControlOption& aPreferred, |
|
134 const TRetransmissionAndFlowControlOption& aPeer) const; |
|
135 inline void PrepareImplicitPeerResponse(TRetransmissionAndFlowControlOption& aImplicitResponse, |
|
136 const TRetransmissionAndFlowControlOption& aPreferred) const; |
|
137 inline void SetMaxTransmit(TRetransmissionAndFlowControlOption& aFecOption, TUint8 aMaxTransmit) const; |
|
138 inline void ZeroUnspecifiedRequestFields(TRetransmissionAndFlowControlOption& aFecOption) const; |
|
139 inline void ZeroUnspecifiedResponseFields(TRetransmissionAndFlowControlOption& aFecOption) const; |
|
140 private: |
|
141 TModeSpecificFecOptionHandlerBase& Handler(const TRetransmissionAndFlowControlOption& aFecOption); |
|
142 const TModeSpecificFecOptionHandlerBase& Handler(const TRetransmissionAndFlowControlOption& aFecOption) const; |
|
143 |
|
144 TModeSpecificFecOptionHandlerBase* ModeToHandler(TL2CapChannelMode aMode); |
|
145 const TModeSpecificFecOptionHandlerBase* ModeToHandler(TL2CapChannelMode aMode) const; |
|
146 |
|
147 #ifdef __FLOG_ACTIVE |
|
148 void LogCurrentValues(const TRetransmissionAndFlowControlOption& aPreferred, |
|
149 const TRetransmissionAndFlowControlOption& aPeer) const; |
|
150 #endif |
|
151 private: |
|
152 TStreamingFecHandler iStreamingFecHandler; |
|
153 TErtmFecHandler iErtmFecHandler; |
|
154 TLegacyFecHandler iLegacyFecHandler; |
|
155 TBasicFecHandler iBasicFecHandler; |
|
156 }; |
|
157 |
|
158 NONSHARABLE_CLASS(TL2CapSingleDirectionFecNegotiatorBase) : public TL2CapConfigurationOptionGroupBase |
|
159 { |
|
160 public: |
|
161 inline TL2CapSingleDirectionFecNegotiatorBase(const TL2CapFecNegotiator& aFecNegotiator); |
|
162 |
|
163 inline void SetPeer(const TRetransmissionAndFlowControlOption& aFecOption); |
|
164 inline void SetPreferred(const TRetransmissionAndFlowControlOption& aFecOption); |
|
165 |
|
166 void SetupForRenegotiation(); |
|
167 |
|
168 inline TOptionConfigStatus ConfigOptionStatus() const; |
|
169 |
|
170 inline const TRetransmissionAndFlowControlOption& Peer() const; |
|
171 inline const TRetransmissionAndFlowControlOption& Preferred() const; |
|
172 |
|
173 |
|
174 protected: |
|
175 TBool IsPeerModeAcceptable(TL2CapChannelMode aPeerMode, TBool& aDisconnect) const; |
|
176 |
|
177 #ifdef __FLOG_ACTIVE |
|
178 void LogState() const; |
|
179 #endif |
|
180 |
|
181 protected: |
|
182 const TL2CapFecNegotiator& iFecNegotiator; |
|
183 |
|
184 TOptionConfigStatus iConfigStatus; |
|
185 TRetransmissionAndFlowControlOption iPeer; |
|
186 TRetransmissionAndFlowControlOption iPreferred; |
|
187 }; |
|
188 |
|
189 NONSHARABLE_CLASS(TL2CapIncomingFecNegotiator) : public TL2CapSingleDirectionFecNegotiatorBase |
|
190 { |
|
191 public: |
|
192 inline TL2CapIncomingFecNegotiator(const TL2CapFecNegotiator& aFecNegotiator); |
|
193 void ProcessPeerValue(const TRetransmissionAndFlowControlOption& aFecOption, |
|
194 TBool aIsUnacceptableParameters); |
|
195 void ProcessImplicitPeerValue(); |
|
196 void Setup(); |
|
197 protected: |
|
198 void BuildRequest(TL2CapChannelMode aMode, TRetransmissionAndFlowControlOption& aFecOption); |
|
199 }; |
|
200 |
|
201 NONSHARABLE_CLASS(TL2CapOutgoingFecNegotiator) : public TL2CapSingleDirectionFecNegotiatorBase |
|
202 { |
|
203 public: |
|
204 inline TL2CapOutgoingFecNegotiator(const TL2CapFecNegotiator& aFecNegotiator); |
|
205 TInt ProcessPeerValue(const TRetransmissionAndFlowControlOption& aFecOption); |
|
206 void Setup(); |
|
207 inline TBool NeedToIncludeInPositiveConfigResponse(); |
|
208 inline void SetIncludeInPositiveConfigResponse(TBool aVal); |
|
209 private: |
|
210 TBool iIncludeValueInPositiveConfigResponse; |
|
211 }; |
|
212 |
|
213 // This is the interface to the FEC option negotiation functionality, through which |
|
214 // all interaction with the external world should be done. |
|
215 NONSHARABLE_CLASS(TL2CapFecNegotiator) |
|
216 { |
|
217 public: |
|
218 // Variants of the negotiation procedure defined in 2.1 Core Spec Addendum 1, |
|
219 // chapter 5.4 Retransmission And Flow Control Option. |
|
220 enum TNegotiationBehavior |
|
221 { |
|
222 // Allows all spec-allowed fallback options: Streaming -> ERTM, ERTM -> Basic and |
|
223 // Streaming -> Basic. E.g. if our preferred mode is ERTM and peer proposes Basic, |
|
224 // we'll fall back to it. The negotiation procedure is a simple minimization |
|
225 // algorithm, where the party with the higher-precedence mode wins. |
|
226 // Also note that we try to apply the same hierarchy to RTM and FC, so effectively |
|
227 // you can read this as Unreliable -> Reliable, Reliable -> Basic and Unreliable -> Basic, |
|
228 // where Reliable = { ERTM, RTM } and Unreliable = { Streaming, FC } |
|
229 // For the precedence of modes, see channel mode <= operator or the spec, same section. |
|
230 EState1, |
|
231 // Like State1, only Unreliable -> Reliable is not allowed (Unreliable -> Basic and |
|
232 // Reliable -> Basic still are). |
|
233 EState1NoUnreliableToReliable, |
|
234 // No fallback - disconnect immediately if peer proposes a different channel mode than |
|
235 // we want. |
|
236 EState2 |
|
237 }; |
|
238 |
|
239 public: |
|
240 inline TL2CapFecNegotiator(); |
|
241 |
|
242 TBool Setup(TL2CapConfig::TChannelReliability aChannelReliability, |
|
243 TBool aLegacyModesDisallowed, |
|
244 const TL2CapEntityInfo& aPeerEntityConfig, |
|
245 TUint8 aMaxTransmit); |
|
246 |
|
247 // Can't renegotiate FEC currently but with Generic AMP time-outs will be renegotiable. |
|
248 void SetupForRenegotiation(); |
|
249 |
|
250 // Methods below implement events in option state machine - they're identical |
|
251 // to the ones in the generic state machine in TL2CapConfigurationOptionGroup. |
|
252 inline TInt PeerRequestsOption(const TRetransmissionAndFlowControlOption& aFecOption); |
|
253 inline TInt PeerRequestsLastAcceptedValue(); |
|
254 |
|
255 inline TInt PeerRejectsOption(const TRetransmissionAndFlowControlOption& aFecOption); |
|
256 inline TInt PeerAcceptsOption(const TRetransmissionAndFlowControlOption& aFecOption); |
|
257 inline void PeerAcceptsOption(); |
|
258 |
|
259 inline TBool NeedToIncludeInPositiveConfigResponse(); |
|
260 |
|
261 void DowngradeIncomingToBasicIfOutgoingIsBasic(); |
|
262 TInt CheckNegotiatedChannelMode(TBool& aDowngrade); |
|
263 |
|
264 // [Methods below add a lot of fluff but they provide strong decoupling and encapsulation. |
|
265 // None of the internal classes are exposed.] |
|
266 |
|
267 inline const TRetransmissionAndFlowControlOption& IncomingPreferred() const; |
|
268 inline const TRetransmissionAndFlowControlOption& OutgoingPreferred() const; |
|
269 |
|
270 inline TL2CapConfigurationOptionGroupBase::TOptionConfigStatus IncomingConfigOptionStatus() const; |
|
271 inline TL2CapConfigurationOptionGroupBase::TOptionConfigStatus OutgoingConfigOptionStatus() const; |
|
272 |
|
273 inline TL2CapDataControllerConfig DataControllerConfig() const; |
|
274 |
|
275 // These abstract away the fact that some parameters are negotiated in opposite paths depending |
|
276 // on the modes used (eg Monitor TO), and which fields the values should be taken from (Peer or |
|
277 // Preferred). |
|
278 inline TL2CapChannelMode OutgoingLinkMode() const; |
|
279 inline TL2CapChannelMode IncomingLinkMode() const; |
|
280 inline TUint8 OutgoingLinkModeAsUnsignedByte() const; |
|
281 inline TUint8 IncomingLinkModeAsUnsignedByte() const; |
|
282 inline TUint8 OutgoingTxWindowSize() const; |
|
283 inline TUint8 IncomingTxWindowSize() const; |
|
284 inline TUint8 OutgoingMaxTransmit() const; |
|
285 inline TUint8 IncomingMaxTransmit() const; |
|
286 inline TUint16 OutgoingRetransmissionTimeout() const; |
|
287 inline TUint16 IncomingRetransmissionTimeout() const; |
|
288 inline TUint16 OutgoingMonitorTimeout() const; |
|
289 inline TUint16 IncomingMonitorTimeout() const; |
|
290 inline TUint16 OutgoingMaximumPDUSize() const; |
|
291 inline TUint16 IncomingMaximumPDUSize() const; |
|
292 |
|
293 // These are for the internal per-direction negotiator objects. |
|
294 TBool IsModeLegal(TL2CapChannelMode aPeerMode) const; |
|
295 inline const TL2CapEntityInfo& PeerSupportedModes() const; |
|
296 inline TNegotiationBehavior NegotiationBehavior() const; |
|
297 inline TL2CapChannelMode DesiredMode() const; |
|
298 inline TUint8 MaxTransmit() const; |
|
299 inline const TFecOptionHandlerDelegator& ModeSpecificHandlers() const; |
|
300 private: |
|
301 TL2CapIncomingFecNegotiator iIncomingNegotiator; |
|
302 TL2CapOutgoingFecNegotiator iOutgoingNegotiator; |
|
303 |
|
304 TL2CapEntityInfo iPeerSupportedModes; |
|
305 TNegotiationBehavior iNegotiationBehavior; |
|
306 TL2CapChannelMode iDesiredMode; |
|
307 TUint8 iMaxTransmit; |
|
308 |
|
309 TFecOptionHandlerDelegator iModeSpecificHandlers; |
|
310 }; |
|
311 |
|
312 #include "L2CapFecNegotiator.inl" |
|
313 |
|
314 #endif /*L2CAPFECNEGOTIATOR_H*/ |