void Session_Service::onRemoteObjectComplete(qi::Future<void> future, long requestId) { qiLogDebug() << "Got metaobject"; boost::recursive_mutex::scoped_lock l(_requestsMutex); ServiceRequest *sr = serviceRequest(requestId); if (!sr) return; if (future.hasError()) { sr->promise.setError(future.error()); removeRequest(requestId); return; } { boost::recursive_mutex::scoped_lock sl(_remoteObjectsMutex); RemoteObjectMap::iterator it = _remoteObjects.find(sr->name); if (it != _remoteObjects.end()) { //another object have been registered before us, return it //the new socket will be closed when the request is deleted qiLogVerbose() << "A request for the service " << sr->name << " have been discarded, " << "the remoteobject on the service was already available."; sr->promise.setValue(it->second); } else { AnyObject o = makeDynamicAnyObject(sr->remoteObject); //register the remote object in the cache addService(sr->name, o); sr->promise.setValue(o); sr->remoteObject = 0; } } removeRequest(requestId); }
void StdMemoryOS::solveRequest(MemRequest *r) { if (busy) { pendingReqs.push_back(r); } else { serviceRequest(r); } }
void Session_Service::onTransportSocketResult(qi::Future<TransportSocketPtr> value, long requestId) { qiLogDebug() << "Got transport socket for service"; { boost::recursive_mutex::scoped_lock sl(_requestsMutex); ServiceRequest *sr = serviceRequest(requestId); if (!sr) return; if (value.hasError()) { sr->promise.setError(value.error()); removeRequest(requestId); return; } } TransportSocketPtr socket = value.value(); // If true, this socket came from the socket cache and has already been identified. // This typically happens when two services are behind the same endpoint. // We forge a message that just shows we've authenticated successfully. if (socket->hasReceivedRemoteCapabilities()) { Message dummy; CapabilityMap cm; cm[AuthProvider::State_Key] = AnyValue::from(AuthProvider::State_Done); dummy.setType(Message::Type_Reply); dummy.setFunction(qi::Message::ServerFunction_Authenticate); dummy.setValue(AnyValue::from(cm), typeOf<CapabilityMap>()->signature()); onAuthentication(TransportSocket::SocketEventData(dummy), requestId, socket, ClientAuthenticatorPtr(new NullClientAuthenticator), SignalSubscriberPtr()); return; } ClientAuthenticatorPtr authenticator = _authFactory->newAuthenticator(); CapabilityMap authCaps; { CapabilityMap tmp = authenticator->initialAuthData(); for (CapabilityMap::iterator it = tmp.begin(), end = tmp.end(); it != end; ++it) authCaps[AuthProvider::UserAuthPrefix + it->first] = it->second; } SignalSubscriberPtr protSubscriber(new SignalSubscriber); *protSubscriber = socket->socketEvent.connect(&Session_Service::onAuthentication, this, _1, requestId, socket, authenticator, protSubscriber); Message msgCapabilities; msgCapabilities.setFunction(Message::ServerFunction_Authenticate); msgCapabilities.setService(Message::Service_Server); msgCapabilities.setType(Message::Type_Call); TransportSocketPtr sdSocket = _sdClient->socket(); CapabilityMap socketCaps; if (sdSocket) { socketCaps = sdSocket->localCapabilities(); socket->advertiseCapabilities(socketCaps); } socketCaps.insert(authCaps.begin(), authCaps.end()); msgCapabilities.setValue(socketCaps, typeOf<CapabilityMap>()->signature()); socket->send(msgCapabilities); }
void QDSActionPrivate::emitRequest() { connectToChannel(); startTimer(); QtopiaServiceRequest serviceRequest( mServiceInfo.serviceId(), mServiceInfo.name() + "(QDSActionRequest)" ); // No tr serviceRequest << QDSActionRequest( mServiceInfo, responseChannel() ); serviceRequest.send(); }
void QDSActionPrivate::emitRequest( const QDSData& requestData, const QByteArray& auxiliary ) { connectToChannel(); startTimer(); QtopiaServiceRequest serviceRequest( mServiceInfo.serviceId(), mServiceInfo.name() + "(QDSActionRequest)" ); // No tr serviceRequest << QDSActionRequest( mServiceInfo, requestData, responseChannel(), auxiliary ); serviceRequest.send(); }
void Session_Service::onTransportSocketResult(qi::Future<TransportSocketPtr> value, long requestId) { qiLogDebug() << "Got transport socket for service"; qi::Future<void> fut; { boost::recursive_mutex::scoped_lock sl(_requestsMutex); ServiceRequest *sr = serviceRequest(requestId); if (!sr) return; if (value.hasError()) { sr->promise.setError(value.error()); removeRequest(requestId); return; } sr->remoteObject = new qi::RemoteObject(sr->serviceId, value.value()); //ask the remoteObject to fetch the metaObject fut = sr->remoteObject->fetchMetaObject(); } fut.connect(&Session_Service::onRemoteObjectComplete, this, _1, requestId); }
void StdMemoryOS::attemptToEmptyQueue(ulong vaddr, ulong phPage) { // attempt a bypass long vPage = GMemorySystem::calcPage(vaddr); std::vector<MemRequest *>::iterator it = pendingReqs.begin(); if(it != pendingReqs.end()) { MemRequest *mm = *it; long tmpPage = GMemorySystem::calcPage(mm->getVaddr()); if(vPage == tmpPage) { launchReq(mm, GMemorySystem::calcPAddr(GMemorySystem::calcFullPage(vPage), mm->getVaddr())); it = pendingReqs.erase(it); } else it++ ; } // wakeup the next request if(!pendingReqs.empty()) { MemRequest *thisReq = pendingReqs.front(); pendingReqs.erase(pendingReqs.begin()); serviceRequest(thisReq); } }
// We received a ServiceInfo, and want to establish a connection void Session_Service::onServiceInfoResult(qi::Future<qi::ServiceInfo> result, long requestId, std::string protocol) { qiLogDebug() << "Got serviceinfo message"; { boost::recursive_mutex::scoped_lock sl(_requestsMutex); ServiceRequest *sr = serviceRequest(requestId); if (!sr) return; if (result.hasError()) { sr->promise.setError(result.error()); removeRequest(requestId); return; } const qi::ServiceInfo &si = result.value(); sr->serviceId = si.serviceId(); if (_sdClient->isLocal()) { // Wait! If sd is local, we necessarily have an open socket // on which service was registered, whose lifetime is bound // to the service TransportSocketPtr s = _sdClient->_socketOfService(sr->serviceId); if (!s) // weird qiLogVerbose() << "_socketOfService returned 0"; else { // check if the socket support that capability if (s->remoteCapability("ClientServerSocket", false)) { qiLogVerbose() << "sd is local and service is capable, going through socketOfService"; onTransportSocketResult(qi::Future<TransportSocketPtr>(s), requestId); return; } } } //empty serviceInfo if (!si.endpoints().size()) { std::stringstream ss; ss << "No endpoints returned for service:" << sr->name << " (id:" << sr->serviceId << ")"; qiLogVerbose() << ss.str(); sr->promise.setError(ss.str()); removeRequest(requestId); return; } if (protocol != "") { std::vector<qi::Url>::const_iterator it = si.endpoints().begin(); for (; it != si.endpoints().end() && it->protocol() != protocol; it++) { continue; } if (it == si.endpoints().end()) { std::stringstream ss; ss << "No " << protocol << " endpoint available for service:" << sr->name << " (id:" << sr->serviceId << ")"; qiLogVerbose() << ss.str(); sr->promise.setError(ss.str()); } } } qiLogDebug() << "Requesting socket from cache"; qi::Future<qi::TransportSocketPtr> fut = _socketCache->socket(result.value(), protocol); fut.connect(&Session_Service::onTransportSocketResult, this, _1, requestId); }
void Session_Service::onAuthentication(const TransportSocket::SocketEventData& data, long requestId, TransportSocketPtr socket, ClientAuthenticatorPtr auth, SignalSubscriberPtr old) { static const std::string cmsig = typeOf<CapabilityMap>()->signature().toString(); boost::recursive_mutex::scoped_lock sl(_requestsMutex); ServiceRequest *sr = serviceRequest(requestId); if (!sr) return; if (data.which() == TransportSocket::Event_Error) { if (old) socket->socketEvent.disconnect(*old); sr->promise.setError(boost::get<std::string>(data)); removeRequest(requestId); return; } #if BOOST_VERSION < 105800 const Message& msg = boost::get<const Message&>(data); #else const Message& msg = boost::relaxed_get<const Message&>(data); #endif int function = msg.function(); bool failure = msg.type() == Message::Type_Error || msg.service() != Message::Service_Server || function != Message::ServerFunction_Authenticate; if (failure) { if (old) socket->socketEvent.disconnect(*old); if (_enforceAuth) { std::stringstream error; if (msg.type() == Message::Type_Error) error << "Error while authenticating: " << msg.value("s", socket).to<std::string>(); else error << "Expected a message for function #" << Message::ServerFunction_Authenticate << " (authentication), received a message for function " << function; sr->promise.setError(error.str()); removeRequest(requestId); } else { session_service_private::sendCapabilities(socket); qi::Future<void> metaObjFut; sr->remoteObject = new qi::RemoteObject(sr->serviceId, socket); metaObjFut = sr->remoteObject->fetchMetaObject(); metaObjFut.connect(&Session_Service::onRemoteObjectComplete, this, _1, requestId); } return; } AnyReference cmref = msg.value(typeOf<CapabilityMap>()->signature(), socket); CapabilityMap authData = cmref.to<CapabilityMap>(); CapabilityMap::iterator authStateIt = authData.find(AuthProvider::State_Key); cmref.destroy(); if (authStateIt == authData.end() || authStateIt->second.to<unsigned int>() < AuthProvider::State_Error || authStateIt->second.to<unsigned int>() > AuthProvider::State_Done) { if (old) socket->socketEvent.disconnect(*old); std::string error = "Invalid authentication state token."; sr->promise.setError(error); removeRequest(requestId); qiLogInfo() << error; return; } if (authData[AuthProvider::State_Key].to<unsigned int>() == AuthProvider::State_Done) { qi::Future<void> metaObjFut; if (old) socket->socketEvent.disconnect(*old); sr->remoteObject = new qi::RemoteObject(sr->serviceId, socket); //ask the remoteObject to fetch the metaObject metaObjFut = sr->remoteObject->fetchMetaObject(); metaObjFut.connect(&Session_Service::onRemoteObjectComplete, this, _1, requestId); return; } CapabilityMap nextData = auth->processAuth(authData); Message authMsg; authMsg.setService(Message::Service_Server); authMsg.setType(Message::Type_Call); authMsg.setValue(nextData, cmsig); authMsg.setFunction(Message::ServerFunction_Authenticate); socket->send(authMsg); }