Arduino: how can i access to the method "fromString" from the class "IPAddress"

Created on 4 Dec 2016  路  4Comments  路  Source: esp8266/Arduino

I would like to use the method "fromString" from the class "IPAddress".
Please have a look at the file:
...\arduino1_6_8\portable\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\IPAddress.cpp + IPAddress.h ,
there that method is defined!

My code segment:

#include <IPAddress.h>

    // String client_ip and String gateway_ip are loaded befor, from the file config.txt
    // something like: "192.168.111.210" and "192.168.111.4"

    uint8_t nError = 0;

    IPAddress ip();
    if ( !ip.fromString(String& client_ip) ) nError++;
    IPAddress gateway();
    if ( !gateway.fromString(String& gateway_ip) ) nError++;
    if ( nError == 0 ) {
      IPAddress subnet(255, 255, 255, 0); 
      WiFi.config(ip, gateway, subnet);       
    }else{ 
      Serial.print("error IP config");
    }

I get the following errormessage:
error: request for member 'fromString' in 'ip', which is of non-class type 'IPAddress()'

thanks for a little help from my ESP-friends

Most helpful comment

thats great!
thanks very much!
I had to change two things:

  1. drop the parentheses from IPAddress ip(), as you proposed!
  2. drop the Sting& from ip.fromString(String& client_ip)

correct is:

    uint8_t nError = 0;

    IPAddress ip;
    if ( !ip.fromString(client_ip) ) nError++;
    IPAddress gateway;
    if ( !gateway.fromString(gateway_ip) ) nError++;
    if ( nError == 0 ) {
      IPAddress subnet(255, 255, 255, 0); 
      WiFi.config(ip, gateway, subnet);       
    }else{ 
      Serial.print("error IP config");
    }

i wish you a nice start to the new week.
Thanks!

All 4 comments

Check out the pfodESP8266BufferedClient.zip library used in my http://www.forward.com.au/pfod/CheapWifiShield/index.html

IPAddress ip(pfodESP8266Utils::ipStrToNum(ipStr));

/**
 * ipStrToNum
 * works for IPV4 only
 * parses  "10.1.1.200" and "10,1,1,200" strings 
 * extra spaces ignored  eg "10, 1, 1, 200" is OK also 
 * return uint32_t for passing to ipAddress( );
 */
uint32_t pfodESP8266Utils::ipStrToNum(const char* ipStr) {
  const int SIZE_OF_NUMS = 4;
  union {
    uint8_t bytes[SIZE_OF_NUMS];  // IPv4 address
    uint32_t dword;
  } _address;
  _address.dword = 0; // clear return

  int i = 0;
  uint8_t num = 0; // start with 0
  while ((*ipStr) != '\0') {
    // while not end of string
    if ((*ipStr == '.') || (*ipStr == ',')) {
      // store num and move on to next position
      _address.bytes[i++] = num;
      num = 0;
      if (i>=SIZE_OF_NUMS) {
        break; // filled array
      }
    } else {  
      if (*ipStr != ' ') {      // skip blanks
        num = (num << 3) + (num << 1); // *10 = *8+*2
        num = num +  (*ipStr - '0');
      }  
    }  
    ipStr++;
  }  
  if (i<SIZE_OF_NUMS) {
    // store last num
    _address.bytes[i++] = num;
  }
  return _address.dword; 
}  

Hallo, thx for your. answer. Nice project!!

i think Adrian McEwen solution, in the ESP-core, is a good woork,
and we should use it, or help to supplement them.

My wish is, to understand, how the arduinos "build process",
knows, how to access, to all the ESP-core classes;
and why the access to the defined method "fromString" from the class "IPAddress", does not work!?
In the directory:
....\portable\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\
inside the files: IPAddress.cpp + IPAddress.h ,
that method is defined as: bool fromString(const String &address) { return fromString(address.c_str()); }
IPAddress.h:

/*
 IPAddress.h - Base class that provides IPAddress
 Copyright (c) 2011 Adrian McEwen.  All right reserved.
............*/
#include <stdint.h>
#include <WString.h>
#include <Printable.h>

// A class to make it easier to handle and pass around IP addresses

class IPAddress: public Printable {
    private:
        union {
                uint8_t bytes[4];  // IPv4 address
                uint32_t dword;
        } _address;

        // Access the raw byte array containing the address.  Because this returns a pointer
        // to the internal structure rather than a copy of the address this function should only
        // be used when you know that the usage of the returned uint8_t* will be transient and not
        // stored.
        uint8_t* raw_address() {
            return _address.bytes;
        }

