1 /* This file is part of the KDE project
2 Copyright (C) 2006 Kevin Ottens <ervin@kde.org>
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 Boston, MA 02110-1301, USA.
20 #include "solid-bluetooth.h"
24 #include <QStringList>
25 #include <QMetaProperty>
29 #include <kcomponentdata.h>
30 #include <kcmdlineargs.h>
32 #include <k3socketaddress.h>
35 #include <solid/device.h>
36 #include <solid/genericinterface.h>
37 #include <solid/storageaccess.h>
38 #include <solid/opticaldrive.h>
40 #include <solid/control/bluetoothmanager.h>
41 #include <solid/control/bluetoothinterface.h>
42 #include <solid/control/bluetoothremotedevice.h>
43 #include <solid/control/bluetoothinputdevice.h>
51 static const char appName
[] = "solid-bluetooth";
52 static const char programName
[] = I18N_NOOP("solid-bluetooth");
54 static const char description
[] = I18N_NOOP("KDE tool for querying and controlling your hardware from the command line");
56 static const char version
[] = "0.1";
58 std::ostream
&operator<<(std::ostream
&out
, const QString
&msg
)
60 return (out
<< msg
.toLocal8Bit().constData());
63 std::ostream
&operator<<(std::ostream
&out
, const QVariant
&value
)
67 case QVariant::StringList
:
71 QStringList list
= value
.toStringList();
73 QStringList::ConstIterator it
= list
.constBegin();
74 QStringList::ConstIterator end
= list
.constEnd();
78 out
<< "'" << *it
<< "'";
86 out
<< "} (string list)";
90 out
<< (value
.toBool()?"true":"false") << " (bool)";
93 out
<< value
.toString()
94 << " (0x" << QString::number(value
.toInt(), 16) << ") (int)";
97 out
<< "'" << value
.toString() << "' (string)";
104 std::ostream
&operator<<(std::ostream
&out
, const Solid::Device
&device
)
106 out
<< " parent = " << QVariant(device
.parentUdi()) << endl
;
107 out
<< " vendor = " << QVariant(device
.vendor()) << endl
;
108 out
<< " product = " << QVariant(device
.product()) << endl
;
110 int index
= Solid::DeviceInterface::staticMetaObject
.indexOfEnumerator("Type");
111 QMetaEnum typeEnum
= Solid::DeviceInterface::staticMetaObject
.enumerator(index
);
113 for (int i
=0; i
<typeEnum
.keyCount(); i
++)
115 Solid::DeviceInterface::Type type
= (Solid::DeviceInterface::Type
)typeEnum
.value(i
);
116 const Solid::DeviceInterface
*interface
= device
.asDeviceInterface(type
);
120 const QMetaObject
*meta
= interface
->metaObject();
122 for (int i
=meta
->propertyOffset(); i
<meta
->propertyCount(); i
++)
124 QMetaProperty property
= meta
->property(i
);
125 out
<< " " << QString(meta
->className()).mid(7) << "." << property
.name()
128 QVariant value
= property
.read(interface
);
130 if (property
.isEnumType()) {
131 QMetaEnum metaEnum
= property
.enumerator();
132 out
<< "'" << metaEnum
.valueToKeys(value
.toInt()).constData() << "'"
133 << " (0x" << QString::number(value
.toInt(), 16) << ") ";
134 if (metaEnum
.isFlag()) {
141 out
<< value
<< endl
;
150 std::ostream
&operator<<(std::ostream
&out
, const QMap
<QString
,QVariant
> &properties
)
152 foreach (const QString
& key
, properties
.keys())
154 out
<< " " << key
<< " = " << properties
[key
] << endl
;
160 void checkArgumentCount(int min
, int max
)
162 int count
= KCmdLineArgs::parsedArgs()->count();
166 cerr
<< i18n("Syntax Error: Not enough arguments") << endl
;
170 if ((max
> 0) && (count
> max
))
172 cerr
<< i18n("Syntax Error: Too many arguments") << endl
;
177 int main(int argc
, char **argv
)
179 KCmdLineArgs::init(argc
, argv
, appName
, 0, ki18n(programName
), version
, ki18n(description
), false);
182 KCmdLineOptions options
;
184 options
.add("commands", ki18n("Show available commands by domains"));
186 options
.add("+command", ki18n("Command (see --commands)"));
188 options
.add("+[arg(s)]", ki18n("Arguments for command"));
190 KCmdLineArgs::addCmdLineOptions(options
);
192 KCmdLineArgs
*args
= KCmdLineArgs::parsedArgs();
194 KComponentData
componentData(appName
);
196 if (args
->isSet("commands"))
198 KCmdLineArgs::enable_i18n();
200 cout
<< endl
<< i18n("Syntax:") << endl
<< endl
;
202 cout
<< " solid-bluetooth listadapters" << endl
;
203 cout
<< i18n(" # List bluetooth adapters/interfaces\n") << endl
;
205 cout
<< " solid-bluetooth defaultadapter" << endl
;
206 cout
<< i18n(" # List bluetooth default adapter/interface\n") << endl
;
208 cout
<< " solid-bluetooth createdevice (interface 'ubi') 'remote-mac'" << endl
;
209 cout
<< i18n(" # Request to create a remote bluetooth device on the bus\n") << endl
;
211 cout
<< " solid-bluetooth removedevice (interface 'ubi') 'remote-mac'" << endl
;
212 cout
<< i18n(" # Request to remove the remote bluetooth device from the bus\n") << endl
;
214 cout
<< " solid-bluetooth getproperties (interface 'ubi') " << endl
;
215 cout
<< i18n(" # Request the properties from the bluetooth adapter\n") << endl
;
219 cout << " solid-bluetooth getremotename (interface 'ubi') 'remote-mac'" << endl;
220 cout << i18n(" # Query the name from the remote device 'remote-mac' with 'ubi'\n") << endl;
222 cout << " solid-bluetooth query (address|bondings|connections|name) (interface 'ubi')" << endl;
223 cout << i18n(" # Query information about the bluetooth adapter/interface with 'ubi'\n") << endl;
225 cout << " solid-bluetooth set (mode|name) (interface 'ubi') 'value'" << endl;
226 cout << i18n(" # Set the bluetooth adapter name.\n"
227 " # Set the bluetooth adapter mode. Where 'value' is one of:\n"
228 " # off|connectable|discoverable\n") << endl;
230 cout << " solid-bluetooth scan (interface 'ubi')" << endl;
231 cout << i18n(" # Scan for bluetooth remote devices.\n") << endl;
233 cout << " solid-bluetooth input listdevices" << endl;
234 cout << i18n(" # List configured input devices.\n") << endl;
236 cout << " solid-bluetooth input (setup|remove|connect|disconnect) (device 'ubi')" << endl;
237 cout << i18n(" # Setup bluetooth input device.\n"
238 " # Remove configuration of remote input device.\n"
239 " # Connect or disconnect bluetooth input device.\n") << endl;
241 cout << " solid-bluetooth remote (createbonding|removebonding|hasbonding) (device 'ubi')" << endl;
242 cout << i18n(" # Create bonding (pairing) with bluetooth remote device.\n"
243 " # Remove bonding of bluetooth remote device.\n"
244 " # Check for bonding of bluetooth remote device.\n") << endl;
249 return SolidBluetooth::doIt() ? 0 : 1;
252 bool SolidBluetooth::doIt()
254 KCmdLineArgs
*args
= KCmdLineArgs::parsedArgs();
255 checkArgumentCount(1, 0);
257 QString
command(args
->arg(0));
260 char **fake_argv
= 0;
261 SolidBluetooth
shell(fake_argc
, fake_argv
);
263 if (command
== "listadapters")
265 return shell
.bluetoothListAdapters();
267 else if (command
== "defaultadapter")
269 return shell
.bluetoothDefaultAdapter();
271 else if (command
== "createdevice")
273 checkArgumentCount(3, 3);
274 QString
adapterUbi(args
->arg(1));
275 QString
mac(args
->arg(2));
276 return shell
.bluetoothCreateDevice(adapterUbi
, mac
);
278 else if (command
== "removedevice")
280 checkArgumentCount(3, 3);
281 QString
adapterUbi(args
->arg(1));
282 QString
remoteUbi(args
->arg(2));
283 return shell
.bluetoothRemoveDevice(adapterUbi
, remoteUbi
);
285 else if (command
== "getproperties")
287 checkArgumentCount(2, 2);
288 QString
ubi (args
->arg(1));
289 return shell
.bluetoothGetProperties(ubi
);
295 else if (command
== "getremotename")
297 checkArgumentCount(3, 3);
298 QString
adapterUbi(args
->arg(1));
299 QString
mac(args
->arg(2));
300 return shell
.bluetoothGetRemoteName(adapterUbi
, mac
);
302 else if (command
== "set")
304 checkArgumentCount(4, 4);
305 QString
what(args
->arg(1));
306 QString
ubi(args
->arg(2));
307 QString
value(args
->arg(3));
311 return shell
.bluetoothAdapterSetName(ubi
, value
);
313 else if (what
== "mode")
315 return shell
.bluetoothAdapterSetMode(ubi
, value
);
319 else if (command
== "query")
321 checkArgumentCount(3, 3);
322 QString
what(args
->arg(1));
323 QString
ubi(args
->arg(2));
327 return shell
.bluetoothAdapterMode(ubi
);
329 else if (what
== "address")
331 return shell
.bluetoothAdapterAddress(ubi
);
333 else if (what
== "name")
335 return shell
.bluetoothAdapterName(ubi
);
337 else if (what
== "connections")
339 return shell
.bluetoothAdapterListConnections(ubi
);
341 else if (what
== "bondings")
343 return shell
.bluetoothAdapterListBondings(ubi
);
347 else if (command
== "scan")
349 checkArgumentCount(2, 2);
350 QString
ubi (args
->arg(1));
351 return shell
.bluetoothAdapterScan(ubi
);
353 else if (command
== "input")
355 checkArgumentCount(2, 3);
356 QString
what (args
->arg(1));
358 if (what
== "listdevices")
360 return shell
.bluetoothInputListDevices();
363 checkArgumentCount(3, 3);
364 QString
ubi (args
->arg(2));
368 return shell
.bluetoothInputSetup(ubi
);
370 else if (what
== "remove")
372 return shell
.bluetoothInputRemoveSetup(ubi
);
374 else if (what
== "connect")
376 return shell
.bluetoothInputConnect(ubi
);
378 else if (what
== "disconnect")
380 return shell
.bluetoothInputDisconnect(ubi
);
383 else if (command
== "remote" && args
->count() >= 3)
385 checkArgumentCount(4, 4);
386 QString
what (args
->arg(1));
387 QString
adapter (args
->arg(2));
388 QString
remote (args
->arg(3));
390 if (what
== "createbonding")
392 return shell
.bluetoothRemoteCreateBonding(adapter
, remote
);
394 else if (what
== "removebonding")
396 return shell
.bluetoothRemoteRemoveBonding(adapter
, remote
);
398 else if (what
== "hasbonding")
400 return shell
.bluetoothRemoteHasBonding(adapter
, remote
);
407 cerr
<< i18n("Syntax Error: Unknown command '%1'" , command
) << endl
;
413 bool SolidBluetooth::bluetoothListAdapters()
415 Solid::Control::BluetoothManager
&manager
= Solid::Control::BluetoothManager::self();
417 foreach (Solid::Control::BluetoothInterface device
, manager
.bluetoothInterfaces())
419 cout
<< "UBI = '" << device
.ubi() << "'" << endl
;
424 bool SolidBluetooth::bluetoothDefaultAdapter()
426 Solid::Control::BluetoothManager
&manager
= Solid::Control::BluetoothManager::self();
428 cout
<< "UBI = '" << manager
.defaultInterface() << "'" << endl
;
433 bool SolidBluetooth::bluetoothCreateDevice(const QString
&adapterUbi
, const QString
&/*mac*/)
435 Solid::Control::BluetoothManager
&manager
= Solid::Control::BluetoothManager::self();
436 Solid::Control::BluetoothInterface adapter
= manager
.findBluetoothInterface(adapterUbi
);
437 // QString remoteDeviceUBI = adapter.createDevice(mac);
438 // cout << "Remote Device UBI: " << remoteDeviceUBI << endl;
442 bool SolidBluetooth::bluetoothRemoveDevice(const QString
&adapterUbi
, const QString
&/*remoteDeviceUbi*/)
444 Solid::Control::BluetoothManager
&manager
= Solid::Control::BluetoothManager::self();
445 Solid::Control::BluetoothInterface adapter
= manager
.findBluetoothInterface(adapterUbi
);
446 // adapter.removeDevice(remoteDeviceUbi);
450 bool SolidBluetooth::bluetoothGetProperties(const QString
&adapterUbi
)
452 Solid::Control::BluetoothManager
&manager
= Solid::Control::BluetoothManager::self();
453 Solid::Control::BluetoothInterface adapter
= manager
.findBluetoothInterface(adapterUbi
);
454 QMap
<QString
,QVariant
> props
= adapter
.getProperties();
455 foreach (QString valName
, props
.keys()) {
456 cout
<< valName
<< ": " << props
[valName
] << endl
;
463 bool SolidBluetooth::bluetoothGetRemoteName(const QString
&adapterUbi
, const QString
&mac
)
465 Solid::Control::BluetoothManager
&manager
= Solid::Control::BluetoothManager::self();
466 Solid::Control::BluetoothInterface adapter
= manager
.findBluetoothInterface(adapterUbi
);
468 cout
<< "Name = '" << adapter
.getRemoteName(mac
) << "'" << endl
;
473 bool SolidBluetooth::bluetoothAdapterAddress(const QString
&ubi
)
475 Solid::Control::BluetoothManager
&manager
= Solid::Control::BluetoothManager::self();
476 Solid::Control::BluetoothInterface adapter
= manager
.findBluetoothInterface(ubi
);
478 cout
<< "'" << adapter
.address() << "'" << endl
;
483 bool SolidBluetooth::bluetoothAdapterName(const QString
&ubi
)
485 Solid::Control::BluetoothManager
&manager
= Solid::Control::BluetoothManager::self();
486 Solid::Control::BluetoothInterface adapter
= manager
.findBluetoothInterface(ubi
);
488 cout
<< "'" << adapter
.name() << "'" << endl
;
493 bool SolidBluetooth::bluetoothAdapterSetName(const QString
&ubi
, const QString
&name
)
495 Solid::Control::BluetoothManager
&manager
= Solid::Control::BluetoothManager::self();
496 Solid::Control::BluetoothInterface adapter
= manager
.findBluetoothInterface(ubi
);
498 adapter
.setName(name
);
503 bool SolidBluetooth::bluetoothAdapterMode(const QString
&ubi
)
505 Solid::Control::BluetoothManager
&manager
= Solid::Control::BluetoothManager::self();
506 Solid::Control::BluetoothInterface adapter
= manager
.findBluetoothInterface(ubi
);
508 cout
<< "'" << adapter
.mode() << "'" << endl
;
513 bool SolidBluetooth::bluetoothAdapterSetMode(const QString
&ubi
, const QString
&mode
)
515 Solid::Control::BluetoothManager
&manager
= Solid::Control::BluetoothManager::self();
516 Solid::Control::BluetoothInterface adapter
= manager
.findBluetoothInterface(ubi
);
517 Solid::Control::BluetoothInterface::Mode
modeEnum(Solid::Control::BluetoothInterface::Off
);
520 modeEnum
= Solid::Control::BluetoothInterface::Off
;
522 else if (mode
== "connectable")
524 modeEnum
= Solid::Control::BluetoothInterface::Connectable
;
526 else if (mode
== "discoverable")
528 modeEnum
= Solid::Control::BluetoothInterface::Discoverable
;
530 adapter
.setMode(modeEnum
);
535 bool SolidBluetooth::bluetoothAdapterListConnections(const QString
&ubi
)
537 Solid::Control::BluetoothManager
&manager
= Solid::Control::BluetoothManager::self();
538 Solid::Control::BluetoothInterface adapter
= manager
.findBluetoothInterface(ubi
);
540 const Solid::Control::BluetoothRemoteDeviceList all
= adapter
.listConnections();
542 cout
<< "Current connections of Bluetooth Adapter: " << ubi
<< endl
;
543 foreach (const Solid::Control::BluetoothRemoteDevice device
, all
)
545 cout
<< "UBI = '" << device
.ubi() << "'" << endl
;
550 bool SolidBluetooth::bluetoothAdapterListBondings(const QString
&ubi
)
552 Solid::Control::BluetoothManager
&manager
= Solid::Control::BluetoothManager::self();
553 Solid::Control::BluetoothInterface adapter
= manager
.findBluetoothInterface(ubi
);
555 const QStringList all
= adapter
.listBondings();
557 cout
<< "Current bonded/paired remote bluetooth devices of Bluetooth Adapter: " << ubi
<< endl
;
558 foreach (const QString device
, all
)
560 cout
<< "UBI = '" << device
<< "'" << endl
;
565 bool SolidBluetooth::bluetoothAdapterScan(const QString
&ubi
)
567 Solid::Control::BluetoothManager
&manager
= Solid::Control::BluetoothManager::self();
568 Solid::Control::BluetoothInterface adapter
= manager
.findBluetoothInterface(ubi
);
570 connect(&adapter
, SIGNAL(remoteDeviceFound(const QString
&, int, int)),
571 this, SLOT(slotBluetoothDeviceFound(const QString
&, int, int)));
572 connect(&adapter
, SIGNAL(discoveryCompleted()),
573 this, SLOT(slotBluetoothDiscoveryCompleted()));
575 adapter
.discoverDevices();
576 // Workaround for the fakebluetooth backend... quit the discovery after 30 seconds
577 QTimer::singleShot(30000, this, SLOT(slotBluetoothDiscoveryCompleted()));
578 cout
<< "Searching ..." << endl
;
584 void SolidBluetooth::slotBluetoothDeviceFound(const QString
&ubi
, int deviceClass
, int rssi
)
586 cout
<< QString("['%1','%2','%3']").arg(ubi
).arg(deviceClass
).arg(rssi
) << endl
;
589 void SolidBluetooth::slotBluetoothDiscoveryCompleted()
595 bool SolidBluetooth::bluetoothInputListDevices()
597 Solid::Control::BluetoothManager
&manager
= Solid::Control::BluetoothManager::self();
598 const Solid::Control::BluetoothInputDeviceList all
= manager
.bluetoothInputDevices();
600 foreach (const Solid::Control::BluetoothInputDevice device
, all
)
602 cout
<< "UBI = '" << device
.ubi() << "'" << endl
;
608 bool SolidBluetooth::bluetoothInputSetup(const QString
&deviceUbi
)
610 Solid::Control::BluetoothManager
&manager
= Solid::Control::BluetoothManager::self();
611 KJob
*job
= manager
.setupInputDevice(deviceUbi
);
615 cerr
<< i18n("Error: unsupported operation!") << endl
;
626 cerr
<< i18n("Error: %1" , m_errorString
) << endl
;
633 bool SolidBluetooth::bluetoothInputRemoveSetup(const QString
&deviceUbi
)
635 Solid::Control::BluetoothManager
&manager
= Solid::Control::BluetoothManager::self();
637 manager
.removeInputDevice(deviceUbi
);
642 bool SolidBluetooth::bluetoothInputConnect(const QString
&deviceUbi
)
644 Solid::Control::BluetoothManager
&manager
= Solid::Control::BluetoothManager::self();
645 Solid::Control::BluetoothInputDevice device
= manager
.findBluetoothInputDevice(deviceUbi
);
647 device
.slotConnect();
652 bool SolidBluetooth::bluetoothInputDisconnect(const QString
&deviceUbi
)
654 Solid::Control::BluetoothManager
&manager
= Solid::Control::BluetoothManager::self();
655 Solid::Control::BluetoothInputDevice device
= manager
.findBluetoothInputDevice(deviceUbi
);
657 device
.slotDisconnect();
662 bool SolidBluetooth::bluetoothRemoteCreateBonding(const QString
&adapterUbi
, const QString
&deviceUbi
)
664 Solid::Control::BluetoothManager
&manager
= Solid::Control::BluetoothManager::self();
665 Solid::Control::BluetoothInterface adapter
= manager
.findBluetoothInterface(adapterUbi
);
666 Solid::Control::BluetoothRemoteDevice device
= adapter
.findBluetoothRemoteDevice(deviceUbi
);
668 KJob
*job
= device
.createBonding();
677 cerr
<< i18n("Error: %1" , m_errorString
) << endl
;
684 bool SolidBluetooth::bluetoothRemoteRemoveBonding(const QString
&adapterUbi
, const QString
&deviceUbi
)
686 Solid::Control::BluetoothManager
&manager
= Solid::Control::BluetoothManager::self();
687 Solid::Control::BluetoothInterface adapter
= manager
.findBluetoothInterface(adapterUbi
);
688 Solid::Control::BluetoothRemoteDevice device
= adapter
.findBluetoothRemoteDevice(deviceUbi
);
690 device
.removeBonding();
695 bool SolidBluetooth::bluetoothRemoteHasBonding(const QString
&adapterUbi
, const QString
&deviceUbi
)
697 Solid::Control::BluetoothManager
&manager
= Solid::Control::BluetoothManager::self();
698 Solid::Control::BluetoothInterface adapter
= manager
.findBluetoothInterface(adapterUbi
);
699 Solid::Control::BluetoothRemoteDevice device
= adapter
.findBluetoothRemoteDevice(deviceUbi
);
701 if (device
.hasBonding())
703 cout
<< "'" << deviceUbi
<< "' is bonded/paired." << endl
;
705 cout
<< "'" << deviceUbi
<< "' is not bonded/paired." << endl
;
711 void SolidBluetooth::connectJob(KJob
*job
)
713 connect(job
, SIGNAL(result(KJob
*)),
714 this, SLOT(slotResult(KJob
*)));
715 connect(job
, SIGNAL(percent(KJob
*, unsigned long)),
716 this, SLOT(slotPercent(KJob
*, unsigned long)));
717 connect(job
, SIGNAL(infoMessage(KJob
*, const QString
&, const QString
&)),
718 this, SLOT(slotInfoMessage(KJob
*, const QString
&)));
721 void SolidBluetooth::slotPercent(KJob */
*job */
, unsigned long percent
)
723 cout
<< i18n("Progress: %1%" , percent
) << endl
;
726 void SolidBluetooth::slotInfoMessage(KJob */
*job */
, const QString
&message
)
728 cout
<< i18n("Info: %1" , message
) << endl
;
731 void SolidBluetooth::slotResult(KJob
*job
)
737 m_error
= job
->error();
738 m_errorString
= job
->errorString();
744 void SolidBluetooth::slotStorageResult(Solid::ErrorType error
, const QVariant
&errorData
)
748 m_errorString
= errorData
.toString();
754 #include "solid-bluetooth.moc"