simplersble 1.1.1-dev12

The all-in-one Bluetooth library that makes it easy to add wireless connectivity to your projects.
Documentation
#include "LocalServiceMac.h"

#include <utility>

#import <CoreBluetooth/CoreBluetooth.h>
#import <Foundation/Foundation.h>

#include <simpleble/Exceptions.h>

#import "LocalCharacteristicMac.h"
#import "LocalPeripheralMac.h"
#import "Utils.h"

namespace SimpleBLE::Local {

ServiceMac::ServiceMac(std::weak_ptr<PeripheralMac> peripheral, BluetoothUUID uuid)
    : _peripheral(std::move(peripheral)), _uuid(std::move(uuid)) {
    auto* service = [[CBMutableService alloc] initWithType:uuidFromSimpleBLE(_uuid) primary:YES];
    _opaque_service = (__bridge_retained void*)service;
}

ServiceMac::~ServiceMac() {
    CBMutableService* service = (__bridge_transfer CBMutableService*)_opaque_service;
    service = nil;
}

BluetoothUUID ServiceMac::uuid() { return _uuid; }

std::shared_ptr<CharacteristicBase> ServiceMac::add_characteristic(BluetoothUUID uuid, std::set<CharacteristicCapability> capabilities) {
    std::scoped_lock lock(_mutex);
    if (_frozen) {
        throw Exception::OperationFailed("The local service cannot be changed while its peripheral is started.");
    }

    auto peripheral = _peripheral.lock();
    if (!peripheral) {
        throw Exception::InvalidReference();
    }

    auto characteristic = std::make_shared<CharacteristicMac>(peripheral, std::move(uuid), std::move(capabilities));
    _characteristics.push_back(characteristic);

    NSMutableArray<CBMutableCharacteristic*>* nativeCharacteristics = [NSMutableArray arrayWithCapacity:_characteristics.size()];
    for (const auto& item : _characteristics) {
        [nativeCharacteristics addObject:(__bridge CBMutableCharacteristic*)item->underlying()];
    }
    ((__bridge CBMutableService*)_opaque_service).characteristics = nativeCharacteristics;
    peripheral->register_characteristic(characteristic);
    return characteristic;
}

std::vector<std::shared_ptr<CharacteristicBase>> ServiceMac::characteristics() {
    std::scoped_lock lock(_mutex);
    return {_characteristics.begin(), _characteristics.end()};
}

void* ServiceMac::underlying() const { return _opaque_service; }

void ServiceMac::freeze() {
    std::scoped_lock lock(_mutex);
    _frozen = true;
}

void ServiceMac::unfreeze() {
    std::scoped_lock lock(_mutex);
    _frozen = false;
}

}  // namespace SimpleBLE::Local