libraries / Mitov / Mitov_ESP8266_WiFi.hon commit Added link to project report (97a3ba0)
   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