Merge pull request #8510 from s-hadinger/unishox_wemo_dev

Compressed string in Wemo emulation
This commit is contained in:
Theo Arends 2020-05-23 10:10:20 +02:00 committed by GitHub
commit 8db2489f59
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 195 additions and 21 deletions

View File

@ -388,9 +388,9 @@ uint32_t Unishox::getNextBit(void) {
in_eof = true;
return 1; // return only 1s, which appends 'r' in worst case
}
byte_in = in[byte_no++];
byte_in = pgm_read_byte(&in[byte_no++]);
if (ESCAPE_MARKER == byte_in) {
byte_in = in[byte_no++] - 1; // we shouldn't need to test if byte_no >= len, because it should not be possible to end with ESCAPE_MARKER
byte_in = pgm_read_byte(&in[byte_no++]) - 1; // we shouldn't need to test if byte_no >= len, because it should not be possible to end with ESCAPE_MARKER
}
bit_no = 0;
}
@ -479,6 +479,9 @@ int32_t Unishox::unishox_decompress(const char *p_in, size_t p_len, char *p_out,
out[ol] = 0;
// while ((byte_no << 3) + bit_no - 8 < len) {
while (!in_eof) {
if (ol >= len_out) {
break;
}
int32_t h, v;
char c = 0;
byte is_upper = is_all_upper;
@ -564,11 +567,11 @@ int32_t Unishox::unishox_decompress(const char *p_in, size_t p_len, char *p_out,
}
}
out[ol++] = c;
if (ol >= len_out) {
return -1; // overflow
}
}
return ol;
if (ol > len_out) {
return -1; // overflow
} else {
return ol;
}
}

View File

@ -1932,3 +1932,35 @@ String escapeJSONString(const char *str) {
return r;
}
/*********************************************************************************************\
* Uncompress static PROGMEM strings
\*********************************************************************************************/
#if defined(USE_RULES_COMPRESSION) || defined(USE_SCRIPT_COMPRESSION)
#include <unishox.h>
Unishox compressor;
String Decompress(const char * compressed, size_t uncompressed_size) {
String content("");
uncompressed_size += 2; // take a security margin
// We use a nasty trick here. To avoid allocating twice the buffer,
// we first extend the buffer of the String object to the target size (maybe overshooting by 7 bytes)
// then we decompress in this buffer,
// and finally assign the raw string to the String, which happens to work: String uses memmove(), so overlapping works
content.reserve(uncompressed_size);
char * buffer = content.begin();
int32_t len = compressor.unishox_decompress(compressed, strlen_P(compressed), buffer, uncompressed_size);
if (len > 0) {
buffer[len] = 0; // terminate string with NULL
content = buffer; // copy in place
}
return content;
}
#endif // defined(USE_RULES_COMPRESSION) || defined(USE_SCRIPT_COMPRESSION)

View File

@ -213,7 +213,7 @@ char rules_vars[MAX_RULE_VARS][33] = {{ 0 }};
#ifdef USE_RULES_COMPRESSION
// Statically allocate one String per rule
String k_rules[MAX_RULE_SETS] = { String(), String(), String() }; // Strings are created empty
Unishox compressor; // singleton
// Unishox compressor; // singleton
#endif // USE_RULES_COMPRESSION
// Returns whether the rule is uncompressed, which means the first byte is not NULL
@ -263,18 +263,7 @@ void GetRule_decompress(String &rule, const char *rule_head) {
size_t buf_len = 1 + *rule_head * 8; // the first byte contains size of buffer for uncompressed rule / 8, buf_len may overshoot by 7
rule_head++; // advance to the actual compressed buffer
// We use a nasty trick here. To avoid allocating twice the buffer,
// we first extend the buffer of the String object to the target size (maybe overshooting by 7 bytes)
// then we decompress in this buffer,
// and finally assign the raw string to the String, which happens to work: String uses memmove(), so overlapping works
rule.reserve(buf_len);
char* buf = rule.begin();
int32_t len_decompressed = compressor.unishox_decompress(rule_head, strlen(rule_head), buf, buf_len);
buf[len_decompressed] = 0; // add NULL terminator
// AddLog_P2(LOG_LEVEL_INFO, PSTR("RUL: Rawdecompressed: %d"), len_decompressed);
rule = buf; // assign the raw string to the String object (in reality re-writing the same data in the same place)
rule = Decompress(rule_head, buf_len);
}
#endif // USE_RULES_COMPRESSION

