You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
234 lines
8.6 KiB
234 lines
8.6 KiB
// |
|
// BabyPeripheralManager.m |
|
// BluetoothStubOnIOS |
|
// |
|
// Created by 刘彦玮 on 15/12/12. |
|
// Copyright © 2015年 刘彦玮. All rights reserved. |
|
// |
|
|
|
#import "BabyPeripheralManager.h" |
|
#import "BabyDefine.h" |
|
|
|
#define callbackBlock(...) if ([[babySpeaker callback] __VA_ARGS__]) [[babySpeaker callback] __VA_ARGS__ ] |
|
|
|
@implementation BabyPeripheralManager { |
|
int PERIPHERAL_MANAGER_INIT_WAIT_TIMES; |
|
int didAddServices; |
|
NSTimer *addServiceTask; |
|
} |
|
|
|
- (instancetype)init { |
|
self = [super init]; |
|
if (self) { |
|
_localName = @"baby-default-name"; |
|
_peripheralManager = [[CBPeripheralManager alloc]initWithDelegate:self queue:nil options:nil]; |
|
} |
|
return self; |
|
} |
|
|
|
|
|
- (BabyPeripheralManager *(^)())startAdvertising { |
|
return ^BabyPeripheralManager *() { |
|
|
|
if ([self canStartAdvertising]) { |
|
PERIPHERAL_MANAGER_INIT_WAIT_TIMES = 0; |
|
NSMutableArray *UUIDS = [NSMutableArray array]; |
|
for (CBMutableService *s in _services) { |
|
[UUIDS addObject:s.UUID]; |
|
} |
|
//启动广播 |
|
[_peripheralManager startAdvertising: |
|
@{ |
|
CBAdvertisementDataServiceUUIDsKey : UUIDS |
|
,CBAdvertisementDataLocalNameKey : _localName |
|
}]; |
|
} |
|
else { |
|
PERIPHERAL_MANAGER_INIT_WAIT_TIMES++; |
|
if (PERIPHERAL_MANAGER_INIT_WAIT_TIMES > 5) { |
|
BabyLog(@">>>error: 第%d次等待peripheralManager打开任然失败,请检查蓝牙设备是否可用",PERIPHERAL_MANAGER_INIT_WAIT_TIMES); |
|
} |
|
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 3.0 * NSEC_PER_SEC); |
|
dispatch_after(popTime, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ |
|
self.startAdvertising(); |
|
}); |
|
BabyLog(@">>> 第%d次等待peripheralManager打开",PERIPHERAL_MANAGER_INIT_WAIT_TIMES); |
|
} |
|
|
|
return self; |
|
}; |
|
} |
|
|
|
- (BOOL)canStartAdvertising { |
|
if (_peripheralManager.state != CBPeripheralManagerStatePoweredOn) { |
|
return NO; |
|
} |
|
if (didAddServices != _services.count) { |
|
return NO; |
|
} |
|
return YES; |
|
} |
|
|
|
- (BOOL)isPoweredOn { |
|
if (_peripheralManager.state != CBPeripheralManagerStatePoweredOn) { |
|
return NO; |
|
} |
|
return YES; |
|
} |
|
|
|
- (BabyPeripheralManager *(^)(NSArray *array))addServices { |
|
return ^BabyPeripheralManager*(NSArray *array) { |
|
_services = [NSMutableArray arrayWithArray:array]; |
|
[self addServicesToPeripheral]; |
|
return self; |
|
}; |
|
} |
|
|
|
- (void)addServicesToPeripheral { |
|
if ([self isPoweredOn]) { |
|
for (CBMutableService *s in _services) { |
|
[_peripheralManager addService:s]; |
|
} |
|
} |
|
else { |
|
[addServiceTask setFireDate:[NSDate distantPast]]; |
|
addServiceTask = [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(addServicesToPeripheral) userInfo:nil repeats:NO]; |
|
} |
|
} |
|
|
|
#pragma mark - peripheralManager delegate |
|
|
|
- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral { |
|
switch (peripheral.state) { |
|
case CBPeripheralManagerStateUnknown: |
|
BabyLog(@">>>CBPeripheralManagerStateUnknown"); |
|
break; |
|
case CBPeripheralManagerStateResetting: |
|
BabyLog(@">>>CBPeripheralManagerStateResetting"); |
|
break; |
|
case CBPeripheralManagerStateUnsupported: |
|
BabyLog(@">>>CBPeripheralManagerStateUnsupported"); |
|
break; |
|
case CBPeripheralManagerStateUnauthorized: |
|
BabyLog(@">>>CBPeripheralManagerStateUnauthorized"); |
|
break; |
|
case CBPeripheralManagerStatePoweredOff: |
|
BabyLog(@">>>CBPeripheralManagerStatePoweredOff"); |
|
break; |
|
case CBPeripheralManagerStatePoweredOn: |
|
BabyLog(@">>>CBPeripheralManagerStatePoweredOn"); |
|
//发送centralManagerDidUpdateState通知 |
|
[[NSNotificationCenter defaultCenter]postNotificationName:@"CBPeripheralManagerStatePoweredOn" object:nil]; |
|
break; |
|
default: |
|
break; |
|
} |
|
|
|
// if([babySpeaker callback] blockOnPeripheralModelDidUpdateState) { |
|
// [currChannel blockOnCancelScan](centralManager); |
|
// } |
|
callbackBlock(blockOnPeripheralModelDidUpdateState)(peripheral); |
|
} |
|
|
|
|
|
- (void)peripheralManager:(CBPeripheralManager *)peripheral didAddService:(CBService *)service error:(NSError *)error { |
|
didAddServices++; |
|
callbackBlock(blockOnPeripheralModelDidAddService)(peripheral,service,error); |
|
} |
|
|
|
- (void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral error:(NSError *)error { |
|
callbackBlock(blockOnPeripheralModelDidStartAdvertising)(peripheral,error); |
|
} |
|
|
|
- (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveReadRequest:(CBATTRequest *)request { |
|
callbackBlock(blockOnPeripheralModelDidReceiveReadRequest)(peripheral, request); |
|
} |
|
|
|
- (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveWriteRequests:(NSArray *)requests { |
|
callbackBlock(blockOnPeripheralModelDidReceiveWriteRequests)(peripheral,requests); |
|
} |
|
|
|
- (void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didSubscribeToCharacteristic:(CBCharacteristic *)characteristic { |
|
callbackBlock(blockOnPeripheralModelDidSubscribeToCharacteristic)(peripheral,central,characteristic); |
|
} |
|
|
|
- (void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didUnsubscribeFromCharacteristic:(CBCharacteristic *)characteristic { |
|
callbackBlock(blockOnPeripheralModelDidUnSubscribeToCharacteristic)(peripheral,central,characteristic); |
|
} |
|
|
|
|
|
@end |
|
|
|
void makeCharacteristicToService(CBMutableService *service,NSString *UUID,NSString *properties,NSString *descriptor) { |
|
|
|
//paramter for properties |
|
CBCharacteristicProperties prop = 0x00; |
|
if ([properties containsString:@"r"]) { |
|
prop = prop | CBCharacteristicPropertyRead; |
|
} |
|
if ([properties containsString:@"w"]) { |
|
prop = prop | CBCharacteristicPropertyWrite; |
|
} |
|
if ([properties containsString:@"n"]) { |
|
prop = prop | CBCharacteristicPropertyNotify; |
|
} |
|
if (properties == nil || [properties isEqualToString:@""]) { |
|
prop = CBCharacteristicPropertyRead | CBCharacteristicPropertyWrite; |
|
} |
|
|
|
CBMutableCharacteristic *c = [[CBMutableCharacteristic alloc]initWithType:[CBUUID UUIDWithString:UUID] properties:prop value:nil permissions:CBAttributePermissionsReadable | CBAttributePermissionsWriteable]; |
|
|
|
//paramter for descriptor |
|
if (!(descriptor == nil || [descriptor isEqualToString:@""])) { |
|
//c设置description对应的haracteristics字段描述 |
|
CBUUID *CBUUIDCharacteristicUserDescriptionStringUUID = [CBUUID UUIDWithString:CBUUIDCharacteristicUserDescriptionString]; |
|
CBMutableDescriptor *desc = [[CBMutableDescriptor alloc]initWithType: CBUUIDCharacteristicUserDescriptionStringUUID value:descriptor]; |
|
[c setDescriptors:@[desc]]; |
|
} |
|
|
|
if (!service.characteristics) { |
|
service.characteristics = @[]; |
|
} |
|
NSMutableArray *cs = [service.characteristics mutableCopy]; |
|
[cs addObject:c]; |
|
service.characteristics = [cs copy]; |
|
} |
|
void makeStaticCharacteristicToService(CBMutableService *service,NSString *UUID,NSString *descriptor,NSData *data) { |
|
|
|
CBMutableCharacteristic *c = [[CBMutableCharacteristic alloc]initWithType:[CBUUID UUIDWithString:UUID] properties:CBCharacteristicPropertyRead value:data permissions:CBAttributePermissionsReadable]; |
|
|
|
//paramter for descriptor |
|
if (!(descriptor == nil || [descriptor isEqualToString:@""])) { |
|
//c设置description对应的haracteristics字段描述 |
|
CBUUID *CBUUIDCharacteristicUserDescriptionStringUUID = [CBUUID UUIDWithString:CBUUIDCharacteristicUserDescriptionString]; |
|
CBMutableDescriptor *desc = [[CBMutableDescriptor alloc]initWithType: CBUUIDCharacteristicUserDescriptionStringUUID value:descriptor]; |
|
[c setDescriptors:@[desc]]; |
|
} |
|
|
|
if (!service.characteristics) { |
|
service.characteristics = @[]; |
|
} |
|
NSMutableArray *cs = [service.characteristics mutableCopy]; |
|
[cs addObject:c]; |
|
service.characteristics = [cs copy]; |
|
} |
|
|
|
|
|
CBMutableService* makeCBService(NSString *UUID) |
|
{ |
|
CBMutableService *s = [[CBMutableService alloc]initWithType:[CBUUID UUIDWithString:UUID] primary:YES]; |
|
return s; |
|
} |
|
|
|
NSString * genUUID() |
|
{ |
|
CFUUIDRef uuid_ref = CFUUIDCreate(NULL); |
|
CFStringRef uuid_string_ref= CFUUIDCreateString(NULL, uuid_ref); |
|
|
|
CFRelease(uuid_ref); |
|
NSString *uuid = [NSString stringWithString:(__bridge NSString*)uuid_string_ref]; |
|
|
|
CFRelease(uuid_string_ref); |
|
return uuid; |
|
} |
|
|
|
|