--- kdebluetooth/kbluetoothd/kcm_btpaired/filesettingsbase.ui +++ kdebluetooth/kbluetoothd/kcm_btpaired/filesettingsbase.ui @@ -1,4 +1,4 @@ - + FileSettingsBase @@ -24,7 +24,7 @@ textLabel3 - Here you have to specify the correct start/stop commands for BlueZ's <i>hcid</i> and the location of BlueZ's <i>link_key</i> file for the distribution you are using. + Here you have to specify the correct start/stop commands for BlueZ's <i>hcid</i> and the directory of the BlueZ's <i>link_key</i> files for the distribution you are using. WordBreak|AlignVCenter @@ -123,7 +123,7 @@ textLabel1_2 - Link key file: + Link key directory: @@ -138,6 +138,9 @@ 0 + + 26 + --- kdebluetooth/kbluetoothd/kcm_btpaired/pairedtab.cpp +++ kdebluetooth/kbluetoothd/kcm_btpaired/pairedtab.cpp @@ -44,6 +44,7 @@ using namespace std; using namespace KBluetooth; +/* linkkey file is now ASCII format struct HcidLinkKeyStruct { bdaddr_t sba; bdaddr_t dba; @@ -54,19 +55,17 @@ uint8_t type; time_t time; }; +*/ PairedTab::PairedTab(QWidget *parent, const char* name) : PairedTabBase(parent, name) { KConfig* config = KApplication::kApplication()->config(); - linkKeyFilename = config->readEntry("linkKeyFile", "/etc/bluetooth/link_key"); - config->writeEntry("linkKeyFile", linkKeyFilename); - hcidStartCommand = config->readEntry("hcidStartCommand", "/etc/init.d/bluez-utils start"); - hcidStopCommand = config->readEntry("hcidStopCommand", "/etc/init.d/bluez-utils stop"); + linkKeyPath = config->readEntry("linkKeyPath", "/var/lib/bluetooth/"); + config->writeEntry("linkKeyPath", linkKeyPath); + hcidStartCommand = config->readEntry("hcidStartCommand", "/etc/init.d/bluetooth start"); + hcidStopCommand = config->readEntry("hcidStopCommand", "/etc/init.d/bluetooth stop"); bDirty = false; - linkKeyFileValid = false; - reloadList(); - updateGUI(); linkKeyFileWatch = new KDirWatch(this); connect(linkKeyFileWatch, SIGNAL(dirty(const QString&)), this, SLOT(slotKeyFileChanged())); @@ -84,13 +83,51 @@ baseDialog->hide(); connect(baseDialog, SIGNAL(applyClicked()), this, SLOT(slotApplyFileSettings())); connect(baseDialog, SIGNAL(okClicked()), this, SLOT(slotApplyFileSettings())); + + watchKeys(); - linkKeyFileWatch->addFile(linkKeyFilename); linkKeyFileWatch->startScan(true, true); + + reloadList(); + updateGUI(); +} + +void PairedTab::watchKeys() { + + kdDebug() << "watchKeys()" << endl; + + QDir keyDir(linkKeyPath); + keyDir.setFilter( QDir::Dirs ); + keyDir.setNameFilter("*:*:*:*:*"); + + QFileInfo *fi; + const QFileInfoList *list = keyDir.entryInfoList(); + QFileInfoListIterator it(*list); + + linkKeyFilename.clear(); + + while ((fi = it.current()) != 0) { + + QString btDeviceDir = fi->fileName(); + QString filename = keyDir.absPath(); + filename.append("/").append(btDeviceDir).append("/").append("linkkeys"); + + QFile keyFile(filename); + + if (keyFile.exists()) { + linkKeyFileWatch->addFile(filename); + linkKeyFilename.append(filename); + } + + ++it; + } } void PairedTab::reloadList() { + + kdDebug() << "relodList()" << endl; + if (bDirty) { if (KMessageBox::warningContinueCancel(this, i18n( "The link key file has changed on disk. Do you want to reload the table and \ @@ -98,82 +135,96 @@ return; } } - - QFile file(linkKeyFilename); - - kdDebug() << "reloadList()" << endl; pairingList.clear(); - linkKeyFileValid = false; - if (file.open(IO_ReadOnly)) { - linkKeyFileValid = true; - bool readSizeMismatch = false; - while (true) { - PairingInfo newInfo; - HcidLinkKeyStruct linkKeyStruct; - int rSize = 0; - if ((rSize = file.readBlock((char*)&linkKeyStruct, sizeof(HcidLinkKeyStruct))) - == sizeof(HcidLinkKeyStruct)) - { - newInfo.localAddr = DeviceAddress(linkKeyStruct.sba); - newInfo.remoteAddr = DeviceAddress(linkKeyStruct.dba); - newInfo.time.setTime_t(linkKeyStruct.time); - newInfo.type = linkKeyStruct.type; - for (int n=0; n<16; ++n) { - newInfo.linkKey[n] = linkKeyStruct.key[n]; - } - newInfo.remoteName = QString(newInfo.remoteAddr); - NameCache::getCachedName(newInfo.remoteAddr, newInfo.remoteName); - newInfo.remoteClass = 0; - NameCache::getCachedClass(newInfo.remoteAddr, newInfo.remoteClass); - pairingList.push_back(newInfo); - } - else { - if (rSize != 0) { - readSizeMismatch = true; - } - break; - } - kdDebug() << "localAddr read:" << QString(newInfo.localAddr) << endl; - } - - linkKeyFileValid = !readSizeMismatch; - file.close(); + + QStringList::iterator it; + for (it = linkKeyFilename.begin(); it != linkKeyFilename.end(); ++it) { + + QFile file((*it)); + + if (file.open(IO_ReadOnly)) { + + QTextStream stream(&file); + QString line, localAddr, remoteAddr, symLink, remoteClass; + + while (!stream.atEnd()) { + PairingInfo newInfo; + + line = stream.readLine(); + + QFileInfo fi(file); + QDir dir(fi.dir()); + localAddr = dir.dirName(); + + remoteAddr = line.left(17); + + newInfo.localAddr = DeviceAddress(localAddr); + newInfo.remoteAddr = DeviceAddress(remoteAddr); + + // XXX: not provided by linkkey file at the moment + // newInfo.time.setTime_t(linkKeyStruct.time); + + newInfo.linkKey = line.mid(18, 32); + + newInfo.remoteName = QString(newInfo.remoteAddr); + NameCache::getCachedName(newInfo.remoteAddr, newInfo.remoteName); + + newInfo.remoteClass = 0; // not provided by linkkey file at the moment(?) FIXME + + NameCache::getCachedClass(newInfo.remoteAddr, newInfo.remoteClass); + pairingList.push_back(newInfo); + } + + file.close(); + } } } bool PairedTab::saveList() { + kdDebug() << "saveList()" << endl; + if (bDirty == false) return true; - kdDebug() << "saveList()" << endl; - if (!stopDaemon()) return false; - - QFile file(linkKeyFilename); - if (file.open(IO_WriteOnly)) { - for (unsigned int n=0; n(&info), sizeof(info)); - } - file.close(); - - if (!startDaemon()) return false; - bDirty = false; - return true; + QStringList::iterator it; + for (it = linkKeyFilename.begin(); it != linkKeyFilename.end(); ++it) { + + QFile file((*it)); + QFileInfo fi(file); + QDir deviceDir(fi.dir()); + + // clear linkkey file + file.remove(); + + if (file.open(IO_WriteOnly)) { + QTextStream stream(&file); + for (unsigned int n=0; n::iterator pairIt; + kdDebug() << "updateGUI()" << endl; + vector::iterator pairIt, remoteIt; + KBluetooth::DeviceAddress prevLocalAddr; + QListViewItem *viewItem = NULL; pairingListView->clear(); for (pairIt = pairingList.begin(); pairIt != pairingList.end(); ++pairIt) { - QListViewItem *viewItem = new QListViewItem(pairingListView); - pairIt->listViewItem = viewItem; - - viewItem->setText(0, QString(pairIt->remoteName)); - QListViewItem *remoteAddrItem = new QListViewItem(viewItem); - remoteAddrItem->setPixmap(0, KGlobal::iconLoader()->loadIcon( - "pda_blue", KIcon::Small, 16)); - remoteAddrItem->setSelectable(false); - remoteAddrItem->setText(0, QString(pairIt->remoteAddr)); - - QListViewItem *localAddrItem = new QListViewItem(viewItem); - localAddrItem->setPixmap(0, KGlobal::iconLoader()->loadIcon( - "usbpendrive_unmount", KIcon::Small, 16)); - localAddrItem->setSelectable(false); - localAddrItem->setText(0, QString(pairIt->localAddr)); - + + if (prevLocalAddr != pairIt->localAddr) { + kdDebug() << ">> " << pairIt->localAddr << endl; + viewItem = new QListViewItem(pairingListView); + viewItem->setSelectable(false); + viewItem->setText(0, QString(pairIt->localAddr)); + viewItem->setOpen(true); + viewItem->setPixmap(0, KGlobal::iconLoader()->loadIcon( + "usbpendrive_unmount", KIcon::Small, 16)); + } + + + remoteIt = pairIt; + if (remoteIt->localAddr == pairIt->localAddr) { + kdDebug() << "\t>> " << remoteIt->remoteAddr << endl; + QListViewItem *remoteAddrItem = new QListViewItem(viewItem); + remoteIt->listViewItem = remoteAddrItem; + QString iconName = DeviceClassMimeConverter::classToIconName(remoteIt->remoteClass); + remoteAddrItem->setPixmap(0, KGlobal::iconLoader()->loadIcon( + iconName, KIcon::Small, 16)); + + remoteAddrItem->setSelectable(true); + + kdDebug() << "remoteName: " << remoteIt->remoteName << endl; + if (remoteIt->remoteName == remoteIt->remoteAddr) + remoteAddrItem->setText(0, QString(remoteIt->remoteAddr)); + else + remoteAddrItem->setText(0, QString(remoteIt->remoteAddr).append(" / ").append(remoteIt->remoteName)); + } + + + /* not provided by the linkkey file at the moment + QListViewItem *timeItem = new QListViewItem(viewItem); timeItem->setPixmap(0, KGlobal::iconLoader()->loadIcon( "clock", KIcon::Small, 16)); timeItem->setSelectable(false); timeItem->setText(0, pairIt->time.toString()); + */ + prevLocalAddr = pairIt->localAddr; - QString iconName = DeviceClassMimeConverter::classToIconName(pairIt->remoteClass); - viewItem->setPixmap(0, KGlobal::iconLoader()->loadIcon( - iconName, KIcon::Small, 16)); } } @@ -232,9 +302,14 @@ void PairedTab::slotRemovePairing() { + kdDebug() << "slotRemovePairing()" << endl; bool bDirty = false; + kdDebug() << "list size: " << pairingList.size() << endl; for (int n=pairingList.size()-1; n>=0; --n) { + kdDebug() << n << " remote: " << pairingList[n].remoteAddr << pairingList[n].listViewItem->text(0) << pairingList[n].listViewItem->isSelected() << endl; if (pairingList[n].listViewItem->isSelected()) { + kdDebug() << "erase pair: " << n << endl; + pairingList.erase(pairingList.begin()+n); bDirty = true; } @@ -248,20 +323,22 @@ void PairedTab::slotSelectionChanged() { - for (QListViewItem* i=pairingListView->firstChild(); i != NULL; - i = i->nextSibling()) - { - if (i->isSelected()) { - removePairingButton->setEnabled(true); - return; - } + for (QListViewItem* i=pairingListView->firstChild(); i != NULL; i = i->nextSibling()) { + for (QListViewItem *child=i->firstChild(); child != NULL; child = child->nextSibling()) + { + if (child->isSelected()) { + removePairingButton->setEnabled(true); + return; + } + } } + removePairingButton->setEnabled(false); } void PairedTab::slotFileSettings() { - fileSettingsDialog->linkKeyFileEdit->setURL(linkKeyFilename); + fileSettingsDialog->linkKeyFileEdit->setURL(linkKeyPath); fileSettingsDialog->startCommandEdit->setURL(hcidStartCommand); fileSettingsDialog->stopCommandEdit->setURL(hcidStopCommand); @@ -270,20 +347,26 @@ void PairedTab::slotApplyFileSettings() { - linkKeyFileWatch->removeFile(linkKeyFilename); + QStringList::iterator it; + for (it = linkKeyFilename.begin(); it != linkKeyFilename.end(); ++it) { + linkKeyFileWatch->removeFile((*it)); + } - linkKeyFilename = fileSettingsDialog->linkKeyFileEdit->url(); + linkKeyPath = fileSettingsDialog->linkKeyFileEdit->url(); hcidStartCommand = fileSettingsDialog->startCommandEdit->url(); hcidStopCommand = fileSettingsDialog->stopCommandEdit->url(); + + kdDebug() << "keypath: " << fileSettingsDialog->linkKeyFileEdit->url() << endl; KConfig* config = KApplication::kApplication()->config(); - config->writeEntry("linkKeyFile", linkKeyFilename); + config->writeEntry("linkKeyPath", linkKeyPath); config->writeEntry("hcidStartCommand", hcidStartCommand); config->writeEntry("hcidStopCommand", hcidStopCommand); + + watchKeys(); + reloadList(); updateGUI(); - - linkKeyFileWatch->addFile(linkKeyFilename); } --- kdebluetooth/kbluetoothd/kcm_btpaired/pairedtab.h +++ kdebluetooth/kbluetoothd/kcm_btpaired/pairedtab.h @@ -43,7 +43,7 @@ KBluetooth::DeviceAddress remoteAddr; QString remoteName; int remoteClass; - uint8_t linkKey[16]; + QString linkKey; uint8_t type; QDateTime time; QListViewItem *listViewItem; @@ -52,12 +52,14 @@ bool linkKeyFileValid; bool bDirty; - QString linkKeyFilename; + QValueList linkKeyFilename; + QString linkKeyPath; QString hcidStartCommand; QString hcidStopCommand; KDirWatch *linkKeyFileWatch; FileSettingsBase *fileSettingsDialog; + void watchKeys(); void reloadList(); bool saveList(); bool startDaemon();