View File

@ -114,6 +114,29 @@ void HueRespondToMSearch(void)
* Hue web server additions
\*********************************************************************************************/
//<?xml version="1.0"?><root xmlns="urn:schemas-upnp-org:device-1-0"><specVersion><major>1</major><minor>0</minor></specVersion><URLBase>http://{x1:80/</URLBase><device><deviceType>urn:schemas-upnp-org:device:Basic:1</deviceType><friendlyName>Amazon-Echo-HA-Bridge ({x1)</friendlyName><manufacturer>Royal Philips Electronics</manufacturer><manufacturerURL>http://www.philips.com</manufacturerURL><modelDescription>Philips hue Personal Wireless Lighting</modelDescription><modelName>Philips hue bridge 2012</modelName><modelNumber>929000226503</modelNumber><serialNumber>{x3</serialNumber><UDN>uuid:{x2</UDN></device></root>\r\n\r\n
//Successfully compressed from 625 to 391 bytes (-37.4%)
// const size_t HUE_DESCRIPTION_XML_size = 625;
// const char HUE_DESCRIPTION_XML[] PROGMEM = "\x3D\x0E\xD1\xB0\x68\x48\xCD\xFF\xDB\x9C\x7C\x3D\x87\x21\xD1\x9E\xC3\xB4\x7E\x1E"
// "\x85\xFC\xCA\x46\xC1\xA1\x77\x8F\x87\xB0\x5F\xF8\xF3\xF0\x62\x98\xDB\xF1\xD6\x2C"
// "\x67\x0C\x3A\xF3\xE3\xC7\x98\x8C\xCF\x43\x67\x59\xC8\x75\xB3\xD8\x7E\x1E\x85\xE1"
// "\x8C\x32\x33\x04\x1C\x78\xFC\x3D\x06\xD9\xAF\x3E\x7E\x1C\x87\xA1\xD8\x40\x83\x14"
// "\xF4\x1B\xBD\x9F\x3F\x0E\x33\xD0\xEC\x20\x41\x8A\x7A\x1D\x80\x91\x85\x10\xB2\xF9"
// "\x04\x43\xAF\xCC\xFC\x15\x54\x30\xF3\x3B\x0E\xC3\xDA\x6C\x39\x0F\x3F\xB3\xB0\xF4"
// "\x3B\x08\x10\xEA\x1E\x80\x83\xA2\x82\x1C\x42\xA3\x21\x8C\xFC\x05\x6D\xB4\xF3\x21"
// "\xD7\xED\x0C\xF3\x39\x0F\x43\xB0\x81\x1B\x0C\x3D\x0C\x7F\x5F\x08\x11\x91\x75\x8D"
// "\x67\xE1\x58\xDB\x36\xE7\x1D\x64\xC3\x15\x87\x59\x0A\x2B\x3A\xC8\x77\xF4\x41\xE6"
// "\x8E\xE9\xED\x36\x1C\x87\x78\xF4\x3B\x08\x12\x30\x63\xD0\x6D\xF0\xB3\x16\x1D\x0B"
// "\xFB\xF9\xF8\x5F\xC3\x2B\x09\x10\xC1\x5A\x16\x8C\xF2\x26\x13\x0E\xBF\x9D\xA1\xF8"
// "\xF4\x3B\x01\x23\x04\x04\x8C\x48\x85\x97\xC8\x20\x43\xE0\xDC\x7C\x7C\x7C\xE8\x30"
// "\x10\x71\xA3\xA0\x78\x34\x12\x71\x22\x16\x5F\x20\x8F\xC3\xD0\x6E\x08\xC2\x21\x1F"
// "\x83\xFE\x8C\xAD\xCE\x3F\x01\x0F\x49\x14\x2D\xA2\x18\xFF\xEC\xEB\x09\x10\xFE\xFD"
// "\x84\xFD\xE4\x41\x68\xF0\xAA\xDE\x1E\x3D\x0E\xC0\x4C\xC5\x41\x07\x27\x2E\xB1\xAC"
// "\x12\x32\x01\xC0\x83\xC2\x41\xCA\x72\x88\x10\xB1\x10\x42\xE1\x13\x04\x61\x17\x0B"
// "\x1A\x39\xFC\xFC\x38\xA9\x36\xEA\xBB\x5D\x90\x21\xE0\x20\x83\x58\xF4\xF3\xFE\xD8"
// "\x21\xCA\x3D\xA6\xC3\x96\x7A\x1D\x84\x09\x13\x8F\x42\x16\x42\x17\x1F\x82\xC5\xE8"
// "\x87\x99\xED\x36\x1C\xA3\xD0\xEC\x22\x16\x42\x17\x1F\x80\x87\xC7\x19\xF8\x7A\x1D"
// "\x9F\xCC\xA3\xF2\x70\xA4\x6E\x9C\x29\x1B\x8D";
const char HUE_DESCRIPTION_XML[] PROGMEM =
"<?xml version=\"1.0\"?>"
"<root xmlns=\"urn:schemas-upnp-org:device-1-0\">"
@ -137,22 +160,59 @@ const char HUE_DESCRIPTION_XML[] PROGMEM =
"</device>"
"</root>\r\n"
"\r\n";
//%s"alert":"none","effect":"none","reachable":true}
//Successfully compressed from 50 to 34 bytes (-32%)
// const size_t HUE_LIGHTS_STATUS_JSON1_SUFFIX_size = 50;
// const char HUE_LIGHTS_STATUS_JSON1_SUFFIX[] PROGMEM = "\x3E\xBC\x7B\x2C\x27\xFA\x3D\x87\x99\xEC\xEC\xE6\x7B\x0E\xA3\xD8\xCC\x18\x61\x82"
// "\x34\xCF\xBB\x0C\x55\x8E\x09\x9E\xC3\xCE\xBE\x2D\x9E\xE3";
const char HUE_LIGHTS_STATUS_JSON1_SUFFIX[] PROGMEM =
"%s\"alert\":\"none\","
"\"effect\":\"none\","
"\"reachable\":true}";
//,"type":"Extended color light","name":"%s","modelid":"%s","manufacturername":"%s","uniqueid":"%s"}
//Successfully compressed from 98 to 64 bytes (-34.7%)
// const size_t HUE_LIGHTS_STATUS_JSON2_size = 98;
// const char HUE_LIGHTS_STATUS_JSON2[] PROGMEM = "\x3A\x8F\x65\x19\x0C\x67\xB0\xF3\x3D\x84\xCD\x94\xF8\x46\x22\x0F\x02\xCF\xA0\xB4"
// "\x78\x55\x1E\xC3\xA8\xF6\x75\x8D\x67\xB0\xF3\x3D\x87\xD7\x8F\x61\xD4\x7B\x06\xE0"
// "\x8C\x2D\x10\x11\x25\xDF\x0B\x31\x61\xD0\xBF\xBF\x82\x3E\x06\x2F\xB4\xD4\x2D\x82"
// "\x1E\x08\x7B\x8D";
const char HUE_LIGHTS_STATUS_JSON2[] PROGMEM =
",\"type\":\"Extended color light\","
"\"name\":\"%s\","
"\"modelid\":\"%s\","
"\"manufacturername\":\"%s\","
"\"uniqueid\":\"%s\"}";
//{"name":"Group 0","lights":[{l1],"type":"LightGroup","action":
//Successfully compressed from 62 to 61 bytes (-1.6%)
const char HUE_GROUP0_STATUS_JSON[] PROGMEM =
"{\"name\":\"Group 0\","
"\"lights\":[{l1],"
"\"type\":\"LightGroup\","
"\"action\":";
// "\"scene\":\"none\",";
//{"name":"Philips hue","mac":"{ma","dhcp":true,"ipaddress":"{ip","netmask":"{ms","gateway":"{gw","proxyaddress":"none","proxyport":0,"bridgeid":"{br","UTC":"{dt","whitelist":{"{id":{"last use date":"{dt","create date":"{dt","name":"Remote"}},"swversion":"01041302","apiversion":"1.17.0","swupdate":{"updatestate":0,"url":"","text":"","notify": false},"linkbutton":false,"portalservices":false}
//Successfully compressed from 392 to 302 bytes (-23%)
// const size_t HueConfigResponse_JSON_size = 392;
// const char HueConfigResponse_JSON[] PROGMEM = "\x3D\xA7\xB3\xAC\x6B\x3D\x87\x99\xEC\x21\x82\xB4\x2D\x19\xE4\x28\x5B\x3D\x87\x51"
// "\xEC\x1B\x61\x9E\xC3\xCC\xF6\x1E\xD1\xB6\x7B\x0E\xA3\xD8\x20\xA0\xC6\x1E\xC3\xCE"
// "\xBE\x2D\x9D\x47\xB3\x46\x58\x82\x7D\xFB\xC7\xB0\xF3\x3D\x87\xB7\x46\x1E\xC3\xA8"
// "\xF6\x73\xA1\xB7\xE3\x43\xD8\x79\x9E\xC3\xDA\x37\xC7\xB0\xEA\x3D\x83\xD7\x4C\x7E"
// "\xCC\x8F\x61\xE6\x7B\x0F\x68\xF0\xF9\xEC\x3A\x8F\x60\xCF\xE1\xB0\xC8\x11\x71\x1E"
// "\xCE\x60\x87\x48\x66\x7E\x8F\x61\xE6\x71\x9D\x47\xB0\x87\x7F\x44\x1E\x7A\x21\xEC"
// "\x3C\xCF\x61\xED\x1D\xF3\xD8\x75\x1E\xC2\x16\x54\x41\x9E\xC3\xCC\xF6\x1E\xD1\x28"
// "\xF6\x1D\x47\xB0\x7C\x56\xD3\x0B\x7D\x47\xB0\xF3\x3D\xA7\xB0\xF6\xE8\x87\xB0\xF3"
// "\x3D\xA7\xB0\x2B\xF5\x21\x7E\x68\x4B\xA6\x08\x98\x30\x7F\x77\x40\x95\x40\x10\xB8"
// "\x3A\x2F\xB1\xB9\x4C\xF6\x1E\xE3\xDC\x75\x1E\xCF\x0F\x99\xBF\xFB\x73\x8F\x61\xE6"
// "\x7B\x0E\x38\xF2\x5B\xA3\xD8\x75\x1E\xC2\xB1\x9A\x08\xB5\x0E\x43\xA4\xF1\xD1\x9E"
// "\xC3\xA8\xF6\x17\x87\xC5\x8C\x04\x1C\xB0\xF6\x9E\xC0\x41\x8D\xEA\xBA\x67\xB0\xF3"
// "\x38\xCE\xA3\xD8\x42\xFE\x11\xEC\x3C\xCF\x61\xEC\x3A\x8F\x65\x33\x65\x02\x0C\x6E"
// "\xCA\xD3\x06\x47\xB0\xF3\x46\x2C\x2F\x33\xDC\x75\x1E\xC0\xB7\x8D\x07\x0B\xAA\xCE"
// "\x3D\x87\x99\x8B\x0B\xCC\xEA\x3D\x83\x33\xF5\x61\x79\xFC\xCF\x43\x7E\x04\x2A\x2B"
// "\x67\xB8";
const char HueConfigResponse_JSON[] PROGMEM =
"{\"name\":\"Philips hue\","
"\"mac\":\"{ma\","

