echo command somewhat working
This commit is contained in:
parent
74418ff85e
commit
5850f35d95
@ -12,14 +12,6 @@
|
||||
#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,
|
||||
@ -31,6 +23,16 @@ struct shelly_header {
|
||||
char character;
|
||||
};
|
||||
|
||||
struct shelly_client_state {
|
||||
struct ump_send_chan *send_chan;
|
||||
struct ump_recv_chan *recv_chan;
|
||||
|
||||
struct capref shared_frame;
|
||||
bool request_ongoing;
|
||||
struct shelly_header * current_request;
|
||||
|
||||
char * buf;
|
||||
};
|
||||
|
||||
errval_t shelly_client_init(void);
|
||||
errval_t shelly_client_getchar(struct aos_rpc * rpc, char * ret);
|
||||
|
||||
@ -16,6 +16,8 @@ errval_t shelly_client_init(void) {
|
||||
waitset_init(&ws);
|
||||
|
||||
state.request_ongoing = false;
|
||||
state.buf = NULL;
|
||||
state.current_request = NULL;
|
||||
|
||||
//connect to shelly
|
||||
struct aos_rpc *rpc = aos_rpc_get_init_channel();
|
||||
@ -41,15 +43,24 @@ static void handle_payload(void *arg, size_t payload_size, void *payload) {
|
||||
}
|
||||
|
||||
static void handle_response(void *arg, size_t header_size, void *header_buf, size_t payload_size) {
|
||||
// struct shelly_header *header = header_buf;
|
||||
struct shelly_header *header = header_buf;
|
||||
SHELLY_CLIENT_DEBUG("[handle_response]\n");
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
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((void *)entry->payload);
|
||||
free(entry);
|
||||
}
|
||||
|
||||
@ -58,14 +69,16 @@ errval_t shelly_client_getchar(struct aos_rpc * rpc, char * ret) {
|
||||
SHELLY_CLIENT_DEBUG("[shelly_client_getchar]\n");
|
||||
|
||||
state.request_ongoing = true;
|
||||
state.buf = ret;
|
||||
|
||||
struct shelly_header * header = malloc(sizeof(struct shelly_header));
|
||||
if (header == NULL) return LIB_ERR_MALLOC_FAIL;
|
||||
state.current_request = header;
|
||||
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';
|
||||
header->character = 0;
|
||||
|
||||
ump_send(state.send_chan, entry, sizeof(struct shelly_header), header, 0, NULL, handle_send_completed, NULL);
|
||||
|
||||
@ -80,6 +93,7 @@ errval_t shelly_client_getchar(struct aos_rpc * rpc, char * ret) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
SHELLY_CLIENT_DEBUG("[shelly_client_getchar] done\n");
|
||||
|
||||
return SYS_ERR_OK;
|
||||
}
|
||||
@ -92,13 +106,14 @@ errval_t shelly_client_putchar(struct aos_rpc * rpc, char input) {
|
||||
|
||||
struct shelly_header * header = malloc(sizeof(struct shelly_header));
|
||||
if (header == NULL) return LIB_ERR_MALLOC_FAIL;
|
||||
state.current_request = header;
|
||||
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);
|
||||
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);
|
||||
@ -111,6 +126,7 @@ errval_t shelly_client_putchar(struct aos_rpc * rpc, char input) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
SHELLY_CLIENT_DEBUG("[shelly_client_getchar] done\n");
|
||||
|
||||
return SYS_ERR_OK;
|
||||
}
|
||||
|
||||
@ -22,10 +22,12 @@
|
||||
//state that is shared for all clients
|
||||
static struct shelly_st_global * global_state;
|
||||
|
||||
#include "shelly_cmd.c"
|
||||
|
||||
__attribute__((__used__))
|
||||
static void shelly_interrupt_handler(void * arg) {
|
||||
static void handle_lpuart_interrupt(void * arg) {
|
||||
errval_t err;
|
||||
SHELLY_DEBUG("[shelly_interrupt_handler]\n");
|
||||
SHELLY_DEBUG("[handle_lpuart_interrupt]\n");
|
||||
assert(global_state);
|
||||
|
||||
char input_char;
|
||||
@ -34,6 +36,28 @@ static void shelly_interrupt_handler(void * arg) {
|
||||
|
||||
err = lpuart_putchar(global_state->uart_s, input_char);
|
||||
if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character");
|
||||
|
||||
if (input_char == ASCII_NL || input_char == ASCII_EOF || input_char == ASCII_CR) {
|
||||
err = lpuart_putchar(global_state->uart_s, '\n');
|
||||
if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character");
|
||||
|
||||
global_state->buf[global_state->buffer_i] = '\0';
|
||||
global_state->buffer_i += 1;
|
||||
|
||||
handle_shelly_cmd(global_state->buf, global_state->buffer_i);
|
||||
|
||||
global_state->buffer_i = 0;
|
||||
|
||||
err = lpuart_putchar(global_state->uart_s, ASCII_EOT);
|
||||
if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character");
|
||||
err = lpuart_putchar(global_state->uart_s, '>');
|
||||
if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character");
|
||||
} else {
|
||||
global_state->buf[global_state->buffer_i] = input_char;
|
||||
global_state->buffer_i += 1;
|
||||
global_state->buffer_i %= SHELLY_BUF_SIZE;
|
||||
}
|
||||
SHELLY_DEBUG("[handle_lpuart_interrupt] done\n");
|
||||
}
|
||||
|
||||
static void handle_send_completed(void *arg, struct ump_send_queue_entry *entry) {
|
||||
@ -45,6 +69,7 @@ static void handle_send_completed(void *arg, struct ump_send_queue_entry *entry)
|
||||
static void send_response(struct shelly_st_local * local_state, errval_t err, size_t payload_size, void *payload) {
|
||||
assert(local_state);
|
||||
|
||||
SHELLY_DEBUG("[send_response]\n");
|
||||
struct shelly_header * header = malloc(sizeof(struct shelly_header));
|
||||
assert(header);
|
||||
header->type = SHELLY_MSG_RESPONSE;
|
||||
@ -62,6 +87,7 @@ static void send_response(struct shelly_st_local * local_state, errval_t err, si
|
||||
handle_send_completed,
|
||||
NULL
|
||||
);
|
||||
SHELLY_DEBUG("[send_response] done\n");
|
||||
}
|
||||
|
||||
static void handle_client_request(void *arg, size_t header_size, void *header_buf, size_t payload_size);
|
||||
@ -69,9 +95,13 @@ static void handle_payload(void *arg, size_t payload_size, void *payload) {
|
||||
struct shelly_st_local * local_state = arg;
|
||||
assert(local_state);
|
||||
assert(global_state);
|
||||
|
||||
SHELLY_DEBUG("[handle_payload]\n");
|
||||
|
||||
// SHELLY_DEBUG("[handle_payload] client_id=%d\n", local_state->client_id);
|
||||
// listen for the next request on this channel
|
||||
ump_recv_header(local_state->recv_chan, handle_client_request, local_state);
|
||||
SHELLY_DEBUG("[handle_payload] done\n");
|
||||
}
|
||||
|
||||
static void handle_client_request(void *arg, size_t header_size, void *header_buf, size_t payload_size) {
|
||||
@ -80,6 +110,8 @@ static void handle_client_request(void *arg, size_t header_size, void *header_bu
|
||||
assert(local_state);
|
||||
assert(global_state);
|
||||
|
||||
SHELLY_DEBUG("[handle_client_request]\n");
|
||||
|
||||
struct shelly_header * header = (struct shelly_header *) header_buf;
|
||||
|
||||
if (header->type == SHELLY_MSG_GETCHAR) {
|
||||
@ -91,12 +123,16 @@ static void handle_client_request(void *arg, size_t header_size, void *header_bu
|
||||
if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character");
|
||||
}
|
||||
|
||||
SHELLY_DEBUG("[handle_client_request] send_response\n");
|
||||
send_response(local_state, SYS_ERR_OK, 0, NULL);
|
||||
|
||||
// skip payload
|
||||
SHELLY_DEBUG("[handle_client_request] skip payload\n");
|
||||
ump_recv_payload(local_state->recv_chan, NULL, handle_payload, local_state);
|
||||
SHELLY_DEBUG("[handle_client_request] done\n");
|
||||
}
|
||||
|
||||
__attribute__((__used__))
|
||||
static errval_t connection_callback(void *arg, struct capref cap) {
|
||||
errval_t err;
|
||||
|
||||
@ -112,7 +148,7 @@ static errval_t connection_callback(void *arg, struct capref cap) {
|
||||
|
||||
// we can run the server on the default waitset since we are dispatching on
|
||||
// it for listening to connections anyways
|
||||
err = ump_chan_init(UMP_ROLE_SERVER, &local_state->send_chan, &local_state->recv_chan, sizeof(struct shelly_header), cap, get_default_waitset());
|
||||
err = ump_chan_init(UMP_ROLE_SERVER, &local_state->send_chan, &local_state->recv_chan, sizeof(struct shelly_header), cap, global_state->ws);
|
||||
if (err_is_fail(err)) return err;
|
||||
// SHELLY_DEBUG("[connection_callback] local_state=%p\n", local_state);
|
||||
|
||||
@ -132,6 +168,10 @@ int main(int argc, char *argv[])
|
||||
global_state = calloc(sizeof(struct shelly_st_global), 1);
|
||||
assert(global_state);
|
||||
|
||||
global_state->num_clients = 0;
|
||||
global_state->buffer_i = 0;
|
||||
global_state->ws = get_default_waitset();
|
||||
|
||||
//afeer: map lpuart registers
|
||||
struct capref cap_arg0 = {
|
||||
.cnode = cnode_arg,
|
||||
@ -179,8 +219,9 @@ int main(int argc, char *argv[])
|
||||
debug_print_cap_at_capref(buf, 256, inter_cap);
|
||||
debug_printf(buf);
|
||||
|
||||
struct waitset * ws = get_default_waitset();
|
||||
err = inthandler_setup(inter_cap, ws, MKCLOSURE(shelly_interrupt_handler, NULL));
|
||||
// struct waitset * ws = calloc(sizeof(struct waitset), 1);
|
||||
// waitset_init(ws);
|
||||
err = inthandler_setup(inter_cap, global_state->ws, MKCLOSURE(handle_lpuart_interrupt, NULL));
|
||||
if (err_is_fail(err)) USER_PANIC_ERR(err, "couln't setup interrupt handler");
|
||||
|
||||
SHELLY_DEBUG("setup interrupt handler\n");
|
||||
@ -195,13 +236,13 @@ int main(int argc, char *argv[])
|
||||
|
||||
SHELLY_DEBUG("enabled lpuart interrupt\n");
|
||||
|
||||
SHELLY_DEBUG("registering as shelly server\n");
|
||||
struct ump_binding_server server;
|
||||
err = ump_binding_register(&server, UMP_SERVER_SHELLY, connection_callback, NULL);
|
||||
if (err_is_fail(err)) USER_PANIC_ERR(err, "Failed to register UMP server");
|
||||
// SHELLY_DEBUG("registering as shelly server\n");
|
||||
// struct ump_binding_server server;
|
||||
// err = ump_binding_register(&server, UMP_SERVER_SHELLY, connection_callback, NULL);
|
||||
// if (err_is_fail(err)) USER_PANIC_ERR(err, "Failed to register UMP server");
|
||||
|
||||
while (true) {
|
||||
err = event_dispatch(ws);
|
||||
err = event_dispatch(global_state->ws);
|
||||
if (err_is_fail(err)) {
|
||||
DEBUG_ERR(err, "in event_dispatch");
|
||||
abort();
|
||||
|
||||
@ -22,9 +22,16 @@
|
||||
#include <drivers/gic_dist.h>
|
||||
#include <aos/ump_chan.h>
|
||||
|
||||
#define ASCII_NL 10 // < new line
|
||||
#define ASCII_CR 13 // < carriage return
|
||||
#define ASCII_EOF 4 // < end of file
|
||||
#define ASCII_EOT 3 // < end of text
|
||||
|
||||
#define SHELLY_BUF_SIZE 2048
|
||||
//state that is shared for all clients
|
||||
struct shelly_st_global {
|
||||
struct waitset * ws;
|
||||
|
||||
void * lpuart_base; // < virtual address of the lpuart device registers
|
||||
void * gic_base; // < virtual address of the gic device registers
|
||||
|
||||
@ -33,6 +40,7 @@ struct shelly_st_global {
|
||||
|
||||
u_int32_t num_clients;
|
||||
char buf[SHELLY_BUF_SIZE];
|
||||
size_t buffer_i;
|
||||
};
|
||||
|
||||
//state that different for each client
|
||||
|
||||
48
usr/shelly/shelly_cmd.c
Normal file
48
usr/shelly/shelly_cmd.c
Normal file
@ -0,0 +1,48 @@
|
||||
#include <stdlib.h>
|
||||
#include "shelly.h"
|
||||
|
||||
|
||||
|
||||
static void shelly_cmd_echo(char* argv[], int argc) {
|
||||
errval_t err;
|
||||
SHELLY_DEBUG("[shelly_cmd_echo] argc=%d\n", argc);
|
||||
|
||||
for (int i = 0; argv[1][i] != '\0'; ++i) {
|
||||
err = lpuart_putchar(global_state->uart_s, argv[1][i]);
|
||||
if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character");
|
||||
}
|
||||
err = lpuart_putchar(global_state->uart_s, '\0');
|
||||
if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character");
|
||||
}
|
||||
|
||||
static void handle_shelly_cmd(char* str, size_t len) {
|
||||
SHELLY_DEBUG("[handle_shelly_cmd] len=%d\n", len);
|
||||
|
||||
if (len <= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
int argc = 1;
|
||||
for (int i = 0; i < len; ++i) {
|
||||
if (str[i] == ' ') ++argc;
|
||||
}
|
||||
char * argv[argc];
|
||||
|
||||
const char delim[2] = " ";
|
||||
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
if (i == 0) {
|
||||
argv[i] = strtok(str, delim);
|
||||
} else {
|
||||
argv[i] = strtok(NULL, delim);
|
||||
}
|
||||
SHELLY_DEBUG("[handle_shelly_cmd] arg[%d]=%s\n", i, argv[i]);
|
||||
}
|
||||
|
||||
if (strcmp(argv[0], "echo") == 0) {
|
||||
shelly_cmd_echo(argv, argc);
|
||||
} else {
|
||||
SHELLY_DEBUG("unknown command %s\n", argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user