bluetoothengine/btui/btuimodel/btdevicedata.cpp
changeset 33 837dcc42fd6a
parent 19 43824b19ee35
child 40 997690c3397a
equal deleted inserted replaced
19:43824b19ee35 33:837dcc42fd6a
    13 *
    13 *
    14 * Description: 
    14 * Description: 
    15 *
    15 *
    16 */
    16 */
    17 
    17 
    18 
       
    19 #include "btdevicedata.h"
    18 #include "btdevicedata.h"
       
    19 #include <QDateTime>
       
    20 #include <btservices/advancedevdiscoverer.h>
       
    21 #include "btuiutil.h"
       
    22 #include "btqtconstants.h"
       
    23 
       
    24 class DevTypeIconMapping {
       
    25 public:    
       
    26     int majorDevClass; // major device class value from CoD
       
    27     int minorDevClass; // minor device class value from CoD
       
    28     int majorProperty;   // one of major properties defined in BtDeviceModel
       
    29     int minorProperty;   // one of minor properties defined in BtDeviceModel
       
    30     char* connectedIcon; // the icon name for connected device
       
    31     char* unconnectedIcon; // the icon name for not connected device.
       
    32 };
       
    33 
       
    34 // mapping table from major and minor Device Classes to device types and icons
       
    35 // which are specifically defined in btapplication namespace.
       
    36 // (Note audio device mapping is not in this table due to its complex logic)
       
    37 static const DevTypeIconMapping DeviceTypeIconMappingTable[] =
       
    38 {
       
    39 {EMajorDeviceComputer, 0, BtDeviceModel::Computer, 0, 
       
    40         ":/icons/qgn_prop_bt_computer_connect.svg", ":/icons/qgn_prop_bt_computer.svg" },
       
    41 {EMajorDevicePhone,    0, BtDeviceModel::Phone,    0, 
       
    42         ":/icons/qgn_prop_bt_phone_connect.svg", ":/icons/qgn_prop_bt_phone.svg"},
       
    43 {EMajorDeviceLanAccessPoint, 0, BtDeviceModel::LANAccessDev, 0, 
       
    44         ":/icons/qgn_prop_bt_misc.svg", ":/icons/qgn_prop_bt_misc.svg" },
       
    45 {EMajorDevicePeripheral, EMinorDevicePeripheralKeyboard, 
       
    46         BtDeviceModel::Peripheral, BtDeviceModel::Keyboard,
       
    47         ":/icons/qgn_prop_bt_keyboard_connect.svg", ":/icons/qgn_prop_bt_keyboard.svg"},
       
    48 {EMajorDevicePeripheral, EMinorDevicePeripheralPointer, 
       
    49         BtDeviceModel::Peripheral, BtDeviceModel::Mouse,
       
    50         ":/icons/qgn_prop_bt_mouse_connect.svg", ":/icons/qgn_prop_bt_mouse.svg"},
       
    51 {EMajorDeviceImaging, 0, BtDeviceModel::ImagingDev, 0, 
       
    52         ":/icons/qgn_prop_bt_printer_connect.svg", ":/icons/qgn_prop_bt_printer.svg"},
       
    53 {EMajorDeviceWearable, 0, BtDeviceModel::WearableDev, 0, 
       
    54         ":/icons/qgn_prop_bt_misc.svg", ":/icons/qgn_prop_bt_misc.svg"},
       
    55 {EMajorDeviceToy, 0, BtDeviceModel::Toy, 0,
       
    56         ":/icons/qgn_prop_bt_misc.svg", ":/icons/qgn_prop_bt_misc.svg"},
       
    57 };
       
    58 
       
    59 static const int DeviceTypeIconMappingTableSize = 
       
    60         sizeof( DeviceTypeIconMappingTable ) / sizeof( DevTypeIconMapping );
    20 
    61 
    21 /*!
    62 /*!
    22     Constructor.
    63     Constructor.
    23  */
    64  */
    24 BtDeviceData::BtDeviceData(
    65 BtDeviceData::BtDeviceData( BtDeviceModel& model, QObject *parent )
    25         const QSharedPointer<BtuiModelDataSource> &data,
    66     : QObject( parent ), mModel( model ), mDiscover( 0 )
    26         QObject *parent)
    67 {
    27     : QObject( parent ), mData( data ), mBtengConnMan(0)
    68     mDeviceRepo = 0;
    28 {
    69     isSearchingDevice = false;
    29     TRAP_IGNORE({
    70     TRAP_IGNORE({
    30         mBtengConnMan = CBTEngConnMan::NewL( this );
    71         mDeviceRepo = CBtDevRepository::NewL();
    31         mDeviceRepo = CBtDevRepository::NewL( );
       
    32     });
    72     });
    33     
       
    34     Q_CHECK_PTR( mBtengConnMan );
       
    35     Q_CHECK_PTR( mDeviceRepo );
    73     Q_CHECK_PTR( mDeviceRepo );
       
    74     TRAP_IGNORE( mDeviceRepo->AddObserverL( this ) );
       
    75     
       
    76     if ( mDeviceRepo->IsInitialized() ) {
       
    77         initializeDataStore();
       
    78     }
    36 }
    79 }
    37 
    80 
    38 /*!
    81 /*!
    39     Destructor.
    82     Destructor.
    40  */
    83  */
    41 BtDeviceData::~BtDeviceData()
    84 BtDeviceData::~BtDeviceData()
    42 {
    85 {
    43     delete mBtengConnMan;
       
    44     delete mDeviceRepo;
    86     delete mDeviceRepo;
    45 }
    87     delete mDiscover;
    46 
    88 }
    47 void BtDeviceData::ConnectComplete( TBTDevAddr& addr, TInt err, 
    89 
    48         RBTDevAddrArray* conflicts ) 
    90 
    49 {
    91 /*!
    50     Q_UNUSED( addr );
    92     Tells whether the given column is in the range of the setting list.
    51     Q_UNUSED( err );
    93     
    52     Q_UNUSED( conflicts );
    94     \param row the row number to be checked
    53 }
    95     \param col the column number to be checked
    54 
    96     
    55 void BtDeviceData::DisconnectComplete( TBTDevAddr& addr, TInt err ) 
    97     \return true if the given row and column are valid; false otherwise.
    56 {
    98 */
    57     Q_UNUSED( addr );
    99 bool BtDeviceData::isValid( int row, int column) const
    58     Q_UNUSED( err );
   100 {
    59 }
   101     return row >= 0 && row < mData.count() && column == 0;
    60 
   102 }
    61 void BtDeviceData::BtDeviceDeleted( const TBTDevAddr& addr ) 
   103 
    62 {
   104 /*!
    63     Q_UNUSED( addr );
   105     \return the total amount of rows.
    64 }
   106     
    65 
   107 */
    66 void BtDeviceData::BtDeviceAdded( const CBTDevice& device ) 
   108 int BtDeviceData::rowCount() const
    67 {
   109 {
    68     Q_UNUSED( device );
   110     return mData.count();
    69 }
   111 }
    70 
   112 
    71 void BtDeviceData::BtDeviceChanged( const CBTDevice& device, TUint similarity )
   113 /*!
    72 {
   114     \return the total amount of columns.
    73     Q_UNUSED( device );
   115     
    74     Q_UNUSED( similarity );
   116 */
    75 }
   117 int BtDeviceData::columnCount() const
    76 
   118 {
       
   119     return 1;
       
   120 }
       
   121 
       
   122 /*!
       
   123     Gets the value within a data item.
       
   124     \param val contains the value at return.
       
   125     \param row the row number which the value is from
       
   126     \param col the column number which the value is from
       
   127     \param role the role idenfier of the value.
       
   128  */
       
   129 void BtDeviceData::data(QVariant& val, int row,  int col, int role ) const
       
   130 {
       
   131     if ( isValid( row, col ) ) {
       
   132         val = mData.at( row ).value( role );
       
   133     }
       
   134     else {
       
   135         val = QVariant( QVariant::Invalid );
       
   136     }
       
   137 }
       
   138 
       
   139 /*!
       
   140     Gets the whole item data at the specified column
       
   141     \param row the row number of the item data to be returned
       
   142     \param col the column number of the item data to be returned
       
   143     \return the item data
       
   144  */
       
   145 BtuiModelDataItem BtDeviceData::itemData( int row, int col ) const
       
   146 {
       
   147     if ( isValid( row, col ) ) {
       
   148         return mData.at( row );
       
   149     }
       
   150     return BtuiModelDataItem();
       
   151 }
       
   152 
       
   153 
       
   154 /*!
       
   155     Requests the model to searching Bluetooth devices.
       
   156     \return true if the request is accepted; false otherwise
       
   157  */
       
   158 bool BtDeviceData::searchDevice()
       
   159 {
       
   160     int err ( 0 );
       
   161     removeTransientDevices();
       
   162     if ( !mDiscover ) {
       
   163         TRAP(err, mDiscover = CAdvanceDevDiscoverer::NewL( *mDeviceRepo, *this) );
       
   164     }
       
   165     if ( !err ) {
       
   166         TRAP(err, mDiscover->DiscoverDeviceL() );
       
   167     }
       
   168     isSearchingDevice = true;
       
   169     return err == 0;
       
   170 }
       
   171 
       
   172 /*!
       
   173     Cancels a possible outstanding device search request.
       
   174  */
       
   175 void BtDeviceData::cancelSearchDevice()
       
   176 {
       
   177     if ( mDiscover ) {
       
   178         isSearchingDevice = false;
       
   179         mDiscover->CancelDiscovery();
       
   180     }
       
   181 }
       
   182 
       
   183 /*!
       
   184     Removes transient (not-in-registry) devices 
       
   185     (added as the result of device search).
       
   186  */
       
   187 void BtDeviceData::removeTransientDevices()
       
   188 {
       
   189     // clear in-range property for all device items in this model.
       
   190     int cnt = mData.count();
       
   191     for ( int i = mData.count() - 1; i > -1; --i)
       
   192         {
       
   193         const BtuiModelDataItem& qtdev = mData.at(i);
       
   194         if(isDeviceInRange(qtdev)) {
       
   195             if(isDeviceInRegistry(qtdev)) {
       
   196                 // we cannot remove this device as it is in registry.
       
   197                 // remove it in-range property.
       
   198                 setMajorProperty(mData[i], BtDeviceModel::InRange, false);
       
   199                 updateRssi(mData[i], RssiInvalid);
       
   200                 mModel.emitDataChanged( i, 0, this );
       
   201             }
       
   202             else {
       
   203                 // this device is not in-registry. Delete it from local
       
   204                 // store.
       
   205                 mModel.beginRemoveRows(QModelIndex(), i, i);
       
   206                 mData.removeAt( i );
       
   207                 mModel.endRemoveRows();
       
   208             }
       
   209         }
       
   210     }
       
   211 }
       
   212 
       
   213 /*!
       
   214     callback from repository.
       
   215     re-initialize our store.
       
   216  */
       
   217 void BtDeviceData::RepositoryInitialized() 
       
   218 {
       
   219     initializeDataStore();
       
   220 }
       
   221 
       
   222 /*!
       
   223     callback from repository.
       
   224     update our store.
       
   225  */
       
   226 void BtDeviceData::DeletedFromRegistry( const TBTDevAddr& addr ) 
       
   227 {
       
   228     int i = indexOf( addr );
       
   229     if ( i > -1 ) {
       
   230         if ( isSearchingDevice && isDeviceInRange( mData.at(i) ) ) {
       
   231             // device searching is ongoing, and it is in-range. we can not 
       
   232             // remore it from model now.
       
   233             // clear-registry related properties, so that
       
   234             // we get a chance to clean it after device searching later.
       
   235             setMajorProperty(mData[i], BtDeviceModel::RegistryProperties, false);
       
   236             mModel.emitDataChanged( i, 0, this );
       
   237         }
       
   238         else {
       
   239             mModel.beginRemoveRows(QModelIndex(), i, i);
       
   240             mData.removeAt( i );
       
   241             mModel.endRemoveRows();
       
   242         }
       
   243     }
       
   244 }
       
   245 
       
   246 /*!
       
   247     callback from repository.
       
   248     update our store.
       
   249  */
       
   250 void BtDeviceData::AddedToRegistry( const CBtDevExtension& dev ) 
       
   251 {
       
   252     ChangedInRegistry( dev, 0 );
       
   253 }
       
   254 
       
   255 /*!
       
   256     callback from repository.
       
   257     update our store.
       
   258  */
       
   259 void BtDeviceData::ChangedInRegistry( 
       
   260         const CBtDevExtension& dev, TUint similarity )
       
   261 {
       
   262     int i = indexOf( dev.Addr() );
       
   263     if ( i == -1 ) {
       
   264         BtuiModelDataItem devData;
       
   265         if ( !isSearchingDevice ) {
       
   266             // Rssi is only available at device inquiry stage. 
       
   267             // We initialize this property to an invalid value
       
   268             updateRssi(devData, RssiInvalid);
       
   269         }
       
   270         // add device-in-registry property:
       
   271         setMajorProperty(devData, BtDeviceModel::InRegistry, true);
       
   272         updateDeviceProperty(devData, dev, 0 );
       
   273         mModel.beginInsertRows( QModelIndex(), mData.count(), mData.count() );
       
   274         mData.append( devData );
       
   275         mModel.endInsertRows();
       
   276     }
       
   277     else {
       
   278         updateDeviceProperty(mData[i], dev, similarity );
       
   279         setMajorProperty(mData[i], BtDeviceModel::InRegistry, true);
       
   280         mModel.emitDataChanged( i, 0, this );
       
   281     }
       
   282 }
       
   283 
       
   284 /*!
       
   285     callback from repository.
       
   286     update our store.
       
   287  */
       
   288 void BtDeviceData::ServiceConnectionChanged(
       
   289         const CBtDevExtension& dev, TBool connected )
       
   290 {
       
   291     int i = indexOf( dev.Addr() );
       
   292     if ( i > -1 ) {
       
   293         int preconn =  BtDeviceModel::Connected 
       
   294                 & mData[i][BtDeviceModel::MajorPropertyRole].toInt();
       
   295         // we only update and signal if connection status is really
       
   296         // changed:
       
   297         if ( ( preconn != 0 && !connected )
       
   298             || ( preconn == 0 && connected ) ) {
       
   299             setMajorProperty(mData[i], BtDeviceModel::Connected, connected );
       
   300             mModel.emitDataChanged( i, 0, this );
       
   301         }
       
   302     }
       
   303     // it is impossible that a device has connected but it is not in
       
   304     // our local store according to current bteng services.
       
   305     // need to take more care in future when this becomes possible.
       
   306 }
       
   307 
       
   308 /*!
       
   309     callback from device search.
       
   310     update our store.
       
   311  */
       
   312 void BtDeviceData::HandleNextDiscoveryResultL( 
       
   313         const TInquirySockAddr& inqAddr, const TDesC& name )
       
   314 {
       
   315     int pos = indexOf( inqAddr.BTAddr() );
       
   316     const CBtDevExtension* dev = mDeviceRepo->Device( inqAddr.BTAddr() );
       
   317     
       
   318     //RssiRole
       
   319     int rssi( RssiInvalid ); // initialize to an invalid value.
       
   320     if( inqAddr.ResultFlags() & TInquirySockAddr::ERssiValid ) {
       
   321         rssi = inqAddr.Rssi();
       
   322     }
       
   323     
       
   324     if ( pos == -1 ) {
       
   325         BtuiModelDataItem devData;
       
   326         setMajorProperty(devData, BtDeviceModel::InRange, true);
       
   327         updateRssi(devData, rssi);
       
   328         CBtDevExtension* devExt(NULL);
       
   329         TRAP_IGNORE( {
       
   330             devExt = CBtDevExtension::NewLC( inqAddr, name );
       
   331             CleanupStack::Pop(); });
       
   332         updateDeviceProperty(devData, *devExt, 0);
       
   333         delete devExt;
       
   334         mModel.beginInsertRows( QModelIndex(), mData.count(), mData.count() );
       
   335         mData.append( devData );
       
   336         mModel.endInsertRows();
       
   337     }
       
   338     else {
       
   339         setMajorProperty(mData[pos], BtDeviceModel::InRange, true);
       
   340         updateRssi(mData[pos], rssi);
       
   341         mModel.emitDataChanged( pos, 0, this );
       
   342     }
       
   343 }
       
   344 
       
   345 /*!
       
   346     callback from device search.
       
   347     inform client.
       
   348  */
       
   349 void BtDeviceData::HandleDiscoveryCompleted( TInt error )
       
   350 {
       
   351     isSearchingDevice = false;
       
   352     mModel.emitdeviceSearchCompleted( (int) error );
       
   353 }
       
   354 
       
   355 void BtDeviceData::initializeDataStore()
       
   356     {
       
   357     // it is possible that we are searching devices.
       
   358     // We use a simple but not-so-efficient method to update the model.
       
   359     
       
   360     // If the device store is not empty, we clear
       
   361     // registry property from these devices first.
       
   362     for (int i = 0; i < mData.count(); ++i) {
       
   363         setMajorProperty(mData[i], BtDeviceModel::RegistryProperties, false);
       
   364     }
       
   365     if ( mData.count() ) {
       
   366         // need to update view because we have changed device properties.
       
   367         QModelIndex top = mModel.createIndex(0, 0, this);
       
   368         QModelIndex bottom = mModel.createIndex(mData.count() - 1, 0, this);
       
   369         mModel.emitDataChanged( top, bottom );
       
   370     }
       
   371 
       
   372     const RDevExtensionArray& devs = mDeviceRepo->AllDevices();
       
   373     for (int i = 0; i < devs.Count(); ++i) {
       
   374         int pos = indexOf( devs[i]->Addr() );
       
   375         if ( pos > -1 ) {
       
   376             // add device-in-registry property:
       
   377             setMajorProperty(mData[pos], BtDeviceModel::InRegistry, true);            
       
   378             updateDeviceProperty(mData[pos], *(devs[i]), 0);
       
   379             mModel.emitDataChanged( pos, 0, this );
       
   380         }
       
   381         else {
       
   382             BtuiModelDataItem devData;
       
   383             // add device-in-registry property:
       
   384             setMajorProperty(devData, BtDeviceModel::InRegistry, true);
       
   385             updateDeviceProperty(devData, *( devs[i] ), 0 );
       
   386             mModel.beginInsertRows(QModelIndex(), mData.count(), mData.count() );
       
   387             mData.append( devData );
       
   388             mModel.endInsertRows();
       
   389         }
       
   390     }
       
   391 }
       
   392 
       
   393 void BtDeviceData::updateDeviceProperty(BtuiModelDataItem& qtdev,
       
   394         const CBtDevExtension& dev, TUint similarity )
       
   395 {
       
   396     // similarity is not used currently. 
       
   397     // It is possible to gain better performance
       
   398     // with this info to avoid re-manipulate
       
   399     // unchanged properties.
       
   400     Q_UNUSED(similarity);
       
   401     
       
   402     //DevDisplayNameRole
       
   403     QString str = QString::fromUtf16( 
       
   404             dev.Alias().Ptr(), dev.Alias().Length() );
       
   405     qtdev[BtDeviceModel::NameAliasRole] = QVariant( str );
       
   406 
       
   407     //DevAddrReadableRole
       
   408     addrSymbianToReadbleString( str, dev.Addr() );
       
   409     qtdev[BtDeviceModel::ReadableBdaddrRole] = QVariant( str );
       
   410 
       
   411     //LastUsedTimeRole
       
   412     TDateTime symDt = dev.Device().Used().DateTime();
       
   413     QDate date( symDt.Year(), symDt.Month(), symDt.Day() );
       
   414     QTime time( symDt.Hour(), symDt.Minute(), symDt.MicroSecond() / 1000 );
       
   415     QDateTime qdt(date, time);
       
   416     qtdev[BtDeviceModel::LastUsedTimeRole] = QVariant(qdt);
       
   417  
       
   418     // set paired status:
       
   419     setMajorProperty(qtdev, BtDeviceModel::Bonded, isBonded( dev.Device() ));
       
   420     
       
   421     // set blocked status:
       
   422     setMajorProperty(qtdev, BtDeviceModel::Blocked, 
       
   423             dev.Device().GlobalSecurity().Banned() );
       
   424     // set trusted status:
       
   425     setMajorProperty(qtdev, BtDeviceModel::Trusted, 
       
   426             dev.Device().GlobalSecurity().NoAuthorise() );
       
   427 
       
   428     //CoDRole
       
   429     //MinorPropertyRole
       
   430     int cod = static_cast<int>( dev.Device().DeviceClass().DeviceClass() );
       
   431     qtdev[BtDeviceModel::CoDRole] = QVariant(cod);
       
   432     
       
   433     // Initially, clear CoD related properties:
       
   434     int majorProperty = qtdev[BtDeviceModel::MajorPropertyRole].toInt() & 
       
   435         ~BtDeviceModel::CodProperties;
       
   436     
       
   437     int minorProperty = BtDeviceModel::NullProperty;
       
   438     
       
   439     // device type must be mapped according to CoD:
       
   440     int majorDevCls = dev.Device().DeviceClass().MajorDeviceClass();
       
   441     int minorDevCls = dev.Device().DeviceClass().MinorDeviceClass();
       
   442 
       
   443     int i;
       
   444     for (i = 0; i < DeviceTypeIconMappingTableSize; ++i ) {
       
   445         if ( DeviceTypeIconMappingTable[i].majorDevClass == majorDevCls &&
       
   446              ( DeviceTypeIconMappingTable[i].minorDevClass == 0 || 
       
   447                DeviceTypeIconMappingTable[i].minorDevClass == minorDevCls ) ) {
       
   448              // device classes match a item in table, get the mapping:
       
   449             majorProperty |= DeviceTypeIconMappingTable[i].majorProperty;
       
   450             minorProperty |= DeviceTypeIconMappingTable[i].minorProperty;
       
   451             break;
       
   452          }
       
   453     }
       
   454     
       
   455     // AV device mapping are not defined in the table, do mapping here if no device
       
   456     // type mapped so far:
       
   457     if ( i == DeviceTypeIconMappingTableSize) {
       
   458         // audio device, carkit, headset or speaker:
       
   459         if( ( majorDevCls == EMajorDeviceAV) 
       
   460             || (dev.Device().DeviceClass().MajorServiceClass() == EMajorServiceRendering 
       
   461             && majorDevCls != EMajorDeviceImaging) ) {
       
   462             
       
   463             majorProperty |= BtDeviceModel::AVDev;
       
   464             
       
   465             if( minorDevCls == EMinorDeviceAVCarAudio ) {
       
   466                 // carkit:
       
   467                 minorProperty |= BtDeviceModel::Carkit; 
       
   468             }
       
   469             else {
       
   470                 // headset:
       
   471                 minorProperty |= BtDeviceModel::Headset;
       
   472             }
       
   473         }
       
   474     }
       
   475     
       
   476     qtdev[BtDeviceModel::MajorPropertyRole] = QVariant( majorProperty );
       
   477     qtdev[BtDeviceModel::MinorPropertyRole] = QVariant( minorProperty );
       
   478 }
       
   479 
       
   480 int BtDeviceData::indexOf( const TBTDevAddr& addr ) const
       
   481 {
       
   482     QString addrStr;
       
   483     addrSymbianToReadbleString( addrStr, addr );
       
   484     for (int i = 0; i < mData.count(); ++i ) {
       
   485         if ( mData.at( i ).value( BtDeviceModel::ReadableBdaddrRole ) 
       
   486                 == addrStr ) {
       
   487             return i;
       
   488         }
       
   489     }
       
   490     return -1;
       
   491 }
       
   492 
       
   493 void BtDeviceData::updateRssi(BtuiModelDataItem& qtdev, int rssi )
       
   494     {
       
   495     qtdev[BtDeviceModel::RssiRole] = QVariant( rssi );
       
   496     }
       
   497 
       
   498 /*!
       
   499     Add the specified major property to the device if addto is true.
       
   500     Otherwise the property is removed from the device. 
       
   501  */
       
   502 void BtDeviceData::setMajorProperty(
       
   503         BtuiModelDataItem& qtdev, int prop, bool addto)
       
   504 {
       
   505     if ( addto ) {
       
   506         qtdev[BtDeviceModel::MajorPropertyRole] = 
       
   507             QVariant( qtdev[BtDeviceModel::MajorPropertyRole].toInt() | prop);
       
   508     }
       
   509     else {
       
   510         qtdev[BtDeviceModel::MajorPropertyRole] = 
       
   511             QVariant( qtdev[BtDeviceModel::MajorPropertyRole].toInt() & ~prop);
       
   512     }
       
   513 }
       
   514 
       
   515 bool BtDeviceData::isDeviceInRange( const BtuiModelDataItem& qtdev )
       
   516 {   
       
   517     return BtDeviceModel::InRange & qtdev[BtDeviceModel::MajorPropertyRole].toInt();
       
   518 }
       
   519 
       
   520 bool BtDeviceData::isDeviceInRegistry( const BtuiModelDataItem& qtdev )
       
   521 {
       
   522     return BtDeviceModel::InRegistry & qtdev[BtDeviceModel::MajorPropertyRole].toInt();
       
   523 }