Commit 2586b0fb authored by Chengzhao Li's avatar Chengzhao Li
Browse files

- add reliable/unreliable mode from central to peripheral

parent b8478c2f
......@@ -32,7 +32,7 @@
-(Boolean)startBrowsing;
-(void)stopBrowsing;
-(void)invitePeer:(NCMCPeerID*)peerID;
-(void)sendCentralData : (NSData*)data toPerihperal:(NSString*)identifier;
-(void)sendCentralData : (NSData*)data toPerihperal:(NSString*)identifier withMode:(NCMCSessionSendDataMode)mode;
-(void)disconnectToPeripheral:(NSString*) identifier;
......
......@@ -12,7 +12,8 @@
#import "NCMCPeerID+Core.h"
#define TRANSFER_CHARACTERISTIC_MSG_FROM_PERIPHERAL_UUID @"B7020F32-5170-4F62-B078-E5C231B71B3F"
#define TRANSFER_CHARACTERISTIC_MSG_FROM_CENTRAL_UUID @"0E182478-7DC7-43D2-9B52-06FE34B325CE"
#define TRANSFER_CHARACTERISTIC_MSG_FROM_CENTRAL_WITH_RESPONSE_UUID @"0E182478-7DC7-43D2-9B52-06FE34B325CE"
#define TRANSFER_CHARACTERISTIC_MSG_FROM_CENTRAL_WITHOUT_RESPONSE_UUID @"541300E2-99C2-4319-A5B9-98E96053D2C9"
@interface NCMCBluetoothLEManager()
{
......@@ -30,7 +31,8 @@
// peripheral properties
@property (strong, nonatomic) CBPeripheralManager *peripheralManager;
@property (strong, nonatomic) CBMutableCharacteristic *sendCharacteristic;
@property (strong, nonatomic) CBMutableCharacteristic *receiveCharacteristic;
@property (strong, nonatomic) CBMutableCharacteristic *receiveWithResponseCharacteristic;
@property (strong, nonatomic) CBMutableCharacteristic *receiveWithoutResponseCharacteristic;
@property (strong, nonatomic) NSMutableDictionary<NSString*, CBCentral*> *connectedCentrals; // key:UUIDString value:CBCentral
......@@ -38,7 +40,7 @@
@implementation NCMCBluetoothLEManager
@synthesize isCentral, session, concurrentBluetoothLEDelegateQueue, serialDataSendingQueue, centralManager, peripheralManager, sendCharacteristic, receiveCharacteristic, isDeviceReady;
@synthesize isCentral, session, concurrentBluetoothLEDelegateQueue, serialDataSendingQueue, centralManager, peripheralManager, sendCharacteristic, receiveWithResponseCharacteristic, receiveWithoutResponseCharacteristic, isDeviceReady;
static NCMCBluetoothLEManager *_sharedNCMCBluetoothLEManager = nil;
......@@ -174,7 +176,7 @@ static NCMCBluetoothLEManager *_sharedNCMCBluetoothLEManager = nil;
if (data != nil) {
[data clearData];
} else {
data = [[NCMCMessageData alloc]initWithDeviceUUID:uuid];
data = [[NCMCMessageData alloc]initWithDeviceUUID:uuid andIsReliable:YES];
}
[data addData:msgData];
......@@ -309,7 +311,7 @@ static NCMCBluetoothLEManager *_sharedNCMCBluetoothLEManager = nil;
}
}
-(void)sendCentralData : (NSData*)data toPerihperal:(NSString*)identifier
-(void)sendCentralData : (NSData*)data toPerihperal:(NSString*)identifier withMode:(NCMCSessionSendDataMode)mode
{
NCMCPeripheralInfo *info = self.discoveredPeripherals[(NSString*)identifier];
if (info) {
......@@ -318,10 +320,11 @@ static NCMCBluetoothLEManager *_sharedNCMCBluetoothLEManager = nil;
}
NSArray *msgs = [self makeMsg:data byCapability:[info.peripheral maximumWriteValueLengthForType: CBCharacteristicWriteWithResponse]];
Boolean isReliable = ((mode == NCMCSessionSendDataReliable) ? YES : NO);
dispatch_async(self.serialDataSendingQueue, ^{
for (NSData *msg in msgs) {
NCMCMessageData *msgData = [[NCMCMessageData alloc]initWithDeviceUUID:info.peripheral.identifier.UUIDString];
NCMCMessageData *msgData = [[NCMCMessageData alloc]initWithDeviceUUID:info.peripheral.identifier.UUIDString andIsReliable:isReliable];
[msgData addData:msg];
[dataToSend addObject:msgData];
}
......@@ -341,8 +344,14 @@ static NCMCBluetoothLEManager *_sharedNCMCBluetoothLEManager = nil;
for (NCMCMessageData *data in dataToSend){
NCMCPeripheralInfo *info = self.discoveredPeripherals[[data deviceUUID]];
if (info != nil) {
[info.peripheral writeValue:[data data] forCharacteristic:info.writeCharacteristic type:CBCharacteristicWriteWithResponse];
NSLog(@"sendDataToClients dataSize = %lu", (unsigned long)[data data].length);
if ([data isReliable]) {
[info.peripheral writeValue:[data data] forCharacteristic:info.writeWithResponseCharacteristic type:CBCharacteristicWriteWithResponse];
NSLog(@"sendDataToClients reliable dataSize = %lu", (unsigned long)[data data].length);
} else {
[info.peripheral writeValue:[data data] forCharacteristic:info.writeWithoutResponseCharacteristic type:CBCharacteristicWriteWithoutResponse];
NSLog(@"sendDataToClients unreliable dataSize = %lu", (unsigned long)[data data].length);
}
}
}
......@@ -387,7 +396,8 @@ static NCMCBluetoothLEManager *_sharedNCMCBluetoothLEManager = nil;
NCMCPeripheralInfo *info = [[NCMCPeripheralInfo alloc]init];
info.peripheral = peripheral;
info.readCharacteristic = nil;
info.writeCharacteristic = nil;
info.writeWithResponseCharacteristic = nil;
info.writeWithoutResponseCharacteristic = nil;
info.name = name;
self.discoveredPeripherals[peripheral.identifier.UUIDString] = info;
peripheral.delegate = self;
......@@ -474,7 +484,7 @@ static NCMCBluetoothLEManager *_sharedNCMCBluetoothLEManager = nil;
for (CBService *service in peripheral.services)
{
[peripheral discoverCharacteristics:@[[CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_MSG_FROM_PERIPHERAL_UUID], [CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_MSG_FROM_CENTRAL_UUID]] forService:service];
[peripheral discoverCharacteristics:@[[CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_MSG_FROM_PERIPHERAL_UUID], [CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_MSG_FROM_CENTRAL_WITH_RESPONSE_UUID], [CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_MSG_FROM_CENTRAL_WITHOUT_RESPONSE_UUID]] forService:service];
}
}
......@@ -498,7 +508,8 @@ static NCMCBluetoothLEManager *_sharedNCMCBluetoothLEManager = nil;
}
BOOL isReadCharFound = NO;
BOOL isWriteCharFoud = NO;
BOOL isWriteWithResponseCharFoud = NO;
BOOL isWriteWithoutResponseCharFoud = NO;
for (CBCharacteristic *characteristic in service.characteristics)
{
......@@ -509,17 +520,23 @@ static NCMCBluetoothLEManager *_sharedNCMCBluetoothLEManager = nil;
isReadCharFound = YES;
}
if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_MSG_FROM_CENTRAL_UUID]])
if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_MSG_FROM_CENTRAL_WITH_RESPONSE_UUID]])
{
info.writeCharacteristic = characteristic;
isWriteCharFoud = YES;
info.writeWithResponseCharacteristic = characteristic;
isWriteWithResponseCharFoud = YES;
}
if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_MSG_FROM_CENTRAL_WITHOUT_RESPONSE_UUID]])
{
info.writeWithoutResponseCharacteristic = characteristic;
isWriteWithoutResponseCharFoud = YES;
}
}
#if __CC_PLATFORM_IOS
NSLog(@"peripheral maxResponse : %lu , maxNoResponse : %lu", (unsigned long)[peripheral maximumWriteValueLengthForType: CBCharacteristicWriteWithResponse], (unsigned long)[peripheral maximumWriteValueLengthForType: CBCharacteristicWriteWithoutResponse]);
#endif
NCMCPeerID* peerID = [[NCMCPeerID alloc]initWithDisplayName:info.name andIdentifier:peripheral.identifier.UUIDString];
if (isReadCharFound && isWriteCharFoud) {
if (isReadCharFound && isWriteWithResponseCharFoud && isWriteWithoutResponseCharFoud) {
// send central info to peripheral and wait for perpheral confirm the connection
if (self.session != nil) {
[self.session sendCentralConnectionRequestToPeer:peerID];
......@@ -632,7 +649,7 @@ static NCMCBluetoothLEManager *_sharedNCMCBluetoothLEManager = nil;
dispatch_async(self.serialDataSendingQueue, ^{
for (NSData *msg in msgs) {
NCMCMessageData *msgData = [[NCMCMessageData alloc]initWithDeviceUUID:identifier];
NCMCMessageData *msgData = [[NCMCMessageData alloc]initWithDeviceUUID:identifier andIsReliable:YES];
[msgData addData:msg];
[dataToSend addObject:msgData];
}
......@@ -691,11 +708,13 @@ static NCMCBluetoothLEManager *_sharedNCMCBluetoothLEManager = nil;
if (peripheral.state == CBPeripheralManagerStatePoweredOn && self.session != nil) {
self.sendCharacteristic = [[CBMutableCharacteristic alloc] initWithType:[CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_MSG_FROM_PERIPHERAL_UUID] properties:CBCharacteristicPropertyNotify | CBCharacteristicPropertyRead value:nil permissions:CBAttributePermissionsReadable];
self.receiveCharacteristic = [[CBMutableCharacteristic alloc] initWithType:[CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_MSG_FROM_CENTRAL_UUID] properties:CBCharacteristicPropertyWrite value:nil permissions:CBAttributePermissionsWriteable];
self.receiveWithResponseCharacteristic = [[CBMutableCharacteristic alloc] initWithType:[CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_MSG_FROM_CENTRAL_WITH_RESPONSE_UUID] properties:CBCharacteristicPropertyWrite value:nil permissions:CBAttributePermissionsWriteable];
self.receiveWithoutResponseCharacteristic = [[CBMutableCharacteristic alloc] initWithType:[CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_MSG_FROM_CENTRAL_WITHOUT_RESPONSE_UUID] properties:CBCharacteristicPropertyWriteWithoutResponse value:nil permissions:CBAttributePermissionsWriteable];
CBMutableService *transferService = [[CBMutableService alloc] initWithType:[CBUUID UUIDWithString:self.session.serviceID] primary:YES];
transferService.characteristics = @[self.sendCharacteristic, self.receiveCharacteristic];
transferService.characteristics = @[self.sendCharacteristic, self.receiveWithResponseCharacteristic, receiveWithoutResponseCharacteristic];
[self.peripheralManager addService:transferService];
......@@ -740,13 +759,13 @@ static NCMCBluetoothLEManager *_sharedNCMCBluetoothLEManager = nil;
- (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveWriteRequests:(NSArray<CBATTRequest *> *)requests
{
for (CBATTRequest *request in requests) {
if ([request.characteristic.UUID isEqual:[CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_MSG_FROM_CENTRAL_UUID]]) {
if ([request.characteristic.UUID isEqual:[CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_MSG_FROM_CENTRAL_WITH_RESPONSE_UUID]]) {
[peripheral respondToRequest:request withResult:CBATTErrorSuccess];
//NSLog(@"peripheralManager receive data length %u", request.value.length);
NSMutableString *identifier = [NSMutableString stringWithString:request.central.identifier.UUIDString];
[self processMsg:request.value from:identifier];
//NSLog(@"peripheralManager receive response data length %u", request.value.length);
}
NSMutableString *identifier = [NSMutableString stringWithString:request.central.identifier.UUIDString];
[self processMsg:request.value from:identifier];
}
}
// end CBPeripheralManagerDelegate
......
......@@ -11,8 +11,9 @@
@interface NCMCMessageData : NSObject
@property(strong, nonatomic) NSString *deviceUUID;
@property(strong, nonatomic) NSMutableData *data;
@property(assign, nonatomic) Boolean isReliable;
-(instancetype)initWithDeviceUUID:(NSString*)uuid;
-(instancetype)initWithDeviceUUID:(NSString*)uuid andIsReliable:(Boolean) reliable;
-(void)addData:(NSData*)d;
-(void)clearData;
@end
......@@ -11,13 +11,15 @@
@implementation NCMCMessageData
@synthesize deviceUUID;
@synthesize data;
@synthesize isReliable;
-(instancetype)initWithDeviceUUID:(NSString *)uuid
-(instancetype)initWithDeviceUUID:(NSString *)uuid andIsReliable:(Boolean) reliable
{
self = [super init];
if (self) {
self.deviceUUID = uuid;
self.isReliable = reliable;
self.data = [[NSMutableData alloc]init];
}
......
......@@ -12,6 +12,7 @@
@interface NCMCPeripheralInfo : NSObject
@property(strong, nonatomic)CBPeripheral *peripheral;
@property (strong, nonatomic) CBCharacteristic *readCharacteristic;
@property (strong, nonatomic) CBCharacteristic *writeCharacteristic;
@property (strong, nonatomic) CBCharacteristic *writeWithResponseCharacteristic;
@property (strong, nonatomic) CBCharacteristic *writeWithoutResponseCharacteristic;
@property(strong, nonatomic)NSString *name;
@end
......@@ -9,5 +9,5 @@
#import "NCMCPeripheralInfo.h"
@implementation NCMCPeripheralInfo
@synthesize peripheral, name, readCharacteristic, writeCharacteristic;
@synthesize peripheral, name, readCharacteristic, writeWithResponseCharacteristic, writeWithoutResponseCharacteristic;
@end
......@@ -14,6 +14,11 @@ typedef NS_ENUM (NSInteger, NCMCSessionState) {
NCMCSessionStateConnected // connected to the session
};
typedef NS_ENUM (NSInteger, NCMCSessionSendDataMode) {
NCMCSessionSendDataReliable, // guaranteed reliable and in-order delivery
NCMCSessionSendDataUnreliable // sent immediately without queuing, no guaranteed delivery
};
@protocol NCMCSessionDelegate;
NS_ASSUME_NONNULL_BEGIN
......@@ -27,7 +32,7 @@ NS_ASSUME_NONNULL_BEGIN
-(void)disconnect;
-(void)sendData:(NSData *)data toPeers:(NSArray<NCMCPeerID *> *)peerIDs;
-(void)sendData:(NSData *)data toPeers:(NSArray<NCMCPeerID *> *)peerIDs withMode:(NCMCSessionSendDataMode)mode;
-(NSArray<NCMCPeerID*>*)getConnectedPeers;
......
......@@ -44,12 +44,12 @@ typedef enum NCMCSystemMessageType {
[self.connectedDevices removeAllObjects];
}
-(void)sendData:(NSData *)data toPeers:(NSArray<NCMCPeerID *> *)peerIDs
-(void)sendData:(NSData *)data toPeers:(NSArray<NCMCPeerID *> *)peerIDs withMode:(NCMCSessionSendDataMode)mode
{
for (NCMCPeerID* peerID in peerIDs) {
NSData* msg = [self packUserMessage:data withTargetPeerID:peerID];
if ([[NCMCBluetoothLEManager instance]isCentral]) {
[[NCMCBluetoothLEManager instance] sendCentralData:msg toPerihperal:peerID.identifier];
[[NCMCBluetoothLEManager instance] sendCentralData:msg toPerihperal:peerID.identifier withMode:mode];
} else {
[[NCMCBluetoothLEManager instance] sendPeriheralData:msg toCentral: [self getCentralDeviceIdentifier]];
}
......@@ -100,7 +100,7 @@ typedef enum NCMCSystemMessageType {
for (NCMCDeviceInfo *info in enmuerator) {
if (info.uniqueID != 0) {
[[NCMCBluetoothLEManager instance] sendCentralData:sysData toPerihperal:info.identifier];
[[NCMCBluetoothLEManager instance] sendCentralData:sysData toPerihperal:info.identifier withMode:NCMCSessionSendDataReliable];
}
}
}
......@@ -239,7 +239,7 @@ typedef enum NCMCSystemMessageType {
NSData* sysData = [self packSystemMessageWithType:CENTRA_PERIPHERAL_CONNECTION_REQUEST andMessage:centralDeviceData];
[[NCMCBluetoothLEManager instance] sendCentralData:sysData toPerihperal:peerID.identifier];
[[NCMCBluetoothLEManager instance] sendCentralData:sysData toPerihperal:peerID.identifier withMode:NCMCSessionSendDataReliable];
}
void(^myInvitationHandler)(BOOL, NCMCSession*, NCMCPeerID*) = ^(BOOL accept, NCMCSession* session, NCMCPeerID *peerID) {
......@@ -314,14 +314,14 @@ void(^myInvitationHandler)(BOOL, NCMCSession*, NCMCPeerID*) = ^(BOOL accept, NCM
NSData* sysData = [self packSystemMessageWithType:CENTRA_PERIPHERAL_ASSIGN_IDENTIFIER andMessage:deviceData];
[[NCMCBluetoothLEManager instance] sendCentralData:sysData toPerihperal:identifier];
[[NCMCBluetoothLEManager instance] sendCentralData:sysData toPerihperal:identifier withMode:NCMCSessionSendDataReliable];
// update new connected device info to all connected periherals
NSData* sysBroadcastNewDeviceData = [self packSystemMessageWithType:CENTRA_PERIPHERAL_DEVICE_CONNECTED andMessage:deviceData];
for (NSString *key in self.connectedDevices) {
NCMCDeviceInfo* peripheralDeviceInfo = self.connectedDevices[key];
if (peripheralDeviceInfo.uniqueID != 0) {
[[NCMCBluetoothLEManager instance] sendCentralData:sysBroadcastNewDeviceData toPerihperal:peripheralDeviceInfo.identifier];
[[NCMCBluetoothLEManager instance] sendCentralData:sysBroadcastNewDeviceData toPerihperal:peripheralDeviceInfo.identifier withMode:NCMCSessionSendDataReliable];
}
}
......@@ -331,7 +331,7 @@ void(^myInvitationHandler)(BOOL, NCMCSession*, NCMCPeerID*) = ^(BOOL accept, NCM
if (peripheralDeviceInfo.uniqueID != 0) {
NSData* peripheralDeviceData = [self encodeDeviceInfo:peripheralDeviceInfo];
NSData* sysBroadcastData = [self packSystemMessageWithType:CENTRA_PERIPHERAL_DEVICE_CONNECTED andMessage:peripheralDeviceData];
[[NCMCBluetoothLEManager instance] sendCentralData:sysBroadcastData toPerihperal:identifier];
[[NCMCBluetoothLEManager instance] sendCentralData:sysBroadcastData toPerihperal:identifier withMode:NCMCSessionSendDataReliable];
}
}
......@@ -427,7 +427,7 @@ void(^myInvitationHandler)(BOOL, NCMCSession*, NCMCPeerID*) = ^(BOOL accept, NCM
// data from peripheral to peripheral
NCMCDeviceInfo* targetDevice = [self getDeviceInfoByUniqueID:extraInfo];
if (targetDevice != nil) {
[[NCMCBluetoothLEManager instance] sendCentralData:data toPerihperal:targetDevice.identifier];
[[NCMCBluetoothLEManager instance] sendCentralData:data toPerihperal:targetDevice.identifier withMode:NCMCSessionSendDataReliable];
}
}
} else {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment