send UDP messages from Wear OS via Bluetooth - android

My goal is to send a UDP message (smaller than 100 bytes) from a SmartWatch (running wear os 2) to an Arduino on the same network. As long as the SmartWatch stays connected to the wifi (ip address of the watch: 145.167.189.23) this works great.
But when I turn on bluetooth, the SmartWatch disables wifi and switches to an internet connection via the bluetooth connected phone.
The SmartWatch gets an ip address in a subnet of the internet connection from the mobile (if the mobile has the ip address 145.167.189.105, it gets 145.167.177.4). TCP requests, like 'stackoverflow.com' work fine.
If I now try to send a UDP message nothing arrives at the Arduino.
I already tried to send a UDP message to 255.255.255.255, 145.255.255.255, 145.167.255.255, 145.167.189.255, but nothing ever arrived at the Arduino ( verified by Wireshark).
Over six years ago there was the same problem (Simple UDP Broadcast not working on Android Wear), at that time wear os 2 was not available. The only proposed solution was the 'Wear Data Layer'. I already tried this as well, but observed very large latencies (about 3 seconds). Therefore, these do not represent a solution for me at all.
The documentation for network access on wear os only says
You can use protocols such as HTTP, TCP, and UDP
Maybe someone could give me a hint why the UDP messages are not forwarded from the phone.

Only DNS udp packages can be forwarded to the phone.
It setup some iptable rules to forward udp packages to the TPROXY. Look at the following rules (iptables -t mangle -L). It does't forward udp packges to Reserved IP addresses.
Chain oem_CW_PROXY_UDP (22 references)
target prot opt source destination
RETURN all -- anywhere 0.0.0.0/8
RETURN all -- anywhere loaclhost/8
RETURN all -- anywhere 100.64.0.0/10
RETURN all -- anywhere 127.0.0.0/8
RETURN all -- anywhere 169.254.0.0/16
RETURN all -- anywhere 172.16.0.0/12
RETURN all -- anywhere 192.0.0.0/29
RETURN all -- anywhere 192.0.2.0/24
RETURN all -- anywhere 192.168.0.0/16
RETURN all -- anywhere 198.18.0.0/15
RETURN all -- anywhere 198.51.100.0/24
RETURN all -- anywhere 203.0.113.0/24
RETURN all -- anywhere 224.0.0.0/4
RETURN all -- anywhere 240.0.0.0/4
RETURN all -- anywhere 255.255.255.255
TPROXY udp -- anywhere anywhere TPROXY redirect 0.0.0.0:35070 mark 0x1/0x1
The TPROXY will forward the reveived udp packcages to the phone throught bluetooth socket. But it will only forwoard DNS packages, which can be seen from the watch's logcat.
It seems that Wear OS decided to only forwoard DNS packages at some time.
05-20 12:20:31.269806 1263 5866 D HOME : [ClockworkProxyUdp]Got packet with 47 bytes, from: /192.168.167.239:36215 original dst: /8.8.8.8:53
05-20 12:21:05.264492 1263 5866 D HOME : [ClockworkProxyUdp]Got packet with 47 bytes, from: /192.168.167.239:63348 original dst: /8.8.8.8:53
05-20 12:21:05.272685 1263 5866 D HOME : [ClockworkProxyUdp]Got packet with 32 bytes, from: /192.168.167.239:34219 original dst: /8.8.8.8:53
05-20 12:21:38.282089 1263 5866 D HOME : [ClockworkProxyUdp]Got packet with 47 bytes, from: /192.168.167.239:54529 original dst: /8.8.8.8:53
05-20 12:21:38.287255 1263 5866 D HOME : [ClockworkProxyUdp]Got packet with 32 bytes, from: /192.168.167.239:58688 original dst: /8.8.8.8:53

Related

Why am I sending an RST if my socket is connected and not closed?

