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