more refactoring
This commit is contained in:
parent
7d576ee9af
commit
7120e736f6
7 changed files with 165 additions and 184 deletions
|
@ -12,8 +12,11 @@ static void usage(int argc, char **argv) {
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
skipstone_link *link;
|
skipstone_link *link;
|
||||||
|
|
||||||
void *buf;
|
void *buf;
|
||||||
uint16_t len, endpoint;
|
ssize_t len;
|
||||||
|
|
||||||
|
uint16_t endpoint;
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
usage(argc, argv);
|
usage(argc, argv);
|
||||||
|
@ -23,12 +26,15 @@ int main(int argc, char **argv) {
|
||||||
goto error_malloc_buf;
|
goto error_malloc_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((link = skipstone_link_open_serial(argv[1])) == NULL) {
|
if ((link = skipstone_link_open(argv[1])) == NULL) {
|
||||||
goto error_link_open;
|
goto error_link_open;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (skipstone_link_recv(link, buf, &len, &endpoint, NULL) >= 0) {
|
while ((len = skipstone_link_recv(link,
|
||||||
printf("Received message %hu bytes for endpoint %hu\n",
|
buf,
|
||||||
|
&endpoint,
|
||||||
|
SKIPSTONE_MESSAGE_MAX_PAYLOAD)) >= 0) {
|
||||||
|
printf("Received message %zd bytes for endpoint %hu\n",
|
||||||
len, endpoint);
|
len, endpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,13 +9,20 @@
|
||||||
|
|
||||||
#include "../src/util.h"
|
#include "../src/util.h"
|
||||||
|
|
||||||
|
struct context {
|
||||||
|
skipstone_link *link;
|
||||||
|
};
|
||||||
|
|
||||||
static void usage(int argc, char **argv) {
|
static void usage(int argc, char **argv) {
|
||||||
fprintf(stderr, "usage: %s /dev/rfcommX\n", argv[0]);
|
fprintf(stderr, "usage: %s /dev/rfcommX\n", argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int answer_phone_version_message(skipstone_message_service *service,
|
static int answer_phone_version_message(skipstone_message_service *service,
|
||||||
void *buf, uint16_t size, uint16_t id, void *context) {
|
void *buf,
|
||||||
|
uint16_t size,
|
||||||
|
uint16_t id,
|
||||||
|
void *context) {
|
||||||
const uint32_t flags = SKIPSTONE_SYSTEM_CLIENT_TELEPHONY
|
const uint32_t flags = SKIPSTONE_SYSTEM_CLIENT_TELEPHONY
|
||||||
| SKIPSTONE_SYSTEM_CLIENT_SMS
|
| SKIPSTONE_SYSTEM_CLIENT_SMS
|
||||||
| SKIPSTONE_SYSTEM_CLIENT_ANDROID;
|
| SKIPSTONE_SYSTEM_CLIENT_ANDROID;
|
||||||
|
@ -24,7 +31,12 @@ static int answer_phone_version_message(skipstone_message_service *service,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int answer_music_message(skipstone_message_service *service,
|
static int answer_music_message(skipstone_message_service *service,
|
||||||
void *buf, uint16_t size, uint16_t id, void *context) {
|
void *buf,
|
||||||
|
uint16_t size,
|
||||||
|
uint16_t id,
|
||||||
|
void *ctx) {
|
||||||
|
struct context *context = ctx;
|
||||||
|
|
||||||
uint8_t message[256];
|
uint8_t message[256];
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
|
|
||||||
|
@ -39,7 +51,9 @@ static int answer_music_message(skipstone_message_service *service,
|
||||||
goto error_message_pack;
|
goto error_message_pack;
|
||||||
}
|
}
|
||||||
|
|
||||||
skipstone_message_service_queue(service, message, len, 32);
|
if (skipstone_link_send(context->link, message, 32, len) < 0) {
|
||||||
|
goto error_link_send;
|
||||||
|
}
|
||||||
|
|
||||||
if ((len = skipstone_message_pack(message,
|
if ((len = skipstone_message_pack(message,
|
||||||
sizeof(message),
|
sizeof(message),
|
||||||
|
@ -54,7 +68,9 @@ static int answer_music_message(skipstone_message_service *service,
|
||||||
goto error_message_pack;
|
goto error_message_pack;
|
||||||
}
|
}
|
||||||
|
|
||||||
skipstone_message_service_queue(service, message, len, 32);
|
if (skipstone_link_send(context->link, message, 32, len) < 0) {
|
||||||
|
goto error_link_send;
|
||||||
|
}
|
||||||
|
|
||||||
if ((len = skipstone_message_pack(message,
|
if ((len = skipstone_message_pack(message,
|
||||||
sizeof(message),
|
sizeof(message),
|
||||||
|
@ -65,19 +81,25 @@ static int answer_music_message(skipstone_message_service *service,
|
||||||
goto error_message_pack;
|
goto error_message_pack;
|
||||||
}
|
}
|
||||||
|
|
||||||
skipstone_message_service_queue(service, message, len, 32);
|
if (skipstone_link_send(context->link, message, 32, len) < 0) {
|
||||||
|
goto error_link_send;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("Got playback command %02x\n", ((uint8_t *)buf)[0]);
|
printf("Got playback command %02x\n", ((uint8_t *)buf)[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
error_link_send:
|
||||||
error_message_pack:
|
error_message_pack:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int answer_phone_message(skipstone_message_service *service,
|
static int answer_phone_message(skipstone_message_service *service,
|
||||||
void *buf, uint16_t size, uint16_t id, void *context) {
|
void *buf,
|
||||||
|
uint16_t size,
|
||||||
|
uint16_t id,
|
||||||
|
void *context) {
|
||||||
printf("Got phone command %02x\n", ((uint8_t *)buf)[0]);
|
printf("Got phone command %02x\n", ((uint8_t *)buf)[0]);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -87,32 +109,31 @@ int main(int argc, char **argv) {
|
||||||
skipstone_link *link;
|
skipstone_link *link;
|
||||||
skipstone_message_service *service;
|
skipstone_message_service *service;
|
||||||
|
|
||||||
|
struct context context;
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
usage(argc, argv);
|
usage(argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((link = skipstone_link_open_serial(argv[1])) == NULL) {
|
if ((link = skipstone_link_open(argv[1])) == NULL) {
|
||||||
perror("skipstone_link_open_serial()");
|
perror("skipstone_link_open()");
|
||||||
goto error_link_open;
|
goto error_link_open;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((service = skipstone_message_service_new()) == NULL) {
|
if ((service = skipstone_message_service_new(link)) == NULL) {
|
||||||
perror("skipstone_message_service_new()");
|
perror("skipstone_message_service_new()");
|
||||||
goto error_message_service_new;
|
goto error_message_service_new;
|
||||||
}
|
}
|
||||||
|
|
||||||
skipstone_message_service_register(service, 17, answer_phone_version_message, NULL);
|
context.link = link;
|
||||||
skipstone_message_service_register(service, 32, answer_music_message, NULL);
|
|
||||||
skipstone_message_service_register(service, 33, answer_phone_message, NULL);
|
skipstone_message_service_register(service, 17, answer_phone_version_message, &context);
|
||||||
|
skipstone_message_service_register(service, 32, answer_music_message, &context);
|
||||||
|
skipstone_message_service_register(service, 33, answer_phone_message, &context);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
struct timeval timeout = {
|
if (skipstone_message_service_event_handle(service) < 0) {
|
||||||
.tv_sec = 0,
|
perror("skipstone_message_service_event_handle()");
|
||||||
.tv_usec = 50000
|
|
||||||
};
|
|
||||||
|
|
||||||
if (skipstone_message_service_next_event(service, link, &timeout) < 0) {
|
|
||||||
perror("skipstone_message_service_next_event()");
|
|
||||||
|
|
||||||
goto error_io;
|
goto error_io;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,14 +6,20 @@
|
||||||
|
|
||||||
typedef struct _skipstone_link skipstone_link;
|
typedef struct _skipstone_link skipstone_link;
|
||||||
|
|
||||||
skipstone_link *skipstone_link_open_serial(const char *device);
|
skipstone_link *skipstone_link_open(const char *device);
|
||||||
|
|
||||||
int skipstone_link_close(skipstone_link *link);
|
int skipstone_link_close(skipstone_link *link);
|
||||||
|
|
||||||
int skipstone_link_send(skipstone_link *link,
|
int skipstone_link_fd(skipstone_link *link);
|
||||||
void *buf, uint16_t size, uint16_t id);
|
|
||||||
|
|
||||||
int skipstone_link_recv(skipstone_link *link,
|
ssize_t skipstone_link_send(skipstone_link *link,
|
||||||
void *buf, uint16_t *size, uint16_t *id, struct timeval *timeout);
|
void *buf,
|
||||||
|
uint16_t id,
|
||||||
|
size_t size);
|
||||||
|
|
||||||
|
ssize_t skipstone_link_recv(skipstone_link *link,
|
||||||
|
void *buf,
|
||||||
|
uint16_t *id,
|
||||||
|
size_t size);
|
||||||
|
|
||||||
#endif /* _SKIPSTONE_LINK_H */
|
#endif /* _SKIPSTONE_LINK_H */
|
||||||
|
|
|
@ -37,10 +37,12 @@ ssize_t skipstone_message_pack(void *message,
|
||||||
size_t len,
|
size_t len,
|
||||||
const char *template, ...);
|
const char *template, ...);
|
||||||
|
|
||||||
skipstone_message_service *skipstone_message_service_new();
|
skipstone_message_service *skipstone_message_service_new(skipstone_link *link);
|
||||||
|
|
||||||
void skipstone_message_service_destroy(skipstone_message_service *service);
|
void skipstone_message_service_destroy(skipstone_message_service *service);
|
||||||
|
|
||||||
|
skipstone_link *skipstone_message_service_link(skipstone_message_service *service);
|
||||||
|
|
||||||
int skipstone_message_service_register(skipstone_message_service *service,
|
int skipstone_message_service_register(skipstone_message_service *service,
|
||||||
uint16_t id,
|
uint16_t id,
|
||||||
skipstone_message_handler *handler,
|
skipstone_message_handler *handler,
|
||||||
|
@ -49,12 +51,6 @@ int skipstone_message_service_register(skipstone_message_service *service,
|
||||||
int skipstone_message_service_deregister(skipstone_message_service *service,
|
int skipstone_message_service_deregister(skipstone_message_service *service,
|
||||||
uint16_t id);
|
uint16_t id);
|
||||||
|
|
||||||
int skipstone_message_service_queue(skipstone_message_service *service,
|
int skipstone_message_service_event_handle(skipstone_message_service *service);
|
||||||
void *buf,
|
|
||||||
uint16_t size,
|
|
||||||
uint16_t id);
|
|
||||||
|
|
||||||
int skipstone_message_service_next_event(skipstone_message_service *service,
|
|
||||||
skipstone_link *link, struct timeval *timeout);
|
|
||||||
|
|
||||||
#endif /* _SKIPSTONE_MESSAGE_H */
|
#endif /* _SKIPSTONE_MESSAGE_H */
|
||||||
|
|
140
src/link.c
140
src/link.c
|
@ -7,68 +7,50 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
|
#include <errno.h>
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#include <skipstone/link.h>
|
#include <skipstone/link.h>
|
||||||
#include <skipstone/message.h>
|
#include <skipstone/message.h>
|
||||||
|
|
||||||
enum skipstone_link_type {
|
|
||||||
SKIPSTONE_WATCH_LINK_SERIAL = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _skipstone_link {
|
struct _skipstone_link {
|
||||||
enum skipstone_link_type type;
|
int fd;
|
||||||
|
struct termios attrs;
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
struct termios attr_old,
|
|
||||||
attr_new;
|
|
||||||
} serial;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
skipstone_link *skipstone_link_open_serial(const char *device) {
|
skipstone_link *skipstone_link_open(const char *device) {
|
||||||
skipstone_link *link;
|
skipstone_link *link;
|
||||||
|
struct termios t;
|
||||||
|
|
||||||
if ((link = malloc(sizeof(*link))) == NULL) {
|
if ((link = malloc(sizeof(*link))) == NULL) {
|
||||||
goto error_malloc_link;
|
goto error_malloc_link;
|
||||||
}
|
}
|
||||||
|
|
||||||
link->type = SKIPSTONE_WATCH_LINK_SERIAL;
|
if ((link->fd = open(device, O_RDWR | O_NOCTTY)) < 0) {
|
||||||
|
|
||||||
if ((link->serial.fd = open(device, O_RDWR | O_NOCTTY)) < 0) {
|
|
||||||
goto error_open;
|
goto error_open;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tcgetattr(link->serial.fd, &link->serial.attr_old) < 0) {
|
if (tcgetattr(link->fd, &link->attrs) < 0) {
|
||||||
goto error_io;
|
goto error_io;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&link->serial.attr_new, 0, sizeof(struct termios));
|
memcpy(&t, &link->attrs, sizeof(t));
|
||||||
|
|
||||||
link->serial.attr_new.c_cflag = CS8 | HUPCL;
|
cfmakeraw(&t);
|
||||||
link->serial.attr_new.c_ispeed = B115200;
|
cfsetspeed(&t, B115200);
|
||||||
link->serial.attr_new.c_ospeed = B115200;
|
|
||||||
link->serial.attr_new.c_iflag = IGNPAR;
|
|
||||||
link->serial.attr_new.c_oflag = 0;
|
|
||||||
link->serial.attr_new.c_lflag = 0;
|
|
||||||
link->serial.attr_new.c_cc[VTIME] = 0;
|
|
||||||
link->serial.attr_new.c_cc[VMIN] = 1;
|
|
||||||
|
|
||||||
if (tcsetattr(link->serial.fd, TCSANOW, &link->serial.attr_new) < 0) {
|
if (tcsetattr(link->fd, TCSANOW, &t) < 0) {
|
||||||
goto error_io;
|
goto error_io;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fcntl(link->serial.fd, F_SETFL, 0) < 0) {
|
if (fcntl(link->fd, F_SETFL, 0) < 0) {
|
||||||
goto error_io;
|
goto error_io;
|
||||||
}
|
}
|
||||||
|
|
||||||
return link;
|
return link;
|
||||||
|
|
||||||
error_io:
|
error_io:
|
||||||
close(link->serial.fd);
|
close(link->fd);
|
||||||
|
|
||||||
error_open:
|
error_open:
|
||||||
free(link);
|
free(link);
|
||||||
|
@ -77,108 +59,70 @@ error_malloc_link:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _watch_link_close_serial(skipstone_link *link) {
|
|
||||||
if (tcsetattr(link->serial.fd, TCSANOW, &link->serial.attr_old) < 0) {
|
|
||||||
goto error_io;
|
|
||||||
}
|
|
||||||
|
|
||||||
return close(link->serial.fd);
|
|
||||||
|
|
||||||
error_io:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int skipstone_link_close(skipstone_link *link) {
|
int skipstone_link_close(skipstone_link *link) {
|
||||||
switch (link->type) {
|
if (tcsetattr(link->fd, TCSANOW, &link->attrs) < 0) {
|
||||||
case SKIPSTONE_WATCH_LINK_SERIAL: {
|
goto error_tcsetattr;
|
||||||
return _watch_link_close_serial(link);
|
|
||||||
}
|
|
||||||
|
|
||||||
default: break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return close(link->fd);
|
||||||
|
|
||||||
|
error_tcsetattr:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int skipstone_link_send(skipstone_link *link, void *buf, uint16_t size, uint16_t id) {
|
int skipstone_link_fd(skipstone_link *link) {
|
||||||
|
return link->fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t skipstone_link_send(skipstone_link *link,
|
||||||
|
void *buf,
|
||||||
|
uint16_t id,
|
||||||
|
size_t size) {
|
||||||
skipstone_message_header header;
|
skipstone_message_header header;
|
||||||
|
|
||||||
ssize_t wrlen;
|
ssize_t len;
|
||||||
|
|
||||||
size_t remaining = (size_t)size,
|
|
||||||
offset = 0;
|
|
||||||
|
|
||||||
if (size > SKIPSTONE_MESSAGE_MAX_PAYLOAD) {
|
if (size > SKIPSTONE_MESSAGE_MAX_PAYLOAD) {
|
||||||
|
errno = EOVERFLOW;
|
||||||
|
|
||||||
goto error_toobig;
|
goto error_toobig;
|
||||||
}
|
}
|
||||||
|
|
||||||
header.size = htobe16(size);
|
header.size = htobe16(size);
|
||||||
header.id = htobe16(id);
|
header.id = htobe16(id);
|
||||||
|
|
||||||
if ((wrlen = write(link->serial.fd, &header, sizeof(header))) < 0) {
|
if ((len = write(link->fd, &header, sizeof(header))) < 0) {
|
||||||
goto error_io;
|
goto error_io;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (remaining) {
|
return write(link->fd, buf, size);
|
||||||
if ((wrlen = write(link->serial.fd, (uint8_t *)buf + offset, remaining)) < 0) {
|
|
||||||
goto error_io;
|
|
||||||
}
|
|
||||||
|
|
||||||
remaining -= (size_t)wrlen;
|
|
||||||
offset += (size_t)wrlen;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
error_io:
|
error_io:
|
||||||
error_toobig:
|
error_toobig:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int skipstone_link_recv(skipstone_link *link,
|
ssize_t skipstone_link_recv(skipstone_link *link,
|
||||||
void *buf, uint16_t *size, uint16_t *id, struct timeval *timeout) {
|
void *buf,
|
||||||
|
uint16_t *id,
|
||||||
|
size_t size) {
|
||||||
skipstone_message_header header;
|
skipstone_message_header header;
|
||||||
|
|
||||||
ssize_t len_read;
|
size_t len;
|
||||||
size_t len_wanted, offset = 0;
|
|
||||||
|
|
||||||
fd_set fds;
|
if (read(link->fd, &header, sizeof(header)) < 0) {
|
||||||
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;
|
goto error_io;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ready == 0) {
|
len = be16toh(header.size);
|
||||||
return 0;
|
|
||||||
}
|
if (len > size) {
|
||||||
|
errno = EOVERFLOW;
|
||||||
|
|
||||||
if (read(link->serial.fd, &header, sizeof(header)) < 0) {
|
|
||||||
goto error_io;
|
goto error_io;
|
||||||
}
|
}
|
||||||
|
|
||||||
len_wanted = (size_t)be16toh(header.size);
|
return read(link->fd, buf, len);
|
||||||
|
|
||||||
if (len_wanted > SKIPSTONE_MESSAGE_MAX_PAYLOAD) {
|
|
||||||
goto error_io;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (len_wanted) {
|
|
||||||
if ((len_read = read(link->serial.fd, (uint8_t *)buf + offset, len_wanted)) < 0) {
|
|
||||||
goto error_io;
|
|
||||||
}
|
|
||||||
|
|
||||||
len_wanted -= len_read;
|
|
||||||
offset += len_read;
|
|
||||||
}
|
|
||||||
|
|
||||||
*size = be16toh(header.size);
|
|
||||||
*id = be16toh(header.id);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
error_io:
|
error_io:
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -16,8 +16,11 @@ struct endpoint {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _skipstone_message_service {
|
struct _skipstone_message_service {
|
||||||
|
skipstone_link *link;
|
||||||
skipstone_map *endpoints;
|
skipstone_map *endpoints;
|
||||||
skipstone_queue *pending;
|
skipstone_queue *pending;
|
||||||
|
|
||||||
|
size_t bufsz;
|
||||||
void *buf;
|
void *buf;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -97,7 +100,7 @@ error_invalid_template:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
skipstone_message_service *skipstone_message_service_new() {
|
skipstone_message_service *skipstone_message_service_new(skipstone_link *link) {
|
||||||
skipstone_message_service *service;
|
skipstone_message_service *service;
|
||||||
|
|
||||||
if ((service = malloc(sizeof(*service))) == NULL) {
|
if ((service = malloc(sizeof(*service))) == NULL) {
|
||||||
|
@ -116,6 +119,9 @@ skipstone_message_service *skipstone_message_service_new() {
|
||||||
goto error_queue_new_pending;
|
goto error_queue_new_pending;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
service->link = link;
|
||||||
|
service->bufsz = SKIPSTONE_MESSAGE_MAX_PAYLOAD;
|
||||||
|
|
||||||
return service;
|
return service;
|
||||||
|
|
||||||
error_queue_new_pending:
|
error_queue_new_pending:
|
||||||
|
@ -143,6 +149,10 @@ void skipstone_message_service_destroy(skipstone_message_service *service) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
skipstone_link *skipstone_message_service_link(skipstone_message_service *service) {
|
||||||
|
return service->link;
|
||||||
|
}
|
||||||
|
|
||||||
int skipstone_message_service_register(skipstone_message_service *service,
|
int skipstone_message_service_register(skipstone_message_service *service,
|
||||||
uint16_t id, skipstone_message_handler *handler, void *context) {
|
uint16_t id, skipstone_message_handler *handler, void *context) {
|
||||||
struct endpoint *endpoint;
|
struct endpoint *endpoint;
|
||||||
|
@ -166,58 +176,54 @@ int skipstone_message_service_deregister(skipstone_message_service *service,
|
||||||
return skipstone_map_set((skipstone_map *)service, id, NULL);
|
return skipstone_map_set((skipstone_map *)service, id, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int skipstone_message_service_queue(skipstone_message_service *service,
|
int skipstone_message_service_event_handle(skipstone_message_service *service) {
|
||||||
void *buf,
|
|
||||||
uint16_t size,
|
|
||||||
uint16_t id) {
|
|
||||||
skipstone_message_header *message;
|
|
||||||
|
|
||||||
if ((message = malloc(sizeof(*message) + size)) == NULL) {
|
|
||||||
goto error_malloc_message;
|
|
||||||
}
|
|
||||||
|
|
||||||
message->size = size;
|
|
||||||
message->id = id;
|
|
||||||
|
|
||||||
memcpy(message + 1, buf, size);
|
|
||||||
|
|
||||||
if (skipstone_queue_add(service->pending, message) < 0) {
|
|
||||||
goto error_queue_add_pending;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
error_queue_add_pending:
|
|
||||||
free(message);
|
|
||||||
|
|
||||||
error_malloc_message:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int skipstone_message_service_next_event(skipstone_message_service *service,
|
|
||||||
skipstone_link *link,
|
|
||||||
struct timeval *timeout) {
|
|
||||||
skipstone_message_header *message;
|
|
||||||
struct endpoint *endpoint;
|
struct endpoint *endpoint;
|
||||||
uint16_t size, id;
|
|
||||||
int ready;
|
|
||||||
|
|
||||||
if ((ready = skipstone_link_recv(link, service->buf, &size, &id, timeout)) < 0) {
|
fd_set fds;
|
||||||
|
|
||||||
|
struct timeval timeout = {
|
||||||
|
.tv_sec = 0,
|
||||||
|
.tv_usec = 50000
|
||||||
|
};
|
||||||
|
|
||||||
|
int fd = skipstone_link_fd(service->link),
|
||||||
|
ready;
|
||||||
|
|
||||||
|
ssize_t len;
|
||||||
|
uint16_t id;
|
||||||
|
|
||||||
|
memset(&fds, '\0', sizeof(fds));
|
||||||
|
|
||||||
|
FD_SET(fd, &fds);
|
||||||
|
|
||||||
|
if ((ready = select(fd + 1,
|
||||||
|
&fds,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&timeout)) < 0) {
|
||||||
|
goto error_io;
|
||||||
|
} else if (ready == 0 || !FD_ISSET(fd, &fds)) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((len = skipstone_link_recv(service->link,
|
||||||
|
service->buf,
|
||||||
|
&id,
|
||||||
|
service->bufsz)) < 0) {
|
||||||
goto error_io;
|
goto error_io;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ready && (endpoint = skipstone_map_get(service->endpoints, id)) != NULL) {
|
if ((endpoint = skipstone_map_get(service->endpoints, id)) != NULL) {
|
||||||
if (endpoint->handler(service, service->buf, size, id, endpoint->context) < 0) {
|
if (endpoint->handler(service,
|
||||||
goto error_io;
|
service->buf,
|
||||||
}
|
len,
|
||||||
}
|
id,
|
||||||
|
endpoint->context) < 0) {
|
||||||
while (skipstone_queue_remove(service->pending, (void **)&message)) {
|
|
||||||
if (skipstone_link_send(link, message + 1, message->size, message->id) < 0) {
|
|
||||||
goto error_io;
|
goto error_io;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error_io:
|
error_io:
|
||||||
|
|
14
src/system.c
14
src/system.c
|
@ -7,6 +7,8 @@
|
||||||
|
|
||||||
int skipstone_system_send_client_version(skipstone_message_service *service,
|
int skipstone_system_send_client_version(skipstone_message_service *service,
|
||||||
uint32_t flags) {
|
uint32_t flags) {
|
||||||
|
skipstone_link *link = skipstone_message_service_link(service);
|
||||||
|
|
||||||
uint8_t message[25];
|
uint8_t message[25];
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
|
|
||||||
|
@ -25,16 +27,16 @@ int skipstone_system_send_client_version(skipstone_message_service *service,
|
||||||
goto error_message_pack;
|
goto error_message_pack;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (skipstone_message_service_queue(service,
|
if (skipstone_link_send(link,
|
||||||
message,
|
message,
|
||||||
(uint16_t)len,
|
SKIPSTONE_SYSTEM_ENDPOINT_PHONE_VERSION,
|
||||||
SKIPSTONE_SYSTEM_ENDPOINT_PHONE_VERSION) < 0) {
|
len) < 0) {
|
||||||
goto error_message_service_queue;
|
goto error_link_send;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error_message_service_queue:
|
error_link_send:
|
||||||
error_message_pack:
|
error_message_pack:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue