// PupStatServ.bcpl

// Last modified January 17, 1979  7:08 PM by Boggs

get "Pup0.decl"
get "Pup1.decl"

external
[
// outgoing procedures
CreateStatServ

// incoming procedures
Allocate; Enqueue; Dequeue; InitializeContext; Block
OpenLevel1Socket; ReleasePBI; ExchangePorts; CompletePup
HLookup

// incoming statics
pupRT
]

static statSoc

manifest
[
psStatistics = 22b
ptSendStats = 200b
ptStatsAck = 201b
ptStatsNak = 202b
]

//----------------------------------------------------------------------------
let CreateStatServ(zone, ctxQ) be
//----------------------------------------------------------------------------
[
statSoc = Allocate(zone, lenPupSoc)
OpenLevel1Socket(statSoc, table [ 0; 0; psStatistics ])
Enqueue(ctxQ,InitializeContext(Allocate(zone, 75), 75, StatServ))
]


//----------------------------------------------------------------------------
and StatServ() be
//----------------------------------------------------------------------------
[
Block() repeatwhile statSoc>>PupSoc.iQ.head eq 0
let pbi = Dequeue(lv statSoc>>PupSoc.iQ)
if pbi>>PBI.pup.type ne ptSendStats then [ ReleasePBI(pbi); loop ]
ExchangePorts(pbi)
let res = valof
   [
   let rte = HLookup(pupRT, pbi>>PBI.pup.words↑1)
   if rte ne 0 then
      if rte>>RTE.hops eq 0 then
         resultis rte>>RTE.ndb>>NDB.level0Stats(pbi, rte>>RTE.ndb)
   resultis false
   ]
test res
   ifso CompletePup(pbi, ptStatsAck)
   ifnot CompletePup(pbi, ptStatsNak, pupOvBytes)
] repeat