00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "solid-bluetooth.h"
00021
00022
00023 #include <QString>
00024 #include <QStringList>
00025 #include <QMetaProperty>
00026 #include <QMetaEnum>
00027 #include <QTimer>
00028
00029 #include <kcomponentdata.h>
00030 #include <kcmdlineargs.h>
00031 #include <klocale.h>
00032 #include <k3socketaddress.h>
00033 #include <kdebug.h>
00034
00035 #include <solid/device.h>
00036 #include <solid/genericinterface.h>
00037 #include <solid/storageaccess.h>
00038 #include <solid/opticaldrive.h>
00039
00040 #include <solid/control/bluetoothmanager.h>
00041 #include <solid/control/bluetoothinterface.h>
00042 #include <solid/control/bluetoothremotedevice.h>
00043 #include <solid/control/bluetoothinputdevice.h>
00044
00045 #include <kjob.h>
00046
00047
00048 #include <iostream>
00049 using namespace std;
00050
00051 static const char appName[] = "solid-bluetooth";
00052 static const char programName[] = I18N_NOOP("solid-bluetooth");
00053
00054 static const char description[] = I18N_NOOP("KDE tool for querying and controlling your hardware from the command line");
00055
00056 static const char version[] = "0.1";
00057
00058 std::ostream &operator<<(std::ostream &out, const QString &msg)
00059 {
00060 return (out << msg.toLocal8Bit().constData());
00061 }
00062
00063 std::ostream &operator<<(std::ostream &out, const QVariant &value)
00064 {
00065 switch (value.type())
00066 {
00067 case QVariant::StringList:
00068 {
00069 out << "{";
00070
00071 QStringList list = value.toStringList();
00072
00073 QStringList::ConstIterator it = list.begin();
00074 QStringList::ConstIterator end = list.end();
00075
00076 for (; it!=end; ++it)
00077 {
00078 out << "'" << *it << "'";
00079
00080 if (it+1!=end)
00081 {
00082 out << ", ";
00083 }
00084 }
00085
00086 out << "} (string list)";
00087 break;
00088 }
00089 case QVariant::Bool:
00090 out << (value.toBool()?"true":"false") << " (bool)";
00091 break;
00092 case QVariant::Int:
00093 out << value.toString()
00094 << " (0x" << QString::number(value.toInt(), 16) << ") (int)";
00095 break;
00096 default:
00097 out << "'" << value.toString() << "' (string)";
00098 break;
00099 }
00100
00101 return out;
00102 }
00103
00104 std::ostream &operator<<(std::ostream &out, const Solid::Device &device)
00105 {
00106 out << " parent = " << QVariant(device.parentUdi()) << endl;
00107 out << " vendor = " << QVariant(device.vendor()) << endl;
00108 out << " product = " << QVariant(device.product()) << endl;
00109
00110 int index = Solid::DeviceInterface::staticMetaObject.indexOfEnumerator("Type");
00111 QMetaEnum typeEnum = Solid::DeviceInterface::staticMetaObject.enumerator(index);
00112
00113 for (int i=0; i<typeEnum.keyCount(); i++)
00114 {
00115 Solid::DeviceInterface::Type type = (Solid::DeviceInterface::Type)typeEnum.value(i);
00116 const Solid::DeviceInterface *interface = device.asDeviceInterface(type);
00117
00118 if (interface)
00119 {
00120 const QMetaObject *meta = interface->metaObject();
00121
00122 for (int i=meta->propertyOffset(); i<meta->propertyCount(); i++)
00123 {
00124 QMetaProperty property = meta->property(i);
00125 out << " " << QString(meta->className()).mid(7) << "." << property.name()
00126 << " = ";
00127
00128 QVariant value = property.read(interface);
00129
00130 if (property.isEnumType()) {
00131 QMetaEnum metaEnum = property.enumerator();
00132 out << "'" << metaEnum.valueToKeys(value.toInt()).constData() << "'"
00133 << " (0x" << QString::number(value.toInt(), 16) << ") ";
00134 if (metaEnum.isFlag()) {
00135 out << "(flag)";
00136 } else {
00137 out << "(enum)";
00138 }
00139 out << endl;
00140 } else {
00141 out << value << endl;
00142 }
00143 }
00144 }
00145 }
00146
00147 return out;
00148 }
00149
00150 std::ostream &operator<<(std::ostream &out, const QMap<QString,QVariant> &properties)
00151 {
00152 foreach (QString key, properties.keys())
00153 {
00154 out << " " << key << " = " << properties[key] << endl;
00155 }
00156
00157 return out;
00158 }
00159
00160 void checkArgumentCount(int min, int max)
00161 {
00162 int count = KCmdLineArgs::parsedArgs()->count();
00163
00164 if (count < min)
00165 {
00166 cerr << i18n("Syntax Error: Not enough arguments") << endl;
00167 ::exit(1);
00168 }
00169
00170 if ((max > 0) && (count > max))
00171 {
00172 cerr << i18n("Syntax Error: Too many arguments") << endl;
00173 ::exit(1);
00174 }
00175 }
00176
00177 int main(int argc, char **argv)
00178 {
00179 KCmdLineArgs::init(argc, argv, appName, 0, ki18n(programName), version, ki18n(description), false);
00180
00181
00182 KCmdLineOptions options;
00183
00184 options.add("commands", ki18n("Show available commands by domains"));
00185
00186 options.add("+command", ki18n("Command (see --commands)"));
00187
00188 options.add("+[arg(s)]", ki18n("Arguments for command"));
00189
00190 KCmdLineArgs::addCmdLineOptions(options);
00191
00192 KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
00193
00194 KComponentData componentData(appName);
00195
00196 if (args->isSet("commands"))
00197 {
00198 KCmdLineArgs::enable_i18n();
00199
00200 cout << endl << i18n("Syntax:") << endl << endl;
00201
00202 cout << " solid-bluetooth listadapters" << endl;
00203 cout << i18n(" # List bluetooth adapters/interfaces\n") << endl;
00204
00205 cout << " solid-bluetooth defaultadapter" << endl;
00206 cout << i18n(" # List bluetooth default adapter/interface\n") << endl;
00207
00208 cout << " solid-bluetooth getremotename (interface 'ubi') 'remote-mac'" << endl;
00209 cout << i18n(" # Query the name from the remote device 'remote-mac' with 'ubi'\n") << endl;
00210
00211 cout << " solid-bluetooth query (address|bondings|connections|name) (interface 'ubi')" << endl;
00212 cout << i18n(" # Query information about the bluetooth adapter/interface with 'ubi'\n") << endl;
00213
00214 cout << " solid-bluetooth set (mode|name) (interface 'ubi') 'value'" << endl;
00215 cout << i18n(" # Set the bluetooth adapter name.\n"
00216 " # Set the bluetooth adapter mode. Where 'value' is one of:\n"
00217 " # off|connectable|discoverable\n") << endl;
00218
00219 cout << " solid-bluetooth scan (interface 'ubi')" << endl;
00220 cout << i18n(" # Scan for bluetooth remote devices.\n") << endl;
00221
00222 cout << " solid-bluetooth input listdevices" << endl;
00223 cout << i18n(" # List configured input devices.\n") << endl;
00224
00225 cout << " solid-bluetooth input (setup|remove|connect|disconnect) (device 'ubi')" << endl;
00226 cout << i18n(" # Setup bluetooth input device.\n"
00227 " # Remove configuration of remote input device.\n"
00228 " # Connect or disconnect bluetooth input device.\n") << endl;
00229
00230 cout << " solid-bluetooth remote (createbonding|removebonding|hasbonding) (device 'ubi')" << endl;
00231 cout << i18n(" # Create bonding (pairing) with bluetooth remote device.\n"
00232 " # Remove bonding of bluetooth remote device.\n"
00233 " # Check for bonding of bluetooth remote device.\n") << endl;
00234
00235 return 0;
00236 }
00237
00238 return SolidBluetooth::doIt() ? 0 : 1;
00239 }
00240
00241 bool SolidBluetooth::doIt()
00242 {
00243 KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
00244 checkArgumentCount(1, 0);
00245
00246 QString command(args->arg(0));
00247
00248 int fake_argc = 0;
00249 char **fake_argv = 0;
00250 SolidBluetooth shell(fake_argc, fake_argv);
00251
00252 if (command == "listadapters")
00253 {
00254 return shell.bluetoothListAdapters();
00255 }
00256 else if (command == "defaultadapter")
00257 {
00258 return shell.bluetoothDefaultAdapter();
00259 }
00260 else if (command == "getremotename")
00261 {
00262 checkArgumentCount(3, 3);
00263 QString adapterUbi(args->arg(1));
00264 QString mac(args->arg(2));
00265 return shell.bluetoothGetRemoteName(adapterUbi, mac);
00266 }
00267 else if (command == "set")
00268 {
00269 checkArgumentCount(4, 4);
00270 QString what(args->arg(1));
00271 QString ubi(args->arg(2));
00272 QString value(args->arg(3));
00273
00274 if (what == "name")
00275 {
00276 return shell.bluetoothAdapterSetName(ubi, value);
00277 }
00278 else if (what == "mode")
00279 {
00280 return shell.bluetoothAdapterSetMode(ubi, value);
00281 }
00282
00283 }
00284 else if (command == "query")
00285 {
00286 checkArgumentCount(3, 3);
00287 QString what(args->arg(1));
00288 QString ubi(args->arg(2));
00289
00290 if (what == "mode")
00291 {
00292 return shell.bluetoothAdapterMode(ubi);
00293 }
00294 else if (what == "address")
00295 {
00296 return shell.bluetoothAdapterAddress(ubi);
00297 }
00298 else if (what == "name")
00299 {
00300 return shell.bluetoothAdapterName(ubi);
00301 }
00302 else if (what == "connections")
00303 {
00304 return shell.bluetoothAdapterListConnections(ubi);
00305 }
00306 else if (what == "bondings")
00307 {
00308 return shell.bluetoothAdapterListBondings(ubi);
00309 }
00310
00311 }
00312 else if (command == "scan")
00313 {
00314 checkArgumentCount(2, 2);
00315 QString ubi (args->arg(1));
00316 return shell.bluetoothAdapterScan(ubi);
00317 }
00318 else if (command == "input")
00319 {
00320 checkArgumentCount(2, 3);
00321 QString what (args->arg(1));
00322
00323 if (what == "listdevices")
00324 {
00325 return shell.bluetoothInputListDevices();
00326 }
00327
00328 checkArgumentCount(3, 3);
00329 QString ubi (args->arg(2));
00330
00331 if (what == "setup")
00332 {
00333 return shell.bluetoothInputSetup(ubi);
00334 }
00335 else if (what == "remove")
00336 {
00337 return shell.bluetoothInputRemoveSetup(ubi);
00338 }
00339 else if (what == "connect")
00340 {
00341 return shell.bluetoothInputConnect(ubi);
00342 }
00343 else if (what == "disconnect")
00344 {
00345 return shell.bluetoothInputDisconnect(ubi);
00346 }
00347 }
00348 else if (command == "remote" && args->count() >= 3)
00349 {
00350 checkArgumentCount(4, 4);
00351 QString what (args->arg(1));
00352 QString adapter (args->arg(2));
00353 QString remote (args->arg(3));
00354
00355 if (what == "createbonding")
00356 {
00357 return shell.bluetoothRemoteCreateBonding(adapter, remote);
00358 }
00359 else if (what == "removebonding")
00360 {
00361 return shell.bluetoothRemoteRemoveBonding(adapter, remote);
00362 }
00363 else if (what == "hasbonding")
00364 {
00365 return shell.bluetoothRemoteHasBonding(adapter, remote);
00366 }
00367
00368 }
00369 else
00370 {
00371 cerr << i18n("Syntax Error: Unknown command '%1'" , command) << endl;
00372 }
00373
00374 return false;
00375 }
00376
00377 bool SolidBluetooth::bluetoothListAdapters()
00378 {
00379 Solid::Control::BluetoothManager &manager = Solid::Control::BluetoothManager::self();
00380
00381 const Solid::Control::BluetoothInterfaceList all = manager.bluetoothInterfaces();
00382
00383 foreach (const Solid::Control::BluetoothInterface device, all)
00384 {
00385 cout << "UBI = '" << device.ubi() << "'" << endl;
00386 }
00387 return true;
00388 }
00389
00390 bool SolidBluetooth::bluetoothDefaultAdapter()
00391 {
00392 Solid::Control::BluetoothManager &manager = Solid::Control::BluetoothManager::self();
00393
00394 cout << "UBI = '" << manager.defaultInterface() << "'" << endl;
00395
00396 return true;
00397 }
00398
00399 bool SolidBluetooth::bluetoothGetRemoteName(const QString &adapterUbi, const QString &mac)
00400 {
00401 Solid::Control::BluetoothManager &manager = Solid::Control::BluetoothManager::self();
00402 Solid::Control::BluetoothInterface adapter = manager.findBluetoothInterface(adapterUbi);
00403
00404 cout << "Name = '" << adapter.getRemoteName(mac) << "'" << endl;
00405
00406 return true;
00407 }
00408
00409 bool SolidBluetooth::bluetoothAdapterAddress(const QString &ubi)
00410 {
00411 Solid::Control::BluetoothManager &manager = Solid::Control::BluetoothManager::self();
00412 Solid::Control::BluetoothInterface adapter = manager.findBluetoothInterface(ubi);
00413
00414 cout << "'" << adapter.address() << "'" << endl;
00415
00416 return true;
00417 }
00418
00419 bool SolidBluetooth::bluetoothAdapterName(const QString &ubi)
00420 {
00421 Solid::Control::BluetoothManager &manager = Solid::Control::BluetoothManager::self();
00422 Solid::Control::BluetoothInterface adapter = manager.findBluetoothInterface(ubi);
00423
00424 cout << "'" << adapter.name() << "'" << endl;
00425
00426 return true;
00427 }
00428
00429 bool SolidBluetooth::bluetoothAdapterSetName(const QString &ubi, const QString &name)
00430 {
00431 Solid::Control::BluetoothManager &manager = Solid::Control::BluetoothManager::self();
00432 Solid::Control::BluetoothInterface adapter = manager.findBluetoothInterface(ubi);
00433
00434 adapter.setName(name);
00435
00436 return true;
00437 }
00438
00439 bool SolidBluetooth::bluetoothAdapterMode(const QString &ubi)
00440 {
00441 Solid::Control::BluetoothManager &manager = Solid::Control::BluetoothManager::self();
00442 Solid::Control::BluetoothInterface adapter = manager.findBluetoothInterface(ubi);
00443
00444 cout << "'" << adapter.mode() << "'" << endl;
00445
00446 return true;
00447 }
00448
00449 bool SolidBluetooth::bluetoothAdapterSetMode(const QString &ubi, const QString &mode)
00450 {
00451 Solid::Control::BluetoothManager &manager = Solid::Control::BluetoothManager::self();
00452 Solid::Control::BluetoothInterface adapter = manager.findBluetoothInterface(ubi);
00453 Solid::Control::BluetoothInterface::Mode modeEnum(Solid::Control::BluetoothInterface::Off);
00454 if (mode == "off")
00455 {
00456 modeEnum = Solid::Control::BluetoothInterface::Off;
00457 }
00458 else if (mode == "connectable")
00459 {
00460 modeEnum = Solid::Control::BluetoothInterface::Connectable;
00461 }
00462 else if (mode == "discoverable")
00463 {
00464 modeEnum = Solid::Control::BluetoothInterface::Discoverable;
00465 }
00466 adapter.setMode(modeEnum);
00467
00468 return true;
00469 }
00470
00471 bool SolidBluetooth::bluetoothAdapterListConnections(const QString &ubi)
00472 {
00473 Solid::Control::BluetoothManager &manager = Solid::Control::BluetoothManager::self();
00474 Solid::Control::BluetoothInterface adapter = manager.findBluetoothInterface(ubi);
00475
00476 const Solid::Control::BluetoothRemoteDeviceList all = adapter.listConnections();
00477
00478 cout << "Current connections of Bluetooth Adapter: " << ubi << endl;
00479 foreach (const Solid::Control::BluetoothRemoteDevice device, all)
00480 {
00481 cout << "UBI = '" << device.ubi() << "'" << endl;
00482 }
00483 return true;
00484 }
00485
00486 bool SolidBluetooth::bluetoothAdapterListBondings(const QString &ubi)
00487 {
00488 Solid::Control::BluetoothManager &manager = Solid::Control::BluetoothManager::self();
00489 Solid::Control::BluetoothInterface adapter = manager.findBluetoothInterface(ubi);
00490
00491 const QStringList all = adapter.listBondings();
00492
00493 cout << "Current bonded/paired remote bluetooth devices of Bluetooth Adapter: " << ubi << endl;
00494 foreach (const QString device, all)
00495 {
00496 cout << "UBI = '" << device << "'" << endl;
00497 }
00498 return true;
00499 }
00500
00501 bool SolidBluetooth::bluetoothAdapterScan(const QString &ubi)
00502 {
00503 Solid::Control::BluetoothManager &manager = Solid::Control::BluetoothManager::self();
00504 Solid::Control::BluetoothInterface adapter = manager.findBluetoothInterface(ubi);
00505
00506 connect(&adapter, SIGNAL(remoteDeviceFound(const QString &, int, int)),
00507 this, SLOT(slotBluetoothDeviceFound(const QString &, int, int)));
00508 connect(&adapter, SIGNAL(discoveryCompleted()),
00509 this, SLOT(slotBluetoothDiscoveryCompleted()));
00510
00511 adapter.discoverDevices();
00512
00513 QTimer::singleShot(30000, this, SLOT(slotBluetoothDiscoveryCompleted()));
00514 cout << "Searching ..." << endl;
00515 m_loop.exec();
00516
00517 return true;
00518 }
00519
00520 void SolidBluetooth::slotBluetoothDeviceFound(const QString &ubi, int deviceClass, int rssi)
00521 {
00522 cout << QString("['%1','%2','%3']").arg(ubi).arg(deviceClass).arg(rssi) << endl;
00523 }
00524
00525 void SolidBluetooth::slotBluetoothDiscoveryCompleted()
00526 {
00527 kDebug() ;
00528 m_loop.exit();
00529 }
00530
00531 bool SolidBluetooth::bluetoothInputListDevices()
00532 {
00533 Solid::Control::BluetoothManager &manager = Solid::Control::BluetoothManager::self();
00534 const Solid::Control::BluetoothInputDeviceList all = manager.bluetoothInputDevices();
00535
00536 foreach (const Solid::Control::BluetoothInputDevice device, all)
00537 {
00538 cout << "UBI = '" << device.ubi() << "'" << endl;
00539 }
00540
00541 return true;
00542 }
00543
00544 bool SolidBluetooth::bluetoothInputSetup(const QString &deviceUbi)
00545 {
00546 Solid::Control::BluetoothManager &manager = Solid::Control::BluetoothManager::self();
00547 KJob *job = manager.setupInputDevice(deviceUbi);
00548
00549 if (job==0)
00550 {
00551 cerr << i18n("Error: unsupported operation!") << endl;
00552 return false;
00553 }
00554
00555 connectJob(job);
00556
00557 job->start();
00558 m_loop.exec();
00559
00560 if (m_error)
00561 {
00562 cerr << i18n("Error: %1" , m_errorString) << endl;
00563 return false;
00564 }
00565
00566 return true;
00567 }
00568
00569 bool SolidBluetooth::bluetoothInputRemoveSetup(const QString &deviceUbi)
00570 {
00571 Solid::Control::BluetoothManager &manager = Solid::Control::BluetoothManager::self();
00572
00573 manager.removeInputDevice(deviceUbi);
00574
00575 return true;
00576 }
00577
00578 bool SolidBluetooth::bluetoothInputConnect(const QString &deviceUbi)
00579 {
00580 Solid::Control::BluetoothManager &manager = Solid::Control::BluetoothManager::self();
00581 Solid::Control::BluetoothInputDevice device = manager.findBluetoothInputDevice(deviceUbi);
00582
00583 device.slotConnect();
00584
00585 return true;
00586 }
00587
00588 bool SolidBluetooth::bluetoothInputDisconnect(const QString &deviceUbi)
00589 {
00590 Solid::Control::BluetoothManager &manager = Solid::Control::BluetoothManager::self();
00591 Solid::Control::BluetoothInputDevice device = manager.findBluetoothInputDevice(deviceUbi);
00592
00593 device.slotDisconnect();
00594
00595 return true;
00596 }
00597
00598 bool SolidBluetooth::bluetoothRemoteCreateBonding(const QString &adapterUbi, const QString &deviceUbi)
00599 {
00600 Solid::Control::BluetoothManager &manager = Solid::Control::BluetoothManager::self();
00601 Solid::Control::BluetoothInterface adapter = manager.findBluetoothInterface(adapterUbi);
00602 Solid::Control::BluetoothRemoteDevice device = adapter.findBluetoothRemoteDevice(deviceUbi);
00603
00604 KJob *job = device.createBonding();
00605
00606 connectJob(job);
00607
00608 job->start();
00609 m_loop.exec();
00610
00611 if (m_error)
00612 {
00613 cerr << i18n("Error: %1" , m_errorString) << endl;
00614 return false;
00615 }
00616
00617 return true;
00618 }
00619
00620 bool SolidBluetooth::bluetoothRemoteRemoveBonding(const QString &adapterUbi, const QString &deviceUbi)
00621 {
00622 Solid::Control::BluetoothManager &manager = Solid::Control::BluetoothManager::self();
00623 Solid::Control::BluetoothInterface adapter = manager.findBluetoothInterface(adapterUbi);
00624 Solid::Control::BluetoothRemoteDevice device = adapter.findBluetoothRemoteDevice(deviceUbi);
00625
00626 device.removeBonding();
00627
00628 return true;
00629 }
00630
00631 bool SolidBluetooth::bluetoothRemoteHasBonding(const QString &adapterUbi, const QString &deviceUbi)
00632 {
00633 Solid::Control::BluetoothManager &manager = Solid::Control::BluetoothManager::self();
00634 Solid::Control::BluetoothInterface adapter = manager.findBluetoothInterface(adapterUbi);
00635 Solid::Control::BluetoothRemoteDevice device = adapter.findBluetoothRemoteDevice(deviceUbi);
00636
00637 if (device.hasBonding())
00638 {
00639 cout << "'" << deviceUbi << "' is bonded/paired." << endl;
00640 } else {
00641 cout << "'" << deviceUbi << "' is not bonded/paired." << endl;
00642 }
00643
00644 return true;
00645 }
00646
00647 void SolidBluetooth::connectJob(KJob *job)
00648 {
00649 connect(job, SIGNAL(result(KJob *)),
00650 this, SLOT(slotResult(KJob *)));
00651 connect(job, SIGNAL(percent(KJob *, unsigned long)),
00652 this, SLOT(slotPercent(KJob *, unsigned long)));
00653 connect(job, SIGNAL(infoMessage(KJob *, const QString &, const QString &)),
00654 this, SLOT(slotInfoMessage(KJob *, const QString &)));
00655 }
00656
00657 void SolidBluetooth::slotPercent(KJob *, unsigned long percent)
00658 {
00659 cout << i18n("Progress: %1%" , percent) << endl;
00660 }
00661
00662 void SolidBluetooth::slotInfoMessage(KJob *, const QString &message)
00663 {
00664 cout << i18n("Info: %1" , message) << endl;
00665 }
00666
00667 void SolidBluetooth::slotResult(KJob *job)
00668 {
00669 m_error = 0;
00670
00671 if (job->error())
00672 {
00673 m_error = job->error();
00674 m_errorString = job->errorString();
00675 }
00676
00677 m_loop.exit();
00678 }
00679
00680 void SolidBluetooth::slotStorageResult(Solid::ErrorType error, const QVariant &errorData)
00681 {
00682 if (error) {
00683 m_error = 1;
00684 m_errorString = errorData.toString();
00685 }
00686 m_loop.exit();
00687 }
00688
00689 #include "solid-bluetooth.moc"