Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions docs/JSON-RPC.md
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,41 @@ Results:
| result | string | Always "acknowledged". To check if the recording was restarted or if there is any error, call `jamulusserver/getRecorderStatus` again. |


### jamulusserver/sendBroadcastChat

Send a chat message to all connected clients. Messages from the server are not escaped and can contain HTML as defined for QTextBrowser.

Parameters:

| Name | Type | Description |
| --- | --- | --- |
| params.textMessage | string | The chat message to be sent. |

Results:

| Name | Type | Description |
| --- | --- | --- |
| result | string | Always "ok". |


### jamulusserver/sendChat

Send a chat message to the channel identified by a specificc address. The chat should be pre-escaped if necessary prior to calling this method.

Parameters:

| Name | Type | Description |
| --- | --- | --- |
| params.address | string | The full channel IP address as a string XXX.XXX.XXX.XXX:PPPPP |
| params.textMessage | string | The chat message to be sent. |

Results:

| Name | Type | Description |
| --- | --- | --- |
| result | string | "ok" if channel could be determined and message sent. |


### jamulusserver/setRecordingDirectory

Sets the server recording directory.
Expand Down Expand Up @@ -445,3 +480,70 @@ Parameters:
| params | object | No parameters (empty object). |


### jamulusserver/chatReceived

Emitted when a chat text is received. Server-generated chats are not included in this notification.

Parameters:

| Name | Type | Description |
| --- | --- | --- |
| params.id | string | The channel ID generating the chat. |
| params.name | string | The user name generating the chat. |
| params.address | number | The address of the channel generating the chat. |
| params.stamp | string | The date/time of the chat (ISO 8601 format, in server configured timezone). |
| params.text | string | The chat text. |


### jamulusserver/clientConnect

Emitted when a new client connects to the server.

Results:

| Name | Type | Description |
| --- | --- | --- |
| result.name | string | The client’s name. |
| result.address | string | The client’s address (ip:port). |
| result.instrumentCode | number | The id of the user's instrument. |
| result.instrumentName | number | The text name of the user's instrument. |
| result.city | string | The user's city name. |
| result.countryCode | number | The id of the country specified by the user (see QLocale::Country). |
| result.countryName | number | The text name of the user's country (see QLocale::Country). |
| result.skillLevelCode | number | The user's skill level id. |
| result.skillLevelName | number | The user's skill level text name. |


### jamulusserver/clientDisconnect

Emitted when a client disconnects from the server.

Results:

| Name | Type | Description |
| --- | --- | --- |
| result.id | string | The client channel id. |
| result.name | string | The client’s name. |
| result.address | string | The client’s address (ip:port). |


### jamulusserver/clientInfoChanged

Emitted when a client changes their information (name, instrument, country, city, skill level).

Results:

| Name | Type | Description |
| --- | --- | --- |
| result.oldName | string | The client’s name just prior to this change. |
| result.name | string | The client’s name (new one, if change). |
| result.address | string | The client’s address (ip:port). |
| result.instrumentCode | number | The id of the user's instrument. |
| result.instrumentName | number | The text name of the user's instrument. |
| result.city | string | The user's city name. |
| result.countryCode | number | The id of the country specified by the user (see QLocale::Country). |
| result.countryName | number | The text name of the user's country (see QLocale::Country). |
| result.skillLevelCode | number | The user's skill level id. |
| result.skillLevelName | number | The user's skill level text name. |


17 changes: 16 additions & 1 deletion src/channel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
*
\******************************************************************************/

#include "rpcserver.h" // Here and not in channel.h to avoid circular issue
#include "channel.h"

// CChannel implementation *****************************************************
Expand Down Expand Up @@ -337,10 +338,24 @@ void CChannel::SetChanInfo ( const CChannelCoreInfo& NChanInf )
// apply value (if a new channel or different from previous one)
if ( !bIsIdentified || ChannelInfo != NChanInf )
{
bIsIdentified = true; // Indicate we have received channel info

QString strOldName = ChannelInfo.strName;

ChannelInfo = NChanInf;

#ifndef NO_JSON_RPC
if ( !bIsIdentified )
{
CRpcLogging::getInstance().rpcOnNewConnection ( *this );
}
else
{
CRpcLogging::getInstance().rpcOnUpdateConnection ( *this, strOldName );
}
#endif

bIsIdentified = true; // Indicate we have received channel info

// fire message that the channel info has changed
emit ChanInfoHasChanged();
}
Expand Down
1 change: 1 addition & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -980,6 +980,7 @@ int main ( int argc, char** argv )
if ( pRpcServer )
{
new CServerRpc ( &Server, pRpcServer, pRpcServer );
CRpcLogging::getInstance().setRpcEnabled();
}
#endif

