📄 ian_xmodem.c
字号:
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 voidputPacket (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 intsendPacket (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 intsync_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 intXup (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 intYup (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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -