123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- //
- // 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;
- }
|