Change wifi multicast state android

Is CHANGE_WIFI_MULTICAST_STATE permission and use of WifiManager.MulticastLock required to receive multicast packets on Android?

I have a test app that I’m using to demonstrate whether or not multicast traffic is making it into an Android device. I’m seeing behavior that appears to contradict Google’s documentation here and here which implies that two prerequisites need to be in place in order for an app to receive multicast traffic:

  1. Acquire the MulticastLock
  2. Add the CHANGE_WIFI_MULTICAST_STATE permission to the app’s manifest

My app is able to receive multicast traffic without either of these items in place. Below is the code snippet that sets up the multicast socket for receiving data.

MulticastSocket multicastReceiveSocket = new MulticastSocket( 18200 ); multicastReceiveSocket.joinGroup( InetAddress.getByName( "232.232.232.232" ) ); byte[] buffer = new byte[ 65536 ]; DatagramPacket packet = new DatagramPacket( buffer, buffer.length ); multicastReceiveSocket.receive( packet ); 

Should this be happening? Should I be able to receive multicast packets without either of the 2 prerequisites in place? I noticed that the MulticastLock documentation says:

Normally the Wifi stack filters out packets not explicitly addressed to this device

Does this mean that the behavior could be different from one device to another? I’m testing my app on a Samsung Galaxy Note4 (model SM-N910T) running Android version 4.4.4. Any clarification on this issue would be greatly appreciated.

unbrokenrabbit

1 Answers

WifiManager.MulticastLock when acquired, would modify the state of Wifi interface on the device (gobally), to allow all apps to receive multicast traffic. your app will need CHANGE_WIFI_MULTICAST_STATE permission if your app wants to acquire this lock.

In your case, if multicast traffic is received without acquiring this lock, it must mean that either

(1) some other app has acquired this lock, due to which, the interface is now parsing/filtering and delivering multicast packets also.

(2) manufacturer of the device ignored this android api while developing the device, and interface always delivers all multicast traffic.

The description of the API does not force manufacturers to only allow multicast traffic when an app has acquired this lock.

Regardless, apps must acquire this lock if they want to reliably receive multicast traffic.

Источник

Multicast Support on Android in Hotspot/Tethering mode

I have a prototype Android app that is listening for multicast packets to ‘discover’ clients to communicate with. The socket set up is similar to this:

InetAddress group = InetAddress.getByName("228.1.2.3"); MulticastSocket s = new MulticastSocket(4000); s.joinGroup(group); 

This works very well when all the devices are connected via WiFi. I would like to support this with the phone acting as a portable hotspot. However, while all my devices appear to connect to the hotspot correctly I no longer receive multicast data. I’m wondering if there are restrictions that disallow this type of communication in hotspot mode, or if there are is any additional network configuration required to enable this? I’ve tried this on a couple different devices running Gingerbread and Froyo with no luck.

Читайте также:  Wi fi calling apk

I’d love to hear if you’ve managed to solve this problem. The way I understand it is that you require a multicastlock in order to get multicast to work at all. And the only way to aquire one is though the wifimanager. Unfortunately with the device set up as a hotspot it appears that the multicast lock is created on the eth0 interface, while the actual communication is happening at wl0.1 This is as far as I’ve got with this problem, not sure if I’m on the right track.

4 Answers 4

you can find the wlan0 eth by :

public static NetworkInterface getWlanEth() < Enumerationenumeration = null; try < enumeration = NetworkInterface.getNetworkInterfaces(); >catch (SocketException e) < e.printStackTrace(); >NetworkInterface wlan0 = null; StringBuilder sb = new StringBuilder(); while (enumeration.hasMoreElements()) < wlan0 = enumeration.nextElement(); sb.append(wlan0.getName() + " "); if (wlan0.getName().equals("wlan0")) < //there is probably a better way to find ethernet interface Log.i(TAG, "wlan0 found"); return wlan0; >> return null; > 

Have a try and lemme know if it works or not in Hotspot mode.

This makes a wrong assumption that there is an interface on each possible phone type that is named «wlan0» and that it is the correct interface to use. I think a better approach would be to get all interfaces that support multicast, create a new multicast socket for each and send/receive on each concurrently. One should probably also periodically refresh the list of available interfaces and add/remove new multicast sockets accordingly.

Do you have the manifest permission and are you creating a lock?

I’ve had the same problem and came up with a solution by the combination of @braden, @user707606 and the mainly the post by Chainfire in this Link.

Post in the link is nice but doesn’t really offer any code samples but here it’s. First you need to Acquire Multicast Lock, this is needed for some Android devices, didn’t try in most of them but it was mentioned in some other posts, so I’ve included it in my code.

