mirror of https://github.com/g4klx/MMDVMHost
Start the IAX state machine.
This commit is contained in:
parent
7508e42547
commit
d3725e1f10
256
FMIAXNetwork.cpp
256
FMIAXNetwork.cpp
|
|
@ -32,6 +32,8 @@
|
||||||
|
|
||||||
#include <md5.h>
|
#include <md5.h>
|
||||||
|
|
||||||
|
#define DEBUG_IAX
|
||||||
|
|
||||||
const unsigned char IAX_PROTO_VERSION = 2U;
|
const unsigned char IAX_PROTO_VERSION = 2U;
|
||||||
|
|
||||||
const unsigned char AST_FRAME_DTMF = 1U;
|
const unsigned char AST_FRAME_DTMF = 1U;
|
||||||
|
|
@ -108,6 +110,9 @@ m_addrLen(0U),
|
||||||
m_debug(debug),
|
m_debug(debug),
|
||||||
m_enabled(false),
|
m_enabled(false),
|
||||||
m_buffer(2000U, "FM Network"),
|
m_buffer(2000U, "FM Network"),
|
||||||
|
m_status(IAXS_DISCONNECTED),
|
||||||
|
m_retryTimer(1000U, 0U, 500U),
|
||||||
|
m_pingTimer(1000U, 20U),
|
||||||
m_timestamp(),
|
m_timestamp(),
|
||||||
m_sCallNo(0U),
|
m_sCallNo(0U),
|
||||||
m_dCallNo(0U),
|
m_dCallNo(0U),
|
||||||
|
|
@ -149,12 +154,29 @@ bool CFMIAXNetwork::open()
|
||||||
|
|
||||||
LogMessage("Opening FM IAX network connection");
|
LogMessage("Opening FM IAX network connection");
|
||||||
|
|
||||||
return m_socket.open(m_addr);
|
bool ret = m_socket.open(m_addr);
|
||||||
|
if (!ret)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ret = writeNew();
|
||||||
|
if (!ret) {
|
||||||
|
m_socket.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_status = IAXS_CONNECTING;
|
||||||
|
m_retryTimer.start();
|
||||||
|
m_dCallNo = 0U;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CFMIAXNetwork::writeStart()
|
bool CFMIAXNetwork::writeStart()
|
||||||
{
|
{
|
||||||
return true;
|
if (m_status != IAXS_CONNECTED)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return writeKey(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CFMIAXNetwork::writeData(const float* data, unsigned int nSamples)
|
bool CFMIAXNetwork::writeData(const float* data, unsigned int nSamples)
|
||||||
|
|
@ -162,16 +184,44 @@ bool CFMIAXNetwork::writeData(const float* data, unsigned int nSamples)
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
assert(nSamples > 0U);
|
assert(nSamples > 0U);
|
||||||
|
|
||||||
|
if (m_status != IAXS_CONNECTED)
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CFMIAXNetwork::writeEnd()
|
bool CFMIAXNetwork::writeEnd()
|
||||||
{
|
{
|
||||||
return true;
|
if (m_status != IAXS_CONNECTED)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return writeKey(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFMIAXNetwork::clock(unsigned int ms)
|
void CFMIAXNetwork::clock(unsigned int ms)
|
||||||
{
|
{
|
||||||
|
m_retryTimer.clock(ms);
|
||||||
|
if (m_retryTimer.isRunning() && m_retryTimer.hasExpired()) {
|
||||||
|
switch (m_status) {
|
||||||
|
case IAXS_CONNECTING:
|
||||||
|
writeNew();
|
||||||
|
break;
|
||||||
|
case IAXS_AUTHORISING:
|
||||||
|
writeAuth();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_retryTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pingTimer.clock(ms);
|
||||||
|
if (m_pingTimer.isRunning() && m_pingTimer.hasExpired()) {
|
||||||
|
writePing();
|
||||||
|
m_pingTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
unsigned char buffer[BUFFER_LENGTH];
|
unsigned char buffer[BUFFER_LENGTH];
|
||||||
|
|
||||||
sockaddr_storage addr;
|
sockaddr_storage addr;
|
||||||
|
|
@ -186,13 +236,96 @@ void CFMIAXNetwork::clock(unsigned int ms)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_enabled)
|
#if !defined(DEBUG_IAX)
|
||||||
return;
|
|
||||||
|
|
||||||
if (m_debug)
|
if (m_debug)
|
||||||
|
#endif
|
||||||
CUtils::dump(1U, "FM IAX Network Data Received", buffer, length);
|
CUtils::dump(1U, "FM IAX Network Data Received", buffer, length);
|
||||||
|
|
||||||
m_buffer.addData(buffer + 32U, length - 32U);
|
unsigned int ts = (buffer[4U] << 24) | (buffer[5U] << 16) | (buffer[6U] << 8) | (buffer[7U] << 0);
|
||||||
|
|
||||||
|
if (compareFrame(buffer, AST_FRAME_IAX, IAX_COMMAND_ACK)) {
|
||||||
|
#if defined(DEBUG_IAX)
|
||||||
|
LogDebug("IAX ACK received");
|
||||||
|
#endif
|
||||||
|
// Grab the destination call number if we don't have it already
|
||||||
|
if (m_dCallNo == 0U)
|
||||||
|
m_dCallNo = ((buffer[0U] << 8) | (buffer[1U] << 0)) & 0x7FFFU;
|
||||||
|
} else if (compareFrame(buffer, AST_FRAME_IAX, IAX_COMMAND_PING)) {
|
||||||
|
#if defined(DEBUG_IAX)
|
||||||
|
LogDebug("IAX PING received");
|
||||||
|
#endif
|
||||||
|
writeAck(ts);
|
||||||
|
writePong(ts);
|
||||||
|
} else if (compareFrame(buffer, AST_FRAME_IAX, IAX_COMMAND_PONG)) {
|
||||||
|
#if defined(DEBUG_IAX)
|
||||||
|
LogDebug("IAX PONG received");
|
||||||
|
#endif
|
||||||
|
writeAck(ts);
|
||||||
|
} else if (compareFrame(buffer, AST_FRAME_IAX, IAX_COMMAND_ACCEPT)) {
|
||||||
|
#if defined(DEBUG_IAX)
|
||||||
|
LogDebug("IAX ACCEPT received");
|
||||||
|
#endif
|
||||||
|
// Grab the destination call number if we don't have it already
|
||||||
|
if (m_dCallNo == 0U)
|
||||||
|
m_dCallNo = ((buffer[0U] << 8) | (buffer[1U] << 0)) & 0x7FFFU;
|
||||||
|
|
||||||
|
writeAck(ts);
|
||||||
|
} else if (compareFrame(buffer, AST_FRAME_IAX, IAX_COMMAND_REGREJ)) {
|
||||||
|
#if defined(DEBUG_IAX)
|
||||||
|
LogDebug("IAX REGREJ received");
|
||||||
|
#endif
|
||||||
|
LogError("Registraton rejected by the IAX gateway");
|
||||||
|
|
||||||
|
m_status = IAXS_DISCONNECTED;
|
||||||
|
m_retryTimer.stop();
|
||||||
|
m_pingTimer.stop();
|
||||||
|
} else if (compareFrame(buffer, AST_FRAME_IAX, IAX_COMMAND_REJECT)) {
|
||||||
|
#if defined(DEBUG_IAX)
|
||||||
|
LogDebug("IAX REJECT received");
|
||||||
|
#endif
|
||||||
|
LogError("Command rejected by the IAX gateway");
|
||||||
|
|
||||||
|
m_status = IAXS_DISCONNECTED;
|
||||||
|
m_retryTimer.stop();
|
||||||
|
m_pingTimer.stop();
|
||||||
|
} else if (compareFrame(buffer, AST_FRAME_IAX, IAX_COMMAND_HANGUP)) {
|
||||||
|
#if defined(DEBUG_IAX)
|
||||||
|
LogDebug("IAX HANGUP received");
|
||||||
|
#endif
|
||||||
|
LogError("Hangup from the IAX gateway");
|
||||||
|
writeAck(ts);
|
||||||
|
|
||||||
|
m_status = IAXS_DISCONNECTED;
|
||||||
|
m_retryTimer.stop();
|
||||||
|
m_pingTimer.stop();
|
||||||
|
} else if (compareFrame(buffer, AST_FRAME_CONTROL, AST_CONTROL_ANSWER)) {
|
||||||
|
#if defined(DEBUG_IAX)
|
||||||
|
LogDebug("IAX ANSWER received");
|
||||||
|
#endif
|
||||||
|
// Grab the destination call number if we don't have it already
|
||||||
|
if (m_dCallNo == 0U)
|
||||||
|
m_dCallNo = ((buffer[0U] << 8) | (buffer[1U] << 0)) & 0x7FFFU;
|
||||||
|
|
||||||
|
writeAck(ts);
|
||||||
|
|
||||||
|
m_status = IAXS_CONNECTED;
|
||||||
|
m_retryTimer.stop();
|
||||||
|
m_pingTimer.start();
|
||||||
|
} else if (compareFrame(buffer, AST_FRAME_IAX, IAX_COMMAND_LAGRQ)) {
|
||||||
|
#if defined(DEBUG_IAX)
|
||||||
|
LogDebug("IAX LAGRQ received");
|
||||||
|
#endif
|
||||||
|
writeAck(ts);
|
||||||
|
writeLagRp();
|
||||||
|
} else if ((buffer[0U] & 0x80U) == 0x00U) {
|
||||||
|
#if defined(DEBUG_IAX)
|
||||||
|
LogDebug("IAX audio received");
|
||||||
|
#endif
|
||||||
|
if (!m_enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_buffer.addData(buffer + 4U, length - 4U);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int CFMIAXNetwork::readData(float* out, unsigned int nOut)
|
unsigned int CFMIAXNetwork::readData(float* out, unsigned int nOut)
|
||||||
|
|
@ -225,8 +358,15 @@ void CFMIAXNetwork::reset()
|
||||||
|
|
||||||
void CFMIAXNetwork::close()
|
void CFMIAXNetwork::close()
|
||||||
{
|
{
|
||||||
|
writeHangup();
|
||||||
|
|
||||||
m_socket.close();
|
m_socket.close();
|
||||||
|
|
||||||
|
m_status = IAXS_DISCONNECTED;
|
||||||
|
|
||||||
|
m_retryTimer.stop();
|
||||||
|
m_pingTimer.stop();
|
||||||
|
|
||||||
LogMessage("Closing FM IAX network connection");
|
LogMessage("Closing FM IAX network connection");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -240,8 +380,11 @@ void CFMIAXNetwork::enable(bool enabled)
|
||||||
m_enabled = enabled;
|
m_enabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CFMIAXNetwork::writeCall()
|
bool CFMIAXNetwork::writeNew()
|
||||||
{
|
{
|
||||||
|
#if defined(DEBUG_IAX)
|
||||||
|
LogDebug("IAX NEW sent");
|
||||||
|
#endif
|
||||||
unsigned short sCall = ++m_sCallNo | 0x8000U;
|
unsigned short sCall = ++m_sCallNo | 0x8000U;
|
||||||
|
|
||||||
m_timestamp.start();
|
m_timestamp.start();
|
||||||
|
|
@ -301,7 +444,9 @@ bool CFMIAXNetwork::writeCall()
|
||||||
buffer[length++] = 0x00U;
|
buffer[length++] = 0x00U;
|
||||||
buffer[length++] = AST_FORMAT_ULAW;
|
buffer[length++] = AST_FORMAT_ULAW;
|
||||||
|
|
||||||
|
#if !defined(DEBUG_IAX)
|
||||||
if (m_debug)
|
if (m_debug)
|
||||||
|
#endif
|
||||||
CUtils::dump(1U, "FM IAX Network Data Sent", buffer, length);
|
CUtils::dump(1U, "FM IAX Network Data Sent", buffer, length);
|
||||||
|
|
||||||
m_oSeqNo++;
|
m_oSeqNo++;
|
||||||
|
|
@ -309,8 +454,11 @@ bool CFMIAXNetwork::writeCall()
|
||||||
return m_socket.write(buffer, length, m_addr, m_addrLen);
|
return m_socket.write(buffer, length, m_addr, m_addrLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CFMIAXNetwork::writeAuth()
|
bool CFMIAXNetwork::writeAuthRep()
|
||||||
{
|
{
|
||||||
|
#if defined(DEBUG_IAX)
|
||||||
|
LogDebug("IAX AUTHREP sent");
|
||||||
|
#endif
|
||||||
char hash[MD5_DIGEST_STRING_LENGTH];
|
char hash[MD5_DIGEST_STRING_LENGTH];
|
||||||
::MD5Data((unsigned char*)m_password.c_str(), m_password.size(), hash);
|
::MD5Data((unsigned char*)m_password.c_str(), m_password.size(), hash);
|
||||||
|
|
||||||
|
|
@ -342,7 +490,9 @@ bool CFMIAXNetwork::writeAuth()
|
||||||
buffer[13U] = MD5_DIGEST_STRING_LENGTH;
|
buffer[13U] = MD5_DIGEST_STRING_LENGTH;
|
||||||
::memcpy(buffer + 14U, hash, MD5_DIGEST_STRING_LENGTH);
|
::memcpy(buffer + 14U, hash, MD5_DIGEST_STRING_LENGTH);
|
||||||
|
|
||||||
|
#if !defined(DEBUG_IAX)
|
||||||
if (m_debug)
|
if (m_debug)
|
||||||
|
#endif
|
||||||
CUtils::dump(1U, "FM IAX Network Data Sent", buffer, 14U + MD5_DIGEST_STRING_LENGTH);
|
CUtils::dump(1U, "FM IAX Network Data Sent", buffer, 14U + MD5_DIGEST_STRING_LENGTH);
|
||||||
|
|
||||||
m_oSeqNo++;
|
m_oSeqNo++;
|
||||||
|
|
@ -352,6 +502,9 @@ bool CFMIAXNetwork::writeAuth()
|
||||||
|
|
||||||
bool CFMIAXNetwork::writeKey(bool key)
|
bool CFMIAXNetwork::writeKey(bool key)
|
||||||
{
|
{
|
||||||
|
#if defined(DEBUG_IAX)
|
||||||
|
LogDebug("IAX KEY/UNKEY sent");
|
||||||
|
#endif
|
||||||
unsigned short sCall = m_sCallNo | 0x8000U;
|
unsigned short sCall = m_sCallNo | 0x8000U;
|
||||||
unsigned int ts = m_timestamp.elapsed();
|
unsigned int ts = m_timestamp.elapsed();
|
||||||
|
|
||||||
|
|
@ -376,7 +529,9 @@ bool CFMIAXNetwork::writeKey(bool key)
|
||||||
|
|
||||||
buffer[11U] = key ? AST_CONTROL_KEY : AST_CONTROL_UNKEY;
|
buffer[11U] = key ? AST_CONTROL_KEY : AST_CONTROL_UNKEY;
|
||||||
|
|
||||||
|
#if !defined(DEBUG_IAX)
|
||||||
if (m_debug)
|
if (m_debug)
|
||||||
|
#endif
|
||||||
CUtils::dump(1U, "FM IAX Network Data Sent", buffer, 12U);
|
CUtils::dump(1U, "FM IAX Network Data Sent", buffer, 12U);
|
||||||
|
|
||||||
m_oSeqNo++;
|
m_oSeqNo++;
|
||||||
|
|
@ -386,6 +541,9 @@ bool CFMIAXNetwork::writeKey(bool key)
|
||||||
|
|
||||||
bool CFMIAXNetwork::writePing()
|
bool CFMIAXNetwork::writePing()
|
||||||
{
|
{
|
||||||
|
#if defined(DEBUG_IAX)
|
||||||
|
LogDebug("IAX PING sent");
|
||||||
|
#endif
|
||||||
unsigned short sCall = m_sCallNo | 0x8000U;
|
unsigned short sCall = m_sCallNo | 0x8000U;
|
||||||
unsigned int ts = m_timestamp.elapsed();
|
unsigned int ts = m_timestamp.elapsed();
|
||||||
|
|
||||||
|
|
@ -410,7 +568,9 @@ bool CFMIAXNetwork::writePing()
|
||||||
|
|
||||||
buffer[11U] = IAX_COMMAND_PING;
|
buffer[11U] = IAX_COMMAND_PING;
|
||||||
|
|
||||||
|
#if !defined(DEBUG_IAX)
|
||||||
if (m_debug)
|
if (m_debug)
|
||||||
|
#endif
|
||||||
CUtils::dump(1U, "FM IAX Network Data Sent", buffer, 12U);
|
CUtils::dump(1U, "FM IAX Network Data Sent", buffer, 12U);
|
||||||
|
|
||||||
m_oSeqNo++;
|
m_oSeqNo++;
|
||||||
|
|
@ -420,6 +580,9 @@ bool CFMIAXNetwork::writePing()
|
||||||
|
|
||||||
bool CFMIAXNetwork::writePong(unsigned int ts)
|
bool CFMIAXNetwork::writePong(unsigned int ts)
|
||||||
{
|
{
|
||||||
|
#if defined(DEBUG_IAX)
|
||||||
|
LogDebug("IAX PONG sent");
|
||||||
|
#endif
|
||||||
unsigned short sCall = m_sCallNo | 0x8000U;
|
unsigned short sCall = m_sCallNo | 0x8000U;
|
||||||
|
|
||||||
unsigned char buffer[50U];
|
unsigned char buffer[50U];
|
||||||
|
|
@ -483,7 +646,9 @@ bool CFMIAXNetwork::writePong(unsigned int ts)
|
||||||
buffer[44U] = (m_rxOOO << 8) & 0xFFU;
|
buffer[44U] = (m_rxOOO << 8) & 0xFFU;
|
||||||
buffer[45U] = (m_rxOOO << 0) & 0xFFU;
|
buffer[45U] = (m_rxOOO << 0) & 0xFFU;
|
||||||
|
|
||||||
|
#if !defined(DEBUG_IAX)
|
||||||
if (m_debug)
|
if (m_debug)
|
||||||
|
#endif
|
||||||
CUtils::dump(1U, "FM IAX Network Data Sent", buffer, 46U);
|
CUtils::dump(1U, "FM IAX Network Data Sent", buffer, 46U);
|
||||||
|
|
||||||
m_oSeqNo++;
|
m_oSeqNo++;
|
||||||
|
|
@ -491,32 +656,37 @@ bool CFMIAXNetwork::writePong(unsigned int ts)
|
||||||
return m_socket.write(buffer, 46U, m_addr, m_addrLen);
|
return m_socket.write(buffer, 46U, m_addr, m_addrLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CFMIAXNetwork::writeAck(unsigned short sCallNo, unsigned short dCallNo, unsigned int ts, unsigned char oSeqNo, unsigned char iSeqNo)
|
bool CFMIAXNetwork::writeAck(unsigned int ts)
|
||||||
{
|
{
|
||||||
unsigned short sCall = sCallNo | 0x8000U;
|
#if defined(DEBUG_IAX)
|
||||||
|
LogDebug("IAX ACK sent");
|
||||||
|
#endif
|
||||||
|
unsigned short sCall = m_sCallNo | 0x8000U;
|
||||||
|
|
||||||
unsigned char buffer[15U];
|
unsigned char buffer[15U];
|
||||||
|
|
||||||
buffer[0U] = (sCall << 8) & 0xFFU;
|
buffer[0U] = (sCall << 8) & 0xFFU;
|
||||||
buffer[1U] = (sCall << 0) & 0xFFU;
|
buffer[1U] = (sCall << 0) & 0xFFU;
|
||||||
|
|
||||||
buffer[2U] = (dCallNo << 8) & 0xFFU;
|
buffer[2U] = (m_dCallNo << 8) & 0xFFU;
|
||||||
buffer[3U] = (dCallNo << 0) & 0xFFU;
|
buffer[3U] = (m_dCallNo << 0) & 0xFFU;
|
||||||
|
|
||||||
buffer[4U] = (ts << 24) & 0xFFU;
|
buffer[4U] = (ts << 24) & 0xFFU;
|
||||||
buffer[5U] = (ts << 16) & 0xFFU;
|
buffer[5U] = (ts << 16) & 0xFFU;
|
||||||
buffer[6U] = (ts << 8) & 0xFFU;
|
buffer[6U] = (ts << 8) & 0xFFU;
|
||||||
buffer[7U] = (ts << 0) & 0xFFU;
|
buffer[7U] = (ts << 0) & 0xFFU;
|
||||||
|
|
||||||
buffer[8U] = oSeqNo;
|
buffer[8U] = m_oSeqNo;
|
||||||
|
|
||||||
buffer[9U] = iSeqNo;
|
buffer[9U] = m_iSeqNo;
|
||||||
|
|
||||||
buffer[10U] = AST_FRAME_IAX;
|
buffer[10U] = AST_FRAME_IAX;
|
||||||
|
|
||||||
buffer[11U] = IAX_COMMAND_ACK;
|
buffer[11U] = IAX_COMMAND_ACK;
|
||||||
|
|
||||||
|
#if !defined(DEBUG_IAX)
|
||||||
if (m_debug)
|
if (m_debug)
|
||||||
|
#endif
|
||||||
CUtils::dump(1U, "FM IAX Network Data Sent", buffer, 12U);
|
CUtils::dump(1U, "FM IAX Network Data Sent", buffer, 12U);
|
||||||
|
|
||||||
m_oSeqNo++;
|
m_oSeqNo++;
|
||||||
|
|
@ -524,8 +694,50 @@ bool CFMIAXNetwork::writeAck(unsigned short sCallNo, unsigned short dCallNo, uns
|
||||||
return m_socket.write(buffer, 12U, m_addr, m_addrLen);
|
return m_socket.write(buffer, 12U, m_addr, m_addrLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CFMIAXNetwork::writeDisconnect()
|
bool CFMIAXNetwork::writeLagRp()
|
||||||
{
|
{
|
||||||
|
#if defined(DEBUG_IAX)
|
||||||
|
LogDebug("IAX LAGRP sent");
|
||||||
|
#endif
|
||||||
|
unsigned short sCall = m_sCallNo | 0x8000U;
|
||||||
|
unsigned int ts = m_timestamp.elapsed();
|
||||||
|
|
||||||
|
unsigned char buffer[15U];
|
||||||
|
|
||||||
|
buffer[0U] = (sCall << 8) & 0xFFU;
|
||||||
|
buffer[1U] = (sCall << 0) & 0xFFU;
|
||||||
|
|
||||||
|
buffer[2U] = (m_dCallNo << 8) & 0xFFU;
|
||||||
|
buffer[3U] = (m_dCallNo << 0) & 0xFFU;
|
||||||
|
|
||||||
|
buffer[4U] = (ts << 24) & 0xFFU;
|
||||||
|
buffer[5U] = (ts << 16) & 0xFFU;
|
||||||
|
buffer[6U] = (ts << 8) & 0xFFU;
|
||||||
|
buffer[7U] = (ts << 0) & 0xFFU;
|
||||||
|
|
||||||
|
buffer[8U] = m_oSeqNo;
|
||||||
|
|
||||||
|
buffer[9U] = m_iSeqNo;
|
||||||
|
|
||||||
|
buffer[10U] = AST_FRAME_IAX;
|
||||||
|
|
||||||
|
buffer[11U] = IAX_COMMAND_LAGRP;
|
||||||
|
|
||||||
|
#if !defined(DEBUG_IAX)
|
||||||
|
if (m_debug)
|
||||||
|
#endif
|
||||||
|
CUtils::dump(1U, "FM IAX Network Data Sent", buffer, 12U);
|
||||||
|
|
||||||
|
m_oSeqNo++;
|
||||||
|
|
||||||
|
return m_socket.write(buffer, 12U, m_addr, m_addrLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CFMIAXNetwork::writeHangup()
|
||||||
|
{
|
||||||
|
#if defined(DEBUG_IAX)
|
||||||
|
LogDebug("IAX HANGUP sent");
|
||||||
|
#endif
|
||||||
const char* REASON = "MMDVM Out";
|
const char* REASON = "MMDVM Out";
|
||||||
|
|
||||||
unsigned short sCall = m_sCallNo | 0x8000U;
|
unsigned short sCall = m_sCallNo | 0x8000U;
|
||||||
|
|
@ -556,7 +768,9 @@ bool CFMIAXNetwork::writeDisconnect()
|
||||||
buffer[13U] = ::strlen(REASON);
|
buffer[13U] = ::strlen(REASON);
|
||||||
::memcpy(buffer + 14U, REASON, ::strlen(REASON));
|
::memcpy(buffer + 14U, REASON, ::strlen(REASON));
|
||||||
|
|
||||||
|
#if !defined(DEBUG_IAX)
|
||||||
if (m_debug)
|
if (m_debug)
|
||||||
|
#endif
|
||||||
CUtils::dump(1U, "FM IAX Network Data Sent", buffer, 14U + ::strlen(REASON));
|
CUtils::dump(1U, "FM IAX Network Data Sent", buffer, 14U + ::strlen(REASON));
|
||||||
|
|
||||||
m_oSeqNo++;
|
m_oSeqNo++;
|
||||||
|
|
@ -564,3 +778,13 @@ bool CFMIAXNetwork::writeDisconnect()
|
||||||
return m_socket.write(buffer, 14U + ::strlen(REASON), m_addr, m_addrLen);
|
return m_socket.write(buffer, 14U + ::strlen(REASON), m_addr, m_addrLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CFMIAXNetwork::compareFrame(const unsigned char* buffer, unsigned char type1, unsigned char type2) const
|
||||||
|
{
|
||||||
|
assert(buffer != NULL);
|
||||||
|
|
||||||
|
if ((buffer[0U] & 0x80U) == 0x00U)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return (buffer[10U] == type1) && (buffer[11U] == type2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,10 +23,18 @@
|
||||||
#include "RingBuffer.h"
|
#include "RingBuffer.h"
|
||||||
#include "UDPSocket.h"
|
#include "UDPSocket.h"
|
||||||
#include "StopWatch.h"
|
#include "StopWatch.h"
|
||||||
|
#include "Timer.h"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
enum IAX_STATUS {
|
||||||
|
IAXS_DISCONNECTED,
|
||||||
|
IAXS_CONNECTING,
|
||||||
|
IAXS_AUTHORISING,
|
||||||
|
IAXS_CONNECTED
|
||||||
|
};
|
||||||
|
|
||||||
class CFMIAXNetwork : public IFMNetwork {
|
class CFMIAXNetwork : public IFMNetwork {
|
||||||
public:
|
public:
|
||||||
CFMIAXNetwork(const std::string& callsign, const std::string& username, const std::string& password, const std::string& node, const std::string& localAddress, unsigned short localPort, const std::string& gatewayAddress, unsigned short gatewayPort, bool debug);
|
CFMIAXNetwork(const std::string& callsign, const std::string& username, const std::string& password, const std::string& node, const std::string& localAddress, unsigned short localPort, const std::string& gatewayAddress, unsigned short gatewayPort, bool debug);
|
||||||
|
|
@ -61,6 +69,9 @@ private:
|
||||||
bool m_debug;
|
bool m_debug;
|
||||||
bool m_enabled;
|
bool m_enabled;
|
||||||
CRingBuffer<unsigned char> m_buffer;
|
CRingBuffer<unsigned char> m_buffer;
|
||||||
|
IAX_STATUS m_status;
|
||||||
|
CTimer m_retryTimer;
|
||||||
|
CTimer m_pingTimer;
|
||||||
CStopWatch m_timestamp;
|
CStopWatch m_timestamp;
|
||||||
unsigned short m_sCallNo;
|
unsigned short m_sCallNo;
|
||||||
unsigned short m_dCallNo;
|
unsigned short m_dCallNo;
|
||||||
|
|
@ -73,13 +84,16 @@ private:
|
||||||
unsigned int m_rxDropped;
|
unsigned int m_rxDropped;
|
||||||
unsigned int m_rxOOO;
|
unsigned int m_rxOOO;
|
||||||
|
|
||||||
bool writeCall();
|
bool writeNew();
|
||||||
bool writeAuth();
|
bool writeAuthRep();
|
||||||
bool writeKey(bool key);
|
bool writeKey(bool key);
|
||||||
bool writePing();
|
bool writePing();
|
||||||
bool writePong(unsigned int ts);
|
bool writePong(unsigned int ts);
|
||||||
bool writeAck(unsigned short sCallNo, unsigned short dCallNo, unsigned int ts, unsigned char oSeqNo, unsigned char iSeqNo);
|
bool writeAck(unsigned int ts);
|
||||||
bool writeDisconnect();
|
bool writeLagRp();
|
||||||
|
bool writeHangup();
|
||||||
|
|
||||||
|
bool compareFrame(const unsigned char* buffer, unsigned char type1, unsigned char type2) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue