diff --git a/cores/esp8266/core_esp8266_noniso.c b/cores/esp8266/core_esp8266_noniso.c index 949d3fabd..107d31bfb 100644 --- a/cores/esp8266/core_esp8266_noniso.c +++ b/cores/esp8266/core_esp8266_noniso.c @@ -1,23 +1,26 @@ /* - core_esp8266_noniso.c - nonstandard (but usefull) conversion functions + core_esp8266_noniso.c - nonstandard (but usefull) conversion functions - Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. - This file is part of the esp8266 core for Arduino environment. + Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. + This file is part of the esp8266 core for Arduino environment. - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Modified 03 April 2015 by Markus Sattler + + */ #include #include "stdlib_noniso.h" @@ -26,241 +29,211 @@ #define sprintf ets_sprintf #define strcpy ets_strcpy -long atol(const char* s) -{ - int result = 0; - int i; - const char* b = s; - int sign = 1; - for (i = 0; *b; ++i, ++b) - { - if (i == 0 && *b == '-') - sign = -1; - int x = *b - '0'; - if (x < 0 || x > 9) - break; - result = result * 10 + x; - } - return sign * result; +int atoi(const char* s) { + return (int) atol(s); +} + +long atol(const char* s) { + long int result = 0; + int i; + const char* b = s; + int sign = 1; + for(i = 0; *b; ++i, ++b) { + if(i == 0 && *b == '-') sign = -1; + int x = *b - '0'; + if(x < 0 || x > 9) break; + result = result * 10 + x; + } + return sign * result; } // Source: // https://github.com/anakod/Sming/blob/master/Sming/system/stringconversion.cpp#L93 -double atof(const char* s) -{ - double result = 0; +double atof(const char* s) { + double result = 0; double factor = 1.0; - while (*s == ' ' || *s == '\t' || *s == '\r' || *s == '\n') - ++s; + while(*s == ' ' || *s == '\t' || *s == '\r' || *s == '\n') + ++s; - if (*s == 0) - return 0; + if(*s == 0) return 0; - if (*s == '-') - { + if(*s == '-') { factor = -1.0; - ++s; - } - if (*s == '+') - { - ++s; - } + ++s; + } + if(*s == '+') { + ++s; + } - bool decimals = false; - char c; - while((c = *s)) - { - if (c == '.') - { - decimals = true; - ++s; - continue; - } + bool decimals = false; + char c; + while((c = *s)) { + if(c == '.') { + decimals = true; + ++s; + continue; + } - int d = c - '0'; - if (d < 0 || d > 9) - break; + int d = c - '0'; + if(d < 0 || d > 9) break; - result = 10.0 * result + d; - if (decimals) - factor *= 0.1; - ++s; - } + result = 10.0 * result + d; + if(decimals) factor *= 0.1; + ++s; + } - return result * factor; + return result * factor; } - -void reverse(char* begin, char* end) -{ - char *is = begin; - char *ie = end - 1; - while (is < ie) - { - char tmp = *ie; - *ie = *is; - *is = tmp; - ++is; - --ie; - } +void reverse(char* begin, char* end) { + char *is = begin; + char *ie = end - 1; + while(is < ie) { + char tmp = *ie; + *ie = *is; + *is = tmp; + ++is; + --ie; + } } -char* itoa( int value, char* result, int base ) -{ - if (base < 2 || base > 16) - { - *result = 0; - return result; - } +char* itoa(int value, char* result, int base) { + if(base < 2 || base > 16) { + *result = 0; + return result; + } - char* out = result; - int quotient = abs(value); + char* out = result; + int quotient = abs(value); - do - { - const int tmp = quotient / base; - *out = "0123456789abcdef"[ quotient - (tmp*base) ]; - ++out; - quotient = tmp; - } while ( quotient ); + do { + const int tmp = quotient / base; + *out = "0123456789abcdef"[quotient - (tmp * base)]; + ++out; + quotient = tmp; + } while(quotient); - // Apply negative sign - if ( value < 0) *out++ = '-'; + // Apply negative sign + if(value < 0) *out++ = '-'; - reverse(result, out); - *out = 0; - return result; + reverse(result, out); + *out = 0; + return result; } -char* ltoa( long value, char* result, int base ) -{ - if (base < 2 || base > 16) - { - *result = 0; - return result; - } +char* ltoa(long value, char* result, int base) { + if(base < 2 || base > 16) { + *result = 0; + return result; + } - char* out = result; - long quotient = abs(value); + char* out = result; + long quotient = abs(value); - do - { - const long tmp = quotient / base; - *out = "0123456789abcdef"[ quotient - (tmp*base) ]; - ++out; - quotient = tmp; - } while ( quotient ); + do { + const long tmp = quotient / base; + *out = "0123456789abcdef"[quotient - (tmp * base)]; + ++out; + quotient = tmp; + } while(quotient); - // Apply negative sign - if ( value < 0) *out++ = '-'; + // Apply negative sign + if(value < 0) *out++ = '-'; - reverse(result, out); - *out = 0; - return result; -} - -char* utoa( unsigned value, char* result, int base ) -{ - if (base < 2 || base > 16) - { - *result = 0; - return result; - } - - char* out = result; - unsigned quotient = value; - - do - { - const unsigned tmp = quotient / base; - *out = "0123456789abcdef"[ quotient - (tmp*base) ]; - ++out; - quotient = tmp; - } while ( quotient ); - - reverse(result, out); - *out = 0; - return result; -} - -char* ultoa( unsigned long value, char* result, int base ) -{ - if (base < 2 || base > 16) - { - *result = 0; - return result; - } - - char* out = result; - unsigned long quotient = value; - - do - { - const unsigned long tmp = quotient / base; - *out = "0123456789abcdef"[ quotient - (tmp*base) ]; - ++out; - quotient = tmp; - } while ( quotient ); - - reverse(result, out); - *out = 0; - return result; + reverse(result, out); + *out = 0; + return result; } -char * dtostrf (double number, signed char width, unsigned char prec, char *s) -{ - size_t n = 0; - - if (isnan(number)) - { - strcpy(s, "nan"); - return s; - } - if (isinf(number)) - { - strcpy(s, "inf"); - return s; - } +char* utoa(unsigned value, char* result, int base) { + if(base < 2 || base > 16) { + *result = 0; + return result; + } - if (number > 4294967040.0 || - number <-4294967040.0) - { - strcpy(s, "ovf"); - return s; - } - char* out = s; - // Handle negative numbers - if (number < 0.0) - { - *out = '-'; - ++out; - number = -number; - } + char* out = result; + unsigned quotient = value; - // Round correctly so that print(1.999, 2) prints as "2.00" - double rounding = 0.5; - for (uint8_t i=0; i 0) { - *out = '.'; - ++out; - } - - while (prec-- > 0) - { - remainder *= 10.0; - } - sprintf(out, "%d", (int)remainder); - - return s; + reverse(result, out); + *out = 0; + return result; +} + +char* ultoa(unsigned long value, char* result, int base) { + if(base < 2 || base > 16) { + *result = 0; + return result; + } + + char* out = result; + unsigned long quotient = value; + + do { + const unsigned long tmp = quotient / base; + *out = "0123456789abcdef"[quotient - (tmp * base)]; + ++out; + quotient = tmp; + } while(quotient); + + reverse(result, out); + *out = 0; + return result; +} + +char * dtostrf(double number, signed char width, unsigned char prec, char *s) { + size_t n = 0; + + if(isnan(number)) { + strcpy(s, "nan"); + return s; + } + if(isinf(number)) { + strcpy(s, "inf"); + return s; + } + + if(number > 4294967040.0 || number < -4294967040.0) { + strcpy(s, "ovf"); + return s; + } + char* out = s; + // Handle negative numbers + if(number < 0.0) { + *out = '-'; + ++out; + number = -number; + } + + // Round correctly so that print(1.999, 2) prints as "2.00" + double rounding = 0.5; + for(uint8_t i = 0; i < prec; ++i) + rounding /= 10.0; + + number += rounding; + + // Extract the integer part of the number and print it + unsigned long int_part = (unsigned long) number; + double remainder = number - (double) int_part; + out += sprintf(out, "%d", int_part); + + // Print the decimal point, but only if there are digits beyond + if(prec > 0) { + *out = '.'; + ++out; + } + + while(prec-- > 0) { + remainder *= 10.0; + } + sprintf(out, "%d", (int) remainder); + + return s; } diff --git a/cores/esp8266/libc_replacements.c b/cores/esp8266/libc_replacements.c index 9346ac4df..072746144 100644 --- a/cores/esp8266/libc_replacements.c +++ b/cores/esp8266/libc_replacements.c @@ -1,24 +1,27 @@ /* - libc_replacements.c - replaces libc functions with functions - from Espressif SDK + libc_replacements.c - replaces libc functions with functions + from Espressif SDK - Copyright (c) 2015 Ivan Grokhotkov. All rights reserved. - This file is part of the esp8266 core for Arduino environment. + Copyright (c) 2015 Ivan Grokhotkov. All rights reserved. + This file is part of the esp8266 core for Arduino environment. - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Modified 03 April 2015 by Markus Sattler + + */ #include #include @@ -31,71 +34,280 @@ void* malloc(size_t size) { - return os_malloc(size); + return os_malloc(size); } void free(void* ptr) { - os_free(ptr); + os_free(ptr); } void* realloc(void* ptr, size_t size) { - return os_realloc(ptr, size); + return os_realloc(ptr, size); } int printf(const char* format, ...) { - va_list arglist; - va_start(arglist, format); - ets_vprintf(format, arglist); - va_end(arglist); + int ret; + va_list arglist; + va_start(arglist, format); + ret = ets_vprintf(format, arglist); + va_end(arglist); + return ret; } int sprintf(char* buffer, const char* format, ...) { - va_list arglist; - va_start(arglist, format); - ets_vsprintf(buffer, format, arglist); - va_end(arglist); + int ret; + va_list arglist; + va_start(arglist, format); + ret = ets_vsprintf(buffer, format, arglist); + va_end(arglist); + return ret; } int snprintf(char* buffer, size_t size, const char* format, ...) { - va_list arglist; - va_start(arglist, format); - ets_vsnprintf(buffer, size, format, arglist); - va_end(arglist); + int ret; + va_list arglist; + va_start(arglist, format); + ret = ets_vsnprintf(buffer, size, format, arglist); + va_end(arglist); + return ret; +} + +int vsnprintf(char * buffer, size_t size, const char * format, va_list arg) { + return ets_vsnprintf(buffer, size, format, arg); } int memcmp(const void *s1, const void *s2, size_t n) { - return ets_memcmp(s1, s2, n); + return ets_memcmp(s1, s2, n); } void* memcpy(void *dest, const void *src, size_t n) { - return ets_memcpy(dest, src, n); + return ets_memcpy(dest, src, n); } void* memset(void *s, int c, size_t n) { - return ets_memset(s, c, n); + return ets_memset(s, c, n); } int strcmp(const char *s1, const char *s2) { - return ets_strcmp(s1, s2); + return ets_strcmp(s1, s2); } char* strcpy(char *dest, const char *src) { - return ets_strcpy(dest, src); + return ets_strcpy(dest, src); } size_t strlen(const char *s) { - return ets_strlen(s); + return ets_strlen(s); } int strncmp(const char *s1, const char *s2, size_t len) { - return ets_strncmp(s1, s2, len); + return ets_strncmp(s1, s2, len); } -char *strncpy(char *dest, const char *src, size_t n) { - return ets_strncpy(dest, src, n); +char *strncpy(char * dest, const char * src, size_t n) { + return ets_strncpy(dest, src, n); } char *ets_strstr(const char *haystack, const char *needle) { - return strstr(haystack, needle); + return strstr(haystack, needle); } +char *strchr(const char * str, int character) { + while(1) { + if(*str == 0x00) { + return NULL; + } + if(*str == (char) character) { + return (char *) str; + } + str++; + } +} + +char *strrchr(const char * str, int character) { + char * ret = NULL; + while(1) { + if(*str == 0x00) { + return ret; + } + if(*str == (char) character) { + ret = (char *) str; + } + str++; + } +} + +char *strcat(char * dest, const char * src) { + return strncat(dest, src, strlen(src)); +} + +char *strncat(char * dest, const char * src, size_t n) { + uint32_t offset = strlen(dest); + for(uint32_t i = 0; i < n; i++) { + *(dest + i + offset) = *(src + i); + if(*(src + i) == 0x00) { + break; + } + } + return dest; +} + +char *strtok_r(char * str, const char * delimiters, char ** temp) { + static char * ret = NULL; + char * start = NULL; + char * end = NULL; + uint32_t size = 0; + + if(str == NULL) { + start = *temp; + } else { + start = str; + } + + if(start == NULL) { + return NULL; + } + + end = start; + + while(1) { + for(uint16_t i = 0; i < strlen(delimiters); i++) { + if(*end == *(delimiters + i)) { + break; + } + } + end++; + if(*end == 0x00) { + break; + } + } + + *temp = end; + + if(ret != NULL) { + free(ret); + } + + size = (end - start); + ret = (char *) malloc(size); + strncpy(ret, start, size); + return ret; +} + +// ########################################################################## +// ctype functions +// ########################################################################## + +int isalnum(int c) { + if(isalpha(c) || isdigit(c)) { + return 1; + } + return 0; +} + +int isalpha(int c) { + if(islower(c) || isupper(c)) { + return 1; + } + return 0; +} + +int iscntrl(int c) { + if(c <= 0x1F || c == 0x7F) { + return 1; + } + return 0; +} + +int isdigit(int c) { + if(c >= '0' && c <= '9') { + return 1; + } + return 0; +} +int isgraph(int c) { + if(isprint(c) && c != ' ') { + return 1; + } + return 0; +} + +int islower(int c) { + if(c >= 'a' && c <= 'z') { + return 1; + } + return 0; +} + +int isprint(int c) { + if(!iscntrl(c)) { + return 1; + } + return 0; +} + +int ispunct(int c) { + if(isgraph(c) && !isalnum(c)) { + return 1; + } + return 0; +} + +int isspace(int c) { + switch(c) { + case 0x20: // ' ' + case 0x09: // '\t' + case 0x0a: // '\n' + case 0x0b: // '\v' + case 0x0c: // '\f' + case 0x0d: // '\r' + return 1; + } + return 0; +} + +int isupper(int c) { + if(c >= 'A' && c <= 'Z') { + return 1; + } + return 0; +} + +int isxdigit(int c) { + if(c >= 'A' && c <= 'F') { + return 1; + } + if(c >= 'a' && c <= 'f') { + return 1; + } + if(isdigit(c)) { + return 1; + } + return 0; +} + +int tolower(int c) { + if(isupper(c)) { + c += 0x20; + } + return c; +} + +int toupper(int c) { + if(islower(c)) { + c -= 0x20; + } + return c; +} + +int isblank(int c) { + switch(c) { + case 0x20: // ' ' + case 0x09: // '\t' + return 1; + } + return 0; +} + +// ########################################################################## + diff --git a/cores/esp8266/pgmspace.h b/cores/esp8266/pgmspace.h index 11c9533cd..0188bc9e5 100644 --- a/cores/esp8266/pgmspace.h +++ b/cores/esp8266/pgmspace.h @@ -7,6 +7,9 @@ #define PGM_P const char * #define PSTR(str) (str) +#define vsnprintf_P(...) vsnprintf( __VA_ARGS__ ) +#define snprintf_P(...) snprintf( __VA_ARGS__ ) + #define _SFR_BYTE(n) (n) typedef void prog_void; diff --git a/cores/esp8266/stdlib_noniso.h b/cores/esp8266/stdlib_noniso.h index 1cfc379c8..2e8930fbe 100644 --- a/cores/esp8266/stdlib_noniso.h +++ b/cores/esp8266/stdlib_noniso.h @@ -26,9 +26,11 @@ extern "C"{ #endif -long atol_internal(const char*); +int atoi(const char *s); -float atof_internal(const char*); +long atol(const char* s); + +double atof(const char* s); char* itoa (int val, char *s, int radix); diff --git a/libraries/ESP8266WiFi/src/WiFiClient.cpp b/libraries/ESP8266WiFi/src/WiFiClient.cpp index b8e27ce1c..35777e2d0 100644 --- a/libraries/ESP8266WiFi/src/WiFiClient.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClient.cpp @@ -40,11 +40,6 @@ extern "C" #include "include/ClientContext.h" #include "c_types.h" -#define MIN_LOCAL_PORT 1024 -#define MAX_LOCAL_PORT 1124 - -static int g_localPort = MIN_LOCAL_PORT; - ICACHE_FLASH_ATTR WiFiClient::WiFiClient() : _client(0) { @@ -98,18 +93,6 @@ int ICACHE_FLASH_ATTR WiFiClient::connect(IPAddress ip, uint16_t port) if (!pcb) return 0; - while(true) - { - err_t err = tcp_bind(pcb, INADDR_ANY, g_localPort); - if (++g_localPort == MAX_LOCAL_PORT) - g_localPort = MIN_LOCAL_PORT; - if (err == ERR_OK) - break; - if (err == ERR_USE) - continue; - tcp_abort(pcb); - return 0; - } ip_addr_t addr; addr.addr = ip; tcp_arg(pcb, this); @@ -136,7 +119,7 @@ int8_t ICACHE_FLASH_ATTR WiFiClient::_connected(void* pcb, int8_t err) void ICACHE_FLASH_ATTR WiFiClient::_err(int8_t err) { - DEBUGV(":err\r\n"); + DEBUGV(":err %d\r\n", err); esp_schedule(); } diff --git a/libraries/ESP8266WiFi/src/include/ClientContext.h b/libraries/ESP8266WiFi/src/include/ClientContext.h index 9c9c0dd1e..06b8f7a64 100644 --- a/libraries/ESP8266WiFi/src/include/ClientContext.h +++ b/libraries/ESP8266WiFi/src/include/ClientContext.h @@ -73,6 +73,7 @@ public: void unref() { + err_t err; DEBUGV(":ur %d\r\n", _refcnt); if (--_refcnt == 0) { @@ -82,7 +83,11 @@ public: tcp_sent(_pcb, NULL); tcp_recv(_pcb, NULL); tcp_err(_pcb, NULL); - tcp_close(_pcb); + err = tcp_close(_pcb); + if(err != ERR_OK) { + DEBUGV(":tc err %d\r\n", err); + tcp_abort(_pcb); + } _pcb = 0; } delete this; @@ -269,7 +274,7 @@ private: void _error(err_t err) { - DEBUGV(":er\r\n"); + DEBUGV(":er %d\r\n", err); _pcb = 0; if (_size_sent && _send_waiting) esp_schedule(); diff --git a/platform.txt b/platform.txt index 8cf256694..505bfea89 100644 --- a/platform.txt +++ b/platform.txt @@ -23,7 +23,7 @@ compiler.S.flags=-c -g -x assembler-with-cpp -MMD compiler.c.elf.ldscript=eagle.app.v6.ld compiler.c.elf.flags=-nostdlib -Wl,--no-check-sections -u call_user_start -Wl,-static "-L{compiler.sdk.path}/lib" "-L{compiler.sdk.path}/ld" "-T{compiler.c.elf.ldscript}" compiler.c.elf.cmd=xtensa-lx106-elf-gcc -compiler.c.elf.libs=-lgcc -lhal -lphy -lnet80211 -llwip -lwpa -lmain -lpp +compiler.c.elf.libs=-lgcc -lm -lhal -lphy -lnet80211 -llwip -lwpa -lmain -lpp compiler.cpp.cmd=xtensa-lx106-elf-g++ compiler.cpp.flags=-c -Os -mlongcalls -mtext-section-literals -fno-exceptions -fno-rtti -std=c++11 -MMD @@ -66,7 +66,7 @@ recipe.S.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.cpreprocessor.fla recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{build.path}/{archive_file}" "{object_file}" ## Combine gc-sections, archives, and objects -recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" -Wl,--start-group {object_files} "{build.path}/{archive_file}" {compiler.c.elf.libs} -Wl,--end-group -lc "-L{build.path}" +recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" -Wl,--start-group {object_files} "{build.path}/{archive_file}" {compiler.c.elf.libs} -Wl,--end-group "-L{build.path}" ## Create eeprom recipe.objcopy.eep.pattern=