Re: Can't discover CBPeripheralManager services
Re: Can't discover CBPeripheralManager services
- Subject: Re: Can't discover CBPeripheralManager services
- From: Arvydas Sidorenko <email@hidden>
- Date: Sun, 17 Feb 2013 11:09:33 +0000
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 <email@hidden> 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 <email@hidden> 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 <email@hidden>
> 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 <email@hidden> 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 (email@hidden)
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden
>
>
>
> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Bluetooth-dev mailing list (email@hidden)
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden
>
>
>
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Bluetooth-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden