@stoprocent/noble 1.9.2-16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/.editorconfig +11 -0
  2. package/.eslintrc.js +25 -0
  3. package/.github/FUNDING.yml +2 -0
  4. package/.github/workflows/fediverse-action.yml +16 -0
  5. package/.github/workflows/nodepackage.yml +77 -0
  6. package/.github/workflows/npm-publish.yml +26 -0
  7. package/.github/workflows/prebuild.yml +65 -0
  8. package/.nycrc.json +4 -0
  9. package/CHANGELOG.md +119 -0
  10. package/LICENSE +20 -0
  11. package/MAINTAINERS.md +1 -0
  12. package/README.md +833 -0
  13. package/assets/noble-logo.png +0 -0
  14. package/assets/noble-logo.svg +13 -0
  15. package/binding.gyp +19 -0
  16. package/codecov.yml +5 -0
  17. package/examples/advertisement-discovery.js +65 -0
  18. package/examples/cache-gatt-discovery.js +198 -0
  19. package/examples/cache-gatt-reconnect.js +164 -0
  20. package/examples/echo.js +104 -0
  21. package/examples/enter-exit.js +78 -0
  22. package/examples/peripheral-explorer-async.js +133 -0
  23. package/examples/peripheral-explorer.js +225 -0
  24. package/examples/pizza/README.md +15 -0
  25. package/examples/pizza/central.js +194 -0
  26. package/examples/pizza/pizza.js +60 -0
  27. package/index.d.ts +203 -0
  28. package/index.js +6 -0
  29. package/lib/characteristic.js +161 -0
  30. package/lib/characteristics.json +449 -0
  31. package/lib/descriptor.js +72 -0
  32. package/lib/descriptors.json +47 -0
  33. package/lib/distributed/bindings.js +326 -0
  34. package/lib/hci-socket/acl-stream.js +60 -0
  35. package/lib/hci-socket/bindings.js +788 -0
  36. package/lib/hci-socket/crypto.js +74 -0
  37. package/lib/hci-socket/gap.js +432 -0
  38. package/lib/hci-socket/gatt.js +809 -0
  39. package/lib/hci-socket/hci-status.json +71 -0
  40. package/lib/hci-socket/hci.js +1264 -0
  41. package/lib/hci-socket/signaling.js +76 -0
  42. package/lib/hci-socket/smp.js +140 -0
  43. package/lib/hci-uart/bindings.js +569 -0
  44. package/lib/hci-uart/hci-serial-parser.js +70 -0
  45. package/lib/hci-uart/hci.js +1336 -0
  46. package/lib/mac/binding.gyp +26 -0
  47. package/lib/mac/bindings.js +11 -0
  48. package/lib/mac/src/ble_manager.h +41 -0
  49. package/lib/mac/src/ble_manager.mm +435 -0
  50. package/lib/mac/src/callbacks.cc +222 -0
  51. package/lib/mac/src/callbacks.h +84 -0
  52. package/lib/mac/src/napi_objc.h +12 -0
  53. package/lib/mac/src/napi_objc.mm +50 -0
  54. package/lib/mac/src/noble_mac.h +34 -0
  55. package/lib/mac/src/noble_mac.mm +264 -0
  56. package/lib/mac/src/objc_cpp.h +26 -0
  57. package/lib/mac/src/objc_cpp.mm +126 -0
  58. package/lib/mac/src/peripheral.h +23 -0
  59. package/lib/manufacture.js +48 -0
  60. package/lib/noble.js +593 -0
  61. package/lib/peripheral.js +219 -0
  62. package/lib/resolve-bindings-web.js +9 -0
  63. package/lib/resolve-bindings.js +44 -0
  64. package/lib/service.js +72 -0
  65. package/lib/services.json +92 -0
  66. package/lib/webbluetooth/bindings.js +368 -0
  67. package/lib/websocket/bindings.js +321 -0
  68. package/lib/win/binding.gyp +23 -0
  69. package/lib/win/bindings.js +11 -0
  70. package/lib/win/src/ble_manager.cc +802 -0
  71. package/lib/win/src/ble_manager.h +77 -0
  72. package/lib/win/src/callbacks.cc +274 -0
  73. package/lib/win/src/callbacks.h +33 -0
  74. package/lib/win/src/napi_winrt.cc +76 -0
  75. package/lib/win/src/napi_winrt.h +12 -0
  76. package/lib/win/src/noble_winrt.cc +308 -0
  77. package/lib/win/src/noble_winrt.h +34 -0
  78. package/lib/win/src/notify_map.cc +62 -0
  79. package/lib/win/src/notify_map.h +50 -0
  80. package/lib/win/src/peripheral.h +23 -0
  81. package/lib/win/src/peripheral_winrt.cc +296 -0
  82. package/lib/win/src/peripheral_winrt.h +82 -0
  83. package/lib/win/src/radio_watcher.cc +125 -0
  84. package/lib/win/src/radio_watcher.h +61 -0
  85. package/lib/win/src/winrt_cpp.cc +82 -0
  86. package/lib/win/src/winrt_cpp.h +11 -0
  87. package/lib/win/src/winrt_guid.cc +12 -0
  88. package/lib/win/src/winrt_guid.h +13 -0
  89. package/misc/nrf52840dk.hex +6921 -0
  90. package/misc/prj.conf +43 -0
  91. package/package.json +96 -0
  92. package/test/lib/characteristic.test.js +791 -0
  93. package/test/lib/descriptor.test.js +249 -0
  94. package/test/lib/distributed/bindings.test.js +918 -0
  95. package/test/lib/hci-socket/acl-stream.test.js +188 -0
  96. package/test/lib/hci-socket/bindings.test.js +1756 -0
  97. package/test/lib/hci-socket/crypto.test.js +55 -0
  98. package/test/lib/hci-socket/gap.test.js +1089 -0
  99. package/test/lib/hci-socket/gatt.test.js +2392 -0
  100. package/test/lib/hci-socket/hci.test.js +1891 -0
  101. package/test/lib/hci-socket/signaling.test.js +94 -0
  102. package/test/lib/hci-socket/smp.test.js +268 -0
  103. package/test/lib/manufacture.test.js +77 -0
  104. package/test/lib/peripheral.test.js +623 -0
  105. package/test/lib/resolve-bindings.test.js +102 -0
  106. package/test/lib/service.test.js +195 -0
  107. package/test/lib/webbluetooth/bindings.test.js +190 -0
  108. package/test/lib/websocket/bindings.test.js +456 -0
  109. package/test/noble.test.js +1565 -0
  110. package/test.js +131 -0
  111. package/with-bindings.js +5 -0
  112. package/ws-slave.js +404 -0
