Skip to content

Commit b1f32b3

Browse files
authored
Merge branch 'espressif:master' into work
2 parents 622e504 + 2b67a4e commit b1f32b3

File tree

12 files changed

+294
-23
lines changed

12 files changed

+294
-23
lines changed

.github/workflows/hil.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
gen_chunks:
1919
if: |
2020
contains(github.event.pull_request.labels.*.name, 'hil_test') ||
21-
github.event_name == 'schedule'
21+
(github.event_name == 'schedule' && github.repository == 'espressif/arduino-esp32')
2222
name: Generate Chunks matrix
2323
runs-on: ubuntu-latest
2424
outputs:

cores/esp32/WString.cpp

+43
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,24 @@ String::String(double value, unsigned int decimalPlaces) {
137137
}
138138
}
139139

140+
String::String(long long value, unsigned char base) {
141+
init();
142+
char buf[2 + 8 * sizeof(long long)];
143+
if (base==10) {
144+
sprintf(buf, "%lld", value); // NOT SURE - NewLib Nano ... does it support %lld?
145+
} else {
146+
lltoa(value, buf, base);
147+
}
148+
*this = buf;
149+
}
150+
151+
String::String(unsigned long long value, unsigned char base) {
152+
init();
153+
char buf[1 + 8 * sizeof(unsigned long long)];
154+
ulltoa(value, buf, base);
155+
*this = buf;
156+
}
157+
140158
String::~String() {
141159
invalidate();
142160
}
@@ -408,6 +426,17 @@ unsigned char String::concat(double num) {
408426
return concat(string, strlen(string));
409427
}
410428

429+
unsigned char String::concat(long long num) {
430+
char buf[2 + 3 * sizeof(long long)];
431+
return concat(buf, sprintf(buf, "%lld", num)); // NOT SURE - NewLib Nano ... does it support %lld?
432+
}
433+
434+
unsigned char String::concat(unsigned long long num) {
435+
char buf[1 + 3 * sizeof(unsigned long long)];
436+
ulltoa(num, buf, 10);
437+
return concat(buf, strlen(buf));
438+
}
439+
411440
unsigned char String::concat(const __FlashStringHelper * str) {
412441
if (!str) return 0;
413442
int length = strlen_P((PGM_P)str);
@@ -493,6 +522,20 @@ StringSumHelper & operator +(const StringSumHelper &lhs, double num) {
493522
return a;
494523
}
495524

525+
StringSumHelper & operator +(const StringSumHelper &lhs, long long num) {
526+
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
527+
if(!a.concat(num))
528+
a.invalidate();
529+
return a;
530+
}
531+
532+
StringSumHelper & operator +(const StringSumHelper &lhs, unsigned long long num) {
533+
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
534+
if(!a.concat(num))
535+
a.invalidate();
536+
return a;
537+
}
538+
496539
StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs)
497540
{
498541
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);

cores/esp32/WString.h

