1////////////////////////////////////////////////////////////////////////////////
2// //
3// This software is supplied under the terms of a license agreement or //
4// nondisclosure agreement with Mitov Software and may not be copied //
5// or disclosed except in accordance with the terms of that agreement. //
6// Copyright(c) 2002-2016 Mitov Software. All Rights Reserved. //
7// //
8////////////////////////////////////////////////////////////////////////////////
9
10#ifndef _MITOV_BASIC_ETHERNET_h
11#define _MITOV_BASIC_ETHERNET_h
12
13#include <Mitov.h>
14//#include <Ethernet.h>
15
16namespace Mitov
17{
18//---------------------------------------------------------------------------
19 class TMACAddress
20 {
21 public:
22 byte FMacAddress[6];
23
24 public:
25 TMACAddress(
26 uint8_t mac_0,
27 uint8_t mac_1,
28 uint8_t mac_2,
29 uint8_t mac_3,
30 uint8_t mac_4,
31 uint8_t mac_5 )
32 {
33 FMacAddress[ 0 ] = mac_0;
34 FMacAddress[ 1 ] = mac_1;
35 FMacAddress[ 2 ] = mac_2;
36 FMacAddress[ 3 ] = mac_3;
37 FMacAddress[ 4 ] = mac_4;
38 FMacAddress[ 5 ] = mac_5;
39 }
40
41 TMACAddress()
42 {
43 memset( FMacAddress, 0, sizeof( FMacAddress ) );
44 }
45 };
46//---------------------------------------------------------------------------
47 inline String MACAdressToString( uint8_t *AMACAddress )
48 {
49 char AMACString[ 6 * 3 + 1 ];
50 sprintf( AMACString, "%02X-%02X-%02X-%02X-%02X-%02X", AMACString[ 0 ], AMACString[ 1 ], AMACString[ 2 ], AMACString[ 3 ], AMACString[ 4 ], AMACString[ 5 ] );
51 return AMACString;
52// MACOutputPin.Notify( AMACString );
53 }
54//---------------------------------------------------------------------------
55 inline String IPAdressToString( ::IPAddress AIPAddress )
56 {
57 char AIPString[ 4 * 4 + 1 ];
58 sprintf( AIPString, "%u.%u.%u.%u", AIPAddress[ 0 ], AIPAddress[ 1 ], AIPAddress[ 2 ], AIPAddress[ 3 ] );
59 return AIPString;
60 }
61//---------------------------------------------------------------------------
62 class BasicShieldIPAddress
63 {
64 public:
65 bool Enabled = false;
66 ::IPAddress IP;
67
68 };
69//---------------------------------------------------------------------------
70 class ShieldGatewayAddress : public BasicShieldIPAddress
71 {
72 public:
73 BasicShieldIPAddress Subnet;
74 };
75//---------------------------------------------------------------------------
76 class ShieldDNSAddress : public BasicShieldIPAddress
77 {
78 public:
79 ShieldGatewayAddress Gateway;
80 };
81//---------------------------------------------------------------------------
82 class ShieldIPAddress : public BasicShieldIPAddress
83 {
84 public:
85 ShieldDNSAddress DNS;
86 };
87//---------------------------------------------------------------------------
88 class ShieldIPDNS2Address : public ShieldIPAddress
89 {
90 public:
91 BasicShieldIPAddress DNS2;
92 };
93//---------------------------------------------------------------------------
94 class BasicSocket : public OpenWire::Component
95 {
96 typedef OpenWire::Component inherited;
97
98 public:
99// OpenWire::SinkPin InputPin;
100 OpenWire::SourcePin OutputPin;
101
102 public:
103 bool Enabled = true;
104 unsigned int Port = 80;
105
106 protected:
107 virtual void StartSocket() = 0;
108
109 public:
110 void SetEnabled( bool AValue )
111 {
112 if( Enabled == AValue )
113 return;
114
115 Enabled = AValue;
116 if( IsEnabled() )
117 StartSocket();
118
119 else
120 StopSocket();
121
122 }
123
124 public:
125 virtual bool IsEnabled()
126 {
127 return Enabled;
128 }
129
130 virtual bool CanSend()
131 {
132 return Enabled;
133 }
134
135 virtual void BeginPacket()
136 {
137 }
138
139 virtual void EndPacket()
140 {
141 }
142
143 virtual void StopSocket() = 0;
144
145 public:
146 virtual void SystemStart()
147 {
148// Serial.println( Enabled );
149 if( Enabled )
150 StartSocket();
151
152 inherited::SystemStart();
153 }
154
155 };
156//---------------------------------------------------------------------------
157 template<typename T_OWNER> class BasicEthernetSocket : public Mitov::BasicSocket
158 {
159 typedef Mitov::BasicSocket inherited;
160
161 protected:
162 T_OWNER &FOwner;
163
164 public:
165 virtual bool IsEnabled()
166 {
167 return Enabled && FOwner.Enabled;
168 }
169
170 virtual bool CanSend()
171 {
172 return Enabled && FOwner.Enabled;
173 }
174
175 virtual Print *GetPrint() = 0;
176
177 public:
178 BasicEthernetSocket( T_OWNER &AOwner ) :
179 FOwner( AOwner )
180 {
181 AOwner.Sockets.push_back( this );
182 }
183
184 };
185//---------------------------------------------------------------------------
186 template<typename T_OWNER, typename T_CLIENT> class BasicEthernetConnectSocket : public Mitov::BasicEthernetSocket<T_OWNER>
187 {
188 typedef Mitov::BasicEthernetSocket<T_OWNER> inherited;
189
190 public:
191 OpenWire::TypedSourcePin<bool> ConnectedOutputPin;
192
193 OpenWire::SinkPin FlushInputPin;
194 OpenWire::SinkPin DisconnectInputPin;
195
196 protected:
197 T_CLIENT FClient;
198
199 protected:
200 void DoDisconnect( void *_Data )
201 {
202 FClient.flush();
203 FClient.stop();
204 ConnectedOutputPin.SetValue( false, true );
205// Serial.println( "DoDisconnect" );
206// Serial.println( FClient.connected() );
207 }
208
209 void DoFlush( void *_Data )
210 {
211 FClient.flush();
212 }
213
214 public:
215 virtual Print *GetPrint()
216 {
217 return &FClient;
218 }
219
220 public:
221 virtual void SystemInit()
222 {
223 ConnectedOutputPin.SetValue( false, false );
224 inherited::SystemInit();
225 }
226
227 public:
228 BasicEthernetConnectSocket( T_OWNER &AOwner ) :
229 inherited( AOwner )
230 {
231 FlushInputPin.SetCallback( this, (OpenWire::TOnPinReceive)&BasicEthernetConnectSocket::DoFlush );
232
233 DisconnectInputPin.SetCallback( this, (OpenWire::TOnPinReceive)&BasicEthernetConnectSocket::DoDisconnect );
234 }
235
236 };
237//---------------------------------------------------------------------------
238 template<typename T_OWNER, typename T_CLIENT> class TCPClientSocket : public BasicEthernetConnectSocket<T_OWNER, T_CLIENT>
239 {
240 typedef BasicEthernetConnectSocket<T_OWNER, T_CLIENT> inherited;
241
242 public:
243 String URL;
244 ::IPAddress IPAddress;
245
246 protected:
247 virtual void StartSocket()
248 {
249// Serial.println( "StartSocket" );
250 if( URL.length() )
251 inherited::FClient.connect( URL.c_str(), inherited::Port );
252
253 else
254 {
255// IPAddress.printTo( Serial );
256 inherited::FClient.connect( IPAddress, inherited::Port );
257 }
258 }
259
260 virtual void StopSocket()
261 {
262 inherited::FClient.flush();
263 inherited::FClient.stop();
264 inherited::ConnectedOutputPin.SetValue( false, true );
265 }
266
267 public:
268 virtual void SystemLoopBegin( unsigned long currentMicros )
269 {
270 if ( inherited::FClient.available() )
271 {
272 unsigned char AByte = inherited::FClient.read();
273 inherited::OutputPin.SendValue( Mitov::TDataBlock( 1, &AByte ));
274// inherited::OutputPin.Notify( &AByte );
275 }
276
277 inherited::ConnectedOutputPin.SetValue( inherited::FClient.connected(), true );
278
279 if (! inherited::FClient.connected())
280 {
281 inherited::FClient.stop(); // Do we need this?
282 inherited::ConnectedOutputPin.SetValue( false, true );
283 }
284
285 inherited::SystemLoopBegin( currentMicros );
286 }
287
288 public:
289 TCPClientSocket( T_OWNER &AOwner, ::IPAddress AIPAddress ) :
290 inherited( AOwner ),
291 IPAddress( AIPAddress )
292 {
293 }
294 };
295//---------------------------------------------------------------------------
296 template<typename T_OWNER, typename T_SERVER, typename T_CLIENT> class TCPServerSocket : public BasicEthernetConnectSocket<T_OWNER, T_CLIENT>
297 {
298 typedef BasicEthernetConnectSocket<T_OWNER, T_CLIENT> inherited;
299
300 protected:
301 T_SERVER *FServer;
302
303 protected:
304 virtual void StartSocket()
305 {
306// Serial.println( "StartSockect" );
307 if( FServer )
308 return;
309
310// Serial.println( Port );
311 FServer = new T_SERVER( inherited::Port );
312 FServer->begin();
313// Serial.println( "Start Server Sockect" );
314// Serial.println( inherited::Port );
315 }
316
317 virtual void SystemLoopBegin( unsigned long currentMicros )
318 {
319 if( FServer )
320 {
321 if( ! inherited::FClient )
322 {
323// Serial.println( inherited::Port );
324// Serial.println( "TRY CLIENT" );
325 inherited::FClient = FServer->available();
326
327// if( inherited::FClient )
328// Serial.println( "CLIENT" );
329
330// Serial.println( "TRY CLIENT OUT" );
331 }
332
333/*
334 if( inherited::FClient )
335 if (! inherited::FClient.connected())
336 {
337 Serial.println( "STOP" );
338 inherited::FClient.stop(); // Do we need this?
339 }
340*/
341 if( inherited::FClient )
342 {
343// Serial.println( "CLIENT" );
344 if( inherited::FClient.available() )
345 {
346 unsigned char AByte = inherited::FClient.read();
347// Serial.println( "RECEIVED" );
348 inherited::OutputPin.SendValue( Mitov::TDataBlock( 1, &AByte ));
349// inherited::OutputPin.Notify( &AByte );
350 }
351
352 if( ! inherited::FClient.connected() )
353 {
354// Serial.println( "STOP" );
355 inherited::FClient.stop(); // Do we need this?
356 inherited::ConnectedOutputPin.SetValue( false, true );
357 }
358 }
359 }
360
361// Serial.println( inherited::FClient.connected() );
362
363 inherited::ConnectedOutputPin.SetValue( inherited::FClient.connected(), true );
364// Serial.println( "SYSTEM_LOOP" );
365 inherited::SystemLoopBegin( currentMicros );
366// Serial.println( "SYSTEM_LOOP_OUT" );
367 }
368
369 public:
370 virtual bool CanSend()
371 {
372 return inherited::Enabled && inherited::FOwner.Enabled && inherited::FClient;
373 }
374
375 virtual void StopSocket()
376 {
377 if( FServer )
378 {
379 delete FServer;
380 FServer = NULL;
381 }
382 }
383
384/*
385 virtual void EndPacket()
386 {
387 Serial.println( "EndPacket" );
388// inherited::FClient.flush();
389// delay(1000);
390// inherited::FClient.stop();
391 }
392*/
393 public:
394 TCPServerSocket( T_OWNER &AOwner ) :
395 inherited( AOwner ),
396 FServer( NULL )
397 {
398 }
399
400/*
401 virtual ~TCPServerSocket()
402 {
403 if( FServer )
404 delete FServer;
405 }
406*/
407 };
408//---------------------------------------------------------------------------
409 template<typename T_OWNER, typename T_UDP> class UDPSocket : public BasicEthernetSocket<T_OWNER>
410 {
411 typedef BasicEthernetSocket<T_OWNER> inherited;
412
413 public:
414 OpenWire::SourcePin RemoteIPOutputPin;
415 OpenWire::SourcePin RemotePortOutputPin;
416
417 public:
418 unsigned int RemotePort = 80;
419 ::IPAddress RemoteIPAddress;
420
421 protected:
422 T_UDP FSocket;
423 String FHostName;
424 bool FResolved;
425
426 public:
427 virtual bool CanSend()
428 {
429 return FResolved && inherited::CanSend();
430 }
431
432 protected:
433 virtual void StartSocket()
434 {
435 if( FHostName != "" )
436 {
437// Serial.println( "TEST1" );
438 FResolved = inherited::FOwner.GetIPFromHostName( FHostName, RemoteIPAddress );
439 }
440
441// Serial.print( "StartSocket: " );
442// Serial.println( inherited::Port );
443 FSocket.begin( inherited::Port );
444 }
445
446 public:
447 virtual void BeginPacket()
448 {
449// Serial.print( "BeginPacket: " );
450// Serial.print( RemoteIPAddress );
451// Serial.print( " " );
452// Serial.println( RemotePort );
453 FSocket.beginPacket( RemoteIPAddress, RemotePort );
454//// FSocket.beginPacket( RemoteIPAddress, 8888 );
455// FSocket.println( "Hello1" );
456//// FSocket.endPacket();
457 }
458
459 virtual void EndPacket()
460 {
461// Serial.println( "EndPacket" );
462// FSocket.println( "Hello" );
463 FSocket.endPacket();
464// delay( 1000 );
465 }
466
467 virtual void StopSocket()
468 {
469// Serial.println( "StopSocket" );
470 FSocket.stop();
471 }
472
473 virtual Print *GetPrint()
474 {
475// FSocket.println( "Hello2" );
476// return &Serial;
477// Serial.println( "GetPrint" );
478 return &FSocket;
479 }
480
481 public:
482 virtual void SystemLoopBegin( unsigned long currentMicros )
483 {
484 int APacketSize = FSocket.parsePacket();
485 if( APacketSize )
486 {
487// Serial.println( APacketSize );
488 byte *Adata = new byte[ APacketSize ];
489 FSocket.read( Adata, APacketSize );
490
491 inherited::OutputPin.SendValue( Mitov::TDataBlock( APacketSize, Adata ));
492 RemoteIPOutputPin.SendValue( IPAdressToString( FSocket.remoteIP() ));
493 RemotePortOutputPin.SendValue( FSocket.remotePort() );
494
495 delete []Adata;
496 }
497/*
498 if ( FSocket.available() )
499 {
500 unsigned char AByte = FSocket.read();
501 inherited::OutputPin.Notify( &AByte );
502 }
503*/
504 inherited::SystemLoopBegin( currentMicros );
505 }
506
507 public:
508 UDPSocket( T_OWNER &AOwner, ::IPAddress ARemoteIPAddress ) :
509 inherited( AOwner ),
510 RemoteIPAddress( ARemoteIPAddress ),
511 FResolved( true )
512 {
513 }
514
515 UDPSocket( T_OWNER &AOwner, String AHostName ) :
516 inherited( AOwner ),
517 FHostName( AHostName ),
518 FResolved( false )
519 {
520 }
521 };
522//---------------------------------------------------------------------------
523 class BasicEthernetShield : public OpenWire::Component
524 {
525 typedef OpenWire::Component inherited;
526
527 public:
528 Mitov::SimpleList<BasicEthernetSocket<BasicEthernetShield>*> Sockets;
529
530 public:
531 bool Enabled = true;
532
533 public:
534 void SetEnabled( bool AValue )
535 {
536 if( Enabled == AValue )
537 return;
538
539 Enabled = AValue;
540 if( Enabled )
541 StartEthernet();
542
543 else
544 StopEthernet();
545
546 }
547
548 public:
549 virtual bool GetIPFromHostName( String AHostName, ::IPAddress &AAdress ) = 0;
550
551 protected:
552 virtual void SystemInit()
553 {
554 if( Enabled )
555 StartEthernet();
556
557 inherited::SystemInit();
558 }
559
560 virtual void StopEthernet()
561 {
562 for( int i = 0; i < Sockets.size(); ++i )
563 Sockets[ i ]->StopSocket();
564 }
565
566 void RestartEthernet()
567 {
568 if( ! Enabled )
569 return;
570
571// T_SERIAL->end();
572// Ethernet.end();
573 StartEthernet();
574 }
575
576 virtual void StartEthernet() = 0;
577
578 };
579//---------------------------------------------------------------------------
580 template<typename T_ROOT, T_ROOT *T_INSTANCE, typename T> class EthernetSocketInput : public Mitov::CommonSink
581 {
582 typedef Mitov::CommonSink inherited;
583
584 protected:
585 virtual void DoReceive( void *_Data )
586 {
587// Serial.print( "DoReceive" );
588 if( T_INSTANCE->CanSend() )
589 {
590 T_INSTANCE->BeginPacket();
591
592// Serial.print( "PRINT: " );
593// Serial.println( *(T*)_Data );
594
595 T_INSTANCE->GetPrint()->println( *(T*)_Data );
596 T_INSTANCE->EndPacket();
597 }
598 }
599 };
600//---------------------------------------------------------------------------
601 template<typename T_ROOT, T_ROOT *T_INSTANCE> class EthernetSocketBinaryInput : public Mitov::CommonSink
602 {
603 typedef Mitov::CommonSink inherited;
604
605 protected:
606 virtual void DoReceive( void *_Data )
607 {
608 if( T_INSTANCE->CanSend() )
609 {
610 T_INSTANCE->BeginPacket();
611 Mitov::TDataBlock ADataBlock = *(Mitov::TDataBlock*)_Data;
612
613// Serial.println( ADataBlock.Size );
614 T_INSTANCE->GetPrint()->write((uint8_t *) ADataBlock.Data, ADataBlock.Size );
615// T_INSTANCE->GetPrint()->write( *(unsigned char*)_Data );
616 T_INSTANCE->EndPacket();
617 }
618 }
619 };
620//---------------------------------------------------------------------------
621 template<typename T_ROOT, T_ROOT *T_INSTANCE> class EthernetSocketStringInput : public Mitov::CommonSink
622 {
623 typedef Mitov::CommonSink inherited;
624
625 protected:
626 virtual void DoReceive( void *_Data )
627 {
628 if( T_INSTANCE->CanSend() )
629 {
630 T_INSTANCE->BeginPacket();
631 T_INSTANCE->GetPrint()->println( (char*)_Data );
632 T_INSTANCE->EndPacket();
633 }
634 }
635 };
636//---------------------------------------------------------------------------
637 template<typename T_ROOT, T_ROOT *T_INSTANCE, typename T_OBJECT> class EthernetSocketObjectInput : public Mitov::CommonSink
638 {
639 typedef Mitov::CommonSink inherited;
640
641 protected:
642 virtual void DoReceive( void *_Data )
643 {
644 if( T_INSTANCE->CanSend() )
645 {
646 T_INSTANCE->BeginPacket();
647 Print *APrint = T_INSTANCE->GetPrint();
648 APrint->println( ((T_OBJECT *)_Data)->ToString().c_str() );
649 T_INSTANCE->EndPacket();
650 }
651 }
652 };
653//---------------------------------------------------------------------------
654}
655#endif