/*
 * Copyright (C) 2017 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.googlecode.android_scripting.facade.wifi;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.net.NetworkSpecifier;
import android.net.wifi.RttManager;
import android.net.wifi.RttManager.RttResult;
import android.net.wifi.aware.AttachCallback;
import android.net.wifi.aware.ConfigRequest;
import android.net.wifi.aware.DiscoverySession;
import android.net.wifi.aware.DiscoverySessionCallback;
import android.net.wifi.aware.IdentityChangedListener;
import android.net.wifi.aware.PeerHandle;
import android.net.wifi.aware.PublishConfig;
import android.net.wifi.aware.PublishDiscoverySession;
import android.net.wifi.aware.SubscribeConfig;
import android.net.wifi.aware.SubscribeDiscoverySession;
import android.net.wifi.aware.TlvBufferUtils;
import android.net.wifi.aware.WifiAwareManager;
import android.net.wifi.aware.WifiAwareNetworkSpecifier;
import android.net.wifi.aware.WifiAwareSession;
import android.os.Bundle;
import android.os.Parcelable;
import android.os.RemoteException;
import android.text.TextUtils;
import android.util.Base64;
import android.util.SparseArray;

import com.android.internal.annotations.GuardedBy;

import libcore.util.HexEncoding;

import com.googlecode.android_scripting.facade.EventFacade;
import com.googlecode.android_scripting.facade.FacadeManager;
import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
import com.googlecode.android_scripting.rpc.Rpc;
import com.googlecode.android_scripting.rpc.RpcOptional;
import com.googlecode.android_scripting.rpc.RpcParameter;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * WifiAwareManager functions.
 */
public class WifiAwareManagerFacade extends RpcReceiver {
    private final Service mService;
    private final EventFacade mEventFacade;
    private final WifiAwareStateChangedReceiver mStateChangedReceiver;

    private final Object mLock = new Object(); // lock access to the following vars

    @GuardedBy("mLock")
    private WifiAwareManager mMgr;

    @GuardedBy("mLock")
    private int mNextDiscoverySessionId = 1;
    @GuardedBy("mLock")
    private SparseArray<DiscoverySession> mDiscoverySessions = new SparseArray<>();
    private int getNextDiscoverySessionId() {
        synchronized (mLock) {
            return mNextDiscoverySessionId++;
        }
    }

    @GuardedBy("mLock")
    private int mNextSessionId = 1;
    @GuardedBy("mLock")
    private SparseArray<WifiAwareSession> mSessions = new SparseArray<>();
    private int getNextSessionId() {
        synchronized (mLock) {
            return mNextSessionId++;
        }
    }

    @GuardedBy("mLock")
    private SparseArray<Long> mMessageStartTime = new SparseArray<>();

    private static final String NS_KEY_TYPE = "type";
    private static final String NS_KEY_ROLE = "role";
    private static final String NS_KEY_CLIENT_ID = "client_id";
    private static final String NS_KEY_SESSION_ID = "session_id";
    private static final String NS_KEY_PEER_ID = "peer_id";
    private static final String NS_KEY_PEER_MAC = "peer_mac";
    private static final String NS_KEY_PMK = "pmk";
    private static final String NS_KEY_PASSPHRASE = "passphrase";
    private static final String NS_KEY_PORT = "port";
    private static final String NS_KEY_TRANSPORT_PROTOCOL = "transport_protocol";

    private static String getJsonString(WifiAwareNetworkSpecifier ns) throws JSONException {
        JSONObject j = new JSONObject();

        j.put(NS_KEY_TYPE, ns.type);
        j.put(NS_KEY_ROLE, ns.role);
        j.put(NS_KEY_CLIENT_ID, ns.clientId);
        j.put(NS_KEY_SESSION_ID, ns.sessionId);
        j.put(NS_KEY_PEER_ID, ns.peerId);
        if (ns.peerMac != null) {
            j.put(NS_KEY_PEER_MAC, Base64.encodeToString(ns.peerMac, Base64.DEFAULT));
        }
        if (ns.pmk != null) {
            j.put(NS_KEY_PMK, Base64.encodeToString(ns.pmk, Base64.DEFAULT));
        }
        if (ns.passphrase != null) {
            j.put(NS_KEY_PASSPHRASE, ns.passphrase);
        }
        if (ns.port != 0) {
            j.put(NS_KEY_PORT, ns.port);
        }
        if (ns.transportProtocol != -1) {
            j.put(NS_KEY_TRANSPORT_PROTOCOL, ns.transportProtocol);
        }

        return j.toString();
    }

