@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.
- package/.editorconfig +11 -0
- package/.eslintrc.js +25 -0
- package/.github/FUNDING.yml +2 -0
- package/.github/workflows/fediverse-action.yml +16 -0
- package/.github/workflows/nodepackage.yml +77 -0
- package/.github/workflows/npm-publish.yml +26 -0
- package/.github/workflows/prebuild.yml +65 -0
- package/.nycrc.json +4 -0
- package/CHANGELOG.md +119 -0
- package/LICENSE +20 -0
- package/MAINTAINERS.md +1 -0
- package/README.md +833 -0
- package/assets/noble-logo.png +0 -0
- package/assets/noble-logo.svg +13 -0
- package/binding.gyp +19 -0
- package/codecov.yml +5 -0
- package/examples/advertisement-discovery.js +65 -0
- package/examples/cache-gatt-discovery.js +198 -0
- package/examples/cache-gatt-reconnect.js +164 -0
- package/examples/echo.js +104 -0
- package/examples/enter-exit.js +78 -0
- package/examples/peripheral-explorer-async.js +133 -0
- package/examples/peripheral-explorer.js +225 -0
- package/examples/pizza/README.md +15 -0
- package/examples/pizza/central.js +194 -0
- package/examples/pizza/pizza.js +60 -0
- package/index.d.ts +203 -0
- package/index.js +6 -0
- package/lib/characteristic.js +161 -0
- package/lib/characteristics.json +449 -0
- package/lib/descriptor.js +72 -0
- package/lib/descriptors.json +47 -0
- package/lib/distributed/bindings.js +326 -0
- package/lib/hci-socket/acl-stream.js +60 -0
- package/lib/hci-socket/bindings.js +788 -0
- package/lib/hci-socket/crypto.js +74 -0
- package/lib/hci-socket/gap.js +432 -0
- package/lib/hci-socket/gatt.js +809 -0
- package/lib/hci-socket/hci-status.json +71 -0
- package/lib/hci-socket/hci.js +1264 -0
- package/lib/hci-socket/signaling.js +76 -0
- package/lib/hci-socket/smp.js +140 -0
- package/lib/hci-uart/bindings.js +569 -0
- package/lib/hci-uart/hci-serial-parser.js +70 -0
- package/lib/hci-uart/hci.js +1336 -0
- package/lib/mac/binding.gyp +26 -0
- package/lib/mac/bindings.js +11 -0
- package/lib/mac/src/ble_manager.h +41 -0
- package/lib/mac/src/ble_manager.mm +435 -0
- package/lib/mac/src/callbacks.cc +222 -0
- package/lib/mac/src/callbacks.h +84 -0
- package/lib/mac/src/napi_objc.h +12 -0
- package/lib/mac/src/napi_objc.mm +50 -0
- package/lib/mac/src/noble_mac.h +34 -0
- package/lib/mac/src/noble_mac.mm +264 -0
- package/lib/mac/src/objc_cpp.h +26 -0
- package/lib/mac/src/objc_cpp.mm +126 -0
- package/lib/mac/src/peripheral.h +23 -0
- package/lib/manufacture.js +48 -0
- package/lib/noble.js +593 -0
- package/lib/peripheral.js +219 -0
- package/lib/resolve-bindings-web.js +9 -0
- package/lib/resolve-bindings.js +44 -0
- package/lib/service.js +72 -0
- package/lib/services.json +92 -0
- package/lib/webbluetooth/bindings.js +368 -0
- package/lib/websocket/bindings.js +321 -0
- package/lib/win/binding.gyp +23 -0
- package/lib/win/bindings.js +11 -0
- package/lib/win/src/ble_manager.cc +802 -0
- package/lib/win/src/ble_manager.h +77 -0
- package/lib/win/src/callbacks.cc +274 -0
- package/lib/win/src/callbacks.h +33 -0
- package/lib/win/src/napi_winrt.cc +76 -0
- package/lib/win/src/napi_winrt.h +12 -0
- package/lib/win/src/noble_winrt.cc +308 -0
- package/lib/win/src/noble_winrt.h +34 -0
- package/lib/win/src/notify_map.cc +62 -0
- package/lib/win/src/notify_map.h +50 -0
- package/lib/win/src/peripheral.h +23 -0
- package/lib/win/src/peripheral_winrt.cc +296 -0
- package/lib/win/src/peripheral_winrt.h +82 -0
- package/lib/win/src/radio_watcher.cc +125 -0
- package/lib/win/src/radio_watcher.h +61 -0
- package/lib/win/src/winrt_cpp.cc +82 -0
- package/lib/win/src/winrt_cpp.h +11 -0
- package/lib/win/src/winrt_guid.cc +12 -0
- package/lib/win/src/winrt_guid.h +13 -0
- package/misc/nrf52840dk.hex +6921 -0
- package/misc/prj.conf +43 -0
- package/package.json +96 -0
- package/test/lib/characteristic.test.js +791 -0
- package/test/lib/descriptor.test.js +249 -0
- package/test/lib/distributed/bindings.test.js +918 -0
- package/test/lib/hci-socket/acl-stream.test.js +188 -0
- package/test/lib/hci-socket/bindings.test.js +1756 -0
- package/test/lib/hci-socket/crypto.test.js +55 -0
- package/test/lib/hci-socket/gap.test.js +1089 -0
- package/test/lib/hci-socket/gatt.test.js +2392 -0
- package/test/lib/hci-socket/hci.test.js +1891 -0
- package/test/lib/hci-socket/signaling.test.js +94 -0
- package/test/lib/hci-socket/smp.test.js +268 -0
- package/test/lib/manufacture.test.js +77 -0
- package/test/lib/peripheral.test.js +623 -0
- package/test/lib/resolve-bindings.test.js +102 -0
- package/test/lib/service.test.js +195 -0
- package/test/lib/webbluetooth/bindings.test.js +190 -0
- package/test/lib/websocket/bindings.test.js +456 -0
- package/test/noble.test.js +1565 -0
- package/test.js +131 -0
- package/with-bindings.js +5 -0
- package/ws-slave.js +404 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
//
|
|
2
|
+
// ble_manager.h
|
|
3
|
+
// noble-winrt-native
|
|
4
|
+
//
|
|
5
|
+
// Created by Georg Vienna on 03.09.18.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include <winrt/Windows.Devices.Bluetooth.Advertisement.h>
|
|
11
|
+
#include <winrt/Windows.Devices.Bluetooth.GenericAttributeProfile.h>
|
|
12
|
+
|
|
13
|
+
#include "callbacks.h"
|
|
14
|
+
#include "peripheral_winrt.h"
|
|
15
|
+
#include "radio_watcher.h"
|
|
16
|
+
#include "notify_map.h"
|
|
17
|
+
|
|
18
|
+
using namespace winrt::Windows::Devices::Bluetooth::GenericAttributeProfile;
|
|
19
|
+
using namespace winrt::Windows::Devices::Bluetooth::Advertisement;
|
|
20
|
+
using winrt::Windows::Foundation::AsyncStatus;
|
|
21
|
+
|
|
22
|
+
class BLEManager
|
|
23
|
+
{
|
|
24
|
+
public:
|
|
25
|
+
// clang-format off
|
|
26
|
+
BLEManager(const Napi::Value& receiver, const Napi::Function& callback);
|
|
27
|
+
void Scan(const std::vector<winrt::guid>& serviceUUIDs, bool allowDuplicates);
|
|
28
|
+
void StopScan();
|
|
29
|
+
bool Connect(const std::string& uuid);
|
|
30
|
+
bool Disconnect(const std::string& uuid);
|
|
31
|
+
bool UpdateRSSI(const std::string& uuid);
|
|
32
|
+
bool DiscoverServices(const std::string& uuid, const std::vector<winrt::guid>& serviceUUIDs);
|
|
33
|
+
bool DiscoverIncludedServices(const std::string& uuid, const winrt::guid& serviceUuid, const std::vector<winrt::guid>& serviceUUIDs);
|
|
34
|
+
bool DiscoverCharacteristics(const std::string& uuid, const winrt::guid& service, const std::vector<winrt::guid>& characteristicUUIDs);
|
|
35
|
+
bool Read(const std::string& uuid, const winrt::guid& serviceUuid, const winrt::guid& characteristicUuid);
|
|
36
|
+
bool Write(const std::string& uuid, const winrt::guid& serviceUuid, const winrt::guid& characteristicUuid, const Data& data, bool withoutResponse);
|
|
37
|
+
bool Notify(const std::string& uuid, const winrt::guid& serviceUuid, const winrt::guid& characteristicUuid, bool on);
|
|
38
|
+
bool DiscoverDescriptors(const std::string& uuid, const winrt::guid& serviceUuid, const winrt::guid& characteristicUuid);
|
|
39
|
+
bool ReadValue(const std::string& uuid, const winrt::guid& serviceUuid, const winrt::guid& characteristicUuid, const winrt::guid& descriptorUuid);
|
|
40
|
+
bool WriteValue(const std::string& uuid, const winrt::guid& serviceUuid, const winrt::guid& characteristicUuid, const winrt::guid& descriptorUuid, const Data& data);
|
|
41
|
+
bool ReadHandle(const std::string& uuid, int handle);
|
|
42
|
+
bool WriteHandle(const std::string& uuid, int handle, Data data);
|
|
43
|
+
// clang-format on
|
|
44
|
+
|
|
45
|
+
private:
|
|
46
|
+
// clang-format off
|
|
47
|
+
void OnRadio(Radio& radio);
|
|
48
|
+
void OnScanResult(BluetoothLEAdvertisementWatcher watcher, const BluetoothLEAdvertisementReceivedEventArgs& args);
|
|
49
|
+
void OnScanStopped(BluetoothLEAdvertisementWatcher watcher, const BluetoothLEAdvertisementWatcherStoppedEventArgs& args);
|
|
50
|
+
void OnConnected(IAsyncOperation<BluetoothLEDevice> asyncOp, AsyncStatus& status, std::string uuid);
|
|
51
|
+
void OnConnectionStatusChanged(BluetoothLEDevice device, winrt::Windows::Foundation::IInspectable inspectable);
|
|
52
|
+
void OnServicesDiscovered(IAsyncOperation<GattDeviceServicesResult> asyncOp, AsyncStatus status, std::string uuid, std::vector<winrt::guid> serviceUUIDs);
|
|
53
|
+
void OnIncludedServicesDiscovered(IAsyncOperation<GattDeviceServicesResult> asyncOp, AsyncStatus status, std::string uuid, std::string serviceId, std::vector<winrt::guid> serviceUUIDs);
|
|
54
|
+
void OnCharacteristicsDiscovered(IAsyncOperation<GattCharacteristicsResult> asyncOp, AsyncStatus status, std::string uuid, std::string serviceId, std::vector<winrt::guid> characteristicUUIDs);
|
|
55
|
+
void OnRead(IAsyncOperation<GattReadResult> asyncOp, AsyncStatus status, std::string uuid, std::string serviceId, std::string characteristicId);
|
|
56
|
+
void OnWrite(IAsyncOperation<GattWriteResult> asyncOp, AsyncStatus status, std::string uuid, std::string serviceId, std::string characteristicId);
|
|
57
|
+
void OnNotify(IAsyncOperation<GattWriteResult> asyncOp, AsyncStatus status, GattCharacteristic characteristic, std::string uuid, std::string serviceId, std::string characteristicId, bool state);
|
|
58
|
+
void OnValueChanged(GattCharacteristic chracteristic, const GattValueChangedEventArgs& args, std::string uuid);
|
|
59
|
+
void OnDescriptorsDiscovered(IAsyncOperation<GattDescriptorsResult> asyncOp, AsyncStatus status, std::string uuid, std::string serviceId, std::string characteristicId);
|
|
60
|
+
void OnReadValue(IAsyncOperation<GattReadResult> asyncOp, AsyncStatus status, std::string uuid, std::string serviceId, std::string characteristicId, std::string descriptorId);
|
|
61
|
+
void OnWriteValue(IAsyncOperation<GattWriteResult> asyncOp, AsyncStatus status, std::string uuid, std::string serviceId, std::string characteristicId, std::string descriptorId);
|
|
62
|
+
void OnReadHandle(IAsyncOperation<GattReadResult> asyncOp, AsyncStatus status, std::string uuid, int handle);
|
|
63
|
+
void OnWriteHandle(IAsyncOperation<GattWriteResult> asyncOp, AsyncStatus status, std::string uuid, int handle);
|
|
64
|
+
// clang-format on
|
|
65
|
+
|
|
66
|
+
Emit mEmit;
|
|
67
|
+
RadioWatcher mWatcher;
|
|
68
|
+
AdapterState mRadioState;
|
|
69
|
+
BluetoothLEAdvertisementWatcher mAdvertismentWatcher;
|
|
70
|
+
winrt::event_revoker<IBluetoothLEAdvertisementWatcher> mReceivedRevoker;
|
|
71
|
+
winrt::event_revoker<IBluetoothLEAdvertisementWatcher> mStoppedRevoker;
|
|
72
|
+
bool mAllowDuplicates;
|
|
73
|
+
|
|
74
|
+
std::unordered_map<std::string, PeripheralWinrt> mDeviceMap;
|
|
75
|
+
std::set<std::string> mAdvertismentMap;
|
|
76
|
+
NotifyMap mNotifyMap;
|
|
77
|
+
};
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
//
|
|
2
|
+
// callbacks.cc
|
|
3
|
+
// noble-mac-native
|
|
4
|
+
//
|
|
5
|
+
// Created by Georg Vienna on 30.08.18.
|
|
6
|
+
//
|
|
7
|
+
#include "callbacks.h"
|
|
8
|
+
|
|
9
|
+
#include <napi-thread-safe-callback.hpp>
|
|
10
|
+
|
|
11
|
+
#define _s(val) Napi::String::New(env, val)
|
|
12
|
+
#define _b(val) Napi::Boolean::New(env, val)
|
|
13
|
+
#define _n(val) Napi::Number::New(env, val)
|
|
14
|
+
#define _u(str) toUuid(env, str)
|
|
15
|
+
|
|
16
|
+
Napi::String toUuid(Napi::Env& env, const std::string& uuid)
|
|
17
|
+
{
|
|
18
|
+
std::string str(uuid);
|
|
19
|
+
str.erase(std::remove(str.begin(), str.end(), '-'), str.end());
|
|
20
|
+
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
|
|
21
|
+
return _s(str);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
Napi::String toAddressType(Napi::Env& env, const AddressType& type)
|
|
25
|
+
{
|
|
26
|
+
if (type == PUBLIC)
|
|
27
|
+
{
|
|
28
|
+
return _s("public");
|
|
29
|
+
}
|
|
30
|
+
else if (type == RANDOM)
|
|
31
|
+
{
|
|
32
|
+
return _s("random");
|
|
33
|
+
}
|
|
34
|
+
return _s("unknown");
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
Napi::Buffer<uint8_t> toBuffer(Napi::Env& env, const Data& data)
|
|
38
|
+
{
|
|
39
|
+
if (data.empty())
|
|
40
|
+
{
|
|
41
|
+
return Napi::Buffer<uint8_t>::New(env, 0);
|
|
42
|
+
}
|
|
43
|
+
return Napi::Buffer<uint8_t>::Copy(env, &data[0], data.size());
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
Napi::Array toUuidArray(Napi::Env& env, const std::vector<std::string>& data)
|
|
47
|
+
{
|
|
48
|
+
if (data.empty())
|
|
49
|
+
{
|
|
50
|
+
return Napi::Array::New(env);
|
|
51
|
+
}
|
|
52
|
+
auto arr = Napi::Array::New(env, data.size());
|
|
53
|
+
for (size_t i = 0; i < data.size(); i++)
|
|
54
|
+
{
|
|
55
|
+
arr.Set(i, _u(data[i]));
|
|
56
|
+
}
|
|
57
|
+
return arr;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
Napi::Array toArray(Napi::Env& env, const std::vector<std::string>& data)
|
|
61
|
+
{
|
|
62
|
+
if (data.empty())
|
|
63
|
+
{
|
|
64
|
+
return Napi::Array::New(env);
|
|
65
|
+
}
|
|
66
|
+
auto arr = Napi::Array::New(env, data.size());
|
|
67
|
+
for (size_t i = 0; i < data.size(); i++)
|
|
68
|
+
{
|
|
69
|
+
arr.Set(i, _s(data[i]));
|
|
70
|
+
}
|
|
71
|
+
return arr;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
void Emit::Wrap(const Napi::Value& receiver, const Napi::Function& callback)
|
|
75
|
+
{
|
|
76
|
+
mCallback = std::make_shared<ThreadSafeCallback>(receiver, callback);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
void Emit::RadioState(const std::string& state)
|
|
80
|
+
{
|
|
81
|
+
mCallback->call([state](Napi::Env env, std::vector<napi_value>& args) {
|
|
82
|
+
// emit('stateChange', state);
|
|
83
|
+
args = { _s("stateChange"), _s(state) };
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
void Emit::ScanState(bool start)
|
|
88
|
+
{
|
|
89
|
+
mCallback->call([start](Napi::Env env, std::vector<napi_value>& args) {
|
|
90
|
+
// emit('scanStart') emit('scanStop')
|
|
91
|
+
args = { _s(start ? "scanStart" : "scanStop") };
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
void Emit::Scan(const std::string& uuid, int rssi, const Peripheral& peripheral)
|
|
96
|
+
{
|
|
97
|
+
auto address = peripheral.address;
|
|
98
|
+
auto addressType = peripheral.addressType;
|
|
99
|
+
auto connectable = peripheral.connectable;
|
|
100
|
+
auto name = peripheral.name;
|
|
101
|
+
auto txPowerLevel = peripheral.txPowerLevel;
|
|
102
|
+
auto manufacturerData = peripheral.manufacturerData;
|
|
103
|
+
auto serviceData = peripheral.serviceData;
|
|
104
|
+
auto serviceUuids = peripheral.serviceUuids;
|
|
105
|
+
mCallback->call([uuid, rssi, address, addressType, connectable, name, txPowerLevel,
|
|
106
|
+
manufacturerData, serviceData,
|
|
107
|
+
serviceUuids](Napi::Env env, std::vector<napi_value>& args) {
|
|
108
|
+
Napi::Object advertisment = Napi::Object::New(env);
|
|
109
|
+
advertisment.Set(_s("localName"), _s(name));
|
|
110
|
+
advertisment.Set(_s("txPowerLevel"), txPowerLevel);
|
|
111
|
+
advertisment.Set(_s("manufacturerData"), toBuffer(env, manufacturerData));
|
|
112
|
+
auto array =
|
|
113
|
+
serviceData.empty() ? Napi::Array::New(env) : Napi::Array::New(env, serviceData.size());
|
|
114
|
+
for (size_t i = 0; i < serviceData.size(); i++)
|
|
115
|
+
{
|
|
116
|
+
Napi::Object data = Napi::Object::New(env);
|
|
117
|
+
data.Set(_s("uuid"), _u(serviceData[i].first));
|
|
118
|
+
data.Set(_s("data"), toBuffer(env, serviceData[i].second));
|
|
119
|
+
array.Set(i, data);
|
|
120
|
+
}
|
|
121
|
+
advertisment.Set(_s("serviceData"), array);
|
|
122
|
+
advertisment.Set(_s("serviceUuids"), toUuidArray(env, serviceUuids));
|
|
123
|
+
// emit('discover', deviceUuid, address, addressType, connectable, advertisement, rssi);
|
|
124
|
+
args = { _s("discover"), _u(uuid), _s(address), toAddressType(env, addressType),
|
|
125
|
+
_b(connectable), advertisment, _n(rssi) };
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
void Emit::Connected(const std::string& uuid, const std::string& error)
|
|
130
|
+
{
|
|
131
|
+
mCallback->call([uuid, error](Napi::Env env, std::vector<napi_value>& args) {
|
|
132
|
+
// emit('connect', deviceUuid) error added here
|
|
133
|
+
args = { _s("connect"), _u(uuid), error.empty() ? env.Null() : _s(error) };
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
void Emit::Disconnected(const std::string& uuid)
|
|
138
|
+
{
|
|
139
|
+
mCallback->call([uuid](Napi::Env env, std::vector<napi_value>& args) {
|
|
140
|
+
// emit('disconnect', deviceUuid);
|
|
141
|
+
args = { _s("disconnect"), _u(uuid) };
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
void Emit::RSSI(const std::string& uuid, int rssi)
|
|
146
|
+
{
|
|
147
|
+
mCallback->call([uuid, rssi](Napi::Env env, std::vector<napi_value>& args) {
|
|
148
|
+
// emit('rssiUpdate', deviceUuid, rssi);
|
|
149
|
+
args = { _s("rssiUpdate"), _u(uuid), _n(rssi) };
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
void Emit::ServicesDiscovered(const std::string& uuid, const std::vector<std::string>& serviceUuids)
|
|
154
|
+
{
|
|
155
|
+
mCallback->call([uuid, serviceUuids](Napi::Env env, std::vector<napi_value>& args) {
|
|
156
|
+
// emit('servicesDiscover', deviceUuid, serviceUuids)
|
|
157
|
+
args = { _s("servicesDiscover"), _u(uuid), toUuidArray(env, serviceUuids) };
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
void Emit::IncludedServicesDiscovered(const std::string& uuid, const std::string& serviceUuid,
|
|
162
|
+
const std::vector<std::string>& serviceUuids)
|
|
163
|
+
{
|
|
164
|
+
mCallback->call(
|
|
165
|
+
[uuid, serviceUuid, serviceUuids](Napi::Env env, std::vector<napi_value>& args) {
|
|
166
|
+
// emit('includedServicesDiscover', deviceUuid, serviceUuid, includedServiceUuids)
|
|
167
|
+
args = { _s("includedServicesDiscover"), _u(uuid), _u(serviceUuid),
|
|
168
|
+
toUuidArray(env, serviceUuids) };
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
void Emit::CharacteristicsDiscovered(
|
|
173
|
+
const std::string& uuid, const std::string& serviceUuid,
|
|
174
|
+
const std::vector<std::pair<std::string, std::vector<std::string>>>& characteristics)
|
|
175
|
+
{
|
|
176
|
+
mCallback->call(
|
|
177
|
+
[uuid, serviceUuid, characteristics](Napi::Env env, std::vector<napi_value>& args) {
|
|
178
|
+
auto arr = characteristics.empty() ? Napi::Array::New(env)
|
|
179
|
+
: Napi::Array::New(env, characteristics.size());
|
|
180
|
+
for (size_t i = 0; i < characteristics.size(); i++)
|
|
181
|
+
{
|
|
182
|
+
Napi::Object characteristic = Napi::Object::New(env);
|
|
183
|
+
characteristic.Set(_s("uuid"), _u(characteristics[i].first));
|
|
184
|
+
characteristic.Set(_s("properties"), toArray(env, characteristics[i].second));
|
|
185
|
+
arr.Set(i, characteristic);
|
|
186
|
+
}
|
|
187
|
+
// emit('characteristicsDiscover', deviceUuid, serviceUuid, { uuid, properties:
|
|
188
|
+
// ['broadcast', 'read', ...]})
|
|
189
|
+
args = { _s("characteristicsDiscover"), _u(uuid), _u(serviceUuid), arr };
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
void Emit::Read(const std::string& uuid, const std::string& serviceUuid,
|
|
194
|
+
const std::string& characteristicUuid, const Data& data, bool isNotification)
|
|
195
|
+
{
|
|
196
|
+
mCallback->call([uuid, serviceUuid, characteristicUuid, data,
|
|
197
|
+
isNotification](Napi::Env env, std::vector<napi_value>& args) {
|
|
198
|
+
// emit('read', deviceUuid, serviceUuid, characteristicsUuid, data, isNotification);
|
|
199
|
+
args = { _s("read"), _u(uuid), _u(serviceUuid), _u(characteristicUuid),
|
|
200
|
+
toBuffer(env, data), _b(isNotification) };
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
void Emit::Write(const std::string& uuid, const std::string& serviceUuid,
|
|
205
|
+
const std::string& characteristicUuid)
|
|
206
|
+
{
|
|
207
|
+
mCallback->call(
|
|
208
|
+
[uuid, serviceUuid, characteristicUuid](Napi::Env env, std::vector<napi_value>& args) {
|
|
209
|
+
// emit('write', deviceUuid, servicesUuid, characteristicsUuid)
|
|
210
|
+
args = { _s("write"), _u(uuid), _u(serviceUuid), _u(characteristicUuid) };
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
void Emit::Notify(const std::string& uuid, const std::string& serviceUuid,
|
|
215
|
+
const std::string& characteristicUuid, bool state)
|
|
216
|
+
{
|
|
217
|
+
mCallback->call([uuid, serviceUuid, characteristicUuid, state](Napi::Env env,
|
|
218
|
+
std::vector<napi_value>& args) {
|
|
219
|
+
// emit('notify', deviceUuid, servicesUuid, characteristicsUuid, state)
|
|
220
|
+
args = { _s("notify"), _u(uuid), _u(serviceUuid), _u(characteristicUuid), _b(state) };
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
void Emit::DescriptorsDiscovered(const std::string& uuid, const std::string& serviceUuid,
|
|
225
|
+
const std::string& characteristicUuid,
|
|
226
|
+
const std::vector<std::string>& descriptorUuids)
|
|
227
|
+
{
|
|
228
|
+
mCallback->call([uuid, serviceUuid, characteristicUuid,
|
|
229
|
+
descriptorUuids](Napi::Env env, std::vector<napi_value>& args) {
|
|
230
|
+
// emit('descriptorsDiscover', deviceUuid, servicesUuid, characteristicsUuid, descriptors:
|
|
231
|
+
// [uuids])
|
|
232
|
+
args = { _s("descriptorsDiscover"), _u(uuid), _u(serviceUuid), _u(characteristicUuid),
|
|
233
|
+
toUuidArray(env, descriptorUuids) };
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
void Emit::ReadValue(const std::string& uuid, const std::string& serviceUuid,
|
|
238
|
+
const std::string& characteristicUuid, const std::string& descriptorUuid,
|
|
239
|
+
const Data& data)
|
|
240
|
+
{
|
|
241
|
+
mCallback->call([uuid, serviceUuid, characteristicUuid, descriptorUuid,
|
|
242
|
+
data](Napi::Env env, std::vector<napi_value>& args) {
|
|
243
|
+
// emit('valueRead', deviceUuid, serviceUuid, characteristicUuid, descriptorUuid, data)
|
|
244
|
+
args = { _s("valueRead"), _u(uuid), _u(serviceUuid),
|
|
245
|
+
_u(characteristicUuid), _u(descriptorUuid), toBuffer(env, data) };
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
void Emit::WriteValue(const std::string& uuid, const std::string& serviceUuid,
|
|
250
|
+
const std::string& characteristicUuid, const std::string& descriptorUuid)
|
|
251
|
+
{
|
|
252
|
+
mCallback->call([uuid, serviceUuid, characteristicUuid,
|
|
253
|
+
descriptorUuid](Napi::Env env, std::vector<napi_value>& args) {
|
|
254
|
+
// emit('valueWrite', deviceUuid, serviceUuid, characteristicUuid, descriptorUuid);
|
|
255
|
+
args = { _s("valueWrite"), _u(uuid), _u(serviceUuid), _u(characteristicUuid),
|
|
256
|
+
_u(descriptorUuid) };
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
void Emit::ReadHandle(const std::string& uuid, int descriptorHandle, const Data& data)
|
|
261
|
+
{
|
|
262
|
+
mCallback->call([uuid, descriptorHandle, data](Napi::Env env, std::vector<napi_value>& args) {
|
|
263
|
+
// emit('handleRead', deviceUuid, descriptorHandle, data);
|
|
264
|
+
args = { _s("handleRead"), _u(uuid), _n(descriptorHandle), toBuffer(env, data) };
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
void Emit::WriteHandle(const std::string& uuid, int descriptorHandle)
|
|
269
|
+
{
|
|
270
|
+
mCallback->call([uuid, descriptorHandle](Napi::Env env, std::vector<napi_value>& args) {
|
|
271
|
+
// emit('handleWrite', deviceUuid, descriptorHandle);
|
|
272
|
+
args = { _s("handleWrite"), _u(uuid), _n(descriptorHandle) };
|
|
273
|
+
});
|
|
274
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <napi.h>
|
|
4
|
+
#include "peripheral.h"
|
|
5
|
+
|
|
6
|
+
class ThreadSafeCallback;
|
|
7
|
+
|
|
8
|
+
class Emit
|
|
9
|
+
{
|
|
10
|
+
public:
|
|
11
|
+
// clang-format off
|
|
12
|
+
void Wrap(const Napi::Value& receiver, const Napi::Function& callback);
|
|
13
|
+
void RadioState(const std::string& status);
|
|
14
|
+
void ScanState(bool start);
|
|
15
|
+
void Scan(const std::string& uuid, int rssi, const Peripheral& peripheral);
|
|
16
|
+
void Connected(const std::string& uuid, const std::string& error = "");
|
|
17
|
+
void Disconnected(const std::string& uuid);
|
|
18
|
+
void RSSI(const std::string& uuid, int rssi);
|
|
19
|
+
void ServicesDiscovered(const std::string& uuid, const std::vector<std::string>& serviceUuids);
|
|
20
|
+
void IncludedServicesDiscovered(const std::string& uuid, const std::string& serviceUuid, const std::vector<std::string>& serviceUuids);
|
|
21
|
+
void CharacteristicsDiscovered(const std::string& uuid, const std::string& serviceUuid, const std::vector<std::pair<std::string, std::vector<std::string>>>& characteristics);
|
|
22
|
+
void Read(const std::string& uuid, const std::string& serviceUuid, const std::string& characteristicUuid, const Data& data, bool isNotification);
|
|
23
|
+
void Write(const std::string& uuid, const std::string& serviceUuid, const std::string& characteristicUuid);
|
|
24
|
+
void Notify(const std::string& uuid, const std::string& serviceUuid, const std::string& characteristicUuid, bool state);
|
|
25
|
+
void DescriptorsDiscovered(const std::string& uuid, const std::string& serviceUuid, const std::string& characteristicUuid, const std::vector<std::string>& descriptorUuids);
|
|
26
|
+
void ReadValue(const std::string& uuid, const std::string& serviceUuid, const std::string& characteristicUuid, const std::string& descriptorUuid, const Data& data);
|
|
27
|
+
void WriteValue(const std::string& uuid, const std::string& serviceUuid, const std::string& characteristicUuid, const std::string& descriptorUuid);
|
|
28
|
+
void ReadHandle(const std::string& uuid, int descriptorHandle, const Data& data);
|
|
29
|
+
void WriteHandle(const std::string& uuid, int descriptorHandle);
|
|
30
|
+
// clang-format on
|
|
31
|
+
protected:
|
|
32
|
+
std::shared_ptr<ThreadSafeCallback> mCallback;
|
|
33
|
+
};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
//
|
|
2
|
+
// napi_objc.mm
|
|
3
|
+
// noble-mac-native
|
|
4
|
+
//
|
|
5
|
+
// Created by Georg Vienna on 30.08.18.
|
|
6
|
+
//
|
|
7
|
+
#include "napi_winrt.h"
|
|
8
|
+
|
|
9
|
+
#include <winrt/Windows.Devices.Bluetooth.GenericAttributeProfile.h>
|
|
10
|
+
#include <rpc.h>
|
|
11
|
+
|
|
12
|
+
using namespace winrt::Windows::Devices::Bluetooth;
|
|
13
|
+
|
|
14
|
+
winrt::guid napiToUuid(Napi::String string)
|
|
15
|
+
{
|
|
16
|
+
std::string str = string.Utf8Value();
|
|
17
|
+
if (str.size() == 32)
|
|
18
|
+
{
|
|
19
|
+
str.insert(8, "-");
|
|
20
|
+
str.insert(13, "-");
|
|
21
|
+
str.insert(18, "-");
|
|
22
|
+
str.insert(23, "-");
|
|
23
|
+
}
|
|
24
|
+
if (str.size() == 4)
|
|
25
|
+
{
|
|
26
|
+
int id = std::stoi(str, 0, 16);
|
|
27
|
+
return BluetoothUuidHelper::FromShortId(id);
|
|
28
|
+
}
|
|
29
|
+
UUID uuid;
|
|
30
|
+
UuidFromString((RPC_CSTR)str.c_str(), &uuid);
|
|
31
|
+
std::array<uint8_t, 8> data4;
|
|
32
|
+
std::copy_n(uuid.Data4, data4.size(), data4.begin());
|
|
33
|
+
return winrt::guid(uuid.Data1, uuid.Data2, uuid.Data3, data4);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
std::vector<winrt::guid> napiToUuidArray(Napi::Array array)
|
|
37
|
+
{
|
|
38
|
+
std::vector<winrt::guid> uuids;
|
|
39
|
+
for (size_t i = 0; i < array.Length(); i++)
|
|
40
|
+
{
|
|
41
|
+
Napi::Value val = array[i];
|
|
42
|
+
uuids.push_back(napiToUuid(val.As<Napi::String>()));
|
|
43
|
+
}
|
|
44
|
+
return uuids;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
Data napiToData(Napi::Buffer<byte> buffer)
|
|
48
|
+
{
|
|
49
|
+
Data data;
|
|
50
|
+
auto bytes = buffer.Data();
|
|
51
|
+
data.assign(bytes, bytes + buffer.Length());
|
|
52
|
+
return data;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
int napiToNumber(Napi::Number number)
|
|
56
|
+
{
|
|
57
|
+
return number.Int32Value();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
std::vector<winrt::guid> getUuidArray(const Napi::Value& value)
|
|
61
|
+
{
|
|
62
|
+
if (value.IsArray())
|
|
63
|
+
{
|
|
64
|
+
return napiToUuidArray(value.As<Napi::Array>());
|
|
65
|
+
}
|
|
66
|
+
return std::vector<winrt::guid>();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
bool getBool(const Napi::Value& value, bool def)
|
|
70
|
+
{
|
|
71
|
+
if (value.IsBoolean())
|
|
72
|
+
{
|
|
73
|
+
return value.As<Napi::Boolean>().Value();
|
|
74
|
+
}
|
|
75
|
+
return def;
|
|
76
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <napi.h>
|
|
4
|
+
#include "winrt/base.h"
|
|
5
|
+
#include "peripheral.h"
|
|
6
|
+
|
|
7
|
+
std::vector<winrt::guid> getUuidArray(const Napi::Value& value);
|
|
8
|
+
bool getBool(const Napi::Value& value, bool def);
|
|
9
|
+
|
|
10
|
+
winrt::guid napiToUuid(Napi::String string);
|
|
11
|
+
Data napiToData(Napi::Buffer<unsigned char> buffer);
|
|
12
|
+
int napiToNumber(Napi::Number number);
|