I am trying to read all the services available and their characteristics value using CoreBluetooth framework from a device.
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral
advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
NSLog(#"Received peripheral : \n%#", peripheral);
NSLog(#"Adv data : %#", advertisementData);
self.activeperipheral=peripheral;
[self.myCentralManager connectPeripheral:peripheral options:nil];
if(peripheral.state==CBPeripheralStateConnected){
peripheral.delegate=self;
NSLog(#"Connected");
}
else
NSLog(#"Not Connected");
NSArray *serviceUUIDs=[advertisementData objectForKey:CBAdvertisementDataServiceUUIDsKey];
for(CBUUID *foundserviceUUIDs in serviceUUIDs){
if([serviceUUIDs containsObject:foundserviceUUIDs]){
NSLog(#"%#",serviceUUIDs);
}
}
}
-(void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{
for(CBService *service in peripheral.services){
[peripheral discoverCharacteristics:nil forService:service];
NSLog(#"Discover Service:%#",service);
}
}
-(void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{
for(CBCharacteristic *characteristic in service.characteristics){
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
self.myCharacteristic=characteristic;
NSLog(#"NotifyValue set on %#",characteristic);
//[peripheral readValueForCharacteristic:myCharacteristic];
}
}
-(void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
if(characteristic.isNotifying)
NSLog(#"Notification began on %#",characteristic);
}
-(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
NSLog(#"%#",characteristic);
// NSLog(#"Characteristic Value Updated");
}
- (int)scanForPeripherals {
NSLog(#"Scanning");
if(self.myCentralManager.state!=CBCentralManagerStatePoweredOn)
NSLog(#"Turn on Bluetooth");
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:NO], CBCentralManagerScanOptionAllowDuplicatesKey,
nil];
NSLog(#"Scanning");
[myCentralManager scanForPeripheralsWithServices:nil options:options];
return 0;
}
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
NSLog(#"Peripheral Connected");
peripheral.delegate=self;
//CBUUID *serviceUUID=[CBUUID UUIDWithString:#"1804"];
[peripheral discoverServices:nil];
//[myCentralManager stopScan];
}
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
NSLog(#"didDisconnectPeripheral");
}
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
NSLog(#"failed to connect");
}
- (void)peripheral:(CBPeripheral *)peripheral didReadRSSI:(NSNumber *)RSSI error:(NSError *)error {
NSLog(#"didReadRSSI");
}
#end
The problem is I cannot setNotifyValue : Yes for other characteristics except the BatteryLevel characteristic and I am also getting the notification for the same only.
Here is my output.
Any idea what am I doing wrong here?
Thanks
That because your characteristic settings in gatt file (your bluetooth project) is not properly setup. See for example another characteristic settings and update your gatt file.
Another way to get characteristic value use a timer in which read your charackteristic:
-(void)TimerFunction
{
[talking_peripher readValueForCharacteristic:_talk_charack];
NSlog("VALUE: %#" _talk_charack);
}
And that is all. But actually best to do - modify your characteristic settings in gatt file (bluetooth project).
Related
I need to edit the advertisement data of bluetooth peripheral from central manager.
i tried a lot..
The following code provides the details :
1.After the Peripheral connection:
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
NSLog(#"Connection successfull to peripheral: %#",peripheral);
peripheral.delegate = self;
[peripheral discoverServices:nil];
//Do somenthing after successfull connection.
}
2.Discovering Services:
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
for (CBService *service in peripheral.services) {
NSLog(#"Discovering characteristics for service %#", service);
[peripheral discoverCharacteristics:nil forService:service];
}
}
3.Discovering characteristics from service:
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error {
for (CBCharacteristic *characteristic in service.characteristics) {
if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:#"B0702880-A295-A8AB-F734-031A98A512DE"]]) {
[peripheral readValueForCharacteristic:characteristic];
NSLog(#"Reading value for characteristic %#", characteristic);
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
}
}
4.Updating Notification State:
- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
NSLog(#"characteristic.properties--------------------->%lu",(unsigned long)characteristic.properties);
if (error) {
NSLog(#"Error changing notification state: %#",[error localizedDescription]);
}
// Notification has started
if (characteristic.isNotifying) {
NSLog(#"Notification began on %#", characteristic);
}
NSString* decodeString = #"teststring";
NSData *encodeData = [decodeString dataUsingEncoding:NSUTF8StringEncoding];
NSLog(#"to write----- %#",encodeData);
if ((characteristic.properties & CBCharacteristicPropertyWrite) ||
(characteristic.properties & CBCharacteristicPropertyWriteWithoutResponse))
{
[peripheral writeValue:encodeData forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
}
else
{
NSLog(#"Not permit to write");
}
}
5.Update Write value in Peripheral:
- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
if (error) {
NSLog(#"Error writing characteristic value: %#",[error localizedDescription]);
}
NSData *data = characteristic.value;
NSLog(#"FinalData:%#",data);
}
i am new to IOS.Helps are appreciated
thanks in advance..
There is no general way of setting advertising data on the peripheral from the central. If you want to do something like this you either have to implement the feature on the peripheral (through a purpose made GATT Service), or this feature is offered by the product somehow.
Also note that advertising is a link layer (LL) feature, and those are normally not exposed by iOS. The iOS APIs for BLE is GAP/GATT level.
I have a BLE device (obd2 dongle) that I want to connect to. I can pair with it through "settings" but I can't discover it via didDiscoverPeripheral delegate method , any help ?
- (void)viewDidLoad {
[super viewDidLoad];
_centralManager =[[CBCentralManager alloc]initWithDelegate:self queue:nil];
[self scan];
}
-(void)scan {
NSDictionary *options1 =#{ CBCentralManagerScanOptionAllowDuplicatesKey : #YES };
[_centralManager scanForPeripheralsWithServices:nil options:options1];
}
-(void)centralManagerDidUpdateState:(CBCentralManager *)central{
if (central.state == CBCentralManagerStatePoweredOn) {
[self scan];
}
}
-(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI {
[peripheral readRSSI];
[central connectPeripheral:peripheral options:nil];
}
-(void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
CBPeripheral *peripheral1 =peripheral;
NSLog(#"peripheral1 name = %#",peripheral1.name); peripheral.delegate=self;
[peripheral discoverServices:nil];
}
I want to use BLE device for IOS which has on/off lights & coloured lights. I am connecting bluetooth using core bluetooth framework.
Now i want on/off or change colour of lights. How to do this from central as app to peripheral as bluetooth device, what are all methods required to do this function ?
1) Scan with nil service id (if you are using in background you would need service id)
2) Scan
[self.centralManager scanForPeripheralsWithServices:nil
options:nil];
3) You would get devices in this delegate method
- (void) centralManager:(CBCentralManager *)central
didDiscoverPeripheral:(CBPeripheral *)peripheral
advertisementData:(NSDictionary *)advertisementData
RSSI:(NSNumber *)RSSI {
// check advertisementData for service UUID
[self.centralManager connectPeripheral:peripheral options:nil];
}
4) on successful Connection
- (void) centralManager:(CBCentralManager *)central
didConnectPeripheral:(CBPeripheral *)peripheral {
[peripheral discoverServices:nil];
}
5) on services discoverd
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
if (error) {
NSLog(#"Error discovering services: %#", [error localizedDescription]);
return;
}
// Discover the characteristic we want...
// Loop through the newly filled peripheral.services array, just in case there's more than one.
for (CBService *service in peripheral.services) {
[peripheral discoverCharacteristics:nil forService:service];
}
}
6) on retrieving charactesicts
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error {
// Deal with errors (if any)
if (error) {
NSLog(#"Error discovering characteristics: %#", [error localizedDescription]);
return;
}
// Again, we loop through the array, just in case.
for (CBCharacteristic *characteristic in service.characteristics) {
// And check if it's the right one
if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:#"FFF1"]]) {
scannedcharacteristic = characteristic;
NSString *str = writeValue.length == 0 ? #"z" : writeValue;
DDLogVerbose(#"Writing value %#", str);
NSData *expectedData = [str dataUsingEncoding:NSUTF8StringEncoding];
[peripheral writeValue:expectedData forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
}
// [peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
}
I'm pulling my hair out of this problems. I'm trying to connect to BLE devices, can't see what I've done wrong in my code below.
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_cm = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
+ (NSString*)UUIDString:(CFUUIDRef)uuid {
CFStringRef string = CFUUIDCreateString(NULL, uuid);
return (__bridge_transfer NSString*)string;
}
- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
if (central.state == CBCentralManagerStatePoweredOn) {
[self scanForPeripherals];
}
}
- (void)centralManager:(CBCentralManager *)central
didDiscoverPeripheral:(CBPeripheral *)peripheral
advertisementData:(NSDictionary *)advertisementData
RSSI:(NSNumber *)RSSI {
// NSLog(#"Received peripheral : \n%#", peripheral);
// NSLog(#"Adv data : %#", advertisementData);
[peripheral setDelegate:self];
[central connectPeripheral:peripheral options:nil];
[peripheral readRSSI];
}
- (int)scanForPeripherals {
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:NO], CBCentralManagerScanOptionAllowDuplicatesKey,
nil];
[_cm scanForPeripheralsWithServices:nil options:options];
return 0;
}
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
NSLog(#"didConnectPeripheral");
}
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
NSLog(#"didDisconnectPeripheral");
}
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
NSLog(#"failed to connect");
}
- (void)peripheral:(CBPeripheral *)peripheral didReadRSSI:(NSNumber *)RSSI error:(NSError *)error {
NSLog(#"didReadRSSI");
}
These devices are not my own. I don't know its proximity UUID, but as far as I know, It won't be needed in connecting via CoreBluetooth right?
All of the devices are discovered in didDiscoverPeripheral:, in the selector I tried to connect them. But there's nothing comes after that.
Am I to expect a dialog with Pairing Password Request when I called to didDiscoverPeripheral:?
If so I don't see any dialog, why is that?
From apple documents, It clearly stated that after trying to connect to a device you should get a called to either didConnectPeripheral or didFailToConnectPeripher but I got none.
Any thoughts? I've been trying for almost a week now.
Appreciate every helps, thanks.
If you don't somehow retain the peripheral object that is delivered to didDiscoverPeripheral then it is released once this delegate method exits and you won't get a connection.
I suggest adding a property to track discovered peripherals
#property (strong,nonatomic) NSMutableArray *peripherals;
initialise this in viewDidLoad or init
self.peripherals=[NSMutableArray new];
And then add the peripheral to it in didDiscoverPeripheral
-(void) centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
NSLog(#"Discovered peripheral %#",peripheral.identifier.UUIDString);
[self.peripherals addObject:peripheral];
[central connectPeripheral:peripheral options:nil];
}
var peripherals = [CBPeripheral]()
func centralManager(central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String : AnyObject], RSSI: NSNumber) {
peripherals.append(peripheral)
bleManager.connectPeripheral(peripheral, options: nil)
}
This is the Swift version.
I initialize the CBCenteralManager in viewdidload on main queue. First time update state method is called and start scanning for bluetooth devices but didDiscoverPeripheral: delegate method never get called.
Code is :
- (void)viewDidLoad
{
[super viewDidLoad];
self.CM = [[CBCentralManager alloc]initWithDelegate:self queue:nil];
}
-(void)centralManagerDidUpdateState:(CBCentralManager *)central{
if (central.state == CBCentralManagerStatePoweredOn) {
[self.CM scanForPeripheralsWithServices:nil options:nil];
}
}
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral(CBPeripheral*)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
}
-(void)centralManager:(CBCentralManager *)central didRetrievePeripherals:(NSArray *)peripherals{
}
-(void)centralManager:(CBCentralManager *)central didRetrieveConnectedPeripherals:(NSArray *)peripherals{
}
-(void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
}
-(void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
}
-(void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
}