diff --git a/Makefile b/Makefile index deea8e7..5970569 100644 --- a/Makefile +++ b/Makefile @@ -48,7 +48,7 @@ dvrptr : qndvrptr itap : qnitap modem : qnmodem -qngateway : QnetGateway.o aprs.o UnixDgramSocket.o QnetConfigure.o $(IRCOBJS) +qngateway : QnetGateway.o aprs.o UnixDgramSocket.o TCPReaderWriterClient.o QnetConfigure.o $(IRCOBJS) g++ $(CPPFLAGS) -o $@ $^ $(LDFLAGS) -pthread qnlink : QnetLink.o DPlusAuthenticator.o TCPReaderWriterClient.o UnixDgramSocket.o QnetConfigure.o diff --git a/QnetGateway.cpp b/QnetGateway.cpp index 74fcf95..4e267da 100644 --- a/QnetGateway.cpp +++ b/QnetGateway.cpp @@ -2007,9 +2007,9 @@ void CQnetGateway::APRSBeaconThread() time_t last_beacon_time = 0; /* This thread is also saying to the APRS_HOST that we are ALIVE */ while (keep_running) { - if (aprs->GetSock() == -1) { + if (aprs->aprs_sock.GetFD() == -1) { aprs->Open(OWNER); - if (aprs->GetSock() == -1) + if (aprs->aprs_sock.GetFD() == -1) sleep(1); else THRESHOLD_COUNTDOWN = 15; @@ -2058,14 +2058,14 @@ void CQnetGateway::APRSBeaconThread() strcat(snd_buf, "\r\n"); while (keep_running) { - if (aprs->GetSock() == -1) { + if (aprs->aprs_sock.GetFD() == -1) { aprs->Open(OWNER); - if (aprs->GetSock() == -1) + if (aprs->aprs_sock.GetFD() == -1) sleep(1); else THRESHOLD_COUNTDOWN = 15; } else { - int rc = aprs->WriteSock(snd_buf, strlen(snd_buf)); + int rc = aprs->aprs_sock.Write((unsigned char *)snd_buf, strlen(snd_buf)); if (rc < 0) { if ((errno == EPIPE) || (errno == ECONNRESET) || @@ -2079,8 +2079,7 @@ void CQnetGateway::APRSBeaconThread() (errno == EHOSTDOWN) || (errno == ENOTCONN)) { printf("send_aprs_beacon: APRS_HOST closed connection,error=%d\n",errno); - close(aprs->GetSock()); - aprs->SetSock( -1 ); + aprs->aprs_sock.Close(); } else if (errno == EWOULDBLOCK) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); } else { @@ -2093,12 +2092,12 @@ void CQnetGateway::APRSBeaconThread() break; } } - int rc = recv(aprs->GetSock(), rcv_buf, sizeof(rcv_buf), 0); + int rc = aprs->aprs_sock.Read((unsigned char *)rcv_buf, sizeof(rcv_buf)); if (rc > 0) THRESHOLD_COUNTDOWN = 15; } } - int rc = recv(aprs->GetSock(), rcv_buf, sizeof(rcv_buf), 0); + int rc = aprs->aprs_sock.Read((unsigned char *)rcv_buf, sizeof(rcv_buf)); if (rc > 0) THRESHOLD_COUNTDOWN = 15; } @@ -2107,7 +2106,7 @@ void CQnetGateway::APRSBeaconThread() /* Are we still receiving from APRS host ? */ - int rc = recv(aprs->GetSock(), rcv_buf, sizeof(rcv_buf), 0); + int rc = aprs->aprs_sock.Read((unsigned char *)rcv_buf, sizeof(rcv_buf)); if (rc < 0) { if ((errno == EPIPE) || (errno == ECONNRESET) || @@ -2121,13 +2120,11 @@ void CQnetGateway::APRSBeaconThread() (errno == EHOSTDOWN) || (errno == ENOTCONN)) { printf("send_aprs_beacon: recv error: APRS_HOST closed connection,error=%d\n",errno); - close(aprs->GetSock()); - aprs->SetSock( -1 ); + aprs->aprs_sock.Close(); } } else if (rc == 0) { printf("send_aprs_beacon: recv: APRS shutdown\n"); - close(aprs->GetSock()); - aprs->SetSock( -1 ); + aprs->aprs_sock.Close(); } else THRESHOLD_COUNTDOWN = 15; @@ -2137,14 +2134,13 @@ void CQnetGateway::APRSBeaconThread() time(&tnow); if ((tnow - last_keepalive_time) > 20) { /* we should be receving keepalive packets ONLY if the connection is alive */ - if (aprs->GetSock() >= 0) { + if (aprs->aprs_sock.GetFD() >= 0) { if (THRESHOLD_COUNTDOWN > 0) THRESHOLD_COUNTDOWN--; if (THRESHOLD_COUNTDOWN == 0) { printf("APRS host keepalive timeout\n"); - close(aprs->GetSock()); - aprs->SetSock( -1 ); + aprs->aprs_sock.Close(); } } /* reset timer */ @@ -2522,8 +2518,8 @@ CQnetGateway::~CQnetGateway() } if (APRS_ENABLE) { - if (aprs->GetSock() != -1) { - close(aprs->GetSock()); + if (aprs->aprs_sock.GetFD() != -1) { + aprs->aprs_sock.Close(); printf("Closed APRS\n"); } delete aprs; @@ -2711,13 +2707,12 @@ void CQnetGateway::build_aprs_from_gps_and_send(short int rptr_idx) // printf("Built APRS from old GPS mode=[%s]\n", buf); strcat(buf, "\r\n"); - if (-1 == aprs->WriteSock(buf, strlen(buf))) { + if (aprs->aprs_sock.Write((unsigned char *)buf, strlen(buf))) { if ((errno == EPIPE) || (errno == ECONNRESET) || (errno == ETIMEDOUT) || (errno == ECONNABORTED) || (errno == ESHUTDOWN) || (errno == EHOSTUNREACH) || (errno == ENETRESET) || (errno == ENETDOWN) || (errno == ENETUNREACH) || (errno == EHOSTDOWN) || (errno == ENOTCONN)) { printf("build_aprs_from_gps_and_send: APRS_HOST closed connection, error=%d\n", errno); - close(aprs->GetSock()); - aprs->SetSock( -1 ); + aprs->aprs_sock.Close(); } else printf("build_aprs_from_gps_and_send: send error=%d\n", errno); } diff --git a/TCPReaderWriterClient.cpp b/TCPReaderWriterClient.cpp index a09e9a0..e65eba0 100644 --- a/TCPReaderWriterClient.cpp +++ b/TCPReaderWriterClient.cpp @@ -146,8 +146,6 @@ int CTCPReaderWriterClient::Read(unsigned char* buffer, const unsigned int lengt int CTCPReaderWriterClient::ReadLine(std::string& line) { - //maybe there is a better way to do this like reading blocks, pushing them for later calls - //Nevermind, we'll read one char at a time for the time being. unsigned char c; int resultCode; int len = 0; @@ -165,7 +163,7 @@ int CTCPReaderWriterClient::ReadLine(std::string& line) return resultCode <= 0 ? resultCode : len; } -bool CTCPReaderWriterClient::Write(const unsigned char* buffer, const unsigned int length) +bool CTCPReaderWriterClient::Write(const unsigned char *buffer, const unsigned int length) { assert(buffer != NULL); assert(length > 0U); diff --git a/aprs.cpp b/aprs.cpp index 46353c9..21c97f7 100644 --- a/aprs.cpp +++ b/aprs.cpp @@ -89,7 +89,7 @@ void CAPRS::ProcessText(unsigned short streamID, unsigned char seq, unsigned cha if ((tnow - aprs_streamID[rptr_idx].last_time) < 30) return; - if (aprs_sock == -1) + if (aprs_sock.GetFD() == -1) return; char *p = strchr((char*)aprs_data, ':'); @@ -110,7 +110,7 @@ void CAPRS::ProcessText(unsigned short streamID, unsigned char seq, unsigned cha sprintf(aprs_buf, "%s,qAR,%s:%s\r\n", hdr, m_rptr->mod[rptr_idx].call.c_str(), aud); // printf("GPS-A=%s", aprs_buf); - int rc = WriteSock(aprs_buf, strlen(aprs_buf)); + int rc = aprs_sock.Write((unsigned char *)aprs_buf, strlen(aprs_buf)); if (rc == -1) { if ((errno == EPIPE) || (errno == ECONNRESET) || @@ -124,8 +124,7 @@ void CAPRS::ProcessText(unsigned short streamID, unsigned char seq, unsigned cha (errno == EHOSTDOWN) || (errno == ENOTCONN)) { printf("CAPRS::ProcessText(): APRS_HOST closed connection, error=%d\n",errno); - close(aprs_sock); - aprs_sock = -1; + aprs_sock.Close(); } else /* if it is WOULDBLOCK, we will not go into a loop here */ printf("CAPRS::ProcessText(): send error=%d\n", errno); } @@ -152,23 +151,9 @@ void CAPRS::Init() aprs_streamID[i].last_time = 0; } - /* Initialize the APRS host */ - memset(&aprs_addr,0,sizeof(struct sockaddr_in)); - aprs_addr_len = sizeof(aprs_addr); - return; } -int CAPRS::GetSock() -{ - return aprs_sock; -} - -void CAPRS::SetSock(int value) -{ - aprs_sock = value; -} - bool CAPRS::WriteData(short int rptr_idx, unsigned char *data) { @@ -252,90 +237,12 @@ unsigned int CAPRS::GetData(short int rptr_idx, unsigned char *data, unsigned in void CAPRS::Open(const std::string OWNER) { - fd_set fdset; - struct timeval tv; - short int MAX_WAIT = 15; /* 15 seconds wait time MAX */ - int val = 1; - socklen_t val_len; char snd_buf[512]; char rcv_buf[512]; - - bool ok = ResolveRmt(m_rptr->aprs.ip.c_str(), SOCK_STREAM, &aprs_addr); - if (!ok) { - printf("Can't resolve APRS_HOST %s\n", m_rptr->aprs.ip.c_str()); - return; - } - - /* fill it in */ - aprs_addr.sin_family = AF_INET; - aprs_addr.sin_port = htons(m_rptr->aprs.port); - - aprs_addr_len = sizeof(aprs_addr); - - aprs_sock = socket(PF_INET, SOCK_STREAM, 0); - if (aprs_sock == -1) { - printf("Failed to create aprs socket,error=%d\n",errno); - return; - } - fcntl(aprs_sock,F_SETFL,O_NONBLOCK); - - val = 1; - if (setsockopt(aprs_sock,IPPROTO_TCP,TCP_NODELAY,(char *)&val, sizeof(val)) == -1) { - printf("setsockopt TCP_NODELAY TCP for aprs socket failed,error=%d\n",errno); - close(aprs_sock); - aprs_sock = -1; - return; - } - - printf("Trying to connect to APRS...\n"); - int rc = connect(aprs_sock, (struct sockaddr *)&aprs_addr, aprs_addr_len); - if (rc != 0) { - if (errno == EINPROGRESS) { - printf("Waiting for up to %d seconds for APRS_HOST\n", MAX_WAIT); - while (MAX_WAIT > 0) { - tv.tv_sec = 0; - tv.tv_usec = 0; - FD_ZERO(&fdset); - FD_SET(aprs_sock, &fdset); - rc = select(aprs_sock + 1, NULL, &fdset, NULL, &tv); - - if (rc < 0) { - printf("Failed to connect to APRS...select,error=%d\n", errno); - close(aprs_sock); - aprs_sock = -1; - return; - } else if (rc == 0) { /* timeout */ - MAX_WAIT--; - sleep(1); - } else { - val = 1; /* Assume it fails */ - val_len = sizeof(val); - if (getsockopt(aprs_sock, SOL_SOCKET, SO_ERROR, (char *) &val, &val_len) < 0) { - printf("Failed to connect to APRS...getsockopt, error=%d\n", errno); - close(aprs_sock); - aprs_sock = -1; - return; - } else if (val == 0) - break; - - MAX_WAIT--; - sleep(1); - } - } - if (MAX_WAIT == 0) { - printf("Failed to connect to APRS...timeout\n"); - close(aprs_sock); - aprs_sock = -1; - return; - } - } else { - printf("Failed to connect to APRS, error=%d\n", errno); - close(aprs_sock); - aprs_sock = -1; - return; - } - } - printf("Connected to APRS %s:%d\n", m_rptr->aprs.ip.c_str(), m_rptr->aprs.port); + while (aprs_sock.Open(m_rptr->aprs.ip, AF_UNSPEC, std::to_string(m_rptr->aprs.port))) { + fprintf(stderr, "Failed to open %s, retry in 10 seconds...\n", m_rptr->aprs.ip.c_str()); + std::this_thread::sleep_for(std::chrono::seconds(10)); + } /* login to aprs */ sprintf(snd_buf, "user %s pass %d vers qngateway 2.99 UDP 5 ", OWNER.c_str(), m_rptr->aprs_hash); @@ -349,10 +256,10 @@ void CAPRS::Open(const std::string OWNER) strcat(snd_buf, "\r\n"); while (true) { - rc = WriteSock(snd_buf, strlen(snd_buf)); + int rc = aprs_sock.Write((unsigned char *)snd_buf, strlen(snd_buf)); if (rc < 0) { if (errno == EWOULDBLOCK) { - recv(aprs_sock, rcv_buf, sizeof(rcv_buf), 0); + aprs_sock.Read((unsigned char *)rcv_buf, sizeof(rcv_buf)); std::this_thread::sleep_for(std::chrono::milliseconds(100)); } else { printf("APRS login command failed, error=%d\n", errno); @@ -363,7 +270,7 @@ void CAPRS::Open(const std::string OWNER) break; } } - recv(aprs_sock, rcv_buf, sizeof(rcv_buf), 0); + aprs_sock.Read((unsigned char *)rcv_buf, sizeof(rcv_buf)); return; } @@ -491,55 +398,6 @@ unsigned int CAPRS::CalcCRC(unsigned char* buf, unsigned int len) return (~my_crc & 0xffff); } -ssize_t CAPRS::WriteSock(char *buffer, size_t n) -{ - ssize_t num_written = 0; - size_t tot_written = 0; - char *buf = buffer; - - for (tot_written = 0; tot_written < n;) { - num_written = write(aprs_sock, buf, n - tot_written); - if (num_written <= 0) { - if ((num_written == -1) && (errno == EINTR)) - continue; - else - return num_written; - } - tot_written += num_written; - buf += num_written; - } - return tot_written; -} - -bool CAPRS::ResolveRmt(const char *name, int type, struct sockaddr_in *addr) -{ - struct addrinfo hints; - struct addrinfo *res; - struct addrinfo *rp; - bool found = false; - - memset(&hints, 0x00, sizeof(struct addrinfo)); - hints.ai_family = AF_INET; - hints.ai_socktype = type; - - int rc = getaddrinfo(name, NULL, &hints, &res); - if (rc != 0) { - printf("getaddrinfo return error code %d for [%s]\n", rc, name); - return false; - } - - for (rp = res; rp != NULL; rp = rp->ai_next) { - if ((rp->ai_family == AF_INET) && - (rp->ai_socktype == type)) { - memcpy(addr, rp->ai_addr, sizeof(struct sockaddr_in)); - found = true; - break; - } - } - freeaddrinfo(res); - return found; -} - CAPRS::CAPRS(SRPTR *prptr) { m_rptr = prptr; @@ -547,4 +405,10 @@ CAPRS::CAPRS(SRPTR *prptr) CAPRS::~CAPRS() { + aprs_sock.Close(); +} + +void CAPRS::CloseSock() +{ + aprs_sock.Close(); } diff --git a/aprs.h b/aprs.h index 6d304de..cb0f69e 100644 --- a/aprs.h +++ b/aprs.h @@ -23,6 +23,7 @@ #include #include +#include "TCPReaderWriterClient.h" #include "IRCutils.h" enum aprs_level { al_none, al_$1, al_$2, al_c1, al_r1, al_c2, al_csum1, al_csum2, al_csum3, al_csum4, al_data, al_end }; @@ -59,18 +60,13 @@ public: SRPTR *m_rptr; void SelectBand(short int rptr_idx, unsigned short streamID); void ProcessText(unsigned short streamID, unsigned char seq, unsigned char *buf); - ssize_t WriteSock(char *buffer, size_t n); void Open(const std::string OWNER); void Init(); - int GetSock(); - void SetSock(int value); + void CloseSock(); + CTCPReaderWriterClient aprs_sock; private: // data - // the aprs TCP socket - int aprs_sock = -1; - struct sockaddr_in aprs_addr; - socklen_t aprs_addr_len; struct { aprs_level al; unsigned char data[300]; @@ -93,5 +89,4 @@ private: bool AddData(short int rptr_idx, unsigned char *data); bool CheckData(short int rptr_idx); unsigned int CalcCRC(unsigned char* buf, unsigned int len); - bool ResolveRmt(const char *name, int type, struct sockaddr_in *addr); };