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

mac: queue notifications when transmit buffer is full. fixes #6 #7

Merged
merged 1 commit into from
Mar 31, 2025
Merged
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
49 changes: 37 additions & 12 deletions lib/mac/src/ble_peripheral_manager.mm
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
@interface BLEPeripheralManager () <CBPeripheralManagerDelegate>

@property (nonatomic, strong) dispatch_queue_t queue;
@property (nonatomic, strong) NSMutableArray<NSDictionary *> *pendingNotifications;
@property (nonatomic, strong) CBPeripheralManager *peripheralManager;

@end
Expand All @@ -22,12 +23,32 @@ @implementation BLEPeripheralManager
- (instancetype)init {
if (self = [super init]) {
// NSLog(@"-[BLEPeripheralManager init]");

self.queue = dispatch_queue_create("CBqueue", 0);
self.queue = dispatch_queue_create("CBqueue", DISPATCH_QUEUE_SERIAL);
self.pendingNotifications = [NSMutableArray array];
}
return self;
}

- (void)sendNotifications {
while (self.pendingNotifications.count > 0) {
NSDictionary *notification = self.pendingNotifications.firstObject;
NSData *data = notification[@"data"];
CBMutableCharacteristic *characteristic = notification[@"characteristic"];
CBCentral *central = notification[@"central"];

BOOL success = [self.peripheralManager updateValue:data
forCharacteristic:characteristic
onSubscribedCentrals:@[central]];

if (!success) {
break; // Wait until next ready callback
}

// Remove the successfully sent notification
[self.pendingNotifications removeObjectAtIndex:0];
}
}

#pragma mark - API

- (void)start {
Expand Down Expand Up @@ -146,19 +167,22 @@ - (void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *

for (auto it = emitters.begin(); it != emitters.end(); ++it) {
if ([it->first isEqual:uuid]) {
auto cb = [peripheral, central, characteristic](NSData *data) {
NSLog(@"subscription note: %@ %@", data, NSStringFromClass(characteristic.class));

[peripheral updateValue:data
forCharacteristic:characteristic
onSubscribedCentrals:@[central]];
auto cb = [=](NSData *data) {
// NSLog(@"subscription note: %@ %@", data, NSStringFromClass(characteristic.class));

// Dispatch since cb is called from node
dispatch_async(self.queue, ^{
NSDictionary *notification = @{
@"data": data,
@"characteristic": characteristic,
@"central": central
};
[self.pendingNotifications addObject:notification];
[self sendNotifications];
});
};

it->second.Subscribe(central.maximumUpdateValueLength, cb);

if ((characteristic.properties & CBCharacteristicPropertyNotify) == CBCharacteristicPropertyNotify) {

}
}
}
}
Expand Down Expand Up @@ -224,6 +248,7 @@ - (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveWriteReque

- (void)peripheralManagerIsReadyToUpdateSubscribers:(CBPeripheralManager *)peripheral {
// NSLog(@"peripheralManagerIsReadyToUpdateSubscribers");
[self sendNotifications];
}

- (void)peripheralManager:(CBPeripheralManager *)peripheral didPublishL2CAPChannel:(CBL2CAPPSM)PSM error:(nullable NSError *)error {
Expand Down
Loading