being mapping bpreader
This commit is contained in:
parent
aad6f5a922
commit
3c1c7aa469
197
board/bpreader.c
197
board/bpreader.c
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
static HRESULT bp_handle_irp(struct irp *irp);
|
static HRESULT bp_handle_irp(struct irp *irp);
|
||||||
static HRESULT bp_handle_irp_locked(struct irp *irp);
|
static HRESULT bp_handle_irp_locked(struct irp *irp);
|
||||||
|
static HRESULT crack_bpreader_request();
|
||||||
|
|
||||||
static struct bpreader_config *config;
|
static struct bpreader_config *config;
|
||||||
static struct uart bp_uart;
|
static struct uart bp_uart;
|
||||||
@ -22,7 +23,7 @@ static CRITICAL_SECTION bp_lock;
|
|||||||
static uint8_t bp_written_bytes[520];
|
static uint8_t bp_written_bytes[520];
|
||||||
static uint8_t bp_readable_bytes[520];
|
static uint8_t bp_readable_bytes[520];
|
||||||
static uint8_t last_cmd = 0;
|
static uint8_t last_cmd = 0;
|
||||||
static uint16_t write_ct = 0;
|
static uint16_t read_ct = 0;
|
||||||
|
|
||||||
HRESULT bpreader_init(struct bpreader_config *cfg, uint16_t port)
|
HRESULT bpreader_init(struct bpreader_config *cfg, uint16_t port)
|
||||||
{
|
{
|
||||||
@ -90,38 +91,37 @@ static HRESULT bp_handle_irp_locked(struct irp *irp)
|
|||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (irp->op == IRP_OP_WRITE) {
|
if (irp->op == IRP_OP_WRITE) {
|
||||||
dprintf("WRITE:\n");
|
dprintf("WRITE:\n");
|
||||||
dump_iobuf(&bp_uart.written);
|
dump_iobuf(&bp_uart.written);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (irp->op == IRP_OP_WRITE) {
|
if (irp->op == IRP_OP_WRITE) {
|
||||||
write_ct = 0;
|
read_ct = 0;
|
||||||
if (bp_uart.written.bytes[0] == 0x55) {
|
if (bp_uart.written.bytes[0] == 0x55) {
|
||||||
dprintf("Reader: Hello\n");
|
dprintf("Reader: Hello\n");
|
||||||
return hr;
|
bp_uart.written.pos = 0; // consume the written buffer
|
||||||
}
|
}
|
||||||
else if (bp_uart.written.bytes[3] == 0x00) {
|
else if (bp_uart.written.bytes[3] == 0x00) {
|
||||||
dprintf("Reader: Wait Next Cmd\n");
|
bp_uart.written.pos = 0; // consume the written buffer
|
||||||
last_cmd = 0x00;
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
last_cmd = bp_uart.written.bytes[3];
|
|
||||||
dprintf("Reader: Wrote Cmd %X\n", last_cmd);
|
|
||||||
return hr;
|
|
||||||
}
|
}
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (irp->op == IRP_OP_READ) {
|
else if (irp->op == IRP_OP_READ) {
|
||||||
dprintf("Reader: last_cmd %02X write_ct %d\n", last_cmd, write_ct);
|
if (!read_ct) {
|
||||||
switch (last_cmd) {
|
dump_iobuf(&bp_uart.written);
|
||||||
|
hr = crack_bpreader_request();
|
||||||
|
}
|
||||||
|
switch (bp_uart.written.bytes[3]) {
|
||||||
case 0x02:
|
case 0x02:
|
||||||
dprintf("Reader: Unknown 0x02\n");
|
if (!read_ct) {
|
||||||
if (!write_ct) {
|
dprintf("Reader: Unknown 0x02\n");
|
||||||
uint8_t buff[] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x05,
|
uint8_t buff[] = { 0x00, 0x00, 0xFF, 0x05,
|
||||||
0xfb, 0xd5, 0x0d, 0x00, 0x06, 0x00, 0x18, 0x00 };
|
0xFB, 0xD5, 0x0D, 0x00, 0x06, 0x00, 0x18, 0x00 };
|
||||||
hr = iobuf_write(&bp_uart.readable, buff, sizeof(buff));
|
hr = iobuf_write(&bp_uart.readable, buff, sizeof(buff));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,9 +129,9 @@ static HRESULT bp_handle_irp_locked(struct irp *irp)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x03:
|
case 0x03:
|
||||||
if (!write_ct) {
|
if (!read_ct) {
|
||||||
dprintf("Reader: Initalize Reader\n");
|
dprintf("Reader: Unknown 0x03\n");
|
||||||
uint8_t buff[] = { 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x02,
|
uint8_t buff[] = { 0x00, 0x00, 0xFF, 0x02,
|
||||||
0xFE, 0xD5, 0x19, 0x12, 0x00 };
|
0xFE, 0xD5, 0x19, 0x12, 0x00 };
|
||||||
hr = iobuf_write(&bp_uart.readable, buff, sizeof(buff));
|
hr = iobuf_write(&bp_uart.readable, buff, sizeof(buff));
|
||||||
}
|
}
|
||||||
@ -139,16 +139,25 @@ static HRESULT bp_handle_irp_locked(struct irp *irp)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x04:
|
case 0x04:
|
||||||
case 0x06:
|
if (!read_ct && bp_uart.written.bytes[6] == 0x0E && last_cmd == 0x04) {
|
||||||
if (!write_ct && bp_uart.written.bytes[6] == 0x0e && last_cmd == 0x04) {
|
|
||||||
dprintf("Reader: Unknown second 0x04\n");
|
dprintf("Reader: Unknown second 0x04\n");
|
||||||
uint8_t buff[] = { 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x02,
|
uint8_t buff[] = { 0x00, 0x00, 0xFF, 0x02,
|
||||||
0xFE, 0xD5, 0x0F, 0x1C, 0x00 };
|
0xFE, 0xD5, 0x0F, 0x1C, 0x00 };
|
||||||
hr = iobuf_write(&bp_uart.readable, buff, sizeof(buff));
|
hr = iobuf_write(&bp_uart.readable, buff, sizeof(buff));
|
||||||
}
|
}
|
||||||
else if (!write_ct) {
|
else if (!read_ct) {
|
||||||
dprintf("Reader: Unknown 0x06/0x04\n");
|
dprintf("Reader: Unknown 0x04\n");
|
||||||
uint8_t buff[] = { 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x02,
|
uint8_t buff[] = { 0x00, 0x00, 0xFF, 0x02,
|
||||||
|
0xFE, 0xD5, 0x33, 0xF8, 0x00 };
|
||||||
|
hr = iobuf_write(&bp_uart.readable, buff, sizeof(buff));
|
||||||
|
}
|
||||||
|
bp_uart.written.pos = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x06:
|
||||||
|
if (!read_ct) {
|
||||||
|
dprintf("Reader: Unknown 0x06\n");
|
||||||
|
uint8_t buff[] = { 0x00, 0x00, 0xFF, 0x02,
|
||||||
0xFE, 0xD5, 0x33, 0xF8, 0x00 };
|
0xFE, 0xD5, 0x33, 0xF8, 0x00 };
|
||||||
hr = iobuf_write(&bp_uart.readable, buff, sizeof(buff));
|
hr = iobuf_write(&bp_uart.readable, buff, sizeof(buff));
|
||||||
}
|
}
|
||||||
@ -156,31 +165,97 @@ static HRESULT bp_handle_irp_locked(struct irp *irp)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x05:
|
case 0x05:
|
||||||
if (!write_ct) {
|
if (!read_ct) {
|
||||||
dprintf("Reader: Unknown 0x05\n");
|
dprintf("Reader: Unknown 0x05\n");
|
||||||
uint8_t buff[] = { 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x03,
|
uint8_t buff[] = { 0x00, 0x00, 0xFF, 0x03,
|
||||||
0xFD, 0xD5, 0x09, 0x00, 0x22, 0x00 };
|
0xFD, 0xD5, 0x09, 0x00, 0x22, 0x00 };
|
||||||
hr = iobuf_write(&bp_uart.readable, buff, sizeof(buff));
|
hr = iobuf_write(&bp_uart.readable, buff, sizeof(buff));
|
||||||
}
|
}
|
||||||
bp_uart.written.pos = 0;
|
bp_uart.written.pos = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0x09:
|
||||||
|
if (!read_ct) {
|
||||||
|
dprintf("Reader: Poll card\n");
|
||||||
|
uint8_t buff[37] = {};
|
||||||
|
if (GetAsyncKeyState(VK_RETURN) & 0x8000) {
|
||||||
|
dprintf("Reader: Touch card %ls\n", config->access_code);
|
||||||
|
uint8_t buff2[] = {
|
||||||
|
0x00, 0x00, 0xFF, 0x18, 0xE8, 0xD5, 0x4B, 0x01, 0x01, 0x14, 0x01, // Data
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // IDm
|
||||||
|
0x00, 0xF1, 0x00, 0x00, 0x00, 0x01, 0x43, 0x00, // PMm
|
||||||
|
0x88, 0xB4, // System Code
|
||||||
|
0x00, 0x00 };
|
||||||
|
/*uint8_t buff2[] = {
|
||||||
|
0x00, 0x00, 0xFF, 0x0C, 0xF4, 0xD5, 0x4B, 0x01, 0x01,
|
||||||
|
0x00, 0x04, // ATQA
|
||||||
|
0x08, //SAK
|
||||||
|
0x04, // Unknown
|
||||||
|
0x42, 0xF0, 0xE7, 0x05, // S/N
|
||||||
|
0xB0, 0x00 }; // Footer*/
|
||||||
|
memcpy_s(buff, sizeof(buff), buff2, sizeof(buff2));
|
||||||
|
} else {
|
||||||
|
uint8_t buff2[] = { 0x00, 0x00, 0xFF, 0x03, 0xFD, 0xD5, 0x4B, 0x00, 0xE0, 0x00 };
|
||||||
|
memcpy_s(buff, sizeof(buff), buff2, sizeof(buff2));
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = iobuf_write(&bp_uart.readable, buff, sizeof(buff));
|
||||||
|
}
|
||||||
|
bp_uart.written.pos = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x0E:
|
||||||
|
if (!read_ct) {
|
||||||
|
dprintf("Reader: Unknown 0x0E\n");
|
||||||
|
uint8_t buff[] = { 0x00, 0x00, 0xff, 0x02,
|
||||||
|
0xfe, 0xd5, 0x33, 0xf8, 0x00 };
|
||||||
|
hr = iobuf_write(&bp_uart.readable, buff, sizeof(buff));
|
||||||
|
}
|
||||||
|
bp_uart.written.pos = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
case 0x12:
|
case 0x12:
|
||||||
if (!write_ct) {
|
if (!read_ct) {
|
||||||
dprintf("Reader: Unknown 0x12\n");
|
dprintf("Reader: Unknown 0x12\n");
|
||||||
uint8_t buff[] = { 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x0a,
|
uint8_t buff[] = { 0x00, 0x00, 0xFF, 0x0a,
|
||||||
0xf6, 0xd5, 0x07, 0xff, 0x3f, 0x0e, 0xf1, 0xff, 0x3f, 0x0e, 0xf1, 0xaa, 0x00 };
|
0xf6, 0xd5, 0x07, 0xff, 0x3f, 0x0e, 0xf1, 0xff, 0x3f, 0x0e, 0xf1, 0xaa, 0x00 };
|
||||||
hr = iobuf_write(&bp_uart.readable, buff, sizeof(buff));
|
hr = iobuf_write(&bp_uart.readable, buff, sizeof(buff));
|
||||||
}
|
}
|
||||||
bp_uart.written.pos = 0;
|
bp_uart.written.pos = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0x14:
|
||||||
|
if (!read_ct) {
|
||||||
|
dprintf("Reader: Unknown 0x14\n");
|
||||||
|
uint8_t buff[] = { 0x00, 0x00, 0xFF, 0x20, 0xE0, 0xD5, 0xA1,
|
||||||
|
0x00, 0x1D, 0x07, // Unknown
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // IDm
|
||||||
|
0x00, 0x00, 0x01, // Unknown
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // IDm
|
||||||
|
0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Unknown
|
||||||
|
0x00, 0x00 };
|
||||||
|
hr = iobuf_write(&bp_uart.readable, buff, sizeof(buff));
|
||||||
|
}
|
||||||
|
bp_uart.written.pos = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x18:
|
||||||
|
if (!read_ct) {
|
||||||
|
dprintf("Reader: Unknown 0x18\n");
|
||||||
|
uint8_t buff[] = { 0x00, 0x00, 0xFF, 0x0D,
|
||||||
|
0xF3, 0xD5, 0x07, 0xDC, 0xF4, 0x3F, 0x11, 0x4D, 0x85, 0x61, 0xF1, 0x26,
|
||||||
|
0x6A, 0x87, 0xC9, 0x00 };
|
||||||
|
hr = iobuf_write(&bp_uart.readable, buff, sizeof(buff));
|
||||||
|
}
|
||||||
|
bp_uart.written.pos = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
dprintf("Reader: Unknown Command %02X\n", last_cmd);
|
dprintf("Reader: Unknown Command %02X\n", last_cmd);
|
||||||
dump_iobuf(&bp_uart.written);
|
dump_iobuf(&bp_uart.written);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
write_ct++;
|
read_ct++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
@ -197,3 +272,61 @@ static HRESULT bp_handle_irp_locked(struct irp *irp)
|
|||||||
bp_uart.written.pos = 0; // consume the written buffer
|
bp_uart.written.pos = 0; // consume the written buffer
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT crack_bpreader_request() {
|
||||||
|
struct bpreader_cmd_header header = { bp_uart.written.bytes[0], bp_uart.written.bytes[1], bp_uart.written.bytes[2],
|
||||||
|
bp_uart.written.bytes[3], bp_uart.written.bytes[4], bp_uart.written.bytes[5], bp_uart.written.bytes[6],
|
||||||
|
};
|
||||||
|
|
||||||
|
assert(header.padding0_00 == 0);
|
||||||
|
assert(header.padding1_00 == 0);
|
||||||
|
assert(header.padding2_ff == 0xFF);
|
||||||
|
assert(header.d_identifier == 0xD4);
|
||||||
|
|
||||||
|
switch(header.cmd) {
|
||||||
|
case 0x06:
|
||||||
|
dprintf("Reader: Cmd 0x06\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x08:
|
||||||
|
dprintf("Reader: Cmd 0x08\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x12:
|
||||||
|
dprintf("Reader: Cmd 0x12\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x18:
|
||||||
|
dprintf("Reader: Initialize\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x0C:
|
||||||
|
dprintf("Reader: Cmd 0x0C\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x0E:
|
||||||
|
dprintf("Reader: Set Output\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x32:
|
||||||
|
dprintf("Reader: Cmd 0x32\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x40:
|
||||||
|
dprintf("Reader: Read Banapass\n"); // 01 03 00 -> Chip ID; 01 30 01 -> Thing after chip ID; 01 60 30 -> send key a
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x4A:
|
||||||
|
dprintf("Reader: Poll Card\n"); // 01 01 00 ff ff 01 00 -> Felica; 01 00 -> Banapass
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xA0:
|
||||||
|
dprintf("Reader: Read Felica\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
dprintf("Reader: Unknown command 0x%02x\n", header.cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
@ -11,3 +11,83 @@ struct bpreader_config {
|
|||||||
|
|
||||||
HRESULT bpreader_init(struct bpreader_config *cfg, uint16_t port);
|
HRESULT bpreader_init(struct bpreader_config *cfg, uint16_t port);
|
||||||
void bpreader_congif_load(struct bpreader_config *cfg, const wchar_t *filename);
|
void bpreader_congif_load(struct bpreader_config *cfg, const wchar_t *filename);
|
||||||
|
|
||||||
|
/*
|
||||||
|
bpreader packet format WIP
|
||||||
|
n = final offset
|
||||||
|
| Offset | Meaning |
|
||||||
|
|--------|--------------------------------------------------------------------|
|
||||||
|
| 0 | Always 00 |
|
||||||
|
| 1 | Always 00 |
|
||||||
|
| 2 | Always FF | Header
|
||||||
|
| 3 | len(Data), 0 means no data |
|
||||||
|
| 4 | FF - ((sum of header bytes) & FF) if data is present |
|
||||||
|
|--------|--------------------------------------------------------------------|
|
||||||
|
| 5 | Always D5 (resp) or D4 (req) if data is present, identifier? |
|
||||||
|
| 6 | Command if data is present | Data
|
||||||
|
| 7..n-2 | Data if data is present |
|
||||||
|
|--------|--------------------------------------------------------------------|
|
||||||
|
| n-1 | FF - ((sum of head + data bytes) & FF) if data is present, else FF | Footer
|
||||||
|
| n | Always 00 |
|
||||||
|
|
||||||
|
Commands
|
||||||
|
| Command | Response | Meaning | Response Data (not including leading 0xD5) |
|
||||||
|
|---------|----------|----------------------------------------------------|------------------------------------------------------------------------|
|
||||||
|
| 0x00 | 0x00 | Wait Next Command | None |
|
||||||
|
| 0x02 | 0x05 | Unknown | 0x0D, 0x00, 0x06, 0x00 |
|
||||||
|
| 0x03 | 0x02 | Unknown, first command and then sent randomly | 0x19 |
|
||||||
|
| 0x04 | 0x02 | Unknown, only command seen to change it's req data | 0x0F/0x33 |
|
||||||
|
| 0x05 | 0x03 | Unknown | 0x09, 0x00 |
|
||||||
|
| 0x06 | 0x02 | Unknown | 0x0F |
|
||||||
|
| 0x09 | 0x18 | Poll for card | 0x4B, 0x01, 0x01, 0x14, 0x01, [IDm], [PMm], [Sys Code] |
|
||||||
|
| 0x0E | 0x02 | Unknown | 0x33 |
|
||||||
|
| 0x12 | 0x0A | Unknown | 0x07, 0xFF, 0x3F, 0x0E, 0xF1, 0xFF, 0x3F, 0x0E, 0xF1 |
|
||||||
|
| 0x14 | 0x20 | Unknown | a lot, see bpreader.c |
|
||||||
|
| 0x18 | 0x0D | Unknown | 0x07, 0xDC, 0xF4, 0x3F, 0x11, 0x4D, 0x85, 0x61, 0xF1, 0x26, 0x6A, 0x87 |
|
||||||
|
*/
|
||||||
|
//const uint8_t bpreader_CMD_GO_NEXT[6] = { 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00 };
|
||||||
|
|
||||||
|
struct bpreader_cmd_header {
|
||||||
|
uint8_t padding0_00;
|
||||||
|
uint8_t padding1_00;
|
||||||
|
uint8_t padding2_ff;
|
||||||
|
uint8_t data_len;
|
||||||
|
uint8_t header_checksum;
|
||||||
|
uint8_t d_identifier;
|
||||||
|
uint8_t cmd;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bpreader_cmd_footer {
|
||||||
|
uint8_t checksum;
|
||||||
|
uint8_t padding;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bpreader_resp_02 {
|
||||||
|
struct bpreader_cmd_header;
|
||||||
|
uint8_t data;
|
||||||
|
struct bpreader_cmd_footer;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bpreader_resp_03 {
|
||||||
|
struct bpreader_cmd_header;
|
||||||
|
uint8_t data[2];
|
||||||
|
struct bpreader_cmd_footer;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bpreader_resp_04 {
|
||||||
|
struct bpreader_cmd_header;
|
||||||
|
uint8_t data[3];
|
||||||
|
struct bpreader_cmd_footer;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bpreader_resp_05 {
|
||||||
|
struct bpreader_cmd_header;
|
||||||
|
uint8_t data[4];
|
||||||
|
struct bpreader_cmd_footer;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bpreader_resp_0A {
|
||||||
|
struct bpreader_cmd_header;
|
||||||
|
uint8_t data[9];
|
||||||
|
struct bpreader_cmd_footer;
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user