From d8d8fc7a0d139e7b864eee3b573bd208f823ad4f Mon Sep 17 00:00:00 2001 From: Javier Date: Sun, 19 Oct 2014 18:45:03 +0200 Subject: initial import, no crypto --- capabilitypeer.cc | 187 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 capabilitypeer.cc (limited to 'capabilitypeer.cc') diff --git a/capabilitypeer.cc b/capabilitypeer.cc new file mode 100644 index 0000000..0290b69 --- /dev/null +++ b/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 *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 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(service.role)); + ragent.info.setVersion(service.aspVersion); + ragent.info.setConnectionTimeout(service.connTimeout); + + _remoteAgents.insert(ragent.agentId, ragent); + + QHash *profiles = profilesByRole(ragent.info.role()); + if (!profiles) continue; + profiles->insert(ragent.info.profile(), ragent.agentId); + } + } + + break; + } + default: + qWarning() << "Unknown message to capability socket"; + break; + } +} + +QHash* CapabilityPeer::profilesByRole(SAPServiceInfo::Role role) +{ + switch (role) { + case SAPServiceInfo::RoleProvider: + return &_providerProfiles; + case SAPServiceInfo::RoleConsumer: + return &_consumerProfiles; + default: + return 0; + } +} -- cgit v1.2.3