1956f54b391677d78379729dd14518edddf3c7660Etan Cohen/*
2956f54b391677d78379729dd14518edddf3c7660Etan Cohen * Copyright (C) 2016 The Android Open Source Project
3956f54b391677d78379729dd14518edddf3c7660Etan Cohen *
4956f54b391677d78379729dd14518edddf3c7660Etan Cohen * Licensed under the Apache License, Version 2.0 (the "License");
5956f54b391677d78379729dd14518edddf3c7660Etan Cohen * you may not use this file except in compliance with the License.
6956f54b391677d78379729dd14518edddf3c7660Etan Cohen * You may obtain a copy of the License at
7956f54b391677d78379729dd14518edddf3c7660Etan Cohen *
8956f54b391677d78379729dd14518edddf3c7660Etan Cohen *      http://www.apache.org/licenses/LICENSE-2.0
9956f54b391677d78379729dd14518edddf3c7660Etan Cohen *
10956f54b391677d78379729dd14518edddf3c7660Etan Cohen * Unless required by applicable law or agreed to in writing, software
11956f54b391677d78379729dd14518edddf3c7660Etan Cohen * distributed under the License is distributed on an "AS IS" BASIS,
12956f54b391677d78379729dd14518edddf3c7660Etan Cohen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13956f54b391677d78379729dd14518edddf3c7660Etan Cohen * See the License for the specific language governing permissions and
14956f54b391677d78379729dd14518edddf3c7660Etan Cohen * limitations under the License.
15956f54b391677d78379729dd14518edddf3c7660Etan Cohen */
16956f54b391677d78379729dd14518edddf3c7660Etan Cohen
17c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohenpackage com.android.server.wifi.aware;
18956f54b391677d78379729dd14518edddf3c7660Etan Cohen
19db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.hardware.wifi.V1_0.NanStatusType;
20c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohenimport android.net.wifi.aware.IWifiAwareDiscoverySessionCallback;
21c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohenimport android.net.wifi.aware.PublishConfig;
22c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohenimport android.net.wifi.aware.SubscribeConfig;
23956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport android.os.RemoteException;
24956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport android.util.Log;
25956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport android.util.SparseArray;
26956f54b391677d78379729dd14518edddf3c7660Etan Cohen
27956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport libcore.util.HexEncoding;
28956f54b391677d78379729dd14518edddf3c7660Etan Cohen
29956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport java.io.FileDescriptor;
30956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport java.io.PrintWriter;
31eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohenimport java.util.Arrays;
32956f54b391677d78379729dd14518edddf3c7660Etan Cohen
33c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen/**
34c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen * Manages the state of a single Aware discovery session (publish or subscribe).
35676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohen * Primary state consists of a callback through which session callbacks are
36c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen * executed as well as state related to currently active discovery sessions:
37c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen * publish/subscribe ID, and MAC address caching (hiding) from clients.
38c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen */
39c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohenpublic class WifiAwareDiscoverySessionState {
40c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen    private static final String TAG = "WifiAwareDiscSessState";
41956f54b391677d78379729dd14518edddf3c7660Etan Cohen    private static final boolean VDBG = false; // STOPSHIP if true
42d187886254382d86f6884f593d851594575acd0cEtan Cohen    /* package */ boolean mDbg = false;
43956f54b391677d78379729dd14518edddf3c7660Etan Cohen
44afca3e98af3129edc899d414301ba7f5b575e9bcEtan Cohen    private static int sNextPeerIdToBeAllocated = 100; // used to create a unique peer ID
45eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen
46db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    private final WifiAwareNativeApi mWifiAwareNativeApi;
47956f54b391677d78379729dd14518edddf3c7660Etan Cohen    private int mSessionId;
480d8e6a7d72e6bd953939dc6976c00eafc08b8fceEtan Cohen    private byte mPubSubId;
49c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen    private IWifiAwareDiscoverySessionCallback mCallback;
5012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    private boolean mIsPublishSession;
5105dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen    private boolean mIsRangingEnabled;
52d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen    private final long mCreationTime;
53956f54b391677d78379729dd14518edddf3c7660Etan Cohen
54eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen    static class PeerInfo {
55eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen        PeerInfo(int instanceId, byte[] mac) {
56eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen            mInstanceId = instanceId;
57eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen            mMac = mac;
58eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen        }
59eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen
60eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen        int mInstanceId;
61eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen        byte[] mMac;
62eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen
63eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen        @Override
64eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen        public String toString() {
65eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen            StringBuilder sb = new StringBuilder("instanceId [");
66eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen            sb.append(mInstanceId).append(", mac=").append(HexEncoding.encode(mMac)).append("]");
67eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen            return sb.toString();
68eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen        }
69eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen    }
70eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen
71eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen    private final SparseArray<PeerInfo> mPeerInfoByRequestorInstanceId = new SparseArray<>();
72956f54b391677d78379729dd14518edddf3c7660Etan Cohen
73db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    public WifiAwareDiscoverySessionState(WifiAwareNativeApi wifiAwareNativeApi, int sessionId,
74d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen            byte pubSubId, IWifiAwareDiscoverySessionCallback callback, boolean isPublishSession,
7505dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen            boolean isRangingEnabled, long creationTime) {
76db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        mWifiAwareNativeApi = wifiAwareNativeApi;
77956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mSessionId = sessionId;
789864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mPubSubId = pubSubId;
79676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohen        mCallback = callback;
8012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mIsPublishSession = isPublishSession;
8105dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        mIsRangingEnabled = isRangingEnabled;
82d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        mCreationTime = creationTime;
83956f54b391677d78379729dd14518edddf3c7660Etan Cohen    }
84956f54b391677d78379729dd14518edddf3c7660Etan Cohen
859864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen    public int getSessionId() {
869864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        return mSessionId;
879864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen    }
889864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
897124382d477741945bdd3af7fec99b702fd1fc23Etan Cohen    public int getPubSubId() {
907124382d477741945bdd3af7fec99b702fd1fc23Etan Cohen        return mPubSubId;
917124382d477741945bdd3af7fec99b702fd1fc23Etan Cohen    }
927124382d477741945bdd3af7fec99b702fd1fc23Etan Cohen
93c2d0f22f7b29507d29e517c329d82a0d30342f44Etan Cohen    public boolean isPublishSession() {
94c2d0f22f7b29507d29e517c329d82a0d30342f44Etan Cohen        return mIsPublishSession;
95c2d0f22f7b29507d29e517c329d82a0d30342f44Etan Cohen    }
96c2d0f22f7b29507d29e517c329d82a0d30342f44Etan Cohen
9705dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen    public boolean isRangingEnabled() {
9805dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen        return mIsRangingEnabled;
9905dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen    }
10005dbaa4579483e9f53f4b6c6e02c02d620f1890fEtan Cohen
101d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen    public long getCreationTime() {
102d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen        return mCreationTime;
103d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen    }
104d8135fd1779f30c7934d87fd65fbfa678db14548Etan Cohen
105c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen    public IWifiAwareDiscoverySessionCallback getCallback() {
1069864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        return mCallback;
1079864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen    }
1089864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
109c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen    /**
110eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen     * Return the peer information of the specified peer ID - or a null if no such peer ID is
1117335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen     * registered.
1127335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen     */
113eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen    public PeerInfo getPeerInfo(int peerId) {
114eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen        return mPeerInfoByRequestorInstanceId.get(peerId);
1157335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen    }
1167335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen
1177335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen    /**
118c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     * Destroy the current discovery session - stops publishing or subscribing
119c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     * if currently active.
120c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     */
12112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    public void terminate() {
1229864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mCallback = null;
12312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
12412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        if (mIsPublishSession) {
125db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            mWifiAwareNativeApi.stopPublish((short) 0, mPubSubId);
12612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        } else {
127db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            mWifiAwareNativeApi.stopSubscribe((short) 0, mPubSubId);
128956f54b391677d78379729dd14518edddf3c7660Etan Cohen        }
129956f54b391677d78379729dd14518edddf3c7660Etan Cohen    }
130956f54b391677d78379729dd14518edddf3c7660Etan Cohen
131c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen    /**
132c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     * Indicates whether the publish/subscribe ID (a HAL ID) corresponds to this
133c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     * session.
134c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     *
135c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     * @param pubSubId The publish/subscribe HAL ID to be tested.
136c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     * @return true if corresponds to this session, false otherwise.
137c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     */
13822b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    public boolean isPubSubIdSession(int pubSubId) {
1399864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        return mPubSubId == pubSubId;
14012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    }
14112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
14212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    /**
14312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * Modify a publish discovery session.
14412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     *
14512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * @param transactionId Transaction ID for the transaction - used in the
14612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     *            async callback to match with the original request.
14712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * @param config Configuration of the publish session.
14812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     */
1499864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen    public boolean updatePublish(short transactionId, PublishConfig config) {
15012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        if (!mIsPublishSession) {
15112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen            Log.e(TAG, "A SUBSCRIBE session is being used to publish");
1529864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen            try {
153db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                mCallback.onSessionConfigFail(NanStatusType.INTERNAL_FAILURE);
1549864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen            } catch (RemoteException e) {
1559864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                Log.e(TAG, "updatePublish: RemoteException=" + e);
1569864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen            }
1579864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen            return false;
15812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        }
159956f54b391677d78379729dd14518edddf3c7660Etan Cohen
1605254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        boolean success = mWifiAwareNativeApi.publish(transactionId, mPubSubId, config);
1615254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        if (!success) {
1625254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen            try {
1635254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen                mCallback.onSessionConfigFail(NanStatusType.INTERNAL_FAILURE);
1645254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen            } catch (RemoteException e) {
1655254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen                Log.w(TAG, "updatePublish onSessionConfigFail(): RemoteException (FYI): " + e);
1665254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen            }
1675254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        }
1685254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen
1695254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        return success;
17012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    }
17112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
17212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    /**
17312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * Modify a subscribe discovery session.
17412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     *
17512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * @param transactionId Transaction ID for the transaction - used in the
17612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     *            async callback to match with the original request.
17712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * @param config Configuration of the subscribe session.
17812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     */
1799864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen    public boolean updateSubscribe(short transactionId, SubscribeConfig config) {
18012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        if (mIsPublishSession) {
18112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen            Log.e(TAG, "A PUBLISH session is being used to subscribe");
1829864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen            try {
183db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                mCallback.onSessionConfigFail(NanStatusType.INTERNAL_FAILURE);
1849864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen            } catch (RemoteException e) {
1859864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                Log.e(TAG, "updateSubscribe: RemoteException=" + e);
1869864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen            }
1879864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen            return false;
18812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        }
189956f54b391677d78379729dd14518edddf3c7660Etan Cohen
1905254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        boolean success = mWifiAwareNativeApi.subscribe(transactionId, mPubSubId, config);
1915254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        if (!success) {
1925254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen            try {
1935254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen                mCallback.onSessionConfigFail(NanStatusType.INTERNAL_FAILURE);
1945254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen            } catch (RemoteException e) {
1955254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen                Log.w(TAG, "updateSubscribe onSessionConfigFail(): RemoteException (FYI): " + e);
1965254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen            }
1975254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        }
1985254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen
1995254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        return success;
200956f54b391677d78379729dd14518edddf3c7660Etan Cohen    }
201956f54b391677d78379729dd14518edddf3c7660Etan Cohen
202c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen    /**
203c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     * Send a message to a peer which is part of a discovery session.
204c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     *
205c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     * @param transactionId Transaction ID for the transaction - used in the
206c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     *            async callback to match with the original request.
207c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     * @param peerId ID of the peer. Obtained through previous communication (a
208c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     *            match indication).
209c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     * @param message Message byte array to send to the peer.
210c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     * @param messageId A message ID provided by caller to be used in any
211c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     *            callbacks related to the message (success/failure).
212c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     */
21380a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen    public boolean sendMessage(short transactionId, int peerId, byte[] message, int messageId) {
214eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen        PeerInfo peerInfo = mPeerInfoByRequestorInstanceId.get(peerId);
215eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen        if (peerInfo == null) {
216956f54b391677d78379729dd14518edddf3c7660Etan Cohen            Log.e(TAG, "sendMessage: attempting to send a message to an address which didn't "
217956f54b391677d78379729dd14518edddf3c7660Etan Cohen                    + "match/contact us");
2189864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen            try {
219db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                mCallback.onMessageSendFail(messageId, NanStatusType.INTERNAL_FAILURE);
2209864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen            } catch (RemoteException e) {
2219864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                Log.e(TAG, "sendMessage: RemoteException=" + e);
2229864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen            }
2239864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen            return false;
224956f54b391677d78379729dd14518edddf3c7660Etan Cohen        }
225956f54b391677d78379729dd14518edddf3c7660Etan Cohen
226eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen        boolean success = mWifiAwareNativeApi.sendMessage(transactionId, mPubSubId,
227eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen                peerInfo.mInstanceId, peerInfo.mMac, message, messageId);
22826f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        if (!success) {
22926f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            try {
23026f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                mCallback.onMessageSendFail(messageId, NanStatusType.INTERNAL_FAILURE);
23126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            } catch (RemoteException e) {
23226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                Log.e(TAG, "sendMessage: RemoteException=" + e);
23326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            }
23426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            return false;
23526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        }
23626f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen
23726f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        return success;
238956f54b391677d78379729dd14518edddf3c7660Etan Cohen    }
239956f54b391677d78379729dd14518edddf3c7660Etan Cohen
240c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen    /**
241c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     * Callback from HAL when a discovery occurs - i.e. when a match to an
242c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     * active subscription request or to a solicited publish request occurs.
243c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     * Propagates to client if registered.
244c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     *
245c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     * @param requestorInstanceId The ID used to identify the peer in this
246c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     *            matched session.
247c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     * @param peerMac The MAC address of the peer. Never propagated to client
248c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     *            due to privacy concerns.
249c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     * @param serviceSpecificInfo Information from the discovery advertisement
250c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     *            (usually not used in the match decisions).
251c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     * @param matchFilter The filter from the discovery advertisement (which was
252c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     *            used in the match decision).
2533709e0d8752b945e19f4c7c9f75b929ee261dfe4Etan Cohen     * @param rangingIndication Bit mask indicating the type of ranging event triggered.
2543709e0d8752b945e19f4c7c9f75b929ee261dfe4Etan Cohen     * @param rangeMm The range to the peer in mm (valid if rangingIndication specifies ingress
2553709e0d8752b945e19f4c7c9f75b929ee261dfe4Etan Cohen     *                or egress events - i.e. non-zero).
256c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     */
257956f54b391677d78379729dd14518edddf3c7660Etan Cohen    public void onMatch(int requestorInstanceId, byte[] peerMac, byte[] serviceSpecificInfo,
2583709e0d8752b945e19f4c7c9f75b929ee261dfe4Etan Cohen            byte[] matchFilter, int rangingIndication, int rangeMm) {
259eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen        int peerId = getPeerIdOrAddIfNew(requestorInstanceId, peerMac);
260956f54b391677d78379729dd14518edddf3c7660Etan Cohen
261956f54b391677d78379729dd14518edddf3c7660Etan Cohen        try {
2623709e0d8752b945e19f4c7c9f75b929ee261dfe4Etan Cohen            if (rangingIndication == 0) {
2633709e0d8752b945e19f4c7c9f75b929ee261dfe4Etan Cohen                mCallback.onMatch(peerId, serviceSpecificInfo, matchFilter);
2643709e0d8752b945e19f4c7c9f75b929ee261dfe4Etan Cohen            } else {
2653709e0d8752b945e19f4c7c9f75b929ee261dfe4Etan Cohen                mCallback.onMatchWithDistance(peerId, serviceSpecificInfo, matchFilter, rangeMm);
2663709e0d8752b945e19f4c7c9f75b929ee261dfe4Etan Cohen            }
267956f54b391677d78379729dd14518edddf3c7660Etan Cohen        } catch (RemoteException e) {
268956f54b391677d78379729dd14518edddf3c7660Etan Cohen            Log.w(TAG, "onMatch: RemoteException (FYI): " + e);
269956f54b391677d78379729dd14518edddf3c7660Etan Cohen        }
270956f54b391677d78379729dd14518edddf3c7660Etan Cohen    }
271956f54b391677d78379729dd14518edddf3c7660Etan Cohen
272c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen    /**
273c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     * Callback from HAL when a message is received from a peer in a discovery
274c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     * session. Propagated to client if registered.
275c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     *
276c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     * @param requestorInstanceId An ID used to identify the peer.
277c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     * @param peerMac The MAC address of the peer sending the message. This
278c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     *            information is never propagated to the client due to privacy
279c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     *            concerns.
280c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     * @param message The received message.
281c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     */
28280a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen    public void onMessageReceived(int requestorInstanceId, byte[] peerMac, byte[] message) {
283eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen        int peerId = getPeerIdOrAddIfNew(requestorInstanceId, peerMac);
284956f54b391677d78379729dd14518edddf3c7660Etan Cohen
285956f54b391677d78379729dd14518edddf3c7660Etan Cohen        try {
286eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen            mCallback.onMessageReceived(peerId, message);
287956f54b391677d78379729dd14518edddf3c7660Etan Cohen        } catch (RemoteException e) {
288956f54b391677d78379729dd14518edddf3c7660Etan Cohen            Log.w(TAG, "onMessageReceived: RemoteException (FYI): " + e);
289956f54b391677d78379729dd14518edddf3c7660Etan Cohen        }
290956f54b391677d78379729dd14518edddf3c7660Etan Cohen    }
291956f54b391677d78379729dd14518edddf3c7660Etan Cohen
292eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen    private int getPeerIdOrAddIfNew(int requestorInstanceId, byte[] peerMac) {
293eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen        for (int i = 0; i < mPeerInfoByRequestorInstanceId.size(); ++i) {
294eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen            PeerInfo peerInfo = mPeerInfoByRequestorInstanceId.valueAt(i);
295eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen            if (peerInfo.mInstanceId == requestorInstanceId && Arrays.equals(peerMac,
296eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen                    peerInfo.mMac)) {
297eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen                return mPeerInfoByRequestorInstanceId.keyAt(i);
298eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen            }
299eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen        }
300eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen
301afca3e98af3129edc899d414301ba7f5b575e9bcEtan Cohen        int newPeerId = sNextPeerIdToBeAllocated++;
302eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen        PeerInfo newPeerInfo = new PeerInfo(requestorInstanceId, peerMac);
303eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen        mPeerInfoByRequestorInstanceId.put(newPeerId, newPeerInfo);
304eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen
305d187886254382d86f6884f593d851594575acd0cEtan Cohen        if (VDBG) {
306d187886254382d86f6884f593d851594575acd0cEtan Cohen            Log.v(TAG, "New peer info: peerId=" + newPeerId + ", peerInfo=" + newPeerInfo);
307eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen        }
308eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen
309eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen        return newPeerId;
310eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen    }
311eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen
312c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen    /**
313c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     * Dump the internal state of the class.
314c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     */
315956f54b391677d78379729dd14518edddf3c7660Etan Cohen    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
316c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        pw.println("AwareSessionState:");
317956f54b391677d78379729dd14518edddf3c7660Etan Cohen        pw.println("  mSessionId: " + mSessionId);
31812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        pw.println("  mIsPublishSession: " + mIsPublishSession);
3199864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        pw.println("  mPubSubId: " + mPubSubId);
320eddf3faabf426d18b7d3dff187ec91fe6a96665dEtan Cohen        pw.println("  mPeerInfoByRequestorInstanceId: [" + mPeerInfoByRequestorInstanceId + "]");
321956f54b391677d78379729dd14518edddf3c7660Etan Cohen    }
322956f54b391677d78379729dd14518edddf3c7660Etan Cohen}
323