Skip to content

Commit b7af0a4

Browse files
Merge pull request firmata#375 from MJPees/master
added server mode to StandardFirmataEthernet
2 parents fd6d2f6 + d1848c1 commit b7af0a4

File tree

4 files changed

+178
-12
lines changed

4 files changed

+178
-12
lines changed

examples/StandardFirmataEthernet/StandardFirmataEthernet.ino

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626
/*
2727
README
2828
29-
StandardFirmataEthernet is a TCP client implementation. You will need a Firmata client library
30-
with a network transport that can act as a TCP server in order to establish a connection between
29+
StandardFirmataEthernet is a TCP client/server implementation. You will need a Firmata client library
30+
with a network transport that can act as a TCP server or client in order to establish a connection between
3131
StandardFirmataEthernet and the Firmata client application.
3232
3333
To use StandardFirmataEthernet you will need to have one of the following
@@ -68,6 +68,7 @@
6868
// follow the instructions in ethernetConfig.h to configure your particular hardware
6969
#include "ethernetConfig.h"
7070
#include "utility/EthernetClientStream.h"
71+
#include "utility/EthernetServerStream.h"
7172

7273
/*
7374
* Uncomment the following include to enable interfacing with Serial devices via hardware or
@@ -103,17 +104,25 @@
103104

104105
#if defined remote_ip && !defined remote_host
105106
#ifdef local_ip
106-
EthernetClientStream stream(client, local_ip, remote_ip, NULL, remote_port);
107+
EthernetClientStream stream(client, local_ip, remote_ip, NULL, network_port);
107108
#else
108-
EthernetClientStream stream(client, IPAddress(0, 0, 0, 0), remote_ip, NULL, remote_port);
109+
EthernetClientStream stream(client, IPAddress(0, 0, 0, 0), remote_ip, NULL, network_port);
109110
#endif
110111
#endif
111112

112113
#if !defined remote_ip && defined remote_host
113114
#ifdef local_ip
114-
EthernetClientStream stream(client, local_ip, IPAddress(0, 0, 0, 0), remote_host, remote_port);
115+
EthernetClientStream stream(client, local_ip, IPAddress(0, 0, 0, 0), remote_host, network_port );
115116
#else
116-
EthernetClientStream stream(client, IPAddress(0, 0, 0, 0), IPAddress(0, 0, 0, 0), remote_host, remote_port);
117+
EthernetClientStream stream(client, IPAddress(0, 0, 0, 0), IPAddress(0, 0, 0, 0), remote_host, network_port);
118+
#endif
119+
#endif
120+
121+
#if !defined remote_ip && !defined remote_host
122+
#ifdef local_ip
123+
EthernetServerStream stream(local_ip, network_port);
124+
#else
125+
EthernetServerStream stream(IPAddress(0, 0, 0, 0), network_port);
117126
#endif
118127
#endif
119128

@@ -864,6 +873,10 @@ void initTransport()
864873
#endif
865874

866875
DEBUG_PRINTLN("connecting...");
876+
877+
DEBUG_PRINT("IP Address: ");
878+
IPAddress ip = Ethernet.localIP();
879+
DEBUG_PRINTLN(ip);
867880
}
868881

869882
void initFirmata()

examples/StandardFirmataEthernet/ethernetConfig.h

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
*
44
* You must configure your particular hardware. Follow the steps below.
55
*
6-
* Currently StandardFirmataEthernet is configured as a TCP client. An
7-
* option to configure as a server may be added in the future.
6+
* By default, StandardFirmataEthernet is configured as a TCP client.
7+
* To configure as a TCP server, see STEP 2
88
*============================================================================*/
99

1010
// STEP 1 [REQUIRED]
@@ -46,16 +46,20 @@ EthernetClient client;
4646
YunClient client;
4747
#endif
4848

49-
// STEP 2[REQUIRED for all boards and shields]
50-
// replace with IP of the server you want to connect to, comment out if using 'remote_host'
49+
// STEP 2 [REQUIRED for all boards and shields]
50+
// TCP Client configuration:
51+
// To configure your board as a TCP client, set the IP address of the server you want to connect to.
52+
// TCP Server configuration:
53+
// To configure your board as a TCP server, comment out the following line and also ensure that
54+
// remote_host is also commented out.
5155
#define remote_ip IPAddress(10, 0, 0, 3)
5256
// *** REMOTE HOST IS NOT YET WORKING ***
5357
// replace with hostname of server you want to connect to, comment out if using 'remote_ip'
5458
// #define remote_host "server.local"
5559

