| // Copyright 2016 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chromeos/services/secure_channel/ble_weave_packet_generator.h" |
| |
| #include <algorithm> |
| #include <memory> |
| #include <string> |
| |
| #include "base/logging.h" |
| #include "base/macros.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace chromeos { |
| |
| namespace secure_channel { |
| |
| namespace weave { |
| |
| class SecureChannelBluetoothLowEnergyWeavePacketGeneratorTest |
| : public testing::Test { |
| protected: |
| SecureChannelBluetoothLowEnergyWeavePacketGeneratorTest() {} |
| |
| void TestConnectionCloseWithReason(ReasonForClose reason_for_close, |
| uint8_t expected_reason_for_close) { |
| std::unique_ptr<BluetoothLowEnergyWeavePacketGenerator> generator = |
| std::make_unique<BluetoothLowEnergyWeavePacketGenerator>(); |
| |
| Packet packet = generator->CreateConnectionClose(reason_for_close); |
| |
| const uint16_t kCloseSize = 3; |
| Packet expected(kCloseSize, 0); |
| // uWeave Header: |
| // 1--- ---- : type = 1 (control packet) |
| // -000 ---- : counter = 0 |
| // ---- 0010 : command = 2 (close) |
| // 1000 0010 = 0x82 |
| expected = {0x82, kEmptyUpperByte, expected_reason_for_close}; |
| |
| EXPECT_EQ(expected, packet); |
| } |
| |
| uint8_t GetCounterFromHeader(uint8_t header) { return (header >> 4) & 7; } |
| |
| uint8_t GetPacketType(uint8_t header) { return (header >> 7) & 1; } |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN( |
| SecureChannelBluetoothLowEnergyWeavePacketGeneratorTest); |
| }; |
| |
| TEST_F(SecureChannelBluetoothLowEnergyWeavePacketGeneratorTest, |
| CreateConnectionRequestTest) { |
| std::unique_ptr<BluetoothLowEnergyWeavePacketGenerator> generator = |
| std::make_unique<BluetoothLowEnergyWeavePacketGenerator>(); |
| |
| Packet packet = generator->CreateConnectionRequest(); |
| |
| const uint16_t kRequestSize = 7; |
| Packet expected(kRequestSize, 0); |
| // uWeave Header: |
| // 1--- ---- : type = 1 (control packet) |
| // -000 ---- : counter = 0 |
| // ---- 0000 : command = 0 (request) |
| // 1000 0000 = 0x80 |
| expected = {0x80, |
| kEmptyUpperByte, |
| kByteWeaveVersion, |
| kEmptyUpperByte, |
| kByteWeaveVersion, |
| kEmptyUpperByte, |
| kByteSelectMaxPacketSize}; |
| |
| EXPECT_EQ(expected, packet); |
| } |
| |
| TEST_F(SecureChannelBluetoothLowEnergyWeavePacketGeneratorTest, |
| CreateConnectionResponseWithDefaultPacketSizeTest) { |
| std::unique_ptr<BluetoothLowEnergyWeavePacketGenerator> generator = |
| std::make_unique<BluetoothLowEnergyWeavePacketGenerator>(); |
| |
| Packet packet = generator->CreateConnectionResponse(); |
| |
| const uint16_t kResponseSize = 5; |
| Packet expected_default(kResponseSize, 0); |
| // uWeave Header: |
| // 1--- ---- : type = 1 (control packet) |
| // -000 ---- : counter = 0 |
| // ---- 0001 : command = 1 (response) |
| // 1000 0001 = 0x81 |
| expected_default = {0x81, kEmptyUpperByte, kByteWeaveVersion, kEmptyUpperByte, |
| kByteDefaultMaxPacketSize}; |
| |
| EXPECT_EQ(expected_default, packet); |
| } |
| |
| TEST_F(SecureChannelBluetoothLowEnergyWeavePacketGeneratorTest, |
| CreateConnectionResponseWithSelectedPacketSizeTest) { |
| std::unique_ptr<BluetoothLowEnergyWeavePacketGenerator> generator = |
| std::make_unique<BluetoothLowEnergyWeavePacketGenerator>(); |
| |
| const uint8_t kSelectedPacketSize = 30; |
| const uint16_t kResponseSize = 5; |
| |
| generator->SetMaxPacketSize(kSelectedPacketSize); |
| |
| Packet packet = generator->CreateConnectionResponse(); |
| |
| Packet expected_selected(kResponseSize, 0); |
| // uWeave Header: |
| // 1--- ---- : type = 1 (control packet) |
| // -000 ---- : counter = 0 |
| // ---- 0001 : command = 1 (response) |
| // 1000 0001 = 0x81 |
| expected_selected = {0x81, kEmptyUpperByte, kByteWeaveVersion, |
| kEmptyUpperByte, kSelectedPacketSize}; |
| EXPECT_EQ(expected_selected, packet); |
| } |
| |
| TEST_F(SecureChannelBluetoothLowEnergyWeavePacketGeneratorTest, |
| CreateConnectionCloseTest) { |
| // Reason for close spec of uWeave. |
| // 0x00: Close without error |
| // 0x01: Unknown error |
| // 0x02: No common version supported |
| // 0x03: Received packet out of sequence |
| // 0x80: Application error |
| |
| TestConnectionCloseWithReason(ReasonForClose::CLOSE_WITHOUT_ERROR, 0x00); |
| TestConnectionCloseWithReason(ReasonForClose::UNKNOWN_ERROR, 0x01); |
| TestConnectionCloseWithReason(ReasonForClose::NO_COMMON_VERSION_SUPPORTED, |
| 0x02); |
| TestConnectionCloseWithReason(ReasonForClose::RECEIVED_PACKET_OUT_OF_SEQUENCE, |
| 0x03); |
| TestConnectionCloseWithReason(ReasonForClose::APPLICATION_ERROR, 0x80); |
| } |
| |
| TEST_F(SecureChannelBluetoothLowEnergyWeavePacketGeneratorTest, |
| EncodeDataMessageWithDefaultPacketSizeTest) { |
| std::unique_ptr<BluetoothLowEnergyWeavePacketGenerator> generator = |
| std::make_unique<BluetoothLowEnergyWeavePacketGenerator>(); |
| |
| std::string data = "abcdefghijklmnopqrstuvwxyz"; |
| |
| std::vector<Packet> packets = generator->EncodeDataMessage(data); |
| |
| std::vector<Packet> expected(2); |
| |
| // uWeave Header: |
| // 0--- ---- : type = 0 (data packet) |
| // -000 ---- : counter = 0 |
| // ---- 1--- : first packet = true |
| // ---- -0-- : last packet = false |
| // ---- --00 : defined by uWeave to be 0 |
| // 0000 1000 = 0x08 |
| expected[0] = {0x08, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', |
| 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's'}; |
| |
| // uWeave Header: |
| // 0--- ---- : type = 0 (data packet) |
| // -001 ---- : counter = 1 |
| // ---- 0--- : first packet = false |
| // ---- -1-- : last packet = true |
| // ---- --00 : defined by uWeave to be 0 |
| // 0001 0100 = 0x14 |
| expected[1] = {0x14, 't', 'u', 'v', 'w', 'x', 'y', 'z'}; |
| |
| EXPECT_EQ(expected, packets); |
| } |
| |
| TEST_F(SecureChannelBluetoothLowEnergyWeavePacketGeneratorTest, |
| EncodeDataMessageWithSelectedPacketSizeTest) { |
| std::unique_ptr<BluetoothLowEnergyWeavePacketGenerator> generator = |
| std::make_unique<BluetoothLowEnergyWeavePacketGenerator>(); |
| |
| const uint32_t packet_size = 30; |
| const uint32_t residual_packet_size = 2; |
| std::string a(packet_size - 1, 'a'); |
| std::string b(packet_size - 1, 'b'); |
| std::string c(residual_packet_size - 1, 'c'); |
| |
| std::string data = a + b + c; |
| |
| generator->SetMaxPacketSize(packet_size); |
| |
| std::vector<Packet> packets = generator->EncodeDataMessage(data); |
| |
| std::vector<Packet> expected(3); |
| |
| expected[0].assign(packet_size, 'a'); |
| // uWeave Header: |
| // 0--- ---- : type = 0 (data packet) |
| // -000 ---- : counter = 0 |
| // ---- 1--- : first packet = true |
| // ---- -0-- : last packet = false |
| // ---- --00 : defined by uWeave to be 0 |
| // 0000 1000 = 0x08 |
| expected[0][0] = 0x08; |
| |
| expected[1].assign(packet_size, 'b'); |
| // uWeave Header: |
| // 0--- ---- : type = 0 (data packet) |
| // -001 ---- : counter = 1 |
| // ---- 0--- : first packet = false |
| // ---- -0-- : last packet = false |
| // ---- --00 : defined by uWeave to be 0 |
| // 0001 0000 = 0x10 |
| expected[1][0] = 0x10; |
| |
| expected[2].assign(residual_packet_size, 'c'); |
| // uWeave Header: |
| // 0--- ---- : type = 0 (data packet) |
| // -010 ---- : counter = 2 |
| // ---- 0--- : first packet = false |
| // ---- -1-- : last packet = true |
| // ---- --00 : defined by uWeave to be 0 |
| // 0010 0100 = 0x24 |
| expected[2][0] = 0x24; |
| |
| EXPECT_EQ(expected, packets); |
| } |
| |
| TEST_F(SecureChannelBluetoothLowEnergyWeavePacketGeneratorTest, |
| PacketCounterForMixedPacketTypesTest) { |
| std::unique_ptr<BluetoothLowEnergyWeavePacketGenerator> generator = |
| std::make_unique<BluetoothLowEnergyWeavePacketGenerator>(); |
| |
| Packet packet = generator->CreateConnectionRequest(); |
| |
| EXPECT_EQ(0, GetCounterFromHeader(packet[0])); |
| |
| std::string data = "a"; |
| std::vector<Packet> packets = generator->EncodeDataMessage(data); |
| |
| EXPECT_EQ(1, GetCounterFromHeader(packets[0][0])); |
| |
| packet = generator->CreateConnectionClose(ReasonForClose::UNKNOWN_ERROR); |
| |
| EXPECT_EQ(2, GetCounterFromHeader(packet[0])); |
| } |
| |
| TEST_F(SecureChannelBluetoothLowEnergyWeavePacketGeneratorTest, |
| PacketCounterWrappedAroundTest) { |
| std::unique_ptr<BluetoothLowEnergyWeavePacketGenerator> generator = |
| std::make_unique<BluetoothLowEnergyWeavePacketGenerator>(); |
| |
| const uint8_t kNumPackets = 100; |
| std::string data(kNumPackets * kByteDefaultMaxPacketSize, 'a'); |
| |
| std::vector<Packet> packets = generator->EncodeDataMessage(data); |
| |
| std::vector<Packet> expected(kNumPackets); |
| |
| const uint8_t kDataType = 0; |
| |
| for (uint8_t i = 0; i < kNumPackets; ++i) { |
| uint8_t header = packets[i][0]; |
| EXPECT_EQ(i % kMaxPacketCounter, GetCounterFromHeader(header)); |
| EXPECT_EQ(kDataType, GetPacketType(header)); |
| } |
| } |
| |
| } // namespace weave |
| |
| } // namespace secure_channel |
| |
| } // namespace chromeos |