-
Notifications
You must be signed in to change notification settings - Fork 0
Notes on Generic Advertisement Service implementation on Android
-
We are using pre-association service discovery using GAS messages. Application Programming Interface described here: WifiP2pManager Android Documentation. Also look at WifiP2pServiceInfo. We are currently using Bonjour txt records. If we find that it is too inefficient for chatting, we might want to move to our own cozybit-specific service (See SERVICE_TYPE_VENDOR_SPECIFIC).
-
Interesting Android source
-
The code in java that creates service query for TXT records for wpa_supplicant.
-
https://android.googlesource.com/platform/frameworks/base//master/wifi/java/android/net/wifi/p2p/WifiP2pManager.java#L994[The implementation of addLocalService], the function that sends the service query to wpa_supplicant. Note that checkServiceInfo() is not doing any particular syntax checking on the service info object. Look at the +static class Channel::handleMessage() in the Manager to see how wpa_supplicant responses are processed.
-
wpa_supplicant source code is here: git://w1.fi/srv/git/hostap.git. Relevant branches: android-jb and android-kk. Service discovery for FWD is implemented in p2p_sd.c. Entry point p2p_sd_request().
-
-
Service discovery for all_peers requests are not removed by wpa_supplicant once a GAS response is received. Details: a service discovery request is added by p2p_sd_request() to the list of service discovery queries p2p->sd_queries. Once a response is received by p2p_rx_gas_initial_resp(), the service discovery request is removed from the list only if for_all_peers is false.
-
wpa_supplicant just takes a TLV buffer (A sequence of type, length, values, as defined in IEEE 802.11 Std) and puts that on the GAS request. Details: This means we should have no issue defining our own service (at least from wpa_supplicant’s perspective). See p2p_build_sd_query()
-
A service discovery GAS request is sent only by p2p_start_sd(), which is schedule via the P2P_DEV_SD_SCHEDULE flag every time a new peer is discovered see p2p_add_device().
-
There is a configurable parameter discoverable interval (see p2p_set_disc_int()).
-
Ah, p2p_ctrl_service_add() only accepts bonjour or upnp. There is a bonjour/upnp service-specific layer above p2p_sd.c and that is in p2p_supplicant.c. See wpas_p2p_service_* functions.
cmd: P2P_SERVICE_ADD
wpa_supplicant_ctrl_iface_process ()2
-> p2p_ctrl_service_add ()
-> p2p_ctrl_service_add_bonjour () # Note error if cmd is not 'bonjour' or 'upnp'
-> wpas_p2p_service_add_bonjour ()
-> service added to wpa_s->global->p2p_srv_bonjourcmd: P2P_SERV_DISC_REQ (assuming dst = NULL, that is a broadcast service discovery
wpa_supplicant_ctrl_iface_process ()
-> p2p_ctrl_serv_disc_req ()
-> wpas_p2p_sd_request ()
-> p2p_sd_request ()
-> service discovery queries now added to p2p->sd_queries
AND
-> P2P_DEV_SD_INFO is cleared on all known peers.After that happens, either starting service discovery (p2p_start_sd() or p2p_add_peer()) will call
p2p_pending_sd_req ()
-> q->for_all_peers && !(dev->flags & P2P_DEV_SD_INFO)
# returns the pending service discovery requests-
A P2P_SERVICE_UPDATE does not clear the P2P_DEV_SD_INFO flag on peers, therefore it would not trigger new GAS Initial Requests.
-
The lowest wifi java layer before going into JNI/C is https://android.googlesource.com/platform/frameworks/base//master/wifi/java/android/net/wifi/WifiNative.java[WifiNative.java]. Here you find which wpa_commands are sent. Compare with +wpa_supplicant/ctrl_iface.c
-
The best way to accelerate GAS exchanges seems to be:
while (true) {
if (!prev_req)
P2P_SERV_DISC_CANCEL_REQ prev_req
flush peers
prev_req = P2P_SERV_DISC_REQ
sleep X
}An X that is too small will result in SD requests being cancelled before GAS frames are exchanged.
-
Ah! There seems to be a way to send GAS frames immediately via P2P_SERV_DISC_RESP! But Java does not give us a way to call it… (or maybe yes??)