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"
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"
27 using testing::AtLeast
;
28 using testing::NiceMock
;
29 using testing::Return
;
30 using testing::StrictMock
;
31 using testing::SaveArg
;
33 namespace proximity_auth
{
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
{
59 MockBluetoothLowEnergyCharacteristicsFinder() {}
60 ~MockBluetoothLowEnergyCharacteristicsFinder() override
{}
63 class MockBluetoothLowEnergyConnection
: public BluetoothLowEnergyConnection
{
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
,
76 to_peripheral_char_uuid
,
77 from_peripheral_char_uuid
,
78 gatt_connection
.Pass(),
79 max_number_of_write_attempts
) {}
81 ~MockBluetoothLowEnergyConnection() override
{}
84 CreateCharacteristicsFinder
,
85 BluetoothLowEnergyCharacteristicsFinder
*(
86 const BluetoothLowEnergyCharacteristicsFinder::SuccessCallback
&
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
;
104 class ProximityAuthBluetoothLowEnergyConnectionTest
: public testing::Test
{
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
>(
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
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(),
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(_
, _
))
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(_
, _
))
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>(¬ify_session_success_callback_
),
224 SaveArg
<1>(¬ify_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(_
, _
, _
))
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<
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();
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
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());
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);
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_
;
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());
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(_
, _
, _
))
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)
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<
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
;
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
;
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.
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
599 EXPECT_CALL(*to_peripheral_char_
, WriteRemoteCharacteristic(_
, _
, _
))
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');
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(_
, _
, _
))
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
644 EXPECT_CALL(*to_peripheral_char_
, WriteRemoteCharacteristic(_
, _
, _
))
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');
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(_
, _
, _
))
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
675 EXPECT_CALL(*to_peripheral_char_
, WriteRemoteCharacteristic(_
, _
, _
))
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