why the hell not

This commit is contained in:
XANTRONIX Development 2017-11-22 20:29:00 +00:00
parent 202c67d5eb
commit 37a1d948f3
12 changed files with 349 additions and 73 deletions

View file

@ -7,7 +7,7 @@ INCLUDE_PATH = ../include
CFLAGS += -I$(INCLUDE_PATH) CFLAGS += -I$(INCLUDE_PATH)
LDFLAGS = -L../src -lskipstone LDFLAGS = -L../src -lskipstone
EXAMPLES = read music EXAMPLES = read music map
RM = /bin/rm RM = /bin/rm

25
examples/map.c Normal file
View file

@ -0,0 +1,25 @@
#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, 0xdeadbeef);
skipstone_map_set(map, 0xbeef, 0xcafebabe);
printf("%p\n", skipstone_map_get(map, 0xdead));
printf("%p\n", skipstone_map_get(map, 0xbeef));
skipstone_map_destroy(map);
return 0;
}

25
examples/map.c-e Normal file
View file

@ -0,0 +1,25 @@
#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, 0xdeadbeef);
skipstone_map_set(map, 0xbeef, 0xcafebabe);
printf("%p\n", skipstone_map_get(map, 0xdead));
printf("%p\n", skipstone_map_get(map, 0xbeef));
skipstone_map_destroy(map);
return 0;
}

View file

