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.util;
18 
19 import static org.junit.Assert.assertEquals;
20 
21 import androidx.test.filters.SmallTest;
22 
23 import com.android.server.wifi.WifiBaseTest;
24 import com.android.server.wifi.WifiLoggerHal;
25 
26 import org.junit.Test;
27 
28 /**
29  * Unit tests for {@link com.android.server.wifi.util.FrameParser}.
30  */
31 @SmallTest
32 public class FrameParserTest extends WifiBaseTest {
33 
34     private static final byte[] TEST_EAPOL_1_OF_4_FRAME_BYTES = new byte[] {
35             (byte) 0x7C, (byte) 0x7D, (byte) 0x3D, (byte) 0x51, (byte) 0x10, (byte) 0xDC,
36             (byte) 0x08, (byte) 0x96, (byte) 0xD7, (byte) 0x8B, (byte) 0xE3, (byte) 0xFB,
37             (byte) 0x88, (byte) 0x8E, (byte) 0x02, (byte) 0x03, (byte) 0x00, (byte) 0x5F,
38             (byte) 0x02, (byte) 0x00, (byte) 0x8A, (byte) 0x00, (byte) 0x10, (byte) 0x00,
39             (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
40             (byte) 0x01, (byte) 0xF2, (byte) 0x0D, (byte) 0xFA, (byte) 0x35, (byte) 0x89,
41             (byte) 0x9C, (byte) 0xA8, (byte) 0x8C, (byte) 0x14, (byte) 0xD9, (byte) 0x3F,
42             (byte) 0xC9, (byte) 0x62, (byte) 0x11, (byte) 0x39, (byte) 0xC3, (byte) 0x34,
43             (byte) 0xE1, (byte) 0x00, (byte) 0x09, (byte) 0xE3, (byte) 0x9C, (byte) 0x0C,
44             (byte) 0x32, (byte) 0xFE, (byte) 0x7F, (byte) 0x79, (byte) 0x29, (byte) 0x3E,
45             (byte) 0x6C, (byte) 0xF2, (byte) 0x57, (byte) 0x00, (byte) 0x00, (byte) 0x00,
46             (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
47             (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
48             (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
49             (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
50             (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
51             (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
52             (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
53             (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00};
54     private static final byte TEST_EAPOL_1_OF_4_FRAME_TYPE =
55             WifiLoggerHal.FRAME_TYPE_ETHERNET_II;
56     private static final String TEST_EAPOL_1_OF_4_FRAME_PROTOCOL_STRING = "EAPOL";
57     private static final String TEST_EAPOL_1_OF_4_FRAME_TYPE_STRING = "Pairwise Key message 1/4";
58 
59     private static final byte[] TEST_EAPOL_2_OF_4_FRAME_BYTES = new byte[] {
60             (byte) 0x08, (byte) 0x96, (byte) 0xD7, (byte) 0x8B, (byte) 0xE3, (byte) 0xFB,
61             (byte) 0x7C, (byte) 0x7D, (byte) 0x3D, (byte) 0x51, (byte) 0x10, (byte) 0xDC,
62             (byte) 0x88, (byte) 0x8E, (byte) 0x01, (byte) 0x03, (byte) 0x00, (byte) 0x75,
63             (byte) 0x02, (byte) 0x01, (byte) 0x0A, (byte) 0x00, (byte) 0x00, (byte) 0x00,
64             (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
65             (byte) 0x01, (byte) 0x42, (byte) 0xAE, (byte) 0x33, (byte) 0x61, (byte) 0xF8,
66             (byte) 0x38, (byte) 0x28, (byte) 0x81, (byte) 0x70, (byte) 0xD8, (byte) 0xA5,
67             (byte) 0xDD, (byte) 0x90, (byte) 0xB1, (byte) 0x8E, (byte) 0xEB, (byte) 0x58,
68             (byte) 0xF1, (byte) 0x0A, (byte) 0xE4, (byte) 0xA1, (byte) 0x93, (byte) 0x34,
69             (byte) 0xE1, (byte) 0x4F, (byte) 0x90, (byte) 0x85, (byte) 0xA0, (byte) 0x21,
70             (byte) 0x95, (byte) 0xC8, (byte) 0xD8, (byte) 0x00, (byte) 0x00, (byte) 0x00,
71             (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
72             (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
73             (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
74             (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
75             (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x53,
76             (byte) 0x12, (byte) 0xE4, (byte) 0x97, (byte) 0xBC, (byte) 0xFF, (byte) 0x15,
77             (byte) 0x45, (byte) 0xCF, (byte) 0x4C, (byte) 0xC0, (byte) 0xB8, (byte) 0xBA,
78             (byte) 0x30, (byte) 0x5F, (byte) 0x6C, (byte) 0x00, (byte) 0x16, (byte) 0x30,
79             (byte) 0x14, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x0F, (byte) 0xAC,
80             (byte) 0x04, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x0F, (byte) 0xAC,
81             (byte) 0x04, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x0F, (byte) 0xAC,
82             (byte) 0x02, (byte) 0x80, (byte) 0x00};
83     private static final byte TEST_EAPOL_2_OF_4_FRAME_TYPE =
84             WifiLoggerHal.FRAME_TYPE_ETHERNET_II;
85     private static final String TEST_EAPOL_2_OF_4_FRAME_PROTOCOL_STRING = "EAPOL";
86     private static final String TEST_EAPOL_2_OF_4_FRAME_TYPE_STRING = "Pairwise Key message 2/4";
87 
88     private static final byte[] TEST_PROBE_RESPONSE_FRAME_BYTES = new byte[] {
89             (byte) 0x50, (byte) 0x08, (byte) 0x3a, (byte) 0x01, (byte) 0x54, (byte) 0x27,
90             (byte) 0x1e, (byte) 0xf2, (byte) 0xcd, (byte) 0x0f, (byte) 0x10, (byte) 0x6f,
91             (byte) 0x3f, (byte) 0xf6, (byte) 0x89, (byte) 0x0e, (byte) 0x10, (byte) 0x6f,
92             (byte) 0x3f, (byte) 0xf6, (byte) 0x89, (byte) 0x0e, (byte) 0x60, (byte) 0xc4,
93             (byte) 0x4a, (byte) 0xaa, (byte) 0x2a, (byte) 0x0d, (byte) 0x00, (byte) 0x00,
94             (byte) 0x00, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0x11, (byte) 0x04,
95             (byte) 0x00, (byte) 0x16, (byte) 0x77, (byte) 0x7a, (byte) 0x72, (byte) 0x5f,
96             (byte) 0x68, (byte) 0x70, (byte) 0x5f, (byte) 0x67, (byte) 0x34, (byte) 0x35,
97             (byte) 0x30, (byte) 0x68, (byte) 0x5f, (byte) 0x67, (byte) 0x5f, (byte) 0x63,
98             (byte) 0x68, (byte) 0x35, (byte) 0x5f, (byte) 0x77, (byte) 0x70, (byte) 0x61,
99             (byte) 0x01, (byte) 0x08, (byte) 0x82, (byte) 0x84, (byte) 0x8b, (byte) 0x96,
100             (byte) 0x0c, (byte) 0x12, (byte) 0x18, (byte) 0x24, (byte) 0x03, (byte) 0x01,
101             (byte) 0x05, (byte) 0x2a, (byte) 0x01, (byte) 0x04, (byte) 0x32, (byte) 0x04,
102             (byte) 0x30, (byte) 0x48, (byte) 0x60, (byte) 0x6c, (byte) 0x30, (byte) 0x18,
103             (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x0f, (byte) 0xac, (byte) 0x02,
104             (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x0f, (byte) 0xac, (byte) 0x04,
105             (byte) 0x00, (byte) 0x0f, (byte) 0xac, (byte) 0x02, (byte) 0x01, (byte) 0x00,
106             (byte) 0x00, (byte) 0x0f, (byte) 0xac, (byte) 0x02, (byte) 0x0c, (byte) 0x00,
107             (byte) 0xdd, (byte) 0x18, (byte) 0x00, (byte) 0x50, (byte) 0xf2, (byte) 0x02,
108             (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0xa4,
109             (byte) 0x00, (byte) 0x00, (byte) 0x27, (byte) 0xa4, (byte) 0x00, (byte) 0x00,
110             (byte) 0x42, (byte) 0x43, (byte) 0x5e, (byte) 0x00, (byte) 0x62, (byte) 0x32,
111             (byte) 0x2f, (byte) 0x00, (byte) 0xdd, (byte) 0x70, (byte) 0x00, (byte) 0x50,
112             (byte) 0xf2, (byte) 0x04, (byte) 0x10, (byte) 0x4a, (byte) 0x00, (byte) 0x01,
113             (byte) 0x10, (byte) 0x10, (byte) 0x44, (byte) 0x00, (byte) 0x01, (byte) 0x02,
114             (byte) 0x10, (byte) 0x3b, (byte) 0x00, (byte) 0x01, (byte) 0x03, (byte) 0x10,
115             (byte) 0x47, (byte) 0x00, (byte) 0x10, (byte) 0xf3, (byte) 0x1b, (byte) 0x31,
116             (byte) 0x7f, (byte) 0x8c, (byte) 0x25, (byte) 0x56, (byte) 0x46, (byte) 0xb5,
117             (byte) 0xc9, (byte) 0x5f, (byte) 0x2f, (byte) 0x0b, (byte) 0xcf, (byte) 0x6a,
118             (byte) 0x14, (byte) 0x10, (byte) 0x21, (byte) 0x00, (byte) 0x06, (byte) 0x44,
119             (byte) 0x44, (byte) 0x2d, (byte) 0x57, (byte) 0x52, (byte) 0x54, (byte) 0x10,
120             (byte) 0x23, (byte) 0x00, (byte) 0x0c, (byte) 0x57, (byte) 0x5a, (byte) 0x52,
121             (byte) 0x2d, (byte) 0x48, (byte) 0x50, (byte) 0x2d, (byte) 0x47, (byte) 0x34,
122             (byte) 0x35, (byte) 0x30, (byte) 0x48, (byte) 0x10, (byte) 0x24, (byte) 0x00,
123             (byte) 0x01, (byte) 0x30, (byte) 0x10, (byte) 0x42, (byte) 0x00, (byte) 0x05,
124             (byte) 0x31, (byte) 0x32, (byte) 0x33, (byte) 0x34, (byte) 0x35, (byte) 0x10,
125             (byte) 0x54, (byte) 0x00, (byte) 0x08, (byte) 0x00, (byte) 0x06, (byte) 0x00,
126             (byte) 0x50, (byte) 0xf2, (byte) 0x04, (byte) 0x00, (byte) 0x01, (byte) 0x10,
127             (byte) 0x11, (byte) 0x00, (byte) 0x06, (byte) 0x44, (byte) 0x44, (byte) 0x2d,
128             (byte) 0x57, (byte) 0x52, (byte) 0x54, (byte) 0x10, (byte) 0x08, (byte) 0x00,
129             (byte) 0x02, (byte) 0x01, (byte) 0x04, (byte) 0x10, (byte) 0x3c, (byte) 0x00,
130             (byte) 0x01, (byte) 0x01, (byte) 0x8a, (byte) 0x0e, (byte) 0x06, (byte) 0xcf};
131     private static final byte TEST_PROBE_RESPONSE_FRAME_TYPE = WifiLoggerHal.FRAME_TYPE_80211_MGMT;
132     private static final String TEST_PROBE_RESPONSE_FRAME_PROTOCOL_STRING = "802.11 Mgmt";
133     private static final String TEST_PROBE_RESPONSE_FRAME_TYPE_STRING = "Probe Response";
134 
135     /**
136      * Test that a probe response frame is parsed correctly.
137      */
138     @Test
parseProbeResponseFrame()139     public void parseProbeResponseFrame() {
140         FrameParser parser = new FrameParser(
141                 TEST_PROBE_RESPONSE_FRAME_TYPE, TEST_PROBE_RESPONSE_FRAME_BYTES);
142         assertEquals(TEST_PROBE_RESPONSE_FRAME_PROTOCOL_STRING, parser.mMostSpecificProtocolString);
143         assertEquals(TEST_PROBE_RESPONSE_FRAME_TYPE_STRING, parser.mTypeString);
144     }
145 
146     /**
147      * Test that pairwise EAPOL 1/4 and 2/4 frames are parsed correctly.
148      */
149     @Test
parseEapolFrames()150     public void parseEapolFrames() {
151         FrameParser parser1 = new FrameParser(
152                 TEST_EAPOL_1_OF_4_FRAME_TYPE, TEST_EAPOL_1_OF_4_FRAME_BYTES);
153         assertEquals(TEST_EAPOL_1_OF_4_FRAME_PROTOCOL_STRING, parser1.mMostSpecificProtocolString);
154         assertEquals(TEST_EAPOL_1_OF_4_FRAME_TYPE_STRING, parser1.mTypeString);
155 
156         FrameParser parser2 = new FrameParser(
157                 TEST_EAPOL_2_OF_4_FRAME_TYPE, TEST_EAPOL_2_OF_4_FRAME_BYTES);
158         assertEquals(TEST_EAPOL_2_OF_4_FRAME_PROTOCOL_STRING, parser2.mMostSpecificProtocolString);
159         assertEquals(TEST_EAPOL_2_OF_4_FRAME_TYPE_STRING, parser2.mTypeString);
160     }
161 
162     /** Test that we parse the status code out of a non-HT authentication reply. */
163     @Test
canParseStatusCodeOutOfNonHtOpenAuthenticationReply()164     public void canParseStatusCodeOutOfNonHtOpenAuthenticationReply() {
165         FrameParser parser = new FrameParser(
166                 WifiLoggerHal.FRAME_TYPE_80211_MGMT,
167                 new byte[] {
168                         (byte) 0xb0,  // type + subtype
169                         0x00,  // flags
170                         0x3c, 0x00,  // duration
171                         0x00, 0x01, 0x02, 0x03, 0x04, 0x05,  // addr1 -- RA
172                         0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,  // addr2 -- TA
173                         0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,  // addr3 -- BSSID
174                         (byte) 0xa0, 0x3b,  // sequence + control
175                         0x00, 0x00,  // auth algorithm
176                         0x02, 0x00,  // auth sequence num
177                         0x11, 0x00  // status code
178                 });
179         assertEquals("802.11 Mgmt", parser.mMostSpecificProtocolString);
180         assertEquals("Authentication", parser.mTypeString);
181         assertEquals("17: Association denied; too many STAs", parser.mResultString);
182     }
183 
184     /** Test that we parse the status code out of a non-HT association response. */
185     @Test
canParseStatusCodeOutOfNonHtAssociationResponse()186     public void canParseStatusCodeOutOfNonHtAssociationResponse() {
187         FrameParser parser = new FrameParser(
188                 WifiLoggerHal.FRAME_TYPE_80211_MGMT,
189                 new byte[] {
190                         0x10,  // type + subtype
191                         0x00,  // flags
192                         0x3c, 0x00,  // duration
193                         0x00, 0x01, 0x02, 0x03, 0x04, 0x05,  // addr1 (RA)
194                         0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,  // addr2 (TA)
195                         0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,  // addr3 (BSSID)
196                         (byte) 0xb0, (byte) 0xbc,   // sequence + control
197                         0x01, 0x01,  // capabilities
198                         0x00, 0x00,  // status code
199                         0x01, (byte) 0xc0, 0x01, 0x08, (byte) 0x8c, 0x12, (byte) 0x98, 0x24,
200                         (byte) 0xb0, 0x48, 0x60, 0x6c, 0x2d, 0x1a, 0x6e, 0x00, 0x1b, (byte) 0xff,
201                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
202                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x16,
203                         0x24, 0x05, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
204                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0xbf,
205                         0x0c, 0x00, 0x00, 0x00, 0x00, (byte) 0xfe, (byte) 0xff, 0x00, 0x00,
206                         (byte) 0xfe, (byte) 0xff, 0x00, 0x00, (byte) 0xc0, 0x05, 0x00, 0x00, 0x00,
207                         (byte) 0xfc, (byte) 0xff, 0x7f, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
208                         0x00, 0x40, (byte) 0xdd, 0x18, 0x00, 0x50, (byte) 0xf2, 0x02, 0x01, 0x01,
209                         0x00, 0x00, 0x03, (byte) 0xa4, 0x00, 0x00, 0x27, (byte) 0xa4, 0x00, 0x00,
210                         0x42, 0x43, 0x5e, 0x00, 0x62, 0x32, 0x2f, 0x00
211                 });
212         assertEquals("802.11 Mgmt", parser.mMostSpecificProtocolString);
213         assertEquals("Association Response", parser.mTypeString);
214         assertEquals("0: Success", parser.mResultString);
215     }
216 
217     /** Test that we do not parse the status code out of a non-HT authentication request. */
218     @Test
doesNotParseStatusCodeOutOfNonHtOpenAuthenticationRequest()219     public void doesNotParseStatusCodeOutOfNonHtOpenAuthenticationRequest() {
220         FrameParser parser = new FrameParser(
221                 WifiLoggerHal.FRAME_TYPE_80211_MGMT,
222                 new byte[] {
223                         (byte) 0xb0,  // type + subtype
224                         0x00,  // flags
225                         0x00, 0x00,  // duration (from host; probably to be filled by firmware)
226                         0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,  // addr1 (RA)
227                         0x00, 0x01, 0x02, 0x03, 0x04, 0x05,  // addr2 (TA)
228                         0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,  // addr3 (BSSID)
229                         0x10, (byte) 0x80,  // sequence + control
230                         0x00, 0x00,  // auth algorithm
231                         0x01, 0x00,  // auth sequence num
232                         0x00, 0x00,  // status code; present but meaningless for first auth frame
233 
234                 });
235         assertEquals("802.11 Mgmt", parser.mMostSpecificProtocolString);
236         assertEquals("Authentication", parser.mTypeString);
237         assertEquals("N/A", parser.mResultString);
238     }
239 
240     /** Test that we do not parse the status code out of an association request. */
241     @Test
doesNotParseStatusCodeOutOfNonHtOpenAssociationRequest()242     public void doesNotParseStatusCodeOutOfNonHtOpenAssociationRequest() {
243         FrameParser parser = new FrameParser(
244                 WifiLoggerHal.FRAME_TYPE_80211_MGMT,
245                 new byte[] {
246                         0x00,  // type + subtype
247                         0x00,  // flags
248                         0x00, 0x00,  // duration (from host; probably to be filled by firmware)
249                         0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,  // addr1 (RA)
250                         0x00, 0x01, 0x02, 0x03, 0x04, 0x05,  // addr2 (TA)
251                         0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,  // addr3 (BSSID)
252                         0x20, (byte) 0x80,  // sequence + control
253                         0x01, 0x11, 0x01, 0x00, 0x00, 0x0b, 0x71, 0x75,
254                         0x69, 0x63, 0x68, 0x65, 0x2d, 0x74, 0x65, 0x73, 0x74, 0x01, 0x08,
255                         (byte) 0x8c, 0x12, (byte) 0x98, 0x24, (byte) 0xb0, 0x48, 0x60, 0x6c, 0x21,
256                         0x02, 0x08, 0x18, 0x24, 0x32, 0x24, 0x01, 0x28, 0x01, 0x2c, 0x01, 0x30,
257                         0x01, 0x34, 0x01, 0x38, 0x01, 0x3c, 0x01, 0x40, 0x01, 0x64, 0x01, 0x68,
258                         0x01, 0x6c, 0x01, 0x70, 0x01, 0x74, 0x01, 0x78, 0x01, 0x7c, 0x01,
259                         (byte) 0x80, 0x01, (byte) 0x84, 0x01, (byte) 0x88, 0x01, (byte) 0x8c, 0x01,
260                         (byte) 0x90, 0x01, (byte) 0x95, 0x01, (byte) 0x99, 0x01, (byte) 0x9d, 0x01,
261                         (byte) 0xa1, 0x01, (byte) 0xa5, 0x01, 0x2d, 0x1a, (byte) 0xef, 0x01, 0x1f,
262                         (byte) 0xff, (byte) 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
263                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
264                         0x00, (byte) 0xdd, 0x07, 0x00, 0x50, (byte) 0xf2, 0x02, 0x00, 0x01, 0x00,
265                         (byte) 0xbf, 0x0c, (byte) 0x92, 0x71, (byte) 0x90, 0x33, (byte) 0xfa,
266                         (byte) 0xff, 0x0c, 0x03, (byte) 0xfa, (byte) 0xff, 0x0c, 0x03, 0x7f, 0x09,
267                         0x04, 0x00, 0x0a, 0x02, 0x01, 0x00, 0x00, 0x40, (byte) 0x80,
268                 });
269         assertEquals("802.11 Mgmt", parser.mMostSpecificProtocolString);
270         assertEquals("Association Request", parser.mTypeString);
271         assertEquals("N/A", parser.mResultString);
272     }
273 
274     /** Test that we parse the result code of a deauthentication frame */
275     @Test
parseDeauthenticationResultCode()276     public void parseDeauthenticationResultCode() {
277         FrameParser parser = new FrameParser(
278                 WifiLoggerHal.FRAME_TYPE_80211_MGMT,
279                 new byte[]{
280                         (byte) 0xc0,  // type + subtype
281                         0x00,  // flags
282                         0x00, 0x00,  // duration (from host; probably to be filled by firmware)
283                         // addr1 (RA):
284                         (byte) 0xa0, 0x63, (byte) 0x91, (byte) 0xa9, (byte) 0xed, (byte) 0xa1,
285                         // addr2 (TA):
286                         (byte) 0xf4, (byte) 0xf5, (byte) 0xe8, 0x51, (byte) 0x9e, 0x09,
287                         // addr3 (BSSID):
288                         (byte) 0xa0, 0x63, (byte) 0x91, (byte) 0xa9, (byte) 0xed, (byte) 0xa1,
289                         0x70, (byte) 0x80,  // sequence + control
290                         0x03, 0x00,  // reason code
291                 });
292         assertEquals("802.11 Mgmt", parser.mMostSpecificProtocolString);
293         assertEquals("Deauthentication", parser.mTypeString);
294         assertEquals(
295                 "3: Deauthenticated because sending STA is leaving (or has left) IBSS or ESS",
296                 parser.mResultString);
297     }
298 
299     /** Test that we parse the result code of a disassociation frame */
300     @Test
parseDisassociationResultCode()301     public void parseDisassociationResultCode() {
302         FrameParser parser = new FrameParser(
303                 WifiLoggerHal.FRAME_TYPE_80211_MGMT,
304                 new byte[]{
305                         (byte) 0xa0,  // type + subtype
306                         0x00,  // flags
307                         0x00, 0x00,  // duration (from host; probably to be filled by firmware)
308                         // addr1 (RA):
309                         (byte) 0xa0, 0x63, (byte) 0x91, (byte) 0xa9, (byte) 0xed, (byte) 0xa1,
310                         // addr2 (TA):
311                         (byte) 0xf4, (byte) 0xf5, (byte) 0xe8, 0x51, (byte) 0x9e, 0x09,
312                         // addr3 (BSSID):
313                         (byte) 0xa0, 0x63, (byte) 0x91, (byte) 0xa9, (byte) 0xed, (byte) 0xa1,
314                         0x70, (byte) 0x80,  // sequence + control
315                         0x04, 0x00,  // reason code
316                 });
317         assertEquals("802.11 Mgmt", parser.mMostSpecificProtocolString);
318         assertEquals("Disassociation", parser.mTypeString);
319         assertEquals("4: Disassociated due to inactivity", parser.mResultString);
320     }
321 
322     /** Test that we parse the subtype of an Action No Ack frame */
323     @Test
parseActionNoAckSubtype()324     public void parseActionNoAckSubtype() {
325         FrameParser parser = new FrameParser(
326                 WifiLoggerHal.FRAME_TYPE_80211_MGMT,
327                 new byte[]{
328                         (byte) 0xe0,  // type + subtype
329                         0x00,  // flags
330                         0x00, 0x00,  // duration (from host; probably to be filled by firmware)
331                         // addr1 (RA):
332                         (byte) 0xa0, 0x63, (byte) 0x91, (byte) 0xa9, (byte) 0xed, (byte) 0xa1,
333                         // addr2 (TA):
334                         (byte) 0xf4, (byte) 0xf5, (byte) 0xe8, 0x51, (byte) 0x9e, 0x09,
335                         // addr3 (BSSID):
336                         (byte) 0xa0, 0x63, (byte) 0x91, (byte) 0xa9, (byte) 0xed, (byte) 0xa1,
337                         0x70, (byte) 0x80,  // sequence + control
338                         0x00, 0x00,  // action
339                 });
340         assertEquals("802.11 Mgmt", parser.mMostSpecificProtocolString);
341         assertEquals("Action No Ack", parser.mTypeString);
342         assertEquals("N/A", parser.mResultString);
343     }
344 }
345