mirror of
https://github.com/rstrouse/ESPSomfy-RTS.git
synced 2025-12-13 19:12:10 +01:00
Merge branch 'rstrouse:main' into main
This commit is contained in:
commit
f3c642d667
13 changed files with 226 additions and 202 deletions
|
|
@ -83,7 +83,7 @@ class ShadeConfigFile : public ConfigFile {
|
||||||
static bool restore(SomfyShadeController *somfy, const char *filename, restore_options_t &opts);
|
static bool restore(SomfyShadeController *somfy, const char *filename, restore_options_t &opts);
|
||||||
bool begin(const char *filename, bool readOnly = false);
|
bool begin(const char *filename, bool readOnly = false);
|
||||||
bool begin(bool readOnly = false);
|
bool begin(bool readOnly = false);
|
||||||
bool save(SomfyShadeController *sofmy);
|
bool save(SomfyShadeController *somfy);
|
||||||
bool backup(SomfyShadeController *somfy);
|
bool backup(SomfyShadeController *somfy);
|
||||||
bool loadFile(SomfyShadeController *somfy, const char *filename = "/shades.cfg");
|
bool loadFile(SomfyShadeController *somfy, const char *filename = "/shades.cfg");
|
||||||
bool restoreFile(SomfyShadeController *somfy, const char *filename, restore_options_t &opts);
|
bool restoreFile(SomfyShadeController *somfy, const char *filename, restore_options_t &opts);
|
||||||
|
|
|
||||||
12
Network.cpp
12
Network.cpp
|
|
@ -63,7 +63,7 @@ void Network::loop() {
|
||||||
}
|
}
|
||||||
if(settings.ssdpBroadcast) {
|
if(settings.ssdpBroadcast) {
|
||||||
if(!SSDP.isStarted) SSDP.begin();
|
if(!SSDP.isStarted) SSDP.begin();
|
||||||
SSDP.loop();
|
if(SSDP.isStarted) SSDP.loop();
|
||||||
}
|
}
|
||||||
else if(!settings.ssdpBroadcast && SSDP.isStarted) SSDP.end();
|
else if(!settings.ssdpBroadcast && SSDP.isStarted) SSDP.end();
|
||||||
mqtt.loop();
|
mqtt.loop();
|
||||||
|
|
@ -187,11 +187,17 @@ void Network::setConnected(conn_types connType) {
|
||||||
//SSDP.setSerialNumber(0, "C2496952-5610-47E6-A968-2FC19737A0DB");
|
//SSDP.setSerialNumber(0, "C2496952-5610-47E6-A968-2FC19737A0DB");
|
||||||
//SSDP.setUUID(0, settings.uuid);
|
//SSDP.setUUID(0, settings.uuid);
|
||||||
SSDP.setModelName(0, "ESPSomfy RTS");
|
SSDP.setModelName(0, "ESPSomfy RTS");
|
||||||
SSDP.setModelNumber(0, "SS v1");
|
if(strlen(settings.chipModel) == 0) SSDP.setModelNumber(0, "ESP32");
|
||||||
|
else {
|
||||||
|
char sModel[20] = "";
|
||||||
|
snprintf(sModel, sizeof(sModel), "ESP32-%S", settings.chipModel);
|
||||||
|
SSDP.setModelNumber(0, sModel);
|
||||||
|
}
|
||||||
SSDP.setModelURL(0, "https://github.com/rstrouse/ESPSomfy-RTS");
|
SSDP.setModelURL(0, "https://github.com/rstrouse/ESPSomfy-RTS");
|
||||||
SSDP.setManufacturer(0, "rstrouse");
|
SSDP.setManufacturer(0, "rstrouse");
|
||||||
SSDP.setManufacturerURL(0, "https://github.com/rstrouse");
|
SSDP.setManufacturerURL(0, "https://github.com/rstrouse");
|
||||||
SSDP.setURL(0, "/");
|
SSDP.setURL(0, "/");
|
||||||
|
SSDP.setActive(0, true);
|
||||||
if(MDNS.begin(settings.hostname)) {
|
if(MDNS.begin(settings.hostname)) {
|
||||||
Serial.printf("MDNS Responder Started: serverId=%s\n", settings.serverId);
|
Serial.printf("MDNS Responder Started: serverId=%s\n", settings.serverId);
|
||||||
//MDNS.addService("http", "tcp", 80);
|
//MDNS.addService("http", "tcp", 80);
|
||||||
|
|
@ -204,7 +210,7 @@ void Network::setConnected(conn_types connType) {
|
||||||
MDNS.addServiceTxt("espsomfy_rts", "tcp", "version", String(settings.fwVersion.name));
|
MDNS.addServiceTxt("espsomfy_rts", "tcp", "version", String(settings.fwVersion.name));
|
||||||
}
|
}
|
||||||
if(settings.ssdpBroadcast) {
|
if(settings.ssdpBroadcast) {
|
||||||
if(SSDP.begin()) Serial.println("SSDP Client Started...");
|
SSDP.begin();
|
||||||
}
|
}
|
||||||
else if(SSDP.isStarted) SSDP.end();
|
else if(SSDP.isStarted) SSDP.end();
|
||||||
this->emitSockets();
|
this->emitSockets();
|
||||||
|
|
|
||||||
325
SSDP.cpp
325
SSDP.cpp
|
|
@ -10,12 +10,15 @@
|
||||||
#define SSDP_URI_SIZE 2
|
#define SSDP_URI_SIZE 2
|
||||||
#define SSDP_BUFFER_SIZE 64
|
#define SSDP_BUFFER_SIZE 64
|
||||||
#define SSDP_MULTICAST_ADDR 239, 255, 255, 250
|
#define SSDP_MULTICAST_ADDR 239, 255, 255, 250
|
||||||
|
//#define DEBUG_SSDP Serial
|
||||||
|
//#define DEBUG_SSDP_PACKET Serial
|
||||||
extern ConfigSettings settings;
|
extern ConfigSettings settings;
|
||||||
|
|
||||||
static const char _ssdp_uuid_template[] PROGMEM = "C2496952-5610-47E6-A968-2FC1%02x%02x%02x%02x";
|
static const char _ssdp_uuid_template[] PROGMEM = "C2496952-5610-47E6-A968-2FC1%02X%02X%02X%02X";
|
||||||
static const char _ssdp_serial_number_template[] PROGMEM = "ESP32-%02x%02x%02x";
|
static const char _ssdp_serial_number_template[] PROGMEM = "ESP32-%02x%02x%02x";
|
||||||
static const char _ssdp_usn_root_template[] PROGMEM = "%s::upnp::rootdevice";
|
static const char _ssdp_usn_root_template[] PROGMEM = "uuid:%s::upnp:rootdevice";
|
||||||
static const char _ssdp_usn_uuid_template[] PROGMEM = "%s::%s";
|
static const char _ssdp_usn_uuid_template[] PROGMEM = "uuid:%s";
|
||||||
|
static const char _ssdp_usn_urn_template[] PROGMEM = "uuid:%s::%s";
|
||||||
static const char _ssdp_response_template[] PROGMEM =
|
static const char _ssdp_response_template[] PROGMEM =
|
||||||
"HTTP/1.1 200 OK\r\n"
|
"HTTP/1.1 200 OK\r\n"
|
||||||
"EXT:\r\n";
|
"EXT:\r\n";
|
||||||
|
|
@ -26,14 +29,21 @@ static const char _ssdp_notify_template[] PROGMEM =
|
||||||
static const char _ssdp_bye_template[] PROGMEM =
|
static const char _ssdp_bye_template[] PROGMEM =
|
||||||
"NOTIFY * HTTP/1.1\r\n"
|
"NOTIFY * HTTP/1.1\r\n"
|
||||||
"HOST: 239.255.255.250:1900\r\n"
|
"HOST: 239.255.255.250:1900\r\n"
|
||||||
"NTS: ssdp:byebye\r\n";
|
"NTS: ssdp:byebye\r\n"
|
||||||
|
"NT: %s\r\n"
|
||||||
|
"USN: %s\r\n"
|
||||||
|
"BOOTID.UPNP.ORG: %ul\r\n"
|
||||||
|
"CONFIGID.UPNP.ORG: %d\r\n"
|
||||||
|
"\r\n";
|
||||||
static const char _ssdp_packet_template[] PROGMEM =
|
static const char _ssdp_packet_template[] PROGMEM =
|
||||||
"%s" // _ssdp_response_template / _ssdp_notify_template
|
"%s" // _ssdp_response_template / _ssdp_notify_template
|
||||||
"CACHE-CONTROL: max-age=%u\r\n" // _interval
|
"CACHE-CONTROL: max-age=%u\r\n" // _interval
|
||||||
"SERVER: Arduino/1.0 UPNP/1.1 %s/%s\r\n" // _modelName, _modelNumber
|
"SERVER: Arduino/1.0 UPnP/1.1 ESPSomfyRTS/2.0\r\n"
|
||||||
"USN: %s\r\n" // _uuid
|
"USN: %s\r\n" // _uuid
|
||||||
"%s: %s\r\n" // "NT" or "ST", _deviceType
|
"%s: %s\r\n" // "NT" or "ST", _deviceType
|
||||||
"LOCATION: http://%u.%u.%u.%u:%u/%s\r\n" // WiFi.localIP(), _port, _schemaURL
|
"LOCATION: http://%u.%u.%u.%u:%u/%s\r\n" // WiFi.localIP(), _port, _schemaURL
|
||||||
|
"BOOTID.UPNP.ORG: %ul\r\n"
|
||||||
|
"CONFIGID.UPNP.ORG: %d\r\n"
|
||||||
"\r\n";
|
"\r\n";
|
||||||
static const char _ssdp_device_schema_template[] PROGMEM =
|
static const char _ssdp_device_schema_template[] PROGMEM =
|
||||||
"<device>"
|
"<device>"
|
||||||
|
|
@ -46,7 +56,7 @@ static const char _ssdp_device_schema_template[] PROGMEM =
|
||||||
"<modelURL>%s</modelURL>"
|
"<modelURL>%s</modelURL>"
|
||||||
"<manufacturer>%s</manufacturer>"
|
"<manufacturer>%s</manufacturer>"
|
||||||
"<manufacturerURL>%s</manufacturerURL>"
|
"<manufacturerURL>%s</manufacturerURL>"
|
||||||
"<modelDescription>Somfy RTS Controller</modelDescription>"
|
"<modelDescription>ESPSomfy RTS Controller</modelDescription>"
|
||||||
"<firmwareVersion>%s</firmwareVersion>"
|
"<firmwareVersion>%s</firmwareVersion>"
|
||||||
"<UDN>%s</UDN>"
|
"<UDN>%s</UDN>"
|
||||||
"<serviceList></serviceList>"
|
"<serviceList></serviceList>"
|
||||||
|
|
@ -87,7 +97,7 @@ UPNPDeviceType::UPNPDeviceType(const char *deviceType) { this->setDeviceType(dev
|
||||||
UPNPDeviceType::UPNPDeviceType(const char *deviceType, const char *uuid){ this->setDeviceType(deviceType); this->setUUID(uuid); }
|
UPNPDeviceType::UPNPDeviceType(const char *deviceType, const char *uuid){ this->setDeviceType(deviceType); this->setUUID(uuid); }
|
||||||
UPNPDeviceType::UPNPDeviceType(const char *deviceType, const char *uuid, const char*friendlyName) { this->setDeviceType(deviceType); this->setUUID(uuid); this->setName(friendlyName);}
|
UPNPDeviceType::UPNPDeviceType(const char *deviceType, const char *uuid, const char*friendlyName) { this->setDeviceType(deviceType); this->setUUID(uuid); this->setName(friendlyName);}
|
||||||
void UPNPDeviceType::setSchemaURL(const char *url) { strlcpy(schemaURL, url, sizeof(schemaURL)); }
|
void UPNPDeviceType::setSchemaURL(const char *url) { strlcpy(schemaURL, url, sizeof(schemaURL)); }
|
||||||
void UPNPDeviceType::setDeviceType(const char *dtype) { strlcpy(deviceType, dtype, sizeof(deviceType)); }
|
void UPNPDeviceType::setDeviceType(const char *dtype) { strlcpy(this->deviceType, dtype, sizeof(deviceType)); }
|
||||||
void UPNPDeviceType::setUUID(const char *id) { snprintf_P(uuid, sizeof(uuid), PSTR("uuid:%s"), id); }
|
void UPNPDeviceType::setUUID(const char *id) { snprintf_P(uuid, sizeof(uuid), PSTR("uuid:%s"), id); }
|
||||||
void UPNPDeviceType::setName(const char *name) { strlcpy(friendlyName, name, sizeof(friendlyName)); }
|
void UPNPDeviceType::setName(const char *name) { strlcpy(friendlyName, name, sizeof(friendlyName)); }
|
||||||
void UPNPDeviceType::setURL(const char *url) { strlcpy(presentationURL, url, sizeof(presentationURL)); }
|
void UPNPDeviceType::setURL(const char *url) { strlcpy(presentationURL, url, sizeof(presentationURL)); }
|
||||||
|
|
@ -99,26 +109,43 @@ void UPNPDeviceType::setModelURL(const char *url) { strlcpy(modelURL, url, sizeo
|
||||||
void UPNPDeviceType::setManufacturer(const char *name) { strlcpy(manufacturer, name, sizeof(manufacturer)); }
|
void UPNPDeviceType::setManufacturer(const char *name) { strlcpy(manufacturer, name, sizeof(manufacturer)); }
|
||||||
void UPNPDeviceType::setManufacturerURL(const char *url) { strlcpy(manufacturerURL, url, sizeof(manufacturerURL)); }
|
void UPNPDeviceType::setManufacturerURL(const char *url) { strlcpy(manufacturerURL, url, sizeof(manufacturerURL)); }
|
||||||
//char * UPNPDeviceType::getUSN() { return this->getUSN(this->deviceType); }
|
//char * UPNPDeviceType::getUSN() { return this->getUSN(this->deviceType); }
|
||||||
|
char * UPNPDeviceType::getUSN(response_types_t responseType) {
|
||||||
|
switch(responseType) {
|
||||||
|
case response_types_t::root:
|
||||||
|
snprintf_P(this->m_usn, sizeof(this->m_usn) - 1, _ssdp_usn_root_template, this->uuid);
|
||||||
|
break;
|
||||||
|
case response_types_t::deviceType:
|
||||||
|
snprintf_P(this->m_usn, sizeof(this->m_usn) -1, _ssdp_usn_urn_template, this->uuid, this->deviceType);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
snprintf_P(this->m_usn, sizeof(this->m_usn) - 1, _ssdp_usn_uuid_template, this->uuid);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return this->m_usn;
|
||||||
|
}
|
||||||
char * UPNPDeviceType::getUSN(const char *st) {
|
char * UPNPDeviceType::getUSN(const char *st) {
|
||||||
#ifdef DEBUG_SSDP
|
//#ifdef DEBUG_SSDP
|
||||||
DEBUG_SSDP.print("GETUSN ST: ");
|
//DEBUG_SSDP.print("GETUSN ST: ");
|
||||||
DEBUG_SSDP.println(st);
|
//DEBUG_SSDP.println(st);
|
||||||
DEBUG_SSDP.print("GETUSN UUID: ");
|
//DEBUG_SSDP.print("GETUSN UUID: ");
|
||||||
DEBUG_SSDP.println(this->uuid);
|
//DEBUG_SSDP.println(this->uuid);
|
||||||
DEBUG_SSDP.print("sizeof(this->m_usn)");
|
//DEBUG_SSDP.print("sizeof(this->m_usn)");
|
||||||
DEBUG_SSDP.println(sizeof(this->m_usn));
|
//DEBUG_SSDP.println(sizeof(this->m_usn));
|
||||||
memset(this->m_usn, 0x00, sizeof(this->m_usn));
|
//#endif
|
||||||
#endif
|
if(strncmp("upnp:rootdevice", st, strlen(st)) == 0) {
|
||||||
if(strncmp("upnp:root", st, strlen(st)) == 0) {
|
|
||||||
snprintf_P(this->m_usn, sizeof(this->m_usn) - 1, _ssdp_usn_root_template, this->uuid);
|
snprintf_P(this->m_usn, sizeof(this->m_usn) - 1, _ssdp_usn_root_template, this->uuid);
|
||||||
}
|
}
|
||||||
|
else if(strncmp("uuid:", st, 5) == 0)
|
||||||
|
snprintf_P(this->m_usn, sizeof(this->m_usn) - 1, _ssdp_usn_uuid_template, this->uuid);
|
||||||
|
else if(strncmp("urn:", st, 4) == 0)
|
||||||
|
snprintf_P(this->m_usn, sizeof(this->m_usn) -1, _ssdp_usn_urn_template, this->uuid, this->deviceType);
|
||||||
else {
|
else {
|
||||||
snprintf_P(this->m_usn, sizeof(this->m_usn) - 1, _ssdp_usn_uuid_template, this->uuid, st);
|
snprintf_P(this->m_usn, sizeof(this->m_usn) - 1, _ssdp_usn_uuid_template, this->uuid);
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_SSDP
|
//#ifdef DEBUG_SSDP
|
||||||
DEBUG_SSDP.print("RESUSN UUID: ");
|
//DEBUG_SSDP.print("RESUSN UUID: ");
|
||||||
DEBUG_SSDP.println(this->m_usn);
|
//DEBUG_SSDP.println(this->m_usn);
|
||||||
#endif
|
//#endif
|
||||||
return this->m_usn;
|
return this->m_usn;
|
||||||
}
|
}
|
||||||
void UPNPDeviceType::setChipId(uint32_t chipId) {
|
void UPNPDeviceType::setChipId(uint32_t chipId) {
|
||||||
|
|
@ -139,7 +166,7 @@ bool SSDPClass::begin() {
|
||||||
for(int i = 0; i < SSDP_QUEUE_SIZE; i++) {
|
for(int i = 0; i < SSDP_QUEUE_SIZE; i++) {
|
||||||
this->sendQueue[i].waiting = false;
|
this->sendQueue[i].waiting = false;
|
||||||
}
|
}
|
||||||
this->end();
|
if(this->_server.connected()) this->end();
|
||||||
//assert(NULL == _server);
|
//assert(NULL == _server);
|
||||||
if(_server.connected()) {
|
if(_server.connected()) {
|
||||||
#ifdef DEBUG_SSDP
|
#ifdef DEBUG_SSDP
|
||||||
|
|
@ -148,6 +175,12 @@ bool SSDPClass::begin() {
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
this->bootId = Timestamp::epoch();
|
||||||
|
if(this->bootId < 1000) {
|
||||||
|
this->isStarted = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this->configId = (settings.fwVersion.major * 100) + (settings.fwVersion.minor * 10) + settings.fwVersion.build;
|
||||||
_server.onPacket([](void * arg, AsyncUDPPacket& packet) { ((SSDPClass*)(arg))->_processRequest(packet); }, this);
|
_server.onPacket([](void * arg, AsyncUDPPacket& packet) { ((SSDPClass*)(arg))->_processRequest(packet); }, this);
|
||||||
if(!_server.listenMulticast(IPAddress(SSDP_MULTICAST_ADDR), SSDP_PORT)) {
|
if(!_server.listenMulticast(IPAddress(SSDP_MULTICAST_ADDR), SSDP_PORT)) {
|
||||||
#ifdef DEBUG_SSDP
|
#ifdef DEBUG_SSDP
|
||||||
|
|
@ -159,22 +192,32 @@ bool SSDPClass::begin() {
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
for(uint8_t i = 0; i < this->m_cdeviceTypes; i++) {
|
||||||
|
Serial.printf("SSDP: %s - %s\n", this->deviceTypes[i].deviceType, this->deviceTypes[i].isActive ? "true" : "false");
|
||||||
|
}
|
||||||
this->isStarted = true;
|
this->isStarted = true;
|
||||||
this->_sendByeBye();
|
this->_sendByeBye();
|
||||||
this->_sendNotify();
|
this->_sendNotify();
|
||||||
Serial.println("Connected to SSDP");
|
Serial.println("Connected to SSDP...");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
void SSDPClass::end() {
|
void SSDPClass::end() {
|
||||||
if(!this->_server || !this->_server.connected()) return; // server isn't connected nothing to do
|
if(!this->_server || !this->_server.connected()) return; // server isn't connected nothing to do
|
||||||
#ifdef DEBUG_SSDP
|
#ifdef DEBUG_SSDP
|
||||||
DEBUG_SSDP.printf(PSTR("SSDP end ... "));
|
DEBUG_SSDP.printf(PSTR("SSDP end ...\n "));
|
||||||
#endif
|
#endif
|
||||||
|
if(this->_server.connected()) {
|
||||||
this->_sendByeBye();
|
this->_sendByeBye();
|
||||||
//this->_stopTimer();
|
|
||||||
this->_server.close();
|
this->_server.close();
|
||||||
|
}
|
||||||
this->isStarted = false;
|
this->isStarted = false;
|
||||||
Serial.println("Disconnected from SSDP");
|
// Clear out the last notified so if the user starts us up again it will notify
|
||||||
|
// that we exist again.
|
||||||
|
for(uint8_t i = 0; i < this->m_cdeviceTypes; i++) {
|
||||||
|
this->deviceTypes[i].lastNotified = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.println("Disconnected from SSDP...");
|
||||||
}
|
}
|
||||||
UPNPDeviceType* SSDPClass::getDeviceType(uint8_t ndx) { if(ndx < this->m_cdeviceTypes) return &this->deviceTypes[ndx]; return nullptr; }
|
UPNPDeviceType* SSDPClass::getDeviceType(uint8_t ndx) { if(ndx < this->m_cdeviceTypes) return &this->deviceTypes[ndx]; return nullptr; }
|
||||||
UPNPDeviceType* SSDPClass::findDeviceByType(char *devType) {
|
UPNPDeviceType* SSDPClass::findDeviceByType(char *devType) {
|
||||||
|
|
@ -242,9 +285,6 @@ void SSDPClass::_parsePacket(ssdp_packet_t *pkt, AsyncUDPPacket &p) {
|
||||||
buffer[0] = '\0';
|
buffer[0] = '\0';
|
||||||
while(p.available() > 0) {
|
while(p.available() > 0) {
|
||||||
char c = p.read();
|
char c = p.read();
|
||||||
//#ifdef DEBUG_SSDP_PACKET
|
|
||||||
//DEBUG_SSDP.print(c);
|
|
||||||
//#endif
|
|
||||||
if(keys == KEY) {
|
if(keys == KEY) {
|
||||||
if(c == ':') {
|
if(c == ':') {
|
||||||
_trim(buffer);
|
_trim(buffer);
|
||||||
|
|
@ -259,12 +299,8 @@ void SSDPClass::_parsePacket(ssdp_packet_t *pkt, AsyncUDPPacket &p) {
|
||||||
else if(strcasecmp(buffer, "LOCATION") == 0) keys = LOCATION;
|
else if(strcasecmp(buffer, "LOCATION") == 0) keys = LOCATION;
|
||||||
else if(strcasecmp(buffer, "USN") == 0) keys = USN;
|
else if(strcasecmp(buffer, "USN") == 0) keys = USN;
|
||||||
else keys = HEAD;
|
else keys = HEAD;
|
||||||
//#ifdef DEBUG_SSDP_PACKET
|
|
||||||
//DEBUG_SSDP.printf("Found a key: %s ", buffer);
|
|
||||||
//#endif
|
|
||||||
pos = 0;
|
pos = 0;
|
||||||
buffer[0] = '\0';
|
buffer[0] = '\0';
|
||||||
|
|
||||||
}
|
}
|
||||||
else if(c == '\r' || c == '\n') {
|
else if(c == '\r' || c == '\n') {
|
||||||
// If we find a key that ends before a : then we need to bugger out.
|
// If we find a key that ends before a : then we need to bugger out.
|
||||||
|
|
@ -284,9 +320,6 @@ void SSDPClass::_parsePacket(ssdp_packet_t *pkt, AsyncUDPPacket &p) {
|
||||||
// We are reading a value
|
// We are reading a value
|
||||||
if(c == '\r' || c == '\n') {
|
if(c == '\r' || c == '\n') {
|
||||||
_trim(buffer);
|
_trim(buffer);
|
||||||
#ifdef DEBUG_SSDP_PACKET
|
|
||||||
DEBUG_SSDP.println(buffer);
|
|
||||||
#endif
|
|
||||||
switch(keys) {
|
switch(keys) {
|
||||||
case HOST:
|
case HOST:
|
||||||
if(strcasecmp(buffer, "239.255.255.250:1900") == 0) pkt->type = MULTICAST;
|
if(strcasecmp(buffer, "239.255.255.250:1900") == 0) pkt->type = MULTICAST;
|
||||||
|
|
@ -324,9 +357,6 @@ void SSDPClass::_parsePacket(ssdp_packet_t *pkt, AsyncUDPPacket &p) {
|
||||||
if(pkt->valid) {
|
if(pkt->valid) {
|
||||||
if(pkt->method == NONE) pkt->valid = false;
|
if(pkt->method == NONE) pkt->valid = false;
|
||||||
if(pkt->method == SEARCH) {
|
if(pkt->method == SEARCH) {
|
||||||
#ifdef DEBUG_SSDP_PACKET
|
|
||||||
//this->_printPacket(pkt);
|
|
||||||
#endif
|
|
||||||
if(strcmp(pkt->man, "ssdp:discover") != 0) pkt->valid = false;
|
if(strcmp(pkt->man, "ssdp:discover") != 0) pkt->valid = false;
|
||||||
if(strlen(pkt->st) == 0) pkt->valid = false;
|
if(strlen(pkt->st) == 0) pkt->valid = false;
|
||||||
else if(strcmp(pkt->st, "ssdp:all") != 0 &&
|
else if(strcmp(pkt->st, "ssdp:all") != 0 &&
|
||||||
|
|
@ -364,11 +394,9 @@ IPAddress SSDPClass::localIP()
|
||||||
}
|
}
|
||||||
return IPAddress(ip.ip.addr);
|
return IPAddress(ip.ip.addr);
|
||||||
}
|
}
|
||||||
void SSDPClass::_sendResponse(IPAddress addr, uint16_t port, UPNPDeviceType *d, char *st, bool sendUUID) {
|
void SSDPClass::_sendResponse(IPAddress addr, uint16_t port, UPNPDeviceType *d, const char *st, response_types_t responseType) {
|
||||||
char buffer[1460];
|
char buffer[1460];
|
||||||
IPAddress ip = this->localIP();
|
IPAddress ip = this->localIP();
|
||||||
//IPAddress ip = WiFi.localIP();
|
|
||||||
|
|
||||||
char *pbuff = (char *)malloc(strlen_P(_ssdp_response_template)+1);
|
char *pbuff = (char *)malloc(strlen_P(_ssdp_response_template)+1);
|
||||||
if(!pbuff) {
|
if(!pbuff) {
|
||||||
#ifdef DEBUG_SSDP
|
#ifdef DEBUG_SSDP
|
||||||
|
|
@ -378,41 +406,17 @@ void SSDPClass::_sendResponse(IPAddress addr, uint16_t port, UPNPDeviceType *d,
|
||||||
}
|
}
|
||||||
strcpy_P(pbuff, _ssdp_response_template);
|
strcpy_P(pbuff, _ssdp_response_template);
|
||||||
|
|
||||||
#ifdef DEBUG_SSDP
|
|
||||||
//3FFC40B8
|
|
||||||
DEBUG_SSDP.println("Before sprintf ");
|
|
||||||
DEBUG_SSDP.print("CACHE-CONTROL: max-age=");
|
|
||||||
DEBUG_SSDP.println(this->_interval);
|
|
||||||
DEBUG_SSDP.print("SERVER: Arduino/1.0 UPNP/1.1 ");
|
|
||||||
DEBUG_SSDP.print(d->modelName);
|
|
||||||
DEBUG_SSDP.print("/");
|
|
||||||
DEBUG_SSDP.println(d->modelNumber);
|
|
||||||
DEBUG_SSDP.print("USN: ");
|
|
||||||
DEBUG_SSDP.println(d->getUSN(st));
|
|
||||||
DEBUG_SSDP.print("ST: ");
|
|
||||||
DEBUG_SSDP.println((sendUUID) ? d->uuid : st);
|
|
||||||
DEBUG_SSDP.print("LOCATION: http://");
|
|
||||||
DEBUG_SSDP.print(ip[0]);
|
|
||||||
DEBUG_SSDP.print(ip[1]);
|
|
||||||
DEBUG_SSDP.print(ip[2]);
|
|
||||||
DEBUG_SSDP.print(ip[3]);
|
|
||||||
DEBUG_SSDP.print(":");
|
|
||||||
DEBUG_SSDP.print(this->_port);
|
|
||||||
DEBUG_SSDP.println(d->schemaURL);
|
|
||||||
#endif
|
|
||||||
// Don't use ip.toString as this fragments the heap like no tomorrow.
|
// Don't use ip.toString as this fragments the heap like no tomorrow.
|
||||||
int len = snprintf_P(buffer, sizeof(buffer)-1,
|
int len = snprintf_P(buffer, sizeof(buffer)-1,
|
||||||
_ssdp_packet_template,
|
_ssdp_packet_template,
|
||||||
pbuff,
|
pbuff,
|
||||||
this->_interval,
|
this->_interval,
|
||||||
d->modelName, d->modelNumber,
|
d->getUSN(responseType),
|
||||||
d->getUSN(st),
|
"ST", st,
|
||||||
"ST", (sendUUID) ? d->uuid : st,
|
ip[0], ip[1], ip[2], ip[3], this->_port, d->schemaURL,
|
||||||
ip[0], ip[1], ip[2], ip[3], this->_port, d->schemaURL);
|
this->bootId, this->configId);
|
||||||
#ifdef DEBUG_SSDP
|
buffer[sizeof(buffer) - 1] = '\0';
|
||||||
DEBUG_SSDP.println(buffer);
|
this->_sendResponse(addr, port, buffer);
|
||||||
#endif
|
|
||||||
|
|
||||||
free(pbuff);
|
free(pbuff);
|
||||||
/*
|
/*
|
||||||
static const char _ssdp_packet_template[] PROGMEM =
|
static const char _ssdp_packet_template[] PROGMEM =
|
||||||
|
|
@ -423,10 +427,9 @@ static const char _ssdp_packet_template[] PROGMEM =
|
||||||
"%s: %s\r\n" // "NT" or "ST", _deviceType
|
"%s: %s\r\n" // "NT" or "ST", _deviceType
|
||||||
"LOCATION: http://%u.%u.%u.%u:%u/%s\r\n" // WiFi.localIP(), _port, _schemaURL
|
"LOCATION: http://%u.%u.%u.%u:%u/%s\r\n" // WiFi.localIP(), _port, _schemaURL
|
||||||
"\r\n";
|
"\r\n";
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
buffer[sizeof(buffer) - 1] = '\0';
|
|
||||||
#ifdef DEBUG_SSDP
|
#ifdef DEBUG_SSDP
|
||||||
DEBUG_SSDP.print("Sending Response to ");
|
DEBUG_SSDP.print("Sending Response to ");
|
||||||
DEBUG_SSDP.print(IPAddress(addr));
|
DEBUG_SSDP.print(IPAddress(addr));
|
||||||
|
|
@ -436,32 +439,47 @@ static const char _ssdp_packet_template[] PROGMEM =
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_server.writeTo((const uint8_t *)buffer, len, addr, port);
|
_server.writeTo((const uint8_t *)buffer, len, addr, port);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
void SSDPClass::_sendResponse(IPAddress addr, uint16_t port, const char *buff) {
|
||||||
|
#ifdef DEBUG_SSDP
|
||||||
|
DEBUG_SSDP.print("Sending Response to ");
|
||||||
|
DEBUG_SSDP.print(IPAddress(addr));
|
||||||
|
DEBUG_SSDP.print(":");
|
||||||
|
DEBUG_SSDP.println(port);
|
||||||
|
DEBUG_SSDP.println(buff);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_server.writeTo((const uint8_t *)buff, strlen(buff), addr, port);
|
||||||
}
|
}
|
||||||
void SSDPClass::_sendNotify() {
|
void SSDPClass::_sendNotify() {
|
||||||
for(uint8_t i = 0; i < this->m_cdeviceTypes; i++) {
|
for(uint8_t i = 0; i < this->m_cdeviceTypes; i++) {
|
||||||
UPNPDeviceType *dev = &this->deviceTypes[i];
|
UPNPDeviceType *dev = &this->deviceTypes[i];
|
||||||
|
if(i == 0 && (strlen(dev->deviceType) == 0 || !dev->isActive)) Serial.printf("The device type is empty: %s\n", dev->isActive ? "true" : "false");
|
||||||
if(strlen(dev->deviceType) > 0 && dev->isActive) {
|
if(strlen(dev->deviceType) > 0 && dev->isActive) {
|
||||||
uint16_t elapsed = (millis() - dev->lastNotified);
|
unsigned long elapsed = (millis() - dev->lastNotified);
|
||||||
if(!dev->lastNotified || (elapsed * 4) > (this->_interval * 1000)) {
|
if(!dev->lastNotified || (elapsed * 5) > (this->_interval * 1000)) {
|
||||||
#ifdef DEBUG_SSDP
|
|
||||||
DEBUG_SSDP.print(dev->deviceType);
|
|
||||||
DEBUG_SSDP.print(" Time since last notified: ");
|
|
||||||
DEBUG_SSDP.print(elapsed);
|
|
||||||
DEBUG_SSDP.print("msec ");
|
|
||||||
DEBUG_SSDP.print(this->_interval);
|
|
||||||
DEBUG_SSDP.println("msec");
|
|
||||||
#endif
|
|
||||||
this->_sendNotify(dev, i == 0);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
#ifdef DEBUG_SSDP
|
#ifdef DEBUG_SSDP
|
||||||
DEBUG_SSDP.print(dev->deviceType);
|
DEBUG_SSDP.print(dev->deviceType);
|
||||||
DEBUG_SSDP.print(" Time since last notified: ");
|
DEBUG_SSDP.print(" Time since last notified: ");
|
||||||
DEBUG_SSDP.print(elapsed/1000);
|
DEBUG_SSDP.print(elapsed/1000);
|
||||||
DEBUG_SSDP.print("msec ");
|
DEBUG_SSDP.print("sec ");
|
||||||
DEBUG_SSDP.print(this->_interval);
|
DEBUG_SSDP.print(this->_interval);
|
||||||
DEBUG_SSDP.println("msec -- SKIPPING");
|
DEBUG_SSDP.println("sec");
|
||||||
#endif
|
#endif
|
||||||
|
this->_sendNotify(dev, i == 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/*
|
||||||
|
#ifdef DEBUG_SSDP
|
||||||
|
DEBUG_SSDP.print(dev->deviceType);
|
||||||
|
DEBUG_SSDP.print(" Time since last notified: ");
|
||||||
|
DEBUG_SSDP.print(elapsed/1000);
|
||||||
|
DEBUG_SSDP.print("sec ");
|
||||||
|
DEBUG_SSDP.print(this->_interval);
|
||||||
|
DEBUG_SSDP.println("sec -- SKIPPING");
|
||||||
|
#endif
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -469,9 +487,13 @@ void SSDPClass::_sendNotify() {
|
||||||
void SSDPClass::_sendNotify(const char *msg) {
|
void SSDPClass::_sendNotify(const char *msg) {
|
||||||
//_server->append(msg, strlen(msg));
|
//_server->append(msg, strlen(msg));
|
||||||
//_server->send(IPAddress(SSDP_MULTICAST_ADDR), SSDP_PORT);
|
//_server->send(IPAddress(SSDP_MULTICAST_ADDR), SSDP_PORT);
|
||||||
|
#ifdef DEBUG_SSDP
|
||||||
|
DEBUG_SSDP.println("--------------- SEND NOTIFY PACKET ----------------");
|
||||||
|
DEBUG_SSDP.println(msg);
|
||||||
|
#endif
|
||||||
_server.writeTo((uint8_t *)msg, strlen(msg), IPAddress(SSDP_MULTICAST_ADDR), SSDP_PORT);
|
_server.writeTo((uint8_t *)msg, strlen(msg), IPAddress(SSDP_MULTICAST_ADDR), SSDP_PORT);
|
||||||
}
|
}
|
||||||
void SSDPClass::_sendNotify(UPNPDeviceType *d) { this->_sendByeBye(d, strcmp(d->deviceType, this->deviceTypes[0].deviceType) == 0); }
|
void SSDPClass::_sendNotify(UPNPDeviceType *d) { this->_sendNotify(d, strcmp(d->deviceType, this->deviceTypes[0].deviceType) == 0); }
|
||||||
void SSDPClass::_sendNotify(UPNPDeviceType *d, bool root) {
|
void SSDPClass::_sendNotify(UPNPDeviceType *d, bool root) {
|
||||||
char buffer[1460];
|
char buffer[1460];
|
||||||
IPAddress ip = this->localIP();
|
IPAddress ip = this->localIP();
|
||||||
|
|
@ -492,60 +514,48 @@ void SSDPClass::_sendNotify(UPNPDeviceType *d, bool root) {
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
strcpy_P(pbuff, _ssdp_response_template);
|
strcpy_P(pbuff, _ssdp_notify_template);
|
||||||
|
|
||||||
#ifdef DEBUG_SSDP
|
|
||||||
//3FFC40B8
|
|
||||||
DEBUG_SSDP.print("Before Notify sprintf ");
|
|
||||||
DEBUG_SSDP.print((uintptr_t)d, HEX);
|
|
||||||
DEBUG_SSDP.println(" ");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(root) {
|
if(root) {
|
||||||
// Send 1 for root
|
// Send 1 for root
|
||||||
snprintf_P(buffer, sizeof(buffer),
|
snprintf_P(buffer, sizeof(buffer),
|
||||||
_ssdp_packet_template,
|
_ssdp_packet_template,
|
||||||
pbuff,
|
pbuff,
|
||||||
this->_interval,
|
this->_interval,
|
||||||
d->modelName, d->modelNumber,
|
d->getUSN(response_types_t::root), // USN
|
||||||
d->getUSN("upnp:rootdevice"), // USN
|
|
||||||
"NT", "upnp:rootdevice",
|
"NT", "upnp:rootdevice",
|
||||||
ip[0], ip[1], ip[2], ip[3], this->_port, d->schemaURL);
|
ip[0], ip[1], ip[2], ip[3], this->_port, d->schemaURL, this->bootId, this->configId);
|
||||||
this->_sendNotify(buffer);
|
this->_sendNotify(buffer);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
// Send 1 for uuid
|
// Send 1 for uuid
|
||||||
snprintf_P(buffer, sizeof(buffer),
|
snprintf_P(buffer, sizeof(buffer),
|
||||||
_ssdp_packet_template,
|
_ssdp_packet_template,
|
||||||
pbuff,
|
pbuff,
|
||||||
this->_interval,
|
this->_interval,
|
||||||
d->modelName,
|
d->getUSN(response_types_t::uuid),
|
||||||
d->modelNumber,
|
"NT", d->getUSN(response_types_t::uuid),
|
||||||
d->uuid,
|
ip[0], ip[1], ip[2], ip[3], _port, d->schemaURL, this->bootId, this->configId);
|
||||||
"NT", d->uuid,
|
|
||||||
ip[0], ip[1], ip[2], ip[3], _port, d->schemaURL);
|
|
||||||
this->_sendNotify(buffer);
|
this->_sendNotify(buffer);
|
||||||
// Send 1 for deviceType
|
// Send 1 for deviceType
|
||||||
snprintf_P(buffer, sizeof(buffer),
|
snprintf_P(buffer, sizeof(buffer),
|
||||||
_ssdp_packet_template,
|
_ssdp_packet_template,
|
||||||
pbuff,
|
pbuff,
|
||||||
this->_interval,
|
this->_interval,
|
||||||
d->modelName,
|
d->getUSN(response_types_t::deviceType),
|
||||||
d->modelNumber,
|
|
||||||
d->getUSN(d->deviceType),
|
|
||||||
"NT", d->deviceType,
|
"NT", d->deviceType,
|
||||||
ip[0], ip[1], ip[2], ip[3], _port, d->schemaURL);
|
ip[0], ip[1], ip[2], ip[3], _port, d->schemaURL, this->bootId, this->configId);
|
||||||
this->_sendNotify(buffer);
|
this->_sendNotify(buffer);
|
||||||
}
|
|
||||||
d->lastNotified = millis();
|
d->lastNotified = millis();
|
||||||
}
|
}
|
||||||
void SSDPClass::setActive(uint8_t ndx, bool isActive) {
|
void SSDPClass::setActive(uint8_t ndx, bool isActive) {
|
||||||
UPNPDeviceType *d = &this->deviceTypes[ndx];
|
UPNPDeviceType *d = &this->deviceTypes[ndx];
|
||||||
if(!isActive) this->_sendByeBye(d, ndx == 0);
|
if(!isActive) {
|
||||||
|
if(this->isStarted) this->_sendByeBye(d, ndx == 0);
|
||||||
|
d->isActive = false;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
d->isActive = true;
|
d->isActive = true;
|
||||||
d->lastNotified = 0;
|
d->lastNotified = 0;
|
||||||
this->_sendNotify(d, ndx == 0);
|
if(this->isStarted) this->_sendNotify(d, ndx == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void SSDPClass::_sendByeBye() {
|
void SSDPClass::_sendByeBye() {
|
||||||
|
|
@ -554,11 +564,9 @@ void SSDPClass::_sendByeBye() {
|
||||||
if(strlen(dev->deviceType) > 0) {
|
if(strlen(dev->deviceType) > 0) {
|
||||||
#ifdef DEBUG_SSDP
|
#ifdef DEBUG_SSDP
|
||||||
DEBUG_SSDP.print(dev->deviceType);
|
DEBUG_SSDP.print(dev->deviceType);
|
||||||
//DEBUG_SSDP.print(" Time since last notified: ");
|
DEBUG_SSDP.print(" ");
|
||||||
//DEBUG_SSDP.print(elapsed);
|
|
||||||
//DEBUG_SSDP.print("msec ");
|
|
||||||
DEBUG_SSDP.print(this->_interval);
|
DEBUG_SSDP.print(this->_interval);
|
||||||
DEBUG_SSDP.println("msec");
|
DEBUG_SSDP.println("sec");
|
||||||
#endif
|
#endif
|
||||||
this->_sendByeBye(dev, i == 0);
|
this->_sendByeBye(dev, i == 0);
|
||||||
}
|
}
|
||||||
|
|
@ -586,42 +594,24 @@ void SSDPClass::_sendByeBye(UPNPDeviceType *d, bool root) {
|
||||||
if(root) {
|
if(root) {
|
||||||
// Send 1 for root
|
// Send 1 for root
|
||||||
snprintf_P(buffer, sizeof(buffer)-1,
|
snprintf_P(buffer, sizeof(buffer)-1,
|
||||||
_ssdp_packet_template,
|
_ssdp_bye_template,
|
||||||
_ssdp_notify_template,
|
"upnp:rootdevice", d->getUSN(response_types_t::root), this->bootId, this->configId);
|
||||||
this->_interval,
|
|
||||||
d->modelName, d->modelNumber,
|
|
||||||
d->getUSN("upnp:rootdevice"), // USN
|
|
||||||
"NT", "upnp:rootdevice",
|
|
||||||
ip[0], ip[1], ip[2], ip[3], this->_port, d->schemaURL);
|
|
||||||
this->_sendNotify(buffer);
|
this->_sendNotify(buffer);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
// Send 1 for uuid
|
// Send 1 for uuid
|
||||||
snprintf_P(buffer, sizeof(buffer)-1,
|
snprintf_P(buffer, sizeof(buffer)-1,
|
||||||
_ssdp_packet_template,
|
_ssdp_bye_template,
|
||||||
_ssdp_notify_template,
|
d->getUSN(response_types_t::uuid),
|
||||||
this->_interval,
|
d->getUSN(response_types_t::uuid), this->bootId, this->configId);
|
||||||
d->modelName,
|
|
||||||
d->modelNumber,
|
|
||||||
d->uuid,
|
|
||||||
"NT", d->uuid,
|
|
||||||
ip[0], ip[1], ip[2], ip[3], this->_port, d->schemaURL);
|
|
||||||
this->_sendNotify(buffer);
|
this->_sendNotify(buffer);
|
||||||
// Send 1 for deviceType
|
// Send 1 for deviceType
|
||||||
snprintf_P(buffer, sizeof(buffer)-1,
|
snprintf_P(buffer, sizeof(buffer)-1,
|
||||||
_ssdp_packet_template,
|
_ssdp_bye_template,
|
||||||
_ssdp_notify_template,
|
d->deviceType,
|
||||||
this->_interval,
|
d->getUSN(response_types_t::deviceType), this->bootId, this->configId);
|
||||||
d->modelName,
|
|
||||||
d->modelNumber,
|
|
||||||
d->getUSN(d->deviceType),
|
|
||||||
"NT", d->deviceType,
|
|
||||||
ip[0], ip[1], ip[2], ip[3], this->_port, d->schemaURL);
|
|
||||||
this->_sendNotify(buffer);
|
this->_sendNotify(buffer);
|
||||||
}
|
}
|
||||||
d->isActive = false;
|
void SSDPClass::_addToSendQueue(IPAddress addr, uint16_t port, UPNPDeviceType *d, const char *st, response_types_t responseType, uint8_t sec) {
|
||||||
}
|
|
||||||
void SSDPClass::_addToSendQueue(IPAddress addr, uint16_t port, UPNPDeviceType *d, char *st, uint8_t sec, bool sendUUID) {
|
|
||||||
/*
|
/*
|
||||||
typedef struct ssdp_response_t {
|
typedef struct ssdp_response_t {
|
||||||
IPAddress address;
|
IPAddress address;
|
||||||
|
|
@ -636,9 +626,9 @@ void SSDPClass::_addToSendQueue(IPAddress addr, uint16_t port, UPNPDeviceType *d
|
||||||
if(this->sendQueue[i].waiting) {
|
if(this->sendQueue[i].waiting) {
|
||||||
// Check to see if this is a reply to the same place.
|
// Check to see if this is a reply to the same place.
|
||||||
ssdp_response_t *q = &this->sendQueue[i];
|
ssdp_response_t *q = &this->sendQueue[i];
|
||||||
if(q->address == addr && q->port == port && q->sendUUID == sendUUID) {
|
if(q->address == addr && q->port == port && q->responseType == responseType) {
|
||||||
#ifdef DEBUG_SSDP
|
#ifdef DEBUG_SSDP
|
||||||
DEBUG_SSDP.printf("There is already a response to this query in slot #u\n", i);
|
DEBUG_SSDP.printf("There is already a response to this query in slot %u\n", i);
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -655,8 +645,8 @@ void SSDPClass::_addToSendQueue(IPAddress addr, uint16_t port, UPNPDeviceType *d
|
||||||
q->dev = d;
|
q->dev = d;
|
||||||
q->sendTime = millis() + (random(0, sec - 1) * 1000L);
|
q->sendTime = millis() + (random(0, sec - 1) * 1000L);
|
||||||
q->address = addr;
|
q->address = addr;
|
||||||
q->port = _port;
|
q->port = port;
|
||||||
q->sendUUID = sendUUID;
|
q->responseType = responseType;
|
||||||
strlcpy(q->st, st, sizeof(ssdp_response_t::st)-1);
|
strlcpy(q->st, st, sizeof(ssdp_response_t::st)-1);
|
||||||
q->waiting = true;
|
q->waiting = true;
|
||||||
return;
|
return;
|
||||||
|
|
@ -677,7 +667,7 @@ void SSDPClass::_sendQueuedResponses() {
|
||||||
DEBUG_SSDP.print("Sending SSDP queued response ");
|
DEBUG_SSDP.print("Sending SSDP queued response ");
|
||||||
DEBUG_SSDP.println(i);
|
DEBUG_SSDP.println(i);
|
||||||
#endif
|
#endif
|
||||||
this->_sendResponse(q->address, q->port, q->dev, q->st, q->sendUUID);
|
this->_sendResponse(q->address, q->port, q->dev, q->st, q->responseType);
|
||||||
q->waiting = false;
|
q->waiting = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -710,6 +700,7 @@ void SSDPClass::_printPacket(ssdp_packet_t *pkt) {
|
||||||
}
|
}
|
||||||
void SSDPClass::_processRequest(AsyncUDPPacket &p) {
|
void SSDPClass::_processRequest(AsyncUDPPacket &p) {
|
||||||
// This pending BS should probably be for unicast request only but we will play along for now.
|
// This pending BS should probably be for unicast request only but we will play along for now.
|
||||||
|
if(!this->_server.connected()) return;
|
||||||
if(p.length() == 0) {
|
if(p.length() == 0) {
|
||||||
//this->_sendQueuedResponses();
|
//this->_sendQueuedResponses();
|
||||||
return;
|
return;
|
||||||
|
|
@ -719,21 +710,29 @@ void SSDPClass::_processRequest(AsyncUDPPacket &p) {
|
||||||
if(pkt.valid && pkt.method == SEARCH) {
|
if(pkt.valid && pkt.method == SEARCH) {
|
||||||
// Check to see if we have anything to respond to from this packet.
|
// Check to see if we have anything to respond to from this packet.
|
||||||
if(strcmp("ssdp:all", pkt.st) == 0) {
|
if(strcmp("ssdp:all", pkt.st) == 0) {
|
||||||
|
#ifdef DEBUG_SSDP
|
||||||
|
DEBUG_SSDP.println("--------------- ALL ---------------------");
|
||||||
|
this->_printPacket(&pkt);
|
||||||
|
#endif
|
||||||
for(uint8_t i = 0; i < this->m_cdeviceTypes; i++) {
|
for(uint8_t i = 0; i < this->m_cdeviceTypes; i++) {
|
||||||
if(strlen(this->deviceTypes[i].deviceType) > 0)
|
UPNPDeviceType *dev = &this->deviceTypes[i];
|
||||||
this->_addToSendQueue(p.remoteIP(), p.remotePort(), &this->deviceTypes[i], this->deviceTypes[i].deviceType, pkt.mx, false);
|
if(strlen(this->deviceTypes[i].deviceType) > 0) {
|
||||||
|
this->_addToSendQueue(p.remoteIP(), p.remotePort(), dev, pkt.st, response_types_t::root, pkt.mx);
|
||||||
|
this->_addToSendQueue(p.remoteIP(), p.remotePort(), dev, pkt.st, response_types_t::uuid, pkt.mx);
|
||||||
|
this->_addToSendQueue(p.remoteIP(), p.remotePort(), dev, pkt.st, response_types_t::deviceType, pkt.mx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(strcmp("upnp:rootdevice", pkt.st) == 0) {
|
else if(strcmp("upnp:rootdevice", pkt.st) == 0) {
|
||||||
UPNPDeviceType *dev = &this->deviceTypes[0];
|
UPNPDeviceType *dev = &this->deviceTypes[0];
|
||||||
#ifdef DEBUG_SSDP
|
#ifdef DEBUG_SSDP
|
||||||
this->_printPacket(&pkt);
|
|
||||||
DEBUG_SSDP.println("--------------- ROOT ---------------------");
|
DEBUG_SSDP.println("--------------- ROOT ---------------------");
|
||||||
|
this->_printPacket(&pkt);
|
||||||
#endif
|
#endif
|
||||||
if(pkt.type == MULTICAST)
|
if(pkt.type == MULTICAST)
|
||||||
this->_addToSendQueue(IPAddress(SSDP_MULTICAST_ADDR), SSDP_PORT, dev, pkt.st, pkt.mx, false);
|
this->_addToSendQueue(IPAddress(SSDP_MULTICAST_ADDR), SSDP_PORT, dev, pkt.st, response_types_t::root, pkt.mx);
|
||||||
else
|
else
|
||||||
this->_sendResponse(p.remoteIP(), p.remotePort(), dev, pkt.st, false);
|
this->_sendResponse(p.remoteIP(), p.remotePort(), dev, pkt.st, response_types_t::root);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
UPNPDeviceType *dev = nullptr;
|
UPNPDeviceType *dev = nullptr;
|
||||||
|
|
@ -749,18 +748,18 @@ void SSDPClass::_processRequest(AsyncUDPPacket &p) {
|
||||||
DEBUG_SSDP.println("-------------- ACCEPT --------------------");
|
DEBUG_SSDP.println("-------------- ACCEPT --------------------");
|
||||||
#endif
|
#endif
|
||||||
if(pkt.type == MULTICAST)
|
if(pkt.type == MULTICAST)
|
||||||
this->_addToSendQueue(IPAddress(SSDP_MULTICAST_ADDR), SSDP_PORT, dev, pkt.st, pkt.mx, useUUID);
|
this->_addToSendQueue(IPAddress(SSDP_MULTICAST_ADDR), SSDP_PORT, dev, pkt.st, useUUID ? response_types_t::uuid : response_types_t::root, pkt.mx);
|
||||||
else {
|
else {
|
||||||
this->_sendResponse(p.remoteIP(), p.remotePort(), dev, pkt.st, useUUID);
|
this->_sendResponse(p.remoteIP(), p.remotePort(), dev, pkt.st, useUUID ? response_types_t::uuid : response_types_t::root);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(pkt.method == SEARCH) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
void SSDPClass::loop() {
|
void SSDPClass::loop() {
|
||||||
this->_sendQueuedResponses();
|
this->_sendQueuedResponses();
|
||||||
|
// We need to send the notify if required.
|
||||||
|
this->_sendNotify();
|
||||||
}
|
}
|
||||||
void SSDPClass::schema(Print &client) {
|
void SSDPClass::schema(Print &client) {
|
||||||
IPAddress ip = this->localIP();
|
IPAddress ip = this->localIP();
|
||||||
|
|
@ -812,7 +811,7 @@ void SSDPClass::schema(Print &client) {
|
||||||
}
|
}
|
||||||
client.print(F("</deviceList></device></root>\r\n"));
|
client.print(F("</deviceList></device></root>\r\n"));
|
||||||
#ifdef DEBUG_SSDP
|
#ifdef DEBUG_SSDP
|
||||||
DEBUG_SSDP.println("Sending Device.xml");
|
DEBUG_SSDP.println("Sending upnp.xml");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
|
@ -836,7 +835,7 @@ void SSDPClass::setSchemaURL(uint8_t ndx, const char *url) { this->deviceTypes[
|
||||||
void SSDPClass::setUUID(uint8_t ndx, const char *uuid) { this->deviceTypes[ndx].setUUID(uuid); }
|
void SSDPClass::setUUID(uint8_t ndx, const char *uuid) { this->deviceTypes[ndx].setUUID(uuid); }
|
||||||
void SSDPClass::setUUID(uint8_t ndx, const char *prefix, uint32_t id) {
|
void SSDPClass::setUUID(uint8_t ndx, const char *prefix, uint32_t id) {
|
||||||
char svcuuid[50];
|
char svcuuid[50];
|
||||||
sprintf(svcuuid, "%s%02x%02x%02x",
|
sprintf(svcuuid, "%s%02X%02X%02X",
|
||||||
prefix,
|
prefix,
|
||||||
(uint16_t)((id >> 16) & 0xff),
|
(uint16_t)((id >> 16) & 0xff),
|
||||||
(uint16_t)((id >> 8) & 0xff),
|
(uint16_t)((id >> 8) & 0xff),
|
||||||
|
|
|
||||||
19
SSDP.h
19
SSDP.h
|
|
@ -7,14 +7,15 @@
|
||||||
#define SSDP_UUID_SIZE 42
|
#define SSDP_UUID_SIZE 42
|
||||||
#define SSDP_SCHEMA_URL_SIZE 64
|
#define SSDP_SCHEMA_URL_SIZE 64
|
||||||
#define SSDP_DEVICE_TYPE_SIZE 64
|
#define SSDP_DEVICE_TYPE_SIZE 64
|
||||||
#define SSDP_FRIENDLY_NAME_SIZE 64
|
|
||||||
#define SSDP_SERIAL_NUMBER_SIZE 37
|
#define SSDP_SERIAL_NUMBER_SIZE 37
|
||||||
#define SSDP_PRESENTATION_URL_SIZE 64
|
#define SSDP_PRESENTATION_URL_SIZE 64
|
||||||
#define SSDP_MODEL_NAME_SIZE 64
|
#define SSDP_MODEL_NAME_SIZE 64
|
||||||
#define SSDP_MODEL_URL_SIZE 64
|
#define SSDP_MODEL_URL_SIZE 64
|
||||||
#define SSDP_MODEL_VERSION_SIZE 32
|
#define SSDP_MODEL_VERSION_SIZE 32
|
||||||
#define SSDP_MANUFACTURER_SIZE 64
|
#define SSDP_MANUFACTURER_SIZE 64
|
||||||
|
#define SSDP_USN_SIZE 128
|
||||||
#define SSDP_MANUFACTURER_URL_SIZE 64
|
#define SSDP_MANUFACTURER_URL_SIZE 64
|
||||||
|
#define SSDP_FRIENDLY_NAME_SIZE 64
|
||||||
#define SSDP_INTERVAL_SECONDS 1800
|
#define SSDP_INTERVAL_SECONDS 1800
|
||||||
#define SSDP_MULTICAST_TTL 2
|
#define SSDP_MULTICAST_TTL 2
|
||||||
#define SSDP_HTTP_PORT 80
|
#define SSDP_HTTP_PORT 80
|
||||||
|
|
@ -29,6 +30,11 @@ typedef enum {
|
||||||
SEARCH,
|
SEARCH,
|
||||||
NOTIFY
|
NOTIFY
|
||||||
} ssdp_method_t;
|
} ssdp_method_t;
|
||||||
|
typedef enum {
|
||||||
|
root,
|
||||||
|
uuid,
|
||||||
|
deviceType
|
||||||
|
} response_types_t;
|
||||||
|
|
||||||
#define SSDP_FIELD_LEN 128
|
#define SSDP_FIELD_LEN 128
|
||||||
#define SSDP_LOCATION_LEN 256
|
#define SSDP_LOCATION_LEN 256
|
||||||
|
|
@ -53,7 +59,7 @@ struct ssdp_packet_t {
|
||||||
};
|
};
|
||||||
|
|
||||||
class UPNPDeviceType {
|
class UPNPDeviceType {
|
||||||
char m_usn[SSDP_MANUFACTURER_URL_SIZE];
|
char m_usn[SSDP_USN_SIZE];
|
||||||
public:
|
public:
|
||||||
UPNPDeviceType();
|
UPNPDeviceType();
|
||||||
UPNPDeviceType(const char *deviceType);
|
UPNPDeviceType(const char *deviceType);
|
||||||
|
|
@ -89,6 +95,7 @@ class UPNPDeviceType {
|
||||||
void setManufacturerURL(const char *url);
|
void setManufacturerURL(const char *url);
|
||||||
//char *getUSN();
|
//char *getUSN();
|
||||||
char *getUSN(const char *st);
|
char *getUSN(const char *st);
|
||||||
|
char *getUSN(response_types_t responseType);
|
||||||
void setChipId(uint32_t chipId);
|
void setChipId(uint32_t chipId);
|
||||||
};
|
};
|
||||||
struct ssdp_response_t {
|
struct ssdp_response_t {
|
||||||
|
|
@ -99,6 +106,7 @@ struct ssdp_response_t {
|
||||||
bool sendUUID;
|
bool sendUUID;
|
||||||
unsigned long sendTime;
|
unsigned long sendTime;
|
||||||
char st[SSDP_DEVICE_TYPE_SIZE];
|
char st[SSDP_DEVICE_TYPE_SIZE];
|
||||||
|
response_types_t responseType;
|
||||||
};
|
};
|
||||||
class SSDPClass {
|
class SSDPClass {
|
||||||
uint8_t m_cdeviceTypes = SSDP_CHILD_DEVICES + 1;
|
uint8_t m_cdeviceTypes = SSDP_CHILD_DEVICES + 1;
|
||||||
|
|
@ -118,7 +126,8 @@ class SSDPClass {
|
||||||
void _sendByeBye(UPNPDeviceType *d, bool root);
|
void _sendByeBye(UPNPDeviceType *d, bool root);
|
||||||
void _sendByeBye(const char *);
|
void _sendByeBye(const char *);
|
||||||
void _sendQueuedResponses();
|
void _sendQueuedResponses();
|
||||||
void _sendResponse(IPAddress addr, uint16_t port, UPNPDeviceType *d, char *st, bool sendUUID);
|
void _sendResponse(IPAddress addr, uint16_t port, UPNPDeviceType *d, const char *st, response_types_t responseType);
|
||||||
|
void _sendResponse(IPAddress addr, uint16_t port, const char *msg);
|
||||||
AsyncUDP _server;
|
AsyncUDP _server;
|
||||||
hw_timer_t* _timer = nullptr;
|
hw_timer_t* _timer = nullptr;
|
||||||
uint16_t _port = SSDP_HTTP_PORT;
|
uint16_t _port = SSDP_HTTP_PORT;
|
||||||
|
|
@ -128,7 +137,7 @@ class SSDPClass {
|
||||||
void _parsePacket(ssdp_packet_t *pkt, AsyncUDPPacket &p);
|
void _parsePacket(ssdp_packet_t *pkt, AsyncUDPPacket &p);
|
||||||
void _printPacket(ssdp_packet_t *pkt);
|
void _printPacket(ssdp_packet_t *pkt);
|
||||||
bool _startsWith(const char* pre, const char* str);
|
bool _startsWith(const char* pre, const char* str);
|
||||||
void _addToSendQueue(IPAddress addr, uint16_t port, UPNPDeviceType *d, char *st, uint8_t sec, bool sendUUID);
|
void _addToSendQueue(IPAddress addr, uint16_t port, UPNPDeviceType *d, const char *st, response_types_t responseType, uint8_t sec);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SSDPClass();
|
SSDPClass();
|
||||||
|
|
@ -138,6 +147,8 @@ class SSDPClass {
|
||||||
void loop();
|
void loop();
|
||||||
void end();
|
void end();
|
||||||
bool isStarted = false;
|
bool isStarted = false;
|
||||||
|
unsigned long bootId = 0;
|
||||||
|
int configId = 0;
|
||||||
IPAddress localIP();
|
IPAddress localIP();
|
||||||
UPNPDeviceType* getDeviceTypes(uint8_t ndx);
|
UPNPDeviceType* getDeviceTypes(uint8_t ndx);
|
||||||
UPNPDeviceType* getDeviceType(uint8_t ndx);
|
UPNPDeviceType* getDeviceType(uint8_t ndx);
|
||||||
|
|
|
||||||
|
|
@ -2702,6 +2702,7 @@ void SomfyShade::moveToTiltTarget(float target) {
|
||||||
else if(target > this->currentTiltPos)
|
else if(target > this->currentTiltPos)
|
||||||
cmd = somfy_commands::Down;
|
cmd = somfy_commands::Down;
|
||||||
if(target >= 0.0f && target <= 100.0f) {
|
if(target >= 0.0f && target <= 100.0f) {
|
||||||
|
// Only send a command if the lift is not moving.
|
||||||
if(this->currentPos == this->target || this->tiltType == tilt_types::tiltmotor) {
|
if(this->currentPos == this->target || this->tiltType == tilt_types::tiltmotor) {
|
||||||
if(cmd != somfy_commands::My) {
|
if(cmd != somfy_commands::My) {
|
||||||
Serial.print("Moving Tilt to ");
|
Serial.print("Moving Tilt to ");
|
||||||
|
|
@ -2712,12 +2713,12 @@ void SomfyShade::moveToTiltTarget(float target) {
|
||||||
Serial.println(translateSomfyCommand(cmd));
|
Serial.println(translateSomfyCommand(cmd));
|
||||||
SomfyRemote::sendCommand(cmd, this->tiltType == tilt_types::tiltmotor ? TILT_REPEATS : this->repeats);
|
SomfyRemote::sendCommand(cmd, this->tiltType == tilt_types::tiltmotor ? TILT_REPEATS : this->repeats);
|
||||||
}
|
}
|
||||||
else
|
// If the blind is currently moving then the command to stop it
|
||||||
SomfyRemote::sendCommand(cmd, this->repeats);
|
// will occur on its own when the tilt target is set.
|
||||||
}
|
}
|
||||||
this->p_tiltTarget(target);
|
this->p_tiltTarget(target);
|
||||||
}
|
}
|
||||||
this->settingTiltPos = true;
|
if(cmd != somfy_commands::My) this->settingTiltPos = true;
|
||||||
}
|
}
|
||||||
void SomfyShade::moveToTarget(float pos, float tilt) {
|
void SomfyShade::moveToTarget(float pos, float tilt) {
|
||||||
somfy_commands cmd = somfy_commands::My;
|
somfy_commands cmd = somfy_commands::My;
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -6,6 +6,13 @@
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* Timestamp class members
|
* Timestamp class members
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
|
unsigned long Timestamp::epoch() {
|
||||||
|
struct tm tmNow;
|
||||||
|
time_t now;
|
||||||
|
if(!getLocalTime(&tmNow)) return 0;
|
||||||
|
time(&now);
|
||||||
|
return now;
|
||||||
|
}
|
||||||
time_t Timestamp::now() {
|
time_t Timestamp::now() {
|
||||||
struct tm tmNow;
|
struct tm tmNow;
|
||||||
getLocalTime(&tmNow);
|
getLocalTime(&tmNow);
|
||||||
|
|
|
||||||
1
Utils.h
1
Utils.h
|
|
@ -63,6 +63,7 @@ class Timestamp {
|
||||||
static time_t mkUTCTime(struct tm *dt);
|
static time_t mkUTCTime(struct tm *dt);
|
||||||
static int calcTZOffset(time_t *dt);
|
static int calcTZOffset(time_t *dt);
|
||||||
static time_t now();
|
static time_t now();
|
||||||
|
static unsigned long epoch();
|
||||||
};
|
};
|
||||||
// Sort an array
|
// Sort an array
|
||||||
template<typename AnyType> void sortArray(AnyType array[], size_t sizeOfArray);
|
template<typename AnyType> void sortArray(AnyType array[], size_t sizeOfArray);
|
||||||
|
|
|
||||||
6
Web.cpp
6
Web.cpp
|
|
@ -1260,7 +1260,7 @@ void Web::begin() {
|
||||||
SomfyShade* shade = nullptr;
|
SomfyShade* shade = nullptr;
|
||||||
if (method == HTTP_POST || method == HTTP_PUT) {
|
if (method == HTTP_POST || method == HTTP_PUT) {
|
||||||
Serial.println("Adding a shade");
|
Serial.println("Adding a shade");
|
||||||
DynamicJsonDocument doc(512);
|
DynamicJsonDocument doc(1024);
|
||||||
DeserializationError err = deserializeJson(doc, server.arg("plain"));
|
DeserializationError err = deserializeJson(doc, server.arg("plain"));
|
||||||
if (err) {
|
if (err) {
|
||||||
switch (err.code()) {
|
switch (err.code()) {
|
||||||
|
|
@ -1285,7 +1285,7 @@ void Web::begin() {
|
||||||
Serial.println("Adding shade");
|
Serial.println("Adding shade");
|
||||||
shade = somfy.addShade(obj);
|
shade = somfy.addShade(obj);
|
||||||
if (shade) {
|
if (shade) {
|
||||||
DynamicJsonDocument sdoc(512);
|
DynamicJsonDocument sdoc(1024);
|
||||||
JsonObject sobj = sdoc.to<JsonObject>();
|
JsonObject sobj = sdoc.to<JsonObject>();
|
||||||
shade->toJSON(sobj);
|
shade->toJSON(sobj);
|
||||||
serializeJson(sdoc, g_content);
|
serializeJson(sdoc, g_content);
|
||||||
|
|
@ -1299,7 +1299,7 @@ void Web::begin() {
|
||||||
}
|
}
|
||||||
if (shade) {
|
if (shade) {
|
||||||
//Serial.println("Serializing shade");
|
//Serial.println("Serializing shade");
|
||||||
DynamicJsonDocument doc(256);
|
DynamicJsonDocument doc(1024);
|
||||||
JsonObject obj = doc.to<JsonObject>();
|
JsonObject obj = doc.to<JsonObject>();
|
||||||
shade->toJSON(obj);
|
shade->toJSON(obj);
|
||||||
serializeJson(doc, g_content);
|
serializeJson(doc, g_content);
|
||||||
|
|
|
||||||
|
|
@ -830,7 +830,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="divHomePnl" style="position:relative;">
|
<div id="divHomePnl" style="position:relative;">
|
||||||
<hr />
|
<hr />
|
||||||
<div id="divRoomSelector" class="room-selector" data-roomid="0" onclick="event.stopPropagation(); somfy.openSelectRoom();">
|
<div id="divRoomSelector" class="room-selector" style="display:none;" data-roomid="0" onclick="event.stopPropagation(); somfy.openSelectRoom();">
|
||||||
<i class="icss-bars"></i><span>Home</span>
|
<i class="icss-bars"></i><span>Home</span>
|
||||||
<div id="divRoomSelector-list" class="room-selector-list"></div>
|
<div id="divRoomSelector-list" class="room-selector-list"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -2181,8 +2181,7 @@ class Somfy {
|
||||||
_rooms.push(room);
|
_rooms.push(room);
|
||||||
divCtl += `<div class='room-row' data-roomid="${room.roomId}" onclick="somfy.selectRoom(${room.roomId});event.stopPropagation();">${room.name}</div>`;
|
divCtl += `<div class='room-row' data-roomid="${room.roomId}" onclick="somfy.selectRoom(${room.roomId});event.stopPropagation();">${room.name}</div>`;
|
||||||
}
|
}
|
||||||
if (rooms.length === 0) document.getElementById('divRoomSelector').style.display = 'none';
|
document.getElementById('divRoomSelector').style.display = rooms.length === 0 ? 'none' : '';
|
||||||
else document.getElementById('divRoomSelector').style.display = '';
|
|
||||||
document.getElementById('divRoomSelector-list').innerHTML = divCtl;
|
document.getElementById('divRoomSelector-list').innerHTML = divCtl;
|
||||||
document.getElementById('divRoomList').innerHTML = divCfg;
|
document.getElementById('divRoomList').innerHTML = divCfg;
|
||||||
document.getElementById('selShadeRoom').innerHTML = divOpts;
|
document.getElementById('selShadeRoom').innerHTML = divOpts;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue