missing files
This commit is contained in:
parent
99c30cb2e7
commit
74418ff85e
39
include/aos/shelly_client.h
Normal file
39
include/aos/shelly_client.h
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef _SHELLY_CLIENT_H_
|
||||
#define _SHELLY_CLIENT_H_
|
||||
|
||||
#include <aos/aos.h>
|
||||
|
||||
// #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_ */
|
||||
116
lib/aos/shelly_client.c
Normal file
116
lib/aos/shelly_client.c
Normal file
@ -0,0 +1,116 @@
|
||||
#include <aos/ump_chan.h>
|
||||
#include <aos/ump_binding.h>
|
||||
#include <aos/aos_rpc.h>
|
||||
#include <aos/deferred.h>
|
||||
#include <aos/shelly_client.h>
|
||||
#include <aos/domain.h>
|
||||
|
||||
// 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;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user