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
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:
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!
Most helpful comment
thats great!
thanks very much!
I had to change two things:
correct is:
i wish you a nice start to the new week.
Thanks!