Sometimes I impress even myself

This commit is contained in:
XANTRONIX Development 2017-11-26 16:22:00 -06:00
parent af4299f155
commit 51a0c51c66
18 changed files with 342 additions and 222 deletions

View file

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

View file

@ -1,86 +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;
struct {
uint8_t command;
uint8_t state;
uint32_t track_position;
uint32_t play_rate;
uint8_t shuffle;
uint8_t repeat;
} play_state = {
0x11, 0x01, 0, 44100, 0x01, 0x01
};
struct {
uint8_t command;
uint8_t artist_len;
char artist[5];
uint8_t album_len;
char album[5];
uint8_t title_len;
char title[5];
} play_track = {
0x10,
5, { 'K', 'M', 'F', 'D', 'M' },
5, { 'N', 'i', 'h', 'i', 'l' },
5, { 'U', 'l', 't', 'r', 'a' }
};
struct {
uint8_t command;
uint8_t package_len;
char package[8];
uint8_t name_len;
char name[8];
} play_info = {
0x13,
8, { 'D', 'e', 'a', 'D', 'B', 'e', 'e', 'F' },
8, { 'R', 'e', 'a', 'L', 'D', 'e', 'a', 'D' }
};
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_watch_link_open;
}
while (skipstone_link_recv(link, buf, &len, &endpoint) >= 0) {
printf("Received message %hu bytes for endpoint %hu\n",
len, endpoint);
skipstone_link_send(link, &play_track, sizeof(play_track), 0x20);
}
perror("skipstone_link_recv()");
skipstone_link_close(link);
return 0;
error_watch_link_open:
free(buf);
error_malloc_buf:
return 1;
}

View file

@ -1,86 +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;
struct {
uint8_t command;
uint8_t state;
uint32_t track_position;
uint32_t play_rate;
uint8_t shuffle;
uint8_t repeat;
} play_state = {
0x11, 0x01, 0, 44100, 0x01, 0x01
};
struct {
uint8_t command;
uint8_t artist_len;
char artist[5];
uint8_t album_len;
char album[5];
uint8_t title_len;
char title[5];
} play_track = {
0x10,
5, { 'K', 'M', 'F', 'D', 'M' },
5, { 'N', 'i', 'h', 'i', 'l' },
5, { 'U', 'l', 't', 'r', 'a' }
};
struct {
uint8_t command;
uint8_t package_len;
char package[8];
uint8_t name_len;
char name[8];
} play_info = {
0x13,
8, { 'D', 'e', 'a', 'D', 'B', 'e', 'e', 'F' },
8, { 'R', 'e', 'a', 'L', 'D', 'e', 'a', 'D' }
};
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_watch_link_open;
}
while (skipstone_link_recv(link, buf, &len, &endpoint) >= 0) {
printf("Received message %hu bytes for endpoint %hu\n",
len, endpoint);
skipstone_link_send(link, &play_track, sizeof(play_track), 0x20);
}
perror("skipstone_link_recv()");
skipstone_link_close(link);
return 0;
error_watch_link_open:
free(buf);
error_malloc_buf:
return 1;
}

View file

