Skip to content

Proposal for a new, more simple Network Upload Notification concept #5655

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

Closed
wants to merge 15 commits into from
11 changes: 11 additions & 0 deletions arduino-core/src/cc/arduino/packages/BoardPort.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public class BoardPort {
private String label;
private final PreferencesMap prefs;
private boolean online;
private long lastseen;

public BoardPort() {
this.prefs = new PreferencesMap();
Expand Down Expand Up @@ -115,4 +116,14 @@ public String getISerial() {
public String toString() {
return this.address+"_"+this.vid+"_"+this.pid;
}


public void setLastseen(long lastseen) {
this.lastseen = lastseen;
}

public long getLastseen() {
return lastseen;
}

}
3 changes: 3 additions & 0 deletions arduino-core/src/cc/arduino/packages/DiscoveryManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

import cc.arduino.packages.discoverers.NetworkDiscovery;
import cc.arduino.packages.discoverers.SerialDiscovery;
import cc.arduino.packages.discoverers.SimpleUDPDiscovery;

import java.util.ArrayList;
import java.util.List;
Expand All @@ -42,11 +43,13 @@ public class DiscoveryManager {
private final List<Discovery> discoverers;
private final SerialDiscovery serialDiscoverer = new SerialDiscovery();
private final NetworkDiscovery networkDiscoverer = new NetworkDiscovery();
private final SimpleUDPDiscovery udpworkDiscoverer = new SimpleUDPDiscovery();

public DiscoveryManager() {
discoverers = new ArrayList<>();
discoverers.add(serialDiscoverer);
discoverers.add(networkDiscoverer);
discoverers.add(udpworkDiscoverer);

// Start all discoverers
for (Discovery d : discoverers) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*
* This file is part of Arduino.
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2013 Arduino LLC (http://www.arduino.cc/)
*/

package cc.arduino.packages.discoverers;

import cc.arduino.packages.BoardPort;
import processing.app.BaseNoGui;
import cc.arduino.packages.Discovery;
import cc.arduino.packages.discoverers.simpleudp.UdpRunnable;

import java.util.LinkedList;
import java.util.List;
import java.util.Timer;

public class SimpleUDPDiscovery implements Discovery {

private Timer udpBoardsListerTimer;
private Thread thread;
private UdpRunnable runner;
//private SerialBoardsLister serialBoardsLister = new SerialBoardsLister((SerialBoardsLister)this);

public SimpleUDPDiscovery() {
}

@Override
public List<BoardPort> listDiscoveredBoards() {
return getudpBoardPorts(false);
}

@Override
public List<BoardPort> listDiscoveredBoards(boolean complete) {
return getudpBoardPorts(complete);
}

private List<BoardPort> getudpBoardPorts(boolean complete) {

zapLongNotSeen();

if (complete) {
return new LinkedList<>(runner.udpBoardPorts);
}
List<BoardPort> onlineBoardPorts = new LinkedList<>();
for (BoardPort port : runner.udpBoardPorts) {
if (port.isOnline() == true) {
onlineBoardPorts.add(port);
}
}
return onlineBoardPorts;
}

public void setudpBoardPorts(List<BoardPort> newudpBoardPorts) {
}

public void zapLongNotSeen() {
//System.out.println("zap");

long jetzt = System.currentTimeMillis();
long alt = jetzt - 60000; // 60 sekunden nicht gesehen? Alt

List<BoardPort> timeouts = new LinkedList<>();
for (BoardPort port : runner.udpBoardPorts) {
if (port.getLastseen() < alt) {
timeouts.add(port);
//System.out.println("Alt!");
}
}
runner.udpBoardPorts.removeAll(timeouts);
}

public void setUploadInProgress(boolean param) {
//serialBoardsLister.uploadInProgress = param;
}

public void pausePolling(boolean param) {
//serialBoardsLister.pausePolling = param;
}

@Override
public void start() {
//System.out.println("SimpleUDPDiscovery.start!!!");

runner = new UdpRunnable();
thread = new Thread(runner);
thread.start();
}

@Override
public void stop() {
runner.terminate();
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
/*
* This file is part of Arduino.
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2013 Arduino LLC (http://www.arduino.cc/)
*/

package cc.arduino.packages.discoverers.simpleudp;

import cc.arduino.packages.BoardPort;
import processing.app.BaseNoGui;
import processing.app.Platform;
import processing.app.debug.TargetBoard;

import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.UnknownHostException;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Collections;

import java.util.*;



public class UdpRunnable implements Runnable {

private boolean running = true;
// local, thread save list
public final List<BoardPort> udpBoardPorts = Collections.synchronizedList(new LinkedList<>());

private int hasip(String ip) {
int i = 0;
for (BoardPort port : udpBoardPorts) {
if (port.getAddress().equals(ip)) {
return i;
}
i++;
}

return -1;
}

public void run(){
//System.out.println("MyRunnable running");

while (running)
{
try
{
DatagramSocket socket = new DatagramSocket(8531, InetAddress.getByName("0.0.0.0"));
socket.setBroadcast(true);
//System.out.println("Listen on " + socket.getLocalAddress() + " from " + socket.getInetAddress() + " port " + socket.getBroadcast());
byte[] buf = new byte[512];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
while (true) {
//System.out.println("Waiting for data");
socket.receive(packet);
//System.out.print(packet.getLength());
//System.out.print(" Data received from ");

InetAddress senderip = packet.getAddress();
//System.out.println(senderip);

String msg = new String(packet.getData());
String[] lines = msg.split("\\n");

//System.out.println("");

//System.out.print(">>>");
//System.out.print(lines[0]);
//System.out.println("<<<<");

// msg typ 1
if (lines[0].equals("1")) {
// check the IP has an entry, if not, create new one, else use exsting one
BoardPort port;
int portexists = hasip(senderip.toString().substring(1));
if (portexists == -1) {
// new port
port = new BoardPort();
udpBoardPorts.add(port);
} else {
port = udpBoardPorts.get(portexists);
}

port.setAddress(senderip.toString().substring(1));
port.setProtocol("network");
port.setOnlineStatus(true);
port.setLabel(lines[1]+" at "+senderip.toString().substring(1));
port.setLastseen(System.currentTimeMillis());

port.getPrefs().put("port", lines[2]);
port.getPrefs().put("board", "");
port.getPrefs().put("ssh_upload", "no");
port.getPrefs().put("tcp_check", "no");
port.getPrefs().put("auth_upload", "no");
} else
// msg typ 2
if (lines[0].equals("2")) {
int portexists = hasip(senderip.toString().substring(1));
if (portexists != -1) {
BoardPort port = udpBoardPorts.get(portexists);
String[] pairs = msg.split("&");
for (String pair : pairs)
{
String[] params = pair.split(":");
port.getPrefs().put(params[0],params[1]);
}
}
}
}
}
catch (UnknownHostException e) {
e.printStackTrace();
}
catch ( Exception e )
{
running = false;
}
}
}

public void terminate()
{
running = false;
}
}

/*
even more simple device discovery protocol

send a broadcast to port 8531

message format

1\nsomethinginascci.

1 - simple menu setup
1\ndisplayname\nuploadport\n

creates a menu entry "displayname" assigned to the senders ip, sets the upload port to "uploadport"

if an entry is already attached to that sender ip the data is updated

2 - set optional parameters
2\nA:B&C:D&E:F
can set optional parameters

Message looks like 2\nA:B&C:D&E:F

will set
port.getPrefs().put("A", "B");
port.getPrefs().put("C", "D");
port.getPrefs().put("F", "F");

multiple messages can be send, any number of pairs can be send

so this is ok
2\nA:B&C:D&E:F
or
2\nA:B&C:D
2\nE:F
or
2\nA:B
2\nC:D
2\nE:F


Basic example:
==============

call this in loop():

void PostMyself(void) {
static unsigned long ticker = 0;

if (millis() - ticker > 15000) {
IPAddress broadcastIp(WiFi.localIP() | ( ~WiFi.subnetMask()));

WiFiUDP udp;
udp.begin(8765);
udp.beginPacket(broadcastIp, 8531);
udp.print("1\nesp8266 " + initmsg1 + "\n8266\n");
udp.endPacket();
delay(1);

ticker = millis();
}
}


*/