diff --git a/carolhook/controlbd.c b/carolhook/controlbd.c index 44fa5a6e..793b0f83 100644 --- a/carolhook/controlbd.c +++ b/carolhook/controlbd.c @@ -21,7 +21,9 @@ static HRESULT controlbd_handle_irp_locked(struct irp *irp); static HRESULT controlbd_frame_decode(struct controlbd_req *dest, struct iobuf *iobuf); static HRESULT controlbd_frame_dispatch(struct controlbd_req *dest); -static HRESULT controlbd_req_nop(uint8_t cmd); +static HRESULT controlbd_req_noop(uint8_t cmd); +static HRESULT controlbd_req_unk7c(uint8_t cmd); +static HRESULT controlbd_req_unkF0(uint8_t cmd); static CRITICAL_SECTION controlbd_lock; static struct uart controlbd_uart; @@ -76,7 +78,7 @@ static HRESULT controlbd_handle_irp_locked(struct irp *irp) hr = carol_dll.controlbd_init(); if (FAILED(hr)) { - dprintf("Control Board: Backend DLL error: %x\n", (int) hr); + dprintf("Control Board: Backend DLL error: 0X%X\n", (int) hr); return hr; } @@ -96,14 +98,14 @@ static HRESULT controlbd_handle_irp_locked(struct irp *irp) hr = controlbd_frame_decode(&req, &controlbd_uart.written); if (FAILED(hr)) { - dprintf("Control Board: Deframe Error: %x\n", (int) hr); + dprintf("Control Board: Deframe Error: 0X%X\n", (int) hr); return hr; } hr = controlbd_frame_dispatch(&req); if (FAILED(hr)) { - dprintf("Control Board: Dispatch Error: %x\n", (int) hr); + dprintf("Control Board: Dispatch Error: 0X%X\n", (int) hr); return hr; } @@ -115,62 +117,104 @@ static HRESULT controlbd_handle_irp_locked(struct irp *irp) static HRESULT controlbd_frame_dispatch(struct controlbd_req *req) { switch (req->cmd) { - case CONTROLBD_CMD_UNK_11: - return controlbd_req_nop(req->cmd); + case CONTROLBD_CMD_UNK_10: + return controlbd_req_noop(req->cmd); + case CONTROLBD_CMD_UNK_7C: + return controlbd_req_unk7c(req->cmd); + case CONTROLBD_CMD_UNK_F0: + return controlbd_req_unkF0(req->cmd); + case CONTROLBD_CMD_UNK_30: + return controlbd_req_noop(req->cmd); default: - dprintf("Unhandled command %#02x\n", req->cmd); - - return S_OK; + dprintf("Unhandled command 0x%02X\n", req->cmd); + return controlbd_req_noop(req->cmd); } } -static HRESULT controlbd_req_nop(uint8_t cmd) +static HRESULT controlbd_req_noop(uint8_t cmd) { - dprintf("Control Board: No-op cmd %#02x\n", cmd); - - controlbd_uart.readable.bytes[controlbd_uart.readable.pos++] = 0xE0; - controlbd_uart.readable.bytes[controlbd_uart.readable.pos++] = 0x01; - controlbd_uart.readable.bytes[controlbd_uart.readable.pos++] = 0x11; - controlbd_uart.readable.bytes[controlbd_uart.readable.pos++] = 0x03; - controlbd_uart.readable.bytes[controlbd_uart.readable.pos++] = 0x01; - controlbd_uart.readable.bytes[controlbd_uart.readable.pos++] = 0x10; - controlbd_uart.readable.bytes[controlbd_uart.readable.pos++] = 0x01; - controlbd_uart.readable.bytes[controlbd_uart.readable.pos++] = 0x27; + dprintf("Control Board: Noop cmd 0x%02X\n", cmd); + uint8_t resp[] = { 0xE0, 0x01, 0x11, 0x03, 0x01, 0x00, 0x01, 0x17 }; + resp[5] = cmd; + resp[7] = 0x17 + cmd; + iobuf_write(&controlbd_uart.readable, resp, 8); return S_OK; } -/* Decodes the response into a struct that's easier to work with. */ +static HRESULT controlbd_req_unk7c(uint8_t cmd) +{ + dprintf("Control Board: Cmd 0x7C\n"); + uint8_t resp[] = { 0xE0, 0x01, 0x11, 0x04, 0x01, 0x7C, 0x01, 0x07, 0x9B }; + iobuf_write(&controlbd_uart.readable, resp, 9); + + return S_OK; +} + +static HRESULT controlbd_req_unkF0(uint8_t cmd) +{ + dprintf("Control Board: Cmd 0xF0\n"); + uint8_t resp[] = { 0xE0, 0x01, 0x11, 0x0A, 0x01, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E }; + iobuf_write(&controlbd_uart.readable, resp, 16); + + return S_OK; +} + +/* Decodes the response into a struct that's easier to work with. TODO: Further validation */ static HRESULT controlbd_frame_decode(struct controlbd_req *dest, struct iobuf *iobuf) { int initial_pos = iobuf->pos; - uint8_t check = 0; + int processed_pos = 0; + uint8_t check = 0; + bool escape = false; + dump_iobuf(iobuf); dest->sync = iobuf->bytes[0]; - iobuf->pos--; - dest->cmd = iobuf->bytes[1]; - iobuf->pos--; + dest->dest = iobuf->bytes[1]; + check += dest->dest; + + dest->src = iobuf->bytes[2]; + check += dest->src; + + dest->data_len = iobuf->bytes[3]; + check += dest->data_len; + + dest->cmd = iobuf->bytes[4]; check += dest->cmd; - dest->checksum = iobuf->bytes[initial_pos - 1]; - iobuf->pos--; - - dest->data_length = initial_pos - 3; // sync, cmd, checksum - if (dest->data_length > 0) { - for (int i = 0; i < dest->data_length; i++) { - dest->data[i] = iobuf->bytes[i+2]; + if (dest->data_len > 1) { + for (int i = 0; i < iobuf->pos - 6; i++) { + if (iobuf->bytes[i+6] == 0xD0) { + escape = true; + } + + dest->data[i] = iobuf->bytes[i+6]; + + if (escape) { + dest->data[i]++; + escape = false; + } + check += dest->data[i]; } + } - iobuf->pos -= dest->data_length; + dest->checksum = iobuf->bytes[iobuf->pos - 1]; + if (escape) { + dest->checksum++; + escape = false; + } + + iobuf->pos = 0; if (dest->sync != 0xe0) { - dprintf("Control Board: Sync error, expected 0xe0, got %x\n", dest->sync); + dprintf("Control Board: Sync error, expected 0xe0, got 0X%02X\n", dest->sync); return E_FAIL; } - if (dest->checksum != check) { - dprintf("Control Board: Checksum error, expected %x, got %x\n", check, dest->checksum); + + if (dest->checksum != (check & 0xFF)) { + dprintf("Control Board: Checksum error, expected 0X%02X, got 0X%02X\n", dest->checksum, check); return E_FAIL; } diff --git a/carolhook/controlbd.h b/carolhook/controlbd.h index 500efd7e..16c3280a 100644 --- a/carolhook/controlbd.h +++ b/carolhook/controlbd.h @@ -7,15 +7,22 @@ struct controlbd_config { bool enable; }; + enum controlbd_cmd { - CONTROLBD_CMD_UNK_11 = 0x11 + CONTROLBD_CMD_UNK_10 = 0x10, + CONTROLBD_CMD_UNK_7C = 0x7C, + CONTROLBD_CMD_UNK_30 = 0x30, + CONTROLBD_CMD_UNK_F0 = 0xF0, }; + struct controlbd_req { - uint8_t sync; // First byte is the sync - uint8_t cmd; // Command byte - uint8_t data[256]; // Request body goes here - uint8_t checksum; // Final byte is all bytes added, except the sync - uint8_t data_length; // Size of the data including command byte + uint8_t sync; // Sync byte, always 0xE0 + uint8_t dest; // command destination id? + uint8_t src; // command source id? + uint8_t data_len; // length of the proceeding data bytes + uint8_t cmd; // might be the command byte? + uint8_t data[255]; // rest of the data, len = data_len - 1 + uint8_t checksum; // final byte is all bytes (excluding sync) added }; HRESULT controlbd_hook_init(const struct controlbd_config *cfg); \ No newline at end of file diff --git a/carolhook/touch.c b/carolhook/touch.c index 8cbb8cae..83d184d1 100644 --- a/carolhook/touch.c +++ b/carolhook/touch.c @@ -71,7 +71,7 @@ static HRESULT touch_handle_irp_locked(struct irp *irp) hr = carol_dll.touch_init(); if (FAILED(hr)) { - dprintf("Touchscreen: Backend DLL error: %x\n", (int) hr); + dprintf("Touchscreen: Backend DLL error: %X\n", (int) hr); return hr; } @@ -91,7 +91,7 @@ static HRESULT touch_handle_irp_locked(struct irp *irp) hr = touch_frame_decode(&req, &touch_uart.written); if (FAILED(hr)) { - dprintf("Touchscreen: Deframe Error: %x\n", (int) hr); + dprintf("Touchscreen: Deframe Error: %X\n", (int) hr); return hr; }