123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471 |
- /**
- \page p2p Wi-Fi Direct - P2P module
- Wi-Fi Direct functionality is implemented any many levels in the WLAN
- stack from low-level driver operations to high-level GUI design. This
- document covers the parts that can be user by wpa_supplicant. However,
- it should be noted that alternative designs are also possible, so some
- of the functionality may reside in other components in the system.
- The driver (or WLAN firmware/hardware) is expected to handle low-level
- operations related to P2P Power Management and channel scheduling. In
- addition, support for virtual network interface and data frame
- processing is done inside the driver. Configuration for these
- low-level operations is defined in the driver interface:
- src/drivers/driver.h. This defines both the commands and events used to
- interact with the driver.
- P2P module implements higher layer functionality for management P2P
- groups. It takes care of Device Discovery, Service Discovery, Group
- Owner Negotiation, P2P Invitation. In addition, it maintains
- information about neighboring P2P Devices. This module could be used
- in designs that do not use wpa_supplicant and it could also reside
- inside the driver/firmware component. P2P module API is defined in
- \ref src/p2p/p2p.h.
- Provisioning step of Group Formation is implemented using WPS
- (\ref src/wps/wps.h).
- wpa_supplicant includes code in interact with both the P2P module
- (\ref wpa_supplicant/p2p_supplicant.c) and WPS
- (\ref wpa_supplicant/wps_supplicant.c). The driver operations are passed
- through these files, i.e., core P2P or WPS code does not interact
- directly with the driver interface.
- \section p2p_arch P2P architecture
- P2P functionality affects many areas of the system architecture. This
- section shows couple of examples on the location of main P2P
- components. In the diagrams below, green arrows are used to show
- communication paths from the P2P module to upper layer management
- functionality and all the way to a GUI that user could use to manage
- P2P connections. Blue arrows show the path taken for lower layer
- operations. Glue code is used to bind the P2P module API to the rest
- of the system to provide access both towards upper and lower layer
- functionality.
- \subsection p2p_arch_mac80211 P2P architecture with Linux/mac80211/ath9k
- An architecture where the P2P module resides inside the
- wpa_supplicant process is used with Linux mac80211-based drivers,
- e.g., ath9k. The following diagram shows the main components related
- to P2P functionality in such an architecture.
- \image html p2p_arch.png "P2P module within wpa_supplicant"
- \image latex p2p_arch.eps "P2P module within wpa_supplicant" width=15cm
- \subsection p2p_arch_umac P2P architecture with UMAC
- The following diagram shows the main components related to P2P
- functionality in an architecture where the P2P module resides inside
- the kernel IEEE 802.11 stack (UMAC in the figure).
- \image html p2p_arch2.png "P2P module in kernel
- \image latex p2p_arch2.eps "P2P module in kernel" width=15cm
- \section p2p_module P2P module
- P2P module manages discovery and group formation with a single state
- machine, i.e., only a single operation per device can be in progress
- at any given time. The following diagram describes the P2P state
- machine. For clarity, it does not include state transitions on
- operation timeouts to the IDLE state. The states that are marked with
- dotted ellipse are listed for clarity to describe the protocol
- functionality for Device Discovery phase, but are not used in the
- implementation (the SEARCH state is used to manage the initial Scan
- and the alternating Listen and Search states within Find).
- \image html p2p_sm.png "P2P module state machine"
- \image latex p2p_sm.eps "P2P module state machine" width=15cm
- \subsection p2p_module_api P2P module API
- P2P module API is defined in \ref src/p2p/p2p.h. The API consists of
- functions for requesting operations and for providing event
- notifications. Similar set of callback functions are configured with
- struct p2p_config to provide callback functions that P2P module can
- use to request operations and to provide event notifications. In
- addition, there are number of generic helper functions that can be
- used for P2P related operations.
- These are the main functions for an upper layer management entity to
- request P2P operations:
- - \ref p2p_find()
- - \ref p2p_stop_find()
- - \ref p2p_listen()
- - \ref p2p_connect()
- - \ref p2p_reject()
- - \ref p2p_prov_disc_req()
- - \ref p2p_sd_request()
- - \ref p2p_sd_cancel_request()
- - \ref p2p_sd_response()
- - \ref p2p_sd_service_update()
- - \ref p2p_invite()
- These are the main callback functions for P2P module to provide event
- notifications to the upper layer management entity:
- - \ref p2p_config::dev_found()
- - \ref p2p_config::go_neg_req_rx()
- - \ref p2p_config::go_neg_completed()
- - \ref p2p_config::sd_request()
- - \ref p2p_config::sd_response()
- - \ref p2p_config::prov_disc_req()
- - \ref p2p_config::prov_disc_resp()
- - \ref p2p_config::invitation_process()
- - \ref p2p_config::invitation_received()
- - \ref p2p_config::invitation_result()
- The P2P module uses following functions to request lower layer driver
- operations:
- - \ref p2p_config::p2p_scan()
- - \ref p2p_config::send_probe_resp()
- - \ref p2p_config::send_action()
- - \ref p2p_config::send_action_done()
- - \ref p2p_config::start_listen()
- - \ref p2p_config::stop_listen()
- Events from lower layer driver operations are delivered to the P2P
- module with following functions:
- - \ref p2p_probe_req_rx()
- - \ref p2p_rx_action()
- - \ref p2p_scan_res_handler()
- - \ref p2p_scan_res_handled()
- - \ref p2p_send_action_cb()
- - \ref p2p_listen_cb()
- In addition to the per-device state, the P2P module maintains
- per-group state for group owners. This is initialized with a call to
- p2p_group_init() when a group is created and deinitialized with
- p2p_group_deinit(). The upper layer GO management entity uses
- following functions to interact with the P2P per-group state:
- - \ref p2p_group_notif_assoc()
- - \ref p2p_group_notif_disassoc()
- - \ref p2p_group_notif_formation_done()
- - \ref p2p_group_match_dev_type()
- The P2P module will use following callback function to update P2P IE
- for GO Beacon and Probe Response frames:
- - \ref p2p_group_config::ie_update()
- \section p2p_driver P2P driver operations (low-level interface)
- The following driver wrapper functions are needed for P2P in addition
- to the standard station/AP mode operations when the P2P module resides
- within wpa_supplicant:
- - \ref wpa_driver_ops::if_add()
- - \ref wpa_driver_ops::if_remove()
- - \ref wpa_driver_ops::remain_on_channel()
- - \ref wpa_driver_ops::cancel_remain_on_channel()
- - \ref wpa_driver_ops::send_action()
- - \ref wpa_driver_ops::probe_req_report()
- The following driver wrapper events are needed for P2P in addition to
- the standard station/AP mode events when the P2P module resides within
- wpa_supplicant:
- - \ref wpa_event_type::EVENT_RX_MGMT
- - \ref wpa_event_type::EVENT_REMAIN_ON_CHANNEL
- - \ref wpa_event_type::EVENT_CANCEL_REMAIN_ON_CHANNEL
- - \ref wpa_event_type::EVENT_RX_PROBE_REQ
- \section p2p_go_neg P2P device discovery and group formation
- This section shows an example sequence of operations that can be used
- to implement P2P device discovery and group formation. The function
- calls are described based on the P2P module API. The exact design for
- the glue code outside the P2P module depends on the architecture used
- in the system.
- An upper layer management entity starts P2P device discovery by
- calling \ref p2p_find(). The P2P module start the discovery by requesting a
- full scan to be completed by calling \ref p2p_config::p2p_scan(). Results
- from the scan will be reported by calling \ref p2p_scan_res_handler() and
- after last result, the scan result processing is terminated with a
- call to \ref p2p_scan_res_handled(). The P2P peers that are found during
- the full scan are reported with the \ref p2p_config::dev_found() callback.
- After the full scan, P2P module start alternating between Listen and
- Search states until the device discovery operation times out or
- terminated, e.g., with a call to \ref p2p_stop_find().
- When going into the Listen state, the P2P module requests the driver
- to be configured to be awake on the listen channel with a call to
- \ref p2p_config::start_listen(). The glue code using the P2P module may
- implement this, e.g., by using remain-on-channel low-level driver
- functionality for off-channel operation. Once the driver is available
- on the requested channel, notification of this is delivered by calling
- \ref p2p_listen_cb(). The Probe Request frames that are received during the
- Listen period are delivered to the P2P module by calling
- \ref p2p_config::p2p_probe_req_rx() and P2P module request a response to
- these to be sent by using \ref p2p_config::send_probe_resp() callback
- function. If a group owner negotiation from another P2P device is
- received during the device discovery phase, that is indicated to the
- upper layer code with the \ref p2p_config::go_neg_req_tx() callback.
- The Search state is implemented by using the normal scan interface,
- i.e., the P2P module will call \ref p2p_config::p2p_scan() just like in the
- full scan phase described. Similarly, scan results from the search
- operation will be delivered to the P2P module using the
- \ref p2p_scan_res_handler() and \ref p2p_scan_res_handled() functions.
- Once the upper layer management entity has found a peer with which it
- wants to connect by forming a new group, it initiates group owner
- negotiation by calling \ref p2p_connect(). Before doing this, the upper
- layer code is responsible for asking the user to provide the PIN to be
- used during the provisioning step with the peer or the push button
- press for PBC mode. The glue code will need to figure out the intended
- interface address for the group before group owner negotiation can be
- started.
- Optional Provision Discovery mechanism can be used to request the peer
- to display a PIN for the local device to enter (and vice versa). Upper
- layer management entity can request the specific mechanism by calling
- \ref p2p_prov_disc_req(). The response to this will be reported with the
- \ref p2p_config::prov_disc_resp() callback. If the peer device started
- Provision Discovery, an accepted request will be reported with the
- \ref p2p_config::prov_disc_req() callback. The P2P module will
- automatically accept the Provision Discovery for display and keypad
- methods, but it is up to the upper layer manegement entity to actually
- generate the PIN and to configure it with following \ref p2p_connect() call
- to actually authorize the connection.
- The P2P module will use \ref p2p_config::send_action() callback to request
- lower layer code to transmit an Action frame during group owner
- negotiation. \ref p2p_send_action_cb() is used to report the result of
- transmission. If the peer is not reachable, the P2P module will try to
- find it by alternating between Action frame send and Listen
- states. The Listen state for this phase will be used similarly to the
- Listen state during device discovery as described above.
- Once the group owner negotiation has been completed, its results will
- be reported with the \ref p2p_config::go_neg_completed() callback. The
- upper layer management code or the glue code using the P2P module API
- is responsible for creating a new group interface and starting
- provisioning step at this point by configuring WPS Registrar or
- Enrollee functionality based on the reported group owner negotiation
- results. The upper layer code is also responsible for timing out WPS
- provisioning if it cannot be completed in 15 seconds.
- Successful completion of the WPS provisioning is reported with a call
- to \ref p2p_wps_success_cb(). The P2P module will clear its group formation
- state at this point and allows new group formation attempts to be
- started. The upper layer management code is responsible for configuring
- the GO to accept associations from devices and the client to connect to
- the GO with the provisioned credentials. GO is also responsible for
- calling \ref p2p_group_notif_formation_done() as described below.
- If the WPS provisioning step fails or times out, this is reported with
- a call to \ref p2p_group_formation_failed(). The P2P module will clear its
- group formation state at this point and allows new group formation
- attempts to be started. The upper layer management code is responsible
- for removing the group interface for the failed group.
- \section p2p_sd P2P service discovery
- P2P protocol includes service discovery functionality that can be used
- to discover which services are provided by the peers before forming a
- group. This leverages the Generic Advertisement Service (GAS) protocol
- from IEEE 802.11u and P2P vendor-specific contents inside the Native
- GAS messages.
- The P2P module takes care of GAS encapsulation, fragmentation, and
- actual transmission and reception of the Action frames needed for
- service discovery. The user of the P2P module is responsible for
- providing P2P specific Service Request TLV(s) for queries and Service
- Response TLV(s) for responses.
- \subsection p2p_sd_query Quering services of peers
- Service discovery is implemented by processing pending queries as a
- part of the device discovery phase. \ref p2p_sd_request() function is used
- to schedule service discovery queries to a specific peer or to all
- discovered peers. \ref p2p_sd_cancel_request() can be used to cancel a
- scheduled query. Queries that are specific to a single peer will be
- removed automatically after the response has been received.
- After the service discovery queries have been queued, device discovery
- is started with a call to \ref p2p_find(). The pending service discovery
- queries are then sent whenever a peer is discovered during the find
- operation. Responses to the queries will be reported with the
- \ref p2p_config::sd_response() callback.
- \subsection p2p_sd_response Replying to service discovery queries from peers
- The received service discovery requests will be indicated with the
- \ref p2p_config::sd_request() callback. The response to the query is sent
- by calling \ref p2p_sd_response().
- \subsection p2p_sd_indicator Service update indicator
- P2P service discovery provides a mechanism to notify peers about
- changes in available services. This works by incrementing Service
- Update Indicator value whenever there is a change in the
- services. This value is included in all SD request and response
- frames. The value received from the peers will be included in the
- \ref p2p_config::sd_request() and \ref p2p_config::sd_response() callbacks. The
- value to be sent to the peers is incremented with a call to
- \ref p2p_sd_service_update() whenever availability of the local services
- changes.
- \section p2p_go P2P group owner
- This section describes how P2P module can be used for managing
- per-group information in a group owner. The function calls are
- described based on the P2P module API. The exact design for the glue
- code outside the P2P module depends on the architecture used in the
- system.
- When a P2P group interface is created in group owner role, per-group
- data is initialized with \ref p2p_group_init(). This call provides a
- pointer to the per-device P2P module context and configures the
- per-group operation. The configured \ref p2p_group_config::ie_update()
- callback is used to set the initial P2P IE for Beacon and Probe
- Response frames in the group owner. The AP mode implementation may use
- this information to add IEs into the frames.
- Once the group formation has been completed (or if it is skipped in
- case of manual group setup), \ref p2p_group_notif_formation_done() is
- called. This will allow the P2P module to update the P2P IE for
- Beacon and Probe Response frames.
- The SME/MLME code that managements IEEE 802.11 association processing
- needs to inform P2P module whenever a P2P client associates or
- disassociates with the group. This is done by calling
- \ref p2p_group_notif_assoc() and \ref p2p_group_notif_disassoc(). The P2P module
- manages a list of group members and updates the P2P Group Information
- subelement in the P2P IE based on the information from the P2P
- clients. The \ref p2p_group_config::ie_update() callback is used whenever
- the P2P IE in Probe Response frames needs to be changed.
- The SME/MLME code that takes care of replying to Probe Request frames
- can use \ref p2p_group_match_dev_type() to check whether the Probe Request
- frame request a reply only from groups that include a specific device
- type in one of the clients or GO. A match will be reported if the
- Probe Request does not request a specific device type, so this
- function can be used to filter or received Probe Request frames and
- only the ones that result in non-zero return value need to be replied.
- When the P2P group interface for GO role is removed,
- \ref p2p_group_deinit() is used to deinitialize the per-group P2P module
- state.
- \section p2p_ctrl_iface P2P control interface
- wpa_supplicant \ref ctrl_iface_page "control interface" can be used
- to manage P2P functionality from an external program (e.g., a GUI or a
- system configuration manager). This interface can be used directly
- through the control interface backend mechanism (e.g., local domain
- sockets on Linux) or with help of wpa_cli (e.g., from a script).
- The following P2P-related commands are available:
- - \ref ctrl_iface_P2P_FIND P2P_FIND
- - \ref ctrl_iface_P2P_STOP_FIND P2P_STOP_FIND
- - \ref ctrl_iface_P2P_CONNECT P2P_CONNECT
- - \ref ctrl_iface_P2P_LISTEN P2P_LISTEN
- - \ref ctrl_iface_P2P_GROUP_REMOVE P2P_GROUP_REMOVE
- - \ref ctrl_iface_P2P_GROUP_ADD P2P_GROUP_ADD
- - \ref ctrl_iface_P2P_PROV_DISC P2P_PROV_DISC
- - \ref ctrl_iface_P2P_SERV_DISC_REQ P2P_SERV_DISC_REQ
- - \ref ctrl_iface_P2P_SERV_DISC_CANCEL_REQ P2P_SERV_DISC_CANCEL_REQ
- - \ref ctrl_iface_P2P_SERV_DISC_RESP P2P_SERV_DISC_RESP
- - \ref ctrl_iface_P2P_SERVICE_UPDATE P2P_SERVICE_UPDATE
- - \ref ctrl_iface_P2P_SERV_DISC_EXTERNAL P2P_SERV_DISC_EXTERNAL
- - \ref ctrl_iface_P2P_REJECT P2P_REJECT
- - \ref ctrl_iface_P2P_INVITE P2P_INVITE
- The following P2P-related events are used:
- - \ref ctrl_iface_event_P2P_EVENT_DEVICE_FOUND P2P-DEVICE-FOUND
- - \ref ctrl_iface_event_P2P_EVENT_GO_NEG_REQUEST P2P-GO-NEG-REQUEST
- - \ref ctrl_iface_event_P2P_EVENT_GO_NEG_SUCCESS P2P-GO-NEG-SUCCESS
- - \ref ctrl_iface_event_P2P_EVENT_GO_NEG_FAILURE P2P-GO-NEG-FAILURE
- - \ref ctrl_iface_event_P2P_EVENT_GROUP_FORMATION_SUCCESS P2P-GROUP-FORMATION-SUCCESS
- - \ref ctrl_iface_event_P2P_EVENT_GROUP_FORMATION_FAILURE P2P-GROUP-FORMATION-FAILURE
- - \ref ctrl_iface_event_P2P_EVENT_GROUP_STARTED P2P-GROUP-STARTED
- - \ref ctrl_iface_event_P2P_EVENT_GROUP_REMOVED P2P-GROUP-REMOVED
- - \ref ctrl_iface_event_P2P_EVENT_PROV_DISC_SHOW_PIN P2P-PROV-DISC-SHOW-PIN
- - \ref ctrl_iface_event_P2P_EVENT_PROV_DISC_ENTER_PIN P2P-PROV-DISC-ENTER-PIN
- - \ref ctrl_iface_event_P2P_EVENT_SERV_DISC_REQ P2P-SERV-DISC-REQ
- - \ref ctrl_iface_event_P2P_EVENT_SERV_DISC_RESP P2P-SERV-DISC-RESP
- - \ref ctrl_iface_event_P2P_EVENT_INVITATION_RECEIVED P2P-INVITATION-RECEIVED
- - \ref ctrl_iface_event_P2P_EVENT_INVITATION_RESULT P2P-INVITATION-RESULT
- \subsection p2p_wpa_gui GUI example (wpa_gui)
- wpa_gui has an example implementation of a GUI that could be used to
- manage P2P operations. The P2P related functionality is contained
- mostly in wpa_supplicant/wpa_gui-qt4/peers.cpp and it shows how the
- control interface commands and events can be used.
- \subsection p2p_wpa_cli wpa_cli example
- wpa_cli can be used to control wpa_supplicant in interactive
- mode. The following sessions show examples of commands used for
- device discovery and group formation. The lines starting with "> " are
- commands from the user (followed by command result indication) and
- lines starting with "<2>" are event messages from wpa_supplicant.
- P2P device "Wireless Client":
- \verbatim
- > p2p_find
- OK
- > <2>P2P-DEVICE-FOUND 02:40:61:c2:f3:b7 p2p_dev_addr=02:40:61:c2:f3:b7
- pri_dev_type=1-0050F204-1 name='Wireless Client 2' config_methods=0x18c
- dev_capab=0x1 group_capab=0x0
- <2>P2P-GO-NEG-REQUEST 02:40:61:c2:f3:b7
- <2>P2P-GO-NEG-REQUEST 02:40:61:c2:f3:b7
- > p2p_connect 02:40:61:c2:f3:b7 pbc
- OK
- <2>P2P-GO-NEG-SUCCESS
- <2>P2P-GROUP-FORMATION-SUCCESS
- <2>P2P-GROUP-STARTED sta0-p2p-0 client DIRECT-vM
- > interface
- Available interfaces:
- sta0-p2p-0
- sta0
- > p2p_group_remove sta0-p2p-0
- <2>P2P-GROUP-REMOVED sta0-p2p-0 client
- OK
- > term
- OK
- \endverbatim
- P2P device "Wireless Client2" (which ended up operating in GO role):
- \verbatim
- > p2p_find
- OK
- <2>P2P-DEVICE-FOUND 02:f0:bc:44:87:62 p2p_dev_addr=02:f0:bc:44:87:62
- pri_dev_type=1-0050F204-1 name='Wireless Client' config_methods=0x18c
- dev_capab=0x1 group_capab=0x0
- > p2p_connect 02:f0:bc:44:87:62 pbc
- OK
- <2>P2P-GO-NEG-SUCCESS
- <2>P2P-GROUP-FORMATION-SUCCESS
- <2>P2P-GROUP-STARTED sta1-p2p-0 GO DIRECT-vM
- > interface
- Available interfaces:
- sta1-p2p-0
- sta1
- > p2p_group_remove sta1-p2p-0
- <2>P2P-GROUP-REMOVED sta1-p2p-0 GO
- OK
- > term
- OK
- \endverbatim
- */
|