diff --git a/examples/test.c b/examples/test.c index 31896f6..7be8e4b 100644 --- a/examples/test.c +++ b/examples/test.c @@ -25,24 +25,19 @@ static int answer_phone_version_message(skipstone_message_service *service, static int answer_media_message(skipstone_message_service *service, void *buf, uint16_t size, uint16_t id, void *context) { - 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' } - }; + skipstone_message *message = skipstone_message_new(32); - printf("Got message on endpoint %hu\n", id); + uint8_t out[4096]; + uint16_t outsz; - skipstone_message_service_queue(service, &play_track, sizeof(play_track), 32); + 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); return 0; } diff --git a/examples/test.c-e b/examples/test.c-e index 31896f6..7be8e4b 100644 --- a/examples/test.c-e +++ b/examples/test.c-e @@ -25,24 +25,19 @@ static int answer_phone_version_message(skipstone_message_service *service, static int answer_media_message(skipstone_message_service *service, void *buf, uint16_t size, uint16_t id, void *context) { - 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' } - }; + skipstone_message *message = skipstone_message_new(32); - printf("Got message on endpoint %hu\n", id); + uint8_t out[4096]; + uint16_t outsz; - skipstone_message_service_queue(service, &play_track, sizeof(play_track), 32); + 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); return 0; } diff --git a/include/skipstone/message.h b/include/skipstone/message.h index 2b912f8..a827e6b 100644 --- a/include/skipstone/message.h +++ b/include/skipstone/message.h @@ -19,6 +19,11 @@ enum { SKIPSTONE_MESSAGE_ENDPOINT_PHONE_CONTROL = 33 }; +enum skipstone_message_endianness { + SKIPSTONE_MESSAGE_ENDIAN_LITTLE, + SKIPSTONE_MESSAGE_ENDIAN_BIG +}; + typedef struct _skipstone_message_header { uint16_t size, id; @@ -26,8 +31,24 @@ typedef struct _skipstone_message_header { typedef struct _skipstone_message_service skipstone_message_service; +typedef struct _skipstone_message skipstone_message; + typedef int (skipstone_message_handler)(skipstone_message_service *service, - void *buf, uint16_t size, uint16_t id, void *context); + void *buf, uint16_t size, uint16_t id, void *context); + +skipstone_message *skipstone_message_new(uint16_t id); + +int skipstone_message_append_string(skipstone_message *message, + char *string, uint8_t size); + +int skipstone_message_append_uint8(skipstone_message *message, + uint8_t value); + +int skipstone_message_append_uint16(skipstone_message *message, + uint16_t value); + +int skipstone_message_pack(skipstone_message *message, + void *buf, uint16_t *size); skipstone_message_service *skipstone_message_service_new(); diff --git a/src/link.c b/src/link.c index 9f3f082..f4f8094 100644 --- a/src/link.c +++ b/src/link.c @@ -134,6 +134,12 @@ error_toobig: return -1; } +int skipstone_link_send_message(skipstone_link *link, skipstone_message *message, uint16_t id) { + skipstone_message_header header; + + return 0; +} + int skipstone_link_recv(skipstone_link *link, void *buf, uint16_t *size, uint16_t *id) { skipstone_message_header header; diff --git a/src/link.c-e b/src/link.c-e index 9f3f082..f4f8094 100644 --- a/src/link.c-e +++ b/src/link.c-e @@ -134,6 +134,12 @@ error_toobig: return -1; } +int skipstone_link_send_message(skipstone_link *link, skipstone_message *message, uint16_t id) { + skipstone_message_header header; + + return 0; +} + int skipstone_link_recv(skipstone_link *link, void *buf, uint16_t *size, uint16_t *id) { skipstone_message_header header; diff --git a/src/message.c b/src/message.c index 9ce49fd..1b42b9c 100644 --- a/src/message.c +++ b/src/message.c @@ -6,10 +6,27 @@ #include #include +enum part_type { + SKIPSTONE_MESSAGE_PART_STRING, + SKIPSTONE_MESSAGE_PART_UINT8, + SKIPSTONE_MESSAGE_PART_UINT16 +}; + +struct part { + enum part_type type; + enum skipstone_message_endianness endianness; + uint16_t size; +}; + +struct _skipstone_message { + uint16_t size, id; + skipstone_queue *parts; +}; + struct endpoint { - uint16_t id; skipstone_message_handler *handler; void *context; + uint16_t id; }; struct _skipstone_message_service { @@ -17,6 +34,151 @@ struct _skipstone_message_service { skipstone_queue *pending; }; +skipstone_message *skipstone_message_new(uint16_t id) { + 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; + message->id = id; + + return message; + +error_queue_new_parts: + free(message); + +error_malloc_message: + return NULL; +} + +int skipstone_message_append_string(skipstone_message *message, + char *string, uint8_t size) { + struct part *part; + + if ((part = malloc(sizeof(*part) + size)) == NULL) { + goto error_malloc_part; + } + + part->type = SKIPSTONE_MESSAGE_PART_STRING; + part->endianness = SKIPSTONE_MESSAGE_ENDIAN_LITTLE; + part->size = size; + + memcpy(part + 1, string, 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_uint8(skipstone_message *message, + uint8_t value) { + struct part *part; + + if ((part = malloc(sizeof(*part) + sizeof(uint8_t))) == NULL) { + goto error_malloc_part; + } + + part->type = SKIPSTONE_MESSAGE_PART_UINT8; + part->endianness = SKIPSTONE_MESSAGE_ENDIAN_LITTLE; + part->size = sizeof(uint8_t); + + ((uint8_t *)(part + 1))[0] = value; + + 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_uint16(skipstone_message *message, + uint16_t value) { + struct part *part; + + if ((part = malloc(sizeof(*part) + sizeof(uint16_t))) == NULL) { + goto error_malloc_part; + } + + part->type = SKIPSTONE_MESSAGE_PART_UINT16; + part->endianness = SKIPSTONE_MESSAGE_ENDIAN_LITTLE; + part->size = sizeof(uint16_t); + + ((uint16_t *)(part + 1))[0] = value; + + 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_pack(skipstone_message *message, + void *buf, uint16_t *size) { + size_t offset = 0; + + struct part *part; + + while (skipstone_queue_remove(message->parts, (void **)&part)) { + switch (part->type) { + case SKIPSTONE_MESSAGE_PART_STRING: { + ((uint8_t *)buf)[offset] = part->size; + + memcpy((uint8_t *)buf + offset + sizeof(uint8_t), part + 1, part->size); + + offset += sizeof(uint8_t) + part->size; + + break; + } + + case SKIPSTONE_MESSAGE_PART_UINT8: { + ((uint8_t *)buf)[offset] = ((uint8_t *)(part + 1))[0]; + + offset += sizeof(uint8_t); + + break; + } + + case SKIPSTONE_MESSAGE_PART_UINT16: { + ((uint16_t *)((uint8_t *)buf + offset))[0] = ((uint16_t *)(part + 1))[0]; + + offset += sizeof(uint16_t); + + break; + } + } + } + + *size = offset; + + return 0; +} + skipstone_message_service *skipstone_message_service_new() { skipstone_message_service *service; diff --git a/src/message.c-e b/src/message.c-e index 9ce49fd..1b42b9c 100644 --- a/src/message.c-e +++ b/src/message.c-e @@ -6,10 +6,27 @@ #include #include +enum part_type { + SKIPSTONE_MESSAGE_PART_STRING, + SKIPSTONE_MESSAGE_PART_UINT8, + SKIPSTONE_MESSAGE_PART_UINT16 +}; + +struct part { + enum part_type type; + enum skipstone_message_endianness endianness; + uint16_t size; +}; + +struct _skipstone_message { + uint16_t size, id; + skipstone_queue *parts; +}; + struct endpoint { - uint16_t id; skipstone_message_handler *handler; void *context; + uint16_t id; }; struct _skipstone_message_service { @@ -17,6 +34,151 @@ struct _skipstone_message_service { skipstone_queue *pending; }; +skipstone_message *skipstone_message_new(uint16_t id) { + 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; + message->id = id; + + return message; + +error_queue_new_parts: + free(message); + +error_malloc_message: + return NULL; +} + +int skipstone_message_append_string(skipstone_message *message, + char *string, uint8_t size) { + struct part *part; + + if ((part = malloc(sizeof(*part) + size)) == NULL) { + goto error_malloc_part; + } + + part->type = SKIPSTONE_MESSAGE_PART_STRING; + part->endianness = SKIPSTONE_MESSAGE_ENDIAN_LITTLE; + part->size = size; + + memcpy(part + 1, string, 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_uint8(skipstone_message *message, + uint8_t value) { + struct part *part; + + if ((part = malloc(sizeof(*part) + sizeof(uint8_t))) == NULL) { + goto error_malloc_part; + } + + part->type = SKIPSTONE_MESSAGE_PART_UINT8; + part->endianness = SKIPSTONE_MESSAGE_ENDIAN_LITTLE; + part->size = sizeof(uint8_t); + + ((uint8_t *)(part + 1))[0] = value; + + 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_uint16(skipstone_message *message, + uint16_t value) { + struct part *part; + + if ((part = malloc(sizeof(*part) + sizeof(uint16_t))) == NULL) { + goto error_malloc_part; + } + + part->type = SKIPSTONE_MESSAGE_PART_UINT16; + part->endianness = SKIPSTONE_MESSAGE_ENDIAN_LITTLE; + part->size = sizeof(uint16_t); + + ((uint16_t *)(part + 1))[0] = value; + + 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_pack(skipstone_message *message, + void *buf, uint16_t *size) { + size_t offset = 0; + + struct part *part; + + while (skipstone_queue_remove(message->parts, (void **)&part)) { + switch (part->type) { + case SKIPSTONE_MESSAGE_PART_STRING: { + ((uint8_t *)buf)[offset] = part->size; + + memcpy((uint8_t *)buf + offset + sizeof(uint8_t), part + 1, part->size); + + offset += sizeof(uint8_t) + part->size; + + break; + } + + case SKIPSTONE_MESSAGE_PART_UINT8: { + ((uint8_t *)buf)[offset] = ((uint8_t *)(part + 1))[0]; + + offset += sizeof(uint8_t); + + break; + } + + case SKIPSTONE_MESSAGE_PART_UINT16: { + ((uint16_t *)((uint8_t *)buf + offset))[0] = ((uint16_t *)(part + 1))[0]; + + offset += sizeof(uint16_t); + + break; + } + } + } + + *size = offset; + + return 0; +} + skipstone_message_service *skipstone_message_service_new() { skipstone_message_service *service;