W5500 Multicast Join Multiple Groups?

Hi

I have built a custom wiznet and MCU board for a Light controller application. Everything is working great so far and the multicast function is doing what it should.

Background info: I have a controller that is capable of receiving multiple universes (sACN e1.31) and per sACN rules it uses a unique Multicast address based on the universe. The example would be universe 1 is 239.255.0.1 and universe 2 is 239.255.0.2 and so on. The question I have is would it be possible to initiate the wiznet to subscribe to multiple multicast group addresses?

One workaround to at least receiving multiple multicast groups is to run in MACRAW mode and let the code filter out what traffic it wants to see based off of receive IP and packet contents. But at some point traffic may get too intense and overload the MCU. Therfore I entertain the thought of utilizing the multicast subscribe feature if at all possible. Perhaps I could craft my own multicast join packet and not use the built in w5500 methods?

Any direction or suggestion on options would be great.

Thanks

crees

Hi Crees, please below the code for the join. I have prefixed the socket API’s with _ in order to be able to test the code on Raspberry Pi Raspbian SPI interface (not conflicting with the Linux socket API’s).

I have not tried to call it for several universes. But basically, this function just generates the join message. What if we call it for each universe to receive ? Does that simply work?

Arjan
http://www.orangepi-dmx.org/allwinner-h3

`#define IPSTR "%d.%d.%d.%d"
#define MACSTR "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x"

int8_t w5x00_join_group(uint8_t sn, uint32_t ip, uint16_t port) {
	DEBUG_ENTRY
	DEBUG_PUTS(_WIZCHIP_ID_);

	uint8_t multicast_ip[4];
	uint8_t multicast_mac[6];

	multicast_ip[0] = ip & 0xFF;
	multicast_ip[1] = (ip >> 8) & 0xFF;
	multicast_ip[2] = (ip >> 16) & 0xFF;
	multicast_ip[3] = (ip >> 24) & 0xFF;

	multicast_mac[0] = 0x01;
	multicast_mac[1] = 0x00;
	multicast_mac[2] = 0x5E;
	multicast_mac[3] = multicast_ip[1] & 0x7F;
	multicast_mac[4] = multicast_ip[2];
	multicast_mac[5] = multicast_ip[3];

#ifndef NDEBUG
	printf("Multicast-Group H/W address : " MACSTR "\n", multicast_mac[0], multicast_mac[1],multicast_mac[2],multicast_mac[3],multicast_mac[4],multicast_mac[5]);
	printf("Multicast-Group IP address : " IPSTR "\n", multicast_ip[0], multicast_ip[1],multicast_ip[2],multicast_ip[3]);
	printf("Multicast-GroupPort number : %d\n", (int) port);
#endif

	/* set Multicast-Group information */
	setSn_DHAR(sn, multicast_mac);	/* set Multicast-Group H/W address */
	setSn_DIPR(sn, multicast_ip);	/* set Multicast-Group IP address */
	setSn_DPORT(sn, port);			/* set Multicast-GroupPort number */

	const uint8_t sd = _socket(sn, Sn_MR_UDP, port, SF_IO_NONBLOCK | Sn_MR_MULTI);

	if (sd < 0) {
		printf("_socket(0, Sn_MR_UDP, %d, SF_IO_NONBLOCK | Sn_MR_MULTI)=%d\n", (int)port, (int) sd);
	}

	return sd;

	DEBUG_EXIT
}`

Forgot to mention, this is working with sACN E1.31. After the join, you can simply do a recvfrom. Note : the socket number 0 is hardcoded in the example below.

uint16_t NetworkW5x00::RecvFrom(uint8_t* packet, uint16_t size, uint32_t* from_ip, uint16_t* from_port) {
	assert(packet != 0);
	assert(from_ip != 0);
	assert(from_port != 0);

	uint8_t remoteAddress[4];

	const int32_t rc = _recvfrom(0, (unsigned char *)packet, size, remoteAddress, from_port);

	if (rc < 0) {
#ifndef NDEBUG
		printf("Error recvfrom=%d\n", (int) rc);
#endif
		return 0;
	} else if (rc > 0) {
#ifndef NDEBUG
		DEBUG_PRINTF("%d", rc);
#endif
	}

	*from_ip = remoteAddress[0] | (remoteAddress[1] << 8)  | (remoteAddress[2] << 16)  | (remoteAddress[3] << 24);

	return (uint16_t) rc;
}

With reference to ioLibrary_Driver/socket.c at master · Wiznet/ioLibrary_Driver · GitHub
it is doing a close. So calling the join multiple times is not working.

Also, I am eager to know how to initiate multiple join’s for a single socket.

1 Like

I may be going about this thought the wrong way (bad hack) Using MacRaw to receive all the multicast traffic so we don’t have to bind IP to socket and then use a custom subscribe packet function to tell the upstream switch/router what multicast streams we are interested in?

I found success receiving multiple multicast streams from different multicast groups in MACRAW mode. However the issue is now that my buffer can only handle so many and I need to learn how to utilize IGMP to subscribe to multiple Groups. I am still looking how to craft an IGMP subscribe function in MACRAW mode.

Anyone have any advice on IGMP code usage in MACRAW mode?