Skip to content

Commit

Permalink
Merge pull request #9 from rosek86/dev
Browse files Browse the repository at this point in the history
v1.1.0
  • Loading branch information
rosek86 authored Dec 3, 2023
2 parents 7b11eba + 144d0c0 commit 031ff02
Show file tree
Hide file tree
Showing 18 changed files with 112 additions and 75 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

All notable changes to this project will be documented in this file.

## [1.1.0] - 2023-12-03

- Fix the problem of connection attempts using an incorrect address type

## [1.0.9] - 2023-12-03

- add chalk to production dependencies
Expand Down
7 changes: 4 additions & 3 deletions examples/CodedPHY/advertising.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import {
LeAdvertisingFilterPolicy,
LePrimaryAdvertisingPhy,
LeSecondaryAdvertisingPhy,
LeAdvertisingDataOperation
LeAdvertisingDataOperation,
AddressType
} from '../../src';
import { ArgsParser } from '../utils/ArgsParser';

Expand Down Expand Up @@ -39,7 +40,7 @@ import { ArgsParser } from '../utils/ArgsParser';
],
ownAddressType: LeOwnAddressType.RandomDeviceAddress,
peerAddressType: LePeerAddressType.PublicDeviceAddress,
peerAddress: Address.from(0x000000000000),
peerAddress: Address.from(0x000000000000, AddressType.PublicDeviceAddress),
advertisingFilterPolicy: LeAdvertisingFilterPolicy.Any,
primaryAdvertisingPhy: LePrimaryAdvertisingPhy.PhyCoded,
secondaryAdvertisingMaxSkip: 0,
Expand All @@ -50,7 +51,7 @@ import { ArgsParser } from '../utils/ArgsParser';
});
console.log(`TX Power: ${selectedTxPower}`);

await hci.leSetAdvertisingSetRandomAddress(0, Address.from(0x1429c386d3a9));
await hci.leSetAdvertisingSetRandomAddress(0, Address.from(0x1429c386d3a9, AddressType.RandomDeviceAddress));

const advertisingData = AdvData.build({
flags: 6,
Expand Down
3 changes: 2 additions & 1 deletion examples/CodedPHY/scanning.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
LeScanningFilterPolicy,
LeScanType,
LeScanFilterDuplicates,
AddressType,
} from '../../src';
import { ArgsParser } from '../utils/ArgsParser';

Expand All @@ -25,7 +26,7 @@ import { ArgsParser } from '../utils/ArgsParser';
const hci = adapter.Hci;
await hci.leAddDeviceToWhiteList({
addressType: LeWhiteListAddressType.Random,
address: Address.from(0x1429c386d3a9),
address: Address.from(0x1429c386d3a9, AddressType.RandomDeviceAddress),
});

const gap = new GapCentral(hci);
Expand Down
6 changes: 3 additions & 3 deletions examples/le-advertising.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AdvData } from '../src';
import { AddressType, AdvData } from '../src';
import {
LeAdvertisingEventProperties,
LeAdvertisingChannelMap,
Expand Down Expand Up @@ -37,7 +37,7 @@ import { createHciSerial } from '../src';
],
ownAddressType: LeOwnAddressType.RandomDeviceAddress,
peerAddressType: LePeerAddressType.PublicDeviceAddress,
peerAddress: Address.from(0x000000000000),
peerAddress: Address.from(0x000000000000, AddressType.PublicDeviceAddress),
advertisingFilterPolicy: LeAdvertisingFilterPolicy.Any,
primaryAdvertisingPhy: LePrimaryAdvertisingPhy.Phy1M,
secondaryAdvertisingMaxSkip: 0,
Expand All @@ -48,7 +48,7 @@ import { createHciSerial } from '../src';
});
console.log(`TX Power: ${selectedTxPower}`);

await hci.leSetAdvertisingSetRandomAddress(0, Address.from(0x1429c386d3a9));
await hci.leSetAdvertisingSetRandomAddress(0, Address.from(0x1429c386d3a9, AddressType.RandomDeviceAddress));