I have an Android device that communicates wirelessly with a PC, using a java.net.Socket. Everything hums along fine, but if I do nothing (i.e., no network use) for exactly 1 minute then when the Android sends a packet of data to the PC the PC receives it and sends an ACK, but the Android responds with an RST.
From Wireshark ( 10.1.2.1 is the Android, 10.1.2.11 is the PC)...
356 0.112470 10.1.2.1 10.1.2.11 TCP 97 34360→181 [PSH, ACK] Seq=1
Ack=1 Win=4935 Len=31 TSval=156103571 TSecr=320673352
359 0.000011 10.1.2.11 10.1.2.1 TCP 66 181→34360 [ACK] Seq=1 Ack=32
Win=260 Len=0 TSval=320738236 TSecr=156103571
360 0.000304 10.1.2.1 10.1.2.11 TCP 60 34360→181 [RST] Seq=32 Win=0
Len=0
At this point if I interrogate the socket's member variables it says . . .
isConnected = true
isCreated = true
isInputShutdown = false
isOutputShutdown = false
isClosed = false
isBound = true
... which looks like I should still be receiving packets just fine. So how do I figure out why I'm sending RST?
N.B. - there are no settings to "sleep" or turn off the wifi or display or any other battery-saving features set enabled on this device.
The 1 minute delay looks like a timeout. It may be the SO_TIMEOUT but this does not generate network activity on itself. Also the fact that the last packet sent contains 31 bytes of data seems to indicate that the application is involved. A possible scenario would be :
The android application times out (on its own or triggered by a socket's SO_TIMEOUT)
It sends a last chunk of data, e.g. by flushing an output stream.
It closes abruptly the socket, for example by using the setSoLinger(true, 0) socket option.
None of those Socket methods returns the state of the connection. They are all about the internal state of the java.net.Socket object, as determined by which constructors and methods you have called on it. They don't magically start returning false if the peer drops the connection.
You will find when you go to use the socket for I/O that you will get an IOException: 'connection reset'.
Why the connection has been reset is another matter. The usual reason is that you had sent to a connection that had already been closed by the peer, or that the peer closed the connection without reading all the data that had already arrived. In other words, an application protocol error. There are other reasons, but these are the most common.
This could be caused by your NAT router that tries to close sockets after a timeout to free up resources. Turning on keep_alive may help. You can also try to create your own network with static IP addresses bypassing the router to rule out this hypothesis.
When the connection is closed the isClosed() method should return TRUE.
It's OK for the isConnected() method to return TRUE even if the connection has been closed because what that method tells you is "if ever you managed to get connected", the variable state is not changed/refreshed when you get disconnected.
However in your case the connection has definitely not been closed as per documentation.
For more info see:
https://docs.oracle.com/javase/8/docs/api/java/net/Socket.html#isConnected--
https://docs.oracle.com/javase/8/docs/api/java/net/Socket.html#isClosed--
Note: It might help you to set to TRUE setKeepAlive(boolean)
See also:
https://docs.oracle.com/javase/8/docs/api/java/net/SocketOptions.html#SO_KEEPALIVE
https://docs.oracle.com/javase/8/docs/api/java/net/Socket.html#setKeepAlive-boolean-
Back to the problem, check for one of the following:
Can you make sure for some reason there isn't another device with
the same IP as the Android? Also turn off you 3G/4G and stay
connected only in the wireless network.
Is there a router doing NAT ? In this case the router can send the
RESET flag.
If everything seems fine (it's your Android phone replying with RST) and the SO_KEEPALIVE does not work then it might be some application level error that is killing the connection.

To discover other device IP:Port in same wifi network using ZeroMQ

I want to discover all Android devices IP and Port in same wifi network using ZeroMQ?
My app basically connect all device in same wifi network (no internet needed) and message to each other. Once ip and port I know I am send message successfully but how to know all device internet Protocol (ip) Using ZeroMQ?
Principle
Part A)
Every IEEE 802.x CSMA/CD network "collision domain" ( wifi AP/SSID is such one ) has to be managed so as to work well. Thus the Address Resolution Protocol [ARP] will help you in the task to find all ISO-OSI-Layer-3 IP Addresses. Wifi Access Point [AP] host, to which all live devices register and handshake with, is the choice to start with.
HG520i> ip arp status
received 54205 badtype 0 bogus addr 0 reqst in 12105 replies 196 reqst out 14301
cache hit 63152696 (24%), cache miss 19455672 (23%)
IP-addr Type Time Addr stat iface
192.168.0.230 10 Mb Ethernet 290 00:15:af:e6:b1:79 41 enif0
192.168.0.62 10 Mb Ethernet 300 00:0c:29:98:d4:3b 41 enif0
192.168.0.55 10 Mb Ethernet 300 00:27:0e:07:c5:9e 41 enif0
192.168.0.255 10 Mb Ethernet 0 ff:ff:ff:ff:ff:ff 43 NULL
num of arp entries= 4
Part B)
Scanning all the ports on all the known IP hosts is a dumb brute force approach to the second issue.
Scanning just a subset of "reasonable" ones would save you both the time and efforts on peer-recognitions.
Using some smarter, active "visibility self-advertisement policy" will save you even more.
Solution
Decide on multi-party system architecture, whether an individual passive scan, a central/distributed proxy-assisted scan or an active self-advertisement policy will be used to build and maintain live records in a neighbouring hosts register.
ZeroMQ per-se brings you a lot of power for the smart solutions, while the dumb-force solutions would have to wait till fully fledged ZeroMQ services will be ready. Low level L2/L3-inspections will have to bring their fruit before ZeroMQ can first .bind()/.connect()
Needless to say, that uncoordinated CSMA/CD networks do not guarantee that all the L2-visible hosts will have "compatible" L3-ip-adddress ( will belong to / have the same L3-ip-network address ).
Thus you never know about all IP addresses without a truly low-level sniffer.

