19 @file BcaIoController.cpp |
19 @file BcaIoController.cpp |
20 */ |
20 */ |
21 |
21 |
22 #include <e32uid.h> |
22 #include <e32uid.h> |
23 #include <nifmbuf.h> |
23 #include <nifmbuf.h> |
|
24 #include <e32svr.h> |
|
25 #include <u32hal.h> |
24 |
26 |
25 #include "Constants.h" |
27 #include "Constants.h" |
26 #include "BcaIoController.h" |
28 #include "BcaIoController.h" |
27 #include "Sender.h" |
29 #include "Sender.h" |
28 #include "Receiver.h" |
30 #include "Receiver.h" |
29 |
31 |
|
32 const TUint KDefaultSendQueueSize=5; |
|
33 |
|
34 #ifdef __EABI__ |
|
35 // Patch data is used and KMaxTxIPPacketSize and KMaxRxIPPacketSize can be modified to a different value in RawIpNif.iby file |
|
36 extern const TInt KMaxSendQueueLen = KDefaultSendQueueSize; |
|
37 extern const TInt KMaxTxIPPacketSize = KMaxIPPacket + KIPTagHeaderLength; |
|
38 extern const TInt KMaxRxIPPacketSize = KMaxIPPacket + KIPTagHeaderLength; |
|
39 #endif |
|
40 |
30 CBcaIoController::CBcaIoController(MControllerObserver& aObserver, |
41 CBcaIoController::CBcaIoController(MControllerObserver& aObserver, |
31 CBttLogger* aTheLogger) |
42 CBttLogger* aTheLogger) |
32 /** |
43 /** |
33 * Constructor. |
44 * Constructor. |
34 * |
45 * |
35 * @param aObserver Reference to the observer of this state machine |
46 * @param aObserver Reference to the observer of this state machine |
36 * @param aTheLogger The logging object |
47 * @param aTheLogger The logging object |
37 */ |
48 */ |
38 : |
49 : iTheLogger(aTheLogger), |
39 CBcaController(aObserver, aTheLogger), |
50 iSendState(EIdle), |
40 iMBca(NULL), |
51 iFlowBlocked(EFalse), |
41 iSender(NULL), |
52 iNumPacketsInSendQueue(0), |
42 iReceiver(NULL), |
53 iObserver(aObserver), |
43 iLoader(NULL) |
54 iMBca(NULL), |
44 { |
55 iSender(NULL), |
45 } |
56 iReceiver(NULL), |
|
57 iLoader(NULL) |
|
58 { |
|
59 } |
46 |
60 |
47 CBcaIoController* CBcaIoController::NewL(MControllerObserver& aObserver, CBttLogger* aTheLogger) |
61 CBcaIoController* CBcaIoController::NewL(MControllerObserver& aObserver, CBttLogger* aTheLogger) |
48 /** |
62 /** |
49 * Two-phase constructor. Creates a new CBcaIoController object, performs |
63 * Two-phase constructor. Creates a new CBcaIoController object, performs |
50 * second-phase construction, then returns it. |
64 * second-phase construction, then returns it. |
51 * |
65 * |
52 * @param aObserver The observer, to which events will be reported |
66 * @param aObserver The observer, to which events will be reported |
53 * @param aTheLogger The logging object |
67 * @param aTheLogger The logging object |
54 * @return A newly constructed CBcaIoController object |
68 * @return A newly constructed CBcaIoController object |
55 */ |
69 */ |
56 { |
70 { |
57 CBcaIoController* self = new (ELeave) CBcaIoController(aObserver, aTheLogger); |
71 CBcaIoController* self = new (ELeave) CBcaIoController(aObserver, aTheLogger); |
58 CleanupStack::PushL(self); |
72 CleanupStack::PushL(self); |
59 self->ConstructL(); |
73 self->ConstructL(); |
60 CleanupStack::Pop(self); |
74 CleanupStack::Pop(self); |
61 return self; |
75 return self; |
62 } |
76 } |
63 |
77 |
64 void CBcaIoController::ConstructL() |
78 void CBcaIoController::ConstructL() |
65 /** |
79 /** |
66 * Second-phase constructor. Creates all the state objects it owns. |
80 * Second-phase constructor. Creates all the state objects it owns. |
67 */ |
81 */ |
68 { |
82 { |
69 _LOG_L1C1(_L8("CBcaIoController::ConstructL")); |
83 _LOG_L1C1(_L8("CBcaIoController::ConstructL")); |
70 BaseConstructL(); |
84 |
71 iSender = CSender::NewL(*this, iTheLogger, iMaxTxPacketSize); |
85 #ifdef RAWIP_HEADER_APPENDED_TO_PACKETS |
72 iReceiver = CReceiver::NewL(*this, iTheLogger, iMaxRxPacketSize); |
86 iIPTagHeader = new (ELeave) CIPTagHeader(iTheLogger); |
73 iLoader = new (ELeave) CBcaControl(*this, iTheLogger); |
87 #endif // RAWIP_HEADER_APPENDED_TO_PACKETS |
74 } |
88 |
|
89 #if defined __EABI__ |
|
90 // Default value for queue length |
|
91 iMaxSendQueueLen = KMaxSendQueueLen; |
|
92 // Default value for Tx and Rx packet size |
|
93 iMaxTxPacketSize = KMaxTxIPPacketSize; |
|
94 iMaxRxPacketSize = KMaxRxIPPacketSize; |
|
95 #else // WINS |
|
96 // Set default values in case patch is not present in epocrawip.ini |
|
97 iMaxSendQueueLen = KDefaultSendQueueSize; |
|
98 iMaxTxPacketSize = KMaxIPPacket + KIPTagHeaderLength; |
|
99 iMaxRxPacketSize = KMaxIPPacket + KIPTagHeaderLength; |
|
100 |
|
101 // for the emulator process is patched via the epocrawip.ini file |
|
102 UserSvr::HalFunction(EHalGroupEmulator,EEmulatorHalIntProperty,(TAny*)"rawip_KMaxSendQueueLen",&iMaxSendQueueLen); |
|
103 UserSvr::HalFunction(EHalGroupEmulator,EEmulatorHalIntProperty,(TAny*)"rawip_KMaxTxIPPacketSize",&iMaxTxPacketSize); |
|
104 UserSvr::HalFunction(EHalGroupEmulator,EEmulatorHalIntProperty,(TAny*)"rawip_KMaxRxIPPacketSize",&iMaxRxPacketSize); |
|
105 #endif |
|
106 |
|
107 // end note |
|
108 |
|
109 iSender = CSender::NewL(*this, iTheLogger, iMaxTxPacketSize); |
|
110 iReceiver = CReceiver::NewL(*this, iTheLogger, iMaxRxPacketSize); |
|
111 iLoader = new (ELeave) CBcaControl(*this, iTheLogger); |
|
112 } |
75 |
113 |
76 |
114 |
77 CBcaIoController::~CBcaIoController() |
115 CBcaIoController::~CBcaIoController() |
78 /** |
116 /** |
79 * Destructor. |
117 * Destructor. |
80 */ |
118 */ |
81 { |
119 { |
|
120 iSendQueue.Free(); |
|
121 iNumPacketsInSendQueue = 0; |
|
122 |
82 delete iReceiver; |
123 delete iReceiver; |
83 delete iSender; |
124 delete iSender; |
84 delete iLoader; |
125 delete iLoader; |
85 |
126 |
|
127 #ifdef RAWIP_HEADER_APPENDED_TO_PACKETS |
|
128 delete iIPTagHeader; |
|
129 #endif // RAWIP_HEADER_APPENDED_TO_PACKETS |
86 } |
130 } |
87 |
131 |
88 /** sets the BCA Stack name |
132 /** sets the BCA Stack name |
89 |
133 |
90 * @param aBcaStack Text composed of bca stack and next bca names |
134 * @param aBcaStack Text composed of bca stack and next bca names |
116 _LOG_L1C1(_L8("CBcaIoController::Stop is called.")); |
160 _LOG_L1C1(_L8("CBcaIoController::Stop is called.")); |
117 |
161 |
118 //Stop all the active objects |
162 //Stop all the active objects |
119 iReceiver->Cancel(); |
163 iReceiver->Cancel(); |
120 |
164 |
121 if(GetSendState() == ESending) |
165 if (iSendState == ESending) |
122 { |
166 { |
123 iSender->Cancel(); |
167 iSender->Cancel(); |
124 } |
168 } |
125 |
169 |
126 // Update module state |
170 // Update module state |
127 SendState(EShuttingDown); |
171 SendState(EShuttingDown); |
128 |
172 |
129 iLoader->ShutdownBca(aError); |
173 iLoader->ShutdownBca(aError); |
130 } |
174 } |
131 |
175 |
132 void CBcaIoController::InitialiseBcaL() |
176 |
133 /** |
177 ESock::MLowerDataSender::TSendResult CBcaIoController::Send(RMBufChain& aPdu) |
134 * Load & Initialise Bca. |
178 /** |
135 */ |
179 * This method is called by CRawIPFlow in order to send a packet down |
136 { |
180 * to the BCA. |
137 _LOG_L1C1(_L8("<<CBcaIoController::InitialiseBcaL")); |
|
138 iLoader->StartLoadL(); |
|
139 } |
|
140 |
|
141 void CBcaIoController::BcaProcess(TDesC8& aPdu) |
|
142 /** |
|
143 * This method will pass on the received data to CRawIPNifMain. |
|
144 * |
181 * |
145 * @param aPdu a data packet |
182 * @param aPdu a data packet |
146 */ |
183 */ |
147 { |
184 { |
148 _LOG_L1C1(_L8(">>CBcaIoController::Process")); |
185 _LOG_L1C1(_L8(">>CBcaIoController::Send")); |
149 |
186 |
150 Process(aPdu); |
187 // Check if flow is shutting down |
151 |
188 if (iSendState == EShuttingDown) |
152 _LOG_L1C1(_L8("<<CBcaIoController::Process")); |
189 { |
153 } |
190 _LOG_L2C1(_L8(" ERROR: Nif is shutting down")); |
154 |
191 |
155 void CBcaIoController::BcaSend(RMBufChain& aPdu) |
192 // when the flow is destroyed the memory for this packet will be |
156 /** |
193 // cleaned up - just tell the layers above to stop sending. |
157 * This method is called by CRawIPNifMain in order to send a packet down |
194 aPdu.Free(); |
158 * to the BCA. The CSender active object will be activated by calling the send |
195 |
159 * method. |
196 return ESock::MLowerDataSender::ESendBlocked; |
160 * |
197 } |
161 * @param aPdu a data packet |
198 |
162 */ |
199 // check that this packet isnt too big - If it is, we dont want to send it or |
163 { |
200 // add it to our queue |
164 _LOG_L1C1(_L8("CBcaIoController::BcaSend")); |
201 if ((aPdu.Length() - aPdu.First()->Length()) > iMaxTxPacketSize) |
165 |
202 { |
166 iSender->Send(aPdu); |
203 _LOG_L2C1(_L8("Packet is too large - discarding")); |
167 } |
204 _LOG_L1C1(_L8("<<CSender::Send -> Error")); |
168 |
205 |
169 TInt CBcaIoController::BcaSendBufferLength() |
206 // in debug panic - this should not happen, MTU on the uplink should |
170 { |
207 // be strictly enforced |
171 return iSender->SendBufferLength(); |
208 __ASSERT_DEBUG(ETrue,Panic(KFlowInvalidULPacketSize)); |
172 } |
209 |
173 |
210 aPdu.Free(); |
174 void CBcaIoController::BcaSendComplete() |
211 |
175 /** |
212 // may be counter intuitive, however the only options here are either |
176 * This method is called after a packet was sent to the board. |
213 // send accepted or blocked (MLowerDataSender). |
177 * If allowed by flow contol flags the NIF can signal the TCP/IP |
214 |
178 * protocol indicating that is available to send more packets. |
215 _LOG_L2C1(_L8("<<CBcaIoController::Send - return ContinueSending")); |
179 */ |
216 return ESock::MLowerDataSender::ESendAccepted; |
180 { |
217 } |
181 _LOG_L1C1(_L8("CBcaController::SendComplete")); |
218 |
182 |
219 // transmit flow control. |
183 SendComplete(); |
220 if (iFlowBlocked) |
184 } |
221 { |
185 |
222 // Transmit is off for this flow - we must have received a block |
186 |
223 // message from our control. append this message to the queue |
|
224 // and tell the layer above it to kindly stop sending. |
|
225 _LOG_L1C1(_L8(" Sender blocked, appending packet to queue")); |
|
226 |
|
227 AppendToSendQueue(aPdu); |
|
228 |
|
229 // may be a bit counter-intuitive, however, even if the flow is blocked |
|
230 // there is no reason not to ask for more data as long as our send |
|
231 // queue isn't full. |
|
232 |
|
233 if (IsSendQueueFull()) |
|
234 { |
|
235 _LOG_L2C1(_L8("<<CBcaIoController::Send - return StopSending")); |
|
236 return ESock::MLowerDataSender::ESendBlocked; |
|
237 } |
|
238 else |
|
239 { |
|
240 _LOG_L2C1(_L8("<<CBcaIoController::Send - return ContinueSending")); |
|
241 return ESock::MLowerDataSender::ESendAccepted; |
|
242 } |
|
243 } |
|
244 |
|
245 // transmit is on for this flow. send a packet or queue it |
|
246 // if we're already sending one. |
|
247 |
|
248 if (iSendState == ESending) |
|
249 // If this happens, it means that TCP/IP has sent us an IP packet |
|
250 // while we're still sending the previous one. |
|
251 { |
|
252 _LOG_L1C1(_L8(" Sender busy, appending packet to queue")); |
|
253 AppendToSendQueue(aPdu); |
|
254 |
|
255 if (IsSendQueueFull()) |
|
256 { |
|
257 _LOG_L2C1(_L8("<<CBcaIoController::Send - return StopSending")); |
|
258 return ESock::MLowerDataSender::ESendBlocked; |
|
259 } |
|
260 } |
|
261 else |
|
262 { |
|
263 // if we're idle, then we must not be sending. If we're not idle |
|
264 // then the SendComplete() will handle sending any additional |
|
265 // packets that might have been queued onto the send queue. |
|
266 |
|
267 // Update module state |
|
268 _LOG_L2C1(_L8(" set State to ESending")); |
|
269 iSendState = ESending; |
|
270 |
|
271 iSender->Send(aPdu); |
|
272 } |
|
273 |
|
274 // if our send queue isn't full, then the send is accepted |
|
275 // otherwise, block this flow until we have room for the next |
|
276 // packet |
|
277 |
|
278 _LOG_L2C1(_L8("<<CBcaIoController::Send - return ContinueSending")); |
|
279 |
|
280 return ESock::MLowerDataSender::ESendAccepted; |
|
281 } |
|
282 |
|
283 void CBcaIoController::SendComplete() |
|
284 /** |
|
285 * A packet has finished sending - check to see if we need |
|
286 * to process more packets. |
|
287 */ |
|
288 { |
|
289 _LOG_L1C1(_L8(">>CBcaIoController::SendComplete")); |
|
290 |
|
291 // if we've been blocked while in the middle of a |
|
292 // send - don't continue sending, this will happen |
|
293 // when the flow is resumed. |
|
294 |
|
295 iSendState = EIdle; |
|
296 |
|
297 // are we available to transmit? |
|
298 |
|
299 if (iFlowBlocked == EFalse) |
|
300 { |
|
301 // flow transmit is on |
|
302 |
|
303 TBool resumeSending = EFalse; |
|
304 |
|
305 // if the queue is full, it means that while a packet was |
|
306 // outstanding in BCA, we've filled up our send queue and |
|
307 // informed the upper layers to stop sending. |
|
308 |
|
309 if (IsSendQueueFull()) |
|
310 { |
|
311 resumeSending = ETrue; |
|
312 } |
|
313 |
|
314 // if the queue has anything inside it, we need to send the |
|
315 // first packet in the queue. note: the resumeSending check is to |
|
316 // short circuit this so we don't check the queue length twice |
|
317 // in the case that it is full |
|
318 |
|
319 if ((resumeSending) || (!IsSendQueueEmpty())) |
|
320 { |
|
321 iSendState = ESending; |
|
322 |
|
323 RMBufChain tmpPdu; |
|
324 _LOG_L1C1(_L8(" Packet removed from queue to send")); |
|
325 RemoveFromSendQueue(tmpPdu); |
|
326 |
|
327 // Update module state |
|
328 _LOG_L2C1(_L8(" set State to ESending")); |
|
329 |
|
330 iSender->Send(tmpPdu); |
|
331 |
|
332 // if the queue was full, again, we told the upper layers |
|
333 // to stop sending, we need to resume this flow. order is |
|
334 // important as we don't want to get a packet before we've |
|
335 // given one to BCA to send. |
|
336 if (resumeSending) |
|
337 { |
|
338 iObserver.ResumeSending(); |
|
339 } |
|
340 } |
|
341 } |
|
342 |
|
343 _LOG_L1C1(_L8("<<CBcaIoController::SendComplete")); |
|
344 } |
|
345 |
|
346 |
|
347 void CBcaIoController::ResumeSending() |
|
348 /** |
|
349 * Flow is being unblocked this will resume sending. |
|
350 */ |
|
351 { |
|
352 _LOG_L1C1(_L8(">>CBcaIoController::ResumeSending")); |
|
353 |
|
354 // allows for normal SendComplete behaviour if there is |
|
355 // a packet outstanding with BCA |
|
356 iFlowBlocked = EFalse; |
|
357 |
|
358 // If the send state is idle, then there isn't a packet |
|
359 // outstanding, check the send queue to see if there are |
|
360 // packets to send. |
|
361 |
|
362 if (iSendState == EIdle) |
|
363 { |
|
364 // flow transmit is on |
|
365 |
|
366 TBool resumeSending = EFalse; |
|
367 |
|
368 if (IsSendQueueFull()) |
|
369 { |
|
370 resumeSending = ETrue; |
|
371 } |
|
372 |
|
373 // if the queue has anything inside it, we need to send the |
|
374 // first packet in the queue. note: the resumeSending check is to |
|
375 // short circuit this so we don't check the queue length twice |
|
376 // in the case that it is full |
|
377 |
|
378 if ((resumeSending) || (!IsSendQueueEmpty())) |
|
379 { |
|
380 RMBufChain tmpPdu; |
|
381 _LOG_L1C1(_L8(" Packet removed from queue to send")); |
|
382 RemoveFromSendQueue(tmpPdu); |
|
383 |
|
384 // Update module state |
|
385 _LOG_L2C1(_L8(" set State to ESending")); |
|
386 iSendState = ESending; |
|
387 |
|
388 iSender->Send(tmpPdu); |
|
389 |
|
390 // if the queue was full, again, we told the upper layers |
|
391 // to stop sending, we need to resume this flow. order is |
|
392 // important as we don't want to get a packet before we've |
|
393 // given one to BCA to send. |
|
394 if (resumeSending) |
|
395 { |
|
396 iObserver.ResumeSending(); |
|
397 } |
|
398 } |
|
399 } |
|
400 |
|
401 _LOG_L1C1(_L8("<<CBcaIoController::ResumeSending")); |
|
402 } |
|
403 |
|
404 #ifdef RAWIP_HEADER_APPENDED_TO_PACKETS |
|
405 void CBcaIoController::SetType(TUint16 aType) |
|
406 { |
|
407 /** |
|
408 * Used to specify the type of the IP header. |
|
409 */ |
|
410 _LOG_L1C1(_L8("CBcaController::SetType")); |
|
411 |
|
412 iIPTagHeader->SetType(aType); |
|
413 } |
|
414 |
|
415 void CBcaIoController::AddHeader(TDes8& aDes) |
|
416 /** |
|
417 * Used to add the IP header to the packet before sending to the BCA. |
|
418 */ |
|
419 { |
|
420 _LOG_L1C1(_L8("CBcaController::AddHeader")); |
|
421 |
|
422 iIPTagHeader->AddHeader(aDes); |
|
423 } |
|
424 |
|
425 TUint16 CBcaIoController::RemoveHeader(RMBufChain& aPdu) |
|
426 /** |
|
427 * Used to remove the IP header from the received the packet before sending to the |
|
428 * TCP/IP layer. |
|
429 * @return The IP header that has been removed from the packet |
|
430 */ |
|
431 { |
|
432 _LOG_L1C1(_L8("CBcaController::RemoveHeader")); |
|
433 |
|
434 return (iIPTagHeader->RemoveHeader(aPdu)); |
|
435 } |
|
436 #endif // RAWIP_HEADER_APPENDED_TO_PACKETS |
|
437 |
|
438 |
187 CBcaControl::CBcaControl(CBcaIoController& aObserver, CBttLogger* aTheLogger) |
439 CBcaControl::CBcaControl(CBcaIoController& aObserver, CBttLogger* aTheLogger) |
188 /** |
440 /** |
189 * Constructor. Performs standard active object initialisation. |
441 * Constructor. Performs standard active object initialisation. |
190 * |
442 * |
191 * @param aObserver Reference to the observer of this state machine |
443 * @param aObserver Reference to the observer of this state machine |