    public:
        // Constructors
        IPAddress();
        IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet);
        IPAddress(uint32_t address);
        IPAddress(const uint8_t *address);

        bool fromString(const char *address);
        bool fromString(const String &address) { return fromString(address.c_str()); }

        // Overloaded cast operator to allow IPAddress objects to be used where a pointer
        // to a four-byte uint8_t array is expected
        operator uint32_t() const {
            return _address.dword;
        }
        bool operator==(const IPAddress& addr) const {
            return _address.dword == addr._address.dword;
        }
        bool operator==(uint32_t addr) const {
            return _address.dword == addr;
        }
        bool operator==(const uint8_t* addr) const;

        // Overloaded index operator to allow getting and setting individual octets of the address
        uint8_t operator[](int index) const {
            return _address.bytes[index];
        }
        uint8_t& operator[](int index) {
            return _address.bytes[index];
        }

        // Overloaded copy operators to allow initialisation of IPAddress objects from other types
        IPAddress& operator=(const uint8_t *address);
        IPAddress& operator=(uint32_t address);

        virtual size_t printTo(Print& p) const;
        String toString();

        friend class EthernetClass;
        friend class UDP;
        friend class Client;
        friend class Server;
        friend class DhcpClass;
        friend class DNSClient;
};
extern const IPAddress INADDR_NONE;
#endif

and IPAddress.cpp:

#include <Arduino.h>
#include <IPAddress.h>
#include <Print.h>

IPAddress::IPAddress() {
    _address.dword = 0;
}
IPAddress::IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet) {
    _address.bytes[0] = first_octet;
    _address.bytes[1] = second_octet;
    _address.bytes[2] = third_octet;
    _address.bytes[3] = fourth_octet;
}

IPAddress::IPAddress(uint32_t address) {
    _address.dword = address;
}

IPAddress::IPAddress(const uint8_t *address) {
    memcpy(_address.bytes, address, sizeof(_address.bytes));
}
bool IPAddress::fromString(const char *address) {
    // TODO: add support for "a", "a.b", "a.b.c" formats

    uint16_t acc = 0; // Accumulator
    uint8_t dots = 0;

    while (*address)
    {
        char c = *address++;
        if (c >= '0' && c <= '9')
        {
            acc = acc * 10 + (c - '0');
            if (acc > 255) {
                // Value out of [0..255] range
                return false;
            }
        }
        else if (c == '.')
        {
            if (dots == 3) {
                // Too much dots (there must be 3 dots)
                return false;
            }
            _address.bytes[dots++] = acc;
            acc = 0;
        }
        else
        {
            // Invalid char
            return false;
        }
    }

    if (dots != 3) {
        // Too few dots (there must be 3 dots)
        return false;
    }
    _address.bytes[3] = acc;
    return true;
}

IPAddress& IPAddress::operator=(const uint8_t *address) {
    memcpy(_address.bytes, address, sizeof(_address.bytes));
    return *this;
}

IPAddress& IPAddress::operator=(uint32_t address) {
    _address.dword = address;
    return *this;
}

bool IPAddress::operator==(const uint8_t* addr) const {
    return memcmp(addr, _address.bytes, sizeof(_address.bytes)) == 0;
}

size_t IPAddress::printTo(Print& p) const {
    size_t n = 0;
    for(int i = 0; i < 3; i++) {
        n += p.print(_address.bytes[i], DEC);
        n += p.print('.');
    }
    n += p.print(_address.bytes[3], DEC);
    return n;
}

String IPAddress::toString()
{
    char szRet[16];
    sprintf(szRet,"%u.%u.%u.%u", _address.bytes[0], _address.bytes[1], _address.bytes[2], _address.bytes[3]);
    return String(szRet);
}

const IPAddress INADDR_NONE(0, 0, 0, 0);

This works for me without any issue:

void ICACHE_FLASH_ATTR saveIpAddress(uint8_t *byteArr, String ipaddrStr) {

    IPAddress ipaddr;
    bool parseSuccess;

    parseSuccess = ipaddr.fromString(ipaddrStr);
    if (parseSuccess) {
        for (int i = 0; i < 4; i++) {
            byteArr[i] = ipaddr[i];
        }
    }
}

I think you need to drop the parentheses from IPAddress ip(); in your code i.e. make it look like this: IPAddress ip;

thats great!
thanks very much!
I had to change two things:

  1. drop the parentheses from IPAddress ip(), as you proposed!
  2. drop the Sting& from ip.fromString(String& client_ip)

correct is:

    uint8_t nError = 0;

    IPAddress ip;
    if ( !ip.fromString(client_ip) ) nError++;
    IPAddress gateway;
    if ( !gateway.fromString(gateway_ip) ) nError++;
    if ( nError == 0 ) {
      IPAddress subnet(255, 255, 255, 0); 
      WiFi.config(ip, gateway, subnet);       
    }else{ 
      Serial.print("error IP config");
    }

i wish you a nice start to the new week.
Thanks!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

markusschweitzer picture markusschweitzer  路  3Comments

mechanic98 picture mechanic98  路  3Comments

treii28 picture treii28  路  3Comments

rudydevolder picture rudydevolder  路  3Comments

horendus picture horendus  路  3Comments