mirror of
https://github.com/google/pebble.git
synced 2025-03-22 11:42:19 +00:00
207 lines
7.4 KiB
C
207 lines
7.4 KiB
C
/*
|
|
* Copyright 2024 Google LLC
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "services/common/bluetooth/bluetooth_persistent_storage.h"
|
|
#include "services/common/bluetooth/local_addr.h"
|
|
|
|
#include <bluetooth/bluetooth_types.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <clar.h>
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Fakes / Stubs
|
|
|
|
#include "stubs_bt_lock.h"
|
|
#include "stubs_logging.h"
|
|
#include "stubs_passert.h"
|
|
|
|
static bool s_last_driver_allow_cycling;
|
|
BTDeviceAddress s_last_driver_addr;
|
|
bool s_last_driver_addr_is_null;
|
|
void bt_driver_set_local_address(bool allow_cycling,
|
|
const BTDeviceAddress *pinned_address) {
|
|
s_last_driver_allow_cycling = allow_cycling;
|
|
if (pinned_address) {
|
|
s_last_driver_addr_is_null = false;
|
|
s_last_driver_addr = *pinned_address;
|
|
} else {
|
|
s_last_driver_addr_is_null = true;
|
|
memset(&s_last_driver_addr, 0x00, sizeof(s_last_driver_addr));
|
|
}
|
|
return cl_mock_type(void);
|
|
}
|
|
|
|
BTDeviceAddress s_last_bt_persist_pinned_addr;
|
|
bool s_last_bt_persist_pinned_addr_is_null;
|
|
|
|
bool bt_persistent_storage_get_ble_pinned_address(BTDeviceAddress *address_out) {
|
|
if (s_last_bt_persist_pinned_addr_is_null) {
|
|
return false;
|
|
}
|
|
if (address_out) {
|
|
*address_out = s_last_bt_persist_pinned_addr;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool bt_persistent_storage_set_ble_pinned_address(const BTDeviceAddress *addr) {
|
|
if (addr) {
|
|
s_last_bt_persist_pinned_addr_is_null = false;
|
|
s_last_bt_persist_pinned_addr = *addr;
|
|
} else {
|
|
s_last_bt_persist_pinned_addr_is_null = true;
|
|
memset(&s_last_bt_persist_pinned_addr, 0x00, sizeof(s_last_bt_persist_pinned_addr));
|
|
}
|
|
return cl_mock_type(bool);
|
|
}
|
|
|
|
bool bt_persistent_storage_has_pinned_ble_pairings(void) {
|
|
return cl_mock_type(bool);
|
|
}
|
|
|
|
#define TEST_PINNED_ADDR_1 ((BTDeviceAddress){ .octets = { 0x11, 0x22, 0x33, 0x33, 0x44, 0x55 } })
|
|
#define TEST_PINNED_ADDR_2 ((BTDeviceAddress){ .octets = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff } })
|
|
|
|
bool bt_driver_id_generate_private_resolvable_address(BTDeviceAddress *root_pinned_address_out) {
|
|
*root_pinned_address_out = TEST_PINNED_ADDR_1;
|
|
return true;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Tests
|
|
|
|
#define TEST_BONDING_ID ((BTBondingID) 1)
|
|
|
|
static void prv_init_no_pinnings_no_pinned_address(void) {
|
|
cl_will_return(bt_persistent_storage_has_pinned_ble_pairings, false);
|
|
cl_will_return(bt_persistent_storage_set_ble_pinned_address, true);
|
|
cl_will_return(bt_driver_set_local_address, 0);
|
|
s_last_bt_persist_pinned_addr_is_null = true;
|
|
bt_local_addr_init();
|
|
}
|
|
|
|
static void prv_assert_driver_addr_is_null(void) {
|
|
cl_assert_equal_b(s_last_driver_addr_is_null, true);
|
|
cl_assert_equal_m(&s_last_driver_addr, &(BTDeviceAddress){}, sizeof(s_last_driver_addr));
|
|
}
|
|
|
|
static void prv_assert_driver_addr_is_addr1(void) {
|
|
cl_assert_equal_b(s_last_driver_addr_is_null, false);
|
|
cl_assert_equal_m(&s_last_driver_addr, &TEST_PINNED_ADDR_1, sizeof(s_last_driver_addr));
|
|
}
|
|
|
|
static void prv_assert_driver_addr_is_addr2(void) {
|
|
cl_assert_equal_b(s_last_driver_addr_is_null, false);
|
|
cl_assert_equal_m(&s_last_driver_addr, &TEST_PINNED_ADDR_2, sizeof(s_last_driver_addr));
|
|
}
|
|
|
|
void test_local_addr__initialize(void) {
|
|
memset(&s_last_bt_persist_pinned_addr, 0xff, sizeof(s_last_bt_persist_pinned_addr));
|
|
memset(&s_last_driver_addr, 0xff, sizeof(s_last_driver_addr));
|
|
s_last_bt_persist_pinned_addr_is_null = false;
|
|
s_last_driver_allow_cycling = false;
|
|
s_last_driver_addr_is_null = false;
|
|
}
|
|
|
|
void test_local_addr__cleanup(void) {
|
|
}
|
|
|
|
void test_local_addr__init_generates_pinned_address_if_needed(void) {
|
|
prv_init_no_pinnings_no_pinned_address();
|
|
cl_assert_equal_b(false, s_last_bt_persist_pinned_addr_is_null);
|
|
cl_assert_equal_m(&s_last_bt_persist_pinned_addr,
|
|
&TEST_PINNED_ADDR_1, sizeof(s_last_bt_persist_pinned_addr));
|
|
cl_assert_equal_b(true, s_last_driver_allow_cycling);
|
|
}
|
|
|
|
void test_local_addr__init_loads_stored_pinned_address(void) {
|
|
cl_will_return(bt_persistent_storage_has_pinned_ble_pairings, true);
|
|
cl_will_return(bt_persistent_storage_set_ble_pinned_address, true);
|
|
cl_will_return(bt_driver_set_local_address, 0);
|
|
s_last_bt_persist_pinned_addr_is_null = false;
|
|
s_last_bt_persist_pinned_addr = TEST_PINNED_ADDR_2;
|
|
bt_local_addr_init();
|
|
cl_assert_equal_b(false, s_last_driver_allow_cycling);
|
|
prv_assert_driver_addr_is_addr2();
|
|
}
|
|
|
|
void test_local_addr__pause_resume(void) {
|
|
prv_init_no_pinnings_no_pinned_address();
|
|
|
|
// flip to make sure that bt_local_addr_pause_cycling() will set these again:
|
|
s_last_driver_allow_cycling = true;
|
|
s_last_driver_addr_is_null = false;
|
|
|
|
cl_will_return(bt_driver_set_local_address, 0);
|
|
bt_local_addr_pause_cycling();
|
|
cl_assert_equal_b(false, s_last_driver_allow_cycling);
|
|
// Check that it's using the pinned address that was generated upon initialization:
|
|
prv_assert_driver_addr_is_addr1();
|
|
|
|
bt_local_addr_pause_cycling();
|
|
// Already paused, shouldn't result in a bt_driver_set_local_address() call.
|
|
|
|
bt_local_addr_resume_cycling();
|
|
// Still paused, shouldn't result in a bt_driver_set_local_address() call.
|
|
|
|
// flip to make sure that bt_local_addr_pause_cycling() will set these again:
|
|
s_last_driver_allow_cycling = true;
|
|
s_last_driver_addr_is_null = false;
|
|
|
|
cl_will_return(bt_driver_set_local_address, 0);
|
|
bt_local_addr_resume_cycling();
|
|
cl_assert_equal_b(true, s_last_driver_allow_cycling);
|
|
prv_assert_driver_addr_is_null();
|
|
}
|
|
|
|
void test_local_addr__pin_unpin(void) {
|
|
prv_init_no_pinnings_no_pinned_address();
|
|
|
|
// Pin:
|
|
cl_will_return(bt_driver_set_local_address, 0);
|
|
cl_will_return(bt_persistent_storage_has_pinned_ble_pairings, true);
|
|
bt_local_addr_pin(&TEST_PINNED_ADDR_1);
|
|
bt_local_addr_handle_bonding_change(TEST_BONDING_ID, BtPersistBondingOpDidAdd);
|
|
cl_assert_equal_b(false, s_last_driver_allow_cycling);
|
|
prv_assert_driver_addr_is_addr1();
|
|
|
|
// Unpin (done implicitly when bonding is removed):
|
|
cl_will_return(bt_persistent_storage_has_pinned_ble_pairings, false);
|
|
cl_will_return(bt_driver_set_local_address, 0);
|
|
bt_local_addr_handle_bonding_change(TEST_BONDING_ID, BtPersistBondingOpWillDelete);
|
|
cl_assert_equal_b(true, s_last_driver_allow_cycling);
|
|
prv_assert_driver_addr_is_null();
|
|
}
|
|
|
|
void test_local_addr__pause_then_pin(void) {
|
|
prv_init_no_pinnings_no_pinned_address();
|
|
|
|
// Pause:
|
|
cl_will_return(bt_driver_set_local_address, 0);
|
|
bt_local_addr_pause_cycling();
|
|
cl_assert_equal_b(false, s_last_driver_allow_cycling);
|
|
prv_assert_driver_addr_is_addr1();
|
|
|
|
// Pin, expect pinned address to be sent to BT driver:
|
|
cl_will_return(bt_driver_set_local_address, 0);
|
|
cl_will_return(bt_persistent_storage_has_pinned_ble_pairings, true);
|
|
bt_local_addr_pin(&TEST_PINNED_ADDR_1);
|
|
bt_local_addr_handle_bonding_change(TEST_BONDING_ID, BtPersistBondingOpDidAdd);
|
|
cl_assert_equal_b(false, s_last_driver_allow_cycling);
|
|
prv_assert_driver_addr_is_addr1();
|
|
}
|