1/*
2 * Copyright (c) 2007-12 ETH Zurich.
3 * All rights reserved.
4 *
5 * This file is distributed under the terms in the attached LICENSE file.
6 * If you do not find this file, copies can be found by writing to:
7 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
8 */
9
10#include <stdio.h>
11#include <string.h>
12
13#include <barrelfish/barrelfish.h>
14#include <barrelfish/waitset.h>
15#include <barrelfish/nameservice_client.h>
16#include <lwip/inet.h>
17
18#include <if/sfn5122f_defs.h>
19
20#include "port_management_support.h"
21#include "device_manager_debug.h"
22
23
24
25/******************************************************************************
26 * Local state
27 ******************************************************************************/
28
29/** Connection to sfn5122f management service */
30struct sfn5122f_binding *sfn5122f_binding = NULL;
31
32/******************************************************************************
33 * Operations for filter interface
34 ******************************************************************************/
35
36// Callback for bind
37static void bind_cb(void *st, errval_t err, struct sfn5122f_binding *b)
38{
39    assert(err_is_ok(err));
40
41    NDM_DEBUG("Sucessfully connected to management interface\n");
42
43    sfn5122f_binding = b;
44    sfn5122f_rpc_client_init(sfn5122f_binding);
45}
46
47/** Open connection to management interface */
48static void connect_to_mngif(char *dev_name)
49{
50    errval_t r;
51    iref_t iref;
52    const char *suffix = "_sfn5122fmng";
53    char name[strlen(dev_name) + strlen(suffix) + 1];
54
55    // Build label for management service
56    sprintf(name, "%s%s", dev_name, suffix);
57
58    // Connect to service
59    r = nameservice_blocking_lookup(name, &iref);
60    assert(err_is_ok(r));
61
62    r = sfn5122f_bind(iref, bind_cb, NULL, get_default_waitset(),
63            IDC_BIND_FLAGS_DEFAULT);
64    assert(err_is_ok(r));
65}
66
67/******************************************************************************
68 * Operations for filter interface
69 ******************************************************************************/
70
71static void init_filters(char *dev_name, qid_t qid)
72{
73    NDM_DEBUG("sfn5122f_flt: init %s %d\n", dev_name, (int) qid);
74
75    // Check if we are already initialized from another queue
76    if (sfn5122f_binding != NULL) {
77        return;
78    }
79
80    connect_to_mngif(dev_name);
81
82    // waiting for connection to succeed.
83    NDM_DEBUG("sfn5122f_init_filters: wait connection\n");
84    while (sfn5122f_binding == NULL) {
85        messages_wait_and_handle_next();
86    }
87}
88
89static void reg_arp_filters(uint64_t id, uint64_t len_rx,
90                            uint64_t len_tx)
91{
92    USER_PANIC("reg_arp_filters() not supported yet in sfn5122f filters");
93}
94
95static errval_t reg_filters(uint16_t port,
96                            port_type_t type,
97                            bufid_t buffer_id_rx,
98                            bufid_t buffer_id_tx,
99                            appid_t appid,
100                            qid_t qid,
101                            uint64_t *id, errval_t *rerr, uint64_t *filter_id)
102{
103    sfn5122f_port_type_t t;
104    assert(sfn5122f_binding != NULL);
105
106    NDM_DEBUG("sfn5122f_reg_filters()\n");
107
108    if (type == net_ports_PORT_TCP) {
109        t = sfn5122f_PORT_TCP;
110    } else {
111        t = sfn5122f_PORT_UDP;
112    }
113    errval_t err;
114    err = sfn5122f_binding->rpc_tx_vtbl.register_port_filter(sfn5122f_binding, buffer_id_rx, buffer_id_tx, qid, t, port, rerr, filter_id);
115
116    return SYS_ERR_OK;
117}
118
119static errval_t unreg_filters(uint64_t filter_id, qid_t qid)
120{
121    assert(sfn5122f_binding != NULL);
122
123    NDM_DEBUG("sfn5122f_unreg_filters()\n");
124    errval_t err, rerr;
125    err = sfn5122f_binding->rpc_tx_vtbl.unregister_filter(sfn5122f_binding, filter_id, &rerr);
126    assert(err_is_ok(err));
127
128    return rerr;
129}
130
131
132/******************************************************************************
133 * Get signature of this service
134 ******************************************************************************/
135
136static struct filters_tx_vtbl sfn5122f_filts_mng = {
137    .type = "sfn5122f_filters",
138    .init_filters = init_filters,
139    .reg_arp_filters = reg_arp_filters,
140    .reg_filters = reg_filters,
141    .unreg_filters = unreg_filters,
142};
143
144struct filters_tx_vtbl *get_sfn5122f_filt_mng_sign(void)
145{
146    return &sfn5122f_filts_mng;
147}
148