USB - MTP/PTP without Interrupt Endpoint - usb

Since we plan to use MTP (Media Transfer Protocol) for your next device, we evaluate the use of MTP as replacement for the current (unstable) USB drivers in the current released device.
The limitation on this device is, that its processor (Strong Arm) supports only up to 3 EndPoints:
"Serial port 0 is a universal serial bus device controller (UDC) that supports three endpoints and can operate half-duplex at a baud rate of 12 Mbps (slave only, not a host or hub controller)."
But according to the specification, MTP needs at least 4 endpoints (from the PTP spec):
"The device shall contain at least four endpoints: default, Data-In, Data-Out, and an Interrupt endpoint."
Now the question: Can we just skip the interrupt endpoint on the device? I know that it violates the specification - but what happens if we do?
From our current evaluation software I can see the following scenarios:
The 'space available' is not updated - the user will see that there is 100Mb of free memory, but placing a 1Mb file gives the error "Not Enough Memory"
Non-host driven actions are not visible on the host (so when on the device files are deleted, created or moved, the connected host does not know about it)
If we can live with it, is it advisable to implement it this way?
UPDATE: Damn... when I tested it last time, I ve just removed the code for interrupt-EP data transmission. Now I also removed the endpoint definition (I do not create the endpoint anymore) and from this point the MTP connection couldn't be established any more :(
It seems that the windows driver (wpd) requires the interrupt endpoint - even if it's not used. Bad luck...
Has anyone an idea, whether and how to get MTP working with 3 endpoints?