@@ -0,0 +1,76 @@
1
+ const debug = require('debug')('signaling');
2
+
3
+ const events = require('events');
4
+ const os = require('os');
5
+ const util = require('util');
6
+
7
+ const CONNECTION_PARAMETER_UPDATE_REQUEST = 0x12;
8
+ const CONNECTION_PARAMETER_UPDATE_RESPONSE = 0x13;
9
+
10
+ const SIGNALING_CID = 0x0005;
11
+
12
+ const Signaling = function (handle, aclStream) {
13
+ this._handle = handle;
14
+ this._aclStream = aclStream;
15
+
16
+ this.onAclStreamDataBinded = this.onAclStreamData.bind(this);
17
+ this.onAclStreamEndBinded = this.onAclStreamEnd.bind(this);
18
+
19
+ this._aclStream.on('data', this.onAclStreamDataBinded);
20
+ this._aclStream.on('end', this.onAclStreamEndBinded);
21
+ };
22
+
23
+ util.inherits(Signaling, events.EventEmitter);
24
+
25
+ Signaling.prototype.onAclStreamData = function (cid, data) {
26
+ if (cid !== SIGNALING_CID) {
27
+ return;
28
+ }
29
+
30
+ debug(`onAclStreamData: ${data.toString('hex')}`);
31
+
32
+ const code = data.readUInt8(0);
33
+ const identifier = data.readUInt8(1);
34
+ const length = data.readUInt16LE(2);
35
+ const signalingData = data.slice(4);
36
+
37
+ debug(`\tcode = ${code}`);
38
+ debug(`\tidentifier = ${identifier}`);
39
+ debug(`\tlength = ${length}`);
40
+
41
+ if (code === CONNECTION_PARAMETER_UPDATE_REQUEST) {
42
+ this.processConnectionParameterUpdateRequest(identifier, signalingData);
43
+ }
44
+ };
45
+
46
+ Signaling.prototype.onAclStreamEnd = function () {
47
+ this._aclStream.removeListener('data', this.onAclStreamDataBinded);
48
+ this._aclStream.removeListener('end', this.onAclStreamEndBinded);
49
+ };
50
+
51
+ Signaling.prototype.processConnectionParameterUpdateRequest = function (identifier, data) {
52
+ const minInterval = data.readUInt16LE(0) * 1.25;
53
+ const maxInterval = data.readUInt16LE(2) * 1.25;
54
+ const latency = data.readUInt16LE(4);
55
+ const supervisionTimeout = data.readUInt16LE(6) * 10;
56
+
57
+ debug('\t\tmin interval = ', minInterval);
58
+ debug('\t\tmax interval = ', maxInterval);
59
+ debug('\t\tlatency = ', latency);
60
+ debug('\t\tsupervision timeout = ', supervisionTimeout);
61
+
62
+ if (os.platform() !== 'linux' || process.env.HCI_CHANNEL_USER) {
63
+ const response = Buffer.alloc(6);
64
+
65
+ response.writeUInt8(CONNECTION_PARAMETER_UPDATE_RESPONSE, 0); // code
66
+ response.writeUInt8(identifier, 1); // identifier
67
+ response.writeUInt16LE(2, 2); // length
68
+ response.writeUInt16LE(0, 4);
69
+
70
+ this._aclStream.write(SIGNALING_CID, response);
71
+
72
+ this.emit('connectionParameterUpdateRequest', this._handle, minInterval, maxInterval, latency, supervisionTimeout);
73
+ }
74
+ };
75
+
76
+ module.exports = Signaling;
@@ -0,0 +1,140 @@
1
+ const events = require('events');
2
+ const util = require('util');
3
+
4
+ const crypto = require('./crypto');
5
+
6
+ const SMP_CID = 0x0006;
7
+
8
+ const SMP_PAIRING_REQUEST = 0x01;
9
+ const SMP_PAIRING_RESPONSE = 0x02;
10
+ const SMP_PAIRING_CONFIRM = 0x03;
11
+ const SMP_PAIRING_RANDOM = 0x04;
12
+ const SMP_PAIRING_FAILED = 0x05;
13
+ const SMP_ENCRYPT_INFO = 0x06;
14
+ const SMP_MASTER_IDENT = 0x07;
15
+
16
+ const Smp = function (aclStream, localAddressType, localAddress, remoteAddressType, remoteAddress) {
17
+ this._aclStream = aclStream;
18
+
19
+ this._iat = Buffer.from([(localAddressType === 'random') ? 0x01 : 0x00]);
20
+ this._ia = Buffer.from(localAddress.split(':').reverse().join(''), 'hex');
21
+ this._rat = Buffer.from([(remoteAddressType === 'random') ? 0x01 : 0x00]);
22
+ this._ra = Buffer.from(remoteAddress.split(':').reverse().join(''), 'hex');
23
+
24
+ this.onAclStreamDataBinded = this.onAclStreamData.bind(this);
25
+ this.onAclStreamEndBinded = this.onAclStreamEnd.bind(this);
26
+
27
+ this._aclStream.on('data', this.onAclStreamDataBinded);
28
+ this._aclStream.on('end', this.onAclStreamEndBinded);
29
+ };
30
+
31
+ util.inherits(Smp, events.EventEmitter);
32
+
33
+ Smp.prototype.sendPairingRequest = function () {
34
+ this._preq = Buffer.from([
35
+ SMP_PAIRING_REQUEST,
36
+ 0x03, // IO capability: NoInputNoOutput
37
+ 0x00, // OOB data: Authentication data not present
38
+ 0x01, // Authentication requirement: Bonding - No MITM
39
+ 0x10, // Max encryption key size
40
+ 0x00, // Initiator key distribution: <none>
41
+ 0x01 // Responder key distribution: EncKey
42
+ ]);
43
+
44
+ this.write(this._preq);
45
+ };
46
+
47
+ Smp.prototype.onAclStreamData = function (cid, data) {
48
+ if (cid !== SMP_CID) {
49
+ return;
50
+ }
51
+
52
+ const code = data.readUInt8(0);
53
+
54
+ if (SMP_PAIRING_RESPONSE === code) {
55
+ this.handlePairingResponse(data);
56
+ } else if (SMP_PAIRING_CONFIRM === code) {
57
+ this.handlePairingConfirm(data);
58
+ } else if (SMP_PAIRING_RANDOM === code) {
59
+ this.handlePairingRandom(data);
60
+ } else if (SMP_PAIRING_FAILED === code) {
61
+ this.handlePairingFailed(data);
62
+ } else if (SMP_ENCRYPT_INFO === code) {
63
+ this.handleEncryptInfo(data);
64
+ } else if (SMP_MASTER_IDENT === code) {
65
+ this.handleMasterIdent(data);
66
+ }
67
+ };
68
+
69
+ Smp.prototype.onAclStreamEnd = function () {
70
+ this._aclStream.removeListener('data', this.onAclStreamDataBinded);
71
+ this._aclStream.removeListener('end', this.onAclStreamEndBinded);
72
+
73
+ this.emit('end');
74
+ };
75
+
76
+ Smp.prototype.handlePairingResponse = function (data) {
77
+ this._pres = data;
78
+
79
+ this._tk = Buffer.from('00000000000000000000000000000000', 'hex');
80
+ this._r = crypto.r();
81
+
82
+ this.write(Buffer.concat([
83
+ Buffer.from([SMP_PAIRING_CONFIRM]),
84
+ crypto.c1(this._tk, this._r, this._pres, this._preq, this._iat, this._ia, this._rat, this._ra)
85
+ ]));
86
+ };
87
+
88
+ Smp.prototype.handlePairingConfirm = function (data) {
89
+ this._pcnf = data;
90
+
91
+ this.write(Buffer.concat([
92
+ Buffer.from([SMP_PAIRING_RANDOM]),
93
+ this._r
94
+ ]));
95
+ };
96
+
97
+ Smp.prototype.handlePairingRandom = function (data) {
98
+ const r = data.slice(1);
99
+
100
+ const pcnf = Buffer.concat([
101
+ Buffer.from([SMP_PAIRING_CONFIRM]),
102
+ crypto.c1(this._tk, r, this._pres, this._preq, this._iat, this._ia, this._rat, this._ra)
103
+ ]);
104
+
105
+ if (this._pcnf.toString('hex') === pcnf.toString('hex')) {
106
+ const stk = crypto.s1(this._tk, r, this._r);
107
+
108
+ this.emit('stk', stk);
109
+ } else {
110
+ this.write(Buffer.from([
111
+ SMP_PAIRING_RANDOM,
112
+ SMP_PAIRING_CONFIRM
113
+ ]));
114
+
115
+ this.emit('fail');
116
+ }
117
+ };
118
+
119
+ Smp.prototype.handlePairingFailed = function (data) {
120
+ this.emit('fail');
121
+ };
122
+
123
+ Smp.prototype.handleEncryptInfo = function (data) {
124
+ const ltk = data.slice(1);
125
+
126
+ this.emit('ltk', ltk);
127
+ };
128
+
129
+ Smp.prototype.handleMasterIdent = function (data) {
130
+ const ediv = data.slice(1, 3);
131
+ const rand = data.slice(3);
132
+
133
+ this.emit('masterIdent', ediv, rand);
134
+ };
135
+
136
+ Smp.prototype.write = function (data) {
137
+ this._aclStream.write(SMP_CID, data);
138
+ };
139
+
140
+ module.exports = Smp;