
////////////////////////////////////////////////////////////////////////////////////////////////////
//ANDRUINO LIBRARY
//A.Scavuzzo
//www.andruino.it
////////////////////////////////////////////////////////////////////////////////////////////////////

void ethsetup_network_setup (bool force_portal);
void ethsetup_server_begin (int port_n);
bool Trigger_pin_param_manager ();

#define IP_PORTAL_LSB           200

///////////////////////////////////////////////////////////
//DISCONNECT

#if WIFI_ESP8266_SHIELD == 1
void ethsetup_network_disconnect () {
  Serial.println(F("Network restarting..."));
  WiFi.disconnect();                    //WIFI
  //release sockets
  memset(WiFi._state, NA_STATE, sizeof(WiFi._state));
}
#endif
#if MCU_ESP8266 == 1
void ethsetup_network_disconnect () {
  Serial.println(F("Network restarting..."));
  //this erase wifi ssid and password, don't use it
  //WiFi.disconnect(true);                    //WIFI
}
#endif

#if ETHERNET_SHIELD == 1 || ETHERNET_SHIELD_V2 == 1
void ethsetup_network_disconnect () {
  Serial.println(F("Network restarting..."));
}
#endif

#if ARDUINO_MK1010_WIFI == 1
void ethsetup_network_disconnect () {
  Serial.println(F("Network restarting..."));
  WiFi.disconnect();                    //WIFI
}
#endif
///////////////////////////////////////////////////////////



#if WIFI_ESP8266_SHIELD == 1
void ethsetup_server_begin ( int port_n) {
  Serial.print(F("Server begin..."));
  _server = WiFiEspServer(port_n);
  _server.begin();
  http_server_enabled = true;
#if (DEBUG_SERIAL == 1)
  Serial.print(F("Server is:"));
  Serial.print(WiFi.localIP());
  Serial.print(F(":"));
  Serial.println(port_n);
#endif
}

#endif
#if MCU_ESP8266 == 1
void ethsetup_server_begin (int port_n) {
  Serial.print(F("Server begin..."));

  _server = WiFiServer(port_n);
  _server.begin();

  http_server_enabled = true;
#if (DEBUG_SERIAL == 1)
  Serial.print(F("Server is:"));
  Serial.print(WiFi.localIP());
  Serial.print(F(":"));
  Serial.println(port_n);
#endif

}
#endif

#if ARDUINO_MK1010_WIFI == 1
void ethsetup_server_begin ( int port_n) {
  Serial.print(F("Server begin..."));
  _server = WiFiServer(port_n);
  _server.begin();
  http_server_enabled = true;
#if (DEBUG_SERIAL == 1)
  Serial.print(F("Server is:"));
  Serial.print(WiFi.localIP());
  Serial.print(F(":"));
  Serial.println(port_n);
#endif
}

#endif


#if ETHERNET_SHIELD == 1 || ETHERNET_SHIELD_V2 == 1
void ethsetup_server_begin  (int port_n) {

  _server = EthernetServer(port_n);
  _server.begin();


  http_server_enabled = true;
  delay(2000);


#if (DEBUG_SERIAL == 1)
  Serial.print(F("Server is:"));
  Serial.print(arduino_ip_address);
  Serial.print(F(":"));
  Serial.println(port_n);
#endif

}
#endif


#define MAX_RETRIES_NUM 2


