#define RESOLVE_DBG
#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 <netat/sysglue.h>
#include <netat/appletalk.h>
#include <netat/at_pcb.h>
#include <netat/ddp.h>
#include <netat/adsp.h>
#include <netat/adsp_internal.h>
#ifdef notdefn
struct adsp_debug adsp_dtable[1025];
int ad_entry = 0;
#endif
int
adspAllocateCCB(gref)
register gref_t *gref;
{
gbuf_t *ccb_mp;
register CCBPtr sp;
if (!(ccb_mp = gbuf_alloc(sizeof(CCB), PRI_LO))) {
return (0);
}
bzero((caddr_t) gbuf_rptr(ccb_mp), sizeof(CCB));
gbuf_wset(ccb_mp,sizeof(CCB));
gref->info = (caddr_t) ccb_mp;
sp = (CCBPtr)gbuf_rptr(((gbuf_t *)gref->info));
sp->pid = gref->pid;
sp->gref = gref;
sp->sp_mp = ccb_mp;
return 1;
}
int
adspRelease(gref)
register gref_t *gref;
{
register CCBPtr sp;
if (gref->info) {
sp = (CCBPtr)gbuf_rptr(((gbuf_t *)gref->info));
if (sp->state == sPassive || sp->state == sClosed ||
sp->state == sOpening || sp->state == sListening) {
if (sp->state == sListening)
CompleteQueue(&sp->opb, errAborted);
sp->removing = 1;
DoClose(sp, errAborted, 0);
return 0;
} else {
sp->state = sClosing;
}
if (CheckOkToClose(sp)) {
sp->sendCtl = B_CTL_CLOSE;
} else {
CheckSend(sp);
if (sp->state != sClosed)
sp->sendCtl = B_CTL_CLOSE;
}
CheckSend(sp);
sp->removing = 1;
sp->state = sClosed;
DoClose(sp, errAborted, 0);
}
return 0;
}
int
adspWriteHandler(gref, mp)
gref_t *gref;
gbuf_t *mp;
{
register ioc_t *iocbp;
register struct adspcmd *ap;
int error, flag;
void *sp;
switch(gbuf_type(mp)) {
case MSG_DATA:
if (gref->info == 0) {
gbuf_freem(mp);
return(STR_IGNORE);
}
ap = (struct adspcmd *)gbuf_rptr(mp);
ap->gref = gref;
ap->ioc = 0;
ap->mp = mp;
sp = (void *)gbuf_rptr(((gbuf_t *)gref->info));
switch(ap->csCode) {
case dspWrite:
if ((error = adspWrite(sp, ap)))
gbuf_freem(mp);
return(STR_IGNORE);
case dspAttention:
if ((error = adspAttention(sp, (CCBPtr)ap)))
gbuf_freem(mp);
return(STR_IGNORE);
}
case MSG_IOCTL:
if (gref->info == 0) {
adspioc_ack(EPROTOTYPE, mp, gref);
return(STR_IGNORE);
}
iocbp = (ioc_t *) gbuf_rptr(mp);
if (ADSP_IOCTL(iocbp->ioc_cmd)) {
iocbp->ioc_count = sizeof(*ap) - 1;
if (gbuf_cont(mp) == 0) {
adspioc_ack(EINVAL, mp, gref);
return(STR_IGNORE);
}
ap = (struct adspcmd *) gbuf_rptr(gbuf_cont(mp));
ap->gref = gref;
ap->ioc = (caddr_t) mp;
ap->mp = gbuf_cont(mp);
ap->ioResult = 0;
if ((gref->info == 0) && ((iocbp->ioc_cmd != ADSPOPEN) &&
(iocbp->ioc_cmd != ADSPCLLISTEN))) {
ap->ioResult = errState;
adspioc_ack(EINVAL, mp, gref);
return(STR_IGNORE);
}
} else
return(STR_PUTNEXT);
sp = (void *)gbuf_rptr(((gbuf_t *)gref->info));
switch(iocbp->ioc_cmd) {
case ADSPOPEN:
case ADSPCLLISTEN:
ap->socket = ((CCBPtr)sp)->localSocket;
flag = (adspMode(ap) == ocAccept) ? 1 : 0;
if (flag && ap->socket) {
if (adspDeassignSocket((CCBPtr)sp) >= 0)
ap->socket = 0;
}
if ((ap->socket == 0) &&
((ap->socket =
(at_socket)adspAssignSocket(gref, flag)) == 0)) {
adspioc_ack(EADDRNOTAVAIL, mp, gref);
return(STR_IGNORE);
}
ap->csCode = iocbp->ioc_cmd == ADSPOPEN ? dspInit : dspCLInit;
if ((error = adspInit(sp, ap)) == 0) {
switch(ap->csCode) {
case dspInit:
ap->csCode = dspOpen;
error = adspOpen(sp, ap);
break;
case dspCLInit:
ap->csCode = dspCLListen;
error = adspCLListen(sp, ap);
break;
}
}
if (error)
adspioc_ack(error, mp, gref);
return(STR_IGNORE);
case ADSPCLOSE:
ap->csCode = dspClose;
if ((error = adspClose(sp, ap))) {
adspioc_ack(error, mp, gref);
break;
}
break;
case ADSPCLREMOVE:
ap->csCode = dspCLRemove;
error = adspClose(sp, ap);
adspioc_ack(error, mp, gref);
return(STR_IGNORE);
case ADSPCLDENY:
ap->csCode = dspCLDeny;
if ((error = adspCLDeny(sp, (CCBPtr)ap))) {
adspioc_ack(error, mp, gref);
}
return(STR_IGNORE);
case ADSPSTATUS:
ap->csCode = dspStatus;
if ((error = adspStatus(sp, ap))) {
adspioc_ack(error, mp, gref);
}
return(STR_IGNORE);
case ADSPREAD:
ap->csCode = dspRead;
if ((error = adspRead(sp, ap))) {
adspioc_ack(error, mp, gref);
}
return(STR_IGNORE);
case ADSPATTENTION:
ap->csCode = dspAttention;
if ((error = adspReadAttention((CCBPtr)sp, ap))) {
adspioc_ack(error, mp, gref);
}
return(STR_IGNORE);
case ADSPOPTIONS:
ap->csCode = dspOptions;
if ((error = adspOptions(sp, ap))) {
adspioc_ack(error, mp, gref);
}
return(STR_IGNORE);
case ADSPRESET:
ap->csCode = dspReset;
if ((error = adspReset(sp, ap))) {
adspioc_ack(error, mp, gref);
}
return(STR_IGNORE);
case ADSPNEWCID:
ap->csCode = dspNewCID;
if ((error = adspNewCID(sp, ap))) {
adspioc_ack(error, mp, gref);
}
return(STR_IGNORE);
default:
return(STR_PUTNEXT);
}
return(STR_IGNORE);
case MSG_PROTO:
default:
gbuf_freem(mp);
}
return(STR_IGNORE);
}
int
adspReadHandler(gref, mp)
gref_t *gref;
gbuf_t *mp;
{
int error;
switch(gbuf_type(mp)) {
case MSG_DATA:
if ((error = adspPacket(gref, mp))) {
gbuf_freem(mp);
}
break;
case MSG_IOCTL:
default:
return(STR_PUTNEXT);
break;
}
return(STR_IGNORE);
}
int
adsp_sendddp(sp, mp, length, dstnetaddr, ddptype)
CCBPtr sp;
gbuf_t *mp;
int length;
AddrUnion *dstnetaddr;
int ddptype;
{
DDPX_FRAME *ddp;
gbuf_t *mlist = mp;
if (mp == 0)
return EINVAL;
if (length > DDP_DATA_SIZE) {
gbuf_freel(mlist);
return EMSGSIZE;
}
while (mp) {
if (length == 0)
length = gbuf_msgsize(mp) - DDPL_FRAME_LEN;
ddp = (DDPX_FRAME *) gbuf_rptr(mp);
UAS_ASSIGN_HTON(ddp->ddpx_length, (length + DDPL_FRAME_LEN));
UAS_ASSIGN(ddp->ddpx_cksm, 0);
if (sp) {
if (sp->useCheckSum)
UAS_ASSIGN_HTON(ddp->ddpx_cksm, 1);
}
NET_ASSIGN(ddp->ddpx_dnet, dstnetaddr->a.net);
ddp->ddpx_dnode = dstnetaddr->a.node;
ddp->ddpx_source = sp ? sp->localSocket : ddp->ddpx_dest;
ddp->ddpx_dest = dstnetaddr->a.socket;
ddp->ddpx_type = ddptype;
length = 0;
mp = gbuf_next(mp);
}
DDP_OUTPUT(mlist);
return 0;
}
void NotifyUser(
__unused CCBPtr sp)
{
}
void UrgentUser(
__unused CCBPtr sp)
{
}