From experience, in a real-world deployment of an Android Wi-Fi Direct application, 20 devices should not be an issue.
Theoretically, the maximum number of devices in a Wi-Fi P2P group, where the GO is an Android device, is 254. The group owner is assigned the IP, 192.168.49.1. Clients are assigned an IP from the range, 192.168.49.2 to 192.168.49.254.
The group owner address is defined by the following in WifiP2pServiceImpl.java
:
/* Is chosen as a unique address to avoid conflict with
the ranges defined in Tethering.java */
private static final String SERVER_ADDRESS = "192.168.49.1";
Determining the range for the clients is done as follows:
In WifiP2pServiceImpl.java
, the startDhcpServer(String intf)
method will start the DHCP server for a given interface - not a surprise. This method is called when the group has started and the device is the group owner.
Taking a closer look at this code, we can see that on the InterfaceConfiguration object, the link address is set to 192.168.49.1 and the prefix length is 24 (prefix length is the number of bits set in a subnet mask, here equivalent to 255.255.255.0) - this implies the answer, but we can dig a little further.
ifcg = mNwService.getInterfaceConfig(intf);
ifcg.setLinkAddress(new LinkAddress(NetworkUtils.numericToInetAddress(
SERVER_ADDRESS), 24));
ifcg.setInterfaceUp();
mNwService.setInterfaceConfig(intf, ifcg);
Next, the following commands will restart tethering with the DHCP range specified by the String[], tetheringDhcpRanges
. The calls of mNwService (Network Management Service) methods will execute the appropriate netd commands.
ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(
Context.CONNECTIVITY_SERVICE);
String[] tetheringDhcpRanges = cm.getTetheredDhcpRanges();
if (mNwService.isTetheringStarted()) {
if (DBG) logd("Stop existing tethering and restart it");
mNwService.stopTethering();
}
mNwService.tetherInterface(intf);
mNwService.startTethering(tetheringDhcpRanges);
And cm.getTetheredDhcpRanges()
is ultimately a reference to the following (ConnectivityManager.getTetheredDhcpRanges() -> ConnectivityService.getTetheredDhcpRanges() -> Tethering.getTetheredDhcpRanges()):
// USB is 192.168.42.1 and 255.255.255.0
// Wifi is 192.168.43.1 and 255.255.255.0
// BT is limited to max default of 5 connections. 192.168.44.1 to 192.168.48.1
// with 255.255.255.0
// P2P is 192.168.49.1 and 255.255.255.0
private String[] mDhcpRange;
private static final String[] DHCP_DEFAULT_RANGE = {
"192.168.42.2", "192.168.42.254", "192.168.43.2", "192.168.43.254",
"192.168.44.2", "192.168.44.254", "192.168.45.2", "192.168.45.254",
"192.168.46.2", "192.168.46.254", "192.168.47.2", "192.168.47.254",
"192.168.48.2", "192.168.48.254", "192.168.49.2", "192.168.49.254",
}
and:
mDhcpRange = context.getResources().getStringArray(
com.android.internal.R.array.config_tether_dhcp_range);
if ((mDhcpRange.length == 0) || (mDhcpRange.length % 2 ==1)) {
mDhcpRange = DHCP_DEFAULT_RANGE;
}
in com.android.server.connectivity.Tethering
.
Of course, it is possible for the device manufacturer to change this code, so this is also worth considering.
For those planning to deploy applications where there will be many users, a mechanism to allow a more than one device to be GO is required. If data needs to be synchronised between devices, it is simple to simulate "churn" and have GOs only be a GO for a time period before becoming a client to another GO and synchronising any data.