1#include <stdio.h>
2#include <string.h>
3
4#include<bulk_transfer/bulk_transfer.h>
5#include<bulk_transfer/bulk_allocator.h>
6#include<bulk_transfer/bulk_local.h>
7
8#define BUFSZ 0x1000
9
10static void dummy_cont_cb(void *arg, errval_t err, struct bulk_channel *channel)
11{
12    //printf("DUMMY CONT\n");
13}
14
15struct bulk_continuation dummy_cont = { .arg = NULL, .handler = dummy_cont_cb, };
16
17/******************************************************************************/
18/* Receiver */
19
20static errval_t cb_rx_bind_received(struct bulk_channel *channel);
21static void cb_rx_move_received(struct bulk_channel *channel,
22                                struct bulk_buffer *buffer,
23                                void *meta);
24static void cb_rx_copy_received(struct bulk_channel *channel,
25                                struct bulk_buffer *buffer,
26                                void *meta);
27static errval_t cb_rx_pool_assigned(struct bulk_channel *channel,
28                                    struct bulk_pool *pool);
29
30static struct bulk_channel rx_channel;
31static struct bulk_channel_callbacks rx_callbacks = { .bind_received =
32    cb_rx_bind_received, .move_received = cb_rx_move_received, .copy_received =
33    cb_rx_copy_received, .pool_assigned = cb_rx_pool_assigned };
34
35static errval_t cb_rx_bind_received(struct bulk_channel *channel)
36{
37    debug_printf("APPL: cb_rx_bind_received\n");
38    return SYS_ERR_OK;
39}
40
41static errval_t cb_rx_pool_assigned(struct bulk_channel *channel,
42                                    struct bulk_pool *pool)
43{
44    debug_printf("APPL: cb_rx_pool_assigned. Checking and reply OK.\n");
45    return SYS_ERR_OK;
46}
47
48static void cb_rx_move_received(struct bulk_channel *channel,
49                                struct bulk_buffer *buffer,
50                                void *meta)
51{
52    uint32_t meta_val = *((uint32_t*) meta);
53    debug_printf("APPL: cb_rx_move_received: %p, meta=%x\n", buffer->address,
54                    meta_val);
55    meta_val++;
56
57    volatile char *e = buffer->address;
58    for (int i = 0; i < buffer->pool->buffer_size; ++i) {
59        assert(e[i] == 123);
60    }
61
62    errval_t err = bulk_channel_pass(channel, buffer, &meta_val, dummy_cont);
63    assert(!err_is_fail(err));
64}
65
66static void cb_rx_copy_received(struct bulk_channel *channel,
67                                struct bulk_buffer *buffer,
68                                void *meta)
69{
70    debug_printf("APPL: cb_rx_copy_received: meta=%x\n", *((uint32_t*) meta));
71    volatile char *e = buffer->address;
72    for (int i = 0; i < buffer->pool->buffer_size; ++i) {
73        assert(e[i] == 101);
74    }
75    errval_t err = bulk_channel_release(channel, buffer, dummy_cont);
76    if (err_is_fail(err)) {
77        DEBUG_ERR(err, "channel release\n");
78        assert(!err_is_fail(err));
79    }
80
81}
82
83static void init_receiver(struct waitset *waitset)
84{
85    static struct bulk_local_endpoint ep;
86    errval_t err;
87    struct bulk_channel_setup setup = { .direction = BULK_DIRECTION_RX,
88                    .role = BULK_ROLE_SLAVE,
89                    .meta_size = sizeof(uint32_t),
90                    .waitset = waitset,
91                    .trust = BULK_TRUST_FULL, };
92
93    bulk_local_init_endpoint(&ep, NULL);
94    err = bulk_channel_create(&rx_channel, &ep.generic, &rx_callbacks, &setup);
95    assert(!err_is_fail(err));
96}
97
98/******************************************************************************/
99/* Sender */
100
101static void cb_tx_bind_done(void *arg,
102                            errval_t err,
103                            struct bulk_channel *channel);
104static void cb_tx_pool_assign_done(void *arg,
105                                   errval_t err,
106                                   struct bulk_channel *channel);
107static void cb_tx_buffer_received(struct bulk_channel *channel,
108                                  struct bulk_buffer *buffer,
109                                  void *meta);
110static void cb_tx_copy_released(struct bulk_channel *channel,
111                                struct bulk_buffer *buffer);
112static errval_t cb_tx_pool_assigned(struct bulk_channel *channel,
113                                    struct bulk_pool *pool);
114
115static struct bulk_channel tx_channel;
116static int tx_phase = 0;
117static struct bulk_allocator tx_allocator;
118static struct bulk_channel_callbacks tx_callbacks = { .buffer_received =
119    cb_tx_buffer_received,
120                .copy_released = cb_tx_copy_released,
121                .pool_assigned = cb_tx_pool_assigned, };
122
123static void cb_tx_pool_assign_done(void *arg,
124                                   errval_t err,
125                                   struct bulk_channel *channel)
126{
127    debug_printf("APPL: cb_tx_pool_assign_done()\n");
128    assert(tx_allocator.pool == arg);
129    tx_phase = 2;
130}
131
132static void cb_tx_bind_done(void *arg,
133                            errval_t err,
134                            struct bulk_channel *channel)
135{
136    debug_printf("APPL: cb_tx_bind_done\n");
137    tx_phase = 1;
138
139    struct bulk_continuation cont = { .handler = cb_tx_pool_assign_done, .arg =
140        NULL };
141
142    err = bulk_channel_assign_pool(channel, tx_allocator.pool, cont);
143    assert(!err_is_fail(err));
144}
145
146static errval_t cb_tx_pool_assigned(struct bulk_channel *channel,
147                                    struct bulk_pool *pool)
148{
149    debug_printf("APPL: cb_tx_pool_assigned()\n");
150
151    return SYS_ERR_OK;
152}
153
154static void cb_tx_buffer_received(struct bulk_channel *channel,
155                                  struct bulk_buffer *buffer,
156                                  void *meta)
157{
158    debug_printf("APPL: cp_tx_buffer_received: %p, meta=%x\n", buffer->address,
159                    *((uint32_t*) meta));
160    errval_t err = bulk_alloc_return_buffer(&tx_allocator, buffer);
161    if (err_is_fail(err)) {
162        DEBUG_ERR(err, "Returning the buffer\n");
163        assert(!err_is_fail(err));
164    }
165
166    tx_phase = 4;
167}
168
169static void cb_tx_copy_released(struct bulk_channel *channel,
170                                struct bulk_buffer *buffer)
171{
172    debug_printf("APPL: cp_tx_copy_released\n");
173    tx_phase = 6;
174    errval_t err = bulk_alloc_return_buffer(&tx_allocator, buffer);
175    assert(!err_is_fail(err));
176
177}
178
179static void init_sender(struct waitset *waitset)
180{
181    static struct bulk_local_endpoint ep;
182    errval_t err;
183    struct bulk_channel_bind_params params = { .waitset = waitset, .trust =
184        BULK_TRUST_FULL, };
185    err = bulk_alloc_init(&tx_allocator, 4, BUFSZ, NULL);
186    assert(!err_is_fail(err));
187    bulk_local_init_endpoint(&ep, &rx_channel);
188    struct bulk_continuation cont = { .handler = cb_tx_bind_done, .arg = NULL, };
189    err = bulk_channel_bind(&tx_channel, &ep.generic, &tx_callbacks, &params,
190                    cont);
191    assert(!err_is_fail(err));
192
193}
194static int count = 0;
195static void tx_process(void)
196{
197    errval_t err;
198    uint32_t meta;
199    struct bulk_buffer *buffer;
200
201    if (tx_phase == 2) {
202        meta = 42;
203        debug_printf("APPL: Allocating buffer...\n");
204        buffer = bulk_alloc_new_buffer(&tx_allocator);
205        assert(buffer);
206        memset(buffer->address, 123, buffer->pool->buffer_size);
207        debug_printf("APPL: Starting move... meta=%x\n", meta);
208        err = bulk_channel_move(&tx_channel, buffer, &meta, dummy_cont);
209        if (err_is_fail(err)) {
210            DEBUG_ERR(err, "Bulk Channel Move Failed...\n");
211            assert(!"FOOFO");
212        }
213
214        tx_phase++;
215    } else if (tx_phase == 4) {
216        meta = 44;
217        debug_printf("APPL: Allocating buffer...\n");
218        buffer = bulk_alloc_new_buffer(&tx_allocator);
219        assert(buffer);
220        memset(buffer->address, 101, buffer->pool->buffer_size);
221        debug_printf("APPL: Starting copy... meta=%x\n", meta);
222        err = bulk_channel_copy(&tx_channel, buffer, &meta, dummy_cont);
223        if (err_is_fail(err)) {
224            DEBUG_ERR(err, "Bulk Channel Move Failed...\n");
225            assert(!"FOOFO");
226        }
227
228        tx_phase++;
229    } else if (tx_phase == 6) {
230        debug_printf("DONE.\n\n");
231        if (3 > count++)
232            tx_phase=2;
233
234    }
235
236}
237
238/******************************************************************************/
239/* Test control */
240
241int main(int argc, char *argv[])
242{
243    struct waitset *ws = get_default_waitset();
244    debug_printf("bulk_mini: enter\n");
245    init_receiver(ws);
246    debug_printf("bulk_mini: rx_init done\n");
247    init_sender(ws);
248    debug_printf("bulk_mini: tx_init done\n");
249    while (true) {
250        tx_process();
251        event_dispatch(ws);
252    }
253    return 0;
254}
255
256