| /* |
| * Copyright (C) 2022 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.server.wifi.hal; |
| |
| import static com.android.server.wifi.aware.WifiAwareStateManager.NAN_BOOTSTRAPPING_ACCEPT; |
| import static com.android.server.wifi.aware.WifiAwareStateManager.NAN_BOOTSTRAPPING_COMEBACK; |
| import static com.android.server.wifi.aware.WifiAwareStateManager.NAN_BOOTSTRAPPING_REJECT; |
| import static com.android.server.wifi.aware.WifiAwareStateManager.NAN_PAIRING_AKM_PASN; |
| import static com.android.server.wifi.aware.WifiAwareStateManager.NAN_PAIRING_AKM_SAE; |
| import static com.android.server.wifi.aware.WifiAwareStateManager.NAN_PAIRING_REQUEST_TYPE_SETUP; |
| import static com.android.server.wifi.aware.WifiAwareStateManager.NAN_PAIRING_REQUEST_TYPE_VERIFICATION; |
| |
| import android.hardware.wifi.IWifiNanIfaceEventCallback; |
| import android.hardware.wifi.NanBootstrappingConfirmInd; |
| import android.hardware.wifi.NanBootstrappingMethod; |
| import android.hardware.wifi.NanBootstrappingRequestInd; |
| import android.hardware.wifi.NanBootstrappingResponseCode; |
| import android.hardware.wifi.NanCapabilities; |
| import android.hardware.wifi.NanCipherSuiteType; |
| import android.hardware.wifi.NanClusterEventInd; |
| import android.hardware.wifi.NanDataPathChannelInfo; |
| import android.hardware.wifi.NanDataPathConfirmInd; |
| import android.hardware.wifi.NanDataPathRequestInd; |
| import android.hardware.wifi.NanDataPathScheduleUpdateInd; |
| import android.hardware.wifi.NanFollowupReceivedInd; |
| import android.hardware.wifi.NanMatchInd; |
| import android.hardware.wifi.NanPairingAkm; |
| import android.hardware.wifi.NanPairingConfig; |
| import android.hardware.wifi.NanPairingConfirmInd; |
| import android.hardware.wifi.NanPairingRequestInd; |
| import android.hardware.wifi.NanPairingRequestType; |
| import android.hardware.wifi.NanStatus; |
| import android.hardware.wifi.NanStatusCode; |
| import android.hardware.wifi.NanSuspensionModeChangeInd; |
| import android.hardware.wifi.NpkSecurityAssociation; |
| import android.hardware.wifi.WifiChannelWidthInMhz; |
| import android.net.MacAddress; |
| import android.net.wifi.ScanResult; |
| import android.net.wifi.WifiAnnotations; |
| import android.net.wifi.aware.AwarePairingConfig; |
| import android.net.wifi.aware.Characteristics; |
| import android.net.wifi.aware.WifiAwareChannelInfo; |
| import android.net.wifi.util.HexEncoding; |
| import android.util.Log; |
| |
| import com.android.server.wifi.aware.Capabilities; |
| import com.android.server.wifi.aware.PairingConfigManager.PairingSecurityAssociationInfo; |
| import com.android.server.wifi.hal.WifiNanIface.NanClusterEventType; |
| import com.android.server.wifi.hal.WifiNanIface.NanRangingIndication; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.List; |
| |
| /** |
| * Callback registered with the Vendor HAL service. On events, converts arguments |
| * to their framework equivalents and calls the registered framework callback. |
| */ |
| public class WifiNanIfaceCallbackAidlImpl extends IWifiNanIfaceEventCallback.Stub { |
| private static final String TAG = "WifiNanIfaceCallbackAidlImpl"; |
| |
| private boolean mVerboseLoggingEnabled; |
| private final WifiNanIfaceAidlImpl mWifiNanIface; |
| |
| public WifiNanIfaceCallbackAidlImpl(WifiNanIfaceAidlImpl wifiNanIface) { |
| mWifiNanIface = wifiNanIface; |
| } |
| |
| /** |
| * Enable verbose logging. |
| */ |
| public void enableVerboseLogging(boolean verbose) { |
| mVerboseLoggingEnabled = verbose; |
| } |
| |
| @Override |
| public void notifyCapabilitiesResponse(char id, NanStatus status, |
| NanCapabilities capabilities) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "notifyCapabilitiesResponse: id=" + id + ", status=" |
| + statusString(status) + ", capabilities=" + capabilities); |
| } |
| |
| if (status.status == NanStatusCode.SUCCESS) { |
| Capabilities frameworkCapabilities = toFrameworkCapability(capabilities); |
| mWifiNanIface.getFrameworkCallback().notifyCapabilitiesResponse( |
| (short) id, frameworkCapabilities); |
| } else { |
| Log.e(TAG, "notifyCapabilitiesResponse: error code=" + status.status + " (" |
| + status.description + ")"); |
| } |
| } |
| |
| @Override |
| public void notifyEnableResponse(char id, NanStatus status) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "notifyEnableResponse: id=" + id + ", status=" + statusString(status)); |
| } |
| |
| if (status.status == NanStatusCode.ALREADY_ENABLED) { |
| Log.wtf(TAG, "notifyEnableResponse: id=" + id + ", already enabled!?"); |
| } |
| mWifiNanIface.getFrameworkCallback().notifyEnableResponse( |
| (short) id, WifiNanIface.NanStatusCode.fromAidl(status.status)); |
| } |
| |
| @Override |
| public void notifyConfigResponse(char id, NanStatus status) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "notifyConfigResponse: id=" + id + ", status=" + statusString(status)); |
| } |
| mWifiNanIface.getFrameworkCallback().notifyConfigResponse( |
| (short) id, WifiNanIface.NanStatusCode.fromAidl(status.status)); |
| } |
| |
| @Override |
| public void notifyDisableResponse(char id, NanStatus status) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "notifyDisableResponse: id=" + id + ", status=" + statusString(status)); |
| } |
| |
| if (status.status != NanStatusCode.SUCCESS) { |
| Log.e(TAG, "notifyDisableResponse: failure - code=" + status.status + " (" |
| + status.description + ")"); |
| } |
| mWifiNanIface.getFrameworkCallback().notifyDisableResponse( |
| (short) id, WifiNanIface.NanStatusCode.fromAidl(status.status)); |
| } |
| |
| @Override |
| public void notifyStartPublishResponse(char id, NanStatus status, byte publishId) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "notifyStartPublishResponse: id=" + id + ", status=" + statusString(status) |
| + ", publishId=" + publishId); |
| } |
| mWifiNanIface.getFrameworkCallback().notifyStartPublishResponse( |
| (short) id, WifiNanIface.NanStatusCode.fromAidl(status.status), publishId); |
| } |
| |
| @Override |
| public void notifyStopPublishResponse(char id, NanStatus status) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "notifyStopPublishResponse: id=" + id + ", status=" + statusString(status)); |
| } |
| |
| if (status.status == NanStatusCode.SUCCESS) { |
| // NOP |
| } else { |
| Log.e(TAG, "notifyStopPublishResponse: failure - code=" + status.status + " (" |
| + status.description + ")"); |
| } |
| } |
| |
| @Override |
| public void notifyStartSubscribeResponse(char id, NanStatus status, byte subscribeId) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "notifyStartSubscribeResponse: id=" + id + ", status=" + statusString(status) |
| + ", subscribeId=" + subscribeId); |
| } |
| mWifiNanIface.getFrameworkCallback().notifyStartSubscribeResponse( |
| (short) id, WifiNanIface.NanStatusCode.fromAidl(status.status), subscribeId); |
| } |
| |
| @Override |
| public void notifyStopSubscribeResponse(char id, NanStatus status) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "notifyStopSubscribeResponse: id=" + id + ", status=" |
| + statusString(status)); |
| } |
| |
| if (status.status == NanStatusCode.SUCCESS) { |
| // NOP |
| } else { |
| Log.e(TAG, "notifyStopSubscribeResponse: failure - code=" + status.status + " (" |
| + status.description + ")"); |
| } |
| } |
| |
| @Override |
| public void notifyTransmitFollowupResponse(char id, NanStatus status) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "notifyTransmitFollowupResponse: id=" + id + ", status=" |
| + statusString(status)); |
| } |
| mWifiNanIface.getFrameworkCallback().notifyTransmitFollowupResponse( |
| (short) id, WifiNanIface.NanStatusCode.fromAidl(status.status)); |
| } |
| |
| @Override |
| public void notifyCreateDataInterfaceResponse(char id, NanStatus status) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "notifyCreateDataInterfaceResponse: id=" + id + ", status=" |
| + statusString(status)); |
| } |
| mWifiNanIface.getFrameworkCallback().notifyCreateDataInterfaceResponse( |
| (short) id, WifiNanIface.NanStatusCode.fromAidl(status.status)); |
| } |
| |
| @Override |
| public void notifyDeleteDataInterfaceResponse(char id, NanStatus status) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "notifyDeleteDataInterfaceResponse: id=" + id + ", status=" |
| + statusString(status)); |
| } |
| mWifiNanIface.getFrameworkCallback().notifyDeleteDataInterfaceResponse( |
| (short) id, WifiNanIface.NanStatusCode.fromAidl(status.status)); |
| } |
| |
| @Override |
| public void notifyInitiateDataPathResponse(char id, NanStatus status, |
| int ndpInstanceId) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "notifyInitiateDataPathResponse: id=" + id + ", status=" |
| + statusString(status) + ", ndpInstanceId=" + ndpInstanceId); |
| } |
| mWifiNanIface.getFrameworkCallback().notifyInitiateDataPathResponse( |
| (short) id, WifiNanIface.NanStatusCode.fromAidl(status.status), ndpInstanceId); |
| } |
| |
| @Override |
| public void notifyRespondToDataPathIndicationResponse(char id, NanStatus status) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "notifyRespondToDataPathIndicationResponse: id=" + id |
| + ", status=" + statusString(status)); |
| } |
| mWifiNanIface.getFrameworkCallback().notifyRespondToDataPathIndicationResponse( |
| (short) id, WifiNanIface.NanStatusCode.fromAidl(status.status)); |
| } |
| |
| @Override |
| public void notifyInitiatePairingResponse(char id, NanStatus status, |
| int pairingInstanceId) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "notifyInitiatePairingResponse: id=" + id |
| + ", status=" + statusString(status)); |
| } |
| mWifiNanIface.getFrameworkCallback().notifyInitiatePairingResponse( |
| (short) id, WifiNanIface.NanStatusCode.fromAidl(status.status), pairingInstanceId); |
| } |
| |
| @Override |
| public void notifyRespondToPairingIndicationResponse(char id, NanStatus status) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "notifyRespondToPairingIndicationResponse: id=" + id |
| + ", status=" + statusString(status)); |
| } |
| mWifiNanIface.getFrameworkCallback().notifyRespondToPairingIndicationResponse( |
| (short) id, WifiNanIface.NanStatusCode.fromAidl(status.status)); |
| } |
| |
| @Override |
| public void notifyInitiateBootstrappingResponse(char id, NanStatus status, |
| int bootstrappingInstanceId) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "notifyInitiateBootstrappingResponse: id=" + id |
| + ", status=" + statusString(status)); |
| } |
| mWifiNanIface.getFrameworkCallback().notifyInitiateBootstrappingResponse( |
| (short) id, WifiNanIface.NanStatusCode.fromAidl(status.status), |
| bootstrappingInstanceId); |
| } |
| |
| @Override |
| public void notifyRespondToBootstrappingIndicationResponse(char id, NanStatus status) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "notifyRespondToBootstrappingIndicationResponse: id=" + id |
| + ", status=" + statusString(status)); |
| } |
| mWifiNanIface.getFrameworkCallback().notifyRespondToBootstrappingIndicationResponse( |
| (short) id, WifiNanIface.NanStatusCode.fromAidl(status.status)); |
| } |
| |
| @Override |
| public void notifyTerminatePairingResponse(char id, NanStatus status) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "notifyTerminatePairingResponse: id=" + id |
| + ", status=" + statusString(status)); |
| } |
| mWifiNanIface.getFrameworkCallback().notifyTerminatePairingResponse( |
| (short) id, WifiNanIface.NanStatusCode.fromAidl(status.status)); |
| } |
| |
| @Override |
| public void notifyTerminateDataPathResponse(char id, NanStatus status) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "notifyTerminateDataPathResponse: id=" + id + ", status=" |
| + statusString(status)); |
| } |
| mWifiNanIface.getFrameworkCallback().notifyTerminateDataPathResponse( |
| (short) id, WifiNanIface.NanStatusCode.fromAidl(status.status)); |
| } |
| |
| @Override |
| public void notifySuspendResponse(char id, NanStatus status) { |
| if (!checkFrameworkCallback()) { |
| return; |
| } |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "notifySuspendResponse: id=" + id + ", status=" |
| + statusString(status)); |
| } |
| mWifiNanIface.getFrameworkCallback().notifySuspendResponse( |
| (short) id, WifiNanIface.NanStatusCode.fromAidl(status.status)); |
| } |
| |
| @Override |
| public void notifyResumeResponse(char id, NanStatus status) { |
| if (!checkFrameworkCallback()) { |
| return; |
| } |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "notifyResumeResponse: id=" + id + ", status=" |
| + statusString(status)); |
| } |
| mWifiNanIface.getFrameworkCallback().notifyResumeResponse( |
| (short) id, WifiNanIface.NanStatusCode.fromAidl(status.status)); |
| } |
| |
| @Override |
| public void eventClusterEvent(NanClusterEventInd event) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "eventClusterEvent: eventType=" + event.eventType + ", addr=" |
| + String.valueOf(HexEncoding.encode(event.addr))); |
| } |
| mWifiNanIface.getFrameworkCallback().eventClusterEvent( |
| NanClusterEventType.fromAidl(event.eventType), event.addr); |
| } |
| |
| @Override |
| public void eventDisabled(NanStatus status) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) Log.v(TAG, "eventDisabled: status=" + statusString(status)); |
| mWifiNanIface.getFrameworkCallback().eventDisabled( |
| WifiNanIface.NanStatusCode.fromAidl(status.status)); |
| } |
| |
| @Override |
| public void eventPublishTerminated(byte sessionId, NanStatus status) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "eventPublishTerminated: sessionId=" + sessionId + ", status=" |
| + statusString(status)); |
| } |
| mWifiNanIface.getFrameworkCallback().eventPublishTerminated( |
| sessionId, WifiNanIface.NanStatusCode.fromAidl(status.status)); |
| } |
| |
| @Override |
| public void eventSubscribeTerminated(byte sessionId, NanStatus status) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "eventSubscribeTerminated: sessionId=" + sessionId + ", status=" |
| + statusString(status)); |
| } |
| mWifiNanIface.getFrameworkCallback().eventSubscribeTerminated( |
| sessionId, WifiNanIface.NanStatusCode.fromAidl(status.status)); |
| } |
| |
| @Override |
| public void eventMatch(NanMatchInd event) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "eventMatch: discoverySessionId=" + event.discoverySessionId |
| + ", peerId=" + event.peerId |
| + ", addr=" + String.valueOf(HexEncoding.encode(event.addr)) |
| + ", serviceSpecificInfo=" + Arrays.toString(event.serviceSpecificInfo) |
| + ", ssi.size()=" + (event.serviceSpecificInfo == null |
| ? 0 : event.serviceSpecificInfo.length) |
| + ", matchFilter=" + Arrays.toString(event.matchFilter) |
| + ", mf.size()=" + (event.matchFilter == null ? 0 : event.matchFilter.length) |
| + ", rangingIndicationType=" + event.rangingIndicationType |
| + ", rangingMeasurementInMm=" + event.rangingMeasurementInMm + ", " |
| + "scid=" + Arrays.toString(event.scid)); |
| } |
| mWifiNanIface.getFrameworkCallback().eventMatch(event.discoverySessionId, event.peerId, |
| event.addr, event.serviceSpecificInfo, event.matchFilter, |
| NanRangingIndication.fromAidl(event.rangingIndicationType), |
| event.rangingMeasurementInMm, event.scid, |
| toPublicDataPathCipherSuites(event.peerCipherType), |
| event.peerNira.nonce, event.peerNira.tag, |
| createPublicPairingConfig(event.peerPairingConfig)); |
| } |
| |
| private AwarePairingConfig createPublicPairingConfig(NanPairingConfig nativePairingConfig) { |
| return new AwarePairingConfig(nativePairingConfig.enablePairingSetup, |
| nativePairingConfig.enablePairingCache, |
| nativePairingConfig.enablePairingVerification, |
| toBootStrappingMethods(nativePairingConfig.supportedBootstrappingMethods)); |
| } |
| |
| private int toBootStrappingMethods(int nativeMethods) { |
| int publicMethods = 0; |
| |
| if ((nativeMethods & NanBootstrappingMethod.BOOTSTRAPPING_OPPORTUNISTIC_MASK) != 0) { |
| publicMethods |= AwarePairingConfig.PAIRING_BOOTSTRAPPING_OPPORTUNISTIC; |
| } |
| if ((nativeMethods & NanBootstrappingMethod.BOOTSTRAPPING_PIN_CODE_DISPLAY_MASK) != 0) { |
| publicMethods |= AwarePairingConfig.PAIRING_BOOTSTRAPPING_PIN_CODE_DISPLAY; |
| } |
| if ((nativeMethods & NanBootstrappingMethod.BOOTSTRAPPING_PASSPHRASE_DISPLAY_MASK) != 0) { |
| publicMethods |= AwarePairingConfig.PAIRING_BOOTSTRAPPING_PASSPHRASE_DISPLAY; |
| } |
| if ((nativeMethods & NanBootstrappingMethod.BOOTSTRAPPING_QR_DISPLAY_MASK) != 0) { |
| publicMethods |= AwarePairingConfig.PAIRING_BOOTSTRAPPING_QR_DISPLAY; |
| } |
| if ((nativeMethods & NanBootstrappingMethod.BOOTSTRAPPING_NFC_TAG_MASK) != 0) { |
| publicMethods |= AwarePairingConfig.PAIRING_BOOTSTRAPPING_NFC_TAG; |
| } |
| if ((nativeMethods & NanBootstrappingMethod.BOOTSTRAPPING_PIN_CODE_KEYPAD_MASK) != 0) { |
| publicMethods |= AwarePairingConfig.PAIRING_BOOTSTRAPPING_PIN_CODE_KEYPAD; |
| } |
| if ((nativeMethods & NanBootstrappingMethod.BOOTSTRAPPING_PASSPHRASE_KEYPAD_MASK) != 0) { |
| publicMethods |= AwarePairingConfig.PAIRING_BOOTSTRAPPING_PASSPHRASE_KEYPAD; |
| } |
| if ((nativeMethods & NanBootstrappingMethod.BOOTSTRAPPING_QR_SCAN_MASK) != 0) { |
| publicMethods |= AwarePairingConfig.PAIRING_BOOTSTRAPPING_QR_SCAN; |
| } |
| if ((nativeMethods & NanBootstrappingMethod.BOOTSTRAPPING_NFC_READER_MASK) != 0) { |
| publicMethods |= AwarePairingConfig.PAIRING_BOOTSTRAPPING_NFC_READER; |
| } |
| |
| return publicMethods; |
| } |
| |
| @Override |
| public void eventMatchExpired(byte discoverySessionId, int peerId) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "eventMatchExpired: discoverySessionId=" + discoverySessionId |
| + ", peerId=" + peerId); |
| } |
| mWifiNanIface.getFrameworkCallback().eventMatchExpired(discoverySessionId, peerId); |
| } |
| |
| @Override |
| public void eventFollowupReceived(NanFollowupReceivedInd event) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "eventFollowupReceived: discoverySessionId=" + event.discoverySessionId |
| + ", peerId=" + event.peerId + ", addr=" + String.valueOf( |
| HexEncoding.encode(event.addr)) + ", serviceSpecificInfo=" + Arrays.toString( |
| event.serviceSpecificInfo) + ", ssi.size()=" |
| + (event.serviceSpecificInfo == null ? 0 : event.serviceSpecificInfo.length)); |
| } |
| mWifiNanIface.getFrameworkCallback().eventFollowupReceived( |
| event.discoverySessionId, event.peerId, event.addr, event.serviceSpecificInfo); |
| } |
| |
| @Override |
| public void eventTransmitFollowup(char id, NanStatus status) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "eventTransmitFollowup: id=" + id + ", status=" + statusString(status)); |
| } |
| mWifiNanIface.getFrameworkCallback().eventTransmitFollowup( |
| (short) id, WifiNanIface.NanStatusCode.fromAidl(status.status)); |
| } |
| |
| @Override |
| public void eventSuspensionModeChanged(NanSuspensionModeChangeInd event) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "eventSuspensionModeChanged: isSuspended=" + event.isSuspended); |
| } |
| mWifiNanIface.getFrameworkCallback().eventSuspensionModeChanged(event.isSuspended); |
| } |
| |
| @Override |
| public void eventDataPathRequest(NanDataPathRequestInd event) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "eventDataPathRequest: discoverySessionId=" + event.discoverySessionId |
| + ", peerDiscMacAddr=" + String.valueOf( |
| HexEncoding.encode(event.peerDiscMacAddr)) + ", ndpInstanceId=" |
| + event.ndpInstanceId + ", appInfo.size()=" + event.appInfo.length); |
| } |
| mWifiNanIface.getFrameworkCallback().eventDataPathRequest(event.discoverySessionId, |
| event.peerDiscMacAddr, event.ndpInstanceId, event.appInfo); |
| } |
| |
| @Override |
| public void eventDataPathConfirm(NanDataPathConfirmInd event) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "eventDataPathConfirm: ndpInstanceId=" + event.ndpInstanceId |
| + ", peerNdiMacAddr=" + String.valueOf( |
| HexEncoding.encode(event.peerNdiMacAddr)) + ", dataPathSetupSuccess=" |
| + event.dataPathSetupSuccess + ", reason=" + event.status.status |
| + ", appInfo.size()=" + event.appInfo.length |
| + ", channelInfo" + Arrays.toString(event.channelInfo)); |
| } |
| List<WifiAwareChannelInfo> wifiAwareChannelInfos = convertHalChannelInfo(event.channelInfo); |
| mWifiNanIface.getFrameworkCallback().eventDataPathConfirm( |
| WifiNanIface.NanStatusCode.fromAidl(event.status.status), event.ndpInstanceId, |
| event.dataPathSetupSuccess, event.peerNdiMacAddr, event.appInfo, |
| wifiAwareChannelInfos); |
| } |
| |
| @Override |
| public void eventDataPathScheduleUpdate(NanDataPathScheduleUpdateInd event) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "eventDataPathScheduleUpdate: peerMac=" |
| + MacAddress.fromBytes(event.peerDiscoveryAddress) |
| + ", ndpIds=" + Arrays.toString(event.ndpInstanceIds) |
| + ", channelInfo=" + Arrays.toString(event.channelInfo)); |
| } |
| List<WifiAwareChannelInfo> wifiAwareChannelInfos = convertHalChannelInfo(event.channelInfo); |
| ArrayList<Integer> ndpInstanceIds = new ArrayList<>(); |
| for (int i : event.ndpInstanceIds) { |
| ndpInstanceIds.add(i); |
| } |
| mWifiNanIface.getFrameworkCallback().eventDataPathScheduleUpdate( |
| event.peerDiscoveryAddress, ndpInstanceIds, wifiAwareChannelInfos); |
| } |
| |
| @Override |
| public void eventDataPathTerminated(int ndpInstanceId) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "eventDataPathTerminated: ndpInstanceId=" + ndpInstanceId); |
| } |
| mWifiNanIface.getFrameworkCallback().eventDataPathTerminated(ndpInstanceId); |
| } |
| |
| @Override |
| public void eventPairingRequest(NanPairingRequestInd event) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "eventPairingRequest:"); |
| } |
| mWifiNanIface.getFrameworkCallback().eventPairingRequest(event.discoverySessionId, |
| event.peerId, event.peerDiscMacAddr, |
| event.pairingInstanceId, pairingRequestTypeFromAidl(event.requestType), |
| event.enablePairingCache, event.peerNira.nonce, event.peerNira.tag); |
| } |
| |
| private static int pairingRequestTypeFromAidl(@NanPairingRequestType int requestType) { |
| if (requestType == NanPairingRequestType.NAN_PAIRING_SETUP) { |
| return NAN_PAIRING_REQUEST_TYPE_SETUP; |
| } |
| return NAN_PAIRING_REQUEST_TYPE_VERIFICATION; |
| } |
| |
| @Override |
| public void eventPairingConfirm(NanPairingConfirmInd event) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "eventPairingConfirm: ndpInstanceId="); |
| } |
| mWifiNanIface.getFrameworkCallback().eventPairingConfirm(event.pairingInstanceId, |
| event.pairingSuccess, WifiNanIface.NanStatusCode.fromAidl(event.status.status), |
| pairingRequestTypeFromAidl(event.requestType), event.enablePairingCache, |
| createPairingSecurityAssociationInfo(event.npksa)); |
| } |
| |
| private static PairingSecurityAssociationInfo createPairingSecurityAssociationInfo( |
| NpkSecurityAssociation npksa) { |
| return new PairingSecurityAssociationInfo(npksa.peerNanIdentityKey, |
| npksa.localNanIdentityKey, npksa.npk, |
| createPublicPairingAkm(npksa.akm), toPublicDataPathCipherSuites(npksa.cipherType)); |
| } |
| |
| private static int createPublicPairingAkm(int aidlAkm) { |
| switch (aidlAkm) { |
| case NanPairingAkm.SAE: |
| return NAN_PAIRING_AKM_SAE; |
| case NanPairingAkm.PASN: |
| return NAN_PAIRING_AKM_PASN; |
| } |
| Log.e(TAG, "unknown pairing AKM"); |
| return aidlAkm; |
| } |
| |
| @Override |
| public void eventBootstrappingRequest(NanBootstrappingRequestInd event) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "eventBootstrappingRequest:"); |
| } |
| mWifiNanIface.getFrameworkCallback().eventBootstrappingRequest(event.discoverySessionId, |
| event.peerId, event.peerDiscMacAddr, |
| event.bootstrappingInstanceId, event.requestBootstrappingMethod); |
| } |
| |
| @Override |
| public void eventBootstrappingConfirm(NanBootstrappingConfirmInd event) { |
| if (!checkFrameworkCallback()) return; |
| if (mVerboseLoggingEnabled) { |
| Log.v(TAG, "eventBootstrappingConfirm:"); |
| } |
| mWifiNanIface.getFrameworkCallback().eventBootstrappingConfirm( |
| event.bootstrappingInstanceId, |
| convertAidlBootstrappingResponseCodeToFramework(event.responseCode), |
| WifiNanIface.NanStatusCode.fromAidl(event.reasonCode.status), event.comeBackDelay, |
| event.cookie); |
| } |
| |
| private int convertAidlBootstrappingResponseCodeToFramework(int aidlCode) { |
| switch (aidlCode) { |
| case NanBootstrappingResponseCode.NAN_BOOTSTRAPPING_REQUEST_ACCEPT: |
| return NAN_BOOTSTRAPPING_ACCEPT; |
| case NanBootstrappingResponseCode.NAN_BOOTSTRAPPING_REQUEST_REJECT: |
| return NAN_BOOTSTRAPPING_REJECT; |
| case NanBootstrappingResponseCode.NAN_BOOTSTRAPPING_REQUEST_COMEBACK: |
| return NAN_BOOTSTRAPPING_COMEBACK; |
| } |
| Log.e(TAG, "unknown bootstrapping response code"); |
| return aidlCode; |
| } |
| |
| @Override |
| public String getInterfaceHash() { |
| return IWifiNanIfaceEventCallback.HASH; |
| } |
| |
| @Override |
| public int getInterfaceVersion() { |
| return IWifiNanIfaceEventCallback.VERSION; |
| } |
| |
| private Capabilities toFrameworkCapability(NanCapabilities capabilities) { |
| Capabilities frameworkCapabilities = new Capabilities(); |
| frameworkCapabilities.maxConcurrentAwareClusters = capabilities.maxConcurrentClusters; |
| frameworkCapabilities.maxPublishes = capabilities.maxPublishes; |
| frameworkCapabilities.maxSubscribes = capabilities.maxSubscribes; |
| frameworkCapabilities.maxServiceNameLen = capabilities.maxServiceNameLen; |
| frameworkCapabilities.maxMatchFilterLen = capabilities.maxMatchFilterLen; |
| frameworkCapabilities.maxTotalMatchFilterLen = capabilities.maxTotalMatchFilterLen; |
| frameworkCapabilities.maxServiceSpecificInfoLen = |
| capabilities.maxServiceSpecificInfoLen; |
| frameworkCapabilities.maxExtendedServiceSpecificInfoLen = |
| capabilities.maxExtendedServiceSpecificInfoLen; |
| frameworkCapabilities.maxNdiInterfaces = capabilities.maxNdiInterfaces; |
| frameworkCapabilities.maxNdpSessions = capabilities.maxNdpSessions; |
| frameworkCapabilities.maxAppInfoLen = capabilities.maxAppInfoLen; |
| frameworkCapabilities.maxQueuedTransmitMessages = |
| capabilities.maxQueuedTransmitFollowupMsgs; |
| frameworkCapabilities.maxSubscribeInterfaceAddresses = |
| capabilities.maxSubscribeInterfaceAddresses; |
| frameworkCapabilities.supportedDataPathCipherSuites = toPublicDataPathCipherSuites( |
| capabilities.supportedCipherSuites); |
| frameworkCapabilities.supportedPairingCipherSuites = toPublicPairingCipherSuites( |
| capabilities.supportedCipherSuites); |
| frameworkCapabilities.isInstantCommunicationModeSupported = |
| capabilities.instantCommunicationModeSupportFlag; |
| frameworkCapabilities.isNanPairingSupported = capabilities.supportsPairing; |
| frameworkCapabilities.isSetClusterIdSupported = capabilities.supportsSetClusterId; |
| frameworkCapabilities.isSuspensionSupported = capabilities.supportsSuspension; |
| frameworkCapabilities.is6gSupported = capabilities.supports6g; |
| frameworkCapabilities.isHeSupported = capabilities.supportsHe; |
| return frameworkCapabilities; |
| } |
| |
| private static int toPublicDataPathCipherSuites(int nativeCipherSuites) { |
| int publicCipherSuites = 0; |
| |
| if ((nativeCipherSuites & NanCipherSuiteType.SHARED_KEY_128_MASK) != 0) { |
| publicCipherSuites |= Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_SK_128; |
| } |
| if ((nativeCipherSuites & NanCipherSuiteType.SHARED_KEY_256_MASK) != 0) { |
| publicCipherSuites |= Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_SK_256; |
| } |
| if ((nativeCipherSuites & NanCipherSuiteType.PUBLIC_KEY_2WDH_256_MASK) != 0) { |
| publicCipherSuites |= Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_PK_128; |
| } |
| if ((nativeCipherSuites & NanCipherSuiteType.PUBLIC_KEY_2WDH_256_MASK) != 0) { |
| publicCipherSuites |= Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_PK_256; |
| } |
| |
| return publicCipherSuites; |
| } |
| |
| private static int toPublicPairingCipherSuites(int nativeCipherSuites) { |
| int publicCipherSuites = 0; |
| |
| if ((nativeCipherSuites & NanCipherSuiteType.PUBLIC_KEY_PASN_128_MASK) != 0) { |
| publicCipherSuites |= Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_PK_PASN_128; |
| } |
| if ((nativeCipherSuites & NanCipherSuiteType.PUBLIC_KEY_PASN_256_MASK) != 0) { |
| publicCipherSuites |= Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_PK_PASN_256; |
| } |
| |
| return publicCipherSuites; |
| } |
| |
| private static String statusString(NanStatus status) { |
| if (status == null) { |
| return "status=null"; |
| } |
| StringBuilder sb = new StringBuilder(); |
| sb.append(status.status).append(" (").append(status.description).append(")"); |
| return sb.toString(); |
| } |
| |
| /** |
| * Convert HAL channelBandwidth to framework enum |
| */ |
| @WifiAnnotations.ChannelWidth |
| private int getChannelBandwidthFromHal(int channelBandwidth) { |
| switch (channelBandwidth) { |
| case WifiChannelWidthInMhz.WIDTH_40: |
| return ScanResult.CHANNEL_WIDTH_40MHZ; |
| case WifiChannelWidthInMhz.WIDTH_80: |
| return ScanResult.CHANNEL_WIDTH_80MHZ; |
| case WifiChannelWidthInMhz.WIDTH_160: |
| return ScanResult.CHANNEL_WIDTH_160MHZ; |
| case WifiChannelWidthInMhz.WIDTH_80P80: |
| return ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ; |
| case WifiChannelWidthInMhz.WIDTH_320: |
| return ScanResult.CHANNEL_WIDTH_320MHZ; |
| default: |
| return ScanResult.CHANNEL_WIDTH_20MHZ; |
| } |
| } |
| |
| /** |
| * Convert HAL NanDataPathChannelInfo to WifiAwareChannelInfo |
| */ |
| private List<WifiAwareChannelInfo> convertHalChannelInfo( |
| NanDataPathChannelInfo[] channelInfos) { |
| List<WifiAwareChannelInfo> wifiAwareChannelInfos = new ArrayList<>(); |
| if (channelInfos == null) { |
| return null; |
| } |
| for (android.hardware.wifi.NanDataPathChannelInfo channelInfo : channelInfos) { |
| wifiAwareChannelInfos.add(new WifiAwareChannelInfo(channelInfo.channelFreq, |
| getChannelBandwidthFromHal(channelInfo.channelBandwidth), |
| channelInfo.numSpatialStreams)); |
| } |
| return wifiAwareChannelInfos; |
| } |
| |
| private boolean checkFrameworkCallback() { |
| if (mWifiNanIface == null) { |
| Log.e(TAG, "mWifiNanIface is null"); |
| return false; |
| } else if (mWifiNanIface.getFrameworkCallback() == null) { |
| Log.e(TAG, "Framework callback is null"); |
| return false; |
| } |
| return true; |
| } |
| } |