pebble/tests/fakes/fake_GAPAPI.c
2025-01-27 11:38:16 -08:00

363 lines
13 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 "fake_GAPAPI.h"
#include "bluetopia_interface.h"
#include <string.h>
#include "clar_asserts.h"
static bool s_is_le_advertising_enabled;
static GAP_LE_Event_Callback_t s_le_adv_connection_event_callback;
static unsigned long s_le_adv_connection_callback_param;
static uint16_t s_min_advertising_interval_slots;
static uint16_t s_max_advertising_interval_slots;
void gap_le_set_advertising_disabled(void) {
s_is_le_advertising_enabled = false;
s_min_advertising_interval_slots = 0;
s_max_advertising_interval_slots = 0;
}
int GAP_LE_Advertising_Disable(unsigned int BluetoothStackID) {
s_is_le_advertising_enabled = false;
s_le_adv_connection_event_callback = NULL;
s_le_adv_connection_callback_param = 0;
s_min_advertising_interval_slots = 0;
s_max_advertising_interval_slots = 0;
return 0;
}
int GAP_LE_Advertising_Enable(unsigned int BluetoothStackID,
Boolean_t EnableScanResponse,
GAP_LE_Advertising_Parameters_t *GAP_LE_Advertising_Parameters,
GAP_LE_Connectability_Parameters_t *GAP_LE_Connectability_Parameters,
GAP_LE_Event_Callback_t GAP_LE_Event_Callback,
unsigned long CallbackParameter) {
s_is_le_advertising_enabled = true;
s_le_adv_connection_event_callback = GAP_LE_Event_Callback;
s_le_adv_connection_callback_param = CallbackParameter;
if (GAP_LE_Advertising_Parameters) {
// Convert from ms to slots:
s_min_advertising_interval_slots =
(GAP_LE_Advertising_Parameters->Advertising_Interval_Min * 16) / 10;
s_max_advertising_interval_slots =
(GAP_LE_Advertising_Parameters->Advertising_Interval_Max * 16) / 10;
} else {
s_min_advertising_interval_slots = 0;
s_max_advertising_interval_slots = 0;
}
return 0;
}
void gap_le_assert_advertising_interval(uint16_t expected_min_slots, uint16_t expected_max_slots) {
cl_assert_equal_i(s_min_advertising_interval_slots, expected_min_slots);
cl_assert_equal_i(s_max_advertising_interval_slots, expected_max_slots);
}
bool gap_le_is_advertising_enabled(void) {
return s_is_le_advertising_enabled;
}
static Advertising_Data_t s_ad_data;
static unsigned int s_ad_data_length;
int GAP_LE_Set_Advertising_Data(unsigned int BluetoothStackID,
unsigned int Length,
Advertising_Data_t *Advertising_Data) {
memcpy(&s_ad_data, Advertising_Data, Length);
s_ad_data_length = Length;
return 0;
}
unsigned int gap_le_get_advertising_data(Advertising_Data_t *ad_data_out) {
*ad_data_out = s_ad_data;
return s_ad_data_length;
}
static Scan_Response_Data_t s_scan_resp_data;
static unsigned int s_scan_resp_data_length;
int GAP_LE_Set_Scan_Response_Data(unsigned int BluetoothStackID,
unsigned int Length,
Scan_Response_Data_t *Scan_Response_Data) {
memcpy(&s_scan_resp_data, Scan_Response_Data, Length);
s_scan_resp_data_length = Length;
return 0;
}
unsigned int gap_le_get_scan_response_data(Scan_Response_Data_t *scan_resp_data_out) {
*scan_resp_data_out = s_scan_resp_data;
return s_scan_resp_data_length;
}
static GAP_LE_Event_Callback_t s_le_create_connection_event_callback;
static unsigned long s_le_create_connection_callback_param;
int GAP_LE_Create_Connection(unsigned int BluetoothStackID,
unsigned int ScanInterval,
unsigned int ScanWindow,
GAP_LE_Filter_Policy_t InitatorFilterPolicy,
GAP_LE_Address_Type_t RemoteAddressType,
BD_ADDR_t *RemoteDevice,
GAP_LE_Address_Type_t LocalAddressType,
GAP_LE_Connection_Parameters_t *ConnectionParameters,
GAP_LE_Event_Callback_t GAP_LE_Event_Callback,
unsigned long CallbackParameter) {
s_le_create_connection_event_callback = GAP_LE_Event_Callback;
s_le_create_connection_callback_param = CallbackParameter;
return 0;
}
void prv_fake_gap_le_create_connection_event_put(GAP_LE_Event_Data_t *event) {
cl_assert(s_le_create_connection_event_callback != NULL);
s_le_create_connection_event_callback(1, event, s_le_create_connection_callback_param);
}
void prv_fake_gap_le_adv_connection_event_put(GAP_LE_Event_Data_t *event) {
cl_assert(s_le_adv_connection_event_callback != NULL);
s_le_adv_connection_event_callback(1, event, s_le_adv_connection_callback_param);
}
void fake_gap_put_connection_event(uint8_t status,
bool is_master,
const BTDeviceInternal *device) {
GAP_LE_Connection_Complete_Event_Data_t event_data =
(GAP_LE_Connection_Complete_Event_Data_t) {
.Status = status,
.Master = is_master,
.Peer_Address_Type = device->is_random_address ? latRandom : latPublic,
.Peer_Address = BTDeviceAddressToBDADDR(device->address),
};
GAP_LE_Event_Data_t event = (GAP_LE_Event_Data_t) {
.Event_Data_Type = etLE_Connection_Complete,
.Event_Data_Size = sizeof(GAP_LE_Connection_Complete_Event_Data_t),
.Event_Data.GAP_LE_Connection_Complete_Event_Data = &event_data,
};
if (is_master) {
prv_fake_gap_le_create_connection_event_put(&event);
} else {
prv_fake_gap_le_adv_connection_event_put(&event);
}
}
void fake_gap_put_disconnection_event(uint8_t status, uint8_t reason,
bool is_master,
const BTDeviceInternal *device) {
GAP_LE_Disconnection_Complete_Event_Data_t event_data =
(GAP_LE_Disconnection_Complete_Event_Data_t) {
.Status = status,
.Reason = reason,
.Peer_Address_Type = device->is_random_address ? latRandom : latPublic,
.Peer_Address = BTDeviceAddressToBDADDR(device->address),
};
GAP_LE_Event_Data_t event = (GAP_LE_Event_Data_t) {
.Event_Data_Type = etLE_Disconnection_Complete,
.Event_Data_Size = sizeof(GAP_LE_Disconnection_Complete_Event_Data_t),
.Event_Data.GAP_LE_Disconnection_Complete_Event_Data = &event_data,
};
if (is_master) {
prv_fake_gap_le_create_connection_event_put(&event);
} else {
prv_fake_gap_le_adv_connection_event_put(&event);
}
}
void fake_GAPAPI_put_encryption_change_event(bool encrypted, uint8_t status, bool is_master,
const BTDeviceInternal *device) {
GAP_LE_Encryption_Change_Event_Data_t event_data =
(GAP_LE_Encryption_Change_Event_Data_t) {
.BD_ADDR = BTDeviceAddressToBDADDR(device->address),
.Encryption_Change_Status = status,
.Encryption_Mode = encrypted ? emEnabled : emDisabled,
};
GAP_LE_Event_Data_t event = (GAP_LE_Event_Data_t) {
.Event_Data_Type = etLE_Encryption_Change,
.Event_Data_Size = sizeof(GAP_LE_Encryption_Change_Event_Data_t),
.Event_Data.GAP_LE_Encryption_Change_Event_Data = &event_data,
};
if (is_master) {
prv_fake_gap_le_create_connection_event_put(&event);
} else {
prv_fake_gap_le_adv_connection_event_put(&event);
}
}
int GAP_LE_Cancel_Create_Connection(unsigned int BluetoothStackID) {
return 0;
}
// Puts the event that the BT Controller will emit after a succesfull
// GAP_LE_Cancel_Create_Connection call.
void fake_gap_le_put_cancel_create_event(const BTDeviceInternal *device, bool is_master) {
fake_gap_put_connection_event(HCI_ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER,
is_master,
device);
}
int GAP_LE_Disconnect(unsigned int BluetoothStackID,
BD_ADDR_t BD_ADDR) {
return 0;
}
int GAP_LE_Pair_Remote_Device(unsigned int BluetoothStackID,
BD_ADDR_t BD_ADDR,
GAP_LE_Pairing_Capabilities_t *Capabilities,
GAP_LE_Event_Callback_t GAP_LE_Event_Callback,
unsigned long CallbackParameter) {
return 0;
}
// -------------------------------------------------------------------------------------------------
// Bluetopia's Security Manager API
int GAP_LE_Authentication_Response(unsigned int BluetoothStackID, BD_ADDR_t BD_ADDR,
GAP_LE_Authentication_Response_Information_t *GAP_LE_Authentication_Information) {
return 0;
}
int GAP_LE_Diversify_Function(unsigned int BluetoothStackID, Encryption_Key_t *Key, Word_t DIn,
Word_t RIn, Encryption_Key_t *Result) {
return 0;
}
int GAP_LE_Generate_Long_Term_Key(unsigned int BluetoothStackID, Encryption_Key_t *DHK,
Encryption_Key_t *ER, Long_Term_Key_t *LTK_Result,
Word_t *DIV_Result, Word_t *EDIV_Result,
Random_Number_t *Rand_Result) {
return 0;
}
static BD_ADDR_t s_encrypted_device;
int GAP_LE_Query_Encryption_Mode(unsigned int BluetoothStackID, BD_ADDR_t BD_ADDR,
GAP_Encryption_Mode_t *GAP_Encryption_Mode) {
*GAP_Encryption_Mode = (COMPARE_BD_ADDR(s_encrypted_device, BD_ADDR)) ? emEnabled : emDisabled;
return 0;
}
void fake_GAPAPI_set_encrypted_for_device(const BTDeviceInternal *device) {
s_encrypted_device = BTDeviceAddressToBDADDR(device->address);
}
int GAP_LE_Regenerate_Long_Term_Key(unsigned int BluetoothStackID, Encryption_Key_t *DHK,
Encryption_Key_t *ER, Word_t EDIV, Random_Number_t *Rand,
Long_Term_Key_t *LTK_Result) {
return 0;
}
int GAP_LE_Register_Remote_Authentication(unsigned int BluetoothStackID, GAP_LE_Event_Callback_t GAP_LE_Event_Callback, unsigned long CallbackParameter) {
return 0;
}
int GAP_LE_Un_Register_Remote_Authentication(unsigned int BluetoothStackID) {
return 0;
}
int GAP_LE_Request_Security(unsigned int BluetoothStackID, BD_ADDR_t BD_ADDR,
GAP_LE_Bonding_Type_t Bonding_Type, Boolean_t MITM,
GAP_LE_Event_Callback_t GAP_LE_Event_Callback,
unsigned long CallbackParameter) {
return 0;
}
int GAP_LE_Set_Pairability_Mode(unsigned int BluetoothStackID,
GAP_LE_Pairability_Mode_t PairableMode) {
return 0;
}
int GAP_LE_Generate_Resolvable_Address(unsigned int BluetoothStackID, Encryption_Key_t *IRK,
BD_ADDR_t *ResolvableAddress_Result) {
return 0;
}
int GAP_LE_Set_Random_Address(unsigned int BluetoothStackID, BD_ADDR_t RandomAddress) {
return 0;
}
int GAP_Query_Local_BD_ADDR(unsigned int BluetoothStackID, BD_ADDR_t *BD_ADDR) {
return 0;
}
static const Encryption_Key_t s_fake_irk = {
0xaa,
0xaa,
};
static const BD_ADDR_t s_resolving_bd_addr = {
0xaa, 0xff, 0xff, 0xff, 0xff,
0x7f /* 6th byte: bit 6 set, bit 7 unset indicates "resolvable private address" */
};
static const BD_ADDR_t s_not_resolving_bd_addr = {
0xff,
};
const Encryption_Key_t *fake_GAPAPI_get_fake_irk(void) {
return &s_fake_irk;
}
const BD_ADDR_t *fake_GAPAPI_get_bd_addr_not_resolving_to_fake_irk(void) {
return &s_not_resolving_bd_addr;
}
const BTDeviceInternal *fake_GAPAPI_get_device_not_resolving_to_fake_irk(void) {
static BTDeviceInternal s_not_resolving_device;
s_not_resolving_device = (const BTDeviceInternal) {
.address = BDADDRToBTDeviceAddress(s_not_resolving_bd_addr),
.is_random_address = true,
};
return &s_not_resolving_device;
}
const BD_ADDR_t *fake_GAPAPI_get_bd_addr_resolving_to_fake_irk(void) {
return &s_resolving_bd_addr;
}
const BTDeviceInternal *fake_GAPAPI_get_device_resolving_to_fake_irk(void) {
static BTDeviceInternal s_resolving_device;
s_resolving_device = (const BTDeviceInternal) {
.address = BDADDRToBTDeviceAddress(s_resolving_bd_addr),
.is_random_address = true,
};
return &s_resolving_device;
}
Boolean_t GAP_LE_Resolve_Address(unsigned int BluetoothStackID, Encryption_Key_t *IRK,
BD_ADDR_t ResolvableAddress) {
return COMPARE_BD_ADDR(ResolvableAddress, s_resolving_bd_addr) &&
COMPARE_ENCRYPTION_KEY(*IRK, s_fake_irk);
}
void fake_GAPAPI_init(void) {
memset(&s_encrypted_device, 0, sizeof(s_encrypted_device));
s_is_le_advertising_enabled = false;
s_le_adv_connection_event_callback = NULL;
s_le_adv_connection_callback_param = 0;
memset(&s_ad_data, 0, sizeof(s_ad_data));
s_ad_data_length = 0;
s_le_create_connection_event_callback = NULL;
s_le_create_connection_callback_param = 0;
memset(&s_scan_resp_data, 0, sizeof(s_scan_resp_data));
s_scan_resp_data_length = 0;
}