summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.cpp386
-rwxr-xr-xnfc_bulk.py33
2 files changed, 46 insertions, 373 deletions
diff --git a/main.cpp b/main.cpp
index 73b4d2c..1ec89a6 100644
--- a/main.cpp
+++ b/main.cpp
@@ -10,10 +10,8 @@
auto dev_desc = device_desc(0x200, 0, 0, 0, 64, 0x1d50, 0x60f8, 0, 0, 0, 0, 1);
auto conf_desc = configuration_desc(1, 1, 0, 0xc0, 0,
- // MSC BBB
- interface_desc(0, 0, 2, 0x08, 0x06, 0x50, 0,
- endpoint_desc(0x81, 0x02, 64, 0), // IN
- endpoint_desc(0x01, 0x02, 64, 0) // OUT
+ interface_desc(1, 0, 1, 0xff, 0x00, 0x00, 0,
+ endpoint_desc(0x81, 0x02, 64, 0)
)
);
@@ -81,384 +79,25 @@ class CR95HF {
};
CR95HF cr95hf(SPI1, nfc_ss);
-/*
-class USB_CR95HF : public USB_class_driver {
- private:
- USB_generic& usb;
-
- uint8_t pend_reg;
- uint32_t pend_len;
- uint8_t buf[256];
-
- bool write(uint16_t wValue, uint16_t wIndex, uint16_t wLength) {
- if(wLength > sizeof(buf)) {
- return false;
- }
-
- if(wLength == 0) {
- cr95hf.send_cmd(wValue, 0, nullptr);
-
- usb.write(0, nullptr, 0);
-
- return true;
- }
-
- pend_reg = wValue;
- pend_len = wLength;
- // Awaiting OUT packet.
-
- return true;
- }
-
- bool read(uint16_t wValue, uint16_t wIndex, uint16_t wLength) {
- if(wLength > sizeof(buf)) {
- return false;
- }
-
- wLength = cr95hf.get_response(wLength, buf);
-
- // TODO: wLength >= 64
-
- usb.write(0, (uint32_t*)buf, wLength);
- return true;
- }
-
- public:
- USB_CR95HF(USB_generic& usbd) : usb(usbd) {
- usb.register_driver(this);
- }
-
- protected:
- virtual SetupStatus handle_setup(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength) {
- if(bmRequestType == 0x40 && bRequest == 0xf2) {
- return write(wValue, wIndex, wLength) ? SetupStatus::Ok : SetupStatus::Stall;
- }
-
- if(bmRequestType == 0xc0 && bRequest == 0xf3) {
- return read(wValue, wIndex, wLength) ? SetupStatus::Ok : SetupStatus::Stall;
- }
-
- return SetupStatus::Unhandled;
- }
-
- virtual void handle_out(uint8_t ep, uint32_t len) {
- if(ep != 0 || len == 0) {
- return;
- }
-
- if(len != pend_len) {
- return;
- }
-
- usb.read(0, (uint32_t*)buf, len);
-
- cr95hf.send_cmd(pend_reg, len, buf);
-
- usb.write(0, nullptr, 0);
- }
-};
-
-USB_CR95HF usb_cr95hf(usb);
-*/
-struct CBW {
- uint32_t dCBWSignature;
- uint32_t dCBWTag;
- uint32_t dCBWDataTransferLength;
- uint8_t bmCBWFlags;
- uint8_t bCBWLUN;
- uint8_t bCBWCBLength;
- uint8_t CBWCB[16];
-} __attribute__((packed));
-
-struct CSW {
- uint32_t dCSWSignature;
- uint32_t dCSWTag;
- uint32_t dCSWDataResidue;
- uint8_t bCSWStatus;
-} __attribute__((packed));
-uint32_t nullbuf[16];
-uint32_t fcapbuf[] = {
- 0x08000000,
- 0x00010000,
- 0x00020002
-};
-uint32_t capbuf[] = {
- 0x00010000,
- 0x00020000
-};
-uint32_t inquirybuf[] = {
- 0x02048000,
- 32,
-
- 0x20202020, 0x20202020,
-
- 0x20202020, 0x20202020, 0x20202020, 0x20202020,
-
- 0x34333231,
-};
-
-uint32_t sensebuf[] = {
- 0x00050070,
- 0x0a000000,
- 0,
- 0x00000020,
- 0
-};
-
-uint32_t modesensebuf[] = {
- 0x00800004
-};
-
-//uint32_t sd_buf[512];
-
-uint8_t sectors[][512] {
- {}, // NULL
- { // MBR
- 0xeb, 0x3c, 0x90, 0x6d, 0x6b, 0x64, 0x6f, 0x73, 0x66, 0x73, 0x00, 0x00, 0x02, 0x04, 0x01, 0x00,
- 0x02, 0x00, 0x02, 0x00, 0x01, 0xf8, 0x01, 0x00, 0x20, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0xc9, 0x6a, 0x10, 0xc4, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x46, 0x41, 0x54, 0x31, 0x32, 0x20, 0x20, 0x20, 0x0e, 0x1f,
- 0xbe, 0x5b, 0x7c, 0xac, 0x22, 0xc0, 0x74, 0x0b, 0x56, 0xb4, 0x0e, 0xbb, 0x07, 0x00, 0xcd, 0x10,
- 0x5e, 0xeb, 0xf0, 0x32, 0xe4, 0xcd, 0x16, 0xcd, 0x19, 0xeb, 0xfe, 0x54, 0x68, 0x69, 0x73, 0x20,
- 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x20, 0x62, 0x6f, 0x6f, 0x74, 0x61, 0x62, 0x6c,
- 0x65, 0x20, 0x64, 0x69, 0x73, 0x6b, 0x2e, 0x20, 0x20, 0x50, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20,
- 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x20, 0x61, 0x20, 0x62, 0x6f, 0x6f, 0x74, 0x61, 0x62, 0x6c,
- 0x65, 0x20, 0x66, 0x6c, 0x6f, 0x70, 0x70, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x0d, 0x0a, 0x70, 0x72,
- 0x65, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x6b, 0x65, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x74,
- 0x72, 0x79, 0x20, 0x61, 0x67, 0x61, 0x69, 0x6e, 0x20, 0x2e, 0x2e, 0x2e, 0x20, 0x0d, 0x0a, 0x00,
- },
- { // FAT
- 0xf8, 0xff, 0xff, 0x00, 0xf0, 0xff,
- },
- { // File table
- 0x41, 0x63, 0x00, 0x61, 0x00, 0x72, 0x00, 0x64, 0x00, 0x30, 0x00, 0x0f, 0x00, 0xa7, 0x2e, 0x00,
- 0x74, 0x00, 0x78, 0x00, 0x74, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
- 0x43, 0x41, 0x52, 0x44, 0x30, 0x20, 0x20, 0x20, 0x54, 0x58, 0x54, 0x20, 0x00, 0x64, 0x53, 0x95,
- 0x03, 0x43, 0x03, 0x43, 0x00, 0x00, 0x53, 0x95, 0x03, 0x43, 0x03, 0x00, 0x10, 0x00, 0x00, 0x00,
- },
- {},
-};
-
-uint8_t* get_sector(uint32_t sector) {
- switch(sector) {
- case 0:
- return sectors[1];
-
- case 1:
- case 2:
- return sectors[2];
-
- case 3:
- return sectors[3];
-
- case 39:
- return sectors[4];
-
- default:
- return sectors[0];
- }
-}
-
-class USB_MSC_BBB : public USB_class_driver {
+class USB_NFC : public USB_class_driver {
private:
USB_generic& usb;
- uint32_t buf[16];
-
- uint32_t pending_data_in;
-
- bool pending_write;
- uint32_t pending_write_addr;
- uint32_t pending_write_num;
-
- CBW cbw;
-
- uint32_t pending_write_recv;
-
- CSW csw;
-
public:
- USB_MSC_BBB(USB_generic& usbd) : usb(usbd) {
+ USB_NFC(USB_generic& usbd) : usb(usbd) {
usb.register_driver(this);
}
-
- protected:
- virtual SetupStatus handle_setup(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength) {
- // Get max LUN
- if(bmRequestType == 0xa1 && bRequest == 0xfe) {
- uint32_t max_lun = 0;
- usb.write(0, &max_lun, 1);
- return SetupStatus::Ok;
- }
-
- // Mass Storage Reset
- if(bmRequestType == 0x21 && bRequest == 0xff) {
- usb.write(0, nullptr, 0);
- return SetupStatus::Ok;
- }
-
- return SetupStatus::Unhandled;
- }
+ protected:
virtual void handle_set_configuration(uint8_t configuration) {
if(configuration) {
- usb.register_out_handler(this, 1);
- usb.hw_conf_ep(0x01, EPType::Bulk, 64);
usb.hw_conf_ep(0x81, EPType::Bulk, 64);
-
- pending_data_in = 0;
- pending_write = false;
}
}
-
- virtual void handle_out(uint8_t ep, uint32_t len) {
- if(ep == 0) {
- if(len) {
- usb.write(0, nullptr, 0);
- }
-
- } else if(ep == 1 && pending_data_in != 0) {
- if(pending_write) {
- usb_rblog.log("Handling write packet. (%d bytes)", len);
-
- //handle_write_block_packet();
-
- } else {
- usb_rblog.log("Ignoring %d bytes of received data.", len);
- }
-
- if(len > pending_data_in) {
- pending_data_in = 0;
- } else {
- pending_data_in -= len;
- }
-
- if(pending_data_in == 0) {
- usb.write(1, (uint32_t*)&csw, sizeof(CSW));
- }
-
- } else if(ep == 1) {
-
- // Read CBW.
- if(len != sizeof(CBW) || usb.read(ep, (uint32_t*)&cbw, len) != sizeof(CBW)) {
- usb_rblog.log("Invalid CBW size.");
- return; // FIXME: Indicate error.
- }
-
- if(cbw.dCBWSignature != 0x43425355) {
- usb_rblog.log("Invalid CBW signature.");
- return; // FIXME: Indicate error.
- }
-
- usb_rblog.log("Received CBW, tl=%d, flags=%#02x", cbw.dCBWDataTransferLength, cbw.bmCBWFlags);
-
- bool cmd_ok = handle_scsi_cmd(cbw.CBWCB, cbw.bCBWCBLength);
-
- if(!cmd_ok && cbw.dCBWDataTransferLength != 0 && cbw.bmCBWFlags & 0x80) {
- write_zero();
- }
-
- if(cmd_ok) {
- csw = {0x53425355, cbw.dCBWTag, 0, 0x00};
- } else {
- csw = {0x53425355, cbw.dCBWTag, cbw.dCBWDataTransferLength, 0x01};
- }
-
- if(cbw.dCBWDataTransferLength != 0 && !(cbw.bmCBWFlags & 0x80)) {
- pending_data_in = cbw.dCBWDataTransferLength;
- return;
- }
-
- usb.write(1, (uint32_t*)&csw, sizeof(CSW));
- }
- }
-
- void write_zero() {
- uint32_t len = cbw.dCBWDataTransferLength;
- while(len > 64) {
- usb.write(1, nullbuf, 64);
- while(!usb.ep_ready(1));
- len -= 64;
- }
-
- usb.write(1, nullbuf, len);
- while(!usb.ep_ready(1));
- }
-
- void handle_read_block() {
- uint32_t block = (cbw.CBWCB[2] << 24) | (cbw.CBWCB[3] << 16) | (cbw.CBWCB[4] << 8) | cbw.CBWCB[5];
- uint16_t num_blocks = (cbw.CBWCB[7] << 8) | cbw.CBWCB[8];
-
- while(num_blocks--) {
- uint32_t* bufp = (uint32_t*)get_sector(block++);
-
- for(uint32_t i = 0; i < 512; i += 64) {
- usb.write(1, bufp + i / 4, 64);
- while(!usb.ep_ready(1));
- }
- }
- }
-
- bool handle_scsi_cmd(uint8_t* cmd, uint32_t len) {
- pending_write = false;
-
- if(!len) {
- return false;
- }
-
- switch(cmd[0]) {
- // TEST UNIT READY
- case 0x00:
- return true;
-
- // REQUEST SENSE
- case 0x03:
- usb.write(1, sensebuf, cbw.dCBWDataTransferLength);
- while(!usb.ep_ready(1));
- return true;
-
- // INQUIRY
- case 0x12:
- if(cmd[2] != 0) {
- return false;
- }
- usb.write(1, inquirybuf, cbw.dCBWDataTransferLength);
- while(!usb.ep_ready(1));
- return true;
-
- // MODE SENSE
- case 0x1a:
- usb.write(1, modesensebuf, cbw.dCBWDataTransferLength > 4 ? 4 : cbw.dCBWDataTransferLength);
- while(!usb.ep_ready(1));
- return true;
-
- // READ FORMAT CAPACITIES
- case 0x23:
- usb.write(1, fcapbuf, sizeof(fcapbuf));
- while(!usb.ep_ready(1));
- return true;
-
- // READ CAPACITY
- case 0x25:
- usb.write(1, capbuf, cbw.dCBWDataTransferLength);
- while(!usb.ep_ready(1));
- return true;
-
- // READ (10)
- case 0x28:
- handle_read_block();
- return true;
-
- default:
- return false;
- }
-
- return true;
- }
};
-USB_MSC_BBB usb_msc_bbb(usb);
+USB_NFC usb_nfc(usb);
int main() {
rcc_init();
@@ -510,6 +149,7 @@ int main() {
uint8_t buf[64];
bool cmd_sent = false;
uint32_t nfc_delay_until = 0;
+ uint8_t bulk_buf[8];
Time::sleep(1000);
@@ -531,15 +171,15 @@ int main() {
if(buf[0] == 128 && buf[14] == 0) {
led.on();
- USB.reg.BCDR &= ~(1 << 15);
uint8_t* id_raw = &buf[11];
- uint8_t* id_ascii = sectors[4];
+ uint8_t* id_buf = bulk_buf;
for(uint32_t i = 0; i < 8; i++) {
- *id_ascii++ = "0123456789ABCDEF"[*id_raw >> 4];
- *id_ascii++ = "0123456789ABCDEF"[*id_raw-- & 0xf];
+ *id_buf++ = *id_raw--;
+ }
+
+ if(usb.ep_ready(1)) {
+ usb.write(1, (uint32_t*)bulk_buf, sizeof(bulk_buf));
}
- Time::sleep(10);
- USB.reg.BCDR |= 1 << 15;
nfc_delay_until = Time::time() + 5000; // Valid for five seconds.
} else {
diff --git a/nfc_bulk.py b/nfc_bulk.py
new file mode 100755
index 0000000..ad6f896
--- /dev/null
+++ b/nfc_bulk.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+
+import usb1, libusb1
+import time, struct
+
+ctx = usb1.LibUSBContext()
+
+dev = ctx.getByVendorIDAndProductID(0x1d50, 0x60f8)
+
+if not dev:
+ print 'Device not found.'
+ exit(1)
+
+handle = dev.open()
+handle.claimInterface(1)
+
+def transfer_cb(t):
+ data = t.getBuffer()[:t.getActualLength()]
+
+ print time.strftime('%H:%M:%S'),
+ print 'Card detected. UID: %s' % ':'.join('%02x' % ord(c) for c in data)
+
+ return True
+
+th = usb1.USBTransferHelper()
+th.setEventCallback(libusb1.LIBUSB_TRANSFER_COMPLETED, transfer_cb)
+
+t = handle.getTransfer()
+t.setBulk(0x81, 64, th)
+t.submit()
+
+while 1:
+ ctx.handleEvents()