int wctx(long flen) { int thisblklen; int sectnum, attempts, firstch; long charssent; //DSERIAL.println("\nwctx"); charssent = 0; firstsec=TRUE; thisblklen = blklen; vfile(F("wctx:file length=%ld"), flen); while ((firstch=readline(Rxtimeout))!=NAK && firstch != WANTCRC && firstch != WANTG && firstch!=TIMEOUT && firstch!=CAN) ; if (firstch==CAN) { zperr("Receiver CANcelled"); return ERROR; } if (firstch==WANTCRC) Crcflg=TRUE; if (firstch==WANTG) Crcflg=TRUE; sectnum=0; for (;;) { if (flen <= (charssent + 896L)) thisblklen = 128; if ( !filbuf(txbuf, thisblklen)) break; if (wcputsec(txbuf, ++sectnum, thisblklen)==ERROR) return ERROR; charssent += thisblklen; } //fclose(in); fout.close(); attempts=0; do { purgeline(); sendline(EOT); //fflush(stdout); ++attempts; } while ((firstch=(readline(Rxtimeout)) != ACK) && attempts < Tx_RETRYMAX); if (attempts == Tx_RETRYMAX) { zperr("No ACK on EOT"); return ERROR; } else return OK; }
static int wcrx(void) { int sectnum, sectcurr; char sendchar; int cblklen; /* bytes to dump this block */ Firstsec = TRUE; sectnum = 0; Eofseen = FALSE; sendchar = Crcflg ? WANTCRC : NAK; for (;;) { xsendline(sendchar); /* send it now, we're ready! */ Lleft = 0; /* Do read next time ... */ sectcurr = wcgetsec(secbuf, (sectnum & 0177) ? 50 : 130); report(sectcurr); if (sectcurr == ((sectnum + 1) & 0377)) { sectnum++; cblklen = Bytesleft > Blklen ? Blklen : Bytesleft; if (putsec(secbuf, cblklen) == ERROR) return ERROR; if ((Bytesleft -= cblklen) < 0) Bytesleft = 0; sendchar = ACK; } else if (sectcurr == (sectnum & 0377)) { zperr("Received dup Sector"); sendchar = ACK; } else if (sectcurr == WCEOT) { if (closeit()) return ERROR; xsendline(ACK); Lleft = 0; /* Do read next time ... */ return OK; } else if (sectcurr == ERROR) return ERROR; else { zperr("Sync Error"); return ERROR; } } }
/* * Fetch a pathname from the other end as a C ctyle ASCIZ string. * Length is indeterminate as long as less than Blklen * A null string represents no more files (YMODEM) */ static int wcrxpn(char *rpn) { int c; readline(1); et_tu: Firstsec = TRUE; Eofseen = FALSE; xsendline(Crcflg ? WANTCRC : NAK); Lleft = 0; /* Do read next time ... */ while ((c = wcgetsec(rpn, 100)) != 0) { if (c == WCEOT) { zperr("Pathname fetch returned %d", c); xsendline(ACK); Lleft = 0; /* Do read next time ... */ readline(1); goto et_tu; } return ERROR; } xsendline(ACK); return OK; }
static int wcgetsec(char *rxbuf, int maxtime) { int checksum, wcj, firstch; unsigned short oldcrc; char *p; int sectcurr; for (Lastrx = errors = 0; errors < RETRYMAX; errors++) { if ((firstch = readline(maxtime)) == STX) { Blklen = 1024; goto get2; } if (firstch == SOH) { Blklen = 128; get2: sectcurr = readline(1); if ((sectcurr + (oldcrc = readline(1))) == 0377) { oldcrc = checksum = 0; for (p = rxbuf, wcj = Blklen; --wcj >= 0;) { if ((firstch = readline(1)) < 0) goto bilge; oldcrc = updcrc(firstch, oldcrc); checksum += (*p++ = firstch); } if ((firstch = readline(1)) < 0) goto bilge; if (Crcflg) { oldcrc = updcrc(firstch, oldcrc); if ((firstch = readline(1)) < 0) goto bilge; oldcrc = updcrc(firstch, oldcrc); if (oldcrc & 0xFFFF) zperr("CRC"); else { Firstsec = FALSE; return sectcurr; } } else if (((checksum - firstch) & 0377) == 0) { Firstsec = FALSE; return sectcurr; } else zperr("Checksum"); } else zperr("Sector number garbled"); } /* make sure eot really is eot and not just mixmash */ else if (firstch == EOT && readline(1) == TIMEOUT) return WCEOT; else if (firstch == CAN) { if (Lastrx == CAN) { zperr("Sender CANcelled"); return ERROR; } else { Lastrx = CAN; continue; } } else if (firstch == TIMEOUT) { if (Firstsec) goto humbug; bilge: zperr("TIMEOUT"); } else zperr("Got 0%o sector header", firstch); humbug: Lastrx = 0; while (readline(1) != TIMEOUT); if (Firstsec) { xsendline(Crcflg ? WANTCRC : NAK); Lleft = 0; /* Do read next time ... */ } else { maxtime = 40; xsendline(NAK); Lleft = 0; /* Do read next time ... */ } } /* try to stop the bubble machine. */ canit(); return ERROR; }
int wcputsec(char *buf,int sectnum,int cseclen) { int checksum, wcj; char *cp; unsigned oldcrc; int firstch; uint8_t attempts; firstch=0; /* part of logic to detect CAN CAN */ if (Verbose>2) fprintf(stderr, "Sector %3d %2dk\n", Totsecs, Totsecs/8 ); else if (Verbose>1) fprintf(stderr, "\rSector %3d %2dk ", Totsecs, Totsecs/8 ); for (attempts=0; attempts <= Tx_RETRYMAX; attempts++) { Lastrx= firstch; sendline(cseclen==1024?STX:SOH); sendline(sectnum); sendline(-sectnum -1); oldcrc=checksum=0; for (wcj=cseclen,cp=buf; --wcj>=0; ) { sendline(*cp); oldcrc=updcrc((0377& *cp), oldcrc); checksum += *cp++; } if (Crcflg) { oldcrc=updcrc(0,updcrc(0,oldcrc)); sendline((int)oldcrc>>8); sendline((int)oldcrc); } else sendline(checksum); if (Optiong) { firstsec = FALSE; return OK; } firstch = readline(Rxtimeout); gotnak: switch (firstch) { case CAN: if(Lastrx == CAN) { cancan: zperr("Cancelled"); return ERROR; } break; case TIMEOUT: zperr("Timeout on sector ACK"); continue; case WANTCRC: if (firstsec) Crcflg = TRUE; case NAK: zperr("NAK on sector"); continue; case ACK: firstsec=FALSE; Totsecs += (cseclen>>7); return OK; case ERROR: zperr("Got burst for sector ACK"); break; default: zperr("Got %02x for sector ACK", firstch); break; } for (;;) { Lastrx = firstch; if ((firstch = readline(Rxtimeout)) == TIMEOUT) break; if (firstch == NAK || firstch == WANTCRC) goto gotnak; if (firstch == CAN && Lastrx == CAN) goto cancan; } }