3 * ===================================
4 * HARP | Host ATM Research Platform
5 * ===================================
8 * This Host ATM Research Platform ("HARP") file (the "Software") is
9 * made available by Network Computing Services, Inc. ("NetworkCS")
10 * "AS IS". NetworkCS does not provide maintenance, improvements or
11 * support of any kind.
13 * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
14 * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
15 * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
16 * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
17 * In no event shall NetworkCS be responsible for any damages, including
18 * but not limited to consequential damages, arising from or relating to
19 * any use of the Software or related support.
21 * Copyright 1994-1998 Network Computing Services, Inc.
23 * Copies of this Software may be made, however, the above copyright
24 * notice must be reproduced on all copies.
26 * @(#) $FreeBSD: src/sys/netatm/uni/sscop_sigcpcs.c,v 1.4 2000/01/17 20:49:52 mks Exp $
27 * @(#) $DragonFly: src/sys/netproto/atm/uni/sscop_sigcpcs.c,v 1.3 2003/08/07 21:17:35 dillon Exp $
31 * ATM Forum UNI Support
32 * ---------------------
34 * SSCOP Common - Process CPCS-signals (SSCOP PDUs)
38 #include <netatm/kern_include.h>
41 #include "sscop_misc.h"
42 #include "sscop_pdu.h"
43 #include "sscop_var.h"
49 * sop pointer to sscop connection block
50 * m pointer to PDU buffer (without trailer)
51 * trlr pointer to PDU trailer
58 sscop_noop(sop, m, trlr)
73 * BGN PDU / SOS_IDLE Processor
76 * sop pointer to sscop connection block
77 * m pointer to PDU buffer (without trailer)
78 * trlr pointer to PDU trailer
85 sscop_bgn_idle(sop, m, trlr)
90 struct bgn_pdu *bp = (struct bgn_pdu *)trlr;
93 if (sop->so_vers == SSCOP_VERS_Q2110) {
95 * "Power-up Robustness" option
97 * Accept BGN regardless of BGN.N(SQ)
99 sop->so_rcvconn = bp->bgn_nsq;
103 * If retransmitted BGN, reject it
105 if (sscop_is_rexmit(sop, bp->bgn_nsq)) {
107 (void) sscop_send_bgrej(sop);
112 if (sop->so_vers == SSCOP_VERS_QSAAL) {
116 if (bp->bgn_type & PT_SOURCE_SSCOP)
117 source = SSCOP_SOURCE_SSCOP;
119 source = SSCOP_SOURCE_USER;
122 * Reset receiver state variables
124 qsaal1_reset_rcvr(sop);
129 * Set initial transmit window
131 SEQ_SET(sop->so_sendmax, ntohl(bp->bgn_nmr));
134 * Pass connection request up to user
136 STACK_CALL(SSCOP_ESTABLISH_IND, sop->so_upper, sop->so_toku,
137 sop->so_connvc, (int)m, source, err);
140 sscop_abort(sop, "stack memory\n");
145 * Wait for user's response
147 sop->so_state = SOS_INCONN;
154 * BGN PDU / SOS_OUTDISC Processor
157 * sop pointer to sscop connection block
158 * m pointer to PDU buffer (without trailer)
159 * trlr pointer to PDU trailer
166 sscop_bgn_outdisc(sop, m, trlr)
171 struct bgn_pdu *bp = (struct bgn_pdu *)trlr;
175 * If retransmitted BGN, ACK it and send new END
177 if (sscop_is_rexmit(sop, bp->bgn_nsq)) {
179 (void) sscop_send_bgak(sop);
180 (void) sscop_send_end(sop, SSCOP_SOURCE_LAST);
185 * Stop retransmit timer
187 sop->so_timer[SSCOP_T_CC] = 0;
190 * Initialize transmit window
192 SEQ_SET(sop->so_sendmax, ntohl(bp->bgn_nmr));
195 * Notify user of connection termination
197 STACK_CALL(SSCOP_RELEASE_CNF, sop->so_upper, sop->so_toku,
198 sop->so_connvc, 0, 0, err);
201 sscop_abort(sop, "stack memory\n");
205 if (sop->so_vers == SSCOP_VERS_QSAAL) {
209 if (bp->bgn_type & PT_SOURCE_SSCOP)
210 source = SSCOP_SOURCE_SSCOP;
212 source = SSCOP_SOURCE_USER;
215 * Reset receiver variables
217 qsaal1_reset_rcvr(sop);
223 * Tell user about incoming connection
225 STACK_CALL(SSCOP_ESTABLISH_IND, sop->so_upper, sop->so_toku,
226 sop->so_connvc, (int)m, source, err);
229 sscop_abort(sop, "stack memory\n");
234 * Wait for user's response
236 sop->so_state = SOS_INCONN;
243 * BGN PDU / SOS_OUTRESYN Processor
246 * sop pointer to sscop connection block
247 * m pointer to PDU buffer (without trailer)
248 * trlr pointer to PDU trailer
255 sscop_bgn_outresyn(sop, m, trlr)
260 struct bgn_pdu *bp = (struct bgn_pdu *)trlr;
264 * If retransmitted BGN, ACK it and send new RS
266 if (sscop_is_rexmit(sop, bp->bgn_nsq)) {
268 (void) sscop_send_bgak(sop);
269 (void) sscop_send_rs(sop);
274 * Stop retransmit timer
276 sop->so_timer[SSCOP_T_CC] = 0;
279 * Initialize transmit window
281 SEQ_SET(sop->so_sendmax, ntohl(bp->bgn_nmr));
283 if (sop->so_vers == SSCOP_VERS_QSAAL) {
285 * Get (possible) Source value
287 if (bp->bgn_type & PT_SOURCE_SSCOP)
288 source = SSCOP_SOURCE_SSCOP;
290 source = SSCOP_SOURCE_USER;
293 * Reset receiver variables
295 qsaal1_reset_rcvr(sop);
298 source = SSCOP_SOURCE_USER;
301 * Notify user of connection termination
303 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
304 sop->so_connvc, SSCOP_UU_NULL, source, err);
307 sscop_abort(sop, "stack memory\n");
312 * Now tell user of a "new" incoming connection
314 STACK_CALL(SSCOP_ESTABLISH_IND, sop->so_upper, sop->so_toku,
315 sop->so_connvc, (int)m, source, err);
318 sscop_abort(sop, "stack memory\n");
323 * Wait for user's response
325 sop->so_state = SOS_INCONN;
332 * BGN PDU / SOS_INRESYN Processor
335 * sop pointer to sscop connection block
336 * m pointer to PDU buffer (without trailer)
337 * trlr pointer to PDU trailer
344 sscop_bgn_inresyn(sop, m, trlr)
349 struct bgn_pdu *bp = (struct bgn_pdu *)trlr;
353 * If retransmitted BGN, oops
355 if (sscop_is_rexmit(sop, bp->bgn_nsq)) {
357 sscop_maa_error(sop, 'B');
362 * Stop data transfer timers
364 sop->so_timer[SSCOP_T_POLL] = 0;
365 sop->so_timer[SSCOP_T_NORESP] = 0;
366 sop->so_timer[SSCOP_T_IDLE] = 0;
367 sop->so_flags &= ~SOF_KEEPALIVE;
370 * Initialize transmit window
372 SEQ_SET(sop->so_sendmax, ntohl(bp->bgn_nmr));
374 if (sop->so_vers == SSCOP_VERS_QSAAL) {
376 * Get (possible) Source value
378 if (bp->bgn_type & PT_SOURCE_SSCOP)
379 source = SSCOP_SOURCE_SSCOP;
381 source = SSCOP_SOURCE_USER;
384 * Reset receiver variables
386 qsaal1_reset_rcvr(sop);
390 * Stop possible retransmit timer
392 sop->so_timer[SSCOP_T_CC] = 0;
395 * Drain receiver queues
397 sscop_rcvr_drain(sop);
400 * Tell user current connection has been released
402 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
403 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_USER, err);
406 sscop_abort(sop, "stack memory\n");
414 * Tell user of incoming connection
416 STACK_CALL(SSCOP_ESTABLISH_IND, sop->so_upper, sop->so_toku,
417 sop->so_connvc, (int)m, source, err);
420 sscop_abort(sop, "stack memory\n");
425 * Wait for user's response
427 sop->so_state = SOS_INCONN;
434 * BGAK PDU / Protocol Error
437 * sop pointer to sscop connection block
438 * m pointer to PDU buffer (without trailer)
439 * trlr pointer to PDU trailer
446 sscop_bgak_error(sop, m, trlr)
453 * Record error condition
455 sscop_maa_error(sop, 'C');
463 * BGAK PDU / SOS_IDLE Processor
466 * sop pointer to sscop connection block
467 * m pointer to PDU buffer (without trailer)
468 * trlr pointer to PDU trailer
475 sscop_bgak_idle(sop, m, trlr)
482 * Record error condition
484 sscop_bgak_error(sop, m, trlr);
487 * Return an END to peer
489 (void) sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
495 * BGAK PDU / SOS_OUTCONN Processor
498 * sop pointer to sscop connection block
499 * m pointer to PDU buffer (without trailer)
500 * trlr pointer to PDU trailer
507 sscop_bgak_outconn(sop, m, trlr)
512 struct bgak_pdu *bp = (struct bgak_pdu *)trlr;
516 * Stop retransmit timer
518 sop->so_timer[SSCOP_T_CC] = 0;
521 * Initialize transmit window
523 SEQ_SET(sop->so_sendmax, ntohl(bp->bgak_nmr));
526 * Notify user of connection establishment
528 if (sop->so_flags & SOF_REESTAB) {
530 STACK_CALL(SSCOP_ESTABLISH_IND, sop->so_upper, sop->so_toku,
531 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
533 sscop_abort(sop, "stack memory\n");
536 sop->so_flags &= ~SOF_REESTAB;
538 STACK_CALL(SSCOP_ESTABLISH_CNF, sop->so_upper, sop->so_toku,
539 sop->so_connvc, (int)m, 0, err);
542 sscop_abort(sop, "stack memory\n");
547 if (sop->so_vers == SSCOP_VERS_QSAAL) {
549 * Reset receiver variables
551 qsaal1_reset_rcvr(sop);
554 * Start polling timer
559 * Start lost poll/stat timer
561 sop->so_timer[SSCOP_T_NORESP] = sop->so_parm.sp_timeresp;
565 * Initialize state variables
567 q2110_init_state(sop);
570 * Start data transfer timers
572 sop->so_timer[SSCOP_T_POLL] = sop->so_parm.sp_timepoll;
573 sop->so_timer[SSCOP_T_NORESP] = sop->so_parm.sp_timeresp;
577 * OK, we're ready for data
579 sop->so_state = SOS_READY;
582 * See if transmit queues need servicing
584 if (sop->so_flags & SOF_XMITSRVC)
585 sscop_service_xmit(sop);
592 * BGREJ PDU / Protocol Error
595 * sop pointer to sscop connection block
596 * m pointer to PDU buffer (without trailer)
597 * trlr pointer to PDU trailer
604 sscop_bgrej_error(sop, m, trlr)
611 * Record error condition
613 sscop_maa_error(sop, 'D');
620 * BGREJ PDU / SOS_OUTCONN Processor
623 * sop pointer to sscop connection block
624 * m pointer to PDU buffer (without trailer)
625 * trlr pointer to PDU trailer
632 sscop_bgrej_outconn(sop, m, trlr)
640 * Stop retransmit timer
642 sop->so_timer[SSCOP_T_CC] = 0;
644 if (sop->so_vers == SSCOP_VERS_QSAAL) {
646 * Clear reestablishment flag
648 sop->so_flags &= ~SOF_REESTAB;
653 source = SSCOP_SOURCE_SSCOP;
656 source = SSCOP_SOURCE_USER;
660 * Notify user of connection failure
662 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
663 sop->so_connvc, uu, source, err);
666 sscop_abort(sop, "stack memory\n");
673 sop->so_state = SOS_IDLE;
680 * BGREJ PDU / SOS_INCONN Processor
683 * sop pointer to sscop connection block
684 * m pointer to PDU buffer (without trailer)
685 * trlr pointer to PDU trailer
692 sscop_bgrej_inconn(sop, m, trlr)
700 * Report protocol error
702 sscop_bgrej_error(sop, m, trlr);
705 * Notify user of connection failure
707 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
708 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
710 sscop_abort(sop, "stack memory\n");
717 sop->so_state = SOS_IDLE;
724 * BGREJ PDU / SOS_OUTRESYN Processor
727 * sop pointer to sscop connection block
728 * m pointer to PDU buffer (without trailer)
729 * trlr pointer to PDU trailer
736 sscop_bgrej_outresyn(sop, m, trlr)
744 * Stop retransmit timer
746 sop->so_timer[SSCOP_T_CC] = 0;
749 * Report protocol error
751 sscop_bgrej_error(sop, m, trlr);
754 * Notify user of connection failure
756 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
757 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
759 sscop_abort(sop, "stack memory\n");
763 if (sop->so_vers == SSCOP_VERS_QSAAL) {
765 * Clear connection data
767 qsaal1_clear_connection(sop);
773 sop->so_state = SOS_IDLE;
780 * BGREJ PDU / SOS_READY Processor
783 * sop pointer to sscop connection block
784 * m pointer to PDU buffer (without trailer)
785 * trlr pointer to PDU trailer
792 sscop_bgrej_ready(sop, m, trlr)
800 * Stop data transfer timers
802 sop->so_timer[SSCOP_T_POLL] = 0;
803 sop->so_timer[SSCOP_T_NORESP] = 0;
804 sop->so_timer[SSCOP_T_IDLE] = 0;
805 sop->so_flags &= ~SOF_KEEPALIVE;
808 * Report protocol error
810 sscop_bgrej_error(sop, m, trlr);
813 * Notify user of connection failure
815 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
816 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
818 sscop_abort(sop, "stack memory\n");
822 if (sop->so_vers == SSCOP_VERS_QSAAL) {
824 * Clear connection data
826 qsaal1_clear_connection(sop);
829 * Clear out appropriate queues
831 q2110_prep_retrieve(sop);
837 sop->so_state = SOS_IDLE;
844 * END PDU / SOS_IDLE Processor
847 * sop pointer to sscop connection block
848 * m pointer to PDU buffer (without trailer)
849 * trlr pointer to PDU trailer
856 sscop_end_idle(sop, m, trlr)
868 * Return an ENDAK to peer
870 (void) sscop_send_endak(sop);
877 * END PDU / SOS_INCONN Processor
880 * sop pointer to sscop connection block
881 * m pointer to PDU buffer (without trailer)
882 * trlr pointer to PDU trailer
889 sscop_end_inconn(sop, m, trlr)
894 struct end_pdu *ep = (struct end_pdu *)trlr;
898 * Stop retransmit timer
900 sop->so_timer[SSCOP_T_CC] = 0;
905 (void) sscop_send_endak(sop);
910 if (ep->end_type & PT_SOURCE_SSCOP)
911 source = SSCOP_SOURCE_SSCOP;
913 source = SSCOP_SOURCE_USER;
916 * Notify user of connection termination
918 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
919 sop->so_connvc, (int)m, source, err);
922 sscop_abort(sop, "stack memory\n");
929 sop->so_state = SOS_IDLE;
936 * END PDU / SOS_OUTDISC Processor
939 * sop pointer to sscop connection block
940 * m pointer to PDU buffer (without trailer)
941 * trlr pointer to PDU trailer
948 sscop_end_outdisc(sop, m, trlr)
956 * Stop retransmit timer
958 sop->so_timer[SSCOP_T_CC] = 0;
968 (void) sscop_send_endak(sop);
971 * Notify user of connection termination
973 STACK_CALL(SSCOP_RELEASE_CNF, sop->so_upper, sop->so_toku,
974 sop->so_connvc, 0, 0, err);
976 sscop_abort(sop, "stack memory\n");
983 sop->so_state = SOS_IDLE;
990 * ENDAK PDU / Protocol Error
993 * sop pointer to sscop connection block
994 * m pointer to PDU buffer (without trailer)
995 * trlr pointer to PDU trailer
1002 sscop_endak_error(sop, m, trlr)
1009 * Record error condition
1011 sscop_maa_error(sop, 'F');
1019 * ENDAK PDU / SOS_INCONN Processor
1022 * sop pointer to sscop connection block
1023 * m pointer to PDU buffer (without trailer)
1024 * trlr pointer to PDU trailer
1031 sscop_endak_inconn(sop, m, trlr)
1039 * Stop retransmit timer
1041 sop->so_timer[SSCOP_T_CC] = 0;
1044 * Report protocol error
1046 sscop_endak_error(sop, m, trlr);
1049 * Notify user of connection termination
1051 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
1052 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
1054 sscop_abort(sop, "stack memory\n");
1059 * Back to idle state
1061 sop->so_state = SOS_IDLE;
1068 * ENDAK PDU / SOS_OUTDISC Processor
1071 * sop pointer to sscop connection block
1072 * m pointer to PDU buffer (without trailer)
1073 * trlr pointer to PDU trailer
1080 sscop_endak_outdisc(sop, m, trlr)
1088 * Stop retransmit timer
1090 sop->so_timer[SSCOP_T_CC] = 0;
1098 * Notify user of connection termination
1100 STACK_CALL(SSCOP_RELEASE_CNF, sop->so_upper, sop->so_toku,
1101 sop->so_connvc, 0, 0, err);
1103 sscop_abort(sop, "stack memory\n");
1108 * Back to idle state
1110 sop->so_state = SOS_IDLE;
1117 * ENDAK PDU / SOS_READY Processor
1120 * sop pointer to sscop connection block
1121 * m pointer to PDU buffer (without trailer)
1122 * trlr pointer to PDU trailer
1129 sscop_endak_ready(sop, m, trlr)
1137 * Stop data transfer timers
1139 sop->so_timer[SSCOP_T_POLL] = 0;
1140 sop->so_timer[SSCOP_T_NORESP] = 0;
1141 sop->so_timer[SSCOP_T_IDLE] = 0;
1142 sop->so_flags &= ~SOF_KEEPALIVE;
1145 * Report protocol error
1147 sscop_endak_error(sop, m, trlr);
1150 * Notify user of connection failure
1152 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
1153 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
1155 sscop_abort(sop, "stack memory\n");
1159 if (sop->so_vers == SSCOP_VERS_QSAAL) {
1161 * Clear connection data
1163 qsaal1_clear_connection(sop);
1166 * Clear out appropriate queues
1168 q2110_prep_retrieve(sop);
1172 * Back to idle state
1174 sop->so_state = SOS_IDLE;
1181 * RS PDU / Protocol Error
1184 * sop pointer to sscop connection block
1185 * m pointer to PDU buffer (without trailer)
1186 * trlr pointer to PDU trailer
1193 sscop_rs_error(sop, m, trlr)
1200 * Record error condition
1202 sscop_maa_error(sop, 'J');
1210 * RS PDU / SOS_IDLE Processor
1213 * sop pointer to sscop connection block
1214 * m pointer to PDU buffer (without trailer)
1215 * trlr pointer to PDU trailer
1222 sscop_rs_idle(sop, m, trlr)
1229 * Report error condition
1231 sscop_rs_error(sop, m, trlr);
1234 * Return an END to peer
1236 (void) sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
1243 * RSAK PDU / Protocol Error
1246 * sop pointer to sscop connection block
1247 * m pointer to PDU buffer (without trailer)
1248 * trlr pointer to PDU trailer
1255 sscop_rsak_error(sop, m, trlr)
1262 * Record error condition
1264 sscop_maa_error(sop, 'K');
1272 * RSAK PDU / SOS_IDLE Processor
1275 * sop pointer to sscop connection block
1276 * m pointer to PDU buffer (without trailer)
1277 * trlr pointer to PDU trailer
1284 sscop_rsak_idle(sop, m, trlr)
1291 * Report error condition
1293 sscop_rsak_error(sop, m, trlr);
1296 * Return an END to peer
1298 (void) sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
1304 * RSAK PDU / SOS_OUTRESYN Processor
1307 * sop pointer to sscop connection block
1308 * m pointer to PDU buffer (without trailer)
1309 * trlr pointer to PDU trailer
1316 sscop_rsak_outresyn(sop, m, trlr)
1321 struct rsak_q2110_pdu *rp = (struct rsak_q2110_pdu *)trlr;
1325 * Stop retransmit timer
1327 sop->so_timer[SSCOP_T_CC] = 0;
1330 * Notify user of resynchronization completion
1332 STACK_CALL(SSCOP_RESYNC_CNF, sop->so_upper, sop->so_toku,
1333 sop->so_connvc, 0, 0, err);
1336 sscop_abort(sop, "stack memory\n");
1340 if (sop->so_vers == SSCOP_VERS_QSAAL) {
1342 * Start the polling timer
1344 sscop_set_poll(sop);
1347 * Start lost poll/stat timer
1349 sop->so_timer[SSCOP_T_NORESP] = sop->so_parm.sp_timeresp;
1352 * Initialize state variables
1354 SEQ_SET(sop->so_sendmax, ntohl(rp->rsak_nmr));
1355 q2110_init_state(sop);
1358 * Start data transfer timers
1360 sop->so_timer[SSCOP_T_POLL] = sop->so_parm.sp_timepoll;
1361 sop->so_timer[SSCOP_T_NORESP] = sop->so_parm.sp_timeresp;
1370 * Now go back to data transfer state
1372 sop->so_state = SOS_READY;
1375 * See if transmit queues need servicing
1377 if (sop->so_flags & SOF_XMITSRVC)
1378 sscop_service_xmit(sop);
1385 * SD PDU / Protocol Error
1388 * sop pointer to sscop connection block
1389 * m pointer to PDU buffer (without trailer)
1390 * trlr pointer to PDU trailer
1397 sscop_sd_error(sop, m, trlr)
1404 * Record error condition
1406 sscop_maa_error(sop, 'A');
1414 * SD PDU / SOS_IDLE Processor
1417 * sop pointer to sscop connection block
1418 * m pointer to PDU buffer (without trailer)
1419 * trlr pointer to PDU trailer
1426 sscop_sd_idle(sop, m, trlr)
1433 * Record error condition
1435 sscop_sd_error(sop, m, trlr);
1438 * Return an END to peer
1440 (void) sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
1446 * SD PDU / SOS_INCONN Processor
1449 * sop pointer to sscop connection block
1450 * m pointer to PDU buffer (without trailer)
1451 * trlr pointer to PDU trailer
1458 sscop_sd_inconn(sop, m, trlr)
1466 * Record error condition
1468 sscop_sd_error(sop, m, trlr);
1471 * Return an END to peer
1473 (void) sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
1476 * Notify user of connection failure
1478 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
1479 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
1481 sscop_abort(sop, "stack memory\n");
1486 * Go back to idle state
1488 sop->so_state = SOS_IDLE;
1495 * POLL PDU / Protocol Error
1498 * sop pointer to sscop connection block
1499 * m pointer to PDU buffer (without trailer)
1500 * trlr pointer to PDU trailer
1507 sscop_poll_error(sop, m, trlr)
1514 * Record error condition
1516 sscop_maa_error(sop, 'G');
1524 * POLL PDU / SOS_IDLE Processor
1527 * sop pointer to sscop connection block
1528 * m pointer to PDU buffer (without trailer)
1529 * trlr pointer to PDU trailer
1536 sscop_poll_idle(sop, m, trlr)
1543 * Report error condition
1545 sscop_poll_error(sop, m, trlr);
1548 * Return an END to peer
1550 (void) sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
1556 * POLL PDU / SOS_INCONN Processor
1559 * sop pointer to sscop connection block
1560 * m pointer to PDU buffer (without trailer)
1561 * trlr pointer to PDU trailer
1568 sscop_poll_inconn(sop, m, trlr)
1576 * Record error condition
1578 sscop_poll_error(sop, m, trlr);
1581 * Return an END to peer
1583 (void) sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
1586 * Notify user of connection failure
1588 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
1589 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
1591 sscop_abort(sop, "stack memory\n");
1596 * Go back to idle state
1598 sop->so_state = SOS_IDLE;
1605 * STAT PDU / Protocol Error
1608 * sop pointer to sscop connection block
1609 * m pointer to PDU buffer (without trailer)
1610 * trlr pointer to PDU trailer
1617 sscop_stat_error(sop, m, trlr)
1624 * Record error condition
1626 sscop_maa_error(sop, 'H');
1634 * STAT PDU / SOS_IDLE Processor
1637 * sop pointer to sscop connection block
1638 * m pointer to PDU buffer (without trailer)
1639 * trlr pointer to PDU trailer
1646 sscop_stat_idle(sop, m, trlr)
1653 * Report error condition
1655 sscop_stat_error(sop, m, trlr);
1658 * Return an END to peer
1660 (void) sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
1666 * STAT PDU / SOS_INCONN Processor
1669 * sop pointer to sscop connection block
1670 * m pointer to PDU buffer (without trailer)
1671 * trlr pointer to PDU trailer
1678 sscop_stat_inconn(sop, m, trlr)
1686 * Record error condition
1688 sscop_stat_error(sop, m, trlr);
1691 * Return an END to peer
1693 (void) sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
1696 * Notify user of connection failure
1698 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
1699 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
1701 sscop_abort(sop, "stack memory\n");
1706 * Go back to idle state
1708 sop->so_state = SOS_IDLE;
1715 * STAT PDU / SOS_READY Processor
1718 * sop pointer to sscop connection block
1719 * m pointer to PDU buffer (without trailer)
1720 * trlr pointer to PDU trailer
1727 sscop_stat_ready(sop, m, trlr)
1732 struct stat_pdu *sp = (struct stat_pdu *)trlr;
1733 struct pdu_hdr *php;
1735 sscop_seq seq1, seq2, opa;
1738 NTOHL(sp->stat_nps);
1739 NTOHL(sp->stat_nmr);
1743 * Validate peer's received poll sequence number
1745 if (SEQ_GT(sop->so_pollack, sp->stat_nps, sop->so_pollack) ||
1746 SEQ_GT(sp->stat_nps, sop->so_pollsend, sop->so_pollack)) {
1748 * Bad poll sequence number
1750 sscop_maa_error(sop, 'R');
1755 * Validate peer's current receive data sequence number
1757 if (SEQ_GT(sop->so_ack, sp->stat_nr, sop->so_ack) ||
1758 SEQ_GT(sp->stat_nr, sop->so_send, sop->so_ack)) {
1760 * Bad data sequence number
1762 sscop_maa_error(sop, 'S');
1767 * Free acknowledged PDUs
1769 for (seq1 = sop->so_ack, SEQ_SET(seq2, sp->stat_nr);
1770 SEQ_LT(seq1, seq2, sop->so_ack);
1771 SEQ_INCR(seq1, 1)) {
1772 sscop_pack_free(sop, seq1);
1776 * Update transmit state variables
1778 opa = sop->so_pollack;
1780 SEQ_SET(sop->so_pollack, sp->stat_nps);
1781 SEQ_SET(sop->so_sendmax, sp->stat_nmr);
1784 * Get first element in STAT list
1786 while (m && (KB_LEN(m) == 0))
1790 m = sscop_stat_getelem(m, &seq1);
1793 * Make sure there's a second element too
1799 * Validate first element (start of missing pdus)
1801 if (SEQ_GT(sop->so_ack, seq1, sop->so_ack) ||
1802 SEQ_GEQ(seq1, sop->so_send, sop->so_ack)) {
1804 * Bad element sequence number
1806 sscop_maa_error(sop, 'S');
1811 * Loop thru all STAT elements in list
1815 * Get next even element (start of received pdus)
1817 m = sscop_stat_getelem(m, &seq2);
1820 * Validate seqence number
1822 if (SEQ_GEQ(seq1, seq2, sop->so_ack) ||
1823 SEQ_GT(seq2, sop->so_send, sop->so_ack)) {
1825 * Bad element sequence number
1827 sscop_maa_error(sop, 'S');
1832 * Process each missing sequence number in this gap
1834 while (SEQ_LT(seq1, seq2, sop->so_ack)) {
1836 * Find corresponding SD PDU on pending ack queue
1838 php = sscop_pack_locate(sop, seq1);
1840 sscop_maa_error(sop, 'S');
1845 * Retransmit this SD PDU only if it was last sent
1846 * during an earlier poll sequence and it's not
1847 * already scheduled for retranmission.
1849 if (SEQ_LT(php->ph_nps, sp->stat_nps, opa) &&
1850 (php->ph_rexmit_lk == NULL) &&
1851 (sop->so_rexmit_tl != php)) {
1853 * Put PDU on retransmit queue and schedule
1854 * transmit servicing
1856 sscop_rexmit_insert(sop, php);
1857 sop->so_flags |= SOF_XMITSRVC;
1862 * Bump to next sequence number
1868 * Now process series of acknowledged PDUs
1870 * Get next odd element (start of missing pdus),
1871 * but make sure there is one and that it's valid
1875 m = sscop_stat_getelem(m, &seq2);
1876 if (SEQ_GEQ(seq1, seq2, sop->so_ack) ||
1877 SEQ_GT(seq2, sop->so_send, sop->so_ack)) {
1879 * Bad element sequence number
1881 sscop_maa_error(sop, 'S');
1886 * Process each acked sequence number
1888 while (SEQ_LT(seq1, seq2, sop->so_ack)) {
1890 * Can we clear transmit buffers ??
1892 if ((sop->so_flags & SOF_NOCLRBUF) == 0) {
1894 * Yes, free acked buffers
1896 sscop_pack_free(sop, seq1);
1900 * Bump to next sequence number
1908 * Free PDU buffer chain
1913 * Report retransmitted PDUs
1916 sscop_maa_error(sop, 'V');
1919 * Record transmit window closed transitions
1921 if (SEQ_LT(sop->so_send, sop->so_sendmax, sop->so_ack)) {
1922 if (sop->so_flags & SOF_NOCREDIT) {
1923 sop->so_flags &= ~SOF_NOCREDIT;
1924 sscop_maa_error(sop, 'X');
1927 if ((sop->so_flags & SOF_NOCREDIT) == 0) {
1928 sop->so_flags |= SOF_NOCREDIT;
1929 sscop_maa_error(sop, 'W');
1933 if (sop->so_vers == SSCOP_VERS_QSAAL)
1935 * Restart lost poll/stat timer
1937 sop->so_timer[SSCOP_T_NORESP] = sop->so_parm.sp_timeresp;
1940 * Determine new polling phase
1942 if ((sop->so_timer[SSCOP_T_POLL] != 0) &&
1943 ((sop->so_flags & SOF_KEEPALIVE) == 0)) {
1945 * Remain in active phase - reset NO-RESPONSE timer
1947 sop->so_timer[SSCOP_T_NORESP] =
1948 sop->so_parm.sp_timeresp;
1950 } else if (sop->so_timer[SSCOP_T_IDLE] == 0) {
1952 * Go from transient to idle phase
1954 sop->so_timer[SSCOP_T_POLL] = 0;
1955 sop->so_flags &= ~SOF_KEEPALIVE;
1956 sop->so_timer[SSCOP_T_NORESP] = 0;
1957 sop->so_timer[SSCOP_T_IDLE] = sop->so_parm.sp_timeidle;
1962 * See if transmit queues need servicing
1964 if (sop->so_flags & SOF_XMITSRVC)
1965 sscop_service_xmit(sop);
1971 * Protocol/parameter error encountered
1975 * Free PDU buffer chain
1979 if (sop->so_vers == SSCOP_VERS_QSAAL)
1981 * Reestablish a new connection
1983 qsaal1_reestablish(sop);
1986 * Initiate error recovery
1988 q2110_error_recovery(sop);
1995 * USTAT PDU / Protocol Error
1998 * sop pointer to sscop connection block
1999 * m pointer to PDU buffer (without trailer)
2000 * trlr pointer to PDU trailer
2007 sscop_ustat_error(sop, m, trlr)
2014 * Record error condition
2016 sscop_maa_error(sop, 'I');
2024 * USTAT PDU / SOS_IDLE Processor
2027 * sop pointer to sscop connection block
2028 * m pointer to PDU buffer (without trailer)
2029 * trlr pointer to PDU trailer
2036 sscop_ustat_idle(sop, m, trlr)
2043 * Report error condition
2045 sscop_ustat_error(sop, m, trlr);
2048 * Return an END to peer
2050 (void) sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
2056 * USTAT PDU / SOS_INCONN Processor
2059 * sop pointer to sscop connection block
2060 * m pointer to PDU buffer (without trailer)
2061 * trlr pointer to PDU trailer
2068 sscop_ustat_inconn(sop, m, trlr)
2076 * Record error condition
2078 sscop_ustat_error(sop, m, trlr);
2081 * Return an END to peer
2083 (void) sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
2086 * Notify user of connection failure
2088 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
2089 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
2091 sscop_abort(sop, "stack memory\n");
2096 * Go back to idle state
2098 sop->so_state = SOS_IDLE;
2105 * USTAT PDU / SOS_READY Processor
2108 * sop pointer to sscop connection block
2109 * m pointer to PDU buffer (without trailer)
2110 * trlr pointer to PDU trailer
2117 sscop_ustat_ready(sop, m, trlr)
2122 struct ustat_pdu *up = (struct ustat_pdu *)trlr;
2123 struct pdu_hdr *php;
2124 sscop_seq seq1, seq2;
2126 NTOHL(up->ustat_nmr);
2127 NTOHL(up->ustat_nr);
2130 * Validate peer's current receive data sequence number
2132 if (SEQ_GT(sop->so_ack, up->ustat_nr, sop->so_ack) ||
2133 SEQ_GEQ(up->ustat_nr, sop->so_send, sop->so_ack)) {
2135 * Bad data sequence number
2141 * Free acknowledged PDUs
2143 for (seq1 = sop->so_ack, SEQ_SET(seq2, up->ustat_nr);
2144 SEQ_LT(seq1, seq2, sop->so_ack);
2145 SEQ_INCR(seq1, 1)) {
2146 sscop_pack_free(sop, seq1);
2150 * Update transmit state variables
2153 SEQ_SET(sop->so_sendmax, up->ustat_nmr);
2156 * Get USTAT list elements
2158 SEQ_SET(seq1, ntohl(up->ustat_le1));
2159 SEQ_SET(seq2, ntohl(up->ustat_le2));
2164 if (SEQ_GT(sop->so_ack, seq1, sop->so_ack) ||
2165 SEQ_GEQ(seq1, seq2, sop->so_ack) ||
2166 SEQ_GEQ(seq2, sop->so_send, sop->so_ack)) {
2168 * Bad element sequence number
2174 * Process each missing sequence number in this gap
2176 while (SEQ_LT(seq1, seq2, sop->so_ack)) {
2178 * Find corresponding SD PDU on pending ack queue
2180 php = sscop_pack_locate(sop, seq1);
2186 * Retransmit this SD PDU if it's not
2187 * already scheduled for retranmission.
2189 if ((php->ph_rexmit_lk == NULL) &&
2190 (sop->so_rexmit_tl != php)) {
2192 * Put PDU on retransmit queue and schedule
2193 * transmit servicing
2195 sscop_rexmit_insert(sop, php);
2196 sop->so_flags |= SOF_XMITSRVC;
2200 * Bump to next sequence number
2206 * Report retransmitted PDUs
2208 sscop_maa_error(sop, 'V');
2211 * Free PDU buffer chain
2216 * See if transmit queues need servicing
2218 if (sop->so_flags & SOF_XMITSRVC)
2219 sscop_service_xmit(sop);
2225 * Protocol/parameter error encountered
2227 sscop_maa_error(sop, 'T');
2230 * Free PDU buffer chain
2234 if (sop->so_vers == SSCOP_VERS_QSAAL)
2236 * Reestablish a new connection
2238 qsaal1_reestablish(sop);
2241 * Initiate error recovery
2243 q2110_error_recovery(sop);
2250 * UD PDU / SOS_* Processor
2253 * sop pointer to sscop connection block
2254 * m pointer to PDU buffer (without trailer)
2255 * trlr pointer to PDU trailer
2262 sscop_ud_all(sop, m, trlr)
2270 * Pass data up to user
2272 STACK_CALL(SSCOP_UNITDATA_IND, sop->so_upper, sop->so_toku,
2273 sop->so_connvc, (int)m, 0, err);
2281 * MD PDU / SOS_* Processor
2284 * sop pointer to sscop connection block
2285 * m pointer to PDU buffer (without trailer)
2286 * trlr pointer to PDU trailer
2293 sscop_md_all(sop, m, trlr)
2300 * We don't support MD PDUs