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.
235 lines
8.6 KiB
235 lines
8.6 KiB
![]()
2 years ago
|
//
|
||
|
// 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;
|
||
|
}
|
||
|
|