📄 ian_xmodem.c
字号:
* - 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 + -