BabyPeripheralManager.m 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. //
  2. // BabyPeripheralManager.m
  3. // BluetoothStubOnIOS
  4. //
  5. // Created by 刘彦玮 on 15/12/12.
  6. // Copyright © 2015年 刘彦玮. All rights reserved.
  7. //
  8. #import "BabyPeripheralManager.h"
  9. #import "BabyDefine.h"
  10. #define callbackBlock(...) if ([[babySpeaker callback] __VA_ARGS__]) [[babySpeaker callback] __VA_ARGS__ ]
  11. @implementation BabyPeripheralManager {
  12. int PERIPHERAL_MANAGER_INIT_WAIT_TIMES;
  13. int didAddServices;
  14. NSTimer *addServiceTask;
  15. }
  16. - (instancetype)init {
  17. self = [super init];
  18. if (self) {
  19. _localName = @"baby-default-name";
  20. _peripheralManager = [[CBPeripheralManager alloc]initWithDelegate:self queue:nil options:nil];
  21. }
  22. return self;
  23. }
  24. - (BabyPeripheralManager *(^)())startAdvertising {
  25. return ^BabyPeripheralManager *() {
  26. if ([self canStartAdvertising]) {
  27. PERIPHERAL_MANAGER_INIT_WAIT_TIMES = 0;
  28. NSMutableArray *UUIDS = [NSMutableArray array];
  29. for (CBMutableService *s in _services) {
  30. [UUIDS addObject:s.UUID];
  31. }
  32. //启动广播
  33. [_peripheralManager startAdvertising:
  34. @{
  35. CBAdvertisementDataServiceUUIDsKey : UUIDS
  36. ,CBAdvertisementDataLocalNameKey : _localName
  37. }];
  38. }
  39. else {
  40. PERIPHERAL_MANAGER_INIT_WAIT_TIMES++;
  41. if (PERIPHERAL_MANAGER_INIT_WAIT_TIMES > 5) {
  42. BabyLog(@">>>error: 第%d次等待peripheralManager打开任然失败,请检查蓝牙设备是否可用",PERIPHERAL_MANAGER_INIT_WAIT_TIMES);
  43. }
  44. dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 3.0 * NSEC_PER_SEC);
  45. dispatch_after(popTime, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  46. self.startAdvertising();
  47. });
  48. BabyLog(@">>> 第%d次等待peripheralManager打开",PERIPHERAL_MANAGER_INIT_WAIT_TIMES);
  49. }
  50. return self;
  51. };
  52. }
  53. - (BOOL)canStartAdvertising {
  54. if (_peripheralManager.state != CBPeripheralManagerStatePoweredOn) {
  55. return NO;
  56. }
  57. if (didAddServices != _services.count) {
  58. return NO;
  59. }
  60. return YES;
  61. }
  62. - (BOOL)isPoweredOn {
  63. if (_peripheralManager.state != CBPeripheralManagerStatePoweredOn) {
  64. return NO;
  65. }
  66. return YES;
  67. }
  68. - (BabyPeripheralManager *(^)(NSArray *array))addServices {
  69. return ^BabyPeripheralManager*(NSArray *array) {
  70. _services = [NSMutableArray arrayWithArray:array];
  71. [self addServicesToPeripheral];
  72. return self;
  73. };
  74. }
  75. - (void)addServicesToPeripheral {
  76. if ([self isPoweredOn]) {
  77. for (CBMutableService *s in _services) {
  78. [_peripheralManager addService:s];
  79. }
  80. }
  81. else {
  82. [addServiceTask setFireDate:[NSDate distantPast]];
  83. addServiceTask = [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(addServicesToPeripheral) userInfo:nil repeats:NO];
  84. }
  85. }
  86. #pragma mark - peripheralManager delegate
  87. - (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral {
  88. switch (peripheral.state) {
  89. case CBPeripheralManagerStateUnknown:
  90. BabyLog(@">>>CBPeripheralManagerStateUnknown");
  91. break;
  92. case CBPeripheralManagerStateResetting:
  93. BabyLog(@">>>CBPeripheralManagerStateResetting");
  94. break;
  95. case CBPeripheralManagerStateUnsupported:
  96. BabyLog(@">>>CBPeripheralManagerStateUnsupported");
  97. break;
  98. case CBPeripheralManagerStateUnauthorized:
  99. BabyLog(@">>>CBPeripheralManagerStateUnauthorized");
  100. break;
  101. case CBPeripheralManagerStatePoweredOff:
  102. BabyLog(@">>>CBPeripheralManagerStatePoweredOff");
  103. break;
  104. case CBPeripheralManagerStatePoweredOn:
  105. BabyLog(@">>>CBPeripheralManagerStatePoweredOn");
  106. //发送centralManagerDidUpdateState通知
  107. [[NSNotificationCenter defaultCenter]postNotificationName:@"CBPeripheralManagerStatePoweredOn" object:nil];
  108. break;
  109. default:
  110. break;
  111. }
  112. // if([babySpeaker callback] blockOnPeripheralModelDidUpdateState) {
  113. // [currChannel blockOnCancelScan](centralManager);
  114. // }
  115. callbackBlock(blockOnPeripheralModelDidUpdateState)(peripheral);
  116. }
  117. - (void)peripheralManager:(CBPeripheralManager *)peripheral didAddService:(CBService *)service error:(NSError *)error {
  118. didAddServices++;
  119. callbackBlock(blockOnPeripheralModelDidAddService)(peripheral,service,error);
  120. }
  121. - (void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral error:(NSError *)error {
  122. callbackBlock(blockOnPeripheralModelDidStartAdvertising)(peripheral,error);
  123. }
  124. - (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveReadRequest:(CBATTRequest *)request {
  125. callbackBlock(blockOnPeripheralModelDidReceiveReadRequest)(peripheral, request);
  126. }
  127. - (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveWriteRequests:(NSArray *)requests {
  128. callbackBlock(blockOnPeripheralModelDidReceiveWriteRequests)(peripheral,requests);
  129. }
  130. - (void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didSubscribeToCharacteristic:(CBCharacteristic *)characteristic {
  131. callbackBlock(blockOnPeripheralModelDidSubscribeToCharacteristic)(peripheral,central,characteristic);
  132. }
  133. - (void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didUnsubscribeFromCharacteristic:(CBCharacteristic *)characteristic {
  134. callbackBlock(blockOnPeripheralModelDidUnSubscribeToCharacteristic)(peripheral,central,characteristic);
  135. }
  136. @end
  137. void makeCharacteristicToService(CBMutableService *service,NSString *UUID,NSString *properties,NSString *descriptor) {
  138. //paramter for properties
  139. CBCharacteristicProperties prop = 0x00;
  140. if ([properties containsString:@"r"]) {
  141. prop = prop | CBCharacteristicPropertyRead;
  142. }
  143. if ([properties containsString:@"w"]) {
  144. prop = prop | CBCharacteristicPropertyWrite;
  145. }
  146. if ([properties containsString:@"n"]) {
  147. prop = prop | CBCharacteristicPropertyNotify;
  148. }
  149. if (properties == nil || [properties isEqualToString:@""]) {
  150. prop = CBCharacteristicPropertyRead | CBCharacteristicPropertyWrite;
  151. }
  152. CBMutableCharacteristic *c = [[CBMutableCharacteristic alloc]initWithType:[CBUUID UUIDWithString:UUID] properties:prop value:nil permissions:CBAttributePermissionsReadable | CBAttributePermissionsWriteable];
  153. //paramter for descriptor
  154. if (!(descriptor == nil || [descriptor isEqualToString:@""])) {
  155. //c设置description对应的haracteristics字段描述
  156. CBUUID *CBUUIDCharacteristicUserDescriptionStringUUID = [CBUUID UUIDWithString:CBUUIDCharacteristicUserDescriptionString];
  157. CBMutableDescriptor *desc = [[CBMutableDescriptor alloc]initWithType: CBUUIDCharacteristicUserDescriptionStringUUID value:descriptor];
  158. [c setDescriptors:@[desc]];
  159. }
  160. if (!service.characteristics) {
  161. service.characteristics = @[];
  162. }
  163. NSMutableArray *cs = [service.characteristics mutableCopy];
  164. [cs addObject:c];
  165. service.characteristics = [cs copy];
  166. }
  167. void makeStaticCharacteristicToService(CBMutableService *service,NSString *UUID,NSString *descriptor,NSData *data) {
  168. CBMutableCharacteristic *c = [[CBMutableCharacteristic alloc]initWithType:[CBUUID UUIDWithString:UUID] properties:CBCharacteristicPropertyRead value:data permissions:CBAttributePermissionsReadable];
  169. //paramter for descriptor
  170. if (!(descriptor == nil || [descriptor isEqualToString:@""])) {
  171. //c设置description对应的haracteristics字段描述
  172. CBUUID *CBUUIDCharacteristicUserDescriptionStringUUID = [CBUUID UUIDWithString:CBUUIDCharacteristicUserDescriptionString];
  173. CBMutableDescriptor *desc = [[CBMutableDescriptor alloc]initWithType: CBUUIDCharacteristicUserDescriptionStringUUID value:descriptor];
  174. [c setDescriptors:@[desc]];
  175. }
  176. if (!service.characteristics) {
  177. service.characteristics = @[];
  178. }
  179. NSMutableArray *cs = [service.characteristics mutableCopy];
  180. [cs addObject:c];
  181. service.characteristics = [cs copy];
  182. }
  183. CBMutableService* makeCBService(NSString *UUID)
  184. {
  185. CBMutableService *s = [[CBMutableService alloc]initWithType:[CBUUID UUIDWithString:UUID] primary:YES];
  186. return s;
  187. }
  188. NSString * genUUID()
  189. {
  190. CFUUIDRef uuid_ref = CFUUIDCreate(NULL);
  191. CFStringRef uuid_string_ref= CFUUIDCreateString(NULL, uuid_ref);
  192. CFRelease(uuid_ref);
  193. NSString *uuid = [NSString stringWithString:(__bridge NSString*)uuid_string_ref];
  194. CFRelease(uuid_string_ref);
  195. return uuid;
  196. }