mirror of
https://github.com/osnr/TabFS.git
synced 2024-05-17 21:16:35 +02:00
fs: Fix formatting.
This commit is contained in:
parent
784ec83696
commit
a8ce61d9a1
54
fs/common.c
54
fs/common.c
|
@ -12,51 +12,51 @@ static int tabfs_to_ws[2];
|
||||||
static int ws_to_tabfs[2];
|
static int ws_to_tabfs[2];
|
||||||
|
|
||||||
void common_init() {
|
void common_init() {
|
||||||
if (pipe(tabfs_to_ws)) exit(1);
|
if (pipe(tabfs_to_ws)) exit(1);
|
||||||
if (pipe(ws_to_tabfs)) exit(1);
|
if (pipe(ws_to_tabfs)) exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void common_send_tabfs_to_ws(char *request_data) {
|
void common_send_tabfs_to_ws(char *request_data) {
|
||||||
write(tabfs_to_ws[1], &request_data, sizeof(request_data));
|
write(tabfs_to_ws[1], &request_data, sizeof(request_data));
|
||||||
}
|
}
|
||||||
|
|
||||||
char *common_receive_tabfs_to_ws(fd_set_filler_fn_t filler) {
|
char *common_receive_tabfs_to_ws(fd_set_filler_fn_t filler) {
|
||||||
fd_set read_fds, write_fds, except_fds;
|
fd_set read_fds, write_fds, except_fds;
|
||||||
FD_ZERO(&read_fds);
|
FD_ZERO(&read_fds);
|
||||||
FD_ZERO(&write_fds);
|
FD_ZERO(&write_fds);
|
||||||
FD_ZERO(&except_fds);
|
FD_ZERO(&except_fds);
|
||||||
|
|
||||||
int max_fd = filler(&read_fds, &write_fds, &except_fds);
|
int max_fd = filler(&read_fds, &write_fds, &except_fds);
|
||||||
|
|
||||||
FD_SET(tabfs_to_ws[0], &read_fds);
|
FD_SET(tabfs_to_ws[0], &read_fds);
|
||||||
if (tabfs_to_ws[0] > max_fd) { max_fd = tabfs_to_ws[0]; }
|
if (tabfs_to_ws[0] > max_fd) { max_fd = tabfs_to_ws[0]; }
|
||||||
|
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
timeout.tv_sec = 0;
|
timeout.tv_sec = 0;
|
||||||
timeout.tv_usec = 200000;
|
timeout.tv_usec = 200000;
|
||||||
|
|
||||||
select(max_fd + 1, &read_fds, &write_fds, &except_fds, &timeout);
|
select(max_fd + 1, &read_fds, &write_fds, &except_fds, &timeout);
|
||||||
|
|
||||||
if (!FD_ISSET(tabfs_to_ws[0], &read_fds)) {
|
if (!FD_ISSET(tabfs_to_ws[0], &read_fds)) {
|
||||||
// We can't read from tabfs_to_ws right now. Could be that it
|
// We can't read from tabfs_to_ws right now. Could be that it
|
||||||
// timed out, could be that we got a websocket event instead,
|
// timed out, could be that we got a websocket event instead,
|
||||||
// whatever.
|
// whatever.
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *request_data;
|
char *request_data;
|
||||||
read(tabfs_to_ws[0], &request_data, sizeof(request_data));
|
read(tabfs_to_ws[0], &request_data, sizeof(request_data));
|
||||||
|
|
||||||
return request_data;
|
return request_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void common_send_ws_to_tabfs(char *response_data) {
|
void common_send_ws_to_tabfs(char *response_data) {
|
||||||
write(ws_to_tabfs[1], &response_data, sizeof(response_data));
|
write(ws_to_tabfs[1], &response_data, sizeof(response_data));
|
||||||
}
|
}
|
||||||
char *common_receive_ws_to_tabfs() {
|
char *common_receive_ws_to_tabfs() {
|
||||||
char *response_data;
|
char *response_data;
|
||||||
read(ws_to_tabfs[0], &response_data, sizeof(response_data));
|
read(ws_to_tabfs[0], &response_data, sizeof(response_data));
|
||||||
|
|
||||||
return response_data;
|
return response_data;
|
||||||
}
|
}
|
||||||
|
|
106
fs/tabfs.c
106
fs/tabfs.c
|
@ -12,56 +12,54 @@
|
||||||
#include "ws.h"
|
#include "ws.h"
|
||||||
|
|
||||||
static cJSON *send_request_then_await_response(cJSON *req) {
|
static cJSON *send_request_then_await_response(cJSON *req) {
|
||||||
char *request_data = cJSON_Print(req); // Will be freed on ws side.
|
char *request_data = cJSON_Print(req); // Will be freed on ws side.
|
||||||
common_send_tabfs_to_ws(request_data);
|
common_send_tabfs_to_ws(request_data);
|
||||||
|
|
||||||
char *response_data = common_receive_ws_to_tabfs();
|
char *response_data = common_receive_ws_to_tabfs();
|
||||||
if (response_data == NULL) {
|
if (response_data == NULL) {
|
||||||
// Connection is dead.
|
// Connection is dead.
|
||||||
return cJSON_Parse("{ \"error\": 5 }");
|
return cJSON_Parse("{ \"error\": 5 }");
|
||||||
}
|
}
|
||||||
|
|
||||||
cJSON *resp = cJSON_Parse((const char *) response_data);
|
cJSON *resp = cJSON_Parse((const char *) response_data);
|
||||||
free(response_data);
|
free(response_data);
|
||||||
|
|
||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAKE_REQ(op, req_body, resp_handler) \
|
#define MAKE_REQ(OP, REQ_BUILDER_BODY, RESP_HANDLER_BODY) \
|
||||||
do { \
|
do { \
|
||||||
int ret = -1; \
|
int ret = -1; \
|
||||||
cJSON *req = NULL; \
|
cJSON *req = NULL; \
|
||||||
cJSON *resp = NULL; \
|
cJSON *resp = NULL; \
|
||||||
\
|
\
|
||||||
req = cJSON_CreateObject(); \
|
req = cJSON_CreateObject(); \
|
||||||
cJSON_AddStringToObject(req, "op", op); \
|
cJSON_AddStringToObject(req, "op", OP); \
|
||||||
req_body \
|
REQ_BUILDER_BODY \
|
||||||
\
|
\
|
||||||
resp = send_request_then_await_response(req); \
|
resp = send_request_then_await_response(req); \
|
||||||
\
|
\
|
||||||
cJSON *error_item = cJSON_GetObjectItemCaseSensitive(resp, "error"); \
|
cJSON *error_item = cJSON_GetObjectItemCaseSensitive(resp, "error"); \
|
||||||
if (error_item) { \
|
if (error_item) { \
|
||||||
ret = -error_item->valueint; \
|
ret = -error_item->valueint; \
|
||||||
if (ret != 0) goto done; \
|
if (ret != 0) goto done; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
ret = -1; \
|
ret = -1; \
|
||||||
resp_handler \
|
RESP_HANDLER_BODY \
|
||||||
\
|
\
|
||||||
done: \
|
done: \
|
||||||
if (req != NULL) cJSON_Delete(req); \
|
if (req != NULL) cJSON_Delete(req); \
|
||||||
if (resp != NULL) cJSON_Delete(resp); \
|
if (resp != NULL) cJSON_Delete(resp); \
|
||||||
return ret; \
|
return ret; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define JSON_GET_PROP_INT(lvalue, key) \
|
#define JSON_GET_PROP_INT(LVALUE, KEY) \
|
||||||
do { \
|
do { \
|
||||||
lvalue = cJSON_GetObjectItemCaseSensitive(resp, key)->valueint; \
|
LVALUE = cJSON_GetObjectItemCaseSensitive(resp, KEY)->valueint; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
static int
|
static int tabfs_getattr(const char *path, struct stat *stbuf) {
|
||||||
tabfs_getattr(const char *path, struct stat *stbuf)
|
|
||||||
{
|
|
||||||
memset(stbuf, 0, sizeof(struct stat));
|
memset(stbuf, 0, sizeof(struct stat));
|
||||||
|
|
||||||
MAKE_REQ("getattr", {
|
MAKE_REQ("getattr", {
|
||||||
|
@ -75,9 +73,7 @@ tabfs_getattr(const char *path, struct stat *stbuf)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int tabfs_readlink(const char *path, char *buf, size_t size) {
|
||||||
tabfs_readlink(const char *path, char *buf, size_t size)
|
|
||||||
{
|
|
||||||
MAKE_REQ("readlink", {
|
MAKE_REQ("readlink", {
|
||||||
cJSON_AddStringToObject(req, "path", path);
|
cJSON_AddStringToObject(req, "path", path);
|
||||||
}, {
|
}, {
|
||||||
|
@ -93,9 +89,7 @@ tabfs_readlink(const char *path, char *buf, size_t size)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int tabfs_open(const char *path, struct fuse_file_info *fi) {
|
||||||
tabfs_open(const char *path, struct fuse_file_info *fi)
|
|
||||||
{
|
|
||||||
MAKE_REQ("open", {
|
MAKE_REQ("open", {
|
||||||
cJSON_AddStringToObject(req, "path", path);
|
cJSON_AddStringToObject(req, "path", path);
|
||||||
cJSON_AddNumberToObject(req, "flags", fi->flags);
|
cJSON_AddNumberToObject(req, "flags", fi->flags);
|
||||||
|
@ -109,8 +103,7 @@ tabfs_open(const char *path, struct fuse_file_info *fi)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
tabfs_read(const char *path, char *buf, size_t size, off_t offset,
|
tabfs_read(const char *path, char *buf, size_t size, off_t offset,
|
||||||
struct fuse_file_info *fi)
|
struct fuse_file_info *fi) {
|
||||||
{
|
|
||||||
MAKE_REQ("read", {
|
MAKE_REQ("read", {
|
||||||
cJSON_AddStringToObject(req, "path", path);
|
cJSON_AddStringToObject(req, "path", path);
|
||||||
cJSON_AddNumberToObject(req, "size", size);
|
cJSON_AddNumberToObject(req, "size", size);
|
||||||
|
@ -143,9 +136,7 @@ static int tabfs_release(const char *path, struct fuse_file_info *fi) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int tabfs_opendir(const char *path, struct fuse_file_info *fi) {
|
||||||
tabfs_opendir(const char *path, struct fuse_file_info *fi)
|
|
||||||
{
|
|
||||||
MAKE_REQ("opendir", {
|
MAKE_REQ("opendir", {
|
||||||
cJSON_AddStringToObject(req, "path", path);
|
cJSON_AddStringToObject(req, "path", path);
|
||||||
cJSON_AddNumberToObject(req, "flags", fi->flags);
|
cJSON_AddNumberToObject(req, "flags", fi->flags);
|
||||||
|
@ -159,9 +150,7 @@ tabfs_opendir(const char *path, struct fuse_file_info *fi)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
tabfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
|
tabfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
|
||||||
off_t offset, struct fuse_file_info *fi)
|
off_t offset, struct fuse_file_info *fi) {
|
||||||
{
|
|
||||||
// send {op: "readdir", path} to the websocket handler
|
|
||||||
MAKE_REQ("readdir", {
|
MAKE_REQ("readdir", {
|
||||||
cJSON_AddStringToObject(req, "path", path);
|
cJSON_AddStringToObject(req, "path", path);
|
||||||
}, {
|
}, {
|
||||||
|
@ -176,8 +165,7 @@ tabfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
tabfs_releasedir(const char *path, struct fuse_file_info *fi)
|
tabfs_releasedir(const char *path, struct fuse_file_info *fi) {
|
||||||
{
|
|
||||||
MAKE_REQ("releasedir", {
|
MAKE_REQ("releasedir", {
|
||||||
cJSON_AddStringToObject(req, "path", path);
|
cJSON_AddStringToObject(req, "path", path);
|
||||||
cJSON_AddNumberToObject(req, "fh", fi->fh);
|
cJSON_AddNumberToObject(req, "fh", fi->fh);
|
||||||
|
|
145
fs/ws.c
145
fs/ws.c
|
@ -13,73 +13,53 @@ static struct wby_server server;
|
||||||
static struct wby_con *con = NULL;
|
static struct wby_con *con = NULL;
|
||||||
|
|
||||||
static int fill_fd_set_with_ws_sockets(fd_set *read_fds, fd_set *write_fds, fd_set *except_fds) {
|
static int fill_fd_set_with_ws_sockets(fd_set *read_fds, fd_set *write_fds, fd_set *except_fds) {
|
||||||
// Based on web.h:1936 (start of wby_update)
|
// Based on web.h:1936 (start of wby_update)
|
||||||
|
|
||||||
int max_fd = 0;
|
int max_fd = 0;
|
||||||
FD_SET(server.socket, read_fds);
|
FD_SET(server.socket, read_fds);
|
||||||
FD_SET(server.socket, except_fds);
|
FD_SET(server.socket, except_fds);
|
||||||
max_fd = WBY_SOCK(server.socket);
|
max_fd = WBY_SOCK(server.socket);
|
||||||
|
|
||||||
if (con == NULL) { return max_fd; }
|
if (con == NULL) { return max_fd; }
|
||||||
|
|
||||||
struct wby_connection *conn = (struct wby_connection *) con;
|
struct wby_connection *conn = (struct wby_connection *) con;
|
||||||
wby_socket socket = WBY_SOCK(conn->socket);
|
wby_socket socket = WBY_SOCK(conn->socket);
|
||||||
FD_SET(socket, read_fds);
|
FD_SET(socket, read_fds);
|
||||||
FD_SET(socket, except_fds);
|
FD_SET(socket, except_fds);
|
||||||
if (conn->state == WBY_CON_STATE_SEND_CONTINUE) {
|
if (conn->state == WBY_CON_STATE_SEND_CONTINUE) {
|
||||||
FD_SET(socket, write_fds);
|
FD_SET(socket, write_fds);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (socket > max_fd) { max_fd = socket; }
|
if (socket > max_fd) { max_fd = socket; }
|
||||||
return max_fd;
|
return max_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void receive_tabfs_request_then_send_to_browser() {
|
static void receive_tabfs_request_then_send_to_browser() {
|
||||||
char *request_data = common_receive_tabfs_to_ws(fill_fd_set_with_ws_sockets);
|
char *request_data = common_receive_tabfs_to_ws(fill_fd_set_with_ws_sockets);
|
||||||
if (request_data == NULL) {
|
if (request_data == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (con == NULL) {
|
if (con == NULL) {
|
||||||
common_send_ws_to_tabfs(NULL);
|
common_send_ws_to_tabfs(NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
wby_frame_begin(con, WBY_WSOP_TEXT_FRAME);
|
wby_frame_begin(con, WBY_WSOP_TEXT_FRAME);
|
||||||
wby_write(con, request_data, strlen(request_data));
|
wby_write(con, request_data, strlen(request_data));
|
||||||
wby_frame_end(con);
|
wby_frame_end(con);
|
||||||
|
|
||||||
/* pthread_mutex_lock(&queue_mutex); */
|
// Was allocated by sender (tabfs.c, send_request_then_await_response).
|
||||||
|
free(request_data);
|
||||||
/* if (con == NULL) goto done; */
|
|
||||||
|
|
||||||
/* for (request_id id = 0; id < REQUEST_RESPONSE_QUEUE_SIZE; id++) { */
|
|
||||||
/* if (queue[id].state == SEND_REQUEST) { */
|
|
||||||
/* char *request = queue[id].request; */
|
|
||||||
|
|
||||||
/* wby_frame_begin(con, WBY_WSOP_TEXT_FRAME); */
|
|
||||||
/* wby_write(con, request, strlen(request)); */
|
|
||||||
/* wby_frame_end(con); */
|
|
||||||
|
|
||||||
/* queue[id].state = RECEIVE_RESPONSE; */
|
|
||||||
/* free(request); */
|
|
||||||
/* queue[id].request = NULL; */
|
|
||||||
/* } */
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
/* done: */
|
|
||||||
/* pthread_mutex_unlock(&queue_mutex); */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
dispatch(struct wby_con *connection, void *userdata)
|
dispatch(struct wby_con *connection, void *userdata) {
|
||||||
{
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
websocket_connect(struct wby_con *connection, void *userdata)
|
websocket_connect(struct wby_con *connection, void *userdata) {
|
||||||
{
|
|
||||||
/* connection bound userdata */
|
/* connection bound userdata */
|
||||||
connection->user_data = NULL;
|
connection->user_data = NULL;
|
||||||
if (0 == strcmp(connection->request.uri, "/"))
|
if (0 == strcmp(connection->request.uri, "/"))
|
||||||
|
@ -88,8 +68,7 @@ websocket_connect(struct wby_con *connection, void *userdata)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
websocket_connected(struct wby_con *connection, void *userdata)
|
websocket_connected(struct wby_con *connection, void *userdata) {
|
||||||
{
|
|
||||||
printf("WebSocket connected\n");
|
printf("WebSocket connected\n");
|
||||||
con = connection;
|
con = connection;
|
||||||
}
|
}
|
||||||
|
@ -99,7 +78,8 @@ websocket_connected(struct wby_con *connection, void *userdata)
|
||||||
static int
|
static int
|
||||||
websocket_frame(struct wby_con *connection, const struct wby_frame *frame, void *userdata)
|
websocket_frame(struct wby_con *connection, const struct wby_frame *frame, void *userdata)
|
||||||
{
|
{
|
||||||
unsigned char *data = calloc(1, MAX_DATA_LENGTH); // Will be freed at receiver (tabfs).
|
// Will be freed at receiver (tabfs.c, send_request_then_await_response).
|
||||||
|
unsigned char *data = calloc(1, MAX_DATA_LENGTH);
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
DEBUG("WebSocket frame incoming\n");
|
DEBUG("WebSocket frame incoming\n");
|
||||||
|
@ -131,73 +111,30 @@ websocket_frame(struct wby_con *connection, const struct wby_frame *frame, void
|
||||||
DEBUG("%c", isprint(buffer[k]) ? buffer[k] : '?');
|
DEBUG("%c", isprint(buffer[k]) ? buffer[k] : '?');
|
||||||
DEBUG("\n");
|
DEBUG("\n");
|
||||||
for (k = 0; k < read_size; ++k)
|
for (k = 0; k < read_size; ++k)
|
||||||
data[i + k] = buffer[k];
|
data[i + k] = buffer[k];
|
||||||
i += (int)read_size;
|
i += (int)read_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((int) strlen((const char *) data) != frame->payload_length) {
|
if ((int) strlen((const char *) data) != frame->payload_length) {
|
||||||
printf("Null in data! [%s]\n", data);
|
printf("Null in data! [%s]\n", data);
|
||||||
}
|
}
|
||||||
|
|
||||||
common_send_ws_to_tabfs((char *) data);
|
common_send_ws_to_tabfs((char *) data);
|
||||||
|
|
||||||
// Will be freed at the receiver end.
|
|
||||||
/* cJSON *resp = cJSON_Parse((const char *) data); */
|
|
||||||
|
|
||||||
/* cJSON *id_item = cJSON_GetObjectItemCaseSensitive(resp, "id"); */
|
|
||||||
/* if (id_item == NULL) { */
|
|
||||||
/* printf("No id in response!\n"); */
|
|
||||||
/* exit(1); */
|
|
||||||
/* } */
|
|
||||||
/* request_id id = id_item->valueint; */
|
|
||||||
|
|
||||||
/* pthread_mutex_lock(&queue_mutex); */
|
|
||||||
|
|
||||||
/* if (queue[id].state != RECEIVE_RESPONSE) { */
|
|
||||||
/* printf("Got response to request in wrong state!\n"); */
|
|
||||||
/* exit(1); */
|
|
||||||
/* } */
|
|
||||||
/* queue[id].state = HANDLE_RESPONSE; */
|
|
||||||
/* queue[id].response = resp; */
|
|
||||||
|
|
||||||
/* pthread_cond_signal(&queue_cv); */
|
|
||||||
/* pthread_mutex_unlock(&queue_mutex); */
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void websocket_closed(struct wby_con *connection, void *userdata) {
|
||||||
websocket_closed(struct wby_con *connection, void *userdata)
|
|
||||||
{
|
|
||||||
printf("WebSocket closed\n");
|
printf("WebSocket closed\n");
|
||||||
|
|
||||||
if (con == connection) con = NULL;
|
if (con == connection) con = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void test_log(const char* text) {
|
||||||
test_log(const char* text)
|
|
||||||
{
|
|
||||||
DEBUG("[debug] %s\n", text);
|
DEBUG("[debug] %s\n", text);
|
||||||
}
|
}
|
||||||
|
|
||||||
void await_io_demand_or_timeout() {
|
void *websocket_main(void *threadid) {
|
||||||
/* pthread_mutex_lock(&queue_mutex); */
|
|
||||||
|
|
||||||
/* struct timeval now; */
|
|
||||||
/* gettimeofday(&now, NULL); */
|
|
||||||
|
|
||||||
/* struct timespec tsp; */
|
|
||||||
/* tsp.tv_sec = now.tv_sec; */
|
|
||||||
/* tsp.tv_nsec = now.tv_usec * 1000; */
|
|
||||||
|
|
||||||
/* tsp.tv_nsec += 200 * 1000000; // wait for 200ms max */
|
|
||||||
/* pthread_cond_timedwait(&queue_cv, &queue_mutex, &tsp); */
|
|
||||||
|
|
||||||
/* pthread_mutex_unlock(&queue_mutex); */
|
|
||||||
}
|
|
||||||
|
|
||||||
void *websocket_main(void *threadid)
|
|
||||||
{
|
|
||||||
void *memory = NULL;
|
void *memory = NULL;
|
||||||
wby_size needed_memory = 0;
|
wby_size needed_memory = 0;
|
||||||
|
|
||||||
|
@ -222,12 +159,8 @@ void *websocket_main(void *threadid)
|
||||||
|
|
||||||
printf("Awaiting WebSocket connection from Chrome extension.\n");
|
printf("Awaiting WebSocket connection from Chrome extension.\n");
|
||||||
for (;;) {
|
for (;;) {
|
||||||
// FIXME: makes reconnect impossible. :<
|
|
||||||
/* await_io_demand_or_timeout(); */
|
|
||||||
|
|
||||||
receive_tabfs_request_then_send_to_browser();
|
receive_tabfs_request_then_send_to_browser();
|
||||||
|
wby_update(&server); // We receive stuff from the browser here.
|
||||||
wby_update(&server); // We receive stuff during this phase.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wby_stop(&server);
|
wby_stop(&server);
|
||||||
|
|
Loading…
Reference in a new issue