//Copyright+LGPL //----------------------------------------------------------------------------------------------------------------------------------------------- // Copyright 2000-2013 Makoto Mori, Nobuyuki Oba //----------------------------------------------------------------------------------------------------------------------------------------------- // This file is part of MMSSTV. // MMSSTV 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. // MMSSTV 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 // . //----------------------------------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------- #include //ja7ude 0521 #pragma hdrstop #include "Comm.h" #include "ComLib.h" #define WAITSTAT 0 #define DEFFSOUND 3 COMMPARA COMM; void InitCOMMPara(void) { COMM.change = 1; } __fastcall CComm::CComm(void) { m_CreateON = FALSE; // クリエイトフラグ m_Command = 0; m_fHnd = NULL; // ファイルハンドル m_ptt = m_scan = 0; m_pEXT = NULL; } /*#$% ============================================================== 通信回線をクローズする -------------------------------------------------------------- -------------------------------------------------------------- -------------------------------------------------------------- ============================================================== */ void __fastcall CComm::Close(void) { if( m_CreateON == TRUE ){ if( m_pEXT != NULL ){ delete m_pEXT; m_pEXT = NULL; } else { ::CloseHandle(m_fHnd); } m_CreateON = FALSE; } } /*#$% ============================================================== 通信回線をオープンする -------------------------------------------------------------- PortName : 回線の名前 pCP : COMMPARAのポインタ(ヌルの時はデフォルトで初期化) RBufSize : 受信バッファのサイズ(default=2048) TBufSize : 送信バッファのサイズ(default=2048) -------------------------------------------------------------- TRUE/FALSE -------------------------------------------------------------- ============================================================== */ BOOL __fastcall CComm::Open(LPCTSTR PortName) { if( m_CreateON == TRUE ) Close(); m_fHnd = ::CreateFile( PortName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if( m_fHnd == INVALID_HANDLE_VALUE ){ AnsiString as = "\\\\.\\"; as += PortName; m_fHnd = ::CreateFile( as.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); } if( m_fHnd == INVALID_HANDLE_VALUE ){ m_pEXT = new CEXTFSK(PortName); if( m_pEXT->IsLib() ){ LONG para; para = (45 << 16) | (5 << 2); m_pEXT->Open(para); m_CreateON = TRUE; return TRUE; } else { delete m_pEXT; m_pEXT = NULL; } return FALSE; } // setup device buffers if( ::SetupComm( m_fHnd, DWORD(1024), DWORD(2) ) == FALSE ){ ::CloseHandle(m_fHnd); 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.BaudRate = 9600; m_dcb.fBinary = TRUE; m_dcb.ByteSize = 8; m_dcb.Parity = NOPARITY; m_dcb.StopBits = ONESTOPBIT; m_dcb.XonChar = 0x11; // XON m_dcb.XoffChar = 0x13; // XOFF m_dcb.fParity = 0; m_dcb.fOutxCtsFlow = FALSE; m_dcb.fInX = m_dcb.fOutX = FALSE; m_dcb.fOutxDsrFlow = FALSE; m_dcb.EvtChar = 0x0d; m_dcb.fRtsControl = RTS_CONTROL_DISABLE; // 送信禁止 m_dcb.fDtrControl = DTR_CONTROL_DISABLE; // 送信禁止 // m_dcb.fTXContinueOnXoff = TRUE; m_dcb.XonLim = USHORT(1024/4); // 1/4 of RBufSize m_dcb.XoffLim = USHORT(1024*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; return TRUE; } //----------------------------------------------------------------- // PTT切り替え用 int __fastcall CComm::PTTOpen(void) { if( m_CreateON == FALSE ){ if( !strcmpi(sys.m_TxRxName.c_str(), "NONE") ) return FALSE; Open(sys.m_TxRxName.c_str()); if( m_CreateON == FALSE ) return FALSE; } return TRUE; } //----------------------------------------------------------------- // PTT切り替え用 int __fastcall CComm::SetPTT(void) { int rts = m_ptt; if( m_pEXT != NULL ){ if( sys.m_RTSonRX && m_scan ) rts |= 2; m_pEXT->SetPTT(rts); } else { if( sys.m_RTSonRX ){ rts |= m_scan; ::EscapeCommFunction(m_fHnd, m_scan ? SETBREAK : CLRBREAK); } ::EscapeCommFunction(m_fHnd, rts ? SETRTS : CLRRTS); ::EscapeCommFunction(m_fHnd, m_ptt ? SETDTR : CLRDTR); } return rts | m_ptt; } //----------------------------------------------------------------- // PTT切り替え用 void __fastcall CComm::SetPTT(int sw) { m_ptt = sw; if( !PTTOpen() ) return; if( !SetPTT() && (!sys.m_TxRxLock) ) Close(); } //----------------------------------------------------------------- // RX-SCAN信号 void __fastcall CComm::SetScan(int scan) { m_scan = scan; if( !sys.m_RTSonRX ) return; if( !PTTOpen() ) return; if( !SetPTT() && (!sys.m_TxRxLock) ) Close(); } /******************************************************************* EXTFSK.DLL *******************************************************************/ __fastcall CEXTFSK::CEXTFSK(LPCSTR pName) { char Name[128]; sprintf(Name, "%s.%s", pName, strcmpi(pName, "EXTFSK") ? "fsk" : "dll"); fextfskOpen = NULL; fextfskClose = NULL; fextfskIsTxBusy = NULL; fextfskPutChar = NULL; fextfskSetPTT = NULL; m_hLib = ::LoadLibrary(Name); if( m_hLib != NULL ){ fextfskOpen = (extfskOpen)GetProc("_extfskOpen"); fextfskClose = (extfskClose)GetProc("_extfskClose"); fextfskIsTxBusy = (extfskIsTxBusy)GetProc("_extfskIsTxBusy"); fextfskPutChar = (extfskPutChar)GetProc("_extfskPutChar"); fextfskSetPTT = (extfskSetPTT)GetProc("_extfskSetPTT"); } } //--------------------------------------------------------------------- __fastcall CEXTFSK::~CEXTFSK() { if( m_hLib != NULL ){ Close(); ::FreeLibrary(m_hLib); m_hLib = NULL; } } //--------------------------------------------------------------------- FARPROC CEXTFSK::GetProc(LPCSTR pName) { FARPROC fn = ::GetProcAddress(m_hLib, pName+1); if( fn == NULL ){ fn = ::GetProcAddress(m_hLib, pName); } return fn; } long __fastcall CEXTFSK::Open(long para) { if( !m_hLib || !fextfskOpen ) return FALSE; return fextfskOpen(para); } void __fastcall CEXTFSK::Close(void) { if( !m_hLib || !fextfskClose ) return; fextfskClose(); } long __fastcall CEXTFSK::IsTxBusy(void) { if( !m_hLib || !fextfskIsTxBusy ) return FALSE; return fextfskIsTxBusy(); } void __fastcall CEXTFSK::PutChar(BYTE c) { if( !m_hLib || !fextfskPutChar ) return; fextfskPutChar(c); } void __fastcall CEXTFSK::SetPTT(long tx) { if( !m_hLib || !fextfskSetPTT ) return; fextfskSetPTT(tx); }