program stuck in session.join() - autobahn

I am using a crossbar.io router with the below configuration, the C++ program seems to be stuck in session.join() call.
{
"controller": {
},
"workers": [
{
"type": "router",
"realms": [
{
"name" : "thinqbot",
"permissions": [
{
"uri": "*",
"join" : true,
"publish": true,
"subscribe": true,
"call": true,
"register": true
}
]
}
],
"transports": [
{
"type": "web",
"endpoint":
{
"type": "tcp",
"port": 8080
},
"paths": {
"/": {
"type": "static",
"directory": ".."
},
"ws": {
"type": "websocket"
}
}
},
{
"type": "rawsocket",
"serializer" : "json",
"endpoint":
{
"type": "unix",
"path" : "/home/rk/router.sock"
}
},
{
"type": "rawsocket",
"serializer" : "json",
"endpoint":
{
"type": "tcp",
"port": 8082
}
}
]
}
]
}
Corresponding C++ code.
int
main (int ac, char **av, char **env)
{
try
{
asio::io_service io;
tcp::socket socket(io);
tcp::resolver resolver(io);
auto endpoint_iterator = resolver.resolve({"127.0.0.1", "8082"});
bool debug = true;
autobahn::session<tcp::socket, tcp::socket> session(io, socket, socket, debug);
future<void> session_future;
std::cerr<<"\nTrying to connect to server ...";
boost::asio::async_connect(socket, endpoint_iterator,
[&](boost::system::error_code ec, tcp::resolver::iterator){
if(!ec){
std::cerr << "\nConnected to server" << endl;
session.start();
std::cerr<<"\nSession started.";
session_future = session.join("realm1").then([&](future<uint64_t> s){
std::cerr << "\nSession joined to realm with session ID " << s.get() << endl;
auto c0 = session.call("com.thinqbot.ping")
.then([](future<any> f){
std::cerr<<"\nping() invoked successfully";
});
c0.wait();
auto finish = when_all(std::move(c0));
finish.then([&](decltype(finish)){
session.publish("com.thinqbot.hello");
std::cerr<<"\nhello event published";
session.leave().then([&](future<string> reason){
std::cerr << "\nSession left [" << reason.get() << "]" << endl;
io.stop();
}).wait();
});
});
} else {
std::cerr << "\nCould not connect to server: " << ec.message() << endl;
}
}
);
io.run();
}
catch (std::exception& e)
{
std::cerr << e.what() << endl;
return 1;
}
return 0;
}
logs on the router.
2014-09-15 14:05:31+0530 [Controller 3457] Log opened.
2014-09-15 14:05:31+0530 [Controller 3457] ============================== Crossbar.io ==============================
2014-09-15 14:05:31+0530 [Controller 3457] Crossbar.io 0.9.7-6 starting
2014-09-15 14:05:31+0530 [Controller 3457] Automatically choosing optimal Twisted reactor
2014-09-15 14:05:31+0530 [Controller 3457] Running Twisted reactor twisted.internet.epollreactor.EPollReactor
2014-09-15 14:05:31+0530 [Controller 3457] Running on CPython using EPollReactor reactor
2014-09-15 14:05:31+0530 [Controller 3457] Starting from node directory /home/rk/work/wamp/.crossbar
2014-09-15 14:05:31+0530 [Controller 3457] Starting from local configuration '/home/rk/work/wamp/.crossbar/config.json'
2014-09-15 14:05:31+0530 [Controller 3457] No WAMPlets detected in enviroment.
2014-09-15 14:05:31+0530 [Controller 3457] Starting Router with ID 'worker1' ..
2014-09-15 14:05:31+0530 [Router 3460] Log opened.
2014-09-15 14:05:31+0530 [Router 3460] Running under CPython using EPollReactor reactor
2014-09-15 14:05:31+0530 [Router 3460] Entering event loop ..
2014-09-15 14:05:31+0530 [Controller 3457] Router with ID 'worker1' and PID 3460 started
2014-09-15 14:05:31+0530 [Controller 3457] Router 'worker1': realm 'realm1' started
2014-09-15 14:05:31+0530 [Router 3460] Site starting on 8080
2014-09-15 14:05:31+0530 [Controller 3457] Router 'worker1': transport 'transport1' started
2014-09-15 14:05:31+0530 [Router 3460] CrossbarWampRawSocketServerFactory starting on u'/home/rk/router.sock'
2014-09-15 14:05:31+0530 [Controller 3457] Router 'worker1': transport 'transport2' started
2014-09-15 14:05:31+0530 [Router 3460] CrossbarWampRawSocketServerFactory starting on 8082
2014-09-15 14:05:31+0530 [Controller 3457] Router 'worker1': transport 'transport3' started

