Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of USBDevice_STM32F103 by
WebUSBDFU.cpp
00001 /* 00002 * Copyright 2016 Devan Lai 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include "stdint.h" 00018 00019 #include "USBHAL.h" 00020 #include "WebUSBDFU.h" 00021 #include "WebUSB.h" 00022 #include "DFU.h" 00023 #include "WinUSB.h" 00024 00025 #include "USBDescriptor.h" 00026 00027 #define DEFAULT_CONFIGURATION (1) 00028 #define DFU_INTERFACE_NUMBER (0) 00029 00030 WebUSBDFU::WebUSBDFU(uint16_t vendor_id, uint16_t product_id, uint16_t product_release, bool connect) 00031 : WebUSBDevice(vendor_id, product_id, product_release), 00032 detach(no_op) 00033 { 00034 if (connect) { 00035 WebUSBDevice::connect(); 00036 } 00037 } 00038 00039 void WebUSBDFU::attach(Callback<void()> func) { 00040 if (func) { 00041 detach.attach(func); 00042 } else { 00043 detach.attach(no_op); 00044 } 00045 } 00046 00047 // 00048 // Route callbacks from lower layers to class(es) 00049 // 00050 00051 00052 // Called in ISR context 00053 // Called by USBDevice on Endpoint0 request 00054 // This is used to handle extensions to standard requests 00055 // and class specific requests 00056 // Return true if class handles this request 00057 bool WebUSBDFU::USBCallback_request() { 00058 bool success = false; 00059 CONTROL_TRANSFER * transfer = getTransferPtr(); 00060 00061 // Handle the Microsoft OS Descriptors 1.0 special string descriptor request 00062 if ((transfer->setup.bmRequestType.Type == STANDARD_TYPE) && 00063 (transfer->setup.bRequest == GET_DESCRIPTOR) && 00064 (DESCRIPTOR_TYPE(transfer->setup.wValue) == STRING_DESCRIPTOR) && 00065 (DESCRIPTOR_INDEX(transfer->setup.wValue) == 0xEE)) 00066 { 00067 static uint8_t msftStringDescriptor[] = { 00068 0x12, /* bLength */ 00069 STRING_DESCRIPTOR, /* bDescriptorType */ 00070 'M',0,'S',0,'F',0,'T',0,'1',0,'0',0,'0',0, /* qWSignature - MSFT100 */ 00071 WINUSB_VENDOR_CODE, /* bMS_VendorCode */ 00072 0x00, /* bPad */ 00073 }; 00074 00075 transfer->remaining = msftStringDescriptor[0]; 00076 transfer->ptr = msftStringDescriptor; 00077 transfer->direction = DEVICE_TO_HOST; 00078 success = true; 00079 } 00080 // Process Microsoft OS Descriptors 1.0 Compatible ID requests 00081 else if ((transfer->setup.bmRequestType.Type == VENDOR_TYPE) && 00082 (transfer->setup.bmRequestType.Recipient == DEVICE_RECIPIENT) && 00083 (transfer->setup.bRequest == WINUSB_VENDOR_CODE) && 00084 (transfer->setup.wIndex == WINUSB_GET_COMPATIBLE_ID_FEATURE_DESCRIPTOR)) 00085 { 00086 static uint8_t msftCompatibleIdDescriptor[] = { 00087 0x28, 0x00, 0x00, 0x00, /* dwLength */ 00088 LSB(COMPATIBLE_ID_VERSION_1_0), /* bcdVersion (LSB) */ 00089 MSB(COMPATIBLE_ID_VERSION_1_0), /* bcdVersion (MSB) */ 00090 LSB(WINUSB_GET_COMPATIBLE_ID_FEATURE_DESCRIPTOR), /* wIndex (LSB) */ 00091 MSB(WINUSB_GET_COMPATIBLE_ID_FEATURE_DESCRIPTOR), /* wIndex (MSB) */ 00092 0x01, /* bCount */ 00093 0, 0, 0, 0, 0, 0, 0, /* reserved */ 00094 DFU_INTERFACE_NUMBER, /* bFirstInterfaceNumber */ 00095 0x00, /* reserved */ 00096 'W','I','N','U','S','B',0,0, /* compatible ID - WINUSB */ 00097 0, 0, 0, 0, 0, 0, 0, 0, /* subCompatibleID */ 00098 0, 0, 0, 0, 0, 0, /* reserved */ 00099 }; 00100 00101 transfer->remaining = sizeof(msftCompatibleIdDescriptor); 00102 transfer->ptr = msftCompatibleIdDescriptor; 00103 transfer->direction = DEVICE_TO_HOST; 00104 success = true; 00105 } 00106 // Process DFU class-specific requests 00107 else if (transfer->setup.bmRequestType.Type == CLASS_TYPE) 00108 { 00109 switch (transfer->setup.bRequest) 00110 { 00111 case DFU_DETACH: 00112 detach.call(); 00113 success = true; 00114 default: 00115 break; 00116 } 00117 } 00118 00119 // Process WebUSB vendor requests 00120 if (!success) 00121 { 00122 success = WebUSBDevice::USBCallback_request(); 00123 } 00124 00125 return success; 00126 } 00127 00128 // Called in ISR context 00129 // Set configuration. Return false if the 00130 // configuration is not supported 00131 bool WebUSBDFU::USBCallback_setConfiguration(uint8_t configuration) { 00132 if (configuration != DEFAULT_CONFIGURATION) { 00133 return false; 00134 } 00135 00136 return true; 00137 } 00138 00139 00140 uint8_t * WebUSBDFU::stringIinterfaceDesc() { 00141 static uint8_t stringIinterfaceDescriptor[] = { 00142 0x08, //bLength 00143 STRING_DESCRIPTOR, //bDescriptorType 0x03 00144 'D',0,'F',0,'U',0, //bString iInterface - DFU 00145 }; 00146 return stringIinterfaceDescriptor; 00147 } 00148 00149 uint8_t * WebUSBDFU::stringIproductDesc() { 00150 static uint8_t stringIproductDescriptor[] = { 00151 0x16, //bLength 00152 STRING_DESCRIPTOR, //bDescriptorType 0x03 00153 'D',0,'F',0,'U',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 //bString iProduct - DFU device 00154 }; 00155 return stringIproductDescriptor; 00156 } 00157 00158 #define DFU_DESCRIPTOR_LENGTH (9) 00159 #define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \ 00160 + (1 * INTERFACE_DESCRIPTOR_LENGTH) \ 00161 + (1 * DFU_DESCRIPTOR_LENGTH)) 00162 00163 #define DETACH_TIMEOUT 255 00164 #define DFU_TRANSFER_SIZE 1024 00165 00166 uint8_t * WebUSBDFU::configurationDesc() { 00167 static uint8_t configurationDescriptor[] = { 00168 CONFIGURATION_DESCRIPTOR_LENGTH,// bLength 00169 CONFIGURATION_DESCRIPTOR, // bDescriptorType 00170 LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB) 00171 MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB) 00172 0x01, // bNumInterfaces 00173 DEFAULT_CONFIGURATION, // bConfigurationValue 00174 STRING_OFFSET_ICONFIGURATION, // iConfiguration 00175 C_RESERVED | C_SELF_POWERED, // bmAttributes 00176 C_POWER(0), // bMaxPower 00177 00178 INTERFACE_DESCRIPTOR_LENGTH, // bLength 00179 INTERFACE_DESCRIPTOR, // bDescriptorType 00180 DFU_INTERFACE_NUMBER, // bInterfaceNumber 00181 0x00, // bAlternateSetting 00182 0x00, // bNumEndpoints 00183 DFU_CLASS_APP_SPECIFIC, // bInterfaceClass 00184 DFU_SUBCLASS_DFU, // bInterfaceSubClass 00185 DFU_PROTO_RUNTIME, // bInterfaceProtocol 00186 STRING_OFFSET_IINTERFACE, // iInterface 00187 00188 DFU_DESCRIPTOR_LENGTH, // bLength 00189 DFU_DESCRIPTOR, // bDescriptorType 00190 (DFU_ATTR_WILL_DETACH // bmAttributes 00191 |DFU_ATTR_CAN_DOWNLOAD), 00192 LSB(DETACH_TIMEOUT), // wDetachTimeOut (LSB) 00193 MSB(DETACH_TIMEOUT), // wDetachTimeOut (MSB) 00194 LSB(DFU_TRANSFER_SIZE), // wTransferSize (LSB) 00195 MSB(DFU_TRANSFER_SIZE), // wTransferSize (MSB) 00196 LSB(DFU_VERSION_1_00), // bcdDFUVersion (LSB) 00197 MSB(DFU_VERSION_1_00), // bcdDFUVersion (MSB) 00198 }; 00199 return configurationDescriptor; 00200 } 00201 00202 #define NUM_ORIGINS 1 00203 #define TOTAL_ORIGINS_LENGTH (WEBUSB_DESCRIPTOR_SET_LENGTH + \ 00204 WEBUSB_CONFIGURATION_SUBSET_LENGTH + \ 00205 WEBUSB_FUNCTION_SUBSET_LENGTH + \ 00206 NUM_ORIGINS) 00207 00208 uint8_t * WebUSBDFU::allowedOriginsDesc() { 00209 static uint8_t allowedOriginsDescriptor[] = { 00210 WEBUSB_DESCRIPTOR_SET_LENGTH, /* bLength */ 00211 WEBUSB_DESCRIPTOR_SET_HEADER, /* bDescriptorType */ 00212 LSB(TOTAL_ORIGINS_LENGTH), /* wTotalLength (LSB) */ 00213 MSB(TOTAL_ORIGINS_LENGTH), /* wTotalLength (MSB) */ 00214 0x01, /* bNumConfigurations */ 00215 00216 WEBUSB_CONFIGURATION_SUBSET_LENGTH, /* bLength */ 00217 WEBUSB_CONFIGURATION_SUBSET_HEADER, /* bDescriptorType */ 00218 DEFAULT_CONFIGURATION, /* bConfigurationValue */ 00219 0x01, /* bNumFunctions */ 00220 00221 (WEBUSB_FUNCTION_SUBSET_LENGTH+NUM_ORIGINS),/* bLength */ 00222 WEBUSB_FUNCTION_SUBSET_HEADER, /* bDescriptorType */ 00223 DFU_INTERFACE_NUMBER, /* bFirstInterfaceNumber */ 00224 URL_OFFSET_ALLOWED_ORIGIN, /* iOrigin[] */ 00225 }; 00226 00227 return allowedOriginsDescriptor; 00228 } 00229 00230 uint8_t * WebUSBDFU::urlIallowedOrigin() { 00231 static uint8_t urlIallowedOriginDescriptor[] = { 00232 0x16, /* bLength */ 00233 WEBUSB_URL, /* bDescriptorType */ 00234 WEBUSB_URL_SCHEME_HTTPS,/* bScheme */ 00235 'd','e','v','a','n','l','a','i','.','g','i','t','h','u','b','.','i','o','/',/* URL - devanlai.github.io */ 00236 }; 00237 return urlIallowedOriginDescriptor; 00238 } 00239 00240 uint8_t * WebUSBDFU::urlIlandingPage() { 00241 static uint8_t urlIlandingPageDescriptor[] = { 00242 0x26, /* bLength */ 00243 WEBUSB_URL, /* bDescriptorType */ 00244 WEBUSB_URL_SCHEME_HTTPS,/* bScheme */ 00245 'd','e','v','a','n','l','a','i','.','g','i','t','h','u','b','.','i','o','/',/* URL - devanlai.github.io/webdfu/dfu-util/ */ 00246 'w','e','b','d','f','u','/','d','f','u','-','u','t','i','l','/' 00247 }; 00248 return urlIlandingPageDescriptor; 00249 }
Generated on Thu Jul 14 2022 08:46:29 by
1.7.2
