⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ian_xmodem.c

📁 完整的Bell实验室的嵌入式文件系统TFS
💻 C
📖 第 1 页 / 共 4 页
字号:
            }            if ( r != sno ) {                /* block sequence number is not quite right,                    but it might still do */                if ( (lsno == 0) || ( sno - r != 1 && r - sno != 0xff ) ) {                    /* shit! desperately out of sync.                        CAN the whole thing */                    Mtrace("S<%02x != %02x>", r, sno);                    doCAN();                    done = XERR_SYNC;                } else {                    /* no worries, it's just a retransmission */                    Mtrace("S");                    rputchar(ACK);                    if (lsno == 1) {                        Mtrace("0");                        rputchar(nak);                    }                }            } else {                /* seq. number just fine */                Mtrace("s");                if ( lsno == 0 ) {                    Mtrace("0");                    rputchar(ACK);                }                done = 1;            }            break;        case CAN:            Mtrace("C");            /* wait for a second CAN */            c = (char)waitchar(CHAR_TMO);            if (c != CAN) {                Mtrace("<%02x>", c);                waitclear();                rputchar(nak);            } else {                Mtrace("C");                done = XERR_CAN;            }            break;        case ESC:            /* User-invoked abort */            Mtrace("X");            /* wait for a second ESC */            c = (char)waitchar(CHAR_TMO);            if (c != ESC) {                waitclear();                rputchar(nak);                done = 0;            } else {                done = XERR_UCAN;            }            break;        case EOT:            Mtrace("E");            /* first make sure that this is really an EOT,               and not a corrupted start-frame; use the fact that               self-respecting EOTs always come alone, not followed                by other characters. */             c = waitchar(CHAR_TMO);            if ( c >= 0 ) {                /* probably not an EOT, request retransmission */                Mtrace("<%02x>", c);                waitclear();                rputchar(nak);                break;            }            /* ok it is probably a true EOT, send an ACK */            rputchar(ACK);            Mtrace("a", c);            if (lsno != 0) {                done = 2;            }            break;        default:            /* request retransmission */            Mtrace("?<%02x>",c);            waitclear();            rputchar(nak);            break;        }    } while (!done);    if (done == 1) {        rval = 0;    } else if (done == 2) {        rval = 1;    } else {        rval = done;    }    return rval;}/***************************************************************************//* Xdown(): * * Download, or verify a file using the XMODEM protocol * * Arguments: *   - xip - structure containing transfer info: *    usecrc       IN  - use 16bit-CRC instead of 8bit-checksum. *    verify       IN  - operate in verification mode. *    dataddr:     IN  - downloaded file will be stored starting from here. *                       in verification mode, downloaded file will be  *                       compared with data starting from here. *    size:        OUT - size of received file in bytes.  *    pktcnt:      OUT - number of frames transfered. *    errcnt:      OUT - number of errors, if mode is verification. *    firsterrat:  OUT - address of first error, if mode is verification. *  - proto - protocol type (y-modem or x-modem); Used to make very small  *  adjustment to the operation of the function.  * * Returns: *    On success: something non-negative. *    On error: something negative. *      XERR_GEN : General error *      XERR_TOUT : Timeout *      XERR_SYNC : Lost synchronization *      XERR_CAN : Operation canceled *      XERR_UCAN : Operation canceled by user */static intXdown(struct xinfo *xip, int proto){    int i, r;    ulong sno;    int psize;    char *tmppkt, *dataddr;    Mtrace("--XD--");    dataddr = (char *)(xip->dataddr);    if ( xip->verify ) {        tmppkt = pktbuff;    } else {        tmppkt = (char *)(xip->dataddr);    }    sno = 1;    xip->pktcnt = 0;    xip->errcnt = 0;    xip->firsterrat = 0;    xip->size = 0;    do {        r = waitPacket(tmppkt, &psize, sno, xip->usecrc);        if ( r == 0 ) {            sno++;            xip->pktcnt++;            xip->size += psize;            if ( xip->verify ) {                for (i = 0; i < psize; i++, dataddr++) {                    if (tmppkt[i] != *dataddr) {                        if (xip->errcnt++ == 0)                            xip->firsterrat = (ulong)dataddr;                    }                }            } else {                tmppkt += psize;            }        }    } while ( ! r );    if ( r == 1 && proto == XMODEM ) {        /* send a couple more ACKs to make sure that at least            one reaches its destination */        rputchar(ACK); rputchar(ACK); rputchar(ACK);        rputchar(ACK); rputchar(ACK); rputchar(ACK);        /* send backspaces in-case ACKs have reached the user's           terminal */        rputchar(BS); rputchar(BS); rputchar(BS);        rputchar(BS); rputchar(BS); rputchar(BS);    }    if (proto == XMODEM) {        /* trash any final garbage send by the transmiter */        waitclear();    }    return r;}/***************************************************************************//* Ydown(): * * Download (uMon <-- Host) a file using the YMODEM protocol * * Arguments: *   - yip - structure containing transfer info: *    usecrc       IN  - use 16bit CRC instead of 8bit checksum. *    onek         x *    verify       IN  - verify the downloaded file against stored data.     *    baseaddr:    IN  - download the first file here. *    flags        IN  - TFS flags to use when writing to TFS.  *    info         IN  - TFS info to use when writing to TFS. *    filecnt      OUT - Number of files successfully downloaded. *    fname[i]     OUT - Name of the i'th file downloaded. *    size[i]:     OUT - size of the i'th file downloaded in bytes. *    pktcnt[i]:   OUT - nr of frames transfered when downloading i'th file. *    errcnt[i]:   OUT - number of errors detected when verifying i'th file. *    firsterrat[i]: OUT - address of the first error of the i'th file. * * Returns: *    On success: something non-negative. *    On error: something negative. *      XERR_GEN : General error *      XERR_TOUT : Timeout *      XERR_NOFILE : File not found (verification mode) *      XERR_TFS : TFS error *      XERR_SYNC : Synchronization error *      XERR_CAN : Operation canceled *      XERR_UCAN : Operation canceled by user */static intYdown(struct yinfo *yip){    TFILE *tfp;    int rval, r, psize;    char *tmppkt;    ulong dataddr;    char *fname, *basename, *s1, *fsize;    rval = 0;    yip->filecnt = 0;    tmppkt = pktbuff;    dataddr = yip->baseaddr;    do {        yip->dataddr[yip->filecnt] = dataddr;        yip->size[yip->filecnt] = 0;        yip->pktcnt[yip->filecnt] = 0;        yip->errcnt[yip->filecnt] = 0;        yip->firsterrat[yip->filecnt] = 0;        /*          * receive and parse the header-block          */        r = waitPacket(tmppkt, &psize, 0, 1);        if ( r < 0 ) {            rval = r;            break;        }        /* first comes the file-name */        fname = (char *)(tmppkt);        /* buggy ymodems delimit fields with SP instead of NULL.           Cope. */        s1 = strchr(fname,' ');        if (s1) *s1 = '\0';        /* if file-name contains path, cut it off and just keep           the stem */        basename = strrchr(fname,'/');        if (! basename) basename = fname;        /* after the file-name comes the file-size */        fsize = basename + strlen(basename) + 1;        /* buggy ymodems delimit fields with SP instead of NULL.           cope. */        s1 = strchr(fsize,' ');        if (s1) *s1 = '\0';                /* copy info to xip fields */        yip->size[yip->filecnt] = atoi(fsize);        strcpy(yip->fname[yip->filecnt], basename);        Mtrace("<f=%s>",yip->fname[yip->filecnt]);        Mtrace("<z=%d>",yip->size[yip->filecnt]);        Mtrace("]");        if ( ! yip->fname[yip->filecnt][0] )            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.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -