CDC Badge OS
Firmware for the CDC Badge v1.0 hardware security key
Loading...
Searching...
No Matches
usb_msc.cpp
Go to the documentation of this file.
1
8
9#include "usb_badge/usb_msc.h"
10#include "cdc_log.h"
11
12extern "C" {
13#include "tusb.h"
14#include "class/msc/msc.h"
15#include "class/msc/msc_device.h"
16}
17
18#include <cstring>
19
20static const char* TAG = "USB_MSC";
21
22static const usb_msc_backend_t* s_backend = nullptr;
23
24extern "C" void usb_msc_set_backend(const usb_msc_backend_t* backend) {
25 s_backend = backend;
26 LOG_I(TAG, "MSC backend %s", backend ? "attached" : "detached");
27}
28
29extern "C" {
30
31void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16],
32 uint8_t product_rev[4]) {
33 (void)lun;
34 const char vid[] = "CDCBadge";
35 const char pid[] = "vFAT Storage";
36 const char rev[] = "1.0";
37 std::memset(vendor_id, ' ', 8);
38 std::memset(product_id, ' ', 16);
39 std::memset(product_rev, ' ', 4);
40 std::memcpy(vendor_id, vid, std::strlen(vid) > 8 ? 8 : std::strlen(vid));
41 std::memcpy(product_id, pid, std::strlen(pid) > 16 ? 16 : std::strlen(pid));
42 std::memcpy(product_rev, rev, std::strlen(rev) > 4 ? 4 : std::strlen(rev));
43}
44
45bool tud_msc_test_unit_ready_cb(uint8_t lun) {
46 (void)lun;
47 return s_backend != nullptr;
48}
49
50void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size) {
51 (void)lun;
52 if (!s_backend) {
53 *block_count = 0;
54 *block_size = 0;
55 return;
56 }
57 const uint16_t bs = s_backend->block_size();
58 *block_size = bs;
59 *block_count = bs ? static_cast<uint32_t>(s_backend->total_bytes() / bs) : 0;
60}
61
62bool tud_msc_is_writable_cb(uint8_t lun) {
63 (void)lun;
64 return s_backend != nullptr;
65}
66
67int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buffer,
68 uint32_t bufsize) {
69 (void)lun;
70 if (!s_backend) return -1;
71 // A host reading the LUN means it has the volume; gate badge-side writes.
72 if (s_backend->set_host_active) s_backend->set_host_active(true);
73 if (!s_backend->read(lba, offset, buffer, bufsize)) return -1;
74 return static_cast<int32_t>(bufsize);
75}
76
77int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer,
78 uint32_t bufsize) {
79 (void)lun;
80 if (!s_backend) return -1;
81 if (s_backend->set_host_active) s_backend->set_host_active(true);
82 if (!s_backend->write(lba, offset, buffer, bufsize)) return -1;
83 return static_cast<int32_t>(bufsize);
84}
85
86bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start,
87 bool load_eject) {
88 (void)lun;
89 (void)power_condition;
90 // An explicit eject releases the volume back to the badge.
91 if (load_eject && !start && s_backend && s_backend->set_host_active) {
92 s_backend->set_host_active(false);
93 }
94 return true;
95}
96
97int32_t tud_msc_scsi_cb(uint8_t lun, uint8_t const scsi_cmd[16], void* buffer,
98 uint16_t bufsize) {
99 (void)buffer;
100 (void)bufsize;
101 (void)scsi_cmd;
102 // Reject any SCSI command not handled by the class driver.
103 tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);
104 return -1;
105}
106
107void tud_umount_cb(void) {
108 // USB disconnect (including our own re-enumeration): release the volume so
109 // the badge regains write access and refreshes its view.
110 if (s_backend && s_backend->set_host_active) s_backend->set_host_active(false);
111}
112
113} // extern "C"
static const char * TAG
CDC Log: logging over TinyUSB CDC and UART.
#define LOG_I(tag, fmt,...)
Definition cdc_log.h:147
Block-device backend for the single USB Mass Storage LUN.
Definition usb_msc.h:20
void tud_umount_cb(void)
Definition usb_msc.cpp:107
int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void *buffer, uint32_t bufsize)
Definition usb_msc.cpp:67
int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t *buffer, uint32_t bufsize)
Definition usb_msc.cpp:77
bool tud_msc_is_writable_cb(uint8_t lun)
Definition usb_msc.cpp:62
void usb_msc_set_backend(const usb_msc_backend_t *backend)
Installs or removes the MSC block backend.
Definition usb_msc.cpp:24
int32_t tud_msc_scsi_cb(uint8_t lun, uint8_t const scsi_cmd[16], void *buffer, uint16_t bufsize)
Definition usb_msc.cpp:97
static const usb_msc_backend_t * s_backend
Definition usb_msc.cpp:22
bool tud_msc_test_unit_ready_cb(uint8_t lun)
Definition usb_msc.cpp:45
bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject)
Definition usb_msc.cpp:86
void tud_msc_capacity_cb(uint8_t lun, uint32_t *block_count, uint16_t *block_size)
Definition usb_msc.cpp:50
void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4])
Definition usb_msc.cpp:31