1/**
2 * \file
3 * \brief Code to initialize the octopus server.
4 *
5 * Sets up bindings and vtables.
6 */
7
8/*
9 * Copyright (c) 2011, 2012, ETH Zurich.
10 * All rights reserved.
11 *
12 * This file is distributed under the terms in the attached LICENSE file.
13 * If you do not find this file, copies can be found by writing to:
14 * ETH Zurich D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
15 */
16
17#include <barrelfish/barrelfish.h>
18#include <barrelfish/nameservice_client.h>
19
20#include <if/octopus_defs.h>
21#include <if/monitor_defs.h>
22
23#include <octopus_server/init.h>
24#include <octopus_server/service.h>
25#include <octopus_server/debug.h>
26
27#define OCT_RPC_SERVICE_NAME "octopus_rpc"
28
29static struct export_state {
30    bool is_done;
31    errval_t err;
32} rpc_export;
33
34static const struct octopus_rx_vtbl rpc_rx_vtbl = {
35        .get_names_call = get_names_handler,
36        .get_call = get_handler,
37        .set_call = set_handler,
38        .get_with_idcap_call = get_with_idcap_handler,
39        .set_with_idcap_call = set_with_idcap_handler,
40        .del_call = del_handler,
41        .exists_call = exists_handler,
42        .wait_for_call = wait_for_handler,
43        .remove_trigger_call = remove_trigger_handler,
44
45        .subscribe_call = subscribe_handler,
46        .unsubscribe_call = unsubscribe_handler,
47        .publish_call = publish_handler,
48
49        .get_identifier_call = get_identifier,
50        .identify_call = identify_binding,
51
52        // Cap storage
53        .get_cap_call = get_cap_handler,
54        .put_cap_call = put_cap_handler,
55        .sput_cap_call = sput_cap_handler,
56        .remove_cap_call = remove_cap_handler,
57};
58
59static void rpc_export_cb(void *st, errval_t err, iref_t iref)
60{
61    rpc_export.is_done = true;
62    rpc_export.err = err;
63
64    if (err_is_ok(err)) {
65        struct monitor_binding *mb = get_monitor_binding();
66        OCT_DEBUG("octopus rpc iref is: %"PRIu32"\n", iref);
67        err = mb->tx_vtbl.set_name_iref_request(mb, NOP_CONT, iref);
68        if(err_is_fail(err)) {
69            USER_PANIC_ERR(err, "failed to send set_name_iref_request to monitor");
70        }
71    }
72}
73
74static errval_t rpc_connect_cb(void *st, struct octopus_binding *b)
75{
76    // Set up continuation queue
77    b->st = NULL;
78
79    // copy my message receive handler vtable to the binding
80    b->rx_vtbl = rpc_rx_vtbl;
81
82    // accept the connection (we could return an error to refuse it)
83    return SYS_ERR_OK;
84}
85
86errval_t rpc_server_init(void)
87{
88    rpc_export.err = SYS_ERR_OK;
89    rpc_export.is_done = false;
90
91    errval_t err = octopus_export(&rpc_export, rpc_export_cb, rpc_connect_cb,
92            get_default_waitset(), IDC_EXPORT_FLAGS_DEFAULT);
93
94    if (err_is_fail(err)) {
95        return err;
96    }
97
98    // XXX: broken
99    while (!rpc_export.is_done) {
100        messages_wait_and_handle_next();
101    }
102
103    return rpc_export.err;
104}
105
106/**
107 * \brief Sets up bindings for the octopus server and registers them in the
108 * nameserver.
109 *
110 * \retval SYS_ERR_OK
111 */
112errval_t oct_server_init(void)
113{
114    errval_t err = rpc_server_init();
115    if (err_is_fail(err)) {
116        return err;
117    }
118    err = init_capstorage();
119
120    return err;
121}
122