1 /*
2  * Copyright (C) 2016 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.nan;
18 
19 import static org.hamcrest.core.IsEqual.equalTo;
20 import static org.mockito.Matchers.eq;
21 import static org.mockito.Mockito.verify;
22 import static org.mockito.Mockito.verifyZeroInteractions;
23 
24 import android.net.wifi.nan.ConfigRequest;
25 import android.net.wifi.nan.PublishData;
26 import android.net.wifi.nan.PublishSettings;
27 import android.net.wifi.nan.SubscribeData;
28 import android.net.wifi.nan.SubscribeSettings;
29 import android.net.wifi.nan.TlvBufferUtils;
30 import android.net.wifi.nan.WifiNanSessionListener;
31 import android.os.Bundle;
32 import android.test.suitebuilder.annotation.SmallTest;
33 
34 import com.android.server.wifi.HalMockUtils;
35 import com.android.server.wifi.WifiNative;
36 
37 import libcore.util.HexEncoding;
38 
39 import org.json.JSONException;
40 import org.junit.Before;
41 import org.junit.Rule;
42 import org.junit.Test;
43 import org.junit.rules.ErrorCollector;
44 import org.mockito.ArgumentCaptor;
45 import org.mockito.Mock;
46 import org.mockito.MockitoAnnotations;
47 
48 import java.lang.reflect.Field;
49 import java.util.Arrays;
50 
51 /**
52  * Unit test harness for WifiNanNative + JNI code interfacing to the HAL.
53  */
54 @SmallTest
55 public class WifiNanHalTest {
56     private WifiNanNative mDut = WifiNanNative.getInstance();
57     private ArgumentCaptor<String> mArgs = ArgumentCaptor.forClass(String.class);
58 
59     @Mock
60     private WifiNanHalMock mNanHalMock;
61     @Mock private WifiNanStateManager mNanStateManager;
62 
63     @Rule
64     public ErrorCollector collector = new ErrorCollector();
65 
66     @Before
setup()67     public void setup() throws Exception {
68         MockitoAnnotations.initMocks(this);
69 
70         HalMockUtils.initHalMockLibrary();
71         WifiNanHalMock.initNanHalMockLibrary();
72         WifiNanNative.initNanHandlersNative(WifiNative.class, WifiNative.sWlan0Index);
73         HalMockUtils.setHalMockObject(mNanHalMock);
74         installMockNanStateManager(mNanStateManager);
75     }
76 
77     @Test
testEnableWith5g()78     public void testEnableWith5g() throws JSONException {
79         final short transactionId = 2346;
80         final int clusterLow = 23;
81         final int clusterHigh = 126;
82         final int masterPref = 234;
83         final boolean enable5g = true;
84 
85         testEnable(transactionId, clusterLow, clusterHigh, masterPref, enable5g);
86     }
87 
88     @Test
testEnableWithout5g()89     public void testEnableWithout5g() throws JSONException {
90         final short transactionId = 1296;
91         final int clusterLow = 17;
92         final int clusterHigh = 197;
93         final int masterPref = 33;
94         final boolean enable5g = false;
95 
96         testEnable(transactionId, clusterLow, clusterHigh, masterPref, enable5g);
97     }
98 
99     @Test
testDisable()100     public void testDisable() {
101         final short transactionId = 5478;
102 
103         mDut.disable(transactionId);
104 
105         verify(mNanHalMock).disableHalMockNative(transactionId);
106     }
107 
108     @Test
testPublishUnsolicited()109     public void testPublishUnsolicited() throws JSONException {
110         final short transactionId = 55;
111         final int publishId = 23;
112         final String serviceName = "some-service-name";
113         final String ssi = "some much longer and more arbitrary data";
114         final int publishCount = 7;
115         final int publishTtl = 66;
116 
117         TlvBufferUtils.TlvConstructor tlvTx = new TlvBufferUtils.TlvConstructor(0, 1);
118         tlvTx.allocate(150).putByte(0, (byte) 10).putInt(0, 100).putString(0, "some string")
119                 .putZeroLengthElement(0);
120 
121         TlvBufferUtils.TlvConstructor tlvRx = new TlvBufferUtils.TlvConstructor(0, 1);
122         tlvRx.allocate(150).putByte(0, (byte) 66).putInt(0, 127).putString(0, "some other string")
123                 .putZeroLengthElement(0).putByteArray(0, serviceName.getBytes());
124 
125         testPublish(transactionId, publishId, PublishSettings.PUBLISH_TYPE_UNSOLICITED, serviceName,
126                 ssi, tlvTx, tlvRx, publishCount, publishTtl);
127     }
128 
129     @Test
testPublishSolicited()130     public void testPublishSolicited() throws JSONException {
131         final short transactionId = 45;
132         final int publishId = 17;
133         final String serviceName = "some-service-name-or-another";
134         final String ssi = "some much longer arbitrary data";
135         final int publishCount = 32;
136         final int publishTtl = 33;
137 
138         TlvBufferUtils.TlvConstructor tlvTx = new TlvBufferUtils.TlvConstructor(0, 1);
139         tlvTx.allocate(150).putByte(0, (byte) 10).putInt(0, 100).putString(0, "some string")
140                 .putZeroLengthElement(0);
141 
142         TlvBufferUtils.TlvConstructor tlvRx = new TlvBufferUtils.TlvConstructor(0, 1);
143         tlvRx.allocate(150).putByte(0, (byte) 66).putInt(0, 127).putString(0, "some other string")
144                 .putZeroLengthElement(0).putByteArray(0, serviceName.getBytes());
145 
146         testPublish(transactionId, publishId, PublishSettings.PUBLISH_TYPE_SOLICITED, serviceName,
147                 ssi, tlvTx, tlvRx, publishCount, publishTtl);
148     }
149 
150     @Test
testPublishCancel()151     public void testPublishCancel() throws JSONException {
152         final short transactionId = 12;
153         final int publishId = 15;
154 
155         mDut.stopPublish(transactionId, publishId);
156 
157         verify(mNanHalMock).publishCancelHalMockNative(eq(transactionId), mArgs.capture());
158 
159         Bundle argsData = HalMockUtils.convertJsonToBundle(mArgs.getValue());
160 
161         collector.checkThat("publish_id", argsData.getInt("publish_id"), equalTo(publishId));
162     }
163 
164     @Test
testSubscribePassive()165     public void testSubscribePassive() throws JSONException {
166         final short transactionId = 45;
167         final int subscribeId = 17;
168         final String serviceName = "some-service-name-or-another";
169         final String ssi = "some much longer arbitrary data";
170         final int subscribeCount = 32;
171         final int subscribeTtl = 33;
172 
173         TlvBufferUtils.TlvConstructor tlvTx = new TlvBufferUtils.TlvConstructor(0, 1);
174         tlvTx.allocate(150).putByte(0, (byte) 10).putInt(0, 100).putString(0, "some string")
175                 .putZeroLengthElement(0);
176 
177         TlvBufferUtils.TlvConstructor tlvRx = new TlvBufferUtils.TlvConstructor(0, 1);
178         tlvRx.allocate(150).putByte(0, (byte) 66).putInt(0, 127).putString(0, "some other string")
179                 .putZeroLengthElement(0).putByteArray(0, serviceName.getBytes());
180 
181         testSubscribe(transactionId, subscribeId, SubscribeSettings.SUBSCRIBE_TYPE_PASSIVE,
182                 serviceName, ssi, tlvTx, tlvRx, subscribeCount, subscribeTtl);
183     }
184 
185     @Test
testSubscribeActive()186     public void testSubscribeActive() throws JSONException {
187         final short transactionId = 45;
188         final int subscribeId = 17;
189         final String serviceName = "some-service-name-or-another";
190         final String ssi = "some much longer arbitrary data";
191         final int subscribeCount = 32;
192         final int subscribeTtl = 33;
193 
194         TlvBufferUtils.TlvConstructor tlvTx = new TlvBufferUtils.TlvConstructor(0, 1);
195         tlvTx.allocate(150).putByte(0, (byte) 10).putInt(0, 100).putString(0, "some string")
196                 .putZeroLengthElement(0);
197 
198         TlvBufferUtils.TlvConstructor tlvRx = new TlvBufferUtils.TlvConstructor(0, 1);
199         tlvRx.allocate(150).putByte(0, (byte) 66).putInt(0, 127).putString(0, "some other string")
200                 .putZeroLengthElement(0).putByteArray(0, serviceName.getBytes());
201 
202         testSubscribe(transactionId, subscribeId, SubscribeSettings.SUBSCRIBE_TYPE_ACTIVE,
203                 serviceName, ssi, tlvTx, tlvRx, subscribeCount, subscribeTtl);
204     }
205 
206     @Test
testSubscribeCancel()207     public void testSubscribeCancel() throws JSONException {
208         final short transactionId = 12;
209         final int subscribeId = 15;
210 
211         mDut.stopSubscribe(transactionId, subscribeId);
212 
213         verify(mNanHalMock).subscribeCancelHalMockNative(eq(transactionId), mArgs.capture());
214 
215         Bundle argsData = HalMockUtils.convertJsonToBundle(mArgs.getValue());
216 
217         collector.checkThat("subscribe_id", argsData.getInt("subscribe_id"), equalTo(subscribeId));
218     }
219 
220     @Test
testSendMessage()221     public void testSendMessage() throws JSONException {
222         final short transactionId = 45;
223         final int pubSubId = 22;
224         final int reqInstanceId = 11;
225         final byte[] peer = HexEncoding.decode("000102030405".toCharArray(), false);
226         final String msg = "Hello there - how are you doing?";
227 
228         mDut.sendMessage(transactionId, pubSubId, reqInstanceId, peer, msg.getBytes(),
229                 msg.length());
230 
231         verify(mNanHalMock).transmitFollowupHalMockNative(eq(transactionId), mArgs.capture());
232 
233         Bundle argsData = HalMockUtils.convertJsonToBundle(mArgs.getValue());
234 
235         collector.checkThat("publish_subscribe_id", argsData.getInt("publish_subscribe_id"),
236                 equalTo(pubSubId));
237         collector.checkThat("requestor_instance_id", argsData.getInt("requestor_instance_id"),
238                 equalTo(reqInstanceId));
239         collector.checkThat("addr", argsData.getByteArray("addr"), equalTo(peer));
240         collector.checkThat("priority", argsData.getInt("priority"), equalTo(0));
241         collector.checkThat("dw_or_faw", argsData.getInt("dw_or_faw"), equalTo(0));
242         collector.checkThat("service_specific_info_len",
243                 argsData.getInt("service_specific_info_len"), equalTo(msg.length()));
244         collector.checkThat("service_specific_info", argsData.getByteArray("service_specific_info"),
245                 equalTo(msg.getBytes()));
246     }
247 
248     @Test
testNotifyCapabilities()249     public void testNotifyCapabilities() throws JSONException {
250         final short transactionId = 23;
251         final int max_concurrent_nan_clusters = 1;
252         final int max_publishes = 2;
253         final int max_subscribes = 3;
254         final int max_service_name_len = 4;
255         final int max_match_filter_len = 5;
256         final int max_total_match_filter_len = 6;
257         final int max_service_specific_info_len = 7;
258         final int max_vsa_data_len = 8;
259         final int max_mesh_data_len = 9;
260         final int max_ndi_interfaces = 10;
261         final int max_ndp_sessions = 11;
262         final int max_app_info_len = 12;
263 
264         ArgumentCaptor<WifiNanNative.Capabilities> capabilitiesCapture = ArgumentCaptor
265                 .forClass(WifiNanNative.Capabilities.class);
266 
267         Bundle args = new Bundle();
268         args.putInt("status", WifiNanNative.NAN_STATUS_SUCCESS);
269         args.putInt("value", 0);
270         args.putInt("response_type", WifiNanNative.NAN_RESPONSE_GET_CAPABILITIES);
271 
272         args.putInt("body.nan_capabilities.max_concurrent_nan_clusters",
273                 max_concurrent_nan_clusters);
274         args.putInt("body.nan_capabilities.max_publishes", max_publishes);
275         args.putInt("body.nan_capabilities.max_subscribes", max_subscribes);
276         args.putInt("body.nan_capabilities.max_service_name_len", max_service_name_len);
277         args.putInt("body.nan_capabilities.max_match_filter_len", max_match_filter_len);
278         args.putInt("body.nan_capabilities.max_total_match_filter_len", max_total_match_filter_len);
279         args.putInt("body.nan_capabilities.max_service_specific_info_len",
280                 max_service_specific_info_len);
281         args.putInt("body.nan_capabilities.max_vsa_data_len", max_vsa_data_len);
282         args.putInt("body.nan_capabilities.max_mesh_data_len", max_mesh_data_len);
283         args.putInt("body.nan_capabilities.max_ndi_interfaces", max_ndi_interfaces);
284         args.putInt("body.nan_capabilities.max_ndp_sessions", max_ndp_sessions);
285         args.putInt("body.nan_capabilities.max_app_info_len", max_app_info_len);
286 
287         WifiNanHalMock.callNotifyResponse(transactionId,
288                 HalMockUtils.convertBundleToJson(args).toString());
289 
290         verify(mNanStateManager).onCapabilitiesUpdate(eq(transactionId),
291                 capabilitiesCapture.capture());
292         WifiNanNative.Capabilities capabilities = capabilitiesCapture.getValue();
293         collector.checkThat("max_concurrent_nan_clusters", capabilities.maxConcurrentNanClusters,
294                 equalTo(max_concurrent_nan_clusters));
295         collector.checkThat("max_publishes", capabilities.maxPublishes, equalTo(max_publishes));
296         collector.checkThat("max_subscribes", capabilities.maxSubscribes, equalTo(max_subscribes));
297         collector.checkThat("max_service_name_len", capabilities.maxServiceNameLen,
298                 equalTo(max_service_name_len));
299         collector.checkThat("max_match_filter_len", capabilities.maxMatchFilterLen,
300                 equalTo(max_match_filter_len));
301         collector.checkThat("max_total_match_filter_len", capabilities.maxTotalMatchFilterLen,
302                 equalTo(max_total_match_filter_len));
303         collector.checkThat("max_service_specific_info_len", capabilities.maxServiceSpecificInfoLen,
304                 equalTo(max_service_specific_info_len));
305         collector.checkThat("max_vsa_data_len", capabilities.maxVsaDataLen,
306                 equalTo(max_vsa_data_len));
307         collector.checkThat("max_mesh_data_len", capabilities.maxMeshDataLen,
308                 equalTo(max_mesh_data_len));
309         collector.checkThat("max_ndi_interfaces", capabilities.maxNdiInterfaces,
310                 equalTo(max_ndi_interfaces));
311         collector.checkThat("max_ndp_sessions", capabilities.maxNdpSessions,
312                 equalTo(max_ndp_sessions));
313         collector.checkThat("max_app_info_len", capabilities.maxAppInfoLen,
314                 equalTo(max_app_info_len));
315     }
316 
317     @Test
testNotifyResponseConfigSuccess()318     public void testNotifyResponseConfigSuccess() throws JSONException {
319         final short transactionId = 23;
320 
321         Bundle args = new Bundle();
322         args.putInt("status", WifiNanNative.NAN_STATUS_SUCCESS);
323         args.putInt("value", 0);
324         args.putInt("response_type", WifiNanNative.NAN_RESPONSE_ENABLED);
325 
326         WifiNanHalMock.callNotifyResponse(transactionId,
327                 HalMockUtils.convertBundleToJson(args).toString());
328 
329         verify(mNanStateManager).onConfigCompleted(transactionId);
330     }
331 
332     @Test
testNotifyResponseConfigFail()333     public void testNotifyResponseConfigFail() throws JSONException {
334         final short transactionId = 23;
335 
336         Bundle args = new Bundle();
337         args.putInt("status", WifiNanNative.NAN_STATUS_INVALID_BAND_CONFIG_FLAGS);
338         args.putInt("value", 0);
339         args.putInt("response_type", WifiNanNative.NAN_RESPONSE_ENABLED);
340 
341         WifiNanHalMock.callNotifyResponse(transactionId,
342                 HalMockUtils.convertBundleToJson(args).toString());
343 
344         verify(mNanStateManager).onConfigFailed(transactionId,
345                 WifiNanSessionListener.FAIL_REASON_INVALID_ARGS);
346     }
347 
348     @Test
testNotifyResponsePublishSuccess()349     public void testNotifyResponsePublishSuccess() throws JSONException {
350         final short transactionId = 23;
351         final int publishId = 127;
352 
353         Bundle args = new Bundle();
354         args.putInt("status", WifiNanNative.NAN_STATUS_SUCCESS);
355         args.putInt("value", 0);
356         args.putInt("response_type", WifiNanNative.NAN_RESPONSE_PUBLISH);
357         args.putInt("body.publish_response.publish_id", publishId);
358 
359         WifiNanHalMock.callNotifyResponse(transactionId,
360                 HalMockUtils.convertBundleToJson(args).toString());
361 
362         verify(mNanStateManager).onPublishSuccess(transactionId, publishId);
363     }
364 
365     @Test
testNotifyResponsePublishFail()366     public void testNotifyResponsePublishFail() throws JSONException {
367         final short transactionId = 23;
368         final int publishId = 127;
369 
370         Bundle args = new Bundle();
371         args.putInt("status", WifiNanNative.NAN_STATUS_NO_SPACE_AVAILABLE);
372         args.putInt("value", 57);
373         args.putInt("response_type", WifiNanNative.NAN_RESPONSE_PUBLISH);
374         args.putInt("body.publish_response.publish_id", publishId);
375 
376         WifiNanHalMock.callNotifyResponse(transactionId,
377                 HalMockUtils.convertBundleToJson(args).toString());
378 
379         verify(mNanStateManager).onPublishFail(transactionId,
380                 WifiNanSessionListener.FAIL_REASON_NO_RESOURCES);
381     }
382 
383     @Test
testNotifyResponsePublishCancel()384     public void testNotifyResponsePublishCancel() throws JSONException {
385         final short transactionId = 23;
386         final int publishId = 127;
387 
388         Bundle args = new Bundle();
389         args.putInt("status", WifiNanNative.NAN_STATUS_SUCCESS);
390         args.putInt("value", 0);
391         args.putInt("response_type", WifiNanNative.NAN_RESPONSE_PUBLISH_CANCEL);
392 
393         WifiNanHalMock.callNotifyResponse(transactionId,
394                 HalMockUtils.convertBundleToJson(args).toString());
395 
396         verifyZeroInteractions(mNanStateManager);
397     }
398 
399     @Test
testNotifyResponseSubscribeSuccess()400     public void testNotifyResponseSubscribeSuccess() throws JSONException {
401         final short transactionId = 17;
402         final int subscribeId = 198;
403 
404         Bundle args = new Bundle();
405         args.putInt("status", WifiNanNative.NAN_STATUS_SUCCESS);
406         args.putInt("value", 0);
407         args.putInt("response_type", WifiNanNative.NAN_RESPONSE_SUBSCRIBE);
408         args.putInt("body.subscribe_response.subscribe_id", subscribeId);
409 
410         WifiNanHalMock.callNotifyResponse(transactionId,
411                 HalMockUtils.convertBundleToJson(args).toString());
412 
413         verify(mNanStateManager).onSubscribeSuccess(transactionId, subscribeId);
414     }
415 
416     @Test
testNotifyResponseSubscribeFail()417     public void testNotifyResponseSubscribeFail() throws JSONException {
418         final short transactionId = 17;
419         final int subscribeId = 198;
420 
421         Bundle args = new Bundle();
422         args.putInt("status", WifiNanNative.NAN_STATUS_DE_FAILURE);
423         args.putInt("value", 0);
424         args.putInt("response_type", WifiNanNative.NAN_RESPONSE_SUBSCRIBE);
425         args.putInt("body.subscribe_response.subscribe_id", subscribeId);
426 
427         WifiNanHalMock.callNotifyResponse(transactionId,
428                 HalMockUtils.convertBundleToJson(args).toString());
429 
430         verify(mNanStateManager).onSubscribeFail(transactionId,
431                 WifiNanSessionListener.FAIL_REASON_OTHER);
432     }
433 
434     @Test
testNotifyResponseSubscribeCancel()435     public void testNotifyResponseSubscribeCancel() throws JSONException {
436         final short transactionId = 23;
437         final int subscribeId = 127;
438 
439         Bundle args = new Bundle();
440         args.putInt("status", WifiNanNative.NAN_STATUS_SUCCESS);
441         args.putInt("value", 0);
442         args.putInt("response_type", WifiNanNative.NAN_RESPONSE_SUBSCRIBE_CANCEL);
443 
444         WifiNanHalMock.callNotifyResponse(transactionId,
445                 HalMockUtils.convertBundleToJson(args).toString());
446 
447         verifyZeroInteractions(mNanStateManager);
448     }
449 
450     @Test
testNotifyResponseTransmitFollowupSuccess()451     public void testNotifyResponseTransmitFollowupSuccess() throws JSONException {
452         final short transactionId = 23;
453 
454         Bundle args = new Bundle();
455         args.putInt("status", WifiNanNative.NAN_STATUS_SUCCESS);
456         args.putInt("value", 0);
457         args.putInt("response_type", WifiNanNative.NAN_RESPONSE_TRANSMIT_FOLLOWUP);
458 
459         WifiNanHalMock.callNotifyResponse(transactionId,
460                 HalMockUtils.convertBundleToJson(args).toString());
461 
462         verify(mNanStateManager).onMessageSendSuccess(transactionId);
463     }
464 
465     @Test
testNotifyResponseTransmitFollowupFail()466     public void testNotifyResponseTransmitFollowupFail() throws JSONException {
467         final short transactionId = 45;
468 
469         Bundle args = new Bundle();
470         args.putInt("status", WifiNanNative.NAN_STATUS_TIMEOUT);
471         args.putInt("value", 0);
472         args.putInt("response_type", WifiNanNative.NAN_RESPONSE_TRANSMIT_FOLLOWUP);
473 
474         WifiNanHalMock.callNotifyResponse(transactionId,
475                 HalMockUtils.convertBundleToJson(args).toString());
476 
477         verify(mNanStateManager).onMessageSendFail(transactionId,
478                 WifiNanSessionListener.FAIL_REASON_OTHER);
479     }
480 
481     @Test
testPublishTerminatedDone()482     public void testPublishTerminatedDone() throws JSONException {
483         final int publishId = 167;
484 
485         Bundle args = new Bundle();
486         args.putInt("publish_id", publishId);
487         args.putInt("reason", WifiNanNative.NAN_TERMINATED_REASON_COUNT_REACHED);
488 
489         WifiNanHalMock.callPublishTerminated(HalMockUtils.convertBundleToJson(args).toString());
490 
491         verify(mNanStateManager).onPublishTerminated(publishId,
492                 WifiNanSessionListener.TERMINATE_REASON_DONE);
493     }
494 
495     @Test
testSubscribeTerminatedFail()496     public void testSubscribeTerminatedFail() throws JSONException {
497         final int subscribeId = 167;
498 
499         Bundle args = new Bundle();
500         args.putInt("subscribe_id", subscribeId);
501         args.putInt("reason", WifiNanNative.NAN_TERMINATED_REASON_FAILURE);
502 
503         WifiNanHalMock.callSubscribeTerminated(HalMockUtils.convertBundleToJson(args).toString());
504 
505         verify(mNanStateManager).onSubscribeTerminated(subscribeId,
506                 WifiNanSessionListener.TERMINATE_REASON_FAIL);
507     }
508 
509     @Test
testFollowup()510     public void testFollowup() throws JSONException {
511         final int pubSubId = 236;
512         final int reqInstanceId = 57;
513         final byte[] peer = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false);
514         final String message = "this is some message received from some peer - hello!";
515 
516         Bundle args = new Bundle();
517         args.putInt("publish_subscribe_id", pubSubId);
518         args.putInt("requestor_instance_id", reqInstanceId);
519         args.putByteArray("addr", peer);
520         args.putInt("dw_or_faw", 0);
521         args.putInt("service_specific_info_len", message.length());
522         args.putByteArray("service_specific_info", message.getBytes());
523 
524         WifiNanHalMock.callFollowup(HalMockUtils.convertBundleToJson(args).toString());
525 
526         verify(mNanStateManager).onMessageReceived(pubSubId, reqInstanceId, peer,
527                 message.getBytes(), message.length());
528     }
529 
530     @Test
testMatch()531     public void testMatch() throws JSONException {
532         final int pubSubId = 287;
533         final int reqInstanceId = 98;
534         final byte[] peer = HexEncoding.decode("010203040506".toCharArray(), false);
535         final String ssi = "some service specific info - really arbitrary";
536         final String filter = "most likely binary - but faking here with some string data";
537 
538         Bundle args = new Bundle();
539         args.putInt("publish_subscribe_id", pubSubId);
540         args.putInt("requestor_instance_id", reqInstanceId);
541         args.putByteArray("addr", peer);
542         args.putInt("service_specific_info_len", ssi.length());
543         args.putByteArray("service_specific_info", ssi.getBytes());
544         args.putInt("sdf_match_filter_len", filter.length());
545         args.putByteArray("sdf_match_filter", filter.getBytes());
546 
547         WifiNanHalMock.callMatch(HalMockUtils.convertBundleToJson(args).toString());
548 
549         verify(mNanStateManager).onMatch(pubSubId, reqInstanceId, peer, ssi.getBytes(),
550                 ssi.length(), filter.getBytes(), filter.length());
551     }
552 
553     @Test
testDiscoveryInterfaceChange()554     public void testDiscoveryInterfaceChange() throws JSONException {
555         final byte[] mac = HexEncoding.decode("060504030201".toCharArray(), false);
556 
557         Bundle args = new Bundle();
558         args.putInt("event_type", WifiNanNative.NAN_EVENT_ID_DISC_MAC_ADDR);
559         args.putByteArray("data", mac);
560 
561         WifiNanHalMock.callDiscEngEvent(HalMockUtils.convertBundleToJson(args).toString());
562 
563         verify(mNanStateManager).onInterfaceAddressChange(mac);
564     }
565 
566     @Test
testClusterChange()567     public void testClusterChange() throws JSONException {
568         final byte[] mac = HexEncoding.decode("060504030201".toCharArray(), false);
569 
570         Bundle args = new Bundle();
571         args.putInt("event_type", WifiNanNative.NAN_EVENT_ID_JOINED_CLUSTER);
572         args.putByteArray("data", mac);
573 
574         WifiNanHalMock.callDiscEngEvent(HalMockUtils.convertBundleToJson(args).toString());
575 
576         verify(mNanStateManager).onClusterChange(WifiNanClientState.CLUSTER_CHANGE_EVENT_JOINED,
577                 mac);
578     }
579 
580     @Test
testDisabled()581     public void testDisabled() throws JSONException {
582         Bundle args = new Bundle();
583         args.putInt("reason", WifiNanNative.NAN_STATUS_DE_FAILURE);
584 
585         WifiNanHalMock.callDisabled(HalMockUtils.convertBundleToJson(args).toString());
586 
587         verify(mNanStateManager).onNanDown(WifiNanSessionListener.FAIL_REASON_OTHER);
588     }
589 
590     /*
591      * Utilities
592      */
593 
testEnable(short transactionId, int clusterLow, int clusterHigh, int masterPref, boolean enable5g)594     private void testEnable(short transactionId, int clusterLow, int clusterHigh, int masterPref,
595             boolean enable5g) throws JSONException {
596         ConfigRequest configRequest = new ConfigRequest.Builder().setClusterLow(clusterLow)
597                 .setClusterHigh(clusterHigh).setMasterPreference(masterPref)
598                 .setSupport5gBand(enable5g).build();
599 
600         mDut.enableAndConfigure(transactionId, configRequest);
601 
602         verify(mNanHalMock).enableHalMockNative(eq(transactionId), mArgs.capture());
603 
604         Bundle argsData = HalMockUtils.convertJsonToBundle(mArgs.getValue());
605 
606         collector.checkThat("master_pref", argsData.getInt("master_pref"), equalTo(masterPref));
607         collector.checkThat("cluster_low", argsData.getInt("cluster_low"), equalTo(clusterLow));
608         collector.checkThat("cluster_high", argsData.getInt("cluster_high"), equalTo(clusterHigh));
609         collector.checkThat("config_support_5g", argsData.getInt("config_support_5g"), equalTo(1));
610         collector.checkThat("support_5g_val", argsData.getInt("support_5g_val"),
611                 equalTo(enable5g ? 1 : 0));
612 
613         collector.checkThat("config_sid_beacon", argsData.getInt("config_sid_beacon"), equalTo(0));
614         collector.checkThat("config_2dot4g_rssi_close", argsData.getInt("config_2dot4g_rssi_close"),
615                 equalTo(0));
616         collector.checkThat("config_2dot4g_rssi_middle",
617                 argsData.getInt("config_2dot4g_rssi_middle"), equalTo(0));
618         collector.checkThat("config_2dot4g_rssi_proximity",
619                 argsData.getInt("config_2dot4g_rssi_proximity"), equalTo(0));
620         collector.checkThat("config_hop_count_limit", argsData.getInt("config_hop_count_limit"),
621                 equalTo(0));
622         collector.checkThat("config_2dot4g_support", argsData.getInt("config_2dot4g_support"),
623                 equalTo(0));
624         collector.checkThat("config_2dot4g_beacons", argsData.getInt("config_2dot4g_beacons"),
625                 equalTo(0));
626         collector.checkThat("config_2dot4g_sdf", argsData.getInt("config_2dot4g_sdf"), equalTo(0));
627         collector.checkThat("config_5g_beacons", argsData.getInt("config_5g_beacons"), equalTo(0));
628         collector.checkThat("config_5g_sdf", argsData.getInt("config_5g_sdf"), equalTo(0));
629         collector.checkThat("config_5g_rssi_close", argsData.getInt("config_5g_rssi_close"),
630                 equalTo(0));
631         collector.checkThat("config_5g_rssi_middle", argsData.getInt("config_5g_rssi_middle"),
632                 equalTo(0));
633         collector.checkThat("config_5g_rssi_close_proximity",
634                 argsData.getInt("config_5g_rssi_close_proximity"), equalTo(0));
635         collector.checkThat("config_rssi_window_size", argsData.getInt("config_rssi_window_size"),
636                 equalTo(0));
637         collector.checkThat("config_oui", argsData.getInt("config_oui"), equalTo(0));
638         collector.checkThat("config_intf_addr", argsData.getInt("config_intf_addr"), equalTo(0));
639         collector.checkThat("config_cluster_attribute_val",
640                 argsData.getInt("config_cluster_attribute_val"), equalTo(0));
641         collector.checkThat("config_scan_params", argsData.getInt("config_scan_params"),
642                 equalTo(0));
643         collector.checkThat("config_random_factor_force",
644                 argsData.getInt("config_random_factor_force"), equalTo(0));
645         collector.checkThat("config_hop_count_force", argsData.getInt("config_hop_count_force"),
646                 equalTo(0));
647     }
648 
testPublish(short transactionId, int publishId, int publishType, String serviceName, String ssi, TlvBufferUtils.TlvConstructor tlvTx, TlvBufferUtils.TlvConstructor tlvRx, int publishCount, int publishTtl)649     private void testPublish(short transactionId, int publishId, int publishType,
650             String serviceName, String ssi, TlvBufferUtils.TlvConstructor tlvTx,
651             TlvBufferUtils.TlvConstructor tlvRx, int publishCount, int publishTtl)
652                     throws JSONException {
653         PublishData publishData = new PublishData.Builder().setServiceName(serviceName)
654                 .setServiceSpecificInfo(ssi)
655                 .setTxFilter(tlvTx.getArray(), tlvTx.getActualLength())
656                 .setRxFilter(tlvRx.getArray(), tlvRx.getActualLength()).build();
657 
658         PublishSettings publishSettings = new PublishSettings.Builder().setPublishType(publishType)
659                 .setPublishCount(publishCount).setTtlSec(publishTtl).build();
660 
661         mDut.publish(transactionId, publishId, publishData, publishSettings);
662 
663         verify(mNanHalMock).publishHalMockNative(eq(transactionId), mArgs.capture());
664 
665         Bundle argsData = HalMockUtils.convertJsonToBundle(mArgs.getValue());
666 
667         collector.checkThat("publish_id", argsData.getInt("publish_id"), equalTo(publishId));
668         collector.checkThat("ttl", argsData.getInt("ttl"), equalTo(publishTtl));
669         collector.checkThat("publish_type", argsData.getInt("publish_type"), equalTo(publishType));
670         collector.checkThat("tx_type", argsData.getInt("tx_type"),
671                 equalTo(publishType == PublishSettings.PUBLISH_TYPE_UNSOLICITED ? 0 : 1));
672         collector.checkThat("publish_count", argsData.getInt("publish_count"),
673                 equalTo(publishCount));
674         collector.checkThat("service_name_len", argsData.getInt("service_name_len"),
675                 equalTo(serviceName.length()));
676         collector.checkThat("service_name", argsData.getByteArray("service_name"),
677                 equalTo(serviceName.getBytes()));
678         collector.checkThat("service_specific_info_len",
679                 argsData.getInt("service_specific_info_len"), equalTo(ssi.length()));
680         collector.checkThat("service_specific_info", argsData.getByteArray("service_specific_info"),
681                 equalTo(ssi.getBytes()));
682         collector.checkThat("publish_match_indicator", argsData.getInt("publish_match_indicator"),
683                 equalTo(0));
684         collector.checkThat("rx_match_filter_len", argsData.getInt("rx_match_filter_len"),
685                 equalTo(tlvRx.getActualLength()));
686         collector.checkThat("rx_match_filter", argsData.getByteArray("rx_match_filter"),
687                 equalTo(Arrays.copyOf(tlvRx.getArray(), tlvRx.getActualLength())));
688         collector.checkThat("tx_match_filter_len", argsData.getInt("tx_match_filter_len"),
689                 equalTo(tlvTx.getActualLength()));
690         collector.checkThat("tx_match_filter", argsData.getByteArray("tx_match_filter"),
691                 equalTo(Arrays.copyOf(tlvTx.getArray(), tlvTx.getActualLength())));
692         collector.checkThat("rssi_threshold_flag", argsData.getInt("rssi_threshold_flag"),
693                 equalTo(0));
694         collector.checkThat("connmap", argsData.getInt("connmap"), equalTo(0));
695     }
696 
testSubscribe(short transactionId, int subscribeId, int subscribeType, String serviceName, String ssi, TlvBufferUtils.TlvConstructor tlvTx, TlvBufferUtils.TlvConstructor tlvRx, int subscribeCount, int subscribeTtl)697     private void testSubscribe(short transactionId, int subscribeId, int subscribeType,
698             String serviceName, String ssi, TlvBufferUtils.TlvConstructor tlvTx,
699             TlvBufferUtils.TlvConstructor tlvRx, int subscribeCount, int subscribeTtl)
700                     throws JSONException {
701         SubscribeData subscribeData = new SubscribeData.Builder().setServiceName(serviceName)
702                 .setServiceSpecificInfo(ssi)
703                 .setTxFilter(tlvTx.getArray(), tlvTx.getActualLength())
704                 .setRxFilter(tlvRx.getArray(), tlvRx.getActualLength()).build();
705 
706         SubscribeSettings subscribeSettings = new SubscribeSettings.Builder()
707                 .setSubscribeType(subscribeType).setSubscribeCount(subscribeCount)
708                 .setTtlSec(subscribeTtl).build();
709 
710         mDut.subscribe(transactionId, subscribeId, subscribeData, subscribeSettings);
711 
712         verify(mNanHalMock).subscribeHalMockNative(eq(transactionId), mArgs.capture());
713 
714         Bundle argsData = HalMockUtils.convertJsonToBundle(mArgs.getValue());
715 
716         collector.checkThat("subscribe_id", argsData.getInt("subscribe_id"), equalTo(subscribeId));
717         collector.checkThat("ttl", argsData.getInt("ttl"), equalTo(subscribeTtl));
718         collector.checkThat("period", argsData.getInt("period"), equalTo(500));
719         collector.checkThat("subscribe_type", argsData.getInt("subscribe_type"),
720                 equalTo(subscribeType));
721         collector.checkThat("serviceResponseFilter", argsData.getInt("serviceResponseFilter"),
722                 equalTo(1));
723         collector.checkThat("serviceResponseInclude", argsData.getInt("serviceResponseInclude"),
724                 equalTo(1));
725         collector.checkThat("useServiceResponseFilter", argsData.getInt("useServiceResponseFilter"),
726                 equalTo(1));
727         collector.checkThat("ssiRequiredForMatchIndication",
728                 argsData.getInt("ssiRequiredForMatchIndication"), equalTo(0));
729         collector.checkThat("subscribe_match_indicator",
730                 argsData.getInt("subscribe_match_indicator"), equalTo(0));
731         collector.checkThat("subscribe_count", argsData.getInt("subscribe_count"),
732                 equalTo(subscribeCount));
733         collector.checkThat("service_name_len", argsData.getInt("service_name_len"),
734                 equalTo(serviceName.length()));
735         collector.checkThat("service_name", argsData.getByteArray("service_name"),
736                 equalTo(serviceName.getBytes()));
737         collector.checkThat("service_specific_info_len",
738                 argsData.getInt("service_specific_info_len"), equalTo(serviceName.length()));
739         collector.checkThat("service_specific_info", argsData.getByteArray("service_specific_info"),
740                 equalTo(ssi.getBytes()));
741         collector.checkThat("rx_match_filter_len", argsData.getInt("rx_match_filter_len"),
742                 equalTo(tlvRx.getActualLength()));
743         collector.checkThat("rx_match_filter", argsData.getByteArray("rx_match_filter"),
744                 equalTo(Arrays.copyOf(tlvRx.getArray(), tlvRx.getActualLength())));
745         collector.checkThat("tx_match_filter_len", argsData.getInt("tx_match_filter_len"),
746                 equalTo(tlvTx.getActualLength()));
747         collector.checkThat("tx_match_filter", argsData.getByteArray("tx_match_filter"),
748                 equalTo(Arrays.copyOf(tlvTx.getArray(), tlvTx.getActualLength())));
749         collector.checkThat("rssi_threshold_flag", argsData.getInt("rssi_threshold_flag"),
750                 equalTo(0));
751         collector.checkThat("connmap", argsData.getInt("connmap"), equalTo(0));
752         collector.checkThat("num_intf_addr_present", argsData.getInt("num_intf_addr_present"),
753                 equalTo(0));
754     }
755 
installMockNanStateManager(WifiNanStateManager nanStateManager)756     private static void installMockNanStateManager(WifiNanStateManager nanStateManager)
757             throws Exception {
758         Field field = WifiNanStateManager.class.getDeclaredField("sNanStateManagerSingleton");
759         field.setAccessible(true);
760         field.set(null, nanStateManager);
761     }
762 }
763