#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" << int(data[0]) << "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; } }