How to wrap a UEFI Driver (EDK II) With a New Protocol - protocols

I'm trying to take a UEFI driver from a 3rd party and wrap it in a different protocol GUID of my own to simplify the interface which is used by a sample application.
I do not want to make changes (other than maybe a GUID change when requesting LocateHandleBuffer()) to the sample application which was originally tied to a driver of my own (not 3rd party) where I didn't have to do any wrapping.
Given that I can't really associate the wrapper with a controller handle or use the USB IO protocol, it seems this does not qualify as a driver anymore.
Is there a way to do this so that I can still provide an abstracted loadable image for the sample application to use, or do I ultimately have to do this wrapping in source in the demo application?

Related

WebUSB API, for pushing commands/configuration to the device through webApp

I am doing some research on the WebUSB API for our company because we are going to start to manufacture devices in house.
Our current device manufacture comes with an application so the team can plug the device into a computer and diagnose it. Their application allows us to read outputs from the device, as well as pushing commands/configuration to the device over a wired connection.
Since this device is 100% ours, we are also responsible for building out the diagnostic tooling. We need some sort of interface that allows a user to read outputs and send commands/configuration to the device over a wired USB connection.
Is the webUSB the correct API? If not, what are some suggestions for accomplishing the requirement? Are we limited to building some sort of desktop or mobile application?
I would recommend resources below to read to help you understand if the WebUSB API fits your needs or not:
https://web.dev/devices-introduction/ helps you pick the appropriate API to communicate with a hardware device of your choice.
https://web.dev/build-for-webusb/ explains how to build a device to take full advantage of the WebUSB API.
From what you describe, WebUSB isn't strictly required but won't hurt either.
First and foremost, you will need to implement the USB interfaces reading data and sending configurations. It will be a custom protocol, and not one of the standard USB device classes such as HID, video or mass storage. The details of the protocol and if you use control, interrupt or bulk transfers is your choice.
I'm assuming you will connect the devices to Windows PCs, and you likely don't want to put money into writing device drivers. If so, the easiest approach is to add the required descriptors and control requests required for Microsoft OS 2.0 Descriptors. That way, the WinUSB driver will be installed automatically when the device is plugged in.
Using the WinUSB API, a Windows application will then be able to communicate with the USB device. No additional drivers are needed. (On macOS and Linux it's even easier as you don't need the Microsoft OS 2.0 Descriptors in the first place.)
On top of that you can implement the additional descriptors and control requests for WebUSB. It will provide the additional benefit that you can write a web application (instead of a native application) for communicating with the USB device. (Currently, you are restricted to the Chrome browser.) WebUSB devices should implement the WinUSB descriptors as the alternative (.INF files, manual installation process) is a pain.
The already mentioned web page https://web.dev/build-for-webusb/ is a complete example of how to implement it.

Where/How should I define my SPI driver pins if I pretend to load the driver manually as a module

I am writing here because I am having some problems understanding some key concepts regarding kernel/drivers development.
First, I am going to try to describe what I want to achieve:
Develop a driver that uses the SPI to communicate receiving the payload from user space (I cannot use spidev because I pretend to transparently add some info to the payload before sending it). I want to load the module manually (insmod).
The problem I am seeing: I do not know where or how to specify my interface. If I define the interface within the device tree, is it mandatory to include the compatible field? I ask this because the driver will not be included within the kernel modules as it starts up... Maybe there is not a problem with it. In the examples, I found about spi they only speak about the BUS, Chip Select... but they do not mention MISO and MOSI, so I guess these must be defined by the device tree or maybe since you specify the bus the definition of the rest of the pins is straight forward... I would like to understand this.
Thanks in advance.
Best regards,
Fulgo.

How do 'clients' fit in with 'platform devices' and 'platform drivers'

Reading about the driver-model platform, my understanding is that a platform driver is a static piece of kernel code that controls a platform device, which is a device which generally is always present in the system, as opposed to a driver composed of a kernel module, which can be loaded or removed at will and controls devices which might not always be connected. This answer seems to support that statement.
If all this is true, I expect it's what I'm looking for. I am trying to write a kernel module which, among other things, needs to communicate with an external device over I2C. While the external device isn't always part of the system, the I2C bus IS, so it ought to be controlled by a platform driver. So rather than writing code in my module to directly control the I2C, I ought to be using the platform driver. I found what I believe to be the proper platform driver for the I2C bus on my platform here, and it does use < linux/platform_device.h >, so that seems to be consistent.
However, in addition to this, when looking up I2C in general, I have seen reference to an I2C "client". From the name alone, this sounds like what I am trying to write now, a kernel module that uses the platform driver to communicate over I2C. However, in the documentation for the driver-model platform, nothing about a "client" is mentioned, so I don't know if this is correct or if it is some completely separate different model.
So how does a "client" kernel module fit into the driver-platform model for interfacing with hardware in Linux? Is my module supposed to instantiate a struct of the i2c_driver, or is that something done by the platform driver, and the module is supposed to create an interface to that?

Adding a wireless AccessPoint through the Smart Device Framework

