My BLE device(slave) set to disable 'connection parameter update request' on Link Layer.
My own Android application on smartphone sends 2 or 3 times of 'connection parameter update request' to slave device when pairing. I did not use requestConnectionPriority(). Why it sent automatically?
On the contrary, when pairing with Bluetooth Setting menu on same smartphone(not my application), it does not send 'connection parameter update request' to slave device.
I want my application to do not send it to slave. Is it possible?
enter image description here
Android usually updates the connection parameters shortly after establishment with decreased connection parameters to speed up GATT service discovery and bonding. When that is finished, it updates back to the initial connection parameters.
The master device controls the link and can hence perform a Connection Update procedure at anytime, and the slave must obey the parameters. (If the slave doesn't like the new parameters, it can disconnect.)
When BLE was introduced with the 4.0 specification, the only available option for the slave to update connection parameters was to use the L2CAP protocol to ask the host to update the parameters, which it could either reject or accept. If the host accepts the parameters, it performs a Connection Update procedure.
In Bluetooth 4.1 a new procedure called Connection Parameters Request procedure was introduced, which can be initiated by both slave and master to negotiate parameters both devices support. However, the master still decides the final parameters to be used and then performs a Connection Update procedure as usual.
So no, you cannot force Android to not perform connection parameter updates, since it's built into the Bluetooth stack and this part can't be controlled by an app.
Related
I am using Spring Integration 2.0.3 with TCP. Application behavior is, it is acting as the TCP client and sending a message to the third-party tool using TCP. So application makes the connection to a third party tool using TCP, sends the message, waits for the reply and when that is received (again acting as the client) will close the connection. Now the issue is third-party tool can neither add any terminator nor make fixed length message.
As per my understanding, there are three ways to make a packet and send it to application
1)Always send fixed-sized messages
2)Send the message size with each message
3)Use a marker system to separate messages
But I cannot use any way mentioned above, I want to know how my application can receive the response message in this scenario, Is it possible?
Is your program supposed to close the connection once you have received the message? Or is the other program supposed to close the connection once it has sent the message to you?
If the latter then it's no problem since you just read until the connection is closed.
If the former, and you can't alter the application protocol and it doesn't already specify these things (is there a specification anywhere?), then wait with a timeout. If you haven't received anything within X seconds consider the full message received and close the connection.
I work on my first IOT POC, the device will usually generate sensor data once per hour/day. I planned to have architecture like this:
- 1 shared topic for sensor data input (device to backend direction)
- Each device will subscribe initially to its own specific topic aka /device/{id}/notification
Now, after sensor data submitted to shared topic, I plan to put device into deep sleep (device can only be waked-up by wifi packet or timer), in this state TCP connection to broker is lost.
Question: After device is back waked-up and TCP connection to MQTT broker is re-established, will the device receive all messages which were generated by server during out-of-service period, or these messages won't be available?
During client connecting to the broker, the CleanSession flag enables the broker to queue up missed messages of QoS 1 or QoS 2 (storing QoS 0 messages is implementation-dependent).
The MQTT 3.1.1 Standard Section 3.1.2.4 specifies that:
If CleanSession is set to 0, the Server MUST resume communications with the Client based on state from the current Session (as identified by the Client identifier). If there is no Session associated with the Client identifier the Server MUST create a new Session. The Client and Server MUST store the Session after the Client and Server are disconnected [MQTT-3.1.2-4]. After the disconnection of a Session that had CleanSession set to 0, the Server MUST store further QoS 1 and QoS 2 messages that match any subscriptions that the client had at the time of disconnection as part of the Session state [MQTT-3.1.2-5]. It MAY also store QoS 0 messages that meet the same criteria
The problem with a persistent session is that it may queue up large numbers of messages, so upon re-connection the client is bombarded with missed messages. This may be desirable if you require to know the full sequence of readings, or highly undesirable if the client is running on a low-power, battery-fed embedded device.
To address this, MQTT provides another feature: retained flag in publication messages.
The MQTT 3.1.1 Standard Section 3.3.1.3 specifies that:
If the RETAIN flag is set to 1, in a PUBLISH Packet sent by a Client to a Server, the Server MUST store the Application Message and its QoS, so that it can be delivered to future subscribers whose subscriptions match its topic name [MQTT-3.3.1-5]. When a new subscription is established, the last retained message, if any, on each matching topic name MUST be sent to the subscriber [MQTT-3.3.1-6]. If the Server receives a QoS 0 message with the RETAIN flag set to 1 it MUST discard any message previously retained for that topic. It SHOULD store the new QoS 0 message as the new retained message for that topic, but MAY choose to discard it at any time - if this happens there will be no retained message for that topic
This ensures that upon re-connection the client receives only the latest message on a given topic.
Very quickly I found an answer by myself. Persistent Session is the anwer. I was looking for persistent subscription and wasn't initially successful...
Here is finally great article about my case:
http://www.hivemq.com/blog/mqtt-essentials-part-7-persistent-session-queuing-messages
So yes, persistent subscriptions is called persistent sessions and yes it is possible.
The Arduino Ethernet (board or shield) supports a maximum of 4 connections. If acting as a server, it is very easy to cause a denial of service: just open 4 connections to the Arduino without sending any data. The server code will never realize that connections were established, as the EthernetServer::available() method only returns an EthernetClient when the connection has data available. The connections will thus remain open for as long as the client maintains them, preventing the Arduino from processing other requests, without an opportunity for the server to close them after some time.
So the question is: is there a way to set a timeout on idle connections, maybe at the Wiznet chip level?
As background information, the GET HTTP model of a dialog is called "stateless" what this means is that the connection can be closed and then re-opened with no loss of information.
However, there is an HTTP keyword where the browser can ask to keep a connection open.
The server is allowed to close a connection, in fact HTTP/1.1 defines a message from the server to browser that does just that.
So, in an Arduino where you control all of the software (TCP/IP stack and server code), then you should be to modify the WizNEt libs or add your own wrappers that time-out a dialog and close it, independent of what the browser is doing.
Thus, no DNS (or at least the keep the line open style of DNS).
Get the HTTP/1.1 spec (it is on the web) for more information and specifics.
I would want to send a message from the server actively, such as using UDP/TCPIP to a client using an arduino. It is known that this is possible if the user has port forward the specific port to the device on local network. However I wouldn't want to have the user to port forward manually, perhaps using another protocol, will this be possible?
1 Arduino Side
I think the closest you can get to this is opening a connection to the server from the arduino, then use available to wait for the server to stream some data to the arduino. Your code will be polling the open connection, but you are avoiding all the back and forth communications to open and close the connection, passing headers back and forth etc.
2 Server Side
This means the bulk of the work will be on the server side, where you will need to manage open connections so you can instantly write to them when a user triggers some event which requires a message to be pushed to the arduino. How to do this varies a bit depending on what type of server application you are running.
2.1 Node.js "walk-through" of main issues
In Node.js for example, you can res.write() on a connection, without closing it - this should give a similar effect as having an open serial connection to the arduino. That leaves you with the issue of managing the connection - should the server periodically check a database for messages for the arduino? That simply removes one link from the arduino -> server -> database polling link, so we should be able to do better.
We can attach a function triggered by the event of a message being added to the database. Node-orm2 is a database Object Relational Model driver for node.js, and it offers hooks such as afterSave and afterCreate which you can utilize for this type of thing. Depending on your application, you may be better off not using a database at all and simply using javascript objects.
The only remaining issue then, is: once the hook is activated, how do we get the correct connection into scope so we can write to it? Well you can save all the relevant data you have on the request to some global data structure, maybe a dictionary with an arduino ID as index, and in the triggered function you fetch all the data, i.e. the request context and you write to it!
See this blog post for a great example, including node.js code which manages open connections, closing them properly and clearing from memory on timeout etc.
3 Conclusion
I haven't tested this myself - but I plan to since I already have an existing application using arduino and node.js which is currently implemented using normal polling. Hopefully I will get around to it soon and return here with results.
Typically in long-polling (from what I've read) the connection is closed once data is sent back to the client (arduino), although I don't see why this would be necessary. I plan to try keeping the same connection open for multiple messages, only closing after a fixed time interval to re-establish the connection - and I hope to set this interval fairly high, 5-15 minutes maybe.
We use Pubnub to send notifications to a client web browser so a user can know immediately when they have received a "message" and stuff like that. It works great.
This seems to have the same constraints that you are looking at: No static IP, no port forwarding. User can theoretically just plug the thing in...
It looks like Pubnub has an Arduino library:
https://github.com/pubnub/arduino
I have a multi-process TCPServer which creates (by fork() on linux) one process (child) per client's request, and in the meanwhile it is listening other connection's request. So I have a 1 to 1 mapping between client and server.
Suppose that one client crashes...is it possible to reconnect it to the same child server process?In other terms..is it possible to restore a pre-exhistent connection which is failed or the attempts to reconnect create a new connection (and then a new child server process)? thank you...
Without some knowledge (by the forker) of the interior session-related details (of the forkee), you have to make assumptions about external details being adequate to determine which remote connections get re-associated with which local connection end-points.
You could change the way things work in your application, though. Oracle SQL*Net does this on some platforms (due to platform limitations).
The initial connection to the TCPServer causes a fork and then opens up a new listening socket, sends back a redirection instruction to connect to the new listening socket & identifying details (to avoid someone else connecting and impersonating the original connector). The client then connects to the new socket, and uses this socket to do any re-connections upon disconnects before their time.
I have done something very similar to this in .NET platform. If you have something which is unique for every connection (for example IMEI of the connecting device this can be done).You should have some global two-dimensional array variable with combination of ProcessID and IMEI. So when device is disconnected and then the device reconnects you only search in this array for this IMEI and you have the process for this device. You should be very carefull with this global variable.
Edited:
I gave an example of some unique identifier. In my case that was the IMEI of the devices. In your case that could be something else which you know it is unique.
I had to do this because I had very big problem with devices breaking up the connection. Every new device was new connection so afterward I ended up with very big CPU usage.
Maybe you can refer https://eternalterminal.dev/howitworks/. Both the client and the server need change.