@@ -34,6 +34,7 @@ static pthread_t m_threadTx;
3434static pthread_mutex_t m_txLock;
3535static pthread_t m_threadRx;
3636static pthread_mutex_t m_rxLock;
37+ static pthread_t m_threadStatus;
3738
3839zmq::context_t m_zmqContextTx;
3940zmq::socket_t m_zmqSocketTx;
@@ -43,12 +44,90 @@ zmq::context_t m_zmqContextRx;
4344zmq::socket_t m_zmqSocketRx;
4445static std::vector<short > m_audioBufRx = std::vector<short >();
4546
47+ static bool m_abort = false ;
48+
49+ static bool m_cosPrev = false ;
4650static bool m_cosInt = false ;
4751
52+ static bool m_pttPrev = false ;
53+ static bool m_ptt = false ;
54+
55+ static bool m_dmrModeToggle = false ;
56+ static bool m_dmrMode = false ;
57+ static bool m_p25ModeToggle = false ;
58+ static bool m_p25Mode = false ;
59+ static bool m_nxdnModeToggle = false ;
60+ static bool m_nxdnMode = false ;
61+
62+ /* */
63+
64+ static void * modemStatusHelper (void * arg)
65+ {
66+ IO* io = (IO*)arg;
67+ if (io != nullptr ) {
68+ while (!m_abort) {
69+ // log flag statuses
70+ if (m_cosPrev != m_cosInt) {
71+ ::LogMessage (" COS %s" , m_cosInt ? " DETECT" : " NO CARRIER" );
72+ m_cosPrev = m_cosInt;
73+ }
74+
75+ if (m_pttPrev != m_ptt) {
76+ ::LogMessage (" PTT %s" , m_ptt ? " TRANSMIT" : " IDLE" );
77+ m_pttPrev = m_ptt;
78+ }
79+
80+ if (m_dmrModeToggle) {
81+ ::LogMessage (" DMR Mode %s" , m_dmrMode ? " ENABLED" : " DISABLED" );
82+ m_dmrModeToggle = false ;
83+ }
84+
85+ if (m_p25ModeToggle) {
86+ ::LogMessage (" P25 Mode %s" , m_p25Mode ? " ENABLED" : " DISABLED" );
87+ m_p25ModeToggle = false ;
88+ }
89+
90+ if (m_nxdnModeToggle) {
91+ ::LogMessage (" NXDN Mode %s" , m_nxdnMode ? " ENABLED" : " DISABLED" );
92+ m_nxdnModeToggle = false ;
93+ }
94+
95+ ::usleep (1000U );
96+ }
97+ }
98+
99+ return NULL ;
100+ }
101+
48102// ---------------------------------------------------------------------------
49103// Public Class Members
50104// ---------------------------------------------------------------------------
51105
106+ /* Finalizes a instance of the IO class. */
107+
108+ IO::~IO ()
109+ {
110+ m_abort = true ;
111+
112+ if (m_threadTx) {
113+ ::pthread_join (m_threadTx, NULL );
114+ }
115+
116+ if (m_threadRx) {
117+ ::pthread_join (m_threadRx, NULL );
118+ }
119+
120+ if (m_threadStatus) {
121+ ::pthread_join (m_threadStatus, NULL );
122+ }
123+
124+ ::pthread_mutex_destroy (&m_txLock);
125+ ::pthread_mutex_destroy (&m_rxLock);
126+
127+ m_zmqSocketTx.close ();
128+ m_zmqSocketRx.close ();
129+ }
130+
52131/* Hardware interrupt handler. */
53132
54133void IO::interrupt ()
@@ -70,7 +149,7 @@ void IO::interrupt()
70149 }
71150 catch (const zmq::error_t & zmqE) { /* stub */ }
72151
73- usleep (9600 * 3 );
152+ :: usleep (9600 * 3 );
74153
75154 m_audioBufTx.erase (m_audioBufTx.begin (), m_audioBufTx.begin () + 720 );
76155 m_audioBufTx.push_back ((short )sample);
@@ -140,21 +219,21 @@ void IO::startInt()
140219 ::LogMessage (" Binding Tx socket to %s" , m_zmqTx.c_str());
141220 m_zmqSocketTx.bind (m_zmqTx);
142221 }
143- catch (const zmq::error_t & zmqE) { ::LogError (" IO::startInt(), Tx Socket: %s" , zmqE.what ()); }
144- catch (const std::exception& e) { ::LogError (" IO::startInt(), Tx Socket: %s" , e.what ()); }
222+ catch (const zmq::error_t & zmqE) { ::LogError (" ZMQ Tx Socket: %s" , zmqE.what ()); }
223+ catch (const std::exception& e) { ::LogError (" ZMQ Tx Socket: %s" , e.what ()); }
145224
146225 try
147226 {
148227 ::LogMessage (" Connecting Rx socket to %s" , m_zmqRx.c_str());
149228 m_zmqSocketRx.connect (m_zmqRx);
150229 if (m_zmqSocketRx.connected ()) {
151- ::LogMessage (" IO::startInt(), connected to remote ZMQ listener" , m_zmqRx.c_str());
230+ ::LogMessage (" ZMQ connected to remote ZMQ listener" , m_zmqRx.c_str());
152231 } else {
153- ::LogWarning (" IO::startInt(), failed to remote ZMQ listener, will continue to retry to connect" , m_zmqRx.c_str());
232+ ::LogWarning (" ZMQ failed to remote ZMQ listener, will continue to retry to connect" , m_zmqRx.c_str());
154233 }
155234 }
156- catch (const zmq::error_t & zmqE) { ::LogError (" IO::startInt(), Rx Socket: %s" , zmqE.what ()); }
157- catch (const std::exception& e) { ::LogError (" IO::startInt(), Rx Socket: %s" , e.what ()); }
235+ catch (const zmq::error_t & zmqE) { ::LogError (" ZMQ Rx Socket: %s" , zmqE.what ()); }
236+ catch (const std::exception& e) { ::LogError (" ZMQ Rx Socket: %s" , e.what ()); }
158237
159238 m_audioBufTx = std::vector<short >();
160239 m_audioBufRx = std::vector<short >();
@@ -173,6 +252,7 @@ void IO::startInt()
173252
174253 ::pthread_create (&m_threadTx, NULL , txThreadHelper, this );
175254 ::pthread_create (&m_threadRx, NULL , rxThreadHelper, this );
255+ ::pthread_create (&m_threadStatus, NULL , modemStatusHelper, this );
176256}
177257
178258/* */
@@ -193,7 +273,7 @@ void IO::setLEDInt(bool on)
193273
194274void IO::setPTTInt (bool on)
195275{
196- /* stub */
276+ m_ptt = on;
197277}
198278
199279/* */
@@ -207,28 +287,37 @@ void IO::setCOSInt(bool on)
207287
208288void IO::setDMRInt (bool on)
209289{
210- /* stub */
290+ if (on != m_dmrMode)
291+ m_dmrModeToggle = true ;
292+
293+ m_dmrMode = on;
211294}
212295
213296/* */
214297
215298void IO::setP25Int (bool on)
216299{
217- /* stub */
300+ if (on != m_p25Mode)
301+ m_p25ModeToggle = true ;
302+
303+ m_p25Mode = on;
218304}
219305
220306/* */
221307
222308void IO::setNXDNInt (bool on)
223309{
224- /* stub */
310+ if (on != m_nxdnMode)
311+ m_nxdnModeToggle = true ;
312+
313+ m_nxdnMode = on;
225314}
226315
227316/* */
228317
229318void IO::delayInt (unsigned int dly)
230319{
231- usleep (dly * 1000 );
320+ :: usleep (dly * 1000U );
232321}
233322
234323/* */
@@ -237,7 +326,7 @@ void* IO::txThreadHelper(void* arg)
237326{
238327 IO* p = (IO*)arg;
239328
240- while (true )
329+ while (!m_abort )
241330 {
242331 if (p->m_txBuffer .getData () < 1 )
243332 usleep (20 );
@@ -283,14 +372,14 @@ void IO::interruptRx()
283372 ::pthread_mutex_lock (&m_rxLock);
284373 uint16_t space = m_rxBuffer.getSpace ();
285374
286- for (int i = 0 ; i < size; i += 2 )
287- {
375+ for (int i = 0 ; i < size; i += 2 ) {
288376 short sample = 0 ;
289377 ::memcpy (&sample, (unsigned char *)msg.data() + i, sizeof(short ));
290378
291379 m_rxBuffer.put ((uint16_t )sample, control);
292380 m_rssiBuffer.put (3U );
293381 }
382+
294383 ::pthread_mutex_unlock (&m_rxLock);
295384}
296385
@@ -300,7 +389,7 @@ void* IO::rxThreadHelper(void* arg)
300389{
301390 IO* p = (IO*)arg;
302391
303- while (true )
392+ while (!m_abort )
304393 p->interruptRx ();
305394
306395 return NULL ;
0 commit comments