diff --git a/hake/menu.lst.armv8_imx8x b/hake/menu.lst.armv8_imx8x index 2d7d0eb..94510ad 100644 --- a/hake/menu.lst.armv8_imx8x +++ b/hake/menu.lst.armv8_imx8x @@ -14,3 +14,4 @@ module /armv8/sbin/echoserver module /armv8/sbin/shelly module /armv8/sbin/filereader module /armv8/sbin/block_driver_server +module /armv8/sbin/netcat diff --git a/lib/aos/shelly_client.c b/lib/aos/shelly_client.c index a380594..be39a9e 100644 --- a/lib/aos/shelly_client.c +++ b/lib/aos/shelly_client.c @@ -49,8 +49,6 @@ static void handle_response(void *arg, size_t header_size, void *header_buf, siz if (state.current_request->type == SHELLY_MSG_GETCHAR) { *state.buf = header->character; - } else if (state.current_request->type == SHELLY_MSG_PUTCHAR) { - //nothing to do } else { SHELLY_CLIENT_DEBUG("[handle_response] unexpected request type"); } @@ -60,34 +58,32 @@ static void handle_response(void *arg, size_t header_size, void *header_buf, siz static void handle_send_completed(void *arg, struct ump_send_queue_entry *entry) { SHELLY_CLIENT_DEBUG("[handle_send_completed]\n"); - free((void *)entry->header); - free((void *)entry->payload); - free(entry); + bool *done = arg; + *done = true; } errval_t shelly_client_getchar(struct aos_rpc * rpc, char * ret) { errval_t err; SHELLY_CLIENT_DEBUG("[shelly_client_getchar]\n"); - struct shelly_header * header = malloc(sizeof(struct shelly_header)); - if (header == NULL) return LIB_ERR_MALLOC_FAIL; - struct ump_send_queue_entry *entry = malloc(sizeof(struct ump_send_queue_entry)); - if (entry == NULL) return LIB_ERR_MALLOC_FAIL; + struct shelly_header header; + struct ump_send_queue_entry entry; state.request_ongoing = true; state.buf = ret; - state.current_request = header; + state.current_request = &header; - header->type = SHELLY_MSG_GETCHAR; - header->character = 0; + header.type = SHELLY_MSG_GETCHAR; + header.character = 0; - ump_send(state.send_chan, entry, sizeof(struct shelly_header), header, 0, NULL, handle_send_completed, NULL); + bool send_done = false; + ump_send(state.send_chan, &entry, sizeof(struct shelly_header), &header, 0, NULL, handle_send_completed, &send_done); // register response handler ump_recv_header(state.recv_chan, handle_response, NULL); // wait for the response - while (state.request_ongoing) { + while (!send_done || state.request_ongoing) { err = event_dispatch(&ws); if (err_is_fail(err)) { DEBUG_ERR(err, "in event_dispatch"); @@ -103,25 +99,17 @@ errval_t shelly_client_putchar(struct aos_rpc * rpc, char input) { errval_t err; SHELLY_CLIENT_DEBUG("[shelly_client_putchar]\n"); - struct shelly_header * header = malloc(sizeof(struct shelly_header)); - if (header == NULL) return LIB_ERR_MALLOC_FAIL; - struct ump_send_queue_entry *entry = malloc(sizeof(struct ump_send_queue_entry)); - if (entry == NULL) return LIB_ERR_MALLOC_FAIL; + struct shelly_header header; + struct ump_send_queue_entry entry; - state.request_ongoing = true; - state.current_request = header; - state.buf = NULL; + header.type = SHELLY_MSG_PUTCHAR; + header.character = input; - header->type = SHELLY_MSG_PUTCHAR; - header->character = input; - - ump_send(state.send_chan, entry, sizeof(struct shelly_header), header, 0, NULL, handle_send_completed, NULL); - - // register response handler - ump_recv_header(state.recv_chan, handle_response, NULL); + bool done = false; + ump_send(state.send_chan, &entry, sizeof(struct shelly_header), &header, 0, NULL, handle_send_completed, &done); // wait for the response - while (state.request_ongoing) { + while (!done) { err = event_dispatch(&ws); if (err_is_fail(err)) { DEBUG_ERR(err, "in event_dispatch"); diff --git a/platforms/Hakefile b/platforms/Hakefile index a5f3e69..b7e1aba 100644 --- a/platforms/Hakefile +++ b/platforms/Hakefile @@ -12,7 +12,7 @@ let -- Default list of modules to build/install - modules_common = [ "/sbin/" ++ f | f <- [ "init", "hello", "mallocator", "stackoverflow", "echoserver", "enet", "shelly", "filereader", "block_driver_server" + modules_common = [ "/sbin/" ++ f | f <- [ "init", "hello", "mallocator", "stackoverflow", "echoserver", "enet", "shelly", "filereader", "block_driver_server", "netcat" ] ] in [ diff --git a/usr/echoserver/Hakefile b/usr/echoserver/Hakefile index be49d16..376c8d2 100644 --- a/usr/echoserver/Hakefile +++ b/usr/echoserver/Hakefile @@ -6,7 +6,6 @@ -- If you do not find this file, copies can be found by writing to: -- ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group. -- --- Hakefile for /usr/init -- -------------------------------------------------------------------------- diff --git a/usr/hello/Hakefile b/usr/hello/Hakefile index abe1e81..60d7dc4 100644 --- a/usr/hello/Hakefile +++ b/usr/hello/Hakefile @@ -6,7 +6,6 @@ -- If you do not find this file, copies can be found by writing to: -- ETH Zurich D-INFK, Universitaetstr 6, CH-8092 Zurich. Attn: Systems Group. -- --- Hakefile for /usr/init -- -------------------------------------------------------------------------- diff --git a/usr/mallocator/Hakefile b/usr/mallocator/Hakefile index c300d68..b6cd6b4 100644 --- a/usr/mallocator/Hakefile +++ b/usr/mallocator/Hakefile @@ -6,12 +6,11 @@ -- If you do not find this file, copies can be found by writing to: -- ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group. -- --- Hakefile for /usr/init -- -------------------------------------------------------------------------- -[ build application - { +[ build application + { target = "mallocator", cFiles = [ "main.c" ] } diff --git a/usr/memeater/Hakefile b/usr/memeater/Hakefile index 1fcf391..7781dc1 100644 --- a/usr/memeater/Hakefile +++ b/usr/memeater/Hakefile @@ -6,12 +6,11 @@ -- If you do not find this file, copies can be found by writing to: -- ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group. -- --- Hakefile for /usr/init -- -------------------------------------------------------------------------- -[ build application - { +[ build application + { target = "memeater", cFiles = [ "main.c" ] } diff --git a/usr/netcat/Hakefile b/usr/netcat/Hakefile new file mode 100644 index 0000000..eb72154 --- /dev/null +++ b/usr/netcat/Hakefile @@ -0,0 +1,17 @@ +-------------------------------------------------------------------------- +-- Copyright (c) 2007-2010, ETH Zurich. +-- All rights reserved. +-- +-- This file is distributed under the terms in the attached LICENSE file. +-- If you do not find this file, copies can be found by writing to: +-- ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group. +-- +-- +-------------------------------------------------------------------------- + +[ build application + { + target = "netcat", + cFiles = [ "main.c" ] + } +] diff --git a/usr/netcat/main.c b/usr/netcat/main.c new file mode 100644 index 0000000..36f68a9 --- /dev/null +++ b/usr/netcat/main.c @@ -0,0 +1,163 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BUF_SIZE (1500 - 20 - 8) +struct send_buf { + struct ump_net_call call; + uint8_t payload[BUF_SIZE]; + size_t send_len; + struct waitset_chanstate chan; +}; + +static uint16_t local_port; +static uint16_t remote_port; +static uint32_t remote_ip; + +static void udp_listen_callback (void *arg, errval_t err, uint16_t src_port) { + if (err_is_fail(err)) { + printf("Failed to listen on port %d:\n", local_port); + err_print_calltrace(err); + return; + } + local_port = src_port; + DEBUG_PRINTF("Listening on UDP port %d.\n", src_port); +} + +static void net_recv_packet (void *arg, size_t payload_size, void *payload) { + printf("%.*s", payload_size, arg); + free(arg); +} + +static void handle_udp_recv (void *arg, struct ump_net_ev_udp_recv *udp_recv, size_t payload_size) { + void *payload = malloc(payload_size); + if (payload == NULL) { + printf("ERROR: malloc failed\n"); + ump_net_recv_payload(NULL, NULL, NULL); + } else { + if (remote_ip == 0) remote_ip = udp_recv->src_ip; + if (remote_port == 0) remote_port = udp_recv->src_port; + ump_net_recv_payload(payload, net_recv_packet, payload); + } +} + +static void send_callback (void *arg, errval_t err) { + struct send_buf *send_buf = arg; + free(send_buf); + if (err_is_fail(err)) { + DEBUG_ERR(err, "failed to send packet"); + } +} + +static void udp_send(void *arg) { + struct send_buf *send_buf = arg; + ump_net_udp_send( + &send_buf->call, + remote_ip, + local_port, remote_port, + send_buf->send_len, &send_buf->payload, + send_callback, send_buf + ); +} + +static struct send_buf *create_send_buffer (void) { + struct send_buf *send_buf = malloc(sizeof(struct send_buf)); + if (send_buf == NULL) { + printf("ERROR: malloc failed\n"); + return NULL; + } + waitset_chanstate_init(&send_buf->chan, CHANTYPE_OTHER); + send_buf->send_len = 0; + return send_buf; +} + +static struct waitset_chanstate exitchan; +static struct ump_net_call stopcall; + +static void udp_stop_callback (void *arg, errval_t err) { + exit(0); +} + +static void exit_process(void *arg) { + ump_net_udp_listen_stop(&stopcall, local_port, udp_stop_callback, NULL); +} + +static int input_reader (void *arg) { + errval_t err; + struct aos_rpc *rpc = aos_rpc_get_serial_channel(); + struct waitset *default_ws = get_default_waitset(); + struct send_buf *send_buf = create_send_buffer(); + if (send_buf == NULL) return 1; + while (true) { + char in; + err = aos_rpc_serial_getchar(rpc, &in); + if (err_is_fail(err)) { + DEBUG_ERR(err, "failed to read"); + return 1; + } + if (in == '\x03') { // Ctrl+C + waitset_chan_trigger_closure(default_ws, &exitchan, MKCLOSURE(exit_process, NULL)); + return 0; + } + if (in == '\0') in = '\n'; + send_buf->payload[send_buf->send_len] = in; + send_buf->send_len++; + if (send_buf->send_len == sizeof(send_buf->payload) || in == '\n') { + if (remote_port == 0 || remote_ip == 0) { + printf("Error: Can't send, remote ip/port not provided and no packet received yet.\n"); + send_buf->send_len = 0; + } else { + waitset_chan_trigger_closure(default_ws, &send_buf->chan, MKCLOSURE(udp_send, send_buf)); + send_buf = create_send_buffer(); + if (send_buf == NULL) return 1; + } + } + } +} + +int main (int argc, char *argv[]) { + errval_t err; + struct waitset *default_ws = get_default_waitset(); + if (argc < 2) { + printf("Usage: netcat local_port [remote_ip] [remote_port]\n"); + return 1; + } + local_port = strtol(argv[1], NULL, 10); + + if (argc > 2) { + int a1, a2, a3, a4; + int parsed = sscanf(argv[2], "%d.%d.%d.%d.", &a1, &a2, &a3, &a4); + if (parsed != 4) { + printf("Error: failed to parse IP address\n"); + return 1; + } + remote_ip = MK_IP(a1, a2, a3, a4); + remote_port = local_port; + } + if (argc > 3) { + remote_port = strtol(argv[3], NULL, 10); + } + + err = ump_net_init(default_ws); + if (err_is_fail(err)) USER_PANIC_ERR(err, "Failed to connect to net server"); + + struct ump_net_call call_udp_listen; + ump_net_udp_listen(&call_udp_listen, local_port, handle_udp_recv, NULL, udp_listen_callback, NULL); + + thread_create(input_reader, NULL); + + while (true) { + err = event_dispatch(default_ws); + if (err_is_fail(err)) { + DEBUG_ERR(err, "in event_dispatch"); + abort(); + } + } +} diff --git a/usr/shelly/shelly.c b/usr/shelly/shelly.c index 66fdba3..b716311 100644 --- a/usr/shelly/shelly.c +++ b/usr/shelly/shelly.c @@ -87,7 +87,7 @@ static void handle_lpuart_interrupt(void * arg) { if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character"); if (is_newline(input_char)) { - err = lpuart_putchar(global_state->uart_s, ASCII_CR); + err = lpuart_putchar(global_state->uart_s, ASCII_NL); if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character"); } @@ -187,7 +187,6 @@ static void handle_client_request(void *arg, size_t header_size, void *header_bu err = lpuart_putchar(global_state->uart_s, ASCII_CR); if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character"); } - send_response(local_state, SYS_ERR_OK, '\0', 0, NULL); } // skip payload @@ -309,4 +308,4 @@ int main(int argc, char *argv[]) USER_PANIC_ERR(err, "in event_dispatch"); } } -} \ No newline at end of file +} diff --git a/usr/stackoverflow/Hakefile b/usr/stackoverflow/Hakefile index f34b5c9..ffb9fc0 100644 --- a/usr/stackoverflow/Hakefile +++ b/usr/stackoverflow/Hakefile @@ -6,12 +6,11 @@ -- If you do not find this file, copies can be found by writing to: -- ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group. -- --- Hakefile for /usr/init -- -------------------------------------------------------------------------- -[ build application - { +[ build application + { target = "stackoverflow", cFiles = [ "main.c" ] }