diff --git a/examples/read.c b/examples/read.c index e5ef18e..f7bd75d 100644 --- a/examples/read.c +++ b/examples/read.c @@ -27,7 +27,7 @@ int main(int argc, char **argv) { goto error_link_open; } - while (skipstone_link_recv(link, buf, &len, &endpoint) >= 0) { + while (skipstone_link_recv(link, buf, &len, &endpoint, NULL) >= 0) { printf("Received message %hu bytes for endpoint %hu\n", len, endpoint); } diff --git a/examples/read.c-e b/examples/read.c-e index e5ef18e..f7bd75d 100644 --- a/examples/read.c-e +++ b/examples/read.c-e @@ -27,7 +27,7 @@ int main(int argc, char **argv) { goto error_link_open; } - while (skipstone_link_recv(link, buf, &len, &endpoint) >= 0) { + while (skipstone_link_recv(link, buf, &len, &endpoint, NULL) >= 0) { printf("Received message %hu bytes for endpoint %hu\n", len, endpoint); } diff --git a/examples/test.c b/examples/test.c index 63a4418..e46ffa7 100644 --- a/examples/test.c +++ b/examples/test.c @@ -78,14 +78,24 @@ int main(int argc, char **argv) { skipstone_message_service_register(service, 17, answer_phone_version_message, NULL); skipstone_message_service_register(service, 32, answer_music_message, NULL); - skipstone_message_service_run(service, link); + while (1) { + struct timeval timeout = { + .tv_sec = 0, + .tv_usec = 50000 + }; - perror("skipstone_message_service_run()"); + if (skipstone_message_service_next_event(service, link, &timeout) < 0) { + perror("skipstone_message_service_next_event()"); + + goto error_io; + } + } skipstone_link_close(link); return 0; +error_io: error_message_service_new: skipstone_link_close(link); diff --git a/examples/test.c-e b/examples/test.c-e index 63a4418..e46ffa7 100644 --- a/examples/test.c-e +++ b/examples/test.c-e @@ -78,14 +78,24 @@ int main(int argc, char **argv) { skipstone_message_service_register(service, 17, answer_phone_version_message, NULL); skipstone_message_service_register(service, 32, answer_music_message, NULL); - skipstone_message_service_run(service, link); + while (1) { + struct timeval timeout = { + .tv_sec = 0, + .tv_usec = 50000 + }; - perror("skipstone_message_service_run()"); + if (skipstone_message_service_next_event(service, link, &timeout) < 0) { + perror("skipstone_message_service_next_event()"); + + goto error_io; + } + } skipstone_link_close(link); return 0; +error_io: error_message_service_new: skipstone_link_close(link); diff --git a/include/skipstone/link.h b/include/skipstone/link.h index 5f1c74e..8e05edd 100644 --- a/include/skipstone/link.h +++ b/include/skipstone/link.h @@ -2,6 +2,7 @@ #define _SKIPSTONE_LINK_H #include +#include typedef struct _skipstone_link skipstone_link; @@ -10,9 +11,9 @@ skipstone_link *skipstone_link_open_serial(const char *device); int skipstone_link_close(skipstone_link *link); int skipstone_link_send(skipstone_link *link, - void *buf, uint16_t size, uint16_t id); + void *buf, uint16_t size, uint16_t id); int skipstone_link_recv(skipstone_link *link, - void *buf, uint16_t *size, uint16_t *id); + void *buf, uint16_t *size, uint16_t *id, struct timeval *timeout); #endif /* _SKIPSTONE_LINK_H */ diff --git a/include/skipstone/message.h b/include/skipstone/message.h index d59fbdc..3578c2d 100644 --- a/include/skipstone/message.h +++ b/include/skipstone/message.h @@ -73,9 +73,6 @@ int skipstone_message_service_queue(skipstone_message_service *service, skipstone_message *message, uint16_t id); int skipstone_message_service_next_event(skipstone_message_service *service, - skipstone_link *link); - -int skipstone_message_service_run(skipstone_message_service *service, - skipstone_link *link); + skipstone_link *link, struct timeval *timeout); #endif /* _SKIPSTONE_MESSAGE_H */ diff --git a/src/link.c b/src/link.c index 9f3f082..294992d 100644 --- a/src/link.c +++ b/src/link.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "util.h" #include @@ -134,12 +135,27 @@ error_toobig: return -1; } -int skipstone_link_recv(skipstone_link *link, void *buf, uint16_t *size, uint16_t *id) { +int skipstone_link_recv(skipstone_link *link, + void *buf, uint16_t *size, uint16_t *id, struct timeval *timeout) { skipstone_message_header header; ssize_t len_read; size_t len_wanted, offset = 0; + fd_set fds; + int ready; + + FD_ZERO(&fds); + FD_SET(link->serial.fd, &fds); + + if ((ready = select(1 + link->serial.fd, &fds, NULL, NULL, timeout)) < 0) { + goto error_io; + } + + if (ready == 0) { + return 0; + } + if (read(link->serial.fd, &header, sizeof(header)) < 0) { goto error_io; } @@ -162,7 +178,7 @@ int skipstone_link_recv(skipstone_link *link, void *buf, uint16_t *size, uint16_ *size = be16toh(header.size); *id = be16toh(header.id); - return 0; + return 1; error_io: return -1; diff --git a/src/link.c-e b/src/link.c-e index 9f3f082..294992d 100644 --- a/src/link.c-e +++ b/src/link.c-e @@ -6,6 +6,7 @@ #include #include #include +#include #include "util.h" #include @@ -134,12 +135,27 @@ error_toobig: return -1; } -int skipstone_link_recv(skipstone_link *link, void *buf, uint16_t *size, uint16_t *id) { +int skipstone_link_recv(skipstone_link *link, + void *buf, uint16_t *size, uint16_t *id, struct timeval *timeout) { skipstone_message_header header; ssize_t len_read; size_t len_wanted, offset = 0; + fd_set fds; + int ready; + + FD_ZERO(&fds); + FD_SET(link->serial.fd, &fds); + + if ((ready = select(1 + link->serial.fd, &fds, NULL, NULL, timeout)) < 0) { + goto error_io; + } + + if (ready == 0) { + return 0; + } + if (read(link->serial.fd, &header, sizeof(header)) < 0) { goto error_io; } @@ -162,7 +178,7 @@ int skipstone_link_recv(skipstone_link *link, void *buf, uint16_t *size, uint16_ *size = be16toh(header.size); *id = be16toh(header.id); - return 0; + return 1; error_io: return -1; diff --git a/src/message.c b/src/message.c index 5f731b4..3c5b2e8 100644 --- a/src/message.c +++ b/src/message.c @@ -298,16 +298,17 @@ error_malloc_packed: } int skipstone_message_service_next_event(skipstone_message_service *service, - skipstone_link *link) { + skipstone_link *link, struct timeval *timeout) { skipstone_message_header *message; struct endpoint *endpoint; uint16_t size, id; + int ready; - if (skipstone_link_recv(link, service->buf, &size, &id) < 0) { + if ((ready = skipstone_link_recv(link, service->buf, &size, &id, timeout)) < 0) { goto error_io; } - if ((endpoint = skipstone_map_get(service->endpoints, id)) != NULL) { + if (ready && (endpoint = skipstone_map_get(service->endpoints, id)) != NULL) { if (endpoint->handler(service, service->buf, size, id, endpoint->context) < 0) { goto error_io; } @@ -324,17 +325,3 @@ int skipstone_message_service_next_event(skipstone_message_service *service, error_io: return -1; } - -int skipstone_message_service_run(skipstone_message_service *service, - skipstone_link *link) { - while (1) { - if (skipstone_message_service_next_event(service, link) < 0) { - goto error_service_next_event; - } - } - - return 0; - -error_service_next_event: - return -1; -} diff --git a/src/message.c-e b/src/message.c-e index 5f731b4..3c5b2e8 100644 --- a/src/message.c-e +++ b/src/message.c-e @@ -298,16 +298,17 @@ error_malloc_packed: } int skipstone_message_service_next_event(skipstone_message_service *service, - skipstone_link *link) { + skipstone_link *link, struct timeval *timeout) { skipstone_message_header *message; struct endpoint *endpoint; uint16_t size, id; + int ready; - if (skipstone_link_recv(link, service->buf, &size, &id) < 0) { + if ((ready = skipstone_link_recv(link, service->buf, &size, &id, timeout)) < 0) { goto error_io; } - if ((endpoint = skipstone_map_get(service->endpoints, id)) != NULL) { + if (ready && (endpoint = skipstone_map_get(service->endpoints, id)) != NULL) { if (endpoint->handler(service, service->buf, size, id, endpoint->context) < 0) { goto error_io; } @@ -324,17 +325,3 @@ int skipstone_message_service_next_event(skipstone_message_service *service, error_io: return -1; } - -int skipstone_message_service_run(skipstone_message_service *service, - skipstone_link *link) { - while (1) { - if (skipstone_message_service_next_event(service, link) < 0) { - goto error_service_next_event; - } - } - - return 0; - -error_service_next_event: - return -1; -}