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.6 2006/01/14 13:36:39 swildner Exp $
31 * ATM Forum UNI Support
32 * ---------------------
34 * SSCOP Common - Process CPCS-signals (SSCOP PDUs)
38 #include <netproto/atm/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(struct sscop *sop, KBuffer *m, caddr_t trlr)
70 * BGN PDU / SOS_IDLE Processor
73 * sop pointer to sscop connection block
74 * m pointer to PDU buffer (without trailer)
75 * trlr pointer to PDU trailer
82 sscop_bgn_idle(struct sscop *sop, KBuffer *m, caddr_t trlr)
84 struct bgn_pdu *bp = (struct bgn_pdu *)trlr;
87 if (sop->so_vers == SSCOP_VERS_Q2110) {
89 * "Power-up Robustness" option
91 * Accept BGN regardless of BGN.N(SQ)
93 sop->so_rcvconn = bp->bgn_nsq;
97 * If retransmitted BGN, reject it
99 if (sscop_is_rexmit(sop, bp->bgn_nsq)) {
101 sscop_send_bgrej(sop);
106 if (sop->so_vers == SSCOP_VERS_QSAAL) {
110 if (bp->bgn_type & PT_SOURCE_SSCOP)
111 source = SSCOP_SOURCE_SSCOP;
113 source = SSCOP_SOURCE_USER;
116 * Reset receiver state variables
118 qsaal1_reset_rcvr(sop);
123 * Set initial transmit window
125 SEQ_SET(sop->so_sendmax, ntohl(bp->bgn_nmr));
128 * Pass connection request up to user
130 STACK_CALL(SSCOP_ESTABLISH_IND, sop->so_upper, sop->so_toku,
131 sop->so_connvc, (int)m, source, err);
134 sscop_abort(sop, "stack memory\n");
139 * Wait for user's response
141 sop->so_state = SOS_INCONN;
148 * BGN PDU / SOS_OUTDISC Processor
151 * sop pointer to sscop connection block
152 * m pointer to PDU buffer (without trailer)
153 * trlr pointer to PDU trailer
160 sscop_bgn_outdisc(struct sscop *sop, KBuffer *m, caddr_t trlr)
162 struct bgn_pdu *bp = (struct bgn_pdu *)trlr;
166 * If retransmitted BGN, ACK it and send new END
168 if (sscop_is_rexmit(sop, bp->bgn_nsq)) {
170 sscop_send_bgak(sop);
171 sscop_send_end(sop, SSCOP_SOURCE_LAST);
176 * Stop retransmit timer
178 sop->so_timer[SSCOP_T_CC] = 0;
181 * Initialize transmit window
183 SEQ_SET(sop->so_sendmax, ntohl(bp->bgn_nmr));
186 * Notify user of connection termination
188 STACK_CALL(SSCOP_RELEASE_CNF, sop->so_upper, sop->so_toku,
189 sop->so_connvc, 0, 0, err);
192 sscop_abort(sop, "stack memory\n");
196 if (sop->so_vers == SSCOP_VERS_QSAAL) {
200 if (bp->bgn_type & PT_SOURCE_SSCOP)
201 source = SSCOP_SOURCE_SSCOP;
203 source = SSCOP_SOURCE_USER;
206 * Reset receiver variables
208 qsaal1_reset_rcvr(sop);
214 * Tell user about incoming connection
216 STACK_CALL(SSCOP_ESTABLISH_IND, sop->so_upper, sop->so_toku,
217 sop->so_connvc, (int)m, source, err);
220 sscop_abort(sop, "stack memory\n");
225 * Wait for user's response
227 sop->so_state = SOS_INCONN;
234 * BGN PDU / SOS_OUTRESYN Processor
237 * sop pointer to sscop connection block
238 * m pointer to PDU buffer (without trailer)
239 * trlr pointer to PDU trailer
246 sscop_bgn_outresyn(struct sscop *sop, KBuffer *m, caddr_t trlr)
248 struct bgn_pdu *bp = (struct bgn_pdu *)trlr;
252 * If retransmitted BGN, ACK it and send new RS
254 if (sscop_is_rexmit(sop, bp->bgn_nsq)) {
256 sscop_send_bgak(sop);
262 * Stop retransmit timer
264 sop->so_timer[SSCOP_T_CC] = 0;
267 * Initialize transmit window
269 SEQ_SET(sop->so_sendmax, ntohl(bp->bgn_nmr));
271 if (sop->so_vers == SSCOP_VERS_QSAAL) {
273 * Get (possible) Source value
275 if (bp->bgn_type & PT_SOURCE_SSCOP)
276 source = SSCOP_SOURCE_SSCOP;
278 source = SSCOP_SOURCE_USER;
281 * Reset receiver variables
283 qsaal1_reset_rcvr(sop);
286 source = SSCOP_SOURCE_USER;
289 * Notify user of connection termination
291 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
292 sop->so_connvc, SSCOP_UU_NULL, source, err);
295 sscop_abort(sop, "stack memory\n");
300 * Now tell user of a "new" incoming connection
302 STACK_CALL(SSCOP_ESTABLISH_IND, sop->so_upper, sop->so_toku,
303 sop->so_connvc, (int)m, source, err);
306 sscop_abort(sop, "stack memory\n");
311 * Wait for user's response
313 sop->so_state = SOS_INCONN;
320 * BGN PDU / SOS_INRESYN Processor
323 * sop pointer to sscop connection block
324 * m pointer to PDU buffer (without trailer)
325 * trlr pointer to PDU trailer
332 sscop_bgn_inresyn(struct sscop *sop, KBuffer *m, caddr_t trlr)
334 struct bgn_pdu *bp = (struct bgn_pdu *)trlr;
338 * If retransmitted BGN, oops
340 if (sscop_is_rexmit(sop, bp->bgn_nsq)) {
342 sscop_maa_error(sop, 'B');
347 * Stop data transfer timers
349 sop->so_timer[SSCOP_T_POLL] = 0;
350 sop->so_timer[SSCOP_T_NORESP] = 0;
351 sop->so_timer[SSCOP_T_IDLE] = 0;
352 sop->so_flags &= ~SOF_KEEPALIVE;
355 * Initialize transmit window
357 SEQ_SET(sop->so_sendmax, ntohl(bp->bgn_nmr));
359 if (sop->so_vers == SSCOP_VERS_QSAAL) {
361 * Get (possible) Source value
363 if (bp->bgn_type & PT_SOURCE_SSCOP)
364 source = SSCOP_SOURCE_SSCOP;
366 source = SSCOP_SOURCE_USER;
369 * Reset receiver variables
371 qsaal1_reset_rcvr(sop);
375 * Stop possible retransmit timer
377 sop->so_timer[SSCOP_T_CC] = 0;
380 * Drain receiver queues
382 sscop_rcvr_drain(sop);
385 * Tell user current connection has been released
387 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
388 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_USER, err);
391 sscop_abort(sop, "stack memory\n");
399 * Tell user of incoming connection
401 STACK_CALL(SSCOP_ESTABLISH_IND, sop->so_upper, sop->so_toku,
402 sop->so_connvc, (int)m, source, err);
405 sscop_abort(sop, "stack memory\n");
410 * Wait for user's response
412 sop->so_state = SOS_INCONN;
419 * BGAK PDU / Protocol Error
422 * sop pointer to sscop connection block
423 * m pointer to PDU buffer (without trailer)
424 * trlr pointer to PDU trailer
431 sscop_bgak_error(struct sscop *sop, KBuffer *m, caddr_t trlr)
435 * Record error condition
437 sscop_maa_error(sop, 'C');
445 * BGAK PDU / SOS_IDLE Processor
448 * sop pointer to sscop connection block
449 * m pointer to PDU buffer (without trailer)
450 * trlr pointer to PDU trailer
457 sscop_bgak_idle(struct sscop *sop, KBuffer *m, caddr_t trlr)
461 * Record error condition
463 sscop_bgak_error(sop, m, trlr);
466 * Return an END to peer
468 sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
474 * BGAK PDU / SOS_OUTCONN Processor
477 * sop pointer to sscop connection block
478 * m pointer to PDU buffer (without trailer)
479 * trlr pointer to PDU trailer
486 sscop_bgak_outconn(struct sscop *sop, KBuffer *m, caddr_t trlr)
488 struct bgak_pdu *bp = (struct bgak_pdu *)trlr;
492 * Stop retransmit timer
494 sop->so_timer[SSCOP_T_CC] = 0;
497 * Initialize transmit window
499 SEQ_SET(sop->so_sendmax, ntohl(bp->bgak_nmr));
502 * Notify user of connection establishment
504 if (sop->so_flags & SOF_REESTAB) {
506 STACK_CALL(SSCOP_ESTABLISH_IND, sop->so_upper, sop->so_toku,
507 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
509 sscop_abort(sop, "stack memory\n");
512 sop->so_flags &= ~SOF_REESTAB;
514 STACK_CALL(SSCOP_ESTABLISH_CNF, sop->so_upper, sop->so_toku,
515 sop->so_connvc, (int)m, 0, err);
518 sscop_abort(sop, "stack memory\n");
523 if (sop->so_vers == SSCOP_VERS_QSAAL) {
525 * Reset receiver variables
527 qsaal1_reset_rcvr(sop);
530 * Start polling timer
535 * Start lost poll/stat timer
537 sop->so_timer[SSCOP_T_NORESP] = sop->so_parm.sp_timeresp;
541 * Initialize state variables
543 q2110_init_state(sop);
546 * Start data transfer timers
548 sop->so_timer[SSCOP_T_POLL] = sop->so_parm.sp_timepoll;
549 sop->so_timer[SSCOP_T_NORESP] = sop->so_parm.sp_timeresp;
553 * OK, we're ready for data
555 sop->so_state = SOS_READY;
558 * See if transmit queues need servicing
560 if (sop->so_flags & SOF_XMITSRVC)
561 sscop_service_xmit(sop);
568 * BGREJ PDU / Protocol Error
571 * sop pointer to sscop connection block
572 * m pointer to PDU buffer (without trailer)
573 * trlr pointer to PDU trailer
580 sscop_bgrej_error(struct sscop *sop, KBuffer *m, caddr_t trlr)
584 * Record error condition
586 sscop_maa_error(sop, 'D');
593 * BGREJ PDU / SOS_OUTCONN Processor
596 * sop pointer to sscop connection block
597 * m pointer to PDU buffer (without trailer)
598 * trlr pointer to PDU trailer
605 sscop_bgrej_outconn(struct sscop *sop, KBuffer *m, caddr_t trlr)
610 * Stop retransmit timer
612 sop->so_timer[SSCOP_T_CC] = 0;
614 if (sop->so_vers == SSCOP_VERS_QSAAL) {
616 * Clear reestablishment flag
618 sop->so_flags &= ~SOF_REESTAB;
623 source = SSCOP_SOURCE_SSCOP;
626 source = SSCOP_SOURCE_USER;
630 * Notify user of connection failure
632 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
633 sop->so_connvc, uu, source, err);
636 sscop_abort(sop, "stack memory\n");
643 sop->so_state = SOS_IDLE;
650 * BGREJ PDU / SOS_INCONN Processor
653 * sop pointer to sscop connection block
654 * m pointer to PDU buffer (without trailer)
655 * trlr pointer to PDU trailer
662 sscop_bgrej_inconn(struct sscop *sop, KBuffer *m, caddr_t trlr)
667 * Report protocol error
669 sscop_bgrej_error(sop, m, trlr);
672 * Notify user of connection failure
674 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
675 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
677 sscop_abort(sop, "stack memory\n");
684 sop->so_state = SOS_IDLE;
691 * BGREJ PDU / SOS_OUTRESYN Processor
694 * sop pointer to sscop connection block
695 * m pointer to PDU buffer (without trailer)
696 * trlr pointer to PDU trailer
703 sscop_bgrej_outresyn(struct sscop *sop, KBuffer *m, caddr_t trlr)
708 * Stop retransmit timer
710 sop->so_timer[SSCOP_T_CC] = 0;
713 * Report protocol error
715 sscop_bgrej_error(sop, m, trlr);
718 * Notify user of connection failure
720 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
721 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
723 sscop_abort(sop, "stack memory\n");
727 if (sop->so_vers == SSCOP_VERS_QSAAL) {
729 * Clear connection data
731 qsaal1_clear_connection(sop);
737 sop->so_state = SOS_IDLE;
744 * BGREJ PDU / SOS_READY Processor
747 * sop pointer to sscop connection block
748 * m pointer to PDU buffer (without trailer)
749 * trlr pointer to PDU trailer
756 sscop_bgrej_ready(struct sscop *sop, KBuffer *m, caddr_t trlr)
761 * Stop data transfer timers
763 sop->so_timer[SSCOP_T_POLL] = 0;
764 sop->so_timer[SSCOP_T_NORESP] = 0;
765 sop->so_timer[SSCOP_T_IDLE] = 0;
766 sop->so_flags &= ~SOF_KEEPALIVE;
769 * Report protocol error
771 sscop_bgrej_error(sop, m, trlr);
774 * Notify user of connection failure
776 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
777 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
779 sscop_abort(sop, "stack memory\n");
783 if (sop->so_vers == SSCOP_VERS_QSAAL) {
785 * Clear connection data
787 qsaal1_clear_connection(sop);
790 * Clear out appropriate queues
792 q2110_prep_retrieve(sop);
798 sop->so_state = SOS_IDLE;
805 * END PDU / SOS_IDLE Processor
808 * sop pointer to sscop connection block
809 * m pointer to PDU buffer (without trailer)
810 * trlr pointer to PDU trailer
817 sscop_end_idle(struct sscop *sop, KBuffer *m, caddr_t trlr)
826 * Return an ENDAK to peer
828 sscop_send_endak(sop);
835 * END PDU / SOS_INCONN Processor
838 * sop pointer to sscop connection block
839 * m pointer to PDU buffer (without trailer)
840 * trlr pointer to PDU trailer
847 sscop_end_inconn(struct sscop *sop, KBuffer *m, caddr_t trlr)
849 struct end_pdu *ep = (struct end_pdu *)trlr;
853 * Stop retransmit timer
855 sop->so_timer[SSCOP_T_CC] = 0;
860 sscop_send_endak(sop);
865 if (ep->end_type & PT_SOURCE_SSCOP)
866 source = SSCOP_SOURCE_SSCOP;
868 source = SSCOP_SOURCE_USER;
871 * Notify user of connection termination
873 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
874 sop->so_connvc, (int)m, source, err);
877 sscop_abort(sop, "stack memory\n");
884 sop->so_state = SOS_IDLE;
891 * END PDU / SOS_OUTDISC Processor
894 * sop pointer to sscop connection block
895 * m pointer to PDU buffer (without trailer)
896 * trlr pointer to PDU trailer
903 sscop_end_outdisc(struct sscop *sop, KBuffer *m, caddr_t trlr)
908 * Stop retransmit timer
910 sop->so_timer[SSCOP_T_CC] = 0;
920 sscop_send_endak(sop);
923 * Notify user of connection termination
925 STACK_CALL(SSCOP_RELEASE_CNF, sop->so_upper, sop->so_toku,
926 sop->so_connvc, 0, 0, err);
928 sscop_abort(sop, "stack memory\n");
935 sop->so_state = SOS_IDLE;
942 * ENDAK PDU / Protocol Error
945 * sop pointer to sscop connection block
946 * m pointer to PDU buffer (without trailer)
947 * trlr pointer to PDU trailer
954 sscop_endak_error(struct sscop *sop, KBuffer *m, caddr_t trlr)
958 * Record error condition
960 sscop_maa_error(sop, 'F');
968 * ENDAK PDU / SOS_INCONN Processor
971 * sop pointer to sscop connection block
972 * m pointer to PDU buffer (without trailer)
973 * trlr pointer to PDU trailer
980 sscop_endak_inconn(struct sscop *sop, KBuffer *m, caddr_t trlr)
985 * Stop retransmit timer
987 sop->so_timer[SSCOP_T_CC] = 0;
990 * Report protocol error
992 sscop_endak_error(sop, m, trlr);
995 * Notify user of connection termination
997 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
998 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
1000 sscop_abort(sop, "stack memory\n");
1005 * Back to idle state
1007 sop->so_state = SOS_IDLE;
1014 * ENDAK PDU / SOS_OUTDISC Processor
1017 * sop pointer to sscop connection block
1018 * m pointer to PDU buffer (without trailer)
1019 * trlr pointer to PDU trailer
1026 sscop_endak_outdisc(struct sscop *sop, KBuffer *m, caddr_t trlr)
1031 * Stop retransmit timer
1033 sop->so_timer[SSCOP_T_CC] = 0;
1041 * Notify user of connection termination
1043 STACK_CALL(SSCOP_RELEASE_CNF, sop->so_upper, sop->so_toku,
1044 sop->so_connvc, 0, 0, err);
1046 sscop_abort(sop, "stack memory\n");
1051 * Back to idle state
1053 sop->so_state = SOS_IDLE;
1060 * ENDAK PDU / SOS_READY Processor
1063 * sop pointer to sscop connection block
1064 * m pointer to PDU buffer (without trailer)
1065 * trlr pointer to PDU trailer
1072 sscop_endak_ready(struct sscop *sop, KBuffer *m, caddr_t trlr)
1077 * Stop data transfer timers
1079 sop->so_timer[SSCOP_T_POLL] = 0;
1080 sop->so_timer[SSCOP_T_NORESP] = 0;
1081 sop->so_timer[SSCOP_T_IDLE] = 0;
1082 sop->so_flags &= ~SOF_KEEPALIVE;
1085 * Report protocol error
1087 sscop_endak_error(sop, m, trlr);
1090 * Notify user of connection failure
1092 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
1093 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
1095 sscop_abort(sop, "stack memory\n");
1099 if (sop->so_vers == SSCOP_VERS_QSAAL) {
1101 * Clear connection data
1103 qsaal1_clear_connection(sop);
1106 * Clear out appropriate queues
1108 q2110_prep_retrieve(sop);
1112 * Back to idle state
1114 sop->so_state = SOS_IDLE;
1121 * RS PDU / Protocol Error
1124 * sop pointer to sscop connection block
1125 * m pointer to PDU buffer (without trailer)
1126 * trlr pointer to PDU trailer
1133 sscop_rs_error(struct sscop *sop, KBuffer *m, caddr_t trlr)
1137 * Record error condition
1139 sscop_maa_error(sop, 'J');
1147 * RS PDU / SOS_IDLE Processor
1150 * sop pointer to sscop connection block
1151 * m pointer to PDU buffer (without trailer)
1152 * trlr pointer to PDU trailer
1159 sscop_rs_idle(struct sscop *sop, KBuffer *m, caddr_t trlr)
1163 * Report error condition
1165 sscop_rs_error(sop, m, trlr);
1168 * Return an END to peer
1170 sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
1177 * RSAK PDU / Protocol Error
1180 * sop pointer to sscop connection block
1181 * m pointer to PDU buffer (without trailer)
1182 * trlr pointer to PDU trailer
1189 sscop_rsak_error(struct sscop *sop, KBuffer *m, caddr_t trlr)
1193 * Record error condition
1195 sscop_maa_error(sop, 'K');
1203 * RSAK PDU / SOS_IDLE Processor
1206 * sop pointer to sscop connection block
1207 * m pointer to PDU buffer (without trailer)
1208 * trlr pointer to PDU trailer
1215 sscop_rsak_idle(struct sscop *sop, KBuffer *m, caddr_t trlr)
1219 * Report error condition
1221 sscop_rsak_error(sop, m, trlr);
1224 * Return an END to peer
1226 sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
1232 * RSAK PDU / SOS_OUTRESYN Processor
1235 * sop pointer to sscop connection block
1236 * m pointer to PDU buffer (without trailer)
1237 * trlr pointer to PDU trailer
1244 sscop_rsak_outresyn(struct sscop *sop, KBuffer *m, caddr_t trlr)
1246 struct rsak_q2110_pdu *rp = (struct rsak_q2110_pdu *)trlr;
1250 * Stop retransmit timer
1252 sop->so_timer[SSCOP_T_CC] = 0;
1255 * Notify user of resynchronization completion
1257 STACK_CALL(SSCOP_RESYNC_CNF, sop->so_upper, sop->so_toku,
1258 sop->so_connvc, 0, 0, err);
1261 sscop_abort(sop, "stack memory\n");
1265 if (sop->so_vers == SSCOP_VERS_QSAAL) {
1267 * Start the polling timer
1269 sscop_set_poll(sop);
1272 * Start lost poll/stat timer
1274 sop->so_timer[SSCOP_T_NORESP] = sop->so_parm.sp_timeresp;
1277 * Initialize state variables
1279 SEQ_SET(sop->so_sendmax, ntohl(rp->rsak_nmr));
1280 q2110_init_state(sop);
1283 * Start data transfer timers
1285 sop->so_timer[SSCOP_T_POLL] = sop->so_parm.sp_timepoll;
1286 sop->so_timer[SSCOP_T_NORESP] = sop->so_parm.sp_timeresp;
1295 * Now go back to data transfer state
1297 sop->so_state = SOS_READY;
1300 * See if transmit queues need servicing
1302 if (sop->so_flags & SOF_XMITSRVC)
1303 sscop_service_xmit(sop);
1310 * SD PDU / Protocol Error
1313 * sop pointer to sscop connection block
1314 * m pointer to PDU buffer (without trailer)
1315 * trlr pointer to PDU trailer
1322 sscop_sd_error(struct sscop *sop, KBuffer *m, caddr_t trlr)
1326 * Record error condition
1328 sscop_maa_error(sop, 'A');
1336 * SD PDU / SOS_IDLE Processor
1339 * sop pointer to sscop connection block
1340 * m pointer to PDU buffer (without trailer)
1341 * trlr pointer to PDU trailer
1348 sscop_sd_idle(struct sscop *sop, KBuffer *m, caddr_t trlr)
1352 * Record error condition
1354 sscop_sd_error(sop, m, trlr);
1357 * Return an END to peer
1359 sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
1365 * SD PDU / SOS_INCONN Processor
1368 * sop pointer to sscop connection block
1369 * m pointer to PDU buffer (without trailer)
1370 * trlr pointer to PDU trailer
1377 sscop_sd_inconn(struct sscop *sop, KBuffer *m, caddr_t trlr)
1382 * Record error condition
1384 sscop_sd_error(sop, m, trlr);
1387 * Return an END to peer
1389 sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
1392 * Notify user of connection failure
1394 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
1395 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
1397 sscop_abort(sop, "stack memory\n");
1402 * Go back to idle state
1404 sop->so_state = SOS_IDLE;
1411 * POLL PDU / Protocol Error
1414 * sop pointer to sscop connection block
1415 * m pointer to PDU buffer (without trailer)
1416 * trlr pointer to PDU trailer
1423 sscop_poll_error(struct sscop *sop, KBuffer *m, caddr_t trlr)
1427 * Record error condition
1429 sscop_maa_error(sop, 'G');
1437 * POLL PDU / SOS_IDLE Processor
1440 * sop pointer to sscop connection block
1441 * m pointer to PDU buffer (without trailer)
1442 * trlr pointer to PDU trailer
1449 sscop_poll_idle(struct sscop *sop, KBuffer *m, caddr_t trlr)
1453 * Report error condition
1455 sscop_poll_error(sop, m, trlr);
1458 * Return an END to peer
1460 sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
1466 * POLL PDU / SOS_INCONN Processor
1469 * sop pointer to sscop connection block
1470 * m pointer to PDU buffer (without trailer)
1471 * trlr pointer to PDU trailer
1478 sscop_poll_inconn(struct sscop *sop, KBuffer *m, caddr_t trlr)
1483 * Record error condition
1485 sscop_poll_error(sop, m, trlr);
1488 * Return an END to peer
1490 sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
1493 * Notify user of connection failure
1495 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
1496 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
1498 sscop_abort(sop, "stack memory\n");
1503 * Go back to idle state
1505 sop->so_state = SOS_IDLE;
1512 * STAT PDU / Protocol Error
1515 * sop pointer to sscop connection block
1516 * m pointer to PDU buffer (without trailer)
1517 * trlr pointer to PDU trailer
1524 sscop_stat_error(struct sscop *sop, KBuffer *m, caddr_t trlr)
1528 * Record error condition
1530 sscop_maa_error(sop, 'H');
1538 * STAT PDU / SOS_IDLE Processor
1541 * sop pointer to sscop connection block
1542 * m pointer to PDU buffer (without trailer)
1543 * trlr pointer to PDU trailer
1550 sscop_stat_idle(struct sscop *sop, KBuffer *m, caddr_t trlr)
1554 * Report error condition
1556 sscop_stat_error(sop, m, trlr);
1559 * Return an END to peer
1561 sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
1567 * STAT PDU / SOS_INCONN Processor
1570 * sop pointer to sscop connection block
1571 * m pointer to PDU buffer (without trailer)
1572 * trlr pointer to PDU trailer
1579 sscop_stat_inconn(struct sscop *sop, KBuffer *m, caddr_t trlr)
1584 * Record error condition
1586 sscop_stat_error(sop, m, trlr);
1589 * Return an END to peer
1591 sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
1594 * Notify user of connection failure
1596 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
1597 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
1599 sscop_abort(sop, "stack memory\n");
1604 * Go back to idle state
1606 sop->so_state = SOS_IDLE;
1613 * STAT PDU / SOS_READY Processor
1616 * sop pointer to sscop connection block
1617 * m pointer to PDU buffer (without trailer)
1618 * trlr pointer to PDU trailer
1625 sscop_stat_ready(struct sscop *sop, KBuffer *m, caddr_t trlr)
1627 struct stat_pdu *sp = (struct stat_pdu *)trlr;
1628 struct pdu_hdr *php;
1630 sscop_seq seq1, seq2, opa;
1633 sp->stat_nps = ntohl(sp->stat_nps);
1634 sp->stat_nmr = ntohl(sp->stat_nmr);
1635 sp->stat_nr = ntohl(sp->stat_nr);
1638 * Validate peer's received poll sequence number
1640 if (SEQ_GT(sop->so_pollack, sp->stat_nps, sop->so_pollack) ||
1641 SEQ_GT(sp->stat_nps, sop->so_pollsend, sop->so_pollack)) {
1643 * Bad poll sequence number
1645 sscop_maa_error(sop, 'R');
1650 * Validate peer's current receive data sequence number
1652 if (SEQ_GT(sop->so_ack, sp->stat_nr, sop->so_ack) ||
1653 SEQ_GT(sp->stat_nr, sop->so_send, sop->so_ack)) {
1655 * Bad data sequence number
1657 sscop_maa_error(sop, 'S');
1662 * Free acknowledged PDUs
1664 for (seq1 = sop->so_ack, SEQ_SET(seq2, sp->stat_nr);
1665 SEQ_LT(seq1, seq2, sop->so_ack);
1666 SEQ_INCR(seq1, 1)) {
1667 sscop_pack_free(sop, seq1);
1671 * Update transmit state variables
1673 opa = sop->so_pollack;
1675 SEQ_SET(sop->so_pollack, sp->stat_nps);
1676 SEQ_SET(sop->so_sendmax, sp->stat_nmr);
1679 * Get first element in STAT list
1681 while (m && (KB_LEN(m) == 0))
1685 m = sscop_stat_getelem(m, &seq1);
1688 * Make sure there's a second element too
1694 * Validate first element (start of missing pdus)
1696 if (SEQ_GT(sop->so_ack, seq1, sop->so_ack) ||
1697 SEQ_GEQ(seq1, sop->so_send, sop->so_ack)) {
1699 * Bad element sequence number
1701 sscop_maa_error(sop, 'S');
1706 * Loop thru all STAT elements in list
1710 * Get next even element (start of received pdus)
1712 m = sscop_stat_getelem(m, &seq2);
1715 * Validate seqence number
1717 if (SEQ_GEQ(seq1, seq2, sop->so_ack) ||
1718 SEQ_GT(seq2, sop->so_send, sop->so_ack)) {
1720 * Bad element sequence number
1722 sscop_maa_error(sop, 'S');
1727 * Process each missing sequence number in this gap
1729 while (SEQ_LT(seq1, seq2, sop->so_ack)) {
1731 * Find corresponding SD PDU on pending ack queue
1733 php = sscop_pack_locate(sop, seq1);
1735 sscop_maa_error(sop, 'S');
1740 * Retransmit this SD PDU only if it was last sent
1741 * during an earlier poll sequence and it's not
1742 * already scheduled for retranmission.
1744 if (SEQ_LT(php->ph_nps, sp->stat_nps, opa) &&
1745 (php->ph_rexmit_lk == NULL) &&
1746 (sop->so_rexmit_tl != php)) {
1748 * Put PDU on retransmit queue and schedule
1749 * transmit servicing
1751 sscop_rexmit_insert(sop, php);
1752 sop->so_flags |= SOF_XMITSRVC;
1757 * Bump to next sequence number
1763 * Now process series of acknowledged PDUs
1765 * Get next odd element (start of missing pdus),
1766 * but make sure there is one and that it's valid
1770 m = sscop_stat_getelem(m, &seq2);
1771 if (SEQ_GEQ(seq1, seq2, sop->so_ack) ||
1772 SEQ_GT(seq2, sop->so_send, sop->so_ack)) {
1774 * Bad element sequence number
1776 sscop_maa_error(sop, 'S');
1781 * Process each acked sequence number
1783 while (SEQ_LT(seq1, seq2, sop->so_ack)) {
1785 * Can we clear transmit buffers ??
1787 if ((sop->so_flags & SOF_NOCLRBUF) == 0) {
1789 * Yes, free acked buffers
1791 sscop_pack_free(sop, seq1);
1795 * Bump to next sequence number
1803 * Free PDU buffer chain
1808 * Report retransmitted PDUs
1811 sscop_maa_error(sop, 'V');
1814 * Record transmit window closed transitions
1816 if (SEQ_LT(sop->so_send, sop->so_sendmax, sop->so_ack)) {
1817 if (sop->so_flags & SOF_NOCREDIT) {
1818 sop->so_flags &= ~SOF_NOCREDIT;
1819 sscop_maa_error(sop, 'X');
1822 if ((sop->so_flags & SOF_NOCREDIT) == 0) {
1823 sop->so_flags |= SOF_NOCREDIT;
1824 sscop_maa_error(sop, 'W');
1828 if (sop->so_vers == SSCOP_VERS_QSAAL)
1830 * Restart lost poll/stat timer
1832 sop->so_timer[SSCOP_T_NORESP] = sop->so_parm.sp_timeresp;
1835 * Determine new polling phase
1837 if ((sop->so_timer[SSCOP_T_POLL] != 0) &&
1838 ((sop->so_flags & SOF_KEEPALIVE) == 0)) {
1840 * Remain in active phase - reset NO-RESPONSE timer
1842 sop->so_timer[SSCOP_T_NORESP] =
1843 sop->so_parm.sp_timeresp;
1845 } else if (sop->so_timer[SSCOP_T_IDLE] == 0) {
1847 * Go from transient to idle phase
1849 sop->so_timer[SSCOP_T_POLL] = 0;
1850 sop->so_flags &= ~SOF_KEEPALIVE;
1851 sop->so_timer[SSCOP_T_NORESP] = 0;
1852 sop->so_timer[SSCOP_T_IDLE] = sop->so_parm.sp_timeidle;
1857 * See if transmit queues need servicing
1859 if (sop->so_flags & SOF_XMITSRVC)
1860 sscop_service_xmit(sop);
1866 * Protocol/parameter error encountered
1870 * Free PDU buffer chain
1874 if (sop->so_vers == SSCOP_VERS_QSAAL)
1876 * Reestablish a new connection
1878 qsaal1_reestablish(sop);
1881 * Initiate error recovery
1883 q2110_error_recovery(sop);
1890 * USTAT PDU / Protocol Error
1893 * sop pointer to sscop connection block
1894 * m pointer to PDU buffer (without trailer)
1895 * trlr pointer to PDU trailer
1902 sscop_ustat_error(struct sscop *sop, KBuffer *m, caddr_t trlr)
1906 * Record error condition
1908 sscop_maa_error(sop, 'I');
1916 * USTAT PDU / SOS_IDLE Processor
1919 * sop pointer to sscop connection block
1920 * m pointer to PDU buffer (without trailer)
1921 * trlr pointer to PDU trailer
1928 sscop_ustat_idle(struct sscop *sop, KBuffer *m, caddr_t trlr)
1932 * Report error condition
1934 sscop_ustat_error(sop, m, trlr);
1937 * Return an END to peer
1939 sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
1945 * USTAT PDU / SOS_INCONN Processor
1948 * sop pointer to sscop connection block
1949 * m pointer to PDU buffer (without trailer)
1950 * trlr pointer to PDU trailer
1957 sscop_ustat_inconn(struct sscop *sop, KBuffer *m, caddr_t trlr)
1962 * Record error condition
1964 sscop_ustat_error(sop, m, trlr);
1967 * Return an END to peer
1969 sscop_send_end(sop, SSCOP_SOURCE_SSCOP);
1972 * Notify user of connection failure
1974 STACK_CALL(SSCOP_RELEASE_IND, sop->so_upper, sop->so_toku,
1975 sop->so_connvc, SSCOP_UU_NULL, SSCOP_SOURCE_SSCOP, err);
1977 sscop_abort(sop, "stack memory\n");
1982 * Go back to idle state
1984 sop->so_state = SOS_IDLE;
1991 * USTAT PDU / SOS_READY Processor
1994 * sop pointer to sscop connection block
1995 * m pointer to PDU buffer (without trailer)
1996 * trlr pointer to PDU trailer
2003 sscop_ustat_ready(struct sscop *sop, KBuffer *m, caddr_t trlr)
2005 struct ustat_pdu *up = (struct ustat_pdu *)trlr;
2006 struct pdu_hdr *php;
2007 sscop_seq seq1, seq2;
2009 up->ustat_nmr = ntohl(up->ustat_nmr);
2010 up->ustat_nr = ntohl(up->ustat_nr);
2013 * Validate peer's current receive data sequence number
2015 if (SEQ_GT(sop->so_ack, up->ustat_nr, sop->so_ack) ||
2016 SEQ_GEQ(up->ustat_nr, sop->so_send, sop->so_ack)) {
2018 * Bad data sequence number
2024 * Free acknowledged PDUs
2026 for (seq1 = sop->so_ack, SEQ_SET(seq2, up->ustat_nr);
2027 SEQ_LT(seq1, seq2, sop->so_ack);
2028 SEQ_INCR(seq1, 1)) {
2029 sscop_pack_free(sop, seq1);
2033 * Update transmit state variables
2036 SEQ_SET(sop->so_sendmax, up->ustat_nmr);
2039 * Get USTAT list elements
2041 SEQ_SET(seq1, ntohl(up->ustat_le1));
2042 SEQ_SET(seq2, ntohl(up->ustat_le2));
2047 if (SEQ_GT(sop->so_ack, seq1, sop->so_ack) ||
2048 SEQ_GEQ(seq1, seq2, sop->so_ack) ||
2049 SEQ_GEQ(seq2, sop->so_send, sop->so_ack)) {
2051 * Bad element sequence number
2057 * Process each missing sequence number in this gap
2059 while (SEQ_LT(seq1, seq2, sop->so_ack)) {
2061 * Find corresponding SD PDU on pending ack queue
2063 php = sscop_pack_locate(sop, seq1);
2069 * Retransmit this SD PDU if it's not
2070 * already scheduled for retranmission.
2072 if ((php->ph_rexmit_lk == NULL) &&
2073 (sop->so_rexmit_tl != php)) {
2075 * Put PDU on retransmit queue and schedule
2076 * transmit servicing
2078 sscop_rexmit_insert(sop, php);
2079 sop->so_flags |= SOF_XMITSRVC;
2083 * Bump to next sequence number
2089 * Report retransmitted PDUs
2091 sscop_maa_error(sop, 'V');
2094 * Free PDU buffer chain
2099 * See if transmit queues need servicing
2101 if (sop->so_flags & SOF_XMITSRVC)
2102 sscop_service_xmit(sop);
2108 * Protocol/parameter error encountered
2110 sscop_maa_error(sop, 'T');
2113 * Free PDU buffer chain
2117 if (sop->so_vers == SSCOP_VERS_QSAAL)
2119 * Reestablish a new connection
2121 qsaal1_reestablish(sop);
2124 * Initiate error recovery
2126 q2110_error_recovery(sop);
2133 * UD PDU / SOS_* Processor
2136 * sop pointer to sscop connection block
2137 * m pointer to PDU buffer (without trailer)
2138 * trlr pointer to PDU trailer
2145 sscop_ud_all(struct sscop *sop, KBuffer *m, caddr_t trlr)
2150 * Pass data up to user
2152 STACK_CALL(SSCOP_UNITDATA_IND, sop->so_upper, sop->so_toku,
2153 sop->so_connvc, (int)m, 0, err);
2161 * MD PDU / SOS_* Processor
2164 * sop pointer to sscop connection block
2165 * m pointer to PDU buffer (without trailer)
2166 * trlr pointer to PDU trailer
2173 sscop_md_all(struct sscop *sop, KBuffer *m, caddr_t trlr)
2177 * We don't support MD PDUs