bluetoothengine/bteng/src/btengsdpdbhandler.cpp
changeset 0 f63038272f30
equal deleted inserted replaced
-1:000000000000 0:f63038272f30
       
     1 /*
       
     2 * Copyright (c) 2006 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:  Helper class for SDP database management.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 #include <btsdp.h>
       
    21 #include <btengsdp.rsg>
       
    22 #include <barsread.h>
       
    23 #include <barsc.h>
       
    24 #include <data_caging_path_literals.hrh>
       
    25 
       
    26 #include "btengsdpdbhandler.h"
       
    27 #include "btengsdp.hrh"
       
    28 #include "debug.h"
       
    29 
       
    30 _LIT( KBTEngSdpResourceFile, "btengsdp.rsc");
       
    31 _LIT( KDriveZ, "z:");
       
    32 _LIT8( KHex, "0x");
       
    33 const TInt KMaxServiceDesLength = 64;
       
    34 const TInt KNumberOfChars = 8;
       
    35 
       
    36 
       
    37 // ======== MEMBER FUNCTIONS ========
       
    38 
       
    39 // ---------------------------------------------------------------------------
       
    40 // C++ default constructor
       
    41 // ---------------------------------------------------------------------------
       
    42 //
       
    43 CBTEngSdpDbHandler::CBTEngSdpDbHandler()
       
    44     {
       
    45     }
       
    46 
       
    47 
       
    48 // ---------------------------------------------------------------------------
       
    49 // Symbian 2nd-phase constructor
       
    50 // ---------------------------------------------------------------------------
       
    51 //
       
    52 void CBTEngSdpDbHandler::ConstructL()
       
    53     {
       
    54     TRACE_FUNC_ENTRY
       
    55     User::LeaveIfError( iSdp.Connect() );
       
    56     User::LeaveIfError( iDb.Open( iSdp ) );
       
    57     TRACE_FUNC_EXIT
       
    58     }
       
    59 
       
    60 
       
    61 // ---------------------------------------------------------------------------
       
    62 // NewL
       
    63 // ---------------------------------------------------------------------------
       
    64 //
       
    65 CBTEngSdpDbHandler* CBTEngSdpDbHandler::NewL()
       
    66     {
       
    67     CBTEngSdpDbHandler* self = new( ELeave ) CBTEngSdpDbHandler();
       
    68     CleanupStack::PushL( self );
       
    69     self->ConstructL();
       
    70     CleanupStack::Pop( self );
       
    71     return self;
       
    72     }
       
    73 
       
    74 
       
    75 // ---------------------------------------------------------------------------
       
    76 // Destructor
       
    77 // ---------------------------------------------------------------------------
       
    78 //
       
    79 CBTEngSdpDbHandler::~CBTEngSdpDbHandler()
       
    80     {
       
    81     iDb.Close();     // This should have no effect if the handle is null.
       
    82     iSdp.Close();
       
    83     }
       
    84 
       
    85 
       
    86 // ---------------------------------------------------------------------------
       
    87 // Register SDP record for the specified service containing the specified 
       
    88 // protocol channel in the protocol descriptor list.
       
    89 // ---------------------------------------------------------------------------
       
    90 //
       
    91 void CBTEngSdpDbHandler::RegisterSdpRecordL( const TUUID& aService, 
       
    92     TInt aChannel, TSdpServRecordHandle& aHandle )
       
    93     {
       
    94     TRACE_FUNC_ARG( ( _L( "channel: %d" ), aChannel ) )
       
    95     iChannel = aChannel;
       
    96     RegisterSdpRecordL( aService, aHandle );
       
    97     }
       
    98 
       
    99 
       
   100 // ---------------------------------------------------------------------------
       
   101 // Register SDP record for the specified service containing the specified 
       
   102 // VendorID and ProductID for the relevant attributes (mainly for DI profile).
       
   103 // ---------------------------------------------------------------------------
       
   104 //
       
   105 void CBTEngSdpDbHandler::RegisterSdpRecordL( const TUUID& aService, 
       
   106     TInt aVendorId, TInt aProductId, TSdpServRecordHandle& aHandle )
       
   107     {
       
   108     TRACE_FUNC_ARG( ( _L( "vendor ID: %d: product ID: %d" ), 
       
   109                           aVendorId, aProductId ) )
       
   110     iVendorId = aVendorId;
       
   111     iProductId = aProductId;
       
   112     RegisterSdpRecordL( aService, aHandle );
       
   113     }
       
   114 
       
   115 
       
   116 // ---------------------------------------------------------------------------
       
   117 // Register SDP record for the specified service.
       
   118 // ---------------------------------------------------------------------------
       
   119 //
       
   120 void CBTEngSdpDbHandler::RegisterSdpRecordL( const TUUID& aService, 
       
   121     TSdpServRecordHandle& aHandle )
       
   122     {
       
   123     TResourceReader reader;
       
   124     HBufC8* record = NULL;
       
   125     TBuf8<KMaxServiceDesLength> serviceBuf( KHex );
       
   126     TPtrC8 ptr = aService.ShortestForm();
       
   127     if( ptr.Length() <= 4 )
       
   128         {
       
   129             // Short form UUID (16 or 32 bytes).
       
   130         TUint service = SdpUtil::GetUint( ptr );
       
   131         serviceBuf.AppendNum( service, EHex );
       
   132         }
       
   133     else
       
   134         {
       
   135             // Long form UUID (128 bytes).
       
   136         TUint64 serviceLo = 0;
       
   137         TUint64 serviceHi = 0;
       
   138         SdpUtil::GetUint128( ptr, serviceLo, serviceHi );
       
   139             // The numbers need to have a fixed width (including leading zeros)
       
   140             // and AppendNumFixedWidth is only avaliable with TUint32.
       
   141         serviceBuf.AppendNumFixedWidth( I64HIGH(serviceHi), EHex, KNumberOfChars );
       
   142         serviceBuf.AppendNumFixedWidth( I64LOW(serviceHi), EHex, KNumberOfChars );
       
   143         serviceBuf.AppendNumFixedWidth( I64HIGH(serviceLo), EHex, KNumberOfChars );
       
   144         serviceBuf.AppendNumFixedWidth( I64LOW(serviceLo), EHex, KNumberOfChars );
       
   145         }
       
   146 
       
   147         // Read the record from resource file.
       
   148     ReadRecordResourceL( serviceBuf, reader, record );
       
   149     CleanupStack::PushL( record );
       
   150 
       
   151     iDb.CreateServiceRecordL( TUUID( 0 ), aHandle );
       
   152     CSdpAttrValue* attrVal = NULL;
       
   153     TUint attrCount = reader.ReadUint16();
       
   154     for( TInt i = 0; i < attrCount; i++ )
       
   155         {
       
   156         TUint16 attrId = reader.ReadUint16();
       
   157         BuildAttributeLC( attrVal, reader, attrId );
       
   158         if( attrVal )
       
   159             {
       
   160             iDb.UpdateAttributeL( aHandle, attrId, *attrVal );
       
   161             CleanupStack::PopAndDestroy( attrVal );
       
   162             attrVal = NULL;
       
   163             }
       
   164         }
       
   165 
       
   166     CleanupStack::PopAndDestroy( record );
       
   167     TRACE_FUNC_EXIT
       
   168     }
       
   169 
       
   170 
       
   171 // ---------------------------------------------------------------------------
       
   172 // Delete the SDP record for the specified record handle.
       
   173 // ---------------------------------------------------------------------------
       
   174 //
       
   175 void CBTEngSdpDbHandler::DeleteSdpRecordL( const TSdpServRecordHandle aHandle )
       
   176     {
       
   177     TRACE_FUNC_ENTRY
       
   178     if( aHandle )
       
   179         {
       
   180         iDb.DeleteRecordL( aHandle );
       
   181         }
       
   182     else
       
   183         {
       
   184         User::Leave( KErrBadHandle );
       
   185         }
       
   186     TRACE_FUNC_EXIT
       
   187     }
       
   188 
       
   189 
       
   190 // ---------------------------------------------------------------------------
       
   191 // Build an SDP attribute.
       
   192 // ---------------------------------------------------------------------------
       
   193 //
       
   194 void CBTEngSdpDbHandler::BuildAttributeLC( CSdpAttrValue*& aAttrVal,
       
   195     TResourceReader& aReader, TInt aAttrId )
       
   196     {
       
   197         // Read the attribute type and ID
       
   198     TUint attrType = aReader.ReadUint8();
       
   199     if( attrType == EElemTypeList )
       
   200         {
       
   201         BuildAttrDesLC( aAttrVal, aReader, aAttrId );
       
   202         }
       
   203     else
       
   204         {
       
   205         BuildAttrValueLC( aAttrVal, aReader, attrType, aAttrId );
       
   206         }
       
   207     }
       
   208 
       
   209 
       
   210 // ---------------------------------------------------------------------------
       
   211 // Build an SDP attribute for a concrete attribute type.
       
   212 // ---------------------------------------------------------------------------
       
   213 //
       
   214 void CBTEngSdpDbHandler::BuildAttrValueLC( CSdpAttrValue*& aAttrVal,
       
   215     TResourceReader& aReader, TUint aAttrType, TInt aAttrId )
       
   216     {
       
   217     TRACE_FUNC_ENTRY
       
   218     switch( aAttrType )
       
   219         {
       
   220         case EElemTypeWord:
       
   221             {
       
   222             TSdpIntBuf<TUint16> buf( aReader.ReadUint16() );
       
   223             if( iVendorId && aAttrId == EVendorID )
       
   224                 {
       
   225                 buf = TSdpIntBuf<TUint16>( iVendorId );
       
   226                 iVendorId = 0;   // Reset vendor ID
       
   227                 }
       
   228             if( iProductId && aAttrId == EProductID )
       
   229                 {
       
   230                 buf = TSdpIntBuf<TUint16>( iProductId );
       
   231                 iProductId = 0;   // Reset vendor ID
       
   232                 }
       
   233             aAttrVal = CSdpAttrValueUint::NewUintL( buf );
       
   234             }
       
   235             break;
       
   236         case EElemTypeLong:
       
   237             {
       
   238             TSdpIntBuf<TUint32> buf( aReader.ReadUint32() );
       
   239             aAttrVal = CSdpAttrValueUint::NewUintL( buf );
       
   240             }
       
   241             break;
       
   242         case EElemTypeUUID:
       
   243             {
       
   244             TUUID uuid( aReader.ReadUint32() );
       
   245             aAttrVal = CSdpAttrValueUUID::NewUUIDL( uuid );
       
   246             }
       
   247             break;
       
   248         case EElemTypeUUID128:
       
   249             {
       
   250             TUUID uuid;
       
   251             uuid.SetL( aReader.ReadTPtrC8() );
       
   252             aAttrVal = CSdpAttrValueUUID::NewUUIDL( uuid );
       
   253             }
       
   254             break;
       
   255         case EElemTypeText:
       
   256             {
       
   257             TPtrC8 ptr = aReader.ReadTPtrC8();
       
   258             aAttrVal = CSdpAttrValueString::NewStringL( ptr );
       
   259             }
       
   260             break;
       
   261         case EElemTypeByte:
       
   262             {
       
   263             TSdpIntBuf<TUint8> buf( aReader.ReadUint8() );
       
   264             if( iChannel && aAttrId == EProtocolDescriptorList )
       
   265                 {
       
   266                 buf = TSdpIntBuf<TUint8>( iChannel );
       
   267                 iChannel = 0;   // Reset channel number
       
   268                 }
       
   269             aAttrVal = CSdpAttrValueUint::NewUintL( buf );
       
   270             }
       
   271             break;
       
   272         case EElemTypeList:
       
   273             {
       
   274             BuildAttrDesLC( aAttrVal, aReader, aAttrId );
       
   275             }
       
   276             break;    
       
   277         case EElemTypeLong64:
       
   278             {
       
   279             TPtrC8 ptr = aReader.ReadTPtrC8();
       
   280             aAttrVal = CSdpAttrValueUint::NewUintL(ptr);
       
   281             break;
       
   282             }
       
   283         case EElemTypeBool:
       
   284             {
       
   285             TBool boolVal = (TBool) aReader.ReadUint8();
       
   286             aAttrVal = CSdpAttrValueBoolean::NewBoolL( boolVal );
       
   287             break;
       
   288             }
       
   289         case EElemTypeLink:
       
   290         default:
       
   291             break;
       
   292         }
       
   293     if( aAttrVal )
       
   294         {
       
   295         CleanupStack::PushL( aAttrVal );
       
   296         }
       
   297     }
       
   298 
       
   299 
       
   300 // ---------------------------------------------------------------------------
       
   301 // Build an SDP Data Elelement Sequence attribute (i.e. a sequence of 
       
   302 // concrete attributes or lists).
       
   303 // ---------------------------------------------------------------------------
       
   304 //
       
   305 void CBTEngSdpDbHandler::BuildAttrDesLC( CSdpAttrValue*& aAttrVal, 
       
   306     TResourceReader& aReader, TInt aAttrId )
       
   307     {
       
   308     TRACE_FUNC_ENTRY
       
   309     TUint elementCount = aReader.ReadUint16();
       
   310     MSdpElementBuilder* builder = NULL;
       
   311     if( !aAttrVal )
       
   312         {
       
   313             // This is the first element of the attribute.
       
   314         aAttrVal = CSdpAttrValueDES::NewDESL( NULL );
       
   315         builder = ( (CSdpAttrValueDES*) aAttrVal )->StartListL();
       
   316         }
       
   317     else
       
   318         {
       
   319             // This is a nested DES. This means that the parent element is
       
   320             // also a DES. Append this DES to the parent.
       
   321         builder = ( (CSdpAttrValueDES*) aAttrVal )->BuildDESL();
       
   322         builder = builder->StartListL();
       
   323         }
       
   324 
       
   325     CleanupStack::PushL( aAttrVal );
       
   326     while( elementCount > 0 )
       
   327         {
       
   328             // Build the list; this can result in another call to this function 
       
   329             // to build a nested list.
       
   330         CSdpAttrValue* element = NULL;
       
   331         BuildAttributeLC( element, aReader, aAttrId );
       
   332         if( element )
       
   333             {
       
   334             CleanupStack::Pop( element );   // Ownership will be passed to DES.
       
   335             CSdpAttrValueDES* list = (CSdpAttrValueDES*) builder;
       
   336             list->AppendValueL( element );
       
   337             }
       
   338         elementCount--;
       
   339         }
       
   340     builder = builder->EndListL();
       
   341     }
       
   342 
       
   343 
       
   344 // ---------------------------------------------------------------------------
       
   345 // Read the service record from the resource file containing all BT Engine's
       
   346 // service record definitions.
       
   347 // ---------------------------------------------------------------------------
       
   348 //
       
   349 void CBTEngSdpDbHandler::ReadRecordResourceL( const TDesC8& aService, 
       
   350     TResourceReader& aReader, HBufC8*& aRecordBuf )
       
   351     {
       
   352     TRACE_FUNC_ENTRY
       
   353         // Find and open resource file
       
   354     TFileName fileName( KDriveZ );
       
   355     fileName.Append( KDC_RESOURCE_FILES_DIR );
       
   356     fileName.Append( KBTEngSdpResourceFile );
       
   357     RFs fsSession;
       
   358     User::LeaveIfError( fsSession.Connect() );
       
   359     CleanupClosePushL( fsSession );
       
   360     RResourceFile resourceFile;
       
   361     resourceFile.OpenL( fsSession, fileName );
       
   362     CleanupClosePushL( resourceFile );
       
   363 
       
   364         // Read the array containing the mappings of UUID to resource definitions.
       
   365     HBufC8* buf = resourceFile.AllocReadLC( R_SERVICE_RECORD_LIST );
       
   366     aReader.SetBuffer( buf );
       
   367     CDesC8ArrayFlat* serviceIdArray = aReader.ReadDesC8ArrayL();
       
   368     CleanupStack::PushL( serviceIdArray );
       
   369 
       
   370         // Find the requested service record.
       
   371     TInt pos = KErrNotFound;
       
   372     for( TInt i = 0; i < serviceIdArray->Count(); i++ )
       
   373         {
       
   374             // CompareF is case insensitive comparison
       
   375         if( aService.CompareF( (*serviceIdArray)[i] ) == 0 )
       
   376             {
       
   377             pos = i;
       
   378             break;
       
   379             }
       
   380         }
       
   381     if( pos < 0 )
       
   382         {
       
   383             // The record is not found from the resource file.
       
   384         User::Leave( pos );
       
   385         }
       
   386 
       
   387         // Read the service record resource in a buffer to pass back.
       
   388     aReader.Advance( 2 * pos + 2 ); // 16bit LINK
       
   389     TUint resourceId = aReader.ReadUint16();
       
   390     aRecordBuf = resourceFile.AllocReadL( resourceId );
       
   391     aReader.SetBuffer( aRecordBuf );
       
   392 
       
   393     CleanupStack::PopAndDestroy( serviceIdArray );
       
   394     CleanupStack::PopAndDestroy( buf );
       
   395     CleanupStack::PopAndDestroy( &resourceFile );
       
   396     CleanupStack::PopAndDestroy( &fsSession );
       
   397     TRACE_FUNC_EXIT
       
   398     }