summaryrefslogtreecommitdiff
path: root/sap/capabilitypeer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sap/capabilitypeer.cc')
-rw-r--r--sap/capabilitypeer.cc187
1 files changed, 187 insertions, 0 deletions
diff --git a/sap/capabilitypeer.cc b/sap/capabilitypeer.cc
new file mode 100644
index 0000000..8dfe603
--- /dev/null
+++ b/sap/capabilitypeer.cc
@@ -0,0 +1,187 @@
+#include "sappeer.h"
+#include "sapconnection.h"
+#include "sapconnectionrequest.h"
+#include "sapsocket.h"
+#include "sapmanager.h"
+#include "capabilitypeer.h"
+
+CapabilityPeer::CapabilityPeer(SAPPeer *peer, QObject *parent) :
+ QObject(parent), _peer(peer), _conn(0), _socket(0)
+{
+ _consumerProfiles.insert(SAProtocol::capabilityDiscoveryProfile,
+ SAProtocol::capabilityDiscoveryAgentId);
+ _providerProfiles.insert(SAProtocol::capabilityDiscoveryProfile,
+ SAProtocol::capabilityDiscoveryAgentId);
+
+ if (_peer->role() == SAProtocol::ClientRole) {
+ _conn = _peer->createServiceConnection(SAProtocol::capabilityDiscoveryProfile,
+ SAProtocol::capabilityDiscoveryProfile, SAPServiceInfo::RoleConsumer);
+ connect(_conn, SIGNAL(connected()), SLOT(handleConnected()));
+ }
+}
+
+void CapabilityPeer::requestConnection(SAPConnectionRequest *request)
+{
+ _conn = request->connection();
+ request->accept();
+}
+
+int CapabilityPeer::remoteAgentId(const QString &profile, SAPServiceInfo::Role role)
+{
+ QHash<QString, int> *profiles = profilesByRole(role);
+ if (!profiles) return -1;
+
+ return profiles->value(profile, -1);
+}
+
+SAPServiceInfo CapabilityPeer::remoteServiceInfo(int agentId) const
+{
+ return _remoteAgents.value(agentId).info;
+}
+
+void CapabilityPeer::handleConnected()
+{
+ Q_ASSERT(_conn);
+ _socket = _conn->getSocket(SAProtocol::capabilityDiscoveryChannel);
+ Q_ASSERT(_socket);
+
+ connect(_socket, SIGNAL(messageReceived()), SLOT(handleMessageReceived()));
+
+ // Send a discovery query.
+ SAProtocol::CapabilityDiscoveryQuery msg;
+
+ msg.messageType = SAProtocol::CapabilityDiscoveryMessageTypeQuery;
+ msg.queryType = 2;
+ msg.checksum = 1;
+
+ // Query for all known profiles
+ QSet<QString> profiles = SAPManager::instance()->allProfiles();
+ profiles.remove(SAProtocol::capabilityDiscoveryProfile);
+ msg.records = profiles.toList();
+
+ qDebug() << "Quering for profiles:" << msg.records;
+
+ if (msg.records.isEmpty()) {
+ // Nothing to do
+ qWarning() << "No local profiles!";
+ return;
+ }
+
+ _socket->send(SAProtocol::packCapabilityDiscoveryQuery(msg));
+}
+
+void CapabilityPeer::handleMessageReceived()
+{
+ QByteArray data = _socket->receive();
+
+ if (data.size() < 6) {
+ qWarning() << "Invalid capability message received";
+ return;
+ }
+
+ switch (data[0]) {
+ case SAProtocol::CapabilityDiscoveryMessageTypeQuery: {
+ SAProtocol::CapabilityDiscoveryQuery msg = SAProtocol::unpackCapabilityDiscoveryQuery(data);
+ SAProtocol::CapabilityDiscoveryResponse resp;
+ SAPManager *manager = SAPManager::instance();
+
+ {
+ QDebug d = qDebug();
+ d << "Queried for caps:";
+ foreach(const QString &cap, msg.records) {
+ d << cap;
+ }
+ }
+
+ qDebug() << "Got checksum" << msg.checksum;
+
+ resp.messageType = SAProtocol::CapabilityDiscoveryMessageTypeResponse;
+ resp.queryType = 3; // Why?
+ resp.checksum = 1; // We will always cause a checksum fail for now.
+
+ foreach (const QString &profile, msg.records) {
+ int agentId = manager->registeredAgentId(profile, SAPServiceInfo::RoleProvider);
+ if (agentId >= 0) {
+ const SAPServiceInfo &info = manager->serviceInfo(agentId);
+ SAProtocol::CapabilityDiscoveryProvider provider;
+ provider.name = info.friendlyName();
+ provider.uuid = 0;
+
+ SAProtocol::CapabilityDiscoveryService service;
+ service.aspVersion = info.version();
+ service.componentId = agentId;
+ service.connTimeout = info.connectionTimeout();
+ service.profile = profile;
+ service.role = info.role();
+ provider.services.append(service);
+
+ Q_ASSERT(service.role == SAPServiceInfo::RoleProvider);
+
+ resp.providers.append(provider);
+ }
+
+ agentId = manager->registeredAgentId(profile, SAPServiceInfo::RoleConsumer);
+ if (agentId >= 0) {
+ const SAPServiceInfo &info = manager->serviceInfo(agentId);
+ SAProtocol::CapabilityDiscoveryProvider provider;
+ provider.name = info.friendlyName();
+ provider.uuid = 0x1234;
+
+ SAProtocol::CapabilityDiscoveryService service;
+ service.aspVersion = info.version();
+ service.componentId = agentId;
+ service.connTimeout = info.connectionTimeout();
+ service.profile = profile;
+ service.role = info.role();
+ provider.services.append(service);
+
+ Q_ASSERT(service.role == SAPServiceInfo::RoleConsumer);
+
+ resp.providers.append(provider);
+ }
+ }
+
+ _socket->send(SAProtocol::packCapabilityDiscoveryResponse(resp));
+
+ break;
+ }
+ case SAProtocol::CapabilityDiscoveryMessageTypeResponse: {
+ SAProtocol::CapabilityDiscoveryResponse msg = SAProtocol::unpackCapabilityDiscoveryResponse(data);
+
+ foreach (const SAProtocol::CapabilityDiscoveryProvider &provider, msg.providers) {
+ foreach (const SAProtocol::CapabilityDiscoveryService &service, provider.services) {
+ RemoteAgent ragent;
+ ragent.agentId = service.componentId;
+ ragent.info.setFriendlyName(provider.name);
+ ragent.info.setProfile(service.profile);
+ ragent.info.setRole(static_cast<SAPServiceInfo::Role>(service.role));
+ ragent.info.setVersion(service.aspVersion);
+ ragent.info.setConnectionTimeout(service.connTimeout);
+
+ _remoteAgents.insert(ragent.agentId, ragent);
+
+ QHash<QString, int> *profiles = profilesByRole(ragent.info.role());
+ if (!profiles) continue;
+ profiles->insert(ragent.info.profile(), ragent.agentId);
+ }
+ }
+
+ break;
+ }
+ default:
+ qWarning() << "Unknown message" << int(data[0]) << "to capability socket";
+ break;
+ }
+}
+
+QHash<QString, int>* CapabilityPeer::profilesByRole(SAPServiceInfo::Role role)
+{
+ switch (role) {
+ case SAPServiceInfo::RoleProvider:
+ return &_providerProfiles;
+ case SAPServiceInfo::RoleConsumer:
+ return &_consumerProfiles;
+ default:
+ return 0;
+ }
+}