mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 14:46:12 -04:00
Add Objective-C++ GATT client wrapper
PiperOrigin-RevId: 557925490
This commit is contained in:
committed by
Copybara-Service
parent
4aa52b45f9
commit
07a94a950d
@@ -573,6 +573,7 @@ let package = Package(
|
||||
// Temporarily ignore BLEv2 source files.
|
||||
// TODO(b/293283024): Stop ignoring these files when BLEv2 migration is complete.
|
||||
"internal/platform/implementation/apple/ble_gatt_server.mm",
|
||||
"internal/platform/implementation/apple/ble_gatt_client.mm",
|
||||
"internal/platform/implementation/apple/ble_peripheral.mm",
|
||||
"internal/platform/implementation/apple/ble_server_socket.mm",
|
||||
"internal/platform/implementation/apple/ble_socket.mm",
|
||||
|
||||
@@ -107,6 +107,7 @@ objc_library(
|
||||
objc_library(
|
||||
name = "ble_v2",
|
||||
srcs = [
|
||||
"ble_gatt_client.mm",
|
||||
"ble_gatt_server.mm",
|
||||
"ble_peripheral.mm",
|
||||
"ble_server_socket.mm",
|
||||
@@ -116,6 +117,7 @@ objc_library(
|
||||
"utils.mm",
|
||||
],
|
||||
hdrs = [
|
||||
"ble_gatt_client.h",
|
||||
"ble_gatt_server.h",
|
||||
"ble_peripheral.h",
|
||||
"ble_server_socket.h",
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Note: File language is detected using heuristics. Many Objective-C++ headers are incorrectly
|
||||
// classified as C++ resulting in invalid linter errors. The use of "NSArray" and other Foundation
|
||||
// classes like "NSData", "NSDictionary" and "NSUUID" are highly weighted for Objective-C and
|
||||
// Objective-C++ scores. Oddly, "#import <Foundation/Foundation.h>" does not contribute any points.
|
||||
// This comment alone should be enough to trick the IDE in to believing this is actually some sort
|
||||
// of Objective-C file. See: cs/google3/devtools/search/lang/recognize_language_classifiers_data
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "internal/platform/implementation/ble_v2.h"
|
||||
#include "internal/platform/uuid.h"
|
||||
|
||||
@class GNCBLEGATTClient;
|
||||
|
||||
namespace nearby {
|
||||
namespace apple {
|
||||
|
||||
class GattClient : public api::ble_v2::GattClient {
|
||||
public:
|
||||
explicit GattClient(GNCBLEGATTClient *gatt_client_);
|
||||
~GattClient() override = default;
|
||||
|
||||
// Discovers the specified characteristics of a service.
|
||||
//
|
||||
// This method blocks until discovery has finished.
|
||||
//
|
||||
// Returns whether or not discovery finished successfully.
|
||||
bool DiscoverServiceAndCharacteristics(const Uuid &service_uuid,
|
||||
const std::vector<Uuid> &characteristic_uuids) override;
|
||||
|
||||
// Retrieves a GATT characteristic.
|
||||
//
|
||||
// DiscoverServiceAndCharacteristics() must be called before this method to fetch all available
|
||||
// services and characteristics first.
|
||||
//
|
||||
// On success, returns the characteristic. On error, returns nullptr.
|
||||
std::optional<api::ble_v2::GattCharacteristic> GetCharacteristic(
|
||||
const Uuid &service_uuid, const Uuid &characteristic_uuid) override;
|
||||
|
||||
// Reads the requested characteristic from the associated remote device.
|
||||
//
|
||||
// On success, returns the characteristic's value. On error, returns nullptr.
|
||||
std::optional<std::string> ReadCharacteristic(
|
||||
const api::ble_v2::GattCharacteristic &characteristic) override;
|
||||
|
||||
// Writes a given characteristic and its values to the associated remote device.
|
||||
//
|
||||
// Returns whether or not the write was successful.
|
||||
bool WriteCharacteristic(const api::ble_v2::GattCharacteristic &characteristic,
|
||||
absl::string_view value,
|
||||
api::ble_v2::GattClient::WriteType type) override;
|
||||
|
||||
// Enable or disable notifications/indications for a given characteristic.
|
||||
//
|
||||
// Once notifications are enabled for a characteristic, on_characteristic_changed_cb will be
|
||||
// triggered if the remote device indicates that the given characteristic has changed.
|
||||
//
|
||||
// Returns whether or not the subscription was successful.
|
||||
bool SetCharacteristicSubscription(
|
||||
const api::ble_v2::GattCharacteristic &characteristic, bool enable,
|
||||
absl::AnyInvocable<void(absl::string_view value)> on_characteristic_changed_cb) override;
|
||||
|
||||
// Disconnects an established connection, or cancels a connection attempt currently in progress.
|
||||
void Disconnect() override;
|
||||
|
||||
private:
|
||||
GNCBLEGATTClient *gatt_client_;
|
||||
};
|
||||
|
||||
} // namespace apple
|
||||
} // namespace nearby
|
||||
@@ -0,0 +1,134 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#import "internal/platform/implementation/apple/ble_gatt_client.h"
|
||||
|
||||
#import <CoreBluetooth/CoreBluetooth.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "internal/platform/implementation/ble_v2.h"
|
||||
|
||||
#import "internal/platform/implementation/apple/Mediums/BLEv2/GNCBLEGATTClient.h"
|
||||
#import "internal/platform/implementation/apple/ble_utils.h"
|
||||
#import "GoogleToolboxForMac/GTMLogger.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace apple {
|
||||
|
||||
GattClient::GattClient(GNCBLEGATTClient *gatt_client) : gatt_client_(gatt_client) {}
|
||||
|
||||
bool GattClient::DiscoverServiceAndCharacteristics(const Uuid &service_uuid,
|
||||
const std::vector<Uuid> &characteristic_uuids) {
|
||||
CBUUID *serviceUUID = CBUUID128FromCPP(service_uuid);
|
||||
NSMutableArray<CBUUID *> *characteristics = [[NSMutableArray alloc] init];
|
||||
for (const auto &uuid : characteristic_uuids) {
|
||||
[characteristics addObject:CBUUID128FromCPP(uuid)];
|
||||
}
|
||||
|
||||
NSCondition *condition = [[NSCondition alloc] init];
|
||||
[condition lock];
|
||||
__block NSError *blockError = nil;
|
||||
[gatt_client_ discoverCharacteristicsWithUUIDs:characteristics
|
||||
serviceUUID:serviceUUID
|
||||
completionHandler:^(NSError *error) {
|
||||
[condition lock];
|
||||
if (error != nil) {
|
||||
GTMLoggerError(@"Error discovering characteristics: %@", error);
|
||||
}
|
||||
blockError = error;
|
||||
[condition signal];
|
||||
[condition unlock];
|
||||
}];
|
||||
[condition wait];
|
||||
[condition unlock];
|
||||
return blockError == nil;
|
||||
}
|
||||
|
||||
std::optional<api::ble_v2::GattCharacteristic> GattClient::GetCharacteristic(
|
||||
const Uuid &service_uuid, const Uuid &characteristic_uuid) {
|
||||
CBUUID *serviceUUID = CBUUID128FromCPP(service_uuid);
|
||||
CBUUID *characteristicUUID = CBUUID128FromCPP(characteristic_uuid);
|
||||
|
||||
NSCondition *condition = [[NSCondition alloc] init];
|
||||
[condition lock];
|
||||
__block GNCBLEGATTCharacteristic *blockCharacteristic = nil;
|
||||
__block NSError *blockError = nil;
|
||||
[gatt_client_ characteristicWithUUID:characteristicUUID
|
||||
serviceUUID:serviceUUID
|
||||
completionHandler:^(GNCBLEGATTCharacteristic *characteristic, NSError *error) {
|
||||
[condition lock];
|
||||
if (error != nil) {
|
||||
GTMLoggerError(@"Error retrieving characteristic: %@", error);
|
||||
}
|
||||
blockCharacteristic = characteristic;
|
||||
blockError = error;
|
||||
[condition signal];
|
||||
[condition unlock];
|
||||
}];
|
||||
[condition wait];
|
||||
[condition unlock];
|
||||
if (blockCharacteristic == nil) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return CPPGATTCharacteristicFromObjC(blockCharacteristic);
|
||||
}
|
||||
|
||||
std::optional<std::string> GattClient::ReadCharacteristic(
|
||||
const api::ble_v2::GattCharacteristic &characteristic) {
|
||||
NSCondition *condition = [[NSCondition alloc] init];
|
||||
[condition lock];
|
||||
__block NSData *blockValue = nil;
|
||||
__block NSError *blockError = nil;
|
||||
[gatt_client_ readValueForCharacteristic:ObjCGATTCharacteristicFromCPP(characteristic)
|
||||
completionHandler:^(NSData *value, NSError *error) {
|
||||
[condition lock];
|
||||
if (error != nil) {
|
||||
GTMLoggerError(@"Error reading characteristic: %@", error);
|
||||
}
|
||||
blockValue = value;
|
||||
blockError = error;
|
||||
[condition signal];
|
||||
[condition unlock];
|
||||
}];
|
||||
[condition wait];
|
||||
[condition unlock];
|
||||
if (blockValue == nil) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return std::string((const char *)blockValue.bytes, blockValue.length);
|
||||
}
|
||||
|
||||
// TODO(b/290385712): Implement.
|
||||
bool GattClient::WriteCharacteristic(const api::ble_v2::GattCharacteristic &characteristic,
|
||||
absl::string_view value,
|
||||
api::ble_v2::GattClient::WriteType type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO(b/290385712): Implement.
|
||||
bool GattClient::SetCharacteristicSubscription(
|
||||
const api::ble_v2::GattCharacteristic &characteristic, bool enable,
|
||||
absl::AnyInvocable<void(absl::string_view value)> on_characteristic_changed_cb) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO(b/290385712): Implement.
|
||||
void GattClient::Disconnect() {}
|
||||
|
||||
} // namespace apple
|
||||
} // namespace nearby
|
||||
Reference in New Issue
Block a user