Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * uMTP Responder
- * Copyright (c) 2018 Viveris Technologies
- *
- * uMTP Responder is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public
- * License as published by the Free Software Foundation; either
- * version 3.0 of the License, or (at your option) any later version.
- *
- * uMTP Responder is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License version 3 for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with uMTP Responder; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
- #include "nx/usbds.h"
- #include "mtp.h"
- #include "logs_out.h"
- #include <stdlib.h>
- #include <malloc.h>
- #include <string.h>
- #include <arpa/inet.h>
- #define USBDS_TIMEOUT_MS 10000
- #define CHKPT printf("%s:%d\n", __FUNCTION__, __LINE__);
- extern void* io_thread(void* arg);
- usb_ctx * init_usb_mtp(mtp_ctx * ctx)
- {
- usb_ctx * usbctx;
- struct usb_device_descriptor desc;
- struct usb_interface_descriptor if_desc;
- struct usb_endpoint_descriptor ep_desc_in, ep_desc_out, ep_desc_int;
- consoleInit(NULL);
- // Initialise sockets
- socketInitializeDefault();
- // Other initialization goes here. As a demonstration, we print hello world.
- printf("Hello World!\n");
- // the host ip where nxlink was launched
- printf("nxlink host is %s\n", inet_ntoa(__nxlink_host));
- // redirect stdout & stderr over network to nxlink
- nxlinkStdio();
- CHKPT
- usbctx = malloc(sizeof(usb_ctx));
- usbctx->stop = 0;
- //usbctx->wrbuffer = memalign(0x1000, ctx->usb_cfg.usb_max_packet_size);
- //usbctx->rdbuffer = memalign(0x1000, ctx->usb_cfg.usb_max_packet_size);
- CHKPT
- if (R_FAILED(usbDsInitialize()))
- {
- PRINT_DEBUG("init_usb_mtp: Failed to initialize usb:ds");
- goto init_fail;
- }
- CHKPT
- static const u16 langs[1] = {0x0409};
- usbDsAddUsbLanguageStringDescriptor(NULL, langs, sizeof(langs)/sizeof(u16));
- CHKPT
- memset(&desc, 0, sizeof(desc));
- desc.bLength = USB_DT_DEVICE_SIZE;
- desc.bDescriptorType = USB_DT_DEVICE;
- desc.bcdUSB = 0x0110;
- desc.bDeviceClass = ctx->usb_cfg.usb_class;
- desc.bDeviceSubClass = ctx->usb_cfg.usb_subclass;
- desc.bDeviceProtocol = ctx->usb_cfg.usb_protocol;
- desc.idVendor = ctx->usb_cfg.usb_vendor_id;
- desc.idProduct = ctx->usb_cfg.usb_product_id;
- desc.bcdDevice = ctx->usb_cfg.usb_dev_version; // Version
- usbDsAddUsbStringDescriptor(&desc.iManufacturer, ctx->usb_cfg.usb_string_manufacturer);
- usbDsAddUsbStringDescriptor(&desc.iProduct, ctx->usb_cfg.usb_string_product);
- usbDsAddUsbStringDescriptor(&desc.iSerialNumber, ctx->usb_cfg.usb_string_serial);
- desc.bNumConfigurations = 1; // Only one configuration
- CHKPT
- if (R_FAILED(usbDsSetUsbDeviceDescriptor(UsbDeviceSpeed_Full, &desc)))
- {
- PRINT_DEBUG("init_usb_mtp: Failed to set usb 1.1 device descriptor");
- goto init_fail;
- }
- CHKPT
- desc.bcdUSB = 0x0200;
- if (R_FAILED(usbDsSetUsbDeviceDescriptor(UsbDeviceSpeed_High, &desc)))
- {
- PRINT_DEBUG("init_usb_mtp: Failed to set usb 2.0 device descriptor");
- goto init_fail;
- }
- CHKPT
- // TODO: USB 3.0 support including Binary Object Store
- if (R_FAILED(usbDsRegisterInterface(&usbctx->intf)))
- {
- PRINT_DEBUG("init_usb_mtp: Failed to register interface");
- goto init_fail;
- }
- CHKPT
- memset(&if_desc, 0, sizeof(if_desc));
- if_desc.bLength = USB_DT_INTERFACE_SIZE;
- if_desc.bDescriptorType = USB_DT_INTERFACE;
- if_desc.bInterfaceNumber = 0;
- if_desc.iInterface = 1;
- if_desc.bAlternateSetting = 0;
- if_desc.bNumEndpoints = 3;
- if_desc.bInterfaceClass = ctx->usb_cfg.usb_class;
- if_desc.bInterfaceSubClass = ctx->usb_cfg.usb_subclass;
- if_desc.bInterfaceProtocol = ctx->usb_cfg.usb_protocol;
- if (R_FAILED(usbDsInterface_AppendConfigurationData(usbctx->intf, UsbDeviceSpeed_Full, &if_desc, USB_DT_INTERFACE_SIZE)))
- {
- PRINT_DEBUG("init_usb_mtp: Failed to append interface configuration");
- goto init_fail;
- }
- CHKPT
- memset(&ep_desc_in, 0, sizeof(ep_desc_in));
- ep_desc_in.bLength = USB_DT_ENDPOINT_SIZE;
- ep_desc_in.bDescriptorType = USB_DT_ENDPOINT;
- ep_desc_in.bEndpointAddress = USB_ENDPOINT_IN + usbctx->intf->interface_index + 1;
- ep_desc_in.bmAttributes = USB_TRANSFER_TYPE_BULK;
- ep_desc_in.wMaxPacketSize = ctx->usb_cfg.usb_max_packet_size;
- if (R_FAILED(usbDsInterface_AppendConfigurationData(usbctx->intf, UsbDeviceSpeed_Full, &ep_desc_in, USB_DT_ENDPOINT_SIZE)))
- {
- PRINT_DEBUG("init_usb_mtp: Failed to append input endpoint configuration");
- goto init_fail;
- }
- CHKPT
- memset(&ep_desc_out, 0, sizeof(ep_desc_out));
- ep_desc_out.bLength = USB_DT_ENDPOINT_SIZE;
- ep_desc_out.bDescriptorType = USB_DT_ENDPOINT;
- ep_desc_out.bEndpointAddress = USB_ENDPOINT_OUT + usbctx->intf->interface_index + 1;
- ep_desc_out.bmAttributes = USB_TRANSFER_TYPE_BULK;
- ep_desc_out.wMaxPacketSize = ctx->usb_cfg.usb_max_packet_size;
- if (R_FAILED(usbDsInterface_AppendConfigurationData(usbctx->intf, UsbDeviceSpeed_Full, &ep_desc_out, USB_DT_ENDPOINT_SIZE)))
- {
- PRINT_DEBUG("init_usb_mtp: Failed to append output endpoint configuration");
- goto init_fail;
- }
- CHKPT
- memset(&ep_desc_int, 0, sizeof(ep_desc_int));
- ep_desc_int.bLength = USB_DT_ENDPOINT_SIZE;
- ep_desc_int.bDescriptorType = USB_DT_ENDPOINT;
- ep_desc_int.bEndpointAddress = USB_ENDPOINT_IN + usbctx->intf->interface_index + 2;
- ep_desc_int.bmAttributes = USB_TRANSFER_TYPE_INTERRUPT;
- ep_desc_int.wMaxPacketSize = 8;
- ep_desc_int.bInterval = 6;
- if (R_FAILED(usbDsInterface_AppendConfigurationData(usbctx->intf, UsbDeviceSpeed_Full, &ep_desc_int, USB_DT_ENDPOINT_SIZE)))
- {
- PRINT_DEBUG("init_usb_mtp: Failed to append interrupt endpoint configuration");
- goto init_fail;
- }
- CHKPT
- if (R_FAILED(usbDsInterface_AppendConfigurationData(usbctx->intf, UsbDeviceSpeed_High, &if_desc, USB_DT_INTERFACE_SIZE)))
- {
- PRINT_DEBUG("init_usb_mtp: Failed to append interface configuration");
- goto init_fail;
- }
- CHKPT
- if (R_FAILED(usbDsInterface_AppendConfigurationData(usbctx->intf, UsbDeviceSpeed_High, &ep_desc_in, USB_DT_ENDPOINT_SIZE)))
- {
- PRINT_DEBUG("init_usb_mtp: Failed to append input endpoint configuration");
- goto init_fail;
- }
- CHKPT
- if (R_FAILED(usbDsInterface_AppendConfigurationData(usbctx->intf, UsbDeviceSpeed_High, &ep_desc_out, USB_DT_ENDPOINT_SIZE)))
- {
- PRINT_DEBUG("init_usb_mtp: Failed to append output endpoint configuration");
- goto init_fail;
- }
- CHKPT
- ep_desc_int.wMaxPacketSize = 28; // HS size
- if (R_FAILED(usbDsInterface_AppendConfigurationData(usbctx->intf, UsbDeviceSpeed_High, &ep_desc_int, USB_DT_ENDPOINT_SIZE)))
- {
- PRINT_DEBUG("init_usb_mtp: Failed to append interrupt endpoint configuration");
- goto init_fail;
- }
- CHKPT
- if (R_FAILED(usbDsInterface_RegisterEndpoint(usbctx->intf, &usbctx->eps[EP_DESCRIPTOR_IN], ep_desc_in.bEndpointAddress)))
- {
- PRINT_DEBUG("init_usb_mtp: Failed to register input endpoint");
- goto init_fail;
- }
- CHKPT
- if (R_FAILED(usbDsInterface_RegisterEndpoint(usbctx->intf, &usbctx->eps[EP_DESCRIPTOR_OUT], ep_desc_out.bEndpointAddress)))
- {
- PRINT_DEBUG("init_usb_mtp: Failed to register output endpoint");
- goto init_fail;
- }
- CHKPT
- if (R_FAILED(usbDsInterface_RegisterEndpoint(usbctx->intf, &usbctx->eps[EP_DESCRIPTOR_INT_IN], ep_desc_int.bEndpointAddress)))
- {
- PRINT_DEBUG("init_usb_mtp: Failed to register interrupt endpoint");
- goto init_fail;
- }
- CHKPT
- if (R_FAILED(usbDsInterface_EnableInterface(usbctx->intf)))
- {
- PRINT_DEBUG("init_usb_mtp: Failed to enable interface");
- goto init_fail;
- }
- CHKPT
- if (R_FAILED(usbDsEnable()))
- {
- PRINT_DEBUG("init_usb_mtp: Failed to enable usb");
- goto init_fail;
- }
- CHKPT
- PRINT_DEBUG("usbDs : USB config done");
- return usbctx;
- init_fail:
- CHKPT
- free(usbctx->rdbuffer);
- free(usbctx->wrbuffer);
- free(usbctx);
- return NULL;
- }
- int read_usb(usb_ctx * ctx, unsigned char * buffer, int maxsize)
- {
- Result rc;
- u32 urbId;
- PRINT_DEBUG("read_usb : Waiting on ready");
- rc = usbDsWaitReady(USBDS_TIMEOUT_MS);
- if (R_FAILED(rc))
- {
- return -1;
- }
- if (!ctx->eps[EP_DESCRIPTOR_OUT] || !maxsize || !buffer)
- {
- return -1;
- }
- PRINT_DEBUG("read_usb : Post buffer");
- rc = usbDsEndpoint_PostBufferAsync(ctx->eps[EP_DESCRIPTOR_OUT], &ctx->rdbuffer, maxsize, &urbId);
- if (R_SUCCEEDED(rc))
- {
- PRINT_DEBUG("read_usb : Wait on event");
- eventWait(&ctx->eps[EP_DESCRIPTOR_OUT]->CompletionEvent, USBDS_TIMEOUT_MS);
- eventClear(&ctx->eps[EP_DESCRIPTOR_OUT]->CompletionEvent);
- }
- PRINT_DEBUG("read_usb : Copying buffer");
- memcpy(buffer, ctx->rdbuffer, maxsize);
- return -rc;
- }
- int write_usb(usb_ctx * ctx, unsigned char * buffer, int size)
- {
- Result rc;
- u32 urbId;
- PRINT_DEBUG("write_usb : Waiting on ready");
- rc = usbDsWaitReady(USBDS_TIMEOUT_MS);
- if (R_FAILED(rc))
- {
- return -1;
- }
- if (!ctx->eps[EP_DESCRIPTOR_IN] || !buffer)
- {
- return -1;
- }
- PRINT_DEBUG("write_usb : Copying buffer");
- memcpy(ctx->wrbuffer, buffer, size);
- PRINT_DEBUG("write_usb : Post buffer");
- rc = usbDsEndpoint_PostBufferAsync(ctx->eps[EP_DESCRIPTOR_IN], &ctx->wrbuffer, size, &urbId);
- if (R_SUCCEEDED(rc))
- {
- PRINT_DEBUG("write_usb : Wait on event");
- eventWait(&ctx->eps[EP_DESCRIPTOR_IN]->CompletionEvent, USBDS_TIMEOUT_MS);
- eventClear(&ctx->eps[EP_DESCRIPTOR_IN]->CompletionEvent);
- }
- return -rc;
- }
- int handle_ep0(usb_ctx * ctx)
- {
- io_thread(ctx);
- PRINT_DEBUG("handle_ep0 : Leaving (ctx->stop=%d)...", ctx->stop);
- return 1;
- }
- int is_usb_up(usb_ctx * ctx)
- {
- // Main loop
- appletMainLoop();
- // Update the console, sending a new frame to the display
- consoleUpdate(NULL);
- return !ctx->stop;
- }
- void stop_usb(usb_ctx * ctx)
- {
- ctx->stop = 1;
- }
- void deinit_usb_mtp(usb_ctx * usbctx)
- {
- free(usbctx->rdbuffer);
- free(usbctx->wrbuffer);
- free(usbctx);
- usbDsExit();
- consoleExit(NULL);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement