tdebluez
objectmanagerImpl.cpp
Go to the documentation of this file.
1/*
2 *
3 * Object Manager implementation of bluez5
4 *
5 * Copyright (C) 2018 Emanoil Kotsev <deloptes@gmail.com>
6 *
7 *
8 * This file is part of libtdebluez.
9 *
10 * libtdebluez is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * libtdebluez is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with kbluetooth; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 *
24 */
25
26#include <tqstringlist.h>
27
28#include <tqdbusmessage.h>
29#include <tqdbusobjectpath.h>
30#include <tqdbusdatamap.h>
31#include <tqdbusdata.h>
32#include <tqdbusdatalist.h>
33#include <tqdbusvariant.h>
34
35#include "objectmanagerImpl.h"
36#include "btuuids.h"
37
38namespace TDEBluetooth
39{
40
42 ObjectManagerProxy(service, path, parent, name)
43{
44 agentManager = 0;
46 healthManager = 0;
48 agentIsDefaultAgent = false;
49 // init connection to dbus
50 initDBUS();
51}
52
54{
55 // close D-Bus connection
56 close();
57
58 if(agentManager)
59 delete agentManager;
61 delete profileManager;
63 delete healthManager;
64}
65
73{
74 // close D-Bus connection
75 close();
76 // init D-Bus conntection
77 return (initDBUS());
78}
79
87{
88 return dBusConn.isConnected();
89}
90
100
108{
113
114 for (PropertiesMap::iterator it = adapters.begin(); it != adapters.end();
115 ++it)
116 {
118 p = it.data();
119 if (p != NULL)
120 delete p;
121 }
122 for (PropertiesMap::iterator it = devices.begin(); it != devices.end();
123 ++it)
124 {
126 p = it.data();
127 if (p != NULL)
128 delete p;
129 }
130 adapters.clear();
131 devices.clear();
132
133 dBusConn.closeConnection(DBUS_CONN_NAME);
134 return true;
135}
136
145
154
163
173
183
189
191{
193 {
194 if (!agentManager)
195 {
196 tqDebug(i18n("AgentManager is not initialized"));
197 return false;
198 }
199
203 if (dbuserror.isValid())
204 {
205 tqDebug(i18n("Could not register agent: %1").arg(dbuserror.message()));
206 return false;
207 }
209 }
210 return true;
211}
212
214{
215 kdDebug() << k_funcinfo << endl;
217 {
221 if (dbuserror.isValid())
222 {
223 tqDebug(i18n("Could not unregister agent"));
224 return false;
225 }
226 agentRegisteredStatus = false;
227 agentIsDefaultAgent = false;
228 }
229 return true;
230}
231
233{
234 if (!agentManager)
235 {
236 tqDebug(i18n("AgentManager is not initialized"));
237 return false;
238 }
239
243 if (dbuserror.isValid())
244 {
245 tqDebug(i18n("Could not request default agent: %1").arg(dbuserror.message()));
246 return false;
247 }
248 agentIsDefaultAgent = true;
249 return true;
250}
251
256
261
269{
270 dBusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus, DBUS_CONN_NAME);
271 if (!dBusConn.isConnected())
272 {
273 tqDebug(i18n("Failed to open connection to system message bus: %1").arg(dBusConn.lastError().message()));
274 TQTimer::singleShot(4000, this, TQ_SLOT(reconnect()));
275 return false;
276 }
278
282 {
283 tqDebug(i18n("GetManagedObjects(objects,error) failed: %1").arg(dbuserror.message()));
284 return false;
285 }
286
288 for (it; it != objects.end(); ++it)
289 {
290 bool ok = false;
291 slotInterfacesAdded(it.key(), it.data().toStringKeyMap(&ok));
292 if (!ok)
293 tqWarning(i18n("Failed to convert dbus data to string map: %1").arg(it.key()));
294 }
295
300
301 return true;
302}
303
306{
308 for (it = changed_properties.begin(); it != changed_properties.end(); ++it)
309 {
310 bool ok = false;
311 if (it.key() == "Powered")
312 emit adapterPowerOnChanged(path, it.data().value.toBool(&ok));
313 else if (it.key() == "Class")
314 emit adapterClassChanged(path, it.data().value.toUInt32(&ok));
315 else if (it.key() == "Name")
316 emit adapterNameChanged(path, it.data().value.toString(&ok));
317 else if (it.key() == "Alias")
318 emit adapterAliasChanged(path, it.data().value.toString(&ok));
319 else if (it.key() == "DiscoverableTimeout")
320 emit adapterDiscoverableTimeoutChanged(path, it.data().value.toUInt32(&ok));
321 else if (it.key() == "Discoverable")
322 emit adapterDiscoverableChanged(path, it.data().value.toBool(&ok));
323 else if (it.key() == "Discovering")
324 emit adapterDiscoveringChanged(path, it.data().value.toBool(&ok));
325 else
326 continue;
327 if (!ok)
328 tqDebug(i18n("ObjectManagerImpl::adapterPropertiesChanged conversion failed"));
329 }
330}
331
333{
334 // https://github.com/r10r/bluez/blob/master/doc/device-api.txt
336 for (it = changed_properties.begin(); it != changed_properties.end(); ++it)
337 {
338 bool ok = false;
339 if (it.key() == "Address")
340 emit deviceAddressChanged(path, it.data().value.toString(&ok));
341 else if (it.key() == "Class")
342 emit deviceClassChanged(path, it.data().value.toUInt32(&ok));
343 else if (it.key() == "Name")
344 emit deviceNameChanged(path, it.data().value.toString(&ok));
345 else if (it.key() == "Alias")
346 emit deviceAliasChanged(path, it.data().value.toString(&ok));
347// https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.gap.appearance.xml
348 else if (it.key() == "Appearance")
349 emit deviceAppearanceChanged(path, it.data().value.toUInt16(&ok));
350 else if (it.key() == "Icon")
351 emit deviceIconChanged(path, it.data().value.toString(&ok));
352 else if (it.key() == "Paired")
353 emit devicePairedChanged(path, it.data().value.toBool(&ok));
354 else if (it.key() == "Trusted")
355 emit deviceTrustedChanged(path, it.data().value.toBool(&ok));
356 else if (it.key() == "Blocked")
357 emit deviceBlockedChanged(path, it.data().value.toBool(&ok));
358 else if (it.key() == "LegacyPairing")
359 emit deviceLegacyPairingChanged(path, it.data().value.toBool(&ok));
360 else if (it.key() == "RSSI")
361 emit deviceRSSIChanged(path, it.data().value.toInt16(&ok)); //INT16
362 else if (it.key() == "Connected")
363 emit deviceConnectedChanged(path, it.data().value.toBool(&ok));
364 else if (it.key() == "UUIDs")
365 {
366 TQT_DBusDataList vl = TQT_DBusDataList(it.data().value.toTQValueList(&ok));
367 emit deviceUUIDsChanged(path, vl.toStringList(&ok));
368 }
369 else if (it.key() == "Adapter")
370 emit deviceAdapterChanged(path, it.data().value.toObjectPath(&ok));
371 else if (it.key() == "ManufacturerData")
372 emit deviceManufacturerDataChanged(path, it.data().value.toUInt16KeyMap(&ok)); //a{qv}
373 else if (it.key() == "ServiceData")
374 emit deviceServiceDataChanged(path, it.data().value.toStringKeyMap(&ok)); //a{sv}
375 else if (it.key() == "TxPower")
376 emit deviceTxPowerChanged(path, it.data().value.toInt16(&ok)); //INT16
377 else if (it.key() == "ServicesResolved")
378 emit deviceServicesResolvedChanged(path, it.data().value.toBool(&ok));
379 else
380 continue;
381 if (!ok)
382 tqDebug(i18n("ObjectManagerImpl::devicePropertiesChanged conversion failed"));
383 }
384
385}
386
388{
390 for (it = changed_properties.begin(); it != changed_properties.end(); ++it)
391 {
392 bool ok = false;
393 if (it.key() == "Connected")
394 emit mediaControlConnectedChanged(path, it.data().value.toBool(&ok));
395 else if (it.key() == "Player")
396 emit mediaControlPlayerChanged(path, it.data().value.toObjectPath(&ok));
397 else
398 continue;
399 if (!ok)
400 tqDebug(i18n("ObjectManagerImpl::mediaControlPropertiesChanged conversion failed"));
401 }
402}
403
405{
407 for (it1; it1 != interfaces.end(); it1++)
408 {
409 TQString interface = it1.key();
410 if (interface == "org.bluez.AgentManager1")
411 {
412 agentManager = new AgentManager1Proxy("org.bluez", object/*, this, "AgentManager1"*/);
413 if (agentManager)
415 }
416 else if (interface == "org.bluez.ProfileManager1")
417 {
418 profileManager = new ProfileManager1Proxy("org.bluez", object/*, this, "ProfileManager1"*/);
419 if (profileManager)
421 }
422 else if (interface == "org.bluez.HealthManager1")
423 {
424 healthManager = new HealthManager1Proxy("org.bluez", object/*, this, "HealthManager1"*/);
425 if (healthManager)
427 }
428 else if (interface == "org.bluez.Adapter1")
429 {
431 properties = new org::freedesktop::DBus::PropertiesProxy("org.bluez", object);
432 properties->setConnection(dBusConn);
434 adapters.insert(TQString(object), properties);
435 //notify others
436 emit adapterAdded(TQString(object));
437 }
438 else if (interface == "org.bluez.GattManager1")
439 {
440 kdDebug() << "Interface not implemented: org.bluez.GattManager1" << endl;
441 // TODO: Implement GattManager1
442 }
443 else if (interface == "org.bluez.Media1")
444 {
445 kdDebug() << "Interface not implemented: org.bluez.Media1" << endl;
446 // TODO: Implement Media1
447 }
448 else if (interface == "org.bluez.NetworkServer1")
449 {
450 kdDebug() << "Interface not implemented: org.bluez.NetworkServer1" << endl;
451 // TODO: Implement NetworkServer1
452 }
453 else if (interface == "org.bluez.Device1")
454 {
456 properties = new org::freedesktop::DBus::PropertiesProxy("org.bluez", object);
457 properties->setConnection(dBusConn);
459 devices.insert(TQString(object), properties);
460 //notify others
461 emit deviceAdded(TQString(object));
462 }
463 else if (interface == "org.bluez.MediaControl1")
464 {
465 kdDebug() << "Interface not implemented: org.bluez.MediaControl1" << endl;
466 kdDebug() << "as the media control is triggered via properties changed." << endl;
467 }
468 else if (interface == "org.bluez.MediaTransport1")
469 {
470 kdDebug() << "Interface not implemented: org.bluez.MediaTransport1" << endl;
471 // TODO: Implement MediaTransport1
472 }
473 else if (interface == "org.freedesktop.DBus.Introspectable")
474 {
475 // do nothing
476 }
477 else if (interface == "org.freedesktop.DBus.Properties")
478 {
479 // do nothing
480 }
481 else
482 {
483 tqWarning(i18n("Interface not implemented: %1").arg(interface));
484 }
485 }
486}
487
489{
490 // TODO: remove interface
491 for (TQValueListConstIterator<TQString> it = interfaces.begin();
492 it != interfaces.end(); ++it)
493 {
494 if ((*it) == "org.bluez.AgentManager1")
495 {
496 kdDebug() << "Remove org.bluez.AgentManager1" << endl;
497 // TODO: remove AgentManager1
498 }
499 else if ((*it) == "org.bluez.ProfileManager1")
500 {
501 kdDebug() << "Interface not implemented: org.bluez.ProfileManager1" << endl;
502 // TODO: remove ProfileManager1
503 }
504 else if ((*it) == "org.bluez.HealthManager1")
505 {
506 kdDebug() << "Interface not implemented: org.bluez.HealthManager1" << endl;
507 // TODO: remove HealthManager1
508 }
509 else if ((*it) == "org.bluez.Adapter1")
510 {
511 kdDebug() << "Remove org.bluez.Adapter1" << endl;
513 adapters.remove(object);
515 }
516 else if ((*it) == "org.bluez.GattManager1")
517 {
518 kdDebug() << "Interface not implemented: org.bluez.GattManager1" << endl;
519 // TODO: Implement GattManager1
520 }
521 else if ((*it) == "org.bluez.Media1")
522 {
523 kdDebug() << "Interface not implemented: org.bluez.Media1" << endl;
524 // TODO: Implement Media1
525 }
526 else if ((*it) == "org.bluez.NetworkServer1")
527 {
528 kdDebug() << "Interface not implemented: org.bluez.NetworkServer1" << endl;
529 // TODO: Implement NetworkServer1
530 }
531 else if ((*it) == "org.bluez.Device1")
532 {
533 kdDebug() << "Remove org.bluez.Device1" << endl;
534 if (devices.contains(object))
535 {
536 disconnect(devices[object], TQ_SIGNAL(PropertiesChanged ( const TQString&, const TQMap< TQString, TQT_DBusVariant >&, const TQStringList& )), this, TQ_SLOT(slotPropertiesChanged ( const TQString& , const TQMap< TQString, TQT_DBusVariant >&, const TQStringList& )));
537 devices.remove(object);
538 emit deviceRemoved(TQString(object));
539 }
540 }
541 else if ((*it) == "org.bluez.MediaControl1")
542 {
543 kdDebug() << "Interface not implemented: org.bluez.MediaControl1" << endl;
544 kdDebug() << "as the media control is triggered via properties changed." << endl;
545 // emit mediaControlRemoved(TQString ( object.data() ));
546 }
547 else if ((*it) == "org.freedesktop.DBus.Introspectable")
548 {
549 // do nothing
550 }
551 else if ((*it) == "org.freedesktop.DBus.Properties")
552 {
553 // do nothing
554 }
555 else
556 {
557 tqWarning(i18n("Interface not implemented: %1").arg((*it)));
558 }
559 }
560}
561
563{
564 // who send the signal ?
565 const TQObject * o = TQObject::sender();
568 if (!obj) {
569 tqWarning("slotPropertiesChanged: sender is not a PropertiesProxy");
570 return;
571 }
573
574 if (interface == "org.bluez.Adapter1")
575 {
576 for (PropertiesMap::Iterator it = adapters.begin();
577 it != adapters.end(); ++it)
578 {
579 if (obj == it.data())
580 path = it.key();
581 }
582 if (!path.isEmpty())
584 }
585 else if (interface == "org.bluez.Device1")
586 {
587 for (PropertiesMap::Iterator it = devices.begin(); it != devices.end();
588 ++it)
589 {
590 if (obj == it.data())
591 path = it.key();
592 }
593 if (!path.isEmpty())
595 }
596 else if (interface == "org.bluez.MediaControl1")
597 {
598 for (PropertiesMap::Iterator it = devices.begin(); it != devices.end();
599 ++it)
600 {
601 if (obj == it.data())
602 path = it.key();
603 }
604 if (!path.isEmpty())
606 }
607
608// TQStringList::const_iterator it1;
609// for ( it1 = invalidated_properties.begin(); it1 != invalidated_properties.end(); ++it1 )
610// {
611// kdDebug() << "Invalidated Key: " << (*it1) << endl;
618// }
619
620}
621
622}; // namespace TDEBluetooth
623
624#include "objectmanagerImpl.moc"
625// End of File
626
627
ObjectManagerImpl(const TQString &service, const TQString &path, TQObject *parent=0, const char *name=0)
void deviceServiceDataChanged(const TQString &, TQT_DBusDataMap< TQString >)
void adapterRemoved(const TQString &)
void adapterNameChanged(const TQString &, const TQString &)
void deviceUUIDsChanged(const TQString &, TQStringList)
void deviceNameChanged(const TQString &, const TQString &)
void devicePropertiesChanged(TQString path, const TQMap< TQString, TQT_DBusVariant > &changed_properties)
bool unregisterAgent()
to unregister the agent to D-Bus
bool requestDefaultAgent()
to register the agent to D-Bus
void adapterDiscoverableChanged(const TQString &, bool state)
void deviceServicesResolvedChanged(const TQString &, bool)
void slotInterfacesRemoved(const TQT_DBusObjectPath &object, const TQStringList &interfaces)
void deviceClassChanged(const TQString &, TQ_UINT32)
void deviceAppearanceChanged(const TQString &, TQ_UINT32)
bool close()
to close the connection to D-Bus
void adapterPropertiesChanged(TQString path, const TQMap< TQString, TQT_DBusVariant > &changed_properties)
void mediaControlPropertiesChanged(TQString path, const TQMap< TQString, TQT_DBusVariant > &changed_properties)
void adapterPowerOnChanged(const TQString &, bool state)
ProfileManager1Proxy * getProfileManager()
void adapterDiscoverableTimeoutChanged(const TQString &, TQ_UINT32 timeout)
void deviceRSSIChanged(const TQString &, TQ_INT16)
HealthManager1Proxy * getHealthManager()
void deviceAliasChanged(const TQString &, const TQString &)
void deviceManufacturerDataChanged(const TQString &, TQT_DBusDataMap< TQ_UINT16 >)
TQT_DBusConnection dBusConn
TQt connection to D-Bus.
bool isConnectedToDBUS()
to get information if TDEBluez is connected to D-Bus
void mediaControlPlayerChanged(const TQString &, const TQT_DBusObjectPath &)
void slotPropertiesChanged(const TQString &interface, const TQMap< TQString, TQT_DBusVariant > &changed_properties, const TQStringList &invalidated_properties)
void deviceIconChanged(const TQString &, const TQString &)
void deviceAdded(const TQString &)
AgentManager1Proxy * getAgentManager()
void deviceConnectedChanged(const TQString &, bool)
ConnectionList listConnections(const TQString &)
ProfileManager1Proxy * profileManager
void adapterAdded(const TQString &)
void deviceAddressChanged(const TQString &, const TQString &)
void deviceTrustedChanged(const TQString &, bool)
void devicePairedChanged(const TQString &, bool)
void deviceBlockedChanged(const TQString &, bool)
HealthManager1Proxy * healthManager
void adapterAliasChanged(const TQString &, const TQString &)
TQT_DBusConnection * getConnection()
pointer to the D-Bus connection
void adapterClassChanged(const TQString &, TQ_UINT32 classvalue)
void deviceRemoved(const TQString &)
void deviceLegacyPairingChanged(const TQString &, bool)
void mediaControlConnectedChanged(const TQString &, bool state)
void adapterDiscoveringChanged(const TQString &, bool state)
bool registerAgent()
to register the agent to D-Bus
void slotInterfacesAdded(const TQT_DBusObjectPath &object, const TQT_DBusDataMap< TQString > &interfaces)
void deviceAdapterChanged(const TQString &, const TQT_DBusObjectPath &)
void deviceTxPowerChanged(const TQString &, TQ_INT16)
void setConnection(const TQT_DBusConnection &connection)
virtual bool UnregisterAgent(const TQT_DBusObjectPath &agent, TQT_DBusError &error)
virtual bool RegisterAgent(const TQT_DBusObjectPath &agent, const TQString &capability, TQT_DBusError &error)
virtual bool RequestDefaultAgent(const TQT_DBusObjectPath &agent, TQT_DBusError &error)
void setConnection(const TQT_DBusConnection &connection)
void setConnection(const TQT_DBusConnection &connection)
virtual bool GetManagedObjects(TQT_DBusDataMap< TQT_DBusObjectPath > &objects, TQT_DBusError &error)
void InterfacesAdded(const TQT_DBusObjectPath &object, const TQT_DBusDataMap< TQString > &interfaces)
void InterfacesRemoved(const TQT_DBusObjectPath &object, const TQStringList &interfaces)
#define DBUS_AUTH_SERVICE_PATH
#define DEVICE_PIN_CAPABILITY
#define DBUS_CONN_NAME