same fixes, some cleanup, some server list implementation

This commit is contained in:
Volker Fischer 2011-03-31 18:25:14 +00:00
parent d470a0bb68
commit c8731e6be6
14 changed files with 89 additions and 101 deletions

View File

@ -1,5 +1,5 @@
/******************************************************************************\
* Copyright (c) 2004-2010
* Copyright (c) 2004-2011
*
* Author(s):
* Volker Fischer
@ -48,7 +48,7 @@ void CSound::OpenJack()
jack_on_shutdown ( pJackClient, shutdownCallback, this );
// TEST check sample rate, if not correct, just fire error
if ( jack_get_sample_rate ( pJackClient ) != SYSTEM_SAMPLE_RATE )
if ( jack_get_sample_rate ( pJackClient ) != SYSTEM_SAMPLE_RATE_HZ )
{
throw CGenErr ( tr ( "Jack server sample rate is different from "
"required one" ) );

View File

@ -1,5 +1,5 @@
/******************************************************************************\
* Copyright (c) 2004-2010
* Copyright (c) 2004-2011
*
* Author(s):
* Volker Fischer

View File

@ -1,5 +1,5 @@
/******************************************************************************\
* Copyright (c) 2004-2010
* Copyright (c) 2004-2011
*
* Author(s):
* Volker Fischer
@ -142,7 +142,7 @@ void CSound::OpenCoreAudio()
// set up stream format
AudioStreamBasicDescription streamFormat;
streamFormat.mSampleRate = SYSTEM_SAMPLE_RATE;
streamFormat.mSampleRate = SYSTEM_SAMPLE_RATE_HZ;
streamFormat.mFormatID = kAudioFormatLinearPCM;
streamFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger;
streamFormat.mFramesPerPacket = 1;
@ -183,12 +183,12 @@ void CSound::OpenCoreAudio()
&inputSampleRate,
&size );
if ( static_cast<int> ( inputSampleRate ) != SYSTEM_SAMPLE_RATE )
if ( static_cast<int> ( inputSampleRate ) != SYSTEM_SAMPLE_RATE_HZ )
{
throw CGenErr ( QString ( tr ( "Current system audio input device sample "
"rate of %1 Hz is not supported. Please open the Audio-MIDI-Setup in "
"Applications->Utilities and try to set a sample rate of %2 Hz." ) ).arg (
static_cast<int> ( inputSampleRate ) ).arg ( SYSTEM_SAMPLE_RATE ) );
static_cast<int> ( inputSampleRate ) ).arg ( SYSTEM_SAMPLE_RATE_HZ ) );
}
// check output device sample rate
@ -201,12 +201,12 @@ void CSound::OpenCoreAudio()
&outputSampleRate,
&size );
if ( static_cast<int> ( outputSampleRate ) != SYSTEM_SAMPLE_RATE )
if ( static_cast<int> ( outputSampleRate ) != SYSTEM_SAMPLE_RATE_HZ )
{
throw CGenErr ( QString ( tr ( "Current system audio output device sample "
"rate of %1 Hz is not supported. Please open the Audio-MIDI-Setup in "
"Applications->Utilities and try to set a sample rate of %2 Hz." ) ).arg (
static_cast<int> ( outputSampleRate ) ).arg ( SYSTEM_SAMPLE_RATE ) );
static_cast<int> ( outputSampleRate ) ).arg ( SYSTEM_SAMPLE_RATE_HZ ) );
}
// allocate memory for buffer struct

View File

@ -1,5 +1,5 @@
/******************************************************************************\
* Copyright (c) 2004-2010
* Copyright (c) 2004-2011
*
* Author(s):
* Volker Fischer

View File

@ -61,7 +61,6 @@ public:
// we have to make "server" the default since I do not see a chance to
// use constructor initialization in the server for a vector of channels
CChannel ( const bool bNIsServer = true );
virtual ~CChannel() {}
EPutDataStat PutData ( const CVector<uint8_t>& vecbyData,
int iNumBytes );
@ -197,7 +196,6 @@ class CConnectionLessChannel : public QObject
public:
CConnectionLessChannel();
virtual ~CConnectionLessChannel() {}
bool ParseConnectionLessMessage ( const CVector<uint8_t>& vecbyData,
const int iNumBytes,

View File

@ -83,7 +83,6 @@ class CClient : public QObject
public:
CClient ( const quint16 iPortNumber );
virtual ~CClient() {}
void Start();
void Stop();

View File

@ -56,7 +56,6 @@ class CLlconServerDlg : public QDialog, private Ui_CLlconServerDlgBase
public:
CLlconServerDlg ( CServer* pNServP, QWidget* parent = 0 );
virtual ~CLlconServerDlg() {}
protected:
QTimer Timer;

View File

@ -107,7 +107,6 @@ public:
const QString& strHTMLStatusFileName,
const QString& strHistoryFileName,
const QString& strServerNameForHTMLStatusFile );
virtual ~CServer() {}
void Start();
void Stop();

View File

@ -24,3 +24,37 @@
#include "serverlist.h"
/* Implementation *************************************************************/
CServerListManager::CServerListManager ( const bool NbEbld )
: bEnabled ( NbEbld )
{
// connections -------------------------------------------------------------
QObject::connect ( &TimerPollList, SIGNAL ( timeout() ),
this, SLOT ( OnTimerPollList() ) );
// Timers ------------------------------------------------------------------
// start timer for polling the server list
if ( bEnabled )
{
// 1 minute = 60 * 1000 ms
TimerPollList.start ( SERVLIST_POLL_TIME_MINUTES * 60000 );
}
}
void CServerListManager::OnTimerPollList()
{
QMutexLocker locker ( &Mutex );
// check all list entries if they are still valid
for ( int iIdx = 0; iIdx < ServerList.size(); iIdx++ )
{
// 1 minute = 60 * 1000 ms
if ( ServerList[iIdx].RegisterTime.elapsed() >
( SERVLIST_TIME_OUT_MINUTES * 60000 ) )
{
// remove this list entry
ServerList.removeAt ( iIdx );
}
}
}

