This file is indexed.

/usr/include/svxlink/EchoLinkQso.h is in libecholib-dev 14.08.1-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
/**
@file	 EchoLinkQso.h
@brief   Contains a class for creating an EchoLink connection
@author  Tobias Blomberg
@date	 2003-03-11

This file contains a class for doing an EchoLink Qso. For more information, see
the documentation for class EchoLink::Qso.

\verbatim
EchoLib - A library for EchoLink communication
Copyright (C) 2003  Tobias Blomberg / SM0SVX

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
\endverbatim
*/

/** @example EchoLinkQso_demo.cpp
An example of how to use the EchoLink::Qso class.

A connection is created to ourself. When the connection has been established
the information message is automatically transmitted. Upon reception of the
information message a disconnect is initiated. When the link has been
disconnected the application exits.
*/


#ifndef ECHOLINK_QSO_INCLUDED
#define ECHOLINK_QSO_INCLUDED


/****************************************************************************
 *
 * System Includes
 *
 ****************************************************************************/

#include <sys/time.h>
#include <sigc++/sigc++.h>
#include <stdint.h>
#include <string>


/****************************************************************************
 *
 * Project Includes
 *
 ****************************************************************************/

extern "C" {
#include <gsm.h>
}
#include <AsyncTimer.h>
#include <AsyncIpAddress.h>
#include <AsyncAudioSink.h>
#include <AsyncAudioSource.h>


/****************************************************************************
 *
 * Local Includes
 *
 ****************************************************************************/



/****************************************************************************
 *
 * Forward declarations
 *
 ****************************************************************************/



/****************************************************************************
 *
 * Namespace
 *
 ****************************************************************************/

