1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 
17 package com.android.server.wifi.p2p;
18 
19 import android.annotation.NonNull;
20 import android.hardware.wifi.supplicant.V1_0.ISupplicantP2pIfaceCallback;
21 import android.hardware.wifi.supplicant.V1_0.WpsConfigMethods;
22 import android.net.MacAddress;
23 import android.net.wifi.WpsInfo;
24 import android.net.wifi.p2p.WifiP2pConfig;
25 import android.net.wifi.p2p.WifiP2pDevice;
26 import android.net.wifi.p2p.WifiP2pGroup;
27 import android.net.wifi.p2p.WifiP2pProvDiscEvent;
28 import android.net.wifi.p2p.WifiP2pWfdInfo;
29 import android.net.wifi.p2p.nsd.WifiP2pServiceResponse;
30 import android.text.TextUtils;
31 import android.util.Log;
32 
33 import com.android.server.wifi.p2p.WifiP2pServiceImpl.P2pStatus;
34 import com.android.server.wifi.util.NativeUtil;
35 
36 import java.util.ArrayList;
37 import java.util.Arrays;
38 import java.util.List;
39 
40 /**
41  * Class used for processing all P2P callbacks for the HIDL implementation.
42  */
43 public class SupplicantP2pIfaceCallbackHidlImpl extends ISupplicantP2pIfaceCallback.Stub {
44     private static final String TAG = "SupplicantP2pIfaceCallbackImpl";
45     private static boolean sVerboseLoggingEnabled = true;
46 
47     private final SupplicantP2pIfaceHalHidlImpl mP2pIfaceHal;
48     private final String mInterface;
49     private final WifiP2pMonitor mMonitor;
50 
SupplicantP2pIfaceCallbackHidlImpl( @onNull SupplicantP2pIfaceHalHidlImpl p2pIfaceHal, @NonNull String iface, @NonNull WifiP2pMonitor monitor)51     public SupplicantP2pIfaceCallbackHidlImpl(
52             @NonNull SupplicantP2pIfaceHalHidlImpl p2pIfaceHal,
53             @NonNull String iface, @NonNull WifiP2pMonitor monitor) {
54         mP2pIfaceHal = p2pIfaceHal;
55         mInterface = iface;
56         mMonitor = monitor;
57     }
58 
59     /**
60      * Enable verbose logging for all sub modules.
61      */
enableVerboseLogging(boolean verboseEnabled, boolean halVerboseEnabled)62     public static void enableVerboseLogging(boolean verboseEnabled, boolean halVerboseEnabled) {
63         sVerboseLoggingEnabled = verboseEnabled;
64     }
65 
logd(String s)66     protected static void logd(String s) {
67         if (sVerboseLoggingEnabled) Log.d(TAG, s, null);
68     }
69 
70     /**
71      * Used to indicate that a new network has been added.
72      *
73      * @param networkId Network ID allocated to the corresponding network.
74      */
onNetworkAdded(int networkId)75     public void onNetworkAdded(int networkId) {
76     }
77 
78 
79     /**
80      * Used to indicate that a network has been removed.
81      *
82      * @param networkId Network ID allocated to the corresponding network.
83      */
onNetworkRemoved(int networkId)84     public void onNetworkRemoved(int networkId) {
85     }
86 
87 
88     /**
89      * Used to indicate that a P2P device has been found.
90      *
91      * @param srcAddress MAC address of the device found. This must either
92      *        be the P2P device address or the P2P interface address.
93      * @param p2pDeviceAddress P2P device address.
94      * @param primaryDeviceType Type of device. Refer to section B.1 of Wifi P2P
95      *        Technical specification v1.2.
96      * @param deviceName Name of the device.
97      * @param configMethods Mask of WPS configuration methods supported by the
98      *        device.
99      * @param deviceCapabilities Refer to section 4.1.4 of Wifi P2P Technical
100      *        specification v1.2.
101      * @param groupCapabilities Refer to section 4.1.4 of Wifi P2P Technical
102      *        specification v1.2.
103      * @param wfdDeviceInfo WFD device info as described in section 5.1.2 of WFD
104      *        technical specification v1.0.0.
105      */
onDeviceFound(byte[] srcAddress, byte[] p2pDeviceAddress, byte[] primaryDeviceType, String deviceName, short configMethods, byte deviceCapabilities, int groupCapabilities, byte[] wfdDeviceInfo)106     public void onDeviceFound(byte[] srcAddress, byte[] p2pDeviceAddress, byte[] primaryDeviceType,
107             String deviceName, short configMethods, byte deviceCapabilities, int groupCapabilities,
108             byte[] wfdDeviceInfo) {
109         WifiP2pDevice device = new WifiP2pDevice();
110         device.deviceName = deviceName;
111         if (deviceName == null) {
112             Log.e(TAG, "Missing device name.");
113             return;
114         }
115 
116         try {
117             device.deviceAddress = NativeUtil.macAddressFromByteArray(p2pDeviceAddress);
118         } catch (Exception e) {
119             Log.e(TAG, "Could not decode device address.", e);
120             return;
121         }
122 
123         try {
124             device.primaryDeviceType = NativeUtil.wpsDevTypeStringFromByteArray(primaryDeviceType);
125         } catch (Exception e) {
126             Log.e(TAG, "Could not encode device primary type.", e);
127             return;
128         }
129 
130         device.deviceCapability = deviceCapabilities;
131         device.groupCapability = groupCapabilities;
132         device.wpsConfigMethodsSupported = configMethods;
133         device.status = WifiP2pDevice.AVAILABLE;
134 
135         if (wfdDeviceInfo != null && wfdDeviceInfo.length >= 6) {
136             device.wfdInfo = new WifiP2pWfdInfo(
137                     ((wfdDeviceInfo[0] & 0xFF) << 8) + (wfdDeviceInfo[1] & 0xFF),
138                     ((wfdDeviceInfo[2] & 0xFF) << 8) + (wfdDeviceInfo[3] & 0xFF),
139                     ((wfdDeviceInfo[4] & 0xFF) << 8) + (wfdDeviceInfo[5] & 0xFF));
140         }
141 
142         logd("Device discovered on " + mInterface + ": " + device);
143         mMonitor.broadcastP2pDeviceFound(mInterface, device);
144     }
145 
146     /**
147      * Used to indicate that a P2P device has been lost.
148      *
149      * @param p2pDeviceAddress P2P device address.
150      */
onDeviceLost(byte[] p2pDeviceAddress)151     public void onDeviceLost(byte[] p2pDeviceAddress) {
152         WifiP2pDevice device = new WifiP2pDevice();
153 
154         try {
155             device.deviceAddress = NativeUtil.macAddressFromByteArray(p2pDeviceAddress);
156         } catch (Exception e) {
157             Log.e(TAG, "Could not decode device address.", e);
158             return;
159         }
160 
161         device.status = WifiP2pDevice.UNAVAILABLE;
162 
163         logd("Device lost on " + mInterface + ": " + device);
164         mMonitor.broadcastP2pDeviceLost(mInterface, device);
165     }
166 
167 
168     /**
169      * Used to indicate the termination of P2P find operation.
170      */
onFindStopped()171     public void onFindStopped() {
172         logd("Search stopped on " + mInterface);
173         mMonitor.broadcastP2pFindStopped(mInterface);
174     }
175 
176 
177     /**
178      * Used to indicate the reception of a P2P Group Owner negotiation request.
179      *
180      * @param srcAddress MAC address of the device that initiated the GO
181      *        negotiation request.
182      * @param passwordId Type of password.
183      */
onGoNegotiationRequest(byte[] srcAddress, short passwordId)184     public void onGoNegotiationRequest(byte[] srcAddress, short passwordId) {
185         WifiP2pConfig config = new WifiP2pConfig();
186 
187         try {
188             config.deviceAddress = NativeUtil.macAddressFromByteArray(srcAddress);
189         } catch (Exception e) {
190             Log.e(TAG, "Could not decode device address.", e);
191             return;
192         }
193 
194         config.wps = new WpsInfo();
195 
196         switch (passwordId) {
197             case WpsDevPasswordId.USER_SPECIFIED:
198                 config.wps.setup = WpsInfo.DISPLAY;
199                 break;
200 
201             case WpsDevPasswordId.PUSHBUTTON:
202                 config.wps.setup = WpsInfo.PBC;
203                 break;
204 
205             case WpsDevPasswordId.REGISTRAR_SPECIFIED:
206                 config.wps.setup = WpsInfo.KEYPAD;
207                 break;
208 
209             default:
210                 config.wps.setup = WpsInfo.PBC;
211                 break;
212         }
213 
214         logd("Group Owner negotiation initiated on " + mInterface + ": " + config);
215         mMonitor.broadcastP2pGoNegotiationRequest(mInterface, config);
216     }
217 
218 
219     /**
220      * Used to indicate the completion of a P2P Group Owner negotiation request.
221      *
222      * @param status Status of the GO negotiation.
223      */
onGoNegotiationCompleted(int status)224     public void onGoNegotiationCompleted(int status) {
225         logd("Group Owner negotiation completed with status: " + status);
226         P2pStatus result = halStatusToP2pStatus(status);
227 
228         if (result == P2pStatus.SUCCESS) {
229             mMonitor.broadcastP2pGoNegotiationSuccess(mInterface);
230         } else {
231             mMonitor.broadcastP2pGoNegotiationFailure(mInterface, result);
232         }
233     }
234 
235 
236     /**
237      * Used to indicate a successful formation of a P2P group.
238      */
onGroupFormationSuccess()239     public void onGroupFormationSuccess() {
240         logd("Group formation successful on " + mInterface);
241         mMonitor.broadcastP2pGroupFormationSuccess(mInterface);
242     }
243 
244 
245     /**
246      * Used to indicate a failure to form a P2P group.
247      *
248      * @param failureReason Failure reason string for debug purposes.
249      */
onGroupFormationFailure(String failureReason)250     public void onGroupFormationFailure(String failureReason) {
251         // TODO(ender): failureReason should probably be an int (P2pStatusCode).
252         logd("Group formation failed on " + mInterface + ": " + failureReason);
253         mMonitor.broadcastP2pGroupFormationFailure(mInterface, failureReason);
254     }
255 
256 
257     /**
258      * Used to indicate the start of a P2P group.
259      *
260      * @param groupIfName Interface name of the group. (For ex: p2p-p2p0-1)
261      * @param isGo Whether this device is owner of the group.
262      * @param ssid SSID of the group.
263      * @param frequency Frequency on which this group is created.
264      * @param psk PSK used to secure the group.
265      * @param passphrase PSK passphrase used to secure the group.
266      * @param goDeviceAddress MAC Address of the owner of this group.
267      * @param isPersistent Whether this group is persisted or not.
268      */
onGroupStarted(String groupIfName, boolean isGo, ArrayList<Byte> ssid, int frequency, byte[] psk, String passphrase, byte[] goDeviceAddress, boolean isPersistent)269     public void onGroupStarted(String groupIfName, boolean isGo, ArrayList<Byte> ssid,
270             int frequency, byte[] psk, String passphrase, byte[] goDeviceAddress,
271             boolean isPersistent) {
272         if (groupIfName == null) {
273             Log.e(TAG, "Missing group interface name.");
274             return;
275         }
276 
277         logd("Group " + groupIfName + " started on " + mInterface);
278 
279         WifiP2pGroup group = new WifiP2pGroup();
280         group.setInterface(groupIfName);
281 
282         try {
283             String quotedSsid = NativeUtil.encodeSsid(ssid);
284             group.setNetworkName(NativeUtil.removeEnclosingQuotes(quotedSsid));
285         } catch (Exception e) {
286             Log.e(TAG, "Could not encode SSID.", e);
287             return;
288         }
289 
290         group.setFrequency(frequency);
291         group.setIsGroupOwner(isGo);
292         group.setPassphrase(passphrase);
293 
294         if (isPersistent) {
295             group.setNetworkId(WifiP2pGroup.NETWORK_ID_PERSISTENT);
296         } else {
297             group.setNetworkId(WifiP2pGroup.NETWORK_ID_TEMPORARY);
298         }
299 
300         WifiP2pDevice owner = new WifiP2pDevice();
301 
302         try {
303             owner.deviceAddress = NativeUtil.macAddressFromByteArray(goDeviceAddress);
304         } catch (Exception e) {
305             Log.e(TAG, "Could not decode Group Owner address.", e);
306             return;
307         }
308 
309         group.setOwner(owner);
310         mMonitor.broadcastP2pGroupStarted(mInterface, group);
311     }
312 
313 
314     /**
315      * Used to indicate the removal of a P2P group.
316      *
317      * @param groupIfName Interface name of the group. (For ex: p2p-p2p0-1)
318      * @param isGo Whether this device is owner of the group.
319      */
onGroupRemoved(String groupIfName, boolean isGo)320     public void onGroupRemoved(String groupIfName, boolean isGo) {
321         if (groupIfName == null) {
322             Log.e(TAG, "Missing group name.");
323             return;
324         }
325 
326         logd("Group " + groupIfName + " removed from " + mInterface);
327         WifiP2pGroup group = new WifiP2pGroup();
328         group.setInterface(groupIfName);
329         group.setIsGroupOwner(isGo);
330         mMonitor.broadcastP2pGroupRemoved(mInterface, group);
331     }
332 
333 
334     /**
335      * Used to indicate the reception of a P2P invitation.
336      *
337      * @param srcAddress MAC address of the device that sent the invitation.
338      * @param goDeviceAddress MAC Address of the owner of this group.
339      * @param bssid Bssid of the group.
340      * @param persistentNetworkId Persistent network Id of the group.
341      * @param operatingFrequency Frequency on which the invitation was received.
342      */
onInvitationReceived(byte[] srcAddress, byte[] goDeviceAddress, byte[] bssid, int persistentNetworkId, int operatingFrequency)343     public void onInvitationReceived(byte[] srcAddress, byte[] goDeviceAddress,
344             byte[] bssid, int persistentNetworkId, int operatingFrequency) {
345         WifiP2pGroup group = new WifiP2pGroup();
346         group.setNetworkId(persistentNetworkId);
347 
348         WifiP2pDevice client = new WifiP2pDevice();
349 
350         try {
351             client.deviceAddress = NativeUtil.macAddressFromByteArray(srcAddress);
352         } catch (Exception e) {
353             Log.e(TAG, "Could not decode MAC address.", e);
354             return;
355         }
356 
357         group.addClient(client);
358 
359         WifiP2pDevice owner = new WifiP2pDevice();
360 
361         try {
362             owner.deviceAddress = NativeUtil.macAddressFromByteArray(goDeviceAddress);
363         } catch (Exception e) {
364             Log.e(TAG, "Could not decode Group Owner MAC address.", e);
365             return;
366         }
367 
368         group.setOwner(owner);
369 
370         logd("Invitation received on " + mInterface + ": " + group);
371         mMonitor.broadcastP2pInvitationReceived(mInterface, group);
372     }
373 
374 
375     /**
376      * Used to indicate the result of the P2P invitation request.
377      *
378      * @param bssid Bssid of the group.
379      * @param status Status of the invitation.
380      */
onInvitationResult(byte[] bssid, int status)381     public void onInvitationResult(byte[] bssid, int status) {
382         logd("Invitation completed with status: " + status);
383         mMonitor.broadcastP2pInvitationResult(mInterface, halStatusToP2pStatus(status));
384     }
385 
convertHalProvDiscStatusToFrameworkStatus( int status)386     private @WifiP2pMonitor.P2pProvDiscStatus int convertHalProvDiscStatusToFrameworkStatus(
387             int status) {
388         switch (status) {
389             case ISupplicantP2pIfaceCallback.P2pProvDiscStatusCode.SUCCESS:
390                 return WifiP2pMonitor.PROV_DISC_STATUS_SUCCESS;
391             case ISupplicantP2pIfaceCallback.P2pProvDiscStatusCode.TIMEOUT:
392                 return WifiP2pMonitor.PROV_DISC_STATUS_TIMEOUT;
393             case ISupplicantP2pIfaceCallback.P2pProvDiscStatusCode.REJECTED:
394                 return WifiP2pMonitor.PROV_DISC_STATUS_REJECTED;
395             case ISupplicantP2pIfaceCallback.P2pProvDiscStatusCode.TIMEOUT_JOIN:
396                 return WifiP2pMonitor.PROV_DISC_STATUS_TIMEOUT_JOIN;
397             case ISupplicantP2pIfaceCallback.P2pProvDiscStatusCode.INFO_UNAVAILABLE:
398                 return WifiP2pMonitor.PROV_DISC_STATUS_INFO_UNAVAILABLE;
399             default:
400                 return WifiP2pMonitor.PROV_DISC_STATUS_UNKNOWN;
401         }
402     }
403 
404     /**
405      * Used to indicate the completion of a P2P provision discovery request.
406      *
407      * @param p2pDeviceAddress P2P device address.
408      * @param isRequest Whether we received or sent the provision discovery.
409      * @param status Status of the provision discovery (SupplicantStatusCode).
410      * @param configMethods Mask of WPS configuration methods supported.
411      *                      Only one configMethod bit should be set per call.
412      * @param generatedPin 8 digit pin generated.
413      */
onProvisionDiscoveryCompleted(byte[] p2pDeviceAddress, boolean isRequest, byte status, short configMethods, String generatedPin)414     public void onProvisionDiscoveryCompleted(byte[] p2pDeviceAddress, boolean isRequest,
415             byte status, short configMethods, String generatedPin) {
416         logd("Provision discovery " + (isRequest ? "request" : "response")
417                 + " for WPS Config method: " + configMethods
418                 + " status: " + status);
419 
420         WifiP2pProvDiscEvent event = new WifiP2pProvDiscEvent();
421         event.device = new WifiP2pDevice();
422 
423         try {
424             event.device.deviceAddress = NativeUtil.macAddressFromByteArray(p2pDeviceAddress);
425         } catch (Exception e) {
426             Log.e(TAG, "Could not decode MAC address.", e);
427             event.device.deviceAddress = null;
428         }
429 
430         if (status != ISupplicantP2pIfaceCallback.P2pProvDiscStatusCode.SUCCESS) {
431             Log.e(TAG, "Provision discovery failed, status code: " + status);
432             mMonitor.broadcastP2pProvisionDiscoveryFailure(mInterface,
433                     convertHalProvDiscStatusToFrameworkStatus(status), event);
434             return;
435         }
436 
437         if (TextUtils.isEmpty(event.device.deviceAddress)) return;
438 
439         if ((configMethods & WpsConfigMethods.PUSHBUTTON) != 0) {
440             if (isRequest) {
441                 event.event = WifiP2pProvDiscEvent.PBC_REQ;
442                 mMonitor.broadcastP2pProvisionDiscoveryPbcRequest(mInterface, event);
443             } else {
444                 event.event = WifiP2pProvDiscEvent.PBC_RSP;
445                 mMonitor.broadcastP2pProvisionDiscoveryPbcResponse(mInterface, event);
446             }
447         } else if (!isRequest && (configMethods & WpsConfigMethods.KEYPAD) != 0) {
448             event.event = WifiP2pProvDiscEvent.SHOW_PIN;
449             event.pin = generatedPin;
450             mMonitor.broadcastP2pProvisionDiscoveryShowPin(mInterface, event);
451         } else if (!isRequest && (configMethods & WpsConfigMethods.DISPLAY) != 0) {
452             event.event = WifiP2pProvDiscEvent.ENTER_PIN;
453             event.pin = generatedPin;
454             mMonitor.broadcastP2pProvisionDiscoveryEnterPin(mInterface, event);
455         } else if (isRequest && (configMethods & WpsConfigMethods.DISPLAY) != 0) {
456             event.event = WifiP2pProvDiscEvent.SHOW_PIN;
457             event.pin = generatedPin;
458             mMonitor.broadcastP2pProvisionDiscoveryShowPin(mInterface, event);
459         } else if (isRequest && (configMethods & WpsConfigMethods.KEYPAD) != 0) {
460             event.event = WifiP2pProvDiscEvent.ENTER_PIN;
461             mMonitor.broadcastP2pProvisionDiscoveryEnterPin(mInterface, event);
462         } else {
463             Log.e(TAG, "Unsupported config methods: " + configMethods);
464         }
465     }
466 
467 
468     /**
469      * Used to indicate the reception of a P2P service discovery response.
470      *
471      * @param srcAddress MAC address of the device that sent the service discovery.
472      * @param updateIndicator Service update indicator. Refer to section 3.1.3 of
473      *        Wifi P2P Technical specification v1.2.
474      * @param tlvs Refer to section 3.1.3.1 of Wifi P2P Technical specification v1.2.
475      */
onServiceDiscoveryResponse(byte[] srcAddress, short updateIndicator, ArrayList<Byte> tlvs)476     public void onServiceDiscoveryResponse(byte[] srcAddress, short updateIndicator,
477             ArrayList<Byte> tlvs) {
478         List<WifiP2pServiceResponse> response = null;
479 
480         logd("Service discovery response received on " + mInterface);
481         try {
482             String srcAddressStr = NativeUtil.macAddressFromByteArray(srcAddress);
483             // updateIndicator is not used
484             response = WifiP2pServiceResponse.newInstance(srcAddressStr,
485                     NativeUtil.byteArrayFromArrayList(tlvs));
486         } catch (Exception e) {
487             Log.e(TAG, "Could not process service discovery response.", e);
488             return;
489         }
490         mMonitor.broadcastP2pServiceDiscoveryResponse(mInterface, response);
491     }
492 
createStaEventDevice(byte[] interfaceAddress, byte[] p2pDeviceAddress)493     private WifiP2pDevice createStaEventDevice(byte[] interfaceAddress, byte[] p2pDeviceAddress) {
494         WifiP2pDevice device = new WifiP2pDevice();
495         byte[] deviceAddressBytes;
496         // Legacy STAs may not supply a p2pDeviceAddress (signaled by a zero'd p2pDeviceAddress)
497         // In this case, use interfaceAddress instead
498         if (!Arrays.equals(NativeUtil.ANY_MAC_BYTES, p2pDeviceAddress)) {
499             deviceAddressBytes = p2pDeviceAddress;
500         } else {
501             deviceAddressBytes = interfaceAddress;
502         }
503         try {
504             device.deviceAddress = NativeUtil.macAddressFromByteArray(deviceAddressBytes);
505             device.setInterfaceMacAddress(MacAddress.fromBytes(interfaceAddress));
506         } catch (Exception e) {
507             Log.e(TAG, "Could not decode MAC address", e);
508             return null;
509         }
510         return device;
511     }
512 
513     /**
514      * Used to indicate when a STA device is connected to this device.
515      *
516      * @param srcAddress MAC address of the device that was authorized.
517      * @param p2pDeviceAddress P2P device address.
518      */
onStaAuthorized(byte[] srcAddress, byte[] p2pDeviceAddress)519     public void onStaAuthorized(byte[] srcAddress, byte[] p2pDeviceAddress) {
520         logd("STA authorized on " + mInterface);
521         WifiP2pDevice device = createStaEventDevice(srcAddress, p2pDeviceAddress);
522         if (device == null) {
523             return;
524         }
525         mMonitor.broadcastP2pApStaConnected(mInterface, device);
526     }
527 
528 
529     /**
530      * Used to indicate when a STA device is disconnected from this device.
531      *
532      * @param srcAddress MAC address of the device that was deauthorized.
533      * @param p2pDeviceAddress P2P device address.
534      */
onStaDeauthorized(byte[] srcAddress, byte[] p2pDeviceAddress)535     public void onStaDeauthorized(byte[] srcAddress, byte[] p2pDeviceAddress) {
536         logd("STA deauthorized on " + mInterface);
537         WifiP2pDevice device = createStaEventDevice(srcAddress, p2pDeviceAddress);
538         if (device == null) {
539             return;
540         }
541         mMonitor.broadcastP2pApStaDisconnected(mInterface, device);
542     }
543 
544 
halStatusToP2pStatus(int status)545     private static P2pStatus halStatusToP2pStatus(int status) {
546         P2pStatus result = P2pStatus.UNKNOWN;
547 
548         switch (status) {
549             case P2pStatusCode.SUCCESS:
550             case P2pStatusCode.SUCCESS_DEFERRED:
551                 result = P2pStatus.SUCCESS;
552                 break;
553 
554             case P2pStatusCode.FAIL_INFO_CURRENTLY_UNAVAILABLE:
555                 result = P2pStatus.INFORMATION_IS_CURRENTLY_UNAVAILABLE;
556                 break;
557 
558             case P2pStatusCode.FAIL_INCOMPATIBLE_PARAMS:
559                 result = P2pStatus.INCOMPATIBLE_PARAMETERS;
560                 break;
561 
562             case P2pStatusCode.FAIL_LIMIT_REACHED:
563                 result = P2pStatus.LIMIT_REACHED;
564                 break;
565 
566             case P2pStatusCode.FAIL_INVALID_PARAMS:
567                 result = P2pStatus.INVALID_PARAMETER;
568                 break;
569 
570             case P2pStatusCode.FAIL_UNABLE_TO_ACCOMMODATE:
571                 result = P2pStatus.UNABLE_TO_ACCOMMODATE_REQUEST;
572                 break;
573 
574             case P2pStatusCode.FAIL_PREV_PROTOCOL_ERROR:
575                 result = P2pStatus.PREVIOUS_PROTOCOL_ERROR;
576                 break;
577 
578             case P2pStatusCode.FAIL_NO_COMMON_CHANNELS:
579                 result = P2pStatus.NO_COMMON_CHANNEL;
580                 break;
581 
582             case P2pStatusCode.FAIL_UNKNOWN_GROUP:
583                 result = P2pStatus.UNKNOWN_P2P_GROUP;
584                 break;
585 
586             case P2pStatusCode.FAIL_BOTH_GO_INTENT_15:
587                 result = P2pStatus.BOTH_GO_INTENT_15;
588                 break;
589 
590             case P2pStatusCode.FAIL_INCOMPATIBLE_PROV_METHOD:
591                 result = P2pStatus.INCOMPATIBLE_PROVISIONING_METHOD;
592                 break;
593 
594             case P2pStatusCode.FAIL_REJECTED_BY_USER:
595                 result = P2pStatus.REJECTED_BY_USER;
596                 break;
597         }
598         return result;
599     }
600 }
601 
602