@ -34,7 +34,10 @@ int main(int argc, char **argv) {
uint8_t title_len; uint8_t title_len;
char title[5]; char title[5];
} play_track = { } play_track = {
0x10, 5, "KMFDM", 5, "Nihil", 5, "Ultra" 0x10,
5, { 'K', 'M', 'F', 'D', 'M' },
5, { 'N', 'i', 'h', 'i', 'l' },
5, { 'U', 'l', 't', 'r', 'a' }
}; };
struct { struct {
@ -44,7 +47,9 @@ int main(int argc, char **argv) {
uint8_t name_len; uint8_t name_len;
char name[8]; char name[8];
} play_info = { } play_info = {
0x13, 8, "DeaDBeeF", 8, "RealDead" 0x13,
8, { 'D', 'e', 'a', 'D', 'B', 'e', 'e', 'F' },
8, { 'R', 'e', 'a', 'L', 'D', 'e', 'a', 'D' }
}; };
if (argc != 2) { if (argc != 2) {
@ -63,9 +68,7 @@ int main(int argc, char **argv) {
printf("Received message %hu bytes for endpoint %hu\n", printf("Received message %hu bytes for endpoint %hu\n",
len, endpoint); len, endpoint);
if (skipstone_send(link, &play_track, sizeof(play_track), 0x20) < 0) { skipstone_send(link, &play_track, sizeof(play_track), 0x20);
printf("Balls\n");
}
} }
perror("skipstone_recv()"); perror("skipstone_recv()");

View file

@ -34,7 +34,10 @@ int main(int argc, char **argv) {
uint8_t title_len; uint8_t title_len;
char title[5]; char title[5];
} play_track = { } play_track = {
0x10, 5, "KMFDM", 5, "Nihil", 5, "Ultra" 0x10,
5, { 'K', 'M', 'F', 'D', 'M' },
5, { 'N', 'i', 'h', 'i', 'l' },
5, { 'U', 'l', 't', 'r', 'a' }
}; };
struct { struct {
@ -44,7 +47,9 @@ int main(int argc, char **argv) {
uint8_t name_len; uint8_t name_len;
char name[8]; char name[8];
} play_info = { } play_info = {
0x13, 8, "DeaDBeeF", 8, "RealDead" 0x13,
8, { 'D', 'e', 'a', 'D', 'B', 'e', 'e', 'F' },
8, { 'R', 'e', 'a', 'L', 'D', 'e', 'a', 'D' }
}; };
if (argc != 2) { if (argc != 2) {
@ -63,9 +68,7 @@ int main(int argc, char **argv) {
printf("Received message %hu bytes for endpoint %hu\n", printf("Received message %hu bytes for endpoint %hu\n",
len, endpoint); len, endpoint);
if (skipstone_send(link, &play_track, sizeof(play_track), 0x20) < 0) { skipstone_send(link, &play_track, sizeof(play_track), 0x20);
printf("Balls\n");
}
} }
perror("skipstone_recv()"); perror("skipstone_recv()");

24
include/skipstone/map.h Normal file
View file

@ -0,0 +1,24 @@
#ifndef _SKIPSTONE_MAP_H
#define _SKIPSTONE_MAP_H
#include <stdint.h>
#define SKIPSTONE_MAP_SLOTS 16
#define SKIPSTONE_MAP_DEPTH 3
typedef struct _skipstone_map {
union {
void *value;
struct _skipstone_map *next;
};
} skipstone_map;
skipstone_map *skipstone_map_new();
void skipstone_map_destroy(skipstone_map *map);
void *skipstone_map_get(skipstone_map *map, uint16_t index);
void *skipstone_map_set(skipstone_map *map, uint16_t index, void *value);
#endif /* _SKIPSTONE_MAP_H */

View file

@ -14,18 +14,36 @@ enum skipstone_message_endpoint {
SKIPSTONE_MESSAGE_ENDPOINT_PHONE_VERSION = 17, SKIPSTONE_MESSAGE_ENDPOINT_PHONE_VERSION = 17,
SKIPSTONE_MESSAGE_ENDPOINT_SYSTEM_MESSAGE = 18, SKIPSTONE_MESSAGE_ENDPOINT_SYSTEM_MESSAGE = 18,
SKIPSTONE_MESSAGE_ENDPOINT_MUSIC_CONTROL = 32, SKIPSTONE_MESSAGE_ENDPOINT_MUSIC_CONTROL = 32,
SKIPSTONE_MESSAGE_ENDPOINT_PHONE_CONTROL = 33, SKIPSTONE_MESSAGE_ENDPOINT_PHONE_CONTROL = 33
}; };
typedef struct _skipstone_message_endpoint skipstone_message_endpoint;
typedef struct _skipstone_watch_link skipstone_watch_link; typedef struct _skipstone_watch_link skipstone_watch_link;
typedef struct _skipstone_watch skipstone_watch;
typedef int (*skipstone_message_handler)(skipstone_watch *watch,
void *buf, uint16_t size, uint16_t endpoint);
skipstone_watch_link *skipstone_watch_link_open_serial(const char *device); skipstone_watch_link *skipstone_watch_link_open_serial(const char *device);
int skipstone_watch_link_close(skipstone_watch_link *link); int skipstone_watch_link_close(skipstone_watch_link *link);
int skipstone_send(skipstone_watch_link *link, void *buf, uint16_t size, uint16_t endpoint); skipstone_watch *skipstone_watch_new(skipstone_watch_link *link);
int skipstone_recv(skipstone_watch_link *link, void *buf, uint16_t *size, uint16_t *endpoint); void skipstone_watch_destroy(skipstone_watch *watch);
int skipstone_watch_main();
void skipstone_watch_register_message_handler(skipstone_watch *watch,
uint16_t endpoint, skipstone_message_handler *handler, void *context);
void skipstone_watch_deregister_message_handler(skipstone_watch *watch,
uint16_t endpoint);
int skipstone_watch_link_send(skipstone_watch_link *link, void *buf, uint16_t size, uint16_t endpoint);
int skipstone_watch_link_recv(skipstone_watch_link *link, void *buf, uint16_t *size, uint16_t *endpoint);
#endif /* _SKIPSTONE_H */ #endif /* _SKIPSTONE_H */

View file

@ -7,9 +7,9 @@ CC = $(CROSS)cc
CFLAGS += -fPIC -I$(INCLUDE_PATH) CFLAGS += -fPIC -I$(INCLUDE_PATH)
LDFLAGS = LDFLAGS =
HEADERS = skipstone.h HEADERS = skipstone.h map.h
OBJS = skipstone.o OBJS = skipstone.o map.o
VERSION_MAJOR = 0 VERSION_MAJOR = 0
VERSION_MINOR = 0.1 VERSION_MINOR = 0.1

79
src/map.c Normal file
View file

@ -0,0 +1,79 @@
#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, int depth) {
uint16_t i;
if (depth > SKIPSTONE_MAP_DEPTH) {
return;
}
for (i=0; i<SKIPSTONE_MAP_SLOTS; i++) {
if (map[i].next) {
_destroy(map[i].next, depth + 1);
}
}
free(map);
}
void skipstone_map_destroy(skipstone_map *map) {
_destroy(map, 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;
}
void *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;
}
return map[index & 0x0f].value = value;
error_new:
return NULL;
}

79
src/map.c-e Normal file
View file

@ -0,0 +1,79 @@
#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, int depth) {
uint16_t i;
if (depth > SKIPSTONE_MAP_DEPTH) {
return;
}
for (i=0; i<SKIPSTONE_MAP_SLOTS; i++) {
if (map[i].next) {
_destroy(map[i].next, depth + 1);
}
}
free(map);
}
void skipstone_map_destroy(skipstone_map *map) {
_destroy(map, 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;
}
void *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;
}
return map[index & 0x0f].value = value;
error_new:
return NULL;
}

View file