Fragmented UDP packets not received by application

Very strange behavior...
I have 3 machines:
----------- ------------ -----------
| A (x86) |-----| B (x86) |-----| C (arm) |
| sender | | receiver | | sender |
----------- ------------ -----------
A and B are Linux (Ubuntu 12.04) machines, kernel 3.2;
C is an android (ICS) machine, kernel 3.0.8;
All are connected via RJ45 cables;
Connections are OK, network is set up correctly;
Issue is: when machine C (ARM-android) sends a UDP packet which payload size is over 1472 bytes (maximum payload before packet gets fragmented), server application on machine B is never able to receive it, ... regarding that:
Source/Dest IP addresses are correct: I can receive all the datagrams I send if I set the payload size less or equal to 1472;
On machine B (receiver), if I dump network traffic with Wireshark, I can see each fragment, and then re-assembled message => from Wireshark point of view, it's all good!
Comparing each fragment header as well as re-assembled message with what I can dump when the same message is sent from machine A (which is always received OK), everything seems perfect (only differences are IP addresses, and checksum, since UDP header checksum takes in account IP address fields).
There is no MTU issue, packets are fragmented as expected.
There is no router/switch between the machines
ifconfig shows neither packets drop, nor overflows, nor any other classical error!
... this is so weird!!
I've spent some time on Internet, but never found any topic like this one. Each time people has troubles with UDP, either their MTU discovery was not correct, or they did some mishandling in the testing procedure, or they could not dump message on receiver host, ... this is not the case here!!
For sure, I know issue is on sender end (machine C), but maybe is could be easier to enable some logs (at kernel level?) on receiver end to understand why UDP datagram disappears!? Any advice? Are there specific files I could check in /proc/sys/net, or kernel options I should enable?
Thanks a lot.
If your machines are indeed connected as depicted, i.e. they are not connected to switch/hub, then you must have two NICs on B therefore they will have different addresses so the address you use to send to B from A will not be the same as sending to B from C. i.e.
Could the address you are sending to be wrong? Though that would not explain how smaller datagrams get through - are you sure they are?
Note: Theses addresses would have to be assigned manually as you are not connected to DHCP, furthermore these addresses will need to be in the same subnet as A and C. Are all your addresses (A, BA, BC and C) in the same subnet? What address:port is the socket on B bound to and listening on? Does B continue to receive after receiving a datagram? Please provdie some code..
OR, even if your machines are connected to a switch/hub,, is the "Don't fragment" bit set on datagrams sent from C which would explain why larger ones are dropped but not smaller ones.

Dataloss at connection android tablet -> lan - RS232 converter, but not on android tablet ->winpc pc -> converter

