usbif.c 28 KB

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