incoming slow data assembly

pull/14/head
Tom Early 6 years ago
parent f626490889
commit 379b750146

@ -71,7 +71,7 @@ int CQnetGateway::FindIndex(const int i) const
return index;
}
bool CQnetGateway::VoicePacketIsSync(const unsigned char *text)
bool CQnetGateway::VoicePacketIsSync(const unsigned char *text) const
{
return *text==0x55U && *(text+1)==0x2DU && *(text+2)==0x16U;
}
@ -682,7 +682,8 @@ bool CQnetGateway::ProcessG2Msg(const unsigned char *data, const int mod, std::s
void CQnetGateway::ProcessSlowData(unsigned char *data, const unsigned short sid)
{
/* extract 20-byte RADIO ID */
if ((data[0] != 0x55) || (data[1] != 0x2d) || (data[2] != 0x16)) {
if (VoicePacketIsSync(data))
return;
// first, unscramble
const unsigned char c1 = data[0] ^ 0x70u;
@ -966,6 +967,113 @@ void CQnetGateway::ProcessSlowData(unsigned char *data, const unsigned short sid
}
}
}
void CQnetGateway::ProcessIncomingSD(const SDSVT &dsvt)
{
int i;
for (i=0; i<3; i++) {
if (Rptr.mod[i].defined && (toRptr[i].streamid == dsvt.streamid))
break;
}
// if i==3, then the streamid of this voice packet didn't match any module
if (VoicePacketIsSync(dsvt.vasd.text))
return;
const unsigned char c[3] = {
static_cast<unsigned char>(dsvt.vasd.text[0] ^ 0x70u),
static_cast<unsigned char>(dsvt.vasd.text[1] ^ 0x4fu),
static_cast<unsigned char>(dsvt.vasd.text[2] ^ 0x93u)
}; // unscramble
if (Sd[i].first) {
Sd[i].size = 0x0FU & c[0];
int size = Sd[i].size;
if (size > 2)
size = 2;
Sd[i].type = 0xF0U & c[0];
switch (Sd[i].type) {
case 0x30U: // GPS data
if (Sd[i].size + Sd[i].ig < 255) {
memcpy(Sd[i].gps+Sd[i].ig, c+1, size);
if (c[1]=='\r' || c[2]=='\r') {
Sd[i].gps[Sd[i].ig + (c[1] == '\r') ? 0 : 1] = '\0';
printf("GPS String=%s\n", Sd[i].gps);
Sd[i].ig = Sd[i].size = 0;
} else
Sd[i].size -= size;
} else {
printf("GPS string is too large at %d bytes\n", Sd[i].ig + Sd[i].size);
Sd[i].size = 0;
}
Sd[i].first = false;
break;
case 0x40U: // 20 character user message
if (Sd[i].size * 5 == Sd[i].im) {
memcpy(Sd[i].message+(5*size), c+1, 2);
Sd[i].im += 2;
} else {
printf("A message voiceframe, #%d, is out of order because message size is %d\n", Sd[i].size, Sd[i].im);
Sd[i].im = 0;
}
Sd[i].first = false;
break;
case 0x50U: // header
if (Sd[i].size + Sd[i].ih < 41) {
memcpy(Sd[i].header+Sd[i].ih, c+1, size);
Sd[i].ih += size;
if (Sd[i].ih == 41) {
memcpy(sdheader.hdr.flag, Sd[i].header, 39);
calcPFCS(sdheader.title, 56);
printf("Header='%x:%x:%x %s' checksum=%02x%02x, calculated=%02x%02x\n", sdheader.hdr.flag[0], sdheader.hdr.flag[1], sdheader.hdr.flag[2], sdheader.hdr.rpt1, Sd[i].header[39], Sd[i].header[40], sdheader.hdr.pfcs[0], sdheader.hdr.pfcs[1]);
Sd[i].ih = Sd[i].size = 0;
}
} else {
printf("Header overflow, %d bytes\n", Sd[i].size + Sd[i].ih);
Sd[i].ih = Sd[i].size = 0;
}
Sd[i].first = false;
break;
default:
return;
}
} else {
// this is the second of a two voice-frame pair
Sd[i].first = true;
if (0 == Sd[i].size)
return;
switch (Sd[i].type) {
case 0x30U: // GPS
memcpy(Sd[i].gps+Sd[i].ig, c, Sd[i].size);
if (c[0]=='\r' || c[1]=='\r' || c[2]=='\r') {
if (c[0]=='\r')
Sd[i].gps[Sd[i].ig] = '\0';
else if (c[1]=='\r')
Sd[i].gps[Sd[i].ig+1] = '\0';
else
Sd[i].gps[Sd[i].ig+2] = '\0';
printf("GPS string=%s\n", Sd[i].gps);
Sd[i].ig = 0;
}
break;
case 0x40U: // message
memcpy(Sd[i].message+Sd[i].im, c, 3);
Sd[i].im += 3;
if (Sd[i].im >= 20) {
Sd[i].message[20] = '\0';
printf("Message='%s'\n", Sd[i].message);
Sd[i].im = 0;
}
break;
case 0x50U: // header
if (Sd[i].size != 3) {
Sd[i].ih = 0;
}
memcpy(Sd[i].header+Sd[i].ih, c, Sd[i].size);
Sd[i].ih += Sd[i].size;
break;
}
}
}
void CQnetGateway::ProcessG2(const ssize_t g2buflen, SDSVT &g2buf, const int source_sock)
@ -976,6 +1084,8 @@ void CQnetGateway::ProcessG2(const ssize_t g2buflen, SDSVT &g2buf, const int sou
static std::string superframe[3];
if ( (g2buflen==56 || g2buflen==27) && 0==memcmp(g2buf.title, "DSVT", 4) && (g2buf.config==0x10 || g2buf.config==0x20) && g2buf.id==0x20) {
if (g2buflen == 56) {
for (int i=0; i<3; i++)
Sd[i].Init(); // only do the first three
// Find out the local repeater module IP/port to send the data to
int i = g2buf.hdr.rpt1[7] - 'A';
/* valid repeater module? */
@ -1031,6 +1141,7 @@ void CQnetGateway::ProcessG2(const ssize_t g2buflen, SDSVT &g2buf, const int sou
}
}
} else { // g2buflen == 27
ProcessIncomingSD(g2buf);
/* find out which repeater module to send the data to */
int i;
for (i=0; i<3; i++) {
@ -1123,6 +1234,7 @@ void CQnetGateway::ProcessG2(const ssize_t g2buflen, SDSVT &g2buf, const int sou
printf("Final[%c]: %s\n", 'A'+i, superframe[i].c_str());
superframe[i].clear();
}
Sd[3].Init();
if (LOG_QSO)
printf("id=%04x END\n", ntohs(g2buf.streamid));
}
@ -2480,6 +2592,10 @@ bool CQnetGateway::Init(char *cfgfile)
if (GATEWAY_SEND_QRGS_MAP)
qrgs_and_maps();
for (int i=0; i<4; i++)
Sd[i].Init();
return false;
}

@ -79,6 +79,20 @@ using SBANDTXT = struct band_txt_tag {
int num_bit_errors;
};
using SSD = struct sd_tag {
unsigned char header[41];
char message[21];
char gps[256];
int ih, im, ig;
unsigned char type;
bool first;
int size;
void Init() { ih = im = ig = 0; first = true; }
};
class CQnetGateway : public CKRBase
{
public:
@ -137,7 +151,7 @@ private:
// must be fed into our local repeater modules.
STOREPEATER toRptr[3]; // 0=A, 1=B, 2=C
SDSVT end_of_audio;
SDSVT end_of_audio, sdheader;
// send packets to g2_link
struct sockaddr_in plug;
@ -165,7 +179,7 @@ private:
int dtmf_last_frame[3];
unsigned int dtmf_counter[3];
bool VoicePacketIsSync(const unsigned char *text);
bool VoicePacketIsSync(const unsigned char *text) const;
int open_port(const SPORTIP *pip, int family);
void calcPFCS(unsigned char *packet, int len);
void GetIRCDataThread(const int i);
@ -176,6 +190,7 @@ private:
void APRSBeaconThread();
void ProcessTimeouts();
void ProcessSlowData(unsigned char *data, const unsigned short sid);
void ProcessIncomingSD(const SDSVT &dsvt);
bool ProcessG2Msg(const unsigned char *data, const int mod, std::string &smrtgrp);
void ProcessG2(const ssize_t g2buflen, SDSVT &g2buf, const int sock_source);
void ProcessModem(const ssize_t len, SDSVT &dsvt);
@ -196,4 +211,7 @@ private:
void set_dest_rptr(const char mod, std::string &call);
bool validate_csum(SBANDTXT &bt, bool is_gps);
// for incoming slow header stuff;
SSD Sd[4];
};

Loading…
Cancel
Save

Powered by TurnKey Linux.