There was a serialization mismatch between the client and router, router was expecting json and client was sending msgpack. The serializer needs to be changed to msgpack when using C++ client. Crossbar msgpack serializer needs to be installed. please add "debug": true in the transport stanza in configuration for more verbose error reporting.

Related

ICDeviceBrowser - does not find camera in Mac OS 13?

We are using ICDeviceBrowser to find the camera devices connected to a Mac system and it runs ok in macOS 12 but the delegate is never called and the device array is always empty in macOS 13.
#interface NKDeviceBrowser () < NKDeviceBrowserDelegate, ICDeviceBrowserDelegate>
{
-(void)startICDeviceBrowser
{
NSLog(#"CALL [ %# ]", NSStringFromSelector(_cmd));
if ((_browsedDeviceTypeMask & NkDeviceLocationTypeBonjour)) {
mDeviceBrowser = [[ICDeviceBrowser alloc] init];
mDeviceBrowser.delegate = self;
mDeviceBrowser.browsedDeviceTypeMask = (ICDeviceTypeMask)(ICDeviceLocationTypeMaskLocal|ICDeviceTypeMaskCamera|ICDeviceLocationTypeBonjour);
[mDeviceBrowser start];
}
}
-(void)deviceBrowser:(ICDeviceBrowser*)browser didAddDevice:(ICDevice*)addedDevice moreComing:(BOOL)moreComing
{
NSLog(#"CALL [ %# ]", NSStringFromSelector(_cmd));
if ( addedDevice.type & ICDeviceTypeCamera ) {
NSLog(#"Added Device Name %#",addedDevice.name);
if ([_delegate respondsToSelector:#selector(deviceBrowser:didAddDevice:moreComing:)]) {
[_delegate deviceBrowser:self didAddDevice:addedDevice moreComing:moreComing];
}
}
}
}
Its working fine till macOS 12 but not working in macOS 13.

Connecting two NestJS gRPC microservices on localhost

Introduction
I am quite new to NestJS, but really like how powerful it is so far, so I wanted to see how far I could get with using Kafka, gRPC and NestJS together.
My end goal is to have the following design, since I want to replicate my Kafka Producers:
gRPC client <---> gRPC server and Kafka client <----> Kafka
Kafka
I have a Kafka cluster which I have built in Kubernetes and which I reach via an L4 Load Balancer from NestJS with ease.
The Kafka side in NestJS is fine. I even rely on kafkajs and simply build out Consumers and Prodcuers using the kafkajs.Producer and kafkajs.Consumer classes accordingly, defining the configuration for the Kafka instance with a ConfigService.
gRPC
It is the gRPC side which I am struggling with as I am trying to let a gRPC server forward a request to a Kafka producer on behalf of the gRPC client.
Problem
I can start my gRPC server, but not my gRPC client. The client returns the following error from #grpc/grpc-js/src/server.ts:569:
[Nest] 50525 - 11/03/2022, 16:09:13 LOG [NestFactory] Starting Nest application...
[Nest] 50525 - 11/03/2022, 16:09:13 LOG [InstanceLoader] AppModule dependencies initialized +17ms
[Nest] 50525 - 11/03/2022, 16:09:13 LOG [InstanceLoader] ClientsModule dependencies initialized +0ms
[Nest] 50525 - 11/03/2022, 16:09:13 LOG [InstanceLoader] GrpcClientModule dependencies initialized +0ms
E No address added out of total 2 resolved
/Users/mattia/github/microservices/kafka-grpc-client/node_modules/#grpc/grpc-js/src/server.ts:569
deferredCallback(new Error(errorString), 0);
^
Error: No address added out of total 2 resolved
at bindResultPromise.then.errorString (/Users/mattia/github/microservices/kafka-grpc-client/node_modules/#grpc/grpc-js/src/server.ts:569:32)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
I am not sure why this happens, but I am suspicious that it has to do with the gRPC channel, or in other words communication link between the server and the client. However, I cannot find any documentation on this matter. Help would be greatly appreciated.
If you follow the stack trace you should notice the following in #grpc/grpc-js/src/server.ts:569:32, in other words that this error is in the #grpc/grpcjs library:
const resolverListener: ResolverListener = {
onSuccessfulResolution: (
addressList,
serviceConfig,
serviceConfigError
) => {
// We only want one resolution result. Discard all future results
resolverListener.onSuccessfulResolution = () => {};
if (addressList.length === 0) {
deferredCallback(new Error(`No addresses resolved for port ${port}`), 0);
return;
}
let bindResultPromise: Promise<BindResult>;
if (isTcpSubchannelAddress(addressList[0])) {
if (addressList[0].port === 0) {
bindResultPromise = bindWildcardPort(addressList);
} else {
bindResultPromise = bindSpecificPort(
addressList,
addressList[0].port,
0
);
}
} else {
// Use an arbitrary non-zero port for non-TCP addresses
bindResultPromise = bindSpecificPort(addressList, 1, 0);
}
bindResultPromise.then(
(bindResult) => {
if (bindResult.count === 0) {
const errorString = `No address added out of total ${addressList.length} resolved`;
logging.log(LogVerbosity.ERROR, errorString);
deferredCallback(new Error(errorString), 0);
} else {
if (bindResult.count < addressList.length) {
logging.log(
LogVerbosity.INFO,
`WARNING Only ${bindResult.count} addresses added out of total ${addressList.length} resolved`
);
}
deferredCallback(null, bindResult.port);
}
},
(error) => {
const errorString = `No address added out of total ${addressList.length} resolved`;
logging.log(LogVerbosity.ERROR, errorString);
deferredCallback(new Error(errorString), 0);
}
);
},
onError: (error) => {
deferredCallback(new Error(error.details), 0);
},
};
My code
Because gRPC requires a shared .proto file, I use the following:
syntax = "proto3";
package KAFKA_GRPC_SERVICE;
service KafkaGrpcService {
rpc Produce(ProducerRequest) returns(Empty) {}
}
// See `kafkajs/types/ProducerRecord`
message ProducerRequest {
// See `kafkajs/types/Message`
message Message {
required string value = 1;
optional string key = 2;
optional int32 partition = 3;
optional string timestamp = 4;
}
required string topic = 1;
repeated Message messages = 2;
optional int32 acks = 3;
optional int32 timeout = 4;
}
message Empty {}
I then autogenerate the interface required which gives me:
/**
* This file is auto-generated by nestjs-proto-gen-ts
*/
import { Observable } from 'rxjs';
import { Metadata } from '#grpc/grpc-js';
export namespace KAFKA_GRPC_SERVICE {
export interface KafkaGrpcService {
produce(data: ProducerRequest, metadata?: Metadata): Observable<Empty>;
}
// See `kafkajs/types/ProducerRecord`
export interface ProducerRequest {
topic: string;
messages: ProducerRequest.Message[];
acks?: number;
timeout?: number;
}
export namespace ProducerRequest {
// See `kafkajs/types/ProducerRecord`
// See `kafkajs/types/Message`
export interface Message {
value: string;
key?: string;
partition?: number;
timestamp?: string;
}
}
// tslint:disable-next-line:no-empty-interface
export interface Empty {
}
}
Note I have tweaked some of the interface since it provides certain elements as optional, when I need a few of them to be required to be compatible with kafkajs/ProducerRecord.
My repository has two different NestJS apps, one called kafka-grpc-server and another called kafka-grpc-client respectively, so the code is slightly different. I won't post the ProducerService here for sake of brevity.
Server
Myconfig for the gRPC service is defined in a grpc.options.ts file that looks as follows:
import { Transport } from "#nestjs/microservices";
import { join } from "path";
export const grpcOptions = {
transport: Transport.GRPC,
options: {
package: 'KAFKA_GRPC_SERVICE',
url: 'localhost:5000',
protoPath: join(__dirname, 'grpc/proto/kafkagrpcservice.proto'),
},
}
My Controller on the Server side looks like this:
import { Controller,Logger } from "#nestjs/common";
import { GrpcMethod } from "#nestjs/microservices";
import { Observable } from "rxjs";
import { KAFKA_GRPC_SERVICE } from './grpc/interfaces/kafkagrpcservice';
import { ProducerService } from "./kafka/producer/producer.service";
#Controller()
export class KafkaGrpcController implements KAFKA_GRPC_SERVICE.KafkaGrpcService {
private logger = new Logger(KafkaGrpcController.name)
constructor(private readonly kafkaProducer: ProducerService) {}
#GrpcMethod('KafkaGrpcService', 'Produce')
produce(data: KAFKA_GRPC_SERVICE.ProducerRequest, metadata: any): Observable<any> {
this.logger.log('Producing message: {} with metadata: {}', data, metadata.toString());
this.kafkaProducer.produce(data);
return;
}
}
and my main.ts server side is like this:
import { Logger } from '#nestjs/common';
import { NestFactory } from '#nestjs/core';
import { grpcOptions } from './grpc.options';
import { KafkaGrpcServerModule } from './kafkagrpcserver.module';
async function bootstrap() {
const logger = new Logger('Main')
const app = await NestFactory.createMicroservice(KafkaGrpcServerModule, grpcOptions);
await app.listen();
logger.log(`Microservice is listening on '${grpcOptions.options.url}'`);
}
bootstrap();
I can successfully start the server without any issues, although I do notice that there is one process with two file descriptors listening on :5000, with TCP. I am not sure whether this is standard. First question I have is why are there two services, and not one when I just create one microservice? Is this a NestJS thing?
node 50355 mattia 27u IPv6 * 0t0 TCP localhost:commplex-main (LISTEN)
node 50355 mattia 29u IPv4 * 0t0 TCP localhost:commplex-main (LISTEN)
Client
Client side is slightly different. I use the same .proto file. However, the grpc.options.ts file is slightly different since this needs to be a client:
export const grpcOptions: ClientOptions = {
transport: Transport.GRPC,
options: {
package: 'KAFKA_GRPC_SERVICE',
url: 'localhost:5000',
protoPath: join(__dirname, 'grpc/proto/kafkagrpcservice.proto'),
},
}
As you can see, ClientOptions are used for the client, but not for the server.
Client side, I have a GrpcClientModule which looks like this:
import { Module } from "#nestjs/common";
import { ClientsModule } from "#nestjs/microservices";
import { grpcOptions } from "../grpc.options";
import { GrpcClientController } from "./grpcclient.controller";
#Module({
imports: [
ClientsModule.register([
{
name: 'KAFKA_GRPC_SERVICE',
...grpcOptions,
}
])
],
controllers: [
GrpcClientController,
],
})
export class GrpcClientModule {}
and the GrpClientController is like this:
import { Metadata } from "#grpc/grpc-js";
import { Body, Controller, Get, Inject, OnModuleInit, Post } from "#nestjs/common";
import { Client, ClientGrpc } from "#nestjs/microservices";
import { Observable } from "rxjs";
import { grpcOptions } from "src/grpc.options";
import { KAFKA_GRPC_SERVICE } from "./interfaces/kafkagrpcservice";
#Controller()
export class GrpcClientController implements OnModuleInit {
constructor(#Inject('KAFKA_GRPC_SERVICE') private client: ClientGrpc) {}
private grpcService: KAFKA_GRPC_SERVICE.KafkaGrpcService;
onModuleInit(): void {
this.grpcService = this.client.getService<KAFKA_GRPC_SERVICE.KafkaGrpcService>('KafkaRpcService')
}
#Post('produce')
async produce(data: KAFKA_GRPC_SERVICE.ProducerRequest): Promise<Observable<KAFKA_GRPC_SERVICE.ProducerResponse>> {
const metadata = new Metadata();
metadata.add('Set-Cookie', 'my_cookie=in_milk');
return this.grpcService.produce( { topic: data.topic, messages: data.messages }, metadata );
}
}
I start my client as follows:
import { NestFactory } from '#nestjs/core';
import { grpcOptions } from './grpc.options';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.createMicroservice(AppModule, grpcOptions);
await app.listen();
}
bootstrap();
Any help would be great!
So, I found the answer. It seems that it is impossible to start a single microservice as a gRPC server. Indeed, whenever I turn the microservice into a hybrid application as follows:
import { Logger } from '#nestjs/common';
import { NestFactory } from '#nestjs/core';
import { grpcOptions } from './grpc.options';
import { KafkaGrpcServerModule } from './kafkagrpcserver.module';
async function bootstrap() {
const logger = new Logger('Main')
const app = await NestFactory.create(KafkaGrpcServerModule);
const grpcServer = await NestFactory.createMicroservice(KafkaGrpcServerModule, grpcOptions);
await app.startAllMicroservices();
await app.listen(3000);
}
bootstrap();
I am able to connect the client.

IOS SWIFT PARSE : Pfcloud.callFunction

i have an old app in objective C using cloudcode to send pushes to back4app platform.
The app manage to send correctly the pushes and this is the code :
- (IBAction)inviaPush:(UIButton *)sender {
NSString *canale;
for (int i=0; i<=4; i++) {
switch (i) {
case 0:canale=#"TraduzioniEDI";
break;
case 1:canale=#"NavFtpYM";
break;
case 2:canale=#"InvioMailFTP";
break;
case 3:canale=#"VermasMto";
break;
case 4:canale=#"EdiAltova";
break;
default:
break;
}
NSString *testoPush =[NSString stringWithFormat:#"%# Test Invio %#", canale,[NSDate date]];
[PFCloud callFunctionInBackground:#"push"
withParameters:#{#"channels": #[canale], #"data": #{#"alert": testoPush,#"badge":#"Increment"}}
block:^( NSString *result, NSError *error) {
if (!error) {
NSLog(#"Risultato: %#",result);
} else{
NSLog(#"Errore %#",error);
}
}];
}
}
Running the code i receive the 5 pushes and in the info of back4app dashboard i find :
2020-03-02T01:14:53.533Z - Ran cloud function push for user undefined with:
Input: {"channels":["VermasMto"],"data":{"alert":"VermasMto Test Invio 2020-03-02 01:14:52 +0000"}}
Result: "Sent!!"
i tried to convert the program in swift
the code to send push is :
func inviaPush (){
var canale :String = ""
for i in 0...4
{
switch i {
case 0: canale = "TraduzioniEDI"
case 1: canale = "NavFtpYM"
case 2: canale = "InvioMailFTP"
case 3: canale = "VermasMto"
case 4: canale = "EdiAltova"
default: canale=""
}
let testoPush = "\(canale) Test invio - Swift"
PFCloud.callFunction(inBackground: "push", withParameters: ["channels": canale, "data": ["alert": testoPush,"badge":"Increment"]], block: {
(result: Any?, error: Error?) -> Void in
if error != nil {
if let descrip = error?.localizedDescription{
print(descrip)
}
}else{
print(result as! String)
}
})
}
}
in this case i receive no pushes, and in the info i find following :
2020-03-02T01:17:25.505Z - Ran cloud function push for user undefined with:
Input: {"channels":"NavFtpYM","data":{"alert":"NavFtpYM Test invio"}}
Result: "Sent!!"
2020-03-02T01:17:25.504Z - Can't count installations for PushStatus hm5hbCzDvd: bad $in value
Comparing the info shown in the dashboard i see a difference in input
in ojective C (Working) the in input the channel have a square bracket :
Input: {"channels":["VermasMto"],
while when sent from swift they have not
Input: {"channels":"NavFtpYM",
surely i'm calling the method PFCloud.callFunction in a wrong way.
Any suggestion ?
Fabrizio
the solution was simple ...
need to change
PFCloud.callFunction(inBackground: "push", withParameters: ["channels": canale, "data": ["alert": testoPush,"badge":"Increment"]], block: {
in
PFCloud.callFunction(inBackground: "push", withParameters: ["channels": [canale], "data": ["alert": testoPush,"badge":"Increment"]], block: {
Fabrizio

Jenkins pipeline RejectedAccessException error

I am trying to setup a jenkins pipeline script that sends out an email when there is a job that have been running for more than 24 hours.
// Long running jobs
pipeline {
agent any
environment {
EMAIL_ALERT_TO = "address"
EMAIL_ALERT_CC = "address"
}
stages {
stage('def methods') {
steps {
script {
Jenkins.instance.getAllItems(Job).each(){ job -> job.isBuildable()
if (job.isBuilding()){
def myBuild= job.getLastBuild()
def runningSince= groovy.time.TimeCategory.minus( new Date(), myBuild.getTime() )
echo "myBuild = ${myBuild}"
echo "runningSince = ${runningSince}"
env.myBuild = myBuild
env.runningSince = runningSince
}
}
}
}
}
}
post {
// Email out the results
always {
script {
if (runningSince.hours >= 1){
mail to: "${env.EMAIL_ALERT_CC}",
cc: "${env.EMAIL_ALERT_CC}",
subject: "Long Running Jobs",
body: "Build: ${myBuild} ---- Has Been Running for ${runningSince.hours} hours:${runningSince.minutes} minutes"
}
}
}
}
}
I am seeing RejectedAccessException which appears to be related to arrays/list.
This is what I believe you are looking for
https://issues.jenkins-ci.org/browse/JENKINS-54952?page=com.atlassian.jira.plugin.system.issuetabpanels%3Achangehistory-tabpanel

Every time on scanning bluetooth devices gives CBCentralManagerStateUnknown?

First time I am using coreBluetooth.
Here is my implementation is there any thing wrong in it.
#synthesize CM,activePeripheral;
- (id)init
{
if ((self = [super init]))
{
CM = [[CBCentralManager alloc]initWithDelegate:self queue:dispatch_get_main_queue()];
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (int) scanForPeripherals
{
if (self.CM.state != CBCentralManagerStatePoweredOn)
{
NSLog(#"CoreBluetooth is %s",[self centralManagerStateToString:self.CM.state]);
return -1;
}
[self.CM scanForPeripheralsWithServices:[NSArray arrayWithObject:[CBUUID UUIDWithString:#"180D"]] options:#{CBCentralManagerScanOptionAllowDuplicatesKey: #YES}];
return 0;
}
- (const char *) centralManagerStateToString: (int)state
{
switch(state)
{
case CBCentralManagerStateUnknown:
return "State unknown (CBCentralManagerStateUnknown)";
case CBCentralManagerStateResetting:
return "State resetting (CBCentralManagerStateUnknown)";
case CBCentralManagerStateUnsupported:
return "State BLE unsupported (CBCentralManagerStateResetting)";
case CBCentralManagerStateUnauthorized:
return "State unauthorized (CBCentralManagerStateUnauthorized)";
case CBCentralManagerStatePoweredOff:
return "State BLE powered off (CBCentralManagerStatePoweredOff)";
case CBCentralManagerStatePoweredOn:
return "State powered up and ready (CBCentralManagerStatePoweredOn)";
default:
return "State unknown";
}
return "Unknown state";
}
- (void) connectPeripheral:(CBPeripheral *)peripheral {
printf("Connecting to peripheral with UUID : %s\r\n",[self UUIDToString:peripheral.UUID]);
self.activePeripheral = peripheral;
self.activePeripheral.delegate = self;
[self.CM connectPeripheral:self.activePeripheral options:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:CBConnectPeripheralOptionNotifyOnDisconnectionKey]];
}
-(const char *) UUIDToString:(CFUUIDRef)UUID
{
if (!UUID)
return "NULL";
CFStringRef s = CFUUIDCreateString(NULL, UUID);
return CFStringGetCStringPtr(s, 0);
}
#pragma mark -Central manager delegate method
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
NSLog(#"hits it");
if (central.state != CBCentralManagerStatePoweredOn) {
return;
}
isOn=YES;
}
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
NSLog(#"Received periferal :%#",peripheral);
NSLog(#"Ad data :%#",advertisementData);
[MBProgressHUD hideHUDForView:self.view animated:YES];
}
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
NSLog(#"Connected peripheral %#",peripheral);
}
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
NSLog(#"Error occured :%#",[error localizedDescription]);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)scanDevices:(id)sender {
if (isOn) {
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
[self scanForPeripherals];
}
}
Every time it gives log
CoreBluetooth is State unknown (CBCentralManagerStateUnknown)
update to question
After suggestion given by #Michael Dautermann , I come to know that my centralManagerDidUpdateState delegate method is not hitting.I dunno why this is happening.If anybody finds the reason please notify me.
Thanks you.
CoreBluetooth is simply in the process of starting up.
You need this delegate method to hit first:
- (void) centralManagerDidUpdateState: (CBCentralManager *) central;
And once it does, then you can start scanning for peripherals.
After few days, I checked out the initialization of CentralManager and I come to know that init method on firstViewController never called.I checked out by printing log in init method.
- (id)init
{
NSLog(#"hello init");
if ((self = [super init]))
{
CM = [[CBCentralManager alloc]initWithDelegate:self queue:dispatch_get_main_queue()];
}
return self;
}
- (void)viewDidLoad
{ CM = [[CBCentralManager alloc]initWithDelegate:self queue:dispatch_get_main_queue()];
isOn=NO;
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
So , I initialize the central manager in viewDidLoad and now it is initialized and centralManagerDidUpdateState finally called.Now printing CBCentralManagerStateUnsupported and that's not the issue because iPhone 4 doesn't support it.Thanks to michael help me a lot.
Where do you call scanDevices? I think you're calling it too early. You should call it inside centralManagerDidUpdateState.
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
NSLog(#"hits it");
if (central.state != CBCentralManagerStatePoweredOn) {
[self scanDevices]:
}
isOn=YES;
}

Resources