1 /* |
|
2 * Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 #include <wlanscaninfo.h> |
|
21 #include "t_rsocketdata.h" |
|
22 |
|
23 /*@{*/ |
|
24 // LITs from the ini file |
|
25 _LIT( KSocketServ, "socketserv"); |
|
26 _LIT( KConnection, "connection"); |
|
27 _LIT( KScanInfo, "scaninfo"); |
|
28 _LIT( KAddress, "Ip"); |
|
29 _LIT( KPort, "Port"); |
|
30 _LIT( KFile, "File"); |
|
31 _LIT( KSave, "Save"); |
|
32 _LIT( KARates, "rate"); |
|
33 _LIT( KFileServer, "FileServer"); |
|
34 /*@}*/ |
|
35 |
|
36 /*@{*/ |
|
37 // Upload |
|
38 _LIT(KNullFile, "KNullDesC"); |
|
39 /*@}*/ |
|
40 |
|
41 /*@{*/ |
|
42 // LITs for the commands |
|
43 _LIT( KCmdOpen, "Open"); |
|
44 _LIT( KCmdConnect, "Connect"); |
|
45 _LIT( KCmdHttpGet, "HttpGet"); |
|
46 _LIT( KCmdDownloadSendHTTPGet, "DownloadSendHTTPGet"); |
|
47 _LIT( KCmdRecvOneOrMore, "RecvOneOrMore"); |
|
48 _LIT( KCmdUploadSendHTTPPost, "UploadSendHTTPPost"); |
|
49 _LIT( KCmdCheckSupportedRates, "CheckSupportedRates"); |
|
50 _LIT( KCmdShutdown, "Shutdown"); |
|
51 _LIT( KCmdClose, "Close"); |
|
52 /*@}*/ |
|
53 |
|
54 /*@{*/ |
|
55 // Constants for creating a HTTP request in the command DoCmdDownloadSendHTTPGet |
|
56 _LIT8( KHTTPGET, "GET"); |
|
57 _LIT8( KHTTPSeparator, " "); |
|
58 _LIT8( KHTTPSuffix, "HTTP/1.1"); |
|
59 _LIT( KHostS, "Host"); |
|
60 _LIT8( KLineFeed, "\r\n"); |
|
61 _LIT8( KEmptyLine, "\r\n\r\n"); |
|
62 _LIT8( KHeaderEndMark, "\r\n\r\n" ); |
|
63 _LIT8( KContentLengthField, "Content-Length: "); |
|
64 _LIT8( KFieldEnd, "\r\n" ); |
|
65 _LIT8( KGETHTTP, "GET / HTTP/1.0\r\n\r\n" ); |
|
66 /*@}*/ |
|
67 |
|
68 /*@{*/ |
|
69 // Constants for CreateHTTPHeaderStart |
|
70 _LIT8(KHTTPPOST, "POST"); |
|
71 _LIT8(KLineBreak, "\r\n"); |
|
72 _LIT(KClientID, "clientID"); |
|
73 _LIT(KServerScript, "serverScript"); |
|
74 _LIT8(KFrom, "From:"); |
|
75 _LIT8(KHosts, "Host:"); |
|
76 _LIT8(KContentType, "Content-Type:"); |
|
77 _LIT8(KContentLength, "Content-Length:"); |
|
78 _LIT8(KContentDisposition, "Content-Disposition:"); |
|
79 _LIT8(KMultipartType, "multipart/form-data;"); |
|
80 _LIT8(KOctetType, "application/octet-stream"); |
|
81 _LIT8(KBoundary, "boundary=---------------------------sg976436h73"); |
|
82 _LIT8(KBoundaryStart, "-----------------------------sg976436h73"); |
|
83 _LIT8(KDisposition, "form-data; name=\"userfile\"; filename="); |
|
84 _LIT8(KBackS, "\""); |
|
85 _LIT8(KBoundaryEnd, "-----------------------------sg976436h73--"); |
|
86 /*@}*/ |
|
87 |
|
88 |
|
89 const TInt KHttpHeaderBufferIncrement = 4096; |
|
90 // Const for supported rates |
|
91 // The first bit includes information about BSSBasicRateSet, |
|
92 // mask it out |
|
93 |
|
94 const TUint32 KBasicRateMask = 0x7F; |
|
95 // 802.11g supported speed rate |
|
96 const TUint8 K80211Rate1Mbit = 2; |
|
97 const TUint8 K80211Rate2Mbit = 4; |
|
98 const TUint8 K80211Rate5Mbit = 11; |
|
99 const TUint8 K80211Rate11Mbit = 22; |
|
100 const TUint8 K80211Rate12Mbit = 24; |
|
101 const TUint8 K80211Rate18Mbit = 36; |
|
102 const TUint8 K80211Rate22Mbit = 44; |
|
103 const TUint8 K80211Rate24Mbit = 48; |
|
104 const TUint8 K80211Rate33Mbit = 66; |
|
105 const TUint8 K80211Rate36Mbit = 72; |
|
106 const TUint8 K80211Rate48Mbit = 96; |
|
107 const TUint8 K80211Rate54Mbit = 108; |
|
108 |
|
109 |
|
110 |
|
111 |
|
112 |
|
113 |
|
114 |
|
115 /** |
|
116 * Two phase constructor |
|
117 * |
|
118 * @leave system wide error |
|
119 */ |
|
120 CT_RSocketData* CT_RSocketData::NewL() |
|
121 { |
|
122 CT_RSocketData * ret = new (ELeave)CT_RSocketData(); |
|
123 CleanupStack::PushL(ret); |
|
124 ret->ConstructL(); |
|
125 CleanupStack::Pop(ret); |
|
126 return ret; |
|
127 } |
|
128 |
|
129 /* |
|
130 *RunL method for management Active callbacks |
|
131 * @param aActive param to review which active call back is being fished |
|
132 * @param aIndex |
|
133 * @return void |
|
134 */ |
|
135 void CT_RSocketData::RunL(CActive* aActive, TInt /*aIndex*/) |
|
136 { |
|
137 INFO_PRINTF1(_L("*START* CT_RSocketData::RunL")); |
|
138 DecOutstanding(); // One of the async calls has completed |
|
139 TInt err(KErrNone); |
|
140 if(aActive == iActiveCallback) |
|
141 { |
|
142 INFO_PRINTF1(_L("active call back for Write Socket.")); |
|
143 err = iActiveCallback->iStatus.Int(); |
|
144 if(err != KErrNone) |
|
145 { |
|
146 ERR_PRINTF1(_L("iSocket->Write(...) Fail")); |
|
147 SetError(err); |
|
148 } |
|
149 else |
|
150 { |
|
151 INFO_PRINTF2(_L("CT_RSocketData::SendHTTPGet [%d]"), iActiveCallback->iStatus.Int()); |
|
152 INFO_PRINTF1(_L("Asynchronous task has completed. RunL called")); |
|
153 } |
|
154 } |
|
155 else if(aActive == iActCallConnectSocket) |
|
156 { |
|
157 INFO_PRINTF1(_L("active call back for Connect Socket.")); |
|
158 err = iActCallConnectSocket->iStatus.Int(); |
|
159 if(err != KErrNone) |
|
160 { |
|
161 ERR_PRINTF1(_L("iSocket->Connect(...) Fail")); |
|
162 SetError(err); |
|
163 } |
|
164 else |
|
165 { |
|
166 INFO_PRINTF1(_L("CT_RSocketData::DoCmdConnect(...) success")); |
|
167 iSocketOpened = ETrue; |
|
168 } |
|
169 } |
|
170 else if(aActive == iActCallShutDownSocket) |
|
171 { |
|
172 INFO_PRINTF1(_L("active call back for Shutdown Socket.")); |
|
173 err = iActCallShutDownSocket->iStatus.Int(); |
|
174 if(err != KErrNone) |
|
175 { |
|
176 ERR_PRINTF2(_L("iSocket->Shutdown(...): [%d] Fail"),iActCallShutDownSocket->iStatus.Int()); |
|
177 SetError(err); |
|
178 } |
|
179 else |
|
180 { |
|
181 INFO_PRINTF1(_L("CT_RSocketData::Shutdown success")); |
|
182 iSocketStarted = EFalse; |
|
183 } |
|
184 } |
|
185 else |
|
186 { |
|
187 ERR_PRINTF1(_L("An unchecked active object completed")); |
|
188 SetBlockResult(EFail); |
|
189 } |
|
190 |
|
191 INFO_PRINTF1(_L("*END* CT_RSocketData::RunL")); |
|
192 } |
|
193 /* |
|
194 * public destructor |
|
195 */ |
|
196 CT_RSocketData::~CT_RSocketData() |
|
197 { |
|
198 if (iSocketStarted) |
|
199 { |
|
200 INFO_PRINTF1(_L("CT_RSocketData: Shutting down socket")); |
|
201 Shutdown(); |
|
202 } |
|
203 if (iSocketOpened) |
|
204 { |
|
205 Close(); |
|
206 } |
|
207 if (iDownloadBuffer) |
|
208 { |
|
209 delete iDownloadBuffer; |
|
210 iDownloadBuffer = NULL; |
|
211 } |
|
212 if (iSocket) |
|
213 { |
|
214 delete iSocket; |
|
215 iSocket = NULL; |
|
216 } |
|
217 if (iActiveCallback) |
|
218 { |
|
219 delete iActiveCallback; |
|
220 iActiveCallback = NULL; |
|
221 } |
|
222 if (iActCallShutDownSocket) |
|
223 { |
|
224 delete iActCallShutDownSocket; |
|
225 iActCallShutDownSocket = NULL; |
|
226 } |
|
227 if (iActCallConnectSocket) |
|
228 { |
|
229 delete iActCallConnectSocket; |
|
230 iActCallConnectSocket = NULL; |
|
231 } |
|
232 |
|
233 iFs.Close(); |
|
234 |
|
235 if (iUploadBuffer) |
|
236 { |
|
237 delete iUploadBuffer; |
|
238 iUploadBuffer = NULL; |
|
239 } |
|
240 } |
|
241 |
|
242 /** |
|
243 * Private constructor. First phase construction |
|
244 * |
|
245 */ |
|
246 CT_RSocketData::CT_RSocketData() |
|
247 : iSocket(NULL), |
|
248 iActiveCallback(NULL), |
|
249 iActCallConnectSocket(NULL), |
|
250 iActCallShutDownSocket(NULL), |
|
251 iSocketOpened(EFalse), |
|
252 iSocketStarted(EFalse), |
|
253 iAsyncErrorIndex(0), |
|
254 iDownloadBuffer(NULL), |
|
255 iUploadBuffer(NULL), |
|
256 iHttpResponseHeader(), |
|
257 iDownloadThroughput(0.0), |
|
258 iFs(), |
|
259 iUploadThroughput(0.0), |
|
260 itotalReceived(0) |
|
261 { |
|
262 |
|
263 } |
|
264 |
|
265 /** |
|
266 * Second phase construction |
|
267 * |
|
268 * @internalComponent |
|
269 * |
|
270 * @return N/A |
|
271 * |
|
272 * @pre None |
|
273 * @post None |
|
274 * |
|
275 * @leave system wide error |
|
276 */ |
|
277 void CT_RSocketData::ConstructL() |
|
278 { |
|
279 const TInt KDefaultBufferSize = 4096; |
|
280 TInt err(KErrNone); |
|
281 iSocket = new (ELeave) RSocket(); |
|
282 iActiveCallback = CActiveCallback::NewL(*this); |
|
283 iActCallConnectSocket = CActiveCallback::NewL(*this); |
|
284 iActCallShutDownSocket = CActiveCallback::NewL(*this); |
|
285 iDownloadBuffer = HBufC8::NewL( KDefaultBufferSize); |
|
286 iUploadBuffer = HBufC8::NewL(KDefaultBufferSize); |
|
287 err = iFs.Connect(); |
|
288 if(err != KErrNone) |
|
289 { |
|
290 SetError(err); |
|
291 } |
|
292 } |
|
293 |
|
294 |
|
295 /** |
|
296 * Return a pointer to the object that the data wraps |
|
297 * |
|
298 * @return pointer to the object that the data wraps |
|
299 */ |
|
300 TAny* CT_RSocketData::GetObject() |
|
301 { |
|
302 return iSocket; |
|
303 } |
|
304 |
|
305 |
|
306 |
|
307 /** |
|
308 * Process a command read from the Ini file |
|
309 * @param aCommand The command to process |
|
310 * @param aSection The section get from the *.ini file of the project T_Wlan |
|
311 * @param aAsyncErrorIndex Command index for async calls to returns errors to |
|
312 * @return TBool ETrue if the command is process |
|
313 * @leave system wide error |
|
314 * |
|
315 */ |
|
316 TBool CT_RSocketData::DoCommandL(const TTEFFunction& aCommand, const TTEFSectionName& aSection, const TInt aAsyncErrorIndex) |
|
317 { |
|
318 TBool ret = ETrue; |
|
319 if(aCommand == KCmdOpen ) |
|
320 { |
|
321 DoCmdOpen(aSection); |
|
322 } |
|
323 else if(aCommand == KCmdConnect) |
|
324 { |
|
325 DoCmdConnect(aSection,aAsyncErrorIndex); |
|
326 } |
|
327 else if(aCommand == KCmdDownloadSendHTTPGet) |
|
328 { |
|
329 DoCmdDownloadSendHTTPGet(aSection,aAsyncErrorIndex); |
|
330 } |
|
331 else if(aCommand == KCmdRecvOneOrMore) |
|
332 { |
|
333 DoCmdRecvOneOrMore(aSection); |
|
334 } |
|
335 else if(aCommand == KCmdUploadSendHTTPPost) |
|
336 { |
|
337 DoCmdUploadSendHTTPPost(aSection); |
|
338 } |
|
339 else if(aCommand == KCmdShutdown) |
|
340 { |
|
341 DoCmdShutdown(aAsyncErrorIndex); |
|
342 } |
|
343 else if(aCommand == KCmdClose) |
|
344 { |
|
345 DoCmdClose(); |
|
346 } |
|
347 else if(aCommand == KCmdHttpGet) |
|
348 { |
|
349 DoCmdHttpGet(); |
|
350 } |
|
351 else if(aCommand == KCmdCheckSupportedRates) |
|
352 { |
|
353 DoCmdCheckSupportedRates(aSection); |
|
354 } |
|
355 else |
|
356 { |
|
357 ERR_PRINTF1(_L("Unknown command.")); |
|
358 ret = EFalse; |
|
359 } |
|
360 return ret; |
|
361 } |
|
362 |
|
363 |
|
364 |
|
365 |
|
366 /** |
|
367 * Open the Socket from RSocket. The errors are management with SetError() and SetBlockResult(). |
|
368 * @param aSection Section in the ini file for this command. |
|
369 * @return |
|
370 */ |
|
371 void CT_RSocketData::DoCmdOpen(const TTEFSectionName& aSection) |
|
372 { |
|
373 INFO_PRINTF1(_L("*START* CT_RSocketData::DoCmdOpen")); |
|
374 TBool dataOk = ETrue; |
|
375 |
|
376 TPtrC connectionName; |
|
377 if(! GetStringFromConfig(aSection, KConnection, connectionName)) |
|
378 { |
|
379 ERR_PRINTF2(_L("Error in getting parameter %S from INI file"), &KConnection); |
|
380 SetBlockResult(EFail); |
|
381 dataOk = EFalse; |
|
382 } |
|
383 |
|
384 TPtrC socketServName; |
|
385 if(! GetStringFromConfig(aSection, KSocketServ, socketServName)) |
|
386 { |
|
387 ERR_PRINTF2(_L("Error in getting parameter %S from INI file"), &KSocketServ); |
|
388 SetBlockResult(EFail); |
|
389 dataOk = EFalse; |
|
390 } |
|
391 |
|
392 if (dataOk) |
|
393 { |
|
394 INFO_PRINTF1(_L("Opening a TCP/IP socket")); |
|
395 |
|
396 RConnection* rConnection = static_cast<RConnection*>(GetDataObjectL(connectionName)); |
|
397 RSocketServ* rSocketServ = static_cast<RSocketServ*>(GetDataObjectL(socketServName)); |
|
398 |
|
399 if(rConnection != NULL && rSocketServ != NULL) |
|
400 { |
|
401 TInt error = iSocket->Open( *rSocketServ, KAfInet, KSockStream, KProtocolInetTcp, *rConnection ); |
|
402 |
|
403 if(error == KErrNone) |
|
404 { |
|
405 iSocketOpened = ETrue; |
|
406 } |
|
407 else |
|
408 { |
|
409 ERR_PRINTF2(_L("Socket opening failed [%d]"), error); |
|
410 SetError(error); |
|
411 } |
|
412 } |
|
413 else |
|
414 { |
|
415 if(rConnection == NULL) |
|
416 { |
|
417 ERR_PRINTF2(_L("rConnection is NULL: %S"),rConnection); |
|
418 SetBlockResult(EFail); |
|
419 } |
|
420 |
|
421 if(rSocketServ == NULL) |
|
422 { |
|
423 INFO_PRINTF2(_L("rSocketServ is NULL: %S"),rSocketServ); |
|
424 SetBlockResult(EFail); |
|
425 } |
|
426 } |
|
427 } |
|
428 |
|
429 INFO_PRINTF1(_L("*END* CT_RSocketData::DoCmdOpen")); |
|
430 } |
|
431 |
|
432 /** |
|
433 * Command to Connect a Socket of RSocket. |
|
434 * @param aSection Section to read from the ini file |
|
435 * @param aAsyncErrorIndex Command index for async calls to returns errors to |
|
436 * @return |
|
437 */ |
|
438 void CT_RSocketData::DoCmdConnect(const TTEFSectionName& aSection, const TInt aAsyncErrorIndex) |
|
439 { |
|
440 INFO_PRINTF1(_L("*START* CT_RSocketData::DoCmdConnect")); |
|
441 TBool dataOk = ETrue; |
|
442 |
|
443 //Getting from the .ini the IP Address |
|
444 TPtrC aIpAddr; |
|
445 if(!GetStringFromConfig( aSection, KAddress, aIpAddr )) |
|
446 { |
|
447 ERR_PRINTF2(_L("Error in getting parameter %S from INI file"), &KAddress); |
|
448 SetBlockResult(EFail); |
|
449 dataOk = EFalse; |
|
450 } |
|
451 |
|
452 //Getting the port from the file ini |
|
453 TInt aPort; |
|
454 if(!GetIntFromConfig( aSection, KPort,aPort )) |
|
455 { |
|
456 ERR_PRINTF2(_L("Error in getting parameter %S from INI file"), &KPort); |
|
457 SetBlockResult(EFail); |
|
458 dataOk = EFalse; |
|
459 } |
|
460 |
|
461 if(dataOk) |
|
462 { |
|
463 // Set the IP Address |
|
464 TInetAddr inetAddr; |
|
465 TInt err = inetAddr.Input( aIpAddr ) ; |
|
466 if(err == KErrNone) |
|
467 { |
|
468 INFO_PRINTF2(_L("Remote IP: %S"), &aIpAddr ); |
|
469 INFO_PRINTF2( _L("Port: %d"), aPort ); |
|
470 // Set the port |
|
471 inetAddr.SetPort( aPort ); |
|
472 // Connect an IP through the Port 80 |
|
473 iSocket->Connect( inetAddr, iActCallConnectSocket->iStatus ); |
|
474 iActCallConnectSocket->Activate(aAsyncErrorIndex); |
|
475 IncOutstanding(); |
|
476 } |
|
477 else |
|
478 { |
|
479 ERR_PRINTF2(_L("inetAddr.Input( aIpAddr ) Failed with error %d"), err); |
|
480 SetError(err); |
|
481 } |
|
482 } |
|
483 |
|
484 INFO_PRINTF1(_L("*END* CT_RSocketData::DoCmdConnect")); |
|
485 } |
|
486 |
|
487 /** |
|
488 * Command to send the HTTP Get, using the socket Write. |
|
489 * @param aSection Section to read from the ini file |
|
490 * @param aAsyncErrorIndex Command index for async calls to returns errors to |
|
491 * @return |
|
492 */ |
|
493 void CT_RSocketData::DoCmdDownloadSendHTTPGet(const TTEFSectionName& aSection, const TInt aAsyncErrorIndex ) |
|
494 { |
|
495 INFO_PRINTF1(_L("*START* CT_RSocketData::DoCmdDownloadSendHTTPGet")); |
|
496 TBool dataOk = ETrue; |
|
497 |
|
498 // Read params from the ini file |
|
499 TPtrC aHost; |
|
500 if(!GetStringFromConfig( aSection, KHostS, aHost)) |
|
501 { |
|
502 ERR_PRINTF2(_L("Error in getting parameter %S from INI file"), &KHostS); |
|
503 SetBlockResult(EFail); |
|
504 dataOk = EFalse; |
|
505 } |
|
506 |
|
507 TPtrC aFilename; |
|
508 if(!GetStringFromConfig( aSection, KFile, aFilename )) |
|
509 { |
|
510 ERR_PRINTF2(_L("Error in getting parameter %S from INI file"), &KFile); |
|
511 SetBlockResult(EFail); |
|
512 dataOk = EFalse; |
|
513 } |
|
514 |
|
515 if (dataOk) |
|
516 { |
|
517 const TInt KMaxHostNameLength(256); |
|
518 if( aHost.Length() > KMaxHostNameLength ) |
|
519 { |
|
520 ERR_PRINTF1(_L("Host is too long, cannot send HTTP request")); |
|
521 SetBlockResult(EFail); |
|
522 } |
|
523 else if( aFilename.Length() > KMaxFileName ) |
|
524 { |
|
525 ERR_PRINTF1(_L("Filename is too long, cannot send HTTP request")); |
|
526 SetBlockResult(EFail); |
|
527 } |
|
528 else |
|
529 { |
|
530 INFO_PRINTF1(_L("Create HTTP GET request")); |
|
531 // Buffer that will hold the request. |
|
532 TBuf8< sizeof( KHTTPGET ) + |
|
533 sizeof( KHTTPSeparator ) + |
|
534 KMaxFileName + |
|
535 sizeof( KHTTPSeparator ) + |
|
536 sizeof( KHTTPSuffix ) + |
|
537 sizeof( KLineFeed ) + |
|
538 sizeof( KHosts ) + |
|
539 KMaxHostNameLength + |
|
540 sizeof( KEmptyLine ) > request; |
|
541 // Construct the final request. |
|
542 request.Copy( KHTTPGET ); |
|
543 request.Append( KHTTPSeparator ); |
|
544 request.Append( aFilename ); |
|
545 request.Append( KHTTPSeparator ); |
|
546 request.Append( KHTTPSuffix ); |
|
547 request.Append( KLineFeed ); |
|
548 request.Append( KHosts ); |
|
549 request.Append( aHost ); |
|
550 request.Append( KEmptyLine ); |
|
551 |
|
552 INFO_PRINTF1(_L("Write to socket")); |
|
553 // Send the request through socket |
|
554 iSocket->Write(request, iActiveCallback->iStatus); |
|
555 iActiveCallback->Activate(aAsyncErrorIndex); |
|
556 IncOutstanding(); |
|
557 } |
|
558 } |
|
559 |
|
560 INFO_PRINTF1(_L("*END* CT_RSocketData::DoCmdDownloadSendHTTPGet")); |
|
561 } |
|
562 |
|
563 /** |
|
564 * Command to receive an HTTP Response for Upload and Download of files. |
|
565 * @param aSection Section to read from the ini file |
|
566 * @return |
|
567 */ |
|
568 void CT_RSocketData::DoCmdRecvOneOrMore(const TTEFSectionName& aSection) |
|
569 { |
|
570 INFO_PRINTF1(_L("*START* CT_RSocketData::DoCmdRecvOneOrMore")); |
|
571 TBool dataOk = ETrue; |
|
572 |
|
573 // Read from the ini file |
|
574 TPtrC aFilename; |
|
575 if(!GetStringFromConfig( aSection, KSave,aFilename )) |
|
576 { |
|
577 ERR_PRINTF2(_L("Error in getting parameter %S from INI file"), &KSave); |
|
578 SetBlockResult(EFail); |
|
579 dataOk = EFalse; |
|
580 } |
|
581 |
|
582 if (dataOk) |
|
583 { |
|
584 RFile file; |
|
585 TInt error = KErrNone; |
|
586 |
|
587 //if KNullFile then Upload |
|
588 TBool discardData = ( aFilename == KNullFile); |
|
589 INFO_PRINTF2(_L("File and path to Download: %S"),&aFilename); |
|
590 if( !discardData ) |
|
591 { |
|
592 INFO_PRINTF1( _L("Data is not discarded, creating file") ); |
|
593 error = file.Replace( iFs, aFilename, EFileShareAny|EFileWrite ); |
|
594 } |
|
595 else |
|
596 { |
|
597 INFO_PRINTF1( _L("Discarding downloaded data") ); |
|
598 } |
|
599 |
|
600 if( error == KErrNone ) |
|
601 { |
|
602 TSockXfrLength received; |
|
603 TInt totalReceived = 0; |
|
604 TInt contentReceived = 0; |
|
605 TInt timedReceived = 0; |
|
606 TInt contentLength = 0; |
|
607 TRequestStatus status; |
|
608 TPtr8 downloadBufferPtr( iDownloadBuffer->Des() ); |
|
609 |
|
610 downloadBufferPtr.SetMax(); |
|
611 INFO_PRINTF2( _L("Using buffer size [%d]"), downloadBufferPtr.MaxSize() ); |
|
612 |
|
613 INFO_PRINTF1(_L("Set time stamps for download")); |
|
614 TTime endTime; |
|
615 TTime startTime; |
|
616 |
|
617 INFO_PRINTF1( _L("Receiving data")); |
|
618 |
|
619 // Let's assume that we receive a HTTP header first |
|
620 TBool header( ETrue ); |
|
621 TBool timerStarted( EFalse ); |
|
622 TBool failure = EFalse; // a flag to delete multiple returns |
|
623 |
|
624 iHttpResponseHeader.Zero(); |
|
625 // receive until RecvOneOrMore fails or all content is received |
|
626 do |
|
627 { |
|
628 if( !timerStarted && !header) |
|
629 { |
|
630 startTime.HomeTime(); |
|
631 endTime.HomeTime(); |
|
632 timerStarted = ETrue; |
|
633 } |
|
634 |
|
635 iSocket->RecvOneOrMore( downloadBufferPtr, 0, status, received ); |
|
636 User::WaitForRequest( status ); |
|
637 if( !header ) |
|
638 { |
|
639 timedReceived += received(); |
|
640 } |
|
641 |
|
642 if( KErrNone == status.Int() ) |
|
643 { |
|
644 // Check if we are still receiving the HTTP header |
|
645 if( header ) |
|
646 { |
|
647 //Increase httpResponseheader size if needed |
|
648 if(iHttpResponseHeader.Length() + downloadBufferPtr.Length() > iHttpResponseHeader.MaxLength()) |
|
649 { |
|
650 error = iHttpResponseHeader.ReAlloc(iHttpResponseHeader.MaxLength() + KHttpHeaderBufferIncrement); |
|
651 if(error != KErrNone) |
|
652 { |
|
653 ERR_PRINTF2( _L("iHttpResponseHeader.ReAlloc(...) Failed with error %d"), error); |
|
654 SetError( error ); |
|
655 failure = ETrue; |
|
656 break; |
|
657 } |
|
658 } |
|
659 |
|
660 //Append the donwloaded content to headerbuffer |
|
661 iHttpResponseHeader.Append(downloadBufferPtr); |
|
662 TInt headerEndIndex = iHttpResponseHeader.Find( KHeaderEndMark ); |
|
663 if( headerEndIndex != KErrNotFound ) |
|
664 { |
|
665 INFO_PRINTF1( _L("Header end mark found")); |
|
666 //Parse Content-Length field and extract content length |
|
667 TInt contentLengthStart = iHttpResponseHeader.Find( KContentLengthField ); |
|
668 //If Content-Length field is found |
|
669 if( contentLengthStart != KErrNotFound ) |
|
670 { |
|
671 INFO_PRINTF1(_L("Content-Length field found from HTTP response")); |
|
672 contentLengthStart += KContentLengthField().Length(); |
|
673 TPtrC8 contentLengthDes; |
|
674 contentLengthDes.Set(iHttpResponseHeader.Mid( contentLengthStart )); |
|
675 TInt contentLengthEnd = contentLengthDes.Find( KFieldEnd ); |
|
676 contentLengthDes.Set(contentLengthDes.Mid(0, contentLengthEnd)); |
|
677 TLex8 lex; |
|
678 lex.Assign( contentLengthDes ); |
|
679 lex.Val(contentLength); |
|
680 INFO_PRINTF2( _L("Content-Length: [%d]"), contentLength ); |
|
681 } |
|
682 else |
|
683 { |
|
684 INFO_PRINTF1( _L("No Content-Length field found from HTTP response")); |
|
685 INFO_PRINTF1( _L("Assuming Content-Length: 0")); |
|
686 contentLength = 0; |
|
687 file.Close(); |
|
688 error = iFs.Delete(aFilename); |
|
689 if(error != KErrNone) |
|
690 { |
|
691 INFO_PRINTF3(_L("Error [%d] for delete the file %S"), &aFilename,error); |
|
692 SetError(error); |
|
693 failure = ETrue; |
|
694 break; |
|
695 } |
|
696 ERR_PRINTF2(_L("File %S was not found"), &aFilename); |
|
697 SetBlockResult(EFail); |
|
698 failure = ETrue; |
|
699 break; |
|
700 } |
|
701 // Header was found |
|
702 headerEndIndex += KHeaderEndMark().Length(); |
|
703 //Convert the headerEndIndex in httpResponseheader to index in downloadBuffer |
|
704 headerEndIndex -= totalReceived; |
|
705 //Delete remaining parts of the HTTP header from the download buffer |
|
706 downloadBufferPtr.Delete( 0, headerEndIndex ); |
|
707 header = EFalse; |
|
708 } |
|
709 } |
|
710 |
|
711 // Increase the total received amount as we receive more data. |
|
712 // Note: received data count also counts headers, this is taken |
|
713 // into account in timing (startTime) |
|
714 totalReceived += received(); |
|
715 if(!header) |
|
716 { |
|
717 contentReceived += downloadBufferPtr.Length(); |
|
718 } |
|
719 |
|
720 if( !discardData ) |
|
721 { |
|
722 error = file.Write( *iDownloadBuffer ); |
|
723 if( KErrNone != error ) |
|
724 { |
|
725 ERR_PRINTF2( _L("Failed to write local file [%d]"), error ); |
|
726 file.Close(); |
|
727 SetError(error); |
|
728 failure = ETrue; |
|
729 break; |
|
730 } |
|
731 } |
|
732 } |
|
733 else |
|
734 { |
|
735 INFO_PRINTF1(_L("Set end time")); |
|
736 endTime.HomeTime(); |
|
737 INFO_PRINTF2( _L("Receiving err [%d]"), status.Int()); |
|
738 break; |
|
739 } |
|
740 } |
|
741 while( KErrNone == status.Int() && contentReceived < contentLength ); |
|
742 |
|
743 if (!failure) |
|
744 { |
|
745 endTime.HomeTime(); |
|
746 INFO_PRINTF2( _L("Received total of [%d] bytes (inc headers)"), totalReceived ); |
|
747 INFO_PRINTF2( _L("Content received [%d] bytes"), contentReceived ); |
|
748 |
|
749 //Set this printing optional |
|
750 //Print only if any amount of datatransfer was timed (skipped in the case of very short data transfers) |
|
751 if( timerStarted ) |
|
752 { |
|
753 INFO_PRINTF1(_L("Calculate duration of the transfer")); |
|
754 TTimeIntervalMicroSeconds duration = endTime.MicroSecondsFrom( startTime ); |
|
755 INFO_PRINTF2( _L("Duration for the timed data transfer was [%Ld] microseconds"), duration.Int64() ); |
|
756 INFO_PRINTF2( _L("Received [%d] bytes during timed data transfer"), timedReceived); |
|
757 iDownloadThroughput = ThroughputInMegaBits( duration, timedReceived ); |
|
758 } |
|
759 else |
|
760 { |
|
761 INFO_PRINTF1( _L("Data transfer too short for throughput calculation")); |
|
762 } |
|
763 |
|
764 // We allow any response to our reply at the moment. |
|
765 if( !discardData ) |
|
766 { |
|
767 file.Close(); |
|
768 } |
|
769 } |
|
770 } |
|
771 else |
|
772 { |
|
773 ERR_PRINTF2( _L("Failed to open local file [%d]"), error ); |
|
774 SetError(error); |
|
775 } |
|
776 } |
|
777 |
|
778 INFO_PRINTF1(_L("*END* CT_RSocketData::DoCmdRecvOneOrMore")); |
|
779 } |
|
780 |
|
781 /** |
|
782 * Create an HTTP Post for uploading files. |
|
783 * @param aSection Section to read from the ini file |
|
784 * @return |
|
785 */ |
|
786 void CT_RSocketData::DoCmdUploadSendHTTPPost(const TTEFSectionName& aSection) |
|
787 { |
|
788 INFO_PRINTF1(_L("*START* CT_RSocketData::DoCmdUploadSendHTTPPost")); |
|
789 TBool dataOk = ETrue; |
|
790 |
|
791 INFO_PRINTF1( _L("Write to socket")); |
|
792 |
|
793 TPtrC aFilename; |
|
794 if(!GetStringFromConfig(aSection,KFile,aFilename)) |
|
795 { |
|
796 ERR_PRINTF2(_L("Error in getting parameter %S from INI file"), &KFile); |
|
797 SetBlockResult(EFail); |
|
798 dataOk = EFalse; |
|
799 } |
|
800 |
|
801 TPtrC fileServer; |
|
802 if(!GetStringFromConfig(aSection,KFileServer,fileServer)) |
|
803 { |
|
804 ERR_PRINTF2(_L("Error in getting parameter %S from INI file"), &KFileServer); |
|
805 SetBlockResult(EFail); |
|
806 dataOk = EFalse; |
|
807 } |
|
808 |
|
809 TPtrC clientID; |
|
810 if(!GetStringFromConfig(aSection,KClientID,clientID)) |
|
811 { |
|
812 ERR_PRINTF2(_L("Error in getting parameter %S from INI file"), &KClientID); |
|
813 SetBlockResult(EFail); |
|
814 dataOk = EFalse; |
|
815 } |
|
816 |
|
817 TPtrC serverScript; |
|
818 if(!GetStringFromConfig(aSection,KServerScript,serverScript)) |
|
819 { |
|
820 ERR_PRINTF2(_L("Error in getting parameter %S from INI file"), &KServerScript); |
|
821 SetBlockResult(EFail); |
|
822 dataOk = EFalse; |
|
823 } |
|
824 |
|
825 if (dataOk) |
|
826 { |
|
827 const TInt KMaxTag = 256; |
|
828 // KHeaderWithoutData will change if you alter the header in any way that changes the |
|
829 // amount of characters in it! SO REMEMBER to calclulate header size again. |
|
830 const TInt KHeaderWithoutData = 200; |
|
831 TBuf8<KMaxTag + KHeaderWithoutData> request; |
|
832 TRequestStatus status; |
|
833 |
|
834 CreateHTTPHeaderStart(request, ReadFileSizeL(aFilename),fileServer, clientID, serverScript); |
|
835 |
|
836 iSocket->Write( request,status); |
|
837 User::WaitForRequest( status ); |
|
838 if(status.Int() == KErrNone) |
|
839 { |
|
840 INFO_PRINTF1( _L("HTTP POST request send, sending payload next")); |
|
841 // Send file to iSocket |
|
842 SendFileToSocketL(aFilename); |
|
843 request.SetLength( 0 ); |
|
844 CreateHTTPHeaderEnd(request); |
|
845 |
|
846 // Send the rest of the header |
|
847 INFO_PRINTF1(_L("Sending boundary end")); |
|
848 iSocket->Write( request, status ); |
|
849 User::WaitForRequest( status ); |
|
850 if(status.Int() != KErrNone) |
|
851 { |
|
852 ERR_PRINTF2(_L("CT_RSocketData::DoCmdUploadSendHTTPPost: iSocket->Write( request,status) Failed with error %d"), status.Int()); |
|
853 SetError(status.Int()); |
|
854 } |
|
855 } |
|
856 else |
|
857 { |
|
858 ERR_PRINTF2(_L("CT_RSocketData::DoCmdUploadSendHTTPPost: iSocket->Write( request,status) Failed with error %d"), status.Int()); |
|
859 SetError(status.Int()); |
|
860 } |
|
861 } |
|
862 |
|
863 INFO_PRINTF1(_L("*END* CT_RSocketData::DoCmdUploadSendHTTPPost")); |
|
864 } |
|
865 |
|
866 /** |
|
867 * Create or build the header for POST. |
|
868 * @param aRequest Descriptor with a lenght of 456 that contain the parameters for the POST |
|
869 * @param aDataSize Size of the file |
|
870 * @return |
|
871 */ |
|
872 void CT_RSocketData::CreateHTTPHeaderStart(TDes8& aRequest, TInt aDataSize,TDesC& aFileServer, TDesC& clientID,TDesC& serverScript) |
|
873 { |
|
874 // Manually created HTTP Post request is difficult to maintain. |
|
875 // Request and server responce is logged into file during test run. |
|
876 |
|
877 // KHeaderWithoutData will change if you alter the header in any way |
|
878 // that changes the amount of characters in it! SO REMEMBER to calclulate |
|
879 // header size again. |
|
880 const TInt KHeaderWithoutData = 200; |
|
881 INFO_PRINTF1( _L("Set socket remote name")); |
|
882 TSockAddr address; |
|
883 iSocket->RemoteName( address ); |
|
884 |
|
885 // Construct request |
|
886 aRequest.Append(KHTTPPOST); |
|
887 aRequest.Append(KHTTPSeparator); |
|
888 aRequest.Append(serverScript); |
|
889 aRequest.Append(KHTTPSeparator); |
|
890 aRequest.Append(KHTTPSuffix); |
|
891 aRequest.Append(KLineBreak); |
|
892 |
|
893 aRequest.Append(KHosts); |
|
894 aRequest.Append(KHTTPSeparator); |
|
895 aRequest.Append(address); |
|
896 aRequest.Append(KLineBreak); |
|
897 |
|
898 aRequest.Append(KFrom); |
|
899 aRequest.Append(KHTTPSeparator); |
|
900 aRequest.Append(clientID); |
|
901 aRequest.Append(KLineBreak); |
|
902 |
|
903 aRequest.Append(KContentType); |
|
904 aRequest.Append(KHTTPSeparator); |
|
905 aRequest.Append(KMultipartType); |
|
906 aRequest.Append(KHTTPSeparator); |
|
907 aRequest.Append(KBoundary); |
|
908 aRequest.Append(KLineBreak); |
|
909 |
|
910 aRequest.Append(KContentLength); |
|
911 aRequest.Append(KHTTPSeparator); |
|
912 // aRequest size + size of the data to be sent. Server must know how much |
|
913 // data is coming. |
|
914 aRequest.AppendNum(KHeaderWithoutData+aDataSize); |
|
915 aRequest.Append(KLineBreak); |
|
916 |
|
917 // extra line break |
|
918 aRequest.Append(KLineBreak); |
|
919 |
|
920 aRequest.Append(KBoundaryStart); |
|
921 aRequest.Append(KLineBreak); |
|
922 |
|
923 aRequest.Append(KContentDisposition); |
|
924 aRequest.Append(KHTTPSeparator); |
|
925 aRequest.Append(KDisposition); |
|
926 aRequest.Append(KBackS); |
|
927 aRequest.Append(aFileServer); |
|
928 aRequest.Append(KBackS); |
|
929 aRequest.Append(KLineBreak); |
|
930 |
|
931 aRequest.Append(KContentType); |
|
932 aRequest.Append(KHTTPSeparator); |
|
933 aRequest.Append(KOctetType); |
|
934 aRequest.Append(KLineBreak); |
|
935 |
|
936 aRequest.Append(KLineBreak); |
|
937 } |
|
938 |
|
939 /** |
|
940 * Send aFilename parameter to the Socket with RSocket::Write |
|
941 * @param aFilename name of the file send to the Socket |
|
942 * @return |
|
943 */ |
|
944 void CT_RSocketData::SendFileToSocketL(const TDesC& aFilename) |
|
945 { |
|
946 TInt err(KErrNone); |
|
947 TPtr8 buffer( iUploadBuffer->Des() ); |
|
948 buffer.SetMax(); |
|
949 INFO_PRINTF2( _L("Using buffer size [%d]"), buffer.MaxSize() ); |
|
950 TInt bytesSent = 0; |
|
951 |
|
952 INFO_PRINTF1( _L("Open file")); |
|
953 RFile file; |
|
954 |
|
955 err = file.Open(iFs, aFilename, EFileShareAny|EFileRead); |
|
956 |
|
957 if(err == KErrNone) |
|
958 { |
|
959 CleanupClosePushL( file ); |
|
960 INFO_PRINTF1(_L("Read file size")); |
|
961 TInt fileSize = ReadFileSizeL(aFilename); |
|
962 |
|
963 INFO_PRINTF1( _L("Set time stamps for upload")); |
|
964 TTime endTime; |
|
965 endTime.HomeTime(); |
|
966 TTime startTime; |
|
967 startTime.HomeTime(); |
|
968 |
|
969 INFO_PRINTF1( _L("Send file")); |
|
970 // Loop while enough bytes are sent to socket |
|
971 while( bytesSent < fileSize ) |
|
972 { |
|
973 TInt err = file.Read( buffer ); |
|
974 |
|
975 if( err == KErrEof ) |
|
976 { |
|
977 INFO_PRINTF1(_L("File sending finished")); |
|
978 INFO_PRINTF2( _L("Upload buffer length is [%d]"), buffer.Length()); |
|
979 break; |
|
980 } |
|
981 else if( err != KErrNone ) |
|
982 { |
|
983 ERR_PRINTF2( _L("Failed to read file [%d]"), err ); |
|
984 SetError( err ); |
|
985 break; |
|
986 } |
|
987 |
|
988 TRequestStatus status(KRequestPending); |
|
989 iSocket->Write( buffer, status ); |
|
990 User::WaitForRequest( status ); |
|
991 err = status.Int(); |
|
992 if(err != KErrNone) |
|
993 { |
|
994 ERR_PRINTF2(_L("CT_RSocketData::SendFileToSocketL:iSocket->Write(...) Fail [%d] "),err); |
|
995 SetError(err); |
|
996 break; |
|
997 } |
|
998 |
|
999 bytesSent += ( buffer.Length() ); |
|
1000 } |
|
1001 |
|
1002 if (err == KErrNone || err == KErrEof) |
|
1003 { |
|
1004 INFO_PRINTF1( _L("Set end time")); |
|
1005 endTime.HomeTime(); |
|
1006 INFO_PRINTF2( _L("Sent [%d] bytes to server"), bytesSent); |
|
1007 |
|
1008 INFO_PRINTF1( _L("Calculate duration of the transfer")); |
|
1009 TTimeIntervalMicroSeconds duration = endTime.MicroSecondsFrom( startTime ); |
|
1010 INFO_PRINTF2( _L("Duration for the data transfer was [%Ld] microseconds"), duration.Int64() ); |
|
1011 iUploadThroughput = ThroughputInMegaBits( duration, bytesSent ); |
|
1012 CleanupStack::PopAndDestroy( &file ); |
|
1013 } |
|
1014 } |
|
1015 else |
|
1016 { |
|
1017 ERR_PRINTF2(_L("CT_RSocket::SendFileToSocketL::file.Open(...) Failed with error %d"), err); |
|
1018 SetError(err); |
|
1019 } |
|
1020 } |
|
1021 |
|
1022 /** |
|
1023 * Calculated the throughput based on duration of a data transfer and total transferred bytes. |
|
1024 * @param aDuration Duration of the transfer |
|
1025 * @param aBytes Total transferred in bytes |
|
1026 * @return Throughput in MBps |
|
1027 */ |
|
1028 TReal CT_RSocketData::ThroughputInMegaBits(TTimeIntervalMicroSeconds aDuration, TInt aBytes ) |
|
1029 { |
|
1030 const TReal KBitsInByte(8.0); |
|
1031 TReal throughput = ( KBitsInByte * (TReal) aBytes ) / (TReal) aDuration.Int64(); |
|
1032 return throughput; |
|
1033 } |
|
1034 |
|
1035 /** |
|
1036 * Read the lenght of the file (aFileName) |
|
1037 * @param aFileName file to read the lenght |
|
1038 * @return |
|
1039 */ |
|
1040 TInt CT_RSocketData::ReadFileSizeL(const TDesC& aFilename) |
|
1041 { |
|
1042 RFile file; |
|
1043 TInt error = file.Open(iFs, aFilename, EFileShareAny|EFileRead); |
|
1044 if ( error != KErrNone) |
|
1045 { |
|
1046 ERR_PRINTF2( _L("Failed to open local file [%d]"), error); |
|
1047 SetError(error); |
|
1048 return error; |
|
1049 } |
|
1050 |
|
1051 TInt fileSize = 0; |
|
1052 error = file.Size(fileSize); |
|
1053 |
|
1054 if (error!= KErrNone) |
|
1055 { |
|
1056 ERR_PRINTF2(_L("Failed to read file size [%d]"), error); |
|
1057 file.Close(); |
|
1058 SetError(error); |
|
1059 return error; |
|
1060 } |
|
1061 |
|
1062 file.Close(); |
|
1063 return fileSize; |
|
1064 } |
|
1065 |
|
1066 /** |
|
1067 * Build the final header to POST for uploading files |
|
1068 * @param aRequest Descriptor with 456 of lenght that contain the final POST request |
|
1069 * @return |
|
1070 */ |
|
1071 void CT_RSocketData::CreateHTTPHeaderEnd(TDes8& aRequest) |
|
1072 { |
|
1073 //TRequestStatus status; |
|
1074 aRequest.SetLength( 0 ); |
|
1075 //Create the rest of the header data |
|
1076 aRequest.Append( KLineBreak ); |
|
1077 aRequest.Append( KBoundaryEnd ); |
|
1078 aRequest.Append( KLineBreak ); |
|
1079 } |
|
1080 |
|
1081 |
|
1082 /** |
|
1083 * Make a HTTP request to the socket |
|
1084 * @param |
|
1085 * @return |
|
1086 */ |
|
1087 void CT_RSocketData::DoCmdHttpGet() |
|
1088 { |
|
1089 INFO_PRINTF1(_L("*START* CT_RSocketData::DoCmdHttpGet")); |
|
1090 |
|
1091 TInt err(KErrNone); |
|
1092 //Constant for creating a HTTP request. |
|
1093 const TInt KHTTPSize = 128; |
|
1094 // Buffer that will hold the request. |
|
1095 TBuf8 <KHTTPSize> request; |
|
1096 // Construct the final request. |
|
1097 request.Append( KGETHTTP ); |
|
1098 |
|
1099 INFO_PRINTF1( _L("Write to socket") ); |
|
1100 TRequestStatus status( KRequestPending ); |
|
1101 iSocket->Write( request, status); |
|
1102 User::WaitForRequest( status ); |
|
1103 INFO_PRINTF2( _L("CT_RSocketData::DoCmdHttpGet: Write done: [%d]"), status.Int() ); |
|
1104 err = status.Int(); |
|
1105 |
|
1106 if(err == KErrNone) |
|
1107 { |
|
1108 INFO_PRINTF1( _L("CT_RSocketData::DoCmdHttpGet: Receive from socket") ); |
|
1109 // receive until RecvOneOrMore fails |
|
1110 do |
|
1111 { |
|
1112 RecvOneOrMore(status); |
|
1113 } |
|
1114 while( status.Int() == KErrNone ); |
|
1115 |
|
1116 INFO_PRINTF2( _L("CT_RSocketData::DoCmdHttpGet: Receiving finished. Received [%d] bytes in total"), itotalReceived ); |
|
1117 |
|
1118 // Currently all error codes returned by the server are accepted. |
|
1119 // Should only KErrEof be accepted? |
|
1120 INFO_PRINTF2( _L("Ignoring error code from RSocket::RecvOneOrMore [%d]"), status.Int()); |
|
1121 } |
|
1122 else |
|
1123 { |
|
1124 ERR_PRINTF2(_L("CT_RSocketData::DoCmdHttpGet: iSocket.Write(...) Failed with error %d"), err); |
|
1125 SetError(err); |
|
1126 } |
|
1127 |
|
1128 INFO_PRINTF1(_L("*END* CT_RSocketData::DoCmdHttpGet")); |
|
1129 } |
|
1130 |
|
1131 /** |
|
1132 * Receive data from a remote host. |
|
1133 * @param status Indicates the complexion status of the request |
|
1134 * @return |
|
1135 */ |
|
1136 void CT_RSocketData::RecvOneOrMore(TRequestStatus &status) |
|
1137 { |
|
1138 TInt err(KErrNone); |
|
1139 // Create variables for receive buffer and received data counting variables. |
|
1140 const TInt KBufferSize(1024); |
|
1141 TBuf8<KBufferSize> buffer; |
|
1142 TSockXfrLength received; |
|
1143 iSocket->RecvOneOrMore( buffer, 0, status, received); |
|
1144 User::WaitForRequest( status ); |
|
1145 err = status.Int(); |
|
1146 if( err == KErrNone ) |
|
1147 { |
|
1148 INFO_PRINTF2( _L("CWlanTestWrapper: Received [%d] bytes"), received() ); |
|
1149 itotalReceived += received(); |
|
1150 } |
|
1151 else if( err == KErrEof ) |
|
1152 { |
|
1153 INFO_PRINTF1(_L("End of File reached")); |
|
1154 } |
|
1155 else |
|
1156 { |
|
1157 ERR_PRINTF2(_L("RecvOneOrMore async call failed with error %d"), err); |
|
1158 SetError(err); |
|
1159 } |
|
1160 } |
|
1161 |
|
1162 |
|
1163 |
|
1164 /** |
|
1165 * Check the supported rates for the IAP. |
|
1166 * @param aSection Section to read from the ini file |
|
1167 * @return |
|
1168 */ |
|
1169 void CT_RSocketData::DoCmdCheckSupportedRates(const TTEFSectionName& aSection) |
|
1170 { |
|
1171 INFO_PRINTF1(_L("*START* CT_RSocketData::DoCmdCheckSupportedRates")); |
|
1172 TBool dataOk = ETrue; |
|
1173 |
|
1174 // Read from the ini file |
|
1175 TInt aRate; |
|
1176 if(!GetIntFromConfig(aSection,KARates,aRate)) |
|
1177 { |
|
1178 ERR_PRINTF2(_L("Error in getting parameter %S from INI file"), &KARates); |
|
1179 SetBlockResult(EFail); |
|
1180 dataOk = EFalse; |
|
1181 } |
|
1182 |
|
1183 // Check if a scan has been made |
|
1184 TPtrC iScanInfoName; |
|
1185 if(!GetStringFromConfig(aSection,KScanInfo,iScanInfoName )) |
|
1186 { |
|
1187 ERR_PRINTF2(_L("Error in getting parameter %S from INI file"), &KScanInfo); |
|
1188 SetBlockResult(EFail); |
|
1189 dataOk = EFalse; |
|
1190 } |
|
1191 |
|
1192 if (dataOk) |
|
1193 { |
|
1194 CWlanScanInfo* iScanInfo = static_cast<CWlanScanInfo*>(GetDataObjectL(iScanInfoName)); |
|
1195 |
|
1196 // Check if a scan has been made |
|
1197 if( iScanInfo != NULL ) |
|
1198 { |
|
1199 const TUint8 KTemp80211SupRatesId = 1; |
|
1200 const TUint8 KTemp80211SupRatesMaxLen = 18; |
|
1201 // Scan info gives data as "information elements" |
|
1202 TUint8 ieLen(0); |
|
1203 const TUint8* ieData(0); |
|
1204 |
|
1205 TInt err = iScanInfo->InformationElement( KTemp80211SupRatesId, ieLen, &ieData ); |
|
1206 |
|
1207 // Check supported rate if the information element was available |
|
1208 if(err == KErrNone) |
|
1209 { |
|
1210 TBuf8<KTemp80211SupRatesMaxLen> supRates8; |
|
1211 supRates8.Copy( ieData, ieLen ); |
|
1212 TBool supported = CheckSupportedRates( supRates8, aRate ); |
|
1213 if(!supported) |
|
1214 { |
|
1215 ERR_PRINTF2( _L("%d rate not supportedRates"), aRate ); |
|
1216 SetError(KErrNotSupported); |
|
1217 } |
|
1218 } |
|
1219 else |
|
1220 { |
|
1221 ERR_PRINTF2( _L("err: [%d]"), err ); |
|
1222 SetError(err); |
|
1223 } |
|
1224 } |
|
1225 else |
|
1226 { |
|
1227 ERR_PRINTF1(_L("Failed to get CWlanScanInfo object")); |
|
1228 SetBlockResult(EFail); |
|
1229 } |
|
1230 } |
|
1231 |
|
1232 INFO_PRINTF1(_L("*END* CT_RSocketData::DoCmdCheckSupportedRates")); |
|
1233 } |
|
1234 |
|
1235 /** |
|
1236 * Review if the rate its supported. |
|
1237 * @param aSupportedRates Rate to calculate and if match with the desired rate |
|
1238 * @param aRate rate to verify if is supporrted, The rate to be checked in 0.5Mb/s units. |
|
1239 * Ie. 2 = 2 * 0.5Mb/s = 1Mb/s. |
|
1240 * @return Etrue if the rate is supported |
|
1241 */ |
|
1242 TBool CT_RSocketData::CheckSupportedRates(const TDesC8& aSupportedRates, const TUint8 aRate) |
|
1243 { |
|
1244 // Supported rates information element format is the following: |
|
1245 // | element id (1 octet) | length (1 octet) | supported rates (1-8 octets) | |
|
1246 // where each octet of supported rates contains one supported rate in |
|
1247 // units of 500 kb/s. The first bit of supported rates field is always 1 |
|
1248 // if the rate belongs to the BSSBasicRateSet, if the rate does not belong |
|
1249 // to the BSSBasicRateSet the first bit is 0. |
|
1250 |
|
1251 // For example Supported rates information element with value |
|
1252 // 0x01,0x02,0x82,0x84 |
|
1253 // would mean that BSSBasicRateSet rates 1Mb/s and 2Mb/s are supported |
|
1254 |
|
1255 TBool supported( EFalse ); |
|
1256 |
|
1257 for ( TInt i( 0 ); i < aSupportedRates.Length(); i++ ) |
|
1258 { |
|
1259 TUint8 rate = aSupportedRates[i] & KBasicRateMask; |
|
1260 if( rate == aRate ) supported = ETrue; |
|
1261 //INFO_PRINTF2( _L("speed rate [%d]"), rate); |
|
1262 switch( rate ) |
|
1263 { |
|
1264 case K80211Rate1Mbit: |
|
1265 INFO_PRINTF1( _L("AP can support Speed Rate 1Mbit") ); |
|
1266 break; |
|
1267 case K80211Rate2Mbit: |
|
1268 INFO_PRINTF1( _L("AP can support Speed Rate 2Mbit") ); |
|
1269 break; |
|
1270 case K80211Rate5Mbit: |
|
1271 INFO_PRINTF1( _L("AP can support Speed Rate 5Mbit") ); |
|
1272 break; |
|
1273 case K80211Rate11Mbit: |
|
1274 INFO_PRINTF1( _L("AP can support Speed Rate 11Mbit") ); |
|
1275 break; |
|
1276 case K80211Rate12Mbit: |
|
1277 INFO_PRINTF1( _L("AP can support Speed Rate 12Mbit") ); |
|
1278 break; |
|
1279 case K80211Rate18Mbit: |
|
1280 INFO_PRINTF1( _L("AP can support Speed Rate 18Mbit") ); |
|
1281 break; |
|
1282 case K80211Rate22Mbit: |
|
1283 INFO_PRINTF1( _L("AP can support Speed Rate 22Mbit") ); |
|
1284 break; |
|
1285 case K80211Rate24Mbit: |
|
1286 INFO_PRINTF1( _L("AP can support Speed Rate 24Mbit") ); |
|
1287 break; |
|
1288 case K80211Rate36Mbit: |
|
1289 INFO_PRINTF1( _L("AP can support Speed Rate 36Mbit") ); |
|
1290 break; |
|
1291 case K80211Rate48Mbit: |
|
1292 INFO_PRINTF1( _L("AP can support Speed Rate 48Mbit") ); |
|
1293 break; |
|
1294 case K80211Rate54Mbit: |
|
1295 INFO_PRINTF1( _L("AP can support Speed Rate 54Mbit") ); |
|
1296 break; |
|
1297 |
|
1298 default: |
|
1299 break; |
|
1300 } |
|
1301 } |
|
1302 |
|
1303 return supported; |
|
1304 } |
|
1305 |
|
1306 /** |
|
1307 * Shutdown the socket (RSocket::Shutdown). |
|
1308 * @param aAsyncErrorIndex Command index for async calls to returns errors to |
|
1309 * @return |
|
1310 */ |
|
1311 void CT_RSocketData::DoCmdShutdown( const TInt aAsyncErrorIndex) |
|
1312 { |
|
1313 INFO_PRINTF1(_L("*START* CT_RSocketData::DoCmdShutdown")); |
|
1314 INFO_PRINTF1(_L("Starting to shutdown Socket")); |
|
1315 iSocket->Shutdown( RSocket::ENormal, iActCallShutDownSocket->iStatus); |
|
1316 iActCallShutDownSocket->Activate(aAsyncErrorIndex); |
|
1317 IncOutstanding(); |
|
1318 INFO_PRINTF1(_L("*END* CT_RSocketData::DoCmdShutdown")); |
|
1319 } |
|
1320 /** |
|
1321 * Helper function calling from the destroyer. |
|
1322 * @param |
|
1323 * @return |
|
1324 */ |
|
1325 void CT_RSocketData::Shutdown() |
|
1326 { |
|
1327 TInt err(KErrNone); |
|
1328 TRequestStatus status; |
|
1329 iSocket->Shutdown(RSocket::ENormal, status); |
|
1330 User::WaitForRequest( status ); |
|
1331 err = status.Int(); |
|
1332 if( err != KErrNone ) |
|
1333 { |
|
1334 ERR_PRINTF2( _L("CT_RSocketData::Shutdown(): error[%d]"), err); |
|
1335 SetError(err); |
|
1336 } |
|
1337 } |
|
1338 |
|
1339 /** |
|
1340 * Close de socket. |
|
1341 * @param |
|
1342 * @return |
|
1343 */ |
|
1344 void CT_RSocketData::DoCmdClose() |
|
1345 { |
|
1346 INFO_PRINTF1(_L("*START* CT_RSocketData::DoCmdClose")); |
|
1347 Close(); |
|
1348 INFO_PRINTF1(_L("*END* CT_RSocketData::DoCmdClose")); |
|
1349 } |
|
1350 /** |
|
1351 * Helper function to close the socket. |
|
1352 * @param |
|
1353 * @return |
|
1354 */ |
|
1355 void CT_RSocketData::Close() |
|
1356 { |
|
1357 iSocket->Close(); |
|
1358 iSocketOpened = EFalse; |
|
1359 } |
|