usbif.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741
  1. #include "furi_hal_version.h"
  2. #include "furi_hal_usb_i.h"
  3. #include "furi_hal_usb_hid_u2f.h"
  4. #include <furi.h>
  5. #include "usb.h"
  6. #include <usb_hid.h>
  7. #include "usbd_core.h"
  8. #include "usb_std.h"
  9. #include "filelogger.h"
  10. #include "usbif.h"
  11. #include <storage/storage.h>
  12. #include "constants.h"
  13. #include <hid_usage_desktop.h>
  14. static const struct usb_string_descriptor dev_manuf_desc = USB_STRING_DESC("Flipper Devices Inc.");
  15. static const struct usb_string_descriptor dev_prod_desc = USB_STRING_DESC("U2F Token");
  16. #define HID_PAGE_FIDO 0xF1D0
  17. #define HID_FIDO_U2F 0x01
  18. #define HID_FIDO_INPUT 0x20
  19. #define HID_FIDO_OUTPUT 0x21
  20. #define HID_EP_IN 0x81
  21. #define HID_EP_OUT 0x01
  22. static const uint8_t endpoint_type = USB_EPTYPE_INTERRUPT;
  23. struct HidIadDescriptor {
  24. struct usb_interface_descriptor hid;
  25. struct usb_hid_descriptor hid_desc;
  26. struct usb_endpoint_descriptor hid_ep_in;
  27. struct usb_endpoint_descriptor hid_ep_out;
  28. struct usb_interface_descriptor hid2;
  29. struct usb_hid_descriptor hid_desc2;
  30. struct usb_endpoint_descriptor hid_ep_in2;
  31. struct usb_endpoint_descriptor hid_ep_out2;
  32. struct usb_interface_descriptor hid3;
  33. struct usb_hid_descriptor hid_desc3;
  34. struct usb_endpoint_descriptor hid_ep_in3;
  35. struct usb_endpoint_descriptor hid_ep_out3;
  36. struct usb_interface_descriptor hid4;
  37. struct usb_hid_descriptor hid_desc4;
  38. struct usb_endpoint_descriptor hid_ep_in4;
  39. struct usb_endpoint_descriptor hid_ep_out4;
  40. struct usb_interface_descriptor hid5;
  41. struct usb_hid_descriptor hid_desc5;
  42. struct usb_endpoint_descriptor hid_ep_in5;
  43. struct usb_endpoint_descriptor hid_ep_out5;
  44. struct usb_interface_descriptor hid6;
  45. struct usb_hid_descriptor hid_desc6;
  46. struct usb_endpoint_descriptor hid_ep_in6;
  47. struct usb_endpoint_descriptor hid_ep_out6;
  48. // struct usb_interface_descriptor hid7;
  49. // struct usb_hid_descriptor hid_desc7;
  50. // struct usb_endpoint_descriptor hid_ep_in7;
  51. // struct usb_endpoint_descriptor hid_ep_out7;
  52. // struct usb_interface_descriptor hid8;
  53. // struct usb_hid_descriptor hid_desc8;
  54. // struct usb_endpoint_descriptor hid_ep_in8;
  55. // struct usb_endpoint_descriptor hid_ep_out8;
  56. } __attribute__((packed));
  57. struct HidConfigDescriptor {
  58. struct usb_config_descriptor config;
  59. struct HidIadDescriptor iad_0;
  60. } __attribute__((packed));
  61. static const struct usb_device_descriptor hid_u2f_device_desc = {
  62. .bLength = sizeof(struct usb_device_descriptor),
  63. .bDescriptorType = USB_DTYPE_DEVICE,
  64. .bcdUSB = VERSION_BCD(2, 0, 0),
  65. .bDeviceClass = 0,
  66. .bDeviceSubClass = 0,
  67. .bDeviceProtocol = 0,
  68. .bMaxPacketSize0 = USB_EP0_SIZE,
  69. .idVendor = 0x485, // 0x0483,
  70. .idProduct = 0xFFFF, //0x5741,
  71. .bcdDevice = VERSION_BCD(1, 0, 0),
  72. .iManufacturer = UsbDevManuf,
  73. .iProduct = UsbDevProduct,
  74. .iSerialNumber = 0,
  75. .bNumConfigurations = 1,
  76. };
  77. /* HID report: FIDO U2F */
  78. static const uint8_t hid_u2f_report_desc[] = {
  79. HID_RI_USAGE_PAGE(16, 0xff00),
  80. HID_USAGE(HID_FIDO_U2F),
  81. HID_COLLECTION(HID_APPLICATION_COLLECTION),
  82. HID_USAGE(HID_FIDO_INPUT),
  83. HID_LOGICAL_MINIMUM(0x00),
  84. HID_RI_LOGICAL_MAXIMUM(16, 0xFF),
  85. HID_REPORT_SIZE(8),
  86. HID_REPORT_COUNT(HID_U2F_PACKET_LEN),
  87. HID_INPUT(HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
  88. HID_USAGE(HID_FIDO_OUTPUT),
  89. HID_LOGICAL_MINIMUM(0x00),
  90. HID_RI_LOGICAL_MAXIMUM(16, 0xFF),
  91. HID_REPORT_SIZE(8),
  92. HID_REPORT_COUNT(HID_U2F_PACKET_LEN),
  93. HID_OUTPUT(HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
  94. HID_END_COLLECTION,
  95. };
  96. // static const uint8_t hid_u2f_report_desc[] = {
  97. // 0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00)
  98. // 0x09, 0x01, // Usage (0x01)
  99. // 0xA1, 0x01, // Collection (Application)
  100. // 0x19, 0x01, // Usage Minimum (0x01)
  101. // 0x29, 0x40, // Usage Maximum (0x40)
  102. // 0x15, 0x00, // Logical Minimum (0)
  103. // 0x26, 0xFF, 0x00, // Logical Maximum (255)
  104. // 0x75, 0x08, // Report Size (8)
  105. // 0x95, 0x01, // Report Count (1)
  106. // 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
  107. // 0x19, 0x01, // Usage Minimum (0x01)
  108. // 0x29, 0x40, // Usage Maximum (0x40)
  109. // 0x15, 0x00, // Logical Minimum (0)
  110. // 0x26, 0xFF, 0x00, // Logical Maximum (255)
  111. // 0x75, 0x08, // Report Size (8)
  112. // 0x95, 0x01, // Report Count (1)
  113. // 0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
  114. // 0xC0, // End Collection
  115. // };
  116. /* Device configuration descriptor */
  117. static const struct HidConfigDescriptor
  118. hid_u2f_cfg_desc =
  119. {
  120. .config =
  121. {
  122. .bLength = sizeof(struct usb_config_descriptor),
  123. .bDescriptorType = USB_DTYPE_CONFIGURATION,
  124. .wTotalLength = sizeof(struct HidConfigDescriptor),
  125. .bNumInterfaces = NUM_OF_INTERFACES,
  126. .bConfigurationValue = 1,
  127. .iConfiguration = NO_DESCRIPTOR,
  128. .bmAttributes = USB_CFG_ATTR_RESERVED | USB_CFG_ATTR_SELFPOWERED,
  129. .bMaxPower = USB_CFG_POWER_MA(100),
  130. },
  131. .iad_0 =
  132. {
  133. .hid =
  134. {
  135. .bLength = sizeof(struct usb_interface_descriptor),
  136. .bDescriptorType = USB_DTYPE_INTERFACE,
  137. .bInterfaceNumber = 0,
  138. .bAlternateSetting = 0,
  139. .bNumEndpoints = 2,
  140. .bInterfaceClass = USB_CLASS_HID,
  141. .bInterfaceSubClass = USB_HID_SUBCLASS_NONBOOT,
  142. .bInterfaceProtocol = USB_HID_PROTO_NONBOOT,
  143. .iInterface = NO_DESCRIPTOR,
  144. },
  145. .hid_desc =
  146. {
  147. .bLength = sizeof(struct usb_hid_descriptor),
  148. .bDescriptorType = USB_DTYPE_HID,
  149. .bcdHID = VERSION_BCD(1, 0, 0),
  150. .bCountryCode = USB_HID_COUNTRY_NONE,
  151. .bNumDescriptors = 1,
  152. .bDescriptorType0 = USB_DTYPE_HID_REPORT,
  153. .wDescriptorLength0 = sizeof(hid_u2f_report_desc),
  154. },
  155. .hid_ep_in =
  156. {
  157. .bLength = sizeof(struct usb_endpoint_descriptor),
  158. .bDescriptorType = USB_DTYPE_ENDPOINT,
  159. .bEndpointAddress = HID_EP_IN,
  160. .bmAttributes = endpoint_type,
  161. .wMaxPacketSize = HID_U2F_PACKET_LEN,
  162. .bInterval = 1,
  163. },
  164. .hid_ep_out =
  165. {
  166. .bLength = sizeof(struct usb_endpoint_descriptor),
  167. .bDescriptorType = USB_DTYPE_ENDPOINT,
  168. .bEndpointAddress = HID_EP_OUT,
  169. .bmAttributes = endpoint_type,
  170. .wMaxPacketSize = HID_U2F_PACKET_LEN,
  171. .bInterval = 1,
  172. },
  173. .hid2 =
  174. {
  175. .bLength = sizeof(struct usb_interface_descriptor),
  176. .bDescriptorType = USB_DTYPE_INTERFACE,
  177. .bInterfaceNumber = 1,
  178. .bAlternateSetting = 0,
  179. .bNumEndpoints = 2,
  180. .bInterfaceClass = USB_CLASS_HID,
  181. .bInterfaceSubClass = USB_HID_SUBCLASS_NONBOOT,
  182. .bInterfaceProtocol = USB_HID_PROTO_NONBOOT,
  183. .iInterface = NO_DESCRIPTOR,
  184. },
  185. .hid_desc2 =
  186. {
  187. .bLength = sizeof(struct usb_hid_descriptor),
  188. .bDescriptorType = USB_DTYPE_HID,
  189. .bcdHID = VERSION_BCD(1, 0, 0),
  190. .bCountryCode = USB_HID_COUNTRY_NONE,
  191. .bNumDescriptors = 1,
  192. .bDescriptorType0 = USB_DTYPE_HID_REPORT,
  193. .wDescriptorLength0 = sizeof(hid_u2f_report_desc),
  194. },
  195. .hid_ep_in2 =
  196. {
  197. .bLength = sizeof(struct usb_endpoint_descriptor),
  198. .bDescriptorType = USB_DTYPE_ENDPOINT,
  199. .bEndpointAddress = HID_EP_IN + 1,
  200. .bmAttributes = endpoint_type,
  201. .wMaxPacketSize = HID_U2F_PACKET_LEN,
  202. .bInterval = 1,
  203. },
  204. .hid_ep_out2 =
  205. {
  206. .bLength = sizeof(struct usb_endpoint_descriptor),
  207. .bDescriptorType = USB_DTYPE_ENDPOINT,
  208. .bEndpointAddress = HID_EP_OUT + 1,
  209. .bmAttributes = endpoint_type,
  210. .wMaxPacketSize = HID_U2F_PACKET_LEN,
  211. .bInterval = 1,
  212. },
  213. .hid3 =
  214. {
  215. .bLength = sizeof(struct usb_interface_descriptor),
  216. .bDescriptorType = USB_DTYPE_INTERFACE,
  217. .bInterfaceNumber = 2,
  218. .bAlternateSetting = 0,
  219. .bNumEndpoints = 2,
  220. .bInterfaceClass = USB_CLASS_HID,
  221. .bInterfaceSubClass = USB_HID_SUBCLASS_NONBOOT,
  222. .bInterfaceProtocol = USB_HID_PROTO_NONBOOT,
  223. .iInterface = NO_DESCRIPTOR,
  224. },
  225. .hid_desc3 =
  226. {
  227. .bLength = sizeof(struct usb_hid_descriptor),
  228. .bDescriptorType = USB_DTYPE_HID,
  229. .bcdHID = VERSION_BCD(1, 0, 0),
  230. .bCountryCode = USB_HID_COUNTRY_NONE,
  231. .bNumDescriptors = 1,
  232. .bDescriptorType0 = USB_DTYPE_HID_REPORT,
  233. .wDescriptorLength0 = sizeof(hid_u2f_report_desc),
  234. },
  235. .hid_ep_in3 =
  236. {
  237. .bLength = sizeof(struct usb_endpoint_descriptor),
  238. .bDescriptorType = USB_DTYPE_ENDPOINT,
  239. .bEndpointAddress = HID_EP_IN + 2,
  240. .bmAttributes = endpoint_type,
  241. .wMaxPacketSize = HID_U2F_PACKET_LEN,
  242. .bInterval = 1,
  243. },
  244. .hid_ep_out3 =
  245. {
  246. .bLength = sizeof(struct usb_endpoint_descriptor),
  247. .bDescriptorType = USB_DTYPE_ENDPOINT,
  248. .bEndpointAddress = HID_EP_OUT + 2,
  249. .bmAttributes = endpoint_type,
  250. .wMaxPacketSize = HID_U2F_PACKET_LEN,
  251. .bInterval = 1,
  252. },
  253. .hid4 =
  254. {
  255. .bLength = sizeof(struct usb_interface_descriptor),
  256. .bDescriptorType = USB_DTYPE_INTERFACE,
  257. .bInterfaceNumber = 3,
  258. .bAlternateSetting = 0,
  259. .bNumEndpoints = 2,
  260. .bInterfaceClass = USB_CLASS_HID,
  261. .bInterfaceSubClass = USB_HID_SUBCLASS_NONBOOT,
  262. .bInterfaceProtocol = USB_HID_PROTO_NONBOOT,
  263. .iInterface = NO_DESCRIPTOR,
  264. },
  265. .hid_desc4 =
  266. {
  267. .bLength = sizeof(struct usb_hid_descriptor),
  268. .bDescriptorType = USB_DTYPE_HID,
  269. .bcdHID = VERSION_BCD(1, 0, 0),
  270. .bCountryCode = USB_HID_COUNTRY_NONE,
  271. .bNumDescriptors = 1,
  272. .bDescriptorType0 = USB_DTYPE_HID_REPORT,
  273. .wDescriptorLength0 = sizeof(hid_u2f_report_desc),
  274. },
  275. .hid_ep_in4 =
  276. {
  277. .bLength = sizeof(struct usb_endpoint_descriptor),
  278. .bDescriptorType = USB_DTYPE_ENDPOINT,
  279. .bEndpointAddress = HID_EP_IN + 3,
  280. .bmAttributes = endpoint_type,
  281. .wMaxPacketSize = HID_U2F_PACKET_LEN,
  282. .bInterval = 1,
  283. },
  284. .hid_ep_out4 =
  285. {
  286. .bLength = sizeof(struct usb_endpoint_descriptor),
  287. .bDescriptorType = USB_DTYPE_ENDPOINT,
  288. .bEndpointAddress = HID_EP_OUT + 3,
  289. .bmAttributes = endpoint_type,
  290. .wMaxPacketSize = HID_U2F_PACKET_LEN,
  291. .bInterval = 1,
  292. },
  293. .hid5 =
  294. {
  295. .bLength = sizeof(struct usb_interface_descriptor),
  296. .bDescriptorType = USB_DTYPE_INTERFACE,
  297. .bInterfaceNumber = 4,
  298. .bAlternateSetting = 0,
  299. .bNumEndpoints = 2,
  300. .bInterfaceClass = USB_CLASS_HID,
  301. .bInterfaceSubClass = USB_HID_SUBCLASS_NONBOOT,
  302. .bInterfaceProtocol = USB_HID_PROTO_NONBOOT,
  303. .iInterface = NO_DESCRIPTOR,
  304. },
  305. .hid_desc5 =
  306. {
  307. .bLength = sizeof(struct usb_hid_descriptor),
  308. .bDescriptorType = USB_DTYPE_HID,
  309. .bcdHID = VERSION_BCD(1, 0, 0),
  310. .bCountryCode = USB_HID_COUNTRY_NONE,
  311. .bNumDescriptors = 1,
  312. .bDescriptorType0 = USB_DTYPE_HID_REPORT,
  313. .wDescriptorLength0 = sizeof(hid_u2f_report_desc),
  314. },
  315. .hid_ep_in5 =
  316. {
  317. .bLength = sizeof(struct usb_endpoint_descriptor),
  318. .bDescriptorType = USB_DTYPE_ENDPOINT,
  319. .bEndpointAddress = HID_EP_IN + 4,
  320. .bmAttributes = endpoint_type,
  321. .wMaxPacketSize = HID_U2F_PACKET_LEN,
  322. .bInterval = 1,
  323. },
  324. .hid_ep_out5 =
  325. {
  326. .bLength = sizeof(struct usb_endpoint_descriptor),
  327. .bDescriptorType = USB_DTYPE_ENDPOINT,
  328. .bEndpointAddress = HID_EP_OUT + 4,
  329. .bmAttributes = endpoint_type,
  330. .wMaxPacketSize = HID_U2F_PACKET_LEN,
  331. .bInterval = 1,
  332. },
  333. .hid6 =
  334. {
  335. .bLength = sizeof(struct usb_interface_descriptor),
  336. .bDescriptorType = USB_DTYPE_INTERFACE,
  337. .bInterfaceNumber = 5,
  338. .bAlternateSetting = 0,
  339. .bNumEndpoints = 2,
  340. .bInterfaceClass = USB_CLASS_HID,
  341. .bInterfaceSubClass = USB_HID_SUBCLASS_NONBOOT,
  342. .bInterfaceProtocol = USB_HID_PROTO_NONBOOT,
  343. .iInterface = NO_DESCRIPTOR,
  344. },
  345. .hid_desc6 =
  346. {
  347. .bLength = sizeof(struct usb_hid_descriptor),
  348. .bDescriptorType = USB_DTYPE_HID,
  349. .bcdHID = VERSION_BCD(1, 0, 0),
  350. .bCountryCode = USB_HID_COUNTRY_NONE,
  351. .bNumDescriptors = 1,
  352. .bDescriptorType0 = USB_DTYPE_HID_REPORT,
  353. .wDescriptorLength0 = sizeof(hid_u2f_report_desc),
  354. },
  355. .hid_ep_in6 =
  356. {
  357. .bLength = sizeof(struct usb_endpoint_descriptor),
  358. .bDescriptorType = USB_DTYPE_ENDPOINT,
  359. .bEndpointAddress = HID_EP_IN + 5,
  360. .bmAttributes = endpoint_type,
  361. .wMaxPacketSize = HID_U2F_PACKET_LEN,
  362. .bInterval = 1,
  363. },
  364. .hid_ep_out6 =
  365. {
  366. .bLength = sizeof(struct usb_endpoint_descriptor),
  367. .bDescriptorType = USB_DTYPE_ENDPOINT,
  368. .bEndpointAddress = HID_EP_OUT + 5,
  369. .bmAttributes = endpoint_type,
  370. .wMaxPacketSize = HID_U2F_PACKET_LEN,
  371. .bInterval = 1,
  372. },
  373. },
  374. };
  375. static void hid_u2f_init(usbd_device* dev, FuriHalUsbInterface* intf, void* ctx);
  376. static void hid_u2f_deinit(usbd_device* dev);
  377. static void hid_u2f_on_wakeup(usbd_device* dev);
  378. static void hid_u2f_on_suspend(usbd_device* dev);
  379. //static bool hid_u2f_send_report(uint8_t report_id);
  380. static usbd_respond hid_u2f_ep_config(usbd_device* dev, uint8_t cfg);
  381. usbd_respond hid_u2f_controlf(usbd_device* dev, usbd_ctlreq* req, usbd_rqc_callback* callback);
  382. static usbd_device* usb_dev;
  383. static bool hid_u2f_connected = false;
  384. static void* cb_ctx;
  385. bool furi_hal_hid_u2f_is_connected() {
  386. return hid_u2f_connected;
  387. }
  388. static void callbackf(HidU2fEvent ev, void* context) {
  389. FURI_LOG_D(TAG_IF, "callback %d", ev);
  390. if(context) {
  391. return;
  392. }
  393. }
  394. FuriHalUsbInterface usb_hid_bulk = {
  395. .init = hid_u2f_init,
  396. .deinit = hid_u2f_deinit,
  397. .wakeup = hid_u2f_on_wakeup,
  398. .suspend = hid_u2f_on_suspend,
  399. .dev_descr = (struct usb_device_descriptor*)&hid_u2f_device_desc,
  400. .str_manuf_descr = (void*)&dev_manuf_desc,
  401. .str_prod_descr = (void*)&dev_prod_desc,
  402. .str_serial_descr = NULL,
  403. .cfg_descr = (void*)&hid_u2f_cfg_desc,
  404. };
  405. FuriHalUsbInterface* getUsbHidBulk() {
  406. return &usb_hid_bulk;
  407. }
  408. typedef struct ThreadContext {
  409. uint8_t id;
  410. FuriThread* thread;
  411. FuriSemaphore* hid;
  412. } ThreadContext;
  413. static ThreadContext* threadContexts[NUM_OF_INTERFACES];
  414. static FuriMessageQueue* dataQueue;
  415. static uint32_t tick_space = 0;
  416. static void logQueueStats() {
  417. uint32_t ticks = furi_get_tick();
  418. if(ticks - tick_space > 4000) {
  419. tick_space = ticks;
  420. size_t queueSize = furi_message_queue_get_count(dataQueue);
  421. size_t freeS = furi_message_queue_get_space(dataQueue);
  422. double heapFree = memmgr_get_free_heap() / 1000;
  423. double totalHeap = memmgr_get_total_heap() / 1000;
  424. FURI_LOG_D(
  425. TAG,
  426. "Stats:\r\n\tQueueCount: %d\r\n\tQueueSpace: %d\r\n\tHeapFree: %.3f\r\n\tTotalHeap: %.3f",
  427. queueSize,
  428. freeS,
  429. heapFree,
  430. totalHeap);
  431. }
  432. }
  433. int32_t send_data_thread(void* context) {
  434. ThreadContext* ctx = (ThreadContext*)context;
  435. while(true) {
  436. ThreadMessage msg;
  437. furi_check(furi_message_queue_get(dataQueue, &msg, FuriWaitForever) == FuriStatusOk);
  438. if(msg.dataPointer == NULL) {
  439. FURI_LOG_D(
  440. TAG_IF,
  441. "Shutting down thread %s",
  442. furi_thread_get_name(furi_thread_get_id(ctx->thread)));
  443. return 0;
  444. }
  445. furi_check(furi_semaphore_acquire(ctx->hid, FuriWaitForever) == FuriStatusOk);
  446. usbd_ep_write(usb_dev, HID_EP_IN + ctx->id, msg.dataPointer, 64);
  447. free(msg.dataPointer);
  448. furi_thread_yield();
  449. }
  450. }
  451. int32_t receive_data_thread(void* context) {
  452. ThreadContext* ctx = (ThreadContext*)context;
  453. uint8_t* data;
  454. int32_t len;
  455. bool received = false;
  456. while(true) {
  457. if(!received) {
  458. furi_check(furi_semaphore_acquire(ctx->hid, FuriWaitForever) == FuriStatusOk);
  459. } else {
  460. FuriStatus status = furi_semaphore_acquire(ctx->hid, 5000);
  461. if(status == FuriStatusErrorTimeout) {
  462. FURI_LOG_I(TAG_IF, "Timeout, terminating thread %d", ctx->id);
  463. ThreadMessage msg = {.dataPointer = NULL};
  464. furi_check(
  465. furi_message_queue_put(dataQueue, &msg, FuriWaitForever) == FuriStatusOk);
  466. return 0;
  467. }
  468. furi_check(status == FuriStatusOk);
  469. }
  470. data = malloc(64);
  471. len = usbd_ep_read(usb_dev, HID_EP_OUT + ctx->id, data, 64);
  472. if(len <= 0) {
  473. FURI_LOG_D(TAG_IF, "Received 0 bytes (EP %d)", ctx->id);
  474. free(data);
  475. furi_thread_yield();
  476. continue;
  477. } else if(len < 64) {
  478. FURI_LOG_D(TAG_IF, "Received %ld bytes (EP %d)", len, ctx->id);
  479. }
  480. //FURI_LOG_D(TAG_IF, "Received %ld bytes (EP %d)", len, ctx->id);
  481. //FURI_LOG_D(TAG_IF, "0: %02x last: %02x", data[0], data[len-1]);
  482. received = true;
  483. ThreadMessage msg = {.dataPointer = data};
  484. furi_check(furi_message_queue_put(dataQueue, &msg, FuriWaitForever) == FuriStatusOk);
  485. logQueueStats();
  486. furi_thread_yield();
  487. }
  488. }
  489. static int sendThreads = 0;
  490. void initializeSendingData(int sendingThreads) {
  491. furi_check(sendingThreads <= NUM_OF_INTERFACES);
  492. sendThreads = sendingThreads;
  493. for(int i = 0; i < sendThreads; i++) {
  494. ThreadContext* ctx = threadContexts[i];
  495. char name[15];
  496. snprintf(name, 15, "SendThread %d", ctx->id);
  497. FURI_LOG_D(TAG_IF, "Spawn thread %s", name);
  498. ctx->thread = furi_thread_alloc_ex(name, 512, send_data_thread, ctx);
  499. furi_thread_start(ctx->thread);
  500. }
  501. }
  502. void stopSendingData() {
  503. for(int i = 0; i < sendThreads; i++) {
  504. ThreadMessage msg = {.dataPointer = NULL};
  505. furi_check(furi_message_queue_put(dataQueue, &msg, FuriWaitForever) == FuriStatusOk);
  506. }
  507. for(int i = 0; i < sendThreads; i++) {
  508. ThreadContext* ctx = threadContexts[i];
  509. furi_thread_join(ctx->thread);
  510. furi_thread_free(ctx->thread);
  511. }
  512. }
  513. FuriMessageQueue* initializeReceivingData() {
  514. for(int i = 0; i < NUM_OF_INTERFACES; i++) {
  515. ThreadContext* ctx = threadContexts[i];
  516. char name[16];
  517. snprintf(name, 16, "RecThread %d", ctx->id);
  518. FURI_LOG_D(TAG_IF, "Spawn thread %s", name);
  519. ctx->thread = furi_thread_alloc_ex(name, 1024, receive_data_thread, ctx);
  520. furi_thread_start(ctx->thread);
  521. }
  522. return dataQueue;
  523. }
  524. void stopReceivingData() {
  525. for(int i = 0; i < NUM_OF_INTERFACES; i++) {
  526. ThreadContext* ctx = threadContexts[i];
  527. furi_thread_join(ctx->thread);
  528. furi_thread_free(ctx->thread);
  529. }
  530. }
  531. void sendBulkData(uint8_t* data, uint8_t len) {
  532. UNUSED(len);
  533. ThreadMessage msg = {.dataPointer = data};
  534. logQueueStats();
  535. furi_check(furi_message_queue_put(dataQueue, &msg, FuriWaitForever) == FuriStatusOk);
  536. }
  537. void sendViaEP(uint8_t* data, int interfaceNumber) {
  538. ThreadContext* ctx = threadContexts[interfaceNumber];
  539. furi_check(furi_semaphore_acquire(ctx->hid, FuriWaitForever) == FuriStatusOk);
  540. usbd_ep_write(usb_dev, HID_EP_IN + ctx->id, data, 64);
  541. }
  542. void receiveFromEP(uint8_t* outBuf, int interfaceNumber) {
  543. ThreadContext* ctx = threadContexts[interfaceNumber];
  544. furi_check(furi_semaphore_acquire(ctx->hid, FuriWaitForever) == FuriStatusOk);
  545. usbd_ep_read(usb_dev, HID_EP_OUT + ctx->id, outBuf, 64);
  546. }
  547. static void hid_u2f_init(usbd_device* dev, FuriHalUsbInterface* intf, void* ctx) {
  548. FURI_LOG_D(TAG_IF, "hid_u2f_init");
  549. UNUSED(intf);
  550. UNUSED(ctx);
  551. if(threadContexts[0] == NULL) {
  552. dataQueue = furi_message_queue_alloc(1000, sizeof(ThreadMessage));
  553. for(int i = 0; i < NUM_OF_INTERFACES; i++) {
  554. ThreadContext* ctx = malloc(sizeof(ThreadContext));
  555. threadContexts[i] = ctx;
  556. ctx->hid = furi_semaphore_alloc(1, 1);
  557. ctx->id = i;
  558. }
  559. }
  560. usb_dev = dev;
  561. usbd_reg_config(dev, hid_u2f_ep_config);
  562. usbd_reg_control(dev, hid_u2f_controlf);
  563. usbd_connect(dev, true);
  564. }
  565. static void hid_u2f_deinit(usbd_device* dev) {
  566. FURI_LOG_D(TAG_IF, "hid_u2f_deinit");
  567. usbd_reg_config(dev, NULL);
  568. usbd_reg_control(dev, NULL);
  569. for(int i = 0; i < NUM_OF_INTERFACES; i++) {
  570. ThreadContext* ctx = threadContexts[i];
  571. furi_semaphore_free(ctx->hid);
  572. free(threadContexts[i]);
  573. }
  574. }
  575. static void hid_u2f_on_wakeup(usbd_device* dev) {
  576. FURI_LOG_D(TAG_IF, "hid_u2f_on_wakeup");
  577. UNUSED(dev);
  578. hid_u2f_connected = true;
  579. callbackf(HidU2fConnected, cb_ctx);
  580. }
  581. static void hid_u2f_on_suspend(usbd_device* dev) {
  582. FURI_LOG_D(TAG_IF, "hid_u2f_on_suspend");
  583. UNUSED(dev);
  584. if(hid_u2f_connected) {
  585. hid_u2f_connected = false;
  586. for(int i = 0; i < NUM_OF_INTERFACES; i++) {
  587. furi_semaphore_release(threadContexts[i]->hid);
  588. }
  589. callbackf(HidU2fDisconnected, cb_ctx);
  590. }
  591. }
  592. static void hid_u2f_txrx_ep_callback(usbd_device* dev, uint8_t event, uint8_t ep) {
  593. UNUSED(dev);
  594. UNUSED(event);
  595. UNUSED(ep);
  596. if(ep >= HID_EP_IN) {
  597. furi_semaphore_release(threadContexts[ep - HID_EP_IN]->hid);
  598. } else {
  599. furi_semaphore_release(threadContexts[ep - HID_EP_OUT]->hid);
  600. }
  601. }
  602. /* Configure endpoints */
  603. static usbd_respond hid_u2f_ep_config(usbd_device* dev, uint8_t cfg) {
  604. switch(cfg) {
  605. case 0:
  606. /* deconfiguring device */
  607. for(int i = 0; i < NUM_OF_INTERFACES; i++) {
  608. usbd_ep_deconfig(dev, HID_EP_OUT + i);
  609. usbd_ep_deconfig(dev, HID_EP_IN + i);
  610. usbd_reg_endpoint(dev, HID_EP_OUT + i, 0);
  611. usbd_reg_endpoint(dev, HID_EP_IN + i, 0);
  612. }
  613. return usbd_ack;
  614. case 1:
  615. /* configuring device */
  616. for(int i = 0; i < NUM_OF_INTERFACES; i++) {
  617. usbd_ep_config(dev, HID_EP_IN + i, endpoint_type, HID_U2F_PACKET_LEN);
  618. usbd_ep_config(dev, HID_EP_OUT + i, endpoint_type, HID_U2F_PACKET_LEN);
  619. usbd_reg_endpoint(dev, HID_EP_IN + i, hid_u2f_txrx_ep_callback);
  620. usbd_reg_endpoint(dev, HID_EP_OUT + i, hid_u2f_txrx_ep_callback);
  621. usbd_ep_write(dev, HID_EP_IN + 1, 0, 0);
  622. }
  623. return usbd_ack;
  624. default:
  625. return usbd_fail;
  626. }
  627. }
  628. /* Control requests handler */
  629. usbd_respond hid_u2f_controlf(usbd_device* dev, usbd_ctlreq* req, usbd_rqc_callback* callback) {
  630. UNUSED(callback);
  631. FURI_LOG_D(
  632. TAG_IF,
  633. "control: RT %02x, R %02x, V %04x, I %04x, L %04x",
  634. req->bmRequestType,
  635. req->bRequest,
  636. req->wValue,
  637. req->wIndex,
  638. req->wLength);
  639. /* HID control requests */
  640. if(((USB_REQ_RECIPIENT | USB_REQ_TYPE) & req->bmRequestType) ==
  641. (USB_REQ_INTERFACE | USB_REQ_CLASS) &&
  642. req->wIndex == 0) {
  643. switch(req->bRequest) {
  644. case USB_HID_SETIDLE:
  645. return usbd_ack;
  646. case USB_STD_SET_INTERFACE:
  647. return usbd_ack;
  648. default:
  649. return usbd_fail;
  650. }
  651. }
  652. if(((USB_REQ_RECIPIENT | USB_REQ_TYPE) & req->bmRequestType) ==
  653. (USB_REQ_INTERFACE | USB_REQ_STANDARD) &&
  654. req->bRequest == USB_STD_GET_DESCRIPTOR) {
  655. switch(req->wValue >> 8) {
  656. case USB_DTYPE_HID:
  657. //dev->status.data_ptr = (uint8_t*)&(hid_u2f_cfg_desc.iad_0.hid_desc2);
  658. //dev->status.data_count = sizeof(hid_u2f_cfg_desc.iad_0.hid_desc2);
  659. return usbd_fail;
  660. case USB_DTYPE_HID_REPORT:
  661. dev->status.data_ptr = (uint8_t*)hid_u2f_report_desc;
  662. dev->status.data_count = sizeof(hid_u2f_report_desc);
  663. return usbd_ack;
  664. case USB_STD_SET_INTERFACE:
  665. case USB_STD_GET_INTERFACE:
  666. return usbd_ack;
  667. default:
  668. return usbd_fail;
  669. }
  670. }
  671. return usbd_fail;
  672. }