mirror of
https://github.com/g4klx/ircDDBGateway.git
synced 2026-04-21 06:03:58 +00:00
Initial commit.
This commit is contained in:
commit
12d55cef37
430 changed files with 72067 additions and 0 deletions
601
APRSTransmit/APRSParser.cpp
Normal file
601
APRSTransmit/APRSParser.cpp
Normal file
|
|
@ -0,0 +1,601 @@
|
|||
/*
|
||||
* Copyright (C) 2014 by Jonathan Naylor G4KLX
|
||||
* APRSTransmit Copyright (C) 2015 Geoffrey Merck F4FXL / KC3FRA
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
// Most of the code has been borrowed from APRX Software. I just kept the parts I need for my purpose and C++ed it. Hence the copyright text below.
|
||||
//https://github.com/PhirePhly/aprx/blob/master/parse_aprs.c
|
||||
|
||||
/********************************************************************
|
||||
* APRX -- 2nd generation APRS-i-gate with *
|
||||
* minimal requirement of esoteric facilities or *
|
||||
* libraries of any kind beyond UNIX system libc. *
|
||||
* *
|
||||
* (c) Matti Aarnio - OH2MQK, 2007-2014 *
|
||||
* *
|
||||
********************************************************************/
|
||||
/*
|
||||
* Some parts of this code are copied from:
|
||||
*
|
||||
* aprsc
|
||||
*
|
||||
* (c) Heikki Hannikainen, OH7LZB <hessu@hes.iki.fi>
|
||||
*
|
||||
* This program is licensed under the BSD license, which can be found
|
||||
* in the file LICENSE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "APRSParser.h"
|
||||
#include <wx/log.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
CAPRSPacket::CAPRSPacket() :
|
||||
m_type(APT_Unknown),
|
||||
m_latitude(0.0F),
|
||||
m_longitude(0.0F),
|
||||
m_symbol('\0'),
|
||||
m_symbolTable('\0'),
|
||||
m_typeChar('\0'),
|
||||
m_body(),
|
||||
m_raw()
|
||||
{
|
||||
}
|
||||
CAPRSPacket::CAPRSPacket(APRSPacketType type, float latitude, float longitude, const wxString& infoText, const wxString raw) :
|
||||
m_type(type),
|
||||
m_latitude(latitude),
|
||||
m_longitude(longitude),
|
||||
m_symbol('\0'),
|
||||
m_symbolTable('\0'),
|
||||
m_typeChar('\0'),
|
||||
m_body(infoText),
|
||||
m_raw(raw),
|
||||
m_destCall(),
|
||||
m_srcCall()
|
||||
{
|
||||
}
|
||||
|
||||
float& CAPRSPacket::Longitude(){
|
||||
return m_longitude;
|
||||
}
|
||||
float& CAPRSPacket::Latitude(){
|
||||
return m_latitude;
|
||||
}
|
||||
wxString& CAPRSPacket::Body(){
|
||||
return m_body;
|
||||
}
|
||||
wxString& CAPRSPacket::Raw(){
|
||||
return m_raw;
|
||||
}
|
||||
|
||||
wxChar& CAPRSPacket::Symbol(){
|
||||
return m_symbol;
|
||||
}
|
||||
|
||||
wxChar& CAPRSPacket::SymbolTable(){
|
||||
return m_symbolTable;
|
||||
}
|
||||
|
||||
wxChar& CAPRSPacket::TypeChar(){
|
||||
return m_typeChar;
|
||||
}
|
||||
|
||||
APRSPacketType& CAPRSPacket::Type(){
|
||||
return m_type;
|
||||
}
|
||||
|
||||
|
||||
wxString& CAPRSPacket::SourceCall(){
|
||||
return m_srcCall;
|
||||
}
|
||||
wxString& CAPRSPacket::DestinationCall(){
|
||||
return m_destCall;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Parsed an APRS string into an APRS frame
|
||||
* currently it does nothing but determine if the packet is Icom supported
|
||||
* I already added provision for conversion of unsupported packet formats to supported formats
|
||||
******************************************************************************/
|
||||
bool CAPRSParser::Parse(const wxString& aprsFrame, CAPRSPacket& packet)
|
||||
{
|
||||
wxString aprsFrameLocal(aprsFrame);
|
||||
stripFrame(aprsFrameLocal);
|
||||
if(!preprocessFrame(packet, aprsFrameLocal))
|
||||
return false;
|
||||
|
||||
switch(packet.TypeChar())
|
||||
{
|
||||
case '\'':
|
||||
case '`' :
|
||||
{
|
||||
//Packet is of MicE type
|
||||
//Icom radios do not support MicE so convert
|
||||
if(parse_aprs_mice(packet)){
|
||||
wxLogMessage(wxT("Got MicE format, converting to Icom supported"));
|
||||
convertToIcomCompatible(packet);
|
||||
return Parse(packet.Raw(), packet);
|
||||
}
|
||||
packet.Type() = APT_Position;
|
||||
return false;
|
||||
}
|
||||
case '!' :
|
||||
if(packet.Body().GetChar(0) == '!'){
|
||||
//Ultimeter 2000 weather station
|
||||
//same procedure as above, ignore for now
|
||||
return false;
|
||||
}
|
||||
case '=' :
|
||||
case '/' :
|
||||
case '@' :
|
||||
{
|
||||
if(packet.Body().Length() < 10) return false;//enough chars to have a chance to parse it ?
|
||||
/* Normal or compressed location packet, with or without
|
||||
* timestamp, with or without messaging capability
|
||||
*
|
||||
* ! and / have messaging, / and @ have a prepended timestamp
|
||||
*/
|
||||
packet.Type() = APT_Position;
|
||||
if(packet.TypeChar() == '/' || packet.TypeChar() == '@')//With a prepended timestamp, jump over it.
|
||||
packet.Body() = packet.Body().Mid(7);
|
||||
|
||||
wxChar posChar = packet.Body().GetChar(0);
|
||||
if(valid_sym_table_compressed(posChar)//Compressed format
|
||||
&& packet.Body().Length() >= 13){//we need at least 13 char
|
||||
//icom unsupported, ignore for now
|
||||
return false;//parse_aprs_compressed(pb, body, body_end);
|
||||
}
|
||||
else if(posChar >= '0' && posChar <= '9' //Normal uncompressed format
|
||||
&& packet.Body().Length() >=19){//we need at least 19 chars for it to be valid
|
||||
|
||||
if(ensureIsIcomCompatible(packet))
|
||||
return Parse(packet.Raw(), packet);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '$' : //NMEA packet
|
||||
if(packet.Body().Length() > 10){
|
||||
packet.Type() = APT_NMEA;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case ':' :
|
||||
//We have an APRS message
|
||||
packet.Type() = APT_Message;
|
||||
//Nice future feature would be to add conversion to icom Android App messaging
|
||||
return false;
|
||||
case ';' :
|
||||
//we have an object
|
||||
if(packet.Body().Length() > 29){
|
||||
//TODO : Parsing ...
|
||||
packet.Type() = APT_Object;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case ')' :
|
||||
//this is an item
|
||||
if(packet.Body().Length() > 19){
|
||||
//TODO : Parsing ...
|
||||
packet.Type() = APT_Item;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case '>' ://APRS status...
|
||||
case '<' ://stat capa
|
||||
case '?' ://Query
|
||||
case 'T' ://Telemetry
|
||||
return false;//not supported
|
||||
case '#': /* Peet Bros U-II Weather Station */
|
||||
case '*': /* Peet Bros U-I Weather Station */
|
||||
case '_': /* Weather report without position */
|
||||
packet.Type() = APT_WX;
|
||||
return true; // AFAIK _ is supported, not sure for the others
|
||||
case '{' ://custom
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CAPRSParser::convertToIcomCompatible(CAPRSPacket& packet)
|
||||
{
|
||||
//first build the coordinate string
|
||||
float degrees = ::floor(::fabs(packet.Latitude()));
|
||||
float minutes = (::fabs(packet.Latitude()) - degrees) * 60.0f;
|
||||
char hemisphere = packet.Latitude() > 0.0f ? 'N' : 'S';
|
||||
wxString latString = wxString::Format(wxT("%02.0f%05.2f%c"), degrees, minutes, hemisphere);
|
||||
|
||||
degrees = ::floor(::fabs(packet.Longitude()));
|
||||
minutes = (::fabs(packet.Longitude()) - degrees) * 60.0f;
|
||||
hemisphere = packet.Longitude() > 0.0f ? 'E' : 'W';
|
||||
wxString longString = wxString::Format(wxT("%03.0f%05.2f%c"), degrees, minutes, hemisphere);
|
||||
|
||||
/*packet.Raw() = wxString::Format(wxT("%s>%s:=%s%c%s%c/%s"),
|
||||
packet.SourceCall().mb_str().data(),
|
||||
packet.DestinationCall().mb_str().data(),
|
||||
latString.mb_str().data(),
|
||||
(char)packet.SymbolTable(),
|
||||
longString.mb_str().data(),
|
||||
(char)packet.Symbol(),
|
||||
packet.Body().mb_str().data());*/
|
||||
|
||||
//above code behaved in different manner under wx2.8 let's do it the brutal way !
|
||||
packet.Raw() = packet.SourceCall()
|
||||
+ wxT(">")
|
||||
+ packet.DestinationCall()
|
||||
+ wxT(":=")
|
||||
+ latString
|
||||
+ packet.SymbolTable()
|
||||
+ longString
|
||||
+ packet.Symbol()
|
||||
+ wxT("/")
|
||||
+ packet.Body();
|
||||
}
|
||||
|
||||
//configures the packet's raw, source call and dest call
|
||||
bool CAPRSParser::preprocessFrame(CAPRSPacket& packet, const wxString& aprsFrame)
|
||||
{
|
||||
wxString addressField = aprsFrame.BeforeFirst(':');
|
||||
wxString body = aprsFrame.AfterFirst(':');
|
||||
if(addressField == aprsFrame || body.IsEmpty()){
|
||||
wxLogWarning(wxT("Failed to find body of aprs frame"));
|
||||
return false;
|
||||
}
|
||||
|
||||
wxString srcCall = addressField.BeforeFirst('>');
|
||||
wxString destCall = addressField.AfterFirst('>');
|
||||
if(srcCall == addressField){
|
||||
wxLogWarning(wxT("Failed to extract source and destination call"));
|
||||
return false;
|
||||
}
|
||||
|
||||
packet.TypeChar() = body.GetChar(0);
|
||||
packet.Body() = body.Mid(1);//strip the type char
|
||||
packet.SourceCall() = srcCall;
|
||||
packet.DestinationCall() = destCall;
|
||||
packet.Raw() = wxString(aprsFrame);
|
||||
packet.Type() = APT_Unknown;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Stupidly icom always expects a / after the symbol char, even if no data extension is present -_-
|
||||
* This function makes sure the frame is icom compatible. In case the frame is invalid, A COMPLETE aprsFrame is built.
|
||||
* If no modifications were made true is returned, otherwise false */
|
||||
bool CAPRSParser::ensureIsIcomCompatible(CAPRSPacket& packet)
|
||||
{
|
||||
bool changeMade = false;
|
||||
wxChar symbol = packet.Body().GetChar(18);
|
||||
wxChar charAfterSymbol = packet.Body().GetChar(19);
|
||||
wxString newBody(packet.Body());
|
||||
wxString aprsFrame(packet.Raw());
|
||||
|
||||
if(charAfterSymbol != '/'
|
||||
&& symbol != '_'){//do not do this for weather packets !
|
||||
newBody = packet.Body().Mid(0, 19) + wxT("/") + packet.Body().Mid(19);
|
||||
aprsFrame.Replace(packet.Body(), newBody);
|
||||
changeMade = true;
|
||||
}
|
||||
|
||||
if(stripFrame(aprsFrame)) changeMade = true;
|
||||
|
||||
packet.Body() = newBody;
|
||||
packet.Raw() = aprsFrame;
|
||||
|
||||
return changeMade;
|
||||
}
|
||||
|
||||
bool CAPRSParser::stripFrame(wxString& aprsFrame)
|
||||
{
|
||||
const unsigned int maxAprsFrameLen = 64U;
|
||||
|
||||
bool changeMade = false;
|
||||
|
||||
//Trim the path, only keep from and to. Icom device do not support too long frames.
|
||||
if(aprsFrame.Length() > maxAprsFrameLen){
|
||||
wxString dataField = aprsFrame.AfterFirst(':');
|
||||
wxString addressField = aprsFrame.BeforeFirst(':');
|
||||
addressField = addressField.BeforeFirst(',');
|
||||
aprsFrame = addressField + wxT(":") + dataField;
|
||||
changeMade = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Still too long ?
|
||||
if(aprsFrame.Length() > maxAprsFrameLen){
|
||||
aprsFrame = aprsFrame.Left(maxAprsFrameLen);
|
||||
changeMade = true;
|
||||
}
|
||||
|
||||
return changeMade;
|
||||
}
|
||||
|
||||
|
||||
bool CAPRSParser::parse_aprs_mice(CAPRSPacket& packet)
|
||||
{
|
||||
float lat = 0.0, lng = 0.0;
|
||||
unsigned int lat_deg = 0, lat_min = 0, lat_min_frag = 0, lng_deg = 0, lng_min = 0, lng_min_frag = 0;
|
||||
//const char *d_start;
|
||||
char dstcall[7];
|
||||
char *p;
|
||||
char sym_table, sym_code;
|
||||
int posambiguity = 0;
|
||||
int i;
|
||||
|
||||
//code below is just to map wxWidgets stuff to original APRX pointer based logic.
|
||||
char* body = new char[packet.Body().length()];
|
||||
for (unsigned int i = 0U; i < packet.Body().length(); i++)
|
||||
body[i] = packet.Body().GetChar(i);
|
||||
char* body_end = body + packet.Body().length();
|
||||
|
||||
char* d_start = new char[packet.Body().length()];
|
||||
for (unsigned int i = 0U; i < packet.Body().length(); i++)
|
||||
d_start[i] = packet.DestinationCall().GetChar(i);
|
||||
char* dstcall_end_or_ssid = d_start + packet.DestinationCall().length();
|
||||
|
||||
|
||||
//Original APRX code follows.. Just a few minor changes
|
||||
|
||||
/* check packet length */
|
||||
if (body_end - body < 8) {
|
||||
delete[] body;
|
||||
delete[] d_start;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* check that the destination call exists and is of the right size for mic-e */
|
||||
//d_start = pb->srccall_end+1;
|
||||
if (dstcall_end_or_ssid - d_start != 6) {
|
||||
//DEBUG_LOG(".. bad destcall length! ");
|
||||
delete[] body;
|
||||
delete[] d_start;
|
||||
return false; /* eh...? */
|
||||
}
|
||||
|
||||
/* validate destination call:
|
||||
* A-K characters are not used in the last 3 characters
|
||||
* and MNO are never used
|
||||
*/
|
||||
//if (debug)printf(" destcall='%6.6s'",d_start);
|
||||
for (i = 0; i < 3; i++)
|
||||
if (!((d_start[i] >= '0' && d_start[i] <= '9')
|
||||
|| (d_start[i] >= 'A' && d_start[i] <= 'L')
|
||||
|| (d_start[i] >= 'P' && d_start[i] <= 'Z'))) {
|
||||
//DEBUG_LOG(".. bad destcall characters in posits 1..3");
|
||||
delete[] body;
|
||||
delete[] d_start;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 3; i < 6; i++)
|
||||
if (!((d_start[i] >= '0' && d_start[i] <= '9')
|
||||
|| (d_start[i] == 'L')
|
||||
|| (d_start[i] >= 'P' && d_start[i] <= 'Z'))) {
|
||||
//DEBUG_LOG(".. bad destcall characters in posits 4..6");
|
||||
delete[] body;
|
||||
delete[] d_start;
|
||||
return false;
|
||||
}
|
||||
|
||||
//DEBUG_LOG("\tpassed dstcall format check");
|
||||
|
||||
/* validate information field (longitude, course, speed and
|
||||
* symbol table and code are checked). Not bullet proof..
|
||||
*
|
||||
* 0 1 23 4 5 6 7
|
||||
* /^[\x26-\x7f][\x26-\x61][\x1c-\x7f]{2}[\x1c-\x7d][\x1c-\x7f][\x21-\x7b\x7d][\/\\A-Z0-9]/
|
||||
*/
|
||||
if (body[0] < 0x26 || body[0] > 0x7f) {
|
||||
//DEBUG_LOG("..bad infofield column 1");
|
||||
delete[] body;
|
||||
delete[] d_start;
|
||||
return false;
|
||||
}
|
||||
if (body[1] < 0x26 || body[1] > 0x61) {
|
||||
//DEBUG_LOG("..bad infofield column 2");
|
||||
delete[] body;
|
||||
delete[] d_start;
|
||||
return false;
|
||||
}
|
||||
if (body[2] < 0x1c || body[2] > 0x7f) {
|
||||
//DEBUG_LOG("..bad infofield column 3");
|
||||
delete[] body;
|
||||
delete[] d_start;
|
||||
return false;
|
||||
}
|
||||
if (body[3] < 0x1c || body[3] > 0x7f) {
|
||||
//DEBUG_LOG("..bad infofield column 4");
|
||||
delete[] body;
|
||||
delete[] d_start;
|
||||
return false;
|
||||
}
|
||||
if (body[4] < 0x1c || body[4] > 0x7d) {
|
||||
//DEBUG_LOG("..bad infofield column 5");
|
||||
//delete[] body;
|
||||
//delete[] d_start;
|
||||
//return false;
|
||||
}
|
||||
if (body[5] < 0x1c || body[5] > 0x7f) {
|
||||
//DEBUG_LOG("..bad infofield column 6");
|
||||
delete[] body;
|
||||
delete[] d_start;
|
||||
return false;
|
||||
}
|
||||
if ((body[6] < 0x21 || body[6] > 0x7b)
|
||||
&& body[6] != 0x7d) {
|
||||
//DEBUG_LOG("..bad infofield column 7");
|
||||
delete[] body;
|
||||
delete[] d_start;
|
||||
return false;
|
||||
}
|
||||
if (!valid_sym_table_uncompressed(body[7])) {
|
||||
//DEBUG_LOG("..bad symbol table entry on column 8");
|
||||
delete[] body;
|
||||
delete[] d_start;
|
||||
return false;
|
||||
}
|
||||
|
||||
//DEBUG_LOG("\tpassed info format check");
|
||||
|
||||
/* make a local copy, we're going to modify it */
|
||||
strncpy(dstcall, d_start, 6);
|
||||
dstcall[6] = 0;
|
||||
|
||||
/* First do the destination callsign
|
||||
* (latitude, message bits, N/S and W/E indicators and long. offset)
|
||||
*
|
||||
* Translate the characters to get the latitude
|
||||
*/
|
||||
|
||||
//fprintf(stderr, "\tuntranslated dstcall: %s\n", dstcall);
|
||||
for (p = dstcall; *p; p++) {
|
||||
if (*p >= 'A' && *p <= 'J')
|
||||
*p -= 'A' - '0';
|
||||
else if (*p >= 'P' && *p <= 'Y')
|
||||
*p -= 'P' - '0';
|
||||
else if (*p == 'K' || *p == 'L' || *p == 'Z')
|
||||
*p = '_';
|
||||
}
|
||||
//fprintf(stderr, "\ttranslated dstcall: %s\n", dstcall);
|
||||
|
||||
// position ambiquity is going to get ignored now,
|
||||
// it's not needed in this application.
|
||||
|
||||
if (dstcall[5] == '_') { dstcall[5] = '5'; posambiguity = 1; }
|
||||
if (dstcall[4] == '_') { dstcall[4] = '5'; posambiguity = 2; }
|
||||
if (dstcall[3] == '_') { dstcall[3] = '5'; posambiguity = 3; }
|
||||
if (dstcall[2] == '_') { dstcall[2] = '3'; posambiguity = 4; }
|
||||
if (dstcall[1] == '_' || dstcall[0] == '_') {
|
||||
//DEBUG_LOG("..bad pos-ambiguity on destcall");
|
||||
delete[] body;
|
||||
delete[] d_start;
|
||||
return false;
|
||||
} // cannot use posamb here
|
||||
|
||||
// convert to degrees, minutes and decimal degrees,
|
||||
// and then to a float lat
|
||||
|
||||
if (sscanf(dstcall, "%2u%2u%2u",
|
||||
&lat_deg, &lat_min, &lat_min_frag) != 3) {
|
||||
//DEBUG_LOG("\tsscanf failed");
|
||||
delete[] body;
|
||||
delete[] d_start;
|
||||
return false;
|
||||
}
|
||||
lat = (float)lat_deg + (float)lat_min / 60.0 + (float)lat_min_frag / 6000.0;
|
||||
|
||||
// check the north/south direction and correct the latitude if necessary
|
||||
if (d_start[3] <= 0x4c)
|
||||
lat = 0 - lat;
|
||||
|
||||
/* Decode the longitude, the first three bytes of the body
|
||||
* after the data type indicator. First longitude degrees,
|
||||
* remember the longitude offset.
|
||||
*/
|
||||
lng_deg = body[0] - 28;
|
||||
if (d_start[4] >= 0x50)
|
||||
lng_deg += 100;
|
||||
if (lng_deg >= 180 && lng_deg <= 189)
|
||||
lng_deg -= 80;
|
||||
else if (lng_deg >= 190 && lng_deg <= 199)
|
||||
lng_deg -= 190;
|
||||
|
||||
/* Decode the longitude minutes */
|
||||
lng_min = body[1] - 28;
|
||||
if (lng_min >= 60)
|
||||
lng_min -= 60;
|
||||
|
||||
/* ... and minute decimals */
|
||||
lng_min_frag = body[2] - 28;
|
||||
|
||||
/* apply position ambiguity to longitude */
|
||||
switch (posambiguity) {
|
||||
case 0:
|
||||
/* use everything */
|
||||
lng = (float)lng_deg + (float)lng_min / 60.0
|
||||
+ (float)lng_min_frag / 6000.0;
|
||||
break;
|
||||
case 1:
|
||||
/* ignore last number of lng_min_frag */
|
||||
lng = (float)lng_deg + (float)lng_min / 60.0
|
||||
+ (float)(lng_min_frag - lng_min_frag % 10 + 5) / 6000.0;
|
||||
break;
|
||||
case 2:
|
||||
/* ignore lng_min_frag */
|
||||
lng = (float)lng_deg + ((float)lng_min + 0.5) / 60.0;
|
||||
break;
|
||||
case 3:
|
||||
/* ignore lng_min_frag and last number of lng_min */
|
||||
lng = (float)lng_deg + (float)(lng_min - lng_min % 10 + 5) / 60.0;
|
||||
break;
|
||||
case 4:
|
||||
/* minute is unused -> add 0.5 degrees to longitude */
|
||||
lng = (float)lng_deg + 0.5;
|
||||
break;
|
||||
default:
|
||||
//DEBUG_LOG(".. posambiguity code BUG!");
|
||||
delete[] body;
|
||||
delete[] d_start;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* check the longitude E/W sign */
|
||||
if (d_start[5] >= 0x50)
|
||||
lng = 0 - lng;
|
||||
|
||||
/* save the symbol table and code */
|
||||
sym_code = body[6];
|
||||
sym_table = body[7];
|
||||
|
||||
/* ok, we're done */
|
||||
/*
|
||||
fprintf(stderr, "\tlat %u %u.%u (%.4f) lng %u %u.%u (%.4f)\n",
|
||||
lat_deg, lat_min, lat_min_frag, lat,
|
||||
lng_deg, lng_min, lng_min_frag, lng);
|
||||
fprintf(stderr, "\tsym '%c' '%c'\n", sym_table, sym_code);
|
||||
*/
|
||||
|
||||
|
||||
//return pbuf_fill_pos(pb, lat, lng, sym_table, sym_code);
|
||||
|
||||
///End of APRX original code
|
||||
packet.Latitude() = lat;
|
||||
packet.Longitude() = lng;
|
||||
packet.Symbol() = sym_code;
|
||||
packet.SymbolTable() = sym_table;
|
||||
packet.Body() = packet.Body().Mid(9);//if MicE has additional info like heading it'll be longer than 9, ignore for now
|
||||
|
||||
delete[] body;
|
||||
delete[] d_start;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CAPRSParser::valid_sym_table_compressed(wxChar c)
|
||||
{
|
||||
return (c == '/' || c == '\\' || (c >= 0x41 && c <= 0x5A)
|
||||
|| (c >= 0x61 && c <= 0x6A)); /* [\/\\A-Za-j] */
|
||||
}
|
||||
|
||||
bool CAPRSParser::valid_sym_table_uncompressed(wxChar c)
|
||||
{
|
||||
return (c == '/' || c == '\\' || (c >= 0x41 && c <= 0x5A)
|
||||
|| (c >= 0x30 && c <= 0x39)); /* [\/\\A-Z0-9] */
|
||||
}
|
||||
79
APRSTransmit/APRSParser.h
Normal file
79
APRSTransmit/APRSParser.h
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright (C) 2014 by Jonathan Naylor G4KLX
|
||||
* APRSTransmit Copyright (C) 2015 Geoffrey Merck F4FXL / KC3FRA
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef APRSParserAppD_H
|
||||
#define APRSParserAppD_H
|
||||
|
||||
#include <wx/string.h>
|
||||
|
||||
enum APRSPacketType {
|
||||
APT_Unknown,
|
||||
APT_Position,
|
||||
APT_WX,
|
||||
APT_Object,
|
||||
APT_Item,
|
||||
APT_Message,
|
||||
APT_NMEA
|
||||
};
|
||||
|
||||
class CAPRSPacket{
|
||||
public :
|
||||
CAPRSPacket();
|
||||
CAPRSPacket(APRSPacketType type, float latitude, float longitude, const wxString& infoText, const wxString raw);
|
||||
|
||||
float& Longitude();
|
||||
float& Latitude();
|
||||
wxString& SourceCall();
|
||||
wxChar& Symbol();
|
||||
wxChar& SymbolTable();
|
||||
wxChar& TypeChar();
|
||||
wxString& DestinationCall();
|
||||
wxString& Body();
|
||||
wxString& Raw();
|
||||
APRSPacketType& Type();
|
||||
|
||||
private:
|
||||
APRSPacketType m_type;
|
||||
float m_latitude;
|
||||
float m_longitude;
|
||||
wxChar m_symbol;
|
||||
wxChar m_symbolTable;
|
||||
wxChar m_typeChar;
|
||||
wxString m_body;
|
||||
wxString m_raw;//raw string in TNC2 format, including '\r'
|
||||
wxString m_destCall;
|
||||
wxString m_srcCall;
|
||||
};
|
||||
|
||||
class CAPRSParser{
|
||||
public:
|
||||
static bool Parse(const wxString& aprsString, CAPRSPacket& packet);
|
||||
|
||||
private :
|
||||
static bool valid_sym_table_compressed(wxChar c);
|
||||
static bool valid_sym_table_uncompressed(wxChar c);
|
||||
static bool parse_aprs_mice(CAPRSPacket& packet);
|
||||
|
||||
static bool ensureIsIcomCompatible(CAPRSPacket& packet);
|
||||
static bool stripFrame(wxString& aprsFrame);
|
||||
static bool preprocessFrame(CAPRSPacket& packet, const wxString& aprsFrame);
|
||||
static void convertToIcomCompatible(CAPRSPacket& packet);
|
||||
};
|
||||
|
||||
#endif
|
||||
174
APRSTransmit/APRSTransmit.cpp
Normal file
174
APRSTransmit/APRSTransmit.cpp
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
/*
|
||||
* Copyright (C) 2014 by Jonathan Naylor G4KLX
|
||||
* APRSTransmit Copyright (C) 2015 Geoffrey Merck F4FXL / KC3FRA
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "SlowDataEncoder.h"
|
||||
#include "DStarDefines.h"
|
||||
#include "APRSTransmit.h"
|
||||
#include "APRSParser.h"
|
||||
|
||||
|
||||
CAPRSTransmit::CAPRSTransmit(const wxString& callsign, const wxString& text) :
|
||||
m_socket(wxEmptyString, 0U),
|
||||
m_repeaterCallsign(callsign),
|
||||
m_APRSCallsign(callsign),
|
||||
m_text(text)
|
||||
{
|
||||
int index = m_text.Find(wxT(">"));
|
||||
if(index != wxNOT_FOUND)
|
||||
m_APRSCallsign = m_text.Left(index);
|
||||
}
|
||||
|
||||
CAPRSTransmit::~CAPRSTransmit()
|
||||
{
|
||||
}
|
||||
|
||||
bool CAPRSTransmit::run()
|
||||
{
|
||||
//First see if the packet is Icom supported...
|
||||
CAPRSPacket aprsPacket;
|
||||
if(!CAPRSParser::Parse(m_text, aprsPacket)){
|
||||
wxLogWarning(wxT("Unsupported APRS Format, ignoring => ") + m_text.Trim(true));
|
||||
return false;
|
||||
}
|
||||
|
||||
wxString textWithCRC(aprsPacket.Raw());
|
||||
wxLogMessage(wxT("Supported APRS Format => ") + textWithCRC.Trim(true));
|
||||
//add nececessary stuff to text, but keep it the original
|
||||
textWithCRC.Replace(wxT("\n"), wxEmptyString);
|
||||
if(!textWithCRC.EndsWith(wxT("\r"))) textWithCRC.Append(wxT("\r"));
|
||||
wxString crc = wxString::Format(wxT("$$CRC%04X,"), calcCRC(textWithCRC));
|
||||
textWithCRC.Prepend(crc);
|
||||
|
||||
bool opened = m_socket.open();
|
||||
if (!opened)
|
||||
return false;
|
||||
|
||||
in_addr address = CUDPReaderWriter::lookup(wxT("127.0.0.1"));
|
||||
|
||||
unsigned int id = CHeaderData::createId();
|
||||
|
||||
wxString callsignG = m_repeaterCallsign.Left(LONG_CALLSIGN_LENGTH - 1U);
|
||||
callsignG.Append(wxT("G"));
|
||||
|
||||
CHeaderData header;
|
||||
header.setId(id);
|
||||
header.setMyCall1(m_APRSCallsign);
|
||||
header.setMyCall2(wxT("APRS"));
|
||||
header.setRptCall1(callsignG);
|
||||
header.setRptCall2(m_repeaterCallsign);
|
||||
header.setYourCall(wxT("CQCQCQ "));
|
||||
header.setDestination(address, G2_DV_PORT);
|
||||
|
||||
sendHeader(header);
|
||||
|
||||
CSlowDataEncoder encoder;
|
||||
encoder.setHeaderData(header);
|
||||
encoder.setGPSData(textWithCRC);
|
||||
encoder.setTextData(wxT("APRS to DPRS"));
|
||||
|
||||
CAMBEData data;
|
||||
data.setDestination(address, G2_DV_PORT);
|
||||
data.setId(id);
|
||||
|
||||
wxStopWatch timer;
|
||||
timer.Start();
|
||||
|
||||
unsigned int out = 0U;
|
||||
unsigned int dataOut = 0U;
|
||||
unsigned int needed = (encoder.getInterleavedDataLength() / (DATA_FRAME_LENGTH_BYTES)) * 2U;
|
||||
|
||||
while (dataOut < needed) {
|
||||
data.setSeq(out);
|
||||
|
||||
unsigned char buffer[DV_FRAME_LENGTH_BYTES];
|
||||
::memcpy(buffer + 0U, NULL_AMBE_DATA_BYTES, VOICE_FRAME_LENGTH_BYTES);
|
||||
|
||||
// Insert sync bytes when the sequence number is zero, slow data otherwise
|
||||
if (out == 0U) {
|
||||
::memcpy(buffer + VOICE_FRAME_LENGTH_BYTES, DATA_SYNC_BYTES, DATA_FRAME_LENGTH_BYTES);
|
||||
} else {
|
||||
encoder.getInterleavedData(buffer + VOICE_FRAME_LENGTH_BYTES);
|
||||
dataOut++;
|
||||
}
|
||||
|
||||
data.setData(buffer, DV_FRAME_LENGTH_BYTES);
|
||||
|
||||
sendData(data);
|
||||
out++;
|
||||
|
||||
if (out == 21U) out = 0U;
|
||||
}
|
||||
|
||||
data.setData(END_PATTERN_BYTES, DV_FRAME_LENGTH_BYTES);
|
||||
data.setSeq(out >= 21U ? 0U : out);
|
||||
data.setEnd(true);
|
||||
|
||||
sendData(data);
|
||||
|
||||
m_socket.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CAPRSTransmit::sendHeader(const CHeaderData& header)
|
||||
{
|
||||
unsigned char buffer[60U];
|
||||
unsigned int length = header.getG2Data(buffer, 60U, true);
|
||||
|
||||
for (unsigned int i = 0U; i < 2U; i++) {
|
||||
bool res = m_socket.write(buffer, length, header.getYourAddress(), header.getYourPort());
|
||||
if (!res)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CAPRSTransmit::sendData(const CAMBEData& data)
|
||||
{
|
||||
unsigned char buffer[60U];
|
||||
unsigned int length = data.getG2Data(buffer, 60U);
|
||||
|
||||
return m_socket.write(buffer, length, data.getYourAddress(), data.getYourPort());
|
||||
}
|
||||
|
||||
unsigned int CAPRSTransmit::calcCRC(const wxString& gpsData)
|
||||
{
|
||||
size_t length = gpsData.length();
|
||||
wxASSERT(length > 0U);
|
||||
|
||||
unsigned int icomcrc = 0xFFFFU;
|
||||
|
||||
for (unsigned int j = 0U; j < length; j++) {
|
||||
unsigned char ch = gpsData.GetChar(j);
|
||||
|
||||
for (unsigned int i = 0U; i < 8U; i++) {
|
||||
bool xorflag = (((icomcrc ^ ch) & 0x01U) == 0x01U);
|
||||
|
||||
icomcrc >>= 1;
|
||||
|
||||
if (xorflag)
|
||||
icomcrc ^= 0x8408U;
|
||||
|
||||
ch >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
return ~icomcrc & 0xFFFFU;
|
||||
}
|
||||
44
APRSTransmit/APRSTransmit.h
Normal file
44
APRSTransmit/APRSTransmit.h
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (C) 2014 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef TextTransmit_H
|
||||
#define TextTransmit_H
|
||||
|
||||
#include "UDPReaderWriter.h"
|
||||
#include "HeaderData.h"
|
||||
#include "AMBEData.h"
|
||||
|
||||
class CAPRSTransmit {
|
||||
public:
|
||||
CAPRSTransmit(const wxString& callsign, const wxString& text);
|
||||
~CAPRSTransmit();
|
||||
|
||||
bool run();
|
||||
|
||||
private:
|
||||
CUDPReaderWriter m_socket;
|
||||
wxString m_repeaterCallsign;
|
||||
wxString m_APRSCallsign;
|
||||
wxString m_text;
|
||||
|
||||
bool sendHeader(const CHeaderData& header);
|
||||
bool sendData(const CAMBEData& data);
|
||||
unsigned int calcCRC(const wxString& gpsData);
|
||||
};
|
||||
|
||||
#endif
|
||||
188
APRSTransmit/APRSTransmit.vcxproj
Normal file
188
APRSTransmit/APRSTransmit.vcxproj
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{F26EA1DB-74CF-4C52-A425-00235C8ABED2}</ProjectGuid>
|
||||
<RootNamespace>APRSTransmit</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>14.0.24720.0</_ProjectFileVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
|
||||
<IntDir>$(Configuration)\$(ProjectName)</IntDir>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>$(WXWIN)\include;$(WXWIN)\lib\vc_dll\mswud;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>$(WXWIN)\include;$(WXWIN)\lib\vc_x64_dll\mswud;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
|
||||
<IntDir>$(Configuration)\$(ProjectName)</IntDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>$(WXWIN)\include\msvc;$(WXWIN)\include;../Common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;WINVER=0x0400;__WXMSW__;WXUSINGDLL;wxUSE_GUI=1;__WXDEBUG__;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATEWIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader />
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(WXWIN)\lib\vc_dll;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>$(WXWIN)\include\msvc;$(WXWIN)\include;../Common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;WINVER=0x0400;__WXMSW__;WXUSINGDLL;wxUSE_GUI=1;__WXDEBUG__;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATEWIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(WXWIN)\lib\vc_x64_dll;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>$(WXWIN)\include\msvc;$(WXWIN)\include;../ircDDB;../Common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;WINVER=0x0400;__WXMSW__;WXUSINGDLL;wxUSE_GUI=1;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<PrecompiledHeader />
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(WXWIN)\lib\vc_dll;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>$(WXWIN)\include\msvc;$(WXWIN)\include;../ircDDB;../Common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;WINVER=0x0400;__WXMSW__;WXUSINGDLL;wxUSE_GUI=1;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(WXWIN)\lib\vc_x64_dll;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="APRSParser.cpp" />
|
||||
<ClCompile Include="APRSTransmit.cpp" />
|
||||
<ClCompile Include="APRSTransmitApp.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="APRSParser.h" />
|
||||
<ClInclude Include="APRSTransmit.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Common\Common.vcxproj">
|
||||
<Project>{e793cb8e-2ac9-431a-bbfc-3f52537bb3cf}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
32
APRSTransmit/APRSTransmit.vcxproj.filters
Normal file
32
APRSTransmit/APRSTransmit.vcxproj.filters
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="APRSParser.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="APRSTransmit.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="APRSTransmitApp.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="APRSParser.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="APRSTransmit.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
100
APRSTransmit/APRSTransmitApp.cpp
Normal file
100
APRSTransmit/APRSTransmitApp.cpp
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Copyright (C) 2014 by Jonathan Naylor G4KLX
|
||||
* APRSTransmit Copyright (C) 2015 Geoffrey Merck F4FXL / KC3FRA
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "DStarDefines.h"
|
||||
#include "APRSTransmit.h"
|
||||
|
||||
#include <wx/textfile.h>
|
||||
#include <wx/cmdline.h>
|
||||
|
||||
const wxChar* REPEATER_PARAM = wxT("Repeater");
|
||||
const wxChar* FILE_OPTION = wxT("file");
|
||||
const wxChar* APRS_OPTION = wxT("aprs");
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
bool res = ::wxInitialize();
|
||||
if (!res) {
|
||||
::fprintf(stderr, "aprstransmit: failed to initialise the wxWidgets library, exiting\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
wxCmdLineParser parser(argc, argv);
|
||||
parser.AddParam(REPEATER_PARAM, wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL);
|
||||
parser.AddOption(APRS_OPTION, wxEmptyString, wxEmptyString, wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL);
|
||||
parser.AddOption(FILE_OPTION, wxEmptyString, wxEmptyString, wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL);
|
||||
|
||||
int cmd = parser.Parse();
|
||||
if (cmd != 0) {
|
||||
::wxUninitialize();
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (parser.GetParamCount() < 1U) {
|
||||
::fprintf(stderr, "aprstransmit: invalid command line usage: aprstransmit <repeater> -aprs <aprs_tnc2_string>|-file <filename>, exiting\n");
|
||||
::wxUninitialize();
|
||||
return 1;
|
||||
}
|
||||
|
||||
wxString text;
|
||||
bool aprsFound = parser.Found(APRS_OPTION, &text);
|
||||
|
||||
wxString filename;
|
||||
bool fileFound = parser.Found(FILE_OPTION, &filename);
|
||||
|
||||
if (!aprsFound && !fileFound) {
|
||||
::fprintf(stderr, "aprstransmit: invalid command line usage: aprstransmit <repeater> -aprs <text>|-file <filename>, exiting\n");
|
||||
::wxUninitialize();
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (aprsFound && fileFound) {
|
||||
::fprintf(stderr, "aprstransmit: invalid command line usage: aprstransmit <repeater> -aprs <text>|-file <filename>, exiting\n");
|
||||
::wxUninitialize();
|
||||
return 1;
|
||||
}
|
||||
|
||||
wxString repeater = parser.GetParam(0U);
|
||||
repeater.Replace(wxT("_"), wxT(" "));
|
||||
repeater.resize(LONG_CALLSIGN_LENGTH, wxT(' '));
|
||||
repeater.MakeUpper();
|
||||
|
||||
if (fileFound) {
|
||||
wxTextFile file;
|
||||
bool found = file.Open(filename);
|
||||
if (!found) {
|
||||
::fprintf(stderr, "aprstransmit: unable to open the file, exiting\n");
|
||||
::wxUninitialize();
|
||||
return 1;
|
||||
}
|
||||
|
||||
text = file.GetFirstLine();
|
||||
|
||||
file.Close();
|
||||
}
|
||||
|
||||
|
||||
CAPRSTransmit tt(repeater, text);
|
||||
bool ret = tt.run();
|
||||
|
||||
::wxUninitialize();
|
||||
|
||||
return ret ? 0 : 1;
|
||||
}
|
||||
|
||||
272
APRSTransmit/APRSTransmitAppD.cpp
Normal file
272
APRSTransmit/APRSTransmitAppD.cpp
Normal file
|
|
@ -0,0 +1,272 @@
|
|||
/*
|
||||
* Copyright (C) 2014 by Jonathan Naylor G4KLX
|
||||
* APRSTransmit Copyright (C) 2015 Geoffrey Merck F4FXL / KC3FRA
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "DStarDefines.h"
|
||||
#include "APRSTransmit.h"
|
||||
#include "APRSTransmitAppD.h"
|
||||
#include "APRSWriterThread.h"
|
||||
|
||||
#include <wx/textfile.h>
|
||||
#include <wx/cmdline.h>
|
||||
#include <signal.h>
|
||||
#include <iostream>
|
||||
|
||||
#if defined(__WINDOWS__)
|
||||
#include <Windows.h>
|
||||
#include <wx/filename.h>
|
||||
#endif
|
||||
|
||||
const wxChar* REPEATER_PARAM = wxT("Repeater");
|
||||
const wxChar* APRS_HOST = wxT("host");
|
||||
const wxChar* APRS_PORT = wxT("port");
|
||||
const wxChar* APRS_FILTER = wxT("filter");
|
||||
const wxChar* DAEMON_SWITCH = wxT("daemon");
|
||||
|
||||
static CAPRSTransmitAppD* m_aprsTransmit = NULL;
|
||||
|
||||
static void handler(int signum)
|
||||
{
|
||||
m_aprsTransmit->kill();
|
||||
}
|
||||
|
||||
static void aprsFrameCallback(const wxString& aprsFrame)
|
||||
{
|
||||
//wxLogMessage(wxT("Received APRS Frame : ") + aprsFrame);
|
||||
m_aprsTransmit->m_aprsFramesQueue->addData(new wxString(aprsFrame.Clone()));
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
bool res = ::wxInitialize();
|
||||
if (!res) {
|
||||
::fprintf(stderr, "aprstransmit: failed to initialise the wxWidgets library, exiting\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
wxCmdLineParser parser(argc, argv);
|
||||
parser.AddParam(REPEATER_PARAM, wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL);
|
||||
parser.AddOption(APRS_HOST, wxEmptyString, wxEmptyString, wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL);
|
||||
parser.AddOption(APRS_PORT, wxEmptyString, wxEmptyString, wxCMD_LINE_VAL_NUMBER, wxCMD_LINE_PARAM_OPTIONAL);
|
||||
parser.AddOption(APRS_FILTER, wxEmptyString, wxEmptyString, wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL);
|
||||
parser.AddSwitch(DAEMON_SWITCH, wxEmptyString, wxEmptyString, wxCMD_LINE_PARAM_OPTIONAL);
|
||||
|
||||
int cmd = parser.Parse();
|
||||
if (cmd != 0) {
|
||||
::wxUninitialize();
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (parser.GetParamCount() < 1U) {
|
||||
::fprintf(stderr, "aprstransmitd: invalid command line usage: aprstransmitd <repeater> [-host <aprs_server>] [-port <aprs_port>] [-filter <aprsis_filter1>[;<aprsis_filter2]] [-daemon] exiting\n");
|
||||
::wxUninitialize();
|
||||
return 1;
|
||||
}
|
||||
|
||||
wxString repeater = parser.GetParam(0U);
|
||||
if (repeater.length() != LONG_CALLSIGN_LENGTH) {
|
||||
wxString callErrorMsg;
|
||||
callErrorMsg << wxT("Invalid repeater call. ") << repeater << wxT("Call must be ") << LONG_CALLSIGN_LENGTH << wxT(" characters long.\n");
|
||||
callErrorMsg << wxT("Valid example : A1ABC__B\n");
|
||||
::fputs(callErrorMsg.c_str(), stderr);
|
||||
::wxUninitialize();
|
||||
return 1;
|
||||
}
|
||||
repeater.Replace(wxT("_"), wxT(" "));
|
||||
repeater.MakeUpper();
|
||||
|
||||
long aprsPort;
|
||||
if(!parser.Found(APRS_PORT, &aprsPort))
|
||||
aprsPort = 14580;
|
||||
|
||||
wxString aprsHost;
|
||||
if(!parser.Found(APRS_HOST, &aprsHost)){
|
||||
aprsHost = wxT("rotate.aprs2.net");
|
||||
}
|
||||
|
||||
wxString aprsFilter;
|
||||
if(!parser.Found(APRS_FILTER, &aprsFilter)) {
|
||||
/* no filter specified on command line,
|
||||
build one which will tell the APRS server to pass
|
||||
us all stations 50km around our repeater */
|
||||
aprsFilter = wxT("m/50");
|
||||
}
|
||||
|
||||
bool daemon = parser.Found(DAEMON_SWITCH);
|
||||
|
||||
#if defined(__WINDOWS__)
|
||||
m_aprsTransmit = new CAPRSTransmitAppD(repeater, aprsHost, aprsPort, aprsFilter, daemon);
|
||||
if (!m_aprsTransmit->init()) {
|
||||
::wxUninitialize();
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
if (daemon) {
|
||||
pid_t pid = ::fork();
|
||||
|
||||
if (pid < 0) {
|
||||
::fprintf(stderr, "aprstransmitd: error in fork(), exiting\n");
|
||||
::wxUninitialize();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// If this is the parent, exit
|
||||
if (pid > 0)
|
||||
return 0;
|
||||
|
||||
// We are the child from here onwards
|
||||
::setsid();
|
||||
::chdir("/");
|
||||
::umask(0);
|
||||
}
|
||||
|
||||
//create a pid file
|
||||
wxString pidFileName = wxT("/var/run/aprstransmit.pid");
|
||||
FILE* fp = ::fopen(pidFileName.mb_str(), "wt");
|
||||
if (fp != NULL) {
|
||||
::fprintf(fp, "%u\n", ::getpid());
|
||||
::fclose(fp);
|
||||
}
|
||||
|
||||
m_aprsTransmit = new CAPRSTransmitAppD(repeater, aprsHost, aprsPort, aprsFilter, daemon);
|
||||
if (!m_aprsTransmit->init()) {
|
||||
::wxUninitialize();
|
||||
return 1;
|
||||
}
|
||||
|
||||
::signal(SIGUSR1, handler);
|
||||
|
||||
|
||||
::unlink(pidFileName.mb_str());
|
||||
#endif
|
||||
m_aprsTransmit->run();
|
||||
delete m_aprsTransmit;
|
||||
::wxUninitialize();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CAPRSTransmitAppD::CAPRSTransmitAppD(const wxString& repeater, const wxString& aprsHost, unsigned int aprsPort, const wxString& aprsFilter, bool daemon) :
|
||||
m_aprsFramesQueue(NULL),
|
||||
m_repeater(repeater),
|
||||
m_aprsHost(aprsHost),
|
||||
m_aprsFilter(aprsFilter),
|
||||
m_aprsPort(aprsPort),
|
||||
m_aprsThread(NULL),
|
||||
m_run(false),
|
||||
m_checker(NULL),
|
||||
m_daemon(daemon)
|
||||
{
|
||||
}
|
||||
|
||||
CAPRSTransmitAppD::~CAPRSTransmitAppD()
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
|
||||
|
||||
bool CAPRSTransmitAppD::init()
|
||||
{
|
||||
#if defined(__WINDOWS__)
|
||||
wxString tempPath = wxFileName::GetTempDir();
|
||||
m_checker = new wxSingleInstanceChecker(wxT("aprstransmit"), tempPath);
|
||||
#else
|
||||
m_checker = new wxSingleInstanceChecker(wxT("aprstransmit"), wxT("/tmp"));
|
||||
#endif
|
||||
bool ret = m_checker->IsAnotherRunning();
|
||||
if (ret) {
|
||||
wxLogError(wxT("Another copy of APRSTransmit is running, exiting"));
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(__WINDOWS__)
|
||||
wxLog* logger = new wxLogStream(&std::cout);
|
||||
wxLog::SetActiveTarget(logger);
|
||||
wxLog::SetLogLevel(wxLOG_Message);
|
||||
if(m_daemon)
|
||||
wxLogMessage(wxT("Daemon not supported under Windows, ignoring"));
|
||||
m_daemon = false;
|
||||
#else
|
||||
if(!m_daemon){
|
||||
wxLog* logger = new wxLogStream(&std::cout);
|
||||
wxLog::SetActiveTarget(logger);
|
||||
wxLog::SetLogLevel(wxLOG_Message);
|
||||
} else {
|
||||
new wxLogNull;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CAPRSTransmitAppD::run()
|
||||
{
|
||||
if(m_run) return;
|
||||
|
||||
m_aprsFramesQueue = new CRingBuffer<wxString*>(30U);
|
||||
m_aprsThread = new CAPRSWriterThread(m_repeater, wxT("0.0.0.0"), m_aprsHost, m_aprsPort, m_aprsFilter, wxT("APRSTransmit 1.1"));
|
||||
m_aprsThread->setReadAPRSCallback(aprsFrameCallback);
|
||||
m_aprsThread->start();
|
||||
|
||||
wxString * aprsFrame;
|
||||
|
||||
m_run = true;
|
||||
while(m_run){
|
||||
wxMilliSleep(10U);
|
||||
aprsFrame = m_aprsFramesQueue->getData();
|
||||
if(aprsFrame){
|
||||
CAPRSTransmit aprsTransmit(m_repeater, wxString(*aprsFrame));
|
||||
aprsTransmit.run();
|
||||
delete aprsFrame;
|
||||
}
|
||||
}
|
||||
|
||||
m_aprsThread->stop();
|
||||
|
||||
cleanup();
|
||||
}
|
||||
|
||||
|
||||
void CAPRSTransmitAppD::cleanup()
|
||||
{
|
||||
m_aprsThread->setReadAPRSCallback(NULL);
|
||||
|
||||
if(m_aprsFramesQueue)
|
||||
{
|
||||
while(m_aprsFramesQueue->peek()) delete m_aprsFramesQueue->getData();
|
||||
delete m_aprsFramesQueue;
|
||||
m_aprsFramesQueue = NULL;
|
||||
}
|
||||
if(m_checker) {
|
||||
delete m_checker;
|
||||
m_checker = NULL;
|
||||
}
|
||||
|
||||
if(m_aprsThread)
|
||||
{
|
||||
delete m_aprsThread;
|
||||
m_aprsThread = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void CAPRSTransmitAppD::kill()
|
||||
{
|
||||
m_run = false;
|
||||
}
|
||||
|
||||
54
APRSTransmit/APRSTransmitAppD.h
Normal file
54
APRSTransmit/APRSTransmitAppD.h
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (C) 2014 by Jonathan Naylor G4KLX
|
||||
* APRSTransmit Copyright (C) 2015 Geoffrey Merck F4FXL / KC3FRA
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef APRSTransmitAppD_H
|
||||
#define APRSTransmitAppD_H
|
||||
|
||||
#include "RingBuffer.h"
|
||||
#include "APRSWriterThread.h"
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include <wx/config.h>
|
||||
#include <wx/snglinst.h>
|
||||
|
||||
|
||||
class CAPRSTransmitAppD {
|
||||
|
||||
public:
|
||||
CAPRSTransmitAppD(const wxString& repeater, const wxString& aprsHost, unsigned int aprsPort, const wxString& aprsFilter, bool daemon);
|
||||
~CAPRSTransmitAppD();
|
||||
|
||||
CRingBuffer<wxString*> * m_aprsFramesQueue;
|
||||
|
||||
bool init();
|
||||
void run();
|
||||
void kill();
|
||||
|
||||
private:
|
||||
wxString m_repeater, m_aprsHost, m_aprsFilter;
|
||||
unsigned int m_aprsPort;
|
||||
CAPRSWriterThread * m_aprsThread;
|
||||
bool m_run;
|
||||
wxSingleInstanceChecker * m_checker;
|
||||
bool m_daemon;
|
||||
|
||||
void cleanup();
|
||||
};
|
||||
|
||||
#endif
|
||||
189
APRSTransmit/APRSTransmitD.vcxproj
Normal file
189
APRSTransmit/APRSTransmitD.vcxproj
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{C706EF5D-3917-4796-8BEB-823498A1B13C}</ProjectGuid>
|
||||
<RootNamespace>APRSTransmit</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>14.0.24720.0</_ProjectFileVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
|
||||
<IntDir>$(Configuration)\$(ProjectName)\</IntDir>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>$(WXWIN)\include;$(WXWIN)\lib\vc_dll\mswud;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>$(WXWIN)\include;$(WXWIN)\lib\vc_dll\mswud;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
|
||||
<IntDir>$(Configuration)\$(ProjectName)\</IntDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>$(WXWIN)\include\msvc;$(WXWIN)\include;../Common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;WINVER=0x0400;__WXMSW__;WXUSINGDLL;wxUSE_GUI=1;__WXDEBUG__;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATEWIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader />
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(WXWIN)\lib\vc_dll;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>$(WXWIN)\include\msvc;$(WXWIN)\include;../Common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;WINVER=0x0400;__WXMSW__;WXUSINGDLL;wxUSE_GUI=1;__WXDEBUG__;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATEWIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(WXWIN)\lib\vc_x64_dll;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>$(WXWIN)\include\msvc;$(WXWIN)\include;../ircDDB;../Common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;WINVER=0x0400;__WXMSW__;WXUSINGDLL;wxUSE_GUI=1;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<PrecompiledHeader />
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(WXWIN)\lib\vc_dll;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>$(WXWIN)\include\msvc;$(WXWIN)\include;../ircDDB;../Common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;WINVER=0x0400;__WXMSW__;WXUSINGDLL;wxUSE_GUI=1;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(WXWIN)\lib\vc_x64_dll;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="APRSParser.cpp" />
|
||||
<ClCompile Include="APRSTransmit.cpp" />
|
||||
<ClCompile Include="APRSTransmitAppD.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="APRSParser.h" />
|
||||
<ClInclude Include="APRSTransmit.h" />
|
||||
<ClInclude Include="APRSTransmitAppD.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Common\Common.vcxproj">
|
||||
<Project>{e793cb8e-2ac9-431a-bbfc-3f52537bb3cf}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
35
APRSTransmit/APRSTransmitD.vcxproj.filters
Normal file
35
APRSTransmit/APRSTransmitD.vcxproj.filters
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="APRSParser.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="APRSTransmit.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="APRSTransmitAppD.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="APRSParser.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="APRSTransmit.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="APRSTransmitAppD.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Loading…
Add table
Add a link
Reference in a new issue