Skip to content

Commit

Permalink
fix(bluetooth): further improve adapter stability
Browse files Browse the repository at this point in the history
These changesets are getting quite big because I end up doing lots of
trial and error before I find something that is worth committing. I will
have to go back and provide new tests as well as possibly refactor some
code later on.
  • Loading branch information
mKeRix committed Jan 17, 2021
1 parent ad1a79b commit fef1a2c
Show file tree
Hide file tree
Showing 9 changed files with 857 additions and 218 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,6 @@ docs/.vuepress/dist
# Config
config/*.yml
!config/test.yml

# Test Setup Utils
update-test-instances.sh
727 changes: 643 additions & 84 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,11 @@
"webpack": "^4.45.0"
},
"optionalDependencies": {
"@mkerix/noble": "1.9.2-10.3",
"@mkerix/noble": "1.9.2-10.4",
"i2c-bus": "^5.1.0",
"mdns": "^2.5.1",
"onoff": "^6.0.0"
"onoff": "^6.0.0",
"winston-elasticsearch": "^0.12.3"
},
"engines": {
"node": ">= 10 < 13"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ jest.useFakeTimers();
describe('BluetoothLowEnergyService', () => {
let service: BluetoothLowEnergyService;
const bluetoothService = {
lowEnergyScanUptime: 16 * 1000,
onLowEnergyDiscovery: jest.fn(),
connectLowEnergyDevice: jest.fn(),
disconnectLowEnergyDevice: jest.fn(),
Expand Down Expand Up @@ -197,6 +198,7 @@ describe('BluetoothLowEnergyService', () => {
'Test Beacon',
'abcd1234',
false,
false,
-50,
-52,
0.7
Expand Down Expand Up @@ -232,6 +234,7 @@ describe('BluetoothLowEnergyService', () => {
'Test Beacon',
'abcd1234',
false,
false,
-59,
-59,
1
Expand Down Expand Up @@ -264,6 +267,7 @@ describe('BluetoothLowEnergyService', () => {
'Test BLE Device',
'123-123',
false,
false,
-81,
-59,
10.5
Expand Down Expand Up @@ -380,6 +384,7 @@ describe('BluetoothLowEnergyService', () => {
'Test BLE Device',
'abcd',
false,
false,
-81,
-80,
1.1
Expand Down Expand Up @@ -768,6 +773,7 @@ describe('BluetoothLowEnergyService', () => {
'Test',
'test',
false,
false,
-80,
-50,
2
Expand All @@ -791,6 +797,7 @@ describe('BluetoothLowEnergyService', () => {
'New Tag',
'new',
false,
false,
-80,
-50,
1.3
Expand Down Expand Up @@ -827,6 +834,7 @@ describe('BluetoothLowEnergyService', () => {
'New Tag',
'new',
false,
false,
-80,
-50,
1.3,
Expand Down Expand Up @@ -864,6 +872,7 @@ describe('BluetoothLowEnergyService', () => {
'Test',
'test',
false,
false,
-80,
-50,
2
Expand All @@ -880,6 +889,7 @@ describe('BluetoothLowEnergyService', () => {
'Test',
'test',
false,
false,
-40,
-45,
2
Expand All @@ -892,6 +902,7 @@ describe('BluetoothLowEnergyService', () => {
'Test',
'test',
false,
false,
-70,
-50,
2
Expand Down Expand Up @@ -1002,35 +1013,15 @@ describe('BluetoothLowEnergyService', () => {
expect(discoverSpy).not.toHaveBeenCalled();
});

it('should ignore Apple advertisements from non iOS-devices', async () => {
jest
.spyOn(service, 'handleNewDistance')
.mockImplementation(() => undefined);
jest.spyOn(service, 'isAllowlistEnabled').mockReturnValue(true);
jest.spyOn(service, 'isOnAllowlist').mockReturnValue(true);
const discoverSpy = jest.spyOn(service, 'discoverCompanionAppId');

await service.handleDiscovery({
id: 'abcd1234',
rssi: -50,
connectable: true,
advertisement: {
localName: 'Test Beacon',
txPowerLevel: -72,
manufacturerData: APPLE_MANUFACTURER_DATA.slice(0, 6),
},
} as Peripheral);

expect(discoverSpy).not.toHaveBeenCalled();
});

it('should override tag ids with companion app IDs', async () => {
const handleDistanceSpy = jest
.spyOn(service, 'handleNewDistance')
.mockImplementation(() => undefined);
jest.spyOn(service, 'isAllowlistEnabled').mockReturnValue(true);
jest.spyOn(service, 'isOnAllowlist').mockReturnValue(true);
jest.spyOn(service, 'discoverCompanionAppId').mockResolvedValue('app-id');
jest
.spyOn(service, 'discoverCompanionAppId')
.mockResolvedValue({ appId: 'app-id', modelName: null });

await service.handleDiscovery({
id: 'abcd1234',
Expand Down Expand Up @@ -1096,7 +1087,7 @@ describe('BluetoothLowEnergyService', () => {
jest.spyOn(service, 'isOnAllowlist').mockReturnValue(true);
const discoverSpy = jest
.spyOn(service, 'discoverCompanionAppId')
.mockResolvedValue('app-id');
.mockResolvedValue({ appId: 'app-id', modelName: null });

const peripheral = {
id: 'abcd1234',
Expand All @@ -1121,7 +1112,9 @@ describe('BluetoothLowEnergyService', () => {
.mockImplementation(() => undefined);
jest.spyOn(service, 'isAllowlistEnabled').mockReturnValue(true);
jest.spyOn(service, 'isOnAllowlist').mockReturnValue(true);
jest.spyOn(service, 'discoverCompanionAppId').mockResolvedValue('app-id');
jest
.spyOn(service, 'discoverCompanionAppId')
.mockResolvedValue({ appId: 'app-id', modelName: null });

await service.handleDiscovery({
id: 'abcd1234',
Expand Down Expand Up @@ -1159,6 +1152,7 @@ describe('BluetoothLowEnergyService', () => {
'Test',
'peripheral-id',
true,
true,
-80,
-50,
2
Expand All @@ -1177,7 +1171,7 @@ describe('BluetoothLowEnergyService', () => {
expect(discoverSpy).not.toHaveBeenCalled();
});

it('should temporarily denylist devices that time out from discovery attempts', async () => {
it('should denylist devices that time out from discovery attempts', async () => {
jest.useFakeTimers('modern');
jest
.spyOn(service, 'handleNewDistance')
Expand All @@ -1203,12 +1197,6 @@ describe('BluetoothLowEnergyService', () => {
await service.handleDiscovery(peripheral);

expect(discoverSpy).toHaveBeenCalledTimes(1);

jest.advanceTimersByTime(3 * 60 * 1000);

await service.handleDiscovery(peripheral);

expect(discoverSpy).toHaveBeenCalledTimes(2);
});

it('should discover the companion app ID from the well known characteristic', async () => {
Expand Down Expand Up @@ -1238,7 +1226,9 @@ describe('BluetoothLowEnergyService', () => {

const actual = await service.discoverCompanionAppId(new Tag(peripheral));

expect(actual).toBe('app-id');
expect(actual).toMatchObject({
appId: 'app-id',
});
});

it('should return null if device does not have characteristic', async () => {
Expand Down
Loading

0 comments on commit fef1a2c

Please sign in to comment.