//////////////////////////////////////////////////////////////////////////////////
//ESP8266
//////////////////////////////////////////////////////////////////////////////////
#if WIFI_ESP8266_SHIELD == 1
void ethsetup_network_setup (bool force_portal) {
  int status = WL_IDLE_STATUS;
  int TimeOut = 0;
  bool captive_portal_en = false;
  char ssid_station_char[SSID_LENGHT] = {'\0'};
  char pass_station_char[PASS_LENGHT] = {'\0'};
  char ap_name[35] = {'\0'};

  ap_enabled = eeprom_read_byteNEW ((FLA_AP_ENABLED_ADDRESS));

  //check if captive portal  PIN is press
  captive_portal_en = Trigger_pin_param_manager();
  if (force_portal)
    captive_portal_en = true;


#ifdef STARTUP_BLINK_LED_ENABLED
  if (captive_portal_en) {
    deattach_interrupt_startup_led_timer();
    attach_interrupt_startup_led_timer(150);
  }
#endif


  Serial.println(F("\nEsp8266 init..."));


  Serial1.begin(115200);
  while (!Serial1) {}

  // attempt to connect to Wifi network:
  while ( status != WL_CONNECTED && TimeOut < 2) {


    //reset ESP8266 (D20=RST)
    pinMode(WIFI_ESP8266_SHIELD_RESET_PIN, OUTPUT);
    digitalWrite(WIFI_ESP8266_SHIELD_RESET_PIN, LOW);
    delay(700);
    digitalWrite(WIFI_ESP8266_SHIELD_RESET_PIN, HIGH);

    //delay before setup ESP (needed)
    delay(1000);
    // initialize ESP module
    WiFi.init(&Serial1);

    // check for the presence of the shield:
    if (WiFi.status() == WL_NO_SHIELD)
      Serial.println(F("WiFi not present"));

    Serial.print(F("ESP fw:"));
    Serial.println(WiFi.firmwareVersion());

    Serial.println(F("WiFi connecting..."));



    if (captive_portal_en || ap_enabled) {
      //ethernet_id created starting from the board name and email
      ethernet_id = 0;
      for (int k = 0; k < sizeof(AndruinoApp_email_array); k++) {
        ethernet_id = ethernet_id + (byte)AndruinoApp_email_array[k];
      }
      for (int k = 0; k < sizeof(board_name_array); k++) {
        ethernet_id = ethernet_id + (byte)board_name_array[k];
      }
      if (pin_push_flash == 0)
        sprintf(ap_name, "Andruino_AP_%d", ethernet_id);
      else
        sprintf(ap_name, "Andruino_AP_%s_%d", board_name_array, ethernet_id);

      Serial.print(F("AP: ")); Serial.print(ap_enabled); Serial.print(F(", ethernet_id:")); Serial.println(ethernet_id);
    }

    if (captive_portal_en) {
      delay(3000);
      IPAddress localIp(10, 0, 1, 200);
      WiFi.configAP(localIp);
      delay(2000);

      status = WiFi.beginAP(ap_name, 10, ESP8266_AP_WIFI_PASS, ENC_TYPE_NONE, 0);
      //Serial1.println("AT+CIPDNS_CUR=1,\"10.0.1.200\"");
      Serial.println("Access point started");
      status = WL_CONNECTED;
      access_point_connection_ok = true;
    }
    else {


      //AP enabled
      if (ap_enabled) {
        Serial.print("Starting AP name: "); Serial.print(ap_name); Serial.print(F("..."));
        IPAddress localIp(192, 168, 1, 253);
        WiFi.config(localIp);

        Serial.print("beginning AP...");
        status = WiFi.beginAP(ap_name, 6, ESP8266_AP_WIFI_PASS, ENC_TYPE_NONE, false);
        if (status) {
          Serial.println(F("AP enabled"));
          access_point_connection_ok = true;
          //to skip the retry if wifi station fail
          TimeOut = 3;
        } else {
          Serial.println(F("AP error"));
        }

        delay(2000);
      }




      //read SSID from flash
      eeprom_read_blockNEW (ssid_station_char, FLA_SSIDWIFI_ADDRESS, SSID_LENGHT);
      eeprom_read_blockNEW (pass_station_char, FLA_PASSWIFI_ADDRESS, PASS_LENGHT);
      Serial.print(F("Connecting to wifi with SSID:"));
      Serial.print(ssid_station_char); Serial.print(F("..."));

      status = WiFi.begin(ssid_station_char, pass_station_char);         // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
      if (status == WL_CONNECTED)  {
        station_connection_ok = true;
        Serial.println(F("connected!"));
      }
      else {
        Serial.println(F("not connected!"));
        station_connection_ok = false;
      }

    }

    TimeOut++;
  }



  if (access_point_connection_ok || station_connection_ok) {

    IPAddress_device =  WiFi.localIP();
    IPAddress gateway = IPAddress_device;
    gateway[3] = GATEWAY_IP_LSB;


#if GATEWAY_DNS == 1
#if ETHERNET_DHCP == 0
    IPAddress_device[3] = IP_LSB;
    //  WiFi.config(IPAddress_device, dnsAdd, gateway);
    WiFi.config(IPAddress_device);
#endif
#else
#if ETHERNET_DHCP == 0
    IPAddress_device[3] = IP_LSB;
    WiFi.config(IPAddress_device);
#endif
#endif


    sprintf(arduino_ip_address, "%d.%d.%d.%d", IPAddress_device[0], IPAddress_device[1], IPAddress_device[2], IPAddress_device[3]);
    printWifiStatus(arduino_ip_address);


    //change IP
    if (captive_portal_en) {
      IPAddress_device[3] = IP_PORTAL_LSB;
#if GATEWAY_DNS == 1
      WiFi.config(IPAddress_device);
      // WiFi.config(IPAddress_device, dnsAdd, gateway);
#else
      WiFi.config(IPAddress_device);
#endif
      sprintf(arduino_ip_address, "%d.%d.%d.%d", IPAddress_device[0], IPAddress_device[1], IPAddress_device[2], IPAddress_device[3]);
      Serial.print(F("arduino_ip_address:"));  Serial.println(arduino_ip_address);
      printWifiStatus(arduino_ip_address);

    }
  }
  else {
    Serial.println(F("not connected!"));
    station_connection_ok = false;
    access_point_connection_ok = false;
  }

  Serial1.println("AT+CSYSWDTENABLE");        //Watchdog, auto restart when program errors occur: enable



  //enable captive portal
  if (captive_portal_en) {
    delay(2000);
    ethsetup_server_begin(80);
    ethernet_manager_portal(80);
  }





}
#endif



