1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 x25_mpx:
23 procedure;
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
51
52
53
54
55
56
57
58
59
60 dcl x25_chain_ptr ptr parameter;
61 dcl x25_code fixed bin (35) parameter;
62 dcl x25_infop ptr parameter;
63 dcl x25_int_data bit (72) aligned parameter;
64 dcl x25_int_type fixed bin parameter;
65 dcl x25_modes char (*) parameter;
66 dcl x25_order char (*) parameter;
67 dcl X25_data_ptr ptr parameter;
68 dcl x25_mclp ptr parameter;
69 dcl X25_scx fixed bin parameter;
70
71
72
73 dcl (endp, prev_blockp, chain_ptr, leftover_chain_ptr) ptr;
74 dcl (called_dte_addr_length, calling_dte_addr_length) unsigned fixed bin (4);
75 dcl (facility_disp, user_data_disp, facility_length, user_data_length) fixed bin;
76 dcl temp_ps unsigned fixed bin (7);
77 dcl lcx uns fixed bin (12);
78 dcl scx fixed bin;
79 dcl code fixed bin (35);
80 dcl (i, j) fixed bin;
81 dcl infop ptr;
82 dcl int_data bit (72) aligned;
83 dcl int_type fixed bin;
84 dcl (hdr_size, nchars) fixed bin (21);
85 dcl mode_found bit (1) aligned;
86 dcl order char (32) aligned;
87 dcl addr_string char (30) aligned;
88 dcl set_entry bit (1) aligned;
89 dcl pr_error bit (1) unaligned;
90 dcl protocol_mpx bit (1) unaligned;
91 dcl Call_data char (16);
92
93
94 dcl 1 write_status_info aligned based (infop),
95 2 ev_chan fixed bin (71),
96 2 output_pending bit (1);
97
98 dcl dial_out_info aligned varying char (24) based (infop);
99 dcl 1 reason_of_hangup aligned based (infop) like NDIS_IND_REASON;
100 dcl 1 N_I_i aligned based (addr (buffer.chars)) like NCON_IND_info;
101 dcl 1 ifci aligned like input_flow_control_info based (infop);
102 dcl 1 ofci aligned like output_flow_control_info based (infop);
103 dcl 1 ftd aligned like foreign_terminal_data based (infop);
104
105 dcl 1 lap_down_status aligned based (addr (x25_int_data)),
106 2 link_down_status uns fixed bin (18) unaligned,
107 2 last_function_process fixed bin (17) unaligned,
108 2 which_state_process uns fixed bin (9) unaligned,
109 2 main_state uns fixed bin (9) unaligned,
110 2 primary_sub_state uns fixed bin (9) unaligned,
111 2 secondary_sub_state uns fixed bin (9) unaligned;
112
113 dcl 1 lap_cmdr_status aligned based (addr (x25_int_data)),
114 2 cmdr_status uns fixed bin (18) unaligned,
115 2 cmdr_bytes (3) unaligned,
116 3 pad bit (1) unaligned,
117 3 byte bit (8) unaligned,
118 2 pad bit (27) unaligned;
119
120 dcl 1 x25_pkt aligned based (blockp),
121 2 buffer_header bit (36),
122 2 l2_pad char (2 ) unal,
123 2 l3_header unal,
124 3 pad1 bit (1) unal,
125 3 q bit (1) unal,
126 3 d bit (1) unal,
127 3 format bit (2) unal,
128 3 lcgn bit (4) unal,
129 3 pad2 bit (1) unal,
130 3 lcn bit (8) unal,
131 2 l3_fc bit (0) unal,
132 2 pad3 bit (1) unal,
133 2 type bit (8) unal,
134 2 no_fc_data (56) bit (9) unal;
135
136 dcl l3_call_data char (user_data_length) based (addr (x25_pkt.no_fc_data (user_data_disp)));
137
138 dcl l3_facilities char (facility_length) based (addr (x25_pkt.no_fc_data (facility_disp + 1)));
139 dcl 1 m8_fc_data unal based (addr (x25_pkt.l3_fc)),
140 2 pad bit (1),
141 2 pr uns fixed bin (3),
142 2 m bit (1),
143 2 ps uns fixed bin (3),
144 2 data_sw bit (1),
145 2 user_data bit (0);
146
147 dcl 1 m128_fc_data unal based (addr (x25_pkt.l3_fc)),
148 2 pad1 bit (1),
149 2 ps uns fixed bin (7),
150 2 data_sw bit (1),
151 2 pad2 bit (1),
152 2 pr uns fixed bin (7),
153 2 m bit (1),
154 2 user_data bit (0);
155
156 dcl l4_data_ptr ptr;
157 dcl l4_data (56) bit (9) unal based (l4_data_ptr);
158
159 dcl based_area area based;
160
161
162
163 dcl L2_HEADER_PAD fixed bin static options (constant) init (2);
164 dcl TIMEOUT fixed bin (71) static options (constant) init (1000000);
165 dcl T20 fixed bin (71) static options (constant) init (180000000);
166 dcl MPX_UP fixed bin (71) static options (constant) init (1);
167 dcl MPX_DOWN fixed bin (71) static options (constant) init (2);
168 dcl MPX_MASKED fixed bin (71) static options (constant) init (3);
169 dcl DEFAULT_BAUD fixed bin internal static options (constant) init (1200);
170 dcl (
171 MODE_RAWI init (1),
172 MODE_ECHOPLEX init (2),
173 MODE_BREAKALL init (3),
174 MODE_IFLOW init (4),
175 MODE_OFLOW init (5),
176 MODE_HNDLQUIT init (6),
177 MODE_LFECHO init (7),
178 MODE_POLITE init (8),
179 MODE_8BIT init (9)
180 ) fixed bin static options (constant);
181 dcl mode_names (11) char (8) aligned static options (constant)
182 init ("rawi", "echoplex", "breakall", "iflow", "oflow", "hndlquit", "lfecho", "polite", "8bit", "oddp",
183 "no_outp");
184
185 dcl CALLRQ bit (8) unal static options (constant) init ("0b"b4);
186
187 dcl CALLAC bit (8) unal static options (constant) init ("0f"b4);
188
189 dcl CLRRQ bit (8) unal static options (constant) init ("13"b4);
190
191 dcl CLRCN bit (8) unal static options (constant) init ("17"b4);
192
193 dcl RSRTRQ bit (8) unal static options (constant) init ("fb"b4);
194
195 dcl RSRTCN bit (8) unal static options (constant) init ("ff"b4);
196
197 dcl DIAG bit (8) unal static options (constant) init ("f1"b4);
198
199 dcl RESTRQ bit (8) unal static options (constant) init ("1b"b4);
200
201 dcl RESTCN bit (8) unal static options (constant) init ("1f"b4);
202
203 dcl SNITRQ bit (8) unal static options (constant) init ("23"b4);
204
205 dcl SNITCN bit (8) unal static options (constant) init ("27"b4);
206
207 dcl SNRR bit (8) unal static options (constant) init ("01"b4);
208
209 dcl SNRNR bit (8) unal static options (constant) init ("05"b4);
210
211 dcl SNREJ bit (8) unal static options (constant) init ("09"b4);
212 dcl SNMASK bit (8) unal static options (constant) init ("0f"b4);
213
214 dcl NL char (1) static options (constant) init ("
215 ");
216 dcl CR_LF_FF char (3) int static options (constant) init ("^M
217 ^L");
218
219
220
221 dcl et_action_not_performed fixed bin (35) static;
222 dcl et_bad_arg fixed bin (35) static;
223 dcl et_bad_mode fixed bin (35) static;
224 dcl et_invalid_state fixed bin (35) static;
225 dcl et_noalloc fixed bin (35) static;
226 dcl et_resource_unavailable fixed bin (35) static;
227 dcl et_undefined_order_request fixed bin (35) static;
228 dcl et_unimplemented_version fixed bin (35) static;
229
230
231
232 dcl error_table_$action_not_performed fixed bin (35) ext static;
233 dcl error_table_$bad_arg fixed bin (35) ext static;
234 dcl error_table_$bad_mode fixed bin (35) ext static;
235 dcl error_table_$invalid_state fixed bin (35) ext static;
236 dcl error_table_$noalloc fixed bin (35) ext static;
237 dcl error_table_$resource_unavailable fixed bin (35) ext static;
238 dcl error_table_$undefined_order_request fixed bin (35) ext static;
239 dcl error_table_$unimplemented_version fixed bin (35) ext static;
240
241 dcl x25_mpx_data$trans_no_parity char (256) aligned external;
242 dcl x25_mpx_data$trans_no_parity_lfecho char (256) aligned external;
243 dcl x25_mpx_data$trans_parity_lfecho char (256) aligned external;
244 dcl x25_mpx_data$eight_bit char (512) aligned external;
245 dcl based_trans_table char (512) aligned based;
246
247
248
249 dcl (addr, after, before, binary, bit, clock, dimension, divide, hbound, lbound, length, min, mod, null, pointer, rel,
250 rtrim, size, string, substr, unspec, verify) builtin;
251
252
253 dcl mrl_ entry (ptr, fixed bin (21), ptr, fixed bin (21));
254 dcl mvt_ entry (ptr, ptr, fixed bin (21), char (512) aligned);
255 dcl pxss$ring_0_wakeup entry (bit (36) aligned, fixed bin (71), fixed bin (71), fixed bin (35));
256 dcl syserr entry options (variable);
257 dcl wire_proc$wire_me entry;
258 %page;
259
260
261 control:
262 entry (X25_data_ptr, X25_scx, x25_order, x25_infop, x25_code);
263
264 call setup_subchan;
265 order = x25_order;
266 infop = x25_infop;
267 pinfop = infop;
268 x25_code = 0;
269
270 protocol_mpx = get_protocol_sc ();
271
272 if xlcep = null ()
273 then if order = "listen" then do;
274 xsce.state = SC_LISTENING;
275 end;
276
277 else if order = "dial_out" then do;
278 if x25_data.lc_ptr = null () then do;
279 x25_code = et_invalid_state;
280 return;
281 end;
282 do lcx = x25_data.n_lc by -1 to 1 + x25_data.n_pvc while (x25_lces.lc (lcx).state ^= READY);
283
284 end;
285 if lcx < 1 then do;
286 x25_code = et_resource_unavailable;
287 return;
288 end;
289 xlcep = addr (x25_lces.lc (lcx));
290 xlce.flags.originate = "1"b;
291
292 if (^protocol_mpx & length (dial_out_info) > 0) then do;
293 xlce.call_data = after (dial_out_info, ":");
294 xlce.baud_rate = x25_data.dialup_info.baud_rate;
295 xlce.flags.originate = "1"b;
296 xlce.flags.collect_call = x25_data.flags.out_calls_collect;
297
298 if substr (before (dial_out_info, ":"), 1, 4) = "x29," then do;
299
300 xlce.his_address = substr (before (dial_out_info, ":"), 5);
301 xlce.flags.iti_call = "1"b;
302 end;
303
304 else if substr (before (dial_out_info, ":"), 1, 1) = "*" then do;
305
306 xlce.his_address = substr (before (dial_out_info, ":"), 2);
307 xlce.flags.iti_call = "1"b;
308 end;
309
310 else do;
311 xlce.his_address = before (dial_out_info, ":");
312 xlce.flags.iti_call = "0"b;
313 call get_buffer (16);
314 end;
315 end;
316
317
318
319
320
321 else if (length (dial_out_info) = 0) then do;
322
323
324
325 xlce.baud_rate = DEFAULT_BAUD;
326 xlce.call_data = NCON_REQ_info.data;
327
328 xlce.his_address = NCON_REQ_info.to_address;
329 xlce.flags.iti_call = "0"b;
330 xsce.trans_table_ptr = null ();
331 call get_buffer (32);
332 end;
333 if xlce.flags.iti_call then do;
334 xlce.iti_params (13) = 4;
335 call get_buffer (16);
336 end;
337
338 call make_header (lcx, "0"b);
339 x25_pkt.type = CALLRQ;
340 if ^x25_data.flags.no_d then x25_pkt.l3_header.d = "1"b;
341 calling_dte_addr_length = length (x25_data.my_address);
342 called_dte_addr_length = length (xlce.his_address);
343 x25_pkt.no_fc_data (1) = "0"b || bit (calling_dte_addr_length) || bit (called_dte_addr_length);
344 facility_disp = 2 + divide (called_dte_addr_length + calling_dte_addr_length + 1, 2, 17, 0);
345
346 addr_string = xlce.his_address || x25_data.my_address;
347 do i = 2 to facility_disp - 1;
348 x25_pkt.no_fc_data (i) =
349 "0"b || substr (unspec (substr (addr_string, 2 * i - 3, 1)), 6, 4)
350 || substr (unspec (substr (addr_string, 2 * i - 2, 1)), 6, 4);
351 end;
352
353
354
355 x25_pkt.no_fc_data (facility_disp) = "002"b3;
356 x25_pkt.no_fc_data (facility_disp + 1) = "001"b3;
357 if protocol_mpx then do;
358 facility_length = 2;
359 if xlce.collect_call
360 then l3_facilities = "^A^A";
361 else l3_facilities = "^A^@";
362 user_data_disp = facility_disp + 3;
363 facility_length = length (NCON_REQ_info.facilities);
364 if facility_length ^= 0 then do;
365 x25_pkt.no_fc_data (facility_disp) = substr (unspec (facility_length), 27, 9);
366 l3_facilities = NCON_REQ_info.facilities;
367 user_data_disp = facility_disp + facility_length + 1;
368 end;
369 user_data_length = length (NCON_REQ_info.data);
370 l3_call_data = NCON_REQ_info.data;
371 end;
372 else do;
373 if xlce.collect_call
374 then x25_pkt.no_fc_data (facility_disp + 2) = "001"b3;
375 else x25_pkt.no_fc_data (facility_disp + 2) = "000"b3;
376 user_data_disp = facility_disp + 3;
377 user_data_length = length (xlce.call_data) + 4;
378 unspec (substr (l3_call_data, 1, 4)) = ""b3;
379 if xlce.flags.iti_call then unspec (substr (l3_call_data, 1, 1)) = "001"b3;
380 substr (l3_call_data, 5) = xlce.call_data;
381 end;
382
383 buffer.tally = 2 + user_data_disp + user_data_length + L2_HEADER_PAD;
384 call write_pkt;
385 call send_output;
386
387 xsce.state = SC_DIALING;
388 xsce.lcx = lcx;
389 xlce.scx = scx;
390 call state_change (DTE_WAITING);
391 end;
392
393 else if order = "hangup" then do;
394 call reset_xsce;
395 end;
396
397 else if (protocol_mpx & order = "get_network_infos") then do;
398
399 network_infos.network_address = x25_data.my_address;
400 network_infos.max_packet_size = x25_lces.lc (1).max_packet_size;
401 end;
402 else x25_code = et_undefined_order_request;
403 %page;
404 else if order = "hangup" then do;
405 if xlce.flags.iti_call & ^xlce.flags.originate then do;
406 call get_buffer (16);
407 call make_header (lcx, "1"b);
408 l4_data (1) = "001"b3;
409 buffer.tally = hdr_size + 1 + L2_HEADER_PAD;
410 call write_data_pkt;
411 end;
412
413 else if (protocol_mpx & infop ^= null ()) then call clear_call ((reason_of_hangup.diag));
414 else call clear_call (0);
415 end;
416
417 else if (protocol_mpx & (order = "connect_response")) then do;
418
419 if xlce.state ^= CONRESP_WAITING | xsce.state ^= SC_DIALING
420 then x25_code = et_invalid_state;
421 else do;
422 call reset_timer;
423 call send_NCON_RESP;
424 xsce.state = SC_DIALING;
425 xlce.state = FLOW_CONTROL_READY;
426 xsce.flags.output_ready = "1"b;
427 call channel_manager$interrupt (xsce.devx, SEND_OUTPUT, ""b);
428 x25_code = 0;
429 end;
430 end;
431
432 else if order = "wru" then do;
433 if ^xsce.flags.wru_done then do;
434 call tty_space_man$get_buffer (xsce.devx, 16, INPUT, blockp);
435 if blockp ^= null () then do;
436 buffer.next = 0;
437 string (buffer.flags) = ""b;
438 buffer.flags.break = "1"b;
439 string (buffer.chars) = "X.25:" || xlce.his_address || NL;
440 buffer.tally = length (rtrim (string (buffer.chars)));
441
442 rtx_info.input_chain.chain_head, rtx_info.input_chain.chain_tail = rel (blockp);
443 rtx_info.input_count = 16;
444 string (rtx_info.flags) = ""b;
445 rtx_info.flags.break_char = "1"b;
446
447 call channel_manager$interrupt (xsce.devx, ACCEPT_INPUT, unspec (rtx_info));
448 xsce.flags.wru_done = "1"b;
449 end;
450 end;
451 end;
452
453 else if order = "abort" then ;
454
455 else if order = "write_status" then do;
456 write_status_info.output_pending = (xlce.next_send_seq ^= xlce.next_ack_seq);
457 if write_status_info.output_pending & ^xlce.flags.write_status_sync_sent then call send_sync;
458
459 end;
460
461 else if order = "interrupt" then do;
462 if xlce.flags.int_issued then return;
463 call get_buffer (16);
464 call make_header (lcx, "0"b);
465 x25_pkt.type = SNITRQ;
466 x25_pkt.no_fc_data (1) = ""b;
467 buffer.tally = 4 + L2_HEADER_PAD;
468 call write_pkt;
469 call send_output;
470 xlce.flags.int_issued = "1"b;
471
472 if xlce.flags.iti_call & (xlce.iti_params (7) = 21) then do;
473 call get_buffer (16);
474 call make_header (lcx, "1"b);
475 l4_data (1) = "003"b3;
476 l4_data (2) = "010"b3;
477 l4_data (3) = "001"b3;
478 buffer.tally = hdr_size + 3 + L2_HEADER_PAD;
479 call write_data_pkt;
480 xlce.iti_params (8) = 1;
481 end;
482 end;
483
484 else if order = "input_flow_control_chars" then do;
485 if (ifci.suspend_seq.count ^= 1) | (ifci.resume_seq.count ^= 1)
486 | (substr (ifci.suspend_seq.chars, 1, 1) ^= "^S" )
487 | (substr (ifci.resume_seq.chars, 1, 1) ^= "^Q" )
488 then x25_code = et_bad_arg;
489 end;
490
491 else if order = "output_flow_control_chars" then do;
492 if string (ofci.flags) ^= ""b
493 & ((^ofci.flags.suspend_resume) | (ofci.suspend_or_etb_seq.count > 1)
494 | (ofci.resume_or_ack_seq.count > 1)
495 | (substr (ofci.suspend_or_etb_seq.chars, 1, 1) ^= "^S" )
496 | (substr (ofci.resume_or_ack_seq.chars, 1, 1) ^= "^Q" ))
497 then x25_code = et_bad_arg;
498 end;
499
500 else if order = "set_framing_chars" then ;
501
502 else if xlce.flags.iti_call & xlce.flags.originate & (order = "get_foreign_terminal_data") then do;
503 if ftd.version ^= FOREIGN_TERMINAL_DATA_VERSION_1 then do;
504 x25_code = et_unimplemented_version;
505 return;
506 end;
507 number_of_modes = 7;
508 allocate mode_string_info in (ftd.area_ptr -> based_area) set (mode_string_info_ptr);
509 mode_string_info.version = mode_string_info_version_2;
510 do i = 1 to number_of_modes;
511 mode_string_info.modes (i).version = mode_value_version_3;
512 mode_string_info.modes (i).mode_name = mode_names (i);
513 mode_string_info.modes (i).flags.boolean_valuep = "1"b;
514 end;
515 mode_string_info.modes (MODE_RAWI).boolean_value = (xlce.iti_params (1) = 0);
516 mode_string_info.modes (MODE_ECHOPLEX).boolean_value = (xlce.iti_params (2) ^= 0);
517 mode_string_info.modes (MODE_BREAKALL).boolean_value = (xlce.iti_params (4) ^= 0);
518 mode_string_info.modes (MODE_IFLOW).boolean_value = (xlce.iti_params (5) ^= 0);
519 mode_string_info.modes (MODE_OFLOW).boolean_value = (xlce.iti_params (12) ^= 0);
520 mode_string_info.modes (MODE_HNDLQUIT).boolean_value = (xlce.iti_params (7) = 21);
521 mode_string_info.modes (MODE_LFECHO).boolean_value = (xlce.iti_params (13) ^= 0);
522
523 ftd.mode_string_info_ptr = mode_string_info_ptr;
524 xsce.flags.need_ftd = "1"b;
525 end;
526
527 else x25_code = et_undefined_order_request;
528
529 return;
530 %page;
531
532
533 check_modes:
534 entry (X25_data_ptr, X25_scx, x25_mclp, x25_code);
535
536 set_entry = "0"b;
537 goto modes_common;
538
539
540
541 set_modes:
542 entry (X25_data_ptr, X25_scx, x25_mclp, x25_code);
543
544 set_entry = "1"b;
545 modes_common:
546 call setup_subchan;
547 if xlcep = null () then do;
548 x25_code = et_invalid_state;
549 return;
550 end;
551 x25_code = 0;
552 mclp = x25_mclp;
553
554 if mcl.version ^= mcl_version_2 then do;
555 x25_code = et_unimplemented_version;
556 return;
557 end;
558
559 if set_entry then do;
560 if mcl.init then do;
561 string (xsce.mode) = ""b;
562 end;
563 end;
564
565 do i = 1 to mcl.n_entries;
566 mclep = addr (mcl.entries (i));
567 mode_found = "0"b;
568 do j = 1 to dimension (mode_names, 1);
569 if mcle.mode_name = mode_names (j) then do;
570 mode_found = "1"b;
571 if set_entry
572 then if mcle.mpx_mode
573 then xsce.mode (j) = mcle.mode_switch;
574 else ;
575 else mcle.mpx_mode = "1"b;
576 end;
577 end;
578
579 if ^mode_found
580 then if set_entry
581 then if mcle.mpx_mode & ^mcle.force then do;
582
583 mcle.error = "1"b;
584 x25_code = et_bad_mode;
585 end;
586 else ;
587 else mcle.mpx_mode = "0"b;
588 end;
589
590 if set_entry then do;
591
592
593
594 if xsce.mode (MODE_8BIT) then do;
595 if xsce.mode (MODE_LFECHO)
596 then xsce.trans_table_ptr = addr (x25_mpx_data$trans_parity_lfecho);
597 else xsce.trans_table_ptr = null ();
598 end;
599
600 else if xsce.mode (MODE_LFECHO) then xsce.trans_table_ptr = addr (x25_mpx_data$trans_no_parity_lfecho);
601
602 else xsce.trans_table_ptr = addr (x25_mpx_data$trans_no_parity);
603
604
605
606
607 if xlce.flags.iti_call & ^xlce.flags.originate then do;
608 call get_buffer (16);
609 call make_header (lcx, "1"b);
610 l4_data (1) = "002"b3;
611 nchars = 1;
612
613
614
615 call add_iti_mode (MODE_RAWI, 1, 0, 1);
616 call add_iti_mode (MODE_ECHOPLEX, 2, 1, 0);
617 call add_iti_mode (MODE_BREAKALL, 3, 0, 2);
618 call add_iti_mode (MODE_BREAKALL, 4, (x25_data.breakall_idle_timer), 0);
619
620 call add_iti_mode (MODE_IFLOW, 5, 1, 0);
621 call add_iti_mode (MODE_HNDLQUIT, 7, 21, 1);
622 call add_iti_mode (MODE_OFLOW, 12, 1, 0);
623 call add_iti_mode (MODE_LFECHO, 13, 4, 0);
624
625 call add_iti_param (10, 0);
626 call add_iti_param (15, 0);
627
628
629
630 if x25_data.net_type = "datapac" then do;
631 call add_iti_param (0, 0);
632 call add_iti_mode (MODE_POLITE, 125, 30, 0);
633 call add_iti_mode (MODE_LFECHO, 126, 4, 0);
634 end;
635
636 else if x25_data.net_type = "telenet" then do;
637 call add_iti_param (0, 33);
638 call add_iti_mode (MODE_LFECHO, 1, 4, 0);
639 end;
640
641 else if x25_data.net_type = "tymnet" then ;
642
643 else ;
644
645 buffer.tally = hdr_size + nchars + L2_HEADER_PAD;
646 call write_data_pkt;
647 end;
648 end;
649
650
651
652 return;
653
654
655
656 get_modes:
657 entry (X25_data_ptr, X25_scx, x25_modes, x25_code);
658
659 x25_code = 0;
660 x25_modes = "";
661 return;
662 %page;
663
664
665 write:
666 entry (X25_data_ptr, X25_scx, x25_chain_ptr, x25_code);
667
668 call setup_subchan;
669 if xlcep = null () then do;
670 x25_code = et_invalid_state;
671 return;
672 end;
673 x25_code = 0;
674
675 protocol_mpx = get_protocol_sc ();
676
677 xsce.flags.output_ready = "0"b;
678
679 if xlce.flags.iti_break then return;
680
681 do chain_ptr = x25_chain_ptr repeat (leftover_chain_ptr)
682 while ((chain_ptr ^= null ()) & ^xsce.flags.end_of_page);
683 nchars = 0;
684 prev_blockp = null ();
685 do blockp = chain_ptr repeat (pointer (blockp, buffer.next));
686 nchars = nchars + buffer.tally;
687 call mvt_ (addr (buffer.chars), addr (buffer.chars), (buffer.tally), x25_mpx_data$eight_bit);
688 if (nchars > xlce.max_packet_size) | (buffer.next = 0) | buffer.flags.end_of_page | buffer.flags.break
689 then goto end_chain;
690 string (buffer.flags) = ""b;
691 prev_blockp = blockp;
692 end;
693
694
695
696
697
698
699
700
701
702
703 end_chain:
704 if nchars > xlce.max_packet_size then do;
705 prev_blockp -> buffer.next = 0;
706 leftover_chain_ptr = blockp;
707 endp = prev_blockp;
708 end;
709
710 else do;
711 endp = blockp;
712 if buffer.next = 0
713 then leftover_chain_ptr = null ();
714 else do;
715 leftover_chain_ptr = pointer (blockp, buffer.next);
716 buffer.next = 0;
717 end;
718 end;
719
720
721
722
723
724
725
726
727
728 xsce.flags.end_of_page = endp -> buffer.flags.end_of_page;
729
730 blockp = chain_ptr;
731 if x25_data.seq_mod = 8 then do;
732 hdr_size = 3;
733 l4_data_ptr = addr (m8_fc_data.user_data);
734 end;
735 else do;
736 hdr_size = 4;
737 l4_data_ptr = addr (m128_fc_data.user_data);
738 end;
739 call mrl_ (addr (buffer.chars), (buffer.tally), l4_data_ptr, (buffer.tally));
740 buffer.tally = buffer.tally + hdr_size + L2_HEADER_PAD;
741
742 call make_header (lcx, "0"b);
743 x25_pkt.type = "00"b4;
744
745
746
747
748
749
750
751 if protocol_mpx then do;
752 if ^xlce.flags.iti_call & ^endp -> buffer.flags.break
753 then if x25_data.seq_mod = 8
754 then m8_fc_data.m = "1"b;
755 else m128_fc_data.m = "1"b;
756 end;
757
758 call tty_space_man$switch_chain (xsce.devx, x25_data.devx, OUTPUT, OUTPUT, blockp);
759 string (endp -> buffer.flags) = ""b;
760 call write_data_pkt;
761 end;
762
763 call solicit_output;
764 x25_chain_ptr = chain_ptr;
765 x25_code = 0;
766 return;
767 %page;
768
769
770 interrupt:
771 entry (X25_data_ptr, x25_int_type, x25_int_data);
772
773 x25_data_ptr = X25_data_ptr;
774 int_type = x25_int_type;
775 int_data = x25_int_data;
776 xscep, xlcep = null ();
777
778 if (int_type < lbound (INTERRUPT, 1)) | (int_type > hbound (INTERRUPT, 1))
779 then goto bad_interrupt;
780 else goto INTERRUPT (int_type);
781
782
783 INTERRUPT (1):
784 if x25_data.state ^= X25_LISTENING then goto bad_interrupt;
785 unspec (x25_data.dialup_info) = int_data;
786 if ^x25_data.flags.bypass_restart then call restart (0);
787 return;
788
789
790 INTERRUPT (2):
791 call pxss$ring_0_wakeup (x25_data.load_proc_id, x25_data.load_ev_chan, MPX_DOWN, code);
792
793 if x25_data.state ^= X25_HUNGUP then do;
794 call crash_subchannels;
795 call x25_hangup;
796 end;
797
798 return;
799
800 INTERRUPT (3):
801 if x25_data.state ^= X25_HUNGUP then do;
802 call crash_subchannels;
803 call x25_hangup;
804 end;
805
806 return;
807
808 INTERRUPT (9):
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825 if lap_down_status.link_down_status = 1
826 then call syserr (Log_message,
827 "x25_mpx(^a): Failure, Link state: ^d, Current action: ^d, in ^d, Primary state: ^d, Secondary state: ^d",
828 x25_data.name, lap_down_status.main_state, lap_down_status.last_function_process,
829 lap_down_status.which_state_process, lap_down_status.primary_sub_state,
830 lap_down_status.secondary_sub_state);
831
832 else if lap_cmdr_status.cmdr_status = 3
833 then call syserr (Log_message,
834 "x25_mpx(^a): Link disconnected due to mis-matched frame sizes. CMDR/FRMR frame: ^( ^.4b^).",
835 x25_data.name, lap_cmdr_status.cmdr_bytes.byte (*));
836
837 else goto bad_interrupt;
838
839 return;
840
841
842 INTERRUPT (4):
843 x25_data.flags.send_output = "1"b;
844
845 if (x25_data.long_packet_head ^= 0) & (x25_data.write_head = null ()) then do;
846 scx = x25_data.long_packet_head;
847 xscep = addr (x25_data.sc (scx));
848 lcx = xsce.lcx;
849 xlcep = addr (x25_lces.lc (lcx));
850 x25_data.long_packet_head = xsce.long_packet_next_scx;
851 if x25_data.long_packet_head = 0 then x25_data.long_packet_tail = 0;
852 xsce.flags.long_packet_pending = "0"b;
853 call send_data_packets;
854 end;
855
856 call send_output;
857 return;
858
859
860 INTERRUPT (5):
861 INTERRUPT (10):
862 INTERRUPT (11):
863 bad_interrupt:
864 call syserr (Log_message, "x25_mpx(^a): Unexpected interrupt ^d ^.3b received.", x25_data.name, int_type,
865 int_data);
866
867 INTERRUPT (7):
868 INTERRUPT (8):
869 INTERRUPT (12):
870 INTERRUPT (13):
871 INTERRUPT (14):
872 INTERRUPT (16):
873 return;
874
875 INTERRUPT (17):
876 call pxss$ring_0_wakeup (x25_data.load_proc_id, x25_data.load_ev_chan, MPX_MASKED, code);
877
878 if x25_data.state ^= X25_HUNGUP then do;
879 call crash_subchannels;
880 x25_data.state = X25_HUNGUP;
881 end;
882
883 return;
884
885 INTERRUPT (15):
886 unspec (timer_info) = int_data;
887 lcx = timer_info.subchan_idx;
888
889 if lcx = 0 then do;
890 if (x25_data.state = X25_RESTARTING) & (clock () > x25_data.restart_time + T20) then do;
891 call restart (52);
892 end;
893 return;
894 end;
895
896 xlcep = addr (x25_lces.lc (lcx));
897 xlce.flags.timer_set = "0"b;
898 scx = xlce.scx;
899 xscep = addr (x25_data.sc (scx));
900 protocol_mpx = get_protocol_sc ();
901
902 if xlce.state = FLOW_CONTROL_READY then do;
903 call send_rr;
904 return;
905 end;
906
907 if clock () > xlce.state_time + T20 then do;
908 call syserr (Log_message, "x25_mpx(^a/^d): Time out in state ^d.", x25_data.name, lcx, xlce.state);
909 if xlce.state = DTE_WAITING then do;
910 call clear_call (49);
911 return;
912 end;
913 else if xlce.state = DTE_RESET_REQUEST then do;
914 call clear_call (51);
915 return;
916 end;
917 else if xlce.state = DTE_CLEAR_REQUEST then do;
918 call clear_call (50);
919 return;
920 end;
921 else if protocol_mpx & (xlce.state = CONRESP_WAITING) then do;
922 call clear_call (48);
923 return;
924 end;
925 end;
926
927 return;
928 %page;
929 INTERRUPT (6):
930 unspec (rtx_info) = int_data;
931 chain_ptr, blockp = pointer (x25_data_ptr, rtx_info.chain_head);
932 endp = pointer (x25_data_ptr, rtx_info.chain_tail);
933
934 if buffer.tally < L2_HEADER_PAD + 3 then do;
935 call syserr (Log_message, "x25_mpx(^a): Packet too short.", x25_data.name);
936 call dump_pkt;
937 call send_diag (38);
938 goto done_in_pkt;
939 end;
940
941 if x25_pkt.l3_header.format ^= x25_data.gfid then do;
942
943 call syserr (Log_message, "x25_mpx(^a): Unrecognized general format ID ^b^b^2b.", x25_data.name,
944 x25_pkt.l3_header.q, x25_pkt.l3_header.d, x25_pkt.l3_header.format);
945 call dump_pkt;
946 call send_diag (40);
947 goto done_in_pkt;
948 end;
949
950 lcx = binary (x25_pkt.l3_header.lcgn || x25_pkt.l3_header.lcn, 12);
951
952
953
954 if lcx > x25_data.n_lc then do;
955 call syserr (Log_message, "x25_mpx(^a): Invalid channel number ^d.", x25_data.name, lcx);
956 call dump_pkt;
957 call send_diag (36);
958 goto done_in_pkt;
959 end;
960 %page;
961 protocol_mpx = "0"b;
962 if x25_data.state = X25_ACTIVE then do;
963 if lcx = 0 then do;
964
965
966
967 if x25_pkt.type = RSRTRQ then do;
968 call crash_subchannels;
969 call free_in_pkt;
970 call get_buffer (16);
971 call make_header (0, "0"b);
972 x25_pkt.type = RSRTCN;
973 buffer.tally = 3 + L2_HEADER_PAD;
974 call write_pkt;
975 call send_output;
976 goto done_in_pkt;
977 end;
978
979
980
981 if x25_pkt.type = RSRTCN then do;
982 call free_in_pkt;
983 call restart (16);
984 goto done_in_pkt;
985 end;
986
987
988
989 if x25_pkt.type = DIAG then do;
990 call syserr (Log_message, "x25_mpx(^a): Diagnostic type ^d.", x25_data.name,
991 binary (x25_pkt.no_fc_data (1), 8));
992 call dump_pkt;
993 goto done_in_pkt;
994 end;
995
996 call syserr (Log_message, "x25_mpx(^a): Invalid packet type ^.4b on LC 0.", x25_data.name,
997 x25_pkt.type);
998 call dump_pkt;
999 goto done_in_pkt;
1000 end;
1001 %page;
1002
1003
1004 xlcep = addr (x25_lces.lc (lcx));
1005 scx = xlce.scx;
1006 if scx > 0 then do;
1007 xscep = addr (x25_data.sc (scx));
1008 protocol_mpx = get_protocol_sc ();
1009
1010 if protocol_mpx
1011 then if x25_data.packet_trace_sw then call log_packet ("0"b);
1012 %page;
1013
1014
1015 if substr (x25_pkt.type, 8, 1) = "0"b then do;
1016
1017 if xlce.state ^= FLOW_CONTROL_READY then do;
1018 call handle_data_or_fc_error;
1019 goto done_in_pkt;
1020 end;
1021
1022
1023 call proc_pr (pr_error);
1024 if pr_error then goto done_in_pkt;
1025
1026 if x25_data.seq_mod = 8
1027 then do;
1028 temp_ps = m8_fc_data.ps;
1029 hdr_size = 3;
1030 l4_data_ptr = addr (m8_fc_data.user_data);
1031 rtx_info.break_char, endp -> buffer.flags.break = ^m8_fc_data.m;
1032 end;
1033 else do;
1034 temp_ps = m128_fc_data.ps;
1035 hdr_size = 4;
1036 l4_data_ptr = addr (m128_fc_data.user_data);
1037 rtx_info.break_char, endp -> buffer.flags.break = ^m128_fc_data.m;
1038 end;
1039
1040 if temp_ps ^= xlce.next_recv_seq then do;
1041
1042 call syserr (Log_message, "x25_mpx(^a): Sequence error P(S)=^d V(R)=^d.", xsce.name,
1043 temp_ps, xlce.next_recv_seq);
1044 call dump_pkt;
1045 call reset_lc (1);
1046 goto done_in_pkt;
1047 end;
1048
1049 xlce.next_recv_seq = mod (xlce.next_recv_seq + 1, x25_data.seq_mod);
1050
1051 if x25_pkt.l3_header.d
1052 then xlce.force_ack_time = 0;
1053 else xlce.force_ack_time = clock () + TIMEOUT;
1054
1055
1056 if x25_pkt.l3_header.q then do;
1057 if ^xlce.flags.iti_call then do;
1058
1059 int_data = substr (string (l4_data), 1, 72);
1060 call channel_manager$interrupt (xsce.devx, LINE_STATUS, int_data);
1061 end;
1062 else do;
1063 i = binary (l4_data (1), 8);
1064
1065 if i > hbound (iti, 1) then do;
1066 call syserr (Log_message, "x25_mpx(^a): Invalid X.29 command ^d.", xsce.name, i);
1067 call dump_pkt;
1068 call get_buffer (16);
1069 call make_header (lcx, "1"b);
1070 l4_data (1) = "005"b3;
1071 l4_data (2) = "001"b3;
1072 l4_data (3) = bit (binary (i, 9));
1073 buffer.tally = hdr_size + 3 + L2_HEADER_PAD;
1074 call write_data_pkt;
1075 goto done_data_pkt;
1076 end;
1077 else goto iti (i);
1078
1079 iti (0):
1080 do i = 2 by 2 to buffer.tally - hdr_size - L2_HEADER_PAD;
1081 if l4_data (i) = "00000000"b then goto done_data_pkt;
1082
1083
1084
1085
1086
1087
1088
1089 if xlce.flags.iti_break & (l4_data (i) = "000001000"b)
1090
1091 & (l4_data (i + 1) = "000000000"b) then do;
1092 call free_in_pkt;
1093 call confirm_interrupt;
1094 xlce.flags.iti_break = "0"b;
1095 end;
1096 end;
1097 goto done_data_pkt;
1098
1099 iti (1):
1100 call free_in_pkt;
1101 call clear_call (0);
1102 goto done_in_pkt;
1103
1104 iti (2):
1105 call set_x29 ("1"b, "0"b);
1106 goto done_data_pkt;
1107
1108 iti (3):
1109 if xlce.flags.iti_break then do;
1110 call channel_manager$interrupt (xsce.devx, QUIT, ""b);
1111 call free_in_pkt;
1112 call get_buffer (16);
1113 call make_header (lcx, "1"b);
1114 substr (string (l4_data), 1, 3 * 9) = "006010000"b3;
1115 buffer.tally = hdr_size + 3 + L2_HEADER_PAD;
1116
1117 call write_data_pkt;
1118 xsce.flags.end_of_page = "0"b;
1119 end;
1120 goto done_data_pkt;
1121
1122 iti (4):
1123 call set_x29 ("0"b, "1"b);
1124 goto done_data_pkt;
1125
1126 iti (5):
1127 call syserr (Log_message, "x25_mpx(^a): X.29 ERROR ^d/^d", xsce.name,
1128 binary (l4_data (2), 9), binary (l4_data (3), 9));
1129 goto done_data_pkt;
1130
1131 iti (6):
1132 call set_x29 ("1"b, "1"b);
1133 goto done_data_pkt;
1134 end;
1135 goto done_data_pkt;
1136 end;
1137
1138
1139
1140 if xlce.flags.iti_break then goto done_data_pkt;
1141
1142 nchars = buffer.tally - hdr_size - L2_HEADER_PAD;
1143 if nchars <= 0 then goto done_data_pkt;
1144
1145
1146 substr (string (buffer.chars), 1, nchars) =
1147 substr (string (buffer.chars), hdr_size + L2_HEADER_PAD + 1, nchars);
1148 buffer.tally = nchars;
1149
1150 rtx_info.output_in_ring_0 = (xsce.write_head ^= null ());
1151 rtx_info.output_in_fnp = (xlce.next_send_seq ^= xlce.next_ack_seq);
1152 rtx_info.input_count = rtx_info.input_count - hdr_size - L2_HEADER_PAD;
1153
1154 if xsce.trans_table_ptr ^= null () then do;
1155 do blockp = chain_ptr repeat (pointer (blockp, buffer.next)) while (rel (blockp) ^= ""b);
1156
1157 call mvt_ (addr (buffer.chars), addr (buffer.chars), (buffer.tally),
1158 xsce.trans_table_ptr -> based_trans_table);
1159 end;
1160 blockp = chain_ptr;
1161 end;
1162
1163 if xsce.flags.end_of_page & rtx_info.break_char then do;
1164 xsce.flags.end_of_page = "0"b;
1165
1166 if (buffer.tally <= 2) & (buffer.next = 0)
1167 & (verify (substr (string (buffer.chars), 1, buffer.tally), CR_LF_FF) = 0)
1168 then goto done_data_pkt;
1169 end;
1170
1171 blockp = null ();
1172 call tty_space_man$switch_chain (x25_data.devx, xsce.devx, INPUT, INPUT, chain_ptr);
1173 call channel_manager$interrupt (xsce.devx, ACCEPT_INPUT, unspec (rtx_info));
1174 goto done_data_pkt;
1175 end;
1176 %page;
1177
1178
1179 if (x25_pkt.type & SNMASK) = SNRR then do;
1180
1181 if xlce.state ^= FLOW_CONTROL_READY then do;
1182 call handle_data_or_fc_error;
1183 goto done_in_pkt;
1184 end;
1185
1186 call proc_pr (pr_error);
1187 if pr_error then goto done_in_pkt;
1188
1189 xlce.flags.rnr_received = "0"b;
1190 call free_in_pkt;
1191 call send_data_packets;
1192 call send_output;
1193 call solicit_output;
1194 goto done_in_pkt;
1195 end;
1196
1197
1198
1199 if (x25_pkt.type & SNMASK) = SNRNR then do;
1200
1201 if xlce.state ^= FLOW_CONTROL_READY then do;
1202 call handle_data_or_fc_error;
1203 goto done_in_pkt;
1204 end;
1205
1206 call proc_pr (pr_error);
1207 if pr_error then goto done_in_pkt;
1208
1209 xlce.flags.rnr_received = "1"b;
1210 call free_in_pkt;
1211 goto done_in_pkt;
1212 end;
1213
1214
1215
1216 if (x25_pkt.type & SNMASK) = SNREJ then do;
1217 if xlce.state ^= FLOW_CONTROL_READY then do;
1218 call handle_data_or_fc_error;
1219 goto done_in_pkt;
1220 end;
1221
1222 call proc_pr (pr_error);
1223 if pr_error then goto done_in_pkt;
1224
1225 call syserr (Log_message, "x25_mpx(^a): Received REJ packet.", xsce.name);
1226 call dump_pkt;
1227 call reset_lc (37);
1228 goto done_in_pkt;
1229 end;
1230 %page;
1231
1232
1233 if x25_pkt.type = CALLRQ then do;
1234 if xlce.state = FLOW_CONTROL_READY | xlce.state = DTE_RESET_REQUEST then do;
1235 call syserr (Log_message, "x25_mpx(^a): Call Request in state ^d.", xsce.name, xlce.state);
1236 call dump_pkt;
1237 call clear_call (23);
1238 end;
1239
1240 else call free_in_pkt;
1241
1242 goto done_in_pkt;
1243 end;
1244
1245
1246
1247 if x25_pkt.type = CALLAC then do;
1248 if xlce.state = DTE_WAITING then do;
1249 if protocol_mpx & ^xlce.iti_call then do;
1250
1251 call set_up_dialup_info;
1252 call channel_manager$interrupt (xsce.devx, USER_INTERRUPT, unspec (dialup_info));
1253 xsce.state = SC_DIALED;
1254 xlce.state = FLOW_CONTROL_READY;
1255 call reset_timer;
1256 xsce.flags.output_ready = "1"b;
1257 call channel_manager$interrupt (xsce.devx, SEND_OUTPUT, ""b);
1258 end;
1259 else call signal_dialup;
1260 call free_in_pkt;
1261 goto done_in_pkt;
1262 end;
1263
1264 call syserr (Log_message, "x25_mpx(^a): Call Confirm in state ^d.", xsce.name, xlce.state);
1265 call dump_pkt;
1266 call clear_call (16);
1267 goto done_in_pkt;
1268 end;
1269
1270
1271
1272 if x25_pkt.type = CLRRQ then do;
1273 if protocol_mpx & (x25_pkt.no_fc_data (1) ^= ""b)
1274 | ^protocol_mpx & ((x25_pkt.no_fc_data (1) ^= ""b) | (x25_pkt.no_fc_data (2) ^= ""b))
1275 then call syserr (Log_message_or_discard, "x25_mpx(^a): Clear Indication ^d/^d.", xsce.name,
1276 binary (x25_pkt.no_fc_data (1), 8), binary (x25_pkt.no_fc_data (2), 8));
1277 if protocol_mpx then do;
1278 disconnect_info.cause = x25_pkt.no_fc_data (1);
1279 disconnect_info.diag = x25_pkt.no_fc_data (2);
1280 end;
1281 call free_in_pkt;
1282 if xlce.state ^= DTE_CLEAR_REQUEST then call clear_confirm;
1283 call proc_clear;
1284 goto done_in_pkt;
1285 end;
1286
1287
1288
1289 if x25_pkt.type = CLRCN then do;
1290 if xlce.state ^= DTE_CLEAR_REQUEST then do;
1291 call syserr (Log_message, "x25_mpx(^a): Clear Confirm in state ^d.", xsce.name, xlce.state);
1292 call dump_pkt;
1293 call clear_call (16);
1294 end;
1295
1296 else do;
1297 call proc_clear;
1298 call free_in_pkt;
1299 end;
1300
1301 goto done_in_pkt;
1302 end;
1303 %page;
1304
1305
1306 if xlce.state = DTE_CLEAR_REQUEST then do;
1307 call free_in_pkt;
1308 goto done_in_pkt;
1309 end;
1310
1311 if xlce.state = DTE_WAITING | (protocol_mpx & (xlce.state = CONRESP_WAITING)) then do;
1312 call syserr (Log_message, "x25_mpx(^a): Data packet received in state ^d.", xsce.name,
1313 xlce.state);
1314 call dump_pkt;
1315 call clear_call (16);
1316 goto done_in_pkt;
1317 end;
1318
1319
1320
1321 if x25_pkt.type = RESTRQ then do;
1322 if xlce.state ^= DTE_RESET_REQUEST then do;
1323
1324 call syserr (Log_message, "x25_mpx(^a): Reset received ^d/^d", xsce.name,
1325 binary (x25_pkt.no_fc_data (1), 8), binary (x25_pkt.no_fc_data (2), 8));
1326 call dump_pkt;
1327 call get_buffer (16);
1328 call make_header (lcx, "0"b);
1329 x25_pkt.type = RESTCN;
1330 buffer.tally = 3 + L2_HEADER_PAD;
1331 call write_pkt;
1332 call send_output;
1333 end;
1334 else call free_in_pkt;
1335
1336 call proc_reset_lc;
1337 goto done_in_pkt;
1338 end;
1339
1340
1341
1342 if x25_pkt.type = RESTCN then do;
1343 if xlce.state = DTE_RESET_REQUEST
1344 then do;
1345 call proc_reset_lc;
1346 call free_in_pkt;
1347 end;
1348 else do;
1349 call syserr (Log_message, "x25_mpx(^a): Reset Confirm in state ^d.", xsce.name, xlce.state);
1350 call dump_pkt;
1351 call reset_lc (16);
1352 end;
1353 goto done_in_pkt;
1354 end;
1355 %page;
1356
1357
1358 if xlce.state ^= FLOW_CONTROL_READY then do;
1359 call free_in_pkt;
1360 goto done_in_pkt;
1361 end;
1362
1363
1364
1365 if x25_pkt.type = SNITRQ then do;
1366 call free_in_pkt;
1367 if xlce.iti_call & xsce.mode (MODE_HNDLQUIT)
1368
1369 then do;
1370 xlce.flags.iti_break = "1"b;
1371 end;
1372 else do;
1373 call channel_manager$interrupt (xsce.devx, QUIT, ""b);
1374
1375 call confirm_interrupt;
1376 xsce.flags.end_of_page = "0"b;
1377 end;
1378 goto done_in_pkt;
1379 end;
1380
1381
1382
1383 if x25_pkt.type = SNITCN then do;
1384 if ^xlce.flags.int_issued then do;
1385 call syserr (Log_message, "x25_mpx(^a): Unexpected Interrupt Confirm.", xsce.name);
1386 call dump_pkt;
1387 call reset_lc (43);
1388 end;
1389 else do;
1390 xlce.flags.int_issued = "0"b;
1391 call free_in_pkt;
1392 end;
1393 goto done_in_pkt;
1394 end;
1395
1396 call syserr (Log_message, "x25_mpx(^a): Unexpected packet type ^.4b", xsce.name, x25_pkt.type);
1397 call dump_pkt;
1398 call reset_lc (32);
1399 goto done_in_pkt;
1400 end;
1401 %page;
1402
1403
1404 else do;
1405
1406
1407
1408 if x25_pkt.type = CALLRQ then do;
1409 if xlce.state ^= READY then do;
1410 call syserr (Log_message, "x25_mpx(^a/^d): Call Request in state ^d.", x25_data.name, lcx,
1411 xlce.state);
1412 call dump_pkt;
1413 call clear_call (16);
1414 goto done_in_pkt;
1415 end;
1416
1417 calling_dte_addr_length = binary (substr (x25_pkt.no_fc_data (1), 2, 4), 4);
1418 called_dte_addr_length = binary (substr (x25_pkt.no_fc_data (1), 6, 4), 4);
1419 facility_disp = 2 + divide (1 + calling_dte_addr_length + called_dte_addr_length, 2, 6, 0);
1420 facility_length = binary (substr (x25_pkt.no_fc_data (facility_disp), 4, 6), 6);
1421
1422 do i = 2 to facility_disp - 1;
1423 unspec (substr (addr_string, 2 * i - 3, 1)) =
1424 "00011"b || substr (x25_pkt.no_fc_data (i), 2, 4);
1425 unspec (substr (addr_string, 2 * i - 2, 1)) =
1426 "00011"b || substr (x25_pkt.no_fc_data (i), 6, 4);
1427 end;
1428 xlce.his_address = substr (addr_string, 1 + called_dte_addr_length, calling_dte_addr_length);
1429
1430 user_data_disp = facility_disp + facility_length + 1;
1431 user_data_length = buffer.tally - 2 - user_data_disp - L2_HEADER_PAD;
1432 if protocol_mpx then do;
1433 xlce.baud_rate = DEFAULT_BAUD;
1434 xlce.call_data = "";
1435 if user_data_length >= 4 & x25_pkt.no_fc_data (user_data_disp) = "000000001"b then do;
1436
1437 xlce.flags.iti_call = "1"b;
1438 if user_data_length > 4 then do;
1439
1440 Call_data = substr (l3_call_data, 5);
1441 call mvt_ (addr (Call_data), addr (Call_data),
1442
1443 user_data_length - 4, (x25_mpx_data$trans_no_parity));
1444 xlce.call_data = substr (Call_data, 1, user_data_length - 4);
1445 end;
1446 scx = find_sc (xlce.call_data);
1447 if scx = 0 then scx = find_sc ("");
1448 if (scx = 0) | ^x25_data.flags.mpx_started then do;
1449 call syserr (Log_message, "x25_mpx(^a/^d): No listening channels. , scx=^d",
1450 x25_data.name, lcx, scx);
1451 call dump_pkt;
1452 call clear_call (64);
1453 goto done_in_pkt;
1454 end;
1455
1456 call check_facilities ();
1457 xscep = addr (x25_data.sc (scx));
1458 xsce.lcx = lcx;
1459 xlce.scx = scx;
1460 call free_in_pkt;
1461 call send_NCON_RESP;
1462 call signal_dialup;
1463 goto done_in_pkt;
1464 end;
1465 else do;
1466 if ^x25_data.flags.mpx_started then do;
1467
1468 call syserr (Log_message, "x25_mpx(^a/^d): No listening ISO_channels.",
1469 x25_data.name, lcx);
1470 call dump_pkt;
1471 call clear_call (64);
1472 goto done_in_pkt;
1473 end;
1474 xscep = addr (x25_data.sc (scx));
1475
1476 xsce.lcx = lcx;
1477 xlce.scx = scx;
1478 xlce.call_data = l3_call_data;
1479 xsce.trans_table_ptr = null ();
1480 NCON_IND_info.his_address = xlce.his_address;
1481 NCON_IND_info.our_address = x25_data.my_address;
1482 NCON_IND_info.data = l3_call_data;
1483 NCON_IND_info.facilities = l3_facilities;
1484 call set_up_dialup_info;
1485 unspec (NCON_IND_info.dial_info) = unspec (dialup_info);
1486 call free_in_pkt;
1487 call get_buffer (32);
1488 call tty_space_man$switch_chain (x25_data.devx, xsce.devx, OUTPUT, INPUT, blockp);
1489 unspec (DIALUP_info) = "0"b;
1490 DIALUP_info.info_relp = rel (blockp);
1491 N_I_i = NCON_IND_info;
1492 buffer.next = 0;
1493 string (buffer.flags) = ""b;
1494 buffer.tally = size (NCON_IND_info) * 4;
1495 xsce.state = SC_DIALING;
1496 call state_change (CONRESP_WAITING);
1497 call channel_manager$interrupt (xsce.devx, DIALUP, unspec (DIALUP_info));
1498 goto done_in_pkt;
1499 end;
1500 end;
1501 else do;
1502 xlce.baud_rate = x25_data.dialup_info.baud_rate;
1503 if user_data_length >= 4 then do;
1504 xlce.call_data = substr (l3_call_data, 5);
1505 if x25_pkt.no_fc_data (user_data_disp) = "000000001"b then do;
1506 xlce.flags.iti_call = "1"b;
1507 end;
1508 end;
1509 else xlce.call_data = "";
1510
1511 scx = find_sc (xlce.call_data);
1512
1513 if scx = 0 then scx = find_sc ("");
1514
1515 if (scx = 0) | ^x25_data.flags.mpx_started then do;
1516 call syserr (Log_message, "x25_mpx(^a/^d): No listening channels.", x25_data.name, lcx)
1517 ;
1518 call dump_pkt;
1519 call clear_call (64);
1520 goto done_in_pkt;
1521 end;
1522
1523 xscep = addr (x25_data.sc (scx));
1524 xsce.lcx = lcx;
1525 xlce.scx = scx;
1526 call free_in_pkt;
1527 call get_buffer (16);
1528 call make_header (lcx, "0"b);
1529 x25_pkt.type = CALLAC;
1530 buffer.tally = 3 + L2_HEADER_PAD;
1531 call write_pkt;
1532 call send_output;
1533 call signal_dialup;
1534 goto done_in_pkt;
1535 end;
1536 end;
1537
1538
1539
1540 if x25_pkt.type = CLRRQ then do;
1541 call syserr (Log_message_or_discard, "x25_mpx(^a/^d): Clear Indication ^d/^d on idle VC.",
1542 x25_data.name, lcx, binary (x25_pkt.no_fc_data (1), 8), binary (x25_pkt.no_fc_data (2), 8));
1543 call dump_pkt;
1544 if xlce.state ^= DTE_CLEAR_REQUEST then call clear_confirm;
1545 call reset_xlce;
1546 goto done_in_pkt;
1547 end;
1548
1549
1550
1551 if x25_pkt.type = CLRCN then do;
1552 if xlce.state = DTE_CLEAR_REQUEST then do;
1553 call reset_xlce;
1554 call free_in_pkt;
1555 goto done_in_pkt;
1556 end;
1557
1558 else do;
1559 call syserr (Log_message_or_discard,
1560 "x25_mpx(^a/^d): Clear Confirm in state ^d on idle VC.", x25_data.name, lcx,
1561 xlce.state);
1562 call free_in_pkt;
1563 call clear_call (20);
1564 goto done_in_pkt;
1565 end;
1566 end;
1567
1568
1569
1570 call syserr (Log_message, "x25_mpx(^a/^d); Unexpected packet type ^.4b on idle VC.", x25_data.name,
1571 lcx, x25_pkt.type);
1572 call dump_pkt;
1573 call clear_call (20);
1574 goto done_in_pkt;
1575 end;
1576 end;
1577 %page;
1578
1579
1580 else if x25_data.state = X25_RESTARTING then do;
1581 if ((x25_pkt.type = RSRTRQ) | (x25_pkt.type = RSRTCN)) & (lcx = 0) then do;
1582 call mcs_timer$reset (x25_data.devx, 0, ""b);
1583 x25_data.state = X25_ACTIVE;
1584 call pxss$ring_0_wakeup (x25_data.load_proc_id, x25_data.load_ev_chan, MPX_UP, code);
1585 end;
1586 call free_in_pkt;
1587 goto done_in_pkt;
1588 end;
1589
1590
1591
1592 else do;
1593 call free_in_pkt;
1594 goto done_in_pkt;
1595 end;
1596 %page;
1597 done_in_pkt:
1598 return;
1599
1600
1601 done_data_pkt:
1602 if blockp ^= null () then call free_in_pkt;
1603 if xlce.state = FLOW_CONTROL_READY then do;
1604 call send_data_packets;
1605 call send_output;
1606 call solicit_output;
1607 call send_rr;
1608 end;
1609 return;
1610 ^L
1611
1612
1613
1614 add_iti_mode:
1615 procedure (Mode, Id, True, False);
1616
1617 dcl Mode fixed bin parameter;
1618 dcl (Id, True, False) uns fixed bin (9) parameter;
1619
1620 if xsce.mode (Mode)
1621 then call add_iti_param (Id, True);
1622 else call add_iti_param (Id, False);
1623 return;
1624 end add_iti_mode;
1625
1626
1627
1628 add_iti_param:
1629 procedure (Id, Value);
1630
1631 dcl (Id, Value) uns fixed bin (9) parameter;
1632
1633 nchars = nchars + 2;
1634 l4_data (nchars - 1) = bit (Id);
1635 l4_data (nchars) = bit (Value);
1636 return;
1637 end add_iti_param;
1638
1639
1640
1641 clear_call:
1642 procedure (Cause);
1643
1644 dcl Cause uns fixed bin (9) parameter;
1645
1646 call get_buffer (16);
1647 call make_header (lcx, "0"b);
1648 x25_pkt.type = CLRRQ;
1649 x25_pkt.no_fc_data (2) = bit (Cause);
1650 buffer.tally = 5 + L2_HEADER_PAD;
1651 call write_pkt;
1652 call send_output;
1653 call state_change (DTE_CLEAR_REQUEST);
1654 return;
1655 end clear_call;
1656
1657
1658
1659 clear_confirm:
1660 procedure;
1661
1662 call get_buffer (16);
1663 call make_header (lcx, "0"b);
1664 x25_pkt.type = CLRCN;
1665 buffer.tally = 3 + L2_HEADER_PAD;
1666 call write_pkt;
1667 call send_output;
1668 return;
1669 end clear_confirm;
1670
1671
1672
1673 confirm_interrupt:
1674 procedure;
1675
1676 call get_buffer (16);
1677 call make_header (lcx, "0"b);
1678 x25_pkt.type = SNITCN;
1679 buffer.tally = 3 + L2_HEADER_PAD;
1680 call write_pkt;
1681 call send_output;
1682 return;
1683 end confirm_interrupt;
1684
1685
1686
1687 crash_subchannels:
1688 procedure;
1689
1690 do lcx = 1 to x25_data.n_lc;
1691 xlcep = addr (x25_lces.lc (lcx));
1692 call reset_xlce;
1693 end;
1694 do scx = 1 to x25_data.n_sc;
1695 xscep = addr (x25_data.sc (scx));
1696 call reset_xsce;
1697 end;
1698 return;
1699 end crash_subchannels;
1700
1701
1702
1703 dump_pkt:
1704 procedure;
1705
1706 dcl 1 dump_buf (buffer.tally) unaligned based (addr (buffer.chars)),
1707 2 pad bit (1),
1708 2 byte bit (8);
1709
1710 call syserr (Log_message_or_discard, "x25_mpx(^a):^( ^.4b^)", x25_data.name, dump_buf.byte (*));
1711 call free_in_pkt;
1712 return;
1713 end dump_pkt;
1714
1715
1716
1717 find_sc:
1718 procedure (Call_data) returns (fixed bin);
1719
1720 dcl Call_data varying char (16) parameter;
1721 dcl scx fixed bin;
1722
1723 do scx = 1 to x25_data.n_sc;
1724 if (x25_data.sc (scx).state = SC_LISTENING) & (x25_data.sc (scx).service = Call_data) then return (scx);
1725 end;
1726 return (0);
1727 end find_sc;
1728
1729
1730
1731 free_in_pkt:
1732 procedure;
1733
1734 call tty_space_man$free_chain (x25_data.devx, INPUT, blockp);
1735 blockp = null ();
1736 return;
1737 end free_in_pkt;
1738
1739
1740
1741 free_write_chain:
1742 procedure;
1743
1744 if xsce.write_head ^= null () then do;
1745 call tty_space_man$free_chain (xsce.devx, OUTPUT, xsce.write_head);
1746 xsce.write_head, xsce.write_tail = null ();
1747 xsce.flags.end_of_page = "0"b;
1748 xsce.flags.long_packet_pending = "0"b;
1749 end;
1750 return;
1751 end free_write_chain;
1752
1753
1754
1755 free_x25_data_chain:
1756 procedure;
1757
1758 if x25_data.write_head ^= null () then do;
1759 call tty_space_man$free_chain (x25_data.devx, OUTPUT, x25_data.write_head);
1760 x25_data.write_head, x25_data.write_tail = null ();
1761 end;
1762 return;
1763 end free_x25_data_chain;
1764
1765
1766
1767 get_buffer:
1768 procedure (Size);
1769
1770 dcl Size fixed bin parameter;
1771
1772 call tty_space_man$get_buffer (x25_data.devx, Size, OUTPUT, blockp);
1773 endp = blockp;
1774 if blockp = null () then do;
1775 call free_x25_data_chain ();
1776 call syserr (Log_message, "x25_mpx(^a): No buffers available", x25_data.name);
1777 call channel_manager$control (x25_data.devx, "hangup", null (), code);
1778
1779 goto done_in_pkt;
1780 end;
1781 return;
1782 end get_buffer;
1783
1784
1785
1786 handle_data_or_fc_error:
1787 procedure;
1788
1789 if xlce.state = DTE_CLEAR_REQUEST | xlce.state = DTE_RESET_REQUEST
1790 then call free_in_pkt;
1791 else do;
1792 call syserr (Log_message, "x25_mpx(^a): Data or flow control packet received in state ^d.", xsce.name,
1793 xlce.state);
1794 call dump_pkt;
1795 if xlce.state = READY
1796 then call clear_call (20);
1797 else call clear_call (21);
1798 end;
1799 end handle_data_or_fc_error;
1800
1801
1802
1803 make_header:
1804 procedure (Lcn, Q);
1805 dcl Lcn uns fixed bin (12) parm;
1806 dcl Q bit aligned parm;
1807
1808 string (x25_pkt.l3_header) = ""b;
1809 x25_pkt.l3_header.q = Q;
1810 x25_pkt.l3_header.format = x25_data.gfid;
1811 x25_pkt.l3_header.lcgn = substr (bit (Lcn), 1, 4);
1812 x25_pkt.l3_header.lcn = substr (bit (Lcn), 5, 8);
1813 if xlcep = null () then do;
1814 l4_data_ptr = null ();
1815 hdr_size = 0;
1816 end;
1817 else if x25_data.seq_mod = 8 then do;
1818 l4_data_ptr = addr (m8_fc_data.user_data);
1819 hdr_size = 3;
1820 end;
1821 else do;
1822 l4_data_ptr = addr (m128_fc_data.user_data);
1823 hdr_size = 4;
1824 end;
1825 return;
1826 end make_header;
1827
1828
1829
1830 proc_clear:
1831 procedure;
1832
1833 call reset_xlce;
1834 call reset_xsce;
1835 return;
1836 end proc_clear;
1837
1838
1839
1840 proc_pr:
1841 procedure (error_flag);
1842
1843 dcl error_flag bit (1) unaligned parameter;
1844 dcl temp_pr unsigned fixed bin (7);
1845
1846 error_flag = "0"b;
1847
1848 xlce.flags.write_status_sync_sent = "0"b;
1849
1850 if x25_data.seq_mod = 8
1851 then temp_pr = m8_fc_data.pr;
1852 else temp_pr = m128_fc_data.pr;
1853
1854
1855
1856
1857
1858
1859
1860
1861 if (xlce.next_ack_seq <= temp_pr & temp_pr <= xlce.next_send_seq)
1862 | (xlce.next_send_seq <= xlce.next_ack_seq & xlce.next_ack_seq <= temp_pr)
1863 | (temp_pr <= xlce.next_send_seq & xlce.next_send_seq <= xlce.next_ack_seq)
1864 then xlce.next_ack_seq = temp_pr;
1865
1866 else do;
1867 error_flag = "1"b;
1868 call syserr (Log_message,
1869 "x25_mpx(^a): Sequence error: P(R) (= ^d) is not between previous P(R) (= ^d) and V(S) (= ^d).",
1870 xsce.name, temp_pr, xlce.next_ack_seq, xlce.next_send_seq);
1871 call dump_pkt;
1872 call reset_lc (2);
1873 end;
1874
1875 return;
1876 end proc_pr;
1877
1878
1879
1880 proc_reset_lc:
1881 procedure;
1882
1883 call reset_seq_nos;
1884 call free_write_chain ();
1885 xlce.state = FLOW_CONTROL_READY;
1886 call reset_timer;
1887
1888
1889
1890 xlce.flags.iti_break = "0"b;
1891 xlce.flags.int_issued = "0"b;
1892 xlce.flags.rnr_received = "0"b;
1893 xlce.flags.write_status_sync_sent = "0"b;
1894
1895
1896
1897 call channel_manager$interrupt (xsce.devx, LINE_STATUS, "1"b);
1898
1899 call solicit_output ();
1900
1901 return;
1902 end proc_reset_lc;
1903
1904
1905
1906 reset_lc:
1907 procedure (Cause);
1908
1909 dcl Cause uns fixed bin (9) parameter;
1910
1911 call get_buffer (16);
1912 call make_header (lcx, "0"b);
1913 x25_pkt.type = RESTRQ;
1914 x25_pkt.no_fc_data (2) = bit (Cause);
1915 buffer.tally = 5 + L2_HEADER_PAD;
1916 call write_pkt;
1917 call send_output;
1918 call state_change (DTE_RESET_REQUEST);
1919
1920 xlce.flags.iti_break, xlce.flags.int_issued, xlce.flags.rnr_received, xlce.flags.write_status_sync_sent = "0"b;
1921 return;
1922 end reset_lc;
1923
1924
1925
1926 reset_seq_nos:
1927 procedure;
1928
1929 xlce.next_recv_seq, xlce.next_send_seq, xlce.last_recv_seq, xlce.next_ack_seq = 0;
1930 return;
1931 end reset_seq_nos;
1932
1933
1934
1935 reset_timer:
1936 procedure;
1937
1938 if xlce.flags.timer_set then do;
1939 call mcs_timer$reset (x25_data.devx, (lcx), ""b);
1940 xlce.flags.timer_set = "0"b;
1941 end;
1942 return;
1943 end reset_timer;
1944
1945
1946
1947 reset_xlce:
1948 procedure;
1949
1950 call reset_seq_nos;
1951 call reset_timer;
1952 string (xlce.flags) = ""b;
1953 xlce.iti_params (*) = 0;
1954
1955 if lcx <= x25_data.n_pvc then do;
1956 xlce.state = FLOW_CONTROL_READY;
1957 end;
1958 else do;
1959 xlce.state = READY;
1960 xlce.scx = 0;
1961 end;
1962 return;
1963 end reset_xlce;
1964
1965
1966
1967 reset_xsce:
1968 procedure;
1969
1970 call free_write_chain;
1971 string (xsce.mode) = ""b;
1972 string (xsce.flags) = ""b;
1973 if xsce.state = SC_DIALING then do;
1974 if protocol_mpx
1975 then call channel_manager$interrupt (xsce.devx, DIAL_STATUS,
1976 "122"b3 || (27)"0"b || unspec (disconnect_info));
1977 else call channel_manager$interrupt (xsce.devx, DIAL_STATUS, "122"b3);
1978 end;
1979 else if xsce.state > SC_HUNGUP then do;
1980 if protocol_mpx then do;
1981 if x25_data.state = X25_ACTIVE
1982 then call channel_manager$interrupt (xsce.devx, HANGUP, (36)"0"b || unspec (disconnect_info));
1983 else call channel_manager$interrupt (xsce.devx, CRASH, (36)"0"b || unspec (disconnect_info));
1984 end;
1985 else do;
1986 if x25_data.state = X25_ACTIVE
1987 then call channel_manager$interrupt (xsce.devx, HANGUP, ""b);
1988 else call channel_manager$interrupt (xsce.devx, CRASH, ""b);
1989 end;
1990 end;
1991 xsce.state = SC_HUNGUP;
1992 xsce.lcx = 0;
1993 return;
1994 end reset_xsce;
1995
1996
1997
1998 restart:
1999 procedure (Cause);
2000
2001 dcl Cause uns fixed bin (9) parameter;
2002
2003 call get_buffer (16);
2004 call make_header (0, "0"b);
2005 x25_pkt.type = RSRTRQ;
2006 x25_pkt.no_fc_data (2) = bit (Cause);
2007 buffer.tally = 5 + L2_HEADER_PAD;
2008 call write_pkt;
2009 call send_output;
2010 x25_data.state = X25_RESTARTING;
2011 x25_data.restart_time = clock ();
2012 call mcs_timer$set (x25_data.devx, 0, x25_data.restart_time + T20, ""b);
2013 return;
2014 end restart;
2015
2016
2017
2018 send_data_packets:
2019 procedure;
2020
2021 dcl pkt_size fixed bin;
2022
2023 if xsce.flags.long_packet_pending | xlce.flags.rnr_received then return;
2024
2025 do while ((mod (xlce.next_send_seq - xlce.next_ack_seq, x25_data.seq_mod) < xlce.max_window_size)
2026 & (xsce.write_head ^= null ()));
2027
2028 blockp = xsce.write_head;
2029 pkt_size = buffer.tally;
2030 do endp = blockp repeat pointer (endp, endp -> buffer.next) while (^endp -> buffer.flags.break);
2031 pkt_size = pkt_size + buffer.tally;
2032 end;
2033
2034 if (pkt_size >= x25_data.long_packet_size)
2035 & (^x25_data.flags.send_output | (x25_data.write_head ^= null ())) then do;
2036 xsce.flags.long_packet_pending = "1"b;
2037 xsce.long_packet_next_scx = 0;
2038 if x25_data.long_packet_head = 0
2039 then x25_data.long_packet_head = scx;
2040 else x25_data.sc (x25_data.long_packet_tail).long_packet_next_scx = scx;
2041 x25_data.long_packet_tail = scx;
2042 return;
2043 end;
2044
2045 if endp -> buffer.next = 0
2046 then xsce.write_head, xsce.write_tail = null ();
2047 else xsce.write_head = pointer (endp, endp -> buffer.next);
2048 endp -> buffer.next = 0;
2049
2050 if x25_data.seq_mod = 8 then do;
2051 m8_fc_data.ps = xlce.next_send_seq;
2052 m8_fc_data.pr = xlce.next_recv_seq;
2053 end;
2054 else do;
2055 m128_fc_data.ps = xlce.next_send_seq;
2056 m128_fc_data.pr = xlce.next_recv_seq;
2057 end;
2058
2059 call write_pkt;
2060
2061 xlce.next_send_seq = mod (xlce.next_send_seq + 1, x25_data.seq_mod);
2062 xlce.last_recv_seq = xlce.next_recv_seq;
2063 end;
2064 return;
2065 end send_data_packets;
2066
2067
2068
2069 send_diag:
2070 procedure (Cause);
2071
2072 dcl Cause uns fixed bin (9) parameter;
2073
2074 call get_buffer (16);
2075 call make_header (0, "0"b);
2076 x25_pkt.type = DIAG;
2077 x25_pkt.no_fc_data (1) = bit (Cause);
2078 buffer.tally = 4 + L2_HEADER_PAD;
2079 call write_pkt;
2080 call send_output;
2081 return;
2082 end send_diag;
2083
2084
2085
2086 send_output:
2087 procedure;
2088
2089 if x25_data.flags.send_output & (x25_data.write_head ^= null ()) then do;
2090 x25_data.flags.send_output = "0"b;
2091 call channel_manager$write (x25_data.devx, x25_data.write_head, code);
2092 if code ^= 0 then do;
2093 call syserr (Log_message, "x25_mpx(^a): Error ^w from write.", x25_data.name, code);
2094 call channel_manager$control (x25_data.devx, "hangup", null (), code);
2095 end;
2096 if x25_data.write_head = null () then x25_data.write_tail = null ();
2097 end;
2098 return;
2099 end send_output;
2100
2101
2102
2103 send_rr:
2104 procedure;
2105
2106 dcl packets_out fixed bin (7);
2107
2108 ttybp = addr (tty_buf$);
2109 lctep = addr (tty_buf.lct_ptr -> lct.lcte_array (xsce.devx));
2110 packets_out = mod (xlce.next_recv_seq - xlce.last_recv_seq, x25_data.seq_mod);
2111
2112 if (3 * lcte.input_words) < tty_buf.bleft
2113 then if (clock () > xlce.force_ack_time) | (packets_out >= xlce.max_window_size) | xlce.flags.rnr_sent then do;
2114 call get_buffer (16);
2115 call make_header (lcx, "0"b);
2116 x25_pkt.type = SNRR;
2117 if x25_data.seq_mod = 8
2118 then m8_fc_data.pr = xlce.next_recv_seq;
2119 else m128_fc_data.pr = xlce.next_recv_seq;
2120 buffer.tally = hdr_size + L2_HEADER_PAD;
2121 call write_pkt;
2122 call send_output;
2123 xlce.last_recv_seq = xlce.next_recv_seq;
2124 call reset_timer;
2125 xlce.flags.rnr_sent = "0"b;
2126 end;
2127 else if packets_out = 0 then ;
2128 else call set_timer (TIMEOUT);
2129
2130 else do;
2131 if ^xlce.flags.rnr_sent then do;
2132 call get_buffer (16);
2133 call make_header (lcx, "0"b);
2134 x25_pkt.type = SNRNR;
2135 if x25_data.seq_mod = 8
2136 then m8_fc_data.pr = xlce.next_recv_seq;
2137 else m128_fc_data.pr = xlce.next_recv_seq;
2138 buffer.tally = hdr_size + L2_HEADER_PAD;
2139 call write_pkt;
2140 call send_output;
2141 xlce.last_recv_seq = xlce.next_recv_seq;
2142 xlce.flags.rnr_sent = "1"b;
2143 end;
2144 call set_timer (TIMEOUT);
2145 end;
2146
2147 return;
2148 end send_rr;
2149
2150
2151
2152 send_sync:
2153 procedure;
2154
2155 if (^x25_data.flags.no_d | ((x25_data.net_type = "tymnet") & (xsce.write_head = null ())))
2156 & ^xlce.flags.rnr_received then do;
2157 call get_buffer (16);
2158 call make_header (lcx, "0"b);
2159 if ^x25_data.flags.no_d then x25_pkt.l3_header.d = "1"b;
2160 buffer.tally = hdr_size + L2_HEADER_PAD;
2161 call write_data_pkt;
2162 xlce.flags.write_status_sync_sent = "1"b;
2163 end;
2164 return;
2165 end send_sync;
2166
2167
2168
2169 set_timer:
2170 procedure (Time);
2171
2172 dcl Time fixed bin (71) parameter;
2173
2174 if ^xlce.flags.timer_set then do;
2175 call mcs_timer$set (x25_data.devx, (lcx), clock () + Time, ""b);
2176 xlce.flags.timer_set = "1"b;
2177 end;
2178 return;
2179 end set_timer;
2180
2181
2182
2183 set_x29:
2184 procedure (Set, Write);
2185
2186 dcl (Set, Write) bit (1) aligned parameter;
2187 dcl write bit (1) aligned;
2188 dcl (i, p) fixed bin;
2189
2190 write = Write;
2191 if Set then do;
2192 do i = 2 by 2 to buffer.tally - hdr_size - L2_HEADER_PAD;
2193 p = binary (substr (l4_data (i), 3, 7), 7);
2194 if (p < lbound (xlce.iti_params, 1)) | (p > hbound (xlce.iti_params, 1)) then do;
2195 write = "1"b;
2196 substr (l4_data (i), 2, 1) = "1"b;
2197 end;
2198 else xlce.iti_params (p) = binary (l4_data (i + 1), 8);
2199 end;
2200 if xsce.flags.need_ftd then do;
2201 call channel_manager$interrupt (xsce.devx, LINE_STATUS, ""b);
2202 xsce.flags.need_ftd = "0"b;
2203 end;
2204 end;
2205
2206 if write then do;
2207
2208
2209
2210 if protocol_mpx then do;
2211 if buffer.tally < hdr_size + L2_HEADER_PAD + 2 then do;
2212 call free_in_pkt;
2213 call get_buffer (16);
2214 call make_header (lcx, "1"b);
2215 l4_data (1) = "000"b3;
2216 do i = 1 to lbound (xlce.iti_params, 1) - 1;
2217
2218 l4_data (2 * i) = substr (unspec (i), 27, 9);
2219 l4_data (2 * i + 1) = "000"b3;
2220 end;
2221 do i = lbound (xlce.iti_params, 1) to hbound (xlce.iti_params, 1);
2222 l4_data (2 * i) = substr (unspec (i), 27, 9);
2223 l4_data (2 * i + 1) = bit (xlce.iti_params (i));
2224 end;
2225 buffer.tally = hdr_size + L2_HEADER_PAD + 2 * hbound (xlce.iti_params, 1) + 1;
2226 call write_data_pkt;
2227 return;
2228 end;
2229 end;
2230 l4_data (1) = "000"b3;
2231 do i = 2 by 2 to buffer.tally - hdr_size - L2_HEADER_PAD;
2232 p = binary (substr (l4_data (i), 3, 7), 7);
2233 if (p >= lbound (xlce.iti_params, 1)) & (p <= hbound (xlce.iti_params, 1))
2234 then l4_data (i + 1) = bit (xlce.iti_params (p));
2235 end;
2236 call tty_space_man$switch_chain (x25_data.devx, x25_data.devx, INPUT, OUTPUT, chain_ptr);
2237 call write_data_pkt;
2238 end;
2239 return;
2240 end set_x29;
2241
2242
2243
2244 setup_subchan:
2245 procedure;
2246
2247 x25_data_ptr = X25_data_ptr;
2248 scx = X25_scx;
2249 xscep = addr (x25_data.sc (scx));
2250 lcx = xsce.lcx;
2251 if lcx = 0
2252 then xlcep = null ();
2253 else xlcep = addr (x25_lces.lc (xsce.lcx));
2254 return;
2255 end setup_subchan;
2256
2257
2258
2259 signal_dialup:
2260 procedure;
2261
2262 dialup_info = x25_data.dialup_info;
2263 dialup_info.line_type = LINE_ASCII;
2264 dialup_info.baud_rate = xlce.baud_rate;
2265 if x25_data.seq_mod = 8
2266 then dialup_info.buffer_pad = dialup_info.buffer_pad + 3 + L2_HEADER_PAD;
2267
2268 else dialup_info.buffer_pad = dialup_info.buffer_pad + 4 + L2_HEADER_PAD;
2269
2270 dialup_info.max_buf_size = min (dialup_info.max_buf_size, divide (xlce.max_packet_size, 4, 9, 0));
2271 call channel_manager$interrupt (xsce.devx, DIALUP, unspec (dialup_info));
2272 xsce.state = SC_DIALED;
2273 xlce.state = FLOW_CONTROL_READY;
2274 call reset_timer;
2275 xsce.flags.output_ready = "1"b;
2276 call channel_manager$interrupt (xsce.devx, SEND_OUTPUT, ""b);
2277 return;
2278 end signal_dialup;
2279
2280
2281
2282 solicit_output:
2283 procedure;
2284
2285 if ^xsce.flags.output_ready & ^xsce.flags.end_of_page & ^xlce.flags.iti_break & (xsce.write_head = null ())
2286 then do;
2287 xsce.flags.output_ready = "1"b;
2288 call channel_manager$interrupt (xsce.devx, SEND_OUTPUT, ""b);
2289 end;
2290 return;
2291 end solicit_output;
2292
2293
2294
2295 state_change:
2296 procedure (State);
2297
2298 dcl State fixed bin;
2299
2300 xlce.state = State;
2301 xlce.state_time = clock ();
2302 call reset_timer;
2303 call set_timer (T20);
2304 return;
2305 end state_change;
2306
2307
2308
2309 write_data_pkt:
2310 procedure;
2311
2312 endp -> buffer.flags.break = "1"b;
2313
2314 if xsce.write_head = null () then do;
2315 xsce.write_head = blockp;
2316 xsce.write_tail = endp;
2317 blockp, endp = null ();
2318 call send_data_packets;
2319 call send_output;
2320 end;
2321 else do;
2322 xsce.write_tail -> buffer.next = binary (rel (blockp), 18);
2323 xsce.write_tail = endp;
2324 blockp, endp = null ();
2325 end;
2326 return;
2327 end write_data_pkt;
2328
2329
2330
2331 write_pkt:
2332 procedure;
2333
2334 endp -> buffer.flags.break = "1"b;
2335 unspec (substr (endp -> buffer.chars (endp -> buffer.tally - 1), 1)) =
2336 unspec (substr (endp -> buffer.chars (endp -> buffer.tally - 1), 1)) | "400"b3;
2337
2338 if protocol_mpx
2339 then if x25_data.packet_trace_sw then call log_packet ("1"b);
2340
2341 if x25_data.write_head = null ()
2342 then x25_data.write_head = blockp;
2343 else x25_data.write_tail -> buffer.next = binary (rel (blockp), 18);
2344 x25_data.write_tail = endp;
2345 blockp, endp = null ();
2346 return;
2347 end write_pkt;
2348
2349
2350
2351 x25_hangup:
2352 procedure;
2353
2354 dcl size builtin;
2355
2356 call mcs_timer$reset_all (x25_data.devx);
2357 call free_x25_data_chain ();
2358
2359 if x25_data.lc_ptr ^= null () then do;
2360 call tty_space_man$free_space (size (x25_lces), x25_data.lc_ptr);
2361 x25_data.lc_ptr = null ();
2362 end;
2363 x25_data.state = X25_HUNGUP;
2364 return;
2365 end x25_hangup;
2366 ^L
2367 log_packet:
2368 procedure (Write_sw);
2369
2370 dcl Write_sw bit (1) parameter;
2371 dcl 1 log_buf (buffer.tally) unaligned based (addr (buffer.chars)),
2372 2 pad bit (1),
2373 2 byte bit (8);
2374 dcl n_octets fixed bin;
2375
2376 if substr (x25_pkt.type, 8, 1) = "0"b & ^x25_pkt.l3_header.q
2377 then n_octets = 5;
2378 else n_octets = buffer.tally;
2379 call syserr (Log_message_or_discard, "x25_mpx(^a): Packet ^[out^;in^]:^v( ^.4b^)", x25_data.name, Write_sw,
2380 n_octets, log_buf.byte (*));
2381 return;
2382 end log_packet;
2383
2384 send_NCON_RESP:
2385 proc;
2386 call get_buffer (16);
2387 call make_header (lcx, "0"b);
2388 x25_pkt.type = CALLAC;
2389 buffer.tally = 3 + L2_HEADER_PAD;
2390 call write_pkt;
2391 call send_output;
2392
2393 end send_NCON_RESP;
2394
2395 check_facilities:
2396 proc;
2397
2398
2399
2400
2401 dcl i fixed bin;
2402 dcl 1 facilities (facility_length) unal based (addr (l3_facilities)),
2403 2 pad bit (1) unal,
2404 2 par_length fixed bin (2) uns unal,
2405 2 code fixed bin (6) uns unal;
2406
2407 xlce.flags.collect_call = "0"b;
2408 i = 1;
2409 do while (i <= facility_length);
2410 if facilities.code (i) = 1
2411 then
2412 if facilities.code (i + 1) = 1 then xlce.flags.collect_call = "1"b;
2413
2414 if facilities.par_length (i) = 3
2415 then
2416 i = i + facilities.code (i + 1) + 2;
2417 else i = i + facilities.par_length (i) + 2;
2418 end;
2419
2420 end check_facilities;
2421
2422 get_protocol_sc:
2423 proc returns (bit (1));
2424
2425 ttybp = addr (tty_buf$);
2426 lctep = addr (tty_buf.lct_ptr -> lct.lcte_array (xsce.devx));
2427 if (lcte.channel_type = PROTOCOL_MPX) then return ("1"b);
2428 return ("0"b);
2429
2430 end get_protocol_sc;
2431
2432 set_up_dialup_info:
2433 proc;
2434
2435 dialup_info = x25_data.dialup_info;
2436 dialup_info.line_type = LINE_ASYNC1;
2437 if x25_data.seq_mod = 8
2438 then dialup_info.buffer_pad = x25_data.dialup_info.buffer_pad + 3 + L2_HEADER_PAD;
2439
2440 else dialup_info.buffer_pad = x25_data.dialup_info.buffer_pad + 4 + L2_HEADER_PAD;
2441
2442 dialup_info.max_buf_size = min (dialup_info.max_buf_size, divide (xlce.max_packet_size, 4, 9, 0));
2443
2444 end set_up_dialup_info;
2445
2446 %page;
2447
2448
2449
2450
2451 system_init:
2452 entry;
2453
2454
2455
2456 et_undefined_order_request = error_table_$undefined_order_request;
2457 et_noalloc = error_table_$noalloc;
2458 et_action_not_performed = error_table_$action_not_performed;
2459 et_bad_arg = error_table_$bad_arg;
2460 et_bad_mode = error_table_$bad_mode;
2461 et_invalid_state = error_table_$invalid_state;
2462 et_resource_unavailable = error_table_$resource_unavailable;
2463 et_unimplemented_version = error_table_$unimplemented_version;
2464
2465 call wire_proc$wire_me;
2466 return;
2467 %page;
2468 %include x25_data;
2469 %include protocol_infos;
2470 %include flow_control_info;
2471 %include foreign_terminal_data;
2472 %include lct;
2473 %include line_types;
2474 %include mcs_modes_change_list;
2475 %include mode_string_info;
2476 %include tty_buf;
2477 %include tty_buffer_block;
2478 %include channel_manager_dcls;
2479 %include mcs_timer_dcls;
2480 %include tty_space_man_dcls;
2481 %include multiplexer_types;
2482
2483
2484
2485 %include syserr_codes;
2486 %page;
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868 end x25_mpx;