Skip to content
Closed
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();
}
}


*/