2 * Copyright (C) 2011 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package android.net.wifi.p2p;
19 import android.os.Parcelable;
20 import android.os.Parcel;
22 import java.util.ArrayList;
23 import java.util.List;
24 import java.util.Collection;
25 import java.util.Collections;
26 import java.util.regex.Pattern;
27 import java.util.regex.Matcher;
30 * A class representing a Wi-Fi P2p group. A p2p group consists of a single group
31 * owner and one or more clients. In the case of a group with only two devices, one
32 * will be the group owner and the other will be a group client.
34 * {@see WifiP2pManager}
36 public class WifiP2pGroup implements Parcelable {
38 /** The temporary network id.
40 public static final int TEMPORARY_NET_ID = -1;
42 /** The persistent network id.
43 * If a matching persistent profile is found, use it.
44 * Otherwise, create a new persistent profile.
46 public static final int PERSISTENT_NET_ID = -2;
48 /** The network name */
49 private String mNetworkName;
52 private WifiP2pDevice mOwner;
54 /** Device is group owner */
55 private boolean mIsGroupOwner;
58 private List<WifiP2pDevice> mClients = new ArrayList<WifiP2pDevice>();
60 /** The passphrase used for WPA2-PSK */
61 private String mPassphrase;
63 private String mInterface;
65 /** The network id in the wpa_supplicant */
68 /** P2P group started string pattern */
69 private static final Pattern groupStartedPattern = Pattern.compile(
72 "(?:psk=)?([0-9a-fA-F]{64})?" +
73 "(?:passphrase=)?(?:\"(.{0,63})\")? " +
74 "go_dev_addr=((?:[0-9a-f]{2}:){5}[0-9a-f]{2})" +
75 " ?(\\[PERSISTENT\\])?"
78 public WifiP2pGroup() {
82 * @param supplicantEvent formats supported include
84 * P2P-GROUP-STARTED p2p-wlan0-0 [client|GO] ssid="DIRECT-W8" freq=2437
85 * [psk=2182b2e50e53f260d04f3c7b25ef33c965a3291b9b36b455a82d77fd82ca15bc|
86 * passphrase="fKG4jMe3"] go_dev_addr=fa:7b:7a:42:02:13 [PERSISTENT]
88 * P2P-GROUP-REMOVED p2p-wlan0-0 [client|GO] reason=REQUESTED
90 * P2P-INVITATION-RECEIVED sa=fa:7b:7a:42:02:13 go_dev_addr=f8:7b:7a:42:02:13
91 * bssid=fa:7b:7a:42:82:13 unknown-network
93 * P2P-INVITATION-RECEIVED sa=b8:f9:34:2a:c7:9d persistent=0
95 * Note: The events formats can be looked up in the wpa_supplicant code
98 public WifiP2pGroup(String supplicantEvent) throws IllegalArgumentException {
100 String[] tokens = supplicantEvent.split(" ");
102 if (tokens.length < 3) {
103 throw new IllegalArgumentException("Malformed supplicant event");
106 if (tokens[0].startsWith("P2P-GROUP")) {
107 mInterface = tokens[1];
108 mIsGroupOwner = tokens[2].equals("GO");
110 Matcher match = groupStartedPattern.matcher(supplicantEvent);
115 mNetworkName = match.group(1);
116 //freq and psk are unused right now
117 //int freq = Integer.parseInt(match.group(2));
118 //String psk = match.group(3);
119 mPassphrase = match.group(4);
120 mOwner = new WifiP2pDevice(match.group(5));
121 if (match.group(6) != null) {
122 mNetId = PERSISTENT_NET_ID;
124 mNetId = TEMPORARY_NET_ID;
126 } else if (tokens[0].equals("P2P-INVITATION-RECEIVED")) {
128 mNetId = PERSISTENT_NET_ID;
129 for (String token : tokens) {
130 String[] nameValue = token.split("=");
131 if (nameValue.length != 2) continue;
133 if (nameValue[0].equals("sa")) {
136 // set source address into the client list.
137 WifiP2pDevice dev = new WifiP2pDevice();
138 dev.deviceAddress = nameValue[1];
143 if (nameValue[0].equals("go_dev_addr")) {
144 mOwner = new WifiP2pDevice(nameValue[1]);
148 if (nameValue[0].equals("persistent")) {
149 mNetId = Integer.parseInt(nameValue[1]);
154 throw new IllegalArgumentException("Malformed supplicant event");
159 public void setNetworkName(String networkName) {
160 mNetworkName = networkName;
164 * Get the network name (SSID) of the group. Legacy Wi-Fi clients will discover
165 * the p2p group using the network name.
167 public String getNetworkName() {
172 public void setIsGroupOwner(boolean isGo) {
173 mIsGroupOwner = isGo;
176 /** Check whether this device is the group owner of the created p2p group */
177 public boolean isGroupOwner() {
178 return mIsGroupOwner;
182 public void setOwner(WifiP2pDevice device) {
186 /** Get the details of the group owner as a {@link WifiP2pDevice} object */
187 public WifiP2pDevice getOwner() {
192 public void addClient(String address) {
193 addClient(new WifiP2pDevice(address));
197 public void addClient(WifiP2pDevice device) {
198 for (WifiP2pDevice client : mClients) {
199 if (client.equals(device)) return;
201 mClients.add(device);
205 public boolean removeClient(String address) {
206 return mClients.remove(new WifiP2pDevice(address));
210 public boolean removeClient(WifiP2pDevice device) {
211 return mClients.remove(device);
215 public boolean isClientListEmpty() {
216 return mClients.size() == 0;
219 /** @hide Returns {@code true} if the device is part of the group */
220 public boolean contains(WifiP2pDevice device) {
221 if (mOwner.equals(device) || mClients.contains(device)) return true;
225 /** Get the list of clients currently part of the p2p group */
226 public Collection<WifiP2pDevice> getClientList() {
227 return Collections.unmodifiableCollection(mClients);
231 public void setPassphrase(String passphrase) {
232 mPassphrase = passphrase;
236 * Get the passphrase of the group. This function will return a valid passphrase only
237 * at the group owner. Legacy Wi-Fi clients will need this passphrase alongside
238 * network name obtained from {@link #getNetworkName()} to join the group
240 public String getPassphrase() {
245 public void setInterface(String intf) {
249 /** Get the interface name on which the group is created */
250 public String getInterface() {
255 public int getNetworkId() {
260 public void setNetworkId(int netId) {
264 public String toString() {
265 StringBuffer sbuf = new StringBuffer();
266 sbuf.append("network: ").append(mNetworkName);
267 sbuf.append("\n isGO: ").append(mIsGroupOwner);
268 sbuf.append("\n GO: ").append(mOwner);
269 for (WifiP2pDevice client : mClients) {
270 sbuf.append("\n Client: ").append(client);
272 sbuf.append("\n interface: ").append(mInterface);
273 sbuf.append("\n networkId: ").append(mNetId);
274 return sbuf.toString();
277 /** Implement the Parcelable interface */
278 public int describeContents() {
282 /** copy constructor */
283 public WifiP2pGroup(WifiP2pGroup source) {
284 if (source != null) {
285 mNetworkName = source.getNetworkName();
286 mOwner = new WifiP2pDevice(source.getOwner());
287 mIsGroupOwner = source.mIsGroupOwner;
288 for (WifiP2pDevice d : source.getClientList()) mClients.add(d);
289 mPassphrase = source.getPassphrase();
290 mInterface = source.getInterface();
291 mNetId = source.getNetworkId();
295 /** Implement the Parcelable interface */
296 public void writeToParcel(Parcel dest, int flags) {
297 dest.writeString(mNetworkName);
298 dest.writeParcelable(mOwner, flags);
299 dest.writeByte(mIsGroupOwner ? (byte) 1: (byte) 0);
300 dest.writeInt(mClients.size());
301 for (WifiP2pDevice client : mClients) {
302 dest.writeParcelable(client, flags);
304 dest.writeString(mPassphrase);
305 dest.writeString(mInterface);
306 dest.writeInt(mNetId);
309 /** Implement the Parcelable interface */
310 public static final Creator<WifiP2pGroup> CREATOR =
311 new Creator<WifiP2pGroup>() {
312 public WifiP2pGroup createFromParcel(Parcel in) {
313 WifiP2pGroup group = new WifiP2pGroup();
314 group.setNetworkName(in.readString());
315 group.setOwner((WifiP2pDevice)in.readParcelable(null));
316 group.setIsGroupOwner(in.readByte() == (byte)1);
317 int clientCount = in.readInt();
318 for (int i=0; i<clientCount; i++) {
319 group.addClient((WifiP2pDevice) in.readParcelable(null));
321 group.setPassphrase(in.readString());
322 group.setInterface(in.readString());
323 group.setNetworkId(in.readInt());
327 public WifiP2pGroup[] newArray(int size) {
328 return new WifiP2pGroup[size];