Making WebUSB Work with the Teensy - What is PluggableUSB?

Status
Not open for further replies.

mcsteeze

Active member
Hi,

Similar to this question: https://forum.pjrc.com/threads/40381-WebUSB?highlight=webusb

I am trying to get WebUSB to work with the Teensy. I am using a Teensy 3.2

The key thing for WebUSB is that a microcontroller needs direct USB access which I think the Teensy does.

However, when I try to get the examples from https://github.com/webusb/arduino to work, I get the following errors:

Code:
Arduino: 1.8.12 (Linux), TD: 1.51, Board: "Arduino Uno"

In file included from /home/user/Desktop/sketch_may07a/sketch_may07a.ino:1:0:
/home/user/Applications/arduino-1.8.12/libraries/WebUSB/WebUSB.h:27:26: fatal error: PluggableUSB.h: No such file or directory
compilation terminated.
Error compiling for board Teensy 3.2 / 3.1.

Does anybody know what PluggableUSB is or what I need to make it work with the Teensy?
 
PluggableUSB.h is a file that is part of the Arduino avr core files and does not exist in the teensy core files.

Not sure what a full work around for this would be, as the two systems have reasonably different underlying USB code.
 
As of interest, the full source code looks like:

Code:
#include <WebUSB.h>

/**
 * Creating an instance of WebUSBSerial will add an additional USB interface to
 * the device that is marked as vendor-specific (rather than USB CDC-ACM) and
 * is therefore accessible to the browser.
 *
 * The URL here provides a hint to the browser about what page the user should
 * navigate to to interact with the device.
 */
WebUSB WebUSBSerial(1 /* https:// */, "webusb.github.io/arduino/demos/console");

#define Serial WebUSBSerial

const int ledPin = 13;

void setup() {
  while (!Serial) {
    ;
  }
  Serial.begin(9600);
  Serial.write("Sketch begins.\r\n> ");
  Serial.flush();
  pinMode(ledPin, OUTPUT);
}

void loop() {
  if (Serial && Serial.available()) {
    int byte = Serial.read();
    Serial.write(byte);
    if (byte == 'H') {
      Serial.write("\r\nTurning LED on.");
      digitalWrite(ledPin, HIGH);
    } else if (byte == 'L') {
      Serial.write("\r\nTurning LED off.");
      digitalWrite(ledPin, LOW);
    }
    Serial.write("\r\n> ");
    Serial.flush();
  }
}
 
Code:
will add an additional USB interface to
 * the device that is marked as vendor-specific (rather than USB CDC-ACM) and
 * is therefore accessible to the browser.

Maybe try using Tools > USB Type set to Dual Serial.

Then edit usb_desc.c to change the 2nd port's bFunctionClass and bInterfaceClass (and maybe other fields) to whatever WebUSB needs. To find the right place to edit, search that file for "CDC2_DATA_INTERFACE".

Teensy 3 and 4 each have their own separate copy of that file, so pay attention to the name of the folder so you edit the right one. If using Teensy 4, there are 2 complete copies of the config descriptor, one for 480 Mbit and the other for 12 Mbit speed. Edit both. Teensy 3 only runs at 12 Mbit speed, so there isn't a 2nd copy to edit.
 
Thanks for the follow up. I do not see a "Dual Serial" option. I see: Serial, Keyboard, Keyboard + Touchscreen....all the way to "No USB".

Is "Dual Serial" the same as Keyboard + Touchscreen?

Also, looking at the code I see a:
Code:
CDC_DATA_INTERFACE
but not a
Code:
CDC2_DATA_INTERFACE
definition. Was that a typo?

The code comments for
Code:
bFunctionClass
are located in
Code:
CDC_IAD_DESCRIPTOR
Am I at the right spot?

I'll ask what values are needed for WebUSB but I am worried that editing that file might break existing functionality. Is that the case?

I am also curious why the 2nd port should be edited and not the first?

Also, as a bit of a follow up - am I correct that these different options are the device types supported by USB (HID, MIDI Device, Keyboard) etc? It seems limiting to have to define a type for every single thing connected to a USB port. What if a fingerprint scanner were connected? Which profile would it use?
 
Awesome. I got the Teensyduino working - but still the same error:

Code:
In file included from /home/user/Desktop/sketch_may12a/sketch_may12a.ino:1:0:
/home/user/Applications/arduino-1.8.12/libraries/WebUSB/WebUSB.h:27:26: fatal error: PluggableUSB.h: No such file or directory
compilation terminated.
Error compiling for board Teensy 3.2 / 3.1.

Is there a way to bypass this PluggableUSB.h file?
Also, are these modes (Dual Serial, Raw HID etc.) what are known as USB profiles?
 