@ -4,6 +4,7 @@
#include <skipstone/link.h>
#include <skipstone/message.h>
#include <skipstone/system.h>
static void usage(int argc, char **argv) {
fprintf(stderr, "usage: %s /dev/rfcommX\n", argv[0]);
@ -12,30 +13,24 @@ static void usage(int argc, char **argv) {
static int answer_phone_version_message(skipstone_message_service *service,
void *buf, uint16_t size, uint16_t id, void *context) {
uint8_t response[13] = {
1, 0xff, 0xff, 0xff, 0xff, 0x80, 0, 0, 0, 0, 0, 0, 0x32
};
const uint32_t flags = SKIPSTONE_SYSTEM_CLIENT_ANDROID;
skipstone_message_service_queue(service, &response, sizeof(response), id);
return 0;
return skipstone_system_send_client_version(service, flags);
}
static int answer_media_message(skipstone_message_service *service,
static int answer_music_message(skipstone_message_service *service,
void *buf, uint16_t size, uint16_t id, void *context) {
skipstone_message *message = skipstone_message_new(32);
skipstone_message *message = skipstone_message_new();
uint8_t out[4096];
uint16_t outsz;
printf("Received music message size %hu value %02x\n", size,
((uint8_t *)buf)[0]);
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_pack(message, &out, &outsz);
skipstone_message_service_queue(service, &out, outsz, 32);
skipstone_message_service_queue(service, message, 32);
return 0;
}
@ -80,7 +75,7 @@ int main(int argc, char **argv) {
}
skipstone_message_service_register(service, 17, answer_phone_version_message, NULL);
skipstone_message_service_register(service, 32, answer_media_message, NULL);
skipstone_message_service_register(service, 32, answer_music_message, NULL);
skipstone_message_service_run(service, link);

View file

@ -4,6 +4,7 @@
#include <skipstone/link.h>
#include <skipstone/message.h>
#include <skipstone/system.h>
static void usage(int argc, char **argv) {
fprintf(stderr, "usage: %s /dev/rfcommX\n", argv[0]);
@ -12,30 +13,24 @@ static void usage(int argc, char **argv) {
static int answer_phone_version_message(skipstone_message_service *service,
void *buf, uint16_t size, uint16_t id, void *context) {
uint8_t response[13] = {
1, 0xff, 0xff, 0xff, 0xff, 0x80, 0, 0, 0, 0, 0, 0, 0x32
};
const uint32_t flags = SKIPSTONE_SYSTEM_CLIENT_ANDROID;
skipstone_message_service_queue(service, &response, sizeof(response), id);
return 0;
return skipstone_system_send_client_version(service, flags);
}
static int answer_media_message(skipstone_message_service *service,
static int answer_music_message(skipstone_message_service *service,
void *buf, uint16_t size, uint16_t id, void *context) {
skipstone_message *message = skipstone_message_new(32);
skipstone_message *message = skipstone_message_new();
uint8_t out[4096];
uint16_t outsz;
printf("Received music message size %hu value %02x\n", size,
((uint8_t *)buf)[0]);
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_pack(message, &out, &outsz);
skipstone_message_service_queue(service, &out, outsz, 32);
skipstone_message_service_queue(service, message, 32);
return 0;
}
@ -80,7 +75,7 @@ int main(int argc, char **argv) {
}
skipstone_message_service_register(service, 17, answer_phone_version_message, NULL);
skipstone_message_service_register(service, 32, answer_media_message, NULL);
skipstone_message_service_register(service, 32, answer_music_message, NULL);
skipstone_message_service_run(service, link);

View file

@ -10,9 +10,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 endpoint);
void *buf, uint16_t size, uint16_t id);
int skipstone_link_recv(skipstone_link *link,
void *buf, uint16_t *size, uint16_t *endpoint);
void *buf, uint16_t *size, uint16_t *id);
#endif /* _SKIPSTONE_LINK_H */

View file

@ -38,6 +38,10 @@ typedef int (skipstone_message_handler)(skipstone_message_service *service,
skipstone_message *skipstone_message_new();
void skipstone_message_destroy(skipstone_message *message);
uint16_t skipstone_message_size(skipstone_message *message);
int skipstone_message_append_string(skipstone_message *message,
char *string, uint8_t size);
@ -47,8 +51,10 @@ int skipstone_message_append_uint8(skipstone_message *message,
int skipstone_message_append_uint16(skipstone_message *message,
uint16_t value);
int skipstone_message_pack(skipstone_message *message,
void *buf, uint16_t *size);
int skipstone_message_append_uint32(skipstone_message *message,
uint32_t value);
int skipstone_message_pack(skipstone_message *message, void *buf);
skipstone_message_service *skipstone_message_service_new();
@ -58,9 +64,12 @@ int skipstone_message_service_register(skipstone_message_service *service,
int skipstone_message_service_deregister(skipstone_message_service *service,
uint16_t id);
int skipstone_message_service_queue(skipstone_message_service *service,
int skipstone_message_service_queue_packed(skipstone_message_service *service,
void *buf, uint16_t size, uint16_t id);
int skipstone_message_service_queue(skipstone_message_service *service,
skipstone_message *message, uint16_t id);
int skipstone_message_service_run(skipstone_message_service *service,
skipstone_link *link);

17
include/skipstone/music.h Normal file
View file

@ -0,0 +1,17 @@
#ifndef _SKIPSTONE_MUSIC_H
#define _SKIPSTONE_MUSIC_H
#include <skipstone/message.h>
enum {
SKIPSTONE_MUSIC_EVENT_PLAY_PAUSE = 0x01,
SKIPSTONE_MUSIC_EVENT_NEXT = 0x04,
SKIPSTONE_MUSIC_EVENT_PREV = 0x05,
SKIPSTONE_MUSIC_EVENT_VOLUME_UP = 0x06,
SKIPSTONE_MUSIC_EVENT_VOLUME_DOWN = 0x07
};
int skipstone_music_send_current_track(skipstone_message_service *service,
char *artist, char *album, char *song);
#endif /* _SKIPSTONE_MUSIC_H */

View file

@ -0,0 +1,38 @@
#ifndef _SKIPSTONE_SYSTEM_H
#define _SKIPSTONE_SYSTEM_H
#include <stdint.h>
#include <skipstone/message.h>
#define SKIPSTONE_SYSTEM_ENDPOINT_PHONE_VERSION 0x11
#define SKIPSTONE_SYSTEM_PROTOCOL 0xffffffff
#define SKIPSTONE_SYSTEM_SESSION_GAMMA_RAY 0x80000000
#define SKIPSTONE_SYSTEM_CLIENT_TELEPHONY (1 << 4)
#define SKIPSTONE_SYSTEM_CLIENT_SMS (1 << 5)
#define SKIPSTONE_SYSTEM_CLIENT_GPS (1 << 6)
#define SKIPSTONE_SYSTEM_CLIENT_BTLE (1 << 7)
#define SKIPSTONE_SYSTEM_CLIENT_CAMERA_REAR (1 << 8)
#define SKIPSTONE_SYSTEM_CLIENT_ACCEL (1 << 9)
#define SKIPSTONE_SYSTEM_CLIENT_GYRO (1 << 10)
#define SKIPSTONE_SYSTEM_CLIENT_COMPASS (1 << 11)
enum {
SKIPSTONE_SYSTEM_CLIENT_UNKNOWN = 0,
SKIPSTONE_SYSTEM_CLIENT_IOS = 1,
SKIPSTONE_SYSTEM_CLIENT_ANDROID = 2,
SKIPSTONE_SYSTEM_CLIENT_OSX = 3,
SKIPSTONE_SYSTEM_CLIENT_LINUX = 4,
SKIPSTONE_SYSTEM_CLIENT_WINDOWS = 5
};
enum {
SKIPSTONE_SYSTEM_RESPONSE_VERSION = 1
};
int skipstone_system_send_client_version(skipstone_message_service *service,
uint32_t capabilities);
#endif /* _SKIPSTONE_SYSTEM_H */

View file

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

View file

@ -134,10 +134,33 @@ error_toobig:
return -1;
}
int skipstone_link_send_message(skipstone_link *link, skipstone_message *message, uint16_t id) {
skipstone_message_header header;
int skipstone_link_send_message(skipstone_link *link,
skipstone_message *message, uint16_t id) {
void *buf;
uint16_t size = skipstone_message_size(message);
if ((buf = malloc(size)) == NULL) {
goto error_malloc_size;
}
if (skipstone_message_pack(message, buf) < 0) {
goto error_message_pack;
}
if (skipstone_link_send(link, buf, size, id) < 0) {
goto error_link_send;
}
free(buf);
return 0;
error_link_send:
error_message_pack:
free(buf);
error_malloc_size:
return -1;
}
int skipstone_link_recv(skipstone_link *link, void *buf, uint16_t *size, uint16_t *id) {

View file

@ -134,10 +134,33 @@ error_toobig:
return -1;
}
int skipstone_link_send_message(skipstone_link *link, skipstone_message *message, uint16_t id) {
skipstone_message_header header;
int skipstone_link_send_message(skipstone_link *link,
skipstone_message *message, uint16_t id) {
void *buf;
uint16_t size = skipstone_message_size(message);
if ((buf = malloc(size)) == NULL) {
goto error_malloc_size;
}
if (skipstone_message_pack(message, buf) < 0) {
goto error_message_pack;
}
if (skipstone_link_send(link, buf, size, id) < 0) {
goto error_link_send;
}
free(buf);
return 0;
error_link_send:
error_message_pack:
free(buf);
error_malloc_size:
return -1;
}
int skipstone_link_recv(skipstone_link *link, void *buf, uint16_t *size, uint16_t *id) {

View file

@ -48,6 +48,20 @@ 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;
@ -101,6 +115,10 @@ 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;
@ -121,8 +139,17 @@ int skipstone_message_append_uint16(skipstone_message *message, uint16_t value)
return 0;
}
int skipstone_message_pack(skipstone_message *message,
void *buf, uint16_t *size) {
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_pack(skipstone_message *message, void *buf) {
size_t offset = 0;
struct part *part;
@ -137,8 +164,6 @@ int skipstone_message_pack(skipstone_message *message,
offset += part->size;
}
*size = offset;
return 0;
}
@ -191,7 +216,7 @@ int skipstone_message_service_deregister(skipstone_message_service *service, uin
return skipstone_map_set((skipstone_map *)service, id, NULL);
}
int skipstone_message_service_queue(skipstone_message_service *service,
int skipstone_message_service_queue_packed(skipstone_message_service *service,
void *buf, uint16_t size, uint16_t id) {
skipstone_message_header *message;
@ -217,6 +242,35 @@ 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_run(skipstone_message_service *service,
skipstone_link *link) {
void *buf;

View file

@ -48,6 +48,20 @@ 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;
@ -101,6 +115,10 @@ 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;
@ -121,8 +139,17 @@ int skipstone_message_append_uint16(skipstone_message *message, uint16_t value)
return 0;
}
int skipstone_message_pack(skipstone_message *message,
void *buf, uint16_t *size) {
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_pack(skipstone_message *message, void *buf) {
size_t offset = 0;
struct part *part;
@ -137,8 +164,6 @@ int skipstone_message_pack(skipstone_message *message,
offset += part->size;
}
*size = offset;
return 0;
}
@ -191,7 +216,7 @@ int skipstone_message_service_deregister(skipstone_message_service *service, uin
return skipstone_map_set((skipstone_map *)service, id, NULL);
}
int skipstone_message_service_queue(skipstone_message_service *service,
int skipstone_message_service_queue_packed(skipstone_message_service *service,
void *buf, uint16_t size, uint16_t id) {
skipstone_message_header *message;
@ -217,6 +242,35 @@ 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_run(skipstone_message_service *service,
skipstone_link *link) {
void *buf;

6
src/music.c Normal file
View file

@ -0,0 +1,6 @@
#include <skipstone/music.h>
int skipstone_music_send_current_track(skipstone_message_service *service,
char *artist, char *album, char *song) {
return 0;
}

6
src/music.c-e Normal file
View file

@ -0,0 +1,6 @@
#include <skipstone/music.h>
int skipstone_music_send_current_track(skipstone_message_service *service,
char *artist, char *album, char *song) {
return 0;
}

36
src/system.c Normal file
View file

@ -0,0 +1,36 @@
#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 capabilities) {
skipstone_message *message;
static const uint32_t flags = SKIPSTONE_SYSTEM_CLIENT_TELEPHONY
| SKIPSTONE_SYSTEM_CLIENT_SMS
| SKIPSTONE_SYSTEM_CLIENT_ANDROID;
if ((message = skipstone_message_new()) == NULL) {
goto error_message_new;
}
skipstone_message_append_uint8( message, SKIPSTONE_SYSTEM_RESPONSE_VERSION);
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));
if (skipstone_message_service_queue(service, message, SKIPSTONE_SYSTEM_ENDPOINT_PHONE_VERSION) < 0) {
goto error_message_service_queue;
}
return 0;
error_message_service_queue:
skipstone_message_destroy(message);
error_message_new:
return -1;
}

36
src/system.c-e Normal file
View file

@ -0,0 +1,36 @@
#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 capabilities) {
skipstone_message *message;
static const uint32_t flags = SKIPSTONE_SYSTEM_CLIENT_TELEPHONY
| SKIPSTONE_SYSTEM_CLIENT_SMS
| SKIPSTONE_SYSTEM_CLIENT_ANDROID;
if ((message = skipstone_message_new()) == NULL) {
goto error_message_new;
}
skipstone_message_append_uint8( message, SKIPSTONE_SYSTEM_RESPONSE_VERSION);
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));
if (skipstone_message_service_queue(service, message, SKIPSTONE_SYSTEM_ENDPOINT_PHONE_VERSION) < 0) {
goto error_message_service_queue;
}
return 0;
error_message_service_queue:
skipstone_message_destroy(message);
error_message_new:
return -1;
}