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