Bluetooth LE Characteristic Write Response - bluetooth-lowenergy

I have an embedded device running BT5 with GATT server setup. On the server I have setup a service with various characteristics to allow a client (PC or Mobile Device) to adjust various parameters of the device by writing to the characteristics.
I would like, for the device to send a response back from the application level for each write. It's not clear to me what the recommended way would be.
I thought about having the client read or subscribe to a general status characteristic, but I want to make sure I am not missing an easier way to do this. I looked at the BT write with response command, but it seems the acknowledgement for that may happen lower than the application.

You should be able to use the Write Response as "application level response". I have not seen any Bluetooth stack where this response is sent at a lower level before the application has processed the request. The reason is probably because the application can even send an Application Error code instead of a Write Response, so it would be stupid to move the Write Response handling to a lower level. Even in Android (if you set up a GATT server) you send the Write Response from the application.
The situation is different with Indications, though, where the Bluetooth stack sometimes sends the Confirmation at a lower level than the application, before it even informs the application that an Indication has arrived, which I find a bit strange and makes Indications kind of pointless compared to Notifications.

I solved this using a Notification characteristic. The client first subscribes to notification events on that CCD, and then every command sent to the host/device is acknowledged by the host firing the notification. To better synchronize command-and-response, you could add an incremental command-id with every command, and have the command-id be part of the notification data that is sent back to the client.
However I implemented this because I needed a response after the device has processed the command, with the results sent back to the client. If all you want to know is whether or not the host has received the command, a Write-With-Response CCD is the way to go.
I looked at the BT write with response command, but it seems the acknowledgement for that may happen lower than the application.
Indeed, the Write-With-Response-Handler is almost always implemented on the BLE stack, not on application level. However I don't see why this would be a problem; you should get error reports by your BLE stack in some form when a Write-with-Response fails. If it's a blocking call it might even return a success-value.

Related

How to receive TCP packets without using terminator or fixed length message

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.

How can a Pinoccio lead scout make a POST request to a remote server?

