gigaboot: Update to the 1.1 version of the protocol.

Change-Id: If876562f56ab94fe06afca35611b6e32ab5926ff
diff --git a/src/net/gigaboot/gigaboot.c b/src/net/gigaboot/gigaboot.c
index 5d1414f..720b163 100644
--- a/src/net/gigaboot/gigaboot.c
+++ b/src/net/gigaboot/gigaboot.c
@@ -48,11 +48,15 @@
 
 enum {
 	GigabootVersion_1_0 = 0x0001000,
+	GigabootVersion_1_1 = 0x0001010,
+	GigabootVersion_Current = GigabootVersion_1_1,
 };
 
 enum {
 	// Used to acknowledge receipt of a command.
 	GigabootAck = 0,
+	// Used to acknowledge the receipt of all a file's data.
+	GigabootFileReceived = 0x70000001,
 	// Doesn't do anything.
 	GigabootCommandCommand = 1,
 	// Start receiving a file.
@@ -61,6 +65,8 @@
 	GigabootCommandData = 3,
 	// Boot using the data received so far.
 	GigabootCommandBoot = 4,
+	// Receive the last chunk of data for the file started with SendFile.
+	GigabootCommandLastData = 11,
 };
 
 typedef struct {
@@ -162,6 +168,8 @@
 	state->ack.cookie = msg->hdr.cookie;
 	state->ack.arg = msg->hdr.arg;
 
+	int send_ack = 1;
+
 	switch (msg->hdr.command) {
 	case GigabootCommandCommand:
 		if (data_size == 0)
@@ -192,18 +200,30 @@
 		break;
 
 	case GigabootCommandData:
+	case GigabootCommandLastData:
 		if (!state->buffer)
 			return;
-		if (msg->hdr.arg != state->buffer->offset)
-			return;
-		if (state->buffer->offset + data_size > state->buffer->size) {
+		if (msg->hdr.arg != state->buffer->offset) {
+			printf("gigaboot: received chunk at offset %d but "
+			       "current offset is %zu\n",
+			       msg->hdr.arg, state->buffer->offset);
+			state->ack.arg = state->buffer->offset;
+			state->ack.command = GigabootAck;
+		} else if (state->buffer->offset + data_size >
+			   state->buffer->size) {
 			state->ack.command = GigabootErrorTooLarge;
+			state->ack.arg = msg->hdr.arg;
 		} else {
 			memcpy((uint8_t *)state->buffer->data +
 				state->buffer->offset,
 			       msg->data, data_size);
 			state->buffer->offset += data_size;
-			state->ack.command = GigabootAck;
+			if (msg->hdr.command == GigabootCommandLastData) {
+				state->ack.command = GigabootFileReceived;
+			} else {
+				state->ack.command = GigabootAck;
+				send_ack = 0;
+			}
 		}
 		break;
 
@@ -228,7 +248,8 @@
 		state->ack.arg = 0;
 	}
 
-	netcon_send(state->con, &state->ack, sizeof(state->ack));
+	if (send_ack)
+		netcon_send(state->con, &state->ack, sizeof(state->ack));
 }
 
 
@@ -240,7 +261,7 @@
 static void gigaboot_advertise(GigabootState *state)
 {
 	static const char ad_data[] =
-		"version\01.0\0"
+		"version\01.1\0"
 		"serialno\0unknown\0"
 		"board\0unknown\0";
 
@@ -252,7 +273,7 @@
 			.magic = GigabootMagic,
 			.cookie = 0,
 			.command = GigabootAdvertise,
-			.arg = GigabootVersion_1_0,
+			.arg = GigabootVersion_Current,
 		},
 	};
 	if (!ad_message.data[0])