bluetoothmgmt/btmgr/BTManServer/BTRegistrySQL.cpp
changeset 0 29b1cd4cb562
equal deleted inserted replaced
-1:000000000000 0:29b1cd4cb562
       
     1 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "BTRegistryDB.h"
       
    17 #include <bluetooth/logger.h>
       
    18 
       
    19 #ifdef __FLOG_ACTIVE
       
    20 _LIT8(KLogComponent, LOG_COMPONENT_BT_MANAGER_SERVER);
       
    21 #endif
       
    22 
       
    23 const TInt KMaxLengthConstraintInitial = 60;	// constraint length is initially this
       
    24 const TInt KMaxLengthConstraintIncrement = 60;	// - then we extend as necessary by this amount
       
    25 
       
    26 RBTDbQuery::RBTDbQuery()
       
    27 /**
       
    28 	Required for non-default constructed RTextBuf
       
    29 **/
       
    30 	{
       
    31 	LOG_FUNC
       
    32 	}
       
    33 
       
    34 void RBTDbQuery::Close()
       
    35 	{
       
    36 	LOG_FUNC
       
    37 	iQueryBuf.Close();
       
    38 	}
       
    39 
       
    40 const TPtrC RBTDbQuery::QuoteEscapeLC(const TBTDevAddr& aBDAddr) const
       
    41 	{
       
    42 	LOG_FUNC
       
    43 	TBuf<6> wideAddr;	// needed to stop implicit converstion back to DevAddr!
       
    44 	wideAddr.Copy(aBDAddr.Des());
       
    45 	return QuoteEscapeLC(wideAddr);
       
    46 	}
       
    47 
       
    48 const TPtrC RBTDbQuery::QuoteEscapeLC(const TDesC& aDes) const
       
    49 /**
       
    50 	Can't search for a string in SQL with a quote (') in un-escaped
       
    51 	Escape by putting extra quote in for every quote in the descriptor
       
    52 **/
       
    53 	{
       
    54 	LOG_FUNC
       
    55 	const TUint16 KEscapeCode = 0x0027;	// SQL escape value
       
    56 	// maximum size of new descriptor will be twice the original (if it contained all quotes!)
       
    57 	HBufC* escaped = HBufC::NewMaxLC(2*aDes.Length());
       
    58 	TPtr escapedPtr= escaped->Des();
       
    59 
       
    60 	TInt i=0;
       
    61 	TInt escapedIndex = 0;
       
    62 	while (i<aDes.Length())
       
    63 		{
       
    64 		const TChar& element = aDes[i++];	// copes with narrow and wide
       
    65 #pragma warning (disable : 4244)  // conversion - its ok here
       
    66 		escapedPtr[escapedIndex++] = element;
       
    67 #pragma warning (default : 4244)
       
    68 		if (element == KEscapeCode)
       
    69 			{
       
    70 			escapedPtr[escapedIndex++] = KEscapeCode;
       
    71 			}
       
    72 		}
       
    73 	escapedPtr.SetLength(escapedIndex);	// bring down from the MaxLength
       
    74 	return escapedPtr;	// returns ownership of the HBuf via cleanupstack
       
    75 	}
       
    76 
       
    77 void RBTDbQuery::FindDeviceL(const TBTDevAddr& aBDAddr)
       
    78 /**
       
    79 	Construct a simple SQL query to see if the device is present
       
    80 **/
       
    81 	{
       
    82 	LOG_FUNC
       
    83 	// this is used to see if the device is in the registry
       
    84 	TBuf<KMaxConstraintLen> constraint;
       
    85 
       
    86 	constraint.Append(KColName_DeviceAddress);
       
    87 	constraint.Append(KSQLEqual);
       
    88 	constraint.Append(KSQLQuote);
       
    89 	constraint.Append(QuoteEscapeLC(aBDAddr));
       
    90 	constraint.Append(KSQLQuote);
       
    91 
       
    92 	iQueryBuf.SetMaxLengthL(constraint.Length() + KSQLSelectAllConstrained().Length() + KDeviceTable().Length());
       
    93 	iQueryBuf.Text().Format(KSQLSelectAllConstrained, &KDeviceTable, &constraint);
       
    94 
       
    95 	CleanupStack::PopAndDestroy(1); // address buffer
       
    96 	}
       
    97 
       
    98 void RBTDbQuery::FindCommPortL(TUint32 aUnitNumber)
       
    99 /**
       
   100 	Construct a SQL query to find the virtual serial port with aUnitNumber
       
   101 **/
       
   102 	{
       
   103 	LOG_FUNC
       
   104 	TBuf<KMaxConstraintLen> constraint;
       
   105 
       
   106 	constraint.Append(KBTCOMMColName_Port);
       
   107 	constraint.Append(KSQLEqual);
       
   108 	constraint.AppendNum(static_cast<TUint>(aUnitNumber), EDecimal);
       
   109 
       
   110 	iQueryBuf.SetMaxLengthL(constraint.Length() + KSQLSelectAllConstrained().Length() + KCSYTable().Length());
       
   111 	iQueryBuf.Text().Format(KSQLSelectAllConstrained, &KCSYTable, &constraint);
       
   112 	}
       
   113 
       
   114 void RBTDbQuery::MatchLinkKeyTypeL(TBTLinkKeyType aLinkKeyType)
       
   115 /**
       
   116  	Construct a SQL query to find entries that have a link key of a specific type.
       
   117 **/
       
   118 	{
       
   119 	LOG_FUNC
       
   120 	TBuf<KMaxConstraintLen> constraint;
       
   121 
       
   122 	constraint.Append(KDeviceColName_LinkKeyType);
       
   123 	constraint.Append(KSQLEqual);
       
   124 	constraint.AppendNum(static_cast<TUint>(aLinkKeyType), EDecimal);
       
   125 
       
   126 	iQueryBuf.SetMaxLengthL(constraint.Length() + KSQLSelectAllConstrained().Length() + KDeviceTable().Length());
       
   127 	iQueryBuf.Text().Format(KSQLSelectAllConstrained, &KDeviceTable, &constraint);
       
   128 	}
       
   129 
       
   130 const TDesC& RBTDbQuery::QueryBuf() const
       
   131 	{
       
   132 	LOG_FUNC
       
   133 	return iQueryBuf.Text();
       
   134 	}
       
   135 
       
   136 TPtrC RBTDbQuery::ConstraintBuf() const
       
   137 	{
       
   138 	LOG_FUNC
       
   139 	TInt index = QueryBuf().Find(KSQLWhere);
       
   140 	return (index==KErrNotFound) ? TPtrC() : QueryBuf().Mid(index+KSQLWhere().Length());
       
   141 	}
       
   142 
       
   143 void RBTDbQuery::ExtendForAnotherTokenL(RTextBuf& aSQLBuf, TUint aMask)
       
   144 /**
       
   145 	Sees if the token 'AND' is required in a constrained search
       
   146 	If so, add into the SQL query
       
   147 	If the buffer is getting small, extend it
       
   148 **/
       
   149 	{
       
   150 	LOG_FUNC
       
   151 	if (aMask)
       
   152 		{
       
   153 		// need an AND - more constraints follow
       
   154 		aSQLBuf.Text().Append(KSQLAnd);
       
   155 		//Need to increase the size of the bufferno
       
   156 		// RTextBuf::SetMaxLengthL is bad as it closes the textbuf
       
   157 		RTextBuf copy;
       
   158 		copy.SetMaxLengthL(aSQLBuf.Text().Length());
       
   159 		CleanupClosePushL(copy);
       
   160 		copy.Text().Append(aSQLBuf.Text());
       
   161 		aSQLBuf.SetMaxLengthL(aSQLBuf.Text().Length()+KMaxLengthConstraintIncrement);
       
   162 		//copy back from the copy to the aSQLBuf
       
   163 		aSQLBuf.Text().Append(copy.Text());
       
   164 		CleanupStack::PopAndDestroy();
       
   165 		}
       
   166 	// else do nothing - no further constraint to follow
       
   167 	}
       
   168 
       
   169 void RBTDbQuery::SearchL(const TBTRegistrySearch& aPattern)
       
   170 /**
       
   171 	Converts a search mask into SQL search tokens
       
   172 **/
       
   173 	{
       
   174 	LOG_FUNC
       
   175 	// do the catch all first - saves time
       
   176 	if (aPattern.iSearchMask & TBTRegistrySearch::EAll)
       
   177 		{
       
   178 		iQueryBuf.SetMaxLengthL(KSQLSelectAll().Length() + KDeviceTable().Length());
       
   179 		iQueryBuf.Text().Format(KSQLSelectAll, &KDeviceTable);
       
   180 		return;
       
   181 		}
       
   182 
       
   183 	// we have a constrained search; formulate the SQL
       
   184 	// we use a RTextBuf that can grow as needed (to reduce stack usage)
       
   185 
       
   186 	RTextBuf constraintBuf;
       
   187 
       
   188 	constraintBuf.SetMaxLengthL(KMaxLengthConstraintInitial);
       
   189 
       
   190 	TPtr& constraint = constraintBuf.Text();
       
   191 
       
   192 	TUint toSearch = aPattern.iSearchMask;
       
   193 	
       
   194 	if (toSearch & TBTRegistrySearch::EAddress)
       
   195 		{
       
   196 		constraint.Append(KColName_DeviceAddress);
       
   197 		constraint.Append(KSQLEqual);
       
   198 		constraint.Append(KSQLQuote);
       
   199 		constraint.Append(QuoteEscapeLC(aPattern.iDeviceAddress));
       
   200 		constraint.Append(KSQLQuote);
       
   201 		CleanupStack::PopAndDestroy(1); // address buffer
       
   202 		
       
   203 		toSearch &= ~TBTRegistrySearch::EAddress;
       
   204 		ExtendForAnotherTokenL(constraintBuf, toSearch);
       
   205 		}
       
   206 
       
   207 
       
   208 	if (toSearch & TBTRegistrySearch::ECoD)
       
   209 		{
       
   210 		constraint.Append(KDeviceColName_CoD);
       
   211 		constraint.Append(KSQLEqual);
       
   212 		TUint cod = aPattern.iDeviceClass.DeviceClass();
       
   213 		constraint.AppendNum(cod, EDecimal);
       
   214 
       
   215 		toSearch &= ~TBTRegistrySearch::ECoD;
       
   216 		ExtendForAnotherTokenL(constraintBuf, toSearch);
       
   217 		}
       
   218 		
       
   219 	if (toSearch & TBTRegistrySearch::ECoDMajorDev)
       
   220 		{
       
   221 		constraint.Append(KDeviceColName_CoD_MajorDev);
       
   222 		constraint.Append(KSQLEqual);
       
   223 		TUint majDev = aPattern.iDeviceClass.MajorDeviceClass();
       
   224 		constraint.AppendNum(majDev, EDecimal);
       
   225 
       
   226 		toSearch &= ~TBTRegistrySearch::ECoDMajorDev;
       
   227 		ExtendForAnotherTokenL(constraintBuf, toSearch);
       
   228 		}
       
   229 
       
   230 	if (toSearch & TBTRegistrySearch::ECoDMinorDev)
       
   231 		{
       
   232 		constraint.Append(KDeviceColName_CoD_MinorDev);
       
   233 		constraint.Append(KSQLEqual);
       
   234 		TUint minDev = aPattern.iDeviceClass.MinorDeviceClass();
       
   235 		constraint.AppendNum(minDev, EDecimal);
       
   236 
       
   237 		toSearch &= ~TBTRegistrySearch::ECoDMinorDev;
       
   238 		ExtendForAnotherTokenL(constraintBuf, toSearch);
       
   239 		}
       
   240 
       
   241 	if (toSearch & TBTRegistrySearch::EBTName)
       
   242 		{
       
   243 		constraint.Append(KDeviceColName_BluetoothName);
       
   244 		constraint.Append(KSQLEqual);
       
   245 		constraint.Append(KSQLQuote);
       
   246 		TBuf<KMaxBluetoothNameLen> widened;
       
   247 		widened.Copy(aPattern.iBluetoothName);
       
   248 		constraint.Append(QuoteEscapeLC(widened));
       
   249 		constraint.Append(KSQLQuote);
       
   250 		CleanupStack::PopAndDestroy(1); //name
       
   251 
       
   252 		toSearch &= ~TBTRegistrySearch::EBTName;
       
   253 		ExtendForAnotherTokenL(constraintBuf, toSearch);
       
   254 		}
       
   255 
       
   256 	if (toSearch & TBTRegistrySearch::EFriendlyName)
       
   257 		{
       
   258 		constraint.Append(KDeviceColName_FriendlyName);
       
   259 		constraint.Append(KSQLEqual);
       
   260 		constraint.Append(KSQLQuote);
       
   261 		constraint.Append(QuoteEscapeLC(aPattern.iFriendlyName));
       
   262 		constraint.Append(KSQLQuote);
       
   263 		CleanupStack::PopAndDestroy(1); // name
       
   264 
       
   265 		toSearch &= ~TBTRegistrySearch::EFriendlyName;
       
   266 		ExtendForAnotherTokenL(constraintBuf, toSearch);
       
   267 		}
       
   268 
       
   269 	if (toSearch & TBTRegistrySearch::EProcess)
       
   270 		{
       
   271 		constraint.Append(KColName_ProcessSID);
       
   272 		constraint.Append(KSQLEqual);
       
   273 		constraint.AppendNum(MAKE_TUINT64(0,aPattern.iCurrentProcessSID.iUid), EDecimal);
       
   274 
       
   275 		toSearch &= ~TBTRegistrySearch::EProcess;
       
   276 		ExtendForAnotherTokenL(constraintBuf, toSearch);
       
   277 		}
       
   278 
       
   279 	if (toSearch & TBTRegistrySearch::EBonded)
       
   280 		{
       
   281 		constraint.Append(KDeviceColName_LinkKey);
       
   282 		constraint.Append(KSQLIsNotNull);
       
   283 
       
   284 		toSearch &= ~TBTRegistrySearch::EBonded;
       
   285 		ExtendForAnotherTokenL(constraintBuf, toSearch);
       
   286 		}
       
   287 
       
   288 	if (toSearch & TBTRegistrySearch::ETrusted)
       
   289 		{
       
   290 		// check global security for no authorisation AND authentication
       
   291 		constraint.Append(KSQLOpenParentheses);
       
   292 		constraint.Append(KDeviceColName_GlobalSecSecurity);
       
   293 		constraint.Append(KSQLEqual);
       
   294 
       
   295 		// we do this here in case TBTDeviceSecurity changes
       
   296 		// trusted device = 'NoAuthentication'=No (MUST authenticate!),
       
   297 		//					'NoAuthorisation'=Yes
       
   298 		//					'Encryption' could be either.
       
   299 		//					'Banned' =No (!)
       
   300 
       
   301 		TBTDeviceSecurity noEncryption(EFalse, ETrue, EFalse, EFalse);
       
   302 		constraint.AppendNum(static_cast<TUint>(noEncryption.SecurityValue()));
       
   303 
       
   304 		constraint.Append(KSQLOr);
       
   305 		constraint.Append(KDeviceColName_GlobalSecSecurity);
       
   306 		constraint.Append(KSQLEqual);
       
   307 		
       
   308 		TBTDeviceSecurity encryption(EFalse, ETrue, ETrue, EFalse);
       
   309 		constraint.AppendNum(static_cast<TUint>(encryption.SecurityValue()));
       
   310 		constraint.Append(KSQLCloseParentheses);
       
   311 
       
   312 		toSearch &= ~TBTRegistrySearch::ETrusted;
       
   313 		ExtendForAnotherTokenL(constraintBuf, toSearch);
       
   314 		}
       
   315 
       
   316 	if (toSearch & TBTRegistrySearch::ELastSeen)
       
   317 		{
       
   318 		constraint.Append(KDeviceColName_LastSeen);
       
   319 		constraint.Append(KSQLGreaterEqual);
       
   320 		constraint.AppendNum(aPattern.iLastSeen.Int64());
       
   321 		toSearch &= ~TBTRegistrySearch::ELastSeen;
       
   322 		ExtendForAnotherTokenL(constraintBuf, toSearch);
       
   323 		}
       
   324 
       
   325 	if (toSearch & TBTRegistrySearch::ELastUsed)
       
   326 		{
       
   327 		constraint.Append(KDeviceColName_LastUsed);
       
   328 		constraint.Append(KSQLGreaterEqual);
       
   329 		constraint.AppendNum(aPattern.iLastUsed.Int64());
       
   330 		toSearch &= ~TBTRegistrySearch::ELastUsed;
       
   331 		ExtendForAnotherTokenL(constraintBuf, toSearch);
       
   332 		}
       
   333 	
       
   334 	if (toSearch & TBTRegistrySearch::EUiCookie)
       
   335 		{
       
   336 		constraint.Append(KDeviceColName_UiCookie);
       
   337 		constraint.Append(KSQLLike);
       
   338 		constraint.Append(KSQLQuote);
       
   339 		static const TUint8 KCookieBinaryRepresentationWidth = 32; // 32bits encoded as binary string.
       
   340 		TBuf<KCookieBinaryRepresentationWidth> cookiePattern;
       
   341 		cookiePattern.NumFixedWidth(aPattern.iUiCookie, EBinary, KCookieBinaryRepresentationWidth);
       
   342 		TUint32 shiftedMask = aPattern.iUiCookieMask;
       
   343 		for(TInt i=KCookieBinaryRepresentationWidth-1; i>=0; --i)
       
   344 			{
       
   345 			if(!(shiftedMask&1)) // check the bottom bit (we loop through them all by shifting.)
       
   346 				{
       
   347 				// bit "i" isn't masked, and so we should ignore it.
       
   348 				cookiePattern[i] = '?';
       
   349 				}
       
   350 			shiftedMask >>= 1;
       
   351 			}
       
   352 		constraint.Append(cookiePattern);
       
   353 		constraint.Append(KSQLQuote);
       
   354 		
       
   355 		toSearch &= ~TBTRegistrySearch::EUiCookie;
       
   356 		ExtendForAnotherTokenL(constraintBuf, toSearch);
       
   357 		}
       
   358 	
       
   359 	if(toSearch)
       
   360 		{
       
   361 		// There is an unhandled search attribute that has been provided by the user.
       
   362 		// If left the trailing SQL "AND" would trigger the KErrArgument error anyway.
       
   363 		User::Leave(KErrArgument);
       
   364 		}
       
   365 
       
   366 	iQueryBuf.SetMaxLengthL(constraint.Length() + KSQLSelectAllConstrained().Length() + KDeviceTable().Length());
       
   367 	iQueryBuf.Text().Format(KSQLSelectAllConstrained, &KDeviceTable, &constraint);
       
   368 	}
       
   369