Example #1
0
    ServerImpl::ServerImpl(connection::ConnectionPtr const &conn,
                           boost::optional<std::string> const &host,
                           boost::optional<int> const &port)
        : m_conn(conn), m_ctx(make_shared<pluginhost::RegistrationContext>()),
          m_host(host.get_value_or("localhost")),
          m_port(port.get_value_or(util::UseDefaultPort)),
          m_log(util::log::make_logger(util::log::OSVR_SERVER_LOG)) {
        if (!m_conn) {
            throw std::logic_error(
                "Can't pass a null ConnectionPtr into Server constructor!");
        }
        osvr::connection::Connection::storeConnection(*m_ctx, m_conn);

        // Get the underlying VRPN connection, and make sure it's OK.
        auto vrpnConn = getVRPNConnection(m_conn);

        if (!(vrpnConn->doing_okay())) {
            throw ServerCreationFailure();
        }

        // Set up system device/system component
        m_systemDevice = common::createServerDevice(
            common::SystemComponent::deviceName(), vrpnConn);

        m_systemComponent =
            m_systemDevice->addComponent(common::SystemComponent::create());
        m_systemComponent->registerClientRouteUpdateHandler(
            &ServerImpl::m_handleUpdatedRoute, this);

        // Things to do when we get a new incoming connection
        // No longer doing hardware detect unconditionally here - see
        // triggerHardwareDetect()
        m_commonComponent =
            m_systemDevice->addComponent(common::CommonComponent::create());
        m_commonComponent->registerPingHandler([&] { m_queueTreeSend(); });

        // Set up the default display descriptor.
        m_tree.getNodeByPath("/display").value() =
            common::elements::StringElement(util::makeString(display_json));
        // Deal with updated device descriptors.
        m_conn->registerDescriptorHandler([&] { m_handleDeviceDescriptors(); });

        // Set up handlers to enter/exit idle sleep mode.
        // Can't do this with the nice wrappers on the CommonComponent of the
        // system device, I suppose since people aren't really connecting to
        // that device.
        vrpnConn->register_handler(
            vrpnConn->register_message_type(vrpn_got_first_connection),
            &ServerImpl::m_exitIdle, this);
        vrpnConn->register_handler(
            vrpnConn->register_message_type(vrpn_dropped_last_connection),
            &ServerImpl::m_enterIdle, this);
    }
Example #2
0
vrpn_File_Connection::vrpn_File_Connection (const char * station_name,
                         const char * local_in_logfile_name,
                         const char * local_out_logfile_name) :
    vrpn_Connection (local_in_logfile_name, local_out_logfile_name, NULL, NULL),
    d_controllerId (register_sender("vrpn File Controller")),
    d_set_replay_rate_type(register_message_type("vrpn_File set_replay_rate")),
    d_reset_type (register_message_type("vrpn_File reset")),
    d_play_to_time_type (register_message_type("vrpn_File play_to_time")),
    d_fileName (NULL),
    d_file (NULL),
    d_logHead (NULL),
    d_logTail (NULL),
    d_currentLogEntry (NULL),
    d_preload(vrpn_FILE_CONNECTIONS_SHOULD_PRELOAD),
    d_accumulate(vrpn_FILE_CONNECTIONS_SHOULD_ACCUMULATE)
{
    // Because we are a file connection, our status should be CONNECTED
    // Later set this to BROKEN if there is a problem opening/reading the file.
    if (d_endpoints[0] == NULL) {
      fprintf(stderr,"vrpn_File_Connection::vrpn_File_Connection(): NULL zeroeth endpoint\n");
    } else {
      connectionStatus = CONNECTED;
      d_endpoints[0]->status = CONNECTED;
    }

    // If we are preloading, then we must accumulate messages.
    if (d_preload) {
      d_accumulate = true;
    }

    // These are handlers for messages that may be sent from a
    // vrpn_File_Controller object that may attach itself to us.
    register_handler(d_set_replay_rate_type, handle_set_replay_rate,
                     this, d_controllerId);
    register_handler(d_reset_type, handle_reset, this, d_controllerId);
    register_handler(d_play_to_time_type, handle_play_to_time,
                     this, d_controllerId);

    // necessary to initialize properly in mainloop()
    d_last_time.tv_usec = d_last_time.tv_sec = 0;
    
    d_fileName = vrpn_copy_file_name(station_name);
    if (!d_fileName) {
        fprintf(stderr, "vrpn_File_Connection:  Out of memory!\n");
        connectionStatus = BROKEN;
        return;
    }

    d_file = fopen(d_fileName, "rb");
    if (!d_file) {
        fprintf(stderr, "vrpn_File_Connection:  "
                "Could not open file \"%s\".\n", d_fileName);
        connectionStatus = BROKEN;
        return;
    }

    // Read the cookie from the file.  It will print an error message if it
    // can't read it, so we just pass the broken status on up the chain.
    if (read_cookie() < 0) {
	connectionStatus = BROKEN;
	return;
    }

    // If we are supposed to preload the entire file into memory buffers,
    // then keep reading until we get to the end.  Otherwise, just read the
    // first message to get things going.
    if (d_preload) {
      while (!read_entry()) { }
    } else {
      read_entry();
    }

    // Initialize the "current message" pointer to the first log-file
    // entry that was read, and set the start time for the file and
    // the current time to the one in this message.
    if (d_logHead) {
      d_currentLogEntry = d_logHead;
      d_startEntry = d_logHead;
      d_start_time = d_startEntry->data.msg_time;  
      d_time = d_start_time;
      d_earliest_user_time.tv_sec = d_earliest_user_time.tv_usec = 0;
      d_earliest_user_time_valid = false;
      d_highest_user_time.tv_sec = d_highest_user_time.tv_usec = 0;
      d_highest_user_time_valid = false;
    } else {
      fprintf(stderr, "vrpn_File_Connection: Can't read first message\n");
      connectionStatus = BROKEN;
      return;
    }

    // This is useful to play the initial system messages
    // (the sender/type ones) automatically.  These might not be
    // time synched so if we don't play them automatically they
    // can mess up playback if their timestamps are later then
    // the first user message.
    if (vrpn_FILE_CONNECTIONS_SHOULD_SKIP_TO_USER_MESSAGES) {
	play_to_user_message();
	if (d_currentLogEntry) {
	    d_start_time = d_currentLogEntry->data.msg_time;
	    d_time = d_start_time;
	}
    }

    // Add this to the list of known connections.
    vrpn_ConnectionManager::instance().addConnection(this, station_name);
}