Is anyone still watching this thread and interested in WebUSB?

Where "interested" means time to beta test next week. If nobody has time to test this (as we're in beta now for 1.53), I'll probably put it off until 1.54 or later.
 
Is anyone still watching this thread and interested in WebUSB?

Where "interested" means time to beta test next week. ...

Yes, Running updated Windows EDGE based on ChromeEngine says it should work.

Worked to run AdaFruit unit with their 'browser' desktop : https://adafruit-webbt-playground.glitch.me/ after making the setting change to allow access - that is using BlueTooth.

Does it work something like this ( sorry the 3D bunny showing his tail ):
afDesktopBt.jpg

I also have some of the T_3.2 based 'ONLYKEY' units I never used because they required g00gle Chrome - assume that must use the same interface? I'll power one up and try updating and connecting that : https://crp.to/okstart/
 
Please keep following this thread, and encourage anyone else who wants WebUSB support to follow here.

When I posted msg #9 last week, it appeared as if nobody was following, so I decided not to work on WebUSB for 1.53. I also tried to email "mcsteeze" directly, but the email bounced.
 
Please keep following this thread, and encourage anyone else who wants WebUSB support to follow here.

When I posted msg #9 last week, it appeared as if nobody was following, so I decided not to work on WebUSB for 1.53. I also tried to email "mcsteeze" directly, but the email bounced.

Missed original post #9 - only saw it when I saw post #10.

I have no idea what it or how WebUSB works - only became interested in UI options this week when the NRF52840 units arrived (from AdaF CLUE and SENSE), figured watching WEBUSB come online with Teensy would help.

BTW first look: those units with 64 MHz bluetooth equipped M4F run loop() cycles at ~20% the speed of a T_3.2 at 48 Mhz {code in while(1) is 1.3X faster on T_3.2 at 16 Mhz slower MCU clock}. They do it running at 10 mA - they are new and have limited docs and lots of room for tuning. Seems RTOS was shoehorned in and have native USB for DFU upload that is quick. So again - Kudos on attention to detail and efficiency with Teensy focus! And this forum is better too.
 
In my dream world, where I have unlimited hours in every day and where I'm much better/faster at JavaScript, my hope is to use WebUSB in the Audio Design Tool to connect to a Teensy and have it run the audio design in real time as you change the connections.

But today the design tool only represents audio data flow. There's no connection for control of parameters. To be genuinely useful, non-audio inputs and outputs would need to be added. Maybe they would be on the top and bottom edges, so non-audio control flow would be mostly vertical lines, which would be thinner or otherwise visually distinct from audio connections. Many more objects would need to be added, for things like MIDI input & output, analog knobs, buttons, sensors, and maybe showing of parameters on an ILI9341 or similar display.

At least that's my dream world. Back here in reality, there's little to no chance I'll manage to do all that anytime soon. But when/if at least 2 or 3 people willing to really test and use WebUSB come along, I'll probably pour some time into getting the USB side implemented.
 
I'll look at the NRF52 units and see what I can figure out if they work. To pad an order last year I ordered an NRF52 feather express that is listed as supported - the Sense is the same but with 9DOF, mic and other items added - the CLUE {AdaF upgraded micro.bit} has those and buzzer and 240x240 display (factory demo updates display 1.84Hz!). I'll see what I find. The alternate (?) p#9 Dashboard interface is bluetooth only(?) and has support on their python - this other linked console shows the ones online are not running the right code.

Found it under tinyusb\webusb - And these notes in: C:\Users\defragster\AppData\Local\Arduino15\packages\adafruit\hardware\nrf52\0.20.1\cores\nRF5\TinyUSB\Adafruit_TinyUSB_ArduinoCore\tinyusb\src\device\usbd.h
Code:
 * The MIT License (MIT)
 *
 * Copyright (c) 2019 Ha Thach (tinyusb.org)
...

//------------- WebUSB BOS Platform -------------//

// Descriptor Length
#define TUD_BOS_WEBUSB_DESC_LEN         24

// Vendor Code, iLandingPage
#define TUD_BOS_WEBUSB_DESCRIPTOR(_vendor_code, _ipage) \
  TUD_BOS_PLATFORM_DESCRIPTOR(TUD_BOS_WEBUSB_UUID, U16_TO_U8S_LE(0x0100), _vendor_code, _ipage)

#define TUD_BOS_WEBUSB_UUID   \
  0x38, 0xB6, 0x08, 0x34, 0xA9, 0x09, 0xA0, 0x47, \

That gets used Here : T:\tCode\libraries\Adafruit_TinyUSB_Library\src\Adafruit_USBD_WebUSB.cpp
Code:
 * The MIT License (MIT)
 *
 * Copyright (c) 2019 hathach for Adafruit Industries
...

// BOS Descriptor is required for webUSB
uint8_t const desc_bos[] = {
    // total length, number of device caps
    TUD_BOS_DESCRIPTOR(BOS_TOTAL_LEN, 2),

    // Vendor Code, iLandingPage
    TUD_BOS_WEBUSB_DESCRIPTOR(VENDOR_REQUEST_WEBUSB, 1),

    // Microsoft OS 2.0 descriptor
    TUD_BOS_MS_OS_20_DESCRIPTOR(MS_OS_20_DESC_LEN, VENDOR_REQUEST_MICROSOFT)};

uint8_t const *tud_descriptor_bos_cb(void) { return desc_bos; }

uint8_t desc_ms_os_20[] = {
    // Set header: length, type, windows version, total length
    U16_TO_U8S_LE(0x000A), U16_TO_U8S_LE(MS_OS_20_SET_HEADER_DESCRIPTOR),
    U32_TO_U8S_LE(0x06030000), U16_TO_U8S_LE(MS_OS_20_DESC_LEN),

    // Configuration subset header: length, type, configuration index, reserved,
    // configuration total length
    U16_TO_U8S_LE(0x0008), U16_TO_U8S_LE(MS_OS_20_SUBSET_HEADER_CONFIGURATION),
    0, 0, U16_TO_U8S_LE(MS_OS_20_DESC_LEN - 0x0A),

    // Function Subset header: length, type, first interface, reserved, subset
    // length
    U16_TO_U8S_LE(0x0008), U16_TO_U8S_LE(MS_OS_20_SUBSET_HEADER_FUNCTION),
    0 /*itf num*/, 0, U16_TO_U8S_LE(MS_OS_20_DESC_LEN - 0x0A - 0x08),

    // MS OS 2.0 Compatible ID descriptor: length, type, compatible ID, sub
    // compatible ID
    U16_TO_U8S_LE(0x0014), U16_TO_U8S_LE(MS_OS_20_FEATURE_COMPATBLE_ID), 'W',
    'I', 'N', 'U', 'S', 'B', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, // sub-compatible

    // MS OS 2.0 Registry property descriptor: length, type
    U16_TO_U8S_LE(MS_OS_20_DESC_LEN - 0x0A - 0x08 - 0x08 - 0x14),
    U16_TO_U8S_LE(MS_OS_20_FEATURE_REG_PROPERTY), U16_TO_U8S_LE(0x0007),
    U16_TO_U8S_LE(0x002A), // wPropertyDataType, wPropertyNameLength and
                           // PropertyName "DeviceInterfaceGUIDs\0" in UTF-16
    'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, 'c', 0x00, 'e', 0x00, 'I', 0x00,
    'n', 0x00, 't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00, 'a', 0x00, 'c', 0x00,
    'e', 0x00, 'G', 0x00, 'U', 0x00, 'I', 0x00, 'D', 0x00, 's', 0x00, 0x00,
    0x00,
    U16_TO_U8S_LE(0x0050), // wPropertyDataLength
    // bPropertyData: “{975F44D9-0D08-43FD-8B3E-127CA8AFFF9D}”.
    '{', 0x00, '9', 0x00, '7', 0x00, '5', 0x00, 'F', 0x00, '4', 0x00, '4', 0x00,
    'D', 0x00, '9', 0x00, '-', 0x00, '0', 0x00, 'D', 0x00, '0', 0x00, '8', 0x00,
    '-', 0x00, '4', 0x00, '3', 0x00, 'F', 0x00, 'D', 0x00, '-', 0x00, '8', 0x00,
    'B', 0x00, '3', 0x00, 'E', 0x00, '-', 0x00, '1', 0x00, '2', 0x00, '7', 0x00,
    'C', 0x00, 'A', 0x00, '8', 0x00, 'A', 0x00, 'F', 0x00, 'F', 0x00, 'F', 0x00,
    '9', 0x00, 'D', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00};
 
If there is any way I can contribute to getting WebUSB to work on Teensies, I will gladly do so.

I am fairly new to Teensy / Arduino, but I have about 15 years of professional experience coding in languages like Java, Python, PHP and I have a little bit of experience with C++. Maybe with some help of you guys I can be of any value getting WebUSB to work for Teensies.

If I am not mistaken, I've read somewhere during my research, that Teensies have their own kind of implementation of PluggableUSB. Is this true? And does any of you know where I should look for this? If there is an alternative to PluggableUSB for Teensies I might be able to fork the WebUSB repo and change the current implementation or just add the Teensies alternative to PluggableUSB.

In case you guys think or know, that the changes have to be made on the Teensyduino side, let me know if you think that I can be of any help.
 
I've read somewhere during my research, that Teensies have their own kind of implementation of PluggableUSB. Is this true?

We don't do runtime config like PluggableUSB, but we do have usb_desc.h and usb_desc.c which are influenced by the defines from boards.txt which configures Arduino's menus.


And does any of you know where I should look for this?

Those files and the USB serial code are in the core library, in {Arduino}/hardware/teensy/avr/cores/teensy4.

There's already plenty of general guidance earlier in this thread about what needs to be done with those files. Just scroll up to read it.


In case you guys think or know, that the changes have to be made on the Teensyduino side, let me know if you think that I can be of any help.

If you want to give it a try, just start editing those files. If you get something working or even partially working, please share here (click "Go Advanced" for the editor which lets you attach files) or on github.

Fairly deep knowledge of USB is needed to edit that code. While all the USB info is available online, it's a really deep rabbit hole and easy to get lost in the details. Don't feel bad if it's overwhelming. That's absolutely normal. But please do keep watching this thread. Eventually I will get around to doing this. People willing to test with various browsers and operating systems and different JavaScript code is what will really matter as the USB side is in development.
 
I am also interested in WebUSB and would be glad to help test.


It seems as though Adafruit's TinyUSB library already has WebUSB built in to it (see the examples): https://github.com/adafruit/Adafruit_TinyUSB_Arduino

It also looks like this library has a number of other useful features, namely reading the Teensy's flash and SD storage as a Mass Storage Device (MSC).
It appears that Teensy 4.x wouldn't be too difficult to port over to this library, as the original library from Hathach already supports Teensy 4.0: https://github.com/hathach/tinyusb/blob/master/docs/boards.md


I bring this up, because it would be a great way to get two birds with one stone: WebUSB & the largely discussed/desired feature of reading an SD card as a Mass Storage Device on a computer via Teensy's USB port (eliminating the need to open up projects and pull out the microSD to be read with an additional adapter).

I started a discussion about this here: https://forum.pjrc.com/threads/60646-Adafruit-s-TinyUSB-with-Teensy-4-0?highlight=tinyusb
and here: https://github.com/adafruit/Adafruit_TinyUSB_Arduino/issues/63

I'm relatively new to this world of coding, so I have hit a dead end in making it happen – but would be eternally grateful of someone else knows how to do it!

(Apologies if that information is not relevant or helpful!)
 
So, what about
"WebUSB was enabled by default in Chrome 61 on September 5 2017, but was disabled after privacy and security concerns were raised" (Wikipedia) ?
Is that still the case?
 
Good detail @luni, didn't find that one.

March 2018: story below notes the problem - seems a link from the wiki page matches the only interesting search result ...
Anything with the power to be useful it seems can be abused IRL - or the computer if it can access a device HDD or USB ... or get a user to allow it ... so Off by default seems a safe option with most users never knowing about it.
Now that MSFT's new edge is built on chr0me engine it shares this and requires turning on ... with warnings about it being a really bad idea to enable such things.
Code:
Google disables WebUSB in Chrome amidst phishing concerns
Phishing is a major concern if you live a lot of your life on the internet. There are plenty of ways to protect against phishing attacks with software, but one of the best methods is hardware USB keys. An authentication device can protect you even if the attacker has your username and password. At least that’s what they’ll tell you. A pair of researchers proved that these devices are not invincible. A feature in Chrome called WebUSB made it possible to bypass the protections.

WebUSB is a feature that allows websites to directly connect to USB devices; it was added in Chrome 61. Attackers can use the feature with an accompanying website to convince someone to type in their username and password and send it directly to the authentication device to unlock the account. Obviously, which Chrome being the most popular browser on the planet, this is a pretty serious vulnerability.

When asked about it, Google’s security product manager said they are aware of the situation. They consider this type of attack to be an edge case, but they are working to fix the problem. For the time being, Google has disabled the WebUSB feature entirely. This was discovered in Chromium just yesterday. Users can apply a command line flag if they really want to re-enable the feature. For now, the problem has been solved by removing the moving parts.
 
If this can be a way to easily distribute firmware updates and other configuration information to Teensy based products out in the wild, I'd be interested, too!
 
If this can be a way to easily distribute firmware updates and other configuration information to Teensy based products out in the wild, I'd be interested, too!

Yes, apparently BBC Micro.bit uses this - wasn't sure if that was a potential way to push code over USB - problem is the Teensy will be in Sketch Run mode with WebUSB not bootloader mode so didn't get my hopes up.
 
Status
Not open for further replies.
Back
Top