  *
  * is valid.
  */ 
+
+#define CHECK_ABORT()     do { if (Sync.abort) return; } while (0);
+
 void sync_listen() {
-  uint8_t readpos = 0;
-  for (readpos = 0; Serial.available() && readpos < sizeof(_sbuf)-1; ++readpos) {
-    _sbuf[readpos] = Serial.read();
-  }
+  Sync.abort = 0;
+  if (Serial.available()) {
+    if (sync_get_word("SYNC;") == OK) {
+      Serial.println("SYNC START");
+    } else {
+      sync_abort("SYNC; expected");
+      return;
+    }
 
-  if (readpos == 0) return;
-  
-  _sbuf[readpos] = '\0';
+    uint8_t hours = sync_get_int();
+    uint8_t minutes = sync_get_int();
+    uint8_t seconds = sync_get_int();
 
-  if (strstr(_sbuf, "SYNC;") == _sbuf) {
-    // we have start of sync, yay
-    char *sptr = _sbuf+5;
-    Serial.println("Starting SYNC");
-  } else sync_abort("SYNC; expected");
+    CHECK_ABORT();
+
+    sprintf(_sbuf, "Time: %02d:%02d:%02d\n", hours, minutes, seconds);
+    Serial.print(_sbuf);
+  } 
 }

#define SYNC_TEXT_COLOR     (COLOR_WHITE)

#define SYNC_DELIMITER      ';'

void sync_init() {
}

void sync_abort(char *msg) {
  Serial.print("SYNC aborted:");
  Serial.println(msg);
}

int8_t sync_blocking_read() {
  int8_t c;
  uint16_t startt = millis();

  do {
    c = Serial.read();
    if (millis() - startt > SYNC_SERIAL_TIMEOUT) {
      sync_abort("communication timed out");
      Sync.abort = 1;
      break;
    }
  } while (c == -1);
  return c;
}

/**
 * Looks for the given word in the serial input.
 */ 
uint8_t sync_get_word(char *w) {
  char *p = w;
  uint8_t c;
  while(*p && Sync.abort == 0) {
    c = sync_blocking_read();
    if (c == *p) p++;
    else return ERROR;
  }

  return OK;
}

/**
 * Reads serial stream until SYNC_DELIMITER is found or out of space, then
 * uses atoi to convert the string into an integer, returning the result.
 */
int16_t sync_get_int() {
  uint8_t readpos = 0;
  uint8_t c;
  do {
    c = sync_blocking_read();
    if (c == SYNC_DELIMITER) break;
    else _sbuf[readpos++] = c;
  } while (readpos < sizeof(_sbuf)-1 && Sync.abort == 0);

  _sbuf[readpos] = '\0';
  return atoi(_sbuf);
}

/**