const advertisingData = AdvData.build({
flags: 6,
Expand Down
2 changes: 1 addition & 1 deletion examples/le-central-lbs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class App extends NbleGapCentral {
this.state = 'connecting';

// Connect to device with timeout
await this.connect(report.address, { connectionTimeoutMs: 2000 });
await this.connect({ peerAddress: report.address, timeoutMs: 2000 });
console.log(`Connecting to ${report.address.toString()} (${name}) at RSSI ${report.rssi} dBm...`);

} catch (e) {
Expand Down
6 changes: 3 additions & 3 deletions examples/le-conn-peripheral.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
LeSecondaryAdvertisingPhy,
LeAdvertisingDataOperation,
LeScanResponseDataOperation,
Address, AdvData, L2CAP, Att
Address, AdvData, L2CAP, Att, AddressType
} from '../src';

(async () => {
Expand Down Expand Up @@ -38,7 +38,7 @@ import {
],
ownAddressType: LeOwnAddressType.RandomDeviceAddress,
peerAddressType: LePeerAddressType.PublicDeviceAddress,
peerAddress: Address.from(0x000000000000),
peerAddress: Address.from(0x000000000000, AddressType.PublicDeviceAddress),
advertisingFilterPolicy: LeAdvertisingFilterPolicy.Any,
primaryAdvertisingPhy: LePrimaryAdvertisingPhy.Phy1M,
secondaryAdvertisingMaxSkip: 0,
Expand All @@ -49,7 +49,7 @@ import {
});
console.log(`TX Power: ${selectedTxPower}`);

await hci.leSetAdvertisingSetRandomAddress(0, Address.from('AA:BB:CC:DD:EE:FF'));
await hci.leSetAdvertisingSetRandomAddress(0, Address.from('AA:BB:CC:DD:EE:FF', AddressType.RandomDeviceAddress));

const advertisingData = AdvData.build({
flags: 6,
Expand Down
2 changes: 1 addition & 1 deletion examples/le-discover-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class App extends NbleGapCentral {
this.state = 'connecting';

// Connect to device with timeout
await this.connect(report.address, { connectionTimeoutMs: 2000 });
await this.connect({ peerAddress: report.address, timeoutMs: 2000 });
console.log(`Connecting to ${report.address.toString()} (${name}) at RSSI ${report.rssi} dBm...`);

} catch (e) {
Expand Down
39 changes: 24 additions & 15 deletions examples/le-scanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import chalk from 'chalk';
import {
HciAdapter, createHciSerial,
GapCentral, GapAdvertReport,
LeScanFilterDuplicates
LeScanFilterDuplicates,
LeScanType
} from '../src';
import { ArgsParser } from './utils/ArgsParser.js';
import { getCompanyName } from '../assigned-numbers/Company Identifiers.js';
Expand Down Expand Up @@ -30,8 +31,16 @@ const adverts = new Map<string, { adv?: GapAdvertReportExt; sr?: GapAdvertReport
const gap = new GapCentral(adapter.Hci);
await gap.init();

await gap.setScanParameters();
await gap.startScanning({ filterDuplicates: LeScanFilterDuplicates.Enabled });
await gap.setScanParameters({
scanningPhy: {
Phy1M: {
type: LeScanType.Active,
intervalMs: 100,
windowMs: 50,
}
}
});
await gap.startScanning({ filterDuplicates: LeScanFilterDuplicates.Disabled });
console.log('scanning...');

gap.on('GapLeScanState', (scanning) => {
Expand Down Expand Up @@ -78,50 +87,50 @@ function printDeviceInfo(address: string, { adv, sr }: { adv?: GapAdvertReportEx
process.stdout.write(`${chalk.blue.bold(address)} ${chalk.magenta(adv?.timestamp?.toLocaleTimeString())}\n`);

if (adv) {
process.stdout.write(` Advertisement:\n`);
process.stdout.write(` Advertisement:\n`);
printReport(adv);
}
if (sr) {
process.stdout.write(` Scan Response:\n`);
process.stdout.write(` Scan Response:\n`);
printReport(sr);
}
}

function printReport(r: GapAdvertReport) {
const report = structuredClone(r);
process.stdout.write(` - RSSI: ${report.rssi} dBm\n`);
process.stdout.write(` - RSSI: ${report.rssi} dBm\n`);
if (report.data?.completeLocalName) {
process.stdout.write(` - Name: ${report.data.completeLocalName}\n`);
process.stdout.write(` - Name: ${report.data.completeLocalName}\n`);
delete report.data.completeLocalName;
}
if (report.data?.shortenedLocalName) {
process.stdout.write(` - Short Name: ${report.data.shortenedLocalName}\n`);
process.stdout.write(` - Short Name: ${report.data.shortenedLocalName}\n`);
delete report.data.shortenedLocalName;
}
if (report.data?.manufacturerData) {
const companyName = getCompanyName(report.data?.manufacturerData.ident);
process.stdout.write(` - Company Name: ${chalk.green(companyName ?? 'unknown')}\n`);
process.stdout.write(` - Manufacturer Data: ${JSON.stringify([...report.data.manufacturerData.data])}\n`);
process.stdout.write(` - Company Name: ${chalk.green(companyName ?? 'unknown')}\n`);
process.stdout.write(` - Manufacturer Data: ${JSON.stringify([...report.data.manufacturerData.data])}\n`);
delete report.data.manufacturerData;
}
if (report.data?.appearance) {
const appearance = getAppearanceSubcategoryName(report.data.appearance.category, report.data.appearance.subcategory);
process.stdout.write(` - Appearance: ${chalk.yellow(appearance)}\n`);
process.stdout.write(` - Appearance: ${chalk.yellow(appearance)}\n`);
delete report.data.appearance;
}
if (report.data?.txPowerLevel) {
process.stdout.write(` - Tx Power Level: ${report.data.txPowerLevel} dBm\n`);
process.stdout.write(` - Tx Power Level: ${report.data.txPowerLevel} dBm\n`);
delete report.data.txPowerLevel;
}
if (report.data?.completeListOf16bitServiceClassUuids) {
process.stdout.write(` - 16-bit UUIDs: ${report.data.completeListOf16bitServiceClassUuids}\n`);
process.stdout.write(` - 16-bit UUIDs: ${report.data.completeListOf16bitServiceClassUuids}\n`);
delete report.data.completeListOf16bitServiceClassUuids;
}
if (report.data?.incompleteListOf16bitServiceClassUuids) {
process.stdout.write(` - Incomplete 16-bit UUIDs: ${report.data.incompleteListOf16bitServiceClassUuids}\n`);
process.stdout.write(` - Incomplete 16-bit UUIDs: ${report.data.incompleteListOf16bitServiceClassUuids}\n`);
delete report.data.incompleteListOf16bitServiceClassUuids;
}
if (Object.keys(report.data).length > 0) {
process.stdout.write(` - Data: ${JSON.stringify(report.data)}\n`);
process.stdout.write(` - Data: ${JSON.stringify(report.data)}\n`);
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "bluetooth-hci",
"version": "1.0.9",
"version": "1.1.0",
"description": "Bluetooth HCI host implementation",
"main": "lib/src/index.js",
"types": "lib/src/index.d.ts",
Expand Down
23 changes: 13 additions & 10 deletions src/gap/GapCentral.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
LeExtendedCreateConnectionV1,
LeExtendedCreateConnectionPhy,
LeExtendedScanEnabled, LeExtendedScanParameters, LeInitiatorFilterPolicy,
LeOwnAddressType, LePeerAddressType, LeScanFilterDuplicates,
LeOwnAddressType, LeScanFilterDuplicates,
LeScanningFilterPolicy, LeScanType, LeSupportedFeatures
} from '../hci/HciLeController.js';
import { Address } from '../utils/Address.js';
Expand All @@ -26,7 +26,10 @@ import { HciErrorCode } from '../hci/HciError.js';

export type GapScanParamsOptions = Partial<LeExtendedScanParameters>;
export type GapScanStartOptions = Partial<Omit<LeExtendedScanEnabled, 'enable'>>;
export type GapConnectParams = Partial<Omit<LeExtendedCreateConnectionV1, 'peerAddress'>> & { peerAddress: Address };
export type GapConnectParams = Partial<Omit<LeExtendedCreateConnectionV1, 'peerAddress' | 'peerAddressType'>> & {
peerAddress: Address;
timeoutMs?: number;
};

export interface GapAdvertReport {
address: Address;
Expand Down Expand Up @@ -244,7 +247,7 @@ export class GapCentral extends EventEmitter {
}
}

public async connect(params: GapConnectParams, timeoutMs?: number): Promise<void> {
public async connect(params: GapConnectParams): Promise<void> {
if (this.pendingCreateConnection) {
debug('Connection already in progress');
throw new Error('Connection already in progress');
Expand All @@ -265,9 +268,9 @@ export class GapCentral extends EventEmitter {
if (this.extended) {
await this.hci.leExtendedCreateConnectionV1({
ownAddressType: params?.ownAddressType ?? LeOwnAddressType.RandomDeviceAddress,
initiatorFilterPolicy: params?.initiatorFilterPolicy ?? LeInitiatorFilterPolicy.PeerAddress,
peerAddressType: params?.peerAddressType ?? LePeerAddressType.RandomDeviceAddress,
peerAddress: params.peerAddress,
peerAddressType: params.peerAddress.getLePeerAddressType(),
initiatorFilterPolicy: params?.initiatorFilterPolicy ?? LeInitiatorFilterPolicy.PeerAddress,
initiatingPhy: params?.initiatingPhy ?? { Phy1M: defaultScanParams },
});
} else {
Expand All @@ -276,15 +279,15 @@ export class GapCentral extends EventEmitter {
}
await this.hci.leCreateConnection({
ownAddressType: params?.ownAddressType ?? LeOwnAddressType.RandomDeviceAddress,
initiatorFilterPolicy: params?.initiatorFilterPolicy ?? LeInitiatorFilterPolicy.PeerAddress,
peerAddressType: params?.peerAddressType ?? LePeerAddressType.RandomDeviceAddress,
peerAddress: params.peerAddress,
peerAddressType: params.peerAddress.getLePeerAddressType(),
initiatorFilterPolicy: params?.initiatorFilterPolicy ?? LeInitiatorFilterPolicy.PeerAddress,
...(params?.initiatingPhy?.Phy1M ?? defaultScanParams),
});
}

if (timeoutMs) {
debug('Connection timeout', timeoutMs);
if (params.timeoutMs) {
debug('Connection timeout', params.timeoutMs);
this.pendingCreateConnection.timeoutId = setTimeout(() => {
this.hci.leCreateConnectionCancel()
.then(() => {
Expand All @@ -301,7 +304,7 @@ export class GapCentral extends EventEmitter {
.finally(() => {
this.pendingCreateConnection = null;
});
}, timeoutMs);
}, params.timeoutMs);
}

debug('Connecting to', params.peerAddress.toString());
Expand Down
4 changes: 2 additions & 2 deletions src/hci/Hci.ts
Original file line number Diff line number Diff line change
Expand Up @@ -614,14 +614,14 @@ export class Hci extends EventEmitter {
const ocf = HciOcfLeControllerCommands.ReadPeerResolvableAddress;
const payload = LeReadPeerResolvableAddress.inParams(params);
const result = await this.cmd.leController({ ocf, payload });
return LeReadPeerResolvableAddress.outParams(result.returnParameters);
return LeReadPeerResolvableAddress.outParams(params, result.returnParameters);
}

public async leReadLocalResolvableAddress(params: LeLocalPeerResolvableAddress): Promise<Address> {
const ocf = HciOcfLeControllerCommands.ReadLocalResolvableAddress;
const payload = LeLocalPeerResolvableAddress.inParams(params);
const result = await this.cmd.leController({ ocf, payload });
return LeLocalPeerResolvableAddress.outParams(result.returnParameters);
return LeLocalPeerResolvableAddress.outParams(params, result.returnParameters);
}

public async leSetAddressResolutionEnable(enable: boolean): Promise<void> {
Expand Down
16 changes: 8 additions & 8 deletions src/hci/HciEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ export class LeAdvReport {
reports.push({
eventType,
addressType,
address: Address.from(address),
address: Address.from(address, addressType),
rssi: powerOrNull(rssi),
data: advData,
});
Expand Down Expand Up @@ -376,7 +376,7 @@ export class LeExtAdvReport {
reports.push({
eventType: LeExtAdvEventTypeParser.parse(eventType),
addressType,
address: Address.from(address),
address: Address.from(address, addressType),
primaryPhy,
secondaryPhy,
advertisingSid,
Expand Down Expand Up @@ -449,7 +449,7 @@ export class LeConnectionComplete {
connectionHandle,
role,
peerAddressType,
peerAddress: Address.from(peerAddress),
peerAddress: Address.from(peerAddress, peerAddressType),
connectionIntervalMs: connectionInterval * 1.25,
connectionLatency,
supervisionTimeoutMs: supervisionTimeout * 10,
Expand Down Expand Up @@ -490,9 +490,9 @@ export class LeEnhConnectionComplete {
connectionHandle,
role,
peerAddressType,
peerAddress: Address.from(peerAddress),
localResolvablePrivateAddress: Address.from(localResolvablePrivateAddress),
peerResolvablePrivateAddress: Address.from(peerResolvablePrivateAddress),
peerAddress: Address.from(peerAddress, peerAddressType),
localResolvablePrivateAddress: Address.from(localResolvablePrivateAddress, peerAddressType),
peerResolvablePrivateAddress: Address.from(peerResolvablePrivateAddress, peerAddressType),
connectionIntervalMs: connectionInterval * 1.25,
connectionLatency,
supervisionTimeoutMs: supervisionTimeout * 10,
Expand Down Expand Up @@ -762,9 +762,9 @@ export class LeDirectedAdvertisingReport {
reports.push({
eventType,
addressType,
address: Address.from(address),
address: Address.from(address, addressType),
directAddressType,
directAddress: Address.from(directAddress),
directAddress: Address.from(directAddress, directAddressType),
rssi: powerOrNull(rssi),
});
}
Expand Down
4 changes: 2 additions & 2 deletions src/hci/HciInformationParameters.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Address } from "../utils/Address.js";
import { Address, AddressType } from "../utils/Address.js";
import { HciParserErrorType, makeParserError } from "./HciError.js";
import { bitGet } from "../utils/Utils.js";

Expand Down Expand Up @@ -175,7 +175,7 @@ export class ReadBdAddr {
if (!params || params.length < 6) {
throw makeParserError(HciParserErrorType.InvalidPayloadSize);
}
return Address.from(params.readUIntLE(0, 6));
return Address.from(params.readUIntLE(0, 6), AddressType.PublicDeviceAddress);
}
}

Expand Down
Loading

0 comments on commit 031ff02

Please sign in to comment.