From 84be82bdb438324bc8d8190cf0f0874bcba63bf6 Mon Sep 17 00:00:00 2001 From: Sacha Froment Date: Mon, 29 Oct 2018 16:24:14 +0100 Subject: [PATCH] fix(ble): fix stream close Signed-off-by: Sacha Froment --- core/network/ble/BertyDevice.h | 15 +- core/network/ble/BertyDevice.m | 23 +- core/network/ble/ble.h | 15 +- core/network/ble/ble.m | 506 ++++++++++++++++++++++----------- core/network/ble/conn.go | 82 +++++- core/network/ble/listener.go | 1 + core/network/ble/transport.go | 11 +- 7 files changed, 461 insertions(+), 192 deletions(-) diff --git a/core/network/ble/BertyDevice.h b/core/network/ble/BertyDevice.h index b4646ccb26..5b01e4807a 100644 --- a/core/network/ble/BertyDevice.h +++ b/core/network/ble/BertyDevice.h @@ -18,7 +18,20 @@ @property (nonatomic, readwrite, strong) NSString *peerID; @property (nonatomic, readwrite, strong) NSString *ma; @property (nonatomic, readwrite, assign) BOOL isWaiting; -@property (nonatomic, readwrite, strong) CBPeripheral *peripheral; +@property (atomic, readwrite, assign) BOOL closedSend; +@property (atomic, readwrite, assign) BOOL closed; +@property (atomic, readwrite, assign) BOOL didRdySema; +@property (atomic, readwrite, strong) CBPeripheral *peripheral; +@property (atomic, readwrite, strong) CBService *svc; +@property (atomic, readwrite, strong) CBCharacteristic *writer; +@property (atomic, readwrite, strong) CBCharacteristic *isRdy; +@property (atomic, readwrite, strong) CBCharacteristic *closer; +@property (atomic, readwrite, strong) CBCharacteristic *accepter; +@property (atomic, readwrite, strong) dispatch_semaphore_t writeWaiter; +@property (atomic, readwrite, strong) dispatch_semaphore_t acceptWaiterSema; +@property (atomic, readwrite, strong) dispatch_semaphore_t closerWaiterSema; +@property (atomic, readwrite, strong) dispatch_semaphore_t closerSema; +@property (atomic, readwrite, strong) dispatch_semaphore_t isRdySema; @property (atomic, readwrite, strong) dispatch_semaphore_t connSema; @property (atomic, readwrite, strong) dispatch_semaphore_t svcSema; @property (atomic, readwrite, strong) dispatch_semaphore_t acceptSema; diff --git a/core/network/ble/BertyDevice.m b/core/network/ble/BertyDevice.m index cf8e946d7b..1e3440518d 100644 --- a/core/network/ble/BertyDevice.m +++ b/core/network/ble/BertyDevice.m @@ -16,9 +16,17 @@ - (instancetype)initWithPeripheral:(CBPeripheral *)peripheral { self = [super init]; self.peripheral = peripheral; self.toSend = [[NSMutableArray alloc]init]; + self.closed = NO; self.isWaiting = NO; + self.closedSend = NO; + self.didRdySema = NO; self.connSema = dispatch_semaphore_create(0); + self.closerWaiterSema = dispatch_semaphore_create(0); + self.acceptWaiterSema = dispatch_semaphore_create(0); + self.closerSema = dispatch_semaphore_create(0); + self.writeWaiter = dispatch_semaphore_create(0); self.svcSema = dispatch_semaphore_create(0); + self.isRdySema = dispatch_semaphore_create(0); self.acceptSema = dispatch_semaphore_create(0); self.maSema = dispatch_semaphore_create(0); self.peerIDSema = dispatch_semaphore_create(0); @@ -63,9 +71,11 @@ - (void)write:(NSData *)data { [self.toSend addObject:chunk]; } while (offset < length); } + if (self.isWaiting == NO) { self.isWaiting = YES; - [self.peripheral writeValue:self.toSend[0] forCharacteristic:[self getWriter] type:CBCharacteristicWriteWithResponse]; + [self.peripheral writeValue:self.toSend[0] forCharacteristic:self.writer type:CBCharacteristicWriteWithResponse]; + dispatch_semaphore_wait(self.writeWaiter, DISPATCH_TIME_FOREVER); } } @@ -76,17 +86,20 @@ - (void)popToSend { } if ([self.toSend count] == 0) { self.isWaiting = NO; + dispatch_semaphore_signal(self.writeWaiter); } } } - (void)checkAndWrite { + if (self.closed == YES && self.closedSend == NO) { + self.closedSend = YES; + [self.peripheral writeValue:[[NSData alloc] init] forCharacteristic:self.closer type:CBCharacteristicWriteWithResponse]; + } @synchronized (self.toSend) { if ([self.toSend count] >= 1) { - @synchronized (self.toSend) { - NSData *data = self.toSend[0]; - [self.peripheral writeValue:data forCharacteristic:[self getWriter] type:CBCharacteristicWriteWithResponse]; - } + NSData *data = self.toSend[0]; + [self.peripheral writeValue:data forCharacteristic:self.writer type:CBCharacteristicWriteWithResponse]; } } } diff --git a/core/network/ble/ble.h b/core/network/ble/ble.h index 56c40c74f3..83f89d60e1 100644 --- a/core/network/ble/ble.h +++ b/core/network/ble/ble.h @@ -22,15 +22,14 @@ int dialPeer(char *peerID); char *readPeerID(char *peerID); NSData *Bytes2NSData(void *bytes, int length); void writeNSData(NSData *data, char *ma); +void closeConn(char *ma); +int isClosed(char *ma); @interface BertyCentralManager : NSObject @property (nonatomic, assign) BOOL serviceAdded; -@property (nonatomic, strong) NSMutableDictionary *discoveredDevice; -@property (nonatomic, strong) NSMutableDictionary *peripheralToPeerID; -@property (nonatomic, strong) NSMutableDictionary *peerIDToPeripheral; @property (nonatomic, strong) NSMutableDictionary *bertyDevices; -@property (nonatomic, strong) NSMutableDictionary *acceptSemaphore; +@property (nonatomic, strong) NSMutableDictionary *oldDevices; @property (nonatomic, strong) CBCentralManager *centralManager; @property (nonatomic, strong) CBPeripheralManager *peripheralManager; @property (nonatomic, strong) CBMutableService *bertyService; @@ -38,6 +37,8 @@ void writeNSData(NSData *data, char *ma); @property (nonatomic, strong) CBMutableCharacteristic *maCharacteristic; @property (nonatomic, strong) CBMutableCharacteristic *peerIDCharacteristic; @property (nonatomic, strong) CBMutableCharacteristic *writerCharacteristic; +@property (nonatomic, strong) CBMutableCharacteristic *isRdyCharacteristic; +@property (nonatomic, strong) CBMutableCharacteristic *closerCharacteristic; @property (nonatomic, strong) NSString *ma; @property (nonatomic, strong) NSString *peerID; @property (nonatomic, strong) CBUUID *serviceUUID; @@ -45,15 +46,19 @@ void writeNSData(NSData *data, char *ma); @property (nonatomic, strong) CBUUID *peerUUID; @property (nonatomic, strong) CBUUID *dialUUID; @property (nonatomic, strong) CBUUID *writerUUID; +@property (nonatomic, strong) CBUUID *isRdyUUID; +@property (nonatomic, strong) CBUUID *closerUUID; @property (nonatomic, strong) CBUUID *acceptUUID; @property (nonatomic, strong) NSMutableArray* toSend; +@property (atomic, readwrite, strong) dispatch_semaphore_t centralWaiter; - (void)startAdvertising; - (void)startDiscover; - (instancetype)initWithMa:(NSString *)ma AndPeerID:(NSString *)peerID; - (void)write:(NSData *)data forMa:(NSString *)ma; -- (char *)readPeerID:(NSString *)ma; - (int)dialPeer:(NSString *)peerID; +- (void)close:(NSString *)ma; +- (int)isClosed:(NSString *)ma; @end diff --git a/core/network/ble/ble.m b/core/network/ble/ble.m index 7b9bc985cd..a763ae872d 100644 --- a/core/network/ble/ble.m +++ b/core/network/ble/ble.m @@ -51,20 +51,28 @@ void writeNSData(NSData *data, char *ma) { [bcm write:data forMa: [NSString stringWithUTF8String:ma]]; } -char *readPeerID(char *peerID) { - return [bcm readPeerID:[NSString stringWithUTF8String:peerID]]; -} - int dialPeer(char *peerID) { return [bcm dialPeer:[NSString stringWithUTF8String:peerID]]; } +void closeConn(char *ma) { + [bcm close:[NSString stringWithUTF8String:ma]]; +} + +int isClosed(char *ma) { + return [bcm isClosed:[NSString stringWithUTF8String:ma]]; +} + @implementation BertyCentralManager NSString* const SERVICE_UUID = @"A06C6AB8-886F-4D56-82FC-2CF8610D6663"; NSString* const WRITER_UUID = @"000CBD77-8D30-4EFF-9ADD-AC5F10C2CC1C"; +NSString* const CLOSER_UUID = @"AD127A46-D065-4D72-B15A-EB2B3DA20561"; + +NSString* const IS_READY_UUID = @"D27DE0B5-2170-4C59-9C0B-750C760C74E6"; + NSString* const MA_READER_UUID = @"9B827770-DC72-4C55-B8AE-0870C7AC15A8"; NSString* const PEER_ID_READER_UUID = @"0EF50D30-E208-4315-B323-D05E0A23E6B3"; @@ -77,24 +85,29 @@ - (instancetype)initWithMa:(NSString *)ma AndPeerID:(NSString *)peerID { self.serviceAdded = NO; self.ma = ma; self.peerID = peerID; - self.discoveredDevice = [[NSMutableDictionary alloc] init]; self.bertyDevices = [[NSMutableDictionary alloc] init]; - self.acceptSemaphore = [[NSMutableDictionary alloc] init]; - self.peerIDToPeripheral = [[NSMutableDictionary alloc] init]; + self.oldDevices = [[NSMutableDictionary alloc] init]; self.serviceUUID = [CBUUID UUIDWithString:SERVICE_UUID]; self.maUUID = [CBUUID UUIDWithString:MA_READER_UUID]; self.peerUUID = [CBUUID UUIDWithString:PEER_ID_READER_UUID]; self.writerUUID = [CBUUID UUIDWithString:WRITER_UUID]; self.acceptUUID = [CBUUID UUIDWithString:ACCEPT_UUID]; + self.closerUUID = [CBUUID UUIDWithString:CLOSER_UUID]; + self.isRdyUUID = [CBUUID UUIDWithString:IS_READY_UUID]; self.bertyService = [[CBMutableService alloc] initWithType:self.serviceUUID primary:YES]; self.acceptCharacteristic = [[CBMutableCharacteristic alloc] initWithType:self.acceptUUID properties:CBCharacteristicPropertyRead | CBCharacteristicPropertyWrite value:nil permissions:CBAttributePermissionsReadable | CBAttributePermissionsWriteable]; self.maCharacteristic = [[CBMutableCharacteristic alloc] initWithType:self.maUUID properties:CBCharacteristicPropertyRead value:[ma dataUsingEncoding:NSUTF8StringEncoding] permissions:CBAttributePermissionsReadable]; self.peerIDCharacteristic = [[CBMutableCharacteristic alloc] initWithType:self.peerUUID properties:CBCharacteristicPropertyRead value:[peerID dataUsingEncoding:NSUTF8StringEncoding] permissions:CBAttributePermissionsReadable]; self.writerCharacteristic = [[CBMutableCharacteristic alloc] initWithType:self.writerUUID properties:CBCharacteristicPropertyWrite value:nil permissions:CBAttributePermissionsWriteable]; + self.isRdyCharacteristic = [[CBMutableCharacteristic alloc] initWithType:self.isRdyUUID properties:CBCharacteristicPropertyWrite value:nil permissions:CBAttributePermissionsWriteable]; + self.closerCharacteristic = [[CBMutableCharacteristic alloc] initWithType:self.closerUUID properties:CBCharacteristicPropertyWrite value:nil permissions:CBAttributePermissionsWriteable]; + + self.bertyService.characteristics = @[self.isRdyCharacteristic, self.closerCharacteristic, self.writerCharacteristic, self.acceptCharacteristic, self.maCharacteristic, self.peerIDCharacteristic]; + self.centralWaiter = dispatch_semaphore_create(0); + + self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) options:@{CBCentralManagerOptionShowPowerAlertKey:[NSNumber numberWithBool:YES]}]; + self.peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) options:@{CBPeripheralManagerOptionShowPowerAlertKey:[NSNumber numberWithBool:YES]}]; - self.bertyService.characteristics = @[self.writerCharacteristic, self.acceptCharacteristic, self.maCharacteristic, self.peerIDCharacteristic]; - self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0) options:@{CBCentralManagerOptionShowPowerAlertKey:[NSNumber numberWithBool:YES]}]; - self.peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0) options:@{CBPeripheralManagerOptionShowPowerAlertKey:[NSNumber numberWithBool:YES]}]; self.centralManager.delegate = self; self.peripheralManager.delegate = self; } @@ -107,112 +120,177 @@ - (instancetype)initWithMa:(NSString *)ma AndPeerID:(NSString *)peerID { return self; } +- (void)dispatchCharacteristics:(CBCharacteristic *)characteristic forDevice:(BertyDevice *)device { + if ([characteristic.UUID isEqual:self.maUUID] || [characteristic.UUID isEqual:self.peerUUID]) { + [device.peripheral readValueForCharacteristic:characteristic]; + [self checkUpdateValueCharacteristic:characteristic forDevice:device]; + } else if ([characteristic.UUID isEqual:self.acceptUUID]) { + device.accepter = characteristic; + dispatch_semaphore_signal(device.acceptSema); + } else if ([characteristic.UUID isEqual:self.writerUUID]) { + device.writer = characteristic; + dispatch_semaphore_signal(device.writerSema); + } else if ([characteristic.UUID isEqual:self.closerUUID]) { + device.closer = characteristic; + dispatch_semaphore_signal(device.closerSema); + } else if ([characteristic.UUID isEqual:self.isRdyUUID]) { + device.isRdy = characteristic; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + while (device.didRdySema == NO) { + [device.peripheral writeValue:[[NSData alloc] init] forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse]; + [NSThread sleepForTimeInterval:1.0f]; + } + }); + } +} + - (void)checkDiscoverBertyDeviceCharacteristic:(BertyDevice *)device { - for (CBCharacteristic *characteristic in [self getSvcForPeripheral:device.peripheral].characteristics) { - if ([characteristic.UUID isEqual:self.maUUID] || [characteristic.UUID isEqual:self.peerUUID]) { - [device.peripheral readValueForCharacteristic:characteristic]; - } else if ([characteristic.UUID isEqual:self.acceptUUID]) { - dispatch_semaphore_signal(device.acceptSema); - } else if ([characteristic.UUID isEqual:self.writerUUID]) { - dispatch_semaphore_signal(device.writerSema); + NSArray *needToDiscover = @[self.maUUID, self.peerUUID, self.acceptUUID, self.writerUUID, self.closerUUID, self.isRdyUUID]; + NSArray *toDiscover = [[NSArray alloc] init]; + CBCharacteristic *characteristic; + + for (CBUUID *uuid in needToDiscover) { + characteristic = [self characteristicWithUUID:uuid forServiceUUID:self.serviceUUID inPeripheral:device.peripheral]; + if (characteristic == nil) { + toDiscover = [toDiscover arrayByAddingObject: uuid]; + } else { + [self dispatchCharacteristics:characteristic forDevice:device]; } } + + if (toDiscover.count > 0) { + [device.peripheral discoverCharacteristics:toDiscover + forService:device.svc]; + } } -- (void)checkUpdateValueCharacteristic:(CBCharacteristic *)charact ForDevice:(BertyDevice *)device { - if ([charact.UUID isEqual:self.maUUID]) { +- (void)checkUpdateValueCharacteristic:(CBCharacteristic *)charact forDevice:(BertyDevice *)device { + if ([charact.UUID isEqual:self.maUUID] && charact.value != nil) { + NSLog(@"val ma"); device.ma = [[NSString alloc] initWithData:charact.value encoding:NSUTF8StringEncoding]; dispatch_semaphore_signal(device.maSema); - } else if ([charact.UUID isEqual:self.peerUUID]) { + } else if ([charact.UUID isEqual:self.peerUUID] && charact.value != nil) { + NSLog(@"val peer"); device.peerID = [[NSString alloc] initWithData:charact.value encoding:NSUTF8StringEncoding]; dispatch_semaphore_signal(device.peerIDSema); } } -- (BertyDevice *)newDevice:(CBPeripheral *)peripheral { - BertyDevice *device = [self getDeviceFromPeripheral:peripheral]; - [peripheral setDelegate:self]; +- (void)checkConnectBertyDevice:(BertyDevice *)device { + if (device.peripheral.state == CBPeripheralStateConnected) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + dispatch_semaphore_signal(device.connSema); + }); + } else { + [self.centralManager connectPeripheral:device.peripheral options:nil]; + } +} - if (device == nil) { - device = [[BertyDevice alloc] initWithPeripheral:peripheral]; - @synchronized (self.bertyDevices) { - [self.bertyDevices setObject:device forKey:[peripheral.identifier UUIDString]]; - } +- (void)checkSvcBertyDevice:(BertyDevice *)device { + CBService *service = [self getSvcForPeripheral:device.peripheral]; + NSLog(@"service %@", service); + if (service != nil) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + device.svc = service; + dispatch_semaphore_signal(device.svcSema); + }); + } else { + [device.peripheral discoverServices:@[self.serviceUUID]]; } +} - [self.centralManager connectPeripheral:device.peripheral options:nil]; +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + if ([keyPath isEqualToString:@"state"]) { + NSLog(@"OBJECT OBS %@", object); + return ; + } + [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; +} - // once device we have the device init dispact a block that will wait for the connection - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ +- (BertyDevice *)waiterForDeviceRdy:(BertyDevice *)device { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + [self checkConnectBertyDevice:device]; dispatch_semaphore_wait(device.connSema, DISPATCH_TIME_FOREVER); - [peripheral discoverServices:@[self.serviceUUID]]; + NSLog(@"device conn released"); + [self checkSvcBertyDevice:device]; + NSLog(@"device svc disco launched"); dispatch_semaphore_wait(device.svcSema, DISPATCH_TIME_FOREVER); + NSLog(@"device svc released"); // once service is disco asked for charact retrieve - [device.peripheral discoverCharacteristics:@[self.peerUUID, self.maUUID, self.writerUUID, self.acceptUUID] - forService:[self getSvcForPeripheral:device.peripheral]]; + [self checkDiscoverBertyDeviceCharacteristic:device]; dispatch_group_t group = dispatch_group_create(); - dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ + dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ dispatch_semaphore_wait(device.writerSema, DISPATCH_TIME_FOREVER); + NSLog(@"READ writerSema %@", device); }); - dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ + dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ dispatch_semaphore_wait(device.acceptSema, DISPATCH_TIME_FOREVER); + NSLog(@"READ acceptSema %@", device); }); - dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ + dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ dispatch_semaphore_wait(device.maSema, DISPATCH_TIME_FOREVER); + NSLog(@"READ maSema %@", device); }); - dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ + dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ dispatch_semaphore_wait(device.peerIDSema, DISPATCH_TIME_FOREVER); + NSLog(@"READ peerIDSema %@", device); + }); + dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + dispatch_semaphore_wait(device.closerSema, DISPATCH_TIME_FOREVER); + NSLog(@"READ cloSema %@", device); + }); + dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + dispatch_semaphore_wait(device.isRdySema, DISPATCH_TIME_FOREVER); + NSLog(@"READ rdySema %@", device); }); dispatch_group_wait(group, DISPATCH_TIME_FOREVER); - NSLog(@"READY device %@", peripheral); + NSLog(@"READY device %@", device.peripheral); AddToPeerStore([device.peerID UTF8String], [device.ma UTF8String]); }); return device; } -- (CBCharacteristic *)getWriterForPeripheral:(CBPeripheral *)peripheral { - return [self characteristicWithUUID:self.writerUUID forServiceUUID:self.serviceUUID inPeripheral:peripheral]; -} - -- (CBCharacteristic *)getAcceptForPeripheral:(CBPeripheral *)peripheral { - return [self characteristicWithUUID:self.acceptUUID forServiceUUID:self.serviceUUID inPeripheral:peripheral]; -} - -- (CBCharacteristic *)getPeerForPeripheral:(CBPeripheral *)peripheral { - return [self characteristicWithUUID:self.peerUUID forServiceUUID:self.serviceUUID inPeripheral:peripheral]; -} +- (BertyDevice *)newDevice:(CBPeripheral *)peripheral { + [peripheral setDelegate:self]; + BertyDevice *device = [[BertyDevice alloc] initWithPeripheral:peripheral]; -- (CBCharacteristic *)getMaForPeripheral:(CBPeripheral *)peripheral { - return [self characteristicWithUUID:self.maUUID forServiceUUID:self.serviceUUID inPeripheral:peripheral]; -} + @synchronized (self.bertyDevices) { + [self.bertyDevices setObject:device forKey:[peripheral.identifier UUIDString]]; + } -- (CBService *)getSvcForPeripheral:(CBPeripheral *)peripheral { - return [self serviceWithUUID:self.serviceUUID forPeripheral:peripheral]; + [peripheral addObserver:self forKeyPath:@"state" options:0 context:nil]; + [self waiterForDeviceRdy:device]; + return device; } -- (int)dialPeer:(NSString *)peerID { - BertyDevice *device = nil; - while (device == nil) { - device = [self getDeviceFromPeerID:peerID]; - if (device != nil) { - NSLog(@"device123 waaaaaaaait %@", device); - // [device waitDeviceRdy]; - dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); - [self.acceptSemaphore setObject:semaphore forKey:device.peripheral.identifier]; - NSLog(@"device123Found %@", device); - CBCharacteristic *charact = nil; - while (charact == nil) { - NSLog(@"device123Found"); - charact = [self getAcceptForPeripheral:device.peripheral]; - } - [device.peripheral writeValue:[[NSData alloc] init] forCharacteristic:charact type:CBCharacteristicWriteWithResponse]; - dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); - dispatch_release(semaphore); - return 1; +- (int)dialPeer:(NSString *)ma { + BertyDevice *device = [self getDeviceFromMa:ma]; + NSLog(@"DIAL PEER %@", ma); + if (device == nil) { + __block NSString *identifier; + @synchronized (self.oldDevices) { + identifier = [self.oldDevices objectForKey:ma]; } + NSArray *peripherals = [self.centralManager retrievePeripheralsWithIdentifiers:@[ + [CBUUID UUIDWithString:identifier] + ] + ]; + if (peripherals.count == 0) { + return 0; + } + NSLog(@"TRYING TO MAKE NEW PEER %@", peripherals); + device = [self newDevice:peripherals[0]]; + } + if (device != nil) { + NSLog(@"device123Found %@", device); + // [device.peripheral writeValue:[[NSData alloc] init] forCharacteristic:device.accepter type:CBCharacteristicWriteWithResponse]; + // dispatch_semaphore_wait(device.acceptWaiterSema, DISPATCH_TIME_FOREVER); + return 1; } + return 0; } @@ -221,14 +299,30 @@ - (void)write:(NSData *)data forMa:(NSString *)ma { [device write:data]; } -- (void)sendToAcceptIncomingChannel:(BertyDevice*)device { - sendAcceptToListenerForPeerID([self.ma UTF8String], [device.ma UTF8String], [device.peerID UTF8String]); +- (int)isClosed:(NSString *)ma { + BertyDevice *device = [self getDeviceFromMa:ma]; + if (device.peripheral.state == CBPeripheralStateConnected) { + return 0; + } + return 1; } -- (char *)readPeerID:(NSString *)ma { - CBCharacteristic *characteristic = [self characteristicWithUUID:self.peerUUID - forServiceUUID:self.serviceUUID inPeripheral:[self.peerIDToPeripheral objectForKey:ma]]; - return [[[NSString alloc] initWithData:characteristic.value encoding:NSUTF8StringEncoding] UTF8String]; +- (void)close:(NSString *)ma { + BertyDevice *device = [self getDeviceFromMa:ma]; + NSLog(@"TRY CLOSING %@ %@", device, [self.centralManager retrieveConnectedPeripheralsWithServices:@[self.serviceUUID]]); + if (device != nil && device.peripheral != nil && device.closed == NO) { + device.closed = YES; + [device checkAndWrite]; + [self removeBertyDevice:device]; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + setConnClosed([device.ma UTF8String]); + }); + dispatch_semaphore_wait(device.closerWaiterSema, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(NSEC_PER_SEC * 10))); + } +} + +- (void)sendToAcceptIncomingChannel:(BertyDevice*)device { + sendAcceptToListenerForPeerID([self.ma UTF8String], [device.ma UTF8String], [device.peerID UTF8String]); } - (void)startAdvertising { @@ -254,7 +348,7 @@ - (CBCharacteristic *)characteristicWithUUID:(CBUUID *)characteristicUUID forSer return nil; } -- (CBService *)serviceWithUUID:(CBUUID *)serviceUUID forPeripheral:(CBPeripheral *)peripheral { +- (nullable CBService *)serviceWithUUID:(CBUUID *)serviceUUID forPeripheral:(CBPeripheral *)peripheral { for (CBService *service in peripheral.services) { if ([service.UUID isEqual:serviceUUID]) { return service; @@ -266,16 +360,24 @@ - (CBService *)serviceWithUUID:(CBUUID *)serviceUUID forPeripheral:(CBPeripheral - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral { - NSLog(@"didConnectPeriheral: %@", [peripheral.identifier UUIDString]); BertyDevice *device = [self getDeviceFromPeripheral:peripheral]; + if (device == nil) { + NSLog(@"didConnectPeripheral: %@", [peripheral.identifier UUIDString]); + [self newDevice:peripheral]; + } + NSLog(@"didConnectPeriheral: %@ %@", [peripheral.identifier UUIDString], device); dispatch_semaphore_signal(device.connSema); } - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error { - [self.bertyDevices removeObjectForKey:[peripheral.identifier UUIDString]]; - NSLog(@"didDisConnectPeriheral: %@", [peripheral.identifier UUIDString]); + BertyDevice *device = [self getDeviceFromPeripheral:peripheral]; + [self removeBertyDevice:device]; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + setConnClosed([device.ma UTF8String]); + }); + NSLog(@"didDisConnectPeriheral: %@ %@", [peripheral.identifier UUIDString], error); } - (void)centralManager:(CBCentralManager *)central @@ -291,6 +393,7 @@ - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI { + [peripheral setDelegate:self]; if (![self getDeviceFromPeripheral:peripheral]) { NSLog(@"didDiscoverPeripheral: %@", [peripheral.identifier UUIDString]); [self newDevice:peripheral]; @@ -312,6 +415,9 @@ - (void)centralManagerDidUpdateState:(CBCentralManager *)central { break; case CBManagerStatePoweredOn: stateString = @"Bluetooth is currently powered on and available to use."; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + dispatch_semaphore_signal(self.centralWaiter); + }); break; default: stateString = @"State unknown, update imminent."; @@ -325,7 +431,7 @@ - (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error { NSLog(@"didDiscoverServices %@", [peripheral.identifier UUIDString]); BertyDevice *device = [self getDeviceFromPeripheral:peripheral]; - dispatch_semaphore_signal(device.svcSema); + [self checkSvcBertyDevice:device]; } - (void)peripheral:(CBPeripheral *)peripheral @@ -358,7 +464,7 @@ - (void)peripheral:(CBPeripheral *)peripheral error:(NSError *)error { NSLog(@"didUpdateValueForCharacteristic %@ %@", [peripheral.identifier UUIDString], [characteristic.UUID UUIDString]); BertyDevice *device = [self getDeviceFromPeripheral:peripheral]; - [self checkUpdateValueCharacteristic:characteristic ForDevice:device]; + [self checkUpdateValueCharacteristic:characteristic forDevice:device]; if (error) { NSLog(@"error: %@", [error localizedDescription]); @@ -377,13 +483,19 @@ - (void)peripheral:(CBPeripheral *)peripheral - (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error { - if ([characteristic.UUID isEqual:self.acceptUUID]) { - dispatch_semaphore_signal([self.acceptSemaphore objectForKey:peripheral.identifier]); + BertyDevice *device = [self getDeviceFromPeripheral:peripheral]; + if (device == nil) { + device = [self newDevice:peripheral]; } - if ([characteristic.UUID isEqual:self.writerUUID]) { - BertyDevice *device = [self getDeviceFromPeripheral:peripheral]; + if ([characteristic.UUID isEqual:self.closerUUID]) { + dispatch_semaphore_signal(device.closerWaiterSema); + } else if ([characteristic.UUID isEqual:self.acceptUUID]) { + dispatch_semaphore_signal(device.acceptWaiterSema); + } else if ([characteristic.UUID isEqual:self.writerUUID]) { [device popToSend]; [device checkAndWrite]; + } else if ([characteristic.UUID isEqual:self.isRdyUUID]) { + device.didRdySema = YES; } if (error) { NSLog(@"error: %@", [error localizedFailureReason]); @@ -426,7 +538,7 @@ - (void)peripheral:(CBPeripheral *)peripheral NSLog(@"didModifyServices %@", invalidatedServices); for (CBService* svc in invalidatedServices) { if ([svc.UUID isEqual:self.serviceUUID]) { - [self.centralManager cancelPeripheralConnection:peripheral]; + // [self.centralManager cancelPeripheralConnection:peripheral force:YES]; } } } @@ -462,9 +574,12 @@ - (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral { break; case CBManagerStatePoweredOn: stateString = @"CBManagerStatePoweredOn"; - if (self.centralManager.state == CBManagerStatePoweredOn && self.serviceAdded == NO) { - self.serviceAdded = YES; - [self.peripheralManager addService:self.bertyService]; + if (self.serviceAdded == NO) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + dispatch_semaphore_wait(self.centralWaiter, DISPATCH_TIME_FOREVER); + self.serviceAdded = YES; + [self.peripheralManager addService:self.bertyService]; + }); } break; default: @@ -475,10 +590,6 @@ - (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral { NSLog(@"State change peripheral manager: %@", stateString); } -- (void)peripheralManager:(CBPeripheralManager *)peripheral - willRestoreState:(NSDictionary *)dict { - NSLog(@"Will restore State invoked"); -} - (void)peripheralManager:(CBPeripheralManager *)peripheral didAddService:(CBService *)service @@ -498,31 +609,12 @@ - (void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral NSLog(@"peripheral start advertising %d", [peripheral isAdvertising]); } -- (void)peripheralManager:(CBPeripheralManager *)peripheral - central:(CBCentral *)central - didSubscribeToCharacteristic:(CBCharacteristic *)characteristic { - NSLog(@"Subscription to characteristic: %@", characteristic.UUID); -} - -- (void)peripheralManager:(CBPeripheralManager *)peripheral - central:(CBCentral *)central - didUnsubscribeFromCharacteristic:(CBCharacteristic *)characteristic { - NSLog(@"Unsubscribed to characteristic: %@", characteristic.UUID); -} - -- (void)peripheralManagerIsReadyToUpdateSubscribers:(CBPeripheralManager *)peripheral { - NSLog(@"peripheralManagerIsReadyToUpdateSubscribers"); -} - - (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveReadRequest:(CBATTRequest *)request { - NSLog(@"REICEVE READ REQ"); if ([request.characteristic.UUID isEqual:self.maUUID]) { request.value = self.maCharacteristic.value; - NSLog(@"REICEVE READ REQ ma"); [self.peripheralManager respondToRequest:request withResult:CBATTErrorSuccess]; } else if ([request.characteristic.UUID isEqual:self.peerUUID]) { - NSLog(@"REICEVE READ REQ peer"); request.value = self.peerIDCharacteristic.value; [self.peripheralManager respondToRequest:request withResult:CBATTErrorSuccess]; } @@ -533,29 +625,59 @@ - (void)peripheralManager:(CBPeripheralManager *)peripheral [self.peripheralManager respondToRequest:request withResult:CBATTErrorInvalidHandle]; } -- (void)peripheralManager:(CBPeripheralManager *)peripheral +- (void)acceptRequest:(CBPeripheralManager *)peripheral + req:(CBATTRequest *)request forDevice:(BertyDevice *)device { + [peripheral respondToRequest:request withResult:CBATTErrorSuccess]; +} + +- (void)writeRequest:(CBPeripheralManager *)peripheral + req:(CBATTRequest *)request forDevice:(BertyDevice *)device { + if (request.value != nil) { + sendBytesToConn([device.ma UTF8String], [request.value bytes], (int)[request.value length]); + } + [peripheral respondToRequest:request withResult:CBATTErrorSuccess]; +} + +- (void)closeRequest:(CBPeripheralManager *)peripheral + req:(CBATTRequest *)request forDevice:(BertyDevice *)device { + device.closedSend = YES; + device.closed = YES; + [self removeBertyDevice:device]; + [peripheral respondToRequest:request withResult:CBATTErrorSuccess]; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + setConnClosed([device.ma UTF8String]); + }); +} + +- (void)isRdyRequest:(CBPeripheralManager *)peripheral + req:(CBATTRequest *)request forDevice:(BertyDevice *)device { + dispatch_semaphore_signal(device.isRdySema); + [peripheral respondToRequest:request withResult:CBATTErrorSuccess]; +} + +- (void)peripheralManager:(CBPeripheralManager *)pm didReceiveWriteRequests:(NSArray *)requests { - // NSLog(@"REQUEST WRITE"); for (CBATTRequest *request in requests) { - if ([request.characteristic.UUID isEqual:self.acceptUUID]) { - [peripheral respondToRequest:request withResult:CBATTErrorSuccess]; - BertyDevice *device = nil; - while (device == nil) { - device = [self getDeviceFromUUID:[request.central.identifier UUIDString]]; + BertyDevice *device = [self + getDeviceFromUUID:[request.central.identifier UUIDString]]; + if (device == nil) { + NSArray *peripherals = [self.centralManager retrievePeripheralsWithIdentifiers:@[request.central.identifier]]; + if (peripherals.count == 0) { + continue; } - // NSLog(@"request ACEEPT"); - // [device wai] - // [self sendToAcceptIncomingChannel:device]; - [peripheral respondToRequest:request withResult:CBATTErrorSuccess]; - } else if ([request.characteristic.UUID isEqual:self.writerUUID]) { - BertyDevice *device = [self getDeviceFromUUID:[request.central.identifier UUIDString]]; - if (request.value != nil) { - sendBytesToConn([device.ma UTF8String], [request.value bytes], (int)[request.value length]); - } - [peripheral respondToRequest:request withResult:CBATTErrorSuccess]; + device = [self newDevice:peripherals[0]]; } - else { - [peripheral respondToRequest:request withResult:CBATTErrorInsufficientAuthorization]; + + if ([request.characteristic.UUID isEqual:self.acceptUUID]) { + [self acceptRequest:pm req:request forDevice:device]; + } else if ([request.characteristic.UUID isEqual:self.writerUUID]) { + [self writeRequest:pm req:request forDevice:device]; + } else if ([request.characteristic.UUID isEqual:self.closerUUID]) { + [self closeRequest:pm req:request forDevice:device]; + } else if ([request.characteristic.UUID isEqual:self.isRdyUUID]) { + [self isRdyRequest:pm req:request forDevice:device]; + } else { + [pm respondToRequest:request withResult:CBATTErrorInsufficientAuthorization]; } } } @@ -564,50 +686,50 @@ - (void)discoverDescriptorsForCharacteristic:(CBCharacteristic *)characteristic NSLog(@"disco for charact %@", characteristic.UUID); } +- (void)removeBertyDevice:(BertyDevice *)device { + @synchronized (self.bertyDevices) { + if ([self.bertyDevices objectForKey:[device.peripheral.identifier UUIDString]]) { + [self.bertyDevices removeObjectForKey:[device.peripheral.identifier UUIDString]]; + } + } + @synchronized (self.oldDevices) { + if (device.ma != nil) { + [self.oldDevices setObject:[device.peripheral.identifier UUIDString] forKey:device.ma]; + } + } +} + - (nullable BertyDevice*)getDeviceFromPeerID:(NSString*)peerID { - dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); __block BertyDevice* device; - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + @synchronized (self.bertyDevices) { for (NSString *key in self.bertyDevices.allKeys) { device = [self.bertyDevices objectForKey:key]; - NSLog(@"FRom peer %@ %@", device.peerID, peerID); - if (device.peerID != nil && [device.peerID isEqual:peerID]) { - dispatch_semaphore_signal(semaphore); - return ; + if (device.peerID != nil && ([device.peerID isEqual:peerID])) { + return device; } - [NSThread sleepForTimeInterval:.5]; } - device = nil; - dispatch_semaphore_signal(semaphore); - }); - dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); - dispatch_release(semaphore); - return device; + } + return nil; } - (nullable BertyDevice*)getDeviceFromMa:(NSString*)ma { - dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); __block BertyDevice* device; - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + @synchronized (self.bertyDevices) { for (NSString *key in self.bertyDevices.allKeys) { device = [self.bertyDevices objectForKey:key]; if (device.ma != nil && [device.ma isEqual:ma]) { - dispatch_semaphore_signal(semaphore); - return ; + return device; } - [NSThread sleepForTimeInterval:.5]; - } - device = nil; - dispatch_semaphore_signal(semaphore); - }); - dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); - dispatch_release(semaphore); - return device; + } + return nil; } -- (BertyDevice*)getDeviceFromPeripheral:(CBPeripheral*)peripheral { - BertyDevice *device = [self.bertyDevices objectForKey:[peripheral.identifier UUIDString]]; +- (nullable BertyDevice*)getDeviceFromPeripheral:(CBPeripheral*)peripheral { + __block BertyDevice *device; + @synchronized (self.bertyDevices) { + device = [self.bertyDevices objectForKey:[peripheral.identifier UUIDString]]; + } if (device != nil) { return device; } @@ -615,11 +737,61 @@ - (BertyDevice*)getDeviceFromPeripheral:(CBPeripheral*)peripheral { } - (nullable BertyDevice*)getDeviceFromUUID:(NSString*)key { - BertyDevice *device = [self.bertyDevices objectForKey:key]; - if (device != nil) { - return device; + __block BertyDevice *device; + @synchronized (self.bertyDevices) { + device = [self.bertyDevices objectForKey:key]; } - return nil; + + return device; +} + +- (CBCharacteristic *)getIsRdyForPeripheral:(CBPeripheral *)peripheral { + return [self characteristicWithUUID:self.isRdyUUID forServiceUUID:self.serviceUUID inPeripheral:peripheral]; +} + +- (CBCharacteristic *)getCloserForPeripheral:(CBPeripheral *)peripheral { + return [self characteristicWithUUID:self.closerUUID forServiceUUID:self.serviceUUID inPeripheral:peripheral]; +} + +- (CBCharacteristic *)getWriterForPeripheral:(CBPeripheral *)peripheral { + return [self characteristicWithUUID:self.writerUUID forServiceUUID:self.serviceUUID inPeripheral:peripheral]; +} + +- (CBCharacteristic *)getAcceptForPeripheral:(CBPeripheral *)peripheral { + return [self characteristicWithUUID:self.acceptUUID forServiceUUID:self.serviceUUID inPeripheral:peripheral]; +} + +- (CBCharacteristic *)getPeerForPeripheral:(CBPeripheral *)peripheral { + return [self characteristicWithUUID:self.peerUUID forServiceUUID:self.serviceUUID inPeripheral:peripheral]; +} + +- (CBCharacteristic *)getMaForPeripheral:(CBPeripheral *)peripheral { + return [self characteristicWithUUID:self.maUUID forServiceUUID:self.serviceUUID inPeripheral:peripheral]; +} + +- (CBService *)getSvcForPeripheral:(CBPeripheral *)peripheral { + return [self serviceWithUUID:self.serviceUUID forPeripheral:peripheral]; +} + +- (void)peripheralManagerIsReadyToUpdateSubscribers:(CBPeripheralManager *)peripheral { + NSLog(@"peripheralManagerIsReadyToUpdateSubscribers"); +} + +- (void)peripheralManager:(CBPeripheralManager *)peripheral + central:(CBCentral *)central + didSubscribeToCharacteristic:(CBCharacteristic *)characteristic { + NSLog(@"Subscription to characteristic: %@", characteristic.UUID); +} + +- (void)peripheralManager:(CBPeripheralManager *)peripheral + central:(CBCentral *)central + didUnsubscribeFromCharacteristic:(CBCharacteristic *)characteristic { + NSLog(@"Unsubscribed to characteristic: %@", characteristic.UUID); +} + +- (void)peripheralManager:(CBPeripheralManager *)peripheral + willRestoreState:(NSDictionary *)dict { + NSLog(@"Will restore State invoked"); } @end diff --git a/core/network/ble/conn.go b/core/network/ble/conn.go index 03f2f9801d..83e789cca9 100644 --- a/core/network/ble/conn.go +++ b/core/network/ble/conn.go @@ -10,6 +10,7 @@ package ble import "C" import ( + "fmt" "time" "unsafe" @@ -19,11 +20,12 @@ import ( smu "github.com/libp2p/go-stream-muxer" ma "github.com/multiformats/go-multiaddr" yamux "github.com/whyrusleeping/yamux" + "go.uber.org/zap" ) type Conn struct { tpt.Conn - opened bool + closed bool transport *Transport lID peer.ID rID peer.ID @@ -35,6 +37,10 @@ type Conn struct { accept chan string } +type ConnForSmux struct { + *Conn +} + var conns map[string]*Conn = make(map[string]*Conn) //export sendBytesToConn @@ -52,9 +58,28 @@ func sendBytesToConn(bleUUID *C.char, bytes unsafe.Pointer, length C.int) { }(goBleUUID, b) } +//export setConnClosed +func setConnClosed(bleUUID *C.char) { + goBleUUID := C.GoString(bleUUID) + if conn, ok := conns[goBleUUID]; ok { + delete(conns, goBleUUID) + conn.closed = true + conn.sess.Close() + } +} + +//export callConnClose +func callConnClose(bleUUID *C.char) { + goBleUUID := C.GoString(bleUUID) + if conn, ok := conns[goBleUUID]; ok { + delete(conns, goBleUUID) + conn.sess.Close() + } +} + func NewConn(transport *Transport, lID, rID peer.ID, lAddr, rAddr ma.Multiaddr, dir int) Conn { conn := Conn{ - opened: true, + closed: false, transport: transport, incoming: make(chan []byte), lID: lID, @@ -64,13 +89,19 @@ func NewConn(transport *Transport, lID, rID peer.ID, lAddr, rAddr ma.Multiaddr, notFinishedToRead: make([]byte, 0), } var err error + connForSmux := ConnForSmux{ + &conn, + } + configDefault := yamux.DefaultConfig() + // configDefault.ConnectionWriteTimeout = 120 * time.Second + // configDefault.KeepAliveInterval = 240 * time.Second if dir == 1 { //server side - conn.sess, err = yamux.Server(&conn, yamux.DefaultConfig()) + conn.sess, err = yamux.Server(&connForSmux, configDefault) } else { // cli side - conn.sess, err = yamux.Client(&conn, yamux.DefaultConfig()) + conn.sess, err = yamux.Client(&connForSmux, configDefault) } if err != nil { panic(err) @@ -96,6 +127,9 @@ func (b *Conn) Read(p []byte) (n int, err error) { } func (b *Conn) Write(p []byte) (n int, err error) { + if b.IsClosed() { + return 0, fmt.Errorf("conn already closed") + } val, err := b.rAddr.ValueForProtocol(PBle) if err != nil { return 0, err @@ -103,6 +137,7 @@ func (b *Conn) Write(p []byte) (n int, err error) { ma := C.CString(val) defer C.free(unsafe.Pointer(ma)) + C.writeNSData( C.Bytes2NSData( unsafe.Pointer(&p[0]), @@ -110,7 +145,6 @@ func (b *Conn) Write(p []byte) (n int, err error) { ), ma, ) - return len(p), nil } @@ -145,21 +179,49 @@ func (b *Conn) Transport() tpt.Transport { func (b *Conn) Close() error { logger().Debug("BLEConn Close") - time.Sleep(10 * time.Second) + b.closed = true + val, err := b.rAddr.ValueForProtocol(PBle) + if err != nil { + logger().Debug("BLEConn close", zap.Error(err)) + return err + } + ma := C.CString(val) + defer C.free(unsafe.Pointer(ma)) + C.closeConn(ma) + return nil +} + +func (b *ConnForSmux) Close() error { + logger().Debug("BLEConnForSmux Close") return nil } func (b *Conn) IsClosed() bool { - logger().Debug("BLEConn IsClosed") - return b.sess.IsClosed() + val, err := b.rAddr.ValueForProtocol(PBle) + if err != nil { + logger().Debug("BLEConn IsClosed", zap.Error(err)) + return true + } + ma := C.CString(val) + defer C.free(unsafe.Pointer(ma)) + + return b.closed } // OpenStream creates a new stream. func (b *Conn) OpenStream() (smu.Stream, error) { - return b.sess.OpenStream() + s, err := b.sess.OpenStream() + if err != nil { + logger().Error("BLEConn OpenStream", zap.Error(err)) + } + return s, err } // AcceptStream accepts a stream opened by the other side. func (b *Conn) AcceptStream() (smu.Stream, error) { - return b.sess.AcceptStream() + s, err := b.sess.AcceptStream() + if err != nil { + logger().Error("BLEConn AcceptStream", zap.Error(err)) + } + return s, err } diff --git a/core/network/ble/listener.go b/core/network/ble/listener.go index bcfbd80463..ad427b190f 100644 --- a/core/network/ble/listener.go +++ b/core/network/ble/listener.go @@ -70,6 +70,7 @@ func NewListener(lAddr ma.Multiaddr, hostID peer.ID, t *Transport) *Listener { connected: make(map[string]*Conn), transport: t, } + listeners[t.ID] = listerner return listerner } diff --git a/core/network/ble/transport.go b/core/network/ble/transport.go index b5996bb785..21ac590f32 100644 --- a/core/network/ble/transport.go +++ b/core/network/ble/transport.go @@ -19,7 +19,7 @@ import ( ) /* -#cgo darwin CFLAGS: -x objective-c +#cgo darwin CFLAGS: -x objective-c -Wno-incompatible-pointer-types -Wno-missing-field-initializers -Wno-missing-prototypes -Werror=return-type -Wdocumentation -Wunreachable-code -Wno-implicit-atomic-properties -Werror=deprecated-objc-isa-usage -Wno-objc-interface-ivars -Werror=objc-root-class -Wno-arc-repeated-use-of-weak -Wimplicit-retain-self -Wduplicate-method-match -Wno-missing-braces -Wparentheses -Wswitch -Wunused-function -Wno-unused-label -Wno-unused-parameter -Wunused-variable -Wunused-value -Wempty-body -Wuninitialized -Wconditional-uninitialized -Wno-unknown-pragmas -Wno-shadow -Wno-four-char-constants -Wno-conversion -Wconstant-conversion -Wint-conversion -Wbool-conversion -Wenum-conversion -Wno-float-conversion -Wnon-literal-null-conversion -Wobjc-literal-conversion -Wshorten-64-to-32 -Wpointer-sign -Wno-newline-eof -Wno-selector -Wno-strict-selector-match -Wundeclared-selector -Wdeprecated-implementations -DNS_BLOCK_ASSERTIONS=1 -DOBJC_OLD_DISPATCH_PROTOTYPES=0 #cgo darwin LDFLAGS: -framework Foundation -framework CoreBluetooth #import "ble.h" */ @@ -127,11 +127,14 @@ func (t *Transport) Dial(ctx context.Context, rAddr ma.Multiaddr, p peer.ID) (tp return nil, err } - peerID := C.CString(p.Pretty()) - defer C.free(unsafe.Pointer(peerID)) - go C.dialPeer(peerID) + ma := C.CString(s) + defer C.free(unsafe.Pointer(ma)) + if C.dialPeer(ma) == 0 { + return nil, fmt.Errorf("error dialing ble") + } if conn, ok := conns[s]; ok { + conn.closed = false return conn, nil } c := NewConn(t, t.MySelf.ID(), p, t.lAddr, rAddr, 0)