Expand Down
37 changes: 37 additions & 0 deletions src/rpcserver.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ class CRpcServer : public QObject
// Our errors
static const int iErrAuthenticationFailed = 400;
static const int iErrUnauthenticated = 401;
static const int iErrChannelNotFound = 402;

private:
int iPort;
Expand All @@ -82,3 +83,39 @@ class CRpcServer : public QObject
protected slots:
void OnNewConnection();
};

/**
* Singleton class that will be used as a consolidation point
* for signals emitting from multi-instance classes (ie, channels)
*/

#include "channel.h"

class CRpcLogging : public QObject
{

Q_OBJECT

private:
CRpcLogging() {}

bool rpcEnabled = false;

public:
static CRpcLogging& getInstance()
{
static CRpcLogging instance;
return instance;
}

bool isRpcEnabled() { return rpcEnabled; }
void setRpcEnabled() { rpcEnabled = true; }
void setRpcDisabled() { rpcEnabled = false; }

void rpcOnNewConnection ( CChannel& channel ) { emit rpcClientConnected ( channel ); }
void rpcOnUpdateConnection ( CChannel& channel, const QString strOldName ) { emit rpcUpdateConnection ( channel, strOldName ); }

signals:
void rpcClientConnected ( CChannel& channel );
void rpcUpdateConnection ( CChannel& channel, const QString strOldName );
};
59 changes: 52 additions & 7 deletions src/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -858,6 +858,9 @@ void CServer::DecodeReceiveData ( const int iChanCnt, const int iNumClients )
// and emit the client disconnected signal
if ( eGetStat == GS_CHAN_NOW_DISCONNECTED )
{
// RPC - send the channel object
emit rpcClientDisconnected ( iCurChanID, vecChannels[iCurChanID].GetName(), vecChannels[iCurChanID].GetAddress() );

if ( JamController.GetRecordingEnabled() )
{
emit ClientDisconnected ( iCurChanID ); // TODO do this outside the mutex lock?
Expand Down Expand Up @@ -1231,28 +1234,69 @@ void CServer::CreateAndSendChanListForThisChan ( const int iCurChanID )
vecChannels[iCurChanID].CreateConClientListMes ( vecChanInfo );
}

bool CServer::CreateAndSendPreEscapedChatText ( const int iChannel, const QString& strChatText )
{
if ( iChannel < 0 || iChannel > iMaxNumChannels )
return false;

if ( vecChannels[iChannel].IsConnected() )
{
vecChannels[iChannel].CreateChatTextMes ( strChatText );
return true;
}

return false;
}

void CServer::CreateAndSendChatTextForAllConChannels ( const int iCurChanID, const QString& strChatText )
{
QString strActualMessageText;

// Create message which is sent to all connected clients -------------------
// get client name
QString ChanName = vecChannels[iCurChanID].GetName();

// add time and name of the client at the beginning of the message text and
// use different colors
QString sCurColor = vstrChatColors[iCurChanID % vstrChatColors.Size()];
QString strChanName = ( iCurChanID < 0 ) ? "** Server **" : vecChannels[iCurChanID].GetName();
QString strChanAddr = ( iCurChanID < 0 ) ? "" : vecChannels[iCurChanID].GetAddress().toString ( CHostAddress::SM_IP_PORT );
QString strChatTime = QDateTime::currentDateTime().toString ( Qt::ISODate );

const QString strActualMessageText = "<font color=\"" + sCurColor + "\">(" + QTime::currentTime().toString ( "hh:mm:ss AP" ) + ") <b>" +
ChanName.toHtmlEscaped() + "</b></font> " + strChatText.toHtmlEscaped();
if ( iCurChanID < 0 ) // A server-push chat message
{
// Server can send HTML messages, so no escaping here.

// The decision to prepend "Server Message" to the message here is for consistency of src location.

strActualMessageText =
"<font color=\"#f0f\">(" + QTime::currentTime().toString ( "hh:mm:ss AP" ) + ") <b>Server Message:</b></font> " + strChatText;
}
else
{

// add time and name of the client at the beginning of the message text and
// use different colors

QString sCurColor = vstrChatColors[iCurChanID % vstrChatColors.Size()];

strActualMessageText = "<font color=\"" + sCurColor + "\">(" + QTime::currentTime().toString ( "hh:mm:ss AP" ) + ") <b>" +
strChanName.toHtmlEscaped() + "</b></font> " + strChatText.toHtmlEscaped();
}

// Send chat text to all connected clients ---------------------------------
for ( int i = 0; i < iMaxNumChannels; i++ )
{
// TODO: This section can be refactored to call CreateAndSendPreEscapedChatText if desired
// as the code was duplicated there...

if ( vecChannels[i].IsConnected() )
{
// send message
vecChannels[i].CreateChatTextMes ( strActualMessageText );
}
}

// Only emit signal for client generated chats, not server generated
if ( iCurChanID >= 0 )
{
emit rpcChatSent ( iCurChanID, strChanName, strChanAddr, strChatTime, strChatText );
}
}

void CServer::CreateAndSendRecorderStateForAllConChannels()
Expand Down Expand Up @@ -1490,6 +1534,7 @@ void CServer::GetConCliParam ( CVector<CHostAddress>& vecHostAddresses,
vecsName[i] = vecChannels[i].GetName();
veciJitBufNumFrames[i] = vecChannels[i].GetSockBufNumFrames();
veciNetwFrameSizeFact[i] = vecChannels[i].GetNetwFrameSizeFact();
vecChanInfo[i] = vecChannels[i].GetChanInfo();
}
}
}
Expand Down
12 changes: 9 additions & 3 deletions src/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,11 +168,16 @@ class CServer : public QObject, public CServerSlots<MAX_NUM_CHANNELS>
void SetEnableDelayPanning ( bool bDelayPanningOn ) { bDelayPan = bDelayPanningOn; }
bool IsDelayPanningEnabled() { return bDelayPan; }

