Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | /* * Copyright (c) 2016 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ /** * @file * @brief Sample app for WebUSB enabled custom class driver. * * Sample app for WebUSB enabled custom class driver. The received * data is echoed back to the WebUSB based application running in * the browser at host. */ #include <stdio.h> #include <string.h> #include <device.h> #include <uart.h> #include <zephyr.h> #include "webusb_serial.h" static volatile bool data_transmitted; static volatile bool data_arrived; static uint8_t data_buf[64]; /* WebUSB Platform Capability Descriptor */ static const uint8_t webusb_bos_descriptor[] = { /* Binary Object Store descriptor */ 0x05, 0x0F, 0x1D, 0x00, 0x01, /* WebUSB Platform Capability Descriptor: * https://wicg.github.io/webusb/#webusb-platform-capability-descriptor */ 0x18, 0x10, 0x05, 0x00, /* PlatformCapability UUID */ 0x38, 0xB6, 0x08, 0x34, 0xA9, 0x09, 0xA0, 0x47, 0x8B, 0xFD, 0xA0, 0x76, 0x88, 0x15, 0xB6, 0x65, /* Version, VendorCode, Landing Page */ 0x00, 0x01, 0x01, 0x01, }; /* WebUSB Device Requests */ static const uint8_t webusb_allowed_origins[] = { /* Allowed Origins Header: * https://wicg.github.io/webusb/#get-allowed-origins */ 0x05, 0x00, 0x0D, 0x00, 0x01, /* Configuration Subset Header: * https://wicg.github.io/webusb/#configuration-subset-header */ 0x04, 0x01, 0x01, 0x01, /* Function Subset Header: * https://wicg.github.io/webusb/#function-subset-header */ 0x04, 0x02, 0x02, 0x01 }; /* Number of allowed origins */ #define NUMBER_OF_ALLOWED_ORIGINS 1 /* URL Descriptor: https://wicg.github.io/webusb/#url-descriptor */ static const uint8_t webusb_origin_url[] = { /* Length, DescriptorType, Scheme */ 0x11, 0x03, 0x00, 'l', 'o', 'c', 'a', 'l', 'h', 'o', 's', 't', ':', '8', '0', '0', '0' }; /** * @brief Custom handler for standard requests in * order to catch the request and return the * WebUSB Platform Capability Descriptor. * * @param pSetup Information about the request to execute. * @param len Size of the buffer. * @param data Buffer containing the request result. * * @return 0 on success, negative errno code on fail */ int custom_handle_req(struct usb_setup_packet *pSetup, int32_t *len, uint8_t **data) { if (GET_DESC_TYPE(pSetup->wValue) == DESCRIPTOR_TYPE_BOS) { *data = (uint8_t *)(&webusb_bos_descriptor); *len = sizeof(webusb_bos_descriptor); return 0; } return -ENOTSUP; } /** * @brief Handler called for WebUSB vendor specific commands. * * @param pSetup Information about the request to execute. * @param len Size of the buffer. * @param data Buffer containing the request result. * * @return 0 on success, negative errno code on fail. */ int vendor_handle_req(struct usb_setup_packet *pSetup, int32_t *len, uint8_t **data) { /* Get Allowed origins request */ if (pSetup->bRequest == 0x01 && pSetup->wIndex == 0x01) { *data = (uint8_t *)(&webusb_allowed_origins); *len = sizeof(webusb_allowed_origins); return 0; } else if (pSetup->bRequest == 0x01 && pSetup->wIndex == 0x02) { /* Get URL request */ uint8_t index = GET_DESC_INDEX(pSetup->wValue); if (index == 0 || index > NUMBER_OF_ALLOWED_ORIGINS) return -ENOTSUP; *data = (uint8_t *)(&webusb_origin_url); *len = sizeof(webusb_origin_url); return 0; } return -ENOTSUP; } static void interrupt_handler(struct device *dev) { uart_irq_update(dev); if (uart_irq_tx_ready(dev)) { data_transmitted = true; } if (uart_irq_rx_ready(dev)) { data_arrived = true; } } static void write_data(struct device *dev, const uint8_t *buf, int len) { uart_irq_tx_enable(dev); data_transmitted = false; uart_fifo_fill(dev, buf, len); while (data_transmitted == false) ; uart_irq_tx_disable(dev); } static void read_and_echo_data(struct device *dev, int *bytes_read) { while (data_arrived == false) ; data_arrived = false; /* Read all data and echo it back */ while ((*bytes_read = uart_fifo_read(dev, data_buf, sizeof(data_buf)))) { write_data(dev, data_buf, *bytes_read); } } /* Custom and Vendor request handlers */ static struct webusb_req_handlers req_handlers = { .custom_handler = custom_handle_req, .vendor_handler = vendor_handle_req, }; void main(void) { struct device *dev; uint32_t baudrate, dtr = 0; int ret, bytes_read; dev = device_get_binding(WEBUSB_SERIAL_PORT_NAME); if (!dev) { printf("WebUSB device not found\n"); return; } /* Set the custom and vendor request handlers */ webusb_register_request_handlers(&req_handlers); #ifdef CONFIG_UART_LINE_CTRL printf("Wait for DTR\n"); while (1) { uart_line_ctrl_get(dev, LINE_CTRL_DTR, &dtr); if (dtr) { break; } } printf("DTR set, start test\n"); /* Wait 1 sec for the host to do all settings */ k_busy_wait(1000000); ret = uart_line_ctrl_get(dev, LINE_CTRL_BAUD_RATE, &baudrate); if (ret) { printf("Failed to get baudrate, ret code %d\n", ret); } else { printf("Baudrate detected: %d\n", baudrate); } #endif uart_irq_callback_set(dev, interrupt_handler); /* Enable rx interrupts */ uart_irq_rx_enable(dev); /* Echo the received data */ while (1) { read_and_echo_data(dev, &bytes_read); } } |