ImagePrint/ImagePrintEngine/DeviceProtocols/btprotocol/src/cbtdiscover.cpp
changeset 0 d11fb78c4374
equal deleted inserted replaced
-1:000000000000 0:d11fb78c4374
       
     1 /*
       
     2 * Copyright (c) 2004-2007 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:  Contains the CBtDiscover class definition. Bluetooth device discovery and SDP.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "cbtdiscover.h"
       
    20 #include "clog.h"
       
    21 
       
    22 //////////////////////////////////////////////////////////////////////
       
    23 // Construction/Destruction
       
    24 //////////////////////////////////////////////////////////////////////
       
    25 
       
    26 /**
       
    27  * @brief Instantiate new CBtDiscover object.
       
    28  */
       
    29 CBtDiscover* CBtDiscover::NewL()
       
    30 	{
       
    31 	CBtDiscover* self = new (ELeave) CBtDiscover();
       
    32 	CleanupStack::PushL(self);
       
    33 	self->ConstructL();
       
    34 	CleanupStack::Pop(); // self
       
    35 	return self;
       
    36 	}
       
    37 
       
    38 
       
    39 /**
       
    40  * @brief Two phase construction.
       
    41  */
       
    42 void CBtDiscover::ConstructL()
       
    43 	{
       
    44 	iSdpSearchPattern = CSdpSearchPattern::NewL();
       
    45 	iMatchList = CSdpAttrIdMatchList::NewL();
       
    46 	}
       
    47 
       
    48 /**
       
    49  * @brief Constructor.
       
    50  */
       
    51 CBtDiscover::CBtDiscover() :
       
    52 	iCurrentSDPAttrID(0),
       
    53 	iCurrentServiceUUID(0),
       
    54 	iFoundSTS(EFalse),
       
    55 	iWantedService(ETrue),
       
    56 	iDoingSDP(EFalse),
       
    57 	iFindingDevices(EFalse),
       
    58 	iAgent(NULL),
       
    59 	iRequestStatus(NULL),
       
    60 	iSdpSearchPattern(NULL),
       
    61 	iMatchList(NULL),
       
    62 	iContentTypes(NULL),
       
    63 	iPrinterModel(NULL),
       
    64 	iBPPPort(0),
       
    65 	iSTSPort(0),
       
    66 	iOPPPort(0)
       
    67 	{
       
    68 	}
       
    69 
       
    70 /**
       
    71  * @brief Destructor.
       
    72  */
       
    73 CBtDiscover::~CBtDiscover()
       
    74 	{
       
    75 	LOG("CBtDiscover::~CBtDiscover begin");
       
    76 	Stop();
       
    77 	if(iSdpSearchPattern)
       
    78 		delete iSdpSearchPattern;
       
    79 	if(iMatchList)
       
    80 		delete iMatchList;
       
    81 	if(iContentTypes)
       
    82 		delete iContentTypes;
       
    83 	if(iPrinterModel)
       
    84 		delete iPrinterModel;
       
    85 	if(iAgent)
       
    86 		delete iAgent;
       
    87 	LOG("CBtDiscover::~CBtDiscover end");
       
    88 	}
       
    89 
       
    90 /**
       
    91  * @brief Destructor.
       
    92  */
       
    93 void CBtDiscover::Reset()
       
    94 	{
       
    95 	LOG("CBtDiscover::Reset begin");
       
    96 
       
    97 	StopSDP(); // resets also public member variables and iDoingSDP flag
       
    98 
       
    99 	iBPPPort = 0;
       
   100 	iSTSPort = 0;
       
   101 	iOPPPort = 0;
       
   102 
       
   103 	if(iPrinterModel)
       
   104 		delete iPrinterModel;
       
   105 	iPrinterModel = NULL;
       
   106 
       
   107 	if(iSdpSearchPattern)
       
   108 		iSdpSearchPattern->Reset();
       
   109 	
       
   110 	// No can do if remove fails -> ignore leave
       
   111 	if(iMatchList)
       
   112 		TRAP_IGNORE( iMatchList->RemoveL(TAttrRange(0x0000, 0xFFFF)) );
       
   113 	
       
   114 	if(iContentTypes)
       
   115 		delete iContentTypes;
       
   116 	iContentTypes = NULL;
       
   117 	
       
   118 
       
   119 	if( iRequestStatus )
       
   120 	{
       
   121 		if(KRequestPending == iRequestStatus->Int())
       
   122 			User::RequestComplete(iRequestStatus, KErrNone);
       
   123 	}
       
   124 	iRequestStatus = NULL;
       
   125 
       
   126 	LOG("CBtDiscover::Reset end");
       
   127 	}
       
   128 
       
   129 /**
       
   130   * @brief Starts the asynchronous search for Bluetooth devices.
       
   131   *
       
   132   * Starts the asynchronous search for Bluetooth devices. The Active Object containing
       
   133   * this object, CRsBtDiscoverEngine, is notified after the first device is found.
       
   134   * @param aStatus Status variable from CRsBtDiscoverEngine, receives notification when asynchronous call completes.
       
   135   */
       
   136 void CBtDiscover::Start(TRequestStatus &aStatus)
       
   137 	{
       
   138 	LOG("[CBtDiscover::Start]\t begin");
       
   139 	aStatus = KErrNotSupported;
       
   140 
       
   141 	TInt err = iSocketServ.Connect();
       
   142 	LOG1("[CBtDiscover::Start]\t iSocketServ.Connect() err: %d", err);
       
   143 	if( KErrNone == err )
       
   144 	{
       
   145 		err = iHostResolver.Open( iSocketServ, KBTAddrFamily, KBTLinkManager );
       
   146 		LOG1("[CBtDiscover::Start]\t iHostResolver.Open() err: %d", err);
       
   147 	}
       
   148 
       
   149 	if( KErrNone == err )
       
   150 	{
       
   151 		iFindingDevices = ETrue;
       
   152 		iSockAddr.SetIAC( KGIAC );
       
   153 		iSockAddr.SetAction( KHostResInquiry | KHostResName | KHostResIgnoreCache );
       
   154 		iHostResolver.GetByAddress( iSockAddr, iNameEntry, aStatus );
       
   155 	}
       
   156 	else
       
   157 	{
       
   158 		iFindingDevices = EFalse;
       
   159 		iSocketServ.Close();
       
   160 		iHostResolver.Close();
       
   161 	}
       
   162 
       
   163 	LOG("[CBtDiscover::Start]\t end");
       
   164 	}
       
   165 
       
   166 /**
       
   167   * @brief Continues the asynchronous search for Bluetooth devices.
       
   168   *
       
   169   * Continues the asynchronous search for Bluetooth devices. The Active Object containing
       
   170   * this object, CRsBtDiscoverEngine, is notified after the next device is found.
       
   171   * @param aStatus Status variable from CRsBtDiscoverEngine, receives notification when asynchronous call completes.
       
   172   */
       
   173 void CBtDiscover::GetNextDevice(TRequestStatus &aStatus)
       
   174 	{
       
   175 	LOG("[CBtDiscover::GetNextDevice]\t");
       
   176 	iHostResolver.Next(iNameEntry, aStatus);
       
   177 	}
       
   178 
       
   179 /**
       
   180   * @brief Stop the asynchronous search for Bluetooth devices.
       
   181   */
       
   182 void CBtDiscover::Stop()
       
   183 	{
       
   184 	LOG1("[CBtDiscover::Stop]\t begin with iFindingDevices: %d", iFindingDevices);
       
   185 
       
   186 	if(iFindingDevices)
       
   187 		iHostResolver.Cancel();
       
   188 	iFindingDevices = EFalse;
       
   189 
       
   190 	Reset();
       
   191 
       
   192 	iHostResolver.Close();
       
   193 	iSocketServ.Close();
       
   194 
       
   195 	LOG("[CBtDiscover::Stop]\t end");
       
   196 	}
       
   197 
       
   198 /**
       
   199   * @brief Is an asynchronous search for Bluetooth devices in progress?
       
   200   * @return True, a search is in progress, or False, no search is in progress
       
   201   */
       
   202 TBool CBtDiscover::IsFindingDevices() const
       
   203 	{
       
   204 	return iFindingDevices;
       
   205 	}
       
   206 
       
   207 /**
       
   208   * @brief Get the last Bluetooth device found by the search.
       
   209   * @return The last Bluetooth device found by the search.
       
   210   */
       
   211 TNameRecord CBtDiscover::GetNameRecord() const
       
   212 	{
       
   213 	return iNameEntry();
       
   214 	}
       
   215 
       
   216 /**
       
   217   * @brief Store Bluetooth device information, in preparation for doing an SDP query.
       
   218   */
       
   219 void CBtDiscover::SetNameRecord(TNameRecord aNameRecord)
       
   220 	{
       
   221 	TNameEntry nameEntry(aNameRecord);
       
   222 	iNameEntry = nameEntry;
       
   223 	}
       
   224 
       
   225 /**
       
   226   * @brief Starts the asynchronous request for the SDP record.
       
   227   *
       
   228   * Starts the asynchronous request for the SDP record from a Bluetooth device.
       
   229   * Specifically the device is tested for the BPP and OPP services.
       
   230   * @param aStatus Status variable from CRsBtDiscoverEngine, receives notification when asynchronous call completes.
       
   231   * @param aServiceMask Bitmask to require (only) certain services. All marked by default.
       
   232   */
       
   233 void CBtDiscover::GetSupportedServicesL(TRequestStatus &aStatus, TUint32 aServiceMask)
       
   234 	{
       
   235 	LOG("[CBtDiscover::GetSupportedServicesL]\t begin");
       
   236 
       
   237 	Reset();
       
   238 	iRequestStatus = &aStatus;
       
   239 	*iRequestStatus = KRequestPending;	
       
   240 
       
   241 	iMatchList->RemoveL(TAttrRange(0x0000, 0xFFFF));
       
   242 	iMatchList->AddL(TAttrRange(KSdpAttrIdServiceClassIDList));
       
   243 	iMatchList->AddL(TAttrRange(KSdpAttrIdProtocolDescriptorList));
       
   244 	iMatchList->AddL(TAttrRange(KSdpAttrIdAdditionalProtocolDescriptorLists));
       
   245 	iMatchList->AddL(TAttrRange(KSdpAttrIdDocFormatsSupported));
       
   246 	iMatchList->AddL(TAttrRange(KSdpAttrIdModelID));
       
   247 	iMatchList->AddL(TAttrRange(KSdpAttrIdMaxWidth));
       
   248 	iMatchList->AddL(TAttrRange(KSdpAttrIdMaxLen));
       
   249 
       
   250 	iSdpSearchPattern->Reset();
       
   251 
       
   252 	if(KBtMaskObjectPush & aServiceMask)
       
   253 		iSdpSearchPattern->AddL(KBTSDPOBEXObjectPush); // 0x1105
       
   254 	if(KBtMaskDirectPrinting & aServiceMask)
       
   255 		iSdpSearchPattern->AddL(KBTSDPDirectPrinting); // 0x1118
       
   256 	if(KBtMaskPrintingStatus & aServiceMask)
       
   257 		iSdpSearchPattern->AddL(KBTSDPPrintingStatus); // 0x1123
       
   258 	if(KBtMaskL2CAP & aServiceMask)
       
   259 		iSdpSearchPattern->AddL(KBTSDPL2CAP);
       
   260 	if(KBtMaskRFCOMM & aServiceMask)
       
   261 		iSdpSearchPattern->AddL(KBTSDPRFCOMM);
       
   262 	if(KBtMaskObex & aServiceMask)
       
   263 		iSdpSearchPattern->AddL(KBTSDPObex);
       
   264 
       
   265 	StartSDPL();
       
   266 
       
   267 	LOG("[CBtDiscover::GetSupportedServicesL]\t end");
       
   268 	}
       
   269 
       
   270 /**
       
   271   * @brief Initiate the SDP request started in VerifyServiceSupportL.
       
   272   */
       
   273 void CBtDiscover::StartSDPL()
       
   274 	{
       
   275 	StopSDP();
       
   276 	TBTDevAddr btAddr = ((TInquirySockAddr)iNameEntry().iAddr).BTAddr();
       
   277 	iAgent = CSdpAgent::NewL(*this, btAddr);
       
   278 	iAgent->SetRecordFilterL(*iSdpSearchPattern);
       
   279 	iAgent->SetAttributePredictorListL(*iMatchList);
       
   280 	iAgent->NextRecordRequestL();
       
   281 	iDoingSDP = ETrue;
       
   282 	}
       
   283 
       
   284 /**
       
   285   * @brief Stop the asynchronous request for the SDP record from a Bluetooth device.
       
   286   */
       
   287 void CBtDiscover::StopSDP()
       
   288 	{
       
   289 	LOG1("[CBtDiscover::StopSDP] begin with iAgent address: %d", TInt(iAgent));
       
   290 	iDoingSDP = EFalse;
       
   291 
       
   292 	iCurrentSDPAttrID = 0;
       
   293     iCurrentServiceUUID = 0;
       
   294 	iFoundSTS = EFalse;
       
   295 	iWantedService = ETrue;
       
   296 
       
   297 	if( iAgent )
       
   298 		{
       
   299 		iAgent->Cancel();
       
   300 		delete iAgent;
       
   301 		iAgent = NULL;
       
   302 		}
       
   303 	LOG("[CBtDiscover::StopSDP] end");
       
   304 	}
       
   305 
       
   306 /**
       
   307   * @brief Is an asynchronous request for the SDP record in progress?.
       
   308   *
       
   309   * Is an asynchronous request for the SDP record from a Bluetooth device in progress?
       
   310   * @return True, a request is in progress, or False, no request is in progress
       
   311   */
       
   312 TBool CBtDiscover::IsDoingSDP() const
       
   313 	{
       
   314 	return iDoingSDP;
       
   315 	}
       
   316 
       
   317 /**
       
   318   * The CSdpAgent object calls this to notify that the attributes from an SDP record are ready for parsing.
       
   319   * @param aAttrValue Structured attribute(s) of SDP record, parsed with TBTAttribValVisitor
       
   320   */
       
   321 void CBtDiscover::AttributeRequestResult(TSdpServRecordHandle /*aHandle*/, TSdpAttributeID aAttrID, CSdpAttrValue *aAttrValue)
       
   322 	{
       
   323 	TRAPD( err, AttributeRequestResultL( aAttrID, aAttrValue ) );
       
   324 	if(KErrNone != err)
       
   325 		LOG1("[CBtDiscover::AttributeRequestResult]\t AttributeRequestResultL leaves with: %d", err);
       
   326 	}
       
   327 
       
   328 void CBtDiscover::AttributeRequestResultL( TSdpAttributeID aAttrID, CSdpAttrValue* aValue )
       
   329 	{
       
   330 	LOG1("[CBtDiscover::AttributeRequestResultL]\t *** Device: %S: ", &GetDeviceName() );
       
   331 	LOG2("CBtDiscover::AttributeRequestResultL aAttrID: %d, aValue->Type(): %d", aAttrID, aValue->Type());
       
   332 
       
   333 	iCurrentSDPAttrID = aAttrID;
       
   334 	CBTAttribValVisitor* valVisitor = NULL;
       
   335 
       
   336 	switch( aAttrID )
       
   337 		{
       
   338 		case KSdpAttrIdServiceClassIDList:
       
   339 			iCurrentServiceUUID = 0; // reset
       
   340 		case KSdpAttrIdProtocolDescriptorList:
       
   341 		case KSdpAttrIdAdditionalProtocolDescriptorLists:
       
   342 		case KSdpAttrIdDocFormatsSupported:
       
   343 		case KSdpAttrIdModelID:
       
   344 		case KSdpAttrIdMaxWidth:
       
   345 		case KSdpAttrIdMaxLen:
       
   346 			valVisitor = CBTAttribValVisitor::NewLC( *this );
       
   347 			aValue->AcceptVisitorL( *valVisitor ); // goes in CBTAttribValVisitor::VisitAttributeValueL 
       
   348 			CleanupStack::PopAndDestroy( valVisitor );
       
   349 			break;
       
   350 		default:
       
   351 			break;
       
   352 		}
       
   353 
       
   354 	delete aValue;
       
   355 
       
   356 	LOG("CBtDiscover::AttributeRequestResultL end");
       
   357 	}
       
   358 
       
   359 
       
   360 /**
       
   361   * The CSdpAgent object calls this to notify that the SDP record request has been completed.
       
   362   */
       
   363 void CBtDiscover::NextRecordRequestComplete(TInt aError, TSdpServRecordHandle aHandle, TInt aTotalRecordsCount)
       
   364 	{
       
   365 	LOG1("CBtDiscover::NextRecordRequestComplete aError: %d", aError);
       
   366 	LOG1("CBtDiscover::NextRecordRequestComplete aHandle: %d", aHandle);
       
   367 	LOG1("CBtDiscover::NextRecordRequestComplete aTotalRecordsCount: %d", aTotalRecordsCount);
       
   368 	TInt err( aError );
       
   369 
       
   370 	if( KErrNone == aError  && aTotalRecordsCount > 0)
       
   371 	{
       
   372 		TRAP( err, iAgent->AttributeRequestL( aHandle, KSdpAttrIdServiceClassIDList ) );
       
   373 		LOG1("CBtDiscover::NextRecordRequestComplete err: %d", err);
       
   374 	}
       
   375 
       
   376 	if( KErrNone != err || !aTotalRecordsCount )
       
   377 	{
       
   378 		if( KErrEof == err || !aTotalRecordsCount )
       
   379 		{
       
   380 			err = KErrNone;
       
   381 		}
       
   382 		StopSDP();
       
   383 		LOG("CBtDiscover::NextRecordRequestComplete User::RequestComplete");
       
   384 		User::RequestComplete( iRequestStatus, err );	
       
   385 	}
       
   386 
       
   387 	// reset
       
   388 	iCurrentServiceUUID = 0; 
       
   389 	iWantedService = ETrue;
       
   390 	iCurrentSDPAttrID = 0;
       
   391 	LOG("CBtDiscover::NextRecordRequestComplete end");
       
   392 	}
       
   393 
       
   394 /**
       
   395   * The CSdpAgent object calls this to notify that the current SDP record has no more attributes.
       
   396   * @param aError Standard Symbian error code, KErrNone indicates success.
       
   397   */
       
   398 void CBtDiscover::AttributeRequestComplete(TSdpServRecordHandle aHandle, TInt aError)
       
   399 {
       
   400 	LOG("[CBtDiscover::AttributeRequestComplete]\t Begin.");
       
   401 	if( KErrNone != aError || !iWantedService || 0 == iCurrentSDPAttrID)
       
   402 	{
       
   403 		LOG1("[CBtDiscover::AttributeRequestComplete]\t err: %d", aError);
       
   404 		iCurrentSDPAttrID = 0;
       
   405 		LOG("[CBtDiscover::AttributeRequestComplete]\t Not wanted service. Get next record.");
       
   406 		TRAPD( err, iAgent->NextRecordRequestL() );
       
   407 		if(KErrNone != err)
       
   408 		{
       
   409 			NextRecordRequestComplete(err, aHandle, 0);
       
   410 		}
       
   411 	}
       
   412 	else
       
   413 	{
       
   414 		LOG("[CBtDiscover::AttributeRequestComplete]\t Wanted service. Get next attribute.");
       
   415 		TRAPD( err, GetNextAttributeL(aHandle) );
       
   416 		if( KErrNone != err )
       
   417 			LOG1("[CBtDiscover::AttributeRequestComplete]\t err: %d", err);
       
   418 	}
       
   419 	iCurrentSDPAttrID = 0;
       
   420 	LOG("[CBtDiscover::AttributeRequestComplete]\t End.");
       
   421 }
       
   422 
       
   423 /**
       
   424   * @brief Get BPP port.
       
   425   * @return Port (i.e. Bluetooth channel) of the BPP service on the printer. Returns -1 if port is unknown.
       
   426   */
       
   427 TInt CBtDiscover::GetBPPPort() const
       
   428 	{
       
   429 	return iBPPPort;
       
   430 	}
       
   431 
       
   432 /**
       
   433   * @brief Get Status port.
       
   434   * @return Port (i.e. Bluetooth channel) of the status service on the printer. Returns -1 if port is unknown.
       
   435   */
       
   436 TInt CBtDiscover::GetSTSPort() const
       
   437 	{
       
   438 	return iSTSPort;
       
   439 	}
       
   440 
       
   441 /**
       
   442   * @brief Get OPP port.
       
   443   * @return Port (i.e. Bluetooth channel) of the OPP service on the printer. Returns -1 if port is unknown.
       
   444   */
       
   445 TInt CBtDiscover::GetOPPPort() const
       
   446 	{
       
   447 	return iOPPPort;
       
   448 	}
       
   449 
       
   450 /**
       
   451   * @brief Set the BPP Port.
       
   452   *
       
   453   * Called from TBTAttribValVisitor to set the Port (i.e. Bluetooth channel).
       
   454   * Also used to indicate that the BPP service was successfully detected in the SDP response.
       
   455   */
       
   456 void CBtDiscover::SetBPPPort(TInt aPort)
       
   457 	{
       
   458 	LOG1("CBtDiscover::SetBPPPort aPort: %d", aPort);
       
   459 	iBPPPort = aPort;
       
   460 	}
       
   461 
       
   462 /**
       
   463   * @brief Set the Status Port.
       
   464   *
       
   465   * Called from TBTAttribValVisitor to set the Port (i.e. Bluetooth channel).
       
   466   * Also used to indicate that the Status service was successfully detected in the SDP response.
       
   467   */
       
   468 void CBtDiscover::SetSTSPort(TInt aPort)
       
   469 	{
       
   470 	LOG1("CBtDiscover::SetSTSPort aPort: %d", aPort);
       
   471 	iSTSPort = aPort;
       
   472 	}
       
   473 /**
       
   474   * @brief Set the OPP Port.
       
   475   *
       
   476   * Called from TBTAttribValVisitor to set the Port (i.e. Bluetooth channel).
       
   477   * Also used to indicate that the OPP service was successfully detected in the SDP response.
       
   478   */
       
   479 void CBtDiscover::SetOPPPort(TInt aPort)
       
   480 	{
       
   481 	LOG1("CBtDiscover::SetOPPPort aPort: %d", aPort);
       
   482 	iOPPPort = aPort;
       
   483 	}
       
   484 
       
   485 /**
       
   486   * @brief Bluetooth device supports BPP?.
       
   487   *
       
   488   * Does the SDP response for the current Bluetooth device indicate that BPP is supported?
       
   489   * Checks to make sure that a Port (i.e. Bluetooth channel) for the BPP service was determined,
       
   490   * AND that the device supports the Mime/Multiplex document type.
       
   491   * @return True, BPP is supported, or False, BPP is not supported
       
   492   */
       
   493 TBool CBtDiscover::IsBPPSupported() const
       
   494 	{
       
   495 	_LIT(KMimeXhtmlType, "application/vnd.pwg-xhtml-print+xml");
       
   496 	_LIT(KMimeMultiplexType, "application/vnd.pwg-multiplexed");
       
   497 	LOG1("CBtDiscover::IsBPPSupported iBPPPort: %d", iBPPPort);
       
   498 	return ( iBPPPort && (SupportsContentType( KMimeMultiplexType ) || SupportsContentType( KMimeXhtmlType )) );
       
   499 	}
       
   500 
       
   501 /**
       
   502   * @brief Bluetooth device supports OPP?.
       
   503   *
       
   504   * Does the SDP response for the current Bluetooth device indicate that OPP is supported?
       
   505   * @return True if OPP is supported. False if OPP is not supported.
       
   506   */
       
   507 TBool CBtDiscover::IsOPPSupported() const
       
   508 	{
       
   509 	LOG1("CBtDiscover::IsOPPSupported iOPPPort: %d", iOPPPort);
       
   510 	if(iOPPPort)
       
   511 		return ETrue;
       
   512 	else
       
   513 		return iOPPPort;
       
   514 	}
       
   515 
       
   516 /**
       
   517   * @brief Obtain Bluetooth device class.
       
   518   *
       
   519   * @return Bluetooth device class. Used by CRsBtDiscoverEngine to do the first check
       
   520   * whether the current Bluetooth device is likely to support BPP or OPP.
       
   521   * @sa KBTMinDevClassPrinter
       
   522   */
       
   523 TBTDeviceClass CBtDiscover::GetDeviceClass() const
       
   524 	{
       
   525 	TInquirySockAddr sockAddr = (TInquirySockAddr)iNameEntry().iAddr;
       
   526 	TBTDeviceClass devClass(sockAddr.MajorServiceClass(),
       
   527 		sockAddr.MajorClassOfDevice(),
       
   528 		sockAddr.MinorClassOfDevice());
       
   529 
       
   530 	return devClass;
       
   531 	}
       
   532 
       
   533 /**
       
   534   * @brief Obtain Bluetooth device name.
       
   535   *
       
   536   * @return Friendly name of current Bluetooth device.
       
   537   */
       
   538 const TDesC& CBtDiscover::GetDeviceName() const
       
   539 	{
       
   540 	return iNameEntry().iName;
       
   541 	}
       
   542 
       
   543 /**
       
   544   * @brief Sets supported content types.
       
   545   *
       
   546   * Called from TBTAttribValVisitor to set the supported content types.
       
   547   * @param aString String of comma separated mime-types.
       
   548   */
       
   549 void CBtDiscover::SetContentTypesL(const TPtrC8 &aString)
       
   550 	{
       
   551 #ifdef _DEBUG
       
   552 
       
   553 	LOG1("CBtDiscover::SetContentTypesL %d", aString.Length());
       
   554 	
       
   555 	TInt start = 0;
       
   556 	TInt end = aString.Locate(',');
       
   557 	TPtrC8 ptr;
       
   558 	while(end > 0 && start <= aString.Length())
       
   559 	{
       
   560 		ptr.Set(aString.Mid(start, end));
       
   561 		LOG81("[CBtDiscover::SetContentTypesL]\t ptr: \"%S\"", &ptr);
       
   562 		++end;
       
   563 		start += end;
       
   564 		if(start > aString.Length())
       
   565 			break;
       
   566 		
       
   567 		TPtrC8 left = aString.Mid(start);
       
   568 		end = left.Locate(',');
       
   569 		if(KErrNotFound == end)
       
   570 			end = aString.Length() - start;
       
   571 	}
       
   572 
       
   573 #endif
       
   574 	delete iContentTypes;
       
   575 	iContentTypes = NULL;
       
   576 	iContentTypes = HBufC::NewL(aString.Length());
       
   577 	TPtr bufPtr(iContentTypes->Des());
       
   578 	bufPtr.Copy(aString);
       
   579 	}
       
   580 
       
   581 /**
       
   582   * @brief Ask if device supports a content type.
       
   583   *
       
   584   * Searches the string of supported content types found in the SDP record of the current Bluetooth device.
       
   585   *
       
   586   * @param aContType Mime-type to search for.
       
   587   *
       
   588   * @return True, if the passed in content type was found, False, if it was not found
       
   589   */
       
   590 TBool CBtDiscover::SupportsContentType(const TDesC &aContType) const
       
   591 	{
       
   592 	LOG1("CBtDiscover::SupportsContentType aContType: %S", &aContType);
       
   593 	TPtr bufPtr(iContentTypes->Des());
       
   594 
       
   595 	if( bufPtr.Length() == 0 )
       
   596 		{
       
   597 		LOG("CBtDiscover::SupportsContentType length == 0");
       
   598 		return EFalse;
       
   599 		}
       
   600 
       
   601 	if( bufPtr.Find(aContType) == KErrNotFound )
       
   602 		{
       
   603 		LOG("CBtDiscover::SupportsContentType Find == KErrNotFound");
       
   604 		return EFalse;
       
   605 		}
       
   606 	else
       
   607 		{
       
   608 		LOG("CBtDiscover::SupportsContentType Found");
       
   609 		return ETrue;
       
   610 		}
       
   611 	}
       
   612 
       
   613 /**
       
   614   * @brief Called from TBTAttribValVisitor to set the printer model.
       
   615   * @param aString String of semi-colon separated printer details.
       
   616   */
       
   617 void CBtDiscover::SetPrinterModelL(const TPtrC8 &aString)
       
   618 	{
       
   619 	LOG81("CBtDiscover::SetPrinterModelL aString: %S", &aString);
       
   620 
       
   621 	if(iPrinterModel)
       
   622 		delete iPrinterModel;
       
   623 	iPrinterModel = NULL;
       
   624 	
       
   625 	_LIT8(KModelString, ";MDL:");
       
   626 	TInt pos = aString.Find( KModelString );
       
   627 	LOG1("[CBtDiscover::SetPrinterModelL]\t pos: %d", pos);
       
   628 	if( pos != KErrNotFound )
       
   629 		{
       
   630 		TPtrC8 tmpStr = aString.Right(aString.Length() - pos - 5);
       
   631 		pos = tmpStr.Locate(';');
       
   632 		if( pos != KErrNotFound )
       
   633 			{
       
   634 			iPrinterModel = HBufC::NewL(pos);
       
   635 			iPrinterModel->Des().Copy(tmpStr.Left(pos));
       
   636 			}
       
   637 		}
       
   638 
       
   639 	LOG("CBtDiscover::SetPrinterModelL end");
       
   640 	}
       
   641 
       
   642 /**
       
   643  * @brief Obtain Printer Model.
       
   644  *
       
   645  * Gets a TDesC& to the printer model previously set with SetPrinterModelL(),
       
   646  * or KNullDesC if no printer model has been set.
       
   647  *
       
   648  * @return String with the printer model.
       
   649  */
       
   650 const TDesC& CBtDiscover::GetPrinterModel() const
       
   651 	{
       
   652 	if (iPrinterModel)
       
   653 		return *iPrinterModel;
       
   654 	else
       
   655 		return KNullDesC;
       
   656 	}
       
   657 
       
   658 void CBtDiscover::SetVendor( TPrinter::TPrinterVendor aVendor )
       
   659 	{
       
   660 	LOG1("CBtDiscover::SetVendor aVendor: %d", aVendor);
       
   661 	iVendor = aVendor;
       
   662 	}
       
   663 
       
   664 TPrinter::TPrinterVendor CBtDiscover::GetVendor() const
       
   665 	{
       
   666 	LOG1("CBtDiscover::GetVendor return: %d", iVendor);
       
   667 	return iVendor;
       
   668 	}
       
   669 
       
   670 void CBtDiscover::GetNextAttributeL(TSdpServRecordHandle aHandle)
       
   671 	{
       
   672 	LOG1("[CBtDiscover::GetNextAttributeL]\t iCurrentSDPAttrID: 0x%X", iCurrentSDPAttrID);
       
   673 
       
   674 	TSdpAttributeID nextId;
       
   675 
       
   676 	switch( iCurrentSDPAttrID )
       
   677 	{
       
   678 		case KSdpAttrIdServiceClassIDList:
       
   679 			nextId = KSdpAttrIdProtocolDescriptorList;
       
   680 			break;
       
   681 		case KSdpAttrIdProtocolDescriptorList:
       
   682 			nextId = KSdpAttrIdAdditionalProtocolDescriptorLists;
       
   683 			break;
       
   684 		case KSdpAttrIdAdditionalProtocolDescriptorLists:
       
   685 			nextId = KSdpAttrIdDocFormatsSupported;
       
   686 			break;
       
   687 		case KSdpAttrIdDocFormatsSupported:
       
   688 			nextId = KSdpAttrIdModelID;
       
   689 			break;
       
   690 		case KSdpAttrIdModelID:
       
   691 			nextId = KSdpAttrIdMaxWidth;
       
   692 			break;
       
   693 		case KSdpAttrIdMaxWidth:
       
   694 			nextId = KSdpAttrIdMaxLen;
       
   695 			break;
       
   696 		default:
       
   697 			// all interested attributes received, at tleast asked
       
   698 			//Request 0xFFFFFF to indicate all done
       
   699 			nextId = KSdpAttrIdAllDone;
       
   700 			break;
       
   701 	}
       
   702 
       
   703 	iAgent->AttributeRequestL( aHandle, nextId );
       
   704 
       
   705 	LOG1("[CBtDiscover::GetNextAttributeL]\t end. nextId: 0x%X", nextId);
       
   706 	}
       
   707 
       
   708 
       
   709 
       
   710 /************************************************************************/
       
   711 /* visitor */
       
   712 /************************************************************************/
       
   713 
       
   714 CBTAttribValVisitor* CBTAttribValVisitor::NewLC( CBtDiscover& aDiscover )
       
   715 	{
       
   716 	CBTAttribValVisitor* obj = new (ELeave) CBTAttribValVisitor( aDiscover );
       
   717 	CleanupStack::PushL( obj );
       
   718 	return obj;
       
   719 	}
       
   720 
       
   721 /**
       
   722   * @param aDiscover Stores a pointer to the CBtDiscover object, in order to call
       
   723   * CBtDiscover::SetPort and CBtDiscover::SetContentTypes once those attributes have been
       
   724   * found.
       
   725   */
       
   726 CBTAttribValVisitor::CBTAttribValVisitor(CBtDiscover& aDiscover) : iDiscover(aDiscover)
       
   727 	{
       
   728 	}
       
   729 
       
   730 /**
       
   731   * @brief Called for each of the individual attributes in the SDP record being parsed.
       
   732   * @param aValue Value of the attribute.
       
   733   * @param aType Type of the attribute.
       
   734   */
       
   735 void CBTAttribValVisitor::VisitAttributeValueL(CSdpAttrValue& aValue, TSdpElementType aType)
       
   736 	{
       
   737 	LOG1("[CBTAttribValVisitor::VisitAttributeValueL]\t Begin. aType: %d", aType);
       
   738 
       
   739 	switch ( aType )
       
   740 		{
       
   741 		case ETypeUUID:
       
   742 			CheckUuid(aValue.UUID());
       
   743 			break;
       
   744 		case ETypeUint:
       
   745 			CheckUint(aValue.Uint());
       
   746 			break;
       
   747 		case ETypeString:
       
   748 			switch (iDiscover.iCurrentSDPAttrID)
       
   749 				{
       
   750 				case KSdpAttrIdDocFormatsSupported:
       
   751 					iDiscover.SetContentTypesL(aValue.Des());
       
   752 					break;
       
   753 				case KSdpAttrIdModelID:
       
   754 					CheckVendor( aValue.Des() );
       
   755 					iDiscover.SetPrinterModelL(aValue.Des());
       
   756 					break;
       
   757 				default:
       
   758 					break;
       
   759 				}
       
   760 			break;
       
   761 		default:
       
   762 			break;
       
   763 		}
       
   764 	}
       
   765 
       
   766 /**
       
   767   * @brief Indicates the beginning of an attribute list in the SDP record.
       
   768   */
       
   769 void CBTAttribValVisitor::StartListL(CSdpAttrValueList& /*aList*/)
       
   770 	{
       
   771 	LOG("CBTAttribValVisitor::StartListL");
       
   772 	}
       
   773 
       
   774 /**
       
   775   * @brief Indicates the end of an attribute list in the SDP record.
       
   776   */
       
   777 void CBTAttribValVisitor::EndListL()
       
   778 	{
       
   779 	LOG("CBTAttribValVisitor::EndListL");
       
   780 	}
       
   781 
       
   782 CBTAttribValVisitor::~CBTAttribValVisitor()
       
   783 	{
       
   784 	}
       
   785 
       
   786 //--------------------------------------------------------------------------------------------
       
   787 //
       
   788 // CBtPrinterController::CheckUuid
       
   789 //
       
   790 //--------------------------------------------------------------------------------------------
       
   791 void CBTAttribValVisitor::CheckUuid( const TUUID& aUuid )
       
   792 {
       
   793 	LOG("[CBTAttribValVisitor::CheckUuid]\t begin");
       
   794 
       
   795 	// We're interested only about UUIDs received at KSdpAttrIdServiceClassIDList
       
   796 	if (KSdpAttrIdServiceClassIDList != iDiscover.iCurrentSDPAttrID)
       
   797 	{
       
   798 		LOG1("[CBTAttribValVisitor::CheckUuid]\t Wrong attribute ID: 0x%X",iDiscover.iCurrentSDPAttrID);
       
   799 		return;
       
   800 	}
       
   801 
       
   802 #ifdef _DEBUG
       
   803 	TBuf<20> uidstr;
       
   804 	_LIT(KUidForm, "0x%02X%02X%02X%02X");
       
   805 	uidstr.Format(KUidForm, aUuid[0], aUuid[1], aUuid[2], aUuid[3]);
       
   806 	LOG1("[CBTAttribValVisitor::CheckUuid]\t ETypeUUID: %S", &uidstr);
       
   807 #endif
       
   808 
       
   809 	TUUID uidOpp(KBTSDPOBEXObjectPush);
       
   810 	TUUID uidBpp(KBTSDPDirectPrinting);
       
   811 	TUUID uidSts(KBTSDPPrintingStatus);
       
   812 	
       
   813 	if(aUuid == uidOpp)
       
   814 		iDiscover.iCurrentServiceUUID = KBTSDPOBEXObjectPush;
       
   815 	if(aUuid == uidBpp)
       
   816 		iDiscover.iCurrentServiceUUID = KBTSDPDirectPrinting;
       
   817 	if(aUuid == uidSts)
       
   818 		iDiscover.iFoundSTS = ETrue;
       
   819 
       
   820 	LOG("[CBTAttribValVisitor::CheckUuid]\t end");
       
   821 }
       
   822 
       
   823 //--------------------------------------------------------------------------------------------
       
   824 //
       
   825 // CBtPrinterController::CheckUint
       
   826 //
       
   827 //--------------------------------------------------------------------------------------------
       
   828 void CBTAttribValVisitor::CheckUint( const TUint& aValue )
       
   829 {
       
   830 	LOG("[CBTAttribValVisitor::CheckUint]\t begin");
       
   831 	
       
   832 	switch(iDiscover.iCurrentSDPAttrID)
       
   833 	{
       
   834 		case KSdpAttrIdProtocolDescriptorList:
       
   835 			if (KBTSDPDirectPrinting == iDiscover.iCurrentServiceUUID)
       
   836 			{
       
   837 				LOG1("[CBTAttribValVisitor::CheckUint]\t  iDiscover->SetBPPPort(%d)", aValue);
       
   838 				iDiscover.SetBPPPort(aValue);
       
   839 			}
       
   840 			if (KBTSDPOBEXObjectPush == iDiscover.iCurrentServiceUUID)
       
   841 			{
       
   842 				LOG1("[CBTAttribValVisitor::CheckUint]\t  iDiscover->SetOPPPort(%d)", aValue);
       
   843 				iDiscover.SetOPPPort(aValue);
       
   844 			}
       
   845 			break;
       
   846 		case KSdpAttrIdAdditionalProtocolDescriptorLists:
       
   847 			if(iDiscover.iFoundSTS )
       
   848 			{
       
   849 				LOG1("[CBTAttribValVisitor::CheckUint]\t iDiscover->SetSTSPort(%d)", aValue);
       
   850 				iDiscover.SetSTSPort(aValue);
       
   851 				iDiscover.iFoundSTS = EFalse;
       
   852 			}
       
   853 			break;
       
   854 		case KSdpAttrIdMaxWidth:
       
   855 			LOG1("[CBTAttribValVisitor::CheckUint]\t KSdpAttrIdMaxWidth: %d", aValue);
       
   856 			break;
       
   857 		case KSdpAttrIdMaxLen:
       
   858 			LOG1("[CBTAttribValVisitor::CheckUint]\t KSdpAttrIdMaxLen: %d", aValue);
       
   859 			break;
       
   860 		default:
       
   861 			break;
       
   862 	}
       
   863 
       
   864 	LOG("[CBTAttribValVisitor::CheckUint]\t end");
       
   865 }
       
   866 
       
   867 //--------------------------------------------------------------------------------------------
       
   868 //
       
   869 // CBtPrinterController::CheckVendor
       
   870 //
       
   871 //--------------------------------------------------------------------------------------------
       
   872 void CBTAttribValVisitor::CheckVendor( const TDesC8&  aVendor  )
       
   873 	{
       
   874 	LOG("[CBTAttribValVisitor::CheckVendor]\t Begin");
       
   875 	iDiscover.SetVendor( TPrinter::EVendorNone );
       
   876 	// At the moment this functionality is not used, but no Vendor is set.
       
   877 	HBufC8* vendorName = aVendor.Alloc();
       
   878 	if( vendorName )
       
   879 	{
       
   880 		LOG81("[CBTAttribValVisitor::CheckVendor]\t vendorName: %S", vendorName);
       
   881 		TPtr8 ptr = vendorName->Des();
       
   882 		ptr.LowerCase();
       
   883 		_LIT8( KHp, "mfg:hp;" );
       
   884 
       
   885 		TInt res = vendorName->Find( KHp );
       
   886 		LOG1("[CBTAttribValVisitor::CheckVendor]\t res: %d", res);
       
   887 		
       
   888 		if( res != KErrNotFound ) 
       
   889 			iDiscover.SetVendor( TPrinter::EVendorHp );
       
   890 	}
       
   891 	delete vendorName;
       
   892 	LOG("[CBTAttribValVisitor::CheckVendor]\t End");
       
   893 	}
       
   894 
       
   895 //  End of File