Skip to content

Commit b2f2fa9

Browse files
committed
- Additional device network options for powering on via WOL
1 parent 090d7e9 commit b2f2fa9

8 files changed

Lines changed: 233 additions & 26 deletions

File tree

LGTV Companion Service/Service.cpp

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -695,46 +695,53 @@ void InitDeviceSessions()
695695
json j;
696696
if (item.key() == JSON_PREFS_NODE)
697697
break;
698-
string s;
698+
stringstream s;
699699

700700
SESSIONPARAMETERS params;
701701

702702
params.DeviceId = item.key();
703-
s += params.DeviceId; s += ", ";
703+
s << params.DeviceId << ", ";
704704
if (item.value()["Name"].is_string())
705705
params.Name = item.value()["Name"].get<string>();
706-
s += params.Name;
707-
s += ", with IP ";
706+
s << params.Name << ", with IP ";
707+
708708
if(item.value()["IP"].is_string())
709709
params.IP = item.value()["IP"].get<string>();
710-
s += params.IP; s += " initiated (";
711-
710+
s << params.IP << " initiated (";
711+
712712
if (item.value()["Enabled"].is_boolean())
713713
params.Enabled = item.value()["Enabled"].get<bool>();
714-
s += "Enabled:"; s += params.Enabled ? "yes" : "no"; s += ", ";
715-
714+
s << "Enabled:" << (params.Enabled?"yes":"no") << ", ";
715+
716+
if (item.value()["Subnet"].is_string())
717+
params.Subnet = item.value()["Subnet"].get<string>();
718+
if (item.value()["WOL"].is_number())
719+
params.WOLtype = item.value()["WOL"].get<int>();
720+
s << "WOL:" << params.WOLtype << ", ";
721+
if (params.WOLtype == WOL_SUBNETBROADCAST && params.Subnet != "")
722+
s << "SubnetMask:" << params.Subnet << ", ";
716723
if(item.value()["SessionKey"].is_string())
717724
params.SessionKey = item.value()["SessionKey"].get<string>();
718-
s += "Pairing key:"; s += params.SessionKey =="" ? "n/a" : params.SessionKey; s += ", MAC: ";
725+
s << "Pairing key:" << (params.SessionKey =="" ? "n/a" : params.SessionKey) << ", MAC: ";
719726

720727
j = item.value()["MAC"];
721728
if (!j.empty() && j.size() > 0)
722729
{
723730
for (auto& m : j.items())
724731
{
725732
params.MAC.push_back(m.value().get<string>());
726-
s += m.value().get<string>(); s += " ";
733+
s << m.value().get<string>()<< " ";
727734
}
728-
s += ")";
735+
s << ")";
729736
}
730737
else
731-
s += "n/a )";
738+
s << "n/a )";
732739

733740
params.PowerOnTimeout = Prefs.PowerOnTimeout;
734741

735742
CSession S(&params);
736743
DeviceCtrlSessions.push_back(S);
737-
Log(s);
744+
Log(s.str());
738745
}
739746
return;
740747
}

LGTV Companion Service/Service.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <AccCtrl.h>
2222
#include <sddl.h>
2323
#include <Aclapi.h>
24+
#include <WinSock2.h>
2425

2526
#include "nlohmann/json.hpp"
2627
#include "Handshake.h"
@@ -31,7 +32,7 @@
3132
#pragma comment(lib, "Advapi32.lib")
3233

3334
#define APPNAME L"LGTV Companion"
34-
#define APPVERSION L"1.3.0"
35+
#define APPVERSION L"1.4.0"
3536
#define SVCNAME L"LGTVsvc"
3637
#define SVCDISPLAYNAME L"LGTV Companion Service"
3738
#define SERVICE_PORT "3000"
@@ -65,6 +66,13 @@
6566
#define APP_CMDLINE_AUTOENABLE 3
6667
#define APP_CMDLINE_AUTODISABLE 4
6768

