source: mainline/uspace/lib/c/generic/io/con_srv.c@ 59ff52d

Last change on this file since 59ff52d was 59ff52d, checked in by Jakub Jermar <jakub@…>, 7 years ago

Add async_accept_0() for accepting connections

  • Property mode set to 100644
File size: 9.0 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>
[902f0906]37#include <io/cons_event.h>
[5d94b16c]38#include <ipc/console.h>
39#include <stdlib.h>
[8d2dd7f2]40#include <stddef.h>
[5d94b16c]41
42#include <io/con_srv.h>
43
[984a9ba]44static errno_t console_ev_encode(cons_event_t *event, ipc_call_t *icall)
[902f0906]45{
[984a9ba]46 IPC_SET_ARG1(*icall, event->type);
[902f0906]47
48 switch (event->type) {
49 case CEV_KEY:
[984a9ba]50 IPC_SET_ARG2(*icall, event->ev.key.type);
51 IPC_SET_ARG3(*icall, event->ev.key.key);
52 IPC_SET_ARG4(*icall, event->ev.key.mods);
53 IPC_SET_ARG5(*icall, event->ev.key.c);
[902f0906]54 break;
55 case CEV_POS:
[984a9ba]56 IPC_SET_ARG2(*icall, (event->ev.pos.pos_id << 16) | (event->ev.pos.type & 0xffff));
57 IPC_SET_ARG3(*icall, event->ev.pos.btn_num);
58 IPC_SET_ARG4(*icall, event->ev.pos.hpos);
59 IPC_SET_ARG5(*icall, event->ev.pos.vpos);
[902f0906]60 break;
61 default:
62 return EIO;
63 }
64
65 return EOK;
66}
67
[984a9ba]68static void con_read_srv(con_srv_t *srv, ipc_call_t *icall)
[5d94b16c]69{
70 void *buf;
71 size_t size;
[b7fd2a0]72 errno_t rc;
[5d94b16c]73
[984a9ba]74 ipc_call_t call;
75 if (!async_data_read_receive(&call, &size)) {
76 async_answer_0(icall, EINVAL);
[5d94b16c]77 return;
78 }
79
80 buf = malloc(size);
81 if (buf == NULL) {
[984a9ba]82 async_answer_0(&call, ENOMEM);
83 async_answer_0(icall, ENOMEM);
[5d94b16c]84 return;
85 }
86
87 if (srv->srvs->ops->read == NULL) {
[984a9ba]88 async_answer_0(&call, ENOTSUP);
89 async_answer_0(icall, ENOTSUP);
[ccfe9c3]90 free(buf);
[5d94b16c]91 return;
92 }
93
[c8211849]94 size_t nread;
95 rc = srv->srvs->ops->read(srv, buf, size, &nread);
96 if (rc != EOK) {
[984a9ba]97 async_answer_0(&call, rc);
98 async_answer_0(icall, rc);
[ccfe9c3]99 free(buf);
[5d94b16c]100 return;
101 }
102
[984a9ba]103 async_data_read_finalize(&call, buf, nread);
[5d94b16c]104 free(buf);
105
[984a9ba]106 async_answer_1(icall, EOK, nread);
[5d94b16c]107}
108
[984a9ba]109static void con_write_srv(con_srv_t *srv, ipc_call_t *icall)
[5d94b16c]110{
111 void *data;
112 size_t size;
[b7fd2a0]113 errno_t rc;
[5d94b16c]114
115 rc = async_data_write_accept(&data, false, 0, 0, 0, &size);
116 if (rc != EOK) {
[984a9ba]117 async_answer_0(icall, rc);
[5d94b16c]118 return;
119 }
120
121 if (srv->srvs->ops->write == NULL) {
[984a9ba]122 async_answer_0(icall, ENOTSUP);
[5d94b16c]123 return;
124 }
125
[c8211849]126 size_t nwritten = 0;
127 rc = srv->srvs->ops->write(srv, data, size, &nwritten);
[5d94b16c]128 free(data);
129
[984a9ba]130 async_answer_1(icall, rc, nwritten);
[5d94b16c]131}
132
[984a9ba]133static void con_sync_srv(con_srv_t *srv, ipc_call_t *icall)
[5d94b16c]134{
135 if (srv->srvs->ops->sync == NULL) {
[984a9ba]136 async_answer_0(icall, ENOTSUP);
[5d94b16c]137 return;
138 }
139
140 srv->srvs->ops->sync(srv);
[984a9ba]141 async_answer_0(icall, EOK);
[5d94b16c]142}
143
[984a9ba]144static void con_clear_srv(con_srv_t *srv, ipc_call_t *icall)
[5d94b16c]145{
146 if (srv->srvs->ops->clear == NULL) {
[984a9ba]147 async_answer_0(icall, ENOTSUP);
[5d94b16c]148 return;
149 }
150
151 srv->srvs->ops->clear(srv);
[984a9ba]152 async_answer_0(icall, EOK);
[5d94b16c]153}
154
[984a9ba]155static void con_set_pos_srv(con_srv_t *srv, ipc_call_t *icall)
[5d94b16c]156{
157 sysarg_t col;
158 sysarg_t row;
159
[984a9ba]160 col = IPC_GET_ARG1(*icall);
161 row = IPC_GET_ARG2(*icall);
[5d94b16c]162
163 if (srv->srvs->ops->set_pos == NULL) {
[984a9ba]164 async_answer_0(icall, ENOTSUP);
[5d94b16c]165 return;
166 }
167
168 srv->srvs->ops->set_pos(srv, col, row);
[984a9ba]169 async_answer_0(icall, EOK);
[5d94b16c]170}
171
[984a9ba]172static void con_get_pos_srv(con_srv_t *srv, ipc_call_t *icall)
[5d94b16c]173{
[b7fd2a0]174 errno_t rc;
[5d94b16c]175 sysarg_t col;
176 sysarg_t row;
177
178 if (srv->srvs->ops->get_pos == NULL) {
[984a9ba]179 async_answer_0(icall, ENOTSUP);
[5d94b16c]180 return;
181 }
182
183 rc = srv->srvs->ops->get_pos(srv, &col, &row);
[984a9ba]184 async_answer_2(icall, rc, col, row);
[5d94b16c]185}
186
[984a9ba]187static void con_get_size_srv(con_srv_t *srv, ipc_call_t *icall)
[5d94b16c]188{
[b7fd2a0]189 errno_t rc;
[5d94b16c]190 sysarg_t cols;
191 sysarg_t rows;
192
193 if (srv->srvs->ops->get_size == NULL) {
[984a9ba]194 async_answer_0(icall, ENOTSUP);
[5d94b16c]195 return;
196 }
197
198 rc = srv->srvs->ops->get_size(srv, &cols, &rows);
[984a9ba]199 async_answer_2(icall, rc, cols, rows);
[5d94b16c]200}
201
[984a9ba]202static void con_get_color_cap_srv(con_srv_t *srv, ipc_call_t *icall)
[5d94b16c]203{
[b7fd2a0]204 errno_t rc;
[5d94b16c]205 console_caps_t ccap;
206
207 if (srv->srvs->ops->get_color_cap == NULL) {
[984a9ba]208 async_answer_0(icall, ENOTSUP);
[5d94b16c]209 return;
210 }
211
212 rc = srv->srvs->ops->get_color_cap(srv, &ccap);
[984a9ba]213 async_answer_1(icall, rc, (sysarg_t)ccap);
[5d94b16c]214}
215
[984a9ba]216static void con_set_style_srv(con_srv_t *srv, ipc_call_t *icall)
[5d94b16c]217{
218 console_style_t style;
219
[984a9ba]220 style = IPC_GET_ARG1(*icall);
[5d94b16c]221
222 if (srv->srvs->ops->set_style == NULL) {
[984a9ba]223 async_answer_0(icall, ENOTSUP);
[5d94b16c]224 return;
225 }
226
227 srv->srvs->ops->set_style(srv, style);
[984a9ba]228 async_answer_0(icall, EOK);
[5d94b16c]229}
230
[984a9ba]231static void con_set_color_srv(con_srv_t *srv, ipc_call_t *icall)
[5d94b16c]232{
233 console_color_t bgcolor;
234 console_color_t fgcolor;
235 console_color_attr_t flags;
236
[984a9ba]237 bgcolor = IPC_GET_ARG1(*icall);
238 fgcolor = IPC_GET_ARG2(*icall);
239 flags = IPC_GET_ARG3(*icall);
[5d94b16c]240
241 if (srv->srvs->ops->set_color == NULL) {
[984a9ba]242 async_answer_0(icall, ENOTSUP);
[5d94b16c]243 return;
244 }
245
246 srv->srvs->ops->set_color(srv, bgcolor, fgcolor, flags);
[984a9ba]247 async_answer_0(icall, EOK);
[5d94b16c]248}
249
[984a9ba]250static void con_set_rgb_color_srv(con_srv_t *srv, ipc_call_t *icall)
[5d94b16c]251{
252 pixel_t bgcolor;
253 pixel_t fgcolor;
254
[984a9ba]255 bgcolor = IPC_GET_ARG1(*icall);
256 fgcolor = IPC_GET_ARG2(*icall);
[5d94b16c]257
258 if (srv->srvs->ops->set_rgb_color == NULL) {
[984a9ba]259 async_answer_0(icall, ENOTSUP);
[5d94b16c]260 return;
261 }
262
263 srv->srvs->ops->set_rgb_color(srv, bgcolor, fgcolor);
[984a9ba]264 async_answer_0(icall, EOK);
[5d94b16c]265}
266
[984a9ba]267static void con_set_cursor_visibility_srv(con_srv_t *srv, ipc_call_t *icall)
[5d94b16c]268{
269 bool show;
270
[984a9ba]271 show = IPC_GET_ARG1(*icall);
[5d94b16c]272
273 if (srv->srvs->ops->set_cursor_visibility == NULL) {
[984a9ba]274 async_answer_0(icall, ENOTSUP);
[5d94b16c]275 return;
276 }
277
278 srv->srvs->ops->set_cursor_visibility(srv, show);
[984a9ba]279 async_answer_0(icall, EOK);
[5d94b16c]280}
281
[984a9ba]282static void con_get_event_srv(con_srv_t *srv, ipc_call_t *icall)
[5d94b16c]283{
[b7fd2a0]284 errno_t rc;
[902f0906]285 cons_event_t event;
286 ipc_call_t result;
[5d94b16c]287
288 if (srv->srvs->ops->get_event == NULL) {
[984a9ba]289 async_answer_0(icall, ENOTSUP);
[5d94b16c]290 return;
291 }
292
293 rc = srv->srvs->ops->get_event(srv, &event);
[902f0906]294 if (rc != EOK) {
[984a9ba]295 async_answer_0(icall, rc);
[902f0906]296 return;
297 }
298
299 rc = console_ev_encode(&event, &result);
300 if (rc != EOK) {
[984a9ba]301 async_answer_0(icall, rc);
[902f0906]302 return;
303 }
304
[984a9ba]305 async_answer_5(icall, rc, IPC_GET_ARG1(result), IPC_GET_ARG2(result),
[902f0906]306 IPC_GET_ARG3(result), IPC_GET_ARG4(result), IPC_GET_ARG5(result));
[5d94b16c]307}
308
309static con_srv_t *con_srv_create(con_srvs_t *srvs)
310{
311 con_srv_t *srv;
312
313 srv = calloc(1, sizeof(*srv));
314 if (srv == NULL)
315 return NULL;
316
317 srv->srvs = srvs;
318 return srv;
319}
320
321void con_srvs_init(con_srvs_t *srvs)
322{
323 srvs->ops = NULL;
324 srvs->sarg = NULL;
325 srvs->abort_timeout = 0;
326 srvs->aborted = false;
327}
328
[984a9ba]329errno_t con_conn(ipc_call_t *icall, con_srvs_t *srvs)
[5d94b16c]330{
331 con_srv_t *srv;
[b7fd2a0]332 errno_t rc;
[5d94b16c]333
334 /* Accept the connection */
[59ff52d]335 async_accept_0(icall);
[5d94b16c]336
337 srv = con_srv_create(srvs);
338 if (srv == NULL)
339 return ENOMEM;
340
341 srv->client_sess = NULL;
342
343 rc = srvs->ops->open(srvs, srv);
344 if (rc != EOK)
345 return rc;
346
347 while (true) {
348 ipc_call_t call;
[984a9ba]349 bool received = false;
[5d94b16c]350
[984a9ba]351 while (!received) {
[5d94b16c]352 /* XXX Need to be able to abort immediately */
[984a9ba]353 received = async_get_call_timeout(&call,
[5d94b16c]354 srvs->abort_timeout);
355
356 if (srv->srvs->aborted) {
[984a9ba]357 if (received)
358 async_answer_0(&call, EINTR);
[5d94b16c]359 break;
360 }
361 }
362
[984a9ba]363 if (!received)
[5d94b16c]364 break;
365
366 sysarg_t method = IPC_GET_IMETHOD(call);
367
368 if (!method) {
369 /* The other side has hung up */
[984a9ba]370 async_answer_0(&call, EOK);
[5d94b16c]371 break;
372 }
373
374 switch (method) {
375 case VFS_OUT_READ:
[984a9ba]376 con_read_srv(srv, &call);
[5d94b16c]377 break;
378 case VFS_OUT_WRITE:
[984a9ba]379 con_write_srv(srv, &call);
[5d94b16c]380 break;
381 case VFS_OUT_SYNC:
[984a9ba]382 con_sync_srv(srv, &call);
[5d94b16c]383 break;
384 case CONSOLE_CLEAR:
[984a9ba]385 con_clear_srv(srv, &call);
[5d94b16c]386 break;
387 case CONSOLE_SET_POS:
[984a9ba]388 con_set_pos_srv(srv, &call);
[5d94b16c]389 break;
390 case CONSOLE_GET_POS:
[984a9ba]391 con_get_pos_srv(srv, &call);
[5d94b16c]392 break;
393 case CONSOLE_GET_SIZE:
[984a9ba]394 con_get_size_srv(srv, &call);
[5d94b16c]395 break;
396 case CONSOLE_GET_COLOR_CAP:
[984a9ba]397 con_get_color_cap_srv(srv, &call);
[5d94b16c]398 break;
399 case CONSOLE_SET_STYLE:
[984a9ba]400 con_set_style_srv(srv, &call);
[5d94b16c]401 break;
402 case CONSOLE_SET_COLOR:
[984a9ba]403 con_set_color_srv(srv, &call);
[5d94b16c]404 break;
405 case CONSOLE_SET_RGB_COLOR:
[984a9ba]406 con_set_rgb_color_srv(srv, &call);
[5d94b16c]407 break;
408 case CONSOLE_SET_CURSOR_VISIBILITY:
[984a9ba]409 con_set_cursor_visibility_srv(srv, &call);
[5d94b16c]410 break;
411 case CONSOLE_GET_EVENT:
[984a9ba]412 con_get_event_srv(srv, &call);
[5d94b16c]413 break;
414 default:
[984a9ba]415 async_answer_0(&call, ENOTSUP);
[5d94b16c]416 }
417 }
418
419 rc = srvs->ops->close(srv);
420 free(srv);
421
422 return rc;
423}
424
425/** @}
426 */
Note: See TracBrowser for help on using the repository browser.