View File

@ -4,6 +4,41 @@
* Author(s):
* Volker Fischer
*
Currently, if you want to run a private server, you have to open the firewall of
your computer at the correct ports and introduce a port forwarding at your
router to get it work. Using a central server simplifies the process. The user
who wants to run a llcon server just registers his server a the central server
and a mechanism implemented in the protocol opens the firewall similar to STUN.
REQUIREMENTS:
The client sets the URL of the central llcon server and can get a list of all
currently activated and registered private llcon servers. If the user clicks on
the server of his choice, he gets connected to this server.
The server list must be available in both cases: if the client is connected to
the central server or not.
The server list contains the name of the server, an optional topic, an optional
location, the number of connected users and a ping time which is updated as
long as the server list is visible (similar to the ping measurement in the
general settings dialog). Additional information may be also present in the list
like reliability of the server, etc.
CONNECTION PROCESS:
The private server contacts the central server and registers through some
protocol mechanism.
If a client requests the server list from the central server, the central server
sends the IP address of the client to each registered private servers so that
they can immediately send a "firewall opening" UDP packet to this IP address.
If the client now sends ping messages to each of the private servers in the
list, the firewalls and routers are prepared for receiving UDP packets from this
IP address and will tunnel it through. Note: this mechanism will not work in a
private network.
******************************************************************************
*
* This program is free software; you can redistribute it and/or modify it under
@ -28,79 +63,10 @@
#include <qlocale.h>
#include <qlist.h>
#include <qtimer.h>
#include <qmutex.h>
#include "global.h"
#include "util.h"
/*
MAIN POINTS:
- Currently, if you want to run a private server, you have to open the
firewall of your computer at the correct ports and introduce a port
forwarding at your router to get it work. Using a central server would
simplify the process. The user who wants to run a llcon server just
registers his server a the central server and a mechanism implemented
in the protocol opens the firewall similar to STUN.
- Having private llcon servers will increase the probability that a server
is in the required minimum range of 1000 km of the clients position.
- The problem is that private servers are not reliable, they can be turned
off at any time.
- The private server owner maybe only wants to enable his friends to use
the server but if it is registered at the central server, everybody sees
the new server. Maybe an authentication mechanism might be implemented for
this purpose.
REQUIREMENTS:
- The client sets the URL of the central llcon server and can get a list of
all currently activated and registered private llcon servers. If the user
clicks on the server of his choice, he gets connected to this server.
- The server list must be available in both cases: if the client is connected
to the central server or not.
- The server list contains the name of the server, an optional topic, an
optional location, the number of connected users and a ping time which is
updated as long as the server list is visible (similar to the ping measurement
in the general settings dialog). Additional information may be also present
in the list like reliability of the server, etc.
- If a user starts the server for the first time, he gets automatically asked
if he wants to register his server at the central server. His choice will be
stored in an ini-file.
CONNECTION PROCESS:
* The private server contacts the central server and registers through some
protocol mechanism.
* If a client requests the server list from the central server, the central
server sends the IP address of the client to each registered private servers
so that they can immediately send a "firewall opening" UDP packet to this IP
address. If the client now sends ping messages to each of the private servers
in the list, the firewalls and routers are prepared for receiving UDP packets
from this IP address and will tunnel it through. Note: this mechanism will not
work in a private network.
* The central server polls all registered private servers in regular intervals
to make sure they are still present. If a private server is shut down, it
sends a shutdown message to the central server.
CONSEQUENCES:
- A new connection type is required: connection without transferring audio data,
just protocol.
- It must be possible to maintain the regular and new connection at the same
time.
- It has to be checked for how long a firewall is opened after the "firewall
opening" UDP packet was send. Maybe this message has to be repeated in regular
intervals (but not too long since maybe the client does not even want to connect
to this particular private server).
*/
/* Classes ********************************************************************/
class CServerListProperties
@ -133,8 +99,6 @@ public:
iMaxNumClients ( NiMaxNumClients ),
bPermanentOnline ( NbPermOnline ) { RegisterTime.start(); }
virtual ~CServerListProperties() {}
public:
// time on which the entry was registered
QTime RegisterTime;
@ -171,15 +135,16 @@ class CServerListManager : public QObject
Q_OBJECT
public:
CServerListManager() {}
virtual ~CServerListManager() {}
CServerListManager ( const bool NbEbld );
protected:
QTimer TimerPollList;
QMutex Mutex;
QList<CServerListProperties> ServerList;
bool bEnabled;
public slots:
void OnTimerPollList() { /* TODO */ }
void OnTimerPollList();
};
#endif /* !defined ( SERVERLIST_HOIJH8OUWEF_WFEIOBU_3_43445KJIUHF1912__INCLUDED_ ) */

