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_ESP8266_WIFI_h
11#define _MITOV_ESP8266_WIFI_h
12
13#include <Mitov.h>
14#include <Mitov_BasicEthernet.h>
15#include <ESP8266WiFi.h>
16//#include "ip_addr.h"
17//#include "espconn.h"
18
19namespace Mitov
20{
21 class ESP8266WiFiModule;
22//---------------------------------------------------------------------------
23 class ESP8266WiFiModuleOptionalDisabledElement
24 {
25 public:
26 bool Enabled = false;
27
28 };
29//---------------------------------------------------------------------------
30 class ESP8266WiFiModuleOptionalChannel : public ESP8266WiFiModuleOptionalDisabledElement
31 {
32 public:
33 unsigned long Channel = 1;
34
35 };
36//---------------------------------------------------------------------------
37 class ESP8266WiFiModuleOptionalIPConfig : public ESP8266WiFiModuleOptionalDisabledElement
38 {
39 public:
40 ::IPAddress IP;
41
42 };
43//---------------------------------------------------------------------------
44 class ESP8266WiFiModuleAccessPointConfig
45 {
46 public:
47 bool Enabled = false;
48
49 ::IPAddress IP;
50 ::IPAddress Gateway;
51 ::IPAddress Subnet;
52
53 };
54//---------------------------------------------------------------------------
55 class ESP8266WiFiModuleRemoteConfig : public ESP8266WiFiModuleAccessPointConfig
56 {
57 public:
58 ESP8266WiFiModuleOptionalIPConfig DNS;
59 };
60//---------------------------------------------------------------------------
61 class ESP8266WiFiModuleOptionalMacAddress : public ESP8266WiFiModuleOptionalDisabledElement
62 {
63 public:
64 TMACAddress MacAddress;
65
66 };
67//---------------------------------------------------------------------------
68 class ESP8266ModuleRemoteAccessPoint
69 {
70 public:
71 bool Enabled = true;
72 String SSID;
73 String Password;
74 ESP8266WiFiModuleOptionalChannel Channel;
75 ESP8266WiFiModuleOptionalMacAddress MacAddress;
76 ESP8266WiFiModuleRemoteConfig Config;
77
78// protected:
79// ESP8266WiFiModule &FOwner;
80
81 public:
82 bool Connect()
83 {
84 if( ! Enabled )
85 return false;
86
87 if( SSID == "" )
88 return false;
89
90 const char *APassword;
91 if( Password == "" )
92 APassword = NULL;
93
94 else
95 APassword = Password.c_str();
96
97 int32_t channel;
98
99 if( Channel.Enabled )
100 channel = Channel.Channel;
101
102 else
103 channel = 0;
104
105 const uint8_t* bssid;
106
107 if( MacAddress.Enabled )
108 bssid = MacAddress.MacAddress.FMacAddress;
109
110 else
111 bssid = NULL;
112
113// Serial.println( SSID );
114// Serial.println( APassword );
115
116 if( Config.Enabled )
117 {
118 if( Config.DNS.Enabled )
119 WiFi.config( Config.IP, Config.Gateway, Config.Subnet, Config.DNS.IP );
120
121 else
122 WiFi.config( Config.IP, Config.Gateway, Config.Subnet);
123 }
124
125 WiFi.begin( (char *)SSID.c_str(), APassword, channel, bssid );
126
127 for(;;)
128 {
129// Serial.print( "." ) ;
130 int ARes = WiFi.status();
131 if( ARes == WL_CONNECTED )
132 return true;
133
134 if( ARes == WL_CONNECT_FAILED )
135 return false;
136
137 delay(500);
138 }
139
140/*
141 while (WiFi.status() != WL_CONNECTED) {
142 WL_CONNECT_FAILED
143
144 return ( ARes == WL_CONNECTED );
145*/
146// return ( WiFi.begin( (char *)SSID.c_str(), APassword, channel, bssid ) == WL_CONNECTED );
147
148
149// return ( WiFi.begin( (char *)SSID.c_str() ) == WL_CONNECTED );
150
151
152/*
153 if( Password == "" )
154 return ( LWiFi.connect( SSID.c_str() ) > 0 );
155
156 switch( Encription )
157 {
158 case liweAuto:
159 {
160 if( LWiFi.connectWPA( SSID.c_str(), Password.c_str() ) > 0 )
161 return true;
162
163 return( LWiFi.connectWEP( SSID.c_str(), Password.c_str() ) > 0 );
164 }
165
166 case liweWEP:
167 return( LWiFi.connectWEP( SSID.c_str(), Password.c_str() ) > 0 );
168
169 case liweWPA:
170 return( LWiFi.connectWPA( SSID.c_str(), Password.c_str() ) > 0 );
171 }
172*/
173 }
174
175 protected:
176 void RegisterIn( ESP8266WiFiModule &AOwner );
177
178 public:
179 ESP8266ModuleRemoteAccessPoint( ESP8266WiFiModule &AOwner, TMACAddress AMacAddress ) :
180 ESP8266ModuleRemoteAccessPoint( AOwner )
181 {
182 MacAddress.MacAddress = AMacAddress;
183 }
184
185 ESP8266ModuleRemoteAccessPoint( ESP8266WiFiModule &AOwner )
186 {
187 RegisterIn( AOwner );
188 }
189
190 };
191//---------------------------------------------------------------------------
192 class ESP8266WiFiModuleAccessPoint
193 {
194 protected:
195 ESP8266WiFiModule *FOwner;
196
197 public:
198 bool Enabled = true;
199 String SSID;
200 String Password;
201
202 unsigned long Channel = 1;
203 bool IsHidden = false;
204
205 ESP8266WiFiModuleAccessPointConfig Config;
206
207 public:
208 void SetEnabled( bool AValue )
209 {
210 if( Enabled == AValue )
211 return;
212
213 Enabled = AValue;
214 if( Enabled )
215 TryStart();
216
217 else
218 WiFi.softAPdisconnect();
219
220 }
221
222 public:
223 void TryStart();
224
225 public:
226 ESP8266WiFiModuleAccessPoint( ESP8266WiFiModule * AOwner ) :
227 FOwner( AOwner )
228 {
229 }
230 };
231//---------------------------------------------------------------------------
232 class ESP8266ModuleScanNetworksOperation : public OpenWire::Component
233 {
234 typedef OpenWire::Component inherited;
235
236 public:
237 OpenWire::SinkPin ScanInputPin;
238
239 OpenWire::SourcePin CountOutputPin;
240
241 OpenWire::SourcePin SignalStrengthOutputPin;
242 OpenWire::SourcePin SSIDOutputPin;
243 OpenWire::SourcePin ChannelOutputPin;
244 OpenWire::SourcePin EncryptionOutputPin;
245 OpenWire::SourcePin IsHiddenOutputPin;
246 OpenWire::SourcePin MACAddressOutputPin;
247
248 OpenWire::TypedSourcePin<bool> ScanningOutputPin;
249 OpenWire::SourcePin FailedOutputPin;
250 OpenWire::SourcePin FoundNetworkOutputPin;
251
252 protected:
253 bool FScanRequest = false;
254
255 protected:
256 virtual void SystemLoopBegin( unsigned long currentMicros )
257 {
258 inherited::SystemLoopBegin( currentMicros );
259 ScanningOutputPin.SetValue( FScanRequest, true );
260 if( FScanRequest )
261 {
262 int8_t AComplete = WiFi.scanComplete();
263 if( AComplete == WIFI_SCAN_FAILED )
264 {
265 FailedOutputPin.Notify( NULL );
266 CountOutputPin.SendValue( 0 );
267 FScanRequest = false;
268 }
269
270 else if( AComplete >= 0 )
271 {
272 CountOutputPin.SendValue( (int)AComplete );
273 for( int i = 0; i < AComplete; i ++ )
274 {
275 String ssid;
276 uint8_t encryptionType;
277 int32_t ASetrength;
278 uint8_t* BSSID;
279 int32_t channel;
280 bool isHidden;
281 if( WiFi.getNetworkInfo( i, ssid, encryptionType, ASetrength, BSSID, channel, isHidden ))
282 {
283 String BSSIDStr = WiFi.BSSIDstr( i );
284
285 SSIDOutputPin.Notify( (void *)ssid.c_str() );
286 SignalStrengthOutputPin.Notify( &ASetrength );
287 EncryptionOutputPin.Notify( &encryptionType );
288 MACAddressOutputPin.Notify( (void *)BSSIDStr.c_str() );
289 ChannelOutputPin.Notify( &channel );
290 IsHiddenOutputPin.Notify( &isHidden );
291 }
292
293 FoundNetworkOutputPin.Notify( NULL );
294 }
295
296 FScanRequest = false;
297 }
298 }
299 }
300
301 protected:
302 void DoScanNetworks( void *_Data )
303 {
304 if( WiFi.scanComplete() != WIFI_SCAN_RUNNING )
305 {
306 WiFi.scanNetworks( true );
307 FScanRequest = true;
308 }
309/*
310 for( int i = 0; i < nearbyAccessPointCount; i ++ )
311 {
312 FoundSSIDOutputPin.Notify( LWiFi.SSID( i ));
313
314 int32_t ASetrength = LWiFi.RSSI( i );
315 FoundSignalStrengthOutputPin.Notify( &ASetrength );
316 }
317*/
318 }
319
320 public:
321 ESP8266ModuleScanNetworksOperation()
322 {
323 ScanInputPin.SetCallback( this, (OpenWire::TOnPinReceive)&ESP8266ModuleScanNetworksOperation::DoScanNetworks );
324 }
325 };
326//---------------------------------------------------------------------------
327 class ESP8266WiFiModule : public Mitov::BasicEthernetShield
328 {
329 typedef Mitov::BasicEthernetShield inherited;
330
331 public:
332 OpenWire::SourcePin AddressOutputPin;
333 OpenWire::SourcePin MACOutputPin;
334
335 OpenWire::SourcePin BSSIDOutputPin;
336 OpenWire::SourcePin GatewayIPOutputPin;
337 OpenWire::SourcePin SubnetMaskIPOutputPin;
338
339 OpenWire::TypedSourcePin<bool> RemoteConnectedOutputPin;
340
341 public:
342 ESP8266WiFiModuleAccessPoint AccessPoint;
343 Mitov::SimpleObjectList<ESP8266ModuleRemoteAccessPoint*> AccessPoints;
344
345 public:
346 bool AutoReconnect = true;
347 String HostName;
348
349 public:
350 bool IsStarted = false;
351
352 public:
353 virtual bool GetIPFromHostName( String AHostName, ::IPAddress &AAdress )
354 {
355 bool AResult = ( WiFi.hostByName( AHostName.c_str(), AAdress ) == 1 );
356 if( ! AResult )
357 AAdress = INADDR_NONE;
358
359 return AResult;
360 }
361
362 protected:
363 void StopEthernet()
364 {
365 inherited::StopEthernet();
366
367 WiFi.disconnect( true );
368 IsStarted = false;
369 }
370
371 void StartEthernet()
372 {
373/*
374 if( ! AccessPoints.length() )
375 return;
376
377 if( ! Sockets.length() )
378 return;
379*/
380// Serial.println( "TRY CONNECT" );
381 if( HostName != "" )
382 {
383 WiFi.hostname( HostName );
384// espconn_mdns_set_hostname( (char *) HostName.c_str() );
385 }
386
387
388 bool AConnected = false;
389 for( int i = 0; i < AccessPoints.size(); ++i )
390 if( AccessPoints[ i ]->Connect() )
391 {
392 AConnected = true;
393// Serial.println( "CONNECT" );
394
395 if( AddressOutputPin.IsConnected() )
396 {
397 String IPAddress = IPAdressToString( WiFi.localIP());
398 AddressOutputPin.Notify( (void *)IPAddress.c_str() );
399 }
400
401 IsStarted = true;
402// MACOutputPin;
403 break;
404 }
405
406 if( ! AConnected )
407 WiFi.begin();
408
409 RemoteConnectedOutputPin.SetValue( AConnected, true );
410
411 WiFi.setAutoReconnect( AutoReconnect );
412
413 AccessPoint.TryStart();
414
415 if( BSSIDOutputPin.IsConnected() )
416 BSSIDOutputPin.SendValue( WiFi.BSSIDstr() );
417
418 if( GatewayIPOutputPin.IsConnected() )
419 GatewayIPOutputPin.SendValue( IPAdressToString( WiFi.gatewayIP() ));
420
421 if( SubnetMaskIPOutputPin.IsConnected() )
422 SubnetMaskIPOutputPin.SendValue( IPAdressToString( WiFi.subnetMask() ));
423
424
425 }
426
427 protected:
428 virtual void SystemLoopBegin( unsigned long currentMicros )
429 {
430 if( RemoteConnectedOutputPin.IsConnected() )
431 RemoteConnectedOutputPin.SetValue( WiFi.isConnected(), true );
432
433 inherited::SystemLoopBegin( currentMicros );
434 }
435
436/*
437 void DoCheckSignalStrength( void *_Data )
438 {
439 if( IsStarted )
440 if( SignalStrengthOutputPin.IsConnected() )
441 {
442 int32_t ASetrength = WiFi.RSSI();
443 SignalStrengthOutputPin.Notify( &ASetrength );
444 }
445
446 }
447*/
448 public:
449 ESP8266WiFiModule() :
450 AccessPoint( this )
451 {
452// ScanNetworksInputPin.SetCallback( this, (OpenWire::TOnPinReceive)&ESP8266WiFiModule::DoScanNetworks );
453// CheckSignalStrengthInputPin.SetCallback( this, (OpenWire::TOnPinReceive)&ESP8266WiFiModule::DoCheckSignalStrength );
454 }
455
456 };
457//---------------------------------------------------------------------------
458 class ESP8266ModuleClockedOperation : public Mitov::ClockingSupport
459 {
460 protected:
461 ESP8266WiFiModule &FOwner;
462
463 public:
464 ESP8266ModuleClockedOperation( ESP8266WiFiModule &AOwner ) :
465 FOwner( AOwner )
466 {
467 }
468 };
469//---------------------------------------------------------------------------
470 class ESP8266ModuleSignalStrengthOperation : public ESP8266ModuleClockedOperation
471 {
472 typedef ESP8266ModuleClockedOperation inherited;
473
474 public:
475 OpenWire::SourcePin SignalStrengthOutputPin;
476
477 protected:
478 virtual void DoClockReceive( void *_Data ) override
479 {
480 if( inherited::FOwner.IsStarted )
481 if( SignalStrengthOutputPin.IsConnected() )
482 {
483 int32_t ASetrength = WiFi.RSSI();
484 SignalStrengthOutputPin.Notify( &ASetrength );
485 }
486
487 }
488
489 public:
490 using inherited::inherited;
491
492 };
493//---------------------------------------------------------------------------
494 class ESP8266ModuleReconnectOperation : public ESP8266ModuleClockedOperation
495 {
496 typedef ESP8266ModuleClockedOperation inherited;
497
498 protected:
499 virtual void DoClockReceive( void *_Data ) override
500 {
501 WiFi.reconnect();
502 }
503
504 public:
505 using inherited::inherited;
506
507 };
508//---------------------------------------------------------------------------
509 void ESP8266WiFiModuleAccessPoint::TryStart()
510 {
511 if( FOwner->Enabled )
512 if( Enabled )
513 if( SSID != "" )
514 {
515//Serial.println( "TEST1" );
516//Serial.println( SSID );
517//Serial.println( IsHidden );
518 if( Config.Enabled )
519 WiFi.softAPConfig( Config.IP, Config.Gateway, Config.Subnet );
520
521 if( Password != "" )
522 WiFi.softAP( SSID.c_str(), Password.c_str(), Channel, IsHidden );
523
524 else
525// WiFi.softAP( SSID.c_str() );
526 WiFi.softAP( SSID.c_str(), NULL, Channel, IsHidden );
527
528 WiFi.softAPIP();
529 }
530
531 }
532//---------------------------------------------------------------------------
533 void ESP8266ModuleRemoteAccessPoint::RegisterIn( ESP8266WiFiModule &AOwner )
534 {
535 AOwner.AccessPoints.push_back( this );
536 }
537//---------------------------------------------------------------------------
538}
539
540#endif