Can only restablish a bluetooth connection a finite number of times - bluetooth

I have an application (activity and service) which can establish a connection with a separate device and pull data off it over spp Bluetooth.
It need to do this once a day.
However, there appears to be a limit to the number of times that phone (server) can reestablish a connection with the device (client).
In the LogCat, I see this error:
BluetoothEventLoop.ccp
onCreateDeviceResult: D.Bus error: org.freedesktop.DBus.Error.LimitsExceeded (The maximum number of pending replies per connection has been reached)
BluetoothEventLoop Result of onCreateDeviceResult:-1
I'm thinking about programmatically rebooting the phone but would rather not have to do this?
Have you any ideas how to overcome this problem.
Ideally, the phone will be running as a hub, permanently connected to a power supply, for many weeks.
I'm running Android 2.3.7.

Are you using this method to create the socket in your connect thread?
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
I had the same error on 2.3.6 and fixed it using the reflection method. I replaced the above code with:
Method m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
tmp = (BluetoothSocket) m.invoke(device, 1);
I used the same solution as this other problem:
Service discovery failed exception using Bluetooth on Android

Related

IoT EDGE Device Connection state monitoring

We have a business requirement to maintain Iot Edge devices Connected state in Digital Twins Instance. It should be near to real time, but short delays up to few minutes are acceptable.
I.e., In Digital Twins instance we have DT entity for each IoT Edge device, and it have property Online (true/false).
In production we will have up to few hundreds of devices in total.
We are looking for a good method of monitoring Edge devices connected state.
Our initial attempt was to subscribe an AZ Function for Event Grid Device Connected/Disconnected notifications in IoT Hub events.
After initial testing we found that Event Grid seems cannot be used as a single source. After more research we found following information:
https://learn.microsoft.com/en-us/azure/iot-hub/iot-hub-event-grid#limitations-for-device-connected-and-device-disconnected-events
IoT Hub does not report each individual device connect and disconnect, but rather publishes the current connection state taken at a periodic 60 second snapshot. Receiving either the same connection state event with different sequence numbers or different connection state events both mean that there was a change in the device connection state during the 60 second window.
And another one:
https://learn.microsoft.com/en-us/azure/iot-hub/iot-hub-troubleshoot-connectivity#mqtt-device-disconnect-behavior-with-azure-iot-sdks
Azure IoT device SDKs disconnect from IoT Hub and then reconnect when they renew SAS tokens over the MQTT (and MQTT over WebSockets) protocol….
…
If you're monitoring device connections with Event Hub, make sure you build in a way of filtering out the periodic disconnects due to SAS token renewal. For example, do not trigger actions based on disconnects as long as the disconnect event is followed by a connect event within a certain time span.
Next, after more search on the topic, we found the following question:
Best way to Fetch connectionState from 1000's of devices - Azure IoTHub
Accepted answer suggests using heartbeat pattern, however in official documentation it is clearly stated that it should not be used in production environment:
https://learn.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-identity-registry#device-heartbeat
And in the article describing heartbeat pattern there is a mention of “short expiry time pattern” but not much information given to detail it.
For complete picture, we also found the following article:
https://learn.microsoft.com/en-us/azure/iot-hub/iot-hub-how-to-order-connection-state-events
But it is based on Event Grid subscription and therefore will not provide accurate data.
Finally, after reading all of this, we have the following plan to address the problem:
We will have AZ Function subscribed for Event Grid Device Connected/Disconnected notifications.
If DeviceConnected event received, the function will check device connectivity immediately.
If DeviceDisconnected event received, the function will delay for 90 seconds, as we found DeviceConnected event usually come after ~60 seconds for a given device. And after the delay it will check the device connectivity.
Device Connectivity will be checked with Cloud to Device message send with acknowledgment as described here:
https://learn.microsoft.com/en-us/azure/iot-hub/iot-hub-csharp-csharp-c2d#receive-delivery-feedback
Concerns of the solution:
Complexity.
AZ function would need IoT HUB service Connection string.
Device disconnected event might be delayed up to few minutes.
Can anyone suggest better solution?
Thanks!
EDIT:
In our case, we do not use DeviceClient, but ModuleClient on the Edge devices, and modules does not support C2D messages, which is stated here:
https://learn.microsoft.com/en-us/azure/iot-edge/module-development?view=iotedge-2018-06&WT.mc_id=IoT-MVP-5004034#iot-hub-primitives
So we would need to use Direct Methods instead to test if the device is Online.