    public static NetworkSpecifier getNetworkSpecifier(JSONObject j) throws JSONException {
        if (j == null) {
            return null;
        }

        int type = 0, role = 0, clientId = 0, sessionId = 0, peerId = 0;
        byte[] peerMac = null;
        byte[] pmk = null;
        String passphrase = null;
        int port = 0, transportProtocol = -1;

        if (j.has(NS_KEY_TYPE)) {
            type = j.getInt((NS_KEY_TYPE));
        }
        if (j.has(NS_KEY_ROLE)) {
            role = j.getInt((NS_KEY_ROLE));
        }
        if (j.has(NS_KEY_CLIENT_ID)) {
            clientId = j.getInt((NS_KEY_CLIENT_ID));
        }
        if (j.has(NS_KEY_SESSION_ID)) {
            sessionId = j.getInt((NS_KEY_SESSION_ID));
        }
        if (j.has(NS_KEY_PEER_ID)) {
            peerId = j.getInt((NS_KEY_PEER_ID));
        }
        if (j.has(NS_KEY_PEER_MAC)) {
            peerMac = Base64.decode(j.getString(NS_KEY_PEER_MAC), Base64.DEFAULT);
        }
        if (j.has(NS_KEY_PMK)) {
            pmk = Base64.decode(j.getString(NS_KEY_PMK), Base64.DEFAULT);
        }
        if (j.has(NS_KEY_PASSPHRASE)) {
            passphrase = j.getString(NS_KEY_PASSPHRASE);
        }
        if (j.has(NS_KEY_PORT)) {
            port = j.getInt(NS_KEY_PORT);
        }
        if (j.has(NS_KEY_TRANSPORT_PROTOCOL)) {
            transportProtocol = j.getInt(NS_KEY_TRANSPORT_PROTOCOL);
        }

        return new WifiAwareNetworkSpecifier(type, role, clientId, sessionId, peerId, peerMac, pmk,
                passphrase, port, transportProtocol);
    }

    private static String getStringOrNull(JSONObject j, String name) throws JSONException {
        if (j.isNull(name)) {
            return null;
        }
        return j.getString(name);
    }

