You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
364 lines
13 KiB
364 lines
13 KiB
/***************************************************************************
|
|
Name : SEND.C
|
|
Comment : Sender functions
|
|
|
|
Revision Log
|
|
Date Name Description
|
|
-------- ----- ---------------------------------------------------------
|
|
***************************************************************************/
|
|
#define USE_DEBUG_CONTEXT DEBUG_CONTEXT_T30_MAIN
|
|
|
|
#include "prep.h"
|
|
#include "efaxcb.h"
|
|
#include "glbproto.h"
|
|
#include "t30gl.h"
|
|
|
|
SWORD ICommGetSendBuf(PThrdGlbl pTG, LPBUFFER far* lplpbf, SLONG slOffset)
|
|
{
|
|
/**
|
|
slOffset == SEND_STARTPAGE marks beginning of new block *and* page
|
|
(returns with data from the "appropriate" file offset).
|
|
|
|
slOffset == SEND_SEQ means get buffer from current file position
|
|
slOffset >= 0 gives the offset in bytes from the last marked position
|
|
(beginning of block) to start reading from
|
|
|
|
returns: SEND_ERROR on error, SEND_EOF on eof, SEND_OK otherwise.
|
|
Does not return data on EOF or ERROR, i.e. *lplpbf==0
|
|
**/
|
|
|
|
SWORD sRet = SEND_ERROR;
|
|
LPBUFFER lpbf;
|
|
DWORD dwBytesRead;
|
|
|
|
DEBUG_FUNCTION_NAME(_T("ICommGetSendBuf"));
|
|
|
|
if (pTG->fAbortRequested)
|
|
{
|
|
DebugPrintEx(DEBUG_MSG,"got ABORT");
|
|
sRet = SEND_ERROR;
|
|
goto mutexit;
|
|
}
|
|
|
|
if(slOffset == SEND_STARTPAGE)
|
|
{
|
|
pTG->fTxPageDone = FALSE; // This to mark that we did not finish yet.
|
|
if (pTG->T30.ifrResp == ifrRTN)
|
|
{
|
|
DebugPrintEx( DEBUG_MSG,
|
|
"Re-transmitting: We open again the file: %s",
|
|
pTG->InFileName);
|
|
|
|
if ( ( pTG->InFileHandle = CreateFileA(pTG->InFileName, GENERIC_READ, FILE_SHARE_READ,
|
|
NULL, OPEN_EXISTING, 0, NULL) ) == INVALID_HANDLE_VALUE )
|
|
{
|
|
DebugPrintEx( DEBUG_ERR,
|
|
"OpenFile for Retranmit %s fails; CurrentOut=%d;"
|
|
" CurrentIn=%d",
|
|
pTG->InFileName,
|
|
pTG->CurrentOut,
|
|
pTG->CurrentIn);
|
|
|
|
sRet = SEND_ERROR;
|
|
goto mutexit;
|
|
}
|
|
|
|
pTG->InFileHandleNeedsBeClosed = TRUE;
|
|
|
|
SignalStatusChange(pTG, FS_TRANSMITTING); // This will report the current status
|
|
|
|
DebugPrintEx( DEBUG_MSG,
|
|
"SEND_STARTPAGE: CurrentOut=%d, FirstOut=%d,"
|
|
" LastOut=%d, CurrentIn=%d",
|
|
pTG->CurrentOut,
|
|
pTG->FirstOut,
|
|
pTG->LastOut,
|
|
pTG->CurrentIn);
|
|
|
|
}
|
|
else //First try for the current page
|
|
{
|
|
// Delete last successfully transmitted Tiff Page file.
|
|
// Lets reset the counter of the retries. Attention: The speed remains the same.
|
|
pTG->ProtParams.RTNNumOfRetries = 0;
|
|
_fmemcpy (pTG->InFileName, gT30.TmpDirectory, gT30.dwLengthTmpDirectory);
|
|
_fmemcpy (&pTG->InFileName[gT30.dwLengthTmpDirectory], pTG->lpszPermanentLineID, 8);
|
|
if (pTG->PageCount != 0)
|
|
{
|
|
sprintf( &pTG->InFileName[gT30.dwLengthTmpDirectory+8], ".%03d", pTG->PageCount);
|
|
if (! DeleteFileA (pTG->InFileName) )
|
|
{
|
|
DebugPrintEx( DEBUG_ERR,
|
|
"file %s can't be deleted; le=%lx",
|
|
pTG->InFileName,
|
|
GetLastError());
|
|
}
|
|
else
|
|
{
|
|
DebugPrintEx( DEBUG_MSG,
|
|
"SEND_STARTPAGE: Previous file %s deleted."
|
|
" PageCount=%d, CurrentIn=%d",
|
|
pTG->InFileName,
|
|
pTG->PageCount,
|
|
pTG->CurrentIn);
|
|
}
|
|
|
|
}
|
|
|
|
pTG->PageCount++ ;
|
|
pTG->CurrentIn++ ;
|
|
|
|
DebugPrintEx( DEBUG_MSG,
|
|
"SendBuf: Starting New PAGE %d First=%d Last=%d",
|
|
pTG->PageCount,
|
|
pTG->FirstOut,
|
|
pTG->LastOut);
|
|
|
|
// Server wants to know when we start TX new page.
|
|
SignalStatusChange(pTG, FS_TRANSMITTING);
|
|
|
|
DebugPrintEx( DEBUG_MSG,
|
|
"SEND_STARTPAGE (cont): CurrentOut=%d, FirstOut=%d,"
|
|
" LastOut=%d, CurrentIn=%d",
|
|
pTG->CurrentOut,
|
|
pTG->FirstOut,
|
|
pTG->LastOut,
|
|
pTG->CurrentIn);
|
|
|
|
if (pTG->CurrentOut < pTG->CurrentIn )
|
|
{
|
|
DebugPrintEx( DEBUG_ERR,
|
|
"TIFF PAGE hadn't been started CurrentOut=%d;",
|
|
" CurrentIn=%d",
|
|
pTG->CurrentOut,
|
|
pTG->CurrentIn);
|
|
|
|
sRet = SEND_ERROR;
|
|
goto mutexit;
|
|
}
|
|
|
|
// some slack for 1st page
|
|
if ( (pTG->CurrentOut == pTG->CurrentIn) && (pTG->CurrentIn == 1 ) )
|
|
{
|
|
DebugPrintEx( DEBUG_MSG,
|
|
"SEND: Wait for 1st page: CurrentOut=%d; In=%d",
|
|
pTG->CurrentOut,
|
|
pTG->CurrentIn);
|
|
|
|
if ( WaitForSingleObject(pTG->FirstPageReadyTxSignal, 5000) == WAIT_TIMEOUT )
|
|
{
|
|
DebugPrintEx( DEBUG_ERR,
|
|
"SEND: TIMEOUT ERROR Wait for 1st page:"
|
|
" CurrentOut=%d; In=%d",
|
|
pTG->CurrentOut,
|
|
pTG->CurrentIn);
|
|
}
|
|
|
|
DebugPrintEx( DEBUG_MSG,
|
|
"SEND: Wakeup for 1st page: CurrentOut=%d; In=%d",
|
|
pTG->CurrentOut,
|
|
pTG->CurrentIn);
|
|
}
|
|
|
|
// open the file created by tiff thread
|
|
|
|
sprintf( &pTG->InFileName[gT30.dwLengthTmpDirectory+8], ".%03d", pTG->PageCount);
|
|
|
|
if ( ( pTG->InFileHandle = CreateFileA(pTG->InFileName, GENERIC_READ, FILE_SHARE_READ,
|
|
NULL, OPEN_EXISTING, 0, NULL) ) == INVALID_HANDLE_VALUE )
|
|
{
|
|
DebugPrintEx( DEBUG_ERR,
|
|
"OpenFile %s fails; CurrentOut=%d;"
|
|
" CurrentIn=%d",
|
|
pTG->InFileName,
|
|
pTG->CurrentOut,
|
|
pTG->CurrentIn);
|
|
|
|
sRet = SEND_ERROR;
|
|
goto mutexit;
|
|
}
|
|
|
|
pTG->InFileHandleNeedsBeClosed = TRUE;
|
|
|
|
if ( pTG->CurrentOut == pTG->CurrentIn )
|
|
{
|
|
DebugPrintEx( DEBUG_WRN,
|
|
"CurrentOut=%d; CurrentIn=%d",
|
|
pTG->CurrentOut,
|
|
pTG->CurrentIn);
|
|
}
|
|
|
|
//
|
|
// Signal TIFF thread to start preparing new page if needed.
|
|
//
|
|
|
|
if ( (! pTG->fTiffDocumentDone) && (pTG->LastOut - pTG->CurrentIn < 2) )
|
|
{
|
|
if (!ResetEvent(pTG->ThrdSignal))
|
|
{
|
|
DebugPrintEx( DEBUG_ERR,
|
|
"ResetEvent(0x%lx) returns failure code: %ld",
|
|
(ULONG_PTR)pTG->ThrdSignal,
|
|
(long) GetLastError());
|
|
// this is bad, but not fatal yet.
|
|
// let's wait and see what happens with SetEvent...
|
|
}
|
|
pTG->ReqStartNewPage = 1;
|
|
pTG->AckStartNewPage = 0;
|
|
|
|
DebugPrintEx( DEBUG_MSG,
|
|
"SIGNAL NEW PAGE CurrentOut=%d; CurrentIn=%d",
|
|
pTG->CurrentOut,
|
|
pTG->CurrentIn);
|
|
|
|
if (!SetEvent(pTG->ThrdSignal))
|
|
{
|
|
DebugPrintEx( DEBUG_ERR,
|
|
"SetEvent(0x%lx) returns failure code: %ld",
|
|
(ULONG_PTR)pTG->ThrdSignal,
|
|
(long) GetLastError());
|
|
sRet = SEND_ERROR;
|
|
goto mutexit;
|
|
}
|
|
}
|
|
}
|
|
|
|
pTG->Inst.state = SENDDATA_PHASE;
|
|
sRet = SEND_OK;
|
|
goto mutexit;
|
|
}
|
|
|
|
*lplpbf=0;
|
|
|
|
if(slOffset == SEND_SEQ)
|
|
{
|
|
if (pTG->fTxPageDone)
|
|
{ //In the last read from the file, we can tell that the page is over
|
|
|
|
sRet = SEND_EOF;
|
|
|
|
if (pTG->InFileHandleNeedsBeClosed)
|
|
{
|
|
CloseHandle(pTG->InFileHandle); // If we close the file so rashly, open it again later
|
|
pTG->InFileHandleNeedsBeClosed = FALSE;
|
|
}
|
|
goto mutexit;
|
|
}
|
|
|
|
lpbf = MyAllocBuf(pTG, MY_BIGBUF_SIZE);
|
|
lpbf->lpbBegData = lpbf->lpbBegBuf+4;
|
|
lpbf->wLengthData = MY_BIGBUF_SIZE;
|
|
|
|
if ( ! ReadFile(pTG->InFileHandle, lpbf->lpbBegData, lpbf->wLengthData, &dwBytesRead, 0) )
|
|
{
|
|
DebugPrintEx( DEBUG_ERR,
|
|
"Can't read %d bytes from %s. Last error:%d",
|
|
lpbf->wLengthData,
|
|
pTG->InFileName,
|
|
GetLastError());
|
|
MyFreeBuf (pTG, lpbf);
|
|
sRet = SEND_ERROR;
|
|
goto mutexit;
|
|
}
|
|
|
|
if ( lpbf->wLengthData != (unsigned) dwBytesRead )
|
|
{
|
|
if (pTG->fTiffPageDone || (pTG->CurrentIn != pTG->CurrentOut) )
|
|
{
|
|
// actually reached EndOfPage
|
|
lpbf->wLengthData = (unsigned) dwBytesRead;
|
|
pTG->fTxPageDone = TRUE;
|
|
}
|
|
else
|
|
{
|
|
DebugPrintEx( DEBUG_ERR,
|
|
"Wanted %d bytes but ONLY %d ready from %s",
|
|
lpbf->wLengthData,
|
|
dwBytesRead,
|
|
pTG->InFileName);
|
|
|
|
MyFreeBuf (pTG, lpbf);
|
|
sRet = SEND_ERROR;
|
|
goto mutexit;
|
|
}
|
|
}
|
|
|
|
*lplpbf = lpbf;
|
|
|
|
DebugPrintEx(DEBUG_MSG,"SEND_SEQ: length=%d", lpbf->wLengthData);
|
|
}
|
|
|
|
sRet = SEND_OK;
|
|
|
|
mutexit:
|
|
|
|
return sRet;
|
|
}
|
|
|
|
USHORT ICommNextSend(PThrdGlbl pTG)
|
|
{
|
|
USHORT uRet = NEXTSEND_ERROR;
|
|
|
|
DEBUG_FUNCTION_NAME(_T("ICommNextSend"));
|
|
|
|
if (pTG->PageCount >= pTG->TiffInfo.PageCount)
|
|
{
|
|
pTG->Inst.awfi.fLastPage = 1;
|
|
}
|
|
|
|
if(pTG->Inst.awfi.fLastPage)
|
|
{
|
|
uRet = NEXTSEND_EOP;
|
|
}
|
|
else
|
|
{
|
|
uRet = NEXTSEND_MPS;
|
|
}
|
|
|
|
DebugPrintEx( DEBUG_MSG,
|
|
"uRet=%d, fLastPage=%d",
|
|
uRet,
|
|
pTG->Inst.awfi.fLastPage);
|
|
|
|
return uRet;
|
|
}
|
|
|
|
BOOL ICommRecvCaps(PThrdGlbl pTG, LPBC lpBC)
|
|
{
|
|
BOOL fRet = FALSE;
|
|
|
|
DEBUG_FUNCTION_NAME(_T("ICommRecvCaps"));
|
|
|
|
if (pTG->fAbortRequested)
|
|
{
|
|
DebugPrintEx(DEBUG_MSG,"got ABORT");
|
|
fRet = FALSE;
|
|
goto mutexit;
|
|
}
|
|
|
|
if(pTG->Inst.state != BEFORE_RECVCAPS)
|
|
{
|
|
DebugPrintEx(DEBUG_WRN,"Got caps unexpectedly--ignoring");
|
|
// this will break if we send EOM...
|
|
// then we should go back into RECV_CAPS state
|
|
fRet = TRUE;
|
|
//RSL goto mutexit;
|
|
}
|
|
|
|
_fmemset(&pTG->Inst.RemoteRecvCaps, 0, sizeof(pTG->Inst.RemoteRecvCaps));
|
|
_fmemcpy(&pTG->Inst.RemoteRecvCaps, lpBC, min(sizeof(pTG->Inst.RemoteRecvCaps), lpBC->wTotalSize));
|
|
|
|
if(!NegotiateCaps(pTG))
|
|
{
|
|
_fmemset(&pTG->Inst.SendParams, 0, sizeof(pTG->Inst.SendParams));
|
|
fRet = FALSE;
|
|
goto mutexit;
|
|
}
|
|
|
|
pTG->Inst.state = SENDDATA_BETWEENPAGES;
|
|
fRet = TRUE;
|
|
|
|
mutexit:
|
|
return fRet;
|
|
}
|
|
|