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.
945 lines
20 KiB
945 lines
20 KiB
/* File: C:\WACKER\xfer\mdmx_rcv.c (Created: 18-Jan-1994)
|
|
* created from HAWIN source file
|
|
*
|
|
* mdmx_rcv.c -- XMODEM compatible file receiving routines for HA5G
|
|
*
|
|
* Copyright 1987,88,89,90,1994 by Hilgraeve Inc. -- Monroe, MI
|
|
* All rights reserved
|
|
*
|
|
* $Revision: 9 $
|
|
* $Date: 7/11/02 3:58p $
|
|
*/
|
|
|
|
#include <windows.h>
|
|
#pragma hdrstop
|
|
|
|
#include <stdlib.h>
|
|
// #include <setjmp.h>
|
|
|
|
#define BYTE unsigned char
|
|
|
|
#include <tdll\mc.h>
|
|
#include <tdll\stdtyp.h>
|
|
#include <tdll\com.h>
|
|
#include <tdll\assert.h>
|
|
#include <tdll\session.h>
|
|
#include <tdll\load_res.h>
|
|
#include <tdll\xfer_msc.h>
|
|
#include <tdll\file_io.h>
|
|
#include <tdll\htchar.h>
|
|
#include "xfr_srvc.h"
|
|
#include "xfr_todo.h"
|
|
#include "xfr_dsp.h"
|
|
#include "xfer_tsc.h"
|
|
#include "foo.h"
|
|
|
|
#include "cmprs.h"
|
|
|
|
#include "xfer.h"
|
|
#include "xfer.hh"
|
|
|
|
#include "mdmx.h"
|
|
#include "mdmx.hh"
|
|
|
|
#if !defined(STATIC_FUNC)
|
|
#define STATIC_FUNC
|
|
#endif
|
|
|
|
/* * * * * * * * * * * * *
|
|
* Function Prototypes *
|
|
* * * * * * * * * * * * */
|
|
|
|
STATIC_FUNC void start_receive(ST_MDMX *xc, unsigned expect);
|
|
|
|
STATIC_FUNC int wait_receive(ST_MDMX *xc);
|
|
|
|
STATIC_FUNC int receivepckt(ST_MDMX *xc,
|
|
HSESSION hSession,
|
|
unsigned expect,
|
|
struct s_mdmx_pckt *pckt);
|
|
|
|
STATIC_FUNC void respond(HSESSION hSession, ST_MDMX *xc, char code);
|
|
|
|
STATIC_FUNC void xm_clear_input(HSESSION hSession);
|
|
|
|
STATIC_FUNC void xm_rcheck(ST_MDMX *xc, HSESSION hSession, int before);
|
|
|
|
STATIC_FUNC void xm_check_input(HSESSION hSession, int suspend);
|
|
|
|
extern int xr_collect(ST_MDMX *, int, long, unsigned char **,
|
|
unsigned char *, unsigned *);
|
|
|
|
|
|
/*lint -e502*/ /* lint seems to want the ~ operator applied
|
|
* only to unsigned, wer'e using uchar
|
|
*/
|
|
#define ESC_MSG_COL 1
|
|
|
|
|
|
/* * * * * * * * * * * *
|
|
* Shared Variables *
|
|
* * * * * * * * * * * */
|
|
|
|
// int (NEAR *p_putc)(metachar c) = xm_putc;
|
|
// static struct s_mdmx_pckt *next_pckt;
|
|
// static unsigned this_pckt;
|
|
|
|
// static tiny check_type;
|
|
// static int batch;
|
|
// static int streaming;
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
* mdmx_rcv
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
* ARGUMENTS:
|
|
*
|
|
* RETURNS:
|
|
*
|
|
*/
|
|
int mdmx_rcv(HSESSION hSession, int attended, int method, int single_file)
|
|
{
|
|
ST_MDMX *xc;
|
|
struct s_mdmx_pckt *last_pckt = NULL;
|
|
struct s_mdmx_pckt *swap_pckt = NULL;
|
|
struct st_rcv_open stRcv;
|
|
TCHAR fname[FNAME_LEN];
|
|
TCHAR our_fname[FNAME_LEN];
|
|
long basesize;
|
|
int still_trying = TRUE;
|
|
int xpckt_size;
|
|
int xstatus = TSC_OK;
|
|
int override = FALSE;
|
|
unsigned int uiOldOptions;
|
|
unsigned tries, retries;
|
|
unsigned char *cp;
|
|
int blk_result = UNDEFINED, result = 0;
|
|
char start_char;
|
|
char nak_char;
|
|
|
|
TCHAR_Fill(fname, TEXT('\0'), FNAME_LEN);
|
|
|
|
/* allocate space for large packets since we don't necessarily know what
|
|
* we'll be getting.
|
|
*/
|
|
xc = NULL;
|
|
last_pckt = NULL;
|
|
xc = malloc(sizeof(ST_MDMX));
|
|
if (xc == NULL)
|
|
goto done;
|
|
memset(xc, 0, sizeof(ST_MDMX));
|
|
DbgOutStr("xc = 0x%x\r\n", xc, 0,0,0,0);
|
|
|
|
last_pckt = malloc(sizeof(ST_MDMX) + LARGE_PACKET + 2);
|
|
if (last_pckt == NULL)
|
|
goto done;
|
|
memset(last_pckt, 0, sizeof(ST_MDMX));
|
|
|
|
xc->next_pckt = malloc(sizeof(ST_MDMX) + LARGE_PACKET + 2);
|
|
if (xc->next_pckt == NULL)
|
|
goto done;
|
|
memset(xc->next_pckt, 0, sizeof(ST_MDMX));
|
|
|
|
xc->hSession = hSession;
|
|
xc->hCom = sessQueryComHdl(hSession);
|
|
|
|
DbgOutStr("hs = 0x%x\r\n", hSession, 0,0,0,0);
|
|
|
|
mdmxXferInit(xc, method);
|
|
|
|
if (xfer_set_comport(hSession, FALSE, &uiOldOptions) != TRUE)
|
|
goto done;
|
|
else
|
|
override = TRUE;
|
|
|
|
xc->file_bytes = 0L;
|
|
xc->total_bytes = 0L;
|
|
#if FALSE
|
|
xc->flagkey = kbd_register_flagkey(ESC_KEY, NULL);
|
|
#endif
|
|
xc->fh = NULL;
|
|
xc->xfertimer = -1L;
|
|
xc->xfertime = 0L;
|
|
xc->nfiles = 0;
|
|
xc->filen = 0;
|
|
xc->filesize = -1L;
|
|
xc->nbytes = -1L;
|
|
|
|
still_trying = TRUE;
|
|
blk_result = UNDEFINED;
|
|
xc->batch = TRUE;
|
|
xc->streaming = FALSE;
|
|
start_char = 'C';
|
|
xc->check_type = CRC;
|
|
mdmxdspChecktype(xc, (xc->check_type == CRC) ? 0 : 1);
|
|
if (method == XF_YMODEM_G)
|
|
{
|
|
xc->streaming = TRUE;
|
|
start_char = 'G';
|
|
}
|
|
else if ((method == XF_XMODEM || method == XF_XMODEM_1K) &&
|
|
xc->mdmx_chkt == CHECKSUM)
|
|
{
|
|
start_char = NAK;
|
|
xc->check_type = CHECKSUM;
|
|
}
|
|
|
|
nak_char = start_char;
|
|
xc->this_pckt = 0;
|
|
|
|
tries = 0;
|
|
mdmxdspPacketErrorcnt(xc, tries);
|
|
|
|
retries = 0;
|
|
mdmxdspErrorcnt(xc, retries);
|
|
|
|
xc->mdmx_byte_cnt = 0L;
|
|
|
|
mdmxdspChecktype(xc, (xc->check_type == CRC) ? 0 : 1);
|
|
|
|
start_receive(xc, xc->this_pckt); /* setup to receive first pckt */
|
|
if (attended)
|
|
respond(hSession, xc, start_char);
|
|
|
|
while (still_trying)
|
|
{
|
|
blk_result = wait_receive(xc);
|
|
switch(blk_result)
|
|
{
|
|
case NOBATCH_PCKT:
|
|
/* Received pckt 1 while waiting for pckt 0.
|
|
* This must be an XMODEM as opposed to a YMODEM transfer
|
|
*/
|
|
if (!single_file)
|
|
{
|
|
xstatus = TSC_BAD_FORMAT;
|
|
still_trying = FALSE;
|
|
break;
|
|
}
|
|
xc->this_pckt = 1;
|
|
xc->batch = FALSE;
|
|
xc->filesize = -1L;
|
|
nak_char = NAK;
|
|
|
|
stRcv.pszSuggestedName = "";
|
|
stRcv.pszActualName = our_fname;
|
|
stRcv.lFileTime = 0;
|
|
|
|
result = xfer_open_rcv_file(hSession, &stRcv, 0L);
|
|
if (result != 0)
|
|
{
|
|
switch (result)
|
|
{
|
|
case -6:
|
|
xstatus = TSC_REFUSE;
|
|
break;
|
|
case -5:
|
|
xstatus = TSC_CANT_OPEN;
|
|
break;
|
|
case -4:
|
|
xstatus = TSC_NO_FILETIME;
|
|
break;
|
|
case -3:
|
|
xstatus = TSC_CANT_OPEN;
|
|
break;
|
|
case -2:
|
|
xstatus = TSC_OLDER_FILE;
|
|
break;
|
|
case -1:
|
|
default:
|
|
xstatus = TSC_CANT_OPEN;
|
|
break;
|
|
}
|
|
still_trying = FALSE;
|
|
break;
|
|
}
|
|
|
|
xc->fh = stRcv.bfHdl;
|
|
xc->basesize = stRcv.lInitialSize;
|
|
|
|
basesize = stRcv.lInitialSize;
|
|
|
|
mdmxdspNewfile(xc,
|
|
0,
|
|
our_fname,
|
|
our_fname);
|
|
|
|
/* fall through */
|
|
case ALT_PCKT:
|
|
case GOOD_PCKT:
|
|
/* swap pckt pointers so we can work on this one while receiving
|
|
* the next
|
|
*/
|
|
swap_pckt = last_pckt;
|
|
last_pckt = xc->next_pckt;
|
|
xc->next_pckt = swap_pckt;
|
|
if (xc->this_pckt != 0)
|
|
start_receive(xc, xc->this_pckt + 1);
|
|
|
|
if (!xc->streaming)
|
|
respond(hSession, xc, ACK); /* send ACK as soon as possible */
|
|
/* then send burst for Xmodem pckt 1 */
|
|
if (xc->this_pckt == 0)
|
|
{
|
|
if (!*(last_pckt->bdata)) /* no more files? */
|
|
{
|
|
xc->xfertime = (long)interval(xc->xfertimer);
|
|
still_trying = FALSE;
|
|
break;
|
|
}
|
|
else if (xc->filen > 0 && single_file) /* getting too many files? */
|
|
{
|
|
xstatus = TSC_TOO_MANY;
|
|
still_trying = FALSE;
|
|
break;
|
|
}
|
|
|
|
start_receive(xc, 1);
|
|
respond(hSession, xc, start_char);
|
|
|
|
/* get info out of packet 0 and open file */
|
|
StrCharCopyN(fname, last_pckt->bdata, FNAME_LEN);
|
|
for (cp = fname; *cp != '\0'; cp++)
|
|
if (*cp == '/')
|
|
*cp = '\\';
|
|
|
|
stRcv.pszSuggestedName = fname;
|
|
stRcv.pszActualName = our_fname;
|
|
stRcv.lFileTime = 0;
|
|
xfer_build_rcv_name(hSession, &stRcv);
|
|
|
|
result = xfer_open_rcv_file(hSession, &stRcv, 0L);
|
|
if (result != 0)
|
|
{
|
|
switch (result)
|
|
{
|
|
case -6:
|
|
xstatus = TSC_REFUSE;
|
|
break;
|
|
case -5:
|
|
xstatus = TSC_CANT_OPEN;
|
|
break;
|
|
case -4:
|
|
xstatus = TSC_NO_FILETIME;
|
|
break;
|
|
case -3:
|
|
xstatus = TSC_CANT_OPEN;
|
|
break;
|
|
case -2:
|
|
xstatus = TSC_OLDER_FILE;
|
|
break;
|
|
case -1:
|
|
default:
|
|
xstatus = TSC_CANT_OPEN;
|
|
break;
|
|
}
|
|
still_trying = FALSE;
|
|
break;
|
|
}
|
|
|
|
xc->fh = stRcv.bfHdl;
|
|
xc->basesize = stRcv.lInitialSize;
|
|
|
|
basesize = stRcv.lInitialSize;
|
|
|
|
mdmxdspNewfile(xc,
|
|
++xc->filen,
|
|
fname,
|
|
our_fname);
|
|
|
|
/* accumlate last transfer total and start new counter */
|
|
xc->total_bytes += xc->file_bytes;
|
|
xc->mdmx_byte_cnt = xc->file_bytes = 0L;
|
|
xc->filesize = -1L;
|
|
cp = last_pckt->bdata +
|
|
StrCharGetByteCount(last_pckt->bdata) + 1;
|
|
if (*cp)
|
|
{
|
|
xc->filesize = atol(cp);
|
|
|
|
mdmxdspFilesize(xc, xc->filesize);
|
|
}
|
|
nak_char = NAK;
|
|
}
|
|
else
|
|
{
|
|
/* unload packet data */
|
|
cp = last_pckt->bdata;
|
|
xpckt_size = (last_pckt->start_char == STX ?
|
|
LARGE_PACKET : SMALL_PACKET);
|
|
|
|
if (xs_unload(xc, cp, xpckt_size) == (-1) /* ERROR */ )
|
|
{
|
|
xm_clear_input(hSession);
|
|
respond(hSession, xc, CAN);
|
|
xstatus = TSC_DISK_ERROR;
|
|
still_trying = FALSE;
|
|
break;
|
|
}
|
|
|
|
// if (xc->filesize != -1L) jmh 03-08-96 to match HAWin
|
|
if (xc->filesize > 0)
|
|
xc->file_bytes = min(xc->filesize, xc->mdmx_byte_cnt);
|
|
else
|
|
xc->file_bytes = xc->mdmx_byte_cnt;
|
|
}
|
|
|
|
mdmxdspPacketnumber(xc, (long)++xc->this_pckt);
|
|
|
|
if (tries)
|
|
mdmxdspPacketErrorcnt(xc, tries = 0);
|
|
|
|
mdmx_progress(xc, 0);
|
|
|
|
|
|
break;
|
|
|
|
case END_PCKT:
|
|
/* the special EOT handling was removed from version 3.20
|
|
* due to problems with RBBS-PC. It should be modified and
|
|
* reenabled after experimentation.
|
|
*/
|
|
|
|
|
|
respond(hSession, xc, ACK); /* ACK the EOT */
|
|
mdmx_progress(xc, FILE_DONE);
|
|
|
|
/* It's possible to get an unwanted EOT (if the ACK from the
|
|
* first EOT is lost) so we should treat it like a repeated
|
|
* packet.
|
|
*/
|
|
|
|
if (xc->fh) /* if file was open */
|
|
{
|
|
if (!xfer_close_rcv_file(hSession,
|
|
xc->fh,
|
|
xstatus,
|
|
fname,
|
|
our_fname,
|
|
xfer_save_partial(hSession),
|
|
xc->basesize + xc->file_bytes /*xc->filesize jmh 03-08-96*/,
|
|
0))
|
|
{
|
|
xstatus = TSC_DISK_ERROR;
|
|
still_trying = FALSE;
|
|
break;
|
|
}
|
|
|
|
xc->fh = NULL;
|
|
}
|
|
|
|
if (!xc->batch)
|
|
{
|
|
xc->xfertime = (long)interval(xc->xfertimer);
|
|
still_trying = FALSE;
|
|
}
|
|
else
|
|
{
|
|
start_receive(xc, xc->this_pckt = 0);
|
|
respond(hSession, xc, nak_char = start_char);
|
|
}
|
|
|
|
if (tries)
|
|
// VidWrtStrF(xc->toprow + XR_DR_RETRIES, xc->dc_retries,
|
|
// "^H%-2d", tries = 0);
|
|
mdmxdspPacketErrorcnt(xc, tries = 0);
|
|
|
|
break;
|
|
|
|
case REPEAT_PCKT:
|
|
start_receive(xc, xc->this_pckt);
|
|
respond(hSession, xc, ACK);
|
|
++tries;
|
|
break;
|
|
|
|
case WRONG_PCKT:
|
|
xm_clear_input(hSession);
|
|
respond(hSession, xc, CAN);
|
|
++tries; /* to get packet error on screen */
|
|
still_trying = FALSE;
|
|
xstatus = TSC_OUT_OF_SEQ;
|
|
break;
|
|
|
|
case SHORT_PCKT:
|
|
case BAD_FORMAT:
|
|
case BAD_CHECK:
|
|
case NO_PCKT:
|
|
++tries;
|
|
if (xc->mdmx_chkt == UNDETERMINED && xc->this_pckt == 0 && tries == 3
|
|
&& method == XF_XMODEM)
|
|
{
|
|
xc->check_type = CHECKSUM;
|
|
start_char = nak_char = NAK;
|
|
// VidWrtStr(xc->toprow + XR_DR_ERR_CHK, xc->dc_err_chk,
|
|
// strld(TM_CHECKSUM));
|
|
|
|
mdmxdspChecktype(xc, 1);
|
|
}
|
|
xm_clear_input(hSession);
|
|
respond(hSession, xc, nak_char);
|
|
start_receive(xc, xc->this_pckt);
|
|
break;
|
|
|
|
case BLK_ABORTED:
|
|
xm_clear_input(hSession);
|
|
respond(hSession, xc, CAN);
|
|
xstatus = TSC_USER_CANNED;
|
|
still_trying = FALSE;
|
|
break;
|
|
|
|
case CARRIER_LOST:
|
|
xm_clear_input(hSession);
|
|
xstatus = TSC_LOST_CARRIER;
|
|
still_trying = FALSE;
|
|
break;
|
|
|
|
case CANNED:
|
|
xm_clear_input(hSession);
|
|
xstatus = TSC_RMT_CANNED;
|
|
still_trying = FALSE;
|
|
break;
|
|
|
|
default:
|
|
// assert(FALSE);
|
|
break;
|
|
}
|
|
|
|
if (tries)
|
|
{
|
|
mdmxdspPacketErrorcnt(xc, tries);
|
|
|
|
mdmxdspErrorcnt(xc, ++retries);
|
|
|
|
mdmxdspLastError(xc, blk_result);
|
|
|
|
if ((tries >= (unsigned)xc->mdmx_tries) || (xc->streaming && xc->this_pckt > 0))
|
|
{
|
|
xm_clear_input(hSession);
|
|
respond(hSession, xc, CAN);
|
|
xstatus = TSC_ERROR_LIMIT;
|
|
still_trying = FALSE;
|
|
}
|
|
}
|
|
} /* while (still_trying) */
|
|
|
|
|
|
|
|
done:
|
|
|
|
if (xc)
|
|
{
|
|
if (xc->xfertime == 0L)
|
|
{
|
|
xc->xfertime = (long)interval(xc->xfertimer);
|
|
}
|
|
|
|
mdmx_progress(xc, TRANSFER_DONE);
|
|
}
|
|
|
|
if (override)
|
|
{
|
|
#if FALSE
|
|
cnfg.send_xprot = hld_send_xprot;
|
|
cnfg.save_xprot = hld_save_xprot;
|
|
cnfg.bits_per_char = hld_bits_per_char;
|
|
cnfg.parity_type = hld_parity_type;
|
|
(void)(*ComResetPort)();
|
|
#endif
|
|
xfer_restore_comport(hSession, uiOldOptions);
|
|
}
|
|
|
|
if (xc)
|
|
{
|
|
if (xstatus != TSC_OK)
|
|
{
|
|
if (xc->fh)
|
|
{
|
|
xfer_close_rcv_file(hSession,
|
|
xc->fh,
|
|
xstatus,
|
|
fname,
|
|
our_fname,
|
|
xfer_save_partial(hSession),
|
|
xc->basesize + xc->file_bytes /*xc->filesize jmh 03-08-96*/,
|
|
0);
|
|
}
|
|
}
|
|
|
|
#if FALSE
|
|
kbd_deregister_flagkey(xc->flagkey);
|
|
#endif
|
|
mdmxdspCloseDisplay(xc);
|
|
|
|
#if defined(DEADWOOD)
|
|
if (xc->p_crc_tbl != NULL)
|
|
{
|
|
resFreeDataBlock(xc->hSession, xc->p_crc_tbl);
|
|
xc->p_crc_tbl = NULL;
|
|
}
|
|
#else // defined(DEADWOOD
|
|
//
|
|
// We don't need to free xc->p_crc_tbl since it is pointing
|
|
// to a static constant array. REV: 4/10/2002
|
|
//
|
|
xc->p_crc_tbl = NULL;
|
|
#endif // defined(DEADWOOD)
|
|
|
|
if (xc->next_pckt)
|
|
{
|
|
free(xc->next_pckt);
|
|
xc->next_pckt = NULL;
|
|
}
|
|
|
|
free(xc);
|
|
xc = NULL;
|
|
}
|
|
|
|
if (last_pckt)
|
|
{
|
|
free(last_pckt);
|
|
last_pckt = NULL;
|
|
}
|
|
|
|
return((int)xstatus);
|
|
}
|
|
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
* start_receive
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
* ARGUMENTS:
|
|
*
|
|
* RETURNS:
|
|
*
|
|
*/
|
|
STATIC_FUNC void start_receive(ST_MDMX *xc, unsigned expect)
|
|
{
|
|
xc->next_pckt->result = UNDEFINED;
|
|
xc->next_pckt->expected = expect;
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
* wait_receive
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
* ARGUMENTS:
|
|
*
|
|
* RETURNS:
|
|
*
|
|
*/
|
|
STATIC_FUNC int wait_receive(ST_MDMX *xc)
|
|
{
|
|
if (xc->next_pckt->result == UNDEFINED)
|
|
{
|
|
xc->next_pckt->result = receivepckt(xc,
|
|
xc->hSession,
|
|
xc->next_pckt->expected,
|
|
xc->next_pckt);
|
|
}
|
|
return xc->next_pckt->result;
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
* receivepckt
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
* ARGUMENTS:
|
|
*
|
|
* RETURNS:
|
|
*
|
|
*/
|
|
STATIC_FUNC int receivepckt(ST_MDMX *xc,
|
|
HSESSION hSession,
|
|
unsigned expect,
|
|
struct s_mdmx_pckt *pckt)
|
|
{
|
|
long timer, timeout;
|
|
int gothdr = FALSE;
|
|
int started = FALSE;
|
|
TCHAR cc;
|
|
unsigned char *cp;
|
|
int gotCAN = FALSE;
|
|
unsigned char checksum;
|
|
unsigned crc;
|
|
int count;
|
|
|
|
// DbgOutStr("pckt = 0x%x\r\n", pckt, 0,0,0,0);
|
|
|
|
timer = (long)startinterval();
|
|
|
|
/* wait for valid pckt-start character */
|
|
timeout = (long)(xc->mdmx_pckttime * 10);
|
|
|
|
while (!started)
|
|
{
|
|
#if FALSE
|
|
if (kbd_check_flagkey(xc->flagkey, TRUE))
|
|
{
|
|
kbd_flush();
|
|
return(BLK_ABORTED);
|
|
}
|
|
#endif
|
|
|
|
if (xfer_carrier_lost(hSession))
|
|
return CARRIER_LOST;
|
|
|
|
if (xfer_user_interrupt(hSession))
|
|
{
|
|
mdmxdspLastError(xc, BLK_ABORTED);
|
|
return(BLK_ABORTED);
|
|
}
|
|
|
|
mdmx_progress(xc, 0);
|
|
|
|
if ((long)interval(timer) > timeout)
|
|
return(NO_PCKT);
|
|
|
|
// if ((cc = RemoteGet(hSession)) != -1)
|
|
if (mComRcvChar(xc->hCom, &cc) != 0)
|
|
{
|
|
DbgOutStr("pckt = 0x%x\r\n", pckt, 0,0,0,0);
|
|
switch(pckt->start_char = (unsigned char)cc)
|
|
{
|
|
case EOT:
|
|
if (xc->xfertimer == -1L)
|
|
xc->xfertimer = (long)startinterval();
|
|
return(END_PCKT);
|
|
/*lint -unreachable*/
|
|
break;
|
|
|
|
case SOH:
|
|
case STX:
|
|
started = TRUE;
|
|
if (xc->xfertimer == -1L)
|
|
xc->xfertimer = (long)startinterval();
|
|
break;
|
|
|
|
case CAN:
|
|
/* if two consecutive CANs are received, drop out */
|
|
if (gotCAN)
|
|
return(CANNED);
|
|
gotCAN = TRUE;
|
|
break;
|
|
|
|
default:
|
|
/* ignore */
|
|
gotCAN = FALSE; /* two CANs must be consecutive */
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
xfer_idle(hSession, XFER_IDLE_IO);
|
|
}
|
|
}
|
|
/* got valid start character, get packet numbers, data, & error codes */
|
|
timeout = xc->mdmx_chartime * 10;
|
|
cp = &pckt->pcktnum;
|
|
count = 2;
|
|
for (;;)
|
|
{
|
|
if (!xr_collect(xc, count, timeout, &cp, &checksum, &crc))
|
|
return(SHORT_PCKT);
|
|
if (!gothdr)
|
|
{
|
|
/* got pckt numbers, now get data and check code(s) */
|
|
gothdr = TRUE;
|
|
count = (pckt->start_char == STX ? LARGE_PACKET : SMALL_PACKET);
|
|
count += (xc->check_type == CRC ? 2 : 1);
|
|
checksum = 0;
|
|
crc = 0;
|
|
cp = pckt->bdata;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
|
|
/* all bytes have been collected, check for valid packet */
|
|
if (xc->check_type == CHECKSUM)
|
|
{
|
|
/* at this point we've included the checksum itself in the checksum
|
|
* calculation. We need to back up, subtract the last char. from
|
|
* the computation and use it for comparison instead.
|
|
*/
|
|
--cp; /* point to received checksum */
|
|
checksum = (unsigned char)(checksum - *cp); /* we added one too many */
|
|
if (checksum != *cp)
|
|
return(BAD_CHECK);
|
|
}
|
|
else if (crc != 0)
|
|
return(BAD_CHECK);
|
|
|
|
if (pckt->pcktnum != (unsigned char)((~pckt->npcktnum) & 0xFF))
|
|
{
|
|
return(BAD_FORMAT);
|
|
}
|
|
|
|
if (pckt->pcktnum != (unsigned char)(expect % 256))
|
|
{
|
|
/* we always start out expecting ymodem batch, on an xmodem
|
|
* transfer, this code will detect the situation.
|
|
*/
|
|
if (!xc->filen && expect == 0 && pckt->pcktnum == 1)
|
|
return NOBATCH_PCKT;
|
|
else if (pckt->pcktnum == (unsigned char)((expect % 256) - 1))
|
|
return REPEAT_PCKT; /* repeated packets are harmless */
|
|
else
|
|
return WRONG_PCKT;
|
|
}
|
|
|
|
/* if we got this far, the pckt is good */
|
|
return(GOOD_PCKT);
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
* respond
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
* ARGUMENTS:
|
|
*
|
|
* RETURNS:
|
|
*
|
|
*/
|
|
STATIC_FUNC void respond(HSESSION hSession, ST_MDMX *xc, char code)
|
|
/* wait for line to clear, then send code */
|
|
{
|
|
int i;
|
|
|
|
ComSendChar(xc->hCom, &xc->stP, code);
|
|
if (code == CAN)
|
|
{
|
|
for (i = 4 + 1; --i > 0; )
|
|
ComSendChar(xc->hCom, &xc->stP, CAN);
|
|
}
|
|
ComSendWait(xc->hCom, &xc->stP);
|
|
}
|
|
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
* xm_clear_input
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
*
|
|
* ARGUMENTS:
|
|
*
|
|
*
|
|
* RETURNS:
|
|
*
|
|
*/
|
|
STATIC_FUNC void xm_clear_input(HSESSION hSession)
|
|
{
|
|
// RemoteClear(hSession); /* make sure no junk is left sitting in it */
|
|
ComRcvBufrClear(sessQueryComHdl(hSession));
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
* xm_rcheck
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
*
|
|
* ARGUMENTS:
|
|
*
|
|
*
|
|
* RETURNS:
|
|
*
|
|
*/
|
|
STATIC_FUNC void xm_rcheck(ST_MDMX *xc, HSESSION hSession, int before)
|
|
{
|
|
if (xc->streaming)
|
|
{
|
|
/* Do it different for YMODEM-G, since the sender won't wait for ACK */
|
|
#if FALSE
|
|
if (before)
|
|
suspendinput(FLG_DISK_ACTIVE, 5);
|
|
else
|
|
allowinput(FLG_DISK_ACTIVE);
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
if (before)
|
|
{
|
|
/* wait till next packet is in before writing to disk */
|
|
if (xc->next_pckt->result == UNDEFINED)
|
|
xc->next_pckt->result = wait_receive(xc);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
* xm_check_input
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
* ARGUEMENTS:
|
|
*
|
|
* RETURNS:
|
|
*
|
|
*/
|
|
STATIC_FUNC void xm_check_input(HSESSION hSession, int suspend)
|
|
{
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
* xr_collect
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
*
|
|
* ARGUMENTS:
|
|
*
|
|
*
|
|
* RETURNS:
|
|
*
|
|
*/
|
|
int xr_collect(ST_MDMX *xc, int count, long timeout,
|
|
unsigned char **ptr,
|
|
unsigned char *checksum, unsigned *crc)
|
|
{
|
|
unsigned char lchecksum;
|
|
unsigned char *cp, *head;
|
|
TCHAR rchar;
|
|
int cnt;
|
|
long timer;
|
|
|
|
head = cp = *ptr;
|
|
lchecksum = *checksum;
|
|
cnt = count;
|
|
|
|
while (cnt--)
|
|
{
|
|
// if ((rchar = RemoteGet(xc->hSession)) == -1)
|
|
if (mComRcvChar(xc->hCom, &rchar) == 0)
|
|
{
|
|
xfer_idle(xc->hSession, XFER_IDLE_IO);
|
|
/* driver hasn't put any new chars in rmt_bufr */
|
|
timer = (long)startinterval();
|
|
// while ((rchar = RemoteGet(xc->hSession)) == -1)
|
|
while (mComRcvChar(xc->hCom, &rchar) == 0)
|
|
{
|
|
/* check for char timeout */
|
|
xfer_idle(xc->hSession, XFER_IDLE_IO);
|
|
if ((long)interval(timer) > timeout)
|
|
return(FALSE);
|
|
}
|
|
}
|
|
*cp = (unsigned char)rchar;
|
|
lchecksum += *cp;
|
|
++cp;
|
|
}
|
|
*ptr = cp;
|
|
*checksum = lchecksum;
|
|
if (count > 100)
|
|
*crc = calc_crc(xc, (unsigned)0, head, count);
|
|
return(TRUE);
|
|
}
|
|
|
|
/***************************** end of mdmx_rcv.c **************************/
|