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 $
31 * ATM Forum UNI Support
32 * ---------------------
34 * SSCOP Common - Process CPCS-signals (SSCOP PDUs)
38 #include <netatm/kern_include.h>
40 #include <netatm/uni/sscop.h>
41 #include <netatm/uni/sscop_misc.h>
42 #include <netatm/uni/sscop_pdu.h>
43 #include <netatm/uni/sscop_var.h>
46 __RCSID("@(#) $FreeBSD: src/sys/netatm/uni/sscop_sigcpcs.c,v 1.4 2000/01/17 20:49:52 mks Exp $");
54 * sop pointer to sscop connection block
55 * m pointer to PDU buffer (without trailer)
56 * trlr pointer to PDU trailer
63 sscop_noop(sop, m, trlr)
78 * BGN PDU / SOS_IDLE Processor
81 * sop pointer to sscop connection block
82 * m pointer to PDU buffer (without trailer)
83 * trlr pointer to PDU trailer
90 sscop_bgn_idle(sop, m, trlr)
95 struct bgn_pdu *bp = (struct bgn_pdu *)trlr;
98 if (sop->so_vers == SSCOP_VERS_Q2110) {
100 * "Power-up Robustness" option
102 * Accept BGN regardless of BGN.N(SQ)
104 sop->so_rcvconn = bp->bgn_nsq;
108 * If retransmitted BGN, reject it
110 if (sscop_is_rexmit(sop, bp->bgn_nsq)) {
112 (void) sscop_send_bgrej(sop);
117 if (sop->so_vers == SSCOP_VERS_QSAAL) {
121 if (bp->bgn_type & PT_SOURCE_SSCOP)
122 source = SSCOP_SOURCE_SSCOP;
124 source = SSCOP_SOURCE_USER;
127 * Reset receiver state variables
129 qsaal1_reset_rcvr(sop);
134 * Set initial transmit window
136 SEQ_SET(sop->so_sendmax, ntohl(bp->bgn_nmr));
139 * Pass connection request up to user
141 STACK_CALL(SSCOP_ESTABLISH_IND, sop->so_upper, sop->so_toku,
142 sop->so_connvc, (int)m, source, err);
145 sscop_abort(sop, "stack memory\n");
150 * Wait for user's response
152 sop->so_state = SOS_INCONN;
159 * BGN PDU / SOS_OUTDISC Processor
162 * sop pointer to sscop connection block
163 * m pointer to PDU buffer (without trailer)
164 * trlr pointer to PDU trailer
171 sscop_bgn_outdisc(sop, m, trlr)
176 struct bgn_pdu *bp = (struct bgn_pdu *)trlr;
180 * If retransmitted BGN, ACK it and send new END
182 if (sscop_is_rexmit(sop, bp->bgn_nsq)) {
184 (void) sscop_send_bgak(sop);
185 (void) sscop_send_end(sop, SSCOP_SOURCE_LAST);
190 * Stop retransmit timer
192 sop->so_timer[SSCOP_T_CC] = 0;
195 * Initialize transmit window
197 SEQ_SET(sop->so_sendmax, ntohl(bp->bgn_nmr));
200 * Notify user of connection termination
202 STACK_CALL(SSCOP_RELEASE_CNF, sop->so_upper, sop->so_toku,
203 sop->so_connvc, 0, 0, err);
206 sscop_abort(sop, "stack memory\n");
210 if (sop->so_vers == SSCOP_VERS_QSAAL) {
214 if (bp->bgn_type & PT_SOURCE_SSCOP)
215 source = SSCOP_SOURCE_SSCOP;
217 source = SSCOP_SOURCE_USER;
220 * Reset receiver variables
222 qsaal1_reset_rcvr(sop);
228 * Tell user about incoming connection
230 STACK_CALL(SSCOP_ESTABLISH_IND, sop->so_upper, sop->so_toku,
231 sop->so_connvc, (int)m, source, err);
234 sscop_abort(sop, "stack memory\n");
239 * Wait for user's response
241 sop->so_state = SOS_INCONN;
248 * BGN PDU / SOS_OUTRESYN Processor
251 * sop pointer to sscop connection block
252 * m pointer to PDU buffer (without trailer)
253 * trlr pointer to PDU trailer
260 sscop_bgn_outresyn(sop, m, trlr)
265 struct bgn_pdu *bp = (struct bgn_pdu *)trlr;
269 * If retransmitted BGN, ACK it and send new RS
271 if (sscop_is_rexmit(sop, bp->bgn_nsq)) {
273 (void) sscop_send_bgak(sop);
274 (void) sscop_send_rs(sop);
279 * Stop retransmit timer
281 sop->so_timer[SSCOP_T_CC] = 0;
284 * Initialize transmit window
286 SEQ_SET(sop->so_sendmax, ntohl(bp->bgn_nmr));
288 if (sop->so_vers == SSCOP_VERS_QSAAL) {
290 * Get (possible) Source value
292 if (bp->bgn_type & PT_SOURCE_SSCOP)
293 source = SSCOP_SOURCE_SSCOP;
295 source = SSCOP_SOURCE_USER;
298 * Reset receiver variables
300 qsaal1_reset_rcvr(sop);
303 source = SSCOP_SOURCE_USER;
306 * Notify user of connection termination
308 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
309 sop->so_connvc, SSCOP_UU_NULL, source, err);
312 sscop_abort(sop, "stack memory\n");
317 * Now tell user of a "new" incoming connection
319 STACK_CALL(SSCOP_ESTABLISH_IND, sop->so_upper, sop->so_toku,
320 sop->so_connvc, (int)m, source, err);
323 sscop_abort(sop, "stack memory\n");
328 * Wait for user's response
330 sop->so_state = SOS_INCONN;
337 * BGN PDU / SOS_INRESYN Processor
340 * sop pointer to sscop connection block
341 * m pointer to PDU buffer (without trailer)
342 * trlr pointer to PDU trailer
349 sscop_bgn_inresyn(sop, m, trlr)
354 struct bgn_pdu *bp = (struct bgn_pdu *)trlr;
358 * If retransmitted BGN, oops
360 if (sscop_is_rexmit(sop, bp->bgn_nsq)) {
362 sscop_maa_error(sop, 'B');
367 * Stop data transfer timers
369 sop->so_timer[SSCOP_T_POLL] = 0;
370 sop->so_timer[SSCOP_T_NORESP] = 0;
371 sop->so_timer[SSCOP_T_IDLE] = 0;
372 sop->so_flags &= ~SOF_KEEPALIVE;
375 * Initialize transmit window
377 SEQ_SET(sop->so_sendmax, ntohl(bp->bgn_nmr));
379 if (sop->so_vers == SSCOP_VERS_QSAAL) {
381 * Get (possible) Source value
383 if (bp->bgn_type & PT_SOURCE_SSCOP)
384 source = SSCOP_SOURCE_SSCOP;
386 source = SSCOP_SOURCE_USER;
389 * Reset receiver variables
391 qsaal1_reset_rcvr(sop);
395 * Stop possible retransmit timer
397 sop->so_timer[SSCOP_T_CC] = 0;
400 * Drain receiver queues
402 sscop_rcvr_drain(sop);
405 * Tell user current connection has been released
407 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
408 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_USER, err);
411 sscop_abort(sop, "stack memory\n");
419 * Tell user of incoming connection
421 STACK_CALL(SSCOP_ESTABLISH_IND, sop->so_upper, sop->so_toku,
422 sop->so_connvc, (int)m, source, err);
425 sscop_abort(sop, "stack memory\n");
430 * Wait for user's response
432 sop->so_state = SOS_INCONN;
439 * BGAK PDU / Protocol Error
442 * sop pointer to sscop connection block
443 * m pointer to PDU buffer (without trailer)
444 * trlr pointer to PDU trailer
451 sscop_bgak_error(sop, m, trlr)
458 * Record error condition
460 sscop_maa_error(sop, 'C');
468 * BGAK PDU / SOS_IDLE Processor
471 * sop pointer to sscop connection block
472 * m pointer to PDU buffer (without trailer)
473 * trlr pointer to PDU trailer
480 sscop_bgak_idle(sop, m, trlr)
487 * Record error condition
489 sscop_bgak_error(sop, m, trlr);
492 * Return an END to peer
494 (void) sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
500 * BGAK PDU / SOS_OUTCONN Processor
503 * sop pointer to sscop connection block
504 * m pointer to PDU buffer (without trailer)
505 * trlr pointer to PDU trailer
512 sscop_bgak_outconn(sop, m, trlr)
517 struct bgak_pdu *bp = (struct bgak_pdu *)trlr;
521 * Stop retransmit timer
523 sop->so_timer[SSCOP_T_CC] = 0;
526 * Initialize transmit window
528 SEQ_SET(sop->so_sendmax, ntohl(bp->bgak_nmr));
531 * Notify user of connection establishment
533 if (sop->so_flags & SOF_REESTAB) {
535 STACK_CALL(SSCOP_ESTABLISH_IND, sop->so_upper, sop->so_toku,
536 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
538 sscop_abort(sop, "stack memory\n");
541 sop->so_flags &= ~SOF_REESTAB;
543 STACK_CALL(SSCOP_ESTABLISH_CNF, sop->so_upper, sop->so_toku,
544 sop->so_connvc, (int)m, 0, err);
547 sscop_abort(sop, "stack memory\n");
552 if (sop->so_vers == SSCOP_VERS_QSAAL) {
554 * Reset receiver variables
556 qsaal1_reset_rcvr(sop);
559 * Start polling timer
564 * Start lost poll/stat timer
566 sop->so_timer[SSCOP_T_NORESP] = sop->so_parm.sp_timeresp;
570 * Initialize state variables
572 q2110_init_state(sop);
575 * Start data transfer timers
577 sop->so_timer[SSCOP_T_POLL] = sop->so_parm.sp_timepoll;
578 sop->so_timer[SSCOP_T_NORESP] = sop->so_parm.sp_timeresp;
582 * OK, we're ready for data
584 sop->so_state = SOS_READY;
587 * See if transmit queues need servicing
589 if (sop->so_flags & SOF_XMITSRVC)
590 sscop_service_xmit(sop);
597 * BGREJ PDU / Protocol Error
600 * sop pointer to sscop connection block
601 * m pointer to PDU buffer (without trailer)
602 * trlr pointer to PDU trailer
609 sscop_bgrej_error(sop, m, trlr)
616 * Record error condition
618 sscop_maa_error(sop, 'D');
625 * BGREJ PDU / SOS_OUTCONN Processor
628 * sop pointer to sscop connection block
629 * m pointer to PDU buffer (without trailer)
630 * trlr pointer to PDU trailer
637 sscop_bgrej_outconn(sop, m, trlr)
645 * Stop retransmit timer
647 sop->so_timer[SSCOP_T_CC] = 0;
649 if (sop->so_vers == SSCOP_VERS_QSAAL) {
651 * Clear reestablishment flag
653 sop->so_flags &= ~SOF_REESTAB;
658 source = SSCOP_SOURCE_SSCOP;
661 source = SSCOP_SOURCE_USER;
665 * Notify user of connection failure
667 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
668 sop->so_connvc, uu, source, err);
671 sscop_abort(sop, "stack memory\n");
678 sop->so_state = SOS_IDLE;
685 * BGREJ PDU / SOS_INCONN Processor
688 * sop pointer to sscop connection block
689 * m pointer to PDU buffer (without trailer)
690 * trlr pointer to PDU trailer
697 sscop_bgrej_inconn(sop, m, trlr)
705 * Report protocol error
707 sscop_bgrej_error(sop, m, trlr);
710 * Notify user of connection failure
712 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
713 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
715 sscop_abort(sop, "stack memory\n");
722 sop->so_state = SOS_IDLE;
729 * BGREJ PDU / SOS_OUTRESYN Processor
732 * sop pointer to sscop connection block
733 * m pointer to PDU buffer (without trailer)
734 * trlr pointer to PDU trailer
741 sscop_bgrej_outresyn(sop, m, trlr)
749 * Stop retransmit timer
751 sop->so_timer[SSCOP_T_CC] = 0;
754 * Report protocol error
756 sscop_bgrej_error(sop, m, trlr);
759 * Notify user of connection failure
761 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
762 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
764 sscop_abort(sop, "stack memory\n");
768 if (sop->so_vers == SSCOP_VERS_QSAAL) {
770 * Clear connection data
772 qsaal1_clear_connection(sop);
778 sop->so_state = SOS_IDLE;
785 * BGREJ PDU / SOS_READY Processor
788 * sop pointer to sscop connection block
789 * m pointer to PDU buffer (without trailer)
790 * trlr pointer to PDU trailer
797 sscop_bgrej_ready(sop, m, trlr)
805 * Stop data transfer timers
807 sop->so_timer[SSCOP_T_POLL] = 0;
808 sop->so_timer[SSCOP_T_NORESP] = 0;
809 sop->so_timer[SSCOP_T_IDLE] = 0;
810 sop->so_flags &= ~SOF_KEEPALIVE;
813 * Report protocol error
815 sscop_bgrej_error(sop, m, trlr);
818 * Notify user of connection failure
820 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
821 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
823 sscop_abort(sop, "stack memory\n");
827 if (sop->so_vers == SSCOP_VERS_QSAAL) {
829 * Clear connection data
831 qsaal1_clear_connection(sop);
834 * Clear out appropriate queues
836 q2110_prep_retrieve(sop);
842 sop->so_state = SOS_IDLE;
849 * END PDU / SOS_IDLE Processor
852 * sop pointer to sscop connection block
853 * m pointer to PDU buffer (without trailer)
854 * trlr pointer to PDU trailer
861 sscop_end_idle(sop, m, trlr)
873 * Return an ENDAK to peer
875 (void) sscop_send_endak(sop);
882 * END PDU / SOS_INCONN Processor
885 * sop pointer to sscop connection block
886 * m pointer to PDU buffer (without trailer)
887 * trlr pointer to PDU trailer
894 sscop_end_inconn(sop, m, trlr)
899 struct end_pdu *ep = (struct end_pdu *)trlr;
903 * Stop retransmit timer
905 sop->so_timer[SSCOP_T_CC] = 0;
910 (void) sscop_send_endak(sop);
915 if (ep->end_type & PT_SOURCE_SSCOP)
916 source = SSCOP_SOURCE_SSCOP;
918 source = SSCOP_SOURCE_USER;
921 * Notify user of connection termination
923 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
924 sop->so_connvc, (int)m, source, err);
927 sscop_abort(sop, "stack memory\n");
934 sop->so_state = SOS_IDLE;
941 * END PDU / SOS_OUTDISC Processor
944 * sop pointer to sscop connection block
945 * m pointer to PDU buffer (without trailer)
946 * trlr pointer to PDU trailer
953 sscop_end_outdisc(sop, m, trlr)
961 * Stop retransmit timer
963 sop->so_timer[SSCOP_T_CC] = 0;
973 (void) sscop_send_endak(sop);
976 * Notify user of connection termination
978 STACK_CALL(SSCOP_RELEASE_CNF, sop->so_upper, sop->so_toku,
979 sop->so_connvc, 0, 0, err);
981 sscop_abort(sop, "stack memory\n");
988 sop->so_state = SOS_IDLE;
995 * ENDAK PDU / Protocol Error
998 * sop pointer to sscop connection block
999 * m pointer to PDU buffer (without trailer)
1000 * trlr pointer to PDU trailer
1007 sscop_endak_error(sop, m, trlr)
1014 * Record error condition
1016 sscop_maa_error(sop, 'F');
1024 * ENDAK PDU / SOS_INCONN Processor
1027 * sop pointer to sscop connection block
1028 * m pointer to PDU buffer (without trailer)
1029 * trlr pointer to PDU trailer
1036 sscop_endak_inconn(sop, m, trlr)
1044 * Stop retransmit timer
1046 sop->so_timer[SSCOP_T_CC] = 0;
1049 * Report protocol error
1051 sscop_endak_error(sop, m, trlr);
1054 * Notify user of connection termination
1056 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
1057 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
1059 sscop_abort(sop, "stack memory\n");
1064 * Back to idle state
1066 sop->so_state = SOS_IDLE;
1073 * ENDAK PDU / SOS_OUTDISC Processor
1076 * sop pointer to sscop connection block
1077 * m pointer to PDU buffer (without trailer)
1078 * trlr pointer to PDU trailer
1085 sscop_endak_outdisc(sop, m, trlr)
1093 * Stop retransmit timer
1095 sop->so_timer[SSCOP_T_CC] = 0;
1103 * Notify user of connection termination
1105 STACK_CALL(SSCOP_RELEASE_CNF, sop->so_upper, sop->so_toku,
1106 sop->so_connvc, 0, 0, err);
1108 sscop_abort(sop, "stack memory\n");
1113 * Back to idle state
1115 sop->so_state = SOS_IDLE;
1122 * ENDAK PDU / SOS_READY Processor
1125 * sop pointer to sscop connection block
1126 * m pointer to PDU buffer (without trailer)
1127 * trlr pointer to PDU trailer
1134 sscop_endak_ready(sop, m, trlr)
1142 * Stop data transfer timers
1144 sop->so_timer[SSCOP_T_POLL] = 0;
1145 sop->so_timer[SSCOP_T_NORESP] = 0;
1146 sop->so_timer[SSCOP_T_IDLE] = 0;
1147 sop->so_flags &= ~SOF_KEEPALIVE;
1150 * Report protocol error
1152 sscop_endak_error(sop, m, trlr);
1155 * Notify user of connection failure
1157 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
1158 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
1160 sscop_abort(sop, "stack memory\n");
1164 if (sop->so_vers == SSCOP_VERS_QSAAL) {
1166 * Clear connection data
1168 qsaal1_clear_connection(sop);
1171 * Clear out appropriate queues
1173 q2110_prep_retrieve(sop);
1177 * Back to idle state
1179 sop->so_state = SOS_IDLE;
1186 * RS PDU / Protocol Error
1189 * sop pointer to sscop connection block
1190 * m pointer to PDU buffer (without trailer)
1191 * trlr pointer to PDU trailer
1198 sscop_rs_error(sop, m, trlr)
1205 * Record error condition
1207 sscop_maa_error(sop, 'J');
1215 * RS PDU / SOS_IDLE Processor
1218 * sop pointer to sscop connection block
1219 * m pointer to PDU buffer (without trailer)
1220 * trlr pointer to PDU trailer
1227 sscop_rs_idle(sop, m, trlr)
1234 * Report error condition
1236 sscop_rs_error(sop, m, trlr);
1239 * Return an END to peer
1241 (void) sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
1248 * RSAK PDU / Protocol Error
1251 * sop pointer to sscop connection block
1252 * m pointer to PDU buffer (without trailer)
1253 * trlr pointer to PDU trailer
1260 sscop_rsak_error(sop, m, trlr)
1267 * Record error condition
1269 sscop_maa_error(sop, 'K');
1277 * RSAK PDU / SOS_IDLE Processor
1280 * sop pointer to sscop connection block
1281 * m pointer to PDU buffer (without trailer)
1282 * trlr pointer to PDU trailer
1289 sscop_rsak_idle(sop, m, trlr)
1296 * Report error condition
1298 sscop_rsak_error(sop, m, trlr);
1301 * Return an END to peer
1303 (void) sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
1309 * RSAK PDU / SOS_OUTRESYN Processor
1312 * sop pointer to sscop connection block
1313 * m pointer to PDU buffer (without trailer)
1314 * trlr pointer to PDU trailer
1321 sscop_rsak_outresyn(sop, m, trlr)
1326 struct rsak_q2110_pdu *rp = (struct rsak_q2110_pdu *)trlr;
1330 * Stop retransmit timer
1332 sop->so_timer[SSCOP_T_CC] = 0;
1335 * Notify user of resynchronization completion
1337 STACK_CALL(SSCOP_RESYNC_CNF, sop->so_upper, sop->so_toku,
1338 sop->so_connvc, 0, 0, err);
1341 sscop_abort(sop, "stack memory\n");
1345 if (sop->so_vers == SSCOP_VERS_QSAAL) {
1347 * Start the polling timer
1349 sscop_set_poll(sop);
1352 * Start lost poll/stat timer
1354 sop->so_timer[SSCOP_T_NORESP] = sop->so_parm.sp_timeresp;
1357 * Initialize state variables
1359 SEQ_SET(sop->so_sendmax, ntohl(rp->rsak_nmr));
1360 q2110_init_state(sop);
1363 * Start data transfer timers
1365 sop->so_timer[SSCOP_T_POLL] = sop->so_parm.sp_timepoll;
1366 sop->so_timer[SSCOP_T_NORESP] = sop->so_parm.sp_timeresp;
1375 * Now go back to data transfer state
1377 sop->so_state = SOS_READY;
1380 * See if transmit queues need servicing
1382 if (sop->so_flags & SOF_XMITSRVC)
1383 sscop_service_xmit(sop);
1390 * SD PDU / Protocol Error
1393 * sop pointer to sscop connection block
1394 * m pointer to PDU buffer (without trailer)
1395 * trlr pointer to PDU trailer
1402 sscop_sd_error(sop, m, trlr)
1409 * Record error condition
1411 sscop_maa_error(sop, 'A');
1419 * SD PDU / SOS_IDLE Processor
1422 * sop pointer to sscop connection block
1423 * m pointer to PDU buffer (without trailer)
1424 * trlr pointer to PDU trailer
1431 sscop_sd_idle(sop, m, trlr)
1438 * Record error condition
1440 sscop_sd_error(sop, m, trlr);
1443 * Return an END to peer
1445 (void) sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
1451 * SD PDU / SOS_INCONN Processor
1454 * sop pointer to sscop connection block
1455 * m pointer to PDU buffer (without trailer)
1456 * trlr pointer to PDU trailer
1463 sscop_sd_inconn(sop, m, trlr)
1471 * Record error condition
1473 sscop_sd_error(sop, m, trlr);
1476 * Return an END to peer
1478 (void) sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
1481 * Notify user of connection failure
1483 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
1484 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
1486 sscop_abort(sop, "stack memory\n");
1491 * Go back to idle state
1493 sop->so_state = SOS_IDLE;
1500 * POLL PDU / Protocol Error
1503 * sop pointer to sscop connection block
1504 * m pointer to PDU buffer (without trailer)
1505 * trlr pointer to PDU trailer
1512 sscop_poll_error(sop, m, trlr)
1519 * Record error condition
1521 sscop_maa_error(sop, 'G');
1529 * POLL PDU / SOS_IDLE Processor
1532 * sop pointer to sscop connection block
1533 * m pointer to PDU buffer (without trailer)
1534 * trlr pointer to PDU trailer
1541 sscop_poll_idle(sop, m, trlr)
1548 * Report error condition
1550 sscop_poll_error(sop, m, trlr);
1553 * Return an END to peer
1555 (void) sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
1561 * POLL PDU / SOS_INCONN Processor
1564 * sop pointer to sscop connection block
1565 * m pointer to PDU buffer (without trailer)
1566 * trlr pointer to PDU trailer
1573 sscop_poll_inconn(sop, m, trlr)
1581 * Record error condition
1583 sscop_poll_error(sop, m, trlr);
1586 * Return an END to peer
1588 (void) sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
1591 * Notify user of connection failure
1593 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
1594 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
1596 sscop_abort(sop, "stack memory\n");
1601 * Go back to idle state
1603 sop->so_state = SOS_IDLE;
1610 * STAT PDU / Protocol Error
1613 * sop pointer to sscop connection block
1614 * m pointer to PDU buffer (without trailer)
1615 * trlr pointer to PDU trailer
1622 sscop_stat_error(sop, m, trlr)
1629 * Record error condition
1631 sscop_maa_error(sop, 'H');
1639 * STAT PDU / SOS_IDLE Processor
1642 * sop pointer to sscop connection block
1643 * m pointer to PDU buffer (without trailer)
1644 * trlr pointer to PDU trailer
1651 sscop_stat_idle(sop, m, trlr)
1658 * Report error condition
1660 sscop_stat_error(sop, m, trlr);
1663 * Return an END to peer
1665 (void) sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
1671 * STAT PDU / SOS_INCONN Processor
1674 * sop pointer to sscop connection block
1675 * m pointer to PDU buffer (without trailer)
1676 * trlr pointer to PDU trailer
1683 sscop_stat_inconn(sop, m, trlr)
1691 * Record error condition
1693 sscop_stat_error(sop, m, trlr);
1696 * Return an END to peer
1698 (void) sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
1701 * Notify user of connection failure
1703 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
1704 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
1706 sscop_abort(sop, "stack memory\n");
1711 * Go back to idle state
1713 sop->so_state = SOS_IDLE;
1720 * STAT PDU / SOS_READY Processor
1723 * sop pointer to sscop connection block
1724 * m pointer to PDU buffer (without trailer)
1725 * trlr pointer to PDU trailer
1732 sscop_stat_ready(sop, m, trlr)
1737 struct stat_pdu *sp = (struct stat_pdu *)trlr;
1738 struct pdu_hdr *php;
1740 sscop_seq seq1, seq2, opa;
1743 NTOHL(sp->stat_nps);
1744 NTOHL(sp->stat_nmr);
1748 * Validate peer's received poll sequence number
1750 if (SEQ_GT(sop->so_pollack, sp->stat_nps, sop->so_pollack) ||
1751 SEQ_GT(sp->stat_nps, sop->so_pollsend, sop->so_pollack)) {
1753 * Bad poll sequence number
1755 sscop_maa_error(sop, 'R');
1760 * Validate peer's current receive data sequence number
1762 if (SEQ_GT(sop->so_ack, sp->stat_nr, sop->so_ack) ||
1763 SEQ_GT(sp->stat_nr, sop->so_send, sop->so_ack)) {
1765 * Bad data sequence number
1767 sscop_maa_error(sop, 'S');
1772 * Free acknowledged PDUs
1774 for (seq1 = sop->so_ack, SEQ_SET(seq2, sp->stat_nr);
1775 SEQ_LT(seq1, seq2, sop->so_ack);
1776 SEQ_INCR(seq1, 1)) {
1777 sscop_pack_free(sop, seq1);
1781 * Update transmit state variables
1783 opa = sop->so_pollack;
1785 SEQ_SET(sop->so_pollack, sp->stat_nps);
1786 SEQ_SET(sop->so_sendmax, sp->stat_nmr);
1789 * Get first element in STAT list
1791 while (m && (KB_LEN(m) == 0))
1795 m = sscop_stat_getelem(m, &seq1);
1798 * Make sure there's a second element too
1804 * Validate first element (start of missing pdus)
1806 if (SEQ_GT(sop->so_ack, seq1, sop->so_ack) ||
1807 SEQ_GEQ(seq1, sop->so_send, sop->so_ack)) {
1809 * Bad element sequence number
1811 sscop_maa_error(sop, 'S');
1816 * Loop thru all STAT elements in list
1820 * Get next even element (start of received pdus)
1822 m = sscop_stat_getelem(m, &seq2);
1825 * Validate seqence number
1827 if (SEQ_GEQ(seq1, seq2, sop->so_ack) ||
1828 SEQ_GT(seq2, sop->so_send, sop->so_ack)) {
1830 * Bad element sequence number
1832 sscop_maa_error(sop, 'S');
1837 * Process each missing sequence number in this gap
1839 while (SEQ_LT(seq1, seq2, sop->so_ack)) {
1841 * Find corresponding SD PDU on pending ack queue
1843 php = sscop_pack_locate(sop, seq1);
1845 sscop_maa_error(sop, 'S');
1850 * Retransmit this SD PDU only if it was last sent
1851 * during an earlier poll sequence and it's not
1852 * already scheduled for retranmission.
1854 if (SEQ_LT(php->ph_nps, sp->stat_nps, opa) &&
1855 (php->ph_rexmit_lk == NULL) &&
1856 (sop->so_rexmit_tl != php)) {
1858 * Put PDU on retransmit queue and schedule
1859 * transmit servicing
1861 sscop_rexmit_insert(sop, php);
1862 sop->so_flags |= SOF_XMITSRVC;
1867 * Bump to next sequence number
1873 * Now process series of acknowledged PDUs
1875 * Get next odd element (start of missing pdus),
1876 * but make sure there is one and that it's valid
1880 m = sscop_stat_getelem(m, &seq2);
1881 if (SEQ_GEQ(seq1, seq2, sop->so_ack) ||
1882 SEQ_GT(seq2, sop->so_send, sop->so_ack)) {
1884 * Bad element sequence number
1886 sscop_maa_error(sop, 'S');
1891 * Process each acked sequence number
1893 while (SEQ_LT(seq1, seq2, sop->so_ack)) {
1895 * Can we clear transmit buffers ??
1897 if ((sop->so_flags & SOF_NOCLRBUF) == 0) {
1899 * Yes, free acked buffers
1901 sscop_pack_free(sop, seq1);
1905 * Bump to next sequence number
1913 * Free PDU buffer chain
1918 * Report retransmitted PDUs
1921 sscop_maa_error(sop, 'V');
1924 * Record transmit window closed transitions
1926 if (SEQ_LT(sop->so_send, sop->so_sendmax, sop->so_ack)) {
1927 if (sop->so_flags & SOF_NOCREDIT) {
1928 sop->so_flags &= ~SOF_NOCREDIT;
1929 sscop_maa_error(sop, 'X');
1932 if ((sop->so_flags & SOF_NOCREDIT) == 0) {
1933 sop->so_flags |= SOF_NOCREDIT;
1934 sscop_maa_error(sop, 'W');
1938 if (sop->so_vers == SSCOP_VERS_QSAAL)
1940 * Restart lost poll/stat timer
1942 sop->so_timer[SSCOP_T_NORESP] = sop->so_parm.sp_timeresp;
1945 * Determine new polling phase
1947 if ((sop->so_timer[SSCOP_T_POLL] != 0) &&
1948 ((sop->so_flags & SOF_KEEPALIVE) == 0)) {
1950 * Remain in active phase - reset NO-RESPONSE timer
1952 sop->so_timer[SSCOP_T_NORESP] =
1953 sop->so_parm.sp_timeresp;
1955 } else if (sop->so_timer[SSCOP_T_IDLE] == 0) {
1957 * Go from transient to idle phase
1959 sop->so_timer[SSCOP_T_POLL] = 0;
1960 sop->so_flags &= ~SOF_KEEPALIVE;
1961 sop->so_timer[SSCOP_T_NORESP] = 0;
1962 sop->so_timer[SSCOP_T_IDLE] = sop->so_parm.sp_timeidle;
1967 * See if transmit queues need servicing
1969 if (sop->so_flags & SOF_XMITSRVC)
1970 sscop_service_xmit(sop);
1976 * Protocol/parameter error encountered
1980 * Free PDU buffer chain
1984 if (sop->so_vers == SSCOP_VERS_QSAAL)
1986 * Reestablish a new connection
1988 qsaal1_reestablish(sop);
1991 * Initiate error recovery
1993 q2110_error_recovery(sop);
2000 * USTAT PDU / Protocol Error
2003 * sop pointer to sscop connection block
2004 * m pointer to PDU buffer (without trailer)
2005 * trlr pointer to PDU trailer
2012 sscop_ustat_error(sop, m, trlr)
2019 * Record error condition
2021 sscop_maa_error(sop, 'I');
2029 * USTAT PDU / SOS_IDLE Processor
2032 * sop pointer to sscop connection block
2033 * m pointer to PDU buffer (without trailer)
2034 * trlr pointer to PDU trailer
2041 sscop_ustat_idle(sop, m, trlr)
2048 * Report error condition
2050 sscop_ustat_error(sop, m, trlr);
2053 * Return an END to peer
2055 (void) sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
2061 * USTAT PDU / SOS_INCONN Processor
2064 * sop pointer to sscop connection block
2065 * m pointer to PDU buffer (without trailer)
2066 * trlr pointer to PDU trailer
2073 sscop_ustat_inconn(sop, m, trlr)
2081 * Record error condition
2083 sscop_ustat_error(sop, m, trlr);
2086 * Return an END to peer
2088 (void) sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
2091 * Notify user of connection failure
2093 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
2094 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
2096 sscop_abort(sop, "stack memory\n");
2101 * Go back to idle state
2103 sop->so_state = SOS_IDLE;
2110 * USTAT PDU / SOS_READY Processor
2113 * sop pointer to sscop connection block
2114 * m pointer to PDU buffer (without trailer)
2115 * trlr pointer to PDU trailer
2122 sscop_ustat_ready(sop, m, trlr)
2127 struct ustat_pdu *up = (struct ustat_pdu *)trlr;
2128 struct pdu_hdr *php;
2129 sscop_seq seq1, seq2;
2131 NTOHL(up->ustat_nmr);
2132 NTOHL(up->ustat_nr);
2135 * Validate peer's current receive data sequence number
2137 if (SEQ_GT(sop->so_ack, up->ustat_nr, sop->so_ack) ||
2138 SEQ_GEQ(up->ustat_nr, sop->so_send, sop->so_ack)) {
2140 * Bad data sequence number
2146 * Free acknowledged PDUs
2148 for (seq1 = sop->so_ack, SEQ_SET(seq2, up->ustat_nr);
2149 SEQ_LT(seq1, seq2, sop->so_ack);
2150 SEQ_INCR(seq1, 1)) {
2151 sscop_pack_free(sop, seq1);
2155 * Update transmit state variables
2158 SEQ_SET(sop->so_sendmax, up->ustat_nmr);
2161 * Get USTAT list elements
2163 SEQ_SET(seq1, ntohl(up->ustat_le1));
2164 SEQ_SET(seq2, ntohl(up->ustat_le2));
2169 if (SEQ_GT(sop->so_ack, seq1, sop->so_ack) ||
2170 SEQ_GEQ(seq1, seq2, sop->so_ack) ||
2171 SEQ_GEQ(seq2, sop->so_send, sop->so_ack)) {
2173 * Bad element sequence number
2179 * Process each missing sequence number in this gap
2181 while (SEQ_LT(seq1, seq2, sop->so_ack)) {
2183 * Find corresponding SD PDU on pending ack queue
2185 php = sscop_pack_locate(sop, seq1);
2191 * Retransmit this SD PDU if it's not
2192 * already scheduled for retranmission.
2194 if ((php->ph_rexmit_lk == NULL) &&
2195 (sop->so_rexmit_tl != php)) {
2197 * Put PDU on retransmit queue and schedule
2198 * transmit servicing
2200 sscop_rexmit_insert(sop, php);
2201 sop->so_flags |= SOF_XMITSRVC;
2205 * Bump to next sequence number
2211 * Report retransmitted PDUs
2213 sscop_maa_error(sop, 'V');
2216 * Free PDU buffer chain
2221 * See if transmit queues need servicing
2223 if (sop->so_flags & SOF_XMITSRVC)
2224 sscop_service_xmit(sop);
2230 * Protocol/parameter error encountered
2232 sscop_maa_error(sop, 'T');
2235 * Free PDU buffer chain
2239 if (sop->so_vers == SSCOP_VERS_QSAAL)
2241 * Reestablish a new connection
2243 qsaal1_reestablish(sop);
2246 * Initiate error recovery
2248 q2110_error_recovery(sop);
2255 * UD PDU / SOS_* Processor
2258 * sop pointer to sscop connection block
2259 * m pointer to PDU buffer (without trailer)
2260 * trlr pointer to PDU trailer
2267 sscop_ud_all(sop, m, trlr)
2275 * Pass data up to user
2277 STACK_CALL(SSCOP_UNITDATA_IND, sop->so_upper, sop->so_toku,
2278 sop->so_connvc, (int)m, 0, err);
2286 * MD PDU / SOS_* Processor
2289 * sop pointer to sscop connection block
2290 * m pointer to PDU buffer (without trailer)
2291 * trlr pointer to PDU trailer
2298 sscop_md_all(sop, m, trlr)
2305 * We don't support MD PDUs