]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/ankh/lib/client-c/lib.cc
update
[l4.git] / l4 / pkg / ankh / lib / client-c / lib.cc
1 #include <l4/re/env>
2 #include <l4/re/namespace>
3 #include <l4/re/util/cap_alloc>
4 #include <l4/cxx/ipc_stream>
5 #include <l4/ankh/protocol>
6 #include <l4/ankh/shm>
7 #include <l4/ankh/session>
8 #include <l4/shmc/ringbuf.h>
9 #include <l4/ankh/client-c.h>
10 #include <l4/sys/kdebug.h>
11 #include <l4/sys/debugger.h>
12 #include <cstdio>
13 #include <cassert>
14
15 // XXX: support several ANKH connections
16 static L4::Cap<void> ankh_server;
17 l4shmc_area_t ankh_shmarea;
18 l4shmc_ringbuf_t _snd, _rcv;
19 l4shmc_chunk_t ankh_info_chunk;
20 AnkhSessionDescriptor* ankh_conn_info = NULL;
21 int _initialized = 0;
22 int _snd_init = 0;
23 int _rcv_init = 0;
24
25 L4_CV l4shmc_ringbuf_t *l4ankh_get_sendbuf(void) L4_NOTHROW
26 {       return &_snd; }
27
28 L4_CV l4shmc_ringbuf_t *l4ankh_get_recvbuf(void) L4_NOTHROW
29 {       return &_rcv; }
30
31 L4_CV void l4ankh_init(void) L4_NOTHROW
32 {
33         if (!(ankh_server = L4Re::Env::env()->get_cap<void>("ankh"))) {
34                 printf("Could not find Ankh server.\n");
35                 assert(false);
36         }
37
38         memset(&_snd, 0, sizeof(_snd));
39         memset(&_rcv, 0, sizeof(_rcv));
40 }
41
42
43 /*
44  * XXX: 
45  *      * pass a cap name as parameter to support multiple connections
46  *      * return a local handle (or a struct ptr)
47  */
48 L4_CV int
49 l4ankh_open(char *shm_name, int bufsize) L4_NOTHROW
50 {
51         if (!_initialized)
52                 l4ankh_init();
53
54         int err = l4shmc_attach(shm_name, &ankh_shmarea);
55         ASSERT_OK(err);
56
57         err = l4shmc_rb_init_buffer(&_snd, &ankh_shmarea, "tx_ring", "tx_signal", bufsize);
58         ASSERT_OK(err);
59         err = l4shmc_rb_init_buffer(&_rcv, &ankh_shmarea, "rx_ring", "rx_signal", bufsize);
60         ASSERT_OK(err);
61         err = l4shmc_add_chunk(&ankh_shmarea, "info", sizeof(struct AnkhSessionDescriptor),
62                                &ankh_info_chunk);
63         ASSERT_OK(err);
64
65         L4::Ipc_iostream s(l4_utcb());
66         s << l4_umword_t(Ankh::Opcode::Activate);
67         l4_msgtag_t res = s.call(ankh_server.cap(), Ankh::Protocol::Ankh);
68         ASSERT_EQUAL(l4_ipc_error(res, l4_utcb()), 0);
69         printf("activated Ankh connection.\n");
70
71         return 0;
72 }
73
74
75 L4_CV AnkhSessionDescriptor *l4ankh_get_info() L4_NOTHROW
76 {
77         if (!ankh_conn_info)
78                 ankh_conn_info = static_cast<AnkhSessionDescriptor*>(l4shmc_chunk_ptr(&ankh_info_chunk));
79         return ankh_conn_info;
80 }
81
82
83 #if 0
84 extern "C" __attribute__((weak)) void fixup_shm_caphandlers(
85         int, l4shmc_area_t*, l4shmc_ringbuf_t*, l4shmc_ringbuf_t*);
86 #endif
87
88 L4_CV int l4ankh_prepare_send(l4_cap_idx_t owner) L4_NOTHROW
89 {
90         int r = l4shmc_rb_attach_sender(&_snd, "tx_signal", owner);
91         return r;
92 }
93
94
95 L4_CV int l4ankh_prepare_recv(l4_cap_idx_t owner) L4_NOTHROW
96 {
97         l4shmc_rb_attach_receiver(&_rcv, owner);
98 #if 0
99         if (fixup_shm_caphandlers)
100                 fixup_shm_caphandlers((int)&ankh_server, &ankh_shmarea, &_snd, &_rcv);
101 #endif
102         return 0;
103 }
104
105
106 L4_CV int l4ankh_recv_blocking(char *buffer, unsigned *size) L4_NOTHROW
107 {
108         ASSERT_NOT_NULL(buffer);
109         ASSERT_NOT_NULL(size);
110
111         int err;
112
113         err = l4shmc_rb_receiver_wait_for_data(&_rcv, 1);
114         ASSERT_OK(err);
115
116         err = l4shmc_rb_receiver_copy_out(HEAD(&_rcv), buffer, size);
117         ASSERT_OK(err);
118
119         return err;
120 }
121
122
123 L4_CV int l4ankh_recv_nonblocking(char *buffer, unsigned *size) L4_NOTHROW
124 {
125         ASSERT_NOT_NULL(buffer);
126         ASSERT_NOT_NULL(size);
127
128         int err;
129
130         err = l4shmc_rb_receiver_wait_for_data(&_rcv, 0);
131         if (!err) {
132                 err = l4shmc_rb_receiver_copy_out(HEAD(&_rcv), buffer, size);
133                 ASSERT_OK(err);
134         }
135
136     return err;
137 }
138
139
140 L4_CV int l4ankh_send(char *data, unsigned size, char block) L4_NOTHROW
141 {
142         int err = l4shmc_rb_sender_next_copy_in(&_snd, data, size, block);
143         if (!err)
144                 l4shmc_rb_sender_commit_packet(&_snd);
145
146         return err;
147 }