Python3.5.x deadlock detected while testing connectivity to the internet

A python3.5 application occasionally deadlocks when run.
To give more details about the application, the main thread (thread A) is responsible for receiving data from an external device and sending it to an MQTT broker.
There are two other threads that are spawned – one for checking for internet connectivity ((thread B - explained in detail below) and the other thread runs a class which implements a watchdog to check for possible deadlocks.
Thread A is long-running and sends data to the broker as received. In the case of no Internet connectivity, it starts storing data to a local database.
Thread B is used to check for Internet connectivity every 3 minutes, so that when connectivity is restored, the application can start sending the locally stored data back to the MQTT broker. This is to accommodate the scenario where the application loses Internet connectivity and starts losing data received from the device. To avoid this, the application, when offline, will start storing data locally to a SQLite3 database.
This application is run as a systemd service and internet connectivity is through the WiFi dongle, attached to the system.
Recently, we encountered a case where there was no internet connectivity (all pings were getting routed to the dongle’s IP address), and when the application tried to connect to the MQTT broker, it went into deadlock and the stack trace showed that this happened at the getaddrinfo function in socket.py.
Thread B was created to check for a successful internet connection before trying to connect to the MQTT client (to avoid deadlock).
This thread also checks on connectivity later on, when the Internet goes down, while the application is already up and running.
In this case, occasionally, the application runs into deadlock between the main thread (thread A) and Thread B
Code for Thread B shown below:
while isGoing:
try:
host = socket.gethostbyname("www.google.com")
ip = IP(host)
if ip.iptype() == 'PRIVATE':
disconnected = True
else:
disconnected = False
except Exception as e:
print(e)
disconnected = True
sleep(delay)
When thread B was monitored, it was seen to hand when using the subprocess module, os.system commands, as well as the gethostbyname function.
Note: Paho MQTT on_connect and on_disconnect callbacks are already used to check for connectivity.

How to stay connected to a Bluetooth LE bathroom scales in Linux

I just got a Bluetooth LE/Smart bathroom scales (Model Sanitas SBF 70). I can read data from it using the following command:
gatttool --device=(btaddr) -I
connect
Then when I stand on it, I get multiple notification messages like this:
"Notification handle = 0x002e value: e7 58 01 05 e9"
where the last two bytes are is the mass in 50g increments.
I'd like to integrate this into a few application using a TCP or UDP socket service that broadcasts these messages to any listening clients.
But after some research I have no idea what's the best way to stay connected all the time (the connection times out after a few minutes). Or alternatively to be able to re-establish a connection when the scales is used (I notice lots of activity from 'hcitool lescan' whenever someone steps on the scales).
I don't care what language / library is used. If I can push this to a TCP/UDP socket it will be trivial for other applications to consume the information.
The answer is straightforward: You don't.
Your scale is most likely battery powered. Therefore the Bluetooth communications will only be enabled for a short period of time after having measured your weight. Your application just needs to try connecting to the scale over and over (catch any "unable to connect timeouts") until you step on it. And when connected get the data from it before BLE is shut down again. In pseudo code:
while true:
while not_connected:
try to connect
receive notifications
disconnect
gatttool wrapped by the python module pygatt is perfectly usable to solve this chalenge.
In my case scale data (preceding 30 weights) is transferred after enabling indications of 3 different characteristics.

Object push to bluetooth without pairing

Is it possible to send some notification messages to the nearby Bluetooth devices without pairing.I have found some protocol for these - OBEX Oject Push. But am not clear whether is is feasible without pairing request .Any demo apps for reference?
Yes and no.
If you are actually talking about connecting but not pairing, then, yes.
If you are talking about no connection at all, then no.
When creating a Bluetooth connection between two or more devices the following steps are taken.
Inquiry – If two Bluetooth devices know absolutely nothing about each other, one must run an inquiry to try to discover the other. One device sends out the inquiry request, and any device listening for such a request will respond with its address, and possibly its name and other information. The closest located device is not necessarily the fastest to respond and any device that hears the call will try to respond.
Paging – Paging is the process of forming a connection between two Bluetooth devices. Before this connection can be initiated, each device needs to know the address of the other (found in the inquiry process).
Connection – After a device has completed the paging process, it enters the connection state. While connected, a device can either be actively participating or it can be put into a low power sleep mode.
• Active Mode – This is the regular connected mode, where the device is actively transmitting or receiving data.
• Sniff Mode – This is a power-saving mode, where the device is less active. It’ll sleep and only listen for transmissions at a set interval (e.g. every 100ms).
• Hold Mode – Hold mode is a temporary, power-saving mode where a device sleeps for a defined period and then returns back to active mode when that interval has passed. The master can command a slave device to hold.
• Park Mode – Park is the deepest of sleep modes. A master can command a slave to “park”, and that slave will become inactive until the master tells it to wake back up.
Two devices can be bonded together through a one-time process called pairing. When two devices are paired, they store each other’s addresses, names and profiles in memory, allowing them to automatically establish a connection as soon as they are in range of each other.
It is not possible to send OPP (or other) communication between two devices before connecting.
It is possible to send communication between two devices after connection but before pairing.

Understanding Disconnect / Reconnect Process and Error Messages

I am trying to implement a feature which notifies the user of disconnections to pusher, and indicates when reconnection has occured. My first experiment is simply to log changing pusher states to console:
var pusher = new Pusher('MY_ACCOUNT_STRING');
pusher.connection.bind('state_change', function(states) {
console.log(states.current);
});
I then refresh the page, get a connection to pusher, disable my internet connection, wait for pusher to detect the disconnection, re-enable my internet connection, and wait for pusher to detect that. Here's a screenshot of chrome's console output during the process (click here for a larger version):
Here are my questions:
It took over a minute, possibly even 2-3 minutes, before the disconnection was detected by pusher. Is there a way to decrease that time so pusher detects disconnection within 10 or so seconds?
Why am I seeing those red errors, and what exactly do they mean? Is that normal? I would think with the correct setup the errors would be handled, since a disconnection event is an "expected" exception within the pusher context.
What is the 1006 error and why am I seeing that?
Thanks for any help!
EDIT:
I've been watching the output for a long-standing connection, and I've also seen this a number of times, and would like to know the cause of it, and how I can capture it and handle it?
disconnected login.js:146
connecting login.js:146
Pusher : Error : {"type":"WebSocketError","error":{"type":"PusherError","data":{"code":1007,"message":"Server heartbeat missed"}}} pusher.min.js:12
connected
That's no normal behavior. Have you had the chance to check this on different machine and network? It looks like a network problem.
Question 1.
When I disable wifi it takes pusher 4 seconds to notice and change the state to disconnected and then to unavailable.
When I re-enable wifi I only get same error as you do on http://js.pusher.com/2.1.3/sockjs.js
I've got no idea about the implications of doing so.. but you could try to alter the default timeouts:
var pusher = new Pusher('MY_ACCOUNT_STRING', {
pong_timeout: 6000, //default = 30000
unavailable_timeout: 2000 //default = 10000
});
Question 2.
No idea, I don't think the lib should throw those error's
Question 3.
The error's are from the WebSocket protocol: https://www.rfc-editor.org/rfc/rfc6455
1006 is a reserved value and MUST NOT be set as a status code in a
Close control frame by an endpoint. It is designated for use in
applications expecting a status code to indicate that the
connection was closed abnormally, e.g., without sending or
receiving a Close control frame.
1007 indicates that an endpoint is terminating the connection
because it has received data within a message that was not
consistent with the type of the message (e.g., non-UTF-8 [RFC3629]
data within a text message).

Resources