static char sccsid
[] = "@(#)pk0.c 5.7 (Berkeley) 5/30/86";
char next
[8] = { 1, 2, 3, 4, 5, 6, 7, 0}; /* packet sequence numbers */
char mask
[8] = { 1, 2, 4, 010, 020, 040, 0100, 0200 };
struct pack
*pklines
[NPLINES
];
extern int pktimeout
, pktimeskew
, Ntimeout
;
* receive control messages
register struct pack
*pk
;
logent("PK0", "not cntl");
pk
->p_xsize
= pksizes
[val
];
if (pk
->p_state
& LIVE
) {
if ((pk
->p_state
& INITa
)==0) {
if ((pk
->p_state
&INITab
)==INITab
) {
if (val
== 0 && pk
->p_state
&LIVE
) {
logent("PK0", "alloc change not implemented");
if (pk
->p_rpr
== pk
->p_ps
) {
DEBUG(9, "Reack count is %d\n", ++Reacks
);
DEBUG(6, "Reack overflow on %d\n", val
);
logent("PK0", "srj not implemented");
pk
->p_state
= DOWN
+RCLOSE
;
register struct pack
*pk
;
char m
, cntl
, *p
, imask
, **bp
;
int bad
, accept
, skip
, t
, cc
;
while ((imask
=pk
->p_imap
) == 0 && pk
->p_rcount
== 0) {
* determine input window in m.
t
= (~(-1<<(int)(pk
->p_rwindow
))) <<x
;
* mark newly accepted input buffers
if ((imask
& mask
[x
]) == 0)
if (((cntl
=pk
->p_is
[x
])&0200) == 0) {
bp
= (char **)pk
->p_ib
[x
];
*bp
= (char *)pk
->p_ipool
;
pk
->p_is
[x
] = ~(B_COPY
+B_MARK
);
sum
= (unsigned)chksum(pk
->p_ib
[x
], pk
->p_rsize
) ^ (unsigned)(cntl
&0377);
if (pk
->p_is
[seq
] & (B_COPY
| B_MARK
)) {
pk
->p_ib
[x
] = pk
->p_ib
[seq
];
pk
->p_is
[x
] = pk
->p_is
[seq
];
pk
->p_is
[seq
] = B_MARK
+B_SHORT
;
cc
= (unsigned)*p
++ & 0377;
pk
->p_isum
[seq
] = pk
->p_rsize
- cc
;
* scan window again turning marked buffers into
* COPY buffers and looking for missing sequence
for(x
=next
[pk
->p_pr
]; m
& mask
[x
]; x
= next
[x
]) {
if (pk
->p_is
[x
] & B_MARK
)
if (pk
->p_is
[x
] & B_COPY
) {
bp
= (char **)pk
->p_ib
[x
];
*bp
= (char *)pk
->p_ipool
;
register struct pack
*pk
;
while (pkaccept(pk
) == 0)
cc
= MIN(pk
->p_isum
[x
], icount
);
pkmove(cp
, ibuf
, cc
, B_READ
);
if (pk
->p_isum
[x
] == 0) {
bp
= (char **)pk
->p_ib
[x
];
*bp
= (char *)pk
->p_ipool
;
pkwrite(pk
, ibuf
, icount
)
register struct pack
*pk
;
if (pk
->p_state
&DOWN
|| !pk
->p_state
&LIVE
) {
while (pk
->p_xcount
>=pk
->p_swindow
) {
while (pk
->p_os
[x
]!=B_NULL
) {
cp
= pk
->p_ob
[x
] = malloc((unsigned)pk
->p_xsize
);
if ((int)icount
< pk
->p_xsize
) {
pkmove(cp
, ibuf
, cc
, B_WRITE
);
pk
->p_osum
[x
] = chksum(pk
->p_ob
[x
], pk
->p_xsize
);
pk
->p_os
[x
] = B_READY
+partial
;
register struct pack
*pk
;
for(x
=pk
->p_ps
; x
!=pk
->p_rpr
; ) {
if (pk
->p_os
[x
]&B_SENT
) {
free((char *)pk
->p_ob
[x
]);
register struct pack
*pk
;
* find seq number and buffer state
pk
->p_nxtps
= next
[pk
->p_rpr
];
* Send control packet if indicated
if (pk
->p_msg
& ~M_RR
|| !(bstate
&B_READY
) ) {
x
+= pksize(pk
->p_rsize
);
* Don't send data packets if line is marked dead.
* Start transmission (or retransmission) of data packets.
if (bstate
& (B_READY
|B_SENT
)) {
x
= 0200+pk
->p_pr
+(seq
<<3);
* enable timeout if there's nothing to send
* and transmission buffers are languishing
* releasing space and turning off line discipline
register struct pack
*pk
;
while (pk
->p_xcount
&& pk
->p_state
&LIVE
) {
if (pk
->p_state
&(RCLOSE
+DOWN
) || ++i
> 2)
* try to exchange CLOSE messages
while ((pk
->p_state
&RCLOSE
)==0 && i
<2) {
if (pk
->p_os
[i
] != B_NULL
) {
free((char *)pk
->p_ob
[i
]);
if (pk
->p_is
[i
] != B_NULL
) {
free((char *)pk
->p_ib
[i
]);
while (pk
->p_ipool
!= NULL
) {
pk
->p_ipool
= (char **)*bp
;
if (rcheck
!= pk
->p_rwindow
) {
sprintf(buf
, "PK0: rc %d rw %d", rcheck
, pk
->p_rwindow
);
logent(buf
, "pkclose rcheck != p_rwindow");
register struct pack
*pk
;
pk
->p_ps
= pk
->p_pr
= pk
->p_rpr
= 0;