Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added multicast udp, added callback for interrupt data arrival #7

Closed
wants to merge 2 commits into from

Conversation

straccio
Copy link
Contributor

Implemented begin multicast for receiving multicast udp.
Added ability to add a callback from the interrupt when udp receive data. (Usefull with FreeRTOS.

void EthernetUDP::onDataArrival( std::function<void()> onDataArrival_fn){
  _udp.onDataArrival = onDataArrival_fn;
}

Prereq: stm32duino/Arduino_Core_STM32#198

Implemented begin multicast for receiving multicast udp.
Added ability to add a callback from the interrupt when udp receive data. (Usefull with FreeRTOS.
```
void EthernetUDP::onDataArrival( std::function<void()> onDataArrival_fn){
  _udp.onDataArrival = onDataArrival_fn;
}
```
@fpistm fpistm self-assigned this Jan 16, 2018
@fpistm fpistm added the enhancement New feature or request label Jan 16, 2018
@fpistm
Copy link
Member

fpistm commented Jan 16, 2018

Thanks @straccio
Have you an example to test this?

@straccio
Copy link
Contributor Author

The example here, i don't have the board with me, in order to try this code.
In the example i have used FreeRTOS.

/*
 FreeRTOS DHCP Chat UDP
 */

#include <LwIP.h>
#include <STM32Ethernet.h>
#include <STM32FreeRTOS.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network.
// gateway and subnet are optional:
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 1, 177);
IPAddress myDns(192,168,1, 1);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 0, 0);

IPAddress multicast_address(224,0,1,186);
uint16_t multicast_port = 5684;
uint16_t port = 5683;

// telnet defaults to port 23
EthernetUDP receiver;
EthernetUDP transmitter;
SemaphoreHandle_t recv_sem;

void recv_multicast_message(){
  xSemaphoreGiveFromISR(recv_sem,NULL);
}

static void vReceiverTask(void *pvParameters){
  size_t packetlen;
  char * buffer;
  buffer = (char *) malloc(80);
  for(;;){
    //waiting for inccoming message or 2 ms 
    xSemaphoreTake(recv_sem,2);
    if(packetlen = receiver.parsePacket()>0){
      if(receiver.read(buffer,packetlen)==packetlen){
        IPAddress remote = receiver.remoteIP();
        for (int i = 0; i < 4; i++) {
          Serial.print(remote[i], DEC);
          if (i < 3) {
            Serial.print(".");
          }
        }
        Serial.print(": ");
        Serial.println(buffer);
      }
    }
  }
}

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  // this check is only needed on the Leonardo:
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }


  // start the Ethernet connection:
  Serial.println("Trying to get an IP address using DHCP");
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // initialize the Ethernet device not using DHCP:
    Ethernet.begin(mac, ip, myDns, gateway, subnet);
  }
  // print your local IP address:
  Serial.print("My IP address: ");
  ip = Ethernet.localIP();
  for (byte thisByte = 0; thisByte < 4; thisByte++) {
    // print the value of each byte of the IP address:
    Serial.print(ip[thisByte], DEC);
    Serial.print(".");
  }
  Serial.println();
  recv_sem = xSemaphoreCreateBinary();
  
  // start listening for clients on multicast address
  if(receiver.beginMulticast(multicast_address,multicast_port)==1){
    receiver.onDataArrival(recv_multicast_message);
  }


  // start listening for clients on unicast address
  // used only for transmitting;
  transmitter.begin(port);

  //start receiver task 
  xTaskCreate(vReceiverTask,
    "RECV_TASK",
    configMINIMAL_STACK_SIZE + 100,
    NULL,
    tskIDLE_PRIORITY + 1,
    NULL);

  // start FreeRTOS Scheduler
  vTaskStartScheduler();

  // should never return
  Serial.println(F("Die"));
  while(1);
}

void loop() {
  String toSend;
  //Echoing serial over UDP
  if(Serial.available()){
    toSend = Serial.readString();
    transmitter.beginPacket(multicast_address, multicast_port);
    transmitter.write(toSend.c_str(),toSend.length());
    transmitter.endPacket();
  }
  Ethernet.maintain();
}

@fpistm
Copy link
Member

fpistm commented Jan 24, 2018

I've submitted #8 to avoid LwIP option file core dependency.
Need to see if #define LWIP_IGMP 1 should be added per default.

@rzr
Copy link
Contributor

rzr commented Jan 4, 2019

Unsure it is related but I managed with a couple of fixes to use ArduinoMDNS library on Nucleo-f767zi with this:

stm32duino/Arduino_Core_STM32#401 (Under review)

@fpistm
Copy link
Member

fpistm commented Jan 4, 2019

@rzr did you test this PR?

@rzr
Copy link
Contributor

rzr commented Jan 4, 2019

mine yes, not yours ;) how to reproduce ?

@fpistm
Copy link
Member

fpistm commented Jan 4, 2019

This is not my PR ;)
So if I well understood you implement multicast on your own side ?
I have to admit I'm not an expert about that, so any input are welcome to add it.

@rzr
Copy link
Contributor

rzr commented Jan 4, 2019

well I did use @arduino library it seems to work with my sample code, I can eventually commit a simpler example, meanwhile there are a couple of hints at bottom of:
https://github.com/rzr/webthing-iotjs/wiki/MCU

@fpistm
Copy link
Member

fpistm commented Jan 4, 2019

So if I well understood, this PR is not required for multicast if using third part library.
Last question to check if is this PR is compatible with third party library.

@straccio
Copy link
Contributor Author

straccio commented Jan 7, 2019

This PR is for multicast, in listening,by subscribing to the IGMP group.
This also add a callback when receive message from UDP.

@fpistm fpistm self-requested a review January 7, 2019 10:12
@rzr
Copy link
Contributor

rzr commented May 1, 2019

For the record this change:
#17

is released in:
https://github.com/stm32duino/Arduino_Core_STM32/releases/tag/1.5.0

Sorry for confusion...

@fpistm
Copy link
Member

fpistm commented May 2, 2019

Well, I did not have time to investigate this, yet.
I'm not comfortable with this.
So, what do you advise on this?
Is this PR is requested? useful? compatible with @rzr update?...
How can I validate it simply ?

@fpistm fpistm removed their assignment Nov 9, 2019
@fpistm
Copy link
Member

fpistm commented Nov 10, 2019

Hi @straccio
I've rebased and do some clean/refactor: b956c4b
it works when enable LWIP_IGMP is enabled.
So I close this PR.
Sorry for the delay.

@fpistm fpistm closed this Nov 10, 2019
@fpistm fpistm removed their request for review November 10, 2019 06:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants