Giter Club home page Giter Club logo

esp32ssdp's Introduction

Hi there, you found me 😄

I am the developer of ESP3D, ESP3DLib, ESP3D-WEBUI and several others projects as main developer or contributor.

If you need, you can contact me by email or by discord.

If you like my contributions/work, please feel free to support me at :

  • liberapay Donate using Liberapay
  • Paypal PayPal – The safer, easier way to pay online.
  • ko-fi ko-fi

It is always nice to get support and bring good mojo 😺

Also if you use my work in your projects, do not be shy and share it, it is always nice to be mentioned.

Project Page ESP3D 3.0

esp32ssdp's People

Contributors

allcontributors[bot] avatar cripstian avatar luc-github avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

esp32ssdp's Issues

[Question]License

In LICENSE file and project indicated this is GPL-3 project, however in source code, there is MIT in place.
I want to double confirm which LIC is for this project? Thank you

SSDP Notworking in AP Mode

Hi, thankyou for the nice lib

I have a problem with this library when using WiFi in the mode of Access Point. When in WiFi Client or STA mode everything is OK. I don't know if this library can support working in AP mode or not?

Thankyou for the help.

By the way, ,i found this peace of code in the library file:

    tcpip_adapter_ip_info_t ip;
    if (WiFi.getMode() == WIFI_STA) {
        if (tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip)) {
            return IPAddress();
        }
    } else if (WiFi.getMode() == WIFI_OFF) {
        if (tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)) {
            return IPAddress();
        }
    }
    return IPAddress(ip.ip.addr);
}

[BUG] M-Search reply ST header does not conform to specification.

Section 1.2.3 swww.upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.0-20080424.pdf

"To be found, a device must send a UDP response to the source IP address and port that sent the request to the multicast channel. Devices respond if the ST header of the M-SEARCH request is “ssdp:all”, “upnp:rootdevice”, “uuid:” followed by a UUID that exactly matches one advertised by the device."

It will respond with the device type instead.

_deviceType,

I suggest just keeping track of the ST and returning it "if" a matching device is found. This also is an issue with the current logic on match device types I will discuss in a feature request to replay to ssdp:all and rootdevice as if they are the same as asking for the actual device type.

'tcpip_adapter_ip_info_t' was not declared in this scope

IPAddress SSDPClass::localIP(){
tcpip_adapter_ip_info_t ip;
if (WiFi.getMode() == WIFI_STA) {
if (tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip)) {
return IPAddress();
}
} else if (WiFi.getMode() == WIFI_OFF) {
if (tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)) {
return IPAddress();
}
}
return IPAddress(ip.ip.addr);
}

[BUG]SSDP randomly crash with esp3dlib

I got report that sometimes ssdp crash esp3dlib, disabling ssdp solve the issue.

The decoding stack show ssdp

mmexport1642393259223

I am not able to reproduce as it may be linked to network environment.
My guess is the timer is overflowed by too many packets and the update happen when current update is still ongoing.
3 possibles solutions:
1 - disable timer when update start then enable when done
2 - move update to a dedicated task instead of using timer
3 - Use AsyncUdp

TBD

[BUG] SSDP Async dont work in APSTA mode only in STA