#if MCU_ESP8266 == 1
void ethsetup_network_setup (bool force_portal) {

  bool WiFiManager_andruino_en = false;

  Serial.printf_P("ESP8266 Chip id = %08X\n", ESP.getChipId());


  //check if captive portal  PIN is press
  WiFiManager_andruino_en = Trigger_pin_param_manager();
  if (force_portal)
    WiFiManager_andruino_en = true;


  if (WiFiManager_andruino_en) {
#ifdef STARTUP_BLINK_LED_ENABLED
    deattach_interrupt_startup_led_timer();
    attach_interrupt_startup_led_timer(150);
#endif
    station_connection_ok = ethsetup_network_WiFiManager_andruino(true);       //force captive portal
  }
  else {
    station_connection_ok = ethsetup_network_WiFiManager_andruino(false);      //try to autoconnect with stored SSID and password
  }

  /*
    //and goes into a blocking loop awaiting configuration
    if (!station_connection_ok) {
      Serial.println(F("Wifi Manager: CONNECTION ERROR"));
      delay(3000);
      Restart(false, true);
      //reset and try again, or maybe put it to deep sleep
      //ESP.reset();
      //delay(5000);
    }
  */
  if (station_connection_ok) {

    IPAddress_device =  WiFi.localIP();
    IPAddress gateway = IPAddress_device;
    gateway[3] = GATEWAY_IP_LSB;

#if ETHERNET_DHCP == 0
    IPAddress_device[3] = IP_LSB;
    //WiFi.config(IPAddress_device);
    WiFi.config(IPAddress_device, dnsAdd, gateway);
#endif

    sprintf(arduino_ip_address, "%d.%d.%d.%d", IPAddress_device[0], IPAddress_device[1], IPAddress_device[2], IPAddress_device[3]);
    printWifiStatus(arduino_ip_address);
    WiFi.setAutoReconnect(true);
  }

}
#endif



#if ARDUINO_MK1010_WIFI == 1
void ethsetup_network_setup (bool force_portal) {
  int status = WL_IDLE_STATUS;
  int TimeOut = 0;
  bool captive_portal_en = false;
  char ssid_station_char[SSID_LENGHT] = {'\0'};
  char pass_station_char[PASS_LENGHT] = {'\0'};
  char ap_name[35] = {'\0'};

  ap_enabled = eeprom_read_byteNEW ((FLA_AP_ENABLED_ADDRESS));

  //check if captive portal  PIN is press
  captive_portal_en = Trigger_pin_param_manager();
  if (force_portal)
    captive_portal_en = true;


#ifdef STARTUP_BLINK_LED_ENABLED
  if (captive_portal_en) {
    deattach_interrupt_startup_led_timer();
    attach_interrupt_startup_led_timer(150);
  }
#endif


  Serial.println(F("\nWiFiNINA init..."));


  // attempt to connect to Wifi network:
  while ( status != WL_CONNECTED && TimeOut < 2) {



    // check for the presence of the shield:
    if (WiFi.status() == WL_NO_MODULE)
      Serial.println(F("WiFi not present"));

    Serial.print(F("WiFiNINA fw:"));
    Serial.println(WiFi.firmwareVersion());

    Serial.println(F("WiFi connecting..."));



    if (captive_portal_en || ap_enabled) {
      //ethernet_id created starting from the board name and email
      ethernet_id = 0;
      for (int k = 0; k < sizeof(AndruinoApp_email_array); k++) {
        ethernet_id = ethernet_id + (byte)AndruinoApp_email_array[k];
      }
      for (int k = 0; k < sizeof(board_name_array); k++) {
        ethernet_id = ethernet_id + (byte)board_name_array[k];
      }
      if (pin_push_flash == 0)
        sprintf(ap_name, "Andruino_AP_%d", ethernet_id);
      else
        sprintf(ap_name, "Andruino_AP_%s_%d", board_name_array, ethernet_id);

      Serial.print(F("AP: ")); Serial.print(ap_enabled); Serial.print(F(", ethernet_id:")); Serial.println(ethernet_id);
    }

    if (captive_portal_en) {
      delay(3000);
      IPAddress localIp(10, 0, 1, 200);
      WiFi.config(localIp);
      delay(2000);

      //status = WiFi.beginAP(ap_name, 10, ESP8266_AP_WIFI_PASS, ENC_TYPE_NONE, 0);
      status = WiFi.beginAP(ap_name,  ESP8266_AP_WIFI_PASS, 10);
      Serial.println("Access point started");
      status = WL_CONNECTED;
      access_point_connection_ok = true;
    }
    else {


      //AP enabled
      if (ap_enabled) {
        Serial.print("Starting AP name: "); Serial.print(ap_name); Serial.print(F("..."));
        IPAddress localIp(192, 168, 1, 253);
        WiFi.config(localIp);

        Serial.print("beginning AP...");
        status = WiFi.beginAP(ap_name, ESP8266_AP_WIFI_PASS,6);
        if (status) {
          Serial.println(F("AP enabled"));
          access_point_connection_ok = true;
          //to skip the retry if wifi station fail
          TimeOut = 3;
        } else {
          Serial.println(F("AP error"));
        }

        delay(2000);
      }




      //read SSID from flash
      eeprom_read_blockNEW (ssid_station_char, FLA_SSIDWIFI_ADDRESS, SSID_LENGHT);
      eeprom_read_blockNEW (pass_station_char, FLA_PASSWIFI_ADDRESS, PASS_LENGHT);
      Serial.print(F("Connecting to wifi with SSID:"));
      Serial.print(ssid_station_char); Serial.print(F("..."));

      status = WiFi.begin(ssid_station_char, pass_station_char);         // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
      if (status == WL_CONNECTED)  {
        station_connection_ok = true;
        Serial.println(F("connected!"));
      }
      else {
        Serial.println(F("not connected!"));
        station_connection_ok = false;
      }

    }

    TimeOut++;
  }



  if (access_point_connection_ok || station_connection_ok) {

    IPAddress_device =  WiFi.localIP();
    IPAddress gateway = IPAddress_device;
    gateway[3] = GATEWAY_IP_LSB;


#if GATEWAY_DNS == 1
#if ETHERNET_DHCP == 0
    IPAddress_device[3] = IP_LSB;
    //  WiFi.config(IPAddress_device, dnsAdd, gateway);
    WiFi.config(IPAddress_device);
#endif
#else
#if ETHERNET_DHCP == 0
    IPAddress_device[3] = IP_LSB;
    WiFi.config(IPAddress_device);
#endif
#endif


    sprintf(arduino_ip_address, "%d.%d.%d.%d", IPAddress_device[0], IPAddress_device[1], IPAddress_device[2], IPAddress_device[3]);
    printWifiStatus(arduino_ip_address);


    //change IP
    if (captive_portal_en) {
      IPAddress_device[3] = IP_PORTAL_LSB;
#if GATEWAY_DNS == 1
      WiFi.config(IPAddress_device);
      // WiFi.config(IPAddress_device, dnsAdd, gateway);
#else
      WiFi.config(IPAddress_device);
#endif
      sprintf(arduino_ip_address, "%d.%d.%d.%d", IPAddress_device[0], IPAddress_device[1], IPAddress_device[2], IPAddress_device[3]);
      Serial.print(F("arduino_ip_address:"));  Serial.println(arduino_ip_address);
      printWifiStatus(arduino_ip_address);

    }
  }
  else {
    Serial.println(F("not connected!"));
    station_connection_ok = false;
    access_point_connection_ok = false;
  }

  Serial1.println("AT+CSYSWDTENABLE");        //Watchdog, auto restart when program errors occur: enable



  //enable captive portal
  if (captive_portal_en) {
    delay(2000);
    ethsetup_server_begin(80);
    ethernet_manager_portal(80);
  }





}
#endif



//////////////////////////////////////////////////////////////////////////////////
//ETHERNET SHIELD
//////////////////////////////////////////////////////////////////////////////////
#if ETHERNET_SHIELD == 1 || ETHERNET_SHIELD_V2 == 1
void ethsetup_network_setup (bool force_portal) {
  bool captive_portal_en = false;

  Serial.println();
  Serial.println(F("Ethernet card init..."));

  captive_portal_en = Trigger_pin_param_manager();
  if (force_portal)
    captive_portal_en = true;

  station_connection_ok = Ethernet.begin(mac);

  IPAddress_device =  Ethernet.localIP();
  IPAddress gateway = IPAddress_device;
  gateway[3] = GATEWAY_IP_LSB;


#if GATEWAY_DNS == 1
#if ETHERNET_DHCP == 0
  IPAddress_device[3] = IP_LSB;
  station_connection_ok = Ethernet.begin(mac, IPAddress_device, dnsAdd, gateway);   //no DHCP, gatway and dns forced
#else
  station_connection_ok = Ethernet.begin(mac, dnsAdd, gateway);                     //DHCP, gatway and dns forced
#endif
#else
#if ETHERNET_DHCP == 0
  IPAddress_device[3] = IP_LSB;
  Ethernet.begin(mac, IPAddress_device);                    //no DHCP, gatway and dns from modem
#else
  //Ethernet.begin(mac);                                      //DHCP, gatway and dns from modem
#endif
#endif


  sprintf(arduino_ip_address, "%d.%d.%d.%d", IPAddress_device[0], IPAddress_device[1], IPAddress_device[2], IPAddress_device[3]);
  //change IP
  if (captive_portal_en) {
    IPAddress_device[3] = IP_PORTAL_LSB;
#if GATEWAY_DNS == 1
    Ethernet.begin(mac, IPAddress_device, dnsAdd, gateway);  //no DHCP, gatway and dns forced
#else
    Ethernet.begin(mac, IPAddress_device);                  //no DHCP, gatway and dns from modem
#endif
    sprintf(arduino_ip_address, "%d.%d.%d.%d", IPAddress_device[0], IPAddress_device[1], IPAddress_device[2], IPAddress_device[3]);
    Serial.print(F("arduino_ip_address:"));  Serial.println(arduino_ip_address);
  }

#if (DEBUG_SERIAL == 1)
  Serial.print(F("IP is:"));
  Serial.println(arduino_ip_address);
#endif

  //enable captive portal
  if (captive_portal_en) {
    delay(2000);
    ethsetup_server_begin(80);
    ethernet_manager_portal(80);
  }


}
#endif


