Android MQTT , Client presence How to know setWill is working? - android

I am using below code to connect to MQTT server
MqttConnectOptions options = new MqttConnectOptions();
options.setCleanSession(true);
options.setKeepAliveInterval(Constants.CLOUD_KEEP_CONN_ALIVE);
byte[] payload = String.valueOf(0).getBytes((Charset.defaultCharset());
options.setWill("willTopic", payload, 0, true);
mAndroidAsyncClient.connect(options, this);
Once connected I get a callback . Now my question is how to debug in server , that setWill is working using mosquitto_sub .
I am using setWill to know client presence.
To confirm setWil is working I wanted to debug from server by subscribing to willtopic and get logs .
I tried connecting and disconnecting many times but there is message sent over will topic.
Command I used on server is
mosquitto_sub -t appTopic --will-topic willTopic
It will be helpful if anyone share the command or way to debug Mqtt setWill.
I tried referring to How to Find Connected MQTT Client Details . But it did not workout for me.

The only real way to test that the LWT (Last Will & Testement) message gets sent is to make the broker send it.
To do this you will have to cause a none clean shutdown of the client, given this is on android the easiest way would be to run the app in the emulator, let it connect then kill the emulator (You have to do this because last time I tried to get the emulator to disable all network activity I discovered it just sent the Network Down broadcasts but left the network up). Once the keep alive period expires and the broker notices the client has gone it should publish the LWT message and you should be able to see this with mosquitto_sub.
There may be ways to query the broker for a given LWT message but this would be totally dependant on the broker you are using. I'm not aware of any brokers that make this easy, but there may be something under the '$SYS/#' topic tree on brokers that support that interface.
EDIT:
Also when using mosquitto_sub you should just be using the -t not --will-topic. --will-topic is the topic that mosquitto_sub would publish it's own LWT on if it was disconnected. You can have as many -t options as you need, and -v will print the topic name before the message body so you can tell them apart
mosquitto_sub -v -t appTopic -t willTopic

Related

Bluetooth SPP: Bluetooth SPP Pro (Android) vs. Microchip SmartData (iOS)

All,
I am attempting to communicate, over an SPP profile, with an RN4678 Bluetooth chip connected to a microcontroller.
I never have a problem with the Android app. I can always pair (if not paired), connect, send messages to the chip, and disconnect. An example session is below:
%CONNECT,AB9876543210%
%RFCOMM_OPEN%
%TEST% <-- Message sent using the keyboard ("Byte Stream Mode" option)
%RFCOMM_CLOSE%
%DISCONN%
With the iOS app, I can always pair (if not paired), connect, and disconnect. However, if I cannot send a message to the chip. An example session is below:
%LCONNECT,499B107AB1B5,1%
%LSECURED%
<-- Here I try to send a message, but it is never received
%DISCONN%
The funny thing is that if I first connect/disconnect using the Android, and then I connect using the iPhone/iPad, reception is successful !!!!
%LCONNECT,499B107AB1B5,1%
%LSECURED%
%TEST% <-- Yeah !!! Microcontroller receives the message
%DISCONN%
As far as I know, that path for the processing is the same ... In other words:
if(msg equals "RFCOMM_OPEN" or msg equals "LSECURED")
go to state that monitors incoming messages
I, therefore, kindly ask the following:
1 - Have you encountered anything similar? Do you have any hints? What could the Android App possibly do that the iPhone app is not doing? What am I overlooking or not understanding?
2 - Are you aware of an app that works for both iOS and Android? What I mean, designed by the SAME guy/company?
If you need more info, please ask. I simply did not want to be too 'verbose'.
Thank you for your assistance.
Sincerely,
Vincenzo
All,
At my job we have been playing with two RN modules: the RN4677 (we started with this module) and the RN4678.
The module allows the user to enter (and exit) a command mode. The RN4677 allows bidirectional communication with a manager while still in command mode. The RN4678 does NOT allow bidirectional communication with a manager while still in command mode.
All I needed to do was exit command mode (by issuing the command '---\r'). Now both modules work with Windows/Android/iOS ...
To summarize:
command "$$$\r" to enter command mode
various commands, requests for settings, ...
command "---\r" to exit command mode (a must for RN4678)
Everything will now work fine for both modules
I must say ... that was painful to troubleshoot ...
Sincerely,
Vincenzo

Stream resumption in ejabberd is not working

First Case:
I am using PSI client in Ubuntu 16.04 LTS and my ejabberd version is 16.03.
I am facing message lost issues hence i have gone through this link for stream management : http://xmpp.org/extensions/xep-0198.html
When i send following request
<enable xmlns='urn:xmpp:sm:3' resume='true'/>
Server response is ok for me, i.e
<enabled xmlns="urn:xmpp:sm:3" id="g2gCbQAAAANELTVoA2IAAAW+YgAMmKxiAAnx/A==" max="300" resume="true"/>
After some chatting with other user, when i send following Stream resumption request :
<resume xmlns='urn:xmpp:sm:3'
h='0'
previd='g2gCbQAAAANELTVoA2IAAAW+YgAMmKxiAAnx/A=='/>
I got the following error:
<failed xmlns="urn:xmpp:sm:3"><unexpected-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/></failed>
I have tried all the ways like disconnect the network, kill application and offline the user. But stream resumption is not working.
I am not getting the problem, Please help me.
Second Case:
When i use following configuration in ejabberd.yml:
listen:
port: 5222
module: ejabberd_c2s
resend_on_timeout: if_offline
stream_management: true
And start chatting after enables stream management. Then for the case of network disconnect and application kill, My all messages are storing in the offline queue (if i am not able to reconnect within 300 sec). In this process no one message is lost.
But my problem is this process is work only for mobile (ejabberd_c2s module). Web or Bosh is not supporting the stream management (ejabberd_http module). How can i use stream management for Bosh or web?

Pubnub+Python SDK on an Ubuntu Azure-hosted machine. Connection problems

I am experiencing a bad behavior of Pubnub in the following scenario:
Pubnub SDK for Python as a subscriber
Python 3+Django on Ubuntu 14.04
Ubuntu machine hosted on Azure
Android Pubnub client as a publisher
It seems to be that, at a certain point, the Pubnub connection on the server side becomes stale, that is, any message sent from the client is not received by the subscriber.
I have noticed that there are some errors on the log related to pubnub connection:
WARNING 2015-09-30 17:21:24,778 connectionpool 26551 139638563919616 Retrying (Retry(total=0, connect=None, read=None, redirect=None)) after connection broken by 'ReadTimeoutError("HTTPConnectionPool(host='pubsub.pubnub.com', port=80): Read timed out. (read timeout=320)",)': /subscribe/.../.../0/...?uuid=...&auth=...&pnsdk=PubNub-Python/3.7.3
After about 5 minutes, the message is received and correctly processed.
I guess that the root of the problem lays in the way Azure manages long http connections, as:
The problem does not arise on my local machine, which has the very same OS version and the same stack
There is an obscure 'azure' parameter in the Python SDK. I tried to activate it without any noticeable difference
As a test I added two more subscribers on my pc and they both receive messages instaneously
Thanks.
It seems to be that the root cause is the fact that Azure cuts HTTP connections above 4 minutes (https://azure.microsoft.com/it-it/blog/new-configurable-idle-timeout-for-azure-load-balancer/).
On the other hand, though, Pubnub creates connections with 5 minutes timeout (320 seconds, see https://github.com/pubnub/python/blob/master/pubnub.py#L1881).
Unfortunately, the Pubnub 320 seconds timeout can not be changed, whereas the Azure timeout seems to be modifiable only via Powershell scripts (uncomfortable, especially if you do not have a Microsoft Window machine).
All in all, I changed the Pubnub source code with a 120 seconds timeout and now everything is going pretty well.
It would be advisable to:
Document that on Pubnub side
Modify Pubnub so that the 320 seconds timeout can be changed
Improve the Azure interface in order to change the timeout parameter without using Powershell
If there is anything that can be done from the PubNub SDK, look at this:
Azure flag on init
https://github.com/pubnub/python/blob/master/pubnub.py#L2112
https://github.com/pubnub/python/blob/master/pubnub.py#L2141-L2146
Linux platform
And this should be getting called if Azure is running on linux:
- https://github.com/pubnub/python/blob/master/pubnub.py#L69-L77
Let me know if that helps any.

Google cloud messaging GCM through proxy

I am having trouble sending a message to a device through the company proxy.
I have done the GCM tutorial on the google site and have successfully registered a device on the google servers with the android emulator,
and also on the server at my end.
For this I had to go through the company proxy, setting it in the access point of the emulator.
Now the problem I have is sending a message from my server to the device through the same proxy.
I am using the servlet code from the demo which uses the
com.google.android.gcm.server.Sender
helper class to send the message.
I am running the servlets on tomcat 7.
I have tried setting the proxy up in the catalina.properties file like so.
http.proxyHost=proxy.company.com
http.proxyPort=8080
And I have tried setting properties inside the servlet itself like below.
System.setProperty("http.proxyHost", "proxy.company.com");
System.setProperty("http.proxyPort", "8080");
But still I get the timeout.
I know its the company proxy because I got the messaging working at home where I have no proxy.
I have seen a proxy object created in the java code and then a connection created with it, but I dont think that is usable here since I am using Sender helper class to send the message.
This is the line that fails in a timeout.
Result result = sender.send(message, registrationId, 5);
Any help would be appreciated.
Regards
Bill
Alright, I finally have it working. In my comment I mentioned that I had succeeded in sending out the message, but the emulator was not recieving it. I had forgotten to follow my own earlier advice and run the emulator from the command line with the proxy parameters set like so:
emulator.exe -avd avd22google -http-proxy proxy.company.com:8080 -debug-proxy
So to summarise, my initial problem was that I had registered the emulator on the with GCM and with my local server, but the when I clicked send message I was getting a timeout.
I initially thought it was the firewall so I did some research and set up the proxy in tomcats catalina.properties file.
This made no difference.
I used the "Charles" web proxy debugger software to see where the message was attempting to be sent to and it came up with https://android.googleapis.com:443
So I initially I added the following to my catalina.properties file:
https.proxyHost=proxy.company.com
https.proxyPort=443
It still did not work. A colleague of mine told me that our company proxy handles all types of requests through port 8080, so I changed the the poort line to:
https.proxyPort=8080
This allowed the message to be sent out.
But then the message was not getting through to the emulator and I was receiving the following error in LogCat.
[GTalkConnection.12] doConnect: caught XMPPError connecting to mtalk.google.com:5228.: -- caused by: java.net.SocketException: The operation timed out
Then I remembered that you need to start the emulator with the command line to get it to use the proxy. Once I did this a flood of messages appeared on my emulator!
So I finally have it working end to end. It's taken me about a week to get GCM fully working within my company firewall, so hopefully this post can help some other poor sod doing this in the future.
cheers
Bill

Android sipdemo timeout when making calls

Having a problem with the android sipdemo timing out when making calls. The native sip client on the phone has no issues calling, works perfect. Its When i initiate the call within the sipdemo i get a timeout in the logcat. timeout is set to standard of 30 seconds.. a local asterisk box is what its connecting to. Registers fine.
I'm having the same problem.
I traced packages in wireshark and here's what I found:
I register to SIP server in SipDemo
I register to SIP server on Desktop (using Ekiga)
I place a call in SipDemo to Ekiga.
INVITE message gets sent to Ekiga
Trying is sent from Ekiga to the server
Ringing is sent from Ekiga to SipDemo
I answer the call on Ekiga client
OK (with session description) is sent from Ekiga to SipDemo. This happens 11 times before Ekiga just gives up
BYE is sent from Ekiga client to SipDemo
Please note that OK is being sent 11 times before Ekiga just gives up and ends the call. This is why the call lasts just 30 seconds.
If you take a look at the RFC here:
http://www.ietf.org/rfc/rfc3261.txt section 13.3.1.4
you can see that the reason Ekiga is giving up on SipDemo client is because it never gets ACK back from SipDemo.
I believe this is android bug, but I can't imagine they could have missed something this basic in their SIP implementation.
In the next few days, I'll try to dig up some answers in android source code...
I'll try see what happens when establishing calls between 2 SipDemo applications. If it works, that means android just ignores ACK all together.
EDIT:
I just tried a call between 2 SipDemo clients. It sends OK 5 times and gives up on the OK, but does not end the call. Interesting behavior :)
EDIT2:
I dug up androids SIP implementation, and I found that ACK should get sent... Even logcat logs this, but I still see nothing in Wireshark. I thought maybe it gets blocked or something, so I ran Shark (like Wireshark for android) on the device, pulled the dump to my laptop, opened it up in Wireshark, and I don't see ACK anywhere. I even looked trough all packets... No filters, just in case I might be filtering it out. Anyways... Here's what I found in android code:
http://hi-android.info/src/com/android/server/sip/SipSessionGroup.java.html
class: SipSessionImpl
method: private boolean outgoingCall(EventObject evt)
in case Response.OK:
you can see this call:
mSipHelper.sendInviteAck(event, mDialog);
In SipHelper, method sendInviteAck, you can see:
if (DEBUG) Log.d(TAG, "send ACK: " + ack);
dialog.sendAck(ack);
Dialog is nist javax.sip, so I don't think there's a need to go further...
I see this message "send ACK" in my logcat when running the application
EDIT3:
I noticed that this issue occurs only with some SIP servers. I now tried opensips, and it works fine. I guess the problem I was having had to do with the server responding to androids keep-alive OPTIONS messages with 404 Not Found. Then, android tried to not use the server as soon as possible. Because of that, as soon as android got the address of its peer client, it tried to send a direct message, and failed
Hard to tell just like that. Try capturing the packages with wireshark, filter for the SIP protocol and have a look at what is sent over the network. Also try it with the native client and compare it to the sipdemo.
Another starting point is the log of your asterisk instance (systemlog)
If you can't figure it out yourself, post the results here.

Categories

Resources