Add Objective-C++ GATT server wrapper

PiperOrigin-RevId: 552636264
This commit is contained in:
Nick Bourdakos
2023-07-31 17:20:14 -07:00
committed by Copybara-Service
parent 0d58ead61c
commit 9d2cfc19c9
5 changed files with 188 additions and 0 deletions
+1
View File
@@ -572,6 +572,7 @@ let package = Package(
"internal/platform/medium_environment.cc",
// 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_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_server.mm",
"ble_peripheral.mm",
"ble_server_socket.mm",
"ble_socket.mm",
@@ -115,6 +116,7 @@ objc_library(
"utils.mm",
],
hdrs = [
"ble_gatt_server.h",
"ble_peripheral.h",
"ble_server_socket.h",
"ble_socket.h",
@@ -126,10 +128,12 @@ objc_library(
aspect_hints = ["//tools/build_defs/swift:no_module"],
deps = [
"//internal/platform:base",
"//internal/platform:uuid",
"//internal/platform/implementation:comm",
"//internal/platform/implementation/apple/Mediums",
"//third_party/apple_frameworks:CoreBluetooth",
"//third_party/apple_frameworks:Foundation",
"//third_party/objective_c/google_toolbox_for_mac:GTM_Logger",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/functional:any_invocable",
"@com_google_absl//absl/strings",
@@ -0,0 +1,78 @@
// 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 "internal/platform/implementation/ble_v2.h"
#include "internal/platform/uuid.h"
#import "internal/platform/implementation/apple/ble_peripheral.h"
@class GNCBLEGATTServer;
namespace nearby {
namespace apple {
class GattServer : public api::ble_v2::GattServer {
public:
explicit GattServer(GNCBLEGATTServer *gatt_server_);
~GattServer() override = default;
// Returns an empty BlePeripheral object.
//
// Use of this method should be avoided and its only purpose seems to be a check that the GATT
// server is valid.
api::ble_v2::BlePeripheral &GetBlePeripheral() override;
// Creates a characteristic and adds it to the GATT server under the given characteristic and
// service UUIDs.
//
// Characteristics of the same service UUID will be put under one service rather than many
// services with the same UUID.
//
// Returns no value upon error.
std::optional<api::ble_v2::GattCharacteristic> CreateCharacteristic(
const Uuid &service_uuid, const Uuid &characteristic_uuid,
api::ble_v2::GattCharacteristic::Permission permission,
api::ble_v2::GattCharacteristic::Property property) override;
// Updates a local characteristic with the provided value.
//
// Returns whether or not the update was successful.
bool UpdateCharacteristic(const api::ble_v2::GattCharacteristic &characteristic,
const nearby::ByteArray &value) override;
// Send a notification or indication that a local characteristic has been updated.
//
// Returns an absl::Status indicating success or what went wrong.
absl::Status NotifyCharacteristicChanged(const api::ble_v2::GattCharacteristic &characteristic,
bool confirm, const ByteArray &new_value) override;
// Stops a GATT server.
void Stop() override;
private:
GNCBLEGATTServer *gatt_server_;
BlePeripheral peripheral_;
};
} // namespace apple
} // namespace nearby
@@ -0,0 +1,104 @@
// 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_server.h"
#import <CoreBluetooth/CoreBluetooth.h>
#import <Foundation/Foundation.h>
#include "internal/platform/implementation/ble_v2.h"
#import "internal/platform/implementation/apple/Mediums/BLEv2/GNCBLEGATTServer.h"
#import "internal/platform/implementation/apple/ble_utils.h"
#import "internal/platform/implementation/apple/utils.h"
#import "GoogleToolboxForMac/GTMLogger.h"
namespace nearby {
namespace apple {
GattServer::GattServer(GNCBLEGATTServer *gatt_server) : gatt_server_(gatt_server) {}
std::optional<api::ble_v2::GattCharacteristic> GattServer::CreateCharacteristic(
const Uuid &service_uuid, const Uuid &characteristic_uuid,
api::ble_v2::GattCharacteristic::Permission permission,
api::ble_v2::GattCharacteristic::Property property) {
CBUUID *serviceUUID = CBUUID128FromCPP(service_uuid);
CBUUID *characteristicUUID = CBUUID128FromCPP(characteristic_uuid);
CBAttributePermissions permissions = CBAttributePermissionsFromCPP(permission);
CBCharacteristicProperties properties = CBCharacteristicPropertiesFromCPP(property);
NSCondition *condition = [[NSCondition alloc] init];
[condition lock];
__block GNCBLEGATTCharacteristic *blockCharacteristic = nil;
[gatt_server_ createCharacteristicWithServiceID:serviceUUID
characteristicUUID:characteristicUUID
permissions:permissions
properties:properties
completionHandler:^(GNCBLEGATTCharacteristic *characteristic,
NSError *error) {
[condition lock];
if (error != nil) {
GTMLoggerError(@"Error creating characteristic: %@", error);
}
blockCharacteristic = characteristic;
[condition signal];
[condition unlock];
}];
[condition wait];
[condition unlock];
if (blockCharacteristic == nil) {
return std::nullopt;
}
return CPPGATTCharacteristicFromObjC(blockCharacteristic);
}
bool GattServer::UpdateCharacteristic(const api::ble_v2::GattCharacteristic &characteristic,
const nearby::ByteArray &value) {
NSCondition *condition = [[NSCondition alloc] init];
[condition lock];
__block NSError *blockError = nil;
[gatt_server_ updateCharacteristic:ObjCGATTCharacteristicFromCPP(characteristic)
value:NSDataFromByteArray(value)
completionHandler:^(NSError *error) {
[condition lock];
if (error != nil) {
GTMLoggerError(@"Error updating characteristic: %@", error);
}
blockError = error;
[condition signal];
[condition unlock];
}];
[condition wait];
[condition unlock];
return blockError == nil;
}
// TODO(b/290385712): Implement.
absl::Status GattServer::NotifyCharacteristicChanged(
const api::ble_v2::GattCharacteristic &characteristic, bool confirm,
const ByteArray &new_value) {
return absl::UnimplementedError("");
}
void GattServer::Stop() {
[gatt_server_ stop];
}
// TODO(b/290385712): Implement.
api::ble_v2::BlePeripheral &GattServer::GetBlePeripheral() {
return peripheral_;
}
} // namespace apple
} // namespace nearby
@@ -33,6 +33,7 @@ namespace apple {
// identify a peripheral and connect to its GATT server.
class BlePeripheral : public api::ble_v2::BlePeripheral {
public:
BlePeripheral() = default;
explicit BlePeripheral(CBPeripheral *peripheral);
~BlePeripheral() override = default;