Describe the bug
Using the example for the "async" method, I realized that I only get a response when using STA mode, in APSTA hybrid mode, responses are not sent to multicast (unlike what happens on the 8266, I'm migrating to esp32).

To Reproduce
I used the async web server example contained in ESPAsyncWebSrv.h and added the basics of the ESP32SSDP.h example (also async)
`//
// A simple server implementation showing how to:
// * serve static messages
// * read GET and POST parameters
// * handle missing pages / 404s
//

#include <Arduino.h>
#ifdef ESP32
#include <WiFi.h>
#include <AsyncTCP.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#endif
#include <ESPAsyncWebSrv.h>
#include "ESP32SSDP.h"

AsyncWebServer server(80);

const char* ssid = "XXXXXXXXXXXXX";
const char* password = "XXXXXXXXXXXXX";

const char* PARAM_MESSAGE = "message";

void notFound(AsyncWebServerRequest *request) {
request->send(404, "text/plain", "Not found");
}

void setup() {

Serial.begin(115200);
WiFi.mode(WIFI_MODE_APSTA);
WiFi.begin(ssid, password);
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.printf("WiFi Failed!\n");
    return;
}

Serial.print("IP Address: ");
Serial.println(WiFi.localIP());

server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(200, "text/plain", "Hello, world");
});

// Send a GET request to <IP>/get?message=<message>
server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
    String message;
    if (request->hasParam(PARAM_MESSAGE)) {
        message = request->getParam(PARAM_MESSAGE)->value();
    } else {
        message = "No message sent";
    }
    request->send(200, "text/plain", "Hello, GET: " + message);
});

// Send a POST request to <IP>/post with a form field message set to <message>
server.on("/post", HTTP_POST, [](AsyncWebServerRequest *request){
    String message;
    if (request->hasParam(PARAM_MESSAGE, true)) {
        message = request->getParam(PARAM_MESSAGE, true)->value();
    } else {
        message = "No message sent";
    }
    request->send(200, "text/plain", "Hello, POST: " + message);
});
    server.on("/description.xml", HTTP_GET, [&](AsyncWebServerRequest *request) {
        request->send(200, "text/xml", SSDP.schema(false));
    });
server.onNotFound(notFound);

server.begin();

        //set schema xml url, nees to match http handler
    //"ssdp/schema.xml" if not set
    SSDP.setSchemaURL("description.xml");
    //set port
    //80 if not set
    SSDP.setHTTPPort(80);
    //set device name
    //Null string if not set
    SSDP.setName("Philips hue clone");
    //set Serial Number
    //Null string if not set
    SSDP.setSerialNumber("001788102201");
    //set device url
    //Null string if not set
    SSDP.setURL("index.html");
    //set model name
    //Null string if not set
    SSDP.setModelName("Philips hue bridge 2012");
    //set model description
    //Null string if not set
    SSDP.setModelDescription("This device can be controled by WiFi");
    //set model number
    //Null string if not set
    SSDP.setModelNumber("929000226503");
    //set model url
    //Null string if not set
    SSDP.setModelURL("http://www.meethue.com");
    //set model manufacturer name
    //Null string if not set
    SSDP.setManufacturer("Royal Philips Electronics");
    //set model manufacturer url
    //Null string if not set
    SSDP.setManufacturerURL("http://www.philips.com");
    //set device type
    //"urn:schemas-upnp-org:device:Basic:1" if not set
    SSDP.setDeviceType("rootdevice"); //to appear as root device, other examples: MediaRenderer, MediaServer ...
    //set server name
    //"Arduino/1.0" if not set
    SSDP.setServerName("SSDPServer/1.0");
    //set UUID, you can use https://www.uuidgenerator.net/
    //use 38323636-4558-4dda-9188-cda0e6 + 4 last bytes of mac address if not set
    //use SSDP.setUUID("daa26fa3-d2d4-4072-bc7a-a1b88ab4234a", false); for full UUID
    SSDP.setUUID("daa26fa3-d2d4-4072-bc7a");
    //Set icons list, NB: optional, this is ignored under windows
    SSDP.setIcons(  "<icon>"
                    "<mimetype>image/png</mimetype>"
                    "<height>48</height>"
                    "<width>48</width>"
                    "<depth>24</depth>"
                    "<url>icon48.png</url>"
                    "</icon>");
    //Set service list, NB: optional for simple device
    SSDP.setServices(  "<service>"
                       "<serviceType>urn:schemas-upnp-org:service:SwitchPower:1</serviceType>"
                       "<serviceId>urn:upnp-org:serviceId:SwitchPower:1</serviceId>"
                       "<SCPDURL>/SwitchPower1.xml</SCPDURL>"
                       "<controlURL>/SwitchPower/Control</controlURL>"
                       "<eventSubURL>/SwitchPower/Event</eventSubURL>"
                       "</service>");

    Serial.println("Starting SSDP...");
   if ( SSDP.begin()){
    Serial.println("SSDP started");
   }else{
    Serial.println("SSDP Fail");
   }

// WiFi.mode(WIFI_MODE_APSTA);
}

void loop() {
}`

  1. Changed WiFi.mode(WIFI_MODE_STA); to WiFi.mode(WIFI_MODE_APSTA);

Expected behavior
SSDP response sent to broadcast (Show in windows network) in both STA and APSTA modes.
Screenshots

Firmware:

  • ESP core version: v2.0.14
  • Library Version:1.2.0
  • Wifi mode:APSTA

Board used (please complete the following information):

  • MCU: ESP32
  • Name: esp32dev
  • Flash size: 4MB 1.2M/1.5M

Deprecated schema()

SSDP.schema() is deprecated but still used in your samples,
Can you please update the sample code with SSDP.getSchema() because I can not get it working this way.

Fix Compilation failure on esp32 Core Version 3.0.0

Describe the bug
Changes in rel 3.0.0 of esp32 result in compilation failures

. . . \libraries\ESP32SSDP-1.2.1\src\ESP32SSDP.cpp:158:5: error: 'tcpip_adapter_ip_info_t' was not declared in this scope; did you mean 'tcpip_adapter_if_t'?
158 | tcpip_adapter_ip_info_t ip;
| ^~~~~~~~~~~~~~~~~~~~~~~

. . . \libraries\ESP32SSDP-1.2.1\src\ESP32SSDP.cpp:160:13: error: 'tcpip_adapter_get_ip_info' was not declared in this scope; did you mean 'tcpip_adapter_if_t'?
160 | if (tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip)) {
| ^~~~~~~~~~~~~~~~~~~~~~~~~

To Reproduce
Use esp32 rel 3.0.0

Expected behavior
Compilation without errors

Firmware:

  • ESP core version: 3.0.0
  • Library Version: 1.21
  • Wifi mode:STA

Board used (please complete the following information):

  • MCU: doit esp32

[FEATURE REQUEST] Respont to multiple device types or callback?

Currently the API accepts a single device type. UPNP clients normally look for a root device then read device xml. The xml contains the real device type but the search target header is
"ST: upnp:rootdevice"

So setting the device SSDP.setDeviceType() to say upnp:rootdevice works for discovery to start but fails because the xml device info schema will contain the wrong device type.
<deviceType>upnp:rootdevice</deviceType>

In my case my actual device type is "urn:schemas-upnp-org:device:Basic:1" but I need to respond to "upnp:rootdevice" and "ssdp:all" also the search term reply header is supposed to be the same as the ST in the search regardless of the actual device type.

Maybe this is best handled in a callback of some type? The ability to respond to multiple device types is a good feature but in most cases just one is enough provided the above rootdevice and ssdp:all are also returning a valid reply.

[BUG] Prevent std::bad_alloc when udp.parsePacket() is called

When SSDP library is used on ESP32 with other software that consumes lots of RAM, then it might happen that WiFiudp library tries to allocate 1460 Bytes using new operator (in parsePacket() function), but it throws an error (std::bad_alloc), that lead to reboot of ESP32. The reboot can be prevented if in ESP32SSDP.cpp the line number 322:

nbBytes= _server->parsePacket();

replaced by:

try {nbBytes= _server->parsePacket();} catch (const std::bad_alloc&) { return;}

[BUG] icon list is outside of device tag

Describe the bug
Studying the universal plug and play device arhitecture HERE on page 48-49. I noticed why my details from description.xml is not displayed correctly. The iconList attribute is outside of the device attribute. That causes various clients to not be able to process the data that we need to share.

To Reproduce
The basic example present inside the project is enough to prove my point.
Take a look using WiFiman

Expected behavior
Details regarding my device to be displayed correctly since I comply with the protocol

Firmware:

Board used (please complete the following information):

  • MCU: ESP32
  • Name: esp32doit-devkit-v1
  • Flash size: 16M

Additional context
The following xml is provided

Following is what I get using the basic example, but fixed it by modifying the library you awesomely provided

<root>
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<URLBase>http://192.168.0.118:80/</URLBase>
<device>
<deviceType>my device name</deviceType>
<friendlyName>my device name</friendlyName>
<presentationURL>/</presentationURL>
<serialNumber>123456789</serialNumber>
<modelName>my model name</modelName>
<modelDescription>a model description</modelDescription>
<modelNumber>AA:BB:CC:11:22:33</modelNumber>
<modelURL>http://example.com</modelURL>
<manufacturer>a manufacturer</manufacturer>
<manufacturerURL>https://www.manufacturer.com</manufacturerURL>
<UDN>uuid:322345342-444s44-1242-812juinflsd</UDN>
<serviceList>
<service>
<serviceType>urn:schemas-upnp-org:service:SwitchPower:1</serviceType>
<serviceId>urn:upnp-org:serviceId:SwitchPower:1</serviceId>
<SCPDURL>/SwitchPower1.xml</SCPDURL>
<controlURL>/SwitchPower/Control</controlURL>
<eventSubURL>/SwitchPower/Event</eventSubURL>
</service>
</serviceList>
<iconList>
<icon>
<mimetype>image/png</mimetype>
<height>48</height>
<width>48</width>
<depth>24</depth>
<url>icon48.png</url>
</icon>
</iconList>
</device>
</root>

What you render is (take a look at the iconList location (is outside of the device tag):

<root>
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<URLBase>http://192.168.0.108:80/</URLBase>
<device>
<deviceType>my device type</deviceType>
<friendlyName>a very friendly name</friendlyName>
<presentationURL>/</presentationURL>
<serialNumber>1234567890</serialNumber>
<modelName>a model name</modelName>
<modelDescription/>
<modelNumber>AA:BB:CC:11:22:33</modelNumber>
<modelURL>https://www.model-url.com</modelURL>
<manufacturer>the manufacturer</manufacturer>
<manufacturerURL>https://www.manufacturer.com</manufacturerURL>
<UDN>uuid:322345342-444s44-1242-812juinflsd</UDN>
<serviceList/>
</device>
<iconList/>
</root>

Duplicate Global Scope Enumerations Prevent Compilation

Describe the bug
Duplicate global scope enumerations in libraries (or own code) provent compilation.

ESP32SSDP.h has a global scope enumeration at line 51 -

typedef enum {
NONE,
SEARCH,
NOTIFY
} ssdp_method_t;

The global scope enumeration elements (NONE, SEARCH, NOTIFY) will conflict with amy other variables or other enums and prevent compilation.

In my case this was another library ezTime.

ezTime.h enum at line 69 -

typedef enum {
NONE,
ERROR,
INFO,
DEBUG
} ezDebugLevel_t;

error: 'NONE' conflicts with a previous declaration is raised by the compiler

Moving the ESP32SSDP ssdp_method_t typedef to within the SSDPClass class resolves this conflict.

class SSDPClass
{

typedef enum {
NONE,
SEARCH,
NOTIFY
} ssdp_method_t;

public:
SSDPClass();

I will raise a similar comment with regard to global enums in the ezTime GitHub repository.

To Reproduce
Attempt compilation using:

#include <ezTime.h>
#include <ESP32SSDP.h>

Expected behavior
Successful compilation with local scoped enums

Firmware:

  • ESP core version: 2.0.15
  • Library Version: 1.2.1 async
  • Wifi mode: STA

Board used (please complete the following information):

  • MCU: ESP32
  • Name: DOIT ESP32 DEVKIT V1

SSDPClass::localIP() returns wrong IP if WiFi Mode is WIFI_AP_STA

SSDPClass::localIP() retrung wrong IP if WiFi.getMode() == WIFI_AP_STA.

This leads to wrong ip in description.xml as this case is not covered. Device will not be detected in Windows 10.

A partially solution is to add this case in the condition, but this solution will only work for devices connected via station not for devices connected to AP:

IPAddress SSDPClass::localIP(){ tcpip_adapter_ip_info_t ip; if (WiFi.getMode() == WIFI_STA) { if (tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip)) { return IPAddress(); } } else if (WiFi.getMode() == WIFI_AP_STA) { // added workaround if (tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip)) { return IPAddress(); } } else if (WiFi.getMode() == WIFI_OFF) { if (tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)) { return IPAddress(); } } return IPAddress(ip.ip.addr); }

[BUG] compiler warning - large integer implicitly truncated to unsigned type

Using platformio to compile https://github.com/sharandac/My-TTGO-Watch (which uses this library), gives a warning:

.pio\libdeps\ttgo-t-watch\ESP32SSPD\ESP32SSDP.cpp: In constructor 'SSDPClass::SSDPClass()':
.pio\libdeps\ttgo-t-watch\ESP32SSPD\ESP32SSDP.cpp:112:19: warning: large integer implicitly truncated to unsigned type [-Woverflow]
_notify_time(0)
^

This is actually because of the earlier line in the constructor:
_interval(SSDP_INTERVAL),

Where _interval is uint8_t and SSDP_INTERVAL is 1200

Should _interval be uint32_t or unsigned long instead?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.