mirror of
https://github.com/g4klx/MMDVMHost
synced 2025-12-21 06:55:52 +08:00
Mostly complete processing of RF frames.
This commit is contained in:
@@ -72,7 +72,7 @@ m_networkWatchdog(1000U, 0U, 1500U),
|
|||||||
m_elapsed(),
|
m_elapsed(),
|
||||||
m_rfFrames(0U),
|
m_rfFrames(0U),
|
||||||
m_netFrames(0U),
|
m_netFrames(0U),
|
||||||
m_rfLastFN(0U),
|
m_rfFN(0U),
|
||||||
m_rfErrs(0U),
|
m_rfErrs(0U),
|
||||||
m_rfBits(1U),
|
m_rfBits(1U),
|
||||||
m_rfLICH(),
|
m_rfLICH(),
|
||||||
@@ -179,7 +179,7 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len)
|
|||||||
m_maxRSSI = m_rssi;
|
m_maxRSSI = m_rssi;
|
||||||
m_aveRSSI = m_rssi;
|
m_aveRSSI = m_rssi;
|
||||||
m_rssiCount = 1U;
|
m_rssiCount = 1U;
|
||||||
m_rfLastFN = 0U;
|
m_rfFN = 0U;
|
||||||
|
|
||||||
#if defined(DUMP_M17)
|
#if defined(DUMP_M17)
|
||||||
openFile();
|
openFile();
|
||||||
@@ -259,7 +259,7 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len)
|
|||||||
|
|
||||||
bool valid = CM17CRC::checkCRC(frame, M17_FN_LENGTH_BITS + M17_PAYLOAD_LENGTH_BITS + M17_CRC_LENGTH_BITS);
|
bool valid = CM17CRC::checkCRC(frame, M17_FN_LENGTH_BITS + M17_PAYLOAD_LENGTH_BITS + M17_CRC_LENGTH_BITS);
|
||||||
if (valid) {
|
if (valid) {
|
||||||
m_rfLastFN = (frame[0U] << 8) + (frame[1U] << 0);
|
m_rfFN = (frame[0U] << 8) + (frame[1U] << 0);
|
||||||
|
|
||||||
unsigned int frag1, frag2, frag3, frag4;
|
unsigned int frag1, frag2, frag3, frag4;
|
||||||
|
|
||||||
@@ -270,7 +270,7 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len)
|
|||||||
unsigned int lich3 = CGolay24128::decode24128(frag3);
|
unsigned int lich3 = CGolay24128::decode24128(frag3);
|
||||||
unsigned int lich4 = CGolay24128::decode24128(frag4);
|
unsigned int lich4 = CGolay24128::decode24128(frag4);
|
||||||
|
|
||||||
m_rfLICH.setFragment(data + 2U + M17_SYNC_LENGTH_BYTES, m_rfLastFN & 0x7FFFU);
|
m_rfLICH.setFragment(data + 2U + M17_SYNC_LENGTH_BYTES, m_rfFN & 0x7FFFU);
|
||||||
|
|
||||||
valid = m_rfLICH.isValid();
|
valid = m_rfLICH.isValid();
|
||||||
if (valid) {
|
if (valid) {
|
||||||
@@ -343,12 +343,11 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len)
|
|||||||
#if defined(DUMP_M17)
|
#if defined(DUMP_M17)
|
||||||
writeFile(data + 2U);
|
writeFile(data + 2U);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CM17Convolution conv;
|
CM17Convolution conv;
|
||||||
conv.start();
|
conv.start();
|
||||||
|
|
||||||
unsigned int n = 2U + M17_SYNC_LENGTH_BYTES + M17_LICH_FRAGMENT_LENGTH_BYTES;
|
unsigned int n = 2U + M17_SYNC_LENGTH_BYTES + M17_LICH_FRAGMENT_LENGTH_BYTES;
|
||||||
for (unsigned int i = 0U; i < (M17_LICH_LENGTH_BYTES / 2U); i++) {
|
for (unsigned int i = 0U; i < ((M17_FN_LENGTH_BYTES + M17_PAYLOAD_LENGTH_BYTES + M17_CRC_LENGTH_BYTES) / 2U); i++) {
|
||||||
uint8_t s0 = data[n++];
|
uint8_t s0 = data[n++];
|
||||||
uint8_t s1 = data[n++];
|
uint8_t s1 = data[n++];
|
||||||
|
|
||||||
@@ -360,19 +359,77 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len)
|
|||||||
|
|
||||||
bool valid = CM17CRC::checkCRC(frame, M17_FN_LENGTH_BITS + M17_PAYLOAD_LENGTH_BITS + M17_CRC_LENGTH_BITS);
|
bool valid = CM17CRC::checkCRC(frame, M17_FN_LENGTH_BITS + M17_PAYLOAD_LENGTH_BITS + M17_CRC_LENGTH_BITS);
|
||||||
if (valid) {
|
if (valid) {
|
||||||
m_rfLastFN = (frame[0U] << 8) + (frame[1U] << 0);
|
m_rfFN = (frame[0U] << 8) + (frame[1U] << 0);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
m_rfLastFN++;
|
// Create a silence frame
|
||||||
|
m_rfFN++;
|
||||||
|
|
||||||
|
// The new FN
|
||||||
|
frame[0U] = m_rfFN >> 8;
|
||||||
|
frame[1U] = m_rfFN >> 0;
|
||||||
|
|
||||||
|
// Add silent audio
|
||||||
|
unsigned char dataType = m_rfLICH.getDataType();
|
||||||
|
switch (dataType) {
|
||||||
|
case 2U:
|
||||||
|
::memcpy(frame + M17_FN_LENGTH_BYTES + 0U, M17_3200_SILENCE, 8U);
|
||||||
|
::memcpy(frame + M17_FN_LENGTH_BYTES + 8U, M17_3200_SILENCE, 8U);
|
||||||
|
break;
|
||||||
|
case 3U:
|
||||||
|
::memcpy(frame + M17_FN_LENGTH_BYTES + 0U, M17_1600_SILENCE, 8U);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the CRC
|
||||||
|
CM17CRC::encodeCRC(frame, M17_FN_LENGTH_BITS + M17_PAYLOAD_LENGTH_BITS + M17_CRC_LENGTH_BITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char rfData[2U + M17_FRAME_LENGTH_BYTES];
|
||||||
|
|
||||||
|
rfData[0U] = TAG_DATA;
|
||||||
|
rfData[1U] = 0x00U;
|
||||||
|
|
||||||
|
CSync::addM17Sync(rfData + 2U);
|
||||||
|
|
||||||
|
// Re-encode the LICH fragment
|
||||||
|
m_rfLICH.getFragment(rfData + 2U + M17_SYNC_LENGTH_BYTES, m_rfFN & 0x7FFFU);
|
||||||
|
|
||||||
|
// XXX TODO Golay on LICH fragment
|
||||||
|
|
||||||
|
// Re-encode the payload
|
||||||
|
conv.encode(frame, rfData + 2U + M17_SYNC_LENGTH_BYTES + M17_LICH_FRAGMENT_LENGTH_BYTES, M17_FN_LENGTH_BITS + M17_PAYLOAD_LENGTH_BITS + M17_CRC_LENGTH_BITS);
|
||||||
|
|
||||||
|
// Calculate the BER
|
||||||
|
if (valid) {
|
||||||
|
for (unsigned int i = 2U; i < 50U; i++)
|
||||||
|
m_rfErrs += countBits(rfData[i] ^ data[i]);
|
||||||
|
|
||||||
|
m_rfBits += 272U;
|
||||||
|
|
||||||
|
float ber = float(m_rfErrs) / float(m_rfBits);
|
||||||
|
m_display->writeM17BER(ber);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_duplex)
|
if (m_duplex)
|
||||||
writeQueueRF(data);
|
writeQueueRF(rfData);
|
||||||
|
|
||||||
|
unsigned char netData[M17_LICH_LENGTH_BYTES + M17_FN_LENGTH_BYTES + M17_PAYLOAD_LENGTH_BYTES + M17_CRC_LENGTH_BYTES];
|
||||||
|
|
||||||
|
m_rfLICH.getNetworkData(netData + 0U);
|
||||||
|
|
||||||
|
// Copy the FN and payload from the frame
|
||||||
|
::memcpy(netData + M17_LICH_LENGTH_BYTES, frame, M17_FN_LENGTH_BYTES + M17_PAYLOAD_LENGTH_BYTES);
|
||||||
|
|
||||||
|
CM17CRC::encodeCRC(netData, M17_LICH_LENGTH_BITS + M17_FN_LENGTH_BITS + M17_PAYLOAD_LENGTH_BITS + M17_CRC_LENGTH_BITS);
|
||||||
|
|
||||||
|
writeNetwork(netData);
|
||||||
|
|
||||||
m_rfFrames++;
|
m_rfFrames++;
|
||||||
|
|
||||||
// EOT?
|
// EOT?
|
||||||
if ((m_rfLastFN & 0x8000U) == 0x8000U) {
|
if ((m_rfFN & 0x8000U) == 0x8000U) {
|
||||||
std::string source = m_rfLICH.getSource();
|
std::string source = m_rfLICH.getSource();
|
||||||
std::string dest = m_rfLICH.getDest();
|
std::string dest = m_rfLICH.getDest();
|
||||||
|
|
||||||
@@ -737,3 +794,17 @@ void CM17Control::enable(bool enabled)
|
|||||||
|
|
||||||
m_enabled = enabled;
|
m_enabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int CM17Control::countBits(unsigned char byte)
|
||||||
|
{
|
||||||
|
unsigned int count = 0U;
|
||||||
|
|
||||||
|
const unsigned char* p = &byte;
|
||||||
|
|
||||||
|
for (unsigned int i = 0U; i < 8U; i++) {
|
||||||
|
if (READ_BIT(p, i) != 0U)
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ private:
|
|||||||
CStopWatch m_elapsed;
|
CStopWatch m_elapsed;
|
||||||
unsigned int m_rfFrames;
|
unsigned int m_rfFrames;
|
||||||
unsigned int m_netFrames;
|
unsigned int m_netFrames;
|
||||||
unsigned int m_rfLastFN;
|
unsigned int m_rfFN;
|
||||||
unsigned int m_rfErrs;
|
unsigned int m_rfErrs;
|
||||||
unsigned int m_rfBits;
|
unsigned int m_rfBits;
|
||||||
CM17LICH m_rfLICH;
|
CM17LICH m_rfLICH;
|
||||||
@@ -85,6 +85,8 @@ private:
|
|||||||
void interleaver(const unsigned char* in, unsigned char* out) const;
|
void interleaver(const unsigned char* in, unsigned char* out) const;
|
||||||
void decorrelator(const unsigned char* in, unsigned char* out) const;
|
void decorrelator(const unsigned char* in, unsigned char* out) const;
|
||||||
|
|
||||||
|
unsigned int countBits(unsigned char byte);
|
||||||
|
|
||||||
void writeEndRF();
|
void writeEndRF();
|
||||||
void writeEndNet();
|
void writeEndNet();
|
||||||
|
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ const unsigned char M17_SYNC_BYTES[] = {0x32U, 0x43U};
|
|||||||
const unsigned int M17_SYNC_LENGTH_BITS = 16U;
|
const unsigned int M17_SYNC_LENGTH_BITS = 16U;
|
||||||
const unsigned int M17_SYNC_LENGTH_BYTES = M17_SYNC_LENGTH_BITS / 8U;
|
const unsigned int M17_SYNC_LENGTH_BYTES = M17_SYNC_LENGTH_BITS / 8U;
|
||||||
|
|
||||||
const unsigned int M17_LICH_LENGTH_BITS = 244U;
|
const unsigned int M17_LICH_LENGTH_BITS = 224U;
|
||||||
const unsigned int M17_LICH_LENGTH_BYTES = 31U;
|
const unsigned int M17_LICH_LENGTH_BYTES = M17_LICH_LENGTH_BITS / 8U;
|
||||||
|
|
||||||
const unsigned int M17_LICH_FRAGMENT_LENGTH_BITS = 96U;
|
const unsigned int M17_LICH_FRAGMENT_LENGTH_BITS = 96U;
|
||||||
const unsigned int M17_LICH_FRAGMENT_LENGTH_BYTES = M17_LICH_FRAGMENT_LENGTH_BITS / 8U;
|
const unsigned int M17_LICH_FRAGMENT_LENGTH_BYTES = M17_LICH_FRAGMENT_LENGTH_BITS / 8U;
|
||||||
@@ -43,4 +43,7 @@ const unsigned int M17_FN_LENGTH_BYTES = M17_FN_LENGTH_BITS / 8U;
|
|||||||
const unsigned int M17_CRC_LENGTH_BITS = 16U;
|
const unsigned int M17_CRC_LENGTH_BITS = 16U;
|
||||||
const unsigned int M17_CRC_LENGTH_BYTES = M17_CRC_LENGTH_BITS / 8U;
|
const unsigned int M17_CRC_LENGTH_BYTES = M17_CRC_LENGTH_BITS / 8U;
|
||||||
|
|
||||||
|
const unsigned char M17_3200_SILENCE[] = {0x01U, 0x00U, 0x09U, 0x43U, 0x9CU, 0xE4U, 0x21U, 0x08U};
|
||||||
|
const unsigned char M17_1600_SILENCE[] = {0x01U, 0x00U, 0x04U, 0x00U, 0x25U, 0x75U, 0xDDU, 0xF2U};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -31,8 +31,13 @@ public:
|
|||||||
void setNetworkData(const unsigned char* data);
|
void setNetworkData(const unsigned char* data);
|
||||||
|
|
||||||
std::string getSource() const;
|
std::string getSource() const;
|
||||||
|
void setSource(const std::string& callsign);
|
||||||
|
|
||||||
std::string getDest() const;
|
std::string getDest() const;
|
||||||
|
void setDest(const std::string& callsign);
|
||||||
|
|
||||||
unsigned char getDataType() const;
|
unsigned char getDataType() const;
|
||||||
|
void setDataType(unsigned char type);
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
bool isValid() const;
|
bool isValid() const;
|
||||||
|
|||||||
@@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
const unsigned int BUFFER_LENGTH = 200U;
|
const unsigned int BUFFER_LENGTH = 200U;
|
||||||
|
|
||||||
CM17Network::CM17Network(unsigned int port, bool debug) :
|
CM17Network::CM17Network(const std::string& callsign, unsigned int port, bool debug) :
|
||||||
|
m_callsign(callsign),
|
||||||
m_socket(port),
|
m_socket(port),
|
||||||
m_addr(),
|
m_addr(),
|
||||||
m_addrLen(0U),
|
m_addrLen(0U),
|
||||||
@@ -40,7 +41,7 @@ m_inId(0U),
|
|||||||
m_buffer(1000U, "M17 Network"),
|
m_buffer(1000U, "M17 Network"),
|
||||||
m_random(),
|
m_random(),
|
||||||
m_state(M17N_NOTLINKED),
|
m_state(M17N_NOTLINKED),
|
||||||
m_reflector(NULL),
|
m_encoded(NULL),
|
||||||
m_module(' '),
|
m_module(' '),
|
||||||
m_timer(1000U, 5U)
|
m_timer(1000U, 5U)
|
||||||
{
|
{
|
||||||
@@ -49,6 +50,8 @@ m_timer(1000U, 5U)
|
|||||||
m_random = mt;
|
m_random = mt;
|
||||||
|
|
||||||
m_encoded = new unsigned char[6U];
|
m_encoded = new unsigned char[6U];
|
||||||
|
|
||||||
|
CM17Utils::encodeCallsign(m_callsign, m_encoded);
|
||||||
}
|
}
|
||||||
|
|
||||||
CM17Network::~CM17Network()
|
CM17Network::~CM17Network()
|
||||||
@@ -63,17 +66,14 @@ bool CM17Network::open()
|
|||||||
return m_socket.open(m_addr);
|
return m_socket.open(m_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CM17Network::link(const std::string& address, unsigned int port, const std::string& reflector, char module)
|
bool CM17Network::link(const std::string& address, unsigned int port, char module)
|
||||||
{
|
{
|
||||||
if (CUDPSocket::lookup(address, port, m_addr, m_addrLen) != 0) {
|
if (CUDPSocket::lookup(address, port, m_addr, m_addrLen) != 0) {
|
||||||
m_state = M17N_NOTLINKED;
|
m_state = M17N_NOTLINKED;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_reflector = reflector;
|
m_module = module;
|
||||||
m_module = module;
|
|
||||||
|
|
||||||
CM17Utils::encodeCallsign(m_reflector, m_encoded);
|
|
||||||
|
|
||||||
m_state = M17N_LINKING;
|
m_state = M17N_LINKING;
|
||||||
|
|
||||||
@@ -119,10 +119,12 @@ bool CM17Network::write(const unsigned char* data)
|
|||||||
buffer[4U] = m_outId / 256U; // Unique session id
|
buffer[4U] = m_outId / 256U; // Unique session id
|
||||||
buffer[5U] = m_outId % 256U;
|
buffer[5U] = m_outId % 256U;
|
||||||
|
|
||||||
if (m_debug)
|
::memcpy(buffer + 6U, data, 48U);
|
||||||
CUtils::dump(1U, "M17 data transmitted", buffer, 36U);
|
|
||||||
|
|
||||||
return m_socket.write(buffer, 36U, m_addr, m_addrLen);
|
if (m_debug)
|
||||||
|
CUtils::dump(1U, "M17 data transmitted", buffer, 54U);
|
||||||
|
|
||||||
|
return m_socket.write(buffer, 54U, m_addr, m_addrLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CM17Network::clock(unsigned int ms)
|
void CM17Network::clock(unsigned int ms)
|
||||||
@@ -163,21 +165,21 @@ void CM17Network::clock(unsigned int ms)
|
|||||||
if (::memcmp(buffer + 0U, "ACKN", 4U) == 0) {
|
if (::memcmp(buffer + 0U, "ACKN", 4U) == 0) {
|
||||||
m_timer.stop();
|
m_timer.stop();
|
||||||
m_state = M17N_LINKED;
|
m_state = M17N_LINKED;
|
||||||
LogMessage("M17, linked to %s", m_reflector.c_str());
|
LogMessage("M17, linked to reflector");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (::memcmp(buffer + 0U, "NACK", 4U) == 0) {
|
if (::memcmp(buffer + 0U, "NACK", 4U) == 0) {
|
||||||
m_timer.stop();
|
m_timer.stop();
|
||||||
m_state = M17N_NOTLINKED;
|
m_state = M17N_NOTLINKED;
|
||||||
LogMessage("M17, link refused by %s", m_reflector.c_str());
|
LogMessage("M17, link refused by reflector");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (::memcmp(buffer + 0U, "DISC", 4U) == 0) {
|
if (::memcmp(buffer + 0U, "DISC", 4U) == 0) {
|
||||||
m_timer.stop();
|
m_timer.stop();
|
||||||
m_state = M17N_NOTLINKED;
|
m_state = M17N_NOTLINKED;
|
||||||
LogMessage("M17, unlinked from %s", m_reflector.c_str());
|
LogMessage("M17, unlinked from reflector");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,10 +210,10 @@ void CM17Network::clock(unsigned int ms)
|
|||||||
if ((fn & 0x8000U) == 0x8000U)
|
if ((fn & 0x8000U) == 0x8000U)
|
||||||
m_inId = 0U;
|
m_inId = 0U;
|
||||||
|
|
||||||
unsigned char c = length;
|
unsigned char c = length - 6U;
|
||||||
m_buffer.addData(&c, 1U);
|
m_buffer.addData(&c, 1U);
|
||||||
|
|
||||||
m_buffer.addData(buffer, length);
|
m_buffer.addData(buffer + 6U, length - 6U);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CM17Network::read(unsigned char* data)
|
bool CM17Network::read(unsigned char* data)
|
||||||
|
|||||||
@@ -36,12 +36,12 @@ enum M17NET_STATUS {
|
|||||||
|
|
||||||
class CM17Network {
|
class CM17Network {
|
||||||
public:
|
public:
|
||||||
CM17Network(unsigned int port, bool debug);
|
CM17Network(const std::string& callsign, unsigned int port, bool debug);
|
||||||
~CM17Network();
|
~CM17Network();
|
||||||
|
|
||||||
bool open();
|
bool open();
|
||||||
|
|
||||||
bool link(const std::string& address, unsigned int port, const std::string& reflector, char module);
|
bool link(const std::string& address, unsigned int port, char module);
|
||||||
|
|
||||||
void unlink();
|
void unlink();
|
||||||
|
|
||||||
@@ -58,6 +58,7 @@ public:
|
|||||||
void clock(unsigned int ms);
|
void clock(unsigned int ms);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::string m_callsign;
|
||||||
CUDPSocket m_socket;
|
CUDPSocket m_socket;
|
||||||
sockaddr_storage m_addr;
|
sockaddr_storage m_addr;
|
||||||
unsigned int m_addrLen;
|
unsigned int m_addrLen;
|
||||||
@@ -68,7 +69,6 @@ private:
|
|||||||
CRingBuffer<unsigned char> m_buffer;
|
CRingBuffer<unsigned char> m_buffer;
|
||||||
std::mt19937 m_random;
|
std::mt19937 m_random;
|
||||||
M17NET_STATUS m_state;
|
M17NET_STATUS m_state;
|
||||||
std::string m_reflector;
|
|
||||||
unsigned char* m_encoded;
|
unsigned char* m_encoded;
|
||||||
char m_module;
|
char m_module;
|
||||||
CTimer m_timer;
|
CTimer m_timer;
|
||||||
|
|||||||
@@ -224,7 +224,7 @@ Debug=0
|
|||||||
|
|
||||||
[M17 Network]
|
[M17 Network]
|
||||||
Enable=1
|
Enable=1
|
||||||
GatewayAddress=127.0.0.1
|
GatewayAddress=3.138.122.152
|
||||||
GatewayPort=17000
|
GatewayPort=17000
|
||||||
LocalPort=17000
|
LocalPort=17000
|
||||||
# ModeHang=3
|
# ModeHang=3
|
||||||
|
|||||||
@@ -1551,7 +1551,7 @@ bool CMMDVMHost::createM17Network()
|
|||||||
LogInfo(" Local Port: %u", localPort);
|
LogInfo(" Local Port: %u", localPort);
|
||||||
LogInfo(" Mode Hang: %us", m_m17NetModeHang);
|
LogInfo(" Mode Hang: %us", m_m17NetModeHang);
|
||||||
|
|
||||||
m_m17Network = new CM17Network(localPort, debug);
|
m_m17Network = new CM17Network(m_callsign, localPort, debug);
|
||||||
bool ret = m_m17Network->open();
|
bool ret = m_m17Network->open();
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
delete m_m17Network;
|
delete m_m17Network;
|
||||||
@@ -1559,7 +1559,7 @@ bool CMMDVMHost::createM17Network()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_m17Network->link(gatewayAddress, gatewayPort, "M17-USA", 'A');
|
m_m17Network->link(gatewayAddress, gatewayPort, 'A');
|
||||||
|
|
||||||
m_m17Network->enable(true);
|
m_m17Network->enable(true);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user