1 /*
2     SPDX-FileCopyrightText: 2010 Christian Vetter veaac.fdirct @gmail.com
3     SPDX-License-Identifier: GPL-3.0-or-later OR LGPL-2.0-or-later
4 
5     This file is part of MoNav.
6 */
7 
8 #ifndef SIGNALS_H
9 #define SIGNALS_H
10 
11 #include <QString>
12 #include <QVector>
13 #include <QDataStream>
14 #include <QStringList>
15 #include <QLocalSocket>
16 
17 namespace MoNav {
18 
19 	// has to be send before each command to identify the following command type
20 	struct CommandType {
21 		enum Type{
22 			RoutingCommand = 0,
23 			UnpackCommand = 1
24 		} value;
25 
postCommandType26 		void post( QIODevice* out )
27 		{
28 			qint32 temp = value;
29 			out->write( ( const char* ) &temp, sizeof( qint32 ) );
30 		}
31 
readCommandType32 		bool read( QLocalSocket* in )
33 		{
34 			while ( in->bytesAvailable() < ( int ) sizeof( qint32 ) ) {
35 				if ( in->state() != QLocalSocket::ConnectedState )
36 					return false;
37 				in->waitForReadyRead( 100 );
38 			}
39 
40 			qint32 temp;
41 			in->read( ( char* ) &temp, sizeof( qint32 ) );
42 			value = ( Type ) temp;
43 
44 			return true;
45 		}
46 	};
47 
48 	struct Node {
49 		double latitude;
50 		double longitude;
51 
52 		friend QDataStream& operator<< ( QDataStream& out, const Node& node )
53 		{
54 			out << node.latitude;
55 			out << node.longitude;
56 			return out;
57 		}
58 
59 		friend QDataStream& operator>> ( QDataStream& in, Node& node )
60 		{
61 			in >> node.latitude;
62 			in >> node.longitude;
63 			return in;
64 		}
65 	};
66 
67 	struct Edge {
68 		unsigned length; // length of the edge == number of edges it represents == number of nodes - 1
69 		unsigned name; // name ID of the edge
70 		unsigned type; // type ID of the edge
71 		unsigned seconds; // travel time metric for the edge
72 		bool branchingPossible; // is it possible to choose between more than one subsequent edge ( turning around on bidirectional edges does not count )
73 
74 		friend QDataStream& operator<< ( QDataStream& out, const Edge& edge )
75 		{
76 			out << edge.length;
77 			out << edge.name;
78 			out << edge.type;
79 			out << edge.seconds;
80 			out << edge.branchingPossible;
81 			return out;
82 		}
83 
84 		friend QDataStream& operator>> ( QDataStream& in, Edge& edge )
85 		{
86 			in >> edge.length;
87 			in >> edge.name;
88 			in >> edge.type;
89 			in >> edge.seconds;
90 			in >> edge.branchingPossible;
91 			return in;
92 		}
93 	};
94 
95 	class RoutingCommand {
96 
97 	public:
98 
RoutingCommand()99 		RoutingCommand()
100 		{
101 			lookupRadius = 10000; // 10km should suffice for most applications
102 			lookupStrings = false;
103 		}
104 
105 		// waypoint edge lookup radius in meters
106 		double lookupRadius;
107 		// lookup street name / type strings?
108 		bool lookupStrings;
109 		// a valid  routing module directory
110 		QString dataDirectory;
111 		// waypoints of the route
112 		QVector< Node > waypoints;
113 
post(QIODevice * out)114 		void post( QIODevice* out )
115 		{
116 			QByteArray buffer;
117 			QDataStream stream( &buffer, QIODevice::WriteOnly );
118 			stream << lookupRadius;
119 			stream << lookupStrings;
120 			stream << dataDirectory;
121 			stream << waypoints;
122 			qint32 size = buffer.size();
123 			out->write( ( const char* ) &size, sizeof( qint32 ) );
124 			out->write( buffer.data(), size );
125 		}
126 
read(QLocalSocket * in)127 		bool read( QLocalSocket* in )
128 		{
129 			qint32 size;
130 			while ( in->bytesAvailable() < ( int ) sizeof( qint32 ) ) {
131 				if ( in->state() != QLocalSocket::ConnectedState )
132 					return false;
133 				in->waitForReadyRead( 100 );
134 			}
135 
136 			in->read( ( char* ) &size, sizeof( quint32 ) );
137 
138 			while ( in->bytesAvailable() < size ) {
139 				if ( in->state() != QLocalSocket::ConnectedState )
140 					return false;
141 				in->waitForReadyRead( 100 );
142 			}
143 
144 			QByteArray buffer= in->read( size );
145 			QDataStream stream( buffer );
146 			stream >> lookupRadius;
147 			stream >> lookupStrings;
148 			stream >> dataDirectory;
149 			stream >> waypoints;
150 
151 			return true;
152 		}
153 
154 	};
155 
156 	class RoutingResult {
157 
158 	public:
159 
160 		enum ResultType {
161 			LoadFailed = 1, RouteFailed = 2, NameLookupFailed = 3, TypeLookupFailed = 4, Success = 5
162 		} type;
163 
164 		double seconds;
165 		QVector< Node > pathNodes;
166 		QVector< Edge > pathEdges;
167 		QStringList nameStrings;
168 		QStringList typeStrings;
169 
post(QIODevice * out)170 		void post( QIODevice* out )
171 		{
172 			QByteArray buffer;
173 			QDataStream stream( &buffer, QIODevice::WriteOnly );
174 			stream << qint32( type );
175 			stream << seconds;
176 			stream << pathNodes;
177 			stream << pathEdges;
178 			stream << nameStrings;
179 			stream << typeStrings;
180 			qint32 size = buffer.size();
181 			out->write( ( const char* ) &size, sizeof( qint32 ) );
182 			out->write( buffer.data(), size );
183 		}
184 
read(QLocalSocket * in)185 		bool read( QLocalSocket* in )
186 		{
187 			qint32 size;
188 			while ( in->bytesAvailable() < ( int ) sizeof( qint32 ) ) {
189 				if ( in->state() != QLocalSocket::ConnectedState )
190 					return false;
191 				in->waitForReadyRead( 100 );
192 			}
193 
194 			in->read( ( char* ) &size, sizeof( quint32 ) );
195 
196 			while ( in->bytesAvailable() < size ) {
197 				if ( in->state() != QLocalSocket::ConnectedState )
198 					return false;
199 				in->waitForReadyRead( 100 );
200 			}
201 
202 			QByteArray buffer= in->read( size );
203 			QDataStream stream( buffer );
204 			qint32 temp;
205 			stream >> temp;
206 			type = ( ResultType ) temp;
207 			stream >> seconds;
208 			stream >> pathNodes;
209 			stream >> pathEdges;
210 			stream >> nameStrings;
211 			stream >> typeStrings;
212 
213 			return true;
214 		}
215 
216 	};
217 
218 	class UnpackCommand
219 	{
220 	public:
221 
UnpackCommand()222 		UnpackCommand()
223 		{
224 			deleteFile = false;
225 		}
226 
227 		// MoNav Map Module file to be unpacked
228 		// it will be unpacked in the directory of the same name
229 		// e.g. test.mmm -> test/
230 		QString mapModuleFile;
231 		// delete file after unpacking?
232 		bool deleteFile;
233 
post(QIODevice * out)234 		void post( QIODevice* out )
235 		{
236 			QByteArray buffer;
237 			QDataStream stream( &buffer, QIODevice::WriteOnly );
238 			stream << mapModuleFile;
239 			stream << deleteFile;
240 			qint32 size = buffer.size();
241 			out->write( ( const char* ) &size, sizeof( qint32 ) );
242 			out->write( buffer.data(), size );
243 		}
244 
read(QLocalSocket * in)245 		bool read( QLocalSocket* in )
246 		{
247 			qint32 size;
248 			while ( in->bytesAvailable() < ( int ) sizeof( qint32 ) ) {
249 				if ( in->state() != QLocalSocket::ConnectedState )
250 					return false;
251 				in->waitForReadyRead( 100 );
252 			}
253 
254 			in->read( ( char* ) &size, sizeof( quint32 ) );
255 
256 			while ( in->bytesAvailable() < size ) {
257 				if ( in->state() != QLocalSocket::ConnectedState )
258 					return false;
259 				in->waitForReadyRead( 100 );
260 			}
261 
262 			QByteArray buffer= in->read( size );
263 			QDataStream stream( buffer );
264 			stream >> mapModuleFile;
265 			stream >> deleteFile;
266 
267 			return true;
268 		}
269 	};
270 
271 	class UnpackResult
272 	{
273 	public:
274 
275 		enum ResultType {
276 			FailUnpacking = 1, Success = 2
277 		} type;
278 
post(QIODevice * out)279 		void post( QIODevice* out )
280 		{
281 			qint32 temp = type;
282 			out->write( ( const char* ) &temp, sizeof( qint32 ) );
283 		}
284 
read(QLocalSocket * in)285 		bool read( QLocalSocket* in )
286 		{
287 			while ( in->bytesAvailable() < ( int ) sizeof( qint32 ) ) {
288 				if ( in->state() != QLocalSocket::ConnectedState )
289 					return false;
290 				in->waitForReadyRead( 100 );
291 			}
292 
293 			qint32 temp;
294 			in->read( ( char* ) &temp, sizeof( qint32 ) );
295 			type = ResultType( temp );
296 
297 			return true;
298 		}
299 	};
300 
301 }
302 
303 #endif // SIGNALS_H
304