1/*
2 * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include <camkes.h>
8#include <autoconf.h>
9#include <stdio.h>
10#include <string.h>
11#include <picoserver.h>
12#include <assert.h>
13#include <echo_listener_common.h>
14
15extern void *listener_send_buf;
16extern void *listener_recv_buf;
17
18seL4_CPtr listener_control_notification();
19
20void handle_picoserver_notification(void)
21{
22    picoserver_event_t server_event = listener_control_event_poll();
23    int ret = 0;
24    int socket = 0;
25    uint16_t events = 0;
26    char ip_string[16] = {0};
27
28    while (server_event.num_events_left > 0 || server_event.events) {
29        socket = server_event.socket_fd;
30        events = server_event.events;
31        if (events & PICOSERVER_CONN) {
32            picoserver_peer_t peer = listener_control_accept(socket);
33            if (peer.result == -1) {
34                assert(!"Failed to accept a peer");
35            }
36            pico_ipv4_to_string(ip_string, peer.peer_addr);
37            printf("%s: Connection established with %s on socket %d\n", get_instance_name(), ip_string, socket);
38        }
39        if (events & PICOSERVER_READ) {
40            printf("%s: Received a message on socket %d, going to print it out\n", get_instance_name(), socket);
41            ret = listener_recv_recv(socket, 4096, 0);
42            printf("%s", listener_recv_buf);
43            memset(listener_recv_buf, 0, 4096);
44        }
45        if (events & PICOSERVER_CLOSE) {
46            ret = listener_control_shutdown(socket, PICOSERVER_SHUT_RDWR);
47            printf("%s: Connection closing on socket %d\n", get_instance_name(), socket);
48        }
49        if (events & PICOSERVER_FIN) {
50            printf("%s: Connection closed on socket %d\n", get_instance_name(), socket);
51        }
52        if (events & PICOSERVER_ERR) {
53            printf("%s: Error with socket %d, going to die\n", get_instance_name(), socket);
54            assert(0);
55        }
56        server_event = listener_control_event_poll();
57    }
58}
59
60int run(void)
61{
62    printf("%s instance starting up, going to be listening on %s:%d\n",
63           get_instance_name(), ip_addr, LISTENER_PORT);
64
65    int socket = listener_control_open(false);
66    if (socket == -1) {
67        assert(!"Failed to open a socket for listening!");
68    }
69
70    int ret = listener_control_bind(socket, PICOSERVER_ANY_ADDR_IPV4, LISTENER_PORT);
71    if (ret) {
72        assert(!"Failed to bind a socket for listening!");
73    }
74
75    ret = listener_control_listen(socket, 1);
76    if (ret) {
77        assert(!"Failed to listen for incoming connections!");
78    }
79
80    /* Now poll for events and handle them */
81    seL4_Word badge;
82
83    while (1) {
84        seL4_Wait(listener_control_notification(), &badge);
85        handle_picoserver_notification();
86    }
87}
88