1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 #include <ws_error.h>
51
52
53 #define TIME_OUT 1
54 #define DISCONNECT_OUT 2
55
56
57 #define False 0
58 #define True 1
59
60
61 #define NULL 0
62 #define CR 13
63 #define ESC 27
64 #define LF 10
65 #define SI 15
66 #define SO 14
67 #define SOH 1
68 #define MIN_ASCII 32
69 #define REV_VIDEO 0200
70 #define Null_Convert 20
71 #define MASK_ALL 0377
72 #define MASK_SIX 077
73
74
75 #define ChnCnt 2
76 #define SeqFld 2
77 #define SeqCnt 4
78 #define SeqMsk 3
79
80
81 #define SOPLen 1
82 #define TypLen 1
83 #define MaxDatLen 124
84 #define ChkLen 1
85 #define EOPLen 1
86 #define LenLen 1
87 #define MinPktLen (SOPLen+TypLen+LenLen+ChkLen+EOPLen)
88 #define MaxPktLen (MinPktLen+MaxDatLen)
89
90
91 #define BG 0
92 #define FG 1
93 #define RstOff ' '
94 #define Request 0
95 #define Confirm 1
96 #define RstCnt (Confirm+1)
97 #define BrkOff (RstOff+RstCnt)
98 #define BrkCnt (ChnCnt*(Confirm+1))
99 #define DisCon (BrkOff+(2*BG))
100 #define FGBrk (BrkOff+(2*FG))
101 #define DatOff (BrkOff+BrkCnt)
102 #define DatCnt (ChnCnt*SeqCnt*SeqCnt)
103 #define AckOff (38+DatCnt)
104 #define AckCnt (ChnCnt*SeqCnt)
105 #define NakOff (AckOff+AckCnt)
106 #define NakCnt (ChnCnt*SeqCnt)
107 #define FastDis (NakOff+NakCnt)
108
109
110 #define Debug True
111 #define RQS 2
112 #define RWS 3
113 #define SWS 3
114 #define LimRTmr 7
115 #define LimSTmr 15
116 #define LimPTmr 30
117 #define InitDis 1
118 #define RespDis 2
119 #define InitRst 1
120 #define RespRst 2
121 #define REVPOLY 051
122 #define INIT_CRC 63
123 #define Reset_Timer_X 0
124 #define Dis_Timer_X 1
125 #define Break_Timer_X 2
126
127
128 #if Debug
129 int dbgpkts = False;
130 int dbgrejs = False;
131 int dbgxchr = False;
132 #endif
133
134
135 int apv_locked = False;
136 int ds_pending = 0;
137 int ds_timeout = 0;
138 int rs_pending = 0;
139 int br_pending = 0;
140 int pending_timer[3] = {0,0,0};
141
142
143 char r_EOP = LF;
144 char r_ESC[3] = {ESC, SI, SO};
145 int r_ESC_count = 0;
146 char r_SOP = SOH;
147 int r_asn[ChnCnt] = {0, 0};
148 char r_esckey = '\000';
149 int r_ignoring[ChnCnt] = {False, False};
150 int r_pktin = 0;
151 int r_pktout = 0;
152 int r_psn[ChnCnt] = {0, 0};
153 int r_timer[ChnCnt] = {0, 0};
154 char r_dat[ChnCnt][SeqCnt][1+MaxDatLen];
155 char r_pkt[RQS+1][1+MaxPktLen];
156
157
158 char s_EOP = LF;
159 char s_ESC[3] = {ESC, SI, SO};
160 char s_SOP = SOH;
161 int s_lasn[ChnCnt] = {0, 0};
162 int s_nasn[ChnCnt] = {0, 0};
163 int s_psn[ChnCnt] = {0, 0};
164 int s_timer[ChnCnt] = {0, 0};
165 char s_escreq[256] = {0,1,0,0,0,0,0,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,1,
166 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
167 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
168 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
169 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,
170 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
171 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
172 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
173 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
174 1,1,1,1};
175 char s_dat[ChnCnt][SeqCnt][1+MaxDatLen];
176
177
178 extern int packet_mode;
179 extern int packetize_flag;
180 int mowse_terminating = 0;
181
182
183
184
185
186
187
188
189
190 advtmr()
191 {
192 int chn;
193 int i;
194 char type;
195
196
197
198
199 for (chn = 0; chn < ChnCnt; chn++)
200 { r_timer[chn]++;
201 if (r_timer[chn] > LimRTmr)
202 { r_timer[chn] = 0;
203 if (s_nasn[chn] != s_lasn[chn])
204 sndack(chn);
205 }
206
207
208
209 s_timer[chn]++;
210 if (s_timer[chn] > LimSTmr)
211 { s_timer[chn] = 0;
212 resend(chn);
213 }
214 }
215
216
217
218 for (i = 0; i < 3; pending_timer[i++]++);
219
220
221
222 if ((rs_pending & InitRst) && (pending_timer[Reset_Timer_X] > LimPTmr))
223 { pending_timer[Reset_Timer_X] = 0;
224 type = RstOff + Request;
225 sndpkt(type,"");
226 }
227 if ((rs_pending & RespRst) && (pending_timer[Reset_Timer_X] > LimPTmr))
228 { pending_timer[Reset_Timer_X] = 0;
229 type = RstOff + Confirm;
230 sndpkt(type,"");
231 }
232
233
234
235
236 if ((ds_pending & InitDis) && (pending_timer[Dis_Timer_X] > LimPTmr))
237 { ds_pending &= ~InitDis;
238 ds_timeout = TIME_OUT;
239 }
240
241 if ((ds_pending & RespDis) && (pending_timer[Dis_Timer_X] > LimPTmr))
242 { pending_timer[Dis_Timer_X] = 0;
243 type = DisCon + Confirm;
244 sndpkt(type,"");
245 }
246
247
248
249 if ((br_pending) && (pending_timer[Break_Timer_X] > LimPTmr))
250 { pending_timer[Break_Timer_X] = 0;
251 type = FGBrk + Request;
252 sndpkt(type,"");
253 }
254 }
255
256
257
258
259
260
261
262
263
264 apvpkt (pkt)
265
266 char pkt[];
267 {
268 int chkidx;
269 int lenidx;
270 int pktl;
271 int type;
272 int i;
273
274
275
276
277 pktl = pkt[0] & MASK_ALL;
278 if (pktl < MinPktLen || pktl > MaxPktLen)
279 {
280 #if Debug
281 if (dbgrejs)
282 { if (dbgpkts)
283 sdbgpkt("RcvPkt/", &pkt[1], pktl);
284 sdbgmsg("RejPkt/length");
285 }
286 #endif
287 return;
288 }
289
290
291
292 lenidx = pktl - EOPLen - ChkLen - LenLen + 1;
293 if (check_len (pktl + r_ESC_count) != pkt[lenidx])
294 {
295 #if Debug
296 if (dbgrejs)
297 { if (!dbgpkts)
298 sdbgpkt("RcvPkt/", &pkt[1], pktl);
299 sdbgmsg("RejPkt/chklen");
300 }
301 #endif
302 return;
303 }
304
305
306
307 chkidx = lenidx + LenLen;
308 if (chkcrc(&pkt[1], chkidx-1) != pkt[chkidx])
309 {
310 #if Debug
311 if (dbgrejs)
312 { if (!dbgpkts)
313 sdbgpkt("RcvPkt/", &pkt[1], pktl);
314 sdbgmsg("RejPkt/chksum");
315 }
316 #endif
317 return;
318 }
319
320
321
322 type = pkt[SOPLen + 1];
323 if ((DatOff <= type && type < DatOff+DatCnt) && !rs_pending)
324 prsdat(pkt);
325 else if ((AckOff <= type && type < AckOff+AckCnt) && !rs_pending)
326 prsack(pkt);
327 else if ((NakOff <= type && type < NakOff+NakCnt) && !rs_pending)
328 prsnak(pkt);
329 else if ((BrkOff <= type && type < BrkOff+BrkCnt) && !rs_pending)
330 prsbrk(pkt);
331 else if (RstOff <= type && type < RstOff+RstCnt)
332 prsrst(pkt);
333 else if (FastDis == type)
334 disconnect_confirm (True);
335 else
336 {
337 #if Debug
338 if (dbgrejs)
339 { if (!dbgpkts)
340 sdbgpkt("RcvPkt/", &pkt[1], pktl);
341 sdbgmsg("RejPkt/type");
342 }
343 #endif
344 return;
345 }
346 }
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361 int check_len(length)
362
363 int length;
364 {
365
366 return ((length & MASK_SIX) + MIN_ASCII);
367 }
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397 int crc_char (p_chr, p_seed)
398
399 int p_seed;
400 char p_chr;
401 {
402 int b;
403 int crc;
404 int q;
405 int schr;
406
407 crc = p_seed;
408 schr = p_chr;
409
410
411
412
413
414 for (b = 0; b < 8; b++)
415 { q = (crc + schr) & 1;
416 crc >>= 1;
417 if (q)
418 crc ^= REVPOLY;
419 schr >>= 1;
420 }
421 return (crc);
422 }
423
424
425
426
427
428
429
430
431
432
433
434
435
436 int chkcrc(str, strl)
437
438 char str[];
439 int strl;
440 {
441 int i;
442 int crc;
443
444
445
446 crc = INIT_CRC;
447 for (i = 0; i < strl; i++)
448 { crc = crc_char (str[i], crc);
449 }
450
451
452
453 return (crc + MIN_ASCII);
454 }
455
456
457
458
459
460
461
462
463
464 disconnect_confirm(p_fast)
465
466 int p_fast;
467 {
468 char type;
469
470
471
472 if ((ds_pending & InitDis) && (!p_fast))
473 { ds_timeout = DISCONNECT_OUT;
474 ds_pending = 0;
475 type = DisCon + Confirm;
476 sndpkt (type,"");
477 return (0);
478 }
479
480
481
482 mowse_terminating = True;
483 ds_pending = 0;
484 packet_mode = False;
485 packetize_flag = False;
486 reset();
487 }
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502 int getdat(chn, data)
503
504 int chn;
505 char *data;
506 {
507 char *rdat;
508 int i;
509 int rdatl;
510
511
512
513 if (r_psn[chn] == s_nasn[chn])
514 return 0;
515
516
517
518 rdat = &r_dat[chn][s_nasn[chn]][1];
519 rdatl = rdat[-1] & MASK_ALL;
520 for (i = 0; i < rdatl; i++)
521 { data[i] = rdat[i];
522 }
523 s_nasn[chn] = (s_nasn[chn] + 1) & SeqMsk;
524
525
526
527 if (((s_nasn[chn] - s_lasn[chn]) & SeqMsk) >= RWS-1)
528 sndack(chn);
529
530 return(rdatl);
531 }
532
533
534
535
536
537
538
539
540
541 prsack(pkt)
542
543 char pkt[];
544 {
545 int asn;
546 int asn_valid;
547 int chn;
548 int fields;
549
550
551
552 if (pkt[0] != MinPktLen)
553 {
554 #if Debug
555 if (dbgrejs)
556 { if (!dbgpkts)
557 sdbgpkt("RcvPkt/", &pkt[1], pkt[0] & MASK_ALL);
558 sdbgmsg("RejAck/length");
559 }
560 #endif
561 return;
562 }
563
564
565
566 fields = pkt[SOPLen+1] - AckOff;
567 asn = fields & SeqMsk;
568 chn = fields >> SeqFld;
569
570
571
572 if (r_asn[chn] <= s_psn[chn])
573 asn_valid = (r_asn[chn] <= asn && asn <= s_psn[chn]);
574 else
575 asn_valid = (r_asn[chn] <= asn || asn <= s_psn[chn]);
576 if (!asn_valid)
577 {
578 #if Debug
579 if (dbgrejs)
580 { if (!dbgpkts)
581 sdbgpkt("RcvPkt/", &pkt[1], pkt[0] & MASK_ALL);
582 sdbgmsg("RejAck/asn");
583 }
584 #endif
585 return;
586 }
587
588
589
590 r_asn[chn] = asn;
591 }
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608 prsbrk (pkt)
609
610 char pkt[];
611 {
612 char type;
613
614
615
616 if ((pkt[SOPLen+1] == DisCon + Request) && !ds_pending)
617 { ds_pending = ds_pending | RespDis;
618 pending_timer[Dis_Timer_X] = 0;
619 type = DisCon + Confirm;
620 sndpkt (type,"");
621 }
622
623
624
625 else if (pkt[SOPLen + 1] == DisCon + Confirm)
626 { pending_timer[Dis_Timer_X] = 0;
627 disconnect_confirm(0);
628 }
629
630
631
632 else if (pkt[SOPLen + 1] == FGBrk + Request)
633 {
634 }
635
636
637 else if (pkt[SOPLen + 1] == FGBrk + Confirm)
638 { pending_timer[Break_Timer_X] = 0;
639 br_pending = False;
640 type = FGBrk + Confirm;
641 sndpkt(type,"");
642 }
643 }
644
645
646
647
648
649
650
651
652
653 prsdat(pkt)
654
655 char pkt[];
656 {
657 char *data;
658 char *rdat;
659 int asn;
660 int asn_valid;
661 int chn;
662 int datal;
663 int fields;
664 int i;
665 int psn;
666
667
668
669
670 fields = pkt[SOPLen + 1] - DatOff;
671 asn = fields & SeqMsk;
672 psn = (fields >> SeqFld) & SeqMsk;
673 chn = fields >> (SeqFld + SeqFld);
674
675
676
677 if (r_asn[chn] <= s_psn[chn])
678 asn_valid = (r_asn[chn] <= asn && asn <= s_psn[chn]);
679 else
680 asn_valid = (r_asn[chn] <= asn || asn <= s_psn[chn]);
681 if (!asn_valid)
682 {
683 #if Debug
684 if (dbgrejs)
685 { if (!dbgpkts)
686 sdbgpkt("RcvPkt/", &pkt[1], pkt[0] & MASK_ALL);
687 sdbgmsg("RejDat/asn");
688 }
689 #endif
690 return;
691 }
692
693
694
695 r_asn[chn] = asn;
696
697
698
699 if (ds_pending)
700 return;
701
702
703
704
705 if (psn != r_psn[chn])
706 { if (!r_ignoring[chn])
707 { sndnak(chn);
708 r_ignoring[chn] = True;
709 }
710 #if Debug
711 if (dbgrejs)
712 { if (!dbgpkts)
713 sdbgpkt("RcvPkt/", &pkt[1], pkt[0] & MASK_ALL);
714 sdbgmsg("RejDat/psn");
715 }
716 #endif
717 return;
718 }
719
720
721
722 data = &pkt[SOPLen + TypLen + 1];
723 datal = (pkt[0] & MASK_ALL) - MinPktLen;
724 rdat = &r_dat[chn][psn][1];
725 rdat[-1] = datal;
726 for (i = 0; i < datal; i++)
727 { rdat[i] = data[i];
728 }
729 r_ignoring[chn] = False;
730 r_psn[chn] = (psn + 1) & SeqMsk;
731 }
732
733
734
735
736
737
738
739
740
741 prsnak(pkt)
742
743 char pkt[];
744 {
745 int asn;
746 int asn_valid;
747 int chn;
748 int fields;
749
750
751
752 if (pkt[0] != MinPktLen)
753 {
754 #if Debug
755 if (dbgrejs)
756 { if (!dbgpkts)
757 sdbgpkt("RcvPkt/", &pkt[1], pkt[0] & MASK_ALL);
758 sdbgmsg("RejNak/length");
759 }
760 #endif
761 return;
762 }
763
764
765
766
767 fields = pkt[SOPLen + 1] - NakOff;
768 asn = fields & SeqMsk;
769 chn = fields >> SeqFld;
770
771
772
773 if (r_asn[chn] <= s_psn[chn])
774 asn_valid = (r_asn[chn] <= asn && asn <= s_psn[chn]);
775 else
776 asn_valid = (r_asn[chn] <= asn || asn <= s_psn[chn]);
777 if (!asn_valid)
778 {
779 #if Debug
780 if (dbgrejs)
781 { if (!dbgpkts)
782 sdbgpkt("RcvPkt/", &pkt[1], pkt[0] & MASK_ALL);
783 sdbgmsg("RejNak/asn");
784 }
785 #endif
786 return;
787 }
788
789
790
791 r_asn[chn] = asn;
792
793
794
795 resend(chn);
796 }
797
798
799
800
801
802
803
804
805
806 prsrst(pkt)
807
808 char pkt[];
809 {
810 char type;
811
812
813
814 if (ds_pending)
815 return (0);
816
817
818
819
820 if (pkt[SOPLen+1] == RstOff + Request)
821 { rs_pending = rs_pending | RespRst;
822 reset();
823 r_pktin = 1;
824 type = RstOff + Confirm;
825 sndpkt(type, "");
826 }
827
828
829
830 else if (pkt[SOPLen + 1] == RstOff + Confirm)
831 { if (rs_pending & InitRst)
832 { pending_timer[Reset_Timer_X] = 0;
833 type = RstOff + Confirm;
834 sndpkt (type, "");
835 }
836 packetize_flag = True;
837 rs_pending = 0;
838 }
839 }
840
841
842
843
844
845
846
847
848
849
850 rcvchr(chr)
851
852 char chr;
853 {
854 static int EndPkt = 1;
855 static int ExtChr = 2;
856 static int LngPkt = 3;
857 static int NoRoom = 4;
858
859 int dbgmsg;
860 int nextin;
861 int pktl;
862 int test_ds;
863 char *pkt;
864
865
866
867 if (!chr)
868 return;
869
870
871
872 if (chr == Null_Convert)
873 chr = NULL;
874
875 dbgmsg = 0;
876
877
878
879 pkt = r_pkt[r_pktin];
880
881
882
883 if (chr == r_SOP)
884 { r_esckey = '\000';
885 pkt[0] = 1;
886 pkt[1] = chr;
887 }
888
889
890
891 else if (pkt[0] == 0)
892 { dbgmsg = ExtChr;
893 }
894
895
896
897
898
899 else if (chr == r_EOP)
900 { dbgmsg = EndPkt;
901 pktl = ++pkt[0] & MASK_ALL;
902 pkt[pktl] = chr;
903
904 if (r_pktin < RQS)
905 nextin = r_pktin + 1;
906 else
907 nextin = 0;
908
909 if (nextin != r_pktout)
910 { r_pktin = nextin;
911 r_pkt[r_pktin][0] = 0;
912 }
913 else
914 { dbgmsg = NoRoom;
915 pkt[0] = 0;
916 }
917 }
918
919
920
921
922
923
924 else
925 { if (r_esckey != '\000')
926 { chr = chr ^ r_esckey;
927 r_esckey = '\000';
928 r_ESC_count++;
929 }
930 else if (chr == r_ESC[0])
931 r_esckey = '\100';
932 else if (chr == r_ESC[1])
933 r_esckey = '\200';
934 else if (chr == r_ESC[2])
935 r_esckey = '\300';
936
937 if (r_esckey == '\000')
938 { pktl = ++pkt[0] & MASK_ALL;
939 pkt[pktl] = chr;
940 if (pktl >= MaxPktLen)
941 { dbgmsg = LngPkt;
942 pkt[0] = 0;
943 }
944 }
945 }
946
947
948
949 #if Debug
950 if (dbgmsg != 0)
951 { if (dbgmsg == ExtChr)
952 { if (dbgxchr)
953 { if (chr >= ' ' && chr <= '~')
954 sdbgchr(chr + REV_VIDEO);
955 else
956 { sdbgchr('\\' + REV_VIDEO);
957 sdbgchr(((chr>>6) & 3) + '0' + REV_VIDEO);
958 sdbgchr(((chr>>3) & 7) + '0' + REV_VIDEO);
959 sdbgchr((chr & 7) + '0' + REV_VIDEO);
960 }
961 }
962 }
963 else
964 { if (dbgpkts)
965 sdbgpkt("RcvPkt/", &pkt[1], pktl);
966 if (dbgrejs)
967 { if (dbgmsg == LngPkt)
968 { if (!dbgpkts)
969 sdbgpkt("RcvPkt/", &pkt[1], pktl);
970 sdbgmsg("RejPkt/LngPkt");
971 }
972 else if (dbgmsg == NoRoom)
973 { if (!dbgpkts)
974 sdbgpkt("RcvPkt/", &pkt[1], pktl);
975 sdbgmsg("RejPkt/NoRoom");
976 }
977 }
978 }
979 }
980 #endif
981
982
983
984
985
986
987 if (!apv_locked)
988 { apv_locked = (r_pktin != r_pktout);
989 while (apv_locked)
990 { test_ds = ds_pending;
991 apvpkt(r_pkt[r_pktout]);
992 r_ESC_count = 0;
993 if (r_pktout < RQS)
994 r_pktout++;
995 else
996 r_pktout = 0;
997 apv_locked = (r_pktin != r_pktout);
998
999 if ((test_ds & ds_pending) & RespDis)
1000 disconnect_confirm(0);
1001 }
1002 }
1003 }
1004
1005
1006
1007
1008
1009
1010
1011
1012 resend(chn)
1013
1014 int chn;
1015 {
1016 int psn;
1017 char type;
1018
1019
1020
1021 for (psn = r_asn[chn]; psn != s_psn[chn]; psn = (psn + 1) & SeqMsk)
1022 { type = (((chn << SeqFld) + psn) << SeqFld) + s_nasn[chn] + DatOff;
1023 sndpkt(type, s_dat[chn][psn]);
1024 s_lasn[chn] = s_nasn[chn];
1025 s_timer[chn] = 0;
1026 }
1027 }
1028
1029
1030
1031
1032
1033
1034
1035
1036 reset()
1037
1038 {
1039 int chn;
1040 int i;
1041
1042 apv_locked = False;
1043 ds_pending = 0;
1044 br_pending = 0;
1045 for (i = 0; i < 3; pending_timer[i++] = 0);
1046
1047 for (i = 0; i <= RQS; i++)
1048 { r_pkt[i][0] = 0;
1049 }
1050 r_pktin = 0;
1051 r_pktout = 0;
1052
1053 for (chn = 0; chn < ChnCnt; chn++)
1054 { for (i = 0; i < SeqCnt; i++)
1055 { r_dat[chn][i][0] = 0;
1056 }
1057 r_ignoring[chn] = False;
1058 r_asn[chn] = 0;
1059 r_psn[chn] = 0;
1060 r_timer[chn] = 0;
1061
1062 for (i = 0; i < SeqCnt; i++)
1063 { s_dat[chn][i][0] = 0;
1064 }
1065 s_lasn[chn] = 0;
1066 s_nasn[chn] = 0;
1067 s_psn[chn] = 0;
1068 s_timer[chn] = 0;
1069 }
1070 }
1071
1072
1073
1074 #if Debug
1075
1076
1077
1078
1079
1080
1081 sdbgmsg(msg)
1082
1083 char msg[];
1084 {
1085 int i;
1086
1087
1088
1089 sdbgchr(CR);
1090 sdbgchr(LF);
1091 sdbgchr('(' + REV_VIDEO);
1092
1093
1094
1095 for (i = 0; msg[i] != '\000'; i++)
1096 { sdbgchr(msg[i]);
1097 }
1098
1099
1100
1101 sdbgchr(')' + REV_VIDEO);
1102 sdbgchr(CR);
1103 sdbgchr(LF);
1104 }
1105 #endif
1106
1107
1108
1109 #if Debug
1110
1111
1112
1113
1114
1115
1116 sdbgpkt(msg, pkt, pktl)
1117
1118 char msg[];
1119 char pkt[];
1120 int pktl;
1121 {
1122 char chr;
1123 int i;
1124
1125
1126
1127 sdbgchr(CR);
1128 sdbgchr(LF);
1129 sdbgchr('(' + 128);
1130
1131
1132
1133 for (i = 0; msg[i] != '\0'; i++)
1134 { sdbgchr(msg[i]);
1135 }
1136
1137
1138
1139
1140 for (i = 0; i < pktl; i++)
1141 { chr = pkt[i];
1142 if (chr >= ' ' && chr <= '~')
1143 sdbgchr(chr);
1144 else
1145 { sdbgchr('`');
1146 sdbgchr(((chr>>6) & 3) + '0');
1147 sdbgchr(((chr>>3) & 7) + '0');
1148 sdbgchr((chr & 7) + '0');
1149 }
1150 }
1151
1152
1153
1154 sdbgchr(')' + 128);
1155 sdbgchr(CR);
1156 sdbgchr(LF);
1157 }
1158 #endif
1159
1160
1161
1162
1163
1164
1165
1166
1167 sndack(chn)
1168
1169 int chn;
1170 {
1171 char type;
1172
1173 type = (chn << SeqFld) + s_nasn[chn] + AckOff;
1174 sndpkt(type, "");
1175 s_lasn[chn] = s_nasn[chn];
1176 r_timer[chn] = 0;
1177 }
1178
1179
1180
1181
1182
1183
1184
1185
1186 sndbrk()
1187
1188 {
1189 char type;
1190
1191
1192
1193 br_pending = True;
1194 pending_timer[Break_Timer_X] = 0;
1195
1196
1197
1198 type = FGBrk + Request;
1199 sndpkt (type, "");
1200 }
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218 int snddat(chn, datac, datap, datal)
1219
1220 int chn,
1221 datac,
1222 datal[];
1223 char *datap[];
1224 {
1225 static int TooLong = -1;
1226 static int SentDat = 0;
1227 static int WdwFull = 1;
1228 static int RstPnd = 2;
1229
1230 char *sdat;
1231 char type;
1232 int i;
1233 int j;
1234 int l;
1235 int spsn;
1236
1237
1238
1239 if ((rs_pending) || (!packetize_flag))
1240 return RstPnd;
1241
1242
1243
1244 spsn = s_psn[chn];
1245 if (((spsn - r_asn[chn]) & SeqMsk) >= SWS)
1246 return WdwFull;
1247
1248
1249
1250 sdat = s_dat[chn][spsn];
1251 sdat[0] = 0;
1252 l = 0;
1253 for (i = 0; i < datac; i++)
1254 { for (j = 0; j < datal[i]; j++)
1255 { if (l < MaxDatLen)
1256 sdat[++l] = datap[i][j];
1257 else
1258 return TooLong;
1259 }
1260 }
1261 sdat[0] = l;
1262
1263
1264
1265 if (l == 0)
1266 return SentDat;
1267
1268
1269
1270 s_psn[chn] = (spsn + 1) & SeqMsk;
1271
1272
1273
1274 type = (((chn << SeqFld) + spsn) << SeqFld) + s_nasn[chn] + DatOff;
1275 sndpkt(type, sdat);
1276 s_lasn[chn] = s_nasn[chn];
1277 r_timer[chn] = 0;
1278 s_timer[chn] = 0;
1279 return SentDat;
1280 }
1281
1282
1283
1284
1285
1286
1287
1288
1289 snddis()
1290
1291 {
1292 char type;
1293
1294
1295
1296 if (!packetize_flag || !packet_mode)
1297 return (WSNOTACT);
1298
1299
1300
1301 if (ds_pending)
1302 return (WSDISPEN);
1303
1304
1305
1306 if (ds_timeout & TIME_OUT)
1307 { ds_timeout = 0;
1308 return (TIME_OUT);
1309 }
1310
1311
1312
1313 if (ds_timeout & DISCONNECT_OUT)
1314 { ds_timeout = 0;
1315 return (DISCONNECT_OUT);
1316 }
1317
1318
1319
1320 ds_pending |= InitDis;
1321 ds_timeout = 0;
1322 type = DisCon + Request;
1323 sndpkt (type, "");
1324 return (WSDISPEN);
1325 }
1326
1327
1328
1329
1330
1331
1332
1333
1334 sndnak(chn)
1335
1336 int chn;
1337 {
1338 char type;
1339
1340 type = (chn << SeqFld) + s_nasn[chn] + NakOff;
1341 sndpkt(type, "");
1342 return (0);
1343 }
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379 sndpkt(type, data)
1380
1381 char type;
1382 char data[];
1383 {
1384 static int EscKey[3] = {1*64, 2*64, 3*64},
1385 GrpEscIdx[8] = {0, -1, -1, 0, 2, 1, 1, 2};
1386
1387 int crc;
1388 int chr;
1389 int datal;
1390 int escidx;
1391 int i;
1392 int group;
1393 int pktl;
1394 char pkt[MinPktLen + 2*MaxDatLen];
1395
1396
1397
1398 if (!packet_mode)
1399 return (0);
1400
1401
1402
1403
1404 if (ds_pending && ((type != DisCon + Request) && (type != DisCon + Confirm)))
1405 return(0);
1406
1407
1408
1409 pkt[0] = s_SOP;
1410 pkt[1] = type;
1411 crc = crc_char (pkt[0], INIT_CRC);
1412 crc = crc_char (pkt[1], crc);
1413 pktl = 2;
1414 datal = data[0] & MASK_ALL;
1415 for (i = 1; i <= datal; i++)
1416 { chr = data[i] & MASK_ALL;
1417 crc = crc_char ((char)chr, crc);
1418 group = chr >> 5;
1419 escidx = GrpEscIdx[group];
1420 if (escidx >= 0 && s_escreq[chr])
1421 { pkt[pktl] = s_ESC[escidx];
1422 pktl++;
1423 chr ^= EscKey[escidx];
1424 }
1425 pkt[pktl] = chr;
1426 pktl++;
1427 }
1428
1429
1430
1431 pkt[pktl] = check_len (pktl + LenLen + ChkLen + SOPLen);
1432 crc = crc_char (pkt[pktl], crc);
1433 pktl++;
1434 pkt[pktl] = crc + MIN_ASCII;
1435 pktl++;
1436 pkt[pktl] = s_EOP;
1437 pktl++;
1438
1439
1440
1441 smdmstr(&pkt[0], pktl);
1442
1443 #if Debug
1444 if (dbgpkts)
1445 { sdbgpkt("SndPkt/", &pkt[0], pktl);
1446 }
1447 #endif
1448 }
1449
1450
1451
1452
1453
1454
1455
1456
1457 sndrst()
1458
1459 {
1460 char type;
1461
1462
1463
1464 if (rs_pending)
1465 return (0);
1466
1467
1468
1469 rs_pending = rs_pending | InitRst;
1470 reset();
1471 type = RstOff + Request;
1472 sndpkt(type, "");
1473 }