Upstream version 3.0preAB

pull/2/head
Stelios Bounanos 2008-08-03 01:04:18 +01:00
rodzic 1813c00740
commit 940642e7b9
8 zmienionych plików z 320 dodań i 218 usunięć

Wyświetl plik

@ -9,7 +9,7 @@ dnl major and minor must be integers; patch may
dnl contain other characters or be empty
m4_define(FLDIGI_MAJOR, [3])
m4_define(FLDIGI_MINOR, [0])
m4_define(FLDIGI_PATCH, [preAA])
m4_define(FLDIGI_PATCH, [preAB])
AC_INIT([fldigi], FLDIGI_MAJOR.FLDIGI_MINOR[FLDIGI_PATCH], [w1hkj AT w1hkj DOT com])

Wyświetl plik

@ -259,7 +259,7 @@ fldigi_SOURCES += \
misc/macros.cxx \
misc/misc.cxx \
misc/newinstall.cxx \
misc/pskmail.cxx \
misc/arq_io.cxx \
misc/qrzcall.cxx \
misc/qrzlib.cxx \
misc/stacktrace.cxx \

Wyświetl plik

@ -433,7 +433,7 @@ void cb_mnuSaveMacro(Fl_Menu_*, void*) {
//}
bool clean_exit() {
close_pskmail_loop();
arq_close();
if (progdefaults.changed == true) {
switch (fl_choice("Save changed configuration before exiting?", "Cancel", "Save", "Don't save")) {
@ -2024,11 +2024,10 @@ void put_rx_char(unsigned int data)
#ifndef __CYGWIN__
rxmsgid = msgget( (key_t) progdefaults.rx_msgid, 0666);
#else
rxmsgid = -1;
#endif
if (mailclient || mailserver || rxmsgid != -1 || arqmode)
#else
if (mailclient || mailserver || arqmode)
#endif
asc = ascii2;
if (active_modem->get_mode() == MODE_RTTY ||
active_modem->get_mode() == MODE_CW)
@ -2052,16 +2051,8 @@ void put_rx_char(unsigned int data)
}
last = data;
#ifndef __CYGWIN__
if ( rxmsgid != -1) {
rxmsgst.msg_type = 1;
rxmsgst.c = data;
msgsnd (rxmsgid, (void *)&rxmsgst, 1, IPC_NOWAIT);
}
#else
writeToARQfile(data);
#endif
WriteARQ(data);
string s = iscntrl(data) ? ascii2[data & 0x7F] : string(1, data);
if (Maillogfile)
Maillogfile->log_to_file(cLogfile::LOG_RX, s);
@ -2193,8 +2184,8 @@ void put_rx_data(int *data, int len)
int get_tx_char(void)
{
if (pskmail_text_available)
return pskmail_get_char();
if (arq_text_available)
return arq_get_char();
int c;
static int pending = -1;

Wyświetl plik

@ -39,14 +39,13 @@ extern bool arqmode;
extern string ArqFilename;
extern bool mailclient;
extern bool mailserver;
extern bool pskmail_text_available;
extern char pskmail_get_char();
extern void pskmail_loop(void *);
extern void close_pskmail_loop();
extern bool arq_text_available;
extern char arq_get_char();
#ifdef __CYGWIN__
extern void writeToARQfile(unsigned int);
#endif
// ARQ mail implementation
extern void arq_init();
extern void arq_close();
extern void WriteARQ(unsigned int);
struct RXMSGSTRUC {
long int msg_type;

Wyświetl plik

@ -61,7 +61,7 @@ extern int fl_join(Fl_Thread t);
// we have 4 threads, only 3 of which will use qrunner
enum { UNKNOWN_TID = -1, TRX_TID, QRZ_TID, RIGCTL_TID,
enum { UNKNOWN_TID = -1, TRX_TID, QRZ_TID, RIGCTL_TID, ARQ_TID,
#if USE_XMLRPC
XMLRPC_TID,
#endif

Wyświetl plik

@ -105,7 +105,6 @@ cLogfile *Maillogfile = (cLogfile *)0;
FILE *server;
FILE *client;
bool mailserver = false, mailclient = false, arqmode = false;
extern void start_pskmail();
RXMSGSTRUC rxmsgst;
int rxmsgid = -1;
@ -267,7 +266,7 @@ int main(int argc, char ** argv)
fl_digi_main->show(argc, argv);
progStatus.initLastState();
Fl::add_timeout(1.0, pskmail_loop);
arq_init();
#if USE_XMLRPC
if (progdefaults.xmlrpc_server)

Wyświetl plik

@ -1,5 +1,28 @@
// pskmail.cxx
// support for pskmail server/client system
// ============================================================================
// arq_io.cxx
//
// support for ARQ server/client system such as pskmail and fl_arq
//
// Copyright (C) 2006
// Dave Freese, W1HKJ
//
// This file is part of fldigi.
//
// fldigi 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.
//
// fldigi 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 fldigi; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// ============================================================================
#include <config.h>
@ -16,35 +39,17 @@
#include "configuration.h"
#include "fl_digi.h"
#define _host "127.0.0.1"
#define _port 3122
#include "threads.h"
#define _TX "TX"
#define _RX "RX"
#define _TX2RX "RX_AFTER_TX"
#define _TXCH 25
#define _RXCH 29
#define _TXECHO 28
#define _CMD 26
#define _END 27
#ifdef __CYGWIN__
string str_dirname = "c:/NBEMS/";
string str_infile = "c:/NBEMS/ARQXFR/txfile";
string str_outfile = "c:/NBEMS/ARQXFR/rxfile";
string str_flarqon = "c:/NBEMS/ARQXFR/flarqON";
#endif
#include <FL/Fl.H>
#include <FL/fl_ask.H>
using namespace std;
static string mailtext;
static string arqtext;
string::iterator pText;
#ifndef __CYGWIN__
static char mailline[1000];
#endif
bool pskmail_text_available = false;
bool arq_text_available = false;
void ParseMode(string src)
{
@ -66,24 +71,21 @@ void ParseMode(string src)
}
}
void parse_mailtext()
void parse_arqtext()
{
string strCmdText;
string strSubCmd;
unsigned long int idxCmd, idxCmdEnd, idxSubCmd, idxSubCmdEnd;
idxCmd = mailtext.find("<cmd>");
idxCmdEnd = mailtext.find("</cmd>");
idxCmd = arqtext.find("<cmd>");
idxCmdEnd = arqtext.find("</cmd>");
if ( idxCmd != string::npos && idxCmdEnd != string::npos && idxCmdEnd > idxCmd ) {
strCmdText = mailtext.substr(idxCmd + 5, idxCmdEnd - idxCmd - 5);
strCmdText = arqtext.substr(idxCmd + 5, idxCmdEnd - idxCmd - 5);
if (strCmdText == "server" && mailserver == false && mailclient == false) {
mailserver = true;
mailclient = false;
#ifndef __CYGWIN__
std::cout << "Starting pskmail server transport layer" << std::endl; std::cout.flush();
#endif
string PskMailLogName = PskMailDir;
PskMailLogName += "gMFSK.log";
Maillogfile = new cLogfile(PskMailLogName.c_str());
@ -91,17 +93,11 @@ void parse_mailtext()
} else if (strCmdText == "client" && mailclient == false && mailserver == false) {
mailclient = true;
mailserver = false;
#ifndef __CYGWIN__
std::cout << "Starting pskmail client transport layer" << std::endl; std::cout.flush();
#endif
string PskMailLogName = PskMailDir;
PskMailLogName += "gMFSK.log";
Maillogfile = new cLogfile(PskMailLogName.c_str());
Maillogfile->log_to_file_start();
} else if (strCmdText == "normal") {
#ifndef __CYGWIN__
std::cout << "Closing pskmail transport layer" << std::endl; std::cout.flush();
#endif
mailserver = false;
mailclient = false;
if (Maillogfile) {
@ -118,9 +114,9 @@ void parse_mailtext()
}
}
}
mailtext.erase(idxCmd, idxCmdEnd - idxCmd + 8);
if (mailtext.length() == 1 && mailtext[0] == '\n')
mailtext = "";
arqtext.erase(idxCmd, idxCmdEnd - idxCmd + 8);
if (arqtext.length() == 1 && arqtext[0] == '\n')
arqtext = "";
}
}
@ -128,19 +124,18 @@ void parse_mailtext()
bool bSend0x06 = false;
#ifndef __CYGWIN__
void process_msgque()
{
int nbytes = msgrcv (txmsgid, (void *)&txmsgst, BUFSIZ, 0, IPC_NOWAIT);
if (nbytes > 0) {
mailtext = txmsgst.buffer;
parse_mailtext();
if (mailtext.length() > 0) {
arqtext = txmsgst.buffer;
parse_arqtext();
if (arqtext.length() > 0) {
if (mailserver && progdefaults.PSKmailSweetSpot)
active_modem->set_freq(progdefaults.PSKsweetspot);
pText = mailtext.begin();
pskmail_text_available = true;
pText = arqtext.begin();
arq_text_available = true;
active_modem->set_stopflag(false);
@ -148,12 +143,36 @@ void process_msgque()
}
}
}
#endif
//-----------------------------------------------------------------------------
// SysV ARQ used only on Linux / Free-BSD or Unix type OS
//-----------------------------------------------------------------------------
bool SysV_arqRx()
{
#ifdef __CYGWIN__
return false;
#else
txmsgid = msgget( (key_t) progdefaults.tx_msgid, 0666 );
if (txmsgid != -1) {
process_msgque();
arqmode = true;
return true;
}
return false;
#endif
}
//-----------------------------------------------------------------------------
// File ARQ used on Windows OS
//-----------------------------------------------------------------------------
string str_dirname = "c:/NBEMS/";
string str_infile = "c:/NBEMS/ARQXFR/txfile";
string str_outfile = "c:/NBEMS/ARQXFR/rxfile";
string str_flarqon = "c:/NBEMS/ARQXFR/flarqON";
long infileptr = 0;
bool bInitFilePtr = false;
void initFilePtr()
{
@ -164,74 +183,15 @@ void initFilePtr()
infileptr = ftell(infile);
fclose(infile);
}
bInitFilePtr = true;
}
#endif
void check_formail() {
#ifndef __CYGWIN__
time_t start_time, prog_time;
string sAutoFile = PskMailDir;
txmsgid = msgget( (key_t) progdefaults.tx_msgid, 0666 );
if (txmsgid != -1) {
process_msgque();
arqmode = true;
return;
}
arqmode = false;
if (! (mailserver || mailclient) )
return;
if (gmfskmail == true)
sAutoFile += "gmfsk_autofile";
else
sAutoFile += "pskmail_out";
ifstream autofile(sAutoFile.c_str());
if(autofile) {
mailtext = "";
time(&start_time);
while (!autofile.eof()) {
memset(mailline,0,1000);
autofile.getline(mailline, 998); // leave space for "\n" and null byte
mailtext.append(mailline);
mailtext.append("\n");
FL_AWAKE();
time(&prog_time);
if (prog_time - start_time > TIMEOUT) {
std::cout << "pskmail_out failure" << std::endl;
std::cout.flush();
autofile.close();
std::remove (sAutoFile.c_str());
return;
}
}
autofile.close();
std::remove (sAutoFile.c_str());
parse_mailtext();
if (mailtext.length() > 0) {
if (mailserver && progdefaults.PSKmailSweetSpot)
active_modem->set_freq(progdefaults.PSKsweetspot);
pText = mailtext.begin();
pskmail_text_available = true;
active_modem->set_stopflag(false);
start_tx();
}
}
#else
// Windows file handling for input strings
bool File_arqRx()
{
FILE *infile, *testarq;
testarq = fopen(str_flarqon.c_str(), "r");
arqmode = false;
if (!testarq)
return;
return false;
fclose(testarq);
arqmode = true;
@ -242,17 +202,17 @@ void check_formail() {
if (sz < infileptr)
infileptr = 0; // txfile was probably deleted & restarted
if (sz > infileptr) {
mailtext = "";
arqtext = "";
fseek(infile, infileptr, SEEK_SET);
while (infileptr < sz) {
mailtext += fgetc(infile);
arqtext += fgetc(infile);
infileptr++;
}
if (mailtext.length() > 0) {
parse_mailtext();
if (mailtext.length() > 0) {
pText = mailtext.begin();
pskmail_text_available = true;
if (arqtext.length() > 0) {
parse_arqtext();
if (arqtext.length() > 0) {
pText = arqtext.begin();
arq_text_available = true;
active_modem->set_stopflag(false);
start_tx();
}
@ -260,10 +220,9 @@ void check_formail() {
}
fclose(infile);
}
#endif
return true;
}
#ifdef __CYGWIN__
string holdbuffer;
bool havedir = false;
@ -308,11 +267,121 @@ void writeToARQfile(unsigned int data)
trywrite(NULL);
}
}
//-----------------------------------------------------------------------------
// Gmfsk ARQ file i/o used only on Linux
//-----------------------------------------------------------------------------
bool Gmfsk_arqRx()
{
time_t start_time, prog_time;
string sAutoFile = PskMailDir;
static char mailline[1000];
arqmode = false;
if (! (mailserver || mailclient) )
return false;
if (gmfskmail == true)
sAutoFile += "gmfsk_autofile";
else
sAutoFile += "pskmail_out";
ifstream autofile(sAutoFile.c_str());
if(autofile) {
arqtext = "";
time(&start_time);
while (!autofile.eof()) {
memset(mailline,0,1000);
autofile.getline(mailline, 998); // leave space for "\n" and null byte
arqtext.append(mailline);
arqtext.append("\n");
FL_AWAKE();
time(&prog_time);
if (prog_time - start_time > TIMEOUT) {
std::cout << "pskmail_out failure" << std::endl;
std::cout.flush();
autofile.close();
std::remove (sAutoFile.c_str());
return false;
}
}
autofile.close();
std::remove (sAutoFile.c_str());
parse_arqtext();
if (arqtext.length() > 0) {
if (mailserver && progdefaults.PSKmailSweetSpot)
active_modem->set_freq(progdefaults.PSKsweetspot);
pText = arqtext.begin();
arq_text_available = true;
active_modem->set_stopflag(false);
start_tx();
}
}
return true;
}
//-----------------------------------------------------------------------------
// Socket ARQ i/o used on all platforms
// Socket implementation emulates the MultiPsk socket i/o
//-----------------------------------------------------------------------------
#define _host "127.0.0.1"
#define _port 3122
#define _TX "TX"
#define _RX "RX"
#define _TX2RX "RX_AFTER_TX"
#define _TXCH 25
#define _RXCH 29
#define _TXECHO 28
#define _CMD 26
#define _END 27
void WriteARQsocket(unsigned int data)
{
}
bool Socket_arqRx()
{
return false;
}
//-----------------------------------------------------------------------------
// Send ARQ characters to ARQ client
//-----------------------------------------------------------------------------
void WriteARQSysV(unsigned int data)
{
rxmsgid = msgget( (key_t) progdefaults.rx_msgid, 0666);
if ( rxmsgid != -1) {
rxmsgst.msg_type = 1;
rxmsgst.c = data;
msgsnd (rxmsgid, (void *)&rxmsgst, 1, IPC_NOWAIT);
}
}
void WriteARQ( unsigned int data)
{
WriteARQsocket(data);
#ifndef __CYGWIN__
WriteARQSysV(data);
#endif
#ifdef __CYGWIN__
WriteARQfile(data);
#endif
}
//-----------------------------------------------------------------------------
// Write End of Transmit character to ARQ client
//-----------------------------------------------------------------------------
void send0x06()
{
#ifndef __CYGWIN__
// SysV message que output
if (trx_state == STATE_RX) {
bSend0x06 = false;
rxmsgid = msgget( (key_t) progdefaults.rx_msgid, 0666 );
@ -323,7 +392,7 @@ void send0x06()
}
}
#else
// process output strings for Windows file i/o
// process output strings for File i/o
if (trx_state == STATE_RX) {
bSend0x06 = false;
writeToARQfile(0x06);
@ -331,34 +400,78 @@ void send0x06()
#endif
}
void pskmail_loop(void *)
char arq_get_char()
{
#ifdef __CYGWIN__
if (bInitFilePtr == false)
initFilePtr();
#endif
if (bSend0x06)
send0x06();
check_formail();
Fl::repeat_timeout(0.2, pskmail_loop);//1.0, pskmail_loop);
}
char pskmail_get_char()
{
if (pText != mailtext.end())
if (pText != arqtext.end())
return *pText++;
bSend0x06 = true;
pskmail_text_available = false;
arq_text_available = false;
return 0x03; // tells psk modem to return to rx
}
// ============================================================================
// Implementation using thread vice the fldigi timeout facility
// ============================================================================
void close_pskmail_loop()
static Fl_Thread arq_thread;
static void *arq_loop(void *args);
static bool arq_exit = false;
static bool arq_enabled;
static int arq_dummy;
static void *arq_loop(void *args)
{
SET_THREAD_ID(ARQ_TID);
for (;;) {
/* see if we are being canceled */
if (arq_exit)
break;
if (bSend0x06)
send0x06();
// order of precedence; Socket, SysV, GMFSKfile, ARQfile
if (Socket_arqRx() == false)
if (SysV_arqRx() == false)
if (Gmfsk_arqRx() == false)
File_arqRx();
// delay for 50 msec interval
MilliSleep(50);
}
// exit the arq thread
return NULL;
}
void arq_init()
{
arq_enabled = false;
#ifdef __CYGWIN__
initFilePtr();
#endif
if (fl_create_thread(arq_thread, arq_loop, &arq_dummy) < 0) {
fl_message("arq init: pthread_create failed");
return;
}
arq_enabled = true;
}
void arq_close(void)
{
if (!arq_enabled) return;
// tell the arq thread to kill it self
arq_exit = true;
#ifdef __CYGWIN__
remove(str_outfile.c_str());
#endif
}
// and then wait for it to die
fl_join(arq_thread);
arq_enabled = false;
arq_exit = false;
}

Wyświetl plik

@ -14,14 +14,14 @@ static int numsocks = 0;
Socket::Socket() : error(false), m_sock ( INVALID_SOCKET )
{
#ifdef WIN32
//#ifdef WIN32
// Start Winsock up
WSAData wsaData;
if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
error = true;
else
#endif
numsocks++;
// WSAData wsaData;
// if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
// error = true;
// else
//#endif
numsocks++;
ssize = 0;
sptr = 0;
}
@ -37,11 +37,11 @@ void Socket::close()
if (m_sock != INVALID_SOCKET) {
::close ( m_sock );
numsocks--;
#ifdef WIN32
//#ifdef WIN32
// Shut Winsock down to release DLL resources
if (numsocks == 0)
WSACleanup();
#endif
// if (numsocks == 0)
// WSACleanup();
//#endif
}
}
@ -50,14 +50,14 @@ bool Socket::create()
m_sock = socket ( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if (m_sock == INVALID_SOCKET) {
char szError[40];
#ifdef WIN32
snprintf(szError, sizeof(szError), "Socket error, create(): %ld", WSAGetLastError() );
put_status(szError, 5);
WSACleanup();
#else
//#ifdef WIN32
// snprintf(szError, sizeof(szError), "Socket error, create(): %ld", WSAGetLastError() );
// put_status(szError, 5);
// WSACleanup();
//#else
snprintf(szError, sizeof(szError), "Socket error, create()");
put_status(szError, 5);
#endif
//#endif
return 1;
}
ssize = 0;
@ -100,11 +100,11 @@ bool Socket::listen() const
bool Socket::accept ( Socket& new_socket ) const
{
int addr_length = sizeof ( m_addr );
#ifdef WIN32
new_socket.m_sock = ::accept ( m_sock, ( sockaddr * ) &m_addr, &addr_length );
#else
//#ifdef WIN32
// new_socket.m_sock = ::accept ( m_sock, ( sockaddr * ) &m_addr, &addr_length );
//#else
new_socket.m_sock = ::accept ( m_sock, ( sockaddr * ) &m_addr, ( socklen_t * ) &addr_length );
#endif
//#endif
if ( new_socket.m_sock <= 0 )
return false;
else
@ -113,11 +113,11 @@ bool Socket::accept ( Socket& new_socket ) const
bool Socket::putch(char c)
{
#ifdef WIN32
int status = ::send (m_sock, &c, 1, 0);
#else
//#ifdef WIN32
// int status = ::send (m_sock, &c, 1, 0);
//#else
int status = ::send (m_sock, &c, 1, MSG_NOSIGNAL );
#endif
//#endif
if (status == -1)
return false;
return true;
@ -143,15 +143,15 @@ unsigned char Socket::getbyte()
if (result == 0) { // timeout
return 0;
}
#ifdef WIN32
if (result == SOCKET_ERROR) { // select error
//#ifdef WIN32
// if (result == SOCKET_ERROR) { // select error
//std::cout << WSAGetLastError() << std::endl; std::cout.flush();
return 0;
}
#else
// return 0;
// }
//#else
if (result == -1) // select error
return 0;
#endif
//#endif
if (FD_ISSET(m_sock, &testfds)) {
int status = ::recv ( m_sock, sbuff, 1024, 0 );
if (status > 0) {
@ -176,14 +176,14 @@ bool Socket::send ( const string s) const
{
//printf("%s",s.c_str());
//std::cout.flush();
#ifdef WIN32
int status = ::send (m_sock, s.c_str(), s.size(), 0);
#else
//#ifdef WIN32
// int status = ::send (m_sock, s.c_str(), s.size(), 0);
//#else
int status = ::send ( m_sock, s.c_str(), s.size(), MSG_NOSIGNAL );
#endif
if ( status == -1 )
return false;
return true;
//#endif
if ( status == -1 )
return false;
return true;
}
size_t Socket::recv ( string & s)
@ -218,16 +218,16 @@ bool Socket::connect ( string host, const int port )
void Socket::set_non_blocking ( const bool b )
{
#ifndef WIN32
int opts;
opts = fcntl ( m_sock, F_GETFL );
if ( opts < 0 )
return;
if ( b )
opts = ( opts | O_NONBLOCK );
else
opts = ( opts & ~O_NONBLOCK );
fcntl ( m_sock, F_SETFL,opts );
#endif
return;
//#ifndef WIN32
int opts;
opts = fcntl ( m_sock, F_GETFL );
if ( opts < 0 )
return;
if ( b )
opts = ( opts | O_NONBLOCK );
else
opts = ( opts & ~O_NONBLOCK );
fcntl ( m_sock, F_SETFL,opts );
//#endif
return;
}