]> git.vomp.tv Git - vompclient.git/blob - vconnect.cc
Log conversion
[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 "config.h"
22 #include "video.h"
23 #include "colour.h"
24 #include "control.h"
25 #include "i18n.h"
26 #include "boxstack.h"
27 #include "message.h"
28 #include "oldlog.h"
29 #include "vdr.h"
30 #include "wol.h"
31 #include "vserverselect.h"
32 #include "messagequeue.h"
33 #include "util.h"
34
35 #include "vconnect.h"
36
37 VConnect::VConnect()
38 {
39   boxstack = BoxStack::getInstance();
40   vdr = VDR::getInstance();
41   logger = Log::getInstance();
42
43   setSize(400, 200);
44   createBuffer();
45   if (Video::getInstance()->getFormat() == Video::PAL)
46   {
47     setPosition(170, 200);
48   }
49   else
50   {
51     setPosition(160, 150);
52   }
53
54   exitable = 0;
55 }
56
57 VConnect::~VConnect()
58 {
59   threadReqQuit = true;
60   vdpc.stop();
61   stop();
62 }
63
64 void VConnect::draw()
65 {
66   VInfo::draw();
67   logger->log("VConnect", Log::DEBUG, "Draw done");
68 }
69
70 int VConnect::handleCommand(int /* command */)
71 {
72   return 1;
73 }
74
75 void VConnect::run()
76 {
77   threadMutex.lock();
78   threadReqQuit = false;
79   connectThread = std::thread([this]
80   {
81     threadMutex.lock();
82     threadMutex.unlock();
83     threadMethod();
84   });
85   threadMutex.unlock();
86 }
87
88 void VConnect::stop()
89 {
90   threadMutex.lock();
91   threadReqQuit = true;
92   vdr->abortConnect(); // If this and vdr are connecting, cancel it
93   threadCond.notify_one();
94   threadMutex.unlock();
95   connectThread.join();
96 }
97
98 void VConnect::threadMethod()
99 {
100   logger->log("VConnect", Log::DEBUG, "start threadMethod");
101
102   ULONG delay = 0;
103   int success;
104
105   std::unique_lock<std::mutex> ul(threadMutex, std::defer_lock);
106
107   std::string commandLineServer;
108   Config::getInstance()->getString("main", "argv_server", commandLineServer);
109
110   if (!vdpc.init())
111   {
112     logger->log("VConnect", Log::CRIT, "Failed to init VDPC");
113     return;
114   }
115
116   do
117   {
118     if (!commandLineServer.empty()) // Server is specified, fake a servers array
119     {
120       //servers.emplace_back(commandLineServer, "", 3024, 0);
121       vdpc.TEMPaddCLIServer(commandLineServer); // FIXME move to new config system NCONFIG
122     }
123     else
124     {
125       setOneLiner(tr("Locating server"));
126       draw();
127       boxstack->update(this);
128       vdpc.go();
129       if (threadReqQuit) return;
130     }
131
132     for (ULONG i = 0; i < vdpc.numServers(); i++)
133       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);
134
135     if (vdpc.numServers() == 1)
136     {
137       selectedServer = 0;
138     }
139     else
140     {
141       selectedServer = -1;
142       VServerSelect* vs = new VServerSelect(vdpc, this);
143       vs->draw();
144       boxstack->add(vs);
145       boxstack->update(vs);
146
147       ul.lock();
148       if (threadReqQuit) { ul.unlock(); return; }
149       threadCond.wait(ul);
150       ul.unlock();
151     }
152
153     if (threadReqQuit) return;
154
155     logger->log("VConnect", Log::NOTICE, "Connecting to server at %s %u", vdpc[selectedServer].ip.c_str(), vdpc[selectedServer].port);
156     Wol::getInstance()->setWakeUpIP(vdpc[selectedServer].ip.c_str());
157     vdr->setServerIP(vdpc[selectedServer].ip.c_str());
158     vdr->setServerPort(vdpc[selectedServer].port);
159
160     setOneLiner(tr("Connecting to VDR"));
161     draw();
162     boxstack->update(this);
163
164     if (threadReqQuit) return;
165     success = vdr->connect();
166     if (threadReqQuit) return;
167
168     if (success)
169     {
170       logger->log("VConnect", Log::DEBUG, "Connected ok, doing login");
171       unsigned int version_server_min, version_server_max, version_client;
172       int subtitles;
173       success = vdr->doLogin(&version_server_min, &version_server_max, &version_client, Control::getInstance()->getASLList(), subtitles);
174       Control::getInstance()->setSubDefault(subtitles);
175
176       if (!success)
177       {
178         vdr->disconnect();
179         if (version_server_min >version_client || version_client > version_server_max) {
180                 char buffer[1024];
181                 sprintf(buffer,"Version error: s min: %x s max: %x c: %x",version_server_min,version_server_max,version_client);
182                 setOneLiner(buffer);
183         } else {
184                 setOneLiner(tr("Login failed"));
185         }
186         delay = 3000;
187       }
188     }
189     else
190     {
191       setOneLiner(tr("Connection failed"));
192       delay = 3000;
193     }
194
195     draw();
196     boxstack->update(this);
197
198     MILLISLEEP(delay); // FIXME wait on cond?
199     if (threadReqQuit) return;
200   } while(!success);
201
202   logger->log("VConnect", Log::INFO, "Send VDR connected message");
203   Message* m = new Message(); // Must be done after this thread ends
204   m->from = this;
205   m->p_to = Message::CONTROL;
206   m->message = Message::VDR_CONNECTED;
207   MessageQueue::getInstance()->postMessage(m);
208 }
209
210 void VConnect::processMessage(Message* m)
211 {
212   if (m->message == Message::SERVER_SELECTED)
213   {
214     selectedServer = m->parameter;
215     threadCond.notify_one();
216   }
217 }