//////////////////////////////////////////////////////////////////////////////////
//WIFI Status
//////////////////////////////////////////////////////////////////////////////////
#if (WIFI_ESP8266_SHIELD == 1 || MCU_ESP8266 == 1 || ARDUINO_MK1010_WIFI == 1)
void printWifiStatus(char * ip) {

  // print your WiFi shield's IP address:
  Serial.print(F("IP:"));
  Serial.println(ip);

  Get_Wifi_strength();

  byte mac[6] = {0, 0, 0, 0, 0, 0};
  WiFi.macAddress(mac);

  Serial.print(F("MAC: "));
  Serial.print(mac[5], HEX);
  Serial.print(F(":"));
  Serial.print(mac[4], HEX);
  Serial.print(F(":"));
  Serial.print(mac[3], HEX);
  Serial.print(F(":"));
  Serial.print(mac[2], HEX);
  Serial.print(F(":"));
  Serial.print(mac[1], HEX);
  Serial.print(F(":"));
  Serial.println(mac[0], HEX);
  Serial.println();

}

int Get_Wifi_strength() {
  // print the received signal strength:
  int rssi = WiFi.RSSI();
  if (rssi >= -55) {
    wifi_signal_bars = 5;
  } else if (rssi < -55 & rssi >= -65) {
    wifi_signal_bars = 4;
  } else if (rssi < -65 & rssi >= -70) {
    wifi_signal_bars = 3;
  } else if (rssi < -70 & rssi >= -78) {
    wifi_signal_bars = 2;
  } else if (rssi < -78 & rssi >= -82) {
    wifi_signal_bars = 1;
  } else {
    wifi_signal_bars = 0;                 //<82db
  }
  Serial.print(F("Wifi_strength rssi:")); Serial.print(rssi); Serial.print(F(", bars:")); Serial.println(wifi_signal_bars);
  return (rssi);
}

#endif



//#####################################################################
//chech connection
//#####################################################################
bool ethsetup_CheckConnection (char*www_site, byte max_retries) {

  boolean connected = false;
  unsigned int http_performance;
  connected = ethsetup_CheckHttp(www_site, max_retries, http_performance);
  Serial.print(F("Test time:")); Serial.print(http_performance); Serial.println(F("ms"));
  return (connected);
}

//#####################################################################
//chech and send push notification at startup
//#####################################################################
bool ethsetup_SetupPush(bool send_push) {


  //#if PING_ENABLE == 1
  //connect as ping to check if the network or dns is working
  //  http_test_andruino_site = push_SendPush(andruino_it_ip_address, push_user, board_name_array, "ping", "", "", 0, 0, 0, true);
  Serial.print(F("Pinging..."));
  http_test_andruino_site = push_SendPush2(andruino_it_ip_address, "", "", "ping", "", true);

  Serial.print(F("Pinging result:"));
  Serial.println(http_test_andruino_site);

  //if fails uses the hard (HTTP_ANDRUINO_SITEIP_DNS) andruino.it address
  if (!http_test_andruino_site) {
    Serial.println();
    Serial.println(F("Checking with fixed andruino.it"));
    http_test_andruino_site = push_SendPush2(HTTP_ANDRUINO_SITEIP_DNS, "", "", "ping", "", true);
    if (http_test_andruino_site) {
      //store default IP of Andruino.it
      eep_Write_Andruino_it_address(HTTP_ANDRUINO_SITEIP_DNS);
    } else {
      eep_Read_Andruino_it_address();
    }
  }
  //#endif


  if (send_push) {
    //read poweru-up variable
    int valore = eeprom_read_wordNEW (FLA_POWER_ADDRESS);
    //send push notification using flash stored "andruino" address
    push_SendPush(andruino_it_ip_address, push_user, board_name_array, "pow", "", "", 0, valore, SKETCH_VERSION, false);    //(char *type, char *mode,byte port, byte lim,float value);
    valore++;
    //program the power-on cycling
    eeprom_write_wordNEW ((FLA_POWER_ADDRESS), valore);
  }

  return (http_test_andruino_site);

}

//#####################################################################
//chech performance connection
//#####################################################################
bool ethsetup_CheckHttp (char *http_address, byte max_retries, unsigned int &http_performance) {
  boolean connected = false;
  byte retries = 0;
  unsigned long int performance_start = millis();
  while (!connected && retries < max_retries) {
    if (retries > 0) {
      ethbuff_delay_and_stop();
    }
    Serial.print(F("Testing:"));
    connected = _client.connect(http_address, 80);
    retries++;
  }
  if (connected) {
    Serial.println(F("result: PASS"));
  } else {
    Serial.println(F("result: FAIL"));
  }
  http_performance =  (unsigned int)((unsigned long int)millis() - (unsigned long int)performance_start);

  _client.flush();
  _client.stop();
  delay(50);
  return (connected);
}

