diff --git a/examples/music.c b/examples/music.c
new file mode 100644
index 0000000..884918a
--- /dev/null
+++ b/examples/music.c
@@ -0,0 +1,82 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <skipstone/skipstone.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_watch_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, "KMFDM", 5, "Nihil", 5, "Ultra"
+    };
+
+    struct {
+        uint8_t command;
+        uint8_t package_len;
+        char package[8];
+        uint8_t name_len;
+        char name[8];
+    } play_info = {
+        0x13, 8, "DeaDBeeF", 8, "RealDead"
+    };
+
+    if (argc != 2) {
+        usage(argc, argv);
+    }
+
+    if ((buf = malloc(SKIPSTONE_MESSAGE_MAX_PAYLOAD)) == NULL) {
+        goto error_malloc_buf;
+    }
+
+    if ((link = skipstone_watch_link_open_serial(argv[1])) == NULL) {
+        goto error_watch_link_open;
+    }
+
+    while (skipstone_recv(link, buf, &len, &endpoint) >= 0) {
+        printf("Received message %hu bytes for endpoint %hu\n",
+            len, endpoint);
+
+        if (skipstone_send(link, &play_track, sizeof(play_track), 0x20) < 0) {
+            printf("Balls\n");
+        }
+    }
+
+    perror("skipstone_recv()");
+
+    skipstone_watch_link_close(link);
+
+    return 0;
+
+error_watch_link_open:
+    free(buf);
+
+error_malloc_buf:
+    return 1;
+}
diff --git a/examples/music.c-e b/examples/music.c-e
new file mode 100644
index 0000000..884918a
--- /dev/null
+++ b/examples/music.c-e
@@ -0,0 +1,82 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <skipstone/skipstone.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_watch_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, "KMFDM", 5, "Nihil", 5, "Ultra"
+    };
+
+    struct {
+        uint8_t command;
+        uint8_t package_len;
+        char package[8];
+        uint8_t name_len;
+        char name[8];
+    } play_info = {
+        0x13, 8, "DeaDBeeF", 8, "RealDead"
+    };
+
+    if (argc != 2) {
+        usage(argc, argv);
+    }
+
+    if ((buf = malloc(SKIPSTONE_MESSAGE_MAX_PAYLOAD)) == NULL) {
+        goto error_malloc_buf;
+    }
+
+    if ((link = skipstone_watch_link_open_serial(argv[1])) == NULL) {
+        goto error_watch_link_open;
+    }
+
+    while (skipstone_recv(link, buf, &len, &endpoint) >= 0) {
+        printf("Received message %hu bytes for endpoint %hu\n",
+            len, endpoint);
+
+        if (skipstone_send(link, &play_track, sizeof(play_track), 0x20) < 0) {
+            printf("Balls\n");
+        }
+    }
+
+    perror("skipstone_recv()");
+
+    skipstone_watch_link_close(link);
+
+    return 0;
+
+error_watch_link_open:
+    free(buf);
+
+error_malloc_buf:
+    return 1;
+}
diff --git a/src/skipstone.c b/src/skipstone.c
index 4459675..a089746 100644
--- a/src/skipstone.c
+++ b/src/skipstone.c
@@ -105,6 +105,11 @@ 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_message_header header;
 
+    ssize_t wrlen;
+
+     size_t remaining = (size_t)size,
+               offset = 0;
+
     if (size > SKIPSTONE_MESSAGE_MAX_PAYLOAD) {
         goto error_toobig;
     }
@@ -112,12 +117,17 @@ int skipstone_send(skipstone_watch_link *link, void *buf, uint16_t size, uint16_
     header.size     = htobe16(size);
     header.endpoint = htobe16(endpoint);
 
-    if (write(link->serial.fd, &header, sizeof(header)) < 0) {
+    if ((wrlen = write(link->serial.fd, &header, sizeof(header))) < 0) {
         goto error_io;
     }
 
-    if (write(link->serial.fd, buf, (size_t)size) < 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;
diff --git a/src/skipstone.c-e b/src/skipstone.c-e
index 4459675..a089746 100644
--- a/src/skipstone.c-e
+++ b/src/skipstone.c-e
@@ -105,6 +105,11 @@ 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_message_header header;
 
+    ssize_t wrlen;
+
+     size_t remaining = (size_t)size,
+               offset = 0;
+
     if (size > SKIPSTONE_MESSAGE_MAX_PAYLOAD) {
         goto error_toobig;
     }
@@ -112,12 +117,17 @@ int skipstone_send(skipstone_watch_link *link, void *buf, uint16_t size, uint16_
     header.size     = htobe16(size);
     header.endpoint = htobe16(endpoint);
 
-    if (write(link->serial.fd, &header, sizeof(header)) < 0) {
+    if ((wrlen = write(link->serial.fd, &header, sizeof(header))) < 0) {
         goto error_io;
     }
 
-    if (write(link->serial.fd, buf, (size_t)size) < 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;