Skip to content

Commit 6b36df3

Browse files
authored
Merge pull request #2829 from HiFiPhile/lwip_fix
net_lwip_webserver example fix and improvement
2 parents c6dccff + 79373af commit 6b36df3

File tree

2 files changed

+115
-3
lines changed

2 files changed

+115
-3
lines changed

examples/device/net_lwip_webserver/src/main.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,13 @@ uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg) {
194194
static void service_traffic(void) {
195195
/* handle any packet received by tud_network_recv_cb() */
196196
if (received_frame) {
197-
ethernet_input(received_frame, &netif_data);
198-
pbuf_free(received_frame);
197+
// Surrender ownership of our pbuf unless there was an error
198+
// Only call pbuf_free if not Ok else it will panic with "pbuf_free: p->ref > 0"
199+
// or steal it from whatever took ownership of it with undefined consequences.
200+
// See: https://savannah.nongnu.org/patch/index.php?10121
201+
if (ethernet_input(received_frame, &netif_data)!=ERR_OK) {
202+
pbuf_free(received_frame);
203+
}
199204
received_frame = NULL;
200205
tud_network_recv_renew();
201206
}

examples/device/net_lwip_webserver/src/usb_descriptors.c

Lines changed: 108 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,11 @@ tusb_desc_device_t const desc_device =
7272
{
7373
.bLength = sizeof(tusb_desc_device_t),
7474
.bDescriptorType = TUSB_DESC_DEVICE,
75+
#if CFG_TUD_NCM
76+
.bcdUSB = 0x0201,
77+
#else
7578
.bcdUSB = 0x0200,
76-
79+
#endif
7780
// Use Interface Association Descriptor (IAD) device class
7881
.bDeviceClass = TUSB_CLASS_MISC,
7982
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
@@ -188,6 +191,110 @@ uint8_t const * tud_descriptor_configuration_cb(uint8_t index)
188191
return (index < CONFIG_ID_COUNT) ? configuration_arr[index] : NULL;
189192
}
190193

194+
#if CFG_TUD_NCM
195+
//--------------------------------------------------------------------+
196+
// BOS Descriptor
197+
//--------------------------------------------------------------------+
198+
199+
/* Used to automatically load the NCM driver on Windows 10, otherwise manual driver install is needed.
200+
Associate NCM interface with WINNCM driver. */
201+
202+
/* Microsoft OS 2.0 registry property descriptor
203+
Per MS requirements https://msdn.microsoft.com/en-us/library/windows/hardware/hh450799(v=vs.85).aspx
204+
device should create DeviceInterfaceGUIDs. It can be done by driver and
205+
in case of real PnP solution device should expose MS "Microsoft OS 2.0
206+
registry property descriptor". Such descriptor can insert any record
207+
into Windows registry per device/configuration/interface. In our case it
208+
will insert "DeviceInterfaceGUIDs" multistring property.
209+
210+
GUID is freshly generated and should be OK to use.
211+
212+
https://developers.google.com/web/fundamentals/native-hardware/build-for-webusb/
213+
(Section Microsoft OS compatibility descriptors)
214+
*/
215+
216+
#define BOS_TOTAL_LEN (TUD_BOS_DESC_LEN + TUD_BOS_MICROSOFT_OS_DESC_LEN)
217+
218+
#define MS_OS_20_DESC_LEN 0xB2
219+
220+
// BOS Descriptor is required for webUSB
221+
uint8_t const desc_bos[] =
222+
{
223+
// total length, number of device caps
224+
TUD_BOS_DESCRIPTOR(BOS_TOTAL_LEN, 1),
225+
226+
// Microsoft OS 2.0 descriptor
227+
TUD_BOS_MS_OS_20_DESCRIPTOR(MS_OS_20_DESC_LEN, 1)
228+
};
229+
230+
uint8_t const * tud_descriptor_bos_cb(void)
231+
{
232+
return desc_bos;
233+
}
234+
235+
uint8_t const desc_ms_os_20[] =
236+
{
237+
// Set header: length, type, windows version, total length
238+
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),
239+
240+
// Configuration subset header: length, type, configuration index, reserved, configuration total length
241+
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),
242+
243+
// Function Subset header: length, type, first interface, reserved, subset length
244+
U16_TO_U8S_LE(0x0008), U16_TO_U8S_LE(MS_OS_20_SUBSET_HEADER_FUNCTION), ITF_NUM_CDC, 0, U16_TO_U8S_LE(MS_OS_20_DESC_LEN-0x0A-0x08),
245+
246+
// MS OS 2.0 Compatible ID descriptor: length, type, compatible ID, sub compatible ID
247+
U16_TO_U8S_LE(0x0014), U16_TO_U8S_LE(MS_OS_20_FEATURE_COMPATBLE_ID), 'W', 'I', 'N', 'N', 'C', 'M', 0x00, 0x00,
248+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sub-compatible
249+
250+
// MS OS 2.0 Registry property descriptor: length, type
251+
U16_TO_U8S_LE(MS_OS_20_DESC_LEN-0x0A-0x08-0x08-0x14), U16_TO_U8S_LE(MS_OS_20_FEATURE_REG_PROPERTY),
252+
U16_TO_U8S_LE(0x0007), U16_TO_U8S_LE(0x002A), // wPropertyDataType, wPropertyNameLength and PropertyName "DeviceInterfaceGUIDs\0" in UTF-16
253+
'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, 't', 0x00, 'e', 0x00,
254+
'r', 0x00, 'f', 0x00, 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, 'U', 0x00, 'I', 0x00, 'D', 0x00, 's', 0x00, 0x00, 0x00,
255+
U16_TO_U8S_LE(0x0050), // wPropertyDataLength
256+
//bPropertyData: {12345678-0D08-43FD-8B3E-127CA8AFFF9D}
257+
'{', 0x00, '1', 0x00, '2', 0x00, '3', 0x00, '4', 0x00, '5', 0x00, '6', 0x00, '7', 0x00, '8', 0x00, '-', 0x00,
258+
'0', 0x00, 'D', 0x00, '0', 0x00, '8', 0x00, '-', 0x00, '4', 0x00, '3', 0x00, 'F', 0x00, 'D', 0x00, '-', 0x00,
259+
'8', 0x00, 'B', 0x00, '3', 0x00, 'E', 0x00, '-', 0x00, '1', 0x00, '2', 0x00, '7', 0x00, 'C', 0x00, 'A', 0x00,
260+
'8', 0x00, 'A', 0x00, 'F', 0x00, 'F', 0x00, 'F', 0x00, '9', 0x00, 'D', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00
261+
};
262+
263+
TU_VERIFY_STATIC(sizeof(desc_ms_os_20) == MS_OS_20_DESC_LEN, "Incorrect size");
264+
265+
// Invoked when a control transfer occurred on an interface of this class
266+
// Driver response accordingly to the request and the transfer stage (setup/data/ack)
267+
// return false to stall control endpoint (e.g unsupported request)
268+
bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const* request) {
269+
// nothing to with DATA & ACK stage
270+
if (stage != CONTROL_STAGE_SETUP) return true;
271+
272+
switch (request->bmRequestType_bit.type) {
273+
case TUSB_REQ_TYPE_VENDOR:
274+
switch (request->bRequest) {
275+
case 1:
276+
if (request->wIndex == 7) {
277+
// Get Microsoft OS 2.0 compatible descriptor
278+
uint16_t total_len;
279+
memcpy(&total_len, desc_ms_os_20 + 8, 2);
280+
281+
return tud_control_xfer(rhport, request, (void*)(uintptr_t)desc_ms_os_20, total_len);
282+
} else {
283+
return false;
284+
}
285+
286+
default: break;
287+
}
288+
break;
289+
290+
default: break;
291+
}
292+
293+
// stall unknown request
294+
return false;
295+
}
296+
297+
#endif
191298
//--------------------------------------------------------------------+
192299
// String Descriptors
193300
//--------------------------------------------------------------------+

0 commit comments

Comments
 (0)