+20
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ class String {
7373
explicit String(unsigned long, unsigned char base = 10);
7474
explicit String(float, unsigned int decimalPlaces = 2);
7575
explicit String(double, unsigned int decimalPlaces = 2);
76+
explicit String(long long, unsigned char base = 10);
77+
explicit String(unsigned long long, unsigned char base = 10);
7678
~String(void);
7779

7880
// memory management
@@ -122,6 +124,8 @@ class String {
122124
unsigned char concat(unsigned long num);
123125
unsigned char concat(float num);
124126
unsigned char concat(double num);
127+
unsigned char concat(long long num);
128+
unsigned char concat(unsigned long long num);
125129
unsigned char concat(const __FlashStringHelper * str);
126130

127131
// if there's not enough memory for the concatenated value, the string
@@ -166,6 +170,14 @@ class String {
166170
concat(num);
167171
return (*this);
168172
}
173+
String & operator +=(long long num) {
174+
concat(num);
175+
return (*this);
176+
}
177+
String & operator +=(unsigned long long num) {
178+
concat(num);
179+
return (*this);
180+
}
169181
String & operator += (const __FlashStringHelper *str){
170182
concat(str);
171183
return (*this);
@@ -182,6 +194,8 @@ class String {
182194
friend StringSumHelper & operator +(const StringSumHelper &lhs, float num);
183195
friend StringSumHelper & operator +(const StringSumHelper &lhs, double num);
184196
friend StringSumHelper & operator +(const StringSumHelper &lhs, const __FlashStringHelper *rhs);
197+
friend StringSumHelper & operator +(const StringSumHelper &lhs, long long num);
198+
friend StringSumHelper & operator +(const StringSumHelper &lhs, unsigned long long num);
185199

186200
// comparison (only works w/ Strings and "strings")
187201
operator StringIfHelperType() const {
@@ -373,6 +387,12 @@ class StringSumHelper: public String {
373387
StringSumHelper(double num) :
374388
String(num) {
375389
}
390+
StringSumHelper(long long num) :
391+
String(num) {
392+
}
393+
StringSumHelper(unsigned long long num) :
394+
String(num) {
395+
}
376396
};
377397

378398
extern const String emptyString;

cores/esp32/stdlib_noniso.c

+48
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,31 @@ char* ltoa(long value, char* result, int base) {
6767
return result;
6868
}
6969

70+
char* lltoa (long long val, char* result, int base) {
71+
if(base < 2 || base > 16) {
72+
*result = 0;
73+
return result;
74+
}
75+
76+
char* out = result;
77+
long long quotient = val > 0 ? val : -val;
78+
79+
do {
80+
const long long tmp = quotient / base;
81+
*out = "0123456789abcdef"[quotient - (tmp * base)];
82+
++out;
83+
quotient = tmp;
84+
} while(quotient);
85+
86+
// Apply negative sign
87+
if(val < 0)
88+
*out++ = '-';
89+
90+
reverse(result, out);
91+
*out = 0;
92+
return result;
93+
}
94+
7095
char* ultoa(unsigned long value, char* result, int base) {
7196
if(base < 2 || base > 16) {
7297
*result = 0;
@@ -88,6 +113,27 @@ char* ultoa(unsigned long value, char* result, int base) {
88113
return result;
89114
}
90115

116+
char* ulltoa (unsigned long long val, char* result, int base) {
117+
if(base < 2 || base > 16) {
118+
*result = 0;
119+
return result;
120+
}
121+
122+
char* out = result;
123+
unsigned long long quotient = val;
124+
125+
do {
126+
const unsigned long long tmp = quotient / base;
127+
*out = "0123456789abcdef"[quotient - (tmp * base)];
128+
++out;
129+
quotient = tmp;
130+
} while(quotient);
131+
132+
reverse(result, out);
133+
*out = 0;
134+
return result;
135+
}
136+
91137
char * dtostrf(double number, signed int width, unsigned int prec, char *s) {
92138
bool negative = false;
93139

@@ -160,3 +206,5 @@ char * dtostrf(double number, signed int width, unsigned int prec, char *s) {
160206
*out = 0;
161207
return s;
162208
}
209+
210+

cores/esp32/stdlib_noniso.h

+4
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,14 @@ char* itoa (int val, char *s, int radix);
3535

3636
char* ltoa (long val, char *s, int radix);
3737

38+
char* lltoa (long long val, char* s, int radix);
39+
3840
char* utoa (unsigned int val, char *s, int radix);
3941

4042
char* ultoa (unsigned long val, char *s, int radix);
4143

44+
char* ulltoa (unsigned long long val, char* s, int radix);
45+
4246
char* dtostrf (double val, signed int width, unsigned int prec, char *s);
4347

4448
#ifdef __cplusplus

libraries/Ethernet/src/ETH.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ bool ETHClass::config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, I
407407
esp_err_t err = ESP_OK;
408408
tcpip_adapter_ip_info_t info;
409409

410-
if(local_ip != (uint32_t)0x00000000 && local_ip != INADDR_NONE){
410+
if(static_cast<uint32_t>(local_ip) != 0){
411411
info.ip.addr = static_cast<uint32_t>(local_ip);
412412
info.gw.addr = static_cast<uint32_t>(gateway);
413413
info.netmask.addr = static_cast<uint32_t>(subnet);
@@ -443,13 +443,13 @@ bool ETHClass::config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, I
443443
ip_addr_t d;
444444
d.type = IPADDR_TYPE_V4;
445445

446-
if(dns1 != (uint32_t)0x00000000 && dns1 != INADDR_NONE) {
446+
if(static_cast<uint32_t>(dns1) != 0) {
447447
// Set DNS1-Server
448448
d.u_addr.ip4.addr = static_cast<uint32_t>(dns1);
449449
dns_setserver(0, &d);
450450
}
451451

452-
if(dns2 != (uint32_t)0x00000000 && dns2 != INADDR_NONE) {
452+
if(static_cast<uint32_t>(dns2) != 0) {
453453
// Set DNS2-Server
454454
d.u_addr.ip4.addr = static_cast<uint32_t>(dns2);
455455
dns_setserver(1, &d);

libraries/WiFi/src/WiFiAP.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ extern "C" {
4747
// -----------------------------------------------------------------------------------------------------------------------
4848

4949
esp_netif_t* get_esp_interface_netif(esp_interface_t interface);
50-
esp_err_t set_esp_interface_ip(esp_interface_t interface, IPAddress local_ip=IPAddress(), IPAddress gateway=IPAddress(), IPAddress subnet=IPAddress());
50+
esp_err_t set_esp_interface_ip(esp_interface_t interface, IPAddress local_ip=INADDR_NONE, IPAddress gateway=INADDR_NONE, IPAddress subnet=INADDR_NONE, IPAddress dhcp_lease_start=INADDR_NONE);
5151
static bool softap_config_equal(const wifi_config_t& lhs, const wifi_config_t& rhs);
5252

5353
static size_t _wifi_strncpy(char * dst, const char * src, size_t dst_len){
@@ -195,7 +195,7 @@ String WiFiAPClass::softAPSSID() const
195195
* @param gateway gateway IP
196196
* @param subnet subnet mask
197197
*/
198-
bool WiFiAPClass::softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet)
198+
bool WiFiAPClass::softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dhcp_lease_start)
199199
{
200200
esp_err_t err = ESP_OK;
201201

@@ -204,7 +204,7 @@ bool WiFiAPClass::softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress
204204
return false;
205205
}
206206

207-
err = set_esp_interface_ip(ESP_IF_WIFI_AP, local_ip, gateway, subnet);
207+
err = set_esp_interface_ip(ESP_IF_WIFI_AP, local_ip, gateway, subnet, dhcp_lease_start);
208208
return err == ESP_OK;
209209
}
210210

libraries/WiFi/src/WiFiAP.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class WiFiAPClass
3838
public:
3939

4040
bool softAP(const char* ssid, const char* passphrase = NULL, int channel = 1, int ssid_hidden = 0, int max_connection = 4, bool ftm_responder = false);
41-
bool softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet);
41+
bool softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dhcp_lease_start = INADDR_NONE);
4242
bool softAPdisconnect(bool wifioff = false);
4343

4444
uint8_t softAPgetStationNum();

libraries/WiFi/src/WiFiGeneric.cpp

+58-14
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ extern "C" {
4848
#include <vector>
4949
#include "sdkconfig.h"
5050

51+
#define _byte_swap32(num) (((num>>24)&0xff) | ((num<<8)&0xff0000) | ((num>>8)&0xff00) | ((num<<24)&0xff000000))
5152
ESP_EVENT_DEFINE_BASE(ARDUINO_EVENTS);
5253
/*
5354
* Private (exposable) methods
@@ -82,7 +83,7 @@ esp_err_t set_esp_interface_hostname(esp_interface_t interface, const char * hos
8283
return ESP_FAIL;
8384
}
8485

85-
esp_err_t set_esp_interface_ip(esp_interface_t interface, IPAddress local_ip=IPAddress(), IPAddress gateway=IPAddress(), IPAddress subnet=IPAddress()){
86+
esp_err_t set_esp_interface_ip(esp_interface_t interface, IPAddress local_ip=IPAddress(), IPAddress gateway=IPAddress(), IPAddress subnet=IPAddress(), IPAddress dhcp_lease_start=INADDR_NONE){
8687
esp_netif_t *esp_netif = esp_netifs[interface];
8788
esp_netif_dhcp_status_t status = ESP_NETIF_DHCP_INIT;
8889
esp_netif_ip_info_t info;
@@ -138,20 +139,64 @@ esp_err_t set_esp_interface_ip(esp_interface_t interface, IPAddress local_ip=IPA
138139

139140
dhcps_lease_t lease;
140141
lease.enable = true;
141-
uint32_t dhcp_ipaddr = static_cast<uint32_t>(local_ip);
142-
// prevents DHCP lease range to overflow subnet/24 range
143-
// there will be 11 addresses for DHCP to lease
144-
uint8_t leaseStart = (uint8_t)(~subnet[3] - 12);
145-
if ((local_ip[3]) < leaseStart) {
146-
lease.start_ip.addr = dhcp_ipaddr + (1 << 24);
147-
lease.end_ip.addr = dhcp_ipaddr + (11 << 24);
148-
} else {
149-
// make range stay in the begining of the netmask range
150-
dhcp_ipaddr = (dhcp_ipaddr & 0x00FFFFFF);
151-
lease.start_ip.addr = dhcp_ipaddr + (1 << 24);
152-
lease.end_ip.addr = dhcp_ipaddr + (11 << 24);
142+
uint8_t CIDR = WiFiGenericClass::calculateSubnetCIDR(subnet);
143+
log_v("SoftAP: %s | Gateway: %s | DHCP Start: %s | Netmask: %s", local_ip.toString().c_str(), gateway.toString().c_str(), dhcp_lease_start.toString().c_str(), subnet.toString().c_str());
144+
// netmask must have room for at least 12 IP addresses (AP + GW + 10 DHCP Leasing addresses)
145+
// netmask also must be limited to the last 8 bits of IPv4, otherwise this function won't work
146+
// IDF NETIF checks netmask for the 3rd byte: https://github.com/espressif/esp-idf/blob/master/components/esp_netif/lwip/esp_netif_lwip.c#L1857-L1862
147+
if (CIDR > 28 || CIDR < 24) {
148+
log_e("Bad netmask. It must be from /24 to /28 (255.255.255. 0<->240)");
149+
return ESP_FAIL; // ESP_FAIL if initializing failed
150+
}
151+
// The code below is ready for any netmask, not limited to 255.255.255.0
152+
uint32_t netmask = _byte_swap32(info.netmask.addr);
153+
uint32_t ap_ipaddr = _byte_swap32(info.ip.addr);
154+
uint32_t dhcp_ipaddr = _byte_swap32(static_cast<uint32_t>(dhcp_lease_start));
155+
dhcp_ipaddr = dhcp_ipaddr == 0 ? ap_ipaddr + 1 : dhcp_ipaddr;
156+
uint32_t leaseStartMax = ~netmask - 10;
157+
// there will be 10 addresses for DHCP to lease
158+
lease.start_ip.addr = dhcp_ipaddr;
159+
lease.end_ip.addr = lease.start_ip.addr + 10;
160+
// Check if local_ip is in the same subnet as the dhcp leasing range initial address
161+
if ((ap_ipaddr & netmask) != (dhcp_ipaddr & netmask)) {
162+
log_e("The AP IP address (%s) and the DHCP start address (%s) must be in the same subnet",
163+
local_ip.toString().c_str(), IPAddress(_byte_swap32(dhcp_ipaddr)).toString().c_str());
164+
return ESP_FAIL; // ESP_FAIL if initializing failed
165+
}
166+
// prevents DHCP lease range to overflow subnet range
167+
if ((dhcp_ipaddr & ~netmask) >= leaseStartMax) {
168+
// make first DHCP lease addr stay in the begining of the netmask range
169+
lease.start_ip.addr = (dhcp_ipaddr & netmask) + 1;
170+
lease.end_ip.addr = lease.start_ip.addr + 10;
171+
log_w("DHCP Lease out of range - Changing DHCP leasing start to %s", IPAddress(_byte_swap32(lease.start_ip.addr)).toString().c_str());
153172
}
173+
// Check if local_ip is within DHCP range
174+
if (ap_ipaddr >= lease.start_ip.addr && ap_ipaddr <= lease.end_ip.addr) {
175+
log_e("The AP IP address (%s) can't be within the DHCP range (%s -- %s)",
176+
local_ip.toString().c_str(), IPAddress(_byte_swap32(lease.start_ip.addr)).toString().c_str(), IPAddress(_byte_swap32(lease.end_ip.addr)).toString().c_str());
177+
return ESP_FAIL; // ESP_FAIL if initializing failed
178+
}
179+
// Check if gateway is within DHCP range
180+
uint32_t gw_ipaddr = _byte_swap32(info.gw.addr);
181+
bool gw_in_same_subnet = (gw_ipaddr & netmask) == (ap_ipaddr & netmask);
182+
if (gw_in_same_subnet && gw_ipaddr >= lease.start_ip.addr && gw_ipaddr <= lease.end_ip.addr) {
183+
log_e("The GatewayP address (%s) can't be within the DHCP range (%s -- %s)",
184+
gateway.toString().c_str(), IPAddress(_byte_swap32(lease.start_ip.addr)).toString().c_str(), IPAddress(_byte_swap32(lease.end_ip.addr)).toString().c_str());
185+
return ESP_FAIL; // ESP_FAIL if initializing failed
186+
}
187+
// all done, just revert back byte order of DHCP lease range
188+
lease.start_ip.addr = _byte_swap32(lease.start_ip.addr);
189+
lease.end_ip.addr = _byte_swap32(lease.end_ip.addr);
154190
log_v("DHCP Server Range: %s to %s", IPAddress(lease.start_ip.addr).toString().c_str(), IPAddress(lease.end_ip.addr).toString().c_str());
191+
err = tcpip_adapter_dhcps_option(
192+
(tcpip_adapter_dhcp_option_mode_t)TCPIP_ADAPTER_OP_SET,
193+
(tcpip_adapter_dhcp_option_id_t)ESP_NETIF_SUBNET_MASK,
194+
(void*)&info.netmask.addr, sizeof(info.netmask.addr)
195+
);
196+
if(err){
197+
log_e("DHCPS Set Netmask Failed! 0x%04x", err);
198+
return err;
199+
}
155200
err = tcpip_adapter_dhcps_option(
156201
(tcpip_adapter_dhcp_option_mode_t)TCPIP_ADAPTER_OP_SET,
157202
(tcpip_adapter_dhcp_option_id_t)REQUESTED_IP_ADDRESS,
@@ -161,7 +206,6 @@ esp_err_t set_esp_interface_ip(esp_interface_t interface, IPAddress local_ip=IPA
161206
log_e("DHCPS Set Lease Failed! 0x%04x", err);
162207
return err;
163208
}
164-
165209
err = esp_netif_dhcps_start(esp_netif);
166210
if(err){
167211
log_e("DHCPS Start Failed! 0x%04x", err);

libraries/WiFi/src/WiFiSTA.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ extern "C" {
5151

5252
esp_netif_t* get_esp_interface_netif(esp_interface_t interface);
5353
esp_err_t set_esp_interface_dns(esp_interface_t interface, IPAddress main_dns=IPAddress(), IPAddress backup_dns=IPAddress(), IPAddress fallback_dns=IPAddress());
54-
esp_err_t set_esp_interface_ip(esp_interface_t interface, IPAddress local_ip=IPAddress(), IPAddress gateway=IPAddress(), IPAddress subnet=IPAddress());
54+
esp_err_t set_esp_interface_ip(esp_interface_t interface, IPAddress local_ip=INADDR_NONE, IPAddress gateway=INADDR_NONE, IPAddress subnet=INADDR_NONE, IPAddress dhcp_lease_start=INADDR_NONE);
5555
static bool sta_config_equal(const wifi_config_t& lhs, const wifi_config_t& rhs);
5656

5757
static size_t _wifi_strncpy(char * dst, const char * src, size_t dst_len){

tests/timer/test_timer.py

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
def test_timer(dut):
2+
dut.expect_unity_test_output(timeout=240)

0 commit comments

Comments
 (0)