From 74418ff85e9e3a65c577f0359dcfd5797f2d170c Mon Sep 17 00:00:00 2001 From: Aurel Feer Date: Tue, 31 May 2022 00:36:32 +0200 Subject: [PATCH] missing files --- include/aos/shelly_client.h | 39 ++++++++++++ lib/aos/shelly_client.c | 116 ++++++++++++++++++++++++++++++++++++ 2 files changed, 155 insertions(+) create mode 100644 include/aos/shelly_client.h create mode 100644 lib/aos/shelly_client.c diff --git a/include/aos/shelly_client.h b/include/aos/shelly_client.h new file mode 100644 index 0000000..8592ca6 --- /dev/null +++ b/include/aos/shelly_client.h @@ -0,0 +1,39 @@ +#ifndef _SHELLY_CLIENT_H_ +#define _SHELLY_CLIENT_H_ + +#include + +// #define SHELLY_CLIENT_DEBUG_ON 1 + +#if defined(SHELLY_CLIENT_DEBUG_ON) +#define SHELLY_CLIENT_DEBUG(x...) debug_printf("[SHELLY_CLIENT_DEBUG] " x); +#else +#define SHELLY_CLIENT_DEBUG(x, ...) ((void)0) +#endif + + +struct shelly_client_state { + struct ump_send_chan *send_chan; + struct ump_recv_chan *recv_chan; + + struct capref shared_frame; + bool request_ongoing; +}; + +enum shelly_msg_type { + SHELLY_MSG_PUTCHAR, + SHELLY_MSG_GETCHAR, + SHELLY_MSG_RESPONSE, +}; + +struct shelly_header { + enum shelly_msg_type type; + char character; +}; + + +errval_t shelly_client_init(void); +errval_t shelly_client_getchar(struct aos_rpc * rpc, char * ret); +errval_t shelly_client_putchar(struct aos_rpc * rpc, char input); + +#endif /* _SHELLY_CLIENT_H_ */ \ No newline at end of file diff --git a/lib/aos/shelly_client.c b/lib/aos/shelly_client.c new file mode 100644 index 0000000..6680547 --- /dev/null +++ b/lib/aos/shelly_client.c @@ -0,0 +1,116 @@ +#include +#include +#include +#include +#include +#include + +// use a waitset to make the calls blocking +struct waitset ws; +static struct shelly_client_state state; + +errval_t shelly_client_init(void) { + errval_t err; + SHELLY_CLIENT_DEBUG("[shelly_client_init]\n"); + + waitset_init(&ws); + + state.request_ongoing = false; + + //connect to shelly + struct aos_rpc *rpc = aos_rpc_get_init_channel(); + // retry several times, waiting inbetween in case the server is still starting up + for (int attempts = 0; attempts < 50; attempts++) { + err = aos_rpc_ump_connect(rpc, UMP_SERVER_SHELLY, &state.shared_frame); + if (err_no(err) != LIB_ERR_UMP_NOT_REGISTERED) break; + barrelfish_usleep(100000); + } + if (err_is_fail(err)) return err; + + //create the ump channel to the serial driver (a.k.a. shelly) + err = ump_chan_init(UMP_ROLE_CLIENT, &state.send_chan, &state.recv_chan, sizeof(struct shelly_header), state.shared_frame, &ws); + if (err_is_fail(err)) return err; + + // set_shelly_rpc(rpc); + + return SYS_ERR_OK; +} + +static void handle_payload(void *arg, size_t payload_size, void *payload) { + state.request_ongoing = false; +} + +static void handle_response(void *arg, size_t header_size, void *header_buf, size_t payload_size) { + // struct shelly_header *header = header_buf; + SHELLY_CLIENT_DEBUG("[handle_response]\n"); + + ump_recv_payload(state.recv_chan, NULL, handle_payload, NULL); +} + +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(entry); +} + +errval_t shelly_client_getchar(struct aos_rpc * rpc, char * ret) { + errval_t err; + SHELLY_CLIENT_DEBUG("[shelly_client_getchar]\n"); + + state.request_ongoing = true; + + 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; + + 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); + + // register response handler + ump_recv_header(state.recv_chan, handle_response, NULL); + + // wait for the response + while (state.request_ongoing) { + err = event_dispatch(&ws); + if (err_is_fail(err)) { + DEBUG_ERR(err, "in event_dispatch"); + abort(); + } + } + + return SYS_ERR_OK; +} + +errval_t shelly_client_putchar(struct aos_rpc * rpc, char input) { + errval_t err; + SHELLY_CLIENT_DEBUG("[shelly_client_putchar]\n"); + + state.request_ongoing = true; + + 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; + + header->type = SHELLY_MSG_PUTCHAR; + header->character = input; + + ump_send(state.send_chan, entry, sizeof(struct shelly_header), header, 1, &input, handle_send_completed, NULL); + + // register response handler + ump_recv_header(state.recv_chan, handle_response, NULL); + + // wait for the response + while (state.request_ongoing) { + err = event_dispatch(&ws); + if (err_is_fail(err)) { + DEBUG_ERR(err, "in event_dispatch"); + abort(); + } + } + + return SYS_ERR_OK; +}