diff --git a/openBeken_win32_mvsc2017.vcxproj b/openBeken_win32_mvsc2017.vcxproj
index 484defb19..f043a7e96 100644
--- a/openBeken_win32_mvsc2017.vcxproj
+++ b/openBeken_win32_mvsc2017.vcxproj
@@ -330,6 +330,9 @@
true
+
+ true
+
true
diff --git a/openBeken_win32_mvsc2017.vcxproj.filters b/openBeken_win32_mvsc2017.vcxproj.filters
index 342ff933c..7414979df 100644
--- a/openBeken_win32_mvsc2017.vcxproj.filters
+++ b/openBeken_win32_mvsc2017.vcxproj.filters
@@ -483,6 +483,9 @@
SelfTest
+
+ Drv
+
diff --git a/src/driver/drv_local.h b/src/driver/drv_local.h
index 87416f72c..24c8a2639 100644
--- a/src/driver/drv_local.h
+++ b/src/driver/drv_local.h
@@ -80,3 +80,7 @@ void SHT3X_OnChannelChanged(int ch, int value);
void DRV_MAX72XX_Init();
+void WEMO_Init();
+void WEMO_AppendInformationToHTTPIndexPage(http_request_t* request);
+
+
diff --git a/src/driver/drv_main.c b/src/driver/drv_main.c
index d5e97aa3c..569245c96 100644
--- a/src/driver/drv_main.c
+++ b/src/driver/drv_main.c
@@ -101,6 +101,7 @@ static driver_t g_drivers[] = {
#if defined(PLATFORM_BEKEN) || defined(WINDOWS)
{ "DDP", DRV_DDP_Init, NULL, NULL, DRV_DDP_RunFrame, DRV_DDP_Shutdown, NULL, false },
{ "SSDP", DRV_SSDP_Init, DRV_SSDP_RunEverySecond, NULL, DRV_SSDP_RunQuickTick, DRV_SSDP_Shutdown, NULL, false },
+ { "Wemo", WEMO_Init, NULL, WEMO_AppendInformationToHTTPIndexPage, NULL, NULL, NULL, false },
{ "PWMToggler", DRV_InitPWMToggler, NULL, DRV_Toggler_AppendInformationToHTTPIndexPage, NULL, NULL, NULL, false },
{ "DGR", DRV_DGR_Init, DRV_DGR_RunEverySecond, NULL, DRV_DGR_RunQuickTick, DRV_DGR_Shutdown, DRV_DGR_OnChannelChanged, false },
#endif
diff --git a/src/driver/drv_ssdp.c b/src/driver/drv_ssdp.c
index d404841fc..571fe3a1b 100644
--- a/src/driver/drv_ssdp.c
+++ b/src/driver/drv_ssdp.c
@@ -230,15 +230,29 @@ static const char message_template[] =
/*"DATE: Sat, 22 Oct 2016 14:44:26 GMT\r\n"*/ \
;
+void DRV_WEMO_Send_Advert_To(struct sockaddr_in *addr);
+
+void DRV_SSDP_SendReply(struct sockaddr_in *addr, const char *message) {
-static void DRV_SSDP_Send_Advert_To(struct sockaddr_in *addr) {
int nbytes;
+ if (g_ssdp_socket_receive <= 0) {
+ addLogAdv(LOG_ERROR, LOG_FEATURE_HTTP, "DRV_SSDP_SendReply: no socket");
+ return;
+ }
+ // set up destination address
+ //
+ nbytes = sendto(
+ g_ssdp_socket_receive,
+ (const char*)advert_message,
+ strlen(advert_message),
+ 0,
+ (struct sockaddr*) addr,
+ sizeof(struct sockaddr)
+ );
+}
+static void DRV_SSDP_Send_Advert_To(struct sockaddr_in *addr) {
const char *myip = HAL_GetMyIPString();
- if (g_ssdp_socket_receive <= 0) {
- addLogAdv(LOG_ERROR, LOG_FEATURE_HTTP,"DRV_SSDP_Send_Advert_To: no socket");
- return ;
- }
if (!advert_message){
advert_maxlen = strlen(message_template) + 100;
@@ -250,16 +264,7 @@ static void DRV_SSDP_Send_Advert_To(struct sockaddr_in *addr) {
g_ssdp_uuid,
g_ssdp_uuid);
- // set up destination address
- //
- nbytes = sendto(
- g_ssdp_socket_receive,
- (const char*) advert_message,
- strlen(advert_message),
- 0,
- (struct sockaddr*) addr,
- sizeof(struct sockaddr)
- );
+ DRV_SSDP_SendReply(addr,advert_message);
addLogAdv(LOG_DEBUG, LOG_FEATURE_HTTP,"DRV_SSDP_Send_Advert_To: sent message");
}
@@ -513,7 +518,12 @@ void DRV_SSDP_RunQuickTick() {
if (!strncmp(udp_msgbuf, "M-SEARCH", 8)){
// reply with our advert to the sender
addLogAdv(LOG_EXTRADEBUG, LOG_FEATURE_HTTP,"Is MSEARCH - responding");
- DRV_SSDP_Send_Advert_To(&addr);
+ if (strstr(udp_msgbuf, "urn:belkin:device:**")) {
+ DRV_WEMO_Send_Advert_To(&addr);
+ }
+ else {
+ DRV_SSDP_Send_Advert_To(&addr);
+ }
}
// our NOTIFTY like:
diff --git a/src/driver/drv_ssdp.h b/src/driver/drv_ssdp.h
index 9c9fed49f..36f11a2db 100644
--- a/src/driver/drv_ssdp.h
+++ b/src/driver/drv_ssdp.h
@@ -1,7 +1,12 @@
-extern int DRV_SSDP_Active;
+int DRV_SSDP_Active;
+
+void DRV_SSDP_Init();
+void DRV_SSDP_RunEverySecond();
+void DRV_SSDP_RunQuickTick();
+void DRV_SSDP_Shutdown();
+void DRV_SSDP_SendReply(struct sockaddr_in *addr, const char *message);
+
+
+
-extern void DRV_SSDP_Init();
-extern void DRV_SSDP_RunEverySecond();
-extern void DRV_SSDP_RunQuickTick();
-extern void DRV_SSDP_Shutdown();
diff --git a/src/driver/drv_wemo.c b/src/driver/drv_wemo.c
new file mode 100644
index 000000000..39c6be42c
--- /dev/null
+++ b/src/driver/drv_wemo.c
@@ -0,0 +1,172 @@
+#include "../new_common.h"
+#include "../new_pins.h"
+#include "../new_cfg.h"
+// Commands register, execution API and cmd tokenizer
+#include "../cmnds/cmd_public.h"
+#include "../mqtt/new_mqtt.h"
+#include "../logging/logging.h"
+#include "../hal/hal_pins.h"
+#include "../hal/hal_wifi.h"
+#include "drv_public.h"
+#include "drv_local.h"
+#include "drv_ssdp.h"
+#include "../httpserver/new_http.h"
+
+
+static const char *g_wemo_setup_1 =
+""
+""
+""
+"urn:Belkin:device:controllee:1"
+"";
+static const char *g_wemo_setup_2 =
+""
+"Belkin International Inc."
+"Socket"
+"3.1415"
+"uuid:";
+static const char *g_wemo_setup_3 =
+""
+"";
+static const char *g_wemo_setup_4 =
+""
+"http://";
+static const char *g_wemo_setup_5 =
+":80/"
+"0";
+static const char *g_wemo_setup_6 =
+ ""
+ ""
+ "urn:Belkin:service:basicevent:1"
+ "urn:Belkin:serviceId:basicevent1"
+ "/upnp/control/basicevent1"
+ "/upnp/event/basicevent1"
+ "/eventservice.xml"
+ ""
+ ""
+ "urn:Belkin:service:metainfo:1"
+ "urn:Belkin:serviceId:metainfo1"
+ "/upnp/control/metainfo1"
+ "/upnp/event/metainfo1"
+ "/metainfoservice.xml"
+ ""
+ ""
+ ""
+"\r\n";
+
+const char *g_wemo_msearch =
+"HTTP/1.1 200 OK\r\n"
+"CACHE-CONTROL: max-age=86400\r\n"
+"DATE: Fri, 15 Apr 2016 04:56:29 GMT\r\n"
+"EXT:\r\n"
+"LOCATION: http://%s:80/setup.xml\r\n"
+"OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n"
+"01-NLS: b9200ebb-736d-4b93-bf03-835149d13983\r\n"
+"SERVER: Unspecified, UPnP/1.0, Unspecified\r\n"
+"ST: %s\r\n" // type1 = urn:Belkin:device:**, type2 = upnp:rootdevice
+"USN: uuid:%s::%s\r\n" // type1 = urn:Belkin:device:**, type2 = upnp:rootdevice
+"X-User-Agent: redsonic\r\n"
+"\r\n";
+static char *g_serial = 0;
+static char *g_uid = 0;
+static int outBufferLen = 0;
+static char *buffer_out = 0;
+static int stat_searchesReceived = 0;
+static int stat_setupXMLVisits = 0;
+static int stat_eventsReceived = 0;
+
+void DRV_WEMO_Send_Advert_To(struct sockaddr_in *addr) {
+ char message[128];
+ const char *useType;
+
+ if (g_uid == 0) {
+ // not running
+ return;
+ }
+
+ stat_searchesReceived++;
+
+ useType = "urn:Belkin:device:**";
+
+ if (buffer_out == 0) {
+ outBufferLen = strlen(g_wemo_msearch) + 256;
+ buffer_out = (char*)malloc(outBufferLen);
+ }
+ snprintf(buffer_out, outBufferLen, g_wemo_msearch, HAL_GetMyIPString(), useType, g_uid, useType);
+
+ DRV_SSDP_SendReply(addr, message);
+}
+
+void WEMO_AppendInformationToHTTPIndexPage(http_request_t* request) {
+ hprintf255(request, "WEMO: MSEARCH received %i, setup.xml visits %i, events %i
",
+ stat_searchesReceived, stat_setupXMLVisits, stat_eventsReceived);
+
+}
+static int WEMO_BasicEvent1(http_request_t* request) {
+ const char* cmd = request->bodystart;
+
+
+ addLogAdv(LOG_INFO, LOG_FEATURE_HTTP, "Wemo post event %s", cmd);
+
+ stat_eventsReceived++;
+
+ return 0;
+}
+static int WEMO_EventService(http_request_t* request) {
+
+ return 0;
+}
+static int WEMO_MetaInfoService(http_request_t* request) {
+
+ return 0;
+}
+static int WEMO_Setup(http_request_t* request) {
+ http_setup(request, httpMimeTypeXML);
+ poststr(request, g_wemo_setup_1);
+ // friendly name
+ poststr(request, CFG_GetDeviceName());
+ poststr(request, g_wemo_setup_2);
+ // uuid
+ poststr(request, g_uid);
+ poststr(request, g_wemo_setup_3);
+ // IP str
+ poststr(request, HAL_GetMyIPString());
+ poststr(request, g_wemo_setup_4);
+ // serial str
+ poststr(request, g_serial);
+ poststr(request, g_wemo_setup_5);
+ poststr(request, g_wemo_setup_6);
+ poststr(request, NULL);
+
+ stat_setupXMLVisits++;
+
+ return 0;
+}
+void WEMO_Init() {
+ char uid[64];
+ char serial[32];
+ unsigned char mac[8];
+
+ WiFI_GetMacAddress((char*)mac);
+ snprintf(serial, sizeof(serial), "201612%02X%02X%02X%02X", mac[2], mac[3], mac[4], mac[5]);
+ snprintf(uid, sizeof(uid), "Socket-1_0-%s", serial);
+
+ g_serial = strdup(serial);
+ g_uid = strdup(uid);
+
+ HTTP_RegisterCallback("/upnp/control/basicevent1", HTTP_POST, WEMO_BasicEvent1);
+ HTTP_RegisterCallback("/eventservice.xml", HTTP_GET, WEMO_EventService);
+ HTTP_RegisterCallback("/metainfoservice.xml", HTTP_GET, WEMO_MetaInfoService);
+ HTTP_RegisterCallback("/setup.xml", HTTP_GET, WEMO_Setup);
+
+ //if (DRV_IsRunning("SSDP") == false) {
+// ScheduleDriverStart("SSDP", 5);
+// }
+}
+
+
+
+
+
+
+
diff --git a/src/hal/win32/hal_wifi_win32.c b/src/hal/win32/hal_wifi_win32.c
index 8ea8f3f0c..bf4e4bec1 100644
--- a/src/hal/win32/hal_wifi_win32.c
+++ b/src/hal/win32/hal_wifi_win32.c
@@ -46,7 +46,12 @@ int WiFI_SetMacAddress(char *mac) {
}
void WiFI_GetMacAddress(char *mac) {
-
+ mac[0] = 0xBA;
+ mac[1] = 0xDA;
+ mac[2] = 0x31;
+ mac[3] = 0x45;
+ mac[4] = 0xCA;
+ mac[5] = 0xFF;
}
void HAL_PrintNetworkInfo() {
diff --git a/src/httpserver/new_http.c b/src/httpserver/new_http.c
index 8f283d49f..da1302567 100644
--- a/src/httpserver/new_http.c
+++ b/src/httpserver/new_http.c
@@ -17,6 +17,7 @@
const char httpHeader[] = "HTTP/1.1 %d OK\nContent-type: %s"; // HTTP header
const char httpMimeTypeHTML[] = "text/html"; // HTML MIME type
const char httpMimeTypeText[] = "text/plain"; // TEXT MIME type
+const char httpMimeTypeXML[] = "text/xml"; // TEXT MIME type
const char httpMimeTypeJson[] = "application/json"; // TEXT MIME type
const char httpMimeTypeBinary[] = "application/octet-stream"; // binary/file MIME type
@@ -81,12 +82,22 @@ static http_callback_t* callbacks[MAX_HTTP_CALLBACKS];
static int numCallbacks = 0;
int HTTP_RegisterCallback(const char* url, int method, http_callback_fn callback) {
+ int i;
+
if (!url || !callback) {
return -1;
}
if (numCallbacks >= MAX_HTTP_CALLBACKS) {
return -4;
}
+ for (i = 0; i < MAX_HTTP_CALLBACKS; i++) {
+ if (callbacks[i]) {
+ if (callbacks[i]->callback == callback && !strcmp(callbacks[i]->url, url)
+ && callbacks[i]->method == method) {
+ return i;
+ }
+ }
+ }
callbacks[numCallbacks] = (http_callback_t*)os_malloc(sizeof(http_callback_t));
if (!callbacks[numCallbacks]) {
return -2;
diff --git a/src/httpserver/new_http.h b/src/httpserver/new_http.h
index 21ecb2453..451b0dc57 100644
--- a/src/httpserver/new_http.h
+++ b/src/httpserver/new_http.h
@@ -7,6 +7,7 @@ extern const char httpMimeTypeHTML[]; // HTML MIME type
extern const char httpMimeTypeText[]; // TEXT MIME type
extern const char httpMimeTypeJson[];
extern const char httpMimeTypeBinary[];
+extern const char httpMimeTypeXML[];
extern const char htmlShortcutIcon[];
extern const char htmlDoctype[];
diff --git a/src/new_common.h b/src/new_common.h
index 781573243..4f0658cdf 100644
--- a/src/new_common.h
+++ b/src/new_common.h
@@ -427,6 +427,7 @@ extern int g_startPingWatchDogAfter;
typedef int(*jsonCb_t)(void *userData, const char *fmt, ...);
int JSON_ProcessCommandReply(const char *cmd, void *request, jsonCb_t printer, int flags);
+void ScheduleDriverStart(const char *name, int delay);
#endif /* __NEW_COMMON_H__ */
diff --git a/src/user_main.c b/src/user_main.c
index 5c6c664a2..c60299e00 100644
--- a/src/user_main.c
+++ b/src/user_main.c
@@ -171,7 +171,7 @@ int Time_getUpTimeSeconds() {
static char scheduledDriverName[4][16];
static int scheduledDelay[4] = {-1, -1, -1, -1};
-static void ScheduleDriverStart(const char *name, int delay) {
+void ScheduleDriverStart(const char *name, int delay) {
int i;
for (i = 0; i < 4; i++){
diff --git a/src/win_main.c b/src/win_main.c
index 0f794a629..d46072439 100644
--- a/src/win_main.c
+++ b/src/win_main.c
@@ -184,7 +184,7 @@ int g_bDoingUnitTestsNow = 0;
#include "sim/sim_public.h"
int __cdecl main(int argc, char **argv)
{
- bool bWantsUnitTests = true;
+ bool bWantsUnitTests = false;
if (argc > 1) {
int value;