5660
// STEP 3 [REQUIRED]
57-
// Replace with the port that your server is listening on
58-
#define remote_port 3030
61+
// Replace with the port that your client or server is listening on.
62+
#define network_port 3030
5963

6064
// STEP 4 [REQUIRED unless using DHCP]
6165
// Replace with your board or ethernet shield's IP address

utility/EthernetServerStream.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/*
2+
* Implementation is in EthernetServerStream.h to avoid linker issues.
3+
*/

utility/EthernetServerStream.h

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
/*
2+
EthernetServerStream.h
3+
4+
Copyright (C) 2017 Marc Josef Pees. All rights reserved.
5+
6+
This library is free software; you can redistribute it and/or
7+
modify it under the terms of the GNU Lesser General Public
8+
License as published by the Free Software Foundation; either
9+
version 2.1 of the License, or (at your option) any later version.
10+
11+
See file LICENSE.txt for further informations on licensing terms.
12+
13+
Last updated July 10th, 2017
14+
*/
15+
16+
#ifndef ETHERNETSERVERSTREAM_H
17+
#define ETHERNETSERVERSTREAM_H
18+
19+
#include <inttypes.h>
20+
#include <Stream.h>
21+
#include <Ethernet.h>
22+
23+
//#define SERIAL_DEBUG
24+
#include "firmataDebug.h"
25+
26+
class EthernetServerStream : public Stream
27+
{
28+
public:
29+
EthernetServerStream(IPAddress localip, uint16_t port);
30+
int available();
31+
int read();
32+
int peek();
33+
void flush();
34+
size_t write(uint8_t);
35+
void maintain(IPAddress localip);
36+
37+
private:
38+
EthernetClient client;
39+
IPAddress localip;
40+
uint16_t port;
41+
bool connected;
42+
bool maintain();
43+
void stop();
44+
45+
protected:
46+
EthernetServer server = EthernetServer(3030);
47+
bool listening = false;
48+
bool connect_client();
49+
};
50+
51+
52+
/*
53+
* EthernetServerStream.cpp
54+
* Copied here as a hack to linker issues with 3rd party board packages that don't properly
55+
* implement the Arduino network APIs.
56+
*/
57+
EthernetServerStream::EthernetServerStream(IPAddress localip, uint16_t port)
58+
: localip(localip),
59+
port(port),
60+
connected(false)
61+
{
62+
}
63+
64+
bool EthernetServerStream::connect_client()
65+
{
66+
if ( connected )
67+
{
68+
if ( client && client.connected() ) return true;
69+
stop();
70+
}
71+
72+
EthernetClient newClient = server.available();
73+
if ( !newClient ) return false;
74+
client = newClient;
75+
connected = true;
76+
return true;
77+
}
78+
79+
int
80+
EthernetServerStream::available()
81+
{
82+
return maintain() ? client.available() : 0;
83+
}
84+
85+
int
86+
EthernetServerStream::read()
87+
{
88+
return maintain() ? client.read() : -1;
89+
}
90+
91+
int
92+
EthernetServerStream::peek()
93+
{
94+
return maintain() ? client.peek() : -1;
95+
}
96+
97+
void EthernetServerStream::flush()
98+
{
99+
if (maintain())
100+
client.flush();
101+
}
102+
103+
size_t
104+
EthernetServerStream::write(uint8_t c)
105+
{
106+
return maintain() ? client.write(c) : 0;
107+
}
108+
109+
void
110+
EthernetServerStream::maintain(IPAddress localip)
111+
{
112+
// ensure the local IP is updated in the case that it is changed by the DHCP server
113+
if (this->localip != localip) {
114+
this->localip = localip;
115+
if (connected)
116+
stop();
117+
}
118+
}
119+
120+
void
121+
EthernetServerStream::stop()
122+
{
123+
if(client)
124+
{
125+
client.stop();
126+
}
127+
connected = false;
128+
}
129+
130+
bool
131+
EthernetServerStream::maintain()
132+
{
133+
if (connect_client()) return true;
134+
135+
stop();
136+
137+
if(!listening)
138+
{
139+
server = EthernetServer(port);
140+
server.begin();
141+
listening = true;
142+
}
143+
return false;
144+
}
145+
146+
#endif /* ETHERNETSERVERSTREAM_H */

0 commit comments

Comments
 (0)