File indexing completed on 2024-04-28 16:43:20
0001 /* 0002 * SPDX-FileCopyrightText: 2010-2012 Alejandro Fiestas Olivares <afiestas@kde.org> 0003 * SPDX-FileCopyrightText: 2010 Eduardo Robles Elvira <edulix@gmail.com> 0004 * SPDX-FileCopyrightText: 2010 Rafael Fernández López <ereslibre@kde.org> 0005 * SPDX-FileCopyrightText: 2010 UFO Coders <info@ufocoders.com> 0006 * 0007 * SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 0010 #include "kiobluetooth.h" 0011 #include "filereceiversettings.h" 0012 #include "version.h" 0013 0014 #include <QCoreApplication> 0015 #include <QDBusMetaType> 0016 #include <QThread> 0017 0018 #include <KLocalizedString> 0019 0020 #include <BluezQt/Services> 0021 0022 // Pseudo plugin class to embed meta data 0023 class KIOPluginForMetaData : public QObject 0024 { 0025 Q_OBJECT 0026 Q_PLUGIN_METADATA(IID "org.kde.kio.slave.bluetooth" FILE "bluetooth.json") 0027 }; 0028 0029 extern "C" int Q_DECL_EXPORT kdemain(int argc, char **argv) 0030 { 0031 QCoreApplication app(argc, argv); 0032 0033 if (argc != 4) { 0034 fprintf(stderr, "Usage: kio_bluetooth protocol domain-socket1 domain-socket2\n"); 0035 exit(-1); 0036 } 0037 0038 KioBluetooth slave(argv[2], argv[3]); 0039 slave.dispatchLoop(); 0040 return 0; 0041 } 0042 0043 KioBluetooth::KioBluetooth(const QByteArray &pool, const QByteArray &app) 0044 : SlaveBase(QByteArrayLiteral("bluetooth"), pool, app) 0045 { 0046 qDBusRegisterMetaType<DeviceInfo>(); 0047 qDBusRegisterMetaType<QMapDeviceInfo>(); 0048 0049 m_hasCurrentHost = false; 0050 0051 Service sendFile; 0052 sendFile.name = i18n("Send File"); 0053 sendFile.icon = QStringLiteral("edit-copy"); 0054 sendFile.mimetype = QStringLiteral("application/vnd.kde.bluedevil-sendfile"); 0055 sendFile.uuid = BluezQt::Services::ObexObjectPush; 0056 0057 Service browseFiles; 0058 browseFiles.name = i18n("Browse Files"); 0059 browseFiles.icon = QStringLiteral("edit-find"); 0060 browseFiles.mimetype = QString(); 0061 browseFiles.uuid = BluezQt::Services::ObexFileTransfer; 0062 0063 m_supportedServices.insert(sendFile.uuid, sendFile); 0064 m_supportedServices.insert(browseFiles.uuid, browseFiles); 0065 0066 qCDebug(BLUETOOTH) << "Kio Bluetooth instanced!"; 0067 0068 m_kded = new org::kde::BlueDevil(QStringLiteral("org.kde.kded5"), QStringLiteral("/modules/bluedevil"), QDBusConnection::sessionBus()); 0069 0070 if (!m_kded->isOnline()) { 0071 qCDebug(BLUETOOTH) << "Bluetooth is offline"; 0072 infoMessage(i18n("No Bluetooth adapters have been found.")); 0073 return; 0074 } 0075 } 0076 0077 QList<KioBluetooth::Service> KioBluetooth::getSupportedServices(const QStringList &uuids) 0078 { 0079 qCDebug(BLUETOOTH) << "supported services: " << uuids; 0080 0081 QList<Service> retValue; 0082 for (const QString &uuid : uuids) { 0083 if (m_supportedServices.contains(uuid)) { 0084 retValue << m_supportedServices[uuid]; 0085 } 0086 } 0087 return retValue; 0088 } 0089 0090 void KioBluetooth::listRemoteDeviceServices() 0091 { 0092 infoMessage(i18n("Retrieving services…")); 0093 0094 qCDebug(BLUETOOTH) << "Listing remote devices"; 0095 0096 const DeviceInfo &info = m_kded->device(m_currentHostAddress).value(); 0097 if (info.isEmpty()) { 0098 qCDebug(BLUETOOTH) << "Invalid hostname!"; 0099 infoMessage(i18n("This address is unavailable.")); 0100 finished(); 0101 return; 0102 } 0103 0104 const QList<Service> &services = getSupportedServices(info.value(QStringLiteral("UUIDs")).split(QLatin1Char(','))); 0105 0106 qCDebug(BLUETOOTH) << "Num of supported services: " << services.size(); 0107 0108 int i = 1; 0109 totalSize(services.count()); 0110 0111 for (const Service &service : services) { 0112 KIO::UDSEntry entry; 0113 entry.fastInsert(KIO::UDSEntry::UDS_NAME, service.uuid); 0114 entry.fastInsert(KIO::UDSEntry::UDS_DISPLAY_NAME, service.name); 0115 entry.fastInsert(KIO::UDSEntry::UDS_ICON_NAME, service.icon); 0116 entry.fastInsert(KIO::UDSEntry::UDS_ACCESS, S_IRUSR | S_IRGRP | S_IROTH); 0117 0118 // If it is browse files, act as a folder 0119 if (service.uuid == BluezQt::Services::ObexFileTransfer) { 0120 QUrl obexUrl; 0121 obexUrl.setScheme(QStringLiteral("obexftp")); 0122 obexUrl.setHost(m_currentHostname.replace(QLatin1Char(':'), QLatin1Char('-')).toUpper()); 0123 entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); 0124 entry.fastInsert(KIO::UDSEntry::UDS_URL, obexUrl.toString()); 0125 } else { 0126 entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFREG); 0127 } 0128 0129 if (service.mimetype.isEmpty()) { 0130 entry.fastInsert(KIO::UDSEntry::UDS_MIME_TYPE, QStringLiteral("inode/vnd.kde.bluedevil.service")); 0131 } else { 0132 entry.fastInsert(KIO::UDSEntry::UDS_MIME_TYPE, service.mimetype); 0133 } 0134 0135 listEntry(entry); 0136 processedSize(i++); 0137 } 0138 0139 infoMessage(QString()); 0140 finished(); 0141 } 0142 0143 void KioBluetooth::listDownload() 0144 { 0145 KIO::UDSEntry entry; 0146 entry.clear(); 0147 entry.fastInsert(KIO::UDSEntry::UDS_URL, FileReceiverSettings::saveUrl().toDisplayString()); 0148 entry.fastInsert(KIO::UDSEntry::UDS_NAME, i18n("Received Files")); 0149 entry.fastInsert(KIO::UDSEntry::UDS_ICON_NAME, QStringLiteral("folder-downloads")); 0150 entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); 0151 entry.fastInsert(KIO::UDSEntry::UDS_ACCESS, S_IRUSR | S_IRGRP | S_IROTH); 0152 entry.fastInsert(KIO::UDSEntry::UDS_MIME_TYPE, QStringLiteral("inode/directory")); 0153 listEntry(entry); 0154 } 0155 0156 void KioBluetooth::listDevices() 0157 { 0158 qCDebug(BLUETOOTH) << "Asking kded for devices"; 0159 const QMapDeviceInfo &devices = m_kded->allDevices().value(); 0160 qCDebug(BLUETOOTH) << devices.keys(); 0161 0162 for (const DeviceInfo &device : devices) { 0163 listDevice(device); 0164 } 0165 0166 m_kded->startDiscovering(10 * 1000); 0167 0168 infoMessage(i18n("Scanning for new devices…")); 0169 finished(); 0170 } 0171 0172 void KioBluetooth::listDevice(const DeviceInfo device) 0173 { 0174 qCDebug(BLUETOOTH) << device; 0175 if (getSupportedServices(device[QStringLiteral("UUIDs")].split(QStringLiteral(","))).isEmpty()) { 0176 return; 0177 } 0178 QString target = QStringLiteral("bluetooth://"); 0179 target.append(QString(device[QStringLiteral("address")]).replace(QLatin1Char(':'), QLatin1Char('-')) + QLatin1Char('/')); 0180 0181 KIO::UDSEntry entry; 0182 entry.fastInsert(KIO::UDSEntry::UDS_URL, target); 0183 entry.fastInsert(KIO::UDSEntry::UDS_NAME, device[QStringLiteral("name")]); 0184 entry.fastInsert(KIO::UDSEntry::UDS_ICON_NAME, device[QStringLiteral("icon")]); 0185 entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); 0186 entry.fastInsert(KIO::UDSEntry::UDS_ACCESS, S_IRUSR | S_IRGRP | S_IROTH); 0187 entry.fastInsert(KIO::UDSEntry::UDS_MIME_TYPE, QStringLiteral("inode/vnd.kde.bluedevil.device")); 0188 listEntry(entry); 0189 } 0190 0191 void KioBluetooth::listDir(const QUrl &url) 0192 { 0193 qCDebug(BLUETOOTH) << "Listing..." << url; 0194 0195 // Url is not used here because all we could care about the url is the host, and that's already 0196 // handled in @p setHost 0197 Q_UNUSED(url); 0198 0199 // If we are not online (ie. there's no working bluetooth adapter), list an empty dir 0200 qCDebug(BLUETOOTH) << m_kded->isOnline().value(); 0201 if (!m_kded->isOnline().value()) { 0202 infoMessage(i18n("No Bluetooth adapters have been found.")); 0203 finished(); 0204 return; 0205 } 0206 0207 if (!m_hasCurrentHost) { 0208 listDownload(); 0209 listDevices(); 0210 } else { 0211 listRemoteDeviceServices(); 0212 } 0213 } 0214 0215 void KioBluetooth::stat(const QUrl &url) 0216 { 0217 qCDebug(BLUETOOTH) << "Stat: " << url; 0218 finished(); 0219 } 0220 0221 void KioBluetooth::get(const QUrl &url) 0222 { 0223 m_kded->stopDiscovering(); 0224 qCDebug(BLUETOOTH) << "Get: " << url; 0225 qCDebug(BLUETOOTH) << m_supportedServices.value(url.fileName()).mimetype; 0226 mimeType(m_supportedServices.value(url.fileName()).mimetype); 0227 finished(); 0228 } 0229 0230 void KioBluetooth::setHost(const QString &hostname, quint16 port, const QString &user, const QString &pass) 0231 { 0232 qCDebug(BLUETOOTH) << "Setting host: " << hostname; 0233 0234 // In this kio only the hostname (constHostname) is used 0235 Q_UNUSED(port) 0236 Q_UNUSED(user) 0237 Q_UNUSED(pass) 0238 0239 if (hostname.isEmpty()) { 0240 m_hasCurrentHost = false; 0241 } else { 0242 m_hasCurrentHost = true; 0243 0244 m_currentHostname = hostname; 0245 m_currentHostAddress = hostname.toUpper(); 0246 m_currentHostAddress.replace(QLatin1Char('-'), QLatin1Char(':')); 0247 } 0248 } 0249 0250 Q_LOGGING_CATEGORY(BLUETOOTH, "bluedevil.kio_bluetooth") 0251 0252 #include "kiobluetooth.moc"