1 /******************************************************************************
2  *
3  * Project:  OpenCPN
4  * Purpose:  NMEA Data Object
5  * Author:   David Register
6  *
7  ***************************************************************************
8  *   Copyright (C) 2010 by David S. Register                               *
9  *                                                                         *
10  *   This program is free software; you can redistribute it and/or modify  *
11  *   it under the terms of the GNU General Public License as published by  *
12  *   the Free Software Foundation; either version 2 of the License, or     *
13  *   (at your option) any later version.                                   *
14  *                                                                         *
15  *   This program is distributed in the hope that it will be useful,       *
16  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
17  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
18  *   GNU General Public License for more details.                          *
19  *                                                                         *
20  *   You should have received a copy of the GNU General Public License     *
21  *   along with this program; if not, write to the                         *
22  *   Free Software Foundation, Inc.,                                       *
23  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,  USA.         *
24  ***************************************************************************
25  *
26  *
27  *
28  *
29  */
30 
31 
32 #ifndef __DATASTREAM_H__
33 #define __DATASTREAM_H__
34 
35 #ifdef __MINGW32__
36 #undef IPV6STRICT    // mingw FTBS fix:  missing struct ip_mreq
37 #include <windows.h>
38 #endif
39 
40 #include "wx/wxprec.h"
41 
42 #ifndef  WX_PRECOMP
43   #include "wx/wx.h"
44 #endif //precompiled header
45 
46 
47 #include <wx/datetime.h>
48 
49 
50 #ifdef __WXGTK__
51 // newer versions of glib define its own GSocket but we unfortunately use this
52 // name in our own (semi-)public header and so can't change it -- rename glib
53 // one instead
54 //#include <gtk/gtk.h>
55 #define GSocket GlibGSocket
56 #include "wx/socket.h"
57 #undef GSocket
58 #else
59 #include "wx/socket.h"
60 #endif
61 
62 #ifndef __WXMSW__
63 #include <sys/socket.h>                 // needed for (some) Mac builds
64 #include <netinet/in.h>
65 #endif
66 
67 #ifdef __WXMSW__
68 // #include <windows.h>
69 // #include <dbt.h>
70 // #include <winioctl.h>
71 // #include <initguid.h>
72 #endif
73 #include <string>
74 #include "ConnectionParams.h"
75 #include "dsPortType.h"
76 
77 //----------------------------------------------------------------------------
78 //   constants
79 //----------------------------------------------------------------------------
80 #ifndef PI
81 #define PI        3.1415926535897931160E0      /* pi */
82 #endif
83 
84 #define TIMER_SOCKET   7006
85 
86 //      Error codes, returned by GetLastError()
87 enum {
88     DS_ERROR_PORTNOTFOUND
89 };
90 
91 
92 //      End-of-sentence types
93 enum {
94     DS_EOS_CRLF,
95     DS_EOS_LF,
96     DS_EOS_CR
97 };
98 
99 //      Serial port handshake type
100 enum {
101     DS_HANDSHAKE_NONE,
102     DS_HANDSHAKE_XON_XOFF
103 };
104 
105 #define DS_SOCKET_ID             5001
106 #define DS_SERVERSOCKET_ID       5002
107 #define DS_ACTIVESERVERSOCKET_ID 5003
108 
109 #define     MAX_RX_MESSSAGE_SIZE  4096
110 #define     RX_BUFFER_SIZE        4096
111 
112 
113 // Class declarations
114 
115 
116 
117 
118 
119 // Class declarations
120 class OCP_DataStreamInput_Thread;
121 class DataStream;
122 class GarminProtocolHandler;
123 
124 extern  const wxEventType wxEVT_OCPN_DATASTREAM;
125 extern  const wxEventType wxEVT_OCPN_THREADMSG;
126 
127 bool CheckSumCheck(const std::string& sentence);
128 
129 //----------------------------------------------------------------------------
130 // DataStream
131 //
132 //      Physical port is specified by a string in the class ctor.
133 //      Examples strings:
134 //              Serial:/dev/ttyS0               (Standard serial port)
135 //              Serial:COM4
136 //              TCP:192.168.1.1:5200            (TCP source, address and port specified)
137 //              GPSD:192.168.2.3:5400           (GPSD Wire protocol, address and port specified)
138 //
139 //----------------------------------------------------------------------------
140 
141 
142 
143 class DataStream: public wxEvtHandler
144 {
145 protected:
146     DataStream(wxEvtHandler *input_consumer,
147                const ConnectionType conn_type,
148                const wxString& Port,
149                const wxString& BaudRate,
150                dsPortType io_select,
151                int priority,
152                bool bGarmin,
153                int EOS_type,
154                int handshake_type);
155     DataStream(wxEvtHandler *input_consumer, const ConnectionParams* params);
156 
157 public:
158     virtual ~DataStream();
159 
160     virtual void Close();
161 
IsOk()162     bool IsOk() const { return m_bok; }
GetPort()163     wxString GetPort() const { return m_portstring; }
GetIoSelect()164     dsPortType GetIoSelect() const { return m_io_select; }
GetPriority()165     int GetPriority() const { return m_priority; }
166 
167     virtual bool SendSentence( const wxString &sentence );
168 
GetLastError()169     int GetLastError() const { return m_last_error; }
170 
171  //    Secondary thread life toggle
172  //    Used to inform launching object (this) to determine if the thread can
173  //    be safely called or polled, e.g. wxThread->Destroy();
SetSecThreadActive(void)174     void SetSecThreadActive(void){m_bsec_thread_active = true;}
SetSecThreadInActive(void)175     void SetSecThreadInActive(void){m_bsec_thread_active = false;}
IsSecThreadActive()176     bool IsSecThreadActive() const { return m_bsec_thread_active; }
177 
SetChecksumCheck(bool check)178     void SetChecksumCheck(bool check) { m_bchecksumCheck = check; }
179 
SetInputFilter(wxArrayString filter)180     void SetInputFilter(wxArrayString filter) { m_input_filter = filter; }
SetInputFilterType(ListType filter_type)181     void SetInputFilterType(ListType filter_type) { m_input_filter_type = filter_type; }
SetOutputFilter(wxArrayString filter)182     void SetOutputFilter(wxArrayString filter) { m_output_filter = filter; }
SetOutputFilterType(ListType filter_type)183     void SetOutputFilterType(ListType filter_type) { m_output_filter_type = filter_type; }
184     bool SentencePassesFilter(const wxString& sentence, FilterDirection direction);
185     bool ChecksumOK(const std::string& sentence);
GetGarminMode()186     bool GetGarminMode() const { return m_bGarmin_GRMN_mode; }
187 
GetBaudRate()188     wxString GetBaudRate() const { return m_BaudRate; }
GetPortType()189     dsPortType GetPortType() const { return m_io_select; }
GetInputSentenceList()190     wxArrayString GetInputSentenceList() const { return m_input_filter; }
GetOutputSentenceList()191     wxArrayString GetOutputSentenceList() const { return m_output_filter; }
GetInputSentenceListType()192     ListType GetInputSentenceListType() const { return m_input_filter_type; }
GetOutputSentenceListType()193     ListType GetOutputSentenceListType() const { return m_output_filter_type; }
GetChecksumCheck()194     bool GetChecksumCheck() const { return m_bchecksumCheck; }
GetConnectionType()195     ConnectionType GetConnectionType() const { return m_connection_type; }
GetConnectionParams()196     const ConnectionParams* GetConnectionParams() const { return &m_params; }
197     int                 m_Thread_run_flag;
198 
199 protected:
SetOk(bool ok)200     void SetOk(bool ok) { m_bok = ok; };
201 
SetGarminProtocolHandler(GarminProtocolHandler * garminHandler)202     void SetGarminProtocolHandler(GarminProtocolHandler *garminHandler) {
203         m_GarminHandler = garminHandler;
204     }
205 
SetSecondaryThread(OCP_DataStreamInput_Thread * secondary_Thread)206     void SetSecondaryThread(OCP_DataStreamInput_Thread *secondary_Thread) {
207         m_pSecondary_Thread = secondary_Thread;
208     }
GetSecondaryThread()209     OCP_DataStreamInput_Thread* GetSecondaryThread() { return m_pSecondary_Thread; }
SetThreadRunFlag(int run)210     void SetThreadRunFlag(int run) { m_Thread_run_flag = run; }
211 
GetConsumer()212     wxEvtHandler* GetConsumer() { return m_consumer; }
GetPortString()213     wxString GetPortString(){ return m_portstring; }
214 
SetConnectTime(wxDateTime time)215     void SetConnectTime(wxDateTime time) { m_connect_time = time; }
GetConnectTime()216     wxDateTime GetConnectTime() { return m_connect_time; }
217 
218 
219 private:
220     virtual void Open();
221 
222 
223     bool                m_bok;
224     wxEvtHandler        *m_consumer;
225     wxString            m_portstring;
226     wxString            m_BaudRate;
227     dsPortType          m_io_select;
228     int                 m_priority;
229     int                 m_handshake;
230 
231     OCP_DataStreamInput_Thread *m_pSecondary_Thread;
232     bool                m_bsec_thread_active;
233     int                 m_last_error;
234 
235     ConnectionType      m_connection_type;
236 
237     bool                m_bchecksumCheck;
238     wxArrayString       m_input_filter;
239     ListType            m_input_filter_type;
240     wxArrayString       m_output_filter;
241     ListType            m_output_filter_type;
242 
243     bool                m_bGarmin_GRMN_mode;
244     GarminProtocolHandler *m_GarminHandler;
245     wxDateTime          m_connect_time;
246     ConnectionParams    m_params;
247 
248 };
249 
250 class InternalGPSDataStream : public DataStream {
251 public:
InternalGPSDataStream(wxEvtHandler * input_consumer,const ConnectionParams * params)252     InternalGPSDataStream(wxEvtHandler *input_consumer,
253                           const ConnectionParams *params) : DataStream(input_consumer, params) {
254         Open();
255     }
256 
257 private:
258     void Open();
259 };
260 
261 class InternalBTDataStream : public DataStream {
262 public:
InternalBTDataStream(wxEvtHandler * input_consumer,const ConnectionParams * params)263     InternalBTDataStream(wxEvtHandler *input_consumer,
264                          const ConnectionParams *params) : DataStream(input_consumer, params) {
265         Open();
266     }
267 
268 private:
269     void Open();
270     bool SendSentence( const wxString &sentence );
271 
272 };
273 
274 class NullDataStream : public DataStream {
275 public:
NullDataStream(wxEvtHandler * input_consumer,const ConnectionParams * params)276     NullDataStream(wxEvtHandler *input_consumer,
277                    const ConnectionParams *params) : DataStream(input_consumer, params) {}
278 
279 };
280 
281 // Factory methods, preparation to split into subclasses with clearer
282 // Responsibilities
283 
284 DataStream* makeDataStream(wxEvtHandler *input_consumer, const ConnectionParams* params);
285 
286 
287 #endif
288 
289 
290