/**
 * Resolve the given hostname to an IP address.
 * @param aHostname     Name to be resolved
 * @param aResult       IPAddress structure to store the returned IP address
 * @return 1 if aIPAddrString was successfully converted to an IP address,
 *          else error code
 */
int ESP8266WiFiGenericClass::hostByName(const char* aHostname, IPAddress& aResult) {
    ip_addr_t addr;
    aResult = static_cast<uint32_t>(0);

    if(aResult.fromString(aHostname)) {
        // Host name is a IP address use it!
        DEBUG_WIFI_GENERIC("[hostByName] Host: %s is a IP!\n", aHostname);
        return 1;
    }

    DEBUG_WIFI_GENERIC("[hostByName] request IP for: %s\n", aHostname);
    err_t err = dns_gethostbyname(aHostname, &addr, &wifi_dns_found_callback, &aResult);
    if(err == ERR_OK) {
        aResult = addr.addr;
    } else if(err == ERR_INPROGRESS) {
        esp_yield();
        // will return here when dns_found_callback fires
        if(aResult != 0) {
            err = ERR_OK;
        }
    }

    if(err != 0) {
        DEBUG_WIFI_GENERIC("[hostByName] Host: %s lookup error: %d!\n", aHostname, err);
    } else {
        DEBUG_WIFI_GENERIC("[hostByName] Host: %s IP: %s\n", aHostname, aResult.toString().c_str());
    }

    return (err == ERR_OK) ? 1 : 0;
}
Exemplo n.º 2
0
/**
 * Set ESP8266 station DHCP hostname
 * @param aHostname max length:24
 * @return ok
 */
bool ESP8266WiFiSTAClass::hostname(const char* aHostname) {
  /*
  vvvv RFC952 vvvv
  ASSUMPTIONS
  1. A "name" (Net, Host, Gateway, or Domain name) is a text string up
   to 24 characters drawn from the alphabet (A-Z), digits (0-9), minus
   sign (-), and period (.).  Note that periods are only allowed when
   they serve to delimit components of "domain style names". (See
   RFC-921, "Domain Name System Implementation Schedule", for
   background).  No blank or space characters are permitted as part of a
   name. No distinction is made between upper and lower case.  The first
   character must be an alpha character.  The last character must not be
   a minus sign or period.  A host which serves as a GATEWAY should have
   "-GATEWAY" or "-GW" as part of its name.  Hosts which do not serve as
   Internet gateways should not use "-GATEWAY" and "-GW" as part of
   their names. A host which is a TAC should have "-TAC" as the last
   part of its host name, if it is a DoD host.  Single character names
   or nicknames are not allowed.
  ^^^^ RFC952 ^^^^

  - 24 chars max
  - only a..z A..Z 0..9 '-'
  - no '-' as last char
  */

    size_t len = strlen(aHostname);

    if (len == 0 || len > 32) {
        // nonos-sdk limit is 32
        // (dhcp hostname option minimum size is ~60)
        DEBUG_WIFI_GENERIC("WiFi.(set)hostname(): empty or large(>32) name\n");
        return false;
    }

    // check RFC compliance
    bool compliant = (len <= 24);
    for (size_t i = 0; compliant && i < len; i++)
        if (!isalnum(aHostname[i]) && aHostname[i] != '-')
            compliant = false;
    if (aHostname[len - 1] == '-')
        compliant = false;

    if (!compliant) {
        DEBUG_WIFI_GENERIC("hostname '%s' is not compliant with RFC952\n", aHostname);
    }

    bool ret = wifi_station_set_hostname(aHostname);
    if (!ret) {
        DEBUG_WIFI_GENERIC("WiFi.hostname(%s): wifi_station_set_hostname() failed\n", aHostname);
        return false;
    }

    // now we should inform dhcp server for this change, using lwip_renew()
    // looping through all existing interface
    // harmless for AP, also compatible with ethernet adapters (to come)
    for (netif* intf = netif_list; intf; intf = intf->next) {

        // unconditionally update all known interfaces
#if LWIP_VERSION_MAJOR == 1
        intf->hostname = (char*)wifi_station_get_hostname();
#else
        intf->hostname = wifi_station_get_hostname();
#endif

        if (netif_dhcp_data(intf) != nullptr) {
            // renew already started DHCP leases
            err_t lwipret = dhcp_renew(intf);
            if (lwipret != ERR_OK) {
                DEBUG_WIFI_GENERIC("WiFi.hostname(%s): lwIP error %d on interface %c%c (index %d)\n",
                                   intf->hostname, (int)lwipret, intf->name[0], intf->name[1], intf->num);
                ret = false;
            }
        }
    }

    return ret && compliant;
}
Exemplo n.º 3
0
/**
 * set Sleep mode
 * @param type sleep_type_t
 * @return bool
 */
