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;