@ -8,11 +8,18 @@
#include <endian.h> #include <endian.h>
#include <skipstone/skipstone.h> #include <skipstone/skipstone.h>
#include <skipstone/map.h>
enum skipstone_watch_link_type { enum skipstone_watch_link_type {
SKIPSTONE_WATCH_LINK_SERIAL = 1 SKIPSTONE_WATCH_LINK_SERIAL = 1
}; };
struct _skipstone_message_endpoint {
uint16_t id;
skipstone_message_handler *handler;
void *context;
};
struct _skipstone_watch_link { struct _skipstone_watch_link {
enum skipstone_watch_link_type type; enum skipstone_watch_link_type type;
@ -26,6 +33,11 @@ struct _skipstone_watch_link {
}; };
}; };
struct _skipstone_watch {
skipstone_watch_link *link;
skipstone_map *endpoints;
};
typedef struct _skipstone_message_header { typedef struct _skipstone_message_header {
uint16_t size, uint16_t size,
endpoint; endpoint;
@ -102,7 +114,7 @@ int skipstone_watch_link_close(skipstone_watch_link *link) {
return -1; return -1;
} }
int skipstone_send(skipstone_watch_link *link, void *buf, uint16_t size, uint16_t endpoint) { int skipstone_watch_link_send(skipstone_watch_link *link, void *buf, uint16_t size, uint16_t endpoint) {
skipstone_message_header header; skipstone_message_header header;
ssize_t wrlen; ssize_t wrlen;
@ -137,38 +149,36 @@ error_toobig:
return -1; return -1;
} }
int skipstone_recv(skipstone_watch_link *link, void *buf, uint16_t *size, uint16_t *endpoint) { int skipstone_watch_link_recv(skipstone_watch_link *link, void *buf, uint16_t *size, uint16_t *endpoint) {
skipstone_message_header header; skipstone_message_header header;
while (1) { ssize_t len_read;
ssize_t len_read; size_t len_wanted, offset = 0;
size_t len_wanted, offset = 0;
if (read(link->serial.fd, &header, sizeof(header)) < 0) { if (read(link->serial.fd, &header, sizeof(header)) < 0) {
goto error_io; 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);
*endpoint = be16toh(header.endpoint);
return 0;
} }
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);
*endpoint = be16toh(header.endpoint);
return 0;
error_io: error_io:
return -1; return -1;
} }

View file

@ -8,11 +8,18 @@
#include <endian.h> #include <endian.h>
#include <skipstone/skipstone.h> #include <skipstone/skipstone.h>
#include <skipstone/map.h>
enum skipstone_watch_link_type { enum skipstone_watch_link_type {
SKIPSTONE_WATCH_LINK_SERIAL = 1 SKIPSTONE_WATCH_LINK_SERIAL = 1
}; };
struct _skipstone_message_endpoint {
uint16_t id;
skipstone_message_handler *handler;
void *context;
};
struct _skipstone_watch_link { struct _skipstone_watch_link {
enum skipstone_watch_link_type type; enum skipstone_watch_link_type type;
@ -26,6 +33,11 @@ struct _skipstone_watch_link {
}; };
}; };
struct _skipstone_watch {
skipstone_watch_link *link;
skipstone_map *endpoints;
};
typedef struct _skipstone_message_header { typedef struct _skipstone_message_header {
uint16_t size, uint16_t size,
endpoint; endpoint;
@ -102,7 +114,7 @@ int skipstone_watch_link_close(skipstone_watch_link *link) {
return -1; return -1;
} }
int skipstone_send(skipstone_watch_link *link, void *buf, uint16_t size, uint16_t endpoint) { int skipstone_watch_link_send(skipstone_watch_link *link, void *buf, uint16_t size, uint16_t endpoint) {
skipstone_message_header header; skipstone_message_header header;
ssize_t wrlen; ssize_t wrlen;
@ -137,38 +149,36 @@ error_toobig:
return -1; return -1;
} }
int skipstone_recv(skipstone_watch_link *link, void *buf, uint16_t *size, uint16_t *endpoint) { int skipstone_watch_link_recv(skipstone_watch_link *link, void *buf, uint16_t *size, uint16_t *endpoint) {
skipstone_message_header header; skipstone_message_header header;
while (1) { ssize_t len_read;
ssize_t len_read; size_t len_wanted, offset = 0;
size_t len_wanted, offset = 0;
if (read(link->serial.fd, &header, sizeof(header)) < 0) { if (read(link->serial.fd, &header, sizeof(header)) < 0) {
goto error_io; 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);
*endpoint = be16toh(header.endpoint);
return 0;
} }
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);
*endpoint = be16toh(header.endpoint);
return 0;
error_io: error_io:
return -1; return -1;
} }