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])