This fork re-enables FRDM boards and adds WebUSB CDC functionality

Fork of USBDevice_STM32F103 by Devan Lai

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers WebUSBDevice.cpp Source File

WebUSBDevice.cpp

00001 /*
00002 * Copyright 2016 Devan Lai
00003 * Modifications copyright 2017 Lars Gunder Knudsen
00004 *
00005 * Licensed under the Apache License, Version 2.0 (the "License");
00006 * you may not use this file except in compliance with the License.
00007 * You may obtain a copy of the License at
00008 *
00009 *    http://www.apache.org/licenses/LICENSE-2.0
00010 *
00011 * Unless required by applicable law or agreed to in writing, software
00012 * distributed under the License is distributed on an "AS IS" BASIS,
00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014 * See the License for the specific language governing permissions and
00015 * limitations under the License.
00016 */
00017 
00018 #include "stdint.h"
00019 
00020 #include "USBEndpoints.h"
00021 #include "USBDevice.h"
00022 #include "USBDescriptor.h"
00023 #include "WebUSB.h"
00024 #include "WebUSBDevice.h"
00025 #include "../USBDFU/WinUSB.h"
00026 
00027 WebUSBDevice::WebUSBDevice(uint16_t vendor_id, uint16_t product_id, uint16_t product_release)
00028     : USBDevice(vendor_id, product_id, product_release)
00029 {
00030 
00031 };
00032 
00033 bool WebUSBDevice::requestGetDescriptor(void)
00034 {
00035     bool success = false;
00036     CONTROL_TRANSFER * transfer = getTransferPtr();
00037     switch (DESCRIPTOR_TYPE(transfer->setup.wValue))
00038     {
00039         case BINARY_OBJECT_STORE_DESCRIPTOR:
00040             if (binaryObjectStoreDesc() != NULL)
00041             {
00042                 transfer->remaining = (binaryObjectStoreDesc()[2]
00043                                     | (binaryObjectStoreDesc()[3] << 8));
00044                 transfer->ptr = binaryObjectStoreDesc();
00045                 transfer->direction = DEVICE_TO_HOST;
00046                 success = true;
00047             }
00048             break;
00049         default:
00050             success = USBDevice::requestGetDescriptor();
00051             break;
00052     }
00053 
00054     return success;
00055 }
00056 
00057 bool WebUSBDevice::requestWebUSB(void)
00058 {
00059     bool success = false;
00060 
00061     CONTROL_TRANSFER * transfer = getTransferPtr();
00062     switch (transfer->setup.wIndex)
00063     {
00064         case WEBUSB_GET_ALLOWED_ORIGINS:
00065             if (allowedOriginsDesc())
00066             {
00067                 transfer->remaining = (allowedOriginsDesc()[2]
00068                                    |  (allowedOriginsDesc()[3] << 8));
00069                 transfer->ptr = allowedOriginsDesc();
00070                 transfer->direction = DEVICE_TO_HOST;
00071                 success = true;
00072             }
00073             break;
00074         case WEBUSB_GET_URL:
00075             if (transfer->setup.wValue == URL_OFFSET_LANDING_PAGE)
00076             {
00077                 transfer->remaining = urlIlandingPage()[0];
00078                 transfer->ptr = urlIlandingPage();
00079                 transfer->direction = DEVICE_TO_HOST;
00080                 success = true;
00081             }
00082             else if (transfer->setup.wValue == URL_OFFSET_ALLOWED_ORIGIN)
00083             {
00084                 transfer->remaining = urlIallowedOrigin()[0];
00085                 transfer->ptr = urlIallowedOrigin();
00086                 transfer->direction = DEVICE_TO_HOST;
00087                 success = true;
00088             }
00089             break;
00090         default:
00091             break;
00092     }
00093 
00094     return success;
00095 }
00096 
00097 bool WebUSBDevice::USBCallback_request()
00098 {
00099     bool success = false;
00100     /* Process WebUSB requests */
00101     CONTROL_TRANSFER * transfer = getTransferPtr();
00102     if ((transfer->setup.bmRequestType.Type == VENDOR_TYPE) &&
00103         (transfer->setup.bRequest == WEBUSB_VENDOR_CODE))
00104     {
00105         success = requestWebUSB();
00106     }
00107     
00108     return success;
00109 }
00110 
00111 uint8_t * WebUSBDevice::deviceDesc() {
00112     static uint8_t deviceDescriptor[] = {
00113         DEVICE_DESCRIPTOR_LENGTH,       /* bLength */
00114         DEVICE_DESCRIPTOR,              /* bDescriptorType */
00115         LSB(USB_VERSION_2_1),           /* bcdUSB (LSB) */
00116         MSB(USB_VERSION_2_1),           /* bcdUSB (MSB) */
00117         0x00,                           /* bDeviceClass */
00118         0x00,                           /* bDeviceSubClass */
00119         0x00,                           /* bDeviceprotocol */
00120         MAX_PACKET_SIZE_EP0,            /* bMaxPacketSize0 */
00121         (uint8_t)(LSB(VENDOR_ID)),                 /* idVendor (LSB) */
00122         (uint8_t)(MSB(VENDOR_ID)),                 /* idVendor (MSB) */
00123         (uint8_t)(LSB(PRODUCT_ID)),                /* idProduct (LSB) */
00124         (uint8_t)(MSB(PRODUCT_ID)),                /* idProduct (MSB) */
00125         (uint8_t)(LSB(PRODUCT_RELEASE)),           /* bcdDevice (LSB) */
00126         (uint8_t)(MSB(PRODUCT_RELEASE)),           /* bcdDevice (MSB) */
00127         STRING_OFFSET_IMANUFACTURER,    /* iManufacturer */
00128         STRING_OFFSET_IPRODUCT,         /* iProduct */
00129         STRING_OFFSET_ISERIAL,          /* iSerialNumber */
00130         0x01                            /* bNumConfigurations */
00131     };
00132     return deviceDescriptor;
00133 }
00134 
00135 #define WEBUSB_BOS_TOTAL_LENGTH (BINARY_OBJECT_STORE_DESCRIPTOR_LENGTH \
00136                                  + WEBUSB_PLATFORM_DESCRIPTOR_LENGTH + 28)
00137 
00138 uint8_t * WebUSBDevice::binaryObjectStoreDesc() {
00139     static uint8_t binaryObjectStoreDescriptor[] = {
00140         BINARY_OBJECT_STORE_DESCRIPTOR_LENGTH, /* bLength */
00141         BINARY_OBJECT_STORE_DESCRIPTOR, /* bDescriptorType */
00142         LSB(WEBUSB_BOS_TOTAL_LENGTH),   /* wTotalLength (LSB) */
00143         MSB(WEBUSB_BOS_TOTAL_LENGTH),   /* wTotalLength (MSB) */
00144         0x02,                           /* bNumDeviceCaps (WebUSB + WinUSB) */
00145 
00146         // WebUSB
00147         WEBUSB_PLATFORM_DESCRIPTOR_LENGTH, /* bLength */
00148         DEVICE_CAPABILITY_DESCRIPTOR,   /* bDescriptorType */
00149         USB_DC_PLATFORM,                /* bDevCapabilityType */
00150         0x00,                           /* bReserved */
00151         0x38, 0xB6, 0x08, 0x34,         /* PlatformCapabilityUUID */
00152         0xA9, 0x09, 0xA0, 0x47,
00153         0x8B, 0xFD, 0xA0, 0x76,
00154         0x88, 0x15, 0xB6, 0x65,
00155         LSB(WEBUSB_VERSION_1_0),        /* bcdVersion (LSB) */
00156         MSB(WEBUSB_VERSION_1_0),        /* bcdVersion (MSB) */
00157         WEBUSB_VENDOR_CODE,             /* bVendorCode */
00158         URL_OFFSET_LANDING_PAGE,        /* iLandingPage */
00159 
00160         // Windows related (to get WinUSB auto-loaded)
00161         0x1C, 0x10, 0x05, 0x00, /* Microsoft OS 2.0 Platform Capability Descriptor */
00162         
00163         0xDF, 0x60, 0xDD, 0xD8,  /* MS OS 2.0 Platform Capability ID */
00164         0x89, 0x45, 0xC7, 0x4C,
00165         0x9C, 0xD2, 0x65, 0x9D,
00166         0x9E, 0x64, 0x8A, 0x9F,
00167 
00168         0x00, 0x00, 0x03, 0x06, /* Windows version */
00169         
00170         0xB2, 0x00, WINUSB_VENDOR_CODE, 0x00 /* MS OS 2.0 descriptor size (word), vendor code, no alternate enumeration */
00171     };
00172     return binaryObjectStoreDescriptor;
00173 }