Hi Jose,
Sorry for the long delay. Too much on my plate made me forgetting about
that proposal ;|
Hello everybody,
We would like to propose a RFC to change the way to manage the WPS
connections. Following we present our proposal and the reasons for
suggesting it:
Current implementation of WPS connection requires to specify the
service to which the user wants to connect, and when the connection is
going to finalize, a verification is done in /handle_wps_completion/
function to ensure that the SSID of the AP actually being connected
was the one specified by the user. This violates the WiFi Alliance
specification over WPS and the WPS Certification plan because:
1. WiFi Alliance admits to certify devices that have no mean for the
user to choose an AP to connect to, they define them as "Client
devices with only a simple display or a fixed label containing a
setup password" (Pag. 12 of Wi-Fi Simple Configuration Technical
Specification Version 2.0.5)
2. The WPS protocol includes the transition from un-configured to
configured state of the AP when the first Enrollee connects, some
Access Points change their SSID during this transition, that would
cause the ConnMan to invalidate the connection. A tipical example
of such Access Point is the Atheros used in test 5.4.2 of Wi-Fi
CERTIFIED™ Wi-Fi Protected Setup™ Interoperability Test Plan –
Version 2.0.15
After having performed a detailed study of the wpa_supplicant
implementation for the WPS, we propose to implement a solution with
the following general characteristics:
1. The new implementation must keep current WPS implementation for
compatibility support, but as deprecated.
2. In order to meet the specifications of Wi-Fi Alliance and based on
what the WPS D-Bus Interface of wpa_supplicant offers (Documented
in
https://w1.fi/wpa_supplicant/devel/dbus.html#dbus_wps) we
propose to add two methods to the Technology D-Bus Interface:
/StartWPS/ and /CancelWPS/, analogous to functions WPS.Start and
WPS.Cancel provided by wpa_supplicant. In this way there is no
service specified enabling simple devices to offer a very basic
interface to the user for starting the WPS session. Both methods
would be supported only by WiFi technology.
3. On the other hand, some advanced WiFi modules expose more than one
network interface (one for P2P, one for STA, one for AP ..) that
can be active at the same time, and it is then desirable to not
let connman randomly choose on which start WPS, thuswe propose
also to add the possibility to specify the interface over which
either the start or cancel action will be performed. This would
not be a mandatory parameter in order to keep the things easy for
more simple systems.
Please find below the implementation proposal:
_StartWPS:_
Following the approach of wpa_supplicant, we propose to add the
possibility to choose which role to assume (enrollee, registrar),
which authentication type use (pin, pbc) and get back the pin to be
used (if required), as well as wpa_supplicant does. At this point, we
can briefly define a possible prototype of the method:
dict StartWPS(dict parameters)
Where the returned dictionary could be empty or composed by at most
one entry, which will be the just generated PIN by the wpa_supplicant,
in case it was requested. On the other hand, the function would
receive a dictionary with possible keys: “Ifname", "Role",
"Type" and
"Pin"; where “Ifame” is an optional parameters covering previous
defined characteristic for complex systems. Whereas, parameters
"Role", "Type" and "Pin" follow exactly the same behavior
of the table
presented in
https://w1.fi/wpa_supplicant/devel/dbus.html#dbus_wps for
method Start of fi.w1.wpa_supplicant1.Interface.WPS Interface.
When the /StartWPS/ method gets called, it should verify if interface
was specified through “Ifname” entry key. If so, WPS Session will be
started in that specific interface, otherwise we suggest to look for
the first available interfacewith the capabilities to start a WPS
Session among the device_listof the Wi-Fi Technology. If it is found,
then use it, if not return "[service].Error.NotSupported”.
You don't want to expose ifname. ConnMan's idea is to hide the lower
level things like actual interfaces.
Of course my comment does not help when you need to mitigate which of
the 2+ wifi devices will actually run WPS.
You will have to figure out a way to make ConnMan smart about it.
Let's make things simpler on the other parameters too.
PBC/PIN for instance: make it one unique parameter. If filled in: it's a
PIN, if not: it's PBC.
No need then of type and pin. Just an "authentication" parameter.
Now about the role, it would be great to remove it also. It's trickier
but possible I think.
Thing is, user or UI itsels should not have to choose for the role. It's
an irrelevant information at this level.
ConnMan should be smart enough to figure out what's needed.
For instance, when it wants to connect to an AP, it's surely enrolee.
In case of P2P you can try that idea (I don't guaranty it's a working one):
There as already a logic in gsupplicant code that checks for actual WPS
being ran by some other end (this is currently used to avoid asking user
to run wps or provide a psk once he asked to connect a wifi service).
I am not entirely sure (wps is far away from me) but it's worth checking
in the IE that current WPS being broadcasted is a registrar or an
enrolee. That way: you can tell which role you need.
This works if only the other end has started WPS already.
Now in case you need to be the registrar. When tethering over wifi for
instance. You'll need a different approach.
A method dedicated to the AP mode?
Additionally, current implementation does not allow to start a WPS
Session when the device is playing as Access Point (Tethering). On the
contrary, wpa_supplicant does. Therefore, we propose to also add this
possibility to the new implementation. It would be possible if a
Service D-Bus Object is not required for starting a WPS Session, which
would be true if the new methods are added to the Technology D-Bus
Interface, as we propose.
_CancelWPS:_
This function does not require for any particular parameter. So, we
propose to only continue giving the option to specify the interface.
Therefore, the possible prototype of the method would be:
void CancelWPS(dict parameters)
Where the received dictionary could be empty or composed by at most
one single entry if the user wants to specify the interface using the
key “Ifname”. If so, the /CancelWPS/ function should cancel the
ongoing WPS Session running in that specific interface. Otherwise, we
suggest to do it over all the Device of the Wi-Fi Technology
(device_list).
Get rid of the ifname parameter. Just put no parameters and that's it.
ConnMan should be smart enough to check which device below is running
WPS and cancel those.
And btw: it's against the spec - afaik - to get more than 2 devices
around running WPS, so ConnMan should never start WPS on 2+ devices.
_Going into details of implementation_:
After having studied the ConnMan architecture we think to associate
the WPS concept to the Device Infrastructure because if we want to add
the possibility of specify the interface (“Ifname”), the Device is the
corresponding represents of a real device inside the ConnMan.
Therefore, we think it is the best choice. Additionally, /StartWPS/
and /CancelWPS/ should be added to the device driver:
*static**struct*connman_device_driverwifi_ng_driver = {
.name= "_wifi_",
.type= /CONNMAN_DEVICE_TYPE_WIFI/,
...
.start_wps= wifi_start_wps,
.cancel_wps= wifi_cancel_wps,
};
It means that WiFi plugging must implements both methods
wifi_start_wpsand wifi_cancel_wps. In particular, wifi_start_wpswill
need to receive the WPS parameters to then pass them to the ConnMan’s
supplicant handler (gsuppicant/supplicant.c), which is the only one
that interacts directly with the wpa_supplicant.
Next, the supplicant handler will call methods Start or Cancel of the
fi.w1.wpa_supplicant1.Interface.WPS D-Bus Interface of the
wpa_supplicant, with the required parameters. In case the method Start
returns the newly generated PIN it has to be forwarded towards the
Technology to then be added as an entry in the directory that would be
returned by the /StartWPS/ method. It would imply that we have to
store the request message of the /StartWPS/ method in order to reply
possibly with a the PIN generated by the wpa_supplicant. To do it, we
propose to store that message in the Device structure in order to be
coherent with the association we previously proposed between the WPS
and Device.
Once the WPS Session has been initiated, it could finalize
successfully or fail. The current implementation does not provide
further information aboutsuch a events. Given that, we propose to
notify the following events (Just the most commons):
* Success: WPS provisioning has finished successfully.
* Password Authentication Fail: When pin entered in the registrar
was wrong.
* PBC-Overlap: When an enrollee detects two registrars with PBC
session active.
We think to perform those notifications using a D-Bus Signal added to
the Technology Interface, let’s call it /WPSEvent/. It would simply
indicate when one of the described event takes place. We propose to
just provide a string with the name of the event: "success",
"pwd-auth-fail" or "pbc-overlap", following the wpa_supplicant
notation. All this information is already provided by the
wpa_supplicant in the event fi.w1.wpa_supplicant1.Interface.WPS.Event,
thus it just need to be forwarded to the Technology in order to be
emitted.
Either it's a success or a failure, and nobody above ConnMan cares about
the exact reason.
No need of any event. Just make StartWPS returning a end status, that's
it. No need of any signal.
In order to forward WPS events, we propose to follow the
implementation of the communication between the plug-in and the
supplicant handler, it means to use the callback mechanism adding a
new callback:
*static**const*GSupplicantCallbackscallbacks = {
...
.wps_event= wps_event,
};
Thus the wifi plug-in must implement the wps_eventfunction that will
basically just call a Technology function that will emit the proposed
signal.
What do you think about our proposal? Of course, everybody is welcome
to give feedbacks and suggestions.
Tomasz