Exemple #1
0
  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);
  }
Exemple #2
0
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);
  }
Exemple #4
0
void QDSActionPrivate::emitRequest()
{
    connectToChannel();
    startTimer();

    QtopiaServiceRequest serviceRequest(
        mServiceInfo.serviceId(),
        mServiceInfo.name() + "(QDSActionRequest)" ); // No tr

    serviceRequest << QDSActionRequest( mServiceInfo, responseChannel() );
    serviceRequest.send();
}
Exemple #5
0
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();
}
Exemple #6
0
  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);
  }
Exemple #7
0
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);
    }
}
Exemple #8
0
  // 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);
  }