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

Fork of USBDevice_STM32F103 by Devan Lai

WebUSBDevice/WebUSBDevice.cpp

Committer:
Lars Knudsen
Date:
2017-07-11
Revision:
72:1d8a6665d607
Parent:
67:39396cc073f2

File content as of revision 72:1d8a6665d607:

/*
* Copyright 2016 Devan Lai
* Modifications copyright 2017 Lars Gunder Knudsen
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "stdint.h"

#include "USBEndpoints.h"
#include "USBDevice.h"
#include "USBDescriptor.h"
#include "WebUSB.h"
#include "WebUSBDevice.h"
#include "../USBDFU/WinUSB.h"

WebUSBDevice::WebUSBDevice(uint16_t vendor_id, uint16_t product_id, uint16_t product_release)
    : USBDevice(vendor_id, product_id, product_release)
{

};

bool WebUSBDevice::requestGetDescriptor(void)
{
    bool success = false;
    CONTROL_TRANSFER * transfer = getTransferPtr();
    switch (DESCRIPTOR_TYPE(transfer->setup.wValue))
    {
        case BINARY_OBJECT_STORE_DESCRIPTOR:
            if (binaryObjectStoreDesc() != NULL)
            {
                transfer->remaining = (binaryObjectStoreDesc()[2]
                                    | (binaryObjectStoreDesc()[3] << 8));
                transfer->ptr = binaryObjectStoreDesc();
                transfer->direction = DEVICE_TO_HOST;
                success = true;
            }
            break;
        default:
            success = USBDevice::requestGetDescriptor();
            break;
    }

    return success;
}

bool WebUSBDevice::requestWebUSB(void)
{
    bool success = false;

    CONTROL_TRANSFER * transfer = getTransferPtr();
    switch (transfer->setup.wIndex)
    {
        case WEBUSB_GET_ALLOWED_ORIGINS:
            if (allowedOriginsDesc())
            {
                transfer->remaining = (allowedOriginsDesc()[2]
                                   |  (allowedOriginsDesc()[3] << 8));
                transfer->ptr = allowedOriginsDesc();
                transfer->direction = DEVICE_TO_HOST;
                success = true;
            }
            break;
        case WEBUSB_GET_URL:
            if (transfer->setup.wValue == URL_OFFSET_LANDING_PAGE)
            {
                transfer->remaining = urlIlandingPage()[0];
                transfer->ptr = urlIlandingPage();
                transfer->direction = DEVICE_TO_HOST;
                success = true;
            }
            else if (transfer->setup.wValue == URL_OFFSET_ALLOWED_ORIGIN)
            {
                transfer->remaining = urlIallowedOrigin()[0];
                transfer->ptr = urlIallowedOrigin();
                transfer->direction = DEVICE_TO_HOST;
                success = true;
            }
            break;
        default:
            break;
    }

    return success;
}

bool WebUSBDevice::USBCallback_request()
{
    bool success = false;
    /* Process WebUSB requests */
    CONTROL_TRANSFER * transfer = getTransferPtr();
    if ((transfer->setup.bmRequestType.Type == VENDOR_TYPE) &&
        (transfer->setup.bRequest == WEBUSB_VENDOR_CODE))
    {
        success = requestWebUSB();
    }
    
    return success;
}

uint8_t * WebUSBDevice::deviceDesc() {
    static uint8_t deviceDescriptor[] = {
        DEVICE_DESCRIPTOR_LENGTH,       /* bLength */
        DEVICE_DESCRIPTOR,              /* bDescriptorType */
        LSB(USB_VERSION_2_1),           /* bcdUSB (LSB) */
        MSB(USB_VERSION_2_1),           /* bcdUSB (MSB) */
        0x00,                           /* bDeviceClass */
        0x00,                           /* bDeviceSubClass */
        0x00,                           /* bDeviceprotocol */
        MAX_PACKET_SIZE_EP0,            /* bMaxPacketSize0 */
        (uint8_t)(LSB(VENDOR_ID)),                 /* idVendor (LSB) */
        (uint8_t)(MSB(VENDOR_ID)),                 /* idVendor (MSB) */
        (uint8_t)(LSB(PRODUCT_ID)),                /* idProduct (LSB) */
        (uint8_t)(MSB(PRODUCT_ID)),                /* idProduct (MSB) */
        (uint8_t)(LSB(PRODUCT_RELEASE)),           /* bcdDevice (LSB) */
        (uint8_t)(MSB(PRODUCT_RELEASE)),           /* bcdDevice (MSB) */
        STRING_OFFSET_IMANUFACTURER,    /* iManufacturer */
        STRING_OFFSET_IPRODUCT,         /* iProduct */
        STRING_OFFSET_ISERIAL,          /* iSerialNumber */
        0x01                            /* bNumConfigurations */
    };
    return deviceDescriptor;
}

#define WEBUSB_BOS_TOTAL_LENGTH (BINARY_OBJECT_STORE_DESCRIPTOR_LENGTH \
                                 + WEBUSB_PLATFORM_DESCRIPTOR_LENGTH + 28)

uint8_t * WebUSBDevice::binaryObjectStoreDesc() {
    static uint8_t binaryObjectStoreDescriptor[] = {
        BINARY_OBJECT_STORE_DESCRIPTOR_LENGTH, /* bLength */
        BINARY_OBJECT_STORE_DESCRIPTOR, /* bDescriptorType */
        LSB(WEBUSB_BOS_TOTAL_LENGTH),   /* wTotalLength (LSB) */
        MSB(WEBUSB_BOS_TOTAL_LENGTH),   /* wTotalLength (MSB) */
        0x02,                           /* bNumDeviceCaps (WebUSB + WinUSB) */

        // WebUSB
        WEBUSB_PLATFORM_DESCRIPTOR_LENGTH, /* bLength */
        DEVICE_CAPABILITY_DESCRIPTOR,   /* bDescriptorType */
        USB_DC_PLATFORM,                /* bDevCapabilityType */
        0x00,                           /* bReserved */
        0x38, 0xB6, 0x08, 0x34,         /* PlatformCapabilityUUID */
        0xA9, 0x09, 0xA0, 0x47,
        0x8B, 0xFD, 0xA0, 0x76,
        0x88, 0x15, 0xB6, 0x65,
        LSB(WEBUSB_VERSION_1_0),        /* bcdVersion (LSB) */
        MSB(WEBUSB_VERSION_1_0),        /* bcdVersion (MSB) */
        WEBUSB_VENDOR_CODE,             /* bVendorCode */
        URL_OFFSET_LANDING_PAGE,        /* iLandingPage */

        // Windows related (to get WinUSB auto-loaded)
        0x1C, 0x10, 0x05, 0x00, /* Microsoft OS 2.0 Platform Capability Descriptor */
        
        0xDF, 0x60, 0xDD, 0xD8,  /* MS OS 2.0 Platform Capability ID */
        0x89, 0x45, 0xC7, 0x4C,
        0x9C, 0xD2, 0x65, 0x9D,
        0x9E, 0x64, 0x8A, 0x9F,

        0x00, 0x00, 0x03, 0x06, /* Windows version */
        
        0xB2, 0x00, WINUSB_VENDOR_CODE, 0x00 /* MS OS 2.0 descriptor size (word), vendor code, no alternate enumeration */
    };
    return binaryObjectStoreDescriptor;
}