Home | History | Annotate | Download | only in aware
      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.aware;
     18 
     19 import android.hardware.wifi.V1_0.NanCapabilities;
     20 import android.hardware.wifi.V1_0.NanClusterEventInd;
     21 import android.hardware.wifi.V1_0.NanClusterEventType;
     22 import android.hardware.wifi.V1_0.NanDataPathConfirmInd;
     23 import android.hardware.wifi.V1_0.NanDataPathRequestInd;
     24 import android.hardware.wifi.V1_0.NanFollowupReceivedInd;
     25 import android.hardware.wifi.V1_0.NanMatchInd;
     26 import android.hardware.wifi.V1_0.NanStatusType;
     27 import android.hardware.wifi.V1_0.WifiNanStatus;
     28 import android.hardware.wifi.V1_2.IWifiNanIfaceEventCallback;
     29 import android.hardware.wifi.V1_2.NanDataPathScheduleUpdateInd;
     30 import android.os.ShellCommand;
     31 import android.util.Log;
     32 import android.util.SparseIntArray;
     33 
     34 import libcore.util.HexEncoding;
     35 
     36 import org.json.JSONException;
     37 import org.json.JSONObject;
     38 
     39 import java.io.FileDescriptor;
     40 import java.io.PrintWriter;
     41 import java.util.ArrayList;
     42 import java.util.Arrays;
     43 
     44 /**
     45  * Manages the callbacks from Wi-Fi Aware HIDL (HAL).
     46  */
     47 public class WifiAwareNativeCallback extends IWifiNanIfaceEventCallback.Stub implements
     48         WifiAwareShellCommand.DelegatedShellCommand {
     49     private static final String TAG = "WifiAwareNativeCallback";
     50     private static final boolean VDBG = false;
     51     /* package */ boolean mDbg = false;
     52 
     53     /* package */ boolean mIsHal12OrLater = false;
     54 
     55     private final WifiAwareStateManager mWifiAwareStateManager;
     56 
     57     public WifiAwareNativeCallback(WifiAwareStateManager wifiAwareStateManager) {
     58         mWifiAwareStateManager = wifiAwareStateManager;
     59     }
     60 
     61     /*
     62      * Counts of callbacks from HAL. Retrievable through shell command.
     63      */
     64     private static final int CB_EV_CLUSTER = 0;
     65     private static final int CB_EV_DISABLED = 1;
     66     private static final int CB_EV_PUBLISH_TERMINATED = 2;
     67     private static final int CB_EV_SUBSCRIBE_TERMINATED = 3;
     68     private static final int CB_EV_MATCH = 4;
     69     private static final int CB_EV_MATCH_EXPIRED = 5;
     70     private static final int CB_EV_FOLLOWUP_RECEIVED = 6;
     71     private static final int CB_EV_TRANSMIT_FOLLOWUP = 7;
     72     private static final int CB_EV_DATA_PATH_REQUEST = 8;
     73     private static final int CB_EV_DATA_PATH_CONFIRM = 9;
     74     private static final int CB_EV_DATA_PATH_TERMINATED = 10;
     75     private static final int CB_EV_DATA_PATH_SCHED_UPDATE = 11;
     76 
     77     private SparseIntArray mCallbackCounter = new SparseIntArray();
     78 
     79     private void incrementCbCount(int callbackId) {
     80         mCallbackCounter.put(callbackId, mCallbackCounter.get(callbackId) + 1);
     81     }
     82 
     83     /**
     84      * Interpreter of adb shell command 'adb shell wifiaware native_cb ...'.
     85      *
     86      * @return -1 if parameter not recognized or invalid value, 0 otherwise.
     87      */
     88     @Override
     89     public int onCommand(ShellCommand parentShell) {
     90         final PrintWriter pwe = parentShell.getErrPrintWriter();
     91         final PrintWriter pwo = parentShell.getOutPrintWriter();
     92 
     93         String subCmd = parentShell.getNextArgRequired();
     94         if (VDBG) Log.v(TAG, "onCommand: subCmd='" + subCmd + "'");
     95         switch (subCmd) {
     96             case "get_cb_count": {
     97                 String option = parentShell.getNextOption();
     98                 if (VDBG) Log.v(TAG, "option='" + option + "'");
     99                 boolean reset = false;
    100                 if (option != null) {
    101                     if ("--reset".equals(option)) {
    102                         reset = true;
    103                     } else {
    104                         pwe.println("Unknown option to 'get_cb_count'");
    105                         return -1;
    106                     }
    107                 }
    108 
    109                 JSONObject j = new JSONObject();
    110                 try {
    111                     for (int i = 0; i < mCallbackCounter.size(); ++i) {
    112                         j.put(Integer.toString(mCallbackCounter.keyAt(i)),
    113                                 mCallbackCounter.valueAt(i));
    114                     }
    115                 } catch (JSONException e) {
    116                     Log.e(TAG, "onCommand: get_cb_count e=" + e);
    117                 }
    118                 pwo.println(j.toString());
    119                 if (reset) {
    120                     mCallbackCounter.clear();
    121                 }
    122                 return 0;
    123             }
    124             default:
    125                 pwe.println("Unknown 'wifiaware native_cb <cmd>'");
    126         }
    127 
    128         return -1;
    129     }
    130 
    131     @Override
    132     public void onReset() {
    133         // NOP (onReset is intended for configuration reset - not data reset)
    134     }
    135 
    136     @Override
    137     public void onHelp(String command, ShellCommand parentShell) {
    138         final PrintWriter pw = parentShell.getOutPrintWriter();
    139 
    140         pw.println("  " + command);
    141         pw.println("    get_cb_count [--reset]: gets the number of callbacks (and optionally reset "
    142                 + "count)");
    143     }
    144 
    145     @Override
    146     public void notifyCapabilitiesResponse(short id, WifiNanStatus status,
    147             NanCapabilities capabilities) {
    148         if (mDbg) {
    149             Log.v(TAG, "notifyCapabilitiesResponse: id=" + id + ", status=" + statusString(status)
    150                     + ", capabilities=" + capabilities);
    151         }
    152 
    153         if (status.status == NanStatusType.SUCCESS) {
    154             Capabilities frameworkCapabilities = new Capabilities();
    155             frameworkCapabilities.maxConcurrentAwareClusters = capabilities.maxConcurrentClusters;
    156             frameworkCapabilities.maxPublishes = capabilities.maxPublishes;
    157             frameworkCapabilities.maxSubscribes = capabilities.maxSubscribes;
    158             frameworkCapabilities.maxServiceNameLen = capabilities.maxServiceNameLen;
    159             frameworkCapabilities.maxMatchFilterLen = capabilities.maxMatchFilterLen;
    160             frameworkCapabilities.maxTotalMatchFilterLen = capabilities.maxTotalMatchFilterLen;
    161             frameworkCapabilities.maxServiceSpecificInfoLen =
    162                     capabilities.maxServiceSpecificInfoLen;
    163             frameworkCapabilities.maxExtendedServiceSpecificInfoLen =
    164                     capabilities.maxExtendedServiceSpecificInfoLen;
    165             frameworkCapabilities.maxNdiInterfaces = capabilities.maxNdiInterfaces;
    166             frameworkCapabilities.maxNdpSessions = capabilities.maxNdpSessions;
    167             frameworkCapabilities.maxAppInfoLen = capabilities.maxAppInfoLen;
    168             frameworkCapabilities.maxQueuedTransmitMessages =
    169                     capabilities.maxQueuedTransmitFollowupMsgs;
    170             frameworkCapabilities.maxSubscribeInterfaceAddresses =
    171                     capabilities.maxSubscribeInterfaceAddresses;
    172             frameworkCapabilities.supportedCipherSuites = capabilities.supportedCipherSuites;
    173 
    174             mWifiAwareStateManager.onCapabilitiesUpdateResponse(id, frameworkCapabilities);
    175         } else {
    176             Log.e(TAG, "notifyCapabilitiesResponse: error code=" + status.status + " ("
    177                     + status.description + ")");
    178         }
    179     }
    180 
    181     @Override
    182     public void notifyEnableResponse(short id, WifiNanStatus status) {
    183         if (mDbg) Log.v(TAG, "notifyEnableResponse: id=" + id + ", status=" + statusString(status));
    184 
    185         if (status.status == NanStatusType.ALREADY_ENABLED) {
    186             Log.wtf(TAG, "notifyEnableResponse: id=" + id + ", already enabled!?");
    187         }
    188 
    189         if (status.status == NanStatusType.SUCCESS
    190                 || status.status == NanStatusType.ALREADY_ENABLED) {
    191             mWifiAwareStateManager.onConfigSuccessResponse(id);
    192         } else {
    193             mWifiAwareStateManager.onConfigFailedResponse(id, status.status);
    194         }
    195     }
    196 
    197     @Override
    198     public void notifyConfigResponse(short id, WifiNanStatus status) {
    199         if (mDbg) Log.v(TAG, "notifyConfigResponse: id=" + id + ", status=" + statusString(status));
    200 
    201         if (status.status == NanStatusType.SUCCESS) {
    202             mWifiAwareStateManager.onConfigSuccessResponse(id);
    203         } else {
    204             mWifiAwareStateManager.onConfigFailedResponse(id, status.status);
    205         }
    206     }
    207 
    208     @Override
    209     public void notifyDisableResponse(short id, WifiNanStatus status) {
    210         if (mDbg) {
    211             Log.v(TAG, "notifyDisableResponse: id=" + id + ", status=" + statusString(status));
    212         }
    213 
    214         if (status.status != NanStatusType.SUCCESS) {
    215             Log.e(TAG, "notifyDisableResponse: failure - code=" + status.status + " ("
    216                     + status.description + ")");
    217         }
    218         mWifiAwareStateManager.onDisableResponse(id, status.status);
    219     }
    220 
    221     @Override
    222     public void notifyStartPublishResponse(short id, WifiNanStatus status, byte publishId) {
    223         if (mDbg) {
    224             Log.v(TAG, "notifyStartPublishResponse: id=" + id + ", status=" + statusString(status)
    225                     + ", publishId=" + publishId);
    226         }
    227 
    228         if (status.status == NanStatusType.SUCCESS) {
    229             mWifiAwareStateManager.onSessionConfigSuccessResponse(id, true, publishId);
    230         } else {
    231             mWifiAwareStateManager.onSessionConfigFailResponse(id, true, status.status);
    232         }
    233     }
    234 
    235     @Override
    236     public void notifyStopPublishResponse(short id, WifiNanStatus status) {
    237         if (mDbg) {
    238             Log.v(TAG, "notifyStopPublishResponse: id=" + id + ", status=" + statusString(status));
    239         }
    240 
    241         if (status.status == NanStatusType.SUCCESS) {
    242             // NOP
    243         } else {
    244             Log.e(TAG, "notifyStopPublishResponse: failure - code=" + status.status + " ("
    245                     + status.description + ")");
    246         }
    247     }
    248 
    249     @Override
    250     public void notifyStartSubscribeResponse(short id, WifiNanStatus status, byte subscribeId) {
    251         if (mDbg) {
    252             Log.v(TAG, "notifyStartSubscribeResponse: id=" + id + ", status=" + statusString(status)
    253                     + ", subscribeId=" + subscribeId);
    254         }
    255 
    256         if (status.status == NanStatusType.SUCCESS) {
    257             mWifiAwareStateManager.onSessionConfigSuccessResponse(id, false, subscribeId);
    258         } else {
    259             mWifiAwareStateManager.onSessionConfigFailResponse(id, false, status.status);
    260         }
    261     }
    262 
    263     @Override
    264     public void notifyStopSubscribeResponse(short id, WifiNanStatus status) {
    265         if (mDbg) {
    266             Log.v(TAG, "notifyStopSubscribeResponse: id=" + id + ", status="
    267                     + statusString(status));
    268         }
    269 
    270         if (status.status == NanStatusType.SUCCESS) {
    271             // NOP
    272         } else {
    273             Log.e(TAG, "notifyStopSubscribeResponse: failure - code=" + status.status + " ("
    274                     + status.description + ")");
    275         }
    276     }
    277 
    278     @Override
    279     public void notifyTransmitFollowupResponse(short id, WifiNanStatus status) {
    280         if (mDbg) {
    281             Log.v(TAG, "notifyTransmitFollowupResponse: id=" + id + ", status="
    282                     + statusString(status));
    283         }
    284 
    285         if (status.status == NanStatusType.SUCCESS) {
    286             mWifiAwareStateManager.onMessageSendQueuedSuccessResponse(id);
    287         } else {
    288             mWifiAwareStateManager.onMessageSendQueuedFailResponse(id, status.status);
    289         }
    290     }
    291 
    292     @Override
    293     public void notifyCreateDataInterfaceResponse(short id, WifiNanStatus status) {
    294         if (mDbg) {
    295             Log.v(TAG, "notifyCreateDataInterfaceResponse: id=" + id + ", status="
    296                     + statusString(status));
    297         }
    298 
    299         mWifiAwareStateManager.onCreateDataPathInterfaceResponse(id,
    300                 status.status == NanStatusType.SUCCESS, status.status);
    301     }
    302 
    303     @Override
    304     public void notifyDeleteDataInterfaceResponse(short id, WifiNanStatus status) {
    305         if (mDbg) {
    306             Log.v(TAG, "notifyDeleteDataInterfaceResponse: id=" + id + ", status="
    307                     + statusString(status));
    308         }
    309 
    310         mWifiAwareStateManager.onDeleteDataPathInterfaceResponse(id,
    311                 status.status == NanStatusType.SUCCESS, status.status);
    312     }
    313 
    314     @Override
    315     public void notifyInitiateDataPathResponse(short id, WifiNanStatus status,
    316             int ndpInstanceId) {
    317         if (mDbg) {
    318             Log.v(TAG, "notifyInitiateDataPathResponse: id=" + id + ", status="
    319                     + statusString(status) + ", ndpInstanceId=" + ndpInstanceId);
    320         }
    321 
    322         if (status.status == NanStatusType.SUCCESS) {
    323             mWifiAwareStateManager.onInitiateDataPathResponseSuccess(id, ndpInstanceId);
    324         } else {
    325             mWifiAwareStateManager.onInitiateDataPathResponseFail(id, status.status);
    326         }
    327     }
    328 
    329     @Override
    330     public void notifyRespondToDataPathIndicationResponse(short id, WifiNanStatus status) {
    331         if (mDbg) {
    332             Log.v(TAG, "notifyRespondToDataPathIndicationResponse: id=" + id
    333                     + ", status=" + statusString(status));
    334         }
    335 
    336         mWifiAwareStateManager.onRespondToDataPathSetupRequestResponse(id,
    337                 status.status == NanStatusType.SUCCESS, status.status);
    338     }
    339 
    340     @Override
    341     public void notifyTerminateDataPathResponse(short id, WifiNanStatus status) {
    342         if (mDbg) {
    343             Log.v(TAG, "notifyTerminateDataPathResponse: id=" + id + ", status="
    344                     + statusString(status));
    345         }
    346 
    347         mWifiAwareStateManager.onEndDataPathResponse(id, status.status == NanStatusType.SUCCESS,
    348                 status.status);
    349     }
    350 
    351     @Override
    352     public void eventClusterEvent(NanClusterEventInd event) {
    353         if (mDbg) {
    354             Log.v(TAG, "eventClusterEvent: eventType=" + event.eventType + ", addr="
    355                     + String.valueOf(HexEncoding.encode(event.addr)));
    356         }
    357         incrementCbCount(CB_EV_CLUSTER);
    358 
    359         if (event.eventType == NanClusterEventType.DISCOVERY_MAC_ADDRESS_CHANGED) {
    360             mWifiAwareStateManager.onInterfaceAddressChangeNotification(event.addr);
    361         } else if (event.eventType == NanClusterEventType.STARTED_CLUSTER) {
    362             mWifiAwareStateManager.onClusterChangeNotification(
    363                     WifiAwareClientState.CLUSTER_CHANGE_EVENT_STARTED, event.addr);
    364         } else if (event.eventType == NanClusterEventType.JOINED_CLUSTER) {
    365             mWifiAwareStateManager.onClusterChangeNotification(
    366                     WifiAwareClientState.CLUSTER_CHANGE_EVENT_JOINED, event.addr);
    367         } else {
    368             Log.e(TAG, "eventClusterEvent: invalid eventType=" + event.eventType);
    369         }
    370     }
    371 
    372     @Override
    373     public void eventDisabled(WifiNanStatus status) {
    374         if (mDbg) Log.v(TAG, "eventDisabled: status=" + statusString(status));
    375         incrementCbCount(CB_EV_DISABLED);
    376 
    377         mWifiAwareStateManager.onAwareDownNotification(status.status);
    378     }
    379 
    380     @Override
    381     public void eventPublishTerminated(byte sessionId, WifiNanStatus status) {
    382         if (mDbg) {
    383             Log.v(TAG, "eventPublishTerminated: sessionId=" + sessionId + ", status="
    384                     + statusString(status));
    385         }
    386         incrementCbCount(CB_EV_PUBLISH_TERMINATED);
    387 
    388         mWifiAwareStateManager.onSessionTerminatedNotification(sessionId, status.status, true);
    389     }
    390 
    391     @Override
    392     public void eventSubscribeTerminated(byte sessionId, WifiNanStatus status) {
    393         if (mDbg) {
    394             Log.v(TAG, "eventSubscribeTerminated: sessionId=" + sessionId + ", status="
    395                     + statusString(status));
    396         }
    397         incrementCbCount(CB_EV_SUBSCRIBE_TERMINATED);
    398 
    399         mWifiAwareStateManager.onSessionTerminatedNotification(sessionId, status.status, false);
    400     }
    401 
    402     @Override
    403     public void eventMatch(NanMatchInd event) {
    404         if (mDbg) {
    405             Log.v(TAG, "eventMatch: discoverySessionId=" + event.discoverySessionId + ", peerId="
    406                     + event.peerId + ", addr=" + String.valueOf(HexEncoding.encode(event.addr))
    407                     + ", serviceSpecificInfo=" + Arrays.toString(
    408                     convertArrayListToNativeByteArray(event.serviceSpecificInfo)) + ", ssi.size()="
    409                     + (event.serviceSpecificInfo == null ? 0 : event.serviceSpecificInfo.size())
    410                     + ", matchFilter=" + Arrays.toString(
    411                     convertArrayListToNativeByteArray(event.matchFilter)) + ", mf.size()=" + (
    412                     event.matchFilter == null ? 0 : event.matchFilter.size())
    413                     + ", rangingIndicationType=" + event.rangingIndicationType
    414                     + ", rangingMeasurementInCm=" + event.rangingMeasurementInCm);
    415         }
    416         incrementCbCount(CB_EV_MATCH);
    417 
    418         // TODO: b/69428593 get rid of conversion once HAL moves from CM to MM
    419         mWifiAwareStateManager.onMatchNotification(event.discoverySessionId, event.peerId,
    420                 event.addr, convertArrayListToNativeByteArray(event.serviceSpecificInfo),
    421                 convertArrayListToNativeByteArray(event.matchFilter), event.rangingIndicationType,
    422                 event.rangingMeasurementInCm * 10);
    423     }
    424 
    425     @Override
    426     public void eventMatchExpired(byte discoverySessionId, int peerId) {
    427         if (mDbg) {
    428             Log.v(TAG, "eventMatchExpired: discoverySessionId=" + discoverySessionId
    429                     + ", peerId=" + peerId);
    430         }
    431         incrementCbCount(CB_EV_MATCH_EXPIRED);
    432 
    433         // NOP
    434     }
    435 
    436     @Override
    437     public void eventFollowupReceived(NanFollowupReceivedInd event) {
    438         if (mDbg) {
    439             Log.v(TAG, "eventFollowupReceived: discoverySessionId=" + event.discoverySessionId
    440                     + ", peerId=" + event.peerId + ", addr=" + String.valueOf(
    441                     HexEncoding.encode(event.addr)) + ", serviceSpecificInfo=" + Arrays.toString(
    442                     convertArrayListToNativeByteArray(event.serviceSpecificInfo)) + ", ssi.size()="
    443                     + (event.serviceSpecificInfo == null ? 0 : event.serviceSpecificInfo.size()));
    444         }
    445         incrementCbCount(CB_EV_FOLLOWUP_RECEIVED);
    446 
    447         mWifiAwareStateManager.onMessageReceivedNotification(event.discoverySessionId, event.peerId,
    448                 event.addr, convertArrayListToNativeByteArray(event.serviceSpecificInfo));
    449     }
    450 
    451     @Override
    452     public void eventTransmitFollowup(short id, WifiNanStatus status) {
    453         if (mDbg) {
    454             Log.v(TAG, "eventTransmitFollowup: id=" + id + ", status=" + statusString(status));
    455         }
    456         incrementCbCount(CB_EV_TRANSMIT_FOLLOWUP);
    457 
    458         if (status.status == NanStatusType.SUCCESS) {
    459             mWifiAwareStateManager.onMessageSendSuccessNotification(id);
    460         } else {
    461             mWifiAwareStateManager.onMessageSendFailNotification(id, status.status);
    462         }
    463     }
    464 
    465     @Override
    466     public void eventDataPathRequest(NanDataPathRequestInd event) {
    467         if (mDbg) {
    468             Log.v(TAG, "eventDataPathRequest: discoverySessionId=" + event.discoverySessionId
    469                     + ", peerDiscMacAddr=" + String.valueOf(
    470                     HexEncoding.encode(event.peerDiscMacAddr)) + ", ndpInstanceId="
    471                     + event.ndpInstanceId);
    472         }
    473         incrementCbCount(CB_EV_DATA_PATH_REQUEST);
    474 
    475         mWifiAwareStateManager.onDataPathRequestNotification(event.discoverySessionId,
    476                 event.peerDiscMacAddr, event.ndpInstanceId);
    477     }
    478 
    479     @Override
    480     public void eventDataPathConfirm(NanDataPathConfirmInd event) {
    481         if (mDbg) {
    482             Log.v(TAG, "onDataPathConfirm: ndpInstanceId=" + event.ndpInstanceId
    483                     + ", peerNdiMacAddr=" + String.valueOf(HexEncoding.encode(event.peerNdiMacAddr))
    484                     + ", dataPathSetupSuccess=" + event.dataPathSetupSuccess + ", reason="
    485                     + event.status.status);
    486         }
    487         if (mIsHal12OrLater) {
    488             Log.wtf(TAG, "eventDataPathConfirm should not be called by a >=1.2 HAL!");
    489         }
    490         incrementCbCount(CB_EV_DATA_PATH_CONFIRM);
    491 
    492         mWifiAwareStateManager.onDataPathConfirmNotification(event.ndpInstanceId,
    493                 event.peerNdiMacAddr, event.dataPathSetupSuccess, event.status.status,
    494                 convertArrayListToNativeByteArray(event.appInfo), null);
    495     }
    496 
    497     @Override
    498     public void eventDataPathConfirm_1_2(android.hardware.wifi.V1_2.NanDataPathConfirmInd event) {
    499         if (mDbg) {
    500             Log.v(TAG, "eventDataPathConfirm_1_2: ndpInstanceId=" + event.V1_0.ndpInstanceId
    501                     + ", peerNdiMacAddr=" + String.valueOf(
    502                     HexEncoding.encode(event.V1_0.peerNdiMacAddr)) + ", dataPathSetupSuccess="
    503                     + event.V1_0.dataPathSetupSuccess + ", reason=" + event.V1_0.status.status);
    504         }
    505         if (!mIsHal12OrLater) {
    506             Log.wtf(TAG, "eventDataPathConfirm_1_2 should not be called by a <1.2 HAL!");
    507             return;
    508         }
    509         incrementCbCount(CB_EV_DATA_PATH_CONFIRM);
    510 
    511         mWifiAwareStateManager.onDataPathConfirmNotification(event.V1_0.ndpInstanceId,
    512                 event.V1_0.peerNdiMacAddr, event.V1_0.dataPathSetupSuccess,
    513                 event.V1_0.status.status, convertArrayListToNativeByteArray(event.V1_0.appInfo),
    514                 event.channelInfo);
    515     }
    516 
    517     @Override
    518     public void eventDataPathScheduleUpdate(NanDataPathScheduleUpdateInd event) {
    519         if (mDbg) {
    520             Log.v(TAG, "eventDataPathScheduleUpdate");
    521         }
    522         if (!mIsHal12OrLater) {
    523             Log.wtf(TAG, "eventDataPathScheduleUpdate should not be called by a <1.2 HAL!");
    524             return;
    525         }
    526         incrementCbCount(CB_EV_DATA_PATH_SCHED_UPDATE);
    527 
    528         mWifiAwareStateManager.onDataPathScheduleUpdateNotification(event.peerDiscoveryAddress,
    529                 event.ndpInstanceIds, event.channelInfo);
    530     }
    531 
    532     @Override
    533     public void eventDataPathTerminated(int ndpInstanceId) {
    534         if (mDbg) Log.v(TAG, "eventDataPathTerminated: ndpInstanceId=" + ndpInstanceId);
    535         incrementCbCount(CB_EV_DATA_PATH_TERMINATED);
    536 
    537         mWifiAwareStateManager.onDataPathEndNotification(ndpInstanceId);
    538     }
    539 
    540     /**
    541      * Dump the internal state of the class.
    542      */
    543     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
    544         pw.println("WifiAwareNativeCallback:");
    545         pw.println("  mCallbackCounter: " + mCallbackCounter);
    546     }
    547 
    548 
    549     // utilities
    550 
    551     /**
    552      * Converts an ArrayList<Byte> to a byte[].
    553      *
    554      * @param from The input ArrayList<Byte></Byte> to convert from.
    555      *
    556      * @return A newly allocated byte[].
    557      */
    558     private byte[] convertArrayListToNativeByteArray(ArrayList<Byte> from) {
    559         if (from == null) {
    560             return null;
    561         }
    562 
    563         byte[] to = new byte[from.size()];
    564         for (int i = 0; i < from.size(); ++i) {
    565             to[i] = from.get(i);
    566         }
    567         return to;
    568     }
    569 
    570     private static String statusString(WifiNanStatus status) {
    571         if (status == null) {
    572             return "status=null";
    573         }
    574         StringBuilder sb = new StringBuilder();
    575         sb.append(status.status).append(" (").append(status.description).append(")");
    576         return sb.toString();
    577     }
    578 }
    579