?? ian_xmodem.c
字號(hào):
break;
/*
* receive file-data
*/
xif.dataddr = dataddr;
xif.usecrc = yip->usecrc;
xif.verify = yip->verify;
if ( yip->verify ) {
#if INCLUDE_TFS
if (! (tfp = tfsstat(yip->fname[yip->filecnt])) ) {
waitclear();
doCAN();
rval = XERR_NOFILE;
break;
}
memcpy((char *)(xif.dataddr), TFS_BASE(tfp), tfp->filsize);
#endif
}
r = Xdown(&xif, YMODEM);
if ( r < 0 ) {
rval = r;
break;
}
if (yip->size[yip->filecnt] <= 0) {
yip->size[yip->filecnt] = xif.size;
}
yip->pktcnt[yip->filecnt] = xif.pktcnt;
yip->errcnt[yip->filecnt] = xif.errcnt;
yip->firsterrat[yip->filecnt] = xif.firsterrat;
/*
* write file to TFS
*/
if ( ! yif.verify ) {
#if INCLUDE_TFS
if ( yip->size[yip->filecnt] > 0 ) {
/* save file to TFS */
r = tfsadd(yip->fname[yip->filecnt],
yip->info, yip->flags,
(uchar *)(yip->dataddr[yip->filecnt]),
yip->size[yip->filecnt]);
if (r != TFS_OKAY) {
doCAN();
rval = XERR_TFS;
tfserr = r;
break;
}
}
#endif
}
#if INCLUDE_TFS
dataddr = yip->baseaddr;
#else
dataddr += yip->size[yip->filecnt];
#endif
yip->filecnt++;
} while (yip->filecnt < YFILES_MAX);
if ( yip->filecnt >= YFILES_MAX ) {
/* Cancel the transaction. Let the transmiter know that we
can receiver no more files */
waitclear();
doCAN();
}
/* trash any final garbage send by the transmiter */
waitclear();
return rval;
}
/***************************************************************************
* UPLOAD STUFF
**************************************************************************/
/*
* putPacket
*
* Send an X-Modem or Y-Modem packet
*/
static void
putPacket (uchar *pkt, int len, int sno, int usecrc)
{
int i;
ushort chksm;
chksm = 0;
/* Send start of frame. */
if ( (len == PKTLEN_128) || (sno == 0) ) {
rputchar(SOH);
} else {
rputchar(STX);
}
/* Send sequence number and its complement */
rputchar(sno);
rputchar((uchar)~(sno));
/* Send data. Calculate CRC or checksum. Send CRC or checksum. */
if ( usecrc ) {
for(i=0; i < len; i++) {
rputchar(*pkt);
chksm = (chksm << 8) ^ xcrc16tab[ (chksm>>8) ^ *pkt++ ];
}
rputchar((uchar)(chksm >> 8));
rputchar((uchar)(chksm & 0x00ff));
} else {
for(i=0; i < len; i++) {
rputchar(*pkt);
chksm = ((chksm+*pkt++)&0xff);
}
rputchar((uchar)(chksm&0x00ff));
}
}
/***************************************************************************/
/*
* sendPacket
*
* Send and X or Y modem protocol packet.
*
* Transmits the given frame and waits for acknowledgment.
* Handles retransmitions and cancel requests as well.
*
* Arguments:
* - pb - packet (frame) buffer. The packet to send is here.
* - len - length (in bytes) of the frame to send.
* - sno - sequence number of the frame to send
* - userce - if non-zero, use 16-bit CRC instead of 8-bit checksum.
*
* Returns:
* Non-negative on success (packet sent and acknowledged)
* Something negative on error:
* XERR_RETR : Max. number of retransmissions exceeded
* XERR_TOUT : Timeout (too many 'noise' chars received)
* XERR_CAN : Operation canceled
* XERR_UCAN : Operation canceled by user
*/
static int
sendPacket (uchar *pb, int len, ulong lsno, int usecrc)
{
int sno, c, noise, count, done;
Mtrace("P");
sno = lsno % 0x100;
putPacket(pb, len, sno, usecrc);
noise = 0;
count = RETR_MAX;
done = 0;
do {
c = waitchar(TRANS_TMO);
switch ( c ) {
case ACK:
Mtrace("A");
done = 1;
break;
case NAK:
Mtrace("K");
if ( --count ) {
putPacket(pb, len, sno, usecrc);
} else {
Mtrace("R");
waitclear();
doCAN();
done = XERR_RETR;
}
break;
case CAN:
Mtrace("N");
c = (char)waitchar(CHAR_TMO);
if (c != CAN) {
Mtrace("<%02x>", c);
noise++;
} else {
Mtrace("N");
done = XERR_CAN;
waitclear();
}
break;
case ESC:
Mtrace("X");
c = (char)waitchar(CHAR_TMO);
if (c != ESC) {
Mtrace("<%02x>", c);
noise++;
} else {
Mtrace("N");
done = XERR_UCAN;
waitclear();
}
break;
default:
Mtrace("<%02x>", c);
noise++;
break;
}
} while ( ! done && noise < NOISE_MAX );
if ( noise >= NOISE_MAX ) {
done = XERR_TOUT;
}
return done;
}
/***************************************************************************/
/*
* sync_trx
*
* synchronize transmiter
*
* Called by the upload fucntions and performs initial synchronization
* with the receiver.
*
* Returns:
* On success: Synchronization character send by the receiver (i.e. C
* or NAK).
* On error: something negative.
* XERR_TOUT - Timeout waiting for sync.
* XERR_CAN - Operation canceled.
* XERR_UCAN - Operation canceled by user.
*/
static int
sync_tx (void)
{
int done, c;
Mtrace("r[");
done = 0;
do {
c = waitchar(TRANS_TMO);
if ( c < 0 ) {
Mtrace("T");
done = XERR_TOUT;
waitclear();
doCAN();
break;
}
switch ( c ) {
case NAK:
Mtrace("K");
done = NAK;
break;
case 'C':
Mtrace("C");
done = 'C';
break;
case CAN:
Mtrace("N");
c = waitchar(CHAR_TMO);
if ( c != CAN ) {
Mtrace("<%02x>", c);
} else {
Mtrace("N", c);
done = XERR_CAN;
waitclear();
}
break;
case ESC:
Mtrace("X");
c = waitchar(CHAR_TMO);
if ( c != ESC ) {
Mtrace("<%02x>", c);
} else {
Mtrace("X", c);
done = XERR_UCAN;
waitclear();
}
break;
default:
Mtrace("<%02x>", c);
break;
}
} while ( ! done );
Mtrace("]");
return done;
}
/***************************************************************************/
/* Xup():
*
* Upload (uMon --> Host) a file using the XMODEM protocol
*
* Arguments:
* - xip - structure containing transfer info:
* usecrc OUT - use 16bit-CRC instead of 8bit-checksum.
* verify X
* dataddr: IN - The file to upload is stored here.
* size: IN - size of the file to upload in bytes.
* pktcnt: OUT - number of frames transfered.
* errcnt: x
* firsterrat: x
*
* Returns:
* On success: something non-negative.
* On error: something negative.
* XERR_GEN : General error
* XERR_TOUT : Timeout
* XERR_CAN : Operation canceled
* XERR_RETR : Maximum retransmitions reached
*/
static int
Xup (struct xinfo *xip, int proto)
{
int r, done, c, count, usecrc;
ulong dataddr;
int pktlen;
ulong sno;
long size;
Mtrace("--Xup--");
do { /* dummy */
/* Synchronize */
usecrc = 0;
done = sync_tx();
if ( done < 0 ) {
break;
}
if ( done == 'C' ) {
usecrc = 1;
}
/* Send data */
Mtrace("t[");
sno = 1;
xip->pktcnt = 0;
dataddr = xip->dataddr;
size = xip->size;
pktlen = xip->onek ? PKTLEN_1K : PKTLEN_128;
done = 0;
do {
r = sendPacket((uchar *)dataddr, pktlen, sno, usecrc);
if ( r < 0 ) {
done = r;
} else {
sno++;
xip->pktcnt++;
size -= pktlen;
dataddr += pktlen;
if ( size <= 0 ) {
done = 1;
}
}
} while ( !done );
Mtrace("]");
if (done < 0) {
break;
}
/* Send EOT, and wait for ACK */
count = RETR_MAX;
do {
Mtrace("E");
rputchar(EOT);
c = waitchar(FRAME_TMO);
Mtrace("<%02x>", c);
} while ( --count && c != ACK);
/* no matter if ACK was never received.
consider the deed done. */
} while (0);
if ( proto == XMODEM ) {
/* trash any final garbage from the transmiter */
waitclear();
}
return done;
}
/***************************************************************************/
/* Yup():
*
* Upload (uMon --> Host) a file using the YMODEM protocol
*
* Arguments:
* - yip - structure containing transfer info:
* usecrc x
* onek IN - use 1K blocks (frames) instead of 128bytes ones
* verify x
* baseaddr: IN - The first file to upload is stored here.
* flags x
* info x
* filecnt IN - Number of files to upload
* OUT - Number of files successfully uploaded
* fname[i] IN - Name of the i'th file to upload.
* size[i]: IN - size of the i'th file to upload in bytes.
* OUT - set to the TFS file-size if TFS support is included.
* pktcnt[i]: OUT - nr of frames transfered when uploading i'th file.
* errcnt: x
* firsterrat: x
*
* Returns:
* On success: something non-negative.
* On error: something negative.
* XERR_GEN : General error
* XERR_TOUT : Timeout
* XERR_CAN : Operation canceled
* XERR_RETR : Maximum retransmitions reached
*/
static int
Yup (struct yinfo *yip)
{
TFILE *tfp;
int r, rval, done, cfn;
ulong dataddr;
uchar *tmppkt;
rval = 0;
tmppkt = pktbuff;
dataddr = yip->baseaddr;
do { /* dummy */
/*
* send the files
*/
for (cfn = 0; cfn < yip->filecnt; cfn++) {
#if INCLUDE_TFS
/* read in the file from TFS */
if (! (tfp = tfsstat(yip->fname[cfn])) ) {
waitclear();
doCAN();
rval = XERR_NOFILE;
break;
}
memcpy((char *)(dataddr), TFS_BASE(tfp), tfp->filsize);
/* override given size */
yip->size[cfn] = tfp->filsize;
#endif
/* Synchronize with the receiver */
done = sync_tx();
if ( done < 0 ) {
rval = done;
break;
}
if ( done != 'C' ) {
waitclear();
doCAN();
rval = XERR_SYNC;
break;
}
/* Prepare and send header block */
Mtrace("h[");
memset(tmppkt, 0, PKTLEN_128);
sprintf(tmppkt, "%s", yip->fname[cfn]);
sprintf(tmppkt + strlen(tmppkt) + 1,
"%ld", yip->size[cfn]);
r = sendPacket(tmppkt, PKTLEN_128, 0, 1);
if ( r < 0 ) {
rval = r;
break;
}
/* prepare an xinfo structure */
xif.dataddr = dataddr;
xif.size = yip->size[cfn];
xif.onek = yip->onek;
/* send the file data */
rval = Xup(&xif, YMODEM);
if ( rval < 0 ) {
waitclear();
doCAN();
break;
}
#if INCLUDE_TFS
dataddr += yip->size[cfn];
#endif
} /* of files loop */
if ( rval < 0 )
break;
/*
* Send the footer
*/
/* synchronize with the receiver */
done = sync_tx();
if ( done < 0 ) {
rval = done;
break;
}
if ( done != 'C' ) {
waitclear();
doCAN();
rval = XERR_SYNC;
break;
}
/* Prepare and send the footer block */
Mtrace("f[");
memset(tmppkt, 0, PKTLEN_128);
r = sendPacket(tmppkt, PKTLEN_128, 0, 1);
if ( r < 0 ) {
rval = r;
break;
}
Mtrace("]");
} while (0);
yip->filecnt = cfn;
/* trash any final garbage from the transmiter */
waitclear();
return rval;
}
#endif /* of INCLUDE_XMODEM */
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -