From 7f87579c6aaaf1ec2826434b615a1d38b7ef615e Mon Sep 17 00:00:00 2001 From: Tom Early Date: Fri, 6 Apr 2018 16:09:14 -0700 Subject: [PATCH] finished rough mmdvm_modem --- g2_ircddb.cpp | 6 ++--- g2_typedefs.h | 22 ++++++------------- mmdvm_modem.cpp | 58 +++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 63 insertions(+), 23 deletions(-) diff --git a/g2_ircddb.cpp b/g2_ircddb.cpp index eeabd01..c369aa2 100644 --- a/g2_ircddb.cpp +++ b/g2_ircddb.cpp @@ -709,8 +709,7 @@ void CG2_ircddb::process() // so we could use either FROM_LOCAL_RPTR_TIMEOUT or FROM_REMOTE_G2_TIMEOUT // but FROM_REMOTE_G2_TIMEOUT makes more sense, probably is a bigger number if ((t_now - toRptr[i].last_time) > from_remote_g2_timeout) { - traceit("Inactivity to local rptr mod index %d, removing stream id %04x\n", - i, toRptr[i].streamid); + traceit("Inactivity to local rptr mod index %d, removing stream id %04x\n", i, toRptr[i].streamid); // Send end_of_audio to local repeater. // Let the repeater re-initialize @@ -915,8 +914,7 @@ void CG2_ircddb::process() /* for which repeater this stream has timed out ? */ for (i = 0; i < 3; i++) { /* match saved stream ? */ - if ((memcmp(toRptr[i].saved_hdr + 14, &g2buf.streamid, 2) == 0) && - (toRptr[i].saved_adr == fromDst4.sin_addr.s_addr)) { + if (0==memcmp(toRptr[i].saved_hdr + 14, &g2buf.streamid, 2) && toRptr[i].saved_adr==fromDst4.sin_addr.s_addr) { /* repeater module is inactive ? */ if ((toRptr[i].last_time == 0) && (band_txt[i].last_time == 0)) { traceit("Re-generating header for streamID=%04x\n", g2buf.streamid); diff --git a/g2_typedefs.h b/g2_typedefs.h index 960fb0b..f5c5aa3 100644 --- a/g2_typedefs.h +++ b/g2_typedefs.h @@ -17,8 +17,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -// for communicating with the g2 gateway - +// for communicating with the g2 gateway on the internal port #pragma pack(push, 1) // we need to be sure these structures don't have any dead space typedef struct pkt_tag { unsigned char pkt_id[4]; // 0 @@ -36,7 +35,7 @@ typedef struct pkt_tag { unsigned char snd_rptr_id; // 12 unsigned char snd_term_id; // 13 uint16_t streamid; // 14 - unsigned char ctrl; // 16 + unsigned char ctrl; // 16 sequence number hdr=0, voice%21, end|=0x40 union { struct { unsigned char flag[3]; // 17 @@ -47,15 +46,6 @@ typedef struct pkt_tag { unsigned char sfx[4]; // 52 unsigned char pfcs[2]; // 56 } hdr; // total 58 - struct { - unsigned char flag[3]; // 17 - unsigned char rpt2[8]; // 20 - unsigned char rpt1[8]; // 28 - unsigned char urcall[8];// 36 - unsigned char mycall[8];// 44 - unsigned char sfx[4]; // 52 - unsigned char pfcs[2]; // 56 - } hdrr; // total 58 union { struct { unsigned char voice[9]; // 17 @@ -73,6 +63,7 @@ typedef struct pkt_tag { } SPKT; #pragma pack(pop) +// for the g2 external port #pragma pack(push, 1) typedef struct dsvt_tag { unsigned char title[4]; // 0 "DSVT" @@ -100,14 +91,15 @@ typedef struct dsvt_tag { } SDSVT; #pragma pack(pop) +// for mmdvm #pragma pack(push, 1) typedef struct mmdvm_tag { // offset size - unsigned char title[4]; // "DSRP" 0 + unsigned char title[4]; // "DSRP" 0 unsigned char tag; // Poll : 0xA 4 // Header : busy ? 0x22 : 0x20 // Voice : busy ? 0x23 : 0x21 union { - unsigned char msg[59]; // space for text (release version) 5 64 + unsigned char poll_msg[59]; // space for text 5 variable, max is 64, including trailing null struct { unsigned short id; // random id number 5 unsigned char seq; // 0x0 7 @@ -119,7 +111,7 @@ typedef struct mmdvm_tag { // offset size unsigned char yr[8]; // Your Call 27 unsigned char my[8]; // My Call 35 unsigned char nm[4]; // Name 43 - unsigned short pcfs; // 47 49 + unsigned short pcfs; // checksum 47 49 } header; struct { unsigned short id; // random id number 5 diff --git a/mmdvm_modem.cpp b/mmdvm_modem.cpp index 3a7fba0..1e96e00 100644 --- a/mmdvm_modem.cpp +++ b/mmdvm_modem.cpp @@ -102,7 +102,7 @@ void CMMDVMModem::ProcessGateway(CUDPSocket &gsock, CUDPSocket &msock) return; if (0 > len) { - printf("ERROR: ProcessGateway: Can't read gateway data\n"); + printf("ERROR: ProcessGateway: Can't read gateway packet\n"); keep_running = false; return; } @@ -110,33 +110,83 @@ void CMMDVMModem::ProcessGateway(CUDPSocket &gsock, CUDPSocket &msock) // if there is data, translate it and send it to the MMDVM Modem if (29==len || 58==len) { //here is dstar data SMMDVMPKT pkt; + memcpy(pkt.title, "DSRP", 4); if (29 == len) { // write an AMBE packet pkt.tag = 0x21U; pkt.voice.id = buf.vpkt.streamid; + pkt.voice.seq = buf.vpkt.ctrl; + if (pkt.voice.seq & 0x40) + printf("INFO: ProcessGateway: sending voice end-of-stream\n"); + else if (pkt.voice.seq > 20) + printf("DEBUG: ProcessGateway: unexpected voice sequence number %d\n", pkt.voice.seq); + memcpy(pkt.voice.ambe, buf.vpkt.vasd.text, 12); if (false == msock.write(pkt.title, 21, mmdvm_addr, MMDVM_PORT)) { - printf("ERROR: ProcessGateway: Could not write AMBE data packet to MMDVMHost\n"); + printf("ERROR: ProcessGateway: Could not write AMBE mmdvm packet\n"); keep_running = false; return; } } else { // write a Header packet pkt.tag = 0x20U; pkt.header.id = buf.vpkt.streamid; + pkt.header.seq = buf.vpkt.ctrl; + if (pkt.header.seq) { + printf("DEBUG: ProcessGateway: unexpected .header.seq %d, resetting to 0\n", pkt.header.seq); + pkt.header.seq = 0; + } + memcpy(pkt.header.flag, buf.vpkt.hdr.flag, 41); if (false == msock.write(pkt.title, 49, mmdvm_addr, MMDVM_PORT)) { - printf("ERROR: ProcessGateway: Could not write Header data packet to MMDVMHost\n"); + printf("ERROR: ProcessGateway: Could not write Header mmdvm packet\n"); keep_running = false; } } - } + } else + printf("DEBUG: ProcessGateway: unusual packet size read len=%d\n", len); } void CMMDVMModem::ProcessMMDVM(CUDPSocket &gsock, CUDPSocket &msock) { + SMMDVMPKT mpkt; + unsigned int mmdvm_port = MMDVM_PORT; + in_addr addr; + addr.s_addr = mmdvm_addr.s_addr; + // read from the MMDVM modem + int len = msock.read(mpkt.title, 64, addr, mmdvm_port); + + if (0 == len) // no data available + return; + + if (0 > len) { + printf("ERROR: ProcessMMDVM: Could not read mmdvm packet\n"); + keep_running = false; + return; + } // if there is data, translate it and send it to the Gateway + if (21==len || 49==len) { + unsigned int g2_internal_port = G2_INTERNAL_PORT; + + SPKT gpkt; + memcpy(gpkt.pkt_id, "DSTR", 4); + gpkt.counter = 0; + gpkt.flag[0] = 0x72; + gpkt.flag[1] = 0x12; + gpkt.flag[2] = 0x0; + gpkt.remaining = (21 == len) ? 0x16 : 0x30; + gpkt.vpkt.icm_id = 0x20; + gpkt.vpkt.dst_rptr_id = 0x0; + gpkt.vpkt.snd_rptr_id = 0x1; + gpkt.vpkt.snd_term_id = ('B'==RPTR_MOD) ? 0x1 : (('C'==RPTR_MOD) ? 0x2 : 0x3); + + if (false == gsock.write(gpkt.pkt_id, (21==len) ? 29 : 58, g2_internal_addr, g2_internal_port)) { + printf("ERROR: ProcessMMDVM: Could not write gateway packet\n"); + keep_running = false; + } + } else + printf("DEBUG: ProcessMMDVM: unusual packet size read len=%d\n", len); } bool CMMDVMModem::GetValue(const Config &cfg, const char *path, int &value, const int min, const int max, const int default_value)