17

I've looked everywhere and tried everything, but nothing seems to work :(

On iOS, I'm making an app (for iOS 6 and above) in which iOS devices need to exchange data. Therefore, both devices need to be peripheral and central at the same time. I've done exactly as specified in the WWDC video, but the devices can't connect successfully with each other.

When I make one device only central and the other only peripheral, the central connects seamlessly to the peripheral.

However, when both devices are peripheral and central at the same time, I get random errors: at any stage (discovering services/characteristics or setting notify value to YES) errors sometimes happen, and sometimes discoverServices doesn't even call didDiscoverServices

Is there something different I should be doing? I simply merged the peripheral and central code into one view controller. I've noticed that if device "a" connects to device "b", and then device "b" connects to device "a", it works more often than not. I manage this by using NSThread sleepForTimeInterval: manually for different amounts of time on each device, but how could I get one device to connect first (and then the other) in a reliable (and not manually pre-defined) way?

If I do get errors, usually they're simply Unknown error

Please let me know if you need any code or any other information :)

Macro206
  • 2,093
  • 2
  • 16
  • 24
  • 1
    Did you read this? http://stackoverflow.com/questions/16985891/can-ios-do-central-and-peripheral-work-on-same-app-at-same-time?rq=1 – Stas Aug 01 '13 at 10:15
  • 3
    Yes I have. As I said, "I've looked everywhere and tried everything, but nothing seems to work" – Macro206 Aug 01 '13 at 14:21

3 Answers3

26

Yes, it can be in both roles at the same time. You just have to initialize a CBPeripheralManager and a CBCentralManager. As soon as the peripheral manager is initialized and you receive the POWER ON state the device starts acting as a peripheral. You can add your services at this point and receive connections from other devices. At the same time you can use the central manager to scan and initiate connections to other peripherals.

Note that you cannot connect to your own device even if it acts as a peripheral.

For your errors, I suggest:

  1. Turn off scanning before initiating a connection. That is, scan, find peripheral, stop scan, connect. Connection and scanning do not like each other.
  2. Use a dedicated queue for handling bluetooth events, not the main queue. [[CBCentralManager alloc] initWithDelegate:self queue:my_dedicated_bluetooth_q]
  3. Unfortunately, the stack sometimes become unstable. Even restarts are possible. But this usually happens only under heavy loads or several simultaneous connections. Hopefully, this will be improved in iOS7.
  4. The unfamous Unknown error started to appear for several developers recently. Judging from your description there are probably a number of reasons why your setup may fail and it would require much more info that what fits well into a SO question.

For more info I suggest you search the bluetooth-dev mailing list archives https://lists.apple.com/archives/Bluetooth-dev or send a mail Bluetooth-dev@lists.apple.com. The community provides great help if you approach with reasonable questions like this.

allprog
  • 15,913
  • 8
  • 54
  • 94
  • Is there solution how to the app implemented both central/peripheral connect to each other?? – nao0811ta Jul 11 '14 at 07:56
  • @nao0811ta I'm not sure what you are asking. To see how the central and peripheral can connect, check out the [BTLE Transfer](https://developer.apple.com/library/ios/samplecode/BTLE_Transfer/Introduction/Intro.html) example. The central and peripheral on the same device cannot connect each other. – allprog Jul 11 '14 at 07:58
0

As per my understanding one device can work with one mode at a time . That is if the device is working in the peripheral mode then it you cant work it as a central mode .If you see some standard examples like BTLE transfer or lilke Light Blue those are working in one mode at a time .

V-Xtreme
  • 6,775
  • 6
  • 33
  • 76
  • But I heard about people who got it to work in both modes... And according to them they simply merged the peripheral and central code. And sometimes even I get it to work - it's just that it doesn't happen often. – Macro206 Jul 19 '13 at 07:29
  • 1
    Yes , as per my understanding same application can have both the features of the central and peripheral, Light Blue has that . But the it can work in single mode at a time that is you can receive or transmit the data at a time . – V-Xtreme Jul 19 '13 at 08:29
  • 3
    This is false, it is totally possible for a device to act as a peripheral and central at the same time. I have been doing that ever since it became available. – allprog Aug 06 '13 at 20:27
  • As I said - sometimes I get it to work in both modes at the same time. – Macro206 Aug 06 '13 at 21:03
0

Firstly, what do you mean "the same time"? If you mean the device advertising to other devices while it scanning for other devices, it can not. But you can create two threads which share same lock to advertising and scanning. Before scanning, stop advertising, before advertising, stop scanning. I tested on my iPhone 4s and iPad air, worked well.