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