i have a big problem and i doubt about my intellect... I connected my android tablet (intenso tab814) to a RS232 converter (USR-TCP232-E) via a router (TL-WR740-N) and i send 7 hexadezimal bytes in a block, kinda 03 20 05... with further numbers. My problem is, if i let my tablet send, the converter receives the data, but does not submit it to a listening program on an pc behind the converter complete. There are often complete blocks missing (bnot single Bytes, but the whole command line i send), but if i send my data via tablet to another PC, and let HIM do the sending work to the converter every single byte arrives. It may be a bit dazzling, but i dont know, where this problem could belong to. My App sends every block correctly (the pc is able to receive)
The converters yellow RJ45 port-LED blinks, but i does not give the data to the listening pc.
For better understand:
Tablet(selfpogrammed app) sends data -> router -> converter (everytime blinks) seldom gives the command -> PC(selfwritten listening programm(not written by me, but by the one, i am the follower of, not familiar with language.)
But if i:
Tablet(same app) -> router -> PC (receives all the data) -> router -> converter always give the data to the listening progamm ->pc
What is the matter here? Why does the converter gives the data from app -> pc to listening pc, but not from app to listenign pc?
Tablet is connected via W-Lan to router, the pc's via RJ45-cable, the converter either. Using TCP/IP converter as server.
PLS HELP Q_Q
EDIT:
configuration:
Baud Rate: 115200bits/second
Data Size: 8 bits/characterParity: None NoneOddEvenMarkSpace
Stop Bits: 1bit(s)
Flow Control: None
Local Telnet Port Number: 2001
Remote Telnet Port Number: N/A
Telnet Mode: TCP Server
Telnet Server IP: N/A . . .
Telnet Timeout: 0seconds seconds (< 256, 0 for no timeout)
UART packet Time: 10ms ms (< 256)
UART packet length: 200
EDIT:
forgot sth to mention. the converter is via RS232 to an USB converter from RS232 to USB connected. Its receiving lamp does not blink, when the listening programm does not show my commands, but if the programm spits my lines out, the USB-part blinks too. So the converter receives, but does not give it to the USB. But only if i use my tablet. Same interval all the time.
Was my own fault, forgot to use a bufferedoutputstream, now it works.

Receiving UDP on different Android phones gives different results

I am willing to create a server and client program on my android mobile devices.
The devices communicate with each other on the same wifi network, therefore, some simple scanning mechanism must be implemented - The client phones search for a server phone through some kind of broadcast.
What I did:
My protocol - the client phone broadcasts a message port p on the wifi, the server listens on port p. when the server gets the broadcast message it sends a message back, therefore discovering itself to the client.
My code -
I have opened a broadcast socket on my app, it sends a broadcast message.
Meanwhile there is a python script on my PC that listens and replies - I use python so that my testing will be easier - Wireshark on the PC and I can see everything.
What happens:
When I use one of my Galaxy S phones - it works and I get a response.
When I use the other Galaxy S phone - it doesn't work.
Now this is what I know:
The phone that works actually has Nexus ROM on it Ver. 4.1.1
The phone that doesn't work has 2.3.3 regular galaxy ROM
The python code says it receives both of the broadcasts sent from both phones, and replies to both of them without raising any exception.
So far I was thought the problem may be
1. the older version'd phone.
2. the windows firewall
3. the router firewall
So I have opened Wireshark, and Indeed I saw that both phones are sending their broadcasts - it was logged on Wireshark.
But the python script only responded to the first one.
So this is why 1 & 3 are irrelevant - if the router firewall was blocking my UDP I would have still seen the python server response, same with the older versioned phone.
To get rid of 2 i just disabled the windows firewall - still same problem.
Does anyone has a clue to why this effect might happen?
Thanks!
Edit
My python code:
def scan(data, addr, sock):
print "received scan message:", data, addr
name = u"name".encode("utf-16-le")
data = "DISC" + short2bytes(len(name)) + name
print "sending back %s to %s" % (data, addr)
sock.sendto(data, addr)
if __name__ == "__main__":
sock = socket(AF_INET, SOCK_DGRAM)
sock.bind(('', UDP_PORT))
while 1:
data, addr = sock.recvfrom(1500)
print "received packet " + data
if data.startswith("SCAN"):
scan(data, addr, sock)
edit 2:
Okay! Seems like my code and protocol DID work.
As it turns out the 2.3.3 phone had some severe ARP problems.
After some resets it works flawlessly!

Categories

Resources