I'd like my Pinocc.io lead scout to make a POST request (e.g. to inform a remote service of an event that has been triggered).
Note that I don't want to listen to a constant stream the results (as detailed here) as I don't want to be constantly connected to the HQ (I'm going to enable the wi-fi connection only when required to minimize battery usage), and the events I'm detecting are infrequent.
I would have thought that this is a very common use case, yet I can find no examples of the lead scout POSTing any messages.
I posted the same message directly on the Pinoccio website and I got this answer from an Admin
Out of the gate, that's not supported via HQ. Mainly because to get as
real-time performance between API/HQ and a Lead Scout, it makes most
sense to leave a TCP socket open continually, and transfer data that
way. HTTP, as you know, requires a connection, setup, transfer, and
teardown upon each request.
However, doesn't mean you can't get it
working. In fact, you can do both if you wanted—leave the main TCP
socket connected to HQ, and have a separate TCP client socket connect
to any site/server you want and send whatever you like. It will
require a custom Bootstrap, but you can then expose any aspect of that
functionality to HQ/ScoutScript directly.
If you take a look at this code, that's the client object you'd use to open an HTTP connection.
So in a nutshell the lead scout cannot make a POST request. To do so you'll need to create a custom bootstrap (e.g. using the Arduino IDE).

Remote server push notification to arduino (Ethernet)

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

Delay before sending message over socket - how does that help?

I have a tcpip socket interface to a third party software app. I've implemented this interface for several customer sites with no problem. The latest customer, though... problems. We've turned on logging in the apps on either end, and also installed Wireshark on the PC to log raw tcpip traffic. With that, we've proved that my server app successfully sends the message out, the pc receives the message, but the client app doesn't see it. (This is a totally intermittent problem, which is why it's such a pain to troubleshoot.)
The socket details are as simple as they come: one socket handling two way communications between the server and the pc. The messages are plain ascii text and fairly short (not XML). The server initiates communications by sending the first message, and then the client responds with several messages. The socket is kept open at all times while the apps are running. The client app is designed so that the end user can only process one case at a time, which prevents message collisions from happening. They have some sort of polling set up, their app "hibernates" until it sees the initiating message from the server.
The third party vendor has advised me to add a few second delay before I send them the initiating message. I can't see how that helps. If the client is "sleeping", just polling the socket waiting for a message, how does adding a delay before the first message help? It's not like we send two messages and the second one gets lost. It's losing the first message. So I don't see how it matters if we send that message now or two seconds from now.
I've asked them and they haven't given me details. It could be some proprietary details in their coding that they don't want to disclose to me, and that's fair. So I'm asking here because I'm always learning new things about socket programming. Maybe you guys can shed some light on how polling a tcpip socket can be affected by message timing?
Since its someone else's client and they won't tell you what its doing (other than saying 'insert a delay'), the answer is probably that their client is reading and discarding the message because its not yet in a state to deal with it. The delay will allow the client time to get into a state where it can respond to the message properly.
In other words, the client has a race condition. One easy way this can happen is if they have one thread for reading messages and another for dealing with them.
Short of running strace(1) on the client to see what system calls it is making, its tough to tell what the client is actually doing.

Using NetConnection and URLStream to send/recieve data at high frequency

I'm writing a Comet-like app using Flex on the client and my own hand-written server.
I need to be able to send short bursts of data from the client at quite a high frequency (e.g. of the order of 10ms between sends).
I also need the server to push short bursts of data at a similarly high frequency.
I'm using NetConnection.call() to send the data to the server, and URLStream (with chunked encoding) to push the data from the server to the client.
What I've found is that the data isn't being sent/received as soon as it's available. For example, in IE, it seems the data is sent every 200ms rather than as soon as NetConnection.call() is called. Similarly, URLStream isn't making the data available as soon as the server is sending it.
Judging by the difference in behaviour between the browsers, it seems as though the Flash Player (version 10) is relying on the host browser to do all the comms. Can anyone confirm this? Update: This is very likely as only the host browser would know about the proxy settings that might be set.
I've tried using the Socket class and there's no problem with speed there: it works perfectly. However, I'd like to be able to use HTTP-based (port 80) connections so that my app can run in heavily fire-walled environments (I tried using a Socket over port 80, but that has its problems).
Incidentally, all development/testing has been done on an internal LAN, so bandwidth/latency is not an issue.
Update: The data being sent/received is in small packets and doesn't need to be in any particular format. For example, I might need to send a short array of Numbers, and this could either be encoded in AMF (e.g. via NetConnection.call()) or could be put into GET parameters (e.g. using sendToURL()). The main point of my question is really to see whether anyone else has experienced the same problem in calling NetConnection/URLStream frequently, and whether there is a workaround (it's also possible that the fault lies with my server code of course, rather than Flash).
Thanks.
Turns out the problem had nothing to do with Flash/Flex or any of the host browsers. The problem was in my server code (written in C++ on Linux), and without access to my source code the cause is hard to find (so I couldn't have hoped for an answer from this forum).
Still - thank you everyone who chipped in.
It was only after looking carefully at the output shown in Wireshark that I noticed the problem, which was twofold:
Nagle's algorithm
I was sending replies in multiple packets by calling write() multiple times (e.g. once for the HTTP response header, and again for the HTTP response body). The server's TCP/IP stack was waiting for an ACK for the first packet before sending the second, but because of Nagle's algorithm the client was waiting 200ms before sending back the ACK to the first packet, so the server took at least 200ms to send the full HTTP response.
The solution is to use send() with the flag MSG_MORE until all the logically connected blocks are written. I could also have used writev() or setsockopt() with TCP_CORK, but it suited my existing code better to use send().
Chunk-encoded streams
I'm using a never-ending HTTP response with chunk encoding to push data back to the client. Naggle's algorithm needs to be turned off here because even if each chunk is written as one packet (using MSG_MORE), the client OS TCP/IP stack will still wait up to 200ms before sending back an ACK, and the server can't push a subsequent chunk until it gets that ACK.
The solution here is to ask the server not to wait for an ACK for each sent packet before sending the next packet, and this is done by calling setsockopt() with the TCP_NODELAY flag.
The above solutions only work on Linux and aren't POSIX-compliant (I think), but that isn't a problem for me.
I'm almost 100% sure the player relies on the browser for such communications. Can't find an official page stating so atm, but check this out for example:
Applications hosting the Flash Player
ActiveX control or Flash Player
plug-in can use the
EnforceLocalSecurity and
DisableLocalSecurity API calls to
control security settings.
Which I think somehow implies the idea. Also, I've suffered some network related bugs on FF/IE only which again points out to the player using each browser for networking (otherwise there wouldn't be such differences).
And regarding your latency problem, I think that if speed is critical, your best bet is sockets. You have some work to do, but seems possible, check out the docs again:
This error occurs in SWF content.
Dispatched if a call to
Socket.connect() attempts to connect
either to a server outside the
caller's security sandbox or to a port
lower than 1024. You can work around
either problem by using a cross-domain
policy file on the server.
HTH,
Juan

Resources