Giter VIP home page Giter VIP logo

Comments (13)

fredlcore avatar fredlcore commented on August 17, 2024

ArduinoMDNS states that

any Arduino core and networking library that supports the new virtual UDP::beginMulticast(...) method

would be working. Could that be the root of the problem?

from wifispi.

JiriBilek avatar JiriBilek commented on August 17, 2024

You're absolutely right. This function is not implemented and from the inner class UDP returns always 0.
I don't know what should it look like, nor what should it do. Please hold on, I'll look at it.

from wifispi.

fredlcore avatar fredlcore commented on August 17, 2024

That would be awesome, thanks!

from wifispi.

JiriBilek avatar JiriBilek commented on August 17, 2024

I am sorry, I haven't looked at it yet. It requires some investigation what actually the multicast is and how could I test it.
I am unable to find an example for testing the multicast. Do you have any?

from wifispi.

fredlcore avatar fredlcore commented on August 17, 2024

No worries, I'm glad you're looking into it!
As for what Multicast is, here are a few links with examples that might be helpful (if a destination IP is used, it has to be of the multicast address range, i.e. 224.0.0.0 through 239.255.255.255. ArduinMDNS uses 224.0.0.251):

Arduino UDP Multicast send/receive:
https://tkkrlab.nl/wiki/Arduino_UDP_multicast
Multicast tutorial:
https://community.particle.io/t/multicast-udp-tutorial/19900
Sender and listener for Linux written in C++:
https://gist.github.com/hostilefork/f7cae3dc33e7416f2dd25a402857b6c6

Other than that, this is the beginMulticast-code from EthernetUdp.cpp (the "makesocket" section is releant here, I guess, and most of it is calculating the MAC address based on the Multicast IP address):

// multicast version to set fields before open  thd
uint8_t EthernetClass::socketBeginMulticast(uint8_t protocol, IPAddress ip, uint16_t port)
{
	uint8_t s, status[MAX_SOCK_NUM], chip, maxindex=MAX_SOCK_NUM;

	// first check hardware compatibility
	chip = W5100.getChip();
	if (!chip) return MAX_SOCK_NUM; // immediate error if no hardware detected
#if MAX_SOCK_NUM > 4
	if (chip == 51) maxindex = 4; // W5100 chip never supports more than 4 sockets
#endif
	//Serial.printf("W5000socket begin, protocol=%d, port=%d\n", protocol, port);
	SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
	// look at all the hardware sockets, use any that are closed (unused)
	for (s=0; s < maxindex; s++) {
		status[s] = W5100.readSnSR(s);
		if (status[s] == SnSR::CLOSED) goto makesocket;
	}
	//Serial.printf("W5000socket step2\n");
	// as a last resort, forcibly close any already closing
	for (s=0; s < maxindex; s++) {
		uint8_t stat = status[s];
		if (stat == SnSR::LAST_ACK) goto closemakesocket;
		if (stat == SnSR::TIME_WAIT) goto closemakesocket;
		if (stat == SnSR::FIN_WAIT) goto closemakesocket;
		if (stat == SnSR::CLOSING) goto closemakesocket;
	}
#if 0
	Serial.printf("W5000socket step3\n");
	// next, use any that are effectively closed
	for (s=0; s < MAX_SOCK_NUM; s++) {
		uint8_t stat = status[s];
		// TODO: this also needs to check if no more data
		if (stat == SnSR::CLOSE_WAIT) goto closemakesocket;
	}
#endif
	SPI.endTransaction();
	return MAX_SOCK_NUM; // all sockets are in use
closemakesocket:
	//Serial.printf("W5000socket close\n");
	W5100.execCmdSn(s, Sock_CLOSE);
makesocket:
	//Serial.printf("W5000socket %d\n", s);
	EthernetServer::server_port[s] = 0;
	delayMicroseconds(250); // TODO: is this needed??
	W5100.writeSnMR(s, protocol);
	W5100.writeSnIR(s, 0xFF);
	if (port > 0) {
		W5100.writeSnPORT(s, port);
	} else {
		// if don't set the source port, set local_port number.
		if (++local_port < 49152) local_port = 49152;
		W5100.writeSnPORT(s, local_port);
	}
	// Calculate MAC address from Multicast IP Address
    	byte mac[] = {  0x01, 0x00, 0x5E, 0x00, 0x00, 0x00 };
    	mac[3] = ip[1] & 0x7F;
    	mac[4] = ip[2];
    	mac[5] = ip[3];
    	W5100.writeSnDIPR(s, ip.raw_address());   //239.255.0.1
    	W5100.writeSnDPORT(s, port);
    	W5100.writeSnDHAR(s, mac);
	W5100.execCmdSn(s, Sock_OPEN);
	state[s].RX_RSR = 0;
	state[s].RX_RD  = W5100.readSnRX_RD(s); // always zero?
	state[s].RX_inc = 0;
	state[s].TX_FSR = 0;
	//Serial.printf("W5000socket prot=%d, RX_RD=%d\n", W5100.readSnMR(s), state[s].RX_RD);
	SPI.endTransaction();
	return s;
}

from wifispi.

JAndrassy avatar JAndrassy commented on August 17, 2024

Jiri, it is used the same way as UDP.begin(). Only send WiFiSpiUdp.beginMulticast to WiFiUdp.beginMulticast of the ESP8266WiFi library.

from wifispi.

JiriBilek avatar JiriBilek commented on August 17, 2024

@fredlcore and Juraj: thank you so much. I hope now I have all the information needed to implement it.

from wifispi.

fredlcore avatar fredlcore commented on August 17, 2024

You're most welcome, thank you for your effort, and thanks, @JAndrassy for this really helpful information!

from wifispi.

JiriBilek avatar JiriBilek commented on August 17, 2024

Hi, I realized that on my network, I am not able to use a multicast. It may be an issue of my router (TPLink Archer C5) or whatever. No matter if I try to transmit wired or wireless.
Do you have any ideas? I am not able to test UDP Multicast now.

Edit: it is not an issue with a router but with the VirtualBox, namely its ethernet adapter. Eventually, I tried it on another PC and it runs. (https://www.virtualbox.org/ticket/8698)

from wifispi.

JiriBilek avatar JiriBilek commented on August 17, 2024

I created new branch here and in the WiFiSpiESP repository named UDP_Multicast.
@fredlcore please check them out and test if the library works for you. I also added two examples (multicast transmit and receive).

from wifispi.

fredlcore avatar fredlcore commented on August 17, 2024

Great! I was just about to give up when the errors came again until I ran the test case above again and it notified me that also the ESP part had changed. So once I flashed the ESP with the new version, it works like charm, thanks so much :)!

Will you merge this directly into the master branch or should I refer people to this branch instead?

from wifispi.

JiriBilek avatar JiriBilek commented on August 17, 2024

Thanks for testing, I'll merge it to the master.

from wifispi.

JiriBilek avatar JiriBilek commented on August 17, 2024

Closed via #29

from wifispi.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.