bool CreateAndSendPreEscapedChatText ( const int iChannel, const QString& strChatText );

// Methods formally protected, now public so they can be accessed via RPC
virtual void CreateAndSendChatTextForAllConChannels ( const int iCurChanID, const QString& strChatText );
int FindChannel ( const CHostAddress& CheckAddr, const bool bAllowNew = false );

protected:
// access functions for actual channels
bool IsConnected ( const int iChanNum ) { return vecChannels[iChanNum].IsConnected(); }

int FindChannel ( const CHostAddress& CheckAddr, const bool bAllowNew = false );
void InitChannel ( const int iNewChanID, const CHostAddress& InetAddr );
void FreeChannel ( const int iCurChanID );
void DumpChannels ( const QString& title );
Expand All @@ -181,8 +186,6 @@ class CServer : public QObject, public CServerSlots<MAX_NUM_CHANNELS>
virtual void CreateAndSendChanListForAllConChannels();
virtual void CreateAndSendChanListForThisChan ( const int iCurChanID );

virtual void CreateAndSendChatTextForAllConChannels ( const int iCurChanID, const QString& strChatText );

virtual void CreateOtherMuteStateChanged ( const int iCurChanID, const int iOtherChanID, const bool bIsMuted );

virtual void CreateAndSendJitBufMessage ( const int iCurChanID, const int iNNumFra );
Expand Down Expand Up @@ -311,6 +314,7 @@ class CServer : public QObject, public CServerSlots<MAX_NUM_CHANNELS>
void Started();
void Stopped();
void ClientDisconnected ( const int iChID );
void rpcClientDisconnected ( const int iChID, const QString strName, const CHostAddress HostAddress );
void SvrRegStatusChanged();
void AudioFrame ( const int iChID,
const QString stChName,
Expand All @@ -326,6 +330,8 @@ class CServer : public QObject, public CServerSlots<MAX_NUM_CHANNELS>
void RecordingSessionStarted ( QString sessionDir );
void EndRecorderThread();

void rpcChatSent ( const int iCurChanID, const QString chanName, const QString chanAddr, const QString chatStamp, const QString strChatMessage );

public slots:
void OnTimer();

Expand Down
Loading