Re: Can't discover CBPeripheralManager services
This was a false issue because I had a mistake in the way I was retrieving the services on central side. Not sure whether I should create a new thread about it, but I still can't move forward with using CBPeripheralManager. I am saving a custom service and characteristics in private variabiables and when central discovers them it calls 'setNotifyValue' for the ones which on peripheral device I have given CBCharacteristicPropertyNotify property. On peripheral side didSubscribeToCharacteristic is getting called correctly and in that delegate I start a timer which sends uint16_t type value every 5 seconds. The problem is that on central side didUpdateValueForCharacteristic never gets called. I know that central is setup correctly because I use the same application to connect to another Bluetooth 4.0 accessory, so I assume the issue in on CBPeripheralManager side. What I have noticed is that on didSubscribeToCharacteristic call the characteristic._isNotifying value is always NO. Furthermore updateValue returns me 'YES' twice and then all following calls return 'NO' and peripheralManagerIsReadyToUpdateSubscribers is never called. I have tried all sorts of combinations of properties and attributes when creating the characteristic, but it doesn't seem to have any impact. This is an example: self.periodicNotifChar = [[CBMutableCharacteristic alloc] initWithType:[StUtils UUIDToCBUUID:CHARACTERISTIC_PERIODIC_NOTIF_UUID] properties:CBCharacteristicPropertyNotify value:nil permissions:CBAttributePermissionsReadable And when issuing a notification: BOOL result = [self.peripheralManager updateValue:[@"12" dataUsingEncoding:NSUTF8StringEncoding] forCharacteristic:self.periodicNotifChar onSubscribedCentrals:nil]; if (result) NSLog(@"Interrupting central: success"); else { NSLog(@"Interrupting central: failed"); } The output will always be On Sun, Feb 17, 2013 at 6:45 AM, Andras Kovi <allprog@gmail.com> wrote:
Nice :)
Yes, adding this method should help:
-(void)peripheralManager:(CBPeripheralManager *)peripheral didAddService:(CBService *)service error:(NSError *)error { if (error) { NSLog(@"Service add failed: %@", error); } else { NSLog(@"Service added"); } }
Advertisement will contain the services only if this method indicated the successful addition. Though, you can start advertising right after the addition too.
As a side note: I use ReactiveCocoa everywhere in my code to avoid these kind of choreography issues. Like this:
- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral { [peripheralManagerState sendNext:@([_peripheralManager state])]; }
- (void)centralManagerDidUpdateState:(CBCentralManager *)central { [centralManagerState sendNext:@([_centralManager state])]; }
- (id) init { self = [super init]; if (self != nil) { self.peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:dispatch_get_main_queue()]; self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:dispatch_get_main_queue()];
centralManagerState = [RACSubject subject]; peripheralManagerState = [RACSubject subject];
[[RACSignal zip:@[centralManagerState, peripheralManagerState]] subscribeNext:^(RACTuple *x) { CBCentralManagerState centralState = [x.first intValue]; CBPeripheralManagerState peripheralState = [x.second intValue];
if (centralState == CBCentralManagerStatePoweredOn && peripheralState == CBPeripheralManagerStatePoweredOn) { // Initialize [self initializePeripheralServices]; } ... }]; } return self; }
I'm personally amazed by how powerful this approach is to avoid getting lost in the "forest" of ifs in the delegate callbacks.
Thanks, Andras
On 2013.02.16., at 22:57, Etan Kissling <kissling@oberon.ch> wrote:
Andras
"peripheral" is the default argument name for the [- didUpdateState] delegate method.
There is an additional delegate method [- didAddService:error:] where the source for the issue may be found.
Etan
On 16.02.2013, at 22:25, Andras Kovi <allprog@gmail.com> wrote:
Hi Arvydas,
if you copied your live code here, then I suspect the services are not added to the peripheral manager. Can you change the addService line to send to the peripheralManager instead of the peripheral (which is probably nil thus not causing an error). This is just a suspicion.
Regards, Andras
On 2013.02.16., at 19:43, Arvydas Sidorenko <asido4@gmail.com> wrote:
I am trying CBPeripheralManager on iPad and CBCentralManager on iPhone 4S and I can't make service discovery work.
This is what I do:
In peripheralManagerDidUpdateState when state changes to CBPeripheralManagerStatePoweredOn I add services and start advertising: CBUUID *cUDID = [CBUUID UUIDWithString:@"DA18"]; CBUUID *cUDID1 = [CBUUID UUIDWithString:@"DA17"]; CBUUID *cUDID2 = [CBUUID UUIDWithString:@"DA16"];
CBUUID *sUDID = [CBUUID UUIDWithString:@"DA00"]; characteristic = [[CBMutableCharacteristic alloc]initWithType:cUDID properties:CBCharacteristicPropertyNotify value:nil permissions:CBAttributePermissionsReadable]; characteristic1 = [[CBMutableCharacteristic alloc]initWithType:cUDID1 properties:CBCharacteristicPropertyWrite value:nil permissions:CBAttributePermissionsWriteable]; characteristic2 = [[CBMutableCharacteristic alloc]initWithType:cUDID2 properties:CBCharacteristicPropertyRead value:nil permissions:CBAttributePermissionsReadable]; servicea = [[CBMutableService alloc] initWithType:sUDID primary:YES]; servicea.characteristics = @[characteristic,characteristic1,characteristic2]; [peripheral addService:servicea];
NSDictionary *advertisingData = @{CBAdvertisementDataLocalNameKey : @"peri"}; [self.peripheralManager startAdvertising:advertisingData];
On central device when the device is discovered it establishes connection and when that is done discovers services and service characteristics, but all I can find is Generic Access (0x1800) service with device name characteristics. I tried to run demo applications from other people github where it makes a device advertise with custom services, but I still find the same 0x1800 service only. iPad is running iOS v6.1. Anyone has a clue what is going on? _______________________________________________ Do not post admin requests to the list. They will be ignored. Bluetooth-dev mailing list (Bluetooth-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/bluetooth-dev/allprog%40gmail.com
This email sent to allprog@gmail.com
_______________________________________________ Do not post admin requests to the list. They will be ignored. Bluetooth-dev mailing list (Bluetooth-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/bluetooth-dev/kissling%40oberon.ch
This email sent to kissling@oberon.ch
_______________________________________________ Do not post admin requests to the list. They will be ignored. Bluetooth-dev mailing list (Bluetooth-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/bluetooth-dev/site_archiver%40lists.... This email sent to site_archiver@lists.apple.com
participants (1)
-
Arvydas Sidorenko