//-*-c++-*- /*************************************************************************** * Copyright (C) 2003 by Fred Schaettgen * * kdebluetooth@schaettgen.de * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #include "tdeiobluetooth.h" #include #include #include #include #include #include #include #include using namespace TDEBluetooth; static const TDECmdLineOptions options[] = { { "+protocol", I18N_NOOP( "Protocol name" ), 0 }, { "+pool", I18N_NOOP( "Socket name" ), 0 }, { "+app", I18N_NOOP( "Socket name" ), 0 }, TDECmdLineLastOption }; extern "C" { KDE_EXPORT int kdemain(int argc, char **argv) { TDEInstance instance( "tdeio_bluetooth" ); kdDebug() << "*** Starting tdeio_bluetooth " << endl; if (argc != 4) { kdDebug() << "Usage: tdeio_bluetooth protocol domain-socket1 domain-socket2" << endl; exit(-1); } putenv(strdup("SESSION_MANAGER=")); TDECmdLineArgs::init(argc, argv, "tdeio_bluetooth", 0, 0, 0, 0); TDECmdLineArgs::addCmdLineOptions( options ); TDEApplication app( false, false, false ); app.dcopClient()->attach(); TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); TDEioBluetooth slave( args->arg(0), args->arg(1), args->arg(2) ); kdDebug() << "*** protocol " << args->arg(0) << endl; kdDebug() << "*** pool socket " << args->arg(1) << endl; kdDebug() << "*** app socket " << args->arg(2) << endl; slave.dispatchLoop(); kdDebug() << "*** tdeio_bluetooth Done" << endl; return 0; } } TDEioBluetooth::TDEioBluetooth(const TQCString &protocol, const TQCString &pool_socket, const TQCString &app_socket) : ForwardingSlaveBase(protocol, pool_socket, app_socket) { kdDebug() << k_funcinfo << endl; TDELocale::setMainCatalogue("tdebluez"); TQT_DBusError error; adapter = 0; manager = new TDEBluetooth::ObjectManagerImpl("org.bluez", "/"/*, this, "ObexObjectManager"*/); if (!manager) { ForwardingSlaveBase::error(TDEIO::ERR_SERVICE_NOT_AVAILABLE, i18n("Bluetooth Manager not found")); closeConnection(); } else { if (!manager->getAdapters().isEmpty()) { TDEBluetooth::ObjectManagerImpl::AdapterList al = manager->getAdapters(); TDEBluetooth::ObjectManagerImpl::AdapterList::Iterator ait = al.begin(); for (ait; ait != al.end(); ++ait) { TDEBluetooth::AdapterImpl *ad = new TDEBluetooth::AdapterImpl("org.bluez", (*ait)); ad->setConnection((*(manager->getConnection()))); // FIXME implement multiple adapters if (ad->getPowered(error)) { adapter = ad; break; } } connect(manager, SIGNAL(deviceAdded(const TQString &)), this, SLOT(slotAddDevice(const TQString &))); connect(manager, SIGNAL(deviceRemoved(const TQString &)), this, SLOT(slotRemoveDevice(const TQString &))); connect(manager, SIGNAL(adapterPowerOnChanged(const TQString&, bool )), this, SLOT(slotAdapterPowerOnChanged(const TQString &, bool ))); } else { ForwardingSlaveBase::error(TDEIO::ERR_SERVICE_NOT_AVAILABLE, i18n("No adapter found")); closeConnection(); } } } TDEioBluetooth::~TDEioBluetooth() { kdDebug() << k_funcinfo << endl; if (manager) delete manager; if (adapter) delete adapter; } void TDEioBluetooth::closeConnection() { kdDebug() << k_funcinfo << endl; exit(); } void TDEioBluetooth::stat(const KURL &url) { kdDebug() << __func__ << "(" << url.prettyURL() << ")" << endl; TDEIO::UDSEntry entry; if (!adapter) { // ForwardingSlaveBase::warning(i18n("Bluetooth Adapter not found")); // ForwardingSlaveBase::error(TDEIO::ERR_SERVICE_NOT_AVAILABLE, i18n("Bluetooth Adapter not found")); TQString name = "No device found"; TQ_UINT32 devClass = 0; addAtom(entry, TDEIO::UDS_NAME, name); addAtom(entry, TDEIO::UDS_FILE_TYPE, S_IFDIR); addAtom(entry, TDEIO::UDS_ACCESS, 0555); addAtom(entry, TDEIO::UDS_MIME_TYPE, DeviceMimeConverter::classToMimeType(devClass)); addAtom(entry, TDEIO::UDS_ICON_NAME, DeviceMimeConverter::classToIconName(devClass)); return; } TQT_DBusError dbuserror; TQString path = url.path(); if (path.isEmpty() || path == "/") { // The root is "virtual" - it's not a single physical directory createTopLevelEntry(entry); } else if (path.find(TQRegExp("/\\[([0-9A-F]{2}:){5}[0-9A-F]{2}\\]"), 0) != -1) { createDirEntry(entry, path, path); } else { ForwardingSlaveBase::error(TDEIO::ERR_MALFORMED_URL, i18n("Could not stat %1.").arg(url.prettyURL())); } statEntry(entry); finished(); } void TDEioBluetooth::listDir(const KURL &url) { kdDebug() << k_funcinfo << endl; if (!adapter) { ForwardingSlaveBase::error(TDEIO::ERR_SERVICE_NOT_AVAILABLE, i18n("Bluetooth Adapter not found")); return; } TDEIO::UDSEntry entry; TQValueList list; TQT_DBusError error; TDEIO::UDSEntryList entries; TQString path = url.path(); TQString name = adapter->getName(error); kdDebug() << __func__ << "(" << path << ")" << endl; TQRegExp rx("/" + name + "/\\[([0-9A-F]{2}:){5}[0-9A-F]{2}\\]"); kdDebug() << "Regex: " << rx.search(path) << endl; if (rx.search(path) == 0) { listServices(list, url); } else if (path == "/" + name) { listDevices(list, url); } else if (path == "/") { createTopLevelEntry(entry); listEntry(entry, false); } else { ForwardingSlaveBase::listDir(url); } if (list.count() > 0) { kdDebug() << __func__ << "(" << path << ")" << endl; totalSize(list.count() + 1); TDEIO::UDSEntryListIterator it = list.begin(); TDEIO::UDSEntryListIterator end = list.end(); for (; it != end; ++it) { entries.append(*it); } listEntries(entries); } listEntry(entry, true); finished(); return; } bool TDEioBluetooth::rewriteURL(const KURL &url, KURL &newUrl) { kdDebug() << k_funcinfo << endl; TQString path = url.path(); TQString protocol = url.protocol(); if (protocol == "obexopp" || protocol == "obexftp") { newUrl = url; return true; } else { ForwardingSlaveBase::error(TDEIO::ERR_MALFORMED_URL, url.prettyURL()); return false; } } void TDEioBluetooth::createTopLevelEntry(TDEIO::UDSEntry &entry) { kdDebug() << k_funcinfo << endl; TQT_DBusError error; TQString name = adapter->getName(error); TQ_UINT32 devClass = adapter->getClass(error); addAtom(entry, TDEIO::UDS_NAME, name); addAtom(entry, TDEIO::UDS_FILE_TYPE, S_IFDIR); addAtom(entry, TDEIO::UDS_ACCESS, 0555); addAtom(entry, TDEIO::UDS_MIME_TYPE, DeviceMimeConverter::classToMimeType(devClass)); addAtom(entry, TDEIO::UDS_ICON_NAME, DeviceMimeConverter::classToIconName(devClass)); } bool TDEioBluetooth::listDevice(TDEIO::UDSEntry &entry, const TQString &path, const KURL &url) { kdDebug() << __func__ << "(" << url << ")" << endl; TQT_DBusError error; TDEBluetooth::DeviceImpl *dev = new TDEBluetooth::DeviceImpl("org.bluez", path); dev->setConnection((*(manager->getConnection()))); const TQString addr = dev->getAddress(error); TQString name = dev->getName(error); TQString alias = dev->getAlias(error); const int devClass = dev->getClass(error); TQString aname = adapter->getName(error); delete dev; entry.clear(); if (!alias.isEmpty()) name = alias; else name = alias = addr; createDirEntry(entry, name, TQString("bluetooth:/%1/[%2]").arg(aname).arg(addr), DeviceMimeConverter::classToMimeType(devClass)); return true; } bool TDEioBluetooth::listDevices(TQValueList &list, const KURL &url) { kdDebug() << __func__ << "(" << url << ")" << endl; TDEIO::UDSEntry entry; TDEBluetooth::ObjectManagerImpl::DeviceList dl = manager->getDevices(); TDEBluetooth::ObjectManagerImpl::DeviceList::Iterator dit = dl.begin(); for (dit; dit != dl.end(); ++dit) { entry.clear(); listDevice(entry, (*dit), url); list.append(entry); } return true; } bool TDEioBluetooth::listServices(TQValueList &list, const KURL &url) { kdDebug() << __func__ << "url: " << url << endl; TDEIO::UDSEntry entry; TQString path = url.path(); kdDebug() << __func__ << "path: " << path << endl; int pos = path.find(TQRegExp("/\\[([0-9A-F]{2}:){5}[0-9A-F]{2}\\]"), 0); if (pos != -1) { TQString address = path.remove(0, pos + 2).remove(17, path.length()); kdDebug() << __func__ << "address: " << address << endl; TDEBluetooth::ObjectManagerImpl::DeviceList dl = manager->getDevices(); TDEBluetooth::ObjectManagerImpl::DeviceList::Iterator dit = dl.begin(); for (dit; dit != dl.end(); ++dit) { TDEBluetooth::DeviceImpl *d = new TDEBluetooth::DeviceImpl("org.bluez", (*dit)); d->setConnection((*(manager->getConnection()))); TQT_DBusError dbuserror; TQString addr = d->getAddress(dbuserror); if (addr == address) { TQStringList uuids = d->getUUIDs(dbuserror); for (TQStringList::Iterator it = uuids.begin(); it != uuids.end(); ++it) { entry.clear(); // accepted services OBEX OPP, PCE, FTP //FIXME temporary disabled // if ((*it) == "00001105-0000-1000-8000-00805f9b34fb") // { // createDirEntry(entry, resolveUUID((*it)), TQString("obexopp:/[%1]/").arg(address), "bluetooth/obex-objectpush-profile"); // addAtom(entry, TDEIO::UDS_NAME, "obexopp"); // list.append(entry); // } // else if ((*it) == "00001106-0000-1000-8000-00805f9b34fb") // { // createDirEntry(entry, resolveUUID((*it)), TQString("obexftp:/[%1]/").arg(address), "bluetooth/obex-ftp-profile"); // addAtom(entry, TDEIO::UDS_NAME, "obexftp"); // list.append(entry); // } } break; } delete d; } } else { ForwardingSlaveBase::error(TDEIO::ERR_MALFORMED_URL, url.url()); } return true; } bool TDEioBluetooth::createDirEntry(TDEIO::UDSEntry &entry, const TQString &name, const TQString &dir, const TQString &mimeType) { kdDebug() << k_funcinfo << endl; addAtom(entry, TDEIO::UDS_NAME, name); if (dir != TQString::null) { addAtom(entry, TDEIO::UDS_URL, dir); } addAtom(entry, TDEIO::UDS_MIME_TYPE, mimeType); if (mimeType == "inode/directory") addAtom(entry, TDEIO::UDS_FILE_TYPE, S_IFDIR); else addAtom(entry, TDEIO::UDS_FILE_TYPE, S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); return true; } void TDEioBluetooth::slotAddDevice(const TQString &path) { kdDebug() << k_funcinfo << endl; listDir("bluetooth:/"); } void TDEioBluetooth::slotRemoveDevice(const TQString &path) { kdDebug() << __func__ << "(" << path << ")" << endl; listDir("bluetooth:/"); // TQT_DBusError error; // TDEBluetooth::DeviceImpl *d= new TDEBluetooth::DeviceImpl("org.bluez",path); // d->setConnection((*(manager->getConnection()))); // const TQString address = d->getAddress(error); // delete d; // // listDevice(address); // listEntry(TDEIO::UDSEntry(), true); } void TDEioBluetooth::slotAddService(const KURL &url, const TQString uuid) { kdDebug() << __func__ << "(URL=" << url << ", UUID=" << uuid << ")" << endl; // TQT_DBusError error; // TDEBluetooth::DeviceImpl *d= new TDEBluetooth::DeviceImpl("org.bluez",path); // d->setConnection((*(manager->getConnection()))); // const TQString address = d->getAddress(error); // TQ_UINT32 devclass = d->getClass(error); // const TQString devicon = DeviceMimeConverter::classToIconName(devclass); // delete d; // // TQMap::iterator f=qDevicesList.find(address); // if(f!=qDevicesList.end() && f.data() == devclass) return; // listEntry(UDSEntry(), true); } void TDEioBluetooth::slotAdapterPowerOnChanged(TQString const& path, bool state) { kdDebug() << __func__ << "(" << path << ")" << endl; // // TQT_DBusError error; // TDEBluetooth::DeviceImpl *d= new TDEBluetooth::DeviceImpl("org.bluez",path); // d->setConnection((*(manager->getConnection()))); // const TQString address = d->getAddress(error); // TQ_UINT32 devclass = d->getClass(error); // const TQString devicon = DeviceMimeConverter::classToIconName(devclass); // delete d; // // TQMap::iterator f=qDevicesList.find(address); // if(f!=qDevicesList.end() && f.data() == devclass) return; // qDevicesList.insert(address, devclass); // // listDevice(address); // listEntry(UDSEntry(), true); } void TDEioBluetooth::addAtom(TDEIO::UDSEntry &entry, TDEIO::UDSAtomTypes type, TQString s) { kdDebug() << k_funcinfo << endl; TDEIO::UDSAtom atom; atom.m_uds = type; atom.m_str = s; entry.append(atom); } void TDEioBluetooth::addAtom(TDEIO::UDSEntry &entry, TDEIO::UDSAtomTypes type, long l) { kdDebug() << k_funcinfo << endl; TDEIO::UDSAtom atom; atom.m_uds = type; atom.m_long = l; entry.append(atom); } #include "tdeiobluetooth.moc"