|
1 // Copyright (c) 2008-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 // csendmessagequeue.cpp |
|
15 // |
|
16 // |
|
17 /** |
|
18 @file |
|
19 @internalTechnology |
|
20 */ |
|
21 |
|
22 #include "f32file.h" |
|
23 |
|
24 #include "cmessagehandler.h" |
|
25 #include "csendmessagequeue.h" |
|
26 __FLOG_STMT(_LIT8(KComponent,"MDNSServer");) |
|
27 /** |
|
28 Two phase constructor |
|
29 @param aDnsMessage Dns message to be sent |
|
30 @param aUnicast True if it is a unicast response |
|
31 @param aAddr address to which the packet to be send |
|
32 @return CSendMessageData object |
|
33 */ |
|
34 CSendMessageData* CSendMessageData::NewL(CDnsMessage* aDnsMessage, TBool aUnicast,TSockAddr aAddr,MMessageHandler& aCallback) |
|
35 { |
|
36 CSendMessageData* self = new(ELeave)CSendMessageData(aDnsMessage,aUnicast,aAddr,aCallback); |
|
37 CleanupStack::PushL(self); |
|
38 self->ConstructL(); |
|
39 CleanupStack::Pop(); |
|
40 return self; |
|
41 } |
|
42 |
|
43 /** |
|
44 Constant function which returns the reference to the Dns message object it wraps |
|
45 @return constant reference to dnsmessage object |
|
46 */ |
|
47 const CDnsMessage& CSendMessageData::GetDnsMessage()const |
|
48 { |
|
49 __FLOG(_L8("CSendMessageData::GetDnsMessage - Exit")); |
|
50 return const_cast<CDnsMessage&> (*iMessage); |
|
51 } |
|
52 |
|
53 /** |
|
54 Constant function which returns the address of the data to be sent |
|
55 @return Constant reference to the address |
|
56 */ |
|
57 const TSockAddr& CSendMessageData::GetSockAddress()const |
|
58 { |
|
59 __FLOG(_L8("CSendMessageData::GetSockAddress - Exit")); |
|
60 return iSockAddr; |
|
61 } |
|
62 |
|
63 /** |
|
64 Constant function which returns true if the message is unicast |
|
65 @return True if message is unicast |
|
66 */ |
|
67 const TBool& CSendMessageData::IsUnicast()const |
|
68 { |
|
69 __FLOG(_L8("CSendMessageData::IsUnicast - Exit")); |
|
70 return iUnicast; |
|
71 } |
|
72 /** |
|
73 Destructor |
|
74 */ |
|
75 CSendMessageData::~CSendMessageData() |
|
76 { |
|
77 __FLOG(_L8("CSendMessageData::~CSendMessageData - Entry")); |
|
78 delete iMessage; |
|
79 __FLOG(_L8("CSendMessageData::~CSendMessageData - Exit")); |
|
80 __FLOG_CLOSE; |
|
81 } |
|
82 |
|
83 /** |
|
84 Two phase constructor |
|
85 @param aDnsMessage DnsMessage to be send |
|
86 */ |
|
87 void CSendMessageData::ConstructL() |
|
88 { |
|
89 __FLOG_OPEN(KMDNSSubsystem, KComponent); |
|
90 } |
|
91 |
|
92 /** |
|
93 Constructor |
|
94 @param aUnicast True if it is a unicast response |
|
95 @param aAddr Address to which the data to be sent |
|
96 */ |
|
97 CSendMessageData::CSendMessageData(CDnsMessage* aDnsMessage,TBool aUnicast,TSockAddr aAddr,MMessageHandler& aCallback):iMessage(aDnsMessage),iUnicast(aUnicast),iSockAddr(aAddr),iCallback(aCallback) |
|
98 { |
|
99 |
|
100 } |
|
101 |
|
102 MMessageHandler& CSendMessageData::Callback() |
|
103 { |
|
104 __FLOG(_L8("CSendMessageData::Callback - Exit")); |
|
105 return iCallback; |
|
106 } |
|
107 /** |
|
108 Two phase Constructor |
|
109 @param aSocket reference to the RSocket |
|
110 */ |
|
111 CSendMessageQueue* CSendMessageQueue::NewL(RSocket& aSocket) |
|
112 { |
|
113 CSendMessageQueue* self = new (ELeave)CSendMessageQueue(); |
|
114 CleanupStack::PushL(self); |
|
115 self->ConstructL(aSocket); |
|
116 CleanupStack::Pop(self); |
|
117 return self; |
|
118 } |
|
119 |
|
120 /** |
|
121 Constructor |
|
122 */ |
|
123 CSendMessageQueue::CSendMessageQueue():CTimer(EPriorityStandard) |
|
124 { |
|
125 CActiveScheduler::Add(this); |
|
126 } |
|
127 |
|
128 /** |
|
129 Function derived from MSocketHandler Observer. |
|
130 This method will be called on succesfull sending of the packet. |
|
131 */ |
|
132 void CSendMessageQueue::OnCompletionL(TDesC8& /*aData*/, const TSockAddr& /*aAddr*/, TInt /*aLength*/) |
|
133 { |
|
134 __FLOG(_L8("CSendMessageQueue::OnCompletionL - Entry")); |
|
135 if(iSendMessageData) |
|
136 { |
|
137 iIsSocketActive = EFalse; |
|
138 iSendMessageData->Callback().OnPacketSendL(KErrNone); |
|
139 } |
|
140 delete iSendMessageData; |
|
141 iSendMessageData = NULL; |
|
142 if(iMessageQueue.Count() > 0 && !IsActive() ) |
|
143 { |
|
144 StartTransmit(); |
|
145 } |
|
146 __FLOG(_L8("CSendMessageQueue::OnCompletionL - Exit")); |
|
147 } |
|
148 |
|
149 /* |
|
150 Function derived from MSocketHandler Observer. |
|
151 This method will be called on error in sending the packet. |
|
152 */ |
|
153 void CSendMessageQueue::OnError(TInt aError) |
|
154 { |
|
155 __FLOG(_L8("CSendMessageQueue::OnError - Entry")); |
|
156 if(iSendMessageData) |
|
157 { |
|
158 iSendMessageData->Callback().OnPacketSendL(aError); |
|
159 } |
|
160 __FLOG(_L8("CSendMessageQueue::OnError - Exit")); |
|
161 } |
|
162 |
|
163 /** |
|
164 Destructor |
|
165 */ |
|
166 CSendMessageQueue::~CSendMessageQueue() |
|
167 { |
|
168 __FLOG(_L8("CSendMessageQueue::~CSendMessageQueue - Entry")); |
|
169 delete iSendSocket; |
|
170 delete iSendMessageData; |
|
171 iMessageQueue.ResetAndDestroy(); |
|
172 iMessageQueue.Close(); |
|
173 iOutput.Close(); |
|
174 __FLOG(_L8("CSendMessageQueue::~CSendMessageQueue - Exit")); |
|
175 __FLOG_CLOSE; |
|
176 } |
|
177 |
|
178 /** |
|
179 Two phase constructor |
|
180 @param refernce to RSocket |
|
181 */ |
|
182 void CSendMessageQueue::ConstructL(RSocket& aSocket) |
|
183 { |
|
184 __FLOG(_L8("CSendMessageQueue::ConstructL - Entry")); |
|
185 iSendSocket = CSocketHandler::NewL(aSocket, *this, ESocketSend); |
|
186 CTimer::ConstructL(); |
|
187 iIsSocketActive = EFalse; |
|
188 __FLOG(_L8("CSendMessageQueue::ConstructL - Exit")); |
|
189 } |
|
190 |
|
191 /** |
|
192 Derived from CActive |
|
193 */ |
|
194 void CSendMessageQueue::RunL() |
|
195 { |
|
196 __FLOG(_L8("CSendMessageQueue::RunL - Entry")); |
|
197 if (MessageReady()) |
|
198 { |
|
199 iSendMessageData = NextDnsMessageL(); |
|
200 CleanupStack::PushL(iSendMessageData); |
|
201 const CDnsMessage& dnsMessage = iSendMessageData->GetDnsMessage(); |
|
202 // close the previously allocated memory. |
|
203 iOutput.Close(); |
|
204 //composes the message from the Dnsmessage object . |
|
205 CDnsMessageComposerParser* comPos = CDnsMessageComposerParser::NewL(); |
|
206 CleanupStack::PushL(comPos); |
|
207 comPos->CreateMessageL(iOutput, iSendMessageData->GetDnsMessage()); |
|
208 TSocketHandlerParams param(ESocketSendTo,&iOutput,&(iSendMessageData->GetSockAddress())); |
|
209 iSendSocket->Activate(param); |
|
210 iIsSocketActive = ETrue; |
|
211 CleanupStack::PopAndDestroy();//comPos |
|
212 CleanupStack::Pop(); |
|
213 } |
|
214 __FLOG(_L8("CSendMessageQueue::RunL - Exit")); |
|
215 } |
|
216 /* |
|
217 * Nothing to do. |
|
218 */ |
|
219 void CSendMessageQueue::DoCancel() |
|
220 { |
|
221 __FLOG(_L8("CSendMessageQueue::DoCancel - Exit")); |
|
222 } |
|
223 |
|
224 void CSendMessageQueue::QueueDnsMessageL(const CSendMessageData& aMessageData) |
|
225 { |
|
226 __FLOG(_L8("CSendMessageQueue::QueueDnsMessageL - Entry")); |
|
227 if (aMessageData.IsUnicast()) |
|
228 { |
|
229 // Unicast replies are to be given higher priority . |
|
230 // Insert the unicast response in the queue. |
|
231 TInt count(iMessageQueue.Count()); |
|
232 TInt index(0); |
|
233 for (; index < count; ++index) |
|
234 { |
|
235 if (!iMessageQueue[index]->IsUnicast()) |
|
236 { |
|
237 break; |
|
238 } |
|
239 } |
|
240 iMessageQueue.InsertL(&aMessageData, index); |
|
241 |
|
242 iNextTransmit.HomeTime(); |
|
243 Cancel(); |
|
244 } |
|
245 else |
|
246 { |
|
247 // Queue the packet |
|
248 iMessageQueue.AppendL(&aMessageData); |
|
249 } |
|
250 |
|
251 // kick the transmit limiter, so we're sure the message will be sent |
|
252 if(!iIsSocketActive) |
|
253 { |
|
254 NextTransmitTime(iNextTransmit); |
|
255 } |
|
256 __FLOG(_L8("CSendMessageQueue::QueueDnsMessageL - Exit")); |
|
257 } |
|
258 |
|
259 void CSendMessageQueue::NextTransmitTime(TTime aTime) |
|
260 { |
|
261 __FLOG(_L8("CSendMessageQueue::NextTransmitTime - Entry")); |
|
262 // if we aren't already active, set the next TX time |
|
263 if (!IsActive()) |
|
264 { |
|
265 TTime now; |
|
266 now.HomeTime(); |
|
267 |
|
268 if (aTime > now) |
|
269 { |
|
270 At(aTime); |
|
271 } |
|
272 else |
|
273 { |
|
274 StartTransmit(); |
|
275 } |
|
276 } |
|
277 __FLOG(_L8("CSendMessageQueue::NextTransmitTime - Exit")); |
|
278 } |
|
279 |
|
280 void CSendMessageQueue::StartTransmit() |
|
281 { |
|
282 __FLOG(_L8("CSendMessageQueue::StartTransmit - Entry")); |
|
283 SetActive(); |
|
284 TRequestStatus *status = &iStatus; |
|
285 User::RequestComplete(status,KErrNone); |
|
286 __FLOG(_L8("CSendMessageQueue::StartTransmit - Exit")); |
|
287 } |
|
288 |
|
289 CSendMessageData* CSendMessageQueue::NextDnsMessageL() |
|
290 { |
|
291 __FLOG(_L8("CSendMessageQueue::NextDnsMessageL - Entry")); |
|
292 if (0 == iMessageQueue.Count()) |
|
293 { |
|
294 User::Leave(KErrNotReady); |
|
295 } |
|
296 |
|
297 CSendMessageData* ret = iMessageQueue[0]; |
|
298 iMessageQueue.Remove(0); |
|
299 // calculate the next possible transmit time. |
|
300 iNextTransmit.HomeTime(); |
|
301 TInt delay = 20 + (Math::Rand(iRandomSeed) % 100); |
|
302 iNextTransmit += TTimeIntervalMicroSeconds(delay * 1000); |
|
303 __FLOG(_L8("CSendMessageQueue::NextDnsMessageL - Exit")); |
|
304 return ret; |
|
305 } |
|
306 |
|
307 TBool CSendMessageQueue::MessageReady() |
|
308 { |
|
309 __FLOG(_L8("CSendMessageQueue::MessageReady - Entry")); |
|
310 TBool ready = EFalse; |
|
311 if (0 != iMessageQueue.Count()) |
|
312 { |
|
313 if (iMessageQueue[0]->IsUnicast()) |
|
314 { |
|
315 // unicast messages go out straight away. |
|
316 ready = ETrue; |
|
317 } |
|
318 else |
|
319 { |
|
320 TTime now; |
|
321 now.HomeTime(); |
|
322 if (!IsActive()) |
|
323 { |
|
324 if (now >= iNextTransmit) |
|
325 { |
|
326 ready = ETrue; |
|
327 } |
|
328 else |
|
329 { |
|
330 NextTransmitTime(iNextTransmit); |
|
331 } |
|
332 } |
|
333 } |
|
334 } |
|
335 __FLOG(_L8("CSendMessageQueue::MessageReady - Exit")); |
|
336 return ready; |
|
337 } |
|
338 |