Skip to content

Commit b879ded

Browse files
committed
tidy, fixes, self-test
1 parent b11cfea commit b879ded

File tree

7 files changed

+162
-42
lines changed

7 files changed

+162
-42
lines changed

openBeken_win32_mvsc2017.vcxproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -854,6 +854,7 @@
854854
<ClCompile Include="src\selftest\selftest_util_mqtt.c" />
855855
<ClCompile Include="src\selftest\selftest_util_mqtt_json.c" />
856856
<ClCompile Include="src\selftest\selftest_waitFor.c" />
857+
<ClCompile Include="src\selftest\selftest_wemo.c" />
857858
<ClCompile Include="src\selftest\selftest_ws2812b.c" />
858859
<ClCompile Include="src\sim\Circle.cpp" />
859860
<ClCompile Include="src\sim\Controller_BL0942.cpp" />

openBeken_win32_mvsc2017.vcxproj.filters

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@
290290
<ClCompile Include="src\selftest\selftest_util_mqtt.c" />
291291
<ClCompile Include="src\selftest\selftest_util_mqtt_json.c" />
292292
<ClCompile Include="src\selftest\selftest_waitFor.c" />
293+
<ClCompile Include="src\selftest\selftest_wemo.c" />
293294
<ClCompile Include="src\sim\Circle.cpp" />
294295
<ClCompile Include="src\sim\Controller_BL0942.cpp" />
295296
<ClCompile Include="src\sim\Controller_Bulb.cpp" />

