1 /******************************************************************************
2  *
3  *  Copyright 2017 The Android Open Source Project
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 #include <gtest/gtest.h>
20 
21 #include "advertise_data_parser.h"
22 
TEST(AdvertiseDataParserTest,IsValidEmpty)23 TEST(AdvertiseDataParserTest, IsValidEmpty) {
24   const std::vector<uint8_t> data0;
25   EXPECT_TRUE(AdvertiseDataParser::IsValid(data0));
26 
27   // Single empty field allowed (treated as zero padding).
28   const std::vector<uint8_t> data1{0x00};
29   EXPECT_TRUE(AdvertiseDataParser::IsValid(data1));
30 }
31 
TEST(AdvertiseDataParserTest,IsValidBad)32 TEST(AdvertiseDataParserTest, IsValidBad) {
33   // Single field, field empty.
34   const std::vector<uint8_t> data0{0x01};
35   EXPECT_FALSE(AdvertiseDataParser::IsValid(data0));
36 
37   // Single field, first field length too long.
38   const std::vector<uint8_t> data1{0x05, 0x02, 0x00, 0x00, 0x00};
39   EXPECT_FALSE(AdvertiseDataParser::IsValid(data1));
40 
41   // Two fields, second field length too long.
42   const std::vector<uint8_t> data2{0x02, 0x02, 0x00, 0x02, 0x00};
43   EXPECT_FALSE(AdvertiseDataParser::IsValid(data2));
44 
45   // Two fields, second field empty.
46   const std::vector<uint8_t> data3{0x02, 0x02, 0x00, 0x01};
47   EXPECT_FALSE(AdvertiseDataParser::IsValid(data3));
48 
49   // Non-zero padding at end of packet.
50   const std::vector<uint8_t> data4{0x03, 0x02, 0x01, 0x02, 0x02, 0x03, 0x01,
51                                    0x00, 0x00, 0xBA, 0xBA, 0x00, 0x00};
52   EXPECT_FALSE(AdvertiseDataParser::IsValid(data1));
53 
54   // Non-zero padding at end of packet.
55   const std::vector<uint8_t> data5{0x03, 0x02, 0x01, 0x02, 0x02, 0x03, 0x01, 0x00, 0xBA};
56   EXPECT_FALSE(AdvertiseDataParser::IsValid(data1));
57 }
58 
TEST(AdvertiseDataParserTest,IsValidGood)59 TEST(AdvertiseDataParserTest, IsValidGood) {
60   // Single field.
61   const std::vector<uint8_t> data0{0x03, 0x02, 0x01, 0x02};
62   EXPECT_TRUE(AdvertiseDataParser::IsValid(data0));
63 
64   // Two fields.
65   const std::vector<uint8_t> data1{0x03, 0x02, 0x01, 0x02, 0x02, 0x03, 0x01};
66   EXPECT_TRUE(AdvertiseDataParser::IsValid(data1));
67 
68   // Zero padding at end of packet.
69   const std::vector<uint8_t> data2{0x03, 0x02, 0x01, 0x02, 0x02, 0x03, 0x01, 0x00};
70   EXPECT_TRUE(AdvertiseDataParser::IsValid(data2));
71 
72   // zero padding at end of packet, sample data from real device
73   const std::vector<uint8_t> data3{0x10, 0x096, 0x85, 0x44, 0x32, 0x04, 0x74, 0x32,
74                                    0x03, 0x13,  0x93, 0xa,  0x32, 0x39, 0x3a, 0x65,
75                                    0x32, 0x05,  0x12, 0x50, 0x00, 0x50, 0x00, 0x02,
76                                    0x0a, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00};
77   EXPECT_TRUE(AdvertiseDataParser::IsValid(data3));
78 
79   // Test Quirk for Traxxas (bad name length, should be 0x11 is 0x14)
80   const std::vector<uint8_t> data4{0x14, 0x09, 0x54, 0x52, 0x58, 0x20, 0x42, 0x4C, 0x45,
81                                    0x05, 0x12, 0x60, 0x00, 0xE8, 0x03, 0x02, 0x0A, 0x00};
82   EXPECT_TRUE(AdvertiseDataParser::IsValid(data4));
83 
84   // Test Quirk for Traxxas (bad name length, should be 0x11 is 0x14)
85   const std::vector<uint8_t> data5{0x14, 0x09, 0x54, 0x51, 0x69, 0x20, 0x42, 0x4C, 0x45,
86                                    0x05, 0x12, 0x64, 0x00, 0xE8, 0x03, 0x02, 0x0A, 0x00};
87   EXPECT_TRUE(AdvertiseDataParser::IsValid(data5));
88 
89   // Test Quirk for Traxxas (bad name length, should be 0x11 is 0x14)
90   const std::vector<uint8_t> data6{0x14, 0x09, 0x54, 0x51, 0x69, 0x20, 0x42, 0x4C, 0x45,
91                                    0x05, 0x12, 0x60, 0x00, 0xE8, 0x03, 0x02, 0x0A, 0x00};
92   EXPECT_TRUE(AdvertiseDataParser::IsValid(data6));
93 
94   // Test Quirk for Traxxas (bad length, should be 0x11 is 0x14)
95   // scan response glued after advertise data
96   const std::vector<uint8_t> data7{0x02, 0x01, 0x06, 0x11, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
97                                    0x00, 0x64, 0xB1, 0x73, 0x41, 0xE7, 0xF3, 0xC4, 0xB4, 0x80,
98                                    0x08, 0x14, 0x09, 0x54, 0x51, 0x69, 0x20, 0x42, 0x4C, 0x45,
99                                    0x05, 0x12, 0x60, 0x00, 0xE8, 0x03, 0x02, 0x0A, 0x00};
100   EXPECT_TRUE(AdvertiseDataParser::IsValid(data7));
101 }
102 
TEST(AdvertiseDataParserTest,GetFieldByType)103 TEST(AdvertiseDataParserTest, GetFieldByType) {
104   // Single field.
105   const std::vector<uint8_t> data0{0x03, 0x02, 0x01, 0x02};
106 
107   uint8_t p_length;
108   const uint8_t* data = AdvertiseDataParser::GetFieldByType(data0, 0x02, &p_length);
109   EXPECT_EQ(data0.data() + 2, data);
110   EXPECT_EQ(2, p_length);
111 
112   // Two fields, second field length too long.
113   const std::vector<uint8_t> data1{0x02, 0x02, 0x00, 0x03, 0x00};
114 
115   // First field is ok.
116   data = AdvertiseDataParser::GetFieldByType(data1, 0x02, &p_length);
117   EXPECT_EQ(data1.data() + 2, data);
118   EXPECT_EQ(0x01, p_length);
119 
120   // Second field have bad length.
121   data = AdvertiseDataParser::GetFieldByType(data1, 0x03, &p_length);
122   EXPECT_EQ(nullptr, data);
123   EXPECT_EQ(0, p_length);
124 }
125 
126 // This test makes sure that RemoveTrailingZeros is working correctly. It does
127 // run the RemoveTrailingZeros for ad data, then glue scan response at end of
128 // it, and checks that the resulting data is good.
TEST(AdvertiseDataParserTest,RemoveTrailingZeros)129 TEST(AdvertiseDataParserTest, RemoveTrailingZeros) {
130   std::vector<uint8_t> podo_ad_data{0x02, 0x01, 0x02, 0x11, 0x06, 0x66, 0x9a, 0x0c,
131                                     0x20, 0x00, 0x08, 0x37, 0xa8, 0xe5, 0x11, 0x81,
132                                     0x8b, 0xd0, 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00,
133                                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
134   std::vector<uint8_t> podo_scan_resp{0x03, 0x19, 0x00, 0x80, 0x09, 0x09, 0x50, 0x6f,
135                                       0x64, 0x6f, 0x51, 0x35, 0x56, 0x47, 0x00, 0x00,
136                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
137                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
138 
139   AdvertiseDataParser::RemoveTrailingZeros(podo_ad_data);
140   AdvertiseDataParser::RemoveTrailingZeros(podo_scan_resp);
141 
142   std::vector<uint8_t> glued(podo_ad_data);
143   glued.insert(glued.end(), podo_scan_resp.begin(), podo_scan_resp.end());
144 
145   EXPECT_TRUE(AdvertiseDataParser::IsValid(glued));
146 }
147 
148 // This test makes sure that RemoveTrailingZeros is removing all bytes after
149 // first zero length field. It does run the RemoveTrailingZeros for data with
150 // non-zero bytes after zero length field, then glue scan response at end of it,
151 // and checks that the resulting data is good. Note: specification requires all
152 // bytes after zero length field to be zero padding, but many legacy devices got
153 // this wrong, causing us to have this workaround.
TEST(AdvertiseDataParserTest,RemoveTrailingZerosMalformed)154 TEST(AdvertiseDataParserTest, RemoveTrailingZerosMalformed) {
155   std::vector<uint8_t> ad_data{0x02, 0x01, 0x02, 0x11, 0x06, 0x66, 0x9a, 0x0c, 0x20, 0x00, 0x08,
156                                0x37, 0xa8, 0xe5, 0x11, 0x81, 0x8b, 0xd0, 0xf0, 0xf0, 0xf0, 0x00,
157                                0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
158   std::vector<uint8_t> scan_resp{0x03, 0x19, 0x00, 0x80, 0x09, 0x09, 0x50, 0x6f, 0x64, 0x6f, 0x51,
159                                  0x35, 0x56, 0x47, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
160                                  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
161 
162   AdvertiseDataParser::RemoveTrailingZeros(ad_data);
163   AdvertiseDataParser::RemoveTrailingZeros(scan_resp);
164 
165   std::vector<uint8_t> glued(ad_data);
166   glued.insert(glued.end(), scan_resp.begin(), scan_resp.end());
167 
168   EXPECT_TRUE(AdvertiseDataParser::IsValid(glued));
169 }
170 
TEST(AdvertiseDataParserTest,GetFieldByTypeInLoop)171 TEST(AdvertiseDataParserTest, GetFieldByTypeInLoop) {
172   // Single field.
173   const uint8_t AD_TYPE_SVC_DATA = 0x16;
174   const std::vector<uint8_t> data0{0x02, 0x01, 0x02, 0x07, 0x2e, 0x6a, 0xc1, 0x19, 0x52, 0x1e,
175                                    0x49, 0x09, 0x16, 0x4e, 0x18, 0x00, 0xff, 0x0f, 0x03, 0x00,
176                                    0x00, 0x02, 0x0a, 0x7f, 0x03, 0x16, 0x4f, 0x18, 0x04, 0x16,
177                                    0x53, 0x18, 0x00, 0x0f, 0x09, 0x48, 0x5f, 0x43, 0x33, 0x45,
178                                    0x41, 0x31, 0x36, 0x33, 0x46, 0x35, 0x36, 0x34, 0x46};
179 
180   const uint8_t* p_service_data = data0.data();
181   uint8_t service_data_len = 0;
182 
183   int match_no = 0;
184   while ((p_service_data = AdvertiseDataParser::GetFieldByType(
185                   p_service_data + service_data_len,
186                   data0.size() - (p_service_data - data0.data()) - service_data_len,
187                   AD_TYPE_SVC_DATA, &service_data_len))) {
188     auto position = (p_service_data - data0.data());
189     if (match_no == 0) {
190       EXPECT_EQ(position, 13);
191       EXPECT_EQ(service_data_len, 8);
192     } else if (match_no == 1) {
193       EXPECT_EQ(position, 26);
194       EXPECT_EQ(service_data_len, 2);
195     } else if (match_no == 2) {
196       EXPECT_EQ(position, 30);
197       EXPECT_EQ(service_data_len, 3);
198     }
199     match_no++;
200   }
201   EXPECT_EQ(match_no, 3);
202 }
203