//#####################################################################
//CAPTIVE PORTAL FOR ETH AND ESP8266 WIFI SHIELD
//#####################################################################
#if ETHERNET_SHIELD == 1 || ETHERNET_SHIELD_V2 == 1 || WIFI_ESP8266_SHIELD  || ARDUINO_MK1010_WIFI
void ethernet_manager_portal(int port_n) {
  Serial.println(F("Ethernet manager started"));
  Serial.println(F("*******************************************"));
  Serial.print(F("Open the browser and connect to: ")); Serial.println(arduino_ip_address);
  Serial.println(F("*******************************************"));

  bool p1A_en;
  bool p2A_en;
  bool p3A_en;
  bool p4A_en;
  bool p5A_en;
  bool p6A_en;

#if WIFI_ESP8266_SHIELD == 1 || ARDUINO_MK1010_WIFI == 1 
  char ssid_station_char[SSID_LENGHT] = {'\0'};
  char pass_station_char[PASS_LENGHT] = {'\0'};
  //read SSID from flash
  eeprom_read_blockNEW (ssid_station_char, FLA_SSIDWIFI_ADDRESS, SSID_LENGHT);
  eeprom_read_blockNEW (pass_station_char, FLA_PASSWIFI_ADDRESS, PASS_LENGHT);
#endif

  bool open_captive = true;

  while (1) {
    p1A_en = true;
    p2A_en = true;
    p3A_en = true;
    p4A_en = true;
    p5A_en = true;
    p6A_en = true;
    int counter = 0;
    int bufferSize = 0;
    // Create a _client connection
    _client = _server.available();

    /*
        if(open_captive) {
          Serial.println(F("open_captive"));
          open_captive=false;
          if(_client.connected()) {
          _client.print(F("Location: http://"));_client.println(arduino_ip_address);
          _client.println(F("HTTP/1.1 302 text/plain"));
          _client.println();
          _client.stop();
          }
        }
    */


    if (_client) {
      Serial.println(F("Connected from external"));
      counter = 0;
      while (_client.connected()) {
        if (_client.available()) {
          bufferSize = 0;
          while (_client.available())
          {
            char c = _client.read();
            if (bufferSize < ETH_TX_RX_MAX_PACKET) {
              eth_buffer[bufferSize] = c;
              bufferSize++;
            }
            if (c == '\n' && bufferSize > 0) {
              //eth_buffer[bufferSize] = '\0';
              bufferSize = 0;
              if (p1A_en) {
                if (json_SearchKeyGET(eth_buffer, "p1A=", AndruinoApp_email_array, sizeof(AndruinoApp_email_array), "\r\n")) {
                  p1A_en = false;
                }
              }
              if (p2A_en) {
                if (json_SearchKeyGET(eth_buffer, "p2A=", AndruinoApp_PIN_array, sizeof(AndruinoApp_PIN_array), "\r\n")) {
                  p2A_en = false;
                }
              }
              if (p3A_en) {
                if (json_SearchKeyGET(eth_buffer, "p3A=", board_name_array, sizeof(board_name_array), "\r\n")) {
                  p3A_en = false;
                }
              }
              if (p4A_en) {
                if (json_SearchKeyGET(eth_buffer, "p4A=", board_PORT_array, sizeof(board_PORT_array), "\r\n")) {
                  p4A_en = false;
                }
              }
#if WIFI_ESP8266_SHIELD == 1  || ARDUINO_MK1010_WIFI == 1 
              if (p5A_en) {
                if (json_SearchKeyGET(eth_buffer, "p5A=", ssid_station_char, sizeof(ssid_station_char), "\r\n")) {
                  p5A_en = false;
                }
              }
              if (p6A_en) {
                if (json_SearchKeyGET(eth_buffer, "p6A=", pass_station_char, sizeof(pass_station_char), "\r\n")) {
                  p6A_en = false;
                }
              }
#endif
              memset(eth_buffer, 0, sizeof(eth_buffer));
            }
            //Serial.print(c);
          }

          _client.println(F("HTTP/1.1 200 OK"));
          _client.println(F("Content-Type: text/html\r\nConnection: close"));
          //   _client.print(F("Location: http://"));_client.println(arduino_ip_address);
          _client.println();
          _client.println(F("<HTML>"));
          _client.println(F("<HEAD>"));
          _client.println(F("<TITLE>Andruino App configuration page</TITLE>"));
          _client.println(F("</HEAD>"));
          _client.println(F("<BODY>"));


          if (!p1A_en && !p2A_en && !p3A_en && !p4A_en) {
            _client.println(F("<font color=\"red\"><H1>Andruino configuration has been updated</H1><font color=\"black\">"));
#if WIFI_ESP8266_SHIELD == 1 || ARDUINO_MK1010_WIFI == 1
            _client.print(F("<br>Wifi ssid: ")); _client.println(ssid_station_char);
            _client.print(F("<br>Wifi password: ")); _client.println(pass_station_char);
            //Save Wifi SSID and PASS
            eeprom_write_blockNEW(ssid_station_char, FLA_SSIDWIFI_ADDRESS, SSID_LENGHT);
            eeprom_write_blockNEW(pass_station_char, FLA_PASSWIFI_ADDRESS, PASS_LENGHT);
#endif
            _client.print(F("<br>email: ")); _client.println(AndruinoApp_email_array);
            _client.print(F("<br>PIN: ")); _client.println(AndruinoApp_PIN_array);
            _client.print(F("<br>board name: ")); _client.println(board_name_array);
            _client.print(F("<br>port: ")); _client.println(board_PORT_array);
            _client.println(F("<br><font color=\"red\">Board is restarting..."));
            _client.println(F("<br>Open AndruinoApp, and pair the new board in the board list menu"));
          } else {
            _client.println(F("<H1>Andruino sketch user configuration</H1>"));
            _client.print(F("<FORM  ACTION=\"http://")); _client.print(arduino_ip_address); _client.println(F("\" method=\"post\" enctype=\"text/plain\" onsubmit=\"return confirm('Are you sure you want to submit?');\">"));


#if WIFI_ESP8266_SHIELD == 1 ||  ARDUINO_MK1010_WIFI == 1
            //read SSID from flash
            eeprom_read_blockNEW (ssid_station_char, FLA_SSIDWIFI_ADDRESS, SSID_LENGHT);
            eeprom_read_blockNEW (pass_station_char, FLA_PASSWIFI_ADDRESS, PASS_LENGHT);
            _client.print(F("Wifi SSID:<br><INPUT TYPE=TEXT NAME=\"p5A\" required=\"required\" VALUE=\"")); _client.print(ssid_station_char); _client.println(F("\" SIZE=\"32\" MAXLENGTH=\"32\"><BR>"));
 //           _client.print(F("Wifi Pass:<br><INPUT TYPE=\"password\" NAME=\"p6A\" required=\"required\" pattern=\"[A-Za-z0-9_]+\" title=\"Max 32 digits\" VALUE=\"")); _client.print(pass_station_char); _client.println(F("\" SIZE=\"32\" MAXLENGTH=\"32\"><BR>"));
            _client.print(F("Wifi Pass:<br><INPUT TYPE=\"password\" NAME=\"p6A\" required=\"required\" title=\"Max 32 digits\" VALUE=\"")); _client.print(pass_station_char); _client.println(F("\" SIZE=\"32\" MAXLENGTH=\"32\"><BR>"));
#endif



            _client.print(F("email App:<br><INPUT TYPE=email NAME=\"p1A\" required=\"required\" pattern=\".+@[a-z0-9.-]+\\.[a-z]{2,}$\" VALUE=\"")); _client.print(AndruinoApp_email_array); _client.println(F("\" SIZE=\"40\" MAXLENGTH=\"40\"><BR>"));
            _client.print(F("PIN App:<br><INPUT TYPE=TEXT NAME=\"p2A\" required=\"required\" pattern=\"\\d*\" title=\"Only 4 digits\" VALUE=\"")); _client.print(AndruinoApp_PIN_array); _client.println(F("\" SIZE=\"4\" MAXLENGTH=\"4\"><BR>"));
            _client.print(F("Board name:<br><INPUT TYPE=TEXT NAME=\"p3A\" required=\"required\" pattern=\"[A-Za-z0-9_]+\"  title=\"Max 19 chars\"  VALUE=\"")); _client.print(board_name_array); _client.println(F("\" SIZE=\"20\" MAXLENGTH=\"19\"><BR>"));
            _client.print(F("Port number:<br><INPUT TYPE=TEXT NAME=\"p4A\"  required=\"required\" pattern=\"\\d*\"  title=\"Max 5 digits\" VALUE=\"")); _client.print(board_PORT_array); _client.println(F("\" SIZE=\"5\" MAXLENGTH=\"5\"><BR>"));
            _client.println(F("<BR>"));
            _client.println(F("<INPUT TYPE=SUBMIT NAME=\"submit\"  VALUE=\"Store params\">"));
            _client.println(F("</FORM>"));
          }

          _client.println(F("<BR>"));
          _client.println(F("</BODY>"));
          _client.println(F("</HTML>"));
          delay(1);
          _client.flush();
          //stopping _client
          _client.stop();
#if WIFI_ESP8266_SHIELD == 1
          Serial1.println("AT+CIPCLOSE=0");               //close connection
#endif
          //restart after push submit button
          if (!p1A_en && !p2A_en && !p3A_en && !p4A_en) {
            eep_Write_Andruino_user_parameters();
            eep_Read_Andruino_user_parameters();
            Restart(false, false);
          }

        }
      }
      //delay(1000);
    }
  }
}
#endif