    private static ConfigRequest getConfigRequest(JSONObject j) throws JSONException {
        if (j == null) {
            return null;
        }

        ConfigRequest.Builder builder = new ConfigRequest.Builder();

        if (j.has("Support5gBand")) {
            builder.setSupport5gBand(j.getBoolean("Support5gBand"));
        }
        if (j.has("MasterPreference")) {
            builder.setMasterPreference(j.getInt("MasterPreference"));
        }
        if (j.has("ClusterLow")) {
            builder.setClusterLow(j.getInt("ClusterLow"));
        }
        if (j.has("ClusterHigh")) {
            builder.setClusterHigh(j.getInt("ClusterHigh"));
        }
        if (j.has("DiscoveryWindowInterval")) {
            JSONArray interval = j.getJSONArray("DiscoveryWindowInterval");
            if (interval.length() != 2) {
                throw new JSONException(
                        "Expect 'DiscoveryWindowInterval' to be an array with 2 elements!");
            }
            int intervalValue = interval.getInt(ConfigRequest.NAN_BAND_24GHZ);
            if (intervalValue != ConfigRequest.DW_INTERVAL_NOT_INIT) {
                builder.setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_24GHZ, intervalValue);
            }
            intervalValue = interval.getInt(ConfigRequest.NAN_BAND_5GHZ);
            if (intervalValue != ConfigRequest.DW_INTERVAL_NOT_INIT) {
                builder.setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_5GHZ, intervalValue);
            }
        }

        return builder.build();
    }

    private static List<byte[]> getMatchFilter(JSONArray ja) throws JSONException {
        List<byte[]> la = new ArrayList<>();
        for (int i = 0; i < ja.length(); ++i) {
            la.add(Base64.decode(ja.getString(i).getBytes(StandardCharsets.UTF_8), Base64.DEFAULT));
        }
        return la;
    }

    private static PublishConfig getPublishConfig(JSONObject j) throws JSONException {
        if (j == null) {
            return null;
        }

        PublishConfig.Builder builder = new PublishConfig.Builder();

        if (j.has("ServiceName")) {
            builder.setServiceName(getStringOrNull(j, "ServiceName"));
        }

        if (j.has("ServiceSpecificInfo")) {
            String ssi = getStringOrNull(j, "ServiceSpecificInfo");
            if (ssi != null) {
                builder.setServiceSpecificInfo(ssi.getBytes());
            }
        }

        if (j.has("MatchFilter")) {
            byte[] bytes = Base64.decode(
                    j.getString("MatchFilter").getBytes(StandardCharsets.UTF_8), Base64.DEFAULT);
            List<byte[]> mf = new TlvBufferUtils.TlvIterable(0, 1, bytes).toList();
            builder.setMatchFilter(mf);

        }

        if (!j.isNull("MatchFilterList")) {
            builder.setMatchFilter(getMatchFilter(j.getJSONArray("MatchFilterList")));
        }

        if (j.has("DiscoveryType")) {
            builder.setPublishType(j.getInt("DiscoveryType"));
        }
        if (j.has("TtlSec")) {
            builder.setTtlSec(j.getInt("TtlSec"));
        }
        if (j.has("TerminateNotificationEnabled")) {
            builder.setTerminateNotificationEnabled(j.getBoolean("TerminateNotificationEnabled"));
        }
        if (j.has("RangingEnabled")) {
            builder.setRangingEnabled(j.getBoolean("RangingEnabled"));
        }


        return builder.build();
    }

    private static SubscribeConfig getSubscribeConfig(JSONObject j) throws JSONException {
        if (j == null) {
            return null;
        }

        SubscribeConfig.Builder builder = new SubscribeConfig.Builder();

        if (j.has("ServiceName")) {
            builder.setServiceName(j.getString("ServiceName"));
        }

        if (j.has("ServiceSpecificInfo")) {
            String ssi = getStringOrNull(j, "ServiceSpecificInfo");
            if (ssi != null) {
                builder.setServiceSpecificInfo(ssi.getBytes());
            }
        }

        if (j.has("MatchFilter")) {
            byte[] bytes = Base64.decode(
                    j.getString("MatchFilter").getBytes(StandardCharsets.UTF_8), Base64.DEFAULT);
            List<byte[]> mf = new TlvBufferUtils.TlvIterable(0, 1, bytes).toList();
            builder.setMatchFilter(mf);
        }

        if (!j.isNull("MatchFilterList")) {
            builder.setMatchFilter(getMatchFilter(j.getJSONArray("MatchFilterList")));
        }

        if (j.has("DiscoveryType")) {
            builder.setSubscribeType(j.getInt("DiscoveryType"));
        }
        if (j.has("TtlSec")) {
            builder.setTtlSec(j.getInt("TtlSec"));
        }
        if (j.has("TerminateNotificationEnabled")) {
            builder.setTerminateNotificationEnabled(j.getBoolean("TerminateNotificationEnabled"));
        }
        if (j.has("MinDistanceMm")) {
            builder.setMinDistanceMm(j.getInt("MinDistanceMm"));
        }
        if (j.has("MaxDistanceMm")) {
            builder.setMaxDistanceMm(j.getInt("MaxDistanceMm"));
        }

        return builder.build();
    }

    public WifiAwareManagerFacade(FacadeManager manager) {
        super(manager);
        mService = manager.getService();

        mMgr = (WifiAwareManager) mService.getSystemService(Context.WIFI_AWARE_SERVICE);

        mEventFacade = manager.getReceiver(EventFacade.class);

        mStateChangedReceiver = new WifiAwareStateChangedReceiver();
        IntentFilter filter = new IntentFilter(WifiAwareManager.ACTION_WIFI_AWARE_STATE_CHANGED);
        mService.registerReceiver(mStateChangedReceiver, filter);
    }

    @Override
    public void shutdown() {
        wifiAwareDestroyAll();
        mService.unregisterReceiver(mStateChangedReceiver);
    }

    @Rpc(description = "Does the device support the Wi-Fi Aware feature?")
    public Boolean doesDeviceSupportWifiAwareFeature() {
        return mService.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_AWARE);
    }

    @Rpc(description = "Is Aware Usage Enabled?")
    public Boolean wifiIsAwareAvailable() throws RemoteException {
        synchronized (mLock) {
            return mMgr.isAvailable();
        }
    }

    @Rpc(description = "Destroy all Aware sessions and discovery sessions")
    public void wifiAwareDestroyAll() {
        synchronized (mLock) {
            for (int i = 0; i < mSessions.size(); ++i) {
                mSessions.valueAt(i).close();
            }
            mSessions.clear();

            /* discovery sessions automatically destroyed when containing Aware sessions
             * destroyed */
            mDiscoverySessions.clear();

            mMessageStartTime.clear();
        }
    }

    @Rpc(description = "Attach to Aware.")
    public Integer wifiAwareAttach(
            @RpcParameter(name = "identityCb",
                description = "Controls whether an identity callback is provided")
                @RpcOptional Boolean identityCb,
            @RpcParameter(name = "awareConfig",
                description = "The session configuration, or null for default config")
                @RpcOptional JSONObject awareConfig,
            @RpcParameter(name = "useIdInCallbackEvent",
                description =
                    "Specifies whether the callback events should be decorated with session Id")
                @RpcOptional Boolean useIdInCallbackEvent)
            throws RemoteException, JSONException {
        synchronized (mLock) {
            int sessionId = getNextSessionId();
            boolean useIdInCallbackEventName =
                (useIdInCallbackEvent != null) ? useIdInCallbackEvent : false;
            mMgr.attach(null, getConfigRequest(awareConfig),
                    new AwareAttachCallbackPostsEvents(sessionId, useIdInCallbackEventName),
                    (identityCb != null && identityCb.booleanValue())
                        ? new AwareIdentityChangeListenerPostsEvents(sessionId,
                        useIdInCallbackEventName) : null);
            return sessionId;
        }
    }

    @Rpc(description = "Destroy a Aware session.")
    public void wifiAwareDestroy(
            @RpcParameter(name = "clientId", description = "The client ID returned when a connection was created") Integer clientId)
            throws RemoteException, JSONException {
        WifiAwareSession session;
        synchronized (mLock) {
            session = mSessions.get(clientId);
        }
        if (session == null) {
            throw new IllegalStateException(
                    "Calling WifiAwareDisconnect before session (client ID " + clientId
                            + ") is ready/or already disconnected");
        }
        session.close();
    }

    @Rpc(description = "Publish.")
    public Integer wifiAwarePublish(
            @RpcParameter(name = "clientId", description = "The client ID returned when a connection was created") Integer clientId,
            @RpcParameter(name = "publishConfig") JSONObject publishConfig,
            @RpcParameter(name = "useIdInCallbackEvent",
            description =
                "Specifies whether the callback events should be decorated with session Id")
                @RpcOptional Boolean useIdInCallbackEvent)
            throws RemoteException, JSONException {
        synchronized (mLock) {
            WifiAwareSession session = mSessions.get(clientId);
            if (session == null) {
                throw new IllegalStateException(
                        "Calling WifiAwarePublish before session (client ID " + clientId
                                + ") is ready/or already disconnected");
            }
            boolean useIdInCallbackEventName =
                (useIdInCallbackEvent != null) ? useIdInCallbackEvent : false;

            int discoverySessionId = getNextDiscoverySessionId();
            session.publish(getPublishConfig(publishConfig),
                new AwareDiscoverySessionCallbackPostsEvents(discoverySessionId,
                    useIdInCallbackEventName), null);
            return discoverySessionId;
        }
    }

    @Rpc(description = "Update Publish.")
    public void wifiAwareUpdatePublish(
        @RpcParameter(name = "sessionId", description = "The discovery session ID")
            Integer sessionId,
        @RpcParameter(name = "publishConfig", description = "Publish configuration")
            JSONObject publishConfig)
        throws RemoteException, JSONException {
        synchronized (mLock) {
            DiscoverySession session = mDiscoverySessions.get(sessionId);
            if (session == null) {
                throw new IllegalStateException(
                    "Calling wifiAwareUpdatePublish before session (session ID "
                        + sessionId + ") is ready");
            }
            if (!(session instanceof PublishDiscoverySession)) {
                throw new IllegalArgumentException(
                    "Calling wifiAwareUpdatePublish with a subscribe session ID");
            }
            ((PublishDiscoverySession) session).updatePublish(getPublishConfig(publishConfig));
        }
    }

    @Rpc(description = "Subscribe.")
    public Integer wifiAwareSubscribe(
            @RpcParameter(name = "clientId", description = "The client ID returned when a connection was created") Integer clientId,
            @RpcParameter(name = "subscribeConfig") JSONObject subscribeConfig,
            @RpcParameter(name = "useIdInCallbackEvent",
                description =
                "Specifies whether the callback events should be decorated with session Id")
                @RpcOptional Boolean useIdInCallbackEvent)
            throws RemoteException, JSONException {
        synchronized (mLock) {
            WifiAwareSession session = mSessions.get(clientId);
            if (session == null) {
                throw new IllegalStateException(
                        "Calling WifiAwareSubscribe before session (client ID " + clientId
                                + ") is ready/or already disconnected");
            }
            boolean useIdInCallbackEventName =
                (useIdInCallbackEvent != null) ? useIdInCallbackEvent : false;

            int discoverySessionId = getNextDiscoverySessionId();
            session.subscribe(getSubscribeConfig(subscribeConfig),
                new AwareDiscoverySessionCallbackPostsEvents(discoverySessionId,
                    useIdInCallbackEventName), null);
            return discoverySessionId;
        }
    }

    @Rpc(description = "Update Subscribe.")
    public void wifiAwareUpdateSubscribe(
        @RpcParameter(name = "sessionId", description = "The discovery session ID")
            Integer sessionId,
        @RpcParameter(name = "subscribeConfig", description = "Subscribe configuration")
            JSONObject subscribeConfig)
        throws RemoteException, JSONException {
        synchronized (mLock) {
            DiscoverySession session = mDiscoverySessions.get(sessionId);
            if (session == null) {
                throw new IllegalStateException(
                    "Calling wifiAwareUpdateSubscribe before session (session ID "
                        + sessionId + ") is ready");
            }
            if (!(session instanceof SubscribeDiscoverySession)) {
                throw new IllegalArgumentException(
                    "Calling wifiAwareUpdateSubscribe with a publish session ID");
            }
            ((SubscribeDiscoverySession) session)
                .updateSubscribe(getSubscribeConfig(subscribeConfig));
        }
    }

    @Rpc(description = "Destroy a discovery Session.")
    public void wifiAwareDestroyDiscoverySession(
            @RpcParameter(name = "sessionId", description = "The discovery session ID returned when session was created using publish or subscribe") Integer sessionId)
            throws RemoteException {
        synchronized (mLock) {
            DiscoverySession session = mDiscoverySessions.get(sessionId);
            if (session == null) {
                throw new IllegalStateException(
                        "Calling WifiAwareTerminateSession before session (session ID "
                                + sessionId + ") is ready");
            }
            session.close();
            mDiscoverySessions.remove(sessionId);
        }
    }

    @Rpc(description = "Send peer-to-peer Aware message")
    public void wifiAwareSendMessage(
            @RpcParameter(name = "sessionId", description = "The session ID returned when session"
                    + " was created using publish or subscribe") Integer sessionId,
            @RpcParameter(name = "peerId", description = "The ID of the peer being communicated "
                    + "with. Obtained from a previous message or match session.") Integer peerId,
            @RpcParameter(name = "messageId", description = "Arbitrary handle used for "
                    + "identification of the message in the message status callbacks")
                    Integer messageId,
            @RpcParameter(name = "message") String message,
            @RpcParameter(name = "retryCount", description = "Number of retries (0 for none) if "
                    + "transmission fails due to no ACK reception") Integer retryCount)
                    throws RemoteException {
        DiscoverySession session;
        synchronized (mLock) {
            session = mDiscoverySessions.get(sessionId);
        }
        if (session == null) {
            throw new IllegalStateException(
                    "Calling WifiAwareSendMessage before session (session ID " + sessionId
                            + " is ready");
        }
        byte[] bytes = null;
        if (message != null) {
            bytes = message.getBytes();
        }

        synchronized (mLock) {
            mMessageStartTime.put(messageId, System.currentTimeMillis());
        }
        session.sendMessage(new PeerHandle(peerId), messageId, bytes, retryCount);
    }

    @Rpc(description = "Create a network specifier to be used when specifying a Aware network request")
    public String wifiAwareCreateNetworkSpecifier(
            @RpcParameter(name = "sessionId", description = "The session ID returned when session was created using publish or subscribe")
                    Integer sessionId,
            @RpcParameter(name = "peerId", description = "The ID of the peer (obtained through OnMatch or OnMessageReceived")
                    Integer peerId,
            @RpcParameter(name = "passphrase",
                description = "Passphrase of the data-path. Optional, can be empty/null.")
                @RpcOptional String passphrase,
            @RpcParameter(name = "pmk",
                description = "PMK of the data-path (base64 encoded). Optional, can be empty/null.")
                @RpcOptional String pmk,
            @RpcParameter(name = "port", description = "Port") @RpcOptional Integer port,
            @RpcParameter(name = "transportProtocol", description = "Transport protocol")
                @RpcOptional Integer transportProtocol) throws JSONException {
        DiscoverySession session;
        synchronized (mLock) {
            session = mDiscoverySessions.get(sessionId);
        }
        if (session == null) {
            throw new IllegalStateException(
                    "Calling wifiAwareCreateNetworkSpecifier before session (session ID "
                            + sessionId + " is ready");
        }
        PeerHandle peerHandle = null;
        if (peerId != null) {
            peerHandle = new PeerHandle(peerId);
        }
        byte[] pmkDecoded = null;
        if (!TextUtils.isEmpty(pmk)) {
            pmkDecoded = Base64.decode(pmk, Base64.DEFAULT);
        }

        WifiAwareNetworkSpecifier ns = new WifiAwareNetworkSpecifier(
                (peerHandle == null) ? WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB_ANY_PEER
                        : WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB,
                session instanceof SubscribeDiscoverySession
                        ? WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
                        : WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER,
                session.getClientId(),
                session.getSessionId(),
                peerHandle != null ? peerHandle.peerId : 0, // 0 is an invalid peer ID
                null, // peerMac (not used in this method)
                pmkDecoded,
                passphrase,
                port == null ? 0 : port.intValue(),
                transportProtocol == null ? -1 : transportProtocol.intValue());

        return getJsonString(ns);
    }

    @Rpc(description = "Create a network specifier to be used when specifying an OOB Aware network request")
    public String wifiAwareCreateNetworkSpecifierOob(
            @RpcParameter(name = "clientId",
                    description = "The client ID")
                    Integer clientId,
            @RpcParameter(name = "role", description = "The role: INITIATOR(0), RESPONDER(1)")
                    Integer role,
            @RpcParameter(name = "peerMac",
                    description = "The MAC address of the peer")
                    String peerMac,
            @RpcParameter(name = "passphrase",
                    description = "Passphrase of the data-path. Optional, can be empty/null.")
            @RpcOptional String passphrase,
            @RpcParameter(name = "pmk",
                    description = "PMK of the data-path (base64). Optional, can be empty/null.")
            @RpcOptional String pmk) throws JSONException {
        WifiAwareSession session;
        synchronized (mLock) {
            session = mSessions.get(clientId);
        }
        if (session == null) {
            throw new IllegalStateException(
                    "Calling wifiAwareCreateNetworkSpecifierOob before session (client ID "
                            + clientId + " is ready");
        }
        byte[] peerMacBytes = null;
        if (peerMac != null) {
            peerMacBytes = HexEncoding.decode(peerMac.toCharArray(), false);
        }
        byte[] pmkDecoded = null;
        if (!TextUtils.isEmpty(pmk)) {
            pmkDecoded = Base64.decode(pmk, Base64.DEFAULT);
        }

        WifiAwareNetworkSpecifier ns = new WifiAwareNetworkSpecifier(
                (peerMacBytes == null) ?
                        WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER
                        : WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_OOB,
                role,
                session.getClientId(),
                0, // 0 is an invalid session ID
                0, // 0 is an invalid peer ID
                peerMacBytes,
                pmkDecoded,
                passphrase,
                0, // no port for OOB
                -1); // no transport protocol for OOB

        return getJsonString(ns);
    }

    private class AwareAttachCallbackPostsEvents extends AttachCallback {
        private int mSessionId;
        private long mCreateTimestampMs;
        private boolean mUseIdInCallbackEventName;

        public AwareAttachCallbackPostsEvents(int sessionId, boolean useIdInCallbackEventName) {
            mSessionId = sessionId;
            mCreateTimestampMs = System.currentTimeMillis();
            mUseIdInCallbackEventName = useIdInCallbackEventName;
        }

        @Override
        public void onAttached(WifiAwareSession session) {
            synchronized (mLock) {
                mSessions.put(mSessionId, session);
            }

            Bundle mResults = new Bundle();
            mResults.putInt("sessionId", mSessionId);
            mResults.putLong("latencyMs", System.currentTimeMillis() - mCreateTimestampMs);
            mResults.putLong("timestampMs", System.currentTimeMillis());
            if (mUseIdInCallbackEventName) {
                mEventFacade.postEvent("WifiAwareOnAttached_" + mSessionId, mResults);
            } else {
                mEventFacade.postEvent("WifiAwareOnAttached", mResults);
            }
        }

        @Override
        public void onAttachFailed() {
            Bundle mResults = new Bundle();
            mResults.putInt("sessionId", mSessionId);
            mResults.putLong("latencyMs", System.currentTimeMillis() - mCreateTimestampMs);
            if (mUseIdInCallbackEventName) {
                mEventFacade.postEvent("WifiAwareOnAttachFailed_" + mSessionId, mResults);
            } else {
                mEventFacade.postEvent("WifiAwareOnAttachFailed", mResults);
            }
        }
    }

    private class AwareIdentityChangeListenerPostsEvents extends IdentityChangedListener {
        private int mSessionId;
        private boolean mUseIdInCallbackEventName;

        public AwareIdentityChangeListenerPostsEvents(int sessionId,
            boolean useIdInCallbackEventName) {
            mSessionId = sessionId;
            mUseIdInCallbackEventName = useIdInCallbackEventName;
        }

        @Override
        public void onIdentityChanged(byte[] mac) {
            Bundle mResults = new Bundle();
            mResults.putInt("sessionId", mSessionId);
            mResults.putString("mac", String.valueOf(HexEncoding.encode(mac)));
            mResults.putLong("timestampMs", System.currentTimeMillis());
            if (mUseIdInCallbackEventName) {
                mEventFacade.postEvent("WifiAwareOnIdentityChanged_" + mSessionId, mResults);
            } else {
                mEventFacade.postEvent("WifiAwareOnIdentityChanged", mResults);
            }
        }
    }

    private class AwareDiscoverySessionCallbackPostsEvents extends
            DiscoverySessionCallback {
        private int mDiscoverySessionId;
        private boolean mUseIdInCallbackEventName;
        private long mCreateTimestampMs;

        public AwareDiscoverySessionCallbackPostsEvents(int discoverySessionId,
                boolean useIdInCallbackEventName) {
            mDiscoverySessionId = discoverySessionId;
            mUseIdInCallbackEventName = useIdInCallbackEventName;
            mCreateTimestampMs = System.currentTimeMillis();
        }

        private void postEvent(String eventName, Bundle results) {
            String finalEventName = eventName;
            if (mUseIdInCallbackEventName) {
                finalEventName += "_" + mDiscoverySessionId;
            }

            mEventFacade.postEvent(finalEventName, results);
        }

        @Override
        public void onPublishStarted(PublishDiscoverySession discoverySession) {
            synchronized (mLock) {
                mDiscoverySessions.put(mDiscoverySessionId, discoverySession);
            }

            Bundle mResults = new Bundle();
            mResults.putInt("discoverySessionId", mDiscoverySessionId);
            mResults.putLong("latencyMs", System.currentTimeMillis() - mCreateTimestampMs);
            mResults.putLong("timestampMs", System.currentTimeMillis());
            postEvent("WifiAwareSessionOnPublishStarted", mResults);
        }

        @Override
        public void onSubscribeStarted(SubscribeDiscoverySession discoverySession) {
            synchronized (mLock) {
                mDiscoverySessions.put(mDiscoverySessionId, discoverySession);
            }

            Bundle mResults = new Bundle();
            mResults.putInt("discoverySessionId", mDiscoverySessionId);
            mResults.putLong("latencyMs", System.currentTimeMillis() - mCreateTimestampMs);
            mResults.putLong("timestampMs", System.currentTimeMillis());
            postEvent("WifiAwareSessionOnSubscribeStarted", mResults);
        }

        @Override
        public void onSessionConfigUpdated() {
            Bundle mResults = new Bundle();
            mResults.putInt("discoverySessionId", mDiscoverySessionId);
            postEvent("WifiAwareSessionOnSessionConfigUpdated", mResults);
        }

        @Override
        public void onSessionConfigFailed() {
            Bundle mResults = new Bundle();
            mResults.putInt("discoverySessionId", mDiscoverySessionId);
            postEvent("WifiAwareSessionOnSessionConfigFailed", mResults);
        }

        @Override
        public void onSessionTerminated() {
            Bundle mResults = new Bundle();
            mResults.putInt("discoverySessionId", mDiscoverySessionId);
            postEvent("WifiAwareSessionOnSessionTerminated", mResults);
        }

        private Bundle createServiceDiscoveredBaseBundle(PeerHandle peerHandle,
                byte[] serviceSpecificInfo, List<byte[]> matchFilter) {
            Bundle mResults = new Bundle();
            mResults.putInt("discoverySessionId", mDiscoverySessionId);
            mResults.putInt("peerId", peerHandle.peerId);
            mResults.putByteArray("serviceSpecificInfo", serviceSpecificInfo);
            mResults.putByteArray("matchFilter", new TlvBufferUtils.TlvConstructor(0,
                    1).allocateAndPut(matchFilter).getArray());
            ArrayList<String> matchFilterStrings = new ArrayList<>(matchFilter.size());
            for (byte[] be: matchFilter) {
                matchFilterStrings.add(Base64.encodeToString(be, Base64.DEFAULT));
            }
            mResults.putStringArrayList("matchFilterList", matchFilterStrings);
            mResults.putLong("timestampMs", System.currentTimeMillis());
            return mResults;
        }

        @Override
        public void onServiceDiscovered(PeerHandle peerHandle,
                byte[] serviceSpecificInfo, List<byte[]> matchFilter) {
            Bundle mResults = createServiceDiscoveredBaseBundle(peerHandle, serviceSpecificInfo,
                    matchFilter);
            postEvent("WifiAwareSessionOnServiceDiscovered", mResults);
        }

        @Override
        public void onServiceDiscoveredWithinRange(PeerHandle peerHandle,
                byte[] serviceSpecificInfo,
                List<byte[]> matchFilter, int distanceMm) {
            Bundle mResults = createServiceDiscoveredBaseBundle(peerHandle, serviceSpecificInfo,
                    matchFilter);
            mResults.putInt("distanceMm", distanceMm);
            postEvent("WifiAwareSessionOnServiceDiscovered", mResults);
        }

        @Override
        public void onMessageSendSucceeded(int messageId) {
            Bundle mResults = new Bundle();
            mResults.putInt("discoverySessionId", mDiscoverySessionId);
            mResults.putInt("messageId", messageId);
            synchronized (mLock) {
                Long startTime = mMessageStartTime.get(messageId);
                if (startTime != null) {
                    mResults.putLong("latencyMs",
                            System.currentTimeMillis() - startTime.longValue());
                    mMessageStartTime.remove(messageId);
                }
            }
            postEvent("WifiAwareSessionOnMessageSent", mResults);
        }

        @Override
        public void onMessageSendFailed(int messageId) {
            Bundle mResults = new Bundle();
            mResults.putInt("discoverySessionId", mDiscoverySessionId);
            mResults.putInt("messageId", messageId);
            synchronized (mLock) {
                Long startTime = mMessageStartTime.get(messageId);
                if (startTime != null) {
                    mResults.putLong("latencyMs",
                            System.currentTimeMillis() - startTime.longValue());
                    mMessageStartTime.remove(messageId);
                }
            }
            postEvent("WifiAwareSessionOnMessageSendFailed", mResults);
        }

        @Override
        public void onMessageReceived(PeerHandle peerHandle, byte[] message) {
            Bundle mResults = new Bundle();
            mResults.putInt("discoverySessionId", mDiscoverySessionId);
            mResults.putInt("peerId", peerHandle.peerId);
            mResults.putByteArray("message", message); // TODO: base64
            mResults.putString("messageAsString", new String(message));
            postEvent("WifiAwareSessionOnMessageReceived", mResults);
        }
    }

    class WifiAwareRangingListener implements RttManager.RttListener {
        private int mCallbackId;
        private int mSessionId;

        public WifiAwareRangingListener(int callbackId, int sessionId) {
            mCallbackId = callbackId;
            mSessionId = sessionId;
        }

        @Override
        public void onSuccess(RttResult[] results) {
            Bundle bundle = new Bundle();
            bundle.putInt("callbackId", mCallbackId);
            bundle.putInt("sessionId", mSessionId);

            Parcelable[] resultBundles = new Parcelable[results.length];
            for (int i = 0; i < results.length; i++) {
                resultBundles[i] = WifiRttManagerFacade.RangingListener.packRttResult(results[i]);
            }
            bundle.putParcelableArray("Results", resultBundles);

            mEventFacade.postEvent("WifiAwareRangingListenerOnSuccess", bundle);
        }

        @Override
        public void onFailure(int reason, String description) {
            Bundle bundle = new Bundle();
            bundle.putInt("callbackId", mCallbackId);
            bundle.putInt("sessionId", mSessionId);
            bundle.putInt("reason", reason);
            bundle.putString("description", description);
            mEventFacade.postEvent("WifiAwareRangingListenerOnFailure", bundle);
        }

        @Override
        public void onAborted() {
            Bundle bundle = new Bundle();
            bundle.putInt("callbackId", mCallbackId);
            bundle.putInt("sessionId", mSessionId);
            mEventFacade.postEvent("WifiAwareRangingListenerOnAborted", bundle);
        }

    }

    class WifiAwareStateChangedReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context c, Intent intent) {
            boolean isAvailable = mMgr.isAvailable();
            if (!isAvailable) {
                wifiAwareDestroyAll();
            }
            mEventFacade.postEvent(isAvailable ? "WifiAwareAvailable" : "WifiAwareNotAvailable",
                    new Bundle());
        }
    }
}
