BOOL AppProtocolHandleIncoming(const BYTE* data, UINT32 data_len) { assert(data); if (state != STATE_OPEN) { log_printf("Shouldn't get data after close!"); return FALSE; } while (data_len > 0) { // copy a chunk of data to rx_msg if (data_len >= rx_message_remaining) { memcpy(((BYTE *) &rx_msg) + rx_buffer_cursor, data, rx_message_remaining); data += rx_message_remaining; data_len -= rx_message_remaining; rx_buffer_cursor += rx_message_remaining; rx_message_remaining = 0; } else { memcpy(((BYTE *) &rx_msg) + rx_buffer_cursor, data, data_len); rx_buffer_cursor += data_len; rx_message_remaining -= data_len; data_len = 0; } // change state if (rx_message_remaining == 0) { switch (rx_message_state) { case WAIT_TYPE: rx_message_state = WAIT_ARGS; rx_message_remaining = incoming_arg_size[rx_msg.type]; if (rx_message_remaining) break; // fall-through on purpose case WAIT_ARGS: rx_message_state = WAIT_VAR_ARGS; rx_message_remaining = IncomingVarArgSize(&rx_msg); if (rx_message_remaining) break; // fall-through on purpose case WAIT_VAR_ARGS: rx_message_state = WAIT_TYPE; rx_message_remaining = 1; rx_buffer_cursor = 0; if (!MessageDone()) return FALSE; break; } } } return TRUE; }
bool BootProtocolProcess(const void* data, size_t data_len) { assert(!data_len || data); while (data_len > 0) { if (data_len >= rx_message_remaining) { if (rx_message_state == WAIT_FILE) { int i; for (i = 0; i < rx_message_remaining; ++i) file_checksum += ((const uint8_t *) data)[i]; if (!IOIOFileHandleBuffer(data, rx_message_remaining)) return false; } else { // copy a chunk of data to rx_msg memcpy(((BYTE *) &rx_msg) + rx_buffer_cursor, data, rx_message_remaining); rx_buffer_cursor += rx_message_remaining; } data += rx_message_remaining; data_len -= rx_message_remaining; rx_message_remaining = 0; } else { if (rx_message_state == WAIT_FILE) { int i; for (i = 0; i < data_len; ++i) file_checksum += ((const uint8_t *) data)[i]; if (!IOIOFileHandleBuffer(data, data_len)) return false; } else { // copy a chunk of data to rx_msg memcpy(((BYTE *) &rx_msg) + rx_buffer_cursor, data, data_len); rx_buffer_cursor += data_len; } rx_message_remaining -= data_len; data_len = 0; } // change state if (rx_message_remaining == 0) { switch (rx_message_state) { case WAIT_TYPE: rx_message_state = WAIT_ARGS; if (rx_msg.type >= MESSAGE_TYPE_LIMIT) { log_printf("Unexpected message type: 0x%x", rx_msg.type); return false; } rx_message_remaining = incoming_arg_size[rx_msg.type]; if (rx_message_remaining) break; // fall-through on purpose case WAIT_ARGS: rx_message_state = WAIT_TYPE; rx_message_remaining = 1; rx_buffer_cursor = 0; if (!MessageDone()) return false; if (rx_message_remaining) break; // fall-through on purpose case WAIT_FILE: if (!IOIOFileDone()) { log_printf("Unexpected end of file"); return false; } else { log_printf("Image done successfully"); } SendChecksum(file_checksum); rx_message_state = WAIT_TYPE; rx_message_remaining = 1; break; } } } return true; }