]> git.vomp.tv Git - vompclient.git/blob - vdpc.h
Fix text corruption in live TV OSD clock
[vompclient.git] / vdpc.h
1 /*
2     Copyright 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 #ifndef VDPC_H
21 #define VDPC_H
22
23 // Vomp Discovery Protocol Client
24
25 #include <string>
26 #include <vector>
27 #include <mutex>
28 #include <thread>
29 #include <condition_variable>
30 #include <functional>
31
32 #ifdef WIN32
33   #include <WinSock2.h>
34 #endif
35
36 #include "defines.h"
37
38 #ifdef IPV4
39 #include "udp4.h"
40 #endif
41 #ifdef IPV6
42 #include "udp6.h"
43 #endif
44
45 struct VDRServer
46 {
47   int ipVersion;
48   std::string ip;
49   std::string name;
50   USHORT port;
51   ULONG version;
52
53   VDRServer() {}
54
55   VDRServer(int tipVersion, const std::string tip, const std::string tname, USHORT tport, ULONG tversion)
56   : ipVersion(tipVersion), ip(tip), name(tname), port(tport), version(tversion) {}
57 };
58
59 class ServerSorter
60 {
61   public:
62     ServerSorter() {}
63     bool operator() (const VDRServer& a, const VDRServer& b)
64     {
65       // First sort by name
66       if (a.name == b.name)
67       {
68         // Then by IP version
69         if (a.ipVersion == b.ipVersion)
70         {
71           // Then by IP
72           if (a.ip == b.ip)
73           {
74             // Then by port
75             return a.port < b.port;
76           }
77           else
78             return a.ip < b.ip; // yeah, weird
79         }
80         else
81           return a.ipVersion < b.ipVersion;
82       }
83       else
84         return a.name < b.name;
85     }
86 };
87
88 class VDPC
89 {
90   private:
91     typedef std::function<void(int, const char*, const char*, USHORT, ULONG)> AddServerCallback;
92
93   // Nested classes
94 #ifdef IPV4
95     class VDPC4
96     {
97       public:
98         bool init(AddServerCallback& taddFunc);
99         void run(); // blocks
100         void stop();
101         void sendRequest();
102
103       private:
104         #ifdef WIN32
105           SOCKET quitPipe;
106         #else
107           int pfdsUDP4[2];
108         #endif
109
110         std::mutex startProtect;
111         std::thread receiveThread;
112         bool stopNow{};
113         void threadMethod();
114
115         UDP4 udp4;
116         AddServerCallback addFunc;
117     };
118 #endif
119
120 #ifdef IPV6
121     class VDPC6
122     {
123       public:
124         bool init(AddServerCallback& taddFunc);
125         void run(); // blocks
126         void stop();
127         void sendRequest();
128
129       private:
130         int pfdsUDP6[2];
131
132         std::mutex startProtect;
133         std::thread receiveThread;
134         bool stopNow{};
135         void threadMethod();
136
137         UDP6 udp6;
138         AddServerCallback addFunc;
139     };
140 #endif
141
142   public:
143     bool init();
144     int go();
145     void stop();
146     ULONG numServers() const;
147     const VDRServer& operator[](ULONG index) const;
148
149   private:
150     std::vector<VDRServer> servers;
151     std::mutex serversLock;
152
153     std::condition_variable waitCond;
154     std::mutex waitMutex;
155     bool stopNow{};
156
157 #ifdef IPV4
158     VDPC4 vdpc4;
159 #endif
160 #ifdef IPV6
161     VDPC6 vdpc6;
162 #endif
163 };
164
165 #endif