#include #include #include #include "hook/iobuf.h" #include "hook/iohook.h" #include "hooklib/uart.h" #include "hooklib/fdshark.h" #include "util/dprintf.h" #include "util/dump.h" #include "board/bpreader.h" static HRESULT bp_handle_irp(struct irp *irp); static HRESULT bp_handle_irp_locked(struct irp *irp); static struct bpreader_config *config; static struct uart bp_uart; static CRITICAL_SECTION bp_lock; static uint8_t bp_written_bytes[520]; static uint8_t bp_readable_bytes[520]; static uint8_t last_cmd = 0; static uint16_t write_ct = 0; HRESULT bpreader_init(struct bpreader_config *cfg, uint16_t port) { config = cfg; if (!config->enable) { return S_OK; } if (cfg->port < 0) { port = cfg->port; } uart_init(&bp_uart, port); bp_uart.written.bytes = bp_written_bytes; bp_uart.written.nbytes = sizeof(bp_written_bytes); bp_uart.readable.bytes = bp_readable_bytes; bp_uart.readable.nbytes = sizeof(bp_readable_bytes); InitializeCriticalSection(&bp_lock); dprintf("Reader: Init\n"); return iohook_push_handler(bp_handle_irp); } void bpreader_congif_load(struct bpreader_config *cfg, const wchar_t *filename) { assert(cfg != NULL); assert(filename != NULL); cfg->enable = GetPrivateProfileIntW(L"reader", L"enable", 1, filename); cfg->port = GetPrivateProfileIntW(L"reader", L"port", 0, filename); GetPrivateProfileStringW( L"reader", L"access_code", L"", cfg->access_code, _countof(cfg->access_code), filename); } static HRESULT bp_handle_irp(struct irp *irp) { HRESULT hr; assert(irp != NULL); if (uart_match_irp(&bp_uart, irp)) { EnterCriticalSection(&bp_lock); hr = bp_handle_irp_locked(irp); LeaveCriticalSection(&bp_lock); } else { return iohook_invoke_next(irp); } return hr; } static HRESULT bp_handle_irp_locked(struct irp *irp) { HRESULT hr; if (irp->op == IRP_OP_OPEN) { dprintf("BNG Reader: Starting backend\n"); dprintf("Reader: Baudrate %ld\n", bp_uart.baud.BaudRate); } hr = uart_handle_irp(&bp_uart, irp); if (FAILED(hr)) { return hr; } #if 0 if (irp->op == IRP_OP_WRITE) { dprintf("WRITE:\n"); dump_iobuf(&bp_uart.written); } if (irp->op == IRP_OP_READ) { dprintf("READ:\n"); dump_iobuf(&bp_uart.readable); } #endif if (irp->op == IRP_OP_WRITE) { write_ct = 0; if (bp_uart.written.bytes[0] == 0x55) { dprintf("Reader: Hello\n"); return hr; } else if (bp_uart.written.bytes[3] == 0x00) { dprintf("Reader: Wait Next Cmd\n"); last_cmd = 0x00; return hr; } else { last_cmd = bp_uart.written.bytes[3]; dump_iobuf(&bp_uart.written); return hr; } } if (irp->op == IRP_OP_READ) { dprintf("Reader: last_cmd %d write_ct %d\n", last_cmd, write_ct); switch (last_cmd) { case 0x03: dprintf("Reader: Initalize Reader\n"); uint8_t buff_init[] = { 00, 00, 0xFF, 00, 0xFF, 00, 00, 00, 0xFF, 0x02, 0xFE, 0xD5, 0x19, 0x12, 0x00}; iobuf_write(&bp_uart.readable, buff_init, sizeof(buff_init)); bp_uart.written.pos = 0; break; case 0x06: dprintf("Reader: Unknown 0x06\n"); uint8_t buff_unk6_r1[] = { 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00 }; uint8_t buff_unk6_r2[] = { 0xFF, 0x02, 0xFE, 0xD5, 0x33, 0xF8, 0x00 }; if (!write_ct) { dprintf("Reader: Unknown 0x06 first write\n"); iobuf_write(&bp_uart.readable, buff_unk6_r1, sizeof(buff_unk6_r1)); } else { dprintf("Reader: Unknown 0x06 other write\n"); iobuf_write(&bp_uart.readable, buff_unk6_r2, sizeof(buff_unk6_r2)); } break; default: dprintf("Reader: Unknown Command %02X\n", last_cmd); dump_iobuf(&bp_uart.written); break; } write_ct++; } bp_uart.written.pos = 0; return hr; }