1 #ifndef TRANSCEIVER_FACTORY_HPP__
2 #define TRANSCEIVER_FACTORY_HPP__
3 
4 #include <memory>
5 
6 #include <boost/log/trivial.hpp>
7 #include <boost/log/sources/severity_channel_logger.hpp>
8 
9 #include <QObject>
10 #include <QMap>
11 
12 #include "Transceiver.hpp"
13 
14 #include "qt_helpers.hpp"
15 
16 class QString;
17 class QThread;
18 class QDir;
19 
20 //
21 // Transceiver Factory
22 //
23 class TransceiverFactory
24   : public QObject
25 {
26   Q_OBJECT
27 
28 public:
29   //
30   // Capabilities of a Transceiver that can be determined without
31   // actually instantiating one, these are for use in Configuration
32   // GUI behaviour determination
33   //
34   struct Capabilities
35   {
36     enum PortType {none, serial, network, usb};
37 
CapabilitiesTransceiverFactory::Capabilities38     explicit Capabilities (unsigned model_number = 0
39                            , PortType port_type = none
40                            , bool has_CAT_PTT = false
41                            , bool has_CAT_PTT_mic_data = false
42                            , bool has_CAT_indirect_serial_PTT = false
43                            , bool asynchronous = false)
44       : model_number_ {model_number}
45       , port_type_ {port_type}
46       , has_CAT_PTT_ {has_CAT_PTT}
47       , has_CAT_PTT_mic_data_ {has_CAT_PTT_mic_data}
48       , has_CAT_indirect_serial_PTT_ {has_CAT_indirect_serial_PTT}
49       , asynchronous_ {asynchronous}
50     {
51     }
52 
53     unsigned model_number_;
54     PortType port_type_;
55     bool has_CAT_PTT_;
56     bool has_CAT_PTT_mic_data_;
57     bool has_CAT_indirect_serial_PTT_; // OmniRig controls RTS/DTR via COM interface
58     bool asynchronous_;
59   };
60 
61   //
62   // Dictionary of Transceiver types Capabilities
63   //
64   typedef QMap<QString, Capabilities> Transceivers;
65 
66   //
67   // various Transceiver parameters
68   //
69   enum DataBits {seven_data_bits = 7, eight_data_bits, default_data_bits};
70   Q_ENUM (DataBits)
71   enum StopBits {one_stop_bit = 1, two_stop_bits, default_stop_bits};
72   Q_ENUM (StopBits)
73   enum Handshake {handshake_default, handshake_none, handshake_XonXoff, handshake_hardware};
74   Q_ENUM (Handshake)
75   enum PTTMethod {PTT_method_VOX, PTT_method_CAT, PTT_method_DTR, PTT_method_RTS};
76   Q_ENUM (PTTMethod)
77   enum TXAudioSource {TX_audio_source_front, TX_audio_source_rear};
78   Q_ENUM (TXAudioSource)
79   enum SplitMode {split_mode_none, split_mode_rig, split_mode_emulate};
80   Q_ENUM (SplitMode)
81 
82   TransceiverFactory ();
83   ~TransceiverFactory ();
84 
85   static char const * const basic_transceiver_name_; // dummy transceiver is basic model
86 
87   //
88   // fetch all supported rigs as a list of name and model id
89   //
90   Transceivers const& supported_transceivers () const;
91 
92   // supported model queries
93   Capabilities::PortType CAT_port_type (QString const& name) const; // how to talk to CAT
94   bool has_CAT_PTT (QString const& name) const;	// can be keyed via CAT
95   bool has_CAT_PTT_mic_data (QString const& name) const; // Tx audio port is switchable via CAT
96   bool has_CAT_indirect_serial_PTT (QString const& name) const; // Can PTT via CAT port use DTR or RTS (OmniRig for example)
97   bool has_asynchronous_CAT (QString const& name) const; // CAT asynchronous rather than polled
98 
99   struct ParameterPack
100   {
101     QString rig_name;           // from supported_transceivers () key
102     QString serial_port;        // serial port device name or empty
103     QString network_port;       // hostname:port or empty
104     QString usb_port;           // [vid[:pid[:vendor[:product]]]]
105     int baud;
106     DataBits data_bits;
107     StopBits stop_bits;
108     Handshake handshake;
109     bool force_dtr;
110     bool dtr_high;              // to power interface
111     bool force_rts;
112     bool rts_high;              // to power interface
113     PTTMethod ptt_type;         // "CAT" | "DTR" | "RTS" | "VOX"
114     TXAudioSource audio_source; // some rigs allow audio routing
115                                 // to Mic/Data connector
116     SplitMode split_mode;       // how to support split TX mode
117     QString ptt_port;           // serial port device name or special
118                                 // value "CAT"
119     int poll_interval;          // in seconds for interfaces that
120                                 // require polling for state changes
121 
operator ==TransceiverFactory::ParameterPack122     bool operator == (ParameterPack const& rhs) const
123     {
124       return rhs.rig_name == rig_name
125         && rhs.serial_port == serial_port
126         && rhs.network_port == network_port
127         && rhs.usb_port == usb_port
128         && rhs.baud == baud
129         && rhs.data_bits == data_bits
130         && rhs.stop_bits == stop_bits
131         && rhs.handshake == handshake
132         && rhs.force_dtr == force_dtr
133         && rhs.dtr_high == dtr_high
134         && rhs.force_rts == force_rts
135         && rhs.rts_high == rts_high
136         && rhs.ptt_type == ptt_type
137         && rhs.audio_source == audio_source
138         && rhs.split_mode == split_mode
139         && rhs.ptt_port == ptt_port
140         && rhs.poll_interval == poll_interval
141         ;
142     }
143   };
144 
145   // make a new Transceiver instance
146   //
147   // cat_port, cat_baud, cat_data_bits, cat_stop_bits, cat_handshake,
148   // cat_dtr_control, cat_rts_control are only relevant to interfaces
149   // that are served by Hamlib
150   //
151   // PTT port and to some extent ptt_type are independent of interface
152   // type
153   //
154   std::unique_ptr<Transceiver> create (ParameterPack const&, QThread * target_thread = nullptr);
155 
156 private:
157   Transceiver::logger_type mutable logger_;
158   Transceivers transceivers_;
159 };
160 
161 inline
operator !=(TransceiverFactory::ParameterPack const & lhs,TransceiverFactory::ParameterPack const & rhs)162 bool operator != (TransceiverFactory::ParameterPack const& lhs, TransceiverFactory::ParameterPack const& rhs)
163 {
164   return !(lhs == rhs);
165 }
166 
167 ENUM_QDATASTREAM_OPS_DECL (TransceiverFactory, DataBits);
168 ENUM_QDATASTREAM_OPS_DECL (TransceiverFactory, StopBits);
169 ENUM_QDATASTREAM_OPS_DECL (TransceiverFactory, Handshake);
170 ENUM_QDATASTREAM_OPS_DECL (TransceiverFactory, PTTMethod);
171 ENUM_QDATASTREAM_OPS_DECL (TransceiverFactory, TXAudioSource);
172 ENUM_QDATASTREAM_OPS_DECL (TransceiverFactory, SplitMode);
173 
174 ENUM_CONVERSION_OPS_DECL (TransceiverFactory, DataBits);
175 ENUM_CONVERSION_OPS_DECL (TransceiverFactory, StopBits);
176 ENUM_CONVERSION_OPS_DECL (TransceiverFactory, Handshake);
177 ENUM_CONVERSION_OPS_DECL (TransceiverFactory, PTTMethod);
178 ENUM_CONVERSION_OPS_DECL (TransceiverFactory, TXAudioSource);
179 ENUM_CONVERSION_OPS_DECL (TransceiverFactory, SplitMode);
180 
181 #endif
182