switch-pico/tests/switch2_pairing_test.c

90 lines
3.5 KiB
C

#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <btstack_tlv.h>
#include "parser/uni_switch2_pairing.h"
static struct {
uint32_t tag;
uint8_t data[256];
uint32_t size;
bool fail_write;
} storage;
static int get_tag(void* context, uint32_t tag, uint8_t* data, uint32_t capacity) {
(void)context;
if (tag != storage.tag) return 0;
uint32_t copied = storage.size < capacity ? storage.size : capacity;
memcpy(data, storage.data, copied);
return (int)storage.size;
}
static int store_tag(void* context, uint32_t tag, const uint8_t* data, uint32_t size) {
(void)context;
if (storage.fail_write) return -1;
assert(size <= sizeof(storage.data));
storage.tag = tag;
memcpy(storage.data, data, size);
storage.size = size;
return 0;
}
static const btstack_tlv_t tlv = {get_tag, store_tag, NULL};
void btstack_tlv_get_instance(const btstack_tlv_t** implementation, void** context) {
*implementation = &tlv;
*context = &storage;
}
int main(void) {
uint8_t public_address[6] = {0x10, 2, 3, 4, 5, 6};
uint8_t static_address[6] = {0xc1, 2, 3, 4, 5, 6};
uint8_t private_address[6] = {0x41, 2, 3, 4, 5, 6};
assert(!uni_switch2_pairing_known(0, public_address));
assert(!uni_switch2_pairing_remember(1, private_address));
assert(!uni_switch2_pairing_remember(2, public_address));
assert(uni_switch2_pairing_remember(1, static_address));
assert(uni_switch2_pairing_remember(0, public_address));
assert(uni_switch2_pairing_known(0, public_address));
assert(!uni_switch2_pairing_known(1, public_address));
assert(uni_switch2_pairing_known(1, static_address));
// Duplicate authorization remains valid without requiring another flash write.
storage.fail_write = true;
assert(uni_switch2_pairing_remember(0, public_address));
assert(!uni_switch2_pairing_clear());
assert(uni_switch2_pairing_known(0, public_address));
public_address[5]++;
assert(!uni_switch2_pairing_remember(0, public_address));
assert(!uni_switch2_pairing_known(0, public_address));
public_address[5]--;
storage.fail_write = false;
uint8_t type, observed[6];
assert(uni_switch2_pairing_get(0, &type, observed));
assert(type == 0 && memcmp(observed, public_address, 6) == 0);
assert(uni_switch2_pairing_get(1, &type, observed));
assert(type == 1 && memcmp(observed, static_address, 6) == 0);
assert(!uni_switch2_pairing_get(2, &type, observed));
assert(uni_switch2_pairing_clear());
assert(!uni_switch2_pairing_known(0, public_address));
assert(!uni_switch2_pairing_known(1, static_address));
// Filling the bounded store never silently forgets an earlier controller.
for (uint8_t i = 0; i < UNI_SWITCH2_PAIRING_CAPACITY; ++i) {
public_address[5] = i;
assert(uni_switch2_pairing_remember(0, public_address));
}
public_address[5] = UNI_SWITCH2_PAIRING_CAPACITY;
assert(!uni_switch2_pairing_remember(0, public_address));
public_address[5] = 0;
assert(uni_switch2_pairing_known(0, public_address));
// Corrupt persisted data is not an authorization and can be explicitly cleared.
storage.data[1] = 255;
assert(!uni_switch2_pairing_known(0, public_address));
assert(!uni_switch2_pairing_remember(0, public_address));
assert(uni_switch2_pairing_clear());
assert(uni_switch2_pairing_remember(0, public_address));
storage.size++;
assert(!uni_switch2_pairing_known(0, public_address));
return 0;
}