1 // Copyright 2020 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "core/internal/offline_frames.h"
16
17 #include <array>
18 #include <memory>
19 #include <utility>
20 #include <vector>
21
22 #include "proto/connections/offline_wire_formats.pb.h"
23 #include "platform/base/byte_array.h"
24 #include "gmock/gmock.h"
25 #include "gtest/gtest.h"
26
27 namespace location {
28 namespace nearby {
29 namespace connections {
30 namespace parser {
31 namespace {
32
33 using Medium = proto::connections::Medium;
34 using ::testing::EqualsProto;
35
36 constexpr absl::string_view kEndpointId{"ABC"};
37 constexpr absl::string_view kEndpointName{"XYZ"};
38 constexpr int kNonce = 1234;
39 constexpr bool kSupports5ghz = true;
40 constexpr absl::string_view kBssid{"FF:FF:FF:FF:FF:FF"};
41 constexpr std::array<Medium, 9> kMediums = {
42 Medium::MDNS, Medium::BLUETOOTH, Medium::WIFI_HOTSPOT,
43 Medium::BLE, Medium::WIFI_LAN, Medium::WIFI_AWARE,
44 Medium::NFC, Medium::WIFI_DIRECT, Medium::WEB_RTC,
45 };
46
TEST(OfflineFramesTest,CanParseMessageFromBytes)47 TEST(OfflineFramesTest, CanParseMessageFromBytes) {
48 OfflineFrame tx_message;
49
50 {
51 tx_message.set_version(OfflineFrame::V1);
52 auto* v1_frame = tx_message.mutable_v1();
53 auto* sub_frame = v1_frame->mutable_connection_request();
54
55 v1_frame->set_type(V1Frame::CONNECTION_REQUEST);
56 sub_frame->set_endpoint_id(kEndpointId);
57 sub_frame->set_endpoint_name(kEndpointName);
58 sub_frame->set_endpoint_info(kEndpointName);
59 sub_frame->set_nonce(kNonce);
60 auto* medium_metadata = sub_frame->mutable_medium_metadata();
61
62 medium_metadata->set_supports_5_ghz(kSupports5ghz);
63 medium_metadata->set_bssid(kBssid);
64
65 for (auto& medium : kMediums) {
66 sub_frame->add_mediums(MediumToConnectionRequestMedium(medium));
67 }
68 }
69 auto serialized_bytes = ByteArray(tx_message.SerializeAsString());
70 auto ret_value = FromBytes(serialized_bytes);
71 ASSERT_TRUE(ret_value.ok());
72 const auto& rx_message = ret_value.result();
73 EXPECT_THAT(rx_message, EqualsProto(tx_message));
74 EXPECT_EQ(GetFrameType(rx_message), V1Frame::CONNECTION_REQUEST);
75 EXPECT_EQ(
76 ConnectionRequestMediumsToMediums(rx_message.v1().connection_request()),
77 std::vector(kMediums.begin(), kMediums.end()));
78 }
79
TEST(OfflineFramesTest,CanGenerateConnectionRequest)80 TEST(OfflineFramesTest, CanGenerateConnectionRequest) {
81 constexpr char kExpected[] =
82 R"pb(
83 version: V1
84 v1: <
85 type: CONNECTION_REQUEST
86 connection_request: <
87 endpoint_id: "ABC"
88 endpoint_name: "XYZ"
89 endpoint_info: "XYZ"
90 nonce: 1234
91 medium_metadata: <
92 supports_5_ghz: true
93 bssid: "FF:FF:FF:FF:FF:FF"
94 >
95 mediums: MDNS
96 mediums: BLUETOOTH
97 mediums: WIFI_HOTSPOT
98 mediums: BLE
99 mediums: WIFI_LAN
100 mediums: WIFI_AWARE
101 mediums: NFC
102 mediums: WIFI_DIRECT
103 mediums: WEB_RTC
104 >
105 >)pb";
106 ByteArray bytes = ForConnectionRequest(
107 std::string(kEndpointId), ByteArray{std::string(kEndpointName)}, kNonce,
108 kSupports5ghz, std::string(kBssid),
109 std::vector(kMediums.begin(), kMediums.end()));
110 auto response = FromBytes(bytes);
111 ASSERT_TRUE(response.ok());
112 OfflineFrame message = FromBytes(bytes).result();
113 EXPECT_THAT(message, EqualsProto(kExpected));
114 }
115
TEST(OfflineFramesTest,CanGenerateConnectionResponse)116 TEST(OfflineFramesTest, CanGenerateConnectionResponse) {
117 constexpr char kExpected[] =
118 R"pb(
119 version: V1
120 v1: <
121 type: CONNECTION_RESPONSE
122 connection_response: <
123 status: 1
124 response: REJECT
125 >
126 >)pb";
127 ByteArray bytes = ForConnectionResponse(1);
128 auto response = FromBytes(bytes);
129 ASSERT_TRUE(response.ok());
130 OfflineFrame message = FromBytes(bytes).result();
131 EXPECT_THAT(message, EqualsProto(kExpected));
132 }
133
TEST(OfflineFramesTest,CanGenerateControlPayloadTransfer)134 TEST(OfflineFramesTest, CanGenerateControlPayloadTransfer) {
135 PayloadTransferFrame::PayloadHeader header;
136 PayloadTransferFrame::ControlMessage control;
137 header.set_id(12345);
138 header.set_type(PayloadTransferFrame::PayloadHeader::BYTES);
139 header.set_total_size(1024);
140 control.set_event(PayloadTransferFrame::ControlMessage::PAYLOAD_CANCELED);
141 control.set_offset(150);
142
143 constexpr char kExpected[] =
144 R"pb(
145 version: V1
146 v1: <
147 type: PAYLOAD_TRANSFER
148 payload_transfer: <
149 packet_type: CONTROL,
150 payload_header: < type: BYTES id: 12345 total_size: 1024 >
151 control_message: < event: PAYLOAD_CANCELED offset: 150 >
152 >
153 >)pb";
154 ByteArray bytes = ForControlPayloadTransfer(header, control);
155 auto response = FromBytes(bytes);
156 ASSERT_TRUE(response.ok());
157 OfflineFrame message = FromBytes(bytes).result();
158 EXPECT_THAT(message, EqualsProto(kExpected));
159 }
160
TEST(OfflineFramesTest,CanGenerateDataPayloadTransfer)161 TEST(OfflineFramesTest, CanGenerateDataPayloadTransfer) {
162 PayloadTransferFrame::PayloadHeader header;
163 PayloadTransferFrame::PayloadChunk chunk;
164 header.set_id(12345);
165 header.set_type(PayloadTransferFrame::PayloadHeader::BYTES);
166 header.set_total_size(1024);
167 chunk.set_body("payload data");
168 chunk.set_offset(150);
169 chunk.set_flags(1);
170
171 constexpr char kExpected[] =
172 R"pb(
173 version: V1
174 v1: <
175 type: PAYLOAD_TRANSFER
176 payload_transfer: <
177 packet_type: DATA,
178 payload_header: < type: BYTES id: 12345 total_size: 1024 >
179 payload_chunk: < flags: 1 offset: 150 body: "payload data" >
180 >
181 >)pb";
182 ByteArray bytes = ForDataPayloadTransfer(header, chunk);
183 auto response = FromBytes(bytes);
184 ASSERT_TRUE(response.ok());
185 OfflineFrame message = FromBytes(bytes).result();
186 EXPECT_THAT(message, EqualsProto(kExpected));
187 }
188
TEST(OfflineFramesTest,CanGenerateBwuWifiHotspotPathAvailable)189 TEST(OfflineFramesTest, CanGenerateBwuWifiHotspotPathAvailable) {
190 constexpr char kExpected[] =
191 R"pb(
192 version: V1
193 v1: <
194 type: BANDWIDTH_UPGRADE_NEGOTIATION
195 bandwidth_upgrade_negotiation: <
196 event_type: UPGRADE_PATH_AVAILABLE
197 upgrade_path_info: <
198 medium: WIFI_HOTSPOT
199 wifi_hotspot_credentials: <
200 ssid: "ssid"
201 password: "password"
202 port: 1234
203 gateway: "0.0.0.0"
204 >
205 supports_disabling_encryption: false
206 >
207 >
208 >)pb";
209 ByteArray bytes = ForBwuWifiHotspotPathAvailable("ssid", "password", 1234,
210 "0.0.0.0", false);
211 auto response = FromBytes(bytes);
212 ASSERT_TRUE(response.ok());
213 OfflineFrame message = FromBytes(bytes).result();
214 EXPECT_THAT(message, EqualsProto(kExpected));
215 }
216
TEST(OfflineFramesTest,CanGenerateBwuWifiLanPathAvailable)217 TEST(OfflineFramesTest, CanGenerateBwuWifiLanPathAvailable) {
218 constexpr char kExpected[] =
219 R"pb(
220 version: V1
221 v1: <
222 type: BANDWIDTH_UPGRADE_NEGOTIATION
223 bandwidth_upgrade_negotiation: <
224 event_type: UPGRADE_PATH_AVAILABLE
225 upgrade_path_info: <
226 medium: WIFI_LAN
227 wifi_lan_socket: < ip_address: "\x01\x02\x03\x04" wifi_port: 1234 >
228 >
229 >
230 >)pb";
231 ByteArray bytes = ForBwuWifiLanPathAvailable("\x01\x02\x03\x04", 1234);
232 auto response = FromBytes(bytes);
233 ASSERT_TRUE(response.ok());
234 OfflineFrame message = FromBytes(bytes).result();
235 EXPECT_THAT(message, EqualsProto(kExpected));
236 }
237
TEST(OfflineFramesTest,CanGenerateBwuWifiAwarePathAvailable)238 TEST(OfflineFramesTest, CanGenerateBwuWifiAwarePathAvailable) {
239 constexpr char kExpected[] =
240 R"pb(
241 version: V1
242 v1: <
243 type: BANDWIDTH_UPGRADE_NEGOTIATION
244 bandwidth_upgrade_negotiation: <
245 event_type: UPGRADE_PATH_AVAILABLE
246 upgrade_path_info: <
247 medium: WIFI_AWARE
248 wifi_aware_credentials: <
249 service_id: "service_id"
250 service_info: "service_info"
251 password: "password"
252 >
253 supports_disabling_encryption: false
254 >
255 >
256 >)pb";
257 ByteArray bytes = ForBwuWifiAwarePathAvailable("service_id", "service_info",
258 "password", false);
259 auto response = FromBytes(bytes);
260 ASSERT_TRUE(response.ok());
261 OfflineFrame message = FromBytes(bytes).result();
262 EXPECT_THAT(message, EqualsProto(kExpected));
263 }
264
TEST(OfflineFramesTest,CanGenerateBwuWifiDirectPathAvailable)265 TEST(OfflineFramesTest, CanGenerateBwuWifiDirectPathAvailable) {
266 constexpr char kExpected[] =
267 R"pb(
268 version: V1
269 v1: <
270 type: BANDWIDTH_UPGRADE_NEGOTIATION
271 bandwidth_upgrade_negotiation: <
272 event_type: UPGRADE_PATH_AVAILABLE
273 upgrade_path_info: <
274 medium: WIFI_DIRECT
275 wifi_direct_credentials: <
276 ssid: "DIRECT-A0-0123456789AB"
277 password: "password"
278 port: 1000
279 frequency: 1000
280 >
281 supports_disabling_encryption: false
282 >
283 >
284 >)pb";
285 ByteArray bytes = ForBwuWifiDirectPathAvailable(
286 "DIRECT-A0-0123456789AB", "password", 1000, 1000, false);
287 auto response = FromBytes(bytes);
288 ASSERT_TRUE(response.ok());
289 OfflineFrame message = FromBytes(bytes).result();
290 EXPECT_THAT(message, EqualsProto(kExpected));
291 }
292
TEST(OfflineFramesTest,CanGenerateBwuBluetoothPathAvailable)293 TEST(OfflineFramesTest, CanGenerateBwuBluetoothPathAvailable) {
294 constexpr char kExpected[] =
295 R"pb(
296 version: V1
297 v1: <
298 type: BANDWIDTH_UPGRADE_NEGOTIATION
299 bandwidth_upgrade_negotiation: <
300 event_type: UPGRADE_PATH_AVAILABLE
301 upgrade_path_info: <
302 medium: BLUETOOTH
303 bluetooth_credentials: <
304 service_name: "service"
305 mac_address: "\x11\x22\x33\x44\x55\x66"
306 >
307 >
308 >
309 >)pb";
310 ByteArray bytes =
311 ForBwuBluetoothPathAvailable("service", "\x11\x22\x33\x44\x55\x66");
312 auto response = FromBytes(bytes);
313 ASSERT_TRUE(response.ok());
314 OfflineFrame message = FromBytes(bytes).result();
315 EXPECT_THAT(message, EqualsProto(kExpected));
316 }
317
TEST(OfflineFramesTest,CanGenerateBwuLastWrite)318 TEST(OfflineFramesTest, CanGenerateBwuLastWrite) {
319 constexpr char kExpected[] =
320 R"pb(
321 version: V1
322 v1: <
323 type: BANDWIDTH_UPGRADE_NEGOTIATION
324 bandwidth_upgrade_negotiation: < event_type: LAST_WRITE_TO_PRIOR_CHANNEL >
325 >)pb";
326 ByteArray bytes = ForBwuLastWrite();
327 auto response = FromBytes(bytes);
328 ASSERT_TRUE(response.ok());
329 OfflineFrame message = FromBytes(bytes).result();
330 EXPECT_THAT(message, EqualsProto(kExpected));
331 }
332
TEST(OfflineFramesTest,CanGenerateBwuSafeToClose)333 TEST(OfflineFramesTest, CanGenerateBwuSafeToClose) {
334 constexpr char kExpected[] =
335 R"pb(
336 version: V1
337 v1: <
338 type: BANDWIDTH_UPGRADE_NEGOTIATION
339 bandwidth_upgrade_negotiation: < event_type: SAFE_TO_CLOSE_PRIOR_CHANNEL >
340 >)pb";
341 ByteArray bytes = ForBwuSafeToClose();
342 auto response = FromBytes(bytes);
343 ASSERT_TRUE(response.ok());
344 OfflineFrame message = FromBytes(bytes).result();
345 EXPECT_THAT(message, EqualsProto(kExpected));
346 }
347
TEST(OfflineFramesTest,CanGenerateBwuIntroduction)348 TEST(OfflineFramesTest, CanGenerateBwuIntroduction) {
349 constexpr char kExpected[] =
350 R"pb(
351 version: V1
352 v1: <
353 type: BANDWIDTH_UPGRADE_NEGOTIATION
354 bandwidth_upgrade_negotiation: <
355 event_type: CLIENT_INTRODUCTION
356 client_introduction: < endpoint_id: "ABC" >
357 >
358 >)pb";
359 ByteArray bytes = ForBwuIntroduction(std::string(kEndpointId));
360 auto response = FromBytes(bytes);
361 ASSERT_TRUE(response.ok());
362 OfflineFrame message = FromBytes(bytes).result();
363 EXPECT_THAT(message, EqualsProto(kExpected));
364 }
365
TEST(OfflineFramesTest,CanGenerateKeepAlive)366 TEST(OfflineFramesTest, CanGenerateKeepAlive) {
367 constexpr char kExpected[] =
368 R"pb(
369 version: V1
370 v1: <
371 type: KEEP_ALIVE
372 keep_alive: <>
373 >)pb";
374 ByteArray bytes = ForKeepAlive();
375 auto response = FromBytes(bytes);
376 ASSERT_TRUE(response.ok());
377 OfflineFrame message = FromBytes(bytes).result();
378 EXPECT_THAT(message, EqualsProto(kExpected));
379 }
380
381 } // namespace
382 } // namespace parser
383 } // namespace connections
384 } // namespace nearby
385 } // namespace location
386