|
1 /* |
|
2 * Copyright (c) 2002 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: SyncML Obex client |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "NSmlObexClient.h" |
|
20 #include "NSmlObexServiceSearcher.h" |
|
21 #include "ObexSearcherBase.h" |
|
22 #include "Obexsearcherfactory.h" |
|
23 #include "ExtBTSearcherObserver.h" |
|
24 #include <nsmlconstants.h> |
|
25 #include <nsmldebug.h> |
|
26 |
|
27 #include "nsmlerror.h" |
|
28 #include "wbxml2xmlconverter.h" |
|
29 |
|
30 //============================================================ |
|
31 // CNsmlObexClient definition |
|
32 //============================================================ |
|
33 |
|
34 |
|
35 //------------------------------------------------------------ |
|
36 // CNsmlObexClient::NewL() |
|
37 //------------------------------------------------------------ |
|
38 CNsmlObexClient* CNsmlObexClient::NewL() |
|
39 { |
|
40 CNsmlObexClient* self = new (ELeave) CNsmlObexClient(); |
|
41 CleanupStack::PushL( self ); |
|
42 self->ConstructL( ObexName ); |
|
43 CleanupStack::Pop(); //self |
|
44 return self; |
|
45 } |
|
46 |
|
47 //------------------------------------------------------------ |
|
48 // CNsmlObexClient::CNsmlObexClient() |
|
49 //------------------------------------------------------------ |
|
50 CNsmlObexClient::CNsmlObexClient(): CActive(CActive::EPriorityStandard), |
|
51 iState(EDisconnected), iDataPtr( 0, 0 ) |
|
52 { |
|
53 CActiveScheduler::Add( this ); |
|
54 } |
|
55 |
|
56 //------------------------------------------------------------ |
|
57 // CNsmlObexClient* CreateCNsmlObexClientL() |
|
58 //------------------------------------------------------------ |
|
59 EXPORT_C CNsmlObexClient* CreateCNsmlObexClientL() |
|
60 { |
|
61 return CNsmlObexClient::NewL(); |
|
62 } |
|
63 |
|
64 //------------------------------------------------------------ |
|
65 // CNsmlObexClient::ConstructL( const TDesC8& /*aName*/ ) |
|
66 //------------------------------------------------------------ |
|
67 void CNsmlObexClient::ConstructL( const TDesC8& /*aName*/ ) |
|
68 { |
|
69 iDataBuf = CBufFlat::NewL( KNSmlObexClientGranularity ); |
|
70 iCurrObject = CObexBufObject::NewL( iDataBuf ); |
|
71 } |
|
72 |
|
73 //------------------------------------------------------------ |
|
74 // CNsmlObexClient::~CNsmlObexClient() |
|
75 //------------------------------------------------------------ |
|
76 CNsmlObexClient::~CNsmlObexClient() |
|
77 { |
|
78 if( iClient ) |
|
79 { |
|
80 iClient->Disconnect(iStatus); |
|
81 User::After( 500000 ); |
|
82 delete iClient; |
|
83 User::WaitForRequest( iStatus ); |
|
84 } |
|
85 |
|
86 Cancel(); |
|
87 delete iDataBuf; |
|
88 delete iMimeType; |
|
89 delete iCurrObject; |
|
90 delete iObexSearcher; |
|
91 } |
|
92 |
|
93 //------------------------------------------------------------ |
|
94 // CNsmlObexClient::DoCancel() |
|
95 //------------------------------------------------------------ |
|
96 void CNsmlObexClient::DoCancel() |
|
97 { |
|
98 TRequestStatus* status = iAgentStatus; |
|
99 |
|
100 delete iClient; |
|
101 iClient = NULL; |
|
102 |
|
103 if( *status == KRequestPending ) |
|
104 { |
|
105 User::RequestComplete( status, KErrCancel ); |
|
106 } |
|
107 } |
|
108 |
|
109 //------------------------------------------------------------ |
|
110 // CNsmlObexClient::RunL() |
|
111 //------------------------------------------------------------ |
|
112 void CNsmlObexClient::RunL() |
|
113 { |
|
114 TInt error( iStatus.Int() ); |
|
115 TRequestStatus* status = iAgentStatus; |
|
116 |
|
117 DBG_FILE_CODE( iStatus.Int(), _S8("CNsmlObexClient::RunL \ |
|
118 Before error conversion : ") ); |
|
119 ErrorConversion( iStatus.Int(), error ); |
|
120 |
|
121 if ( iStatus != KErrNone ) |
|
122 { |
|
123 if ( iState == EGettingConnection && |
|
124 iStatus == KErrIrObexClientPeerDoesNotHaveObex ) |
|
125 { |
|
126 iState = EConnectionFailed; |
|
127 ConnectToServerL(); |
|
128 } |
|
129 else if ( iState == EDisconnecting && iStatus == KErrDisconnected ) |
|
130 { |
|
131 iState = EDisconnected; |
|
132 User::RequestComplete( status, error ); |
|
133 } |
|
134 else |
|
135 { |
|
136 iState = EDisconnected; |
|
137 User::RequestComplete( status, KErrCancel ); |
|
138 } |
|
139 } |
|
140 else |
|
141 { |
|
142 switch ( iState ) |
|
143 { |
|
144 case EGettingConnection: |
|
145 case EConnectionFailed: |
|
146 iState = EWaitingToSend; |
|
147 User::RequestComplete( status, error ); |
|
148 break; |
|
149 |
|
150 case EWaitingToSend: |
|
151 iState = EWaitingToReceive; |
|
152 User::RequestComplete( status, error ); |
|
153 break; |
|
154 |
|
155 case EWaitingToReceive: |
|
156 iDataPtr = this->iDataBuf->Ptr( 0 ); |
|
157 iState = EWaitingToSend; |
|
158 User::RequestComplete( status, error ); |
|
159 DBG_DUMP((void*)iDataPtr.Ptr(), iDataPtr.Length(), _S8("ReceiveDataL (WBXML)")); |
|
160 #ifdef __NSML_DEBUG__ |
|
161 _DBG_FILE("CNsmlObexClient::RunL: CWbxml2XmlConverter::ConvertL() begin"); |
|
162 CWbxml2XmlConverter* c; |
|
163 c = CWbxml2XmlConverter::NewLC(); |
|
164 c->ConvertL(iDataPtr.Ptr(), iDataPtr.Length()); |
|
165 DBG_DUMP((void*)c->Document().Ptr(), c->Document().Length(), _S8("ReceiveDataL (XML)") ); |
|
166 CleanupStack::PopAndDestroy(); // c |
|
167 _DBG_FILE("CNsmlObexClient::RunL: CWbxml2XmlConverter::ConvertL() end"); |
|
168 #endif // __NSML_DEBUG__ |
|
169 break; |
|
170 |
|
171 case EDisconnecting: |
|
172 iState = EDisconnected; |
|
173 User::RequestComplete( iAgentStatus, KErrNone ); |
|
174 break; |
|
175 |
|
176 default: |
|
177 Panic( EBTObjectExchangeSdpRecordDelete ); |
|
178 break; |
|
179 }; |
|
180 } |
|
181 } |
|
182 |
|
183 //------------------------------------------------------------ |
|
184 // CNsmlObexClient::ConnectL( TNSmlObexTransport aTransport, TBool /*aServerAlerted*/, TDesC8& aMimeType, TRequestStatus &aStatus ) |
|
185 //------------------------------------------------------------ |
|
186 void CNsmlObexClient::ConnectL( |
|
187 TNSmlObexTransport aTransport, |
|
188 TBool /*aServerAlerted*/, |
|
189 TDesC8& aMimeType, |
|
190 TRequestStatus &aStatus ) |
|
191 { |
|
192 iAgentStatus = &aStatus; |
|
193 // agent |
|
194 *iAgentStatus = KRequestPending; |
|
195 |
|
196 delete iMimeType; |
|
197 iMimeType = NULL; |
|
198 iMimeType = HBufC8::NewL( aMimeType.Length() ); |
|
199 TPtr8 iMIMEptr( iMimeType->Des() ); |
|
200 iMIMEptr.Copy( aMimeType ); |
|
201 |
|
202 if ( iState == EDisconnected && !IsActive() ) |
|
203 { |
|
204 |
|
205 //Delete old and create new device/service searcher |
|
206 delete iObexSearcher; |
|
207 iObexSearcher = NULL; |
|
208 |
|
209 //Handle bluetooth as a special case: |
|
210 if ( aTransport == EObexBt ) |
|
211 { |
|
212 iObexSearcher = CObexSearcherFactory::CreateBTSearcherL( iBTConnInfo ); |
|
213 iObexSearcher->SetObserver( this ); |
|
214 iObexSearcher->SetExtObserver( iExtObserver ); |
|
215 |
|
216 //Search device first if the device address is undefined |
|
217 if ( iBTConnInfo.iDevAddr == TBTDevAddr() ) |
|
218 { |
|
219 iObexSearcher->SearchDeviceL(); |
|
220 } |
|
221 else |
|
222 { |
|
223 //else skip device search and jump straight to the service search |
|
224 iObexSearcher->SearchServiceL(); |
|
225 } |
|
226 } |
|
227 else |
|
228 { |
|
229 //Other cases, only IrDA so far |
|
230 iObexSearcher = CObexSearcherFactory::CreateObexSearcherL( aTransport ); |
|
231 iObexSearcher->SetObserver( this ); |
|
232 iObexSearcher->SetExtObserver( iExtObserver ); |
|
233 iObexSearcher->SearchDeviceL(); |
|
234 } |
|
235 |
|
236 } |
|
237 else |
|
238 { |
|
239 //debug here |
|
240 User::Leave( KErrInUse ); |
|
241 } |
|
242 } |
|
243 |
|
244 //------------------------------------------------------------ |
|
245 // CNsmlObexClient::ConnectToServerL() |
|
246 //------------------------------------------------------------ |
|
247 void CNsmlObexClient::ConnectToServerL() |
|
248 { |
|
249 if (iClient) |
|
250 { |
|
251 delete iClient; |
|
252 iClient = NULL; |
|
253 } |
|
254 |
|
255 //Let the obex searcher create the obex client |
|
256 iClient = iObexSearcher->CreateObexClientL(); |
|
257 |
|
258 iCurrObject->SetTargetL( KClientTargetHeader ); |
|
259 iClient->Connect( *iCurrObject, iStatus ); |
|
260 SetActive(); |
|
261 } |
|
262 |
|
263 //------------------------------------------------------------ |
|
264 // CNsmlObexClient::SendDataL( TDesC8& aStartPtr, TBool /*aFinalPacket*/, TRequestStatus &aStatus ) |
|
265 //------------------------------------------------------------ |
|
266 void CNsmlObexClient::SendDataL( TDesC8& aStartPtr, TBool /*aFinalPacket*/, TRequestStatus &aStatus ) |
|
267 { |
|
268 iAgentStatus = &aStatus; |
|
269 // agent |
|
270 *iAgentStatus = KRequestPending; |
|
271 |
|
272 if ( iState == EWaitingToReceive ) |
|
273 { |
|
274 iClient->Abort(); |
|
275 iState = EWaitingToSend; |
|
276 } |
|
277 if ( iState != EWaitingToSend ) |
|
278 { |
|
279 User::Leave( KErrDisconnected ); |
|
280 } |
|
281 else if ( IsActive() ) |
|
282 { |
|
283 User::Leave( KErrInUse ); |
|
284 } |
|
285 |
|
286 iCurrObject->Reset(); |
|
287 |
|
288 DBG_DUMP((void*)aStartPtr.Ptr(), aStartPtr.Length(), |
|
289 _S8("SendDataL (WBXML)") ); |
|
290 #ifdef __NSML_DEBUG__ |
|
291 _DBG_FILE("CNsmlObexClient::SendDataL: CWbxml2XmlConverter::ConvertL() begin"); |
|
292 CWbxml2XmlConverter* c = CWbxml2XmlConverter::NewLC(); |
|
293 c->ConvertL(aStartPtr.Ptr(), aStartPtr.Length()); |
|
294 DBG_DUMP((void*)c->Document().Ptr(), c->Document().Length(), |
|
295 _S8("SendDataL (XML)") ); |
|
296 CleanupStack::PopAndDestroy(); // c |
|
297 _DBG_FILE("CNsmlObexClient::SendDataL: CWbxml2XmlConverter::ConvertL() end"); |
|
298 #endif // __NSML_DEBUG__ |
|
299 |
|
300 iDocumentLength = aStartPtr.Length(); |
|
301 |
|
302 iDataBuf->Reset(); |
|
303 iDataBuf->InsertL( 0, aStartPtr ); |
|
304 TRAPD( err, iCurrObject->SetDataBufL( iDataBuf ) ); |
|
305 |
|
306 if( KErrNone == err ) |
|
307 { |
|
308 TBuf8<KNameLen> str; |
|
309 str.Copy( this->iMimeType->Des() ); |
|
310 iCurrObject->SetTypeL( str ); |
|
311 |
|
312 iClient->Put( *iCurrObject, iStatus ); |
|
313 SetActive (); |
|
314 } |
|
315 } |
|
316 //------------------------------------------------------------ |
|
317 // CNsmlObexClient::ReceiveDataL( TDes8& aStartPtr, TRequestStatus &aStatus ) |
|
318 //------------------------------------------------------------ |
|
319 void CNsmlObexClient::ReceiveDataL( TPtr8& aStartPtr, TRequestStatus &aStatus ) |
|
320 { |
|
321 iAgentStatus = &aStatus; |
|
322 // agent |
|
323 *iAgentStatus = KRequestPending; |
|
324 |
|
325 iDataPtr.Set( aStartPtr ); |
|
326 |
|
327 if ( iState != EWaitingToReceive ) |
|
328 { |
|
329 User::Leave( KErrDisconnected ); |
|
330 } |
|
331 else if ( IsActive() ) |
|
332 { |
|
333 User::Leave( KErrInUse ); |
|
334 } |
|
335 iDataBuf->Reset(); |
|
336 iCurrObject->Reset(); |
|
337 |
|
338 TBuf8<KNameLen> str; |
|
339 str.Copy( this->iMimeType->Des() ); |
|
340 iCurrObject->SetTypeL( str ); |
|
341 |
|
342 iClient->Get( *iCurrObject, iStatus ); |
|
343 |
|
344 DBG_DUMP((void*)aStartPtr.Ptr(), aStartPtr.Length(), |
|
345 _S8("ReceiveDataL (WBXML)")); |
|
346 #ifdef __NSML_DEBUG__ |
|
347 _DBG_FILE("CNsmlObexClient::ReceiveDataL: CWbxml2XmlConverter::ConvertL()\ |
|
348 begin"); |
|
349 CWbxml2XmlConverter* c = CWbxml2XmlConverter::NewLC(); |
|
350 c->ConvertL(aStartPtr.Ptr(), aStartPtr.Length()); |
|
351 DBG_DUMP((void*)c->Document().Ptr(), c->Document().Length(), |
|
352 _S8("ReceiveDataL (XML)") ); |
|
353 CleanupStack::PopAndDestroy(); // c |
|
354 _DBG_FILE("CNsmlObexClient::ReceiveDataL: CWbxml2XmlConverter::ConvertL() end"); |
|
355 #endif // __NSML_DEBUG__ |
|
356 |
|
357 SetActive (); |
|
358 } |
|
359 //------------------------------------------------------------ |
|
360 // CNsmlObexClient::CloseCommunicationL( TRequestStatus &aStatus ) |
|
361 //------------------------------------------------------------ |
|
362 void CNsmlObexClient::CloseCommunicationL( TRequestStatus &aStatus ) |
|
363 { |
|
364 iAgentStatus = &aStatus; |
|
365 |
|
366 DisconnectL(); |
|
367 |
|
368 if( *iAgentStatus == KRequestPending ) |
|
369 { |
|
370 User::RequestComplete( iAgentStatus, KErrCancel ); |
|
371 } |
|
372 } |
|
373 //------------------------------------------------------------ |
|
374 // CNsmlObexClient::StopL() |
|
375 //------------------------------------------------------------ |
|
376 void CNsmlObexClient::StopL() |
|
377 { |
|
378 if ( iClient ) |
|
379 { |
|
380 delete iClient; |
|
381 iClient = NULL; |
|
382 } |
|
383 } |
|
384 //------------------------------------------------------------ |
|
385 // CNsmlObexClient::DisconnectL() |
|
386 //------------------------------------------------------------ |
|
387 void CNsmlObexClient::DisconnectL() |
|
388 { |
|
389 if ( iObexSearcher ) |
|
390 { |
|
391 iObexSearcher->Cancel(); |
|
392 } |
|
393 |
|
394 StopL(); |
|
395 iState = EDisconnected; |
|
396 } |
|
397 |
|
398 //------------------------------------------------------------ |
|
399 // CNsmlObexClient::IsBusy() |
|
400 //------------------------------------------------------------ |
|
401 TBool CNsmlObexClient::IsBusy() |
|
402 { |
|
403 return IsActive(); |
|
404 } |
|
405 |
|
406 //------------------------------------------------------------ |
|
407 // CNsmlObexClient::IsConnected() |
|
408 //------------------------------------------------------------ |
|
409 TBool CNsmlObexClient::IsConnected() |
|
410 { |
|
411 return iState != EDisconnected; |
|
412 } |
|
413 |
|
414 //---------------------------------------------------------------------------- |
|
415 // CNsmlObexClient::HandleDeviceFoundL() |
|
416 //---------------------------------------------------------------------------- |
|
417 // |
|
418 void CNsmlObexClient::HandleDeviceFoundL() |
|
419 { |
|
420 TRAPD( err, iObexSearcher->SearchServiceL(); ) |
|
421 |
|
422 DBG_FILE_CODE( err, _S8("CNsmlObexClient::HandleDeviceFoundL \ |
|
423 Before error conversion : ") ); |
|
424 ErrorConversion( err, err ); |
|
425 |
|
426 if ( err != KErrNone ) |
|
427 { |
|
428 TRequestStatus* status = iAgentStatus; |
|
429 User::RequestComplete( status, err ); |
|
430 } |
|
431 } |
|
432 |
|
433 //---------------------------------------------------------------------------- |
|
434 // CNsmlObexClient::HandleDeviceErrorL( TInt aErr ) |
|
435 //---------------------------------------------------------------------------- |
|
436 // |
|
437 void CNsmlObexClient::HandleDeviceErrorL( TInt aErr ) |
|
438 { |
|
439 DBG_FILE_CODE( aErr, _S8("CNsmlObexClient::HandleDeviceErrorL \ |
|
440 Before error conversion : ") ); |
|
441 ErrorConversion( aErr, aErr ); |
|
442 |
|
443 TRequestStatus* status = iAgentStatus; |
|
444 User::RequestComplete( status, aErr ); |
|
445 } |
|
446 |
|
447 //---------------------------------------------------------------------------- |
|
448 // CNsmlObexClient::HandleServiceFoundL() |
|
449 //---------------------------------------------------------------------------- |
|
450 // |
|
451 void CNsmlObexClient::HandleServiceFoundL() |
|
452 { |
|
453 TRAPD( err, |
|
454 iState = EGettingConnection; |
|
455 ConnectToServerL(); |
|
456 ) |
|
457 |
|
458 DBG_FILE_CODE( err, _S8("CNsmlObexClient::HandleServiceFoundL \ |
|
459 Before error conversion : ") ); |
|
460 ErrorConversion( err, err ); |
|
461 |
|
462 if ( err != KErrNone ) |
|
463 { |
|
464 TRequestStatus* status = iAgentStatus; |
|
465 User::RequestComplete( status, err ); |
|
466 } |
|
467 } |
|
468 |
|
469 //---------------------------------------------------------------------------- |
|
470 // CNsmlObexClient::HandleServiceErrorL( TInt aErr ) |
|
471 //---------------------------------------------------------------------------- |
|
472 // |
|
473 void CNsmlObexClient::HandleServiceErrorL( TInt aErr ) |
|
474 { |
|
475 DBG_FILE_CODE( aErr, _S8("CNsmlObexClient::HandleServiceErrorL \ |
|
476 Before error conversion : ") ); |
|
477 ErrorConversion( aErr, aErr ); |
|
478 |
|
479 TRequestStatus* status = iAgentStatus; |
|
480 User::RequestComplete( status, aErr ); |
|
481 } |
|
482 |
|
483 //---------------------------------------------------------------------------- |
|
484 // CNsmlObexClient::SetBTConnInfo( const TBTDevAddr aBTDevAddr, const TUUID aUid ) |
|
485 //---------------------------------------------------------------------------- |
|
486 // |
|
487 void CNsmlObexClient::SetBTConnInfo( const TBTDevAddr aBTDevAddr, const TUUID aUid ) |
|
488 { |
|
489 TBTConnInfo info; |
|
490 info.iDevAddr = aBTDevAddr; |
|
491 info.iServiceClass = aUid; |
|
492 |
|
493 iBTConnInfo = info; |
|
494 } |
|
495 |
|
496 //---------------------------------------------------------------------------- |
|
497 // CNsmlObexClient::SetExtObserver( MExtBTSearcherObserver* aExtObserver ) |
|
498 //---------------------------------------------------------------------------- |
|
499 // |
|
500 void CNsmlObexClient::SetExtObserver( MExtBTSearcherObserver* aExtObserver ) |
|
501 { |
|
502 iExtObserver = aExtObserver; |
|
503 } |
|
504 |
|
505 //---------------------------------------------------------------------------- |
|
506 // CNsmlObexClient::ErrorConversion( const TInt aError, TInt& aErrCode ) |
|
507 //---------------------------------------------------------------------------- |
|
508 // |
|
509 void CNsmlObexClient::ErrorConversion( const TInt aError, TInt& aErrCode ) |
|
510 { |
|
511 if ( aError > -6000 && aError <= -1 ) |
|
512 { |
|
513 aErrCode = KErrCancel; |
|
514 return; |
|
515 } |
|
516 else if ( aError > -7000 && aError <= -6000 ) |
|
517 { |
|
518 // Conversion of EPageTimedOut and ERemoteHostTimeout errors |
|
519 aErrCode = TNSmlError::ESmlCommunicationError; |
|
520 return; |
|
521 } |
|
522 |
|
523 aErrCode = aError; |
|
524 } |
|
525 |
|
526 //End of File |
|
527 |