Merge branch 'master' into SimpleDMR
This commit is contained in:
commit
768599af84
6 changed files with 179 additions and 50 deletions
79
OLED.cpp
79
OLED.cpp
|
@ -217,6 +217,7 @@ bool COLED::open()
|
||||||
}
|
}
|
||||||
|
|
||||||
// init done
|
// init done
|
||||||
|
m_display.setTextWrap(false); // disable text wrap as default
|
||||||
m_display.clearDisplay(); // clears the screen buffer
|
m_display.clearDisplay(); // clears the screen buffer
|
||||||
m_display.display(); // display it (clear display)
|
m_display.display(); // display it (clear display)
|
||||||
|
|
||||||
|
@ -271,8 +272,10 @@ void COLED::setErrorInt(const char* text)
|
||||||
m_display.clearDisplay();
|
m_display.clearDisplay();
|
||||||
OLED_statusbar();
|
OLED_statusbar();
|
||||||
|
|
||||||
|
m_display.setTextWrap(true); // text wrap temorally enable
|
||||||
m_display.setCursor(0,OLED_LINE1);
|
m_display.setCursor(0,OLED_LINE1);
|
||||||
m_display.printf("%s\n",text);
|
m_display.printf("%s\n",text);
|
||||||
|
m_display.setTextWrap(false);
|
||||||
|
|
||||||
m_display.display();
|
m_display.display();
|
||||||
}
|
}
|
||||||
|
@ -360,6 +363,16 @@ void COLED::clearDStarInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
void COLED::writeDMRInt(unsigned int slotNo,const std::string& src,bool group,const std::string& dst,const char* type)
|
void COLED::writeDMRInt(unsigned int slotNo,const std::string& src,bool group,const std::string& dst,const char* type)
|
||||||
|
{
|
||||||
|
CUserDBentry tmp;
|
||||||
|
|
||||||
|
tmp.set(keyCALLSIGN, src);
|
||||||
|
writeDMRIntEx(slotNo, tmp, group, dst, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CALLandNAME(u) ((u).get(keyCALLSIGN) + " " + (u).get(keyFIRST_NAME))
|
||||||
|
|
||||||
|
int COLED::writeDMRIntEx(unsigned int slotNo, const class CUserDBentry& src, bool group, const std::string& dst, const char* type)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (m_mode != MODE_DMR) {
|
if (m_mode != MODE_DMR) {
|
||||||
|
@ -368,13 +381,13 @@ void COLED::writeDMRInt(unsigned int slotNo,const std::string& src,bool group,co
|
||||||
clearDMRInt(slotNo);
|
clearDMRInt(slotNo);
|
||||||
}
|
}
|
||||||
// if both slots, use lines 2-3 for slot 1, lines 4-5 for slot 2
|
// if both slots, use lines 2-3 for slot 1, lines 4-5 for slot 2
|
||||||
// if single slot, use lines 3-4
|
// if single slot, use lines 2-3
|
||||||
if ( m_slot1Enabled && m_slot2Enabled ) {
|
if ( m_slot1Enabled && m_slot2Enabled ) {
|
||||||
|
|
||||||
if (slotNo == 1U) {
|
if (slotNo == 1U) {
|
||||||
m_display.fillRect(0,OLED_LINE2,m_display.width(),40,BLACK);
|
m_display.fillRect(0,OLED_LINE2,m_display.width(),40,BLACK);
|
||||||
m_display.setCursor(0,OLED_LINE2);
|
m_display.setCursor(0,OLED_LINE2);
|
||||||
m_display.printf("%s",src.c_str());
|
m_display.printf("%s",CALLandNAME(src).c_str());
|
||||||
m_display.setCursor(0,OLED_LINE3);
|
m_display.setCursor(0,OLED_LINE3);
|
||||||
m_display.printf("Slot: %i %s %s%s",slotNo,type,group ? "TG: " : "",dst.c_str());
|
m_display.printf("Slot: %i %s %s%s",slotNo,type,group ? "TG: " : "",dst.c_str());
|
||||||
}
|
}
|
||||||
|
@ -382,34 +395,41 @@ void COLED::writeDMRInt(unsigned int slotNo,const std::string& src,bool group,co
|
||||||
{
|
{
|
||||||
m_display.fillRect(0,OLED_LINE4,m_display.width(),40,BLACK);
|
m_display.fillRect(0,OLED_LINE4,m_display.width(),40,BLACK);
|
||||||
m_display.setCursor(0,OLED_LINE4);
|
m_display.setCursor(0,OLED_LINE4);
|
||||||
m_display.printf("%s",src.c_str());
|
m_display.printf("%s",CALLandNAME(src).c_str());
|
||||||
m_display.setCursor(0,OLED_LINE5);
|
m_display.setCursor(0,OLED_LINE5);
|
||||||
m_display.printf("Slot: %i %s %s%s",slotNo,type,group ? "TG: " : "",dst.c_str());
|
m_display.printf("Slot: %i %s %s%s",slotNo,type,group ? "TG: " : "",dst.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_display.fillRect(0,OLED_LINE3,m_display.width(),20,BLACK);
|
|
||||||
m_display.setCursor(0,OLED_LINE3);
|
|
||||||
m_display.printf("%s",src.c_str());
|
|
||||||
m_display.setCursor(0,OLED_LINE4);
|
|
||||||
m_display.printf("Slot: %i %s %s%s",slotNo,type,group ? "TG: " : "",dst.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
m_display.fillRect(0,OLED_LINE6,m_display.width(),20,BLACK);
|
m_display.fillRect(0,OLED_LINE6,m_display.width(),20,BLACK);
|
||||||
m_display.setCursor(0,OLED_LINE6);
|
m_display.setCursor(0,OLED_LINE6);
|
||||||
m_display.printf("%s",m_ipaddress.c_str());
|
m_display.printf("%s",m_ipaddress.c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_display.fillRect(0,OLED_LINE2,m_display.width(),m_display.height(),BLACK);
|
||||||
|
m_display.setCursor(0,OLED_LINE2);
|
||||||
|
m_display.printf("%s",CALLandNAME(src).c_str());
|
||||||
|
m_display.setCursor(0,OLED_LINE3);
|
||||||
|
m_display.printf("Slot: %i %s %s%s",slotNo,type,group ? "TG: " : "",dst.c_str());
|
||||||
|
m_display.setCursor(0,OLED_LINE4);
|
||||||
|
m_display.printf("%s",src.get(keyCITY).c_str());
|
||||||
|
m_display.setCursor(0,OLED_LINE5);
|
||||||
|
m_display.printf("%s",src.get(keySTATE).c_str());
|
||||||
|
m_display.setCursor(0,OLED_LINE6);
|
||||||
|
m_display.printf("%s",src.get(keyCOUNTRY).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
OLED_statusbar();
|
OLED_statusbar();
|
||||||
m_display.display();
|
m_display.display();
|
||||||
|
|
||||||
|
// must be 0, to avoid calling writeDMRInt() from CDisplay::writeDMR()
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void COLED::clearDMRInt(unsigned int slotNo)
|
void COLED::clearDMRInt(unsigned int slotNo)
|
||||||
{
|
{
|
||||||
// if both slots, use lines 2-3 for slot 1, lines 4-5 for slot 2
|
// if both slots, use lines 2-3 for slot 1, lines 4-5 for slot 2
|
||||||
// if single slot, use lines 3-4
|
// if single slot, use lines 2-3
|
||||||
if ( m_slot1Enabled && m_slot2Enabled ){
|
if ( m_slot1Enabled && m_slot2Enabled ){
|
||||||
if (slotNo == 1U) {
|
if (slotNo == 1U) {
|
||||||
m_display.fillRect(0, OLED_LINE3, m_display.width(), 40, BLACK);
|
m_display.fillRect(0, OLED_LINE3, m_display.width(), 40, BLACK);
|
||||||
|
@ -423,8 +443,8 @@ void COLED::clearDMRInt(unsigned int slotNo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_display.fillRect(0, OLED_LINE4, m_display.width(), 40, BLACK);
|
m_display.fillRect(0, OLED_LINE2, m_display.width(), m_display.height(), BLACK);
|
||||||
m_display.setCursor(0,OLED_LINE4);
|
m_display.setCursor(0,OLED_LINE3);
|
||||||
m_display.printf("Slot: %i Listening",slotNo);
|
m_display.printf("Slot: %i Listening",slotNo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -497,28 +517,47 @@ void COLED::clearP25Int()
|
||||||
}
|
}
|
||||||
|
|
||||||
void COLED::writeNXDNInt(const char* source, bool group, unsigned int dest, const char* type)
|
void COLED::writeNXDNInt(const char* source, bool group, unsigned int dest, const char* type)
|
||||||
|
{
|
||||||
|
CUserDBentry tmp;
|
||||||
|
|
||||||
|
tmp.set(keyCALLSIGN, source);
|
||||||
|
writeNXDNIntEx(tmp, group, dest, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
int COLED::writeNXDNIntEx(const class CUserDBentry& source, bool group, unsigned int dest, const char* type)
|
||||||
{
|
{
|
||||||
m_mode = MODE_NXDN;
|
m_mode = MODE_NXDN;
|
||||||
|
|
||||||
m_display.clearDisplay();
|
m_display.clearDisplay();
|
||||||
m_display.fillRect(0, OLED_LINE2, m_display.width(), m_display.height(), BLACK);
|
m_display.fillRect(0, OLED_LINE2, m_display.width(), m_display.height(), BLACK);
|
||||||
|
|
||||||
|
m_display.setCursor(0,OLED_LINE2);
|
||||||
|
m_display.printf("%s %s", type, CALLandNAME(source).c_str());
|
||||||
|
|
||||||
m_display.setCursor(0,OLED_LINE3);
|
m_display.setCursor(0,OLED_LINE3);
|
||||||
m_display.printf("%s %.10s", type, source);
|
m_display.printf(" %s%u", group ? "TG" : "", dest);
|
||||||
|
|
||||||
|
m_display.setCursor(0,OLED_LINE4);
|
||||||
|
m_display.printf("%s",source.get(keyCITY).c_str());
|
||||||
|
|
||||||
m_display.setCursor(0,OLED_LINE5);
|
m_display.setCursor(0,OLED_LINE5);
|
||||||
m_display.printf(" %s%u", group ? "TG" : "", dest);
|
m_display.printf("%s",source.get(keySTATE).c_str());
|
||||||
|
|
||||||
|
m_display.setCursor(0,OLED_LINE6);
|
||||||
|
m_display.printf("%s",source.get(keyCOUNTRY).c_str());
|
||||||
|
|
||||||
OLED_statusbar();
|
OLED_statusbar();
|
||||||
m_display.display();
|
m_display.display();
|
||||||
|
|
||||||
|
// must be 0, to avoid calling writeNXDNInt() from CDisplay::writeNXDN()
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void COLED::clearNXDNInt()
|
void COLED::clearNXDNInt()
|
||||||
{
|
{
|
||||||
m_display.fillRect(0, OLED_LINE2, m_display.width(), m_display.height(), BLACK);
|
m_display.fillRect(0, OLED_LINE2, m_display.width(), m_display.height(), BLACK);
|
||||||
|
|
||||||
m_display.setCursor(40,OLED_LINE4);
|
m_display.setCursor(40,OLED_LINE3);
|
||||||
m_display.print("Listening");
|
m_display.print("Listening");
|
||||||
|
|
||||||
m_display.setCursor(0,OLED_LINE6);
|
m_display.setCursor(0,OLED_LINE6);
|
||||||
|
@ -537,8 +576,10 @@ void COLED::writePOCSAGInt(uint32_t ric, const std::string& message)
|
||||||
m_display.setCursor(0,OLED_LINE3);
|
m_display.setCursor(0,OLED_LINE3);
|
||||||
m_display.printf("RIC: %u", ric);
|
m_display.printf("RIC: %u", ric);
|
||||||
|
|
||||||
|
m_display.setTextWrap(true); // text wrap temorally enable
|
||||||
m_display.setCursor(0,OLED_LINE5);
|
m_display.setCursor(0,OLED_LINE5);
|
||||||
m_display.printf("MSG: %s", message.c_str());
|
m_display.printf("MSG: %s", message.c_str());
|
||||||
|
m_display.setTextWrap(false);
|
||||||
|
|
||||||
OLED_statusbar();
|
OLED_statusbar();
|
||||||
m_display.display();
|
m_display.display();
|
||||||
|
|
3
OLED.h
3
OLED.h
|
@ -29,6 +29,7 @@
|
||||||
|
|
||||||
#include "Display.h"
|
#include "Display.h"
|
||||||
#include "Defines.h"
|
#include "Defines.h"
|
||||||
|
#include "UserDBentry.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
@ -56,6 +57,7 @@ public:
|
||||||
virtual void clearDStarInt();
|
virtual void clearDStarInt();
|
||||||
|
|
||||||
virtual void writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type);
|
virtual void writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type);
|
||||||
|
virtual int writeDMRIntEx(unsigned int slotNo, const class CUserDBentry& src, bool group, const std::string& dst, const char* type);
|
||||||
virtual void clearDMRInt(unsigned int slotNo);
|
virtual void clearDMRInt(unsigned int slotNo);
|
||||||
|
|
||||||
virtual void writeFusionInt(const char* source, const char* dest, unsigned char dgid, const char* type, const char* origin);
|
virtual void writeFusionInt(const char* source, const char* dest, unsigned char dgid, const char* type, const char* origin);
|
||||||
|
@ -65,6 +67,7 @@ public:
|
||||||
virtual void clearP25Int();
|
virtual void clearP25Int();
|
||||||
|
|
||||||
virtual void writeNXDNInt(const char* source, bool group, unsigned int dest, const char* type);
|
virtual void writeNXDNInt(const char* source, bool group, unsigned int dest, const char* type);
|
||||||
|
virtual int writeNXDNIntEx(const class CUserDBentry& source, bool group, unsigned int dest, const char* type);
|
||||||
virtual void clearNXDNInt();
|
virtual void clearNXDNInt();
|
||||||
|
|
||||||
virtual void writePOCSAGInt(uint32_t ric, const std::string& message);
|
virtual void writePOCSAGInt(uint32_t ric, const std::string& message);
|
||||||
|
|
|
@ -19,6 +19,6 @@
|
||||||
#if !defined(VERSION_H)
|
#if !defined(VERSION_H)
|
||||||
#define VERSION_H
|
#define VERSION_H
|
||||||
|
|
||||||
const char* VERSION = "20200920";
|
const char* VERSION = "20200924";
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -321,9 +321,16 @@ bool CYSFControl::processVWData(bool valid, unsigned char *data)
|
||||||
unsigned char fn = fich.getFN();
|
unsigned char fn = fich.getFN();
|
||||||
unsigned char ft = fich.getFT();
|
unsigned char ft = fich.getFT();
|
||||||
|
|
||||||
if (fn != 0U || ft != 1U) {
|
if (fn == 0U && ft == 1U) {
|
||||||
// The first packet after the header is odd, don't try and regenerate it
|
// The first packet after the header is odd
|
||||||
unsigned int errors = m_rfPayload.processVoiceFRModeAudio(data + 2U);
|
m_rfPayload.processVoiceFRModeData(data + 2U);
|
||||||
|
unsigned int errors = m_rfPayload.processVoiceFRModeAudio2(data + 2U);
|
||||||
|
m_rfErrs += errors;
|
||||||
|
m_rfBits += 288U;
|
||||||
|
m_display->writeFusionBER(float(errors) / 2.88F);
|
||||||
|
LogDebug("YSF, V Mode 3, seq %u, AMBE FEC %u/288 (%.1f%%)", m_rfFrames % 128, errors, float(errors) / 2.88F);
|
||||||
|
} else {
|
||||||
|
unsigned int errors = m_rfPayload.processVoiceFRModeAudio5(data + 2U);
|
||||||
m_rfErrs += errors;
|
m_rfErrs += errors;
|
||||||
m_rfBits += 720U;
|
m_rfBits += 720U;
|
||||||
m_display->writeFusionBER(float(errors) / 7.2F);
|
m_display->writeFusionBER(float(errors) / 7.2F);
|
||||||
|
@ -991,9 +998,14 @@ void CYSFControl::writeNetwork()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case YSF_DT_VOICE_FR_MODE:
|
case YSF_DT_VOICE_FR_MODE:
|
||||||
if (fn != 0U || ft != 1U) {
|
if (fn == 0U && ft == 1U) {
|
||||||
// The first packet after the header is odd, don't try and regenerate it
|
// The first packet after the header is odd
|
||||||
unsigned int errors = m_netPayload.processVoiceFRModeAudio(data + 35U);
|
m_netPayload.processVoiceFRModeData(data + 35U);
|
||||||
|
unsigned int errors = m_netPayload.processVoiceFRModeAudio2(data + 35U);
|
||||||
|
m_netErrs += errors;
|
||||||
|
m_netBits += 288U;
|
||||||
|
} else {
|
||||||
|
unsigned int errors = m_netPayload.processVoiceFRModeAudio5(data + 35U);
|
||||||
m_netErrs += errors;
|
m_netErrs += errors;
|
||||||
m_netBits += 720U;
|
m_netBits += 720U;
|
||||||
}
|
}
|
||||||
|
|
120
YSFPayload.cpp
120
YSFPayload.cpp
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016,2017 Jonathan Naylor, G4KLX
|
* Copyright (C) 2016,2017,2020 Jonathan Naylor, G4KLX
|
||||||
* Copyright (C) 2016 Mathias Weyland, HB9FRV
|
* Copyright (C) 2016 Mathias Weyland, HB9FRV
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -326,23 +326,23 @@ bool CYSFPayload::processVDMode1Data(unsigned char* data, unsigned char fn, bool
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3U:
|
case 3U:
|
||||||
CUtils::dump(1U, "V/D Mode 1 Data, DT1", output, 20U);
|
// CUtils::dump(1U, "V/D Mode 1 Data, DT1", output, 20U);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4U:
|
case 4U:
|
||||||
CUtils::dump(1U, "V/D Mode 1 Data, DT2", output, 20U);
|
// CUtils::dump(1U, "V/D Mode 1 Data, DT2", output, 20U);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 5U:
|
case 5U:
|
||||||
CUtils::dump(1U, "V/D Mode 1 Data, DT3", output, 20U);
|
// CUtils::dump(1U, "V/D Mode 1 Data, DT3", output, 20U);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 6U:
|
case 6U:
|
||||||
CUtils::dump(1U, "V/D Mode 1 Data, DT4", output, 20U);
|
// CUtils::dump(1U, "V/D Mode 1 Data, DT4", output, 20U);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 7U:
|
case 7U:
|
||||||
CUtils::dump(1U, "V/D Mode 1 Data, DT5", output, 20U);
|
// CUtils::dump(1U, "V/D Mode 1 Data, DT5", output, 20U);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -526,11 +526,11 @@ bool CYSFPayload::processVDMode2Data(unsigned char* data, unsigned char fn, bool
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 6U:
|
case 6U:
|
||||||
CUtils::dump(1U, "V/D Mode 2 Data, DT1", output, YSF_CALLSIGN_LENGTH);
|
// CUtils::dump(1U, "V/D Mode 2 Data, DT1", output, YSF_CALLSIGN_LENGTH);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 7U:
|
case 7U:
|
||||||
CUtils::dump(1U, "V/D Mode 2 Data, DT2", output, YSF_CALLSIGN_LENGTH);
|
// CUtils::dump(1U, "V/D Mode 2 Data, DT2", output, YSF_CALLSIGN_LENGTH);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -612,7 +612,7 @@ bool CYSFPayload::processDataFRModeData(unsigned char* data, unsigned char fn, b
|
||||||
|
|
||||||
switch (fn) {
|
switch (fn) {
|
||||||
case 0U:
|
case 0U:
|
||||||
CUtils::dump(1U, "FR Mode Data, CSD1", output, 20U);
|
// CUtils::dump(1U, "FR Mode Data, CSD1", output, 20U);
|
||||||
|
|
||||||
if (m_dest == NULL) {
|
if (m_dest == NULL) {
|
||||||
m_dest = new unsigned char[YSF_CALLSIGN_LENGTH];
|
m_dest = new unsigned char[YSF_CALLSIGN_LENGTH];
|
||||||
|
@ -627,31 +627,31 @@ bool CYSFPayload::processDataFRModeData(unsigned char* data, unsigned char fn, b
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1U:
|
case 1U:
|
||||||
CUtils::dump(1U, "FR Mode Data, CSD3", output, 20U);
|
// CUtils::dump(1U, "FR Mode Data, CSD3", output, 20U);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2U:
|
case 2U:
|
||||||
CUtils::dump(1U, "FR Mode Data, DT2", output, 20U);
|
// CUtils::dump(1U, "FR Mode Data, DT2", output, 20U);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3U:
|
case 3U:
|
||||||
CUtils::dump(1U, "FR Mode Data, DT4", output, 20U);
|
// CUtils::dump(1U, "FR Mode Data, DT4", output, 20U);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4U:
|
case 4U:
|
||||||
CUtils::dump(1U, "FR Mode Data, DT6", output, 20U);
|
// CUtils::dump(1U, "FR Mode Data, DT6", output, 20U);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 5U:
|
case 5U:
|
||||||
CUtils::dump(1U, "FR Mode Data, DT8", output, 20U);
|
// CUtils::dump(1U, "FR Mode Data, DT8", output, 20U);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 6U:
|
case 6U:
|
||||||
CUtils::dump(1U, "FR Mode Data, DT10", output, 20U);
|
// CUtils::dump(1U, "FR Mode Data, DT10", output, 20U);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 7U:
|
case 7U:
|
||||||
CUtils::dump(1U, "FR Mode Data, DT12", output, 20U);
|
// CUtils::dump(1U, "FR Mode Data, DT12", output, 20U);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -720,7 +720,7 @@ bool CYSFPayload::processDataFRModeData(unsigned char* data, unsigned char fn, b
|
||||||
|
|
||||||
switch (fn) {
|
switch (fn) {
|
||||||
case 0U:
|
case 0U:
|
||||||
CUtils::dump(1U, "FR Mode Data, CSD2", output, 20U);
|
// CUtils::dump(1U, "FR Mode Data, CSD2", output, 20U);
|
||||||
|
|
||||||
if (m_downlink != NULL && !gateway)
|
if (m_downlink != NULL && !gateway)
|
||||||
::memcpy(output + 0U, m_downlink, YSF_CALLSIGN_LENGTH);
|
::memcpy(output + 0U, m_downlink, YSF_CALLSIGN_LENGTH);
|
||||||
|
@ -731,31 +731,31 @@ bool CYSFPayload::processDataFRModeData(unsigned char* data, unsigned char fn, b
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1U:
|
case 1U:
|
||||||
CUtils::dump(1U, "FR Mode Data, DT1", output, 20U);
|
// CUtils::dump(1U, "FR Mode Data, DT1", output, 20U);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2U:
|
case 2U:
|
||||||
CUtils::dump(1U, "FR Mode Data, DT3", output, 20U);
|
// CUtils::dump(1U, "FR Mode Data, DT3", output, 20U);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3U:
|
case 3U:
|
||||||
CUtils::dump(1U, "FR Mode Data, DT5", output, 20U);
|
// CUtils::dump(1U, "FR Mode Data, DT5", output, 20U);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4U:
|
case 4U:
|
||||||
CUtils::dump(1U, "FR Mode Data, DT7", output, 20U);
|
// CUtils::dump(1U, "FR Mode Data, DT7", output, 20U);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 5U:
|
case 5U:
|
||||||
CUtils::dump(1U, "FR Mode Data, DT9", output, 20U);
|
// CUtils::dump(1U, "FR Mode Data, DT9", output, 20U);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 6U:
|
case 6U:
|
||||||
CUtils::dump(1U, "FR Mode Data, DT11", output, 20U);
|
// CUtils::dump(1U, "FR Mode Data, DT11", output, 20U);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 7U:
|
case 7U:
|
||||||
CUtils::dump(1U, "FR Mode Data, DT13", output, 20U);
|
// CUtils::dump(1U, "FR Mode Data, DT13", output, 20U);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -799,7 +799,21 @@ bool CYSFPayload::processDataFRModeData(unsigned char* data, unsigned char fn, b
|
||||||
return ret1 && (fn == 0U);
|
return ret1 && (fn == 0U);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int CYSFPayload::processVoiceFRModeAudio(unsigned char* data)
|
unsigned int CYSFPayload::processVoiceFRModeAudio2(unsigned char* data)
|
||||||
|
{
|
||||||
|
assert(data != NULL);
|
||||||
|
|
||||||
|
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
|
||||||
|
|
||||||
|
// Regenerate the IMBE FEC
|
||||||
|
unsigned int errors = 0U;
|
||||||
|
errors += m_fec.regenerateIMBE(data + 54U);
|
||||||
|
errors += m_fec.regenerateIMBE(data + 72U);
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int CYSFPayload::processVoiceFRModeAudio5(unsigned char* data)
|
||||||
{
|
{
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
|
|
||||||
|
@ -816,6 +830,62 @@ unsigned int CYSFPayload::processVoiceFRModeAudio(unsigned char* data)
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CYSFPayload::processVoiceFRModeData(unsigned char* data)
|
||||||
|
{
|
||||||
|
assert(data != NULL);
|
||||||
|
|
||||||
|
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
|
||||||
|
|
||||||
|
unsigned char dch[45U];
|
||||||
|
::memcpy(dch, data, 45U);
|
||||||
|
|
||||||
|
CYSFConvolution conv;
|
||||||
|
conv.start();
|
||||||
|
|
||||||
|
for (unsigned int i = 0U; i < 180U; i++) {
|
||||||
|
unsigned int n = INTERLEAVE_TABLE_9_20[i];
|
||||||
|
uint8_t s0 = READ_BIT1(dch, n) ? 1U : 0U;
|
||||||
|
|
||||||
|
n++;
|
||||||
|
uint8_t s1 = READ_BIT1(dch, n) ? 1U : 0U;
|
||||||
|
|
||||||
|
conv.decode(s0, s1);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char output[23U];
|
||||||
|
conv.chainback(output, 176U);
|
||||||
|
|
||||||
|
bool ret = CCRC::checkCCITT162(output, 22U);
|
||||||
|
if (ret) {
|
||||||
|
CCRC::addCCITT162(output, 22U);
|
||||||
|
output[22U] = 0x00U;
|
||||||
|
|
||||||
|
unsigned char convolved[45U];
|
||||||
|
conv.encode(output, convolved, 180U);
|
||||||
|
|
||||||
|
unsigned char bytes[45U];
|
||||||
|
unsigned int j = 0U;
|
||||||
|
for (unsigned int i = 0U; i < 180U; i++) {
|
||||||
|
unsigned int n = INTERLEAVE_TABLE_9_20[i];
|
||||||
|
|
||||||
|
bool s0 = READ_BIT1(convolved, j) != 0U;
|
||||||
|
j++;
|
||||||
|
|
||||||
|
bool s1 = READ_BIT1(convolved, j) != 0U;
|
||||||
|
j++;
|
||||||
|
|
||||||
|
WRITE_BIT1(bytes, n, s0);
|
||||||
|
|
||||||
|
n++;
|
||||||
|
WRITE_BIT1(bytes, n, s1);
|
||||||
|
}
|
||||||
|
|
||||||
|
::memcpy(data, bytes, 45U);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void CYSFPayload::writeHeader(unsigned char* data, const unsigned char* csd1, const unsigned char* csd2)
|
void CYSFPayload::writeHeader(unsigned char* data, const unsigned char* csd1, const unsigned char* csd2)
|
||||||
{
|
{
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016,2017 by Jonathan Naylor G4KLX
|
* Copyright (C) 2016,2017,2020 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -38,7 +38,10 @@ public:
|
||||||
|
|
||||||
bool processDataFRModeData(unsigned char* bytes, unsigned char fn, bool gateway = false);
|
bool processDataFRModeData(unsigned char* bytes, unsigned char fn, bool gateway = false);
|
||||||
|
|
||||||
unsigned int processVoiceFRModeAudio(unsigned char* bytes);
|
bool processVoiceFRModeData(unsigned char* bytes);
|
||||||
|
|
||||||
|
unsigned int processVoiceFRModeAudio2(unsigned char* bytes);
|
||||||
|
unsigned int processVoiceFRModeAudio5(unsigned char* bytes);
|
||||||
|
|
||||||
void writeHeader(unsigned char* data, const unsigned char* csd1, const unsigned char* csd2);
|
void writeHeader(unsigned char* data, const unsigned char* csd1, const unsigned char* csd2);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue