Example #1
0
/**
 * \brief Initialize a connection to a terminal server and block until
 *        connection is established.
 *
 * \param client     Terminal client state, initialized by function to default
 *                   values.
 * \param session_id The session the domain is part of.
 *
 * Dispatches the monitor waitset until all the bindings to the terminal server
 * are established.
 */
errval_t term_client_blocking_init(struct term_client *client,
                                   struct capref session_id)
{
    errval_t err;
    iref_t in_iref;
    iref_t out_iref;
    iref_t conf_iref;

    /* Initialize client state to default values. */
    struct_term_client_init(client);

    /* Get the interface references from octopus. */
    err = get_irefs(session_id, &in_iref, &out_iref, &conf_iref);
    if (err_is_fail(err)) {
        return err;
    }

    /* Bind to interface for incoming characters. */
    err = terminal_bind(in_iref, in_bind_cb, client, client->read_ws,
                        IDC_BIND_FLAGS_DEFAULT);
    if (err_is_fail(err)) {
        return err_push(err, TERM_ERR_BIND_IN_INTERFACE);
    }
    TERM_DEBUG("Binding to terminal interface for incoming characters.\n");

    /* Bind to interface for outgoing characters. */
    err = terminal_bind(out_iref, out_bind_cb, client, client->write_ws,
                        IDC_BIND_FLAGS_DEFAULT);
    if (err_is_fail(err)) {
        return err_push(err, TERM_ERR_BIND_OUT_INTERFACE);
    }
    TERM_DEBUG("Binding to terminal interface for outgoing characters.\n");

    /* Bind to interface for incoming characters. */
    err = terminal_config_bind(conf_iref, conf_bind_cb, client,
                               client->conf_ws, IDC_BIND_FLAGS_DEFAULT);
    if (err_is_fail(err)) {
        return err_push(err, TERM_ERR_BIND_CONF_INTERFACE);
    }
    TERM_DEBUG("Binding to terminal configuration interface for configuration "
               "messages.\n");

    /*
     * Dispatch on the monitor binding until the bind completes. Otherwise, we
     * would have to check before every term_client_blocking_read and
     * term_client_blocking_write if we're already connected.
     */
    struct monitor_binding *monitor_b = get_monitor_binding();
    struct waitset *monitor_ws = monitor_b->waitset;
    while (!client->connected) {
        err = event_dispatch(monitor_ws);
        if (err_is_fail(err)) {
                USER_PANIC_ERR(err, "Error dispatching events.");
        }
    }
    TERM_DEBUG("Connection to terminal server successfully established.\n");

    return SYS_ERR_OK;
}
Example #2
0
/**
 * \brief Retrieve interface references for incoming and outgoing characters
 *        as well as for configuration messages from octopus.
 */
static errval_t get_irefs(struct capref session_id, iref_t *in_iref,
                          iref_t *out_iref, iref_t *conf_iref)
{
    errval_t err;

    struct octopus_rpc_client *r = get_octopus_rpc_client();
    assert(r != NULL);

    char *record;
    errval_t error_code;
    octopus_trigger_id_t tid;
    err = r->vtbl.get_with_idcap(r, session_id, NOP_TRIGGER, &record, &tid,
                                 &error_code);
    if (err_is_fail(err)) {
        err_push(err, TERM_ERR_LOOKUP_SESSION_RECORD);
        goto out;
    }
    err = error_code;
    if (err_is_fail(err)) {
        err_push(err, TERM_ERR_LOOKUP_SESSION_RECORD);
        goto out;
    }

    TERM_DEBUG("Record retrieved from octopus: %s\n", record);

    int64_t session_oct;
    int64_t in_oct;
    int64_t out_oct;
    int64_t conf_oct;
    // oct_read can only parse 64-bit values, we need to parse the irefs as 64bit
    // then cast to 32bit
    err = oct_read(record, "_ { session_iref: %d, in_iref: %d, out_iref: %d, "
                   "conf_iref: %d }", &session_oct, &in_oct, &out_oct,
                    &conf_oct);
    //iref_t session_iref = (iref_t)session_oct;
    *in_iref = (iref_t)in_oct;
    *out_iref = (iref_t)out_oct;
    *conf_iref = (iref_t)conf_oct;
    if (err_is_fail(err)) {
        err_push(err, TERM_ERR_PARSE_SESSION_RECORD);
        goto out;
    }
    if ((*in_iref == NULL_IREF) || (*out_iref == NULL_IREF) ||
        (*conf_iref == NULL_IREF)) {
        err = TERM_ERR_PARSE_SESSION_RECORD;
        goto out;
    }

    TERM_DEBUG("Retrieved interface references from octopus. in_iref: %"
               PRIuIREF ", out_iref: %" PRIuIREF ", conf_iref: %" PRIuIREF
               "\n", *in_iref, *out_iref, *conf_iref);

out:
    free(record);
    return err;
}
Example #3
0
static void exit_cb(void *arg)
{
    struct term_client *client = arg;

    client->connected = false;
    TERM_DEBUG("Disconnect message sucessfully sent to terminal server.\n");
}
Example #4
0
/**
 * \brief Retrieve interface references for incoming and outgoing characters
 *        as well as for configuration messages from octopus.
 */
static errval_t get_irefs(struct capref session_id, iref_t *in_iref,
                          iref_t *out_iref, iref_t *conf_iref)
{
    errval_t err;

    struct octopus_rpc_client *r = get_octopus_rpc_client();
    assert(r != NULL);

    char *record;
    errval_t error_code;
    octopus_trigger_id_t tid;
    err = r->vtbl.get_with_idcap(r, session_id, NOP_TRIGGER, &record, &tid,
                                 &error_code);
    if (err_is_fail(err)) {
        err_push(err, TERM_ERR_LOOKUP_SESSION_RECORD);
        goto out;
    }
    err = error_code;
    if (err_is_fail(err)) {
        err_push(err, TERM_ERR_LOOKUP_SESSION_RECORD);
        goto out;
    }

    TERM_DEBUG("Record retrieved from octopus: %s\n", record);

    iref_t session_iref;
    err = oct_read(record, "_ { session_iref: %d, in_iref: %d, out_iref: %d, "
                   "conf_iref: %d }", &session_iref, in_iref, out_iref,
                   conf_iref);
    if (err_is_fail(err)) {
        err_push(err, TERM_ERR_PARSE_SESSION_RECORD);
        goto out;
    }
    if ((*in_iref == NULL_IREF) || (*out_iref == NULL_IREF) ||
        (*conf_iref == NULL_IREF)) {
        err = TERM_ERR_PARSE_SESSION_RECORD;
        goto out;
    }

    TERM_DEBUG("Retrieved interface references from octopus. in_iref: %"
               PRIuIREF ", out_iref: %" PRIuIREF ", conf_iref: %" PRIuIREF
               "\n", *in_iref, *out_iref, *conf_iref);

out:
    free(record);
    return err;
}
Example #5
0
/**
 * \brief Tear down connection to terminal server.
 *
 * \param client Terminal client state.
 *
 * Dispatches the control waitset until the message is sent.
 */
void term_client_blocking_exit(struct term_client *client)
{
    errval_t err;

    TERM_DEBUG("Sending disconnect message to terminal device.\n");

    /* Inform terminal device (server), that domain terminated. */
    err = client->conf_binding->tx_vtbl.disconnect(client->conf_binding,
                                                   MKCONT(exit_cb, client));
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "Error sending disconnect to terminal device.\n");
    }

    /* Wait until message is sent. Necessary to ensure that message is sent
     * before we terminate. */
    TERM_DEBUG("Waiting until disconnect message is sent.\n");
    while (client->connected) {
        err = event_dispatch(client->conf_ws);
        if (err_is_fail(err)) {
            USER_PANIC_ERR(err, "Error dispatching events.");
        }
    }
}