//#####################################################################
//used to read the PIN used to force the captive portal
//#####################################################################
bool Trigger_pin_param_manager () {
  int timeout = 10;
  byte pin_low = 0;
  bool captive_portal_en = false;

  //if -1 the trigger is disabed
  if (PARAM_MANAGER_TRIGGER_PIN == -1)
    return (0);

  Serial.println(F("Captive portal: check if PARAM_MANAGER_TRIGGER_PIN is press"));

  pinMode(PARAM_MANAGER_TRIGGER_PIN, INPUT);
  digitalWrite(PARAM_MANAGER_TRIGGER_PIN, HIGH);              //pullup
  //if button is press (LOW), enter in Wifi manager mode
  while (timeout > 0) {
    timeout--;
    Serial.print(F("."));
    delay(250);

    if (digitalRead(PARAM_MANAGER_TRIGGER_PIN) == LOW) {
      timeout = 10;
      pin_low++;
      if (pin_low > 6) {
        timeout = 0;
        captive_portal_en = true;
        Serial.println(F("\nForced wifi manager by PIN, connect to Access Point"));
      }
    } else
      pin_low = 0;
  }

  return (captive_portal_en);
}


//#####################################################################
//CAPTIVE PORTAL FOR NODE MCU
//#####################################################################
#if MCU_ESP8266 == 1
bool ethsetup_network_WiFiManager_andruino (bool force_start_portal) {
  bool status_out = false;
  String ssid_station, pass_station;
  char ssid_station_char[SSID_LENGHT] = {'\0'};
  char pass_station_char[PASS_LENGHT] = {'\0'};
  char ap_name[35] = {'\0'};

  Serial.println(F("\nWifi manager started"));

  //disable debug on serial port
  WiFiManager_andruino.setDebugOutput(false);

  WiFiManager_andruinoParameter andruino_email("1", "AndruinoApp email", AndruinoApp_email_array, sizeof(AndruinoApp_email_array));
  WiFiManager_andruinoParameter andruino_PIN("2", "AndruinoApp PIN (4 digits)", AndruinoApp_PIN_array, sizeof(AndruinoApp_PIN_array));
  WiFiManager_andruinoParameter board_name("3", "Board name (20 chars max)", board_name_array, sizeof(board_name_array));
  WiFiManager_andruinoParameter server_port("4", "Server port (5 digits max)", board_PORT_array, sizeof(board_PORT_array));

  //add all your parameters here
  WiFiManager_andruino.addParameter(&andruino_email);
  WiFiManager_andruino.addParameter(&andruino_PIN);
  WiFiManager_andruino.addParameter(&board_name);
  WiFiManager_andruino.addParameter(&server_port);


  //sets timeout until configuration portal gets turned off
  //useful to make it all retry or go to sleep
  //in seconds
  if (pin_push_flash > 0 && force_start_portal == false)
    WiFiManager_andruino.setTimeout(10);
  else
    WiFiManager_andruino.setTimeout(120);

  //WITHOUT THIS THE AP DOES NOT SEEM TO WORK PROPERLY WITH SDK 1.5 , update to at least 1.5.1
  //WiFi.mode(WIFI_STA);


  ap_enabled = eeprom_read_byteNEW ((FLA_AP_ENABLED_ADDRESS));


  ethernet_id = ESP.getChipId();
  Serial.print(F("AP: ")); Serial.print(ap_enabled); Serial.print(F(", ethernet_id:")); Serial.println(ethernet_id);


  // String ssid_captive = "Captive_" + String(ethernet_id);
  // String ssid_ap = "Andruino_" + String(ethernet_id);

  if (pin_push_flash == 0)
    sprintf(ap_name, "Andruino_AP_%d", ethernet_id);
  else
    sprintf(ap_name, "Andruino_AP_%s_%d", board_name_array, ethernet_id);

  if (ap_enabled) {
    Serial.print("Starting AP name: "); Serial.print(ap_name); Serial.print(F("..."));
  }

  if (force_start_portal) {
    status_out = WiFiManager_andruino.startConfigPortal(ap_name, ESP8266_AP_WIFI_PASS, ap_enabled);      //force the captive portal
  }
  else {
    Serial.print(F("Wifi id:")); Serial.println(ethernet_id);
    eeprom_read_blockNEW (ssid_station_char, FLA_SSIDWIFI_ADDRESS, SSID_LENGHT);
    eeprom_read_blockNEW (pass_station_char, FLA_PASSWIFI_ADDRESS, PASS_LENGHT);
    Serial.print(F("Trying to connect to the WiFi SSID station: ")); Serial.println(ssid_station_char);
    status_out = WiFiManager_andruino.autoConnect_ext_ssid(ssid_station_char, pass_station_char, ap_name, ESP8266_AP_WIFI_PASS, ap_enabled);            //try to connect using ssid and pass, if fail, open the captive portal
  }

  if (status_out)
    Serial.println(F("Wifi finished"));
  else
    Serial.println(F("Wifi error connection"));

  //  if(WiFi.getMode() != WIFI_STA)
  //     status_out = false;

  //  WiFi.printDiag(Serial);
  //   WiFi.mode(WIFI_AP_STA);
  //   WiFi.printDiag(Serial);

  if (status_out) {

    
    //store SSID
    WiFiManager_andruino.get_int_ssid_pass(ssid_station, pass_station);

    ssid_station.toCharArray(ssid_station_char, SSID_LENGHT);
    eeprom_write_blockNEW(ssid_station_char, FLA_SSIDWIFI_ADDRESS, SSID_LENGHT);

    pass_station.toCharArray(pass_station_char, PASS_LENGHT);
    eeprom_write_blockNEW(pass_station_char, FLA_PASSWIFI_ADDRESS, PASS_LENGHT);


    Serial.print(F("ssid_station: ")); Serial.println(ssid_station_char);
    // Serial.print(F("pass_station: "));Serial.println(pass_station_char);

    //read updated parameters
    strcpy(AndruinoApp_email_array, andruino_email.getValue());
    strcpy(AndruinoApp_PIN_array, andruino_PIN.getValue());
    strcpy(board_name_array, board_name.getValue());
    strcpy(board_PORT_array, server_port.getValue());

    //store on flash
    eep_Write_Andruino_user_parameters();
    eep_Read_Andruino_user_parameters();

    if (force_start_portal) {
      //restart board
      //     Restart(false,false);
    }
    Serial.print(F("Wifi SSID:")); Serial.println(WiFi.SSID());
  }


  return (status_out);

}
#endif
