#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
#include <machine/spl.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/filedesc.h>
#include <sys/fcntl.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <net/if.h>
#include <netat/sysglue.h>
#include <netat/appletalk.h>
#include <netat/at_pcb.h>
#include <netat/at_var.h>
#include <netat/debug.h>
#include <netat/adsp.h>
#include <netat/adsp_internal.h>
void TrashSession(CCBPtr);
void TrashSession(sp)
CCBPtr sp;
{
sp->userFlags |= eTearDown;
sp->removing = 1;
sp->state = sClosed;
DoClose(sp, errAborted, 1);
}
void DoTimerElem(TimerElemPtr);
void DoTimerElem(t)
TimerElemPtr t;
{
CCBPtr sp;
sp = (CCBPtr)((Ptr)t - t->type);
if (t->type == kFlushTimerType) {
if (sp->sData) {
sp->writeFlush = 1;
goto send;
}
} else if (t->type == kRetryTimerType) {
if (sp->waitingAck) {
sp->waitingAck = 0;
sp->sendSeq = sp->firstRtmtSeq;
sp->pktSendCnt = 0;
sp->resentData = 1;
sp->noXmitFlow = 1;
if ((sp->pktSendMax /= 2) == 0)
sp->pktSendMax = 1;
if ((sp->roundTrip *= 2) > sp->probeInterval)
sp->roundTrip = sp->probeInterval;
sp->rtmtInterval = sp->roundTrip + ((short)2 *
(short)sp->deviation);
goto send;
}
} else if (t->type == kAttnTimerType) {
if (sp->sapb) {
sp->sendAttnData = 1;
goto send;
}
} else if (t->type == kResetTimerType) {
if (sp->frpb) {
sp->sendCtl |= B_CTL_FRESET;
goto send;
}
} else if (t->type == kProbeTimerType) {
if (sp->state == sOpen || sp->state == sClosing) {
if (--sp->probeCntr == 0) {
TrashSession(sp);
return;
} else {
InsertTimerElem(&adspGlobal.slowTimers, &sp->ProbeTimer,
sp->probeInterval);
sp->sendCtl |= B_CTL_PROBE;
goto send;
}
} else if (sp->state == sOpening) {
if ((sp->openState == O_STATE_OPENWAIT) ||
(sp->openState == O_STATE_ESTABLISHED))
{
if (--sp->openRetrys == 0) {
sp->state = sClosed;
DoClose(sp, errOpening, 1);
return;
}
else
{
sp->sendCtl |= (sp->openState == O_STATE_OPENWAIT) ?
B_CTL_OREQ : B_CTL_OREQACK;
goto send;
}
}
}
}
else {
dPrintf(D_M_ADSP, D_L_ERROR, ("DoTimerElem:Unknown timer type!\n"));
}
return;
send:
CheckSend(sp);
}
void TimerTick_funnel(void *arg);
void TimerTick_funnel(__unused void *arg)
{
atalk_lock();
TimerTick();
atalk_unlock();
}
static int StopTimer;
void TimerTick()
{
if (StopTimer) {
return;
}
TimerQueueTick(&adspGlobal.slowTimers);
TimerQueueTick(&adspGlobal.fastTimers);
timeout(TimerTick_funnel, (caddr_t)0, HZ/6);
}
void TimerStop()
{
StopTimer = 1;
untimeout(TimerTick_funnel, (caddr_t) 0);
}