arduino stuffs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/*
  EthernetServerStream.h

  Copyright (C) 2017 Marc Josef Pees. All rights reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  See file LICENSE.txt for further informations on licensing terms.

  Last updated July 10th, 2017
 */

#ifndef ETHERNETSERVERSTREAM_H
#define ETHERNETSERVERSTREAM_H

#include <inttypes.h>
#include <Stream.h>
#include <Ethernet.h>

//#define SERIAL_DEBUG
#include "firmataDebug.h"

class EthernetServerStream : public Stream
{
  public:
    EthernetServerStream(IPAddress localip, uint16_t port);
    int available();
    int read();
    int peek();
    void flush();
    size_t write(uint8_t);
    void maintain(IPAddress localip);

  private:
    EthernetClient client;
    IPAddress localip;
    uint16_t port;
    bool connected;
    bool maintain();
    void stop();
    
  protected:
    EthernetServer server = EthernetServer(3030);
    bool listening = false;
    bool connect_client();
};


/*
 * EthernetServerStream.cpp
 * Copied here as a hack to linker issues with 3rd party board packages that don't properly
 * implement the Arduino network APIs.
 */
EthernetServerStream::EthernetServerStream(IPAddress localip, uint16_t port)
  : localip(localip),
    port(port),
    connected(false)
{
}

bool EthernetServerStream::connect_client()
  {
    if ( connected )
    {
      if ( client && client.connected() ) return true;
      stop();
    }

    EthernetClient newClient = server.available();
    if ( !newClient ) return false;
    client = newClient;
    connected = true;
    DEBUG_PRINTLN("Connected");
    return true;
  }

int
EthernetServerStream::available()
{
  return maintain() ? client.available() : 0;
}

int
EthernetServerStream::read()
{
  return maintain() ? client.read() : -1;
}

int
EthernetServerStream::peek()
{
  return maintain() ? client.peek() : -1;
}

void EthernetServerStream::flush()
{
  if (maintain())
    client.flush();
}

size_t
EthernetServerStream::write(uint8_t c)
{
  return maintain() ? client.write(c) : 0;
}

void
EthernetServerStream::maintain(IPAddress localip)
{
  // ensure the local IP is updated in the case that it is changed by the DHCP server
  if (this->localip != localip) {
    this->localip = localip;
    if (connected)
      stop();
  }
}

void
EthernetServerStream::stop()
{
  if(client)
  {
    client.stop();
  }
  connected = false;
}

bool
EthernetServerStream::maintain()
{
  if (connect_client()) return true;
  
  stop();
  
  if(!listening)
  {
    server = EthernetServer(port);
    server.begin();
    listening = true;
  }
  return false;
}

#endif /* ETHERNETSERVERSTREAM_H */