Open-Source-Software-Entwicklung und Downloads

Browse Subversion Repository

Contents of /trunk/teraterm/ttpfile/xmodem.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3221 - (show annotations) (download) (as text)
Tue Mar 24 09:37:20 2009 UTC (15 years, 2 months ago) by maya
File MIME type: text/x-csrc
File size: 10777 byte(s)
CVS から SVN へ移行: trunk に集約
1 /* Tera Term
2 Copyright(C) 1994-1998 T. Teranishi
3 All rights reserved. */
4
5 /* TTFILE.DLL, XMODEM protocol */
6 #include "teraterm.h"
7 #include "tttypes.h"
8 #include "ttftypes.h"
9 #include <stdio.h>
10
11 #include "tt_res.h"
12 #include "ttcommon.h"
13 #include "ttlib.h"
14 #include "ftlib.h"
15 #include "dlglib.h"
16
17 #include "xmodem.h"
18
19 #define TimeOutInit 10
20 #define TimeOutC 3
21 #define TimeOutShort 10
22 #define TimeOutLong 20
23 #define TimeOutVeryLong 60
24
25 int XRead1Byte(PFileVar fv, PXVar xv, PComVar cv, LPBYTE b)
26 {
27 if (CommRead1Byte(cv,b) == 0)
28 return 0;
29
30 if (fv->LogFlag)
31 {
32 if (fv->LogState==0)
33 {
34 fv->LogState = 1;
35 fv->LogCount = 0;
36 _lwrite(fv->LogFile,"\015\012<<<\015\012",7);
37 }
38 FTLog1Byte(fv,*b);
39 }
40 return 1;
41 }
42
43 int XWrite(PFileVar fv, PXVar xv, PComVar cv, PCHAR B, int C)
44 {
45 int i, j;
46
47 i = CommBinaryOut(cv,B,C);
48 if (fv->LogFlag && (i>0))
49 {
50 if (fv->LogState != 0)
51 {
52 fv->LogState = 0;
53 fv->LogCount = 0;
54 _lwrite(fv->LogFile,"\015\012>>>\015\012",7);
55 }
56 for (j=0 ; j <= i-1 ; j++)
57 FTLog1Byte(fv,B[j]);
58 }
59 return i;
60 }
61
62 void XSetOpt(PFileVar fv, PXVar xv, WORD Opt)
63 {
64 char Tmp[21];
65
66 xv->XOpt = Opt;
67
68 strncpy_s(Tmp, sizeof(Tmp),"XMODEM (", _TRUNCATE);
69 switch (xv->XOpt) {
70 case XoptCheck: /* Checksum */
71 strncat_s(Tmp,sizeof(Tmp),"checksum)",_TRUNCATE);
72 xv->DataLen = 128;
73 xv->CheckLen = 1;
74 break;
75 case XoptCRC: /* CRC */
76 strncat_s(Tmp,sizeof(Tmp),"CRC)",_TRUNCATE);
77 xv->DataLen = 128;
78 xv->CheckLen = 2;
79 break;
80 case Xopt1K: /* 1K */
81 strncat_s(Tmp,sizeof(Tmp),"1K)",_TRUNCATE);
82 xv->DataLen = 1024;
83 xv->CheckLen = 2;
84 break;
85 }
86 SetDlgItemText(fv->HWin, IDC_PROTOPROT, Tmp);
87 }
88
89 void XSendNAK(PFileVar fv, PXVar xv, PComVar cv)
90 {
91 BYTE b;
92 int t;
93
94 /* flush comm buffer */
95 cv->InBuffCount = 0;
96 cv->InPtr = 0;
97
98 xv->NAKCount--;
99 if (xv->NAKCount<0)
100 {
101 if (xv->NAKMode==XnakC)
102 {
103 XSetOpt(fv,xv,XoptCheck);
104 xv->NAKMode = XnakNAK;
105 xv->NAKCount = 9;
106 }
107 else {
108 XCancel(fv,xv,cv);
109 return;
110 }
111 }
112
113 if (xv->NAKMode==XnakNAK)
114 {
115 b = NAK;
116 if ((xv->PktNum==0) && (xv->PktNumOffset==0))
117 t = TimeOutInit;
118 else
119 t = xv->TOutLong;
120 }
121 else {
122 b = 'C';
123 t = TimeOutC;
124 }
125 XWrite(fv,xv,cv,&b,1);
126 xv->PktReadMode = XpktSOH;
127 FTSetTimeOut(fv,t);
128 }
129
130 WORD XCalcCheck(PXVar xv, PCHAR PktBuf)
131 {
132 int i;
133 WORD Check;
134
135 if (xv->CheckLen==1) /* CheckSum */
136 {
137 /* Calc sum */
138 Check = 0;
139 for (i = 0 ; i <= xv->DataLen-1 ; i++)
140 Check = Check + (BYTE)(PktBuf[3+i]);
141 return (Check & 0xff);
142 }
143 else { /* CRC */
144 Check = 0;
145 for (i = 0 ; i <= xv->DataLen-1 ; i++)
146 Check = UpdateCRC(PktBuf[3+i],Check);
147 return (Check);
148 }
149 }
150
151 BOOL XCheckPacket(PXVar xv)
152 {
153 WORD Check;
154
155 Check = XCalcCheck(xv,xv->PktIn);
156 if (xv->CheckLen==1) /* Checksum */
157 return ((BYTE)Check==xv->PktIn[xv->DataLen+3]);
158 else
159 return ((HIBYTE(Check)==xv->PktIn[xv->DataLen+3]) &&
160 (LOBYTE(Check)==xv->PktIn[xv->DataLen+4]));
161 }
162
163 void XInit
164 (PFileVar fv, PXVar xv, PComVar cv, PTTSet ts)
165 {
166 char inistr[MAXPATHLEN + 10];
167
168 fv->LogFlag = ((ts->LogFlag & LOG_X)!=0);
169 if (fv->LogFlag)
170 fv->LogFile = _lcreat("XMODEM.LOG",0);
171 fv->LogState = 0;
172 fv->LogCount = 0;
173
174 fv->FileSize = 0;
175 if ((xv->XMode==IdXSend) && fv->FileOpen) {
176 fv->FileSize = GetFSize(fv->FullName);
177 InitDlgProgress(fv->HWin, IDC_PROTOPROGRESS, &fv->ProgStat);
178 }
179 else {
180 fv->ProgStat = -1;
181 }
182
183 SetWindowText(fv->HWin, fv->DlgCaption);
184 SetDlgItemText(fv->HWin, IDC_PROTOFNAME, &(fv->FullName[fv->DirLen]));
185
186 xv->PktNumOffset = 0;
187 xv->PktNum = 0;
188 xv->PktNumSent = 0;
189 xv->PktBufCount = 0;
190 xv->CRRecv = FALSE;
191
192 fv->ByteCount = 0;
193
194 if (cv->PortType==IdTCPIP)
195 {
196 xv->TOutShort = TimeOutVeryLong;
197 xv->TOutLong = TimeOutVeryLong;
198 }
199 else {
200 xv->TOutShort = TimeOutShort;
201 xv->TOutLong = TimeOutLong;
202 }
203
204 XSetOpt(fv,xv,xv->XOpt);
205
206 if (xv->XOpt==XoptCheck)
207 {
208 xv->NAKMode = XnakNAK;
209 xv->NAKCount = 10;
210 }
211 else {
212 xv->NAKMode = XnakC;
213 xv->NAKCount = 3;
214 }
215
216 switch (xv->XMode) {
217 case IdXSend:
218 xv->TextFlag = 0;
219
220 // �t�@�C�����M�J�n�O���A"rx �t�@�C����"�������I�������o���B(2007.12.20 yutaka)
221 if (ts->XModemRcvCommand[0] != '\0') {
222 _snprintf_s(inistr, sizeof(inistr), _TRUNCATE, "%s %s\015",
223 ts->XModemRcvCommand,
224 &(fv->FullName[fv->DirLen]));
225 FTConvFName(inistr + strlen(ts->XModemRcvCommand) + 1);
226 XWrite(fv,xv,cv, inistr , strlen(inistr));
227 }
228
229 FTSetTimeOut(fv,TimeOutVeryLong);
230 break;
231 case IdXReceive:
232 XSendNAK(fv,xv,cv);
233 break;
234 }
235 }
236
237 void XCancel(PFileVar fv, PXVar xv, PComVar cv)
238 {
239 BYTE b;
240
241 b = CAN;
242 XWrite(fv,xv,cv,&b,1);
243 xv->XMode = 0; // quit
244 }
245
246 void XTimeOutProc(PFileVar fv, PXVar xv, PComVar cv)
247 {
248 switch (xv->XMode) {
249 case IdXSend:
250 xv->XMode = 0; // quit
251 break;
252 case IdXReceive:
253 XSendNAK(fv,xv,cv);
254 break;
255 }
256 }
257
258 BOOL XReadPacket(PFileVar fv, PXVar xv, PComVar cv)
259 {
260 BYTE b, d;
261 int i, c;
262 BOOL GetPkt;
263
264 c = XRead1Byte(fv,xv,cv,&b);
265
266 GetPkt = FALSE;
267
268 while ((c>0) && (! GetPkt))
269 {
270 switch (xv->PktReadMode) {
271 case XpktSOH:
272 if (b==SOH)
273 {
274 xv->PktIn[0] = b;
275 xv->PktReadMode = XpktBLK;
276 if (xv->XOpt==Xopt1K)
277 XSetOpt(fv,xv,XoptCRC);
278 FTSetTimeOut(fv,xv->TOutShort);
279 }
280 else if (b==STX)
281 {
282 xv->PktIn[0] = b;
283 xv->PktReadMode = XpktBLK;
284 XSetOpt(fv,xv,Xopt1K);
285 FTSetTimeOut(fv,xv->TOutShort);
286 }
287 else if (b==EOT)
288 {
289 b = ACK;
290 fv->Success = TRUE;
291 XWrite(fv,xv,cv,&b, 1);
292 return FALSE;
293 }
294 else {
295 /* flush comm buffer */
296 cv->InBuffCount = 0;
297 cv->InPtr = 0;
298 return TRUE;
299 }
300 break;
301 case XpktBLK:
302 xv->PktIn[1] = b;
303 xv->PktReadMode = XpktBLK2;
304 FTSetTimeOut(fv,xv->TOutShort);
305 break;
306 case XpktBLK2:
307 xv->PktIn[2] = b;
308 if ((b ^ xv->PktIn[1]) == 0xff)
309 {
310 xv->PktBufPtr = 3;
311 xv->PktBufCount = xv->DataLen + xv->CheckLen;
312 xv->PktReadMode = XpktDATA;
313 FTSetTimeOut(fv,xv->TOutShort);
314 }
315 else
316 XSendNAK(fv,xv,cv);
317 break;
318 case XpktDATA:
319 xv->PktIn[xv->PktBufPtr] = b;
320 xv->PktBufPtr++;
321 xv->PktBufCount--;
322 GetPkt = xv->PktBufCount==0;
323 if (GetPkt)
324 {
325 FTSetTimeOut(fv,xv->TOutLong);
326 xv->PktReadMode = XpktSOH;
327 }
328 else
329 FTSetTimeOut(fv,xv->TOutShort);
330 break;
331 }
332
333 if (! GetPkt) c = XRead1Byte(fv,xv,cv,&b);
334 }
335
336 if (! GetPkt) return TRUE;
337
338 if ((xv->PktIn[1]==0) && (xv->PktNum==0) &&
339 (xv->PktNumOffset==0))
340 {
341 if (xv->NAKMode==XnakNAK)
342 xv->NAKCount = 10;
343 else
344 xv->NAKCount = 3;
345 XSendNAK(fv,xv,cv);
346 return TRUE;
347 }
348
349 GetPkt = XCheckPacket(xv);
350 if (! GetPkt)
351 {
352 XSendNAK(fv,xv,cv);
353 return TRUE;
354 }
355
356 d = xv->PktIn[1] - xv->PktNum;
357 if (d>1)
358 {
359 XCancel(fv,xv,cv);
360 return FALSE;
361 }
362
363 /* send ACK */
364 b = ACK;
365 XWrite(fv,xv,cv,&b, 1);
366 xv->NAKMode = XnakNAK;
367 xv->NAKCount = 10;
368
369 if (d==0) return TRUE;
370 xv->PktNum = xv->PktIn[1];
371 if (xv->PktNum==0)
372 xv->PktNumOffset = xv->PktNumOffset + 256;
373
374 c = xv->DataLen;
375 if (xv->TextFlag>0)
376 while ((c>0) && (xv->PktIn[2+c]==0x1A))
377 c--;
378
379 if (xv->TextFlag>0)
380 for (i = 0 ; i <= c-1 ; i++)
381 {
382 b = xv->PktIn[3+i];
383 if ((b==LF) && (! xv->CRRecv))
384 _lwrite(fv->FileHandle,"\015",1);
385 if (xv->CRRecv && (b!=LF))
386 _lwrite(fv->FileHandle,"\012",1);
387 xv->CRRecv = b==CR;
388 _lwrite(fv->FileHandle,&b,1);
389 }
390 else
391 _lwrite(fv->FileHandle, &(xv->PktIn[3]), c);
392
393 fv->ByteCount = fv->ByteCount + c;
394
395 SetDlgNum(fv->HWin, IDC_PROTOPKTNUM, xv->PktNumOffset+xv->PktNum);
396 SetDlgNum(fv->HWin, IDC_PROTOBYTECOUNT, fv->ByteCount);
397
398 FTSetTimeOut(fv,xv->TOutLong);
399
400 return TRUE;
401 }
402
403 BOOL XSendPacket(PFileVar fv, PXVar xv, PComVar cv)
404 {
405 BYTE b;
406 int i;
407 BOOL SendFlag;
408 WORD Check;
409
410 SendFlag = FALSE;
411 if (xv->PktBufCount==0)
412 {
413 i = XRead1Byte(fv,xv,cv,&b);
414 do {
415 if (i==0) return TRUE;
416 switch (b) {
417 case ACK:
418 if (! fv->FileOpen)
419 {
420 fv->Success = TRUE;
421 return FALSE;
422 }
423 else if (xv->PktNumSent==(BYTE)(xv->PktNum+1))
424 {
425 xv->PktNum = xv->PktNumSent;
426 if (xv->PktNum==0)
427 xv->PktNumOffset = xv->PktNumOffset + 256;
428 SendFlag = TRUE;
429 }
430 break;
431 case NAK:
432 if (xv->PktNum == 0 && xv->XOpt == Xopt1K)
433 {
434 /* we wanted 1k with CRC, but the other end specified checksum */
435 /* keep the 1k block, but move back to checksum mode. */
436 xv->XOpt = XoptCheck;
437 xv->CheckLen = 1;
438 }
439 SendFlag = TRUE;
440 break;
441 case CAN:
442 break;
443 case 0x43:
444 if ((xv->PktNum==0) && (xv->PktNumOffset==0))
445 {
446 if ((xv->XOpt==XoptCheck) &&
447 (xv->PktNumSent==0)) XSetOpt(fv,xv,XoptCRC);
448 if (xv->XOpt!=XoptCheck) SendFlag = TRUE;
449 }
450 break;
451 }
452 if (! SendFlag) i = XRead1Byte(fv,xv,cv,&b);
453 } while (!SendFlag);
454 // reset timeout timer
455 FTSetTimeOut(fv,TimeOutVeryLong);
456
457 do {
458 i = XRead1Byte(fv,xv,cv,&b);
459 } while (i!=0);
460
461 if (xv->PktNumSent==xv->PktNum) /* make a new packet */
462 {
463 xv->PktNumSent++;
464 if (xv->DataLen==128)
465 xv->PktOut[0] = SOH;
466 else
467 xv->PktOut[0] = STX;
468 xv->PktOut[1] = xv->PktNumSent;
469 xv->PktOut[2] = ~ xv->PktNumSent;
470
471 i = 1;
472 while ((i<=xv->DataLen) && fv->FileOpen &&
473 (_lread(fv->FileHandle,&b,1)==1))
474 {
475 xv->PktOut[2+i] = b;
476 i++;
477 fv->ByteCount++;
478 }
479
480 if (i>1)
481 {
482 while (i<=xv->DataLen)
483 {
484 xv->PktOut[2+i] = 0x1A;
485 i++;
486 }
487
488 Check = XCalcCheck(xv,xv->PktOut);
489 if (xv->CheckLen==1) /* Checksum */
490 xv->PktOut[xv->DataLen+3] = (BYTE)Check;
491 else {
492 xv->PktOut[xv->DataLen+3] = HIBYTE(Check);
493 xv->PktOut[xv->DataLen+4] = LOBYTE(Check);
494 }
495 xv->PktBufCount = 3 + xv->DataLen + xv->CheckLen;
496 }
497 else { /* send EOT */
498 if (fv->FileOpen)
499 {
500 _lclose(fv->FileHandle);
501 fv->FileHandle = 0;
502 fv->FileOpen = FALSE;
503 }
504 xv->PktOut[0] = EOT;
505 xv->PktBufCount = 1;
506 }
507 }
508 else { /* resend packet */
509 xv->PktBufCount = 3 + xv->DataLen + xv->CheckLen;
510 }
511 xv->PktBufPtr = 0;
512 }
513 /* a NAK or C could have arrived while we were buffering. Consume it. */
514 do {
515 i = XRead1Byte(fv,xv,cv,&b);
516 } while (i!=0);
517
518 i = 1;
519 while ((xv->PktBufCount>0) && (i>0))
520 {
521 b = xv->PktOut[xv->PktBufPtr];
522 i = XWrite(fv,xv,cv,&b, 1);
523 if (i>0)
524 {
525 xv->PktBufCount--;
526 xv->PktBufPtr++;
527 }
528 }
529
530 if (xv->PktBufCount==0)
531 {
532 SetDlgNum(fv->HWin, IDC_PROTOPKTNUM,
533 xv->PktNumOffset+xv->PktNumSent);
534 SetDlgNum(fv->HWin, IDC_PROTOBYTECOUNT, fv->ByteCount);
535 SetDlgPercent(fv->HWin, IDC_PROTOPERCENT, IDC_PROTOPROGRESS,
536 fv->ByteCount, fv->FileSize, &fv->ProgStat);
537 }
538
539 return TRUE;
540 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26