webservices/idwsfplugin/src/idwsfdiscoveryserviceclient.cpp
changeset 0 62f9d29f7211
equal deleted inserted replaced
-1:000000000000 0:62f9d29f7211
       
     1 /*
       
     2 * Copyright (c) 2002-2005 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 
       
    21 
       
    22 
       
    23 
       
    24 
       
    25 
       
    26 #include <s32mem.h>
       
    27 
       
    28 #include <SenFacet.h>
       
    29 #include <SenServiceConnection.h>
       
    30 #include <SenXmlReader.h>
       
    31 #include <SenXmlUtils.h>
       
    32 
       
    33 #include "msencoreservicemanager.h"
       
    34 #include "sendebug.h"
       
    35 
       
    36 #include "idwsfmessage.h"  // for response parsing and request building
       
    37 #include "idwsfdsqueryresponse.h"
       
    38 #include "idwsfdiscoveryserviceclient.h"
       
    39 #include "idwsfservicesession.h"
       
    40 #include "idwsfdsqueryresponse.h"
       
    41 
       
    42 #include "senlogger.h"
       
    43 // for the parsing and the construction of outgoing DSLookups
       
    44 
       
    45 namespace
       
    46     {
       
    47     // 2004-07-21:
       
    48     _LIT8(KDiscoReqStart1,"<Query xmlns=\"urn:liberty:disco:2003-08\" >");
       
    49 
       
    50     // the resouse id element is not needed if no content is available
       
    51     _LIT8(KDiscoReqResIdStart,"<ResourceID>");
       
    52     _LIT8(KDiscoReqResIdEnd,"</ResourceID>");
       
    53 
       
    54     _LIT8(KEncrStart,"<Encrypted");
       
    55     _LIT8(KDiscoReqEncrResIdStart,"<EncryptedResourceID>");
       
    56     _LIT8(KDiscoReqEncrResIdEnd,"</EncryptedResourceID>");
       
    57 
       
    58     _LIT8(KDiscoReqStart2,"<RequestedServiceType><ServiceType>");
       
    59     _LIT8(KDiscoReqEnd2,"</ServiceType>");
       
    60     _LIT8(KDiscoOptionsStart,"<Options>");
       
    61     _LIT8(KDiscoOptionsEnd,"</Options>");
       
    62     _LIT8(KSenOption,"Option");
       
    63     _LIT8(KDiscoReqEnd, " </RequestedServiceType> </Query>");
       
    64 
       
    65     const TInt KFLATBUF_SIZE = 128;
       
    66     }
       
    67 
       
    68 
       
    69 CIdWsfDiscoveryServiceClient* CIdWsfDiscoveryServiceClient::NewL(
       
    70                                                          CSIF& aSIF)//,
       
    71                                                          //RFileLogger& aLogger)
       
    72     {
       
    73     CIdWsfDiscoveryServiceClient* pNew = NewLC(aSIF);//, aLogger);
       
    74     CleanupStack::Pop();
       
    75     return pNew;
       
    76     }
       
    77 
       
    78 CIdWsfDiscoveryServiceClient* CIdWsfDiscoveryServiceClient::NewLC(
       
    79                                                         CSIF& aSIF)//,
       
    80                                                         //RFileLogger& aLogger)
       
    81     {
       
    82     CIdWsfDiscoveryServiceClient* pNew =
       
    83         new (ELeave) CIdWsfDiscoveryServiceClient(
       
    84                         aSIF,
       
    85                         MSenServiceDescription::EIdWsfDiscoveryServiceClient);//,
       
    86                         //aLogger);
       
    87 
       
    88     CleanupStack::PushL(pNew);
       
    89     pNew->BaseConstructL();
       
    90     return pNew;
       
    91     }
       
    92 
       
    93 CIdWsfDiscoveryServiceClient::CIdWsfDiscoveryServiceClient(CSIF& aSIF,
       
    94                                                            TDescriptionClassType aType)//,
       
    95                                                            //RFileLogger& aLogger) 
       
    96     : CIdWsfCoreServiceConsumer(aSIF, aType),
       
    97     iCState(ENotInitialized),
       
    98     iSession(NULL)//,
       
    99     //iLog(aLogger)
       
   100     {
       
   101     }
       
   102 
       
   103 // returns KErrNotFound, if no matching security mechanism was found
       
   104 // in ProcessResponce() call
       
   105 // returns KErrNotReady, if no service session has been initilized
       
   106 TInt CIdWsfDiscoveryServiceClient::FindServiceL(
       
   107                     RPointerArray<CSenWSDescription>& aServiceArray,
       
   108                     MSenServiceDescription& aPattern,
       
   109                     MSenRemoteServiceConsumer& aRemoteConsumer)
       
   110     {
       
   111     CSLOG_L(aRemoteConsumer.ConnectionId(), KMinLogLevel ,"CIdWsfDiscoveryServiceClient::FindServiceL()");
       
   112 
       
   113     // keep this line first
       
   114     iServedConsumer = &aRemoteConsumer;
       
   115 
       
   116     iResults.ResetAndDestroy(); // clear array and destroy its contents
       
   117     iCState = EHasResults;
       
   118 
       
   119     HBufC8* pLookupReq = NULL;
       
   120     TPtrC8 contract = aPattern.Contract();
       
   121 
       
   122     TInt retVal(KErrNone);
       
   123     if(contract.Length()>0)
       
   124         {
       
   125         // DsLookupRequestL never returns NULL
       
   126         pLookupReq = DsLookupRequestL(aPattern);
       
   127 
       
   128         CleanupStack::PushL(pLookupReq);
       
   129 
       
   130         if(iService)
       
   131             {
       
   132             HBufC8* pResponse = NULL;
       
   133     #ifdef _SENDEBUG
       
   134             TPtr8 lookupRequest = pLookupReq->Des();
       
   135 //wslog            FILELOGALL(_L("SenCoreServiceManager"), _L("DS_lookup_req.xml"), lookupRequest);
       
   136     #endif // _SENDEBUG
       
   137 
       
   138             retVal = iService->SubmitL(*pLookupReq, KNullDesC8, *this, pResponse); 
       
   139             aRemoteConsumer.SetDataTrafficDetails(iDiscDetails);           
       
   140         
       
   141             
       
   142        
       
   143             CleanupStack::PushL(pResponse);
       
   144             if(retVal == KErrNone && pResponse)
       
   145                 {
       
   146     #ifdef _SENDEBUG
       
   147                 TPtr8 lookupResponse= pResponse->Des();
       
   148 //wslog                FILELOGALL(_L("SenCoreServiceManager"), _L("DS_lookup_rsp.xml"), lookupResponse);
       
   149     #endif // _SENDEBUG
       
   150 
       
   151                 CIdWsfDsQueryResponse* pDsQueryResponse =
       
   152                     ParseResponseLC(*pResponse); // push #3
       
   153 
       
   154                 retVal = ProcessResponseL(pDsQueryResponse);
       
   155 
       
   156                 CleanupStack::PopAndDestroy(1); // pDsQueryResponse
       
   157 
       
   158                 TInt count(iResults.Count());
       
   159                 for(TInt i=0; i<count; i++)
       
   160                     {
       
   161     #ifdef _SENDEBUG
       
   162                     if(iResults[0])
       
   163                         {
       
   164                         HBufC* pAsXml = iResults[0]->AsXmlUnicodeL();
       
   165                         if(pAsXml)
       
   166                             {
       
   167                             CleanupStack::PushL(pAsXml);
       
   168                             CSLOG_FORMAT((aRemoteConsumer.ConnectionId(), KMinLogLevel , _L8("Result (%d):"), i));
       
   169                             CSLOG_ALL(aRemoteConsumer.ConnectionId(), KMaxLogLevel ,(*pAsXml));
       
   170                             CleanupStack::PopAndDestroy(); // pAsXml
       
   171                             }
       
   172 
       
   173                         }
       
   174     #endif
       
   175                     // we now could annotate any new service (session) with
       
   176                     // relevant facets from the input ServiceDescription,
       
   177                     // but not with disco_options!
       
   178                     ((CIdWsfServiceSession*)iResults[0])->CopyFacetsFromL(
       
   179                                                                     aPattern);
       
   180                     ((CIdWsfServiceSession*)iResults[0])->SetValidator(this);
       
   181                     TInt appendRetVal = aServiceArray.Append(
       
   182                                     (CSenWSDescription*)iResults[0]);
       
   183                     if(appendRetVal!=KErrNone)
       
   184                         {
       
   185                         // out of memory, free orphan
       
   186                         delete iResults[0];
       
   187                         }
       
   188                     iResults.Remove(0);
       
   189                     }
       
   190                 }
       
   191             CleanupStack::PopAndDestroy(); // pResponse
       
   192             }
       
   193         else
       
   194             {
       
   195             retVal = KErrNotReady;
       
   196             }
       
   197         CleanupStack::PopAndDestroy(); // pLookupReq
       
   198         }
       
   199     else
       
   200         {
       
   201         retVal = KErrSenNoContract;
       
   202         }
       
   203     return retVal;
       
   204     }
       
   205 
       
   206 
       
   207 
       
   208 void CIdWsfDiscoveryServiceClient::BaseConstructL()
       
   209     {
       
   210     CIdWsfCoreServiceConsumer::BaseConstructL();
       
   211 
       
   212     TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel ,(_L("CIdWsfDiscoveryServiceClient::BaseConstructL()")));
       
   213     }
       
   214 
       
   215 TInt CIdWsfDiscoveryServiceClient::ValidateL(
       
   216                                     CIdWsfServiceSession& aSession,
       
   217                                     MSenRemoteServiceConsumer& aRemoteConsumer)
       
   218     {
       
   219     CSLOG_L(aRemoteConsumer.ConnectionId(), KMinLogLevel ,"CIdWsfDiscoveryServiceClient::ValidateL");
       
   220 
       
   221     // keep this line first
       
   222     iServedConsumer = &aRemoteConsumer;
       
   223     iSession = &aSession; // iSession == Java's stateObject !!!
       
   224 
       
   225     iCState = EHasSession;
       
   226     CSLOG_L(aRemoteConsumer.ConnectionId(), KMinLogLevel ,"- creating discovery lookup request.");
       
   227 
       
   228 
       
   229     HBufC8* pLookupReqUtf8 = DsLookupRequestL(aSession);
       
   230     CleanupStack::PushL(pLookupReqUtf8);
       
   231 
       
   232     HBufC8* pSubmitResponse = NULL; // for ref-to-ptr
       
   233 
       
   234 #ifdef _SENDEBUG
       
   235     TPtr8 lookupRequest= pLookupReqUtf8->Des();
       
   236 //wslog    FILELOGALL(_L("SenCoreServiceManager"), _L("DS_lookup_req.xml"), lookupRequest);
       
   237 #endif // _SENDEBUG
       
   238 
       
   239     TInt retVal = iService->SubmitL(*pLookupReqUtf8, KNullDesC8, *this, pSubmitResponse); 
       
   240     CleanupStack::PopAndDestroy(); // pLookupReqUtf8
       
   241 
       
   242     CleanupStack::PushL(pSubmitResponse);
       
   243 	aRemoteConsumer.SetDataTrafficDetails(iDiscDetails);	
       
   244 
       
   245     if(retVal == KErrNone && pSubmitResponse)
       
   246         {
       
   247         // submit ok
       
   248 #ifdef _SENDEBUG
       
   249         TPtr8 lookupResponse = pSubmitResponse->Des();
       
   250 //wslog        FILELOGALL(_L("SenCoreServiceManager"), _L("DS_lookup_rsp.xml"), lookupResponse);
       
   251 #endif // _SENDEBUG
       
   252         CIdWsfDsQueryResponse* theResponse = ParseResponseLC(*pSubmitResponse);
       
   253         retVal = ProcessResponseL(theResponse);
       
   254         CleanupStack::PopAndDestroy(); // theResponse
       
   255         }
       
   256 #ifdef _SENDEBUG
       
   257     else
       
   258         {
       
   259         CSLOG_L(aRemoteConsumer.ConnectionId(), KMinLogLevel ,"CIdWsfDiscoveryServiceClient::ValidateL");
       
   260         CSLOG_FORMAT((aRemoteConsumer.ConnectionId(), KMinLogLevel , _L8("- SubmitL failed: %d"), retVal));
       
   261         }
       
   262 #endif // _SENDEBUG
       
   263     CleanupStack::PopAndDestroy(); // pSubmitResponse
       
   264         
       
   265     if ((retVal == KErrNone) && iSession->IsReadyL())
       
   266         {
       
   267         CSLOG_L(aRemoteConsumer.ConnectionId(), KMinLogLevel ,"- setting this DS client as validator for ID-WFS session.");
       
   268         iSession->SetValidator(this);
       
   269         }
       
   270 
       
   271     return retVal;
       
   272     }
       
   273 
       
   274 CIdWsfDsQueryResponse* CIdWsfDiscoveryServiceClient::ParseResponseLC(
       
   275                                                             TDesC8& aMessage)
       
   276     {
       
   277     TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel ,(_L("CIdWsfDiscoveryServiceClient::ParseResponseLC")));
       
   278     TLSLOG_ALL(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel ,(aMessage));
       
   279 
       
   280     // must be first, if we promise LC in this method..
       
   281     CIdWsfDsQueryResponse* pResponse = CIdWsfDsQueryResponse::NewLC();
       
   282 
       
   283 
       
   284     pResponse->SetReader(*Framework().Manager().XMLReader());
       
   285     pResponse->ParseL(aMessage);
       
   286     return pResponse; // item resides in cleanupstack
       
   287     }
       
   288 
       
   289 // returns KErrNotFound, if no matching security mechanism was found
       
   290 TInt CIdWsfDiscoveryServiceClient::ProcessResponseL(
       
   291                                             CIdWsfDsQueryResponse* aResponse)
       
   292     {
       
   293     TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel ,(_L("CIdWsfDiscoveryServiceClient::ProcessResponseL")));
       
   294 
       
   295     TInt retVal(KErrNone);
       
   296 
       
   297     RPointerArray<CIdWsfServiceInstance> services; // 2004-08-09, bugfix
       
   298 
       
   299     CleanupClosePushL(services);
       
   300     aResponse->GetAllServicesL(services);
       
   301 
       
   302     CIdWsfServiceSession* pTempSession = NULL; // session in Java!
       
   303 
       
   304     switch(iCState)
       
   305         {
       
   306         case EHasSession:
       
   307             {
       
   308             TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel ,(_L("   State: EHasSession")));
       
   309             pTempSession = iSession; // iSession == stateObject in Java!
       
   310             if (pTempSession)
       
   311                 {
       
   312 #ifdef _SENDEBUG
       
   313                 if(pTempSession->IsReadyL())
       
   314                     {
       
   315                     TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel ,"   Current session is valid.");
       
   316                     }
       
   317                 else
       
   318                     {
       
   319                     TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel ,"   Current session is expired.");
       
   320                     }
       
   321 #endif
       
   322 
       
   323                 if (iService)
       
   324                     {
       
   325                     pTempSession->SetClientServerIntervalL(
       
   326                                                 iService->ClientServerInterval());// codescannerwarnings
       
   327                     }
       
   328 
       
   329                 TInt count(services.Count());
       
   330                 for(TInt i=0; !pTempSession->IsReadyL()
       
   331                             && i<count; i++) // not-operation bugfix, 2004-07-20
       
   332                     {
       
   333                     if(services[i])
       
   334                         {
       
   335                         retVal = pTempSession->InitializeFromL(*services[i]);
       
   336                         }
       
   337                     }
       
   338 
       
   339                 if(pTempSession->IsReadyL() && iService)
       
   340                     {
       
   341                     pTempSession->SetTrustAnchorL(iService->TrustAnchor());
       
   342                     }
       
   343                 }
       
   344             iCState = ENotInitialized;
       
   345             }
       
   346             break;
       
   347 
       
   348         case EHasResults:
       
   349             {
       
   350             TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel ,(_L("   State: EHasResults")));
       
   351             TInt count(services.Count());
       
   352             TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase   , KNormalLogLevel  ,_L("Response included %d services."),count));
       
   353             for (TInt i=0; i<count; i++)
       
   354                 {
       
   355                 TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase   , KNormalLogLevel  ,_L("Trying to initialize service number %d "),i));
       
   356                 pTempSession =
       
   357                     (CIdWsfServiceSession*)Framework().NewServiceDescriptionL();
       
   358                 CleanupStack::PushL(pTempSession);
       
   359 
       
   360                 if (iService)
       
   361                     {
       
   362                     pTempSession->SetClientServerIntervalL(
       
   363                                             iService->ClientServerInterval());	//codescannerwarnings
       
   364                     }
       
   365 
       
   366                 for(TInt j=i; j<count && !pTempSession->IsReadyL(); j++)
       
   367                     {
       
   368                     retVal = pTempSession->InitializeFromL(*services[j]);
       
   369                     if(!pTempSession->IsReadyL())
       
   370                         {
       
   371                         i++;
       
   372                         }
       
   373                     }
       
   374                 
       
   375 
       
   376                 if(pTempSession->IsReadyL())
       
   377                     {
       
   378                     if(iService)
       
   379                         {
       
   380                         pTempSession->SetTrustAnchorL(iService->TrustAnchor());
       
   381                         }
       
   382                     TInt appendRetVal = iResults.Append(pTempSession); // only ready ones goto list
       
   383                     if(appendRetVal == KErrNone)
       
   384                         {
       
   385                         CleanupStack::Pop(); //pTempSession
       
   386                         }
       
   387                     else
       
   388                         {
       
   389                         CleanupStack::PopAndDestroy(); // pTempSession
       
   390                         }
       
   391                     }
       
   392                 else
       
   393                     {
       
   394                     // No ready Session found
       
   395                     CleanupStack::PopAndDestroy(); //pTempSession
       
   396                     }
       
   397                 }
       
   398             }
       
   399             break;
       
   400 
       
   401         default:
       
   402             // do nothing
       
   403             break;
       
   404         }
       
   405 
       
   406     CleanupStack::PopAndDestroy(); // close services, // 2004-08-09, bugfix
       
   407     return retVal;
       
   408     }
       
   409 
       
   410 void CIdWsfDiscoveryServiceClient::SetStatusL(const TInt /* aStatus */ )
       
   411     {
       
   412     }
       
   413 
       
   414 
       
   415 
       
   416 CIdWsfDiscoveryServiceClient::~CIdWsfDiscoveryServiceClient()
       
   417     {
       
   418     iResults.ResetAndDestroy();
       
   419     }
       
   420 
       
   421 
       
   422 // overrides the internalserviceconsumer.log() function
       
   423 // to enable using the log delivered as constructor arg.
       
   424 /*RFileLogger* CIdWsfDiscoveryServiceClient::Log() const
       
   425     {
       
   426     return (RFileLogger*) &iLog;
       
   427     }
       
   428 */
       
   429 
       
   430 
       
   431 HBufC8* CIdWsfDiscoveryServiceClient::DsLookupRequestL(
       
   432                                             MSenServiceDescription& aPattern)
       
   433     {
       
   434     TLSLOG(KSenCoreServiceManagerLogChannelBase  , KNormalLogLevel ,(_L("CIdWsfDiscoveryServiceClient::DsLookupRequestL")));
       
   435 
       
   436     RFacetArray options;
       
   437     CleanupClosePushL(options);
       
   438 
       
   439     CIdWsfDiscoveryServiceClient::DSOptionsL(options, aPattern);
       
   440 
       
   441     CBufFlat* pFlat = CBufFlat::NewL(KFLATBUF_SIZE);
       
   442     CleanupStack::PushL(pFlat);
       
   443 
       
   444     RBufWriteStream ws;
       
   445     ws.Open(*pFlat);
       
   446     CleanupClosePushL(ws);
       
   447 
       
   448     // create the disco lookup query and fill it with the passed service type
       
   449     ws.WriteL(KDiscoReqStart1);
       
   450     TPtrC8 resourceId = iService->ResourceId();
       
   451     if(resourceId.Length()>0)
       
   452         {
       
   453         if(resourceId.Find(KEncrStart) == 0)
       
   454             {
       
   455             ws.WriteL(KDiscoReqEncrResIdStart);
       
   456             ws.WriteL(resourceId);
       
   457             ws.WriteL(KDiscoReqEncrResIdEnd);
       
   458             }
       
   459         else
       
   460             {
       
   461             ws.WriteL(KDiscoReqResIdStart);
       
   462             ws.WriteL(resourceId);
       
   463             ws.WriteL(KDiscoReqResIdEnd);
       
   464             }
       
   465         }
       
   466     ws.WriteL(KDiscoReqStart2);
       
   467     ws.WriteL(aPattern.Contract());
       
   468     ws.WriteL(KDiscoReqEnd2);
       
   469 
       
   470     if (options.Count())
       
   471         {
       
   472         ws.WriteL(KDiscoOptionsStart);
       
   473 
       
   474         CSenXmlElement* pOption = NULL; 
       
   475         HBufC8* pOptionAsXml = NULL;
       
   476 
       
   477         TInt count(options.Count());
       
   478         for (TInt i=0; i<count; i++)
       
   479             {
       
   480             pOption = CSenXmlElement::NewL(KSenOption); 
       
   481             CleanupStack::PushL(pOption);
       
   482             pOption->CopyFromL(*options[i]);
       
   483             pOptionAsXml = pOption->AsXmlL();
       
   484             CleanupStack::PushL(pOptionAsXml);
       
   485             ws.WriteL(*pOptionAsXml);
       
   486             CleanupStack::PopAndDestroy(2); // pOptionAsXml, pOption
       
   487             }
       
   488         ws.WriteL(KDiscoOptionsEnd);
       
   489         }
       
   490 
       
   491     ws.WriteL(KDiscoReqEnd);
       
   492 
       
   493     CleanupStack::PopAndDestroy(); // ws.Close();
       
   494 
       
   495     TPtr8 p8 = pFlat->Ptr(0);
       
   496     HBufC8* pReq8 = p8.AllocL();
       
   497     CleanupStack::PopAndDestroy( pFlat );
       
   498     
       
   499 #ifdef _SENDEBUG   
       
   500     CleanupStack::PushL( pReq8 );
       
   501     if( pReq8 )
       
   502         {
       
   503         TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel ,(_L8("Returning Discovery Service Lookup Request:")));
       
   504         TLSLOG_ALL(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel ,(*pReq8));
       
   505         
       
   506         }
       
   507     CleanupStack::Pop( pReq8 ); // pReq8 == return value
       
   508 #endif // _SENDEBUG        
       
   509     options.ResetAndDestroy();
       
   510     CleanupStack::Pop(); // options
       
   511     return pReq8;
       
   512     }
       
   513 
       
   514 TInt CIdWsfDiscoveryServiceClient::DSOptionsL(
       
   515                                 RFacetArray& aOptionArray,
       
   516                                 MSenServiceDescription& aServiceDescription)
       
   517     {
       
   518     TInt retVal = KErrNone;
       
   519 
       
   520     RFacetArray facets;
       
   521     CleanupClosePushL(facets);
       
   522     aServiceDescription.FacetsL(facets);
       
   523 
       
   524     CSenFacet* pFacet = NULL;
       
   525     TInt count(facets.Count());
       
   526     for (TInt i=0; i<count && retVal == KErrNone; i++)
       
   527         {
       
   528         if (facets[i]->Type() == KDiscoOption)
       
   529             {
       
   530             pFacet = CSenFacet::NewL(*facets[i]);
       
   531             retVal = aOptionArray.Append(pFacet);
       
   532             }
       
   533         }
       
   534     facets.ResetAndDestroy();
       
   535     CleanupStack::Pop(); //facets
       
   536 
       
   537     return retVal;
       
   538     }
       
   539 
       
   540 
       
   541 
       
   542 
       
   543 TBool CIdWsfDiscoveryServiceClient::HasSuperClass( TDescriptionClassType aType )
       
   544     {
       
   545    if( aType == MSenServiceDescription::ECoreServiceConsumer ) // direct superclass!    
       
   546         {
       
   547         // If asked type is the know *direct* father/mother, return true:
       
   548         return ETrue; 
       
   549         } 
       
   550     else
       
   551         {
       
   552         // Otherwise, ask from superclass (chain, recursively)
       
   553         return CIdWsfCoreServiceConsumer::HasSuperClass( aType ); 
       
   554         }
       
   555     }
       
   556 
       
   557 void CIdWsfDiscoveryServiceClient::SetDataTrafficDetails( TSenDataTrafficDetails& aDetails) 
       
   558 	{
       
   559 	iDiscDetails = aDetails;
       
   560 	}
       
   561 // End of File
       
   562