View File

@ -85,6 +85,79 @@ void WemoRespondToMSearch(int echo_type)
* Wemo web server additions
\*********************************************************************************************/
#if defined(USE_RULES_COMPRESSION) || defined(USE_SCRIPT_COMPRESSION)
//<scpd xmlns="urn:Belkin:service-1-0"><actionList><action><name>SetBinaryState</name><argumentList><argument><retval/><name>BinaryState</name><relatedStateVariable>BinaryState</relatedStateVariable><direction>in</direction></argument></argumentList></action><action><name>GetBinaryState</name><argumentList><argument><retval/><name>BinaryState</name><relatedStateVariable>BinaryState</relatedStateVariable><direction>out</direction></argument></argumentList></action></actionList><serviceStateTable><stateVariable sendEvents="yes"><name>BinaryState</name><dataType>bool</dataType><defaultValue>0</defaultValue></stateVariable><stateVariable sendEvents="yes"><name>level</name><dataType>string</dataType><defaultValue>0</defaultValue></stateVariable></serviceStateTable></scpd>\r\n\r\n
//Successfully compressed from 779 to 249 bytes (-68%)
const size_t WEMO_EVENTSERVICE_XML_SIZE = 779;
const char WEMO_EVENTSERVICE_XML[] PROGMEM = "\x3D\x3C\x18\xC1\x11\xB0\x68\x5D\xE3\xE1\xEC\x17\xFE\x3C\xC8\x73\x08\xD3\x78\xF3"
"\xF3\xF9\x9E\x86\xCE\xB3\x90\xEB\x67\xB0\xFC\x3D\x0A\xC3\xAD\xCE\x20\xB7\xD4\x08"
"\x72\x0F\xC3\xD3\xAC\x6B\x3F\x0B\xCE\x88\x76\xF5\xFC\xC8\xBD\x57\x4C\xF4\x3B\x3A"
"\xC6\xB3\xF0\xF4\xBF\x8F\x0B\x1A\xFA\x81\x0B\x0D\x04\x29\x47\xE1\xE9\xF7\x46\x76"
"\x11\xD8\x08\x58\xC0\x27\x62\xBF\x61\x5D\x31\x0B\xD5\x74\xC8\xCE\xFF\xB6\x38\x20"
"\x4A\xC1\x01\x42\xF1\xE8\x26\xFD\x82\x0E\xE7\xBC\x7A\x1D\x80\x8B\x28\xF4\x3B\x01"
"\x17\x59\x04\x48\xE0\x83\xB9\x1D\x80\x87\xC1\x20\x24\x70\x58\x43\xC0\xDA\xF8\x2C"
"\xC1\x74\x0C\x2F\x82\xD0\x42\x8A\x08\x34\x81\x0B\x92\x42\xF5\x5D\x32\xA0\x41\xCE"
"\x7C\x08\xFA\x42\xF3\xE1\x09\x99\xBE\xAF\x1F\x0F\x61\x93\xF1\xEC\x05\x5E\x0A\x44"
"\xBA\xB2\xA3\x21\x8C\xFC\x1D\x98\x11\xE8\x76\x02\x24\xB3\xD0\x46\x62\xC5\x85\x44"
"\x67\x61\x0B\x67\xE1\xC6\x7A\x1D\x84\x09\x13\x0F\x43\xB0\x12\x34\xC0\x60\x5A\xD8"
"\x4C\xCD\x84\x09\x9A\xAF\xAB\xFB\xC3\xC0\xC5\x75\x73\xB0\x13\xB8\x6A\x3B\x3C\x18"
"\xC1\x0F\xC9\xC2\x91\xBA\x70\xA4\x6E";
//<scpd xmlns="urn:Belkin:service-1-0"><specVersion><major>1</major><minor>0</minor></specVersion><actionList><action><name>GetMetaInfo</name><argumentList><retval /><name>GetMetaInfo</name><relatedStateVariable>MetaInfo</relatedStateVariable><direction>in</direction></argumentList></action></actionList><serviceStateTable><stateVariable sendEvents="yes"><name>MetaInfo</name><dataType>string</dataType><defaultValue>0</defaultValue></stateVariable></serviceStateTable></scpd>\r\n\r\n
//Successfully compressed from 479 to 253 bytes (-47.2%)
const size_t WEMO_METASERVICE_XML_SIZE = 479;
const char WEMO_METASERVICE_XML[] PROGMEM = "\x3D\x3C\x18\xC1\x11\xB0\x68\x5D\xE3\xE1\xEC\x17\xFE\x3C\xC8\x73\x08\xD3\x78\xF3"
"\xF3\xF9\x9E\x86\xCE\xB3\x90\xEB\x67\xB0\xFC\x3D\x0B\xC3\x18\x64\x66\xFF\xED\xCE"
"\x3F\x0F\x41\xB6\x6B\xCF\x9F\x87\x21\xE8\x76\x10\x20\xC5\x3D\x06\xEF\x67\xCF\xC3"
"\x8C\xF4\x3B\x08\x10\x62\x9E\x87\x60\x24\x61\x56\x1D\x6E\x71\x05\xBE\xA0\x43\x90"
"\x7E\x1E\x9D\x63\x59\xF8\x43\xCE\x88\x6B\xAB\x2D\xE3\x18\x7A\x1D\x9D\x63\x59\xF8"
"\x7A\x5F\xC7\x85\x8D\x7D\x40\x83\x85\x7D\xD1\x9D\x84\x8E\xC0\x55\xC3\x3E\xC2\xBA"
"\x62\x17\xAA\xE9\x91\x9D\xFF\x6C\x70\x4C\xFC\x04\x5C\x04\x14\x2D\x9E\x82\x6F\xD8"
"\x20\xEC\x9B\xC7\xA1\xD8\x08\xB2\x8F\x43\xB0\x12\x75\xB3\xB0\x10\xF8\x0A\x04\x28"
"\xA0\x83\x48\x10\xB8\x74\x2F\x55\xD3\x2A\x2B\x04\x1C\xB7\xC0\x8F\x9E\x2F\x3E\x10"
"\x99\x9B\xEA\xF1\xF0\xF6\x19\x3F\x1E\xC0\x42\xE0\x68\x12\xF8\x17\x12\xEA\xCA\x8C"
"\x86\x33\xF3\xD5\xFD\xE1\xE3\xD0\xEC\x04\x49\xA7\xA0\x8C\xC5\x8B\x0A\x88\xCE\xC2"
"\x16\xCF\xC3\x8C\xF4\x3B\x08\x12\x26\x1E\x87\x60\x24\x69\x67\xE1\xE8\x76\x02\x76"
"\xDC\x76\x78\x31\x82\x1F\x93\x85\x23\x74\xE1\x48\xDC";
//<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:%cetBinaryStateResponse xmlns:u="urn:Belkin:service:basicevent:1"><BinaryState>%d</BinaryState></u:%cetBinaryStateResponse></s:Body></s:Envelope>\r\n
//Successfully compressed from 282 to 161 bytes (-42.9%)
const size_t WEMO_RESPONSE_STATE_SOAP_SIZE = 282;
const char WEMO_RESPONSE_STATE_SOAP[] PROGMEM = "\x3D\x3C\x79\x93\xE3\x36\x16\x0C\x68\xD8\x34\x2E\xF1\xE7\xE3\xE1\xEC\x15\x54\x30"
"\xF3\x3B\x0E\xCF\x06\x29\x8D\xBF\x1D\x0D\x83\x42\xF6\x58\xC3\xA6\x7C\x78\xEC\xF6"
"\x58\xC3\xB1\x82\x16\x1C\x76\x1E\xC5\xE3\xCD\xF0\x78\x26\xF0\xF1\x7A\x8C\x82\x60"
"\xBF\x8C\x02\x0E\x16\x76\x1E\xC3\xF0\xF4\xF1\xE6\x43\xB0\x43\x23\xF0\xF4\x16\x79"
"\x9F\x41\xBA\x21\xDB\xD7\xF3\x22\xF5\x5D\x32\xFB\xF0\xCC\xEF\x02\x1E\xDE\x2C\xF8"
"\x7B\x05\xFF\x8F\x32\x1C\xC2\x34\xDE\x3C\xFC\xFE\x67\xA1\xB3\xCC\x75\xFB\x43\x66"
"\x6F\xA8\xF3\x39\x0F\x61\xF8\x7A\x10\x23\x63\x67\xE1\xF4\x21\xE8\x76\x02\x3C\xC3"
"\xD0\xEC\x05\x4C\xFC\xFC\x3D\x0E\xC0\x43\xD8\xCE\xC0\x45\xE1\xA0\xFC\x9C\x29\x1B"
"\x8D";
//<?xml version="1.0"?><root xmlns="urn:Belkin:device-1-0"><device><deviceType>urn:Belkin:device:controllee:1</deviceType><friendlyName>{x1</friendlyName><manufacturer>Belkin International Inc.</manufacturer><modelName>Socket</modelName><modelNumber>3.1415</modelNumber><UDN>uuid:{x2</UDN><serialNumber>{x3</serialNumber><binaryState>0</binaryState><serviceList><service><serviceType>urn:Belkin:service:basicevent:1</serviceType><serviceId>urn:Belkin:serviceId:basicevent1</serviceId><controlURL>/upnp/control/basicevent1</controlURL><eventSubURL>/upnp/event/basicevent1</eventSubURL><SCPDURL>/eventservice.xml</SCPDURL></service><service><serviceType>urn:Belkin:service:metainfo:1</serviceType><serviceId>urn:Belkin:serviceId:metainfo1</serviceId><controlURL>/upnp/control/metainfo1</controlURL><eventSubURL>/upnp/event/metainfo1</eventSubURL><SCPDURL>/metainfoservice.xml</SCPDURL></service></serviceList></device></root>\r\n
//Successfully compressed from 923 to 392 bytes (-57.5%)
const size_t WEMO_SETUP_XML_SIZE = 923;
const char WEMO_SETUP_XML[] PROGMEM = "\x3D\x0E\xD1\xB0\x68\x48\xCD\xFF\xDB\x9C\x7C\x3D\x87\x21\xD1\x9E\xC3\xB4\x7E\x1E"
"\x85\xFC\xCA\x46\xC1\xA1\x77\x8F\x87\xB0\x5F\xF8\xF3\x21\xCC\x23\x4D\xE3\xCC\x46"
"\x67\xA1\xB3\xAC\xE4\x3A\xD9\xEC\x3F\x0F\x42\x04\x19\x20\x87\x10\xA8\xC8\x63\x3F"
"\x01\x33\x07\x3C\xC3\xCE\xAF\xE0\x41\x36\x79\x9C\x87\xA1\xD8\x40\x8D\x83\x9E\x86"
"\x3F\xAF\x84\x08\xC8\xBA\xC6\xB3\xF0\xF6\x9B\x0E\x43\xD0\xEC\x20\x48\x9C\x7A\x0D"
"\xBE\x16\x62\xC3\xA1\x7F\x7F\x3F\x01\x07\x31\x45\xBD\x4F\xFD\x75\xB9\xD6\x12\x2D"
"\xE0\xCE\x87\xA1\xD8\x09\x18\x21\xE8\x37\x04\x61\x17\x58\xD6\x7E\x17\xB0\x33\x47"
"\x47\xA1\xD8\x08\xB3\x81\x0A\xC8\xB1\xA3\x9F\xCF\xC3\x96\x74\x99\x34\x81\x0E\xD8"
"\x20\xD0\x3D\x08\x59\x08\x5C\x7E\x0B\x17\xA2\x1E\x67\xB4\xD8\x72\x8F\x43\xB0\x88"
"\x59\x08\x5C\x7E\x1E\x9E\x7F\xDB\x04\x3B\xA7\xB4\xD8\x72\xCF\x43\xB0\x81\x22\x71"
"\xE8\x3B\x7A\xFE\x64\x5E\xAB\xA6\x7E\x1C\x67\xA1\xD8\x40\x8F\x2C\xF4\xF3\xF9\x9E"
"\x86\xC8\x2D\xF5\x02\x24\x90\x44\x8A\x09\x7C\x46\x82\x15\x33\xCC\x75\xFB\x43\x66"
"\x6F\xA8\xF3\x39\x0F\x43\xB0\x81\x1F\x09\x04\x3C\x58\xB4\x40\x4E\xC5\x0B\x44\x04"
"\x6C\x58\x11\x71\x52\xD1\x0F\xC3\xD0\x10\xB8\xE0\x21\x65\xF2\x08\xFC\x3B\x05\x8C"
"\xE1\x87\x60\x21\x4D\x3B\x01\x23\x0D\x04\x6C\x08\xF4\x66\x6F\xA8\xBC\x2C\x70\x22"
"\xE1\xEC\xCD\xF5\x02\x4E\x1A\x08\xF8\x09\xE8\x45\xE0\xC6\x08\x2F\xE1\x11\xF8\x08"
"\x34\x81\x0B\x59\x3A\x1B\x06\x84\x7A\x1D\x80\x87\x5C\x11\x37\x2A\x01\x60\xBC\x34"
"\x0D\x75\x7B\xC6\x30\x18\x5F\x0C\xC0\x87\x8A\x03\x02\xE1\x90\x11\xB0\xB0\x5F\xE1"
"\x88\x11\xB0\xB0\x51\xE1\x80\x10\xEE\x82\xDF\x0C\x60\x87\x18\x10\x79\x7D\x04\x2E"
"\x83\xD1\xF8\x7A\x1D\x9F\xCC\xA3\xF2\x70\xA4\x6E";
#else
const char WEMO_EVENTSERVICE_XML[] PROGMEM =
"<scpd xmlns=\"urn:Belkin:service-1-0\">"
"<actionList>"
@ -190,6 +263,7 @@ const char WEMO_SETUP_XML[] PROGMEM =
"</serviceList>"
"</device>"
"</root>\r\n";
#endif
/********************************************************************************************/
@ -219,7 +293,11 @@ void HandleUpnpEvent(void)
}
}
#if defined(USE_RULES_COMPRESSION) || defined(USE_SCRIPT_COMPRESSION)
snprintf_P(event, sizeof(event), Decompress(WEMO_RESPONSE_STATE_SOAP, WEMO_RESPONSE_STATE_SOAP_SIZE).c_str(), state, bitRead(power, devices_present -1), state);
#else
snprintf_P(event, sizeof(event), WEMO_RESPONSE_STATE_SOAP, state, bitRead(power, devices_present -1), state);
#endif
WSSend(200, CT_XML, event);
}
@ -227,21 +305,33 @@ void HandleUpnpService(void)
{
AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_EVENT_SERVICE));
#if defined(USE_RULES_COMPRESSION) || defined(USE_SCRIPT_COMPRESSION)
WSSend(200, CT_PLAIN, Decompress(WEMO_EVENTSERVICE_XML, WEMO_EVENTSERVICE_XML_SIZE));
#else
WSSend(200, CT_PLAIN, FPSTR(WEMO_EVENTSERVICE_XML));
#endif
}
void HandleUpnpMetaService(void)
{
AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_META_SERVICE));
#if defined(USE_RULES_COMPRESSION) || defined(USE_SCRIPT_COMPRESSION)
WSSend(200, CT_PLAIN, Decompress(WEMO_METASERVICE_XML, WEMO_METASERVICE_XML_SIZE));
#else
WSSend(200, CT_PLAIN, FPSTR(WEMO_METASERVICE_XML));
#endif
}
void HandleUpnpSetupWemo(void)
{
AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_SETUP));
#if defined(USE_RULES_COMPRESSION) || defined(USE_SCRIPT_COMPRESSION)
String setup_xml = Decompress(WEMO_SETUP_XML, WEMO_SETUP_XML_SIZE);
#else
String setup_xml = FPSTR(WEMO_SETUP_XML);
#endif
setup_xml.replace("{x1", SettingsText(SET_FRIENDLYNAME1));
setup_xml.replace("{x2", WemoUuid());
setup_xml.replace("{x3", WemoSerialnumber());