]> git.vomp.tv Git - vompclient.git/blob - vconnect.cc
Windows fixes
[vompclient.git] / vconnect.cc
1 /*
2     Copyright 2004-2020 Chris Tallon
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP.  If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 #include "defines.h"
21 #include "video.h"
22 #include "colour.h"
23 #include "command.h"
24 #include "i18n.h"
25 #include "boxstack.h"
26 #include "message.h"
27 #include "log.h"
28 #include "vdr.h"
29 #include "wol.h"
30 #include "vserverselect.h"
31 #include "messagequeue.h"
32
33 #include "vconnect.h"
34
35 VConnect::VConnect()
36 {
37   boxstack = BoxStack::getInstance();
38   vdr = VDR::getInstance();
39   logger = Log::getInstance();
40
41   setSize(400, 200);
42   createBuffer();
43   if (Video::getInstance()->getFormat() == Video::PAL)
44   {
45     setPosition(170, 200);
46   }
47   else
48   {
49     setPosition(160, 150);
50   }
51
52   exitable = 0;
53 }
54
55 VConnect::~VConnect()
56 {
57   threadReqQuit = true;
58   vdpc.stop();
59   stop();
60 }
61
62 void VConnect::draw()
63 {
64   VInfo::draw();
65   logger->log("VConnect", Log::DEBUG, "Draw done");
66 }
67
68 int VConnect::handleCommand(int /* command */)
69 {
70   return 1;
71 }
72
73 void VConnect::run()
74 {
75   threadMutex.lock();
76   threadReqQuit = false;
77   connectThread = std::thread([this]
78   {
79     threadMutex.lock();
80     threadMutex.unlock();
81     threadMethod();
82   });
83   threadMutex.unlock();
84 }
85
86 void VConnect::stop()
87 {
88   threadMutex.lock();
89   threadReqQuit = true;
90   threadCond.notify_one();
91   threadMutex.unlock();
92   connectThread.join();
93 }
94
95 void VConnect::threadMethod()
96 {
97   logger->log("VConnect", Log::DEBUG, "start threadMethod");
98
99   ULONG delay = 0;
100   int success;
101
102   std::unique_lock<std::mutex> ul(threadMutex, std::defer_lock);
103
104   const std::string& commandLineServer = getCommandLineServer();
105
106   if (!vdpc.init())
107   {
108     logger->log("VConnect", Log::CRIT, "Failed to init VDPC");
109     return;
110   }
111
112   do
113   {
114     if (!commandLineServer.empty()) // Server is specified, fake a servers array
115     {
116       //servers.emplace_back(commandLineServer, "", 3024, 0);
117       vdpc.TEMPaddCLIServer(commandLineServer); // FIXME move to new config system NCONFIG
118     }
119     else
120     {
121       setOneLiner(tr("Locating server"));
122       draw();
123       boxstack->update(this);
124       vdpc.go();
125       if (threadReqQuit) return;
126     }
127
128     for (ULONG i = 0; i < vdpc.numServers(); i++)
129       logger->log("VConnect", Log::INFO, "Found server: %i %s %s %u", vdpc[i].ipVersion, vdpc[i].ip.c_str(), vdpc[i].name.c_str(), vdpc[i].port, vdpc[i].version);
130
131     if (vdpc.numServers() == 1)
132     {
133       selectedServer = 0;
134     }
135     else
136     {
137       selectedServer = -1;
138       VServerSelect* vs = new VServerSelect(vdpc, this);
139       vs->draw();
140       boxstack->add(vs);
141       boxstack->update(vs);
142
143       ul.lock();
144       if (threadReqQuit) { ul.unlock(); return; }
145       threadCond.wait(ul);
146       ul.unlock();
147     }
148
149     if (threadReqQuit) return;
150
151     logger->log("VConnect", Log::NOTICE, "Connecting to server at %s %u", vdpc[selectedServer].ip.c_str(), vdpc[selectedServer].port);
152     Wol::getInstance()->setWakeUpIP(vdpc[selectedServer].ip.c_str());
153     vdr->setServerIP(vdpc[selectedServer].ip.c_str());
154     vdr->setServerPort(vdpc[selectedServer].port);
155
156     setOneLiner(tr("Connecting to VDR"));
157     draw();
158     boxstack->update(this);
159
160     success = vdr->connect();
161     if (success)
162     {
163       logger->log("VConnect", Log::DEBUG, "Connected ok, doing login");
164       unsigned int version_server_min, version_server_max, version_client;
165       int subtitles;
166       success = vdr->doLogin(&version_server_min, &version_server_max, &version_client, Command::getInstance()->getASLList(), subtitles);
167       Command::getInstance()->setSubDefault(subtitles);
168
169       if (!success)
170       {
171         vdr->disconnect();
172         if (version_server_min >version_client || version_client > version_server_max) {
173                 char buffer[1024];
174                 sprintf(buffer,"Version error: s min: %x s max: %x c: %x",version_server_min,version_server_max,version_client);
175                 setOneLiner(buffer);
176         } else {
177                 setOneLiner(tr("Login failed"));
178         }
179         delay = 3000;
180       }
181     }
182     else
183     {
184       setOneLiner(tr("Connection failed"));
185       delay = 3000;
186     }
187
188     draw();
189     boxstack->update(this);
190     MILLISLEEP(delay);
191   } while(!success);
192
193   logger->log("VConnect", Log::INFO, "Send VDR connected message");
194   Message* m = new Message(); // Must be done after this thread ends
195   m->from = this;
196   m->to = Command::getInstance();
197   m->message = Message::VDR_CONNECTED;
198   MessageQueue::getInstance()->postMessage(m);
199 }
200
201 void VConnect::processMessage(Message* m)
202 {
203   if (m->message == Message::SERVER_SELECTED)
204   {
205     selectedServer = m->parameter;
206     threadCond.notify_one();
207   }
208 }