View File

@ -56,8 +56,6 @@ public:
const quint16 iPortNumber )
: pServer ( pNServP ), bIsClient ( false ) { Init ( iPortNumber ); }
virtual ~CSocket() {}
void SendPacket ( const CVector<uint8_t>& vecbySendBuf,
const CHostAddress& HostAddr );

View File

@ -41,7 +41,6 @@ public:
void* pParg ) : fpProcessCallback ( fpNewProcessCallback ),
pProcessCallbackArg ( pParg ), bRun ( false ),
bIsCallbackAudioInterface ( bNewIsCallbackAudioInterface ) {}
virtual ~CSoundBase() {}
virtual int Init ( const int iNewPrefMonoBufferSize );
virtual void Start();

View File

@ -74,9 +74,11 @@ inline short Double2Short ( const double dInput )
}
// debug error handling
void DebugError ( const QString& pchErDescr, const QString& pchPar1Descr,
const double dPar1, const QString& pchPar2Descr,
const double dPar2 );
void DebugError ( const QString& pchErDescr,
const QString& pchPar1Descr,
const double dPar1,
const QString& pchPar2Descr,
const double dPar2 );
/******************************************************************************\
@ -88,7 +90,6 @@ public:
CVector() : iVectorSize ( 0 ) { pData = this->begin(); }
CVector ( const int iNeSi ) { Init(iNeSi); }
CVector ( const int iNeSi, const TData tInVa ) { Init ( iNeSi, tInVa ); }
virtual ~CVector() {}
/* Copy constructor: The order of the initialization list must not be
changed. First, the base class must be initialized, then the pData
@ -369,7 +370,6 @@ class CStereoSignalLevelMeter
{
public:
CStereoSignalLevelMeter() { Reset(); }
virtual ~CStereoSignalLevelMeter() {}
void Update ( CVector<short>& vecsAudio );
double MicLevelLeft() { return CalcLogResult ( dCurLevelL ); }
@ -528,7 +528,6 @@ class CCRC
public:
CCRC() : iPoly ( ( 1 << 5 ) | ( 1 << 12 ) ), iBitOutMask ( 1 << 16 )
{ Reset(); }
virtual ~CCRC() {}
void Reset();
void AddByte ( const uint8_t byNewInput );

View File

@ -37,8 +37,6 @@ public:
CSound ( void (*fpNewCallback) ( CVector<int16_t>& psData, void* arg ), void* arg ) :
CSoundBase ( true, fpNewCallback, arg ), iVSTMonoBufferSize ( 0 ) {}
virtual ~CSound() {}
// special VST functions
void SetMonoBufferSize ( const int iNVBS ) { iVSTMonoBufferSize = iNVBS; }
void VSTProcessCallback()