The fuck I do?
This commit is contained in:
parent
3133af8974
commit
6098ef5922
11 changed files with 0 additions and 993 deletions
|
@ -1,25 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <skipstone/map.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
skipstone_map *map;
|
||||
|
||||
if ((map = skipstone_map_new()) == NULL) {
|
||||
perror("skipstone_map_new()");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
skipstone_map_set(map, 0xdead, (void *)0xdeadbeef);
|
||||
skipstone_map_set(map, 0xbeef, (void *)0xcafebabe);
|
||||
|
||||
printf("%p\n", skipstone_map_get(map, 0xdead));
|
||||
printf("%p\n", skipstone_map_get(map, 0xbeef));
|
||||
|
||||
skipstone_map_destroy(map, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <skipstone/queue.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
skipstone_queue *queue;
|
||||
char *message;
|
||||
|
||||
if ((queue = skipstone_queue_new()) == NULL) {
|
||||
perror("skipstone_queue_new()");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
skipstone_queue_add(queue, "poop");
|
||||
skipstone_queue_remove(queue, (void **)&message);
|
||||
|
||||
printf("%s\n", message);
|
||||
|
||||
skipstone_queue_destroy(queue);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <skipstone/link.h>
|
||||
#include <skipstone/message.h>
|
||||
|
||||
static void usage(int argc, char **argv) {
|
||||
fprintf(stderr, "usage: %s /dev/rfcommX\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
skipstone_link *link;
|
||||
void *buf;
|
||||
uint16_t len, endpoint;
|
||||
|
||||
if (argc != 2) {
|
||||
usage(argc, argv);
|
||||
}
|
||||
|
||||
if ((buf = malloc(SKIPSTONE_MESSAGE_MAX_PAYLOAD)) == NULL) {
|
||||
goto error_malloc_buf;
|
||||
}
|
||||
|
||||
if ((link = skipstone_link_open_serial(argv[1])) == NULL) {
|
||||
goto error_link_open;
|
||||
}
|
||||
|
||||
while (skipstone_link_recv(link, buf, &len, &endpoint, NULL) >= 0) {
|
||||
printf("Received message %hu bytes for endpoint %hu\n",
|
||||
len, endpoint);
|
||||
}
|
||||
|
||||
perror("skipstone_link_recv()");
|
||||
|
||||
skipstone_link_close(link);
|
||||
|
||||
return 0;
|
||||
|
||||
error_link_open:
|
||||
free(buf);
|
||||
|
||||
error_malloc_buf:
|
||||
return 1;
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <skipstone/link.h>
|
||||
#include <skipstone/message.h>
|
||||
#include <skipstone/system.h>
|
||||
|
||||
#include "../src/util.h"
|
||||
|
||||
static void usage(int argc, char **argv) {
|
||||
fprintf(stderr, "usage: %s /dev/rfcommX\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int answer_phone_version_message(skipstone_message_service *service,
|
||||
void *buf, uint16_t size, uint16_t id, void *context) {
|
||||
const uint32_t flags = SKIPSTONE_SYSTEM_CLIENT_TELEPHONY
|
||||
| SKIPSTONE_SYSTEM_CLIENT_SMS
|
||||
| SKIPSTONE_SYSTEM_CLIENT_ANDROID;
|
||||
|
||||
return skipstone_system_send_client_version(service, flags);
|
||||
}
|
||||
|
||||
static int answer_music_message(skipstone_message_service *service,
|
||||
void *buf, uint16_t size, uint16_t id, void *context) {
|
||||
skipstone_message *message;
|
||||
|
||||
if (((uint8_t *)buf)[0] == 0x08) {
|
||||
message = skipstone_message_new();
|
||||
skipstone_message_append_uint8(message, 0x10);
|
||||
skipstone_message_append_string(message, "KMFDM", 5);
|
||||
skipstone_message_append_string(message, "Nihil", 5);
|
||||
skipstone_message_append_string(message, "Ultra", 5);
|
||||
skipstone_message_append_uint32(message, htole32(274));
|
||||
skipstone_message_append_uint16(message, htole16(10));
|
||||
skipstone_message_append_uint16(message, htole16(1));
|
||||
skipstone_message_service_queue(service, message, 32);
|
||||
skipstone_message_destroy(message);
|
||||
|
||||
message = skipstone_message_new();
|
||||
skipstone_message_append_uint8(message, 0x11);
|
||||
skipstone_message_append_uint8(message, 1);
|
||||
skipstone_message_append_uint32(message, htole32(120));
|
||||
skipstone_message_append_uint32(message, htole32(320));
|
||||
skipstone_message_append_uint8(message, 1);
|
||||
skipstone_message_append_uint8(message, 1);
|
||||
skipstone_message_service_queue(service, message, 32);
|
||||
skipstone_message_destroy(message);
|
||||
|
||||
message = skipstone_message_new();
|
||||
skipstone_message_append_uint8(message, 0x13);
|
||||
skipstone_message_append_string(message, "DeaDBeeF", 8);
|
||||
skipstone_message_append_string(message, "DeaDBeeF", 8);
|
||||
skipstone_message_service_queue(service, message, 32);
|
||||
skipstone_message_destroy(message);
|
||||
} else {
|
||||
printf("Got playback command %02x\n", ((uint8_t *)buf)[0]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int answer_phone_message(skipstone_message_service *service,
|
||||
void *buf, uint16_t size, uint16_t id, void *context) {
|
||||
printf("Got phone command %02x\n", ((uint8_t *)buf)[0]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
skipstone_link *link;
|
||||
skipstone_message_service *service;
|
||||
|
||||
if (argc != 2) {
|
||||
usage(argc, argv);
|
||||
}
|
||||
|
||||
if ((link = skipstone_link_open_serial(argv[1])) == NULL) {
|
||||
perror("skipstone_link_open_serial()");
|
||||
goto error_link_open;
|
||||
}
|
||||
|
||||
if ((service = skipstone_message_service_new()) == NULL) {
|
||||
perror("skipstone_message_service_new()");
|
||||
goto error_message_service_new;
|
||||
}
|
||||
|
||||
skipstone_message_service_register(service, 17, answer_phone_version_message, NULL);
|
||||
skipstone_message_service_register(service, 32, answer_music_message, NULL);
|
||||
skipstone_message_service_register(service, 33, answer_phone_message, NULL);
|
||||
|
||||
while (1) {
|
||||
struct timeval timeout = {
|
||||
.tv_sec = 0,
|
||||
.tv_usec = 50000
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
error_link_open:
|
||||
return 1;
|
||||
}
|
185
src/link.c-e
185
src/link.c-e
|
@ -1,185 +0,0 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/select.h>
|
||||
#include "util.h"
|
||||
|
||||
#include <skipstone/link.h>
|
||||
#include <skipstone/message.h>
|
||||
|
||||
enum skipstone_link_type {
|
||||
SKIPSTONE_WATCH_LINK_SERIAL = 1
|
||||
};
|
||||
|
||||
struct _skipstone_link {
|
||||
enum skipstone_link_type type;
|
||||
|
||||
union {
|
||||
struct {
|
||||
int fd;
|
||||
|
||||
struct termios attr_old,
|
||||
attr_new;
|
||||
} serial;
|
||||
};
|
||||
};
|
||||
|
||||
skipstone_link *skipstone_link_open_serial(const char *device) {
|
||||
skipstone_link *link;
|
||||
|
||||
if ((link = malloc(sizeof(*link))) == NULL) {
|
||||
goto error_malloc_link;
|
||||
}
|
||||
|
||||
link->type = SKIPSTONE_WATCH_LINK_SERIAL;
|
||||
|
||||
if ((link->serial.fd = open(device, O_RDWR | O_NOCTTY)) < 0) {
|
||||
goto error_open;
|
||||
}
|
||||
|
||||
if (tcgetattr(link->serial.fd, &link->serial.attr_old) < 0) {
|
||||
goto error_io;
|
||||
}
|
||||
|
||||
memset(&link->serial.attr_new, 0, sizeof(struct termios));
|
||||
|
||||
link->serial.attr_new.c_cflag = CS8 | HUPCL;
|
||||
link->serial.attr_new.c_ispeed = 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) {
|
||||
goto error_io;
|
||||
}
|
||||
|
||||
if (fcntl(link->serial.fd, F_SETFL, 0) < 0) {
|
||||
goto error_io;
|
||||
}
|
||||
|
||||
return link;
|
||||
|
||||
error_io:
|
||||
close(link->serial.fd);
|
||||
|
||||
error_open:
|
||||
free(link);
|
||||
|
||||
error_malloc_link:
|
||||
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) {
|
||||
switch (link->type) {
|
||||
case SKIPSTONE_WATCH_LINK_SERIAL: {
|
||||
return _watch_link_close_serial(link);
|
||||
}
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int skipstone_link_send(skipstone_link *link, void *buf, uint16_t size, uint16_t id) {
|
||||
skipstone_message_header header;
|
||||
|
||||
ssize_t wrlen;
|
||||
|
||||
size_t remaining = (size_t)size,
|
||||
offset = 0;
|
||||
|
||||
if (size > SKIPSTONE_MESSAGE_MAX_PAYLOAD) {
|
||||
goto error_toobig;
|
||||
}
|
||||
|
||||
header.size = htobe16(size);
|
||||
header.id = htobe16(id);
|
||||
|
||||
if ((wrlen = write(link->serial.fd, &header, sizeof(header))) < 0) {
|
||||
goto error_io;
|
||||
}
|
||||
|
||||
while (remaining) {
|
||||
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_toobig:
|
||||
return -1;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
len_wanted = (size_t)be16toh(header.size);
|
||||
|
||||
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:
|
||||
return -1;
|
||||
}
|
81
src/map.c-e
81
src/map.c-e
|
@ -1,81 +0,0 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <skipstone/map.h>
|
||||
|
||||
skipstone_map *skipstone_map_new() {
|
||||
skipstone_map *map;
|
||||
|
||||
if ((map = malloc(SKIPSTONE_MAP_SLOTS * sizeof(*map))) == NULL) {
|
||||
goto error_malloc_map;
|
||||
}
|
||||
|
||||
memset(map, 0, SKIPSTONE_MAP_SLOTS * sizeof(*map));
|
||||
|
||||
return map;
|
||||
|
||||
error_malloc_map:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void _destroy(skipstone_map *map, void (*destructor)(void *), int depth) {
|
||||
uint16_t i;
|
||||
|
||||
for (i=0; i<SKIPSTONE_MAP_SLOTS; i++) {
|
||||
if (map[i].next) {
|
||||
if (depth < SKIPSTONE_MAP_DEPTH) {
|
||||
_destroy(map[i].next, destructor, depth + 1);
|
||||
} else if (destructor) {
|
||||
destructor(map[i].value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(map);
|
||||
}
|
||||
|
||||
void skipstone_map_destroy(skipstone_map *map, void (*destructor)(void *)) {
|
||||
_destroy(map, destructor, 0);
|
||||
}
|
||||
|
||||
void *skipstone_map_get(skipstone_map *map, uint16_t index) {
|
||||
uint16_t i;
|
||||
|
||||
for (i=0; i<SKIPSTONE_MAP_DEPTH; i++) {
|
||||
map = map[index & 0xf].next;
|
||||
|
||||
if (map == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
index >>= 4;
|
||||
}
|
||||
|
||||
return map[index & 0x0f].value;
|
||||
}
|
||||
|
||||
int skipstone_map_set(skipstone_map *map, uint16_t index, void *value) {
|
||||
uint16_t i;
|
||||
|
||||
for (i=0; i<SKIPSTONE_MAP_DEPTH; i++) {
|
||||
skipstone_map *next = map[index & 0xf].next;
|
||||
|
||||
if (next == NULL) {
|
||||
if ((next = skipstone_map_new()) == NULL) {
|
||||
goto error_new;
|
||||
}
|
||||
}
|
||||
|
||||
map[index & 0xf].next = next;
|
||||
map = next;
|
||||
|
||||
index >>= 4;
|
||||
}
|
||||
|
||||
map[index & 0x0f].value = value;
|
||||
|
||||
return 0;
|
||||
|
||||
error_new:
|
||||
return -1;
|
||||
}
|
337
src/message.c-e
337
src/message.c-e
|
@ -1,337 +0,0 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <skipstone/link.h>
|
||||
#include <skipstone/map.h>
|
||||
#include <skipstone/queue.h>
|
||||
#include <skipstone/message.h>
|
||||
|
||||
struct part {
|
||||
uint8_t size;
|
||||
};
|
||||
|
||||
struct _skipstone_message {
|
||||
skipstone_queue *parts;
|
||||
uint16_t size;
|
||||
};
|
||||
|
||||
struct endpoint {
|
||||
skipstone_message_handler *handler;
|
||||
void *context;
|
||||
uint16_t id;
|
||||
};
|
||||
|
||||
struct _skipstone_message_service {
|
||||
skipstone_map *endpoints;
|
||||
skipstone_queue *pending;
|
||||
void *buf;
|
||||
};
|
||||
|
||||
skipstone_message *skipstone_message_new() {
|
||||
skipstone_message *message;
|
||||
|
||||
if ((message = malloc(sizeof(*message))) == NULL) {
|
||||
goto error_malloc_message;
|
||||
}
|
||||
|
||||
if ((message->parts = skipstone_queue_new()) == NULL) {
|
||||
goto error_queue_new_parts;
|
||||
}
|
||||
|
||||
message->size = 0;
|
||||
|
||||
return message;
|
||||
|
||||
error_queue_new_parts:
|
||||
free(message);
|
||||
|
||||
error_malloc_message:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void skipstone_message_destroy(skipstone_message *message) {
|
||||
void *part;
|
||||
|
||||
while (skipstone_queue_remove(message->parts, &part)) {
|
||||
free(part);
|
||||
}
|
||||
|
||||
skipstone_queue_destroy(message->parts);
|
||||
|
||||
free(message);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int append_part(skipstone_message *message, void *buf, uint8_t size) {
|
||||
struct part *part;
|
||||
|
||||
if ((part = malloc(sizeof(*part) + size)) == NULL) {
|
||||
goto error_malloc_part;
|
||||
}
|
||||
|
||||
part->size = size;
|
||||
|
||||
memcpy(part + 1, buf, size);
|
||||
|
||||
if (skipstone_queue_add(message->parts, part) < 0) {
|
||||
goto error_queue_add_parts;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error_queue_add_parts:
|
||||
free(part);
|
||||
|
||||
error_malloc_part:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int skipstone_message_append_string(skipstone_message *message,
|
||||
char *string, uint8_t size) {
|
||||
struct part *part;
|
||||
uint8_t bodysz = sizeof(size) + size;
|
||||
|
||||
if ((part = malloc(sizeof(*part) + bodysz)) == NULL) {
|
||||
goto error_malloc_part;
|
||||
}
|
||||
|
||||
part->size = bodysz;
|
||||
|
||||
memcpy(part + 1, &size, sizeof(size));
|
||||
memcpy(((uint8_t *)(part + 1)) + sizeof(size), string, size);
|
||||
|
||||
if (skipstone_queue_add(message->parts, part) < 0) {
|
||||
goto error_queue_add_part;
|
||||
}
|
||||
|
||||
message->size += bodysz;
|
||||
|
||||
return 0;
|
||||
|
||||
error_queue_add_part:
|
||||
free(part);
|
||||
|
||||
error_malloc_part:
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint16_t skipstone_message_size(skipstone_message *message) {
|
||||
return message->size;
|
||||
}
|
||||
|
||||
int skipstone_message_append_uint8(skipstone_message *message, uint8_t value) {
|
||||
if (append_part(message, &value, sizeof(value)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
message->size += sizeof(value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int skipstone_message_append_uint16(skipstone_message *message, uint16_t value) {
|
||||
if (append_part(message, &value, sizeof(value)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
message->size += sizeof(value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int skipstone_message_append_uint32(skipstone_message *message, uint32_t value) {
|
||||
if (append_part(message, &value, sizeof(value)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
message->size += sizeof(value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int skipstone_message_append_uint64(skipstone_message *message, uint64_t value) {
|
||||
if (append_part(message, &value, sizeof(value)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
message->size += sizeof(value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int skipstone_message_pack(skipstone_message *message, void *buf) {
|
||||
size_t offset = 0;
|
||||
|
||||
struct part *part;
|
||||
|
||||
if (message->size > SKIPSTONE_MESSAGE_MAX_PAYLOAD) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (skipstone_queue_remove(message->parts, (void **)&part)) {
|
||||
memcpy(((uint8_t *)buf) + offset, part + 1, part->size);
|
||||
|
||||
offset += part->size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
skipstone_message_service *skipstone_message_service_new() {
|
||||
skipstone_message_service *service;
|
||||
|
||||
if ((service = malloc(sizeof(*service))) == NULL) {
|
||||
goto error_malloc_service;
|
||||
}
|
||||
|
||||
if ((service->buf = malloc(SKIPSTONE_MESSAGE_MAX_PAYLOAD)) == NULL) {
|
||||
goto error_malloc_buf;
|
||||
}
|
||||
|
||||
if ((service->endpoints = skipstone_map_new()) == NULL) {
|
||||
goto error_map_new_endpoints;
|
||||
}
|
||||
|
||||
if ((service->pending = skipstone_queue_new()) == NULL) {
|
||||
goto error_queue_new_pending;
|
||||
}
|
||||
|
||||
return service;
|
||||
|
||||
error_queue_new_pending:
|
||||
skipstone_map_destroy(service->endpoints, free);
|
||||
|
||||
error_map_new_endpoints:
|
||||
free(service->buf);
|
||||
|
||||
error_malloc_buf:
|
||||
free(service);
|
||||
|
||||
error_malloc_service:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void skipstone_message_service_destroy(skipstone_message_service *service) {
|
||||
skipstone_message *message;
|
||||
|
||||
skipstone_map_destroy(service->endpoints, free);
|
||||
|
||||
while (skipstone_queue_remove(service->pending, (void **)&message)) {
|
||||
skipstone_message_destroy(message);
|
||||
}
|
||||
|
||||
skipstone_queue_destroy(service->pending);
|
||||
|
||||
free(service->buf);
|
||||
|
||||
free(service);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int skipstone_message_service_register(skipstone_message_service *service,
|
||||
uint16_t id, skipstone_message_handler *handler, void *context) {
|
||||
struct endpoint *endpoint;
|
||||
|
||||
if ((endpoint = malloc(sizeof(*endpoint))) == NULL) {
|
||||
goto error_malloc_endpoint;
|
||||
}
|
||||
|
||||
endpoint->id = id;
|
||||
endpoint->handler = handler;
|
||||
endpoint->context = context;
|
||||
|
||||
return skipstone_map_set(service->endpoints, id, endpoint);
|
||||
|
||||
error_malloc_endpoint:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int skipstone_message_service_deregister(skipstone_message_service *service, uint16_t id) {
|
||||
return skipstone_map_set((skipstone_map *)service, id, NULL);
|
||||
}
|
||||
|
||||
int skipstone_message_service_queue_packed(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_queue(skipstone_message_service *service,
|
||||
skipstone_message *message, uint16_t id) {
|
||||
skipstone_message_header *packed;
|
||||
|
||||
if ((packed = malloc(sizeof(*packed) + message->size)) == NULL) {
|
||||
goto error_malloc_packed;
|
||||
}
|
||||
|
||||
packed->size = message->size;
|
||||
packed->id = id;
|
||||
|
||||
if (skipstone_message_pack(message, packed + 1) < 0) {
|
||||
goto error_pack;
|
||||
}
|
||||
|
||||
if (skipstone_queue_add(service->pending, packed) < 0) {
|
||||
goto error_queue_add_pending;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error_queue_add_pending:
|
||||
error_pack:
|
||||
free(message);
|
||||
|
||||
error_malloc_packed:
|
||||
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;
|
||||
uint16_t size, id;
|
||||
int ready;
|
||||
|
||||
if ((ready = skipstone_link_recv(link, service->buf, &size, &id, timeout)) < 0) {
|
||||
goto error_io;
|
||||
}
|
||||
|
||||
if (ready && (endpoint = skipstone_map_get(service->endpoints, id)) != NULL) {
|
||||
if (endpoint->handler(service, service->buf, size, id, endpoint->context) < 0) {
|
||||
goto error_io;
|
||||
}
|
||||
}
|
||||
|
||||
while (skipstone_queue_remove(service->pending, (void **)&message)) {
|
||||
if (skipstone_link_send(link, message + 1, message->size, message->id) < 0) {
|
||||
goto error_io;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error_io:
|
||||
return -1;
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
#include <skipstone/music.h>
|
||||
|
||||
int skipstone_music_send_current_track(skipstone_message_service *service,
|
||||
char *artist, char *album, char *song) {
|
||||
return 0;
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include <skipstone/queue.h>
|
||||
|
||||
struct entry {
|
||||
void *value;
|
||||
struct entry *next, *prev;
|
||||
};
|
||||
|
||||
struct _skipstone_queue {
|
||||
size_t count;
|
||||
struct entry *first, *last;
|
||||
};
|
||||
|
||||
skipstone_queue *skipstone_queue_new() {
|
||||
skipstone_queue *queue;
|
||||
|
||||
if ((queue = malloc(sizeof(*queue))) == NULL) {
|
||||
goto error_malloc_queue;
|
||||
}
|
||||
|
||||
queue->count = 0;
|
||||
queue->first = NULL;
|
||||
queue->last = NULL;
|
||||
|
||||
return queue;
|
||||
|
||||
error_malloc_queue:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void skipstone_queue_destroy(skipstone_queue *queue) {
|
||||
while (queue->first) {
|
||||
struct entry *entry = queue->first;
|
||||
|
||||
queue->first = entry->next;
|
||||
|
||||
free(entry);
|
||||
}
|
||||
|
||||
free(queue);
|
||||
}
|
||||
|
||||
size_t skipstone_queue_count(skipstone_queue *queue) {
|
||||
return queue->count;
|
||||
}
|
||||
|
||||
int skipstone_queue_add(skipstone_queue *queue, void *value) {
|
||||
struct entry *next;
|
||||
|
||||
if ((next = malloc(sizeof(*next))) == NULL) {
|
||||
goto error_malloc_next;
|
||||
}
|
||||
|
||||
next->value = value;
|
||||
next->next = NULL;
|
||||
next->prev = queue->last;
|
||||
|
||||
if (queue->first == NULL) {
|
||||
queue->first = next;
|
||||
}
|
||||
|
||||
if (queue->last) {
|
||||
next->prev = queue->last;
|
||||
queue->last->next = next;
|
||||
}
|
||||
|
||||
queue->last = next;
|
||||
queue->count++;
|
||||
|
||||
return 0;
|
||||
|
||||
error_malloc_next:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int skipstone_queue_remove(skipstone_queue *queue, void **value) {
|
||||
struct entry *first = queue->first;
|
||||
|
||||
if (queue->count == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*value = first->value;
|
||||
queue->first = first->next;
|
||||
queue->count--;
|
||||
|
||||
if (queue->count == 0) {
|
||||
queue->last = NULL;
|
||||
}
|
||||
|
||||
free(first);
|
||||
|
||||
return 1;
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include <skipstone/message.h>
|
||||
#include <skipstone/system.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
int skipstone_system_send_client_version(skipstone_message_service *service,
|
||||
uint32_t flags) {
|
||||
skipstone_message *message;
|
||||
|
||||
if ((message = skipstone_message_new()) == NULL) {
|
||||
goto error_message_new;
|
||||
}
|
||||
|
||||
skipstone_message_append_uint8( message, SKIPSTONE_SYSTEM_VERSION_RESPONSE);
|
||||
skipstone_message_append_uint32(message, htobe32(SKIPSTONE_SYSTEM_PROTOCOL));
|
||||
skipstone_message_append_uint32(message, htobe32(SKIPSTONE_SYSTEM_SESSION_GAMMA_RAY));
|
||||
skipstone_message_append_uint32(message, htobe32(flags));
|
||||
skipstone_message_append_uint8( message, 2);
|
||||
skipstone_message_append_uint8( message, SKIPSTONE_SYSTEM_CLIENT_MAJOR);
|
||||
skipstone_message_append_uint8( message, SKIPSTONE_SYSTEM_CLIENT_MINOR);
|
||||
skipstone_message_append_uint8( message, SKIPSTONE_SYSTEM_CLIENT_BUGFIX);
|
||||
skipstone_message_append_uint64(message, htobe64(SKIPSTONE_SYSTEM_PROTOCOL_CAPS));
|
||||
|
||||
if (skipstone_message_service_queue(service, message, SKIPSTONE_SYSTEM_ENDPOINT_PHONE_VERSION) < 0) {
|
||||
goto error_message_service_queue;
|
||||
}
|
||||
|
||||
skipstone_message_destroy(message);
|
||||
|
||||
return 0;
|
||||
|
||||
error_message_service_queue:
|
||||
skipstone_message_destroy(message);
|
||||
|
||||
error_message_new:
|
||||
return -1;
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include <skipstone/watch.h>
|
||||
#include <skipstone/map.h>
|
||||
|
||||
struct _skipstone_watch {
|
||||
skipstone_link *link;
|
||||
skipstone_map *endpoints;
|
||||
};
|
||||
|
||||
skipstone_watch *skipstone_watch_new(skipstone_link *link) {
|
||||
skipstone_watch *watch;
|
||||
|
||||
if ((watch = malloc(sizeof(*watch))) == NULL) {
|
||||
goto error_malloc_watch;
|
||||
}
|
||||
|
||||
if ((watch->endpoints = skipstone_map_new()) == NULL) {
|
||||
goto error_map_new_endpoints;
|
||||
}
|
||||
|
||||
watch->link = link;
|
||||
|
||||
return watch;
|
||||
|
||||
error_map_new_endpoints:
|
||||
free(watch);
|
||||
|
||||
error_malloc_watch:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void skipstone_watch_destroy(skipstone_watch *watch) {
|
||||
skipstone_map_destroy(watch->endpoints, NULL);
|
||||
|
||||
free(watch);
|
||||
}
|
Loading…
Add table
Reference in a new issue