Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support MAC address as the identifier for bluetooth devices #3487

Merged
merged 1 commit into from
May 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/apps/SettingsWindow/src/View/DeviceSelectorView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@ struct DeviceSelectorView: View {
Button(action: {
selectedDevice = connectedDeviceSetting.connectedDevice
}) {
let noId = connectedDeviceSetting.connectedDevice.vendorId == 0 && connectedDeviceSetting.connectedDevice.productId == 0
let label = noId ? connectedDeviceSetting.connectedDevice.deviceAddress : "\(String(connectedDeviceSetting.connectedDevice.vendorId)),\(String(connectedDeviceSetting.connectedDevice.productId))"
HStack {
Text(
"""
\(connectedDeviceSetting.connectedDevice.productName) \
(\(connectedDeviceSetting.connectedDevice.manufacturerName)) \
[\(String(connectedDeviceSetting.connectedDevice.vendorId)),\(String(connectedDeviceSetting.connectedDevice.productId))]
[\(label)]
"""
)

Expand Down
58 changes: 36 additions & 22 deletions src/apps/SettingsWindow/src/View/DevicesView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -94,30 +94,44 @@ struct DevicesView: View {

if connectedDeviceSetting.connectedDevice.transport != "FIFO" {
VStack(alignment: .trailing, spacing: 4.0) {
HStack(alignment: .firstTextBaseline, spacing: 0) {
Spacer()

Text("Vendor ID: ")

Text(
String(
format: "%5d (0x%04x)",
connectedDeviceSetting.connectedDevice.vendorId,
connectedDeviceSetting.connectedDevice.vendorId)
)
if connectedDeviceSetting.connectedDevice.vendorId != 0 {
HStack(alignment: .firstTextBaseline, spacing: 0) {
Spacer()

Text("Vendor ID: ")

Text(
String(
format: "%5d (0x%04x)",
connectedDeviceSetting.connectedDevice.vendorId,
connectedDeviceSetting.connectedDevice.vendorId)
)
}
}

HStack(alignment: .center, spacing: 0) {
Spacer()

Text("Product ID: ")

Text(
String(
format: "%5d (0x%04x)",
connectedDeviceSetting.connectedDevice.productId,
connectedDeviceSetting.connectedDevice.productId)
)
if connectedDeviceSetting.connectedDevice.productId != 0 {
HStack(alignment: .center, spacing: 0) {
Spacer()

Text("Product ID: ")

Text(
String(
format: "%5d (0x%04x)",
connectedDeviceSetting.connectedDevice.productId,
connectedDeviceSetting.connectedDevice.productId)
)
}
}

if !connectedDeviceSetting.connectedDevice.deviceAddress.isEmpty {
HStack(alignment: .center, spacing: 0) {
Spacer()

Text("Device Address: ")

Text(connectedDeviceSetting.connectedDevice.deviceAddress)
}
}
}
.font(.custom("Menlo", size: 12.0))
Expand Down
1 change: 1 addition & 0 deletions src/apps/share/swift/LibKrbn/ConnectedDevices.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ extension LibKrbn {
transport: transport,
vendorId: libkrbn_connected_devices_get_vendor_id(libkrbnConnectedDevices, i),
productId: libkrbn_connected_devices_get_product_id(libkrbnConnectedDevices, i),
deviceAddress: libkrbn_connected_devices_get_device_address(libkrbnConnectedDevices, i),
isKeyboard: libkrbn_connected_devices_get_is_keyboard(libkrbnConnectedDevices, i),
isPointingDevice: libkrbn_connected_devices_get_is_pointing_device(
libkrbnConnectedDevices, i),
Expand Down
4 changes: 4 additions & 0 deletions src/apps/share/swift/LibKrbn/Models/ConnectedDevice.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ extension LibKrbn {
let transport: String
let vendorId: UInt64
let productId: UInt64
let deviceAddress: String
let isKeyboard: Bool
let isPointingDevice: Bool
let isBuiltInKeyboard: Bool
Expand All @@ -25,6 +26,7 @@ extension LibKrbn {
transport: String,
vendorId: UInt64,
productId: UInt64,
deviceAddress: UnsafePointer<CChar>,
isKeyboard: Bool,
isPointingDevice: Bool,
isBuiltInKeyboard: Bool,
Expand All @@ -38,6 +40,7 @@ extension LibKrbn {
self.transport = transport
self.vendorId = vendorId
self.productId = productId
self.deviceAddress = String(cString: deviceAddress)
self.isKeyboard = isKeyboard
self.isPointingDevice = isPointingDevice
self.isBuiltInKeyboard = isBuiltInKeyboard
Expand All @@ -49,6 +52,7 @@ extension LibKrbn {
capacity: 1)
libkrbnDeviceIdentifiers.pointee.vendor_id = vendorId
libkrbnDeviceIdentifiers.pointee.product_id = productId
libkrbnDeviceIdentifiers.pointee.device_address = deviceAddress
libkrbnDeviceIdentifiers.pointee.is_keyboard = isKeyboard
libkrbnDeviceIdentifiers.pointee.is_pointing_device = isPointingDevice
}
Expand Down
1 change: 1 addition & 0 deletions src/lib/libkrbn/include/libkrbn/impl/libkrbn_cpp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class libkrbn_cpp final {
static krbn::device_identifiers make_device_identifiers(const libkrbn_device_identifiers& device_identifiers) {
krbn::device_identifiers identifiers(pqrs::hid::vendor_id::value_t(device_identifiers.vendor_id),
pqrs::hid::product_id::value_t(device_identifiers.product_id),
device_identifiers.device_address ? std::string(device_identifiers.device_address) : "",
device_identifiers.is_keyboard,
device_identifiers.is_pointing_device);
return identifiers;
Expand Down
2 changes: 2 additions & 0 deletions src/lib/libkrbn/include/libkrbn/libkrbn.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ extern "C" {
typedef struct {
uint64_t vendor_id;
uint64_t product_id;
const char* device_address;
bool is_keyboard;
bool is_pointing_device;
} libkrbn_device_identifiers;
Expand Down Expand Up @@ -247,6 +248,7 @@ bool libkrbn_connected_devices_get_device_identifiers(libkrbn_connected_devices*
libkrbn_device_identifiers* device_identifiers);
uint64_t libkrbn_connected_devices_get_vendor_id(libkrbn_connected_devices* p, size_t index);
uint64_t libkrbn_connected_devices_get_product_id(libkrbn_connected_devices* p, size_t index);
const char* libkrbn_connected_devices_get_device_address(libkrbn_connected_devices* p, size_t index);
bool libkrbn_connected_devices_get_is_keyboard(libkrbn_connected_devices* p, size_t index);
bool libkrbn_connected_devices_get_is_pointing_device(libkrbn_connected_devices* p, size_t index);
bool libkrbn_connected_devices_get_is_built_in_keyboard(libkrbn_connected_devices* p, size_t index);
Expand Down
10 changes: 10 additions & 0 deletions src/lib/libkrbn/src/libkrbn_connected_devices.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,16 @@ uint64_t libkrbn_connected_devices_get_product_id(libkrbn_connected_devices* p,
return 0;
}

const char* libkrbn_connected_devices_get_device_address(libkrbn_connected_devices* p, size_t index) {
if (auto c = reinterpret_cast<libkrbn_connected_devices_class*>(p)) {
const auto& devices = c->get_connected_devices().get_devices();
if (index < devices.size()) {
return devices[index].get_identifiers().get_device_address().c_str();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be changed because it returns a pointer to data on the stack.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I misunderstood and this code is fine.
(I misunderstood it as device_properties::get_device_address)

}
}
return nullptr;
}

bool libkrbn_connected_devices_get_is_keyboard(libkrbn_connected_devices* p, size_t index) {
if (auto c = reinterpret_cast<libkrbn_connected_devices_class*>(p)) {
const auto& devices = c->get_connected_devices().get_devices();
Expand Down
16 changes: 16 additions & 0 deletions src/share/device_properties.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class device_properties final {
product_ = hid_device.find_product();
serial_number_ = hid_device.find_serial_number();
transport_ = hid_device.find_transport();
device_address_ = hid_device.find_device_address();
is_keyboard_ = iokit_utility::is_keyboard(hid_device);
is_pointing_device_ = iokit_utility::is_pointing_device(hid_device);

Expand Down Expand Up @@ -138,6 +139,9 @@ class device_properties final {
if (transport_) {
json["transport"] = *transport_;
}
if (device_address_) {
json["device_address"] = *device_address_;
}
if (is_keyboard_) {
json["is_keyboard"] = *is_keyboard_;
}
Expand Down Expand Up @@ -225,6 +229,16 @@ class device_properties final {
return *this;
}

std::optional<std::string> get_device_address(void) const {
return device_address_;
}

device_properties& set_device_address(const std::string& value) {
device_address_ = value;
update_device_identifiers();
return *this;
}

std::optional<device_id> get_device_id(void) const {
return device_id_;
}
Expand Down Expand Up @@ -341,6 +355,7 @@ class device_properties final {
device_identifiers_ = std::make_shared<device_identifiers>(
vendor_id_.value_or(pqrs::hid::vendor_id::value_t(0)),
product_id_.value_or(pqrs::hid::product_id::value_t(0)),
device_address_.value_or(""),
is_keyboard_.value_or(false),
is_pointing_device_.value_or(false));
}
Expand All @@ -353,6 +368,7 @@ class device_properties final {
std::optional<std::string> product_;
std::optional<std::string> serial_number_;
std::optional<std::string> transport_;
std::optional<std::string> device_address_;
std::optional<bool> is_keyboard_;
std::optional<bool> is_pointing_device_;
std::optional<bool> is_built_in_keyboard_;
Expand Down
10 changes: 10 additions & 0 deletions src/share/manipulator/conditions/device.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ class device final : public base {
std::optional<pqrs::hid::vendor_id::value_t> vendor_id;
std::optional<pqrs::hid::product_id::value_t> product_id;
std::optional<location_id> location_id;
std::optional<std::string> device_address;
std::optional<bool> is_keyboard;
std::optional<bool> is_pointing_device;
std::optional<bool> is_touch_bar;
Expand All @@ -132,6 +133,7 @@ class device final : public base {
return vendor_id ||
product_id ||
location_id ||
device_address ||
is_keyboard ||
is_pointing_device ||
is_touch_bar ||
Expand All @@ -154,6 +156,9 @@ class device final : public base {
if (location_id && location_id != device_properties.get_location_id().value_or(krbn::location_id(0))) {
return false;
}
if (device_address && device_address != device_properties.get_device_address().value_or("")) {
return false;
}
if (is_keyboard && is_keyboard != device_properties.get_is_keyboard().value_or(false)) {
return false;
}
Expand Down Expand Up @@ -199,6 +204,11 @@ class device final : public base {

d.location_id = location_id(value.get<int>());

} else if (key == "device_address") {
pqrs::json::requires_string(value, "identifiers entry `device_address`");

d.device_address = value.get<std::string>();

} else if (key == "is_keyboard") {
pqrs::json::requires_boolean(value, "identifiers entry `is_keyboard`");

Expand Down
19 changes: 19 additions & 0 deletions src/share/types/device_identifiers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,18 @@ class device_identifiers final {
public:
device_identifiers(void) : vendor_id_(pqrs::hid::vendor_id::value_t(0)),
product_id_(pqrs::hid::product_id::value_t(0)),
device_address_(""),
is_keyboard_(false),
is_pointing_device_(false) {
}

device_identifiers(pqrs::hid::vendor_id::value_t vendor_id,
pqrs::hid::product_id::value_t product_id,
std::string device_address,
bool is_keyboard,
bool is_pointing_device) : vendor_id_(vendor_id),
product_id_(product_id),
device_address_(device_address),
is_keyboard_(is_keyboard),
is_pointing_device_(is_pointing_device) {
}
Expand Down Expand Up @@ -47,6 +50,14 @@ class device_identifiers final {
product_id_ = value;
}

const std::string& get_device_address(void) const {
return device_address_;
}

void set_device_address(std::string value) {
device_address_ = value;
}

bool get_is_keyboard(void) const {
return is_keyboard_;
}
Expand All @@ -71,6 +82,7 @@ class device_identifiers final {
bool operator==(const device_identifiers& other) const {
return vendor_id_ == other.vendor_id_ &&
product_id_ == other.product_id_ &&
device_address_ == other.device_address_ &&
is_keyboard_ == other.is_keyboard_ &&
is_pointing_device_ == other.is_pointing_device_;
}
Expand All @@ -79,6 +91,7 @@ class device_identifiers final {
nlohmann::json json_;
pqrs::hid::vendor_id::value_t vendor_id_;
pqrs::hid::product_id::value_t product_id_;
std::string device_address_;
bool is_keyboard_;
bool is_pointing_device_;
};
Expand All @@ -87,6 +100,7 @@ inline void to_json(nlohmann::json& json, const device_identifiers& value) {
json = value.get_json();
json["vendor_id"] = type_safe::get(value.get_vendor_id());
json["product_id"] = type_safe::get(value.get_product_id());
json["device_address"] = value.get_device_address();
json["is_keyboard"] = value.get_is_keyboard();
json["is_pointing_device"] = value.get_is_pointing_device();
}
Expand All @@ -105,6 +119,11 @@ inline void from_json(const nlohmann::json& json, device_identifiers& value) {

value.set_product_id(v.get<pqrs::hid::product_id::value_t>());

} else if (k == "device_address") {
pqrs::json::requires_string(v, "`" + k + "`");

value.set_device_address(v.get<std::string>());

} else if (k == "is_keyboard") {
pqrs::json::requires_boolean(v, "`" + k + "`");

Expand Down
10 changes: 8 additions & 2 deletions tests/src/connected_devices/json/connected_devices.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"transport": "USB"
},
"identifiers": {
"device_address": "",
"is_keyboard": true,
"is_pointing_device": false,
"product_id": 5678,
Expand All @@ -22,6 +23,7 @@
"transport": "USB"
},
"identifiers": {
"device_address": "",
"is_keyboard": false,
"is_pointing_device": true,
"product_id": 5679,
Expand All @@ -38,6 +40,7 @@
"transport": "USB"
},
"identifiers": {
"device_address": "",
"is_keyboard": false,
"is_pointing_device": true,
"product_id": 6789,
Expand All @@ -54,6 +57,7 @@
"transport": "Bluetooth"
},
"identifiers": {
"device_address": "ec-ba-73-21-e6-f4",
"is_keyboard": true,
"is_pointing_device": false,
"product_id": 678,
Expand All @@ -70,6 +74,7 @@
"transport": "Bluetooth"
},
"identifiers": {
"device_address": "ec-ba-73-21-e6-f4",
"is_keyboard": false,
"is_pointing_device": true,
"product_id": 678,
Expand All @@ -86,10 +91,11 @@
"transport": "Bluetooth"
},
"identifiers": {
"device_address": "ec-ba-73-21-e6-f5",
"is_keyboard": true,
"is_pointing_device": false,
"product_id": 678,
"vendor_id": 1234
"product_id": 0,
"vendor_id": 0
},
"is_built_in_keyboard": false,
"is_built_in_touch_bar": true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"transport": "USB"
},
"identifiers": {
"device_address": "",
"is_keyboard": true,
"is_pointing_device": false,
"product_id": 5678,
Expand Down
Loading