69+
#define WOL_NETWORKBROADCAST 1
70+
#define WOL_IPSEND 2
71+
#define WOL_SUBNETBROADCAST 3
72+
73+
#define WOL_DEFAULTSUBNET L"255.255.255.0"
74+
75+
6876
#define PIPENAME TEXT("\\\\.\\pipe\\LGTVyolo")
6977

7078

@@ -92,6 +100,8 @@ struct SESSIONPARAMETERS {
92100
int PowerOnTimeout = 40;
93101
std::string Name;
94102
bool Enabled = true;
103+
std::string Subnet;
104+
int WOLtype = 1;
95105
};
96106

97107
class CSession {

LGTV Companion Service/Session.cpp

Lines changed: 83 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ void DisplayPowerOnThread(SESSIONPARAMETERS * CallingSessionParameters, bool * C
199199
handshake.replace(ckf, ck.length(), key);
200200
}
201201

202-
//try waking up the display ten times
202+
//try waking up the display ten times, but not longer than timeout user preference
203203
while (time(0) - origtim < (Timeout+1))
204204
{
205205
time_t looptim = time(0);
@@ -291,7 +291,11 @@ void WOLthread (SESSIONPARAMETERS* CallingSessionParameters, bool* CallingSessio
291291
return;
292292

293293
vector<string> MACs = CallingSessionParameters->MAC;
294+
string IP = CallingSessionParameters->IP;
294295
string device = CallingSessionParameters->DeviceId;
296+
string subnet = CallingSessionParameters->Subnet;
297+
int WOLtype = CallingSessionParameters->WOLtype;
298+
295299
SOCKET WOLsocket = INVALID_SOCKET;
296300
string logmsg;
297301

@@ -301,10 +305,68 @@ void WOLthread (SESSIONPARAMETERS* CallingSessionParameters, bool* CallingSessio
301305
struct sockaddr_in LANDestination {};
302306
LANDestination.sin_family = AF_INET;
303307
LANDestination.sin_port = htons(9);
304-
LANDestination.sin_addr.s_addr = 0xFFFFFFFF;
308+
309+
stringstream wolstr;
310+
311+
if (WOLtype == WOL_SUBNETBROADCAST && subnet != "")
312+
{
313+
vector<string> vIP = stringsplit(IP, ".");
314+
vector<string> vSubnet = stringsplit(subnet, ".");
315+
stringstream broadcastaddress;
316+
317+
if (vIP.size() == 4 && vSubnet.size() == 4)
318+
{
319+
for (int i = 0; i < 4; i++)
320+
{
321+
int a = atoi(vIP[i].c_str());
322+
int b = atoi(vSubnet[i].c_str());
323+
int c = 256 + (a | (~b));
324+
325+
broadcastaddress << c;
326+
if (i < 3)
327+
broadcastaddress << ".";
328+
}
329+
330+
stringstream ss;
331+
332+
wolstr << " using broadcast address: " << broadcastaddress.str();
333+
334+
LANDestination.sin_addr.s_addr = inet_addr(broadcastaddress.str().c_str());
335+
336+
}
337+
else
338+
{
339+
stringstream ss;
340+
ss << device;
341+
ss << ", ERROR! WOLthread malformed subnet/IP";
342+
Log(ss.str());
343+
return;
344+
}
345+
346+
347+
LANDestination.sin_addr.s_addr = 0xFFFFFFFF;
348+
}
349+
else if (WOLtype == WOL_IPSEND)
350+
{
351+
LANDestination.sin_addr.s_addr = inet_addr(IP.c_str());
352+
wolstr << " using IP address: " << IP;
353+
354+
}
355+
else
356+
{
357+
LANDestination.sin_addr.s_addr = 0xFFFFFFFF;
358+
wolstr << " using network broadcast: 255.255.255.255";
359+
}
360+
361+
/* test test test
362+
sockaddr_in host_interface;
363+
host_interface.sin_family = AF_INET;
364+
host_interface.sin_port = htons(0);
365+
host_interface.sin_addr.s_addr = inet_addr("192.168.1.100");
366+
*/
305367
time_t origtim = time(0);
306368

307-
WOLsocket= socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
369+
WOLsocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
308370

309371
if (WOLsocket == INVALID_SOCKET)
310372
{
@@ -318,6 +380,20 @@ void WOLthread (SESSIONPARAMETERS* CallingSessionParameters, bool* CallingSessio
318380
}
319381
else
320382
{
383+
/* test test test
384+
int iRes = ::bind(WOLsocket, (SOCKADDR*)&host_interface, sizeof(host_interface));
385+
if ( iRes == SOCKET_ERROR)
386+
{
387+
closesocket(WOLsocket);
388+
int dw = WSAGetLastError();
389+
stringstream ss;
390+
ss << device;
391+
ss << ", ERROR! WOLthread WS bind(): ";
392+
ss << dw;
393+
Log(ss.str());
394+
return;
395+
}
396+
*/
321397
const bool optval = TRUE;
322398
if (setsockopt(WOLsocket, SOL_SOCKET, SO_BROADCAST, (char*)&optval, sizeof(optval)) == SOCKET_ERROR)
323399
{
@@ -336,6 +412,8 @@ void WOLthread (SESSIONPARAMETERS* CallingSessionParameters, bool* CallingSessio
336412
logmsg = device;
337413
logmsg += ", repeating WOL broadcast started to MAC: ";
338414
logmsg += MAC;
415+
if (wolstr.str() != "")
416+
logmsg += wolstr.str();
339417
Log(logmsg);
340418

341419
//remove filling from MAC
@@ -473,7 +551,7 @@ void DisplayPowerOffThread(SESSIONPARAMETERS* CallingSessionParameters, bool* Ca
473551
host += ':' + std::to_string(ep.port());
474552
if (time(0) - origtim > 10) // this thread should not run too long
475553
{
476-
Log("DisplayPowerOffThread() forced exit.");
554+
Log("DisplayPowerOffThread() - forced exit");
477555
goto threadoffend;
478556
}
479557
// Log("DEBUG INFO: DisplayPowerOffThread() setting options...");
@@ -488,7 +566,7 @@ void DisplayPowerOffThread(SESSIONPARAMETERS* CallingSessionParameters, bool* Ca
488566
}));
489567
if (time(0) - origtim > 10) // this thread should not run too long
490568
{
491-
Log("DisplayPowerOffThread() forced exit.");
569+
Log("DisplayPowerOffThread() - forced exit");
492570
goto threadoffend;
493571
}
494572

LGTV Companion Setup/Product.wxs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<!-- When publishing updated version, make sure to generate new GUID for "Product Id", and update "Version" -->
33
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"><?define LGTV Companion Service_TargetDir=$(var.LGTV Companion Service.TargetDir)?><?define LGTV Companion UI_TargetDir=$(var.LGTV Companion UI.TargetDir)?>
4-
<Product Id="33587CA8-2E58-4EFE-B8AB-43FB30FD0D5A" Name="LGTV Companion" Language="1033" Version="1.3.0" Manufacturer="J Persson" UpgradeCode="0BA17E5B-11CE-491D-B1A1-05DD2D9F610A">
4+
<Product Id="A2C1A6C7-3CC8-4C3C-A3FD-DCE47F173ACE" Name="LGTV Companion" Language="1033" Version="1.4.0" Manufacturer="J Persson" UpgradeCode="0BA17E5B-11CE-491D-B1A1-05DD2D9F610A">
55
<Package Id="*" InstallerVersion="301" Compressed="yes" InstallScope="perMachine" Platform='x64' Description="LGTV Companion installer" InstallPrivileges="elevated" AdminImage="yes"/>
66
<Media Id="1" Cabinet="LGTVapp.cab" EmbedCab="yes" />
77

0 commit comments

Comments
 (0)