Connecting only to paired devices in BLE connection finder.
[chromium-blink-merge.git] / components / proximity_auth / ble / bluetooth_low_energy_connection_unittest.cc
blob87b013a261884298cc7076222ed328e0e25575c8
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/proximity_auth/ble/bluetooth_low_energy_connection.h"
7 #include "base/bind.h"
8 #include "base/memory/ref_counted.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "components/proximity_auth/ble/bluetooth_low_energy_characteristics_finder.h"
11 #include "components/proximity_auth/connection_finder.h"
12 #include "components/proximity_auth/remote_device.h"
13 #include "components/proximity_auth/wire_message.h"
14 #include "device/bluetooth/bluetooth_adapter_factory.h"
15 #include "device/bluetooth/bluetooth_gatt_characteristic.h"
16 #include "device/bluetooth/bluetooth_uuid.h"
17 #include "device/bluetooth/test/mock_bluetooth_adapter.h"
18 #include "device/bluetooth/test/mock_bluetooth_device.h"
19 #include "device/bluetooth/test/mock_bluetooth_discovery_session.h"
20 #include "device/bluetooth/test/mock_bluetooth_gatt_characteristic.h"
21 #include "device/bluetooth/test/mock_bluetooth_gatt_connection.h"
22 #include "device/bluetooth/test/mock_bluetooth_gatt_notify_session.h"
23 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gtest/include/gtest/gtest.h"
26 using testing::_;
27 using testing::AtLeast;
28 using testing::NiceMock;
29 using testing::Return;
30 using testing::StrictMock;
31 using testing::SaveArg;
33 namespace proximity_auth {
34 namespace {
36 const char kDeviceName[] = "Device name";
37 const char kBluetoothAddress[] = "11:22:33:44:55:66";
39 const char kServiceUUID[] = "DEADBEEF-CAFE-FEED-FOOD-D15EA5EBEEEF";
40 const char kToPeripheralCharUUID[] = "FBAE09F2-0482-11E5-8418-1697F925EC7B";
41 const char kFromPeripheralCharUUID[] = "5539ED10-0483-11E5-8418-1697F925EC7B";
43 const char kServiceID[] = "service id";
44 const char kToPeripheralCharID[] = "to peripheral char id";
45 const char kFromPeripheralCharID[] = "from peripheral char id";
47 const device::BluetoothGattCharacteristic::Properties
48 kCharacteristicProperties =
49 device::BluetoothGattCharacteristic::PROPERTY_BROADCAST |
50 device::BluetoothGattCharacteristic::PROPERTY_READ |
51 device::BluetoothGattCharacteristic::PROPERTY_WRITE_WITHOUT_RESPONSE |
52 device::BluetoothGattCharacteristic::PROPERTY_INDICATE;
54 const int kMaxNumberOfTries = 3;
56 class MockBluetoothLowEnergyCharacteristicsFinder
57 : public BluetoothLowEnergyCharacteristicsFinder {
58 public:
59 MockBluetoothLowEnergyCharacteristicsFinder() {}
60 ~MockBluetoothLowEnergyCharacteristicsFinder() override {}
63 class MockBluetoothLowEnergyConnection : public BluetoothLowEnergyConnection {
64 public:
65 MockBluetoothLowEnergyConnection(
66 const RemoteDevice& remote_device,
67 scoped_refptr<device::BluetoothAdapter> adapter,
68 const device::BluetoothUUID remote_service_uuid,
69 const device::BluetoothUUID to_peripheral_char_uuid,
70 const device::BluetoothUUID from_peripheral_char_uuid,
71 scoped_ptr<device::BluetoothGattConnection> gatt_connection,
72 int max_number_of_write_attempts)
73 : BluetoothLowEnergyConnection(remote_device,
74 adapter,
75 remote_service_uuid,
76 to_peripheral_char_uuid,
77 from_peripheral_char_uuid,
78 gatt_connection.Pass(),
79 max_number_of_write_attempts) {}
81 ~MockBluetoothLowEnergyConnection() override {}
83 MOCK_METHOD2(
84 CreateCharacteristicsFinder,
85 BluetoothLowEnergyCharacteristicsFinder*(
86 const BluetoothLowEnergyCharacteristicsFinder::SuccessCallback&
87 success,
88 const BluetoothLowEnergyCharacteristicsFinder::ErrorCallback& error));
90 MOCK_METHOD2(OnDidSendMessage,
91 void(const WireMessage& message, bool success));
92 MOCK_METHOD1(OnBytesReceived, void(const std::string& bytes));
94 // Exposing inherited protected methods for testing.
95 using BluetoothLowEnergyConnection::GattCharacteristicValueChanged;
97 // Exposing inherited protected fields for testing.
98 using BluetoothLowEnergyConnection::status;
99 using BluetoothLowEnergyConnection::sub_status;
102 } // namespace
104 class ProximityAuthBluetoothLowEnergyConnectionTest : public testing::Test {
105 public:
106 ProximityAuthBluetoothLowEnergyConnectionTest()
107 : adapter_(new NiceMock<device::MockBluetoothAdapter>),
108 remote_device_({kDeviceName, kBluetoothAddress}),
109 service_uuid_(device::BluetoothUUID(kServiceUUID)),
110 to_peripheral_char_uuid_(device::BluetoothUUID(kToPeripheralCharUUID)),
111 from_peripheral_char_uuid_(
112 device::BluetoothUUID(kFromPeripheralCharUUID)),
113 gatt_connection_(new NiceMock<device::MockBluetoothGattConnection>(
114 kBluetoothAddress)),
115 gatt_connection_alias_(gatt_connection_.get()),
116 notify_session_alias_(NULL) {}
118 void SetUp() override {
119 device_ = make_scoped_ptr(new NiceMock<device::MockBluetoothDevice>(
120 adapter_.get(), 0, kDeviceName, kBluetoothAddress, false, false));
122 service_ = make_scoped_ptr(new NiceMock<device::MockBluetoothGattService>(
123 device_.get(), kServiceID, service_uuid_, true, false));
124 to_peripheral_char_ =
125 make_scoped_ptr(new NiceMock<device::MockBluetoothGattCharacteristic>(
126 service_.get(), kToPeripheralCharID, to_peripheral_char_uuid_,
127 false, kCharacteristicProperties,
128 device::BluetoothGattCharacteristic::PERMISSION_NONE));
130 from_peripheral_char_ =
131 make_scoped_ptr(new NiceMock<device::MockBluetoothGattCharacteristic>(
132 service_.get(), kFromPeripheralCharID, from_peripheral_char_uuid_,
133 false, kCharacteristicProperties,
134 device::BluetoothGattCharacteristic::PERMISSION_NONE));
136 device::BluetoothAdapterFactory::SetAdapterForTesting(adapter_);
138 std::vector<const device::BluetoothDevice*> devices;
139 devices.push_back(device_.get());
140 ON_CALL(*adapter_, GetDevices()).WillByDefault(Return(devices));
141 ON_CALL(*device_, GetGattService(kServiceID))
142 .WillByDefault(Return(service_.get()));
143 ON_CALL(*service_, GetCharacteristic(kFromPeripheralCharID))
144 .WillByDefault(Return(from_peripheral_char_.get()));
145 ON_CALL(*service_, GetCharacteristic(kToPeripheralCharID))
146 .WillByDefault(Return(to_peripheral_char_.get()));
149 // Creates a BluetoothLowEnergyConnection and verifies it's in DISCONNECTED
150 // state.
151 scoped_ptr<MockBluetoothLowEnergyConnection> CreateConnection() {
152 EXPECT_CALL(*adapter_, AddObserver(_));
153 EXPECT_CALL(*adapter_, RemoveObserver(_));
155 scoped_ptr<MockBluetoothLowEnergyConnection> connection(
156 new MockBluetoothLowEnergyConnection(
157 remote_device_, adapter_, service_uuid_, to_peripheral_char_uuid_,
158 from_peripheral_char_uuid_, gatt_connection_.Pass(),
159 kMaxNumberOfTries));
161 EXPECT_EQ(connection->sub_status(),
162 BluetoothLowEnergyConnection::SubStatus::DISCONNECTED);
163 EXPECT_EQ(connection->status(), Connection::DISCONNECTED);
165 return connection.Pass();
168 // Transitions |connection| from DISCONNECTED to WAITING_CHARACTERISTICS
169 // state, using an existing GATT connection.
170 void ConnectWithExistingGattConnection(
171 MockBluetoothLowEnergyConnection* connection) {
172 EXPECT_CALL(*gatt_connection_alias_, IsConnected()).WillOnce(Return(true));
173 EXPECT_CALL(*connection, CreateCharacteristicsFinder(_, _))
174 .WillOnce(
175 DoAll(SaveArg<0>(&characteristics_finder_success_callback_),
176 SaveArg<1>(&characteristics_finder_error_callback_),
177 Return(new MockBluetoothLowEnergyCharacteristicsFinder)));
179 connection->Connect();
181 EXPECT_EQ(connection->sub_status(),
182 BluetoothLowEnergyConnection::SubStatus::WAITING_CHARACTERISTICS);
183 EXPECT_EQ(connection->status(), Connection::IN_PROGRESS);
186 // Transitions |connection| from DISCONNECTED to WAITING_CHARACTERISTICS
187 // state, without an existing GATT connection.
188 void ConnectWithoutExistingGattConnection(
189 MockBluetoothLowEnergyConnection* connection) {
190 // Preparing |connection| for a CreateGattConnection call.
191 EXPECT_CALL(*gatt_connection_alias_, IsConnected()).WillOnce(Return(false));
192 EXPECT_CALL(*device_, CreateGattConnection(_, _))
193 .WillOnce(DoAll(SaveArg<0>(&create_gatt_connection_success_callback_),
194 SaveArg<1>(&create_gatt_connection_error_callback_)));
196 connection->Connect();
198 EXPECT_EQ(connection->sub_status(),
199 BluetoothLowEnergyConnection::SubStatus::WAITING_GATT_CONNECTION);
200 EXPECT_EQ(connection->status(), Connection::IN_PROGRESS);
202 // Preparing |connection| to run |create_gatt_connection_success_callback_|.
203 EXPECT_FALSE(create_gatt_connection_error_callback_.is_null());
204 ASSERT_FALSE(create_gatt_connection_success_callback_.is_null());
205 EXPECT_CALL(*connection, CreateCharacteristicsFinder(_, _))
206 .WillOnce(DoAll(
207 SaveArg<0>(&characteristics_finder_success_callback_),
208 SaveArg<1>(&characteristics_finder_error_callback_),
209 Return(new NiceMock<MockBluetoothLowEnergyCharacteristicsFinder>)));
211 create_gatt_connection_success_callback_.Run(make_scoped_ptr(
212 new NiceMock<device::MockBluetoothGattConnection>(kBluetoothAddress)));
214 EXPECT_EQ(connection->sub_status(),
215 BluetoothLowEnergyConnection::SubStatus::WAITING_CHARACTERISTICS);
216 EXPECT_EQ(connection->status(), Connection::IN_PROGRESS);
219 // Transitions |connection| from WAITING_CHARACTERISTICS to
220 // WAITING_NOTIFY_SESSION state.
221 void CharacteristicsFound(MockBluetoothLowEnergyConnection* connection) {
222 EXPECT_CALL(*from_peripheral_char_, StartNotifySession(_, _))
223 .WillOnce(DoAll(SaveArg<0>(&notify_session_success_callback_),
224 SaveArg<1>(&notify_session_error_callback_)));
225 EXPECT_FALSE(characteristics_finder_error_callback_.is_null());
226 ASSERT_FALSE(characteristics_finder_success_callback_.is_null());
228 characteristics_finder_success_callback_.Run(
229 {service_uuid_, kServiceID},
230 {to_peripheral_char_uuid_, kToPeripheralCharID},
231 {from_peripheral_char_uuid_, kFromPeripheralCharID});
233 EXPECT_EQ(connection->sub_status(),
234 BluetoothLowEnergyConnection::SubStatus::WAITING_NOTIFY_SESSION);
235 EXPECT_EQ(connection->status(), Connection::IN_PROGRESS);
238 // Transitions |connection| from WAITING_NOTIFY_SESSION to
239 // WAITING_RESPONSE_SIGNAL state.
240 void NotifySessionStarted(MockBluetoothLowEnergyConnection* connection) {
241 EXPECT_CALL(*to_peripheral_char_, WriteRemoteCharacteristic(_, _, _))
242 .WillOnce(
243 DoAll(SaveArg<0>(&last_value_written_on_to_peripheral_char_),
244 SaveArg<1>(&write_remote_characteristic_success_callback_),
245 SaveArg<2>(&write_remote_characteristic_error_callback_)));
246 EXPECT_FALSE(notify_session_error_callback_.is_null());
247 ASSERT_FALSE(notify_session_success_callback_.is_null());
249 // Store an alias for the notify session passed |connection|.
250 scoped_ptr<device::MockBluetoothGattNotifySession> notify_session(
251 new NiceMock<device::MockBluetoothGattNotifySession>(
252 kToPeripheralCharID));
253 notify_session_alias_ = notify_session.get();
254 notify_session_success_callback_.Run(notify_session.Pass());
256 EXPECT_EQ(connection->sub_status(),
257 BluetoothLowEnergyConnection::SubStatus::WAITING_RESPONSE_SIGNAL);
258 EXPECT_EQ(connection->status(), Connection::IN_PROGRESS);
261 // Transitions |connection| from WAITING_RESPONSE_SIGNAL to CONNECTED state.
262 void ResponseSignalReceived(MockBluetoothLowEnergyConnection* connection) {
263 // Written value contains only the
264 // BluetoothLowEneryConnection::ControlSignal::kInviteToConnectSignal.
265 const std::vector<uint8> kInviteToConnectSignal = ToByteVector(static_cast<
266 uint32>(
267 BluetoothLowEnergyConnection::ControlSignal::kInviteToConnectSignal));
268 EXPECT_EQ(last_value_written_on_to_peripheral_char_,
269 kInviteToConnectSignal);
271 EXPECT_CALL(*connection, OnDidSendMessage(_, _)).Times(0);
272 RunWriteCharacteristicSuccessCallback();
274 // Received the
275 // BluetoothLowEneryConnection::ControlSignal::kInvitationResponseSignal.
276 const std::vector<uint8> kInvitationResponseSignal = ToByteVector(
277 static_cast<uint32>(BluetoothLowEnergyConnection::ControlSignal::
278 kInvitationResponseSignal));
279 connection->GattCharacteristicValueChanged(
280 adapter_.get(), from_peripheral_char_.get(), kInvitationResponseSignal);
282 EXPECT_EQ(connection->sub_status(),
283 BluetoothLowEnergyConnection::SubStatus::CONNECTED);
284 EXPECT_EQ(connection->status(), Connection::CONNECTED);
287 // Transitions |connection| to a DISCONNECTED state regardless of its initial
288 // state.
289 void Disconnect(MockBluetoothLowEnergyConnection* connection) {
290 // A notify session was previously set.
291 if (notify_session_alias_)
292 EXPECT_CALL(*notify_session_alias_, Stop(_));
294 connection->Disconnect();
296 EXPECT_EQ(connection->sub_status(),
297 BluetoothLowEnergyConnection::SubStatus::DISCONNECTED);
298 EXPECT_EQ(connection->status(), Connection::DISCONNECTED);
301 void InitializeConnection(MockBluetoothLowEnergyConnection* connection) {
302 ConnectWithExistingGattConnection(connection);
303 CharacteristicsFound(connection);
304 NotifySessionStarted(connection);
305 ResponseSignalReceived(connection);
308 void RunWriteCharacteristicSuccessCallback() {
309 EXPECT_FALSE(write_remote_characteristic_error_callback_.is_null());
310 ASSERT_FALSE(write_remote_characteristic_success_callback_.is_null());
311 write_remote_characteristic_success_callback_.Run();
314 std::vector<uint8> CreateSendSignalWithSize(int message_size) {
315 std::vector<uint8> value = ToByteVector(static_cast<uint32>(
316 BluetoothLowEnergyConnection::ControlSignal::kSendSignal));
317 std::vector<uint8> size = ToByteVector(static_cast<uint32>(message_size));
318 value.insert(value.end(), size.begin(), size.end());
319 return value;
322 std::vector<uint8> ToByteVector(uint32 value) {
323 std::vector<uint8> bytes(4, 0);
324 bytes[0] = static_cast<uint8>(value);
325 bytes[1] = static_cast<uint8>(value >> 8);
326 bytes[2] = static_cast<uint8>(value >> 16);
327 bytes[3] = static_cast<uint8>(value >> 24);
328 return bytes;
331 protected:
332 scoped_refptr<device::MockBluetoothAdapter> adapter_;
333 RemoteDevice remote_device_;
334 device::BluetoothUUID service_uuid_;
335 device::BluetoothUUID to_peripheral_char_uuid_;
336 device::BluetoothUUID from_peripheral_char_uuid_;
337 scoped_ptr<device::MockBluetoothGattConnection> gatt_connection_;
338 device::MockBluetoothGattConnection* gatt_connection_alias_;
339 scoped_ptr<device::MockBluetoothDevice> device_;
340 scoped_ptr<device::MockBluetoothGattService> service_;
341 scoped_ptr<device::MockBluetoothGattCharacteristic> to_peripheral_char_;
342 scoped_ptr<device::MockBluetoothGattCharacteristic> from_peripheral_char_;
343 std::vector<uint8> last_value_written_on_to_peripheral_char_;
344 device::MockBluetoothGattNotifySession* notify_session_alias_;
346 // Callbacks
347 device::BluetoothDevice::GattConnectionCallback
348 create_gatt_connection_success_callback_;
349 device::BluetoothDevice::ConnectErrorCallback
350 create_gatt_connection_error_callback_;
352 BluetoothLowEnergyCharacteristicsFinder::SuccessCallback
353 characteristics_finder_success_callback_;
354 BluetoothLowEnergyCharacteristicsFinder::ErrorCallback
355 characteristics_finder_error_callback_;
357 device::BluetoothGattCharacteristic::NotifySessionCallback
358 notify_session_success_callback_;
359 device::BluetoothGattCharacteristic::ErrorCallback
360 notify_session_error_callback_;
362 base::Closure write_remote_characteristic_success_callback_;
363 device::BluetoothGattCharacteristic::ErrorCallback
364 write_remote_characteristic_error_callback_;
367 TEST_F(ProximityAuthBluetoothLowEnergyConnectionTest,
368 CreateAndDestroyWithouthConnectCallDoesntCrash) {
369 BluetoothLowEnergyConnection connection(
370 remote_device_, adapter_, service_uuid_, to_peripheral_char_uuid_,
371 from_peripheral_char_uuid_, gatt_connection_.Pass(), kMaxNumberOfTries);
374 TEST_F(ProximityAuthBluetoothLowEnergyConnectionTest,
375 Disconect_WithoutConnectDoesntCrash) {
376 scoped_ptr<MockBluetoothLowEnergyConnection> connection(CreateConnection());
377 Disconnect(connection.get());
380 TEST_F(ProximityAuthBluetoothLowEnergyConnectionTest,
381 Connect_Success_WithGattConnection) {
382 scoped_ptr<MockBluetoothLowEnergyConnection> connection(CreateConnection());
383 ConnectWithExistingGattConnection(connection.get());
384 CharacteristicsFound(connection.get());
385 NotifySessionStarted(connection.get());
386 ResponseSignalReceived(connection.get());
389 TEST_F(ProximityAuthBluetoothLowEnergyConnectionTest,
390 Connect_Success_WithoutGattConnection) {
391 scoped_ptr<MockBluetoothLowEnergyConnection> connection(CreateConnection());
392 ConnectWithoutExistingGattConnection(connection.get());
393 CharacteristicsFound(connection.get());
394 NotifySessionStarted(connection.get());
395 ResponseSignalReceived(connection.get());
398 TEST_F(ProximityAuthBluetoothLowEnergyConnectionTest,
399 Connect_Success_Disconnect) {
400 scoped_ptr<MockBluetoothLowEnergyConnection> connection(CreateConnection());
401 InitializeConnection(connection.get());
402 Disconnect(connection.get());
405 TEST_F(
406 ProximityAuthBluetoothLowEnergyConnectionTest,
407 Connect_Incomplete_Disconnect_FromWaitingCharacteristicsStateWithoutExistingGattConnection) {
408 scoped_ptr<MockBluetoothLowEnergyConnection> connection(CreateConnection());
409 ConnectWithoutExistingGattConnection(connection.get());
410 Disconnect(connection.get());
413 TEST_F(ProximityAuthBluetoothLowEnergyConnectionTest,
414 Connect_Incomplete_Disconnect_FromWaitingCharacteristicsState) {
415 scoped_ptr<MockBluetoothLowEnergyConnection> connection(CreateConnection());
416 ConnectWithExistingGattConnection(connection.get());
417 Disconnect(connection.get());
420 TEST_F(ProximityAuthBluetoothLowEnergyConnectionTest,
421 Connect_Incomplete_Disconnect_FromWaitingNotifySessionState) {
422 scoped_ptr<MockBluetoothLowEnergyConnection> connection(CreateConnection());
423 ConnectWithExistingGattConnection(connection.get());
424 CharacteristicsFound(connection.get());
425 Disconnect(connection.get());
428 TEST_F(ProximityAuthBluetoothLowEnergyConnectionTest,
429 Connect_Incomplete_Disconnect_FromWaitingResponseSignalState) {
430 scoped_ptr<MockBluetoothLowEnergyConnection> connection(CreateConnection());
431 ConnectWithExistingGattConnection(connection.get());
432 CharacteristicsFound(connection.get());
433 NotifySessionStarted(connection.get());
434 Disconnect(connection.get());
437 TEST_F(ProximityAuthBluetoothLowEnergyConnectionTest,
438 Connect_Fails_CharacteristicsNotFound) {
439 scoped_ptr<MockBluetoothLowEnergyConnection> connection(CreateConnection());
440 ConnectWithExistingGattConnection(connection.get());
442 EXPECT_CALL(*from_peripheral_char_, StartNotifySession(_, _)).Times(0);
443 EXPECT_FALSE(characteristics_finder_success_callback_.is_null());
444 ASSERT_FALSE(characteristics_finder_error_callback_.is_null());
446 characteristics_finder_error_callback_.Run(
447 {to_peripheral_char_uuid_, kToPeripheralCharID},
448 {from_peripheral_char_uuid_, kFromPeripheralCharID});
450 EXPECT_EQ(connection->sub_status(),
451 BluetoothLowEnergyConnection::SubStatus::DISCONNECTED);
452 EXPECT_EQ(connection->status(), Connection::DISCONNECTED);
455 TEST_F(ProximityAuthBluetoothLowEnergyConnectionTest,
456 Connect_Fails_NotifySessionError) {
457 scoped_ptr<MockBluetoothLowEnergyConnection> connection(CreateConnection());
458 ConnectWithExistingGattConnection(connection.get());
459 CharacteristicsFound(connection.get());
461 EXPECT_CALL(*to_peripheral_char_, WriteRemoteCharacteristic(_, _, _))
462 .Times(0);
463 EXPECT_FALSE(notify_session_success_callback_.is_null());
464 ASSERT_FALSE(notify_session_error_callback_.is_null());
466 notify_session_error_callback_.Run(
467 device::BluetoothGattService::GATT_ERROR_UNKNOWN);
469 EXPECT_EQ(connection->sub_status(),
470 BluetoothLowEnergyConnection::SubStatus::DISCONNECTED);
471 EXPECT_EQ(connection->status(), Connection::DISCONNECTED);
474 TEST_F(ProximityAuthBluetoothLowEnergyConnectionTest,
475 Connect_Fails_ErrorSendingInviteToConnectSignal) {
476 scoped_ptr<MockBluetoothLowEnergyConnection> connection(CreateConnection());
477 ConnectWithExistingGattConnection(connection.get());
478 CharacteristicsFound(connection.get());
479 NotifySessionStarted(connection.get());
481 // |connection| will call WriteRemoteCharacteristics(_,_) to try to send the
482 // message |kMaxNumberOfTries| times. There is alredy one EXPECTA_CALL for
483 // WriteRemoteCharacteristic(_,_,_) in NotifySessionStated, that's why we use
484 // |kMaxNumberOfTries-1| in the EXPECT_CALL statement.
485 EXPECT_CALL(*connection, OnDidSendMessage(_, _)).Times(0);
486 EXPECT_CALL(*to_peripheral_char_, WriteRemoteCharacteristic(_, _, _))
487 .Times(kMaxNumberOfTries - 1)
488 .WillRepeatedly(
489 DoAll(SaveArg<0>(&last_value_written_on_to_peripheral_char_),
490 SaveArg<1>(&write_remote_characteristic_success_callback_),
491 SaveArg<2>(&write_remote_characteristic_error_callback_)));
493 for (int i = 0; i < kMaxNumberOfTries; i++) {
494 const std::vector<uint8> kInviteToConnectSignal = ToByteVector(static_cast<
495 uint32>(
496 BluetoothLowEnergyConnection::ControlSignal::kInviteToConnectSignal));
497 EXPECT_EQ(last_value_written_on_to_peripheral_char_,
498 kInviteToConnectSignal);
499 ASSERT_FALSE(write_remote_characteristic_error_callback_.is_null());
500 EXPECT_FALSE(write_remote_characteristic_success_callback_.is_null());
501 write_remote_characteristic_error_callback_.Run(
502 device::BluetoothGattService::GATT_ERROR_UNKNOWN);
505 EXPECT_EQ(connection->sub_status(),
506 BluetoothLowEnergyConnection::SubStatus::DISCONNECTED);
507 EXPECT_EQ(connection->status(), Connection::DISCONNECTED);
510 TEST_F(ProximityAuthBluetoothLowEnergyConnectionTest,
511 Connect_Fails_CharacteristicsNotFound_WithoutExistingGattConnection) {
512 scoped_ptr<MockBluetoothLowEnergyConnection> connection(CreateConnection());
513 ConnectWithoutExistingGattConnection(connection.get());
515 EXPECT_CALL(*from_peripheral_char_, StartNotifySession(_, _)).Times(0);
516 EXPECT_FALSE(characteristics_finder_success_callback_.is_null());
517 ASSERT_FALSE(characteristics_finder_error_callback_.is_null());
519 characteristics_finder_error_callback_.Run(
520 {to_peripheral_char_uuid_, kToPeripheralCharID},
521 {from_peripheral_char_uuid_, kFromPeripheralCharID});
523 EXPECT_EQ(connection->sub_status(),
524 BluetoothLowEnergyConnection::SubStatus::DISCONNECTED);
525 EXPECT_EQ(connection->status(), Connection::DISCONNECTED);
528 TEST_F(ProximityAuthBluetoothLowEnergyConnectionTest,
529 Receive_MessageSmallerThanCharacteristicSize) {
530 scoped_ptr<MockBluetoothLowEnergyConnection> connection(CreateConnection());
531 InitializeConnection(connection.get());
533 std::string received_bytes;
534 EXPECT_CALL(*connection, OnBytesReceived(_))
535 .WillOnce(SaveArg<0>(&received_bytes));
537 // Message (bytes) that is going to be received.
538 int message_size = 75;
539 std::string message(message_size, 'A');
541 // Sending the |kSendSignal| + |message_size|.
542 connection->GattCharacteristicValueChanged(
543 adapter_.get(), from_peripheral_char_.get(),
544 CreateSendSignalWithSize(message_size));
546 // Sending the message.
547 std::vector<uint8> value;
548 value.push_back(0);
549 value.insert(value.end(), message.begin(), message.end());
550 connection->GattCharacteristicValueChanged(
551 adapter_.get(), from_peripheral_char_.get(), value);
553 EXPECT_EQ(received_bytes, message);
556 TEST_F(ProximityAuthBluetoothLowEnergyConnectionTest,
557 Receive_MessageLargerThanCharacteristicSize) {
558 scoped_ptr<MockBluetoothLowEnergyConnection> connection(CreateConnection());
559 InitializeConnection(connection.get());
561 std::string received_bytes;
562 int chunk_size = 100;
563 EXPECT_CALL(*connection, OnBytesReceived(_))
564 .WillOnce(SaveArg<0>(&received_bytes));
566 // Message (bytes) that is going to be received.
567 int message_size = 150;
568 std::string message(message_size, 'A');
570 // Sending the |kSendSignal| + |message_size|.
571 connection->GattCharacteristicValueChanged(
572 adapter_.get(), from_peripheral_char_.get(),
573 CreateSendSignalWithSize(message_size));
575 // Sending the first chunk.
576 std::vector<uint8> value;
577 value.push_back(0);
578 value.insert(value.end(), message.begin(), message.begin() + chunk_size);
579 connection->GattCharacteristicValueChanged(
580 adapter_.get(), from_peripheral_char_.get(), value);
582 // Sending the second chunk.
583 value.clear();
584 value.push_back(0);
585 value.insert(value.end(), message.begin() + chunk_size, message.end());
586 connection->GattCharacteristicValueChanged(
587 adapter_.get(), from_peripheral_char_.get(), value);
589 EXPECT_EQ(received_bytes, message);
592 TEST_F(ProximityAuthBluetoothLowEnergyConnectionTest,
593 SendMessage_SmallerThanCharacteristicSize) {
594 scoped_ptr<MockBluetoothLowEnergyConnection> connection(CreateConnection());
595 InitializeConnection(connection.get());
597 // Expecting a first call of WriteRemoteCharacteristic, after SendMessage is
598 // called.
599 EXPECT_CALL(*to_peripheral_char_, WriteRemoteCharacteristic(_, _, _))
600 .WillOnce(
601 DoAll(SaveArg<0>(&last_value_written_on_to_peripheral_char_),
602 SaveArg<1>(&write_remote_characteristic_success_callback_),
603 SaveArg<2>(&write_remote_characteristic_error_callback_)));
605 // Message (bytes) that is going to be sent.
606 int message_size = 75;
607 std::string message(message_size, 'A');
608 message[0] = 'B';
609 connection->SendMessage(make_scoped_ptr(new FakeWireMessage(message)));
611 // Expecting that |kSendSignal| + |message_size| was written.
612 EXPECT_EQ(last_value_written_on_to_peripheral_char_,
613 CreateSendSignalWithSize(message_size));
615 // Expecting a second call of WriteRemoteCharacteristic, after success
616 // callback is called.
617 EXPECT_CALL(*to_peripheral_char_, WriteRemoteCharacteristic(_, _, _))
618 .WillOnce(
619 DoAll(SaveArg<0>(&last_value_written_on_to_peripheral_char_),
620 SaveArg<1>(&write_remote_characteristic_success_callback_),
621 SaveArg<2>(&write_remote_characteristic_error_callback_)));
623 RunWriteCharacteristicSuccessCallback();
625 // Expecting that the message was written.
626 std::vector<uint8> expected_value(message.begin(), message.end());
627 std::vector<uint8> written_value(
628 last_value_written_on_to_peripheral_char_.begin() + 1,
629 last_value_written_on_to_peripheral_char_.end());
630 EXPECT_EQ(expected_value, written_value);
631 EXPECT_EQ(expected_value.size(), written_value.size());
633 EXPECT_CALL(*connection, OnDidSendMessage(_, _));
634 RunWriteCharacteristicSuccessCallback();
637 TEST_F(ProximityAuthBluetoothLowEnergyConnectionTest,
638 SendMessage_LagerThanCharacteristicSize) {
639 scoped_ptr<MockBluetoothLowEnergyConnection> connection(CreateConnection());
640 InitializeConnection(connection.get());
642 // Expecting a first call of WriteRemoteCharacteristic, after SendMessage is
643 // called.
644 EXPECT_CALL(*to_peripheral_char_, WriteRemoteCharacteristic(_, _, _))
645 .WillOnce(
646 DoAll(SaveArg<0>(&last_value_written_on_to_peripheral_char_),
647 SaveArg<1>(&write_remote_characteristic_success_callback_),
648 SaveArg<2>(&write_remote_characteristic_error_callback_)));
650 // Message (bytes) that is going to be sent.
651 int message_size = 150;
652 std::string message(message_size, 'A');
653 message[0] = 'B';
654 connection->SendMessage(make_scoped_ptr(new FakeWireMessage(message)));
656 // Expecting that |kSendSignal| + |message_size| was written.
657 EXPECT_EQ(last_value_written_on_to_peripheral_char_,
658 CreateSendSignalWithSize(message_size));
660 // Expecting a second call of WriteRemoteCharacteristic, after success
661 // callback is called.
662 EXPECT_CALL(*to_peripheral_char_, WriteRemoteCharacteristic(_, _, _))
663 .WillOnce(
664 DoAll(SaveArg<0>(&last_value_written_on_to_peripheral_char_),
665 SaveArg<1>(&write_remote_characteristic_success_callback_),
666 SaveArg<2>(&write_remote_characteristic_error_callback_)));
668 RunWriteCharacteristicSuccessCallback();
669 std::vector<uint8> bytes_received(
670 last_value_written_on_to_peripheral_char_.begin() + 1,
671 last_value_written_on_to_peripheral_char_.end());
673 // Expecting a third call of WriteRemoteCharacteristic, after success callback
674 // is called.
675 EXPECT_CALL(*to_peripheral_char_, WriteRemoteCharacteristic(_, _, _))
676 .WillOnce(
677 DoAll(SaveArg<0>(&last_value_written_on_to_peripheral_char_),
678 SaveArg<1>(&write_remote_characteristic_success_callback_),
679 SaveArg<2>(&write_remote_characteristic_error_callback_)));
681 RunWriteCharacteristicSuccessCallback();
682 bytes_received.insert(bytes_received.end(),
683 last_value_written_on_to_peripheral_char_.begin() + 1,
684 last_value_written_on_to_peripheral_char_.end());
686 // Expecting that the message was written.
687 std::vector<uint8> expected_value(message.begin(), message.end());
688 EXPECT_EQ(expected_value.size(), bytes_received.size());
689 EXPECT_EQ(expected_value, bytes_received);
691 EXPECT_CALL(*connection, OnDidSendMessage(_, _));
692 RunWriteCharacteristicSuccessCallback();
695 } // namespace proximity_auth