Permission is required, so first, add the permissions into your Manifest file.

Then the second step is to acquire multicast lock in your method.

/* Acquire MultiCast Lock */ WifiManager wifi = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); WifiManager.MulticastLock multicastLock = wifi.createMulticastLock("multicastLock"); multicastLock.setReferenceCounted(true); multicastLock.acquire(); 

And then, find your Wifi Network Interface

/** * Finds Network Interface of Wifi Ethernet. * * @return */ public static NetworkInterface findWifiNetworkInterface() < Enumerationenumeration = null; try < enumeration = NetworkInterface.getNetworkInterfaces(); >catch (SocketException e) < e.printStackTrace(); >NetworkInterface wlan0 = null; while (enumeration.hasMoreElements()) < wlan0 = enumeration.nextElement(); if (wlan0.getName().equals("wlan0")) < return wlan0; >> return null; > 

Later, create a Multicast socket with an available port and set your Wifi NetworkInterface.

MulticastSocket multicastSocket = new MulticastSocket(); /* Set NetworkInterface of MultiCast Socket */ NetworkInterface wifiNetworkInterface = findWifiNetworkInterface(); if (wifiNetworkInterface != null) multicastSocket.setNetworkInterface(wifiNetworkInterface); 

Then the rest of your implementation remains the same. And once you are done with Multicast Lock, it’s recommended to release it.

Источник

Android device not receiving multicast package

I am developing a chat application where Android clients will exchange their IP’s using multicasting(UDP). Every device will send its ip to multiple clients(all the devices running this app) in one separate Thread. There will be another receiver thread which will listen to these multicast packets. Here is my code. //Multicasting code.

DatagramSocket socket = new DatagramSocket(9898); byte buff[] = ip.getBytes(); DatagramPacket packet = new DatagramPacket(buff, buff.length, InetAddress.getByName("224.0.0.1"),9999); socket.send(packet); socket.close(); 
MulticastSocket socket = new MulticastSocket(9999); InetAddress group = InetAddress.getByName("224.0.0.1"); socket.joinGroup(group); DatagramPacket packet; byte[] buf = new byte[256]; byte b = 'x'; //just a separator for time being Arrays.fill(buf,b); packet = new DatagramPacket(buf, buf.length); String received= ""; while(received!=null) < socket.receive(packet); received = new String(packet.getData()); received = received.substring(0,received.indexOf('x')); this.setIp(received); System.out.println("Address: " + received); >socket.leaveGroup(group); socket.close(); 

The problem is every device prints its own address. It seems it never listens to other multicast packages(I mean it should print other ip’s as well). I also get a below log, not sure if that’s related.

11-04 23:56:17.985: I/OSNetworkSystem(603): mcastAddDropMembership interfaceIndex=0 

2 Answers 2

You need acquire a MulticastLock in your app, which will allow your app receive packets that are not explicitly addressed to this device on the network.

// Acquire multicast lock WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE); MulticastLock multicastLock = wifi.createMulticastLock("multicastLock"); multicastLock.setReferenceCounted(true); multicastLock.acquire(); //Do some mutlicast job here . . // Once your finish using it, release multicast lock if (multicastLock != null)

It looks like this is only for wifi multicast packets. I am multicasting over internet(using normal APN, no WIFI). Will it still work?

Читайте также:  Xbox 360 freeboot ftp wifi

@ShashankKadne, I reviewed one of my project recently, which use JmDNS for some multicast operation. The demo version self-publish a mock mdns service and detect it on the device. I actually forget I use to test and run it many times under 3G network. I just double checked the behaviour and I can confirm now WifiManager.MulticastLock works under 3G network (regardless of whether WIFI is turned on/off, with 3G being active in the status bar). Please try it and let me know if this works on your end too.

As you can see, my demo app create and detect the mock mdns service by itself in the same network (regardless of 3G or WIFI). In you case, if the mdns packets (says raised from another network) is reachable in your phone’s network (may need some routing), it should work as expected.

IPv4 multicast support in android is poorely implemented. There are bugs from cupcake era still present.

I ran into a similar problem I was doing a project that relied on mDNS/multicast for service discovery. My Android app would simply not subscribe to the multicast group. I verified this by creating a portable access point on a Ubuntu 14.04 machine and running tcpdump on it. Android devices connected to it simply didn’t emit IGMP messages required for joining a group. I could send packets but not receive them.

What I noticed that I was getting an IPv6 join group message to all-systems whenever I joined the networked. This prompted me to try a IPv6 multicast address and that worked.

