Getting Wi-fi network response time on android - android

I want to get an access point response time.
I notice that last API has a public long timestamp in class ScanResult.
Unfortunately, I want something that can run over 2.3+.
It's possible to get the "Probe Response" packet of an access point? And so getting the complete packet information, like time, etc.?
I've searched over SO and googled a lot, but I've not found a simple way to send a custom packet over network, or how to receive it.
I would appreciate any hints!
Thank you

Related

Bluetooth Packet Payload Missing in WIreshark

I am trying to get at the Bluetooth data needed to control my Bluetooth lamp. I have created the bt_snoop file after successfully controlling my lamp through the app. I've done this many times and I always get the same result.
When I open bt_snoop in Wireshark and filter for my device all of the data has a warning: "[[Expert Info (Warning/Malformed): Length too short]". It also says "Payload: MISSING". I am able to control the light through the app, but the bt_snoop log just shows that error. I'm really lost and would really appreciate help!

Error codes in Nearby Connections 2.0

I've been experimenting with the new Android Nearby Connections v2.0 API. Most of my devices can now talk to each other most of the time, but I also get a lot of error codes back when trying to connect. Checking status.getStatusCode() inside my program, I can see the following return codes:
STATUS_ALREADY_CONNECTED_TO_ENDPOINT (8003)
STATUS_BLUETOOTH_ERROR (8007)
STATUS_ENDPOINT_IO_ERROR (8012)
STATUS_ERROR (13)
I'm having a hard time making sense of these. The first error code seems self-explanatory, except that I see it in cases when I haven't hit the onConnectionResult callback with a "SUCCESS" return code on either side of the alleged connection. My current code is full of trace statements, and I'd see logging entries if those callbacks had been reached. So maybe the devices are connected at some lower level, but if so, the higher-level code doesn't always hear about it.
I'm guessing that STATUS_BLUETOOTH_ERROR indicates a Bluetooth error on the side that logs it, while STATUS_ENDPOINT_IO_ERROR indicates an error (probably involving Bluetooth) on the other end? Is it possible to get any more details?
The STATUS_ERROR (13) status that I see once in a while sounds like the sort of error code a programmer would use for those "WTF, we should never get here" moments, but without access to the source code, I can only guess.
Note that I see these errors between devices that talk to each other beautifully at other times, using the same code. Sometimes if the code retries enough times, it eventually gets a stable connection. Sometimes it connects and gets instantly disconnected from the other end. Sometimes I just get an endless stream of repeated error messages (STATUS_BLUETOOTH_ERROR and/or STATUS_ENDPOINT_IO_ERROR).
I'm using Nearby Connections with the connection strategy P2P_CLUSTER. These problems seem to happen most often when both sides do both advertising and discovery. However, I wrote two smaller programs that specialize in either advertising or discovery, and they sometimes get these errors too (but less often).
In the trace messages, I've also noticed lots of warning messages from Nearby Connections that look like this:
09-04 22:54:40.070 3866-3924/? W/NearbyConnections: Cannot deserialize BluetoothDeviceName: expecting min 16 raw bytes, got 6
I'm guessing that this is because Nearby Connections uses its own short tokens (like ZGbx) instead of the device Bluetooth name? I'm not at all sure about that, though. And anyway, if these are Nearby Connections' own special tokens, then why would it be issuing warning messages about it?
[Disclaimer: I work on Nearby Connections] I can try and help out.
STATUS_ALREADY_CONNECTED_TO_ENDPOINT: This occurs if you call 'requestConnection' while you have any pending (onConnectionInitiated) or established (onConnectionResult) connections to the given endpoint. Move your log statements earlier, to onConnectionInitiated, and you should see why we throw this error.
STATUS_BLUETOOTH_ERROR: Something went wrong with Bluetooth. The phone is probably in a bad state. This (hopefully) shouldn't happen too often. But if you really want a fix, stop advertising & discovery before reattempting requestConnection. Nearby Connections will toggle Bluetooth when it detects this error, but only if nothing else is going on.
STATUS_ENDPOINT_IO_ERROR: We lost connection to the other device. This can happen for a variety of reasons (they could have walked too far away, Bluetooth was flaky, the device stopped responding, etc). If you're discovering while you have connections, avoid that. Discovery can be hard on the phone and reduces bandwidth at best, causes dropped connections at worst.
STATUS_ERROR: Something went wrong that didn't fit well in the other error codes. It's a catch-all. This is most-often returned in onConnectionResult(FAILED), to notify you that something went wrong in between onConnectionInitiated and waiting for both sides to accept the connection.
We've also lowered the log severity of "Cannot deserialize BluetoothDeviceName" in an upcoming release, since it's not really a warning. It's like you said; expected behavior when we see non-Nearby Connections devices while discovering.
If you continue to see problems, let us know what devices you're using and we'll be sure to add them to our test suite.
I just want to add that it may be necessary to have a short client name string when calling the API.
E.g., Nearby.Connections.requestConnection(googleApiClient, shortNameHere,....)
I had been generating my own client name with UUID.randomUUID().toString() and that seemed to cause the STATUS_BLUETOOTH_ERROR.
All I did was change the code sample to use a UUID name and to use P2P_CLUSTER and I got that error.
This was the solution for me regarding the STATUS_BLUETOOTH_ERROR.

