How Can I set timeout interval when use bluetooth

Viewed 817

When I use bluetooth to write data, I hope get response. But when the peripheral goes wrong, it doesn't send notification. I need set a timeout interval to handle this bad interaction. Like we use urlrequest:

    /// Creates and initializes a URLRequest with the given URL and cache policy.
    /// - parameter: url The URL for the request. 
    /// - parameter: cachePolicy The cache policy for the request. Defaults to `.useProtocolCachePolicy`
    /// - parameter: timeoutInterval The timeout interval for the request. See the commentary for the `timeoutInterval` for more information on timeout intervals. Defaults to 60.0
    public init(url: URL, cachePolicy: CachePolicy = .useProtocolCachePolicy, timeoutInterval: TimeInterval = 60.0) {
        _handle = _MutableHandle(adoptingReference: NSMutableURLRequest(url: url, cachePolicy: cachePolicy, timeoutInterval: timeoutInterval))
    }

How could I make it.

2 Answers

By "when the peripheral goes wrong" - if you mean that the peripheral crashes or stops working then you should get a BLE disconnection event to indicate the crash:

(centralManager:didDisconnectPeripheral:) 

If this is not the case and you just stop receiving notifications after some time and the BLE connection is still alive, then there is no way to tell why the peripheral stopped sending notifications. The reason for this is that there is no specific "time" associated with notifications. Some peripherals send notifications every 1 second and some send notifications every 1 week. Some peripherals send notifications on a value change (e.g. if the temperature increases by 1 degree) and some send notifications on a user action (e.g. the user pressed a button).

The only workaround for this is if you add a timer in your central device, then every time you receive a notification using:

peripheral(_:didUpdateValueFor:error:)

you can reset that timer (if it is the exact notifications you're expecting to timeout). Then if the timer expires, you know that you did not receive your notification on time as expected and therefore you can flag an error or force a disconnection. This is just one example and there are a few variations of this that you can create (e.g. set a flag on peripheral(_:didUpdateValueFor:error:) that you check and reset every 30 seconds). You can find more information about timers in the links below:-

I hope this helps.

This is an interesting question.

After checking CoreBluetooth, i figured out that there's already an timeout Error in their list . https://developer.apple.com/documentation/corebluetooth/cberror/2325746-connectiontimeout

But It's only works for the first time connect to peripheral.

So I think that, if you send a request, but you don't get any response, you have to make your own timer manager.

The concept for timeout is quite complicated. You need make a queue for timer, It's FIFO. You need an uniqueId for each request and you have to map it with your expected response.

Ex :

You call :

  1. Call to get health info via BLE (any thread).
  2. Call to get height info via BLE (any thread).
  3. Call to get health info via BLE (any thread).

Your response :

  1. height info.
  2. health info.

After mapping your request with your response, you will notice that there's one expected response is missing. So how to know the request 1 or request 3 is missing response. It's your choice.

In conclusion, I think that you need a queue request and a queue expected response and a queue for timer. To manage these queue is not really a very big problem.

Related