Newer android devices support IPv6, which has built-in and mandatory multicast support. So instead of using an Class 4 IPv4 multicast address, modify your code to use an IPv6 address. This will make your code to work on at least the local level.

This page has a wealth of information about which IP to use as per your needs.

Some say that it works without the WiFiManager.crrateMulticastLock() but I didn’t try that.

Multicasting to global networks is certainly possible theoretically. But I’ve never seen a successful practical implementation of one. Given the esoteric routers and firewalls that exist all around.

Читайте также:  Домашняя wifi интернет сеть

This SO question shows how it is done on desktop. Similar code also works with android.

Источник

Android can not receive multicast packet

I’m playing a little bit with multicast sockets. I write a server which sends a message to a android client. Until yet the client should only log the received message. I noticed that no multicast packet are received on my device. Here is the code for the server (runs on the pc):

public class MulticastServer < private int port; private boolean running = false; private MulticastSocket serverSocket; private InetAddress group; private String multicastAddress = "230.192.0.11"; public MulticastServer(int port) < super(); this.port = port; init(); >public MusicStreamerServer() < this(5500); >private void init() < try < group = InetAddress.getByName(multicastAddress); serverSocket = new MulticastSocket(port); serverSocket.joinGroup(group); >catch (IOException e) < e.printStackTrace(); >> public void start() throws IOException < System.out.println("server started"); if (running) return; running = true; new Thread(new Runnable() < @Override public void run() < byte[] buf = new byte[1024]; DatagramPacket packet = new DatagramPacket(buf, buf.length, group, port); String msg = "msg"; while (running) < packet.setData(msg.getBytes(), 0, msg.length()); try < serverSocket.send(packet); >catch (IOException e) < e.printStackTrace(); >> > >).start(); > public void stop() throws IOException < running = false; >> 
public class MainActivity extends Activity < private MulticastSocket socket; private InetAddress group; private String multicastAddress = "230.192.0.11"; private int port = 5500; @Override protected void onCreate(Bundle savedInstanceState) < super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); init(); >private void init() < StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder() .permitAll().build(); StrictMode.setThreadPolicy(policy); try < group = InetAddress.getByName(multicastAddress); socket = new MulticastSocket(port); socket.joinGroup(group); socket.setBroadcast(true); >catch (IOException e) < e.printStackTrace(); Log.wtf("init", e.getMessage()); >new Thread(new Runnable() < @Override public void run() < WifiManager wm = (WifiManager) getSystemService(Context.WIFI_SERVICE); WifiManager.MulticastLock multicastLock = wm .createMulticastLock("mylock"); multicastLock.acquire(); byte[] buf = new byte[1024]; while (true) < try < socket.receive(packet); Log.d("receiver","received mt24 mb12">
    androidmulticast
)" data-controller="se-share-sheet" data-se-share-sheet-title="Share a link to this question" data-se-share-sheet-subtitle="" data-se-share-sheet-post-type="question" data-se-share-sheet-social="facebook twitter devto" data-se-share-sheet-location="1" data-se-share-sheet-license-url="https%3a%2f%2fcreativecommons.org%2flicenses%2fby-sa%2f3.0%2f" data-se-share-sheet-license-name="CC BY-SA 3.0" data-s-popover-placement="bottom-start">Share
)" title="">Improve this question
)">edited Jan 4, 2014 at 13:28
asked Jan 4, 2014 at 12:32
3
    In your sample I believe you're missing some code for DatagramPacket creation and handling. I also would like to state for a fact that Android can do mulitcast reception; I've tested it on the Nexus7 and other devices.
    – Paul Gregoire
    Jan 27, 2014 at 1:51
    Have you managed to resolve it yet ?
    – Ahmed
    May 4, 2014 at 19:35
    What network interface do you use? Wifi? Each interface may have its quirks, in order to optimize battery usage.
    – dolmen
    Sep 8, 2014 at 21:09
Add a comment|

2 Answers 2

Reset to default
4

I've seen that the issue is really inconsistent.

Android version: 4.2.x

On Samsung S4 active: Multicast is working as expected.

On Samsung Note 10.1 and Nexus 4.2.3 Multicast is not working as expected.

239.x.x.x is not supported (and sadly it's the one used to multicast television. ) 224.0.0.251 is working as expected.

I think they have a bug with the mask.

A multicast address is normally |1 1 1 0| MULTICAST Address | 224.0.0.0 - 239.255.255.255

11100000.00000000.00000000.00000001 = 224.0.0.1 11101111.00000000.00000000.00000001 = 239.0.0.1

Источник

Оцените статью
Adblock
detector