Finally I got an answer from Microsoft:
The 3-endpoints setup is not supported.
The interrupt endpoint is required so that the driver can receive MTP events from the device. These events are a notification mechanism that the driver relies on to relay events to applications (e.g. when an object is created, updated, or removed).
If your device does nothing with the endpoint (i.e. send no events), applications such as Explorer will not behave correctly whenever objects on your device are changed.
So we buried our plans... :(

Related

Limit total size of inflight iot message

I am using IoTHub device client SDK on an embedded device. The application will send telemetry message to iot hub periodically. The iot device connect to a wireless router and wireless connect to internet via WAN port.
When the wireless router lost internet connection, iot device will not get notified immediately about the disconnection. It takes about 60s to get notified, before that iot device will continue to send telemetry message with IoTHubDeviceClient_LL_SendEventAsync(), all those message get queued in SDK layer and eat memory. Since it's on embedded device with limited resource, memory get eaten up and cause program been killed by a lower memory killer app.
Is there way to specified total size of iot message can be queued in sdk layer? If exceed this quota, IoTHubDeviceClient_LL_SendEventAsync() will failed immediately.
Actually this is also needed for normal scenario too. When iot device send message, seems message been queued in low layer and get flushed out at certain time. I don't see any API that can control the flush. That create another problem, even when there is internet connection, from application level, there is no control of how many message been queued and how long it been queued, in turn, app has no control of how much memory been used by process. On my device, there is system monitor that will kill process use too much memory.
The question is what do you do even in that case if the message failure occurs in the case that the queue is full? Do you lose the information then because of lack of storage capacity? From the IoT perspective, I would recommend in this case to consider if your device is reliable IoT device to handle these edge cases as well. And also knowing the limits of the devices, and knowing how long it can be without the internet connection helps to mitigate these risks from your application, not SDK.
From the GitHub, default sendMessageAsync method throws timeout exception in case your message sending fails, unless you have some kind of retry policies implemented(according to the documentation C SDK does not allow custom retry policies
https://learn.microsoft.com/en-us/azure/iot-hub/iot-hub-reliability-features-in-sdks).
According to the documentation in case of connection failure based on the retry policy(if you have set it), SDK will try to initiate connection this way or that way and queue the messages created in the meantime:
https://github.com/Azure/azure-iot-sdk-c/blob/master/doc/connection_and_messaging_reliability.md
So, an expectation here is that SDK does not take responsibility for the memory limits. This is up to the application to deal. Since your device has some limitations, I would recommend implementing your own queuing mechanism(maybe set no-retry as a policy and that way avoid queuing). That way you have under the control what will happen in the case that there is no internet connection and have under the control memory limitations. Maybe your business case accepts that you calculate an average value and instead of 50 you store 1 message over the time etc..
If this something you do not like, the documentation says also that you set the timeout for the queue - maybe not the memory limit but timeout yes, so maybe you can try to investigate this a bit deeper:
"There are two timeout controls in this system. An original one in the iothub_client_ll layer - which controls the "waiting to send" queue - and a modern one in the protocol transport layer - that applies to the "in progress" list. However, since IoTHubClient_LL_DoWork causes the Telemetry messages to be immediately* processed, sent and moved to the "in progress" list, the first timeout control is virtually non-applicable.
Both can be fine-tuned by users through IoTHubClient_LL_SetOption, and because of that removing the original control could cause a break for existing customers. For that reason it has been kept as is, but it will be re-designed when we move to the next major version of the product."

Issues communicating with devices over usb hub

I'm facing issues when communicating with devices over USB hub. When enumerating devices directly to host port, it does work, some devices over usb hub have issues.
Setup: STM32F103C8 - MAX3421E - LUFA (usb stack) (ported to MAX3421E (host) and STM32F103C8T6 (device)) - USB Full-Speed setup
Scenario:
When I attach device directly to host, I don't experience any issues enumerating almost all (some devices seems to be faulty and have weird/nonstandard behavior) devices. But when I try to enumerate over usb hub, devices starts to behave very strangely. I'm receiving much more NAK's from devices than when connected directly to host. Some devices are able to return Device Descriptor, but retrieving Configuration Descriptor fail. Some devices return Toggle Error after several NAK's, this could be remedied so far by delaying retry IN token. Also there is different behavior of devices when connected over different hubs. I.e. one device has no problems when connected to HUB1, but have issues when connected to HUB2. Then I have HUB3 (7 port) which internally acts as HUB in HUB. On this HUB3 device working fine on port behind secondary internal hub, but not on primary ports exposed over "root" hub.
I'm in suspicion that hub's TT could be somehow interfering with usb communication, but according to information I have found, TT should not be enabled under Full-Speed setup.
I have checked (many times) that I'm setting correct device address assigned during SetAddress phase (which is proved by returning Device Descriptor). When I step debug it seems that I can get Configuration Descriptor also, but while in normal system run, it isn't retrieved, but only over hub.
Does anyone has any ideas, what to look after? I've run out of ideas here after week of trying to find a root cause.
Thanks
so...
- as usual after searching for root cause, solution after days of trying comes naturally after asking on somewhere (this is hapenning to me always, but I do try prior asking always)
- when using hubs, make sure you don't suspend SOF generation during control transfers. LUFA just resume bus inside control transfer routines, so make sure you don"t stops and reenable SOF within (my fault as I'm using ported version to MAX)
- if you have tight main loop make sure you don"t reinitialize usb transfer without completion of previous try, but if you do so, check you don't owerwrite data which haven"t been processed yet fully (especially when using interrupt-driven transfer complete processing) [things seems to work when you have quite some debug output, as it delay that time critical transfers]
Enumeration over hub isuues are now second to none. Small glitches are subject for tweaking.
Unfortunately as I was in question for electrical issues, I had to unsolder usb host shield and soldered another one, which in light of new information seems unneeded. Nevermind, I have trained my soldering skills.

Windows KMDF driver, Informing application of a change via a notification, is it possible

I have built a simple PCI driver for reading and writing data to a PCI device. I have also added interrupt support, so when there is a PCI interrupt an ISR is called. This all seems to work.
I would like to inform an external application of the interrupt. So far I haven't found a suitable mechanism. The interrupt could come at any time, and is dependent on Sensors connected to the PCI device.
I have found the following:-
1 Event objects which can be passed to the KMDF driver via read, write, iocontrol commands (Overlapped object)
2 Plug and Play notifications, which can be use used by (Toaster example code) the driver to inform the app of PNP events.
A notification method would be ideal, however it doesn't look like one exists for my particular use case.
There are at least 2 ways to achieve what you are looking for
Inverted call model - send IOCTL(s) to the driver which the driver will keep pending and will complete them as and when it needs to notify the user mode about the occurrence of the event that it is interested in. You can read more about this approach here.
Use shared event handles. A user mode application communicates the event handle(s) to kernel mode using an IOCTL. The kernel mode increments the reference count to ensure that the handle remains valid when it needs to use it and then signals the event when necessary. You can read more about this approach here.
The first approach is more preferred for various reasons that you will find while reading the linked articles. If your use case requires the kernel mode to not only indicate the occurrence of an event but also send some data back to user mode then the second approach is not suitable for your requirement and you should focus on the first approach alone.

What is the use of multiple control endpoints (non-EP0)?

I learned on OSDev wiki that Endpoint 0 is the default control pipe, allowing for bi-directional control transfers. This is used for device configuration, e.g. to retrieve device descriptors. The USB 2.0 spec explains this more thorougly in section 5.5 Control Transfers.
There are also a limited amount of endpoints available (2 for low-speed, 15 for full- and high-speed devices). Somewhere in the USB 2.0 spec, I have read that there must be at least one control pipe. This implies that there may be multiple control endpoints, but what is the use of it? Do you know any particular USB device or class that has an EP configured as control pipe?
Later, I found this in the spec, section 10.1.2 Control Mechanisms:
A particular USB device may allow the use of additional message pipes
to transfer device-specific control information. These pipes use the
same communications protocol as the default pipe, but the information
transferred is specific to the USB device and is not standardized by
the USB Specification.
If I understand it correctly, this means that non-EP0 cannot be used to configure the device (say, a standard request such as GET_DESCRIPTOR). But the setup/data/status stages seem still to be available ("[..] use the same communications protocol [..]"). Is this correct? Or is the use of standard/class requests forbidden for non-EP0?
Background: while working on an emulated USB device in QEMU, the need for a USB monitor for debugging purposes appeared. During inspection of the QEMU core USB code, I noticed that it only processed control commands for EP0. Other endpoints would be treated as data. There are some virtual devices (host-libusb) that always reject control transfers for those other endpoints. Hence the question whether this is the correct behavior or not (and if valid, whether there exist devices that really implement this).
As far as I can tell, there is no use for a non-EP0 control endpoint. I have developed several products that use custom control transfers on endpoint 0 as the main way to send device-specific requests and I have not encountered any fundamental problems with doing that.
If you did make a non-EP0 control endpoint I think your understanding is correct; you wouldn't be able to use it for standard requests but you would be able to use it for custom requests and the transaction sequences would be the same as on EP0.

Bluetooth low energy : Discovery modes and connection mode, Independent or dependent?

In GAP test spec (4.1.0) there is a test case (TP/DISC/NONM/BV-02-C [Non-discoverable Mode Undirected Connectable Mode]).
Basically i need to put IUT in non-discovarable mode and non-connectable mode.
Let's see what core4.1 spec has to say:
Non-Discovarable mode:
1)Shall not set LE GENERAL and LE LIMITED Flags in ADV data.
2)A Peripheral device in the non-connectable mode may send non-connectable
undirected advertising events or scannable undirected advertising events
or may not send advertising packets.
If the Peripheral device in the non-discoverable mode sends non-connectable
advertising events or scannable undirected advertising events then it is
recommended that the Host configures the Controller as follows:
• The Host should set the advertising filter policy to either ‘process scan and
connection requests only from devices in the White List’ or ‘process scan
and connection requests from all devices’.
Undirected-Connectable mode:
The Host shall configure the Controller to send undirected connectable advertising
events.
Type of advertisement is contradictory. So what should i do for this particular test case?
Just read a book on BLE. It seems Discovery mode has nothing to do with type of advertisement. Discovery mode only and only depends on the flag in advertisement data. Connection mode depends on type of advertisement.
I am not marking this as correct answer. Would like feedback from someone experienced in BLE dev/test.
Update:
Discoverable modes just define the flags in adv packet. They do not dictate any type of advertisement. Any type of advertisement which can carry advertisement data payload can be used in any discoverable mode.
Now when you advertise it has be in one of the connection mode. Connection mode defines type of advertisement and discover mode defines the flag in the advertisement data.
For example:
Peripheral = (No flag + connectable undirected mode ) and Central = (General or limited discovery procedure) then this device will not be seen by application on top of GAP central.