bool ESP8266WiFiGenericClass::setSleepMode(WiFiSleepType_t type, uint8_t listenInterval) {

   /**
    * datasheet:
    *
   wifi_set_sleep_level():
   Set sleep level of modem sleep and light sleep
   This configuration should be called before calling wifi_set_sleep_type
   Modem-sleep and light sleep mode have minimum and maximum sleep levels.
   - In minimum sleep level, station wakes up at every DTIM to receive
     beacon.  Broadcast data will not be lost because it is transmitted after
     DTIM.  However, it can not save much more power if DTIM period is short,
     as specified in AP.
   - In maximum sleep level, station wakes up at every listen interval to
     receive beacon.  Broadcast data may be lost because station may be in sleep
     state at DTIM time.  If listen interval is longer, more power will be saved, but
     it’s very likely to lose more broadcast data.
   - Default setting is minimum sleep level.
   Further reading: https://routerguide.net/dtim-interval-period-best-setting/

   wifi_set_listen_interval():
   Set listen interval of maximum sleep level for modem sleep and light sleep
   It only works when sleep level is set as MAX_SLEEP_T
   It should be called following the order:
     wifi_set_sleep_level(MAX_SLEEP_T)
     wifi_set_listen_interval
     wifi_set_sleep_type
   forum: https://github.com/espressif/ESP8266_NONOS_SDK/issues/165#issuecomment-416121920
   default value seems to be 3 (as recommended by https://routerguide.net/dtim-interval-period-best-setting/)
    */

#ifdef DEBUG_ESP_WIFI
    if (listenInterval && type == WIFI_NONE_SLEEP)
        DEBUG_WIFI_GENERIC("listenInterval not usable with WIFI_NONE_SLEEP\n");
#endif

      if (type == WIFI_LIGHT_SLEEP || type == WIFI_MODEM_SLEEP) {
        if (listenInterval) {
            if (!wifi_set_sleep_level(MAX_SLEEP_T)) {
                DEBUG_WIFI_GENERIC("wifi_set_sleep_level(MAX_SLEEP_T): error\n");
                return false;
            }
            if (listenInterval > 10) {
                DEBUG_WIFI_GENERIC("listenInterval must be in [1..10]\n");
#ifndef DEBUG_ESP_WIFI
                // stay within datasheet range when not in debug mode
                listenInterval = 10;
#endif
            }
            if (!wifi_set_listen_interval(listenInterval)) {
                DEBUG_WIFI_GENERIC("wifi_set_listen_interval(%d): error\n", listenInterval);
                return false;
            }
        } else {
            if (!wifi_set_sleep_level(MIN_SLEEP_T)) {
                DEBUG_WIFI_GENERIC("wifi_set_sleep_level(MIN_SLEEP_T): error\n");
                return false;
            }
        }
    }
    bool ret = wifi_set_sleep_type((sleep_type_t) type);
    if (!ret) {
        DEBUG_WIFI_GENERIC("wifi_set_sleep_type(%d): error\n", (int)type);
    }
    return ret;
}