Advertisement
Guest User

Untitled

a guest
Dec 9th, 2018
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.04 KB | None | 0 0
  1. /*
  2. * uMTP Responder
  3. * Copyright (c) 2018 Viveris Technologies
  4. *
  5. * uMTP Responder is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 3.0 of the License, or (at your option) any later version.
  9. *
  10. * uMTP Responder is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * General Public License version 3 for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with uMTP Responder; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  18. */
  19.  
  20. #include "nx/usbds.h"
  21. #include "mtp.h"
  22. #include "logs_out.h"
  23.  
  24. #include <stdlib.h>
  25. #include <malloc.h>
  26. #include <string.h>
  27. #include <arpa/inet.h>
  28.  
  29. #define USBDS_TIMEOUT_MS 10000
  30. #define CHKPT printf("%s:%d\n", __FUNCTION__, __LINE__);
  31.  
  32. extern void* io_thread(void* arg);
  33.  
  34. usb_ctx * init_usb_mtp(mtp_ctx * ctx)
  35. {
  36. usb_ctx * usbctx;
  37. struct usb_device_descriptor desc;
  38. struct usb_interface_descriptor if_desc;
  39. struct usb_endpoint_descriptor ep_desc_in, ep_desc_out, ep_desc_int;
  40.  
  41. consoleInit(NULL);
  42.  
  43. // Initialise sockets
  44. socketInitializeDefault();
  45.  
  46. // Other initialization goes here. As a demonstration, we print hello world.
  47. printf("Hello World!\n");
  48.  
  49. // the host ip where nxlink was launched
  50. printf("nxlink host is %s\n", inet_ntoa(__nxlink_host));
  51.  
  52. // redirect stdout & stderr over network to nxlink
  53. nxlinkStdio();
  54. CHKPT
  55. usbctx = malloc(sizeof(usb_ctx));
  56. usbctx->stop = 0;
  57. //usbctx->wrbuffer = memalign(0x1000, ctx->usb_cfg.usb_max_packet_size);
  58. //usbctx->rdbuffer = memalign(0x1000, ctx->usb_cfg.usb_max_packet_size);
  59. CHKPT
  60. if (R_FAILED(usbDsInitialize()))
  61. {
  62. PRINT_DEBUG("init_usb_mtp: Failed to initialize usb:ds");
  63. goto init_fail;
  64. }
  65. CHKPT
  66. static const u16 langs[1] = {0x0409};
  67. usbDsAddUsbLanguageStringDescriptor(NULL, langs, sizeof(langs)/sizeof(u16));
  68. CHKPT
  69. memset(&desc, 0, sizeof(desc));
  70. desc.bLength = USB_DT_DEVICE_SIZE;
  71. desc.bDescriptorType = USB_DT_DEVICE;
  72. desc.bcdUSB = 0x0110;
  73. desc.bDeviceClass = ctx->usb_cfg.usb_class;
  74. desc.bDeviceSubClass = ctx->usb_cfg.usb_subclass;
  75. desc.bDeviceProtocol = ctx->usb_cfg.usb_protocol;
  76. desc.idVendor = ctx->usb_cfg.usb_vendor_id;
  77. desc.idProduct = ctx->usb_cfg.usb_product_id;
  78. desc.bcdDevice = ctx->usb_cfg.usb_dev_version; // Version
  79. usbDsAddUsbStringDescriptor(&desc.iManufacturer, ctx->usb_cfg.usb_string_manufacturer);
  80. usbDsAddUsbStringDescriptor(&desc.iProduct, ctx->usb_cfg.usb_string_product);
  81. usbDsAddUsbStringDescriptor(&desc.iSerialNumber, ctx->usb_cfg.usb_string_serial);
  82. desc.bNumConfigurations = 1; // Only one configuration
  83. CHKPT
  84. if (R_FAILED(usbDsSetUsbDeviceDescriptor(UsbDeviceSpeed_Full, &desc)))
  85. {
  86. PRINT_DEBUG("init_usb_mtp: Failed to set usb 1.1 device descriptor");
  87. goto init_fail;
  88. }
  89. CHKPT
  90. desc.bcdUSB = 0x0200;
  91. if (R_FAILED(usbDsSetUsbDeviceDescriptor(UsbDeviceSpeed_High, &desc)))
  92. {
  93. PRINT_DEBUG("init_usb_mtp: Failed to set usb 2.0 device descriptor");
  94. goto init_fail;
  95. }
  96. CHKPT
  97. // TODO: USB 3.0 support including Binary Object Store
  98.  
  99. if (R_FAILED(usbDsRegisterInterface(&usbctx->intf)))
  100. {
  101. PRINT_DEBUG("init_usb_mtp: Failed to register interface");
  102. goto init_fail;
  103. }
  104. CHKPT
  105. memset(&if_desc, 0, sizeof(if_desc));
  106. if_desc.bLength = USB_DT_INTERFACE_SIZE;
  107. if_desc.bDescriptorType = USB_DT_INTERFACE;
  108. if_desc.bInterfaceNumber = 0;
  109. if_desc.iInterface = 1;
  110. if_desc.bAlternateSetting = 0;
  111. if_desc.bNumEndpoints = 3;
  112. if_desc.bInterfaceClass = ctx->usb_cfg.usb_class;
  113. if_desc.bInterfaceSubClass = ctx->usb_cfg.usb_subclass;
  114. if_desc.bInterfaceProtocol = ctx->usb_cfg.usb_protocol;
  115. if (R_FAILED(usbDsInterface_AppendConfigurationData(usbctx->intf, UsbDeviceSpeed_Full, &if_desc, USB_DT_INTERFACE_SIZE)))
  116. {
  117. PRINT_DEBUG("init_usb_mtp: Failed to append interface configuration");
  118. goto init_fail;
  119. }
  120. CHKPT
  121. memset(&ep_desc_in, 0, sizeof(ep_desc_in));
  122. ep_desc_in.bLength = USB_DT_ENDPOINT_SIZE;
  123. ep_desc_in.bDescriptorType = USB_DT_ENDPOINT;
  124. ep_desc_in.bEndpointAddress = USB_ENDPOINT_IN + usbctx->intf->interface_index + 1;
  125. ep_desc_in.bmAttributes = USB_TRANSFER_TYPE_BULK;
  126. ep_desc_in.wMaxPacketSize = ctx->usb_cfg.usb_max_packet_size;
  127. if (R_FAILED(usbDsInterface_AppendConfigurationData(usbctx->intf, UsbDeviceSpeed_Full, &ep_desc_in, USB_DT_ENDPOINT_SIZE)))
  128. {
  129. PRINT_DEBUG("init_usb_mtp: Failed to append input endpoint configuration");
  130. goto init_fail;
  131. }
  132. CHKPT
  133. memset(&ep_desc_out, 0, sizeof(ep_desc_out));
  134. ep_desc_out.bLength = USB_DT_ENDPOINT_SIZE;
  135. ep_desc_out.bDescriptorType = USB_DT_ENDPOINT;
  136. ep_desc_out.bEndpointAddress = USB_ENDPOINT_OUT + usbctx->intf->interface_index + 1;
  137. ep_desc_out.bmAttributes = USB_TRANSFER_TYPE_BULK;
  138. ep_desc_out.wMaxPacketSize = ctx->usb_cfg.usb_max_packet_size;
  139. if (R_FAILED(usbDsInterface_AppendConfigurationData(usbctx->intf, UsbDeviceSpeed_Full, &ep_desc_out, USB_DT_ENDPOINT_SIZE)))
  140. {
  141. PRINT_DEBUG("init_usb_mtp: Failed to append output endpoint configuration");
  142. goto init_fail;
  143. }
  144. CHKPT
  145. memset(&ep_desc_int, 0, sizeof(ep_desc_int));
  146. ep_desc_int.bLength = USB_DT_ENDPOINT_SIZE;
  147. ep_desc_int.bDescriptorType = USB_DT_ENDPOINT;
  148. ep_desc_int.bEndpointAddress = USB_ENDPOINT_IN + usbctx->intf->interface_index + 2;
  149. ep_desc_int.bmAttributes = USB_TRANSFER_TYPE_INTERRUPT;
  150. ep_desc_int.wMaxPacketSize = 8;
  151. ep_desc_int.bInterval = 6;
  152. if (R_FAILED(usbDsInterface_AppendConfigurationData(usbctx->intf, UsbDeviceSpeed_Full, &ep_desc_int, USB_DT_ENDPOINT_SIZE)))
  153. {
  154. PRINT_DEBUG("init_usb_mtp: Failed to append interrupt endpoint configuration");
  155. goto init_fail;
  156. }
  157. CHKPT
  158. if (R_FAILED(usbDsInterface_AppendConfigurationData(usbctx->intf, UsbDeviceSpeed_High, &if_desc, USB_DT_INTERFACE_SIZE)))
  159. {
  160. PRINT_DEBUG("init_usb_mtp: Failed to append interface configuration");
  161. goto init_fail;
  162. }
  163. CHKPT
  164. if (R_FAILED(usbDsInterface_AppendConfigurationData(usbctx->intf, UsbDeviceSpeed_High, &ep_desc_in, USB_DT_ENDPOINT_SIZE)))
  165. {
  166. PRINT_DEBUG("init_usb_mtp: Failed to append input endpoint configuration");
  167. goto init_fail;
  168. }
  169. CHKPT
  170. if (R_FAILED(usbDsInterface_AppendConfigurationData(usbctx->intf, UsbDeviceSpeed_High, &ep_desc_out, USB_DT_ENDPOINT_SIZE)))
  171. {
  172. PRINT_DEBUG("init_usb_mtp: Failed to append output endpoint configuration");
  173. goto init_fail;
  174. }
  175. CHKPT
  176. ep_desc_int.wMaxPacketSize = 28; // HS size
  177. if (R_FAILED(usbDsInterface_AppendConfigurationData(usbctx->intf, UsbDeviceSpeed_High, &ep_desc_int, USB_DT_ENDPOINT_SIZE)))
  178. {
  179. PRINT_DEBUG("init_usb_mtp: Failed to append interrupt endpoint configuration");
  180. goto init_fail;
  181. }
  182. CHKPT
  183. if (R_FAILED(usbDsInterface_RegisterEndpoint(usbctx->intf, &usbctx->eps[EP_DESCRIPTOR_IN], ep_desc_in.bEndpointAddress)))
  184. {
  185. PRINT_DEBUG("init_usb_mtp: Failed to register input endpoint");
  186. goto init_fail;
  187. }
  188. CHKPT
  189. if (R_FAILED(usbDsInterface_RegisterEndpoint(usbctx->intf, &usbctx->eps[EP_DESCRIPTOR_OUT], ep_desc_out.bEndpointAddress)))
  190. {
  191. PRINT_DEBUG("init_usb_mtp: Failed to register output endpoint");
  192. goto init_fail;
  193. }
  194. CHKPT
  195. if (R_FAILED(usbDsInterface_RegisterEndpoint(usbctx->intf, &usbctx->eps[EP_DESCRIPTOR_INT_IN], ep_desc_int.bEndpointAddress)))
  196. {
  197. PRINT_DEBUG("init_usb_mtp: Failed to register interrupt endpoint");
  198. goto init_fail;
  199. }
  200. CHKPT
  201. if (R_FAILED(usbDsInterface_EnableInterface(usbctx->intf)))
  202. {
  203. PRINT_DEBUG("init_usb_mtp: Failed to enable interface");
  204. goto init_fail;
  205. }
  206. CHKPT
  207. if (R_FAILED(usbDsEnable()))
  208. {
  209. PRINT_DEBUG("init_usb_mtp: Failed to enable usb");
  210. goto init_fail;
  211. }
  212. CHKPT
  213. PRINT_DEBUG("usbDs : USB config done");
  214. return usbctx;
  215.  
  216. init_fail:
  217. CHKPT
  218. free(usbctx->rdbuffer);
  219. free(usbctx->wrbuffer);
  220. free(usbctx);
  221. return NULL;
  222. }
  223.  
  224. int read_usb(usb_ctx * ctx, unsigned char * buffer, int maxsize)
  225. {
  226. Result rc;
  227. u32 urbId;
  228.  
  229. PRINT_DEBUG("read_usb : Waiting on ready");
  230. rc = usbDsWaitReady(USBDS_TIMEOUT_MS);
  231. if (R_FAILED(rc))
  232. {
  233. return -1;
  234. }
  235.  
  236. if (!ctx->eps[EP_DESCRIPTOR_OUT] || !maxsize || !buffer)
  237. {
  238. return -1;
  239. }
  240.  
  241. PRINT_DEBUG("read_usb : Post buffer");
  242. rc = usbDsEndpoint_PostBufferAsync(ctx->eps[EP_DESCRIPTOR_OUT], &ctx->rdbuffer, maxsize, &urbId);
  243. if (R_SUCCEEDED(rc))
  244. {
  245. PRINT_DEBUG("read_usb : Wait on event");
  246. eventWait(&ctx->eps[EP_DESCRIPTOR_OUT]->CompletionEvent, USBDS_TIMEOUT_MS);
  247. eventClear(&ctx->eps[EP_DESCRIPTOR_OUT]->CompletionEvent);
  248. }
  249.  
  250. PRINT_DEBUG("read_usb : Copying buffer");
  251. memcpy(buffer, ctx->rdbuffer, maxsize);
  252. return -rc;
  253. }
  254.  
  255. int write_usb(usb_ctx * ctx, unsigned char * buffer, int size)
  256. {
  257. Result rc;
  258. u32 urbId;
  259.  
  260. PRINT_DEBUG("write_usb : Waiting on ready");
  261. rc = usbDsWaitReady(USBDS_TIMEOUT_MS);
  262. if (R_FAILED(rc))
  263. {
  264. return -1;
  265. }
  266.  
  267. if (!ctx->eps[EP_DESCRIPTOR_IN] || !buffer)
  268. {
  269. return -1;
  270. }
  271.  
  272. PRINT_DEBUG("write_usb : Copying buffer");
  273. memcpy(ctx->wrbuffer, buffer, size);
  274.  
  275. PRINT_DEBUG("write_usb : Post buffer");
  276. rc = usbDsEndpoint_PostBufferAsync(ctx->eps[EP_DESCRIPTOR_IN], &ctx->wrbuffer, size, &urbId);
  277. if (R_SUCCEEDED(rc))
  278. {
  279. PRINT_DEBUG("write_usb : Wait on event");
  280. eventWait(&ctx->eps[EP_DESCRIPTOR_IN]->CompletionEvent, USBDS_TIMEOUT_MS);
  281. eventClear(&ctx->eps[EP_DESCRIPTOR_IN]->CompletionEvent);
  282. }
  283.  
  284. return -rc;
  285. }
  286.  
  287. int handle_ep0(usb_ctx * ctx)
  288. {
  289. io_thread(ctx);
  290. PRINT_DEBUG("handle_ep0 : Leaving (ctx->stop=%d)...", ctx->stop);
  291. return 1;
  292. }
  293.  
  294. int is_usb_up(usb_ctx * ctx)
  295. {
  296. // Main loop
  297. appletMainLoop();
  298.  
  299. // Update the console, sending a new frame to the display
  300. consoleUpdate(NULL);
  301.  
  302. return !ctx->stop;
  303. }
  304.  
  305. void stop_usb(usb_ctx * ctx)
  306. {
  307. ctx->stop = 1;
  308. }
  309.  
  310. void deinit_usb_mtp(usb_ctx * usbctx)
  311. {
  312. free(usbctx->rdbuffer);
  313. free(usbctx->wrbuffer);
  314. free(usbctx);
  315. usbDsExit();
  316. consoleExit(NULL);
  317. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement