source: mainline/uspace/srv/net/tcp/service.c@ 779541b

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

TCP transport layer API - somewhat working.

  • Property mode set to 100644
File size: 17.7 KB
Line 
1/*
2 * Copyright (c) 2015 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 udp
30 * @{
31 */
32
33/**
34 * @file HelenOS service implementation
35 */
36
37#include <async.h>
38#include <errno.h>
39#include <inet/endpoint.h>
40#include <inet/inet.h>
41#include <io/log.h>
42#include <ipc/services.h>
43#include <ipc/tcp.h>
44#include <loc.h>
45#include <macros.h>
46#include <stdlib.h>
47
48#include "conn.h"
49#include "service.h"
50#include "tcp_type.h"
51#include "ucall.h"
52
53#define NAME "tcp"
54
55#define MAX_MSG_SIZE DATA_XFER_LIMIT
56
57static void tcp_ev_data(tcp_cconn_t *);
58
59static void tcp_service_cstate_change(tcp_conn_t *, void *);
60static void tcp_service_recv_data(tcp_conn_t *, void *);
61
62static tcp_cb_t tcp_service_cb = {
63 .cstate_change = tcp_service_cstate_change,
64 .recv_data = tcp_service_recv_data
65};
66
67static void tcp_service_cstate_change(tcp_conn_t *conn, void *arg)
68{
69}
70
71static void tcp_service_recv_data(tcp_conn_t *conn, void *arg)
72{
73 tcp_cconn_t *cconn = (tcp_cconn_t *)arg;
74
75 tcp_ev_data(cconn);
76}
77
78static void tcp_ev_data(tcp_cconn_t *cconn)
79{
80 async_exch_t *exch;
81
82 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_ev_data()");
83
84 log_msg(LOG_DEFAULT, LVL_DEBUG, "client=%p\n", cconn->client);
85 log_msg(LOG_DEFAULT, LVL_DEBUG, "sess=%p\n", cconn->client->sess);
86
87 exch = async_exchange_begin(cconn->client->sess);
88 aid_t req = async_send_1(exch, TCP_EV_DATA, cconn->id, NULL);
89 async_exchange_end(exch);
90
91 async_forget(req);
92}
93
94static int tcp_cconn_create(tcp_client_t *client, tcp_conn_t *conn,
95 tcp_cconn_t **rcconn)
96{
97 tcp_cconn_t *cconn;
98 sysarg_t id;
99
100 cconn = calloc(1, sizeof(tcp_cconn_t));
101 if (cconn == NULL)
102 return ENOMEM;
103
104 /* Allocate new ID */
105 id = 0;
106 list_foreach (client->cconn, lclient, tcp_cconn_t, cconn) {
107 if (cconn->id >= id)
108 id = cconn->id + 1;
109 }
110
111 cconn->id = id;
112 cconn->client = client;
113 cconn->conn = conn;
114
115 list_append(&cconn->lclient, &client->cconn);
116 *rcconn = cconn;
117 return EOK;
118}
119
120static void tcp_cconn_destroy(tcp_cconn_t *cconn)
121{
122 list_remove(&cconn->lclient);
123 free(cconn);
124}
125
126static int tcp_clistener_create(tcp_client_t *client, tcp_conn_t *conn,
127 tcp_clst_t **rclst)
128{
129 tcp_clst_t *clst;
130 sysarg_t id;
131
132 clst = calloc(1, sizeof(tcp_clst_t));
133 if (clst == NULL)
134 return ENOMEM;
135
136 /* Allocate new ID */
137 id = 0;
138 list_foreach (client->clst, lclient, tcp_clst_t, clst) {
139 if (clst->id >= id)
140 id = clst->id + 1;
141 }
142
143 clst->id = id;
144 clst->client = client;
145 clst->conn = conn;
146
147 list_append(&clst->lclient, &client->clst);
148 *rclst = clst;
149 return EOK;
150}
151
152static void tcp_clistener_destroy(tcp_clst_t *clst)
153{
154 list_remove(&clst->lclient);
155 free(clst);
156}
157
158static int tcp_cconn_get(tcp_client_t *client, sysarg_t id,
159 tcp_cconn_t **rcconn)
160{
161 list_foreach (client->cconn, lclient, tcp_cconn_t, cconn) {
162 if (cconn->id == id) {
163 *rcconn = cconn;
164 return EOK;
165 }
166 }
167
168 return ENOENT;
169}
170
171static int tcp_clistener_get(tcp_client_t *client, sysarg_t id,
172 tcp_clst_t **rclst)
173{
174 list_foreach (client->clst, lclient, tcp_clst_t, clst) {
175 if (clst->id == id) {
176 *rclst = clst;
177 return EOK;
178 }
179 }
180
181 return ENOENT;
182}
183
184
185static int tcp_conn_create_impl(tcp_client_t *client, inet_ep2_t *epp,
186 sysarg_t *rconn_id)
187{
188 tcp_conn_t *conn;
189 tcp_cconn_t *cconn;
190 tcp_sock_t local;
191 tcp_sock_t remote;
192 inet_addr_t local_addr;
193 int rc;
194 tcp_error_t trc;
195 char *slocal;
196 char *sremote;
197
198 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_create_impl");
199
200 /* Fill in local address? */
201 if (inet_addr_is_any(&epp->local.addr)) {
202 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_create_impl: "
203 "determine local address");
204 rc = inet_get_srcaddr(&epp->remote.addr, 0, &local_addr);
205 if (rc != EOK) {
206 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_create_impl: "
207 "cannot determine local address");
208 return rc;
209 }
210 } else {
211 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_create_impl: "
212 "local address specified");
213 local_addr = epp->local.addr;
214 }
215
216 /* Allocate local port? */
217 if (epp->local.port == 0) {
218 epp->local.port = 49152; /* XXX */
219 }
220
221 local.addr = local_addr;
222 local.port = epp->local.port;
223 remote.addr = epp->remote.addr;
224 remote.port = epp->remote.port;
225
226 inet_addr_format(&local_addr, &slocal);
227 inet_addr_format(&remote.addr, &sremote);
228 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_create: local=%s remote=%s",
229 slocal, sremote);
230
231 trc = tcp_uc_open(&local, &remote, ap_active, tcp_open_nonblock, &conn);
232 if (trc != TCP_EOK)
233 return EIO;
234
235 rc = tcp_cconn_create(client, conn, &cconn);
236 if (rc != EOK) {
237 assert(rc == ENOMEM);
238 tcp_conn_delete(conn);
239 return ENOMEM;
240 }
241
242 /* XXX Is there a race here (i.e. the connection is already active)? */
243 tcp_uc_set_cb(conn, &tcp_service_cb, cconn);
244
245// assoc->cb = &udp_cassoc_cb;
246// assoc->cb_arg = cassoc;
247
248 *rconn_id = cconn->id;
249 return EOK;
250}
251
252static int tcp_conn_destroy_impl(tcp_client_t *client, sysarg_t conn_id)
253{
254 tcp_cconn_t *cconn;
255 int rc;
256
257 rc = tcp_cconn_get(client, conn_id, &cconn);
258 if (rc != EOK) {
259 assert(rc == ENOENT);
260 return ENOENT;
261 }
262
263 tcp_uc_close(cconn->conn);
264 tcp_cconn_destroy(cconn);
265 return EOK;
266}
267
268static int tcp_listener_create_impl(tcp_client_t *client, inet_ep_t *ep,
269 sysarg_t *rlst_id)
270{
271 tcp_conn_t *conn;
272 tcp_clst_t *clst;
273 tcp_sock_t local;
274 int rc;
275 tcp_error_t trc;
276
277 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_listener_create_impl");
278
279 local.addr = ep->addr;
280 local.port = ep->port;
281
282 trc = tcp_uc_open(&local, NULL, ap_passive, 0, &conn);
283 if (trc != TCP_EOK)
284 return EIO;
285
286 rc = tcp_clistener_create(client, conn, &clst);
287 if (rc != EOK) {
288 assert(rc == ENOMEM);
289 tcp_conn_delete(conn);
290 return ENOMEM;
291 }
292
293// assoc->cb = &udp_cassoc_cb;
294// assoc->cb_arg = cassoc;
295
296 *rlst_id = clst->id;
297 return EOK;
298}
299
300static int tcp_listener_destroy_impl(tcp_client_t *client, sysarg_t lst_id)
301{
302 tcp_clst_t *clst;
303 int rc;
304
305 rc = tcp_clistener_get(client, lst_id, &clst);
306 if (rc != EOK) {
307 assert(rc == ENOENT);
308 return ENOENT;
309 }
310
311// tcp_uc_close(cconn->conn);
312 tcp_clistener_destroy(clst);
313 return EOK;
314}
315
316static int tcp_conn_send_fin_impl(tcp_client_t *client, sysarg_t conn_id)
317{
318 tcp_cconn_t *cconn;
319 int rc;
320
321 rc = tcp_cconn_get(client, conn_id, &cconn);
322 if (rc != EOK) {
323 assert(rc == ENOENT);
324 return ENOENT;
325 }
326
327 (void) cconn;
328 /* XXX TODO */
329 return EOK;
330}
331
332static int tcp_conn_push_impl(tcp_client_t *client, sysarg_t conn_id)
333{
334 tcp_cconn_t *cconn;
335 int rc;
336
337 rc = tcp_cconn_get(client, conn_id, &cconn);
338 if (rc != EOK) {
339 assert(rc == ENOENT);
340 return ENOENT;
341 }
342
343 (void) cconn;
344 /* XXX TODO */
345 return EOK;
346}
347
348static int tcp_conn_reset_impl(tcp_client_t *client, sysarg_t conn_id)
349{
350 tcp_cconn_t *cconn;
351 int rc;
352
353 rc = tcp_cconn_get(client, conn_id, &cconn);
354 if (rc != EOK) {
355 assert(rc == ENOENT);
356 return ENOENT;
357 }
358
359 tcp_uc_abort(cconn->conn);
360 return EOK;
361}
362
363static int tcp_conn_send_impl(tcp_client_t *client, sysarg_t conn_id,
364 void *data, size_t size)
365{
366 tcp_cconn_t *cconn;
367 int rc;
368
369 rc = tcp_cconn_get(client, conn_id, &cconn);
370 if (rc != EOK)
371 return rc;
372
373 rc = tcp_uc_send(cconn->conn, data, size, 0);
374 if (rc != EOK)
375 return rc;
376
377 return EOK;
378}
379
380static int tcp_conn_recv_impl(tcp_client_t *client, sysarg_t conn_id,
381 void *data, size_t size, size_t *nrecv)
382{
383 tcp_cconn_t *cconn;
384 xflags_t xflags;
385 int rc;
386
387 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_recv_impl()");
388
389 rc = tcp_cconn_get(client, conn_id, &cconn);
390 if (rc != EOK) {
391 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_recv_impl() - conn not found");
392 return rc;
393 }
394
395 rc = tcp_uc_receive(cconn->conn, data, size, nrecv, &xflags);
396 if (rc != EOK) {
397 switch (rc) {
398 case TCP_EAGAIN:
399 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_recv_impl() - EAGAIN");
400 return EAGAIN;
401 default:
402 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_recv_impl() - trc=%d", rc);
403 return EIO;
404 }
405 }
406
407 return EOK;
408}
409
410static void tcp_callback_create_srv(tcp_client_t *client, ipc_callid_t iid,
411 ipc_call_t *icall)
412{
413 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_callback_create_srv()");
414
415 async_sess_t *sess = async_callback_receive(EXCHANGE_SERIALIZE);
416 if (sess == NULL) {
417 async_answer_0(iid, ENOMEM);
418 return;
419 }
420
421 client->sess = sess;
422 async_answer_0(iid, EOK);
423}
424
425static void tcp_conn_create_srv(tcp_client_t *client, ipc_callid_t iid,
426 ipc_call_t *icall)
427{
428 ipc_callid_t callid;
429 size_t size;
430 inet_ep2_t epp;
431 sysarg_t conn_id;
432 int rc;
433
434 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_create_srv()");
435
436 if (!async_data_write_receive(&callid, &size)) {
437 async_answer_0(callid, EREFUSED);
438 async_answer_0(iid, EREFUSED);
439 return;
440 }
441
442 if (size != sizeof(inet_ep2_t)) {
443 async_answer_0(callid, EINVAL);
444 async_answer_0(iid, EINVAL);
445 return;
446 }
447
448 rc = async_data_write_finalize(callid, &epp, size);
449 if (rc != EOK) {
450 async_answer_0(callid, rc);
451 async_answer_0(iid, rc);
452 return;
453 }
454
455 rc = tcp_conn_create_impl(client, &epp, &conn_id);
456 if (rc != EOK) {
457 async_answer_0(iid, rc);
458 return;
459 }
460
461 async_answer_1(iid, EOK, conn_id);
462}
463
464static void tcp_conn_destroy_srv(tcp_client_t *client, ipc_callid_t iid,
465 ipc_call_t *icall)
466{
467 sysarg_t conn_id;
468 int rc;
469
470 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_destroy_srv()");
471
472 conn_id = IPC_GET_ARG1(*icall);
473 rc = tcp_conn_destroy_impl(client, conn_id);
474 async_answer_0(iid, rc);
475}
476
477static void tcp_listener_create_srv(tcp_client_t *client, ipc_callid_t iid,
478 ipc_call_t *icall)
479{
480 ipc_callid_t callid;
481 size_t size;
482 inet_ep_t ep;
483 sysarg_t lst_id;
484 int rc;
485
486 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_listener_create_srv()");
487
488 if (!async_data_write_receive(&callid, &size)) {
489 async_answer_0(callid, EREFUSED);
490 async_answer_0(iid, EREFUSED);
491 return;
492 }
493
494 if (size != sizeof(inet_ep_t)) {
495 async_answer_0(callid, EINVAL);
496 async_answer_0(iid, EINVAL);
497 return;
498 }
499
500 rc = async_data_write_finalize(callid, &ep, size);
501 if (rc != EOK) {
502 async_answer_0(callid, rc);
503 async_answer_0(iid, rc);
504 return;
505 }
506
507 rc = tcp_listener_create_impl(client, &ep, &lst_id);
508 if (rc != EOK) {
509 async_answer_0(iid, rc);
510 return;
511 }
512
513 async_answer_1(iid, EOK, lst_id);
514}
515
516static void tcp_listener_destroy_srv(tcp_client_t *client, ipc_callid_t iid,
517 ipc_call_t *icall)
518{
519 sysarg_t lst_id;
520 int rc;
521
522 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_listener_destroy_srv()");
523
524 lst_id = IPC_GET_ARG1(*icall);
525 rc = tcp_listener_destroy_impl(client, lst_id);
526 async_answer_0(iid, rc);
527}
528
529static void tcp_conn_send_fin_srv(tcp_client_t *client, ipc_callid_t iid,
530 ipc_call_t *icall)
531{
532 sysarg_t conn_id;
533 int rc;
534
535 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_send_fin_srv()");
536
537 conn_id = IPC_GET_ARG1(*icall);
538 rc = tcp_conn_send_fin_impl(client, conn_id);
539 async_answer_0(iid, rc);
540}
541
542static void tcp_conn_push_srv(tcp_client_t *client, ipc_callid_t iid,
543 ipc_call_t *icall)
544{
545 sysarg_t conn_id;
546 int rc;
547
548 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_push_srv()");
549
550 conn_id = IPC_GET_ARG1(*icall);
551 rc = tcp_conn_push_impl(client, conn_id);
552 async_answer_0(iid, rc);
553}
554
555static void tcp_conn_reset_srv(tcp_client_t *client, ipc_callid_t iid,
556 ipc_call_t *icall)
557{
558 sysarg_t conn_id;
559 int rc;
560
561 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_reset_srv()");
562
563 conn_id = IPC_GET_ARG1(*icall);
564 rc = tcp_conn_reset_impl(client, conn_id);
565 async_answer_0(iid, rc);
566}
567
568static void tcp_conn_send_srv(tcp_client_t *client, ipc_callid_t iid,
569 ipc_call_t *icall)
570{
571 ipc_callid_t callid;
572 size_t size;
573 sysarg_t conn_id;
574 void *data;
575 int rc;
576
577 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_send_srv())");
578
579 /* Receive message data */
580
581 if (!async_data_write_receive(&callid, &size)) {
582 async_answer_0(callid, EREFUSED);
583 async_answer_0(iid, EREFUSED);
584 return;
585 }
586
587 if (size > MAX_MSG_SIZE) {
588 async_answer_0(callid, EINVAL);
589 async_answer_0(iid, EINVAL);
590 return;
591 }
592
593 data = malloc(size);
594 if (data == NULL) {
595 async_answer_0(callid, ENOMEM);
596 async_answer_0(iid, ENOMEM);
597 }
598
599 rc = async_data_write_finalize(callid, data, size);
600 if (rc != EOK) {
601 async_answer_0(callid, rc);
602 async_answer_0(iid, rc);
603 free(data);
604 return;
605 }
606
607 conn_id = IPC_GET_ARG1(*icall);
608
609 rc = tcp_conn_send_impl(client, conn_id, data, size);
610 if (rc != EOK) {
611 async_answer_0(iid, rc);
612 free(data);
613 return;
614 }
615
616 async_answer_0(iid, EOK);
617 free(data);
618}
619
620static void tcp_conn_recv_srv(tcp_client_t *client, ipc_callid_t iid,
621 ipc_call_t *icall)
622{
623 ipc_callid_t callid;
624 sysarg_t conn_id;
625 size_t size, rsize;
626 void *data;
627 int rc;
628
629 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_recv_srv()");
630
631 conn_id = IPC_GET_ARG1(*icall);
632
633 if (!async_data_read_receive(&callid, &size)) {
634 async_answer_0(callid, EREFUSED);
635 async_answer_0(iid, EREFUSED);
636 return;
637 }
638
639 size = max(size, 16384);
640 data = malloc(size);
641 if (data == NULL) {
642 async_answer_0(callid, ENOMEM);
643 async_answer_0(iid, ENOMEM);
644 return;
645 }
646
647 rc = tcp_conn_recv_impl(client, conn_id, data, size, &rsize);
648 if (rc != EOK) {
649 async_answer_0(callid, rc);
650 async_answer_0(iid, rc);
651 free(data);
652 return;
653 }
654
655 rc = async_data_read_finalize(callid, data, size);
656 if (rc != EOK) {
657 async_answer_0(iid, rc);
658 free(data);
659 return;
660 }
661
662 async_answer_1(iid, EOK, rsize);
663 free(data);
664
665 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_recv_srv(): OK");
666}
667
668static void tcp_conn_recv_wait_srv(tcp_client_t *client, ipc_callid_t iid,
669 ipc_call_t *icall)
670{
671 ipc_callid_t callid;
672 sysarg_t conn_id;
673 size_t size, rsize;
674 void *data;
675 int rc;
676
677 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_recv_wait_srv()");
678
679 conn_id = IPC_GET_ARG1(*icall);
680
681 if (!async_data_read_receive(&callid, &size)) {
682 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_recv_wait_srv - data_receive failed");
683 async_answer_0(callid, EREFUSED);
684 async_answer_0(iid, EREFUSED);
685 return;
686 }
687
688 size = min(size, 16384);
689 data = malloc(size);
690 if (data == NULL) {
691 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_recv_wait_srv - allocation failed");
692 async_answer_0(callid, ENOMEM);
693 async_answer_0(iid, ENOMEM);
694 return;
695 }
696
697 rc = tcp_conn_recv_impl(client, conn_id, data, size, &rsize);
698 if (rc != EOK) {
699 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_recv_wait_srv - recv_impl failed rc=%d", rc);
700 async_answer_0(callid, rc);
701 async_answer_0(iid, rc);
702 free(data);
703 return;
704 }
705
706 rc = async_data_read_finalize(callid, data, size);
707 if (rc != EOK) {
708 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_recv_wait_srv - finalize failed");
709 async_answer_0(iid, rc);
710 free(data);
711 return;
712 }
713
714 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_recv_wait_srv(): rsize=%zu", size);
715 async_answer_1(iid, EOK, rsize);
716 free(data);
717
718 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_recv_wait_srv(): OK");
719}
720
721#include <mem.h>
722static void tcp_client_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
723{
724 tcp_client_t client;
725
726 /* Accept the connection */
727 async_answer_0(iid, EOK);
728
729 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_client_conn() - client=%p",
730 &client);
731
732 memset(&client, 0, sizeof(client));
733 client.sess = NULL;
734 list_initialize(&client.cconn);
735 list_initialize(&client.clst);
736// list_initialize(&client.crcv_queue);
737
738 while (true) {
739 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_client_conn: wait req");
740 ipc_call_t call;
741 ipc_callid_t callid = async_get_call(&call);
742 sysarg_t method = IPC_GET_IMETHOD(call);
743
744 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_client_conn: method=%d",
745 (int)method);
746 if (!method) {
747 /* The other side has hung up */
748 async_answer_0(callid, EOK);
749 return;
750 }
751
752 switch (method) {
753 case TCP_CALLBACK_CREATE:
754 tcp_callback_create_srv(&client, callid, &call);
755 break;
756 case TCP_CONN_CREATE:
757 tcp_conn_create_srv(&client, callid, &call);
758 break;
759 case TCP_CONN_DESTROY:
760 tcp_conn_destroy_srv(&client, callid, &call);
761 break;
762 case TCP_LISTENER_CREATE:
763 tcp_listener_create_srv(&client, callid, &call);
764 break;
765 case TCP_LISTENER_DESTROY:
766 tcp_listener_destroy_srv(&client, callid, &call);
767 break;
768 case TCP_CONN_SEND_FIN:
769 tcp_conn_send_fin_srv(&client, callid, &call);
770 break;
771 case TCP_CONN_PUSH:
772 tcp_conn_push_srv(&client, callid, &call);
773 break;
774 case TCP_CONN_RESET:
775 tcp_conn_reset_srv(&client, callid, &call);
776 break;
777 case TCP_CONN_SEND:
778 tcp_conn_send_srv(&client, callid, &call);
779 break;
780 case TCP_CONN_RECV:
781 tcp_conn_recv_srv(&client, callid, &call);
782 break;
783 case TCP_CONN_RECV_WAIT:
784 tcp_conn_recv_wait_srv(&client, callid, &call);
785 break;
786 default:
787 async_answer_0(callid, ENOTSUP);
788 break;
789 }
790 }
791 log_msg(LOG_DEFAULT, LVL_DEBUG,
792 "tcp_client_conn TERMINATED ***************************");
793}
794
795int tcp_service_init(void)
796{
797 int rc;
798 service_id_t sid;
799
800 async_set_client_connection(tcp_client_conn);
801
802 rc = loc_server_register(NAME);
803 if (rc != EOK) {
804 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering server.");
805 return EIO;
806 }
807
808 rc = loc_service_register(SERVICE_NAME_TCP, &sid);
809 if (rc != EOK) {
810 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering service.");
811 return EIO;
812 }
813
814 return EOK;
815}
816
817/**
818 * @}
819 */
Note: See TracBrowser for help on using the repository browser.