mmtty/ctnc.cpp

703 lines
20 KiB
C++
Raw Normal View History

//Copyright+LGPL
//-----------------------------------------------------------------------------------------------------------------------------------------------
// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba
//-----------------------------------------------------------------------------------------------------------------------------------------------
// This file is part of MMTTY.
// MMTTY is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
// MMTTY 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 Lesser General Public License for more details.
// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see
// <http://www.gnu.org/licenses/>.
//-----------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Ctnc.h"
#include "ComLib.h"
#define WAITSTAT 0
CTNCPARA TNC;
void InitTNCPara(void)
{
strcpy(TNC.StrPort, "NONE"); // <20>|<7C>[<5B>g<EFBFBD>̖<EFBFBD><CC96>O
TNC.BaudRate = 1200; // <20>{<7B>[<5B><><EFBFBD>[<5B>g
TNC.BitLen = 1; // 0-7Bit, 1-8Bit
TNC.Stop = 0; // 0-1Bit, 1-2Bit
TNC.Parity = 0; // 0-PN, 1-PE, 2-PO
TNC.flwXON = 1; // Xon/Xoff ON
TNC.flwCTS = 0; // CTS-RTS ON
TNC.Echo = 2;
TNC.Type = (lcid != LANG_JAPANESE) ? 1 : 0; // 0-TNC241, 1-KAM
TNC.TncMode = 1; // Command mode
TNC.change = 1;
}
void LoadTNCSetup(TMemIniFile *pIniFile)
{
AnsiString as = TNC.StrPort;
as = pIniFile->ReadString("TNC", "PortName", as);
StrCopy(TNC.StrPort, as.c_str(), 31);
TNC.Type = pIniFile->ReadInteger("TNC", "Type", TNC.Type);
TNC.BaudRate = pIniFile->ReadInteger("TNC", "BaudRate", TNC.BaudRate);
TNC.BitLen = pIniFile->ReadInteger("TNC", "BitLen", TNC.BitLen);
TNC.Stop = pIniFile->ReadInteger("TNC", "Stop", TNC.Stop);
TNC.Parity = pIniFile->ReadInteger("TNC", "Parity", TNC.Parity);
TNC.flwXON = pIniFile->ReadInteger("TNC", "flwXON", TNC.flwXON);
TNC.flwCTS = pIniFile->ReadInteger("TNC", "flwCTS", TNC.flwCTS);
TNC.Echo = pIniFile->ReadInteger("TNC", "Echo", TNC.Echo);
}
void SaveTNCSetup(TMemIniFile *pIniFile)
{
pIniFile->WriteString("TNC", "PortName", TNC.StrPort);
pIniFile->WriteInteger("TNC", "Type", TNC.Type);
pIniFile->WriteInteger("TNC", "BaudRate", TNC.BaudRate);
pIniFile->WriteInteger("TNC", "BitLen", TNC.BitLen);
pIniFile->WriteInteger("TNC", "Stop", TNC.Stop);
pIniFile->WriteInteger("TNC", "Parity", TNC.Parity);
pIniFile->WriteInteger("TNC", "flwXON", TNC.flwXON);
pIniFile->WriteInteger("TNC", "flwCTS", TNC.flwCTS);
pIniFile->WriteInteger("TNC", "Echo", TNC.Echo);
}
//---------------------------------------------------------------------------
// <20><><EFBFBD><EFBFBD>: VCL <20>I<EFBFBD>u<EFBFBD>W<EFBFBD>F<EFBFBD>N<EFBFBD>g<EFBFBD>̃<EFBFBD><CC83>\<5C>b<EFBFBD>h<EFBFBD>ƃv<C683><76><EFBFBD>p<EFBFBD>e<EFBFBD>B<EFBFBD><42><EFBFBD>g<EFBFBD>p<EFBFBD><70><EFBFBD><EFBFBD><EFBFBD>ɂ<EFBFBD>, Synchronize
// <20><><EFBFBD>g<EFBFBD><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\<5C>b<EFBFBD>h<EFBFBD>Ăяo<D18F><6F><EFBFBD>łȂ<C582><C882><EFBFBD><EFBFBD>΂Ȃ<CE82><C882>܂<EFBFBD><DC82><EFBFBD><EFBFBD>B<EFBFBD><42><EFBFBD>ɗ<EFBFBD><C997><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>܂<EFBFBD><DC82>B
//
// Synchronize(UpdateCaption);
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, UpdateCaption <20>͎<EFBFBD><CD8E>̂悤<CC82>ɋL<C98B>q<EFBFBD>ł<EFBFBD><C582>܂<EFBFBD><DC82>B
//
// void __fastcall CCtnc::UpdateCaption()
// {
// Form1->Caption = "<22>X<EFBFBD><58><EFBFBD>b<EFBFBD>h<EFBFBD><68><EFBFBD><EFBFBD><E78F91><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>܂<EFBFBD><DC82><EFBFBD>";
// }
//---------------------------------------------------------------------------
__fastcall CCtnc::CCtnc(bool CreateSuspended)
: TThread(CreateSuspended)
{
m_CreateON = FALSE; // <20>N<EFBFBD><4E><EFBFBD>G<EFBFBD>C<EFBFBD>g<EFBFBD>t<EFBFBD><74><EFBFBD>O
m_fHnd = NULL; // <20>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD>n<EFBFBD><6E><EFBFBD>h<EFBFBD><68>
m_wHnd = NULL; // <20>e<EFBFBD>̃E<CC83>C<EFBFBD><43><EFBFBD>h<EFBFBD>E<EFBFBD>n<EFBFBD><6E><EFBFBD>h<EFBFBD><68>
m_ID = 0; // <20><><EFBFBD>b<EFBFBD>Z<EFBFBD>[<5B>W<EFBFBD>̂h<CC82>c<EFBFBD>ԍ<EFBFBD>
m_Command = 0; // <20>X<EFBFBD><58><EFBFBD>b<EFBFBD>h<EFBFBD>ւ̃R<CC83>}<7D><><EFBFBD>h
m_TxAbort = 0; // <20><><EFBFBD>M<EFBFBD><4D><EFBFBD>~<7E>t<EFBFBD><74><EFBFBD>O
ClearTxFifo();
ClearRxFifo();
m_timeout = 200;
m_pMMT = NULL;
}
//---------------------------------------------------------------------------
void __fastcall CCtnc::ClearRxFifo(void)
{
m_rxwp = m_rxrp = m_rxcnt = 0;
}
//---------------------------------------------------------------------------
void __fastcall CCtnc::ClearTxFifo(void)
{
m_txwp = m_txrp = m_txcnt = 0;
}
//---------------------------------------------------------------------------
const BYTE tbl[]={
0x00, 0x10, 0x08, 0x18, // 00000 10000 01000 11000
0x04, 0x14, 0x0c, 0x1c, // 00100 10100 01100 11100
0x02, 0x12, 0x0a, 0x1a, // 00010 10010 01010 11010
0x06, 0x16, 0x0e, 0x1e, // 00110 10110 01110 11110
0x01, 0x11, 0x09, 0x19, // 00001 10001 01001 11001
0x05, 0x15, 0x0d, 0x1d, // 00101 10101 01101 11101
0x03, 0x13, 0x0b, 0x1b, // 00011 10011 01011 11011
0x07, 0x17, 0x0f, 0x1f, // 00111 10111 01111 11111
};
//---------------------------------------------------------------------------
BOOL __fastcall CCtnc::PutRxFifo(BYTE c)
{
if( m_rxcnt >= TNC_RXBUFSIZE ) return FALSE;
if( (TNC.Type == 2) && (cm.BitLen <= 6) ){
if( m_pMMT && (c >= 0x20) ){
m_rxbuf[m_rxwp] = c;
}
else {
m_rxbuf[m_rxwp] = tbl[c&0x1f];
}
}
else {
m_rxbuf[m_rxwp] = c;
}
m_rxwp++;
if( m_rxwp >= (int)sizeof(m_rxbuf) ) m_rxwp = 0; //JA7UDE 0428
m_rxcnt++;
return TRUE;
}
//---------------------------------------------------------------------------
void __fastcall CCtnc::Execute()
{
//---- <20>X<EFBFBD><58><EFBFBD>b<EFBFBD>h<EFBFBD>̃R<CC83>[<5B>h<EFBFBD><68><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɋL<C98B>q ----
// Priority = tpLower;
if( TNC.Type == 2 ){
m_PTT = GetPTT();
}
while(1){
if( Terminated == TRUE ){
return;
}
if( m_Command == CTNC_CLOSE ){
m_Command = 0;
return;
}
if( m_CreateON == TRUE ){
if( m_txcnt ){
if( !TxBusy() ){
BYTE d = m_txbuf[m_txrp];
if( TNC.Type == 2 && (cm.BitLen <= 6) ){
d = tbl[d & 0x1f];
}
if( IOPutChar(d) ){
m_txrp++;
if( m_txrp >= TNC_TXBUFSIZE ){
m_txrp = 0;
}
m_txcnt--;
}
}
::Sleep(1);
}
else if( m_rxcnt < (TNC_RXBUFSIZE/2) ){
int len = RecvLen();
if( len ){
BYTE bf[256];
if( len >= (int)sizeof(bf) ) len = sizeof(bf);
if( len && (m_rxcnt < int(sizeof(m_rxbuf) - len)) ){
int size = IORead(bf, len);
for( int i = 0; i < size; i++ ){
PutRxFifo(bf[i]);
}
if( m_wHnd != NULL ){
PostMessage( m_wHnd, m_ID, MMTMSG_NULL, 0);
}
}
}
::Sleep(((TNC.Type != 2) || m_pMMT) ? 10 : 1);
}
else {
::Sleep(10);
}
if( (TNC.Type == 2) && !m_pMMT ){
BOOL tx = GetPTT();
if( (tx != m_PTT) && (tx || !m_rxcnt) ){
m_PTT = tx;
PostMessage(m_wHnd, m_ID, MMTMSG_NULL, 0);
}
::Sleep(1);
}
}
else {
::Sleep(20);
}
}
}
//---------------------------------------------------------------------------
/*#$%
==============================================================
<EFBFBD>ʐM<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>I<EFBFBD>[<EFBFBD>v<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>X<EFBFBD><EFBFBD><EFBFBD>b<EFBFBD>h<EFBFBD><EFBFBD><EFBFBD>A<EFBFBD>N<EFBFBD>e<EFBFBD>B<EFBFBD>u<EFBFBD>ɂ<EFBFBD><EFBFBD><EFBFBD>
--------------------------------------------------------------
PortName : <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̖<EFBFBD><EFBFBD>O
pCP : COMMPARA<EFBFBD>̃|<EFBFBD>C<EFBFBD><EFBFBD><EFBFBD>^<EFBFBD>i<EFBFBD>k<EFBFBD><EFBFBD><EFBFBD>̎<EFBFBD><EFBFBD>̓f<EFBFBD>t<EFBFBD>H<EFBFBD><EFBFBD><EFBFBD>g<EFBFBD>ŏ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>j
pWnd : <EFBFBD><EFBFBD><EFBFBD>b<EFBFBD>Z<EFBFBD>[<EFBFBD>W<EFBFBD><EFBFBD><EFBFBD>M<EFBFBD><EFBFBD><EFBFBD>̃E<EFBFBD>C<EFBFBD><EFBFBD><EFBFBD>h<EFBFBD>E<EFBFBD>N<EFBFBD><EFBFBD><EFBFBD>X<EFBFBD>̃|<EFBFBD>C<EFBFBD><EFBFBD><EFBFBD>^<EFBFBD>i<EFBFBD>k<EFBFBD><EFBFBD><EFBFBD>̎<EFBFBD><EFBFBD><EFBFBD>Ҳ<EFBFBD><EFBFBD>ڰѳ<EFBFBD><EFBFBD><EFBFBD>޳<EFBFBD>j
nID : <EFBFBD>f<EFBFBD>[<EFBFBD>^<EFBFBD><EFBFBD><EFBFBD>M<EFBFBD><EFBFBD><EFBFBD>̃<EFBFBD><EFBFBD>b<EFBFBD>Z<EFBFBD>[<EFBFBD>W<EFBFBD>h<EFBFBD>c
RBufSize : <EFBFBD><EFBFBD><EFBFBD>M<EFBFBD>o<EFBFBD>b<EFBFBD>t<EFBFBD>@<EFBFBD>̃T<EFBFBD>C<EFBFBD>Y(default=2048)
TBufSize : <EFBFBD><EFBFBD><EFBFBD>M<EFBFBD>o<EFBFBD>b<EFBFBD>t<EFBFBD>@<EFBFBD>̃T<EFBFBD>C<EFBFBD>Y(default=2048)
--------------------------------------------------------------
TRUE/FALSE
--------------------------------------------------------------
==============================================================
*/
BOOL __fastcall CCtnc::Open(CTNCPARA *cp, HWND hwnd, UINT nID, COMMPARA *pp)
{
if( m_CreateON == TRUE ) Close();
m_TxAbort = FALSE;
m_wHnd = hwnd;
m_ID = nID;
m_fHnd = ::CreateFile(cp->StrPort, GENERIC_READ | GENERIC_WRITE,
0, NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if( m_fHnd == INVALID_HANDLE_VALUE ) goto _mmt;
// setup device buffers
if( ::SetupComm( m_fHnd, DWORD(TNC_COMBUFSIZE), DWORD(TNC_COMBUFSIZE) ) == FALSE ){
::CloseHandle(m_fHnd);
_mmt:;
m_pMMT = new CMMTnc;
if( m_pMMT->Open(cp->StrPort, m_wHnd, m_ID) ){
m_CreateON = TRUE;
Priority = tpLower;
Resume(); // <20>X<EFBFBD><58><EFBFBD>b<EFBFBD>h<EFBFBD>̎<EFBFBD><CC8E>s
return TRUE;
}
else {
delete m_pMMT;
m_pMMT = NULL;
return FALSE;
}
}
// purge any information in the buffer
::PurgeComm( m_fHnd, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR );
// set up for overlapped I/O
COMMTIMEOUTS TimeOut;
TimeOut.ReadIntervalTimeout = 0xffffffff;
TimeOut.ReadTotalTimeoutMultiplier = 0;
TimeOut.ReadTotalTimeoutConstant = 0;
TimeOut.WriteTotalTimeoutMultiplier = 0;
TimeOut.WriteTotalTimeoutConstant = 20000;
// TimeOut.WriteTotalTimeoutConstant = 1;
if( !::SetCommTimeouts( m_fHnd, &TimeOut ) ){
::CloseHandle( m_fHnd );
return FALSE;
}
::GetCommState( m_fHnd, &m_dcb );
m_dcb.fBinary = TRUE;
const UCHAR _tp[]={NOPARITY, EVENPARITY, ODDPARITY};
const UCHAR _ts[]={ONESTOPBIT,TWOSTOPBITS};
if( TNC.Type == 2 ){
memcpy(&cm, pp, sizeof(cm));
m_dcb.BaudRate = pp->Baud;
m_dcb.ByteSize = WORD(pp->BitLen);
m_dcb.Parity = WORD(pp->Parity);
m_dcb.StopBits = WORD(pp->Stop);
m_dcb.fOutxCtsFlow = FALSE;
m_dcb.fInX = m_dcb.fOutX = FALSE;
}
else {
m_dcb.BaudRate = cp->BaudRate;
m_dcb.ByteSize = USHORT(cp->BitLen ? 8 : 7);
m_dcb.Parity = _tp[cp->Parity];
m_dcb.StopBits = _ts[cp->Stop];
m_dcb.fOutxCtsFlow = cp->flwCTS ? TRUE : FALSE;
m_dcb.fInX = m_dcb.fOutX = cp->flwXON ? TRUE : FALSE;
}
m_dcb.fRtsControl = RTS_CONTROL_ENABLE;
m_dcb.XonChar = 0x11;
m_dcb.XoffChar = 0x13;
m_dcb.fParity = FALSE;
m_dcb.EvtChar = 0x00; // dummy setting
// m_dcb.fTXContinueOnXoff = TRUE;
m_dcb.XonLim = USHORT(TNC_COMBUFSIZE/4); // 1/4 of RBufSize
m_dcb.XoffLim = USHORT(TNC_COMBUFSIZE*3/4); // 3/4 of RBufSize
m_dcb.DCBlength = sizeof( DCB );
if( !::SetCommState( m_fHnd, &m_dcb ) ){
::CloseHandle( m_fHnd );
return FALSE;
}
// get any early notifications
if( !::SetCommMask( m_fHnd, EV_RXFLAG ) ){
::CloseHandle(m_fHnd);
return FALSE;
}
m_CreateON = TRUE;
Priority = tpLower;
Resume(); // <20>X<EFBFBD><58><EFBFBD>b<EFBFBD>h<EFBFBD>̎<EFBFBD><CC8E>s
return TRUE;
}
/*#$%
==============================================================
<EFBFBD>ʐM<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>N<EFBFBD><EFBFBD><EFBFBD>[<EFBFBD>Y<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
--------------------------------------------------------------
--------------------------------------------------------------
--------------------------------------------------------------
<EFBFBD>X<EFBFBD><EFBFBD><EFBFBD>b<EFBFBD>h<EFBFBD><EFBFBD><EFBFBD>I<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>܂ő҂<EFBFBD>
==============================================================
*/
void __fastcall CCtnc::Close(void)
{
if( m_CreateON == TRUE ){
if( m_ID ){
m_Command = CTNC_CLOSE; // <20>X<EFBFBD><58><EFBFBD>b<EFBFBD>h<EFBFBD>I<EFBFBD><49><EFBFBD>R<EFBFBD>}<7D><><EFBFBD>h
Priority = tpNormal; //<2F>X<EFBFBD><58><EFBFBD>b<EFBFBD>h<EFBFBD>͒ʏ<CD92><CA8F>̗D<CC97><44><EFBFBD>x<EFBFBD>ł<EFBFBD><C582><EFBFBD>
WaitFor();
}
if( m_pMMT ){
delete m_pMMT;
m_pMMT = NULL;
}
else {
::CloseHandle(m_fHnd);
}
m_CreateON = FALSE;
}
m_TxAbort = TRUE;
}
void __fastcall CCtnc::ReqClose(void)
{
if( m_CreateON == TRUE ){
if( m_ID ){
m_Command = CTNC_CLOSE; // <20>X<EFBFBD><58><EFBFBD>b<EFBFBD>h<EFBFBD>I<EFBFBD><49><EFBFBD>R<EFBFBD>}<7D><><EFBFBD>h
Priority = tpNormal; //<2F>X<EFBFBD><58><EFBFBD>b<EFBFBD>h<EFBFBD>͒ʏ<CD92><CA8F>̗D<CC97><44><EFBFBD>x<EFBFBD>ł<EFBFBD><C582><EFBFBD>
}
}
}
void __fastcall CCtnc::WaitClose(void)
{
if( m_CreateON == TRUE ){
if( m_ID && m_Command ){
WaitFor();
}
if( m_pMMT ){
delete m_pMMT;
m_pMMT = NULL;
}
else {
::CloseHandle(m_fHnd);
}
m_CreateON = FALSE;
}
m_TxAbort = TRUE;
}
//----------------------------------------------------------------------
BOOL __fastcall CCtnc::GetPTT(void)
{
DWORD d = 0;
BOOL tx = FALSE;
if( !m_pMMT ){
if( ::GetCommModemStatus(m_fHnd, &d) ){
tx = (d & MS_CTS_ON) != 0;
}
}
return tx;
}
/*#$%
==============================================================
<EFBFBD><EFBFBD><EFBFBD>M<EFBFBD>o<EFBFBD>b<EFBFBD>t<EFBFBD>@<EFBFBD><EFBFBD><EFBFBD>̊i<EFBFBD>[<EFBFBD>f<EFBFBD>[<EFBFBD>^<EFBFBD><EFBFBD><EFBFBD>𓾂<EFBFBD>
--------------------------------------------------------------
--------------------------------------------------------------
<EFBFBD>f<EFBFBD>[<EFBFBD>^<EFBFBD>̒<EFBFBD><EFBFBD><EFBFBD>
--------------------------------------------------------------
==============================================================
*/
DWORD __fastcall CCtnc::RecvLen(void)
{
if( m_pMMT ){
return m_pMMT->GetRxLen();
}
else {
COMSTAT ComStat;
DWORD dwErrorFlags;
::ClearCommError( m_fHnd, &dwErrorFlags, &ComStat );
return ComStat.cbInQue;
}
}
/*#$%
==============================================================
<EFBFBD><EFBFBD><EFBFBD>M<EFBFBD>r<EFBFBD>W<EFBFBD>[<EFBFBD><EFBFBD><EFBFBD>ǂ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ׂ<EFBFBD>
--------------------------------------------------------------
--------------------------------------------------------------
TRUE : <EFBFBD><EFBFBD><EFBFBD>M<EFBFBD>r<EFBFBD>W<EFBFBD>[<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
--------------------------------------------------------------
==============================================================
*/
int __fastcall CCtnc::TxBusy(void)
{
if( m_pMMT ){
return m_pMMT->IsTxBusy();
}
else {
COMSTAT ComStat;
DWORD dwErrorFlags;
::ClearCommError( m_fHnd, &dwErrorFlags, &ComStat );
return ComStat.cbOutQue;
}
}
/*#$%
==============================================================
<EFBFBD>ʐM<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>f<EFBFBD>[<EFBFBD>^<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>o<EFBFBD><EFBFBD>
--------------------------------------------------------------
p : <EFBFBD>o<EFBFBD>b<EFBFBD>t<EFBFBD>@<EFBFBD>̃|<EFBFBD>C<EFBFBD><EFBFBD><EFBFBD>^
len : <EFBFBD>o<EFBFBD>b<EFBFBD>t<EFBFBD>@<EFBFBD>̃T<EFBFBD>C<EFBFBD>Y
--------------------------------------------------------------
<EFBFBD><EFBFBD><EFBFBD>ۂɎ<EFBFBD><EFBFBD>M<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>T<EFBFBD>C<EFBFBD>Y
--------------------------------------------------------------
==============================================================
*/
int __fastcall CCtnc::IORead(BYTE *p, DWORD len)
{
DWORD size=0;
if( m_CreateON == TRUE ){
if( m_pMMT ){
for( ; len; len--, size++ ){
*p++ = m_pMMT->GetChar();
}
}
else {
::ReadFile( m_fHnd, p, len, &size, NULL );
}
}
return size;
}
int __fastcall CCtnc::IOPutChar(BYTE c)
{
DWORD size=0;
if( m_CreateON == TRUE ){
if( m_pMMT ){
m_pMMT->PutChar(c);
size = 1;
}
else {
::WriteFile( m_fHnd, &c, 1, &size, NULL );
}
}
return size;
}
/*#$%
==============================================================
<EFBFBD>ʐM<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƀf<EFBFBD>[<EFBFBD>^<EFBFBD>𑗐M<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
--------------------------------------------------------------
--------------------------------------------------------------
--------------------------------------------------------------
==============================================================
*/
void __fastcall CCtnc::PutChar(char c)
{
if( m_CreateON == TRUE ){
if( m_txcnt < TNC_TXBUFSIZE ){
m_txbuf[m_txwp] = c;
m_txwp++;
if( m_txwp >= TNC_TXBUFSIZE ) m_txwp = 0;
m_txcnt++;
}
}
}
/*#$%
==============================================================
<EFBFBD>ʐM<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƀf<EFBFBD>[<EFBFBD>^<EFBFBD>𑗐M<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
--------------------------------------------------------------
p : <EFBFBD>o<EFBFBD>b<EFBFBD>t<EFBFBD>@<EFBFBD>̃|<EFBFBD>C<EFBFBD><EFBFBD><EFBFBD>^
len : <EFBFBD><EFBFBD><EFBFBD>M<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>T<EFBFBD>C<EFBFBD>Y
--------------------------------------------------------------
<EFBFBD><EFBFBD><EFBFBD>ۂɑ<EFBFBD><EFBFBD>M<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>T<EFBFBD>C<EFBFBD>Y
--------------------------------------------------------------
==============================================================
*/
void __fastcall CCtnc::Write(void *s, DWORD len)
{
if( m_CreateON == TRUE ){
char *p;
for( p = (char *)s; len; len--, p++ ){
PutChar(*p);
}
}
}
/*#$%
==============================================================
<EFBFBD>ʐM<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƀf<EFBFBD>[<EFBFBD>^<EFBFBD>𑗐M<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
--------------------------------------------------------------
p : <EFBFBD>o<EFBFBD>b<EFBFBD>t<EFBFBD>@<EFBFBD>̃|<EFBFBD>C<EFBFBD><EFBFBD><EFBFBD>^
len : <EFBFBD><EFBFBD><EFBFBD>M<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>T<EFBFBD>C<EFBFBD>Y
--------------------------------------------------------------
<EFBFBD><EFBFBD><EFBFBD>ۂɑ<EFBFBD><EFBFBD>M<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>T<EFBFBD>C<EFBFBD>Y
--------------------------------------------------------------
==============================================================
*/
void CCtnc::OutStr(LPCSTR fmt, ...)
{
va_list pp;
char bf[1024];
va_start(pp, fmt);
vsprintf( bf, fmt, pp );
va_end(pp);
Write(bf, strlen(bf));
}
void CCtnc::OutLine(LPCSTR fmt, ...)
{
va_list pp;
char bf[1024];
va_start(pp, fmt);
vsprintf( bf, fmt, pp );
va_end(pp);
Write(bf, strlen(bf));
char r[] = "\r";
Write( r, 1 );
//Write("\r", 1);
}
//---------------------------------------------------------------------------
void __fastcall CCtnc::SetPTT(int tx)
{
if( m_pMMT ) m_pMMT->SetPTT(tx);
}
//---------------------------------------------------------------------------
void __fastcall CCtnc::NotifyFreq(LONG mark, LONG space)
{
if( m_pMMT ){
m_pMMT->m_NMMT.m_markfreq = mark;
m_pMMT->m_NMMT.m_spacefreq = space;
}
}
//---------------------------------------------------------------------------
void __fastcall CCtnc::NotifyLevel(LONG sq, LONG lvl)
{
if( m_pMMT ){
m_pMMT->m_NMMT.m_sqlevel = sq;
m_pMMT->m_NMMT.m_siglevel = lvl;
}
}
//==============================================================================
// CMMTnc <20>J<EFBFBD>X<EFBFBD>^<5E><>TNC<4E>G<EFBFBD>~<7E><><EFBFBD><EFBFBD><EFBFBD>[<5B>V<EFBFBD><56><EFBFBD><EFBFBD>
//==============================================================================
//---------------------------------------------------------------------------
__fastcall CMMTnc::CMMTnc(void)
{
m_hLib = NULL;
memset(&m_NMMT, 0, sizeof(m_NMMT));
m_NMMT.m_sampfreq = SampFreq;
m_NMMT.m_demfreq = DemSamp;
m_QueryResult = 0;
}
//---------------------------------------------------------------------------
__fastcall CMMTnc::~CMMTnc()
{
Close();
}
//---------------------------------------------------------------------------
void __fastcall CMMTnc::FreeLib(void)
{
if( m_hLib ){
FreeLibrary(m_hLib);
m_hLib = NULL;
}
}
//---------------------------------------------------------------------------
FARPROC __fastcall CMMTnc::GetProc(LPCSTR pName)
{
if( !m_hLib ) return NULL;
FARPROC fn = ::GetProcAddress(m_hLib, pName+1);
if( fn == NULL ){
fn = ::GetProcAddress(m_hLib, pName);
if( fn == NULL ) FreeLib();
}
return fn;
}
//---------------------------------------------------------------------------
void __fastcall CMMTnc::Close(void)
{
if( IsLib() ){
fmmtClose();
FreeLib();
}
}
//---------------------------------------------------------------------------
BOOL __fastcall CMMTnc::Open(LPCSTR pItemName, HWND hWnd, UINT uMsg)
{
Close();
m_ItemName = pItemName;
char LibName[MAX_PATH];
if( !*GetEXT(pItemName) ){
sprintf(LibName, "%s.mmt", pItemName);
pItemName = LibName;
}
m_hLib = ::LoadLibrary(pItemName);
if( m_hLib ){
fmmtQueryTnc = PROC(mmtQueryTnc);
fmmtOpen = PROC(mmtOpen);
fmmtClose = PROC(mmtClose);
fmmtSetPTT = PROC(mmtSetPTT);
fmmtPutChar = PROC(mmtPutChar);
fmmtGetChar = PROC(mmtGetChar);
fmmtIsTxBusy = PROC(mmtIsTxBusy);
fmmtGetRxLen = PROC(mmtGetRxLen);
fmmtNotify = PROC(mmtNotify);
fmmtNotifyFFT = PROC(mmtNotifyFFT);
fmmtNotifyXY = PROC(mmtNotifyXY);
if( m_hLib ){
m_QueryResult = fmmtQueryTnc((LPLONG)&TNC.Type, (LPLONG)&TNC.Echo);
if( !fmmtOpen(hWnd, uMsg, TNC.Type) ){
FreeLib();
}
}
}
return IsLib();
}
//---------------------------------------------------------------------------
void __fastcall CMMTnc::SetPTT(int ptt)
{
if( !IsLib() ) return;
fmmtSetPTT(ptt);
}
//---------------------------------------------------------------------------
void __fastcall CMMTnc::PutChar(BYTE c)
{
if( !IsLib() ) return;
fmmtPutChar(c);
}
//---------------------------------------------------------------------------
BYTE __fastcall CMMTnc::GetChar(void)
{
if( !IsLib() ) return 0;
return fmmtGetChar();
}
//---------------------------------------------------------------------------
BOOL __fastcall CMMTnc::IsTxBusy(void)
{
if( !IsLib() ) return FALSE;
return fmmtIsTxBusy();
}
//---------------------------------------------------------------------------
LONG __fastcall CMMTnc::GetRxLen(void)
{
if( !IsLib() ) return 0;
return fmmtGetRxLen();
}
//---------------------------------------------------------------------------
void __fastcall CMMTnc::Notify(void)
{
if( !IsLib() ) return;
if( m_QueryResult & ntNOTIFY ) fmmtNotify(&m_NMMT);
}
//---------------------------------------------------------------------------
void __fastcall CMMTnc::NotifyFFT(const int *pFFT)
{
if( !IsLib() ) return;
if( m_QueryResult & ntNOTIFYFFT ) fmmtNotifyFFT(pFFT, FFT_SIZE, SampFreq);
}
//---------------------------------------------------------------------------
void __fastcall CMMTnc::NotifyXY(const double *pX, const double *pY)
{
if( !IsLib() ) return;
if( !(m_QueryResult & ntNOTIFYXY) ) return;
LPLONG px = m_XY;
LPLONG py = &m_XY[XYCOLLECT];
for( int i = 0; i < XYCOLLECT; i++ ){
*px++ = LONG(*pX++);
*py++ = LONG(*pY++);
}
fmmtNotifyXY(m_XY);
}
//---------------------------------------------------------------------------