From ca4a152653036bd3d3ab99e5af7f029b1d726bab Mon Sep 17 00:00:00 2001 From: Vegard Storheil Eriksen Date: Sun, 18 Sep 2016 22:46:37 +0200 Subject: Changed to plain bulk interface. --- main.cpp | 386 ++---------------------------------------------------------- nfc_bulk.py | 33 ++++++ 2 files changed, 46 insertions(+), 373 deletions(-) create mode 100755 nfc_bulk.py 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() -- cgit v1.2.3