src/driver/drv_ssdp.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,8 @@ void DRV_SSDP_RunQuickTick() {
522522
addLogAdv(LOG_EXTRADEBUG, LOG_FEATURE_HTTP,"Is MSEARCH - responding");
523523
#if ENABLE_DRIVER_WEMO
524524
if (DRV_IsRunning("WEMO")) {
525-
if (strcasestr(udp_msgbuf, "urn:belkin:device:**")) {
525+
if (strcasestr(udp_msgbuf, "urn:belkin:device:**")
526+
|| strcasestr(udp_msgbuf, "urn:belkin:device:controllee:1")) {
526527
DRV_WEMO_Send_Advert_To(1, &addr);
527528
return;
528529
}

src/driver/drv_wemo.c

Lines changed: 50 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
11
#include "../new_common.h"
22
#include "../new_pins.h"
33
#include "../new_cfg.h"
4-
// Commands register, execution API and cmd tokenizer
5-
#include "../cmnds/cmd_public.h"
6-
#include "../mqtt/new_mqtt.h"
74
#include "../logging/logging.h"
8-
#include "../hal/hal_pins.h"
95
#include "../hal/hal_wifi.h"
10-
#include "drv_public.h"
116
#include "drv_local.h"
127
#include "drv_ssdp.h"
138
#include "../httpserver/new_http.h"
@@ -222,26 +217,6 @@ static const char *WEMO_FindHeader(http_request_t *request, const char *namePref
222217
return 0;
223218
}
224219

225-
static void WEMO_PostXMLSafe(http_request_t *request, const char *s) {
226-
const char *p;
227-
if (!s) return;
228-
for (p = s; *p; p++) {
229-
switch (*p) {
230-
case '&': poststr(request, "&amp;"); break;
231-
case '<': poststr(request, "&lt;"); break;
232-
case '>': poststr(request, "&gt;"); break;
233-
case '"': poststr(request, "&quot;"); break;
234-
case '\'': poststr(request, "&apos;"); break;
235-
default: {
236-
char c[2];
237-
c[0] = *p;
238-
c[1] = 0;
239-
poststr(request, c);
240-
} break;
241-
}
242-
}
243-
}
244-
245220
static int WEMO_FindMainChannel(void) {
246221
int i;
247222
// Prefer a relay-type channel; fallback to toggle type.
@@ -341,17 +316,20 @@ void DRV_WEMO_Send_Advert_To(int mode, struct sockaddr_in *addr) {
341316
}
342317

343318
stat_searchesReceived++;
319+
if (buffer_out == 0) {
320+
outBufferLen = (int)strlen(g_wemo_msearch) + 256;
321+
buffer_out = (char*)malloc(outBufferLen);
322+
if (buffer_out == 0) {
323+
addLogAdv(LOG_ERROR, LOG_FEATURE_HTTP, "WEMO failed to allocate SSDP response buffer");
324+
return;
325+
}
326+
}
344327

345328
// mode is decided by SSDP driver (historically: 1=Belkin device wildcard, 0=rootdevice).
346329
// For compatibility, when asked for Belkin wildcard, also reply for explicit controllee.
347330
if (mode == 1) {
348331
// 1) urn:Belkin:device:**
349332
useType = "urn:Belkin:device:**";
350-
351-
if (buffer_out == 0) {
352-
outBufferLen = (int)strlen(g_wemo_msearch) + 256;
353-
buffer_out = (char*)malloc(outBufferLen);
354-
}
355333
snprintf(buffer_out, outBufferLen, g_wemo_msearch, HAL_GetMyIPString(), useType, g_uid, useType);
356334
DRV_SSDP_SendReply(addr, buffer_out);
357335

@@ -362,11 +340,6 @@ void DRV_WEMO_Send_Advert_To(int mode, struct sockaddr_in *addr) {
362340
}
363341
else {
364342
useType = "upnp:rootdevice";
365-
366-
if (buffer_out == 0) {
367-
outBufferLen = (int)strlen(g_wemo_msearch) + 256;
368-
buffer_out = (char*)malloc(outBufferLen);
369-
}
370343
snprintf(buffer_out, outBufferLen, g_wemo_msearch, HAL_GetMyIPString(), useType, g_uid, useType);
371344
DRV_SSDP_SendReply(addr, buffer_out);
372345
}
@@ -486,7 +459,7 @@ static int WEMO_Setup(http_request_t* request) {
486459
}
487460

488461
poststr(request, g_wemo_setup_1);
489-
WEMO_PostXMLSafe(request, fname);
462+
poststr_escaped(request, (char*)fname);
490463
poststr(request, g_wemo_setup_2);
491464
poststr(request, g_uid);
492465
poststr(request, g_wemo_setup_3);
@@ -502,18 +475,41 @@ static int WEMO_Setup(http_request_t* request) {
502475
}
503476

504477
void WEMO_Init() {
505-
// (Re)enable Wemo emulation.
506-
g_wemo_enabled = 1;
507478
char uid[64];
508479
char serial[32];
509480
unsigned char mac[8];
481+
char *newSerial;
482+
char *newUid;
510483

511484
WiFI_GetMacAddress((char*)mac);
512485
snprintf(serial, sizeof(serial), "201612%02X%02X%02X%02X", mac[2], mac[3], mac[4], mac[5]);
513486
snprintf(uid, sizeof(uid), "Socket-1_0-%s", serial);
514487

515-
g_serial = strdup(serial);
516-
g_uid = strdup(uid);
488+
newSerial = strdup(serial);
489+
newUid = strdup(uid);
490+
if (!newSerial || !newUid) {
491+
addLogAdv(LOG_ERROR, LOG_FEATURE_HTTP, "WEMO_Init failed to allocate identity strings");
492+
if (newSerial) {
493+
free(newSerial);
494+
}
495+
if (newUid) {
496+
free(newUid);
497+
}
498+
g_wemo_enabled = 0;
499+
return;
500+
}
501+
502+
if (g_serial) {
503+
free(g_serial);
504+
g_serial = 0;
505+
}
506+
if (g_uid) {
507+
free(g_uid);
508+
g_uid = 0;
509+
}
510+
g_serial = newSerial;
511+
g_uid = newUid;
512+
g_wemo_enabled = 1;
517513

518514
HTTP_RegisterCallback("/upnp/control/basicevent1", HTTP_POST, WEMO_BasicEvent1, 0);
519515
HTTP_RegisterCallback("/upnp/control/metainfo1", HTTP_POST, WEMO_MetaInfo1, 0);
@@ -524,6 +520,19 @@ void WEMO_Init() {
524520

525521
void WEMO_Shutdown(void) {
526522
// OpenBeken cannot unregister HTTP callbacks at runtime.
527-
// Disable responses/SSDP adverts without freeing identity strings (callbacks may still be hit).
523+
// Disable responses/SSDP adverts and free runtime buffers.
528524
g_wemo_enabled = 0;
525+
if (g_serial) {
526+
free(g_serial);
527+
g_serial = 0;
528+
}
529+
if (g_uid) {
530+
free(g_uid);
531+
g_uid = 0;
532+
}
533+
if (buffer_out) {
534+
free(buffer_out);
535+
buffer_out = 0;
536+
outBufferLen = 0;
537+
}
529538
}

src/selftest/selftest_local.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ void Test_MAX72XX();
152152
void Test_OpenWeatherMap();
153153
void Test_Shutters();
154154
void Test_Pins();
155+
void Test_Wemo();
155156

156157
void Test_GetJSONValue_Setup(const char *text);
157158
void Test_FakeHTTPClientPacket_GET(const char *tg);

src/selftest/selftest_wemo.c

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
#ifdef WINDOWS
2+
3+
#include "selftest_local.h"
4+
5+
static const char *g_wemo_set_state_on =
6+
"<?xml version=\"1.0\" encoding=\"utf-8\"?>"
7+
"<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">"
8+
"<s:Body>"
9+
"<u:SetBinaryState xmlns:u=\"urn:Belkin:service:basicevent:1\">"
10+
"<BinaryState>1</BinaryState>"
11+
"</u:SetBinaryState>"
12+
"</s:Body>"
13+
"</s:Envelope>";
14+
15+
static const char *g_wemo_set_state_off =
16+
"<?xml version=\"1.0\" encoding=\"utf-8\"?>"
17+
"<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">"
18+
"<s:Body>"
19+
"<u:SetBinaryState xmlns:u=\"urn:Belkin:service:basicevent:1\">"
20+
"<BinaryState>0</BinaryState>"
21+
"</u:SetBinaryState>"
22+
"</s:Body>"
23+
"</s:Envelope>";
24+
25+
static const char *g_wemo_get_state =
26+
"<?xml version=\"1.0\" encoding=\"utf-8\"?>"
27+
"<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">"
28+
"<s:Body>"
29+
"<u:GetBinaryState xmlns:u=\"urn:Belkin:service:basicevent:1\"/>"
30+
"</s:Body>"
31+
"</s:Envelope>";
32+
33+
static void Test_Wemo_RelaySetupAndSoap(void) {
34+
SIM_ClearOBK(0);
35+
36+
CFG_SetDeviceName("Fallback Device Name");
37+
PIN_SetPinRoleForPinIndex(7, IOR_Relay);
38+
PIN_SetPinChannelForPinIndex(7, 2);
39+
CHANNEL_SetLabel(2, "Kitchen & <Plug> \"Main\"", 1);
40+
CHANNEL_SetType(1, ChType_Toggle);
41+
CHANNEL_SetLabel(1, "ShouldNotBeChosen", 1);
42+
CMD_ExecuteCommand("startDriver Wemo", 0);
43+
44+
Test_FakeHTTPClientPacket_GET("setup.xml");
45+
SELFTEST_ASSERT_HTML_REPLY_CONTAINS("Kitchen &amp; &lt;Plug&gt; &quot;Main&quot;");
46+
SELFTEST_ASSERT_HTML_REPLY_NOT_CONTAINS("Fallback Device Name");
47+
SELFTEST_ASSERT_HTML_REPLY_NOT_CONTAINS("ShouldNotBeChosen");
48+
SELFTEST_ASSERT_HTML_REPLY_CONTAINS("<controlURL>/upnp/control/basicevent1</controlURL>");
49+
SELFTEST_ASSERT_HTML_REPLY_CONTAINS("<serviceType>urn:Belkin:service:metainfo:1</serviceType>");
50+
51+
Test_FakeHTTPClientPacket_POST("upnp/control/basicevent1", g_wemo_set_state_on);
52+
SELFTEST_ASSERT_CHANNEL(2, 1);
53+
SELFTEST_ASSERT_CHANNEL(1, 0);
54+
SELFTEST_ASSERT_HTML_REPLY_CONTAINS("<BinaryState>1</BinaryState>");
55+
56+
Test_FakeHTTPClientPacket_POST("upnp/control/basicevent1", g_wemo_get_state);
57+
SELFTEST_ASSERT_HTML_REPLY_CONTAINS("<u:GetBinaryStateResponse");
58+
SELFTEST_ASSERT_HTML_REPLY_CONTAINS("<BinaryState>1</BinaryState>");
59+
60+
Test_FakeHTTPClientPacket_POST("upnp/control/basicevent1", g_wemo_set_state_off);
61+
SELFTEST_ASSERT_CHANNEL(2, 0);
62+
SELFTEST_ASSERT_CHANNEL(1, 0);
63+
SELFTEST_ASSERT_HTML_REPLY_CONTAINS("<BinaryState>0</BinaryState>");
64+
65+
Test_FakeHTTPClientPacket_POST("upnp/control/metainfo1", g_wemo_get_state);
66+
SELFTEST_ASSERT_HTML_REPLY_CONTAINS("MetaInfoResponse");
67+
Test_FakeHTTPClientPacket_GET("eventservice.xml");
68+
SELFTEST_ASSERT_HTML_REPLY_CONTAINS("SetBinaryState");
69+
Test_FakeHTTPClientPacket_GET("metainfoservice.xml");
70+
SELFTEST_ASSERT_HTML_REPLY_CONTAINS("GetExtMetaInfo");
71+
}
72+
73+
static void Test_Wemo_ToggleFallbackAndRestart(void) {
74+
SIM_ClearOBK(0);
75+
76+
CFG_SetDeviceName("Toggle Device");
77+
CHANNEL_SetType(5, ChType_Toggle);
78+
CHANNEL_SetLabel(5, "Toggle Fallback", 1);
79+
CMD_ExecuteCommand("startDriver Wemo", 0);
80+
81+
Test_FakeHTTPClientPacket_GET("setup.xml");
82+
SELFTEST_ASSERT_HTML_REPLY_CONTAINS("Toggle Fallback");
83+
84+
Test_FakeHTTPClientPacket_POST("upnp/control/basicevent1", g_wemo_set_state_on);
85+
SELFTEST_ASSERT_CHANNEL(5, 1);
86+
SELFTEST_ASSERT_HTML_REPLY_CONTAINS("<BinaryState>1</BinaryState>");
87+
88+
CMD_ExecuteCommand("stopDriver Wemo", 0);
89+
Test_FakeHTTPClientPacket_GET("setup.xml");
90+
SELFTEST_ASSERT_HTML_REPLY_CONTAINS("\"error\":404");
91+
92+
CMD_ExecuteCommand("startDriver Wemo", 0);
93+
Test_FakeHTTPClientPacket_GET("setup.xml");
94+
SELFTEST_ASSERT_HTML_REPLY_CONTAINS("Toggle Fallback");
95+
96+
Test_FakeHTTPClientPacket_POST("upnp/control/basicevent1", g_wemo_set_state_off);
97+
SELFTEST_ASSERT_CHANNEL(5, 0);
98+
SELFTEST_ASSERT_HTML_REPLY_CONTAINS("<BinaryState>0</BinaryState>");
99+
}
100+
101+
void Test_Wemo() {
102+
Test_Wemo_RelaySetupAndSoap();
103+
Test_Wemo_ToggleFallbackAndRestart();
104+
}
105+
106+
#endif

src/win_main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ void Win_DoUnitTests()
301301
Test_Scripting();
302302
Test_Tokenizer();
303303
Test_Pins();
304+
Test_Wemo();
304305
Test_Http();
305306
Test_Http_LED();
306307
Test_DeviceGroups();

0 commit comments

Comments
 (0)