I have a couple questions:
In general, what is the general difference between the OpenNETCF.Net namespace and the OpenNETCF.Net.NetworkInformation namespace in the Smart Device Framework? There seems to be a lot of functionality overlap between the two. Is the OpenNETCF.Net namespace now deprecated in favor of the NetworkInformation namespace?
More specifically, I have a device with a wireless adapter. My goal is to be able to query nearby access points and then connect to them through my own user interface.
OpenNETCF.Net.Networking.GetAdapters()[1] gives me my adapter object representing the wireless adapter. Even though this is a wireless adapter, IsWireless and IsWirelessZeroConfigCompatible both return false. However, NearbyAccessPoints DOES return a list of nearby access points as you would expect a wireless adapter to do.
I need a way to add one of the discovered access points to the PreferredAccessPoints collection. I have not found a method to accomplish this within the OpenNETCF.Net namespace. The only way I've found to add an AccessPoint is through the AddPreferredNetwork() method of the OpenNETCF.Net.NetworkInformation.WirelessZeroConfigNetworkInterface class. The problem I'm having is that I've been unable to find a way to obtain a WirelessZeroConfigNetworkInterface object. The object returned by the NetworkInterface.GetAllNetworkInterfaces() method is just a plain old NetWorkInterface object, not a WirelessZeroConfigNetworkInterface object as I hoped. I'm sure this is probably related to the issue with IsWireless returning false in the NetworkAdapter object.
Is there a way to construct the WirelessZeroConfigNetworkInterface object even though the framework seems to think it is not wireless? It looks like the functionality is there as demostrated by the Wireless related methods of the NetworkAdapter object.
The history is a bit confusing, yes. Basically SDF 2.2 (or earlier, I don't recall any more) had everything in the OpenNETCF.Net namespace. When I was adding features in 2.3, I added a boatload of stuff in the OpenNETCF.Net.NetworkInformation namespace that paralleled the full framework. Some of that had functional overlap with things we had done in the wireless stuff, so I made the decision to move everything over to the OpenNETCF.Net.NetworkInformation namespace. I left the originals and marked them as deprecated to try to be friendly to existing deployments. The items you should use are the ones in the OpenNETCF.Net.NetworkInformation namespace.
Now on to how the stuff functions. First we query NDIS for all network interfaces. This gives us wired, RNDIS, wireless, etc - basically everything that the network stack knows about. NDIS, however, doesn't know much about "wireless" stuff - it does know some though.
Once we have our list of known adapters, we then ask NDIS if it's a wireless device - it can at least tell us that becasue the driver tells NDIS at registration.
Once we have a list of wireless adapters, we then walk them and ask the WZC subsystem if it knows about the adapter. WZC is an interface that knows everything about the wireless devices, allowing us to intereact with it through a common, published interface. If WZC does know about it (meaning the driver reported itself at initialization to WZC) then we create a WirelessZeroConfigNetworkInterface for it. If it isn't known by WZC, then we know it's wireless (NDIS told us it was), but we only have the NDIS methods for interacting with it.
NDIS doesn't give us a way to associate. It does give us a way to ask for nearby SSIDs. The Adapter interface you have, then, exposes the capabilities we know of.
In some cases the driver has a proprietary API to manipulate the WiFi settings (e.g. old Cisco cards).
What version of the OS is this you're running on? What WiFi chipset/adapter are you using?

Accessing Bluetooth virtual COM port on Windows without manual pairing

I need to connect to a Bluetooth device through virtual COM port created in Windows. It's easy when the port has been already created during manual pairing procedure. But I would like my application to relieve an user from the manual pairing of a device. I would like to present all devices in the range, allow user to chose one, and then create virtual COM port connected with the selected device. I'm not trying to avoid the pairing procedure itself, but rather I would like to invoke it by my application.
I started getting familiar with Microsoft Bluetooth API. And then some doubts arose. I've been wondering what happen if some user would use different (than Microsoft's) Bluetooth stack? Is the Microsoft's API the real Bluetooth API, which have to be implemented by any other Bluetooth stack provider? Or rather each provider has its own API, and the Microsoft's is only one of many other?
Thanks everyone for valuable input. I'd like to summarize what I've found so far. The Microsoft Bluetooth API is not operating system API. Application written against it will not cooperate correctly with any other Bluetooth stack. It seems that applications which are intended to cooperate with multiple stacks need to provide some stack abstraction layer, and stack specific code for all of them.The other solution is to allow user for manual pairing of the Bluetooth device, which eventually create some virtual device in the operating system (e.g., COM port). Then the application can use standard interface of such a device.
I can't speak for the Microsoft Bluetooth API, but there are multiple Bluetooth stacks available for the PC platform (even more for mobile devices).
The underlying API is defined by the Bluetooth Core Spec and so all stacks should be able to interact, in fact it is mandatory that they interop or they cannot use the Bluetooth name and logo.
As to pairing, your going to have a hard time getting devices to pair if they have default security, which requires a pin code.
Things might be simpler in the (near) future, as the Bluetooth standard has introduced a new security model, secure simple pairing, which has a 'just works' mode that requires no Pin code. This is still stronger then the current security, except against Man in the middle attacks. However, it could be a while before you see the chips with this feature in PCs.
If you can change to using .NET :-/ I can recommend our library 32feet.NET.
For explicit pairing there's BluetoothSecurity.PairDevice. We can also create the virtual port for you, for example:
BluetoothClient cli = new BluetoothClient();
BluetoothDeviceInfo[] list = cli.DiscoverDevices();
BluetoothDeviceInfo selected = GetUserToSelectOne(list);
BluetoothSecurity.PairDevice(selected, pin);
// Ask Win32 to create a virtual serial port
selected.SetServiceState(BluetoothService.SerialPort);
However I really don't like virtual serial ports so I always suggest that people use a normal sockets connection using our BluetoothClient class, it will automatically handle a pairing request if required.
On Win32 we support the stacks from Microsoft, Widcomm/Broadcom, and BlueSoleil. On Widcomm there's no support for SetServiceState there yet, and their API has no support for responding to pairing requests. BlueSoleil should support both.
A brief user's guide is at 32feet.NET — User’s Guide, and all the class documentation is available at the main site http://32feet.net, the Widcomm documentation is only in our code repository at the moment.

Resources