Skip to content

Additions to WiFiClient and WiFiServer #404

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 14, 2017

Conversation

bbx10
Copy link
Contributor

@bbx10 bbx10 commented May 30, 2017

Required for WebServer and DNSServer libraries. May be use by other libraries and apps.

Required for WebServer and/or DNSServer libraries
@@ -103,8 +104,16 @@ bool WiFiServer::hasClient() {
}

void WiFiServer::end(){
close(sockfd);
lwip_close_r(sockfd);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh breaks with the other close...

{
return write(buf, size);
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not official Arduino API is it? We do not really have _P anything ;)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ESP8266WebServer has *_P methods so I added support for them in the ESP32 version.

void WebServer::send_P(int code, PGM_P content_type, PGM_P content) {
    size_t contentLength = 0;

    if (content != NULL) {
        contentLength = strlen_P(content);
    }

    String header;
    char type[64];
    memccpy_P((void*)type, (PGM_VOID_P)content_type, 0, sizeof(type));
    _prepareHeader(header, code, (const char* )type, contentLength);
    _currentClient.write(header.c_str(), header.length());
    sendContent_P(content);
}

void WebServer::send_P(int code, PGM_P content_type, PGM_P content, size_t contentLength) {
    String header;
    char type[64];
    memccpy_P((void*)type, (PGM_VOID_P)content_type, 0, sizeof(type));
    _prepareHeader(header, code, (const char* )type, contentLength);
    sendContent(header);
    sendContent_P(content, contentLength);
}

void WebServer::send(int code, char* content_type, const String& content) {
  send(code, (const char*)content_type, content);
}

void WebServer::send(int code, const String& content_type, const String& content) {
  send(code, (const char*)content_type.c_str(), content);
}

void WebServer::sendContent(const String& content) {
  const char * footer = "\r\n";
  size_t len = content.length();
  if(_chunked) {
    char * chunkSize = (char *)malloc(11);
    if(chunkSize){
      sprintf(chunkSize, "%x%s", len, footer);
      _currentClient.write(chunkSize, strlen(chunkSize));
      free(chunkSize);
    }
  }
  _currentClient.write(content.c_str(), len);
  if(_chunked){
    _currentClient.write(footer, 2);
  }
}

void WebServer::sendContent_P(PGM_P content) {
  sendContent_P(content, strlen_P(content));
}

void WebServer::sendContent_P(PGM_P content, size_t size) {
  const char * footer = "\r\n";
  if(_chunked) {
    char * chunkSize = (char *)malloc(11);
    if(chunkSize){
      sprintf(chunkSize, "%x%s", size, footer);
      _currentClient.write(chunkSize, strlen(chunkSize));
      free(chunkSize);
    }
  }
#ifdef ESP8266
  _currentClient.write_P(content, size);
#else
  // TODO add ESP32 WiFiClient::write_P
  _currentClient.write(content, size);
#endif
  if(_chunked){
    _currentClient.write(footer, 2);
  }
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_P methods imply PROGMEM an we do not have PROGMEM on esp32

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copercini Compare pgmspace.h on ESP32 vs. ESP8266. There is no support for PROGMEM on ESP32 so pgmspace.h neuters the _P functions to their non _P equivalents.

But to avoid breaking lots of apps and libraries is would be good to translate _P functions to something that works on ESP32. Instead of making this change, libs and apps would have to do this.

#ifdef ESP8266
_currentClient.write_P(content, size);
#else
_currentClient.write(content, size);
#endif

If there are many occurrences, perhaps #define write_P write would do the job. But it would be less work and fewer breakage issues if write_P() is added even though it does the same thing as write().

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can not agree to bloat the classes unnecessary just for the sake of compatibility with everything. We have to add all of the _P methods then to Print, Stream and whatever else has them on ESP8266... bad idea!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can agree to mark them deprecated and remove at later point.

What approach would you suggest library authors take when it comes to writing code which supports both the ESP8266 and the ESP32?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would happen if we separate code like it's with WiFi? will all of the source files be included even if not used?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At link time, only the functions which were referenced will be left in the program, if -ffunction-section and -gc-sections options are used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of adding write_P, how about adding #define write_P write to pgmspace.h?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#define write_P write will not lead to proper client.write_P. @igrr correct me if I'm wrong, but that is what I believe the result will be

sockfd = -1;
_listening = false;
}

void WiFiServer::close(){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should go with one or the other ;) What's the official API for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ESP8266WiFiServer has close() and stop(). ESP32 WiFiServer has end(). ESP8266WebServer calls close. I chose to put all three for maximum backwards compatibility.

void WebServer::close() {
#ifdef ESP8266
  _server.close();
#else
  // TODO add ESP32 WiFiServer::close()
  _server.end();
#endif
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ESP32 should actually always use stop() as that is the official Arduino API. close and end should e deprecated.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I can remove close and end.

@me-no-dev me-no-dev merged commit b05c7df into espressif:master Jun 14, 2017
@bestpika
Copy link

bestpika commented Jun 14, 2017

Can't compile...
image

#include <WiFi.h>

void setup() {}
void loop() {}
In file included from C:\Users\...\Documents\Arduino\hardware\espressif\esp32\libraries\WiFi\src/WiFi.h:37:0,

                 from C:\Users\...\AppData\Local\Temp\arduino_modified_sketch_637679\sketch_jun14c.ino:1:

C:\Users\...\Documents\Arduino\hardware\espressif\esp32\libraries\WiFi\src/WiFiClient.h:93:15: error: 'IPAddress WiFiClient::localIP() const' cannot be overloaded

     IPAddress localIP() const;

               ^

C:\Users\...\Documents\Arduino\hardware\espressif\esp32\libraries\WiFi\src/WiFiClient.h:88:15: error: with 'IPAddress WiFiClient::localIP() const'

     IPAddress localIP() const;

               ^

C:\Users\...\Documents\Arduino\hardware\espressif\esp32\libraries\WiFi\src/WiFiClient.h:94:15: error: 'IPAddress WiFiClient::localIP(int) const' cannot be overloaded

     IPAddress localIP(int fd) const;

               ^

C:\Users\...\Documents\Arduino\hardware\espressif\esp32\libraries\WiFi\src/WiFiClient.h:89:15: error: with 'IPAddress WiFiClient::localIP(int) const'

     IPAddress localIP(int fd) const;

               ^

C:\Users\...\Documents\Arduino\hardware\espressif\esp32\libraries\WiFi\src/WiFiClient.h:95:14: error: 'uint16_t WiFiClient::localPort() const' cannot be overloaded

     uint16_t localPort() const;

              ^

C:\Users\...\Documents\Arduino\hardware\espressif\esp32\libraries\WiFi\src/WiFiClient.h:90:14: error: with 'uint16_t WiFiClient::localPort() const'

     uint16_t localPort() const;

              ^

C:\Users\...\Documents\Arduino\hardware\espressif\esp32\libraries\WiFi\src/WiFiClient.h:96:14: error: 'uint16_t WiFiClient::localPort(int) const' cannot be overloaded

     uint16_t localPort(int fd) const;

              ^

C:\Users\...\Documents\Arduino\hardware\espressif\esp32\libraries\WiFi\src/WiFiClient.h:91:14: error: with 'uint16_t WiFiClient::localPort(int) const'

     uint16_t localPort(int fd) const;

              ^

@priyankachepuri09
Copy link

Same issue as @bestpika unable to compile.

@me-no-dev
Copy link
Member

fixed in the latest commit ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants