source: mainline/uspace/lib/c/generic/io/con_srv.c@ 4c84ada5

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 4c84ada5 was 5d94b16c, checked in by Jiri Svoboda <jiri@…>, 13 years ago

Factor out server side of console IPC protocol.

  • Property mode set to 100644
File size: 8.7 KB
RevLine 
[5d94b16c]1/*
2 * Copyright (c) 2012 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup libc
30 * @{
31 */
32/**
33 * @file
34 * @brief Console protocol server stub
35 */
36#include <errno.h>
37#include <ipc/console.h>
38#include <stdlib.h>
39#include <sys/types.h>
40
41#include <io/con_srv.h>
42
43static void con_read_srv(con_srv_t *srv, ipc_callid_t callid,
44 ipc_call_t *call)
45{
46 void *buf;
47 size_t size;
48 int rc;
49 ipc_callid_t rcallid;
50
51 if (!async_data_read_receive(&rcallid, &size)) {
52 async_answer_0(callid, EINVAL);
53 return;
54 }
55
56 buf = malloc(size);
57 if (buf == NULL) {
58 async_answer_0(rcallid, ENOMEM);
59 async_answer_0(callid, ENOMEM);
60 return;
61 }
62
63 if (srv->srvs->ops->read == NULL) {
64 async_answer_0(rcallid, ENOTSUP);
65 async_answer_0(callid, ENOTSUP);
66 return;
67 }
68
69 rc = srv->srvs->ops->read(srv, buf, size);
70 if (rc < 0) {
71 async_answer_0(rcallid, rc);
72 async_answer_0(callid, rc);
73 return;
74 }
75
76 async_data_read_finalize(rcallid, buf, size);
77 free(buf);
78
79 if (rc >= 0)
80 async_answer_1(callid, EOK, rc);
81 else
82 async_answer_0(callid, rc);
83}
84
85static void con_write_srv(con_srv_t *srv, ipc_callid_t callid,
86 ipc_call_t *call)
87{
88 void *data;
89 size_t size;
90 int rc;
91
92 rc = async_data_write_accept(&data, false, 0, 0, 0, &size);
93 if (rc != EOK) {
94 async_answer_0(callid, rc);
95 return;
96 }
97
98 if (srv->srvs->ops->write == NULL) {
99 async_answer_0(callid, ENOTSUP);
100 return;
101 }
102
103 rc = srv->srvs->ops->write(srv, data, size);
104 free(data);
105
106 if (rc >= 0)
107 async_answer_1(callid, EOK, rc);
108 else
109 async_answer_0(callid, rc);
110}
111
112static void con_sync_srv(con_srv_t *srv, ipc_callid_t callid,
113 ipc_call_t *call)
114{
115 if (srv->srvs->ops->sync == NULL) {
116 async_answer_0(callid, ENOTSUP);
117 return;
118 }
119
120 srv->srvs->ops->sync(srv);
121 async_answer_0(callid, EOK);
122}
123
124static void con_clear_srv(con_srv_t *srv, ipc_callid_t callid,
125 ipc_call_t *call)
126{
127 if (srv->srvs->ops->clear == NULL) {
128 async_answer_0(callid, ENOTSUP);
129 return;
130 }
131
132 srv->srvs->ops->clear(srv);
133 async_answer_0(callid, EOK);
134}
135
136static void con_set_pos_srv(con_srv_t *srv, ipc_callid_t callid,
137 ipc_call_t *call)
138{
139 sysarg_t col;
140 sysarg_t row;
141
142 col = IPC_GET_ARG1(*call);
143 row = IPC_GET_ARG2(*call);
144
145 if (srv->srvs->ops->set_pos == NULL) {
146 async_answer_0(callid, ENOTSUP);
147 return;
148 }
149
150 srv->srvs->ops->set_pos(srv, col, row);
151 async_answer_0(callid, EOK);
152}
153
154static void con_get_pos_srv(con_srv_t *srv, ipc_callid_t callid,
155 ipc_call_t *call)
156{
157 int rc;
158 sysarg_t col;
159 sysarg_t row;
160
161 if (srv->srvs->ops->get_pos == NULL) {
162 async_answer_0(callid, ENOTSUP);
163 return;
164 }
165
166 rc = srv->srvs->ops->get_pos(srv, &col, &row);
167 async_answer_2(callid, rc, col, row);
168}
169
170static void con_get_size_srv(con_srv_t *srv, ipc_callid_t callid,
171 ipc_call_t *call)
172{
173 int rc;
174 sysarg_t cols;
175 sysarg_t rows;
176
177 if (srv->srvs->ops->get_size == NULL) {
178 async_answer_0(callid, ENOTSUP);
179 return;
180 }
181
182 rc = srv->srvs->ops->get_size(srv, &cols, &rows);
183 async_answer_2(callid, rc, cols, rows);
184}
185
186static void con_get_color_cap_srv(con_srv_t *srv, ipc_callid_t callid,
187 ipc_call_t *call)
188{
189 int rc;
190 console_caps_t ccap;
191
192 if (srv->srvs->ops->get_color_cap == NULL) {
193 async_answer_0(callid, ENOTSUP);
194 return;
195 }
196
197 rc = srv->srvs->ops->get_color_cap(srv, &ccap);
198 async_answer_1(callid, rc, (sysarg_t)ccap);
199}
200
201static void con_set_style_srv(con_srv_t *srv, ipc_callid_t callid,
202 ipc_call_t *call)
203{
204 console_style_t style;
205
206 style = IPC_GET_ARG1(*call);
207
208 if (srv->srvs->ops->set_style == NULL) {
209 async_answer_0(callid, ENOTSUP);
210 return;
211 }
212
213 srv->srvs->ops->set_style(srv, style);
214 async_answer_0(callid, EOK);
215}
216
217static void con_set_color_srv(con_srv_t *srv, ipc_callid_t callid,
218 ipc_call_t *call)
219{
220 console_color_t bgcolor;
221 console_color_t fgcolor;
222 console_color_attr_t flags;
223
224 bgcolor = IPC_GET_ARG1(*call);
225 fgcolor = IPC_GET_ARG2(*call);
226 flags = IPC_GET_ARG3(*call);
227
228 if (srv->srvs->ops->set_color == NULL) {
229 async_answer_0(callid, ENOTSUP);
230 return;
231 }
232
233 srv->srvs->ops->set_color(srv, bgcolor, fgcolor, flags);
234 async_answer_0(callid, EOK);
235}
236
237static void con_set_rgb_color_srv(con_srv_t *srv, ipc_callid_t callid,
238 ipc_call_t *call)
239{
240 pixel_t bgcolor;
241 pixel_t fgcolor;
242
243 bgcolor = IPC_GET_ARG1(*call);
244 fgcolor = IPC_GET_ARG2(*call);
245
246 if (srv->srvs->ops->set_rgb_color == NULL) {
247 async_answer_0(callid, ENOTSUP);
248 return;
249 }
250
251 srv->srvs->ops->set_rgb_color(srv, bgcolor, fgcolor);
252 async_answer_0(callid, EOK);
253}
254
255static void con_set_cursor_visibility_srv(con_srv_t *srv, ipc_callid_t callid,
256 ipc_call_t *call)
257{
258 bool show;
259
260 show = IPC_GET_ARG1(*call);
261
262 if (srv->srvs->ops->set_cursor_visibility == NULL) {
263 async_answer_0(callid, ENOTSUP);
264 return;
265 }
266
267 srv->srvs->ops->set_cursor_visibility(srv, show);
268 async_answer_0(callid, EOK);
269}
270
271static void con_get_event_srv(con_srv_t *srv, ipc_callid_t callid,
272 ipc_call_t *call)
273{
274 int rc;
275 kbd_event_t event;
276
277 if (srv->srvs->ops->get_event == NULL) {
278 async_answer_0(callid, ENOTSUP);
279 return;
280 }
281
282 rc = srv->srvs->ops->get_event(srv, &event);
283 async_answer_4(callid, rc, event.type, event.key, event.mods, event.c);
284}
285
286static con_srv_t *con_srv_create(con_srvs_t *srvs)
287{
288 con_srv_t *srv;
289
290 srv = calloc(1, sizeof(*srv));
291 if (srv == NULL)
292 return NULL;
293
294 srv->srvs = srvs;
295 return srv;
296}
297
298void con_srvs_init(con_srvs_t *srvs)
299{
300 srvs->ops = NULL;
301 srvs->sarg = NULL;
302 srvs->abort_timeout = 0;
303 srvs->aborted = false;
304}
305
306int con_conn(ipc_callid_t iid, ipc_call_t *icall, con_srvs_t *srvs)
307{
308 con_srv_t *srv;
309 int rc;
310
311 /* Accept the connection */
312 async_answer_0(iid, EOK);
313
314 srv = con_srv_create(srvs);
315 if (srv == NULL)
316 return ENOMEM;
317
318/* async_sess_t *sess = async_callback_receive(EXCHANGE_SERIALIZE);
319 if (sess == NULL)
320 return ENOMEM;
321
322 srv->client_sess = sess;
323*/
324 srv->client_sess = NULL;
325
326 rc = srvs->ops->open(srvs, srv);
327 if (rc != EOK)
328 return rc;
329
330 while (true) {
331 ipc_call_t call;
332 ipc_callid_t callid = 0;
333
334 while (callid == 0) {
335 /* XXX Need to be able to abort immediately */
336 callid = async_get_call_timeout(&call,
337 srvs->abort_timeout);
338
339 if (srv->srvs->aborted) {
340 if (callid != 0)
341 async_answer_0(callid, EINTR);
342 break;
343 }
344 }
345
346 if (callid == 0)
347 break;
348
349 sysarg_t method = IPC_GET_IMETHOD(call);
350
351 if (!method) {
352 /* The other side has hung up */
353 async_answer_0(callid, EOK);
354 break;
355 }
356
357 switch (method) {
358 case VFS_OUT_READ:
359 con_read_srv(srv, callid, &call);
360 break;
361 case VFS_OUT_WRITE:
362 con_write_srv(srv, callid, &call);
363 break;
364 case VFS_OUT_SYNC:
365 con_sync_srv(srv, callid, &call);
366 break;
367 case CONSOLE_CLEAR:
368 con_clear_srv(srv, callid, &call);
369 break;
370 case CONSOLE_SET_POS:
371 con_set_pos_srv(srv, callid, &call);
372 break;
373 case CONSOLE_GET_POS:
374 con_get_pos_srv(srv, callid, &call);
375 break;
376 case CONSOLE_GET_SIZE:
377 con_get_size_srv(srv, callid, &call);
378 break;
379 case CONSOLE_GET_COLOR_CAP:
380 con_get_color_cap_srv(srv, callid, &call);
381 break;
382 case CONSOLE_SET_STYLE:
383 con_set_style_srv(srv, callid, &call);
384 break;
385 case CONSOLE_SET_COLOR:
386 con_set_color_srv(srv, callid, &call);
387 break;
388 case CONSOLE_SET_RGB_COLOR:
389 con_set_rgb_color_srv(srv, callid, &call);
390 break;
391 case CONSOLE_SET_CURSOR_VISIBILITY:
392 con_set_cursor_visibility_srv(srv, callid, &call);
393 break;
394 case CONSOLE_GET_EVENT:
395 con_get_event_srv(srv, callid, &call);
396 break;
397 default:
398 async_answer_0(callid, ENOTSUP);
399 }
400 }
401
402 rc = srvs->ops->close(srv);
403 free(srv);
404
405 return rc;
406}
407
408/** @}
409 */
Note: See TracBrowser for help on using the repository browser.