namespace EchoLink
{

/****************************************************************************
 *
 * Forward declarations inside the declared namespace
 *
 ****************************************************************************/



/****************************************************************************
 *
 * Defines & typedefs
 *
 ****************************************************************************/



/****************************************************************************
 *
 * Exported Global Variables
 *
 ****************************************************************************/



/****************************************************************************
 *
 * Class definitions
 *
 ****************************************************************************/

/**
@brief	A class for creating an EchoLink connection
@author Tobias Blomberg
@date   2003-03-11

This class is used to create a connection to another EchoLink node. It only
handles outgoing connections. To handle incoming connections, have a look at
EchoLink::Dispatcher. However, when an incoming connection has been signalled by
the dispatcher, a Qso object should be created to complete the connection. This
logic should be glued together in the main program.

For an example usage, have a look at the code below. A connection is created to
ourself. When the connection has been established the information message is
automatically transmitted. Upon reception of the information message a
disconnect is initiated. When the link has been disconnected the application
exits.

\include EchoLinkQso_demo.cpp
*/
class Qso
  : public sigc::trackable, public Async::AudioSink, public Async::AudioSource
{
  public:
    struct VoicePacket
    {
      struct {
	uint8_t version;
	uint8_t pt;
	uint16_t seqNum;
	uint32_t time;
	uint32_t ssrc;
      } header;
      uint8_t data[1024];
    } __attribute__ ((packed));
    
    struct RawPacket
    {
      VoicePacket *voice_packet;
      int length;
      short *samples;
    };

    /**
     * @brief The type of the connection state
     */
    typedef enum
    {
      STATE_DISCONNECTED, ///< No connection to the remote station
      STATE_CONNECTING,   ///< Connecting to remote station (not established)
      STATE_BYE_RECEIVED, ///< Received a disconnect request from remote station
      STATE_CONNECTED 	  ///< Connected to remote station
    } State;

    /**
     * @brief 	Constructor
     * @param 	ip The    IP-address of the remote station
     * @param 	callsign  Callsign of local user (not remote callsign)
     * @param 	name  	  Name of local user (not remote name)
     * @param 	info  	  Local information to send upon connect
     */
    Qso(const Async::IpAddress& ip, const std::string& callsign="",
      	const std::string& name="", const std::string& info="");
    
    /**
     * @brief 	Destructor
     */
    ~Qso(void);
  
    /**
     * @brief 	Check that the initialization went ok
     * @return	Returns \em true if the initialization was ok or \em false on
     *	      	failure
     *
     * This function should be called after creating a new Qso object to make
     * sure everything went well.
     */
    bool initOk(void) { return init_ok; }
    
    /**
     * @brief 	Set the local callsign
     * @param 	callsign  The callsign to set
     * @return	Returns \em true on success or \em false on failure
     */
    bool setLocalCallsign(const std::string& callsign);
    
    /**
     * @brief 	Retrieve the local callsign
     * @return	Returns the local callsign
     */
    const std::string& localCallsign(void) const { return callsign; }
    
    /**
     * @brief 	Set the local name (name of station operator)
     * @param 	name  The name to set
     * @return	Returns \em true on success or \em false on failure
     */
    bool setLocalName(const std::string& name);

    /**
     * @brief 	Retrieve the local name
     * @return	Returns the local name
     */
    const std::string& localName(void) const { return name; }
    
    /**
     * @brief 	Set the local info
     * @param 	info  The informational message that is sent to the remote
     *	      	      station upon connection.
     */
    void setLocalInfo(const std::string& info);
        
    /**
     * @brief 	Retrieve the local station info
     * @return	Returns the local station info
     */
    const std::string& localInfo(void) const { return local_stn_info; }
    
    /**
     * @brief 	Initiate a connection to the remote station
     * @return	Returns \em true if the connect message was sent ok or \em false
     *        	on failure
     *
     * Use this function to connect to the remote station. The \em StateChange
     * signal will be emitted to indicate that a connection is in progress.
     * When the connection has been established, the \em stateChange signal
     * will be emitted again. On failure to connect, the \em stateChange
     * signal will be emitted to indicate that the disconnected state
     * has been entered again.
     */
    bool connect(void);
    
    /**
     * @brief 	Accept an incoming connection
     * @return	Returns \em true if the connect message was sent successfully or
     *	      	\em false on failure
     *
     * Use this function to accept an incoming connection. Incoming connections
     * are signalled through the EchoLink::Dispatcher. When an incoming
     * connection has been received, a Qso object should be created and this
     * function should be called to accept the connection. Be sure to check that
     * a valid callsign has connected. At least if the EchoLink node is
     * connected to a radio transmitter.
     *
     * The difference between the connect and accept functions are that the
     * accept function goes right into the connected state. The remote station
     * is assumed to be present. This might not be true in some strange cases.
     * In such a strange case, the connection will timeout after a while.
     */
    bool accept(void);
    
    /**
     * @brief 	Initiate a disconnection from the remote station
     * @return	Returns \em true if the disconnection message was sent
     *	      	successfully or \em false on failure
     */
    bool disconnect(void);
    
    /**
     * @brief 	Send info data to the remote station
     * @param 	info The info to send
     * @return	Returns \em true on success or \em false on failure
     */
    bool sendInfoData(const std::string& info="");
    
    /**
     * @brief 	Send chat data to the remote station
     * @param 	msg The message to send
     * @return	Returns \em true on success or \em false on failure
     */
    bool sendChatData(const std::string& msg);
    
    /**
     * @brief 	Get the IP address of the remote station
     * @return	Returns the IP address
     */
    const Async::IpAddress& remoteIp(void) const
    {
      return remote_ip;
    }
    
    /**
     * @brief 	Send a GSM/SPEEX audio packet to the remote station
     * @param 	raw_packet The packet to send
     *
     * This function can be used to send a GSM/SPEEX packet to the remote
     * station. Probably only useful if you received it from the
     * audioReceivedRaw signal. The raw_packet contains both the network
     * packet and the decoded samples, which is beneficial when the audio
     * frame has to be transcoded (SPEEX -> GSM) prior re-transmission.
     */
    bool sendAudioRaw(RawPacket *raw_packet);

    /**
      * @brief Set parameters of the remote station connection
      * @param priv A private string for passing connection parameters
      */
    void setRemoteParams(const std::string& priv);
    
    /**
     * @brief Set the name of the remote station
     * @param name The name to set
     */
    void setRemoteName(const std::string& name) { remote_name = name; }
    
    /**
     * @brief 	Get the remote name
     * @return	Return the name of the remote station
     * @note  	Valid when the connection has been established
     */
    const std::string& remoteName(void) const { return remote_name; }
    
    /**
     * @brief Set the callsign of the remote station
     * @param call The callsign to set
     */
    void setRemoteCallsign(const std::string& call) { remote_call = call; }
    
    /**
     * @brief 	Get the remote callsign
     * @return	Return the callsign of the remote station
     * @note  	Valid when the connection has been established
     */
    const std::string& remoteCallsign(void) const { return remote_call; }
    
    /**
     * @brief 	Find out if the connection is remotely initiated or
     *          locally initiated.
     * @return	Return \em true if the connection is remotely initiated
     *          or else \em false.
     * @note  	Valid when either connect or accept has been called
     */
    bool isRemoteInitiated(void) const { return is_remote_initiated; }
    
    /**
     * @brief 	Find out if there is audio coming in on this connection
     * @return	Return \em true if audio is being received
     *          or else \em false.
     */
    bool receivingAudio(void) const { return receiving_audio; }

    /**
     * @brief 	Get the current state of the connection
     * @return	Return the current connection state (@see State)
     */
    State currentState(void) const { return state; }
    
    /**
     * @brief A signal that is emitted when a station info message is received
     * @param msg The received message
     */
    sigc::signal<void, const std::string&> infoMsgReceived;
    
    /**
     * @brief A signal that is emitted when a chat message is received
     * @param msg The received chat message
     */
    sigc::signal<void, const std::string&> chatMsgReceived;
    
    /**
     * @brief A signal that is emitted when the connection state changes
     * @param state The new connection state
     */
    sigc::signal<void, State> stateChange;
    
    /**
     * @brief A signal that is emitted when the audio receive state changes
     * @param is_receiving  Is \em true when audio is being received and
     *	      	      	    \em false when not
     * @note This signal can be used to control a reception indicator
     */
    sigc::signal<void, bool> isReceiving;
    
    /**
     * @brief A signal that is emitted when an audio datagram has been received
     * @param data A pointer to the buffer that contains the raw audio packet
     *
     * This signal is emitted whenever an audio packet has been received on
     * the connection. It gives access to the GSM/SPEEX packet. This can be used
     * if the encoded data is going to be retransmitted. In this case it is
     * not good to decode and then encode the data again. It will sound awful.
     */
    sigc::signal<void, RawPacket*>  audioReceivedRaw;
    

    /**
     * @brief 	Write samples into this audio sink
     * @param 	samples The buffer containing the samples
     * @param 	count The number of samples in the buffer
     * @return	Returns the number of samples that has been taken care of
     *
     * This function is used to write audio into this audio sink. If it
     * returns 0, no more samples could be written.
     * If the returned number of written samples is lower than the count
     * parameter value, the sink is not ready to accept more samples.
     * In this case, the audio source requires sample buffering to temporarily
     * store samples that are not immediately accepted by the sink.
     * The writeSamples function should be called on source buffer updates
     * and after a source output request has been received through the
     * requestSamples function.
     * This function is normally only called from a connected source object.
     */
    virtual int writeSamples(const float *samples, int count);
    
    /**
     * @brief 	Tell the sink to flush the previously written samples
     *
     * This function is used to tell the sink to flush previously written
     * samples. When done flushing, the sink should call the
     * sourceAllSamplesFlushed function.
     * This function is normally only called from a connected source object.
     */
    virtual void flushSamples(void);

    /**
     * @brief Resume audio output to the sink
     * 
     * This function will be called when the registered audio sink is ready
     * to accept more samples.
     * This function is normally only called from a connected sink object.
     */
    virtual void resumeOutput(void);
    
    /**
     * @brief Setting GSM as only codec for echolink connections
     *
     * This function can be called when SvxLink is installed and running
     * on a system with smaller cpu to keep the load low.
     */
    void setUseGsmOnly(void);

  protected:
    /**
     * @brief The registered sink has flushed all samples
     *
     * This function will be called when all samples have been flushed in the
     * registered sink. If it is not reimplemented, a handler must be set
     * that handle the function call.
     * This function is normally only called from a connected sink object.
     */
    virtual void allSamplesFlushed(void);

    
  private:
    struct Private;

    static const int  	KEEP_ALIVE_TIME       	= 10000;
    static const int  	MAX_CONNECT_RETRY_CNT 	= 5;
    static const int  	CON_TIMEOUT_TIME      	= 50000;
    static const int  	RX_INDICATOR_POLL_TIME  = 100;  // 10 times/s
    static const int  	RX_INDICATOR_SLACK      = 100;  // 100ms extra time
    static const int  	RX_INDICATOR_MAX_TIME   = 1000; // Max 1s timeout
    static const int    FRAME_COUNT             = 4;
    static const int  	BUFFER_SIZE      	= FRAME_COUNT*160;
    static const int    BLOCK_TIME              = FRAME_COUNT*1000*160/8000;

    bool      	      	init_ok;
    unsigned char      	sdes_packet[1500];
    int       	      	sdes_length;
    State     	      	state;
    gsm       	      	gsmh;
    uint16_t    	next_audio_seq;
    Async::Timer *	keep_alive_timer;
    int       	      	connect_retry_cnt;
    Async::Timer *      con_timeout_timer;
    std::string    	callsign;
    std::string    	name;
    std::string    	local_stn_info;
    short		receive_buffer[BUFFER_SIZE];
    short		send_buffer[BUFFER_SIZE];
    int       	      	send_buffer_cnt;
    Async::IpAddress  	remote_ip;
    Async::Timer *    	rx_indicator_timer;
    std::string       	remote_name;
    std::string       	remote_call;
    bool		is_remote_initiated;
    bool      	      	receiving_audio;
    bool                use_gsm_only;
    Private             *p;
    int                 rx_timeout_left;

    Qso(const Qso&);
    Qso& operator=(const Qso&);
    void printData(const unsigned char *buf, int len);
    void handleCtrlInput(unsigned char *buf, int len);
    inline void handleByePacket(unsigned char *buf, int len);
    inline void handleSdesPacket(unsigned char *buf, int len);
    void handleAudioInput(unsigned char *buf, int len);
    inline void handleNonAudioPacket(unsigned char *buf, int len);
    inline void handleAudioPacket(unsigned char *buf, int len);
    void micAudioRead(void *buf, size_t len);
    bool sendSdesPacket(void);
    void sendKeepAlive(Async::Timer *timer);
    void setState(State state);
    void connectionTimeout(Async::Timer *timer);
    bool setupConnection(void);
    void cleanupConnection(void);
    bool sendVoicePacket(void);
    void checkRxActivity(Async::Timer *timer);
    bool sendByePacket(void);
    
};  /* class Qso */


} /* namespace */

#endif /* ECHOLINK_QSO_INCLUDED */



/*
 * This file has not been truncated
 */