It takes too long to read data from the bluetooth chip

I'm working on a project which using bluetooth to send two bytes data to HC-05 module and receive from it. Everything is going well but there's one thing that I can't bear with, which is stated below.
I use System.currentTimeMills() to get the time interval between sending data and receiving ,and it takes no more than 1ms`` to detect whether there's data in the buffer ofinputStream. However, it takes about30~200msto readtwo bytesof data from thebluetooth` chip on my cell phone.
Dose anyone know how to reduce the time ? Or it's insolvable?
The primary bottleneck should be the protocol scheduling. I don't know how this particular module works, but in Bluetooth in general you have to wait for your timeslot to send or receive.
Suggestions:
Check if you can send more than 2 bytes at the time. The read time is stable, but you get more data transmitted each time.
Check if the API gives you scheduling options, so the wait time goes down.
For your use case I think things would be simpler with Bluetooth low energy (BLE). You will need another module, but IMO it is worth it.

Sending an MMS programatically to Metro PCS MMSC (via Nokia Implementation)

This is my first post so my apologies in advance if this is the wrong site to post this particular question to.
Question
I have integrated Nokia's MMS implementation for android (http://androidbridge.blogspot.com/2011/03/how-to-send-mms-programmatically-in.html) into an android application I am writing and I am able to send MMS's from my personal Metro PCS device to Metro PCS's MMSC and messages are delivered to any recipient without issue.
This is how I am sending the MMS:
public Boolean sendMMSMessage(final String senderNumber, final String smsText, final File imageFile, final Integer requestId){
byte[] out;
Enumeration keys;
//set image File
setImageFile(imageFile);
//create MMMessage
setMMMessage(new MMMessage());
//add text
addText(getMMMessage(),smsText,"<0>",IMMConstants.CT_TEXT_PLAIN);
//add image file
addFromFile(getMMMessage(),getImageFile(),"<1>",IMMConstants.CT_IMAGE_JPEG);
//set MMEncoder
setMMEncoder(new MMEncoder());
getMMEncoder().setMessage(getMMMessage());
//transaction ID (second parameter) is arbitrary
setMessage(getMMMessage(),"T135d743a6b7",senderNumber);
try {
getMMEncoder().encodeMessage();
out = getMMEncoder().getMessage();
setMMSender(new MMSender());
getMMSender().setMMSCURL("http://mms.metropcs.net:3128/mmsc");
//'min' of sending device. Required by Metro PCS MMSC.
getMMSender().addHeader("X-DEVICE-MIN", min);
setMMResponse(getMMSender().send(out));
} catch (Exception e) {
System.out.println(e.getMessage());
return false;
}
return (getMMResponse().getResponseCode()==IMMConstants.HTTP_RESPONSE_OK);
}
I am wondering if it is possible to 'tweak' Nokia's code (if this is necessary) such that any device can send a properly constructed MMS request to Metro PCS's MMSC using my 'min' credentials. I have studied the packet flow (via 'WireShark') of what occurs when an MMS is successfully sent from my particular device to other recipients however when I run this same android app. on another device (a non-Metro PCS device), MMS messages fail to send and 'WireShark' is not helpful in explaining why. Can anyone help lead me in the direction of how I might make this work?
Update: It may help to add that logcat reports:
java.net.SocketTimeoutException: Connection timed out
Second Update: I took a look at another post regarding this issue. It is titled "Android sending image via MMS programatically(Operation timed out)" but unfortunately there currently is not a definite answer and this question has been live for two months. I will try increasing the read 'timeout' as someone suggested (I doubt this is the cause) but if anyone DOES know what the problem might be but simply wishes not to provide a direct answer this is fine. I just need a hint of where to look.
Third Update: Now that I think about it, I wonder if the senders IP address (the actual IP address used by the device) constitutes a factor here. Can anyone confirm?
Fourth Update: I just took a closer look at the code for 'MMSender.java' (specifically at whats going on with the 'HttpURLConnection' object) and according to its setReadTimeout(ms) method, the default value ('0') establishes an infinite wait time anyways and this method is not called anywhere in the code. Just for kicks, however, I manually set this value to 1 minute for both setConnectionTimeout(ms) and setReadTimeout(ms) and as I suspected, no dice. Same connect timeout issue.
Final Update: Sorry. I just realized that I copied this line of code from another posting some time ago:
((ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE)).startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,"enableSUPL");
and now after looking at this call more closely, I wonder if it is possible that I am supplying incorrect parameter values to startUsingNetworkFeature() (at least for the non-Metro PCS device I am trying the application on). I don't want to overkill my 'updates' here for this question but I want you guys (or gals) to be well informed so...; if these parameter values do turn out to be the problem, I will definitely post that fact but this will be my final update. In the mean time, any advice is greatly appreciated.

Doing something just BEFORE wifi disconnection

I understand that on a wifi network there are sudden disconnections which prevent me from sending messages to my server.
But sometimes there's still one last chance before the disconnection, for example if the signal is low or the user is trying to turn off the wifi. On those occasions I would like to send a logout message to my server.
How do I detect disconnections like those?
I tried to retrieve changes of connectivity by registering a broadcast listener:
registerReceiver(this,new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
...
public void onReceive(Context context, Intent intent) {
NetworkInfo info = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
if( (info.getState()== State.DISCONNECTING) && (info.getType() == ConnectivityManager.TYPE_WIFI) ) {
//send logout
}
But it looks like at that time it's already too late. My logout message doesn't go through.
Is there a better way?
[Update 1]
I also tried:
if( (info.getDetailedState()== DetailedState.DISCONNECTING) && connectionTypeOK ) {
[Update 2 - SOLUTION]
The solution is, as stated below, using a combination of receiving the RSSI_CHANGED_ACTION and WIFI_STATE_CHANGED_ACTION broadcasts to monitor the signal strength and the WIFI_STATE_DISABLING events respectively. When this happens, I send my logout request. This works exactly as I needed. Thanks!!
You could try to implement a variable "heartbeat" function, by using WifiManager to detect changes in signal strength. Here you can find some related code, btw.
Now, once you receive a RSSI_CHANGED notification, according to the corresponding signal strength, you will update the frequency of your app's "heartbeats" to the server: if the signal is strong, you will only need to notify the server infrequently that the app is alive. Once the signal becomes week, however, just like adrenaline kicking in for a real live being, so should your app notify the server more frequently. If the signal's strength recovers, you'll send a specific message to let the server know everything is all right again; if, however, the server does not receive this message in a certain period of time and the "heartbeat" stops - your app ceases notifications for that amount of time - then the server logs it out until receiving from it again.
If you're based on TCP connections, the server should know when a session disconnects unexpectedly - it will get an RST or FIN packet, depending on the router configuration between the client and server.
There's no need to do anything from the client's point of view - TCP connections are designed so you can know when they're interrupted.
Why don't you have the server regularly ping the client, at certain intervals, and just log out if it doesn't get a response? Trying to make this happen through client side will be cumbersome.
A better way is not to have sessions at all, if possible.
Why is it a problem if the user doesn't log out?
Maybe this is a long shot.. but why don't you use Google push notifications to start an activity if wifi is on. That would tell the server that the phone is "online". If that doesn't happen in X seconds or 1 minute ou whatever, redirect it to somewhere else.
I would implement a handler on the server that handles when the client is not able to receive a message. After each message the phone could send a message back to the server saying it successfully received the message.
are you looking for a good way for users to send / receive data after a disconnection?
HTML5 has a local storage (with a good file size too) so if a user is attempting a huge form, you first save it locally and then attempt to send it to server. if failed when the user loads the page again, you can first check if the file has some content, and if so, you can send that data, clear the content and proceed accordingly.
may be this will help you out http://www.html5rocks.com/tutorials/appcache/beginner/
or look at the local storage tutorial: http://www.youtube.com/watch?v=h0uZIljjElo
using this you could save frequent status data and modify it on the fly.
and Android should support HTML5 too.

Categories

Resources