diff --git a/mc/hijacknet_extctrl2014.c b/mc/hijacknet_extctrl2014.c
index ba77d4e855ae5f84092851379a6f9c784efe67b7..5fd573c74f1e532f591b7c96ccb060fa47c34bea 100644
--- a/mc/hijacknet_extctrl2014.c
+++ b/mc/hijacknet_extctrl2014.c
@@ -91,16 +91,19 @@ static struct state {
     struct labcomm2014_writer writer;
     struct labcomm2014_writer_action_context action_context;
     struct labcomm2014_encoder *encoder;
-    int sequence;
+    SEM_ID sem;
+    unsigned int sequence;
     int unadjusted;
-    int need_ack;
+    int awaited_ack;
     int frag_start;
     unsigned char buffer[WRITE_BUFFER_SIZE];
   } writer;
   struct {
     struct labcomm2014_reader reader;
     struct labcomm2014_reader_action_context action_context;
+    struct labcomm2014_decoder *decoder;
     SEM_ID sem;
+    unsigned int sequence;
     int lpconsume;
     unsigned char buffer[READ_BUFFER_SIZE];
     unsigned int read_pos;
@@ -108,7 +111,6 @@ static struct state {
     unsigned int available;
   } reader;
   struct {
-    struct labcomm2014_decoder *decoder;
     int sequence;
     int fragment;
     int pos;
@@ -148,12 +150,6 @@ static struct state {
   extctrl2014_force_torque_net force_net;
 } state;
 
-#if 0
-
-#define PROTOCOL_ERROR					    \
-  printf("PROTOCOL ERROR %s:%d\n", __FUNCTION__, __LINE__); \
-  state->state = s_error;
-
 static inline unsigned int rdtsc()
 {
   // Since we have at least one system with broken rdtsc (high and low word
@@ -164,6 +160,20 @@ static inline unsigned int rdtsc()
   return result;
 }
 
+static inline unsigned int next_sequence(unsigned int sequence)
+{
+  do {
+    sequence++;
+  } while (sequence == 0);
+  return sequence;
+}
+
+#if 0
+
+#define PROTOCOL_ERROR					    \
+  printf("PROTOCOL ERROR %s:%d\n", __FUNCTION__, __LINE__); \
+  state->state = s_error;
+
 static int get_robot_index(axis_configuration_t ac)
 {
   int i;
@@ -998,12 +1008,13 @@ static int writer_start(
   printf("%s %p %p\n", __FUNCTION__, signature, value);
   w->pos = 0;
   state.writer.unadjusted = 1;
+  state.writer.sequence = next_sequence(state.writer.sequence);
   if (signature != NULL && value != NULL) {
     /* DATA packet */
-    state.writer.need_ack = 0;
+    state.writer.awaited_ack = 0;
     flags = kind_DATA | flag_LAST_FRAG;
   } else {
-    state.writer.need_ack = 1;
+    state.writer.awaited_ack = state.writer.sequence;
     if (signature == NULL && value == NULL) {
       /* INIT packet, labcomm not involved */
       flags = kind_INIT | flag_LAST_FRAG | flag_NEED_ACK;
@@ -1048,17 +1059,26 @@ static int writer_end(
     labcomm2014_write_packed32(w, 0); /* frag_num */
     labcomm2014_write_packed32(w, length); /* frag_length */
     offset = first - w->pos;
-    w->data[last] = 'X';
     memmove(&w->data[w->pos], &w->data[first], length);
     last = last - offset;
-    w->data[last] = 'Y';
     printf("%s %d %d %d %d\n", __FUNCTION__, first, last, length, offset);
+    while (last < 60) {
+      /* Null padding at end */
+      w->data[last] = 0;
+      last++;
+    }
     w->pos = last;
   }
   printf("%s %d\n", __FUNCTION__, w->pos);
-  hijacknet_send(state.driver, w->data, w->pos);
-
-  taskDelay(1000);
+  while (1) {
+    printf("!%x\n", state.writer.awaited_ack);
+    hijacknet_send(state.driver, w->data, w->pos);
+    if (state.writer.awaited_ack == 0) {
+      break;
+    } else {
+      semTake(state.writer.sem, 1000);
+    }
+  }
   return w->error;
 }
 
@@ -1183,10 +1203,12 @@ static int lp_consume()
   unsigned int avail;
 
   while (1) {
-    semTake(state.reader.sem, 1000);
     avail = (state.reader.write_pos - state.reader.read_pos) % READ_BUFFER_SIZE;
-    if (avail > 2) {
+    if (avail <= 2) {
+      semTake(state.reader.sem, 1000);
+    } else {
       unsigned int length, pos, sane, i, channel, cookie, index;
+      unsigned int frag_num, frag_length;
       unsigned short id;
       unsigned char flags;
       
@@ -1230,8 +1252,10 @@ static int lp_consume()
       sane &= (channel == state.channel);
       cookie = labcomm2014_read_int(&state.reader.reader);
       index = labcomm2014_read_int(&state.reader.reader);
+      frag_num = labcomm2014_read_packed32(&state.reader.reader);
+      frag_length = labcomm2014_read_packed32(&state.reader.reader);
 
-      printf("sane=%d flags=%02x channel=%d cookie=%x index=%u\n",
+      printf("sane=%d flags=%02x channel=%d cookie=%x index=%x\n",
              sane, flags, channel, cookie, index);
 
       if (!sane) { goto out; }
@@ -1240,11 +1264,18 @@ static int lp_consume()
         goto out;
       }
       if ((flags & flag_IS_ACK) != 0) {
-        if (index == state.ack) {
-          self.ack = 0;
-          NOTIFY;
+        if ((flags & kind_MASK) == kind_INIT && state.reader.sequence == 0) {
+          unsigned int remote_index;
+          remote_index = labcomm2014_read_int(&state.reader.reader);
+          state.reader.sequence = remote_index;
+          state.cookie = state.reader.sequence ^ state.writer.sequence;
+          printf("remote_index=%x cookie=%x\n", remote_index, state.cookie);
+        }
+        if (index == state.writer.awaited_ack) {
+          state.writer.awaited_ack = 0;
+          semGive(state.writer.sem);
         }
-        if (index ==
+      }
       /* Decode one package */
       
 
@@ -1437,6 +1468,8 @@ int hijacknet_extctrl2014_connect(char *interface,
   state.mutex = semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE);
   state.sem = semBCreate(0, 0);
   state.sem_communicate = semBCreate(0, 0);
+  state.writer.sem = semBCreate(0, 0);
+  state.writer.sequence = rdtsc();
   state.reader.sem = semBCreate(0, 0);
 
   /* Enumerate signatures, since no proper code init in VxWorks */
@@ -1463,10 +1496,6 @@ int hijacknet_extctrl2014_connect(char *interface,
                            0, NULL, NULL);
   labcomm2014_writer_end(&state.writer.writer,
                          state.writer.writer.action_context);
-  /* Immediate retry... */
-  taskDelay(1000);
-  labcomm2014_writer_end(&state.writer.writer,
-                         state.writer.writer.action_context);
 
   /* register data types */
   state.writer.encoder = labcomm2014_encoder_new(
@@ -1478,7 +1507,7 @@ int hijacknet_extctrl2014_connect(char *interface,
     state.writer.encoder);
   labcomm2014_encoder_register_extctrl2014_force_torque_net(
     state.writer.encoder);    
-  taskDelay(10000);
+  taskDelay(30000);
   labcomm2014_encoder_free(state.writer.encoder);
   hijacknet_del_receive_hook(state.driver, EXTCTRL2015_ETH_ID,
                              receive_hook, NULL);