|
|
DataMuseum.dkPresents historical artifacts from the history of: Rational R1000/400 Tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Rational R1000/400 Tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T
Length: 45502 (0xb1be)
Types: TextFile
Names: »TCPLIB_C«
└─⟦afbc8121e⟧ Bits:30000532 8mm tape, Rational 1000, MC68020_OS2000 7_2_2
└─⟦77aa8350c⟧ »DATA«
└─⟦f794ecd1d⟧
└─⟦this⟧
/*****************************************************************************/
/* */
/* TCP/IP interface between application and driver. */
/* */
/* All calls to the TCP/IP driver are made trough routines in this file. */
/* This file shall be linked with the application programs. */
/* */
/* If switch ERR_REPORT is active the file TCPERR.C also must be linked with */
/* the application programs. */
/* */
/* Application programs may also have to include MSOCKET.H */
/* */
/* The function of each routine is described elsewhere in this file. */
/* */
/* Notes: */
/* 'Port' in OS9 corresponds to 'Socket' in ADA.C */
/* */
/* The parameter iocpara.timeout is passed to the driver. It specifies how */
/* long the program shall wait for an interrupt response from the board. */
/* */
/*---------------------------------------------------------------------------*/
/* Programmer: Lars Engdahl Mikrotell. 87.06.30 */
/* --------------------------------------------------------------------------*/
/* Entries: */
/* -------- */
/* nopen */
/* nsocket */
/* nconnect */
/* naccept */
/* nread */
/* nreread */
/* nwrite */
/* nioctl */
/* nsocketaddr */
/*****************************************************************************/
/*\f
*/
#include "../INCL/msocket.h" /* get the structs shown below */
#define ERR_REPORT /* to get error report */
#define ERR_PRINT /* to get error printout */
int tcp_errno; /* Error code, returned from libcalls below is placed here */
/*----------------------------------------------------------------------------*/
/* The FUNC_xxxxx defines below are also defined in TCPDRIVER.A */
/* These codes are used as parameters to TCPDRIVER.A */
#asm
FUNC_READ equ 140
FUNC_WRITE equ 141
FUNC_SOIOCTL equ 142
FUNC_SOCLOSE equ 143
FUNC_CLEANUP equ 160
ERR_DRV equ $EE00
#endasm
/*----------------------------------------------------------------------------*/
/*\f
*/
/*----------------------------------------------------------------------------*/
/* struct sockaddr */
/* { */
/* short sin_family */
/* Ushort sin_port */
/* Ulong sin_addr */
/* char sin_data[8] */
/* } */
/*----------------------------------------------------------------------------*/
/* struct sockproto not used in OS9 */
/* { */
/* short sp_family */
/* short sp_protocoll */
/* } */
/*----------------------------------------------------------------------------*/
/*
/* struct ioc_para */ /* Used to pass parameters to driver */
/* {
/* short reply ; */ /* must be first */
/* int type; */
/* int cmd; */
/* int sock_id ; */
/* char *bufptr ; */
/* int length ; */
/* short iamroot; */
/* short isaddr; */
/* int options; */
/* struct sockaddr asa; */
/* int timeout; */
/* }; */
/*-------------------------------------------------------------------------*/
int device_id;
/*-------------------------------------------------------------------------*/
/*\f
*/
/*==========================================================================*/
/* NOPEN Open device driver. */
/* */
/* Call: dev_id = nopen() */
/* */
/* Purpose: Open device driver. */
/* */
/* Input: --- */
/* */
/* Output: dev_id = to be used on following calls to nsocket, nsockaddr */
/* naccept, nconnect, nread, nioctl, nwrite, nclose. */
/* */
/* Driver : ---- */
/* */
/* ERROR: dev_id -1 errornumber in tcp_errno. */
/*--------------------------------------------------------------------------*/
/* Corresponding ADA procedure: none */
/*==========================================================================*/
int nopen()
{
int dev_id ;
#ifdef TRACE
printf("TCPLIB: nopen()\n");
#endif
dev_id = open("/tcpdev",3);
#ifdef ERR_PRINT
if (dev_id==-1)
printf("TCPLIB: nopen() *** ERROR. Can't open TCP device.\n");
#endif
#ifdef TRACE
printf("TCPLIB: nopen() done. dev_id =x%x\n", dev_id);
#endif
device_id = dev_id ; /* used by intercept routine */
init_intercept();
return (dev_id) ;
}
/*--------------------------------------------------------------------------*/
/*\f
*/
/*===========================================================================*/
/* NSOCKET create an end point for communication. */
/* */
/* If the socket is to be used for acccept the specified portnumber must be */
/* used by the connecting device. ( in struct asa ) */
/* */
/* Call: socket_id = nsocket(dev_id,type,asp,asa,options) */
/* */
/* input: dev_id = process-path id. (returned from nopen) */
/* type = defines sematics for comm. Only SOCK_STREAM is supported. */
/* *asp = protocoll family. Must be a NULL pointer. */
/* *asa = Used to define a specific local port. */
/* This is the port the Remote will make a connect on. */
/* */
/* 1. If *asa is a NULL pointer the EXOS board */
/* will pick an available port. */
/* nsocketaddr() can be used to find out what port */
/* value it picked. */
/* 2. If a specific port is desired: */
/* asa.sin_port := Local_Port_Number; */
/* asa.sin_family := AF_INET; (address family) */
/* */
/* options = SO_ACCEPTCONN must be used with sockets for accept */
/* */
/* output: socket_id to be used on following accept,connect,open,close requ */
/* */
/* Error: sock_id = -1. errornumber in tcp_errno. */
/* */
/* Driver: xsoioctl in MEXSOCKET */
/*---------------------------------------------------------------------------*/
/* Corresponding ADA procedure: */
/* Procedure Open( Connection: out Transport.Connection_Id; */
/* Status: out Transport_Defs.Status_Type; */
/* Network: Transport_Defs.Network_Name; */
/* Local_Socket: Transport_Defs.Socket_Id ); */
/* */
/* INPUT: Network: = "TCP/IP" */
/* Local_Socket: If Null then the system will pick one. */
/* OUTPUT: Connection: To be used in subsequent procedure calls. */
/* Status: Error message. */
/*===========================================================================*/
/*\f
*/
int nsocket(dev_id,type,asp,asa,options)
int dev_id; /* returned from previuos mopen */
int type; /* must be SOCK_STREAM */
struct sockproto *asp; /* must be a NULL pointer. */
struct sockaddr *asa; /* */
int options;
{
short sock_id;
struct ioc_para iocpara ; /* used to pass param to driver */
#ifdef TRACE
printf("TCPLIB: nsocket(). dev_id = x%x\n",dev_id);
#endif
iocpara.cmd = SOSOCKET;
iocpara.type = SOCK_STREAM; /* ? or input param 'type' */
iocpara.options = options;
iocpara.iamroot = 1; /* always considered privileged */
iocpara.timeout = 2000 ; /* timeout in ticks for board response */
if (asa == (struct sockaddr *) 0 ) iocpara.isaddr = 0 ;
else
{
iocpara.isaddr = 1 ;
iocpara.asa.sin_family = asa->sin_family ;
iocpara.asa.sin_port = asa->sin_port ;
iocpara.asa.sin_addr = asa->sin_addr ;
}
mso_ioctl(dev_id,&iocpara) ;
tcp_errno = iocpara.reply ;
#ifdef TRACE
printf("TCPLIB: nsocket() done. sock_id =x%x. Reply = x%x \n",
iocpara.sock_id,iocpara.reply);
#endif
if (tcp_errno != 0 ) goto error;
return iocpara.sock_id;
error:
#ifdef ERR_REPORT
print_error(tcp_errno,"nsocket().");
#else
#ifdef ERR_PRINT
printf("TCPLIB: *** ERROR in routine nsocket(): ErrCode = x%x\n",tcp_errno);
#endif
#endif
return -1;
}
/*--------------------------------------------------------------------------*/
/*\f
*/
/*===========================================================================*/
/* NSOCKADDR get own address and port. */
/* */
/* If the socket is to be used for acccept the specified portnumber must be */
/* known by the connecting device. */
/* */
/* Call: status = nsockaddr(dev_id,sock_id,asa) */
/* */
/* input: dev_id = process-path id. (returned from nopen) */
/* *asa = ...Used to define a specific local port. */
/* This is the port the Remote will make a connect on. */
/* */
/* output: The result is the same result that a remote host would get from */
/* an naccept call if you connected to him. */
/* asa.sin_port = Local port */
/* asa.sin_addr = Local Host address <<< addr does not work >>> */
/* */
/* Error: sock_id = -1. errornumber in tcp_errno. */
/* */
/* Driver: xsoioctl in MEXSOCKET */
/*---------------------------------------------------------------------------*/
/* Corresponding ADA procedures: Local_Host(...) , Local_Socket(....) */
/*===========================================================================*/
/*\f
*/
int nsockaddr(dev_id,sock_id,asa)
int dev_id; /* returned from previuos mopen */
int sock_id;
struct sockaddr *asa; /* */
{
struct ioc_para iocpara ; /* used to pass param to driver */
#ifdef TRACE
printf("TCPLIB: nsockaddr().\n");
#endif
iocpara.cmd = SOSOCKETADDR;
iocpara.sock_id = sock_id;
iocpara.type = SOCK_STREAM; /* ? or input param 'type' */
iocpara.timeout = 2000 ; /* timeout in ticks for board response */
iocpara.isaddr = 1 ;
mso_ioctl(dev_id,&iocpara) ;
tcp_errno = iocpara.reply ;
if (tcp_errno != 0 ) goto error;
asa->sin_port = iocpara.asa.sin_port ; /* driver placed Local port here*/
asa->sin_addr = iocpara.asa.sin_addr ; /* driver placed Local addr here*/
#ifdef TRACE
printf("TCPLIB: nsockaddr() done. addr =x%x. Port = x%x \n",
asa->sin_addr,asa->sin_port);
#endif
return 0;
error:
#ifdef ERR_REPORT
print_error(tcp_errno,"nsockaddr().");
#else
#ifdef ERR_PRINT
printf("TCPLIB: *** ERROR in routine nsockaddr(): ErrCode= x%x\n",tcp_errno);
#endif
#endif
return -1;
}
/*--------------------------------------------------------------------------*/
/*\f
*/
/*===========================================================================*/
/* NCONNECT initiates a connection request. */
/* */
/* Call: status = nconnect(dev_id,sock_id,asa) */
/* */
/* input: dev_id: device id, returned from previus mopen() */
/* sock_id: socket_id returned by previus socket() call. */
/* asa: pointer to struct with Remote Host's address and port. */
/* (address the remote is making an accept at() */
/* */
/* asa.sin-family = AF_INET */
/* asa.sin-port = Remote_Port_Number */
/* asa.sin_addr = Remote_Host_addr */
/* */
/* output: 0 is returned when the conection is established. */
/* -1 is returned if error. */
/* */
/* output: rval = -1 -- error. (error number is placed in tcp_errno) */
/* */
/* Driver: xsoioctl in MEXSOCKET */
/*---------------------------------------------------------------------------*/
/* Corresponding ADA procedure: */
/* */
/* Procedure Connect -- active connect */
/* ( */
/* Connection : Transport.connection_Id; -- returned from open */
/* Status : out Transport_Defs.Status_Type; */
/* Remote_Host : Transport_Defs.Host_Id; -- remote Host id. */
/* Remote_Socket: Transport_Defs.Socket_Id; -- remote socket id. */
/* Max_Wait : Duration := Duration'last; */
/* ); */
/* */
/*===========================================================================*/
/*\f
*/
nconnect(dev_id,sock_id,asa)
int dev_id; /* returned from previuos mopen */
short sock_id;
struct sockaddr *asa;
{
struct ioc_para iocpara ; /* used to pass param to driver */
#ifdef TRACE
printf("TCPLIB: nconnect()\n");
#endif
iocpara.cmd = SOCONNECT ;
iocpara.timeout = 4000 ; /* timeout in ticks for board response */
iocpara.type = SOCK_STREAM;
iocpara.sock_id = sock_id ;
iocpara.isaddr = 1 ;
iocpara.isaddr = 1 ;
iocpara.asa.sin_family = asa->sin_family ;
iocpara.asa.sin_port = asa->sin_port ;
iocpara.asa.sin_addr = asa->sin_addr ;
mso_ioctl(dev_id,&iocpara) ;
tcp_errno = iocpara.reply ;
#ifdef TRACE
printf("TCPLIB: nconnect() done. Reply = x%x\n",iocpara.reply);
#endif
if (tcp_errno != 0 ) goto error;
return 0;
error:
#ifdef ERR_REPORT
print_error(tcp_errno,"nconnect().");
#else
#ifdef ERR_PRINT
printf("TCPLIB: *** ERROR in routine nconnect(): ErrCode = x%x\n",tcp_errno);
#endif
#endif
return -1;
}
/*--------------------------------------------------------------------------*/
/*\f
*/
/*===========================================================================*/
/* NACCEPT provides the "listen end" of the protocoll handshake. */
/* */
/* Call: status = naccept(dev_id,sock_id,asa) */
/* */
/* input: dev_id: device id, returned from previus mopen() */
/* sock_id: socket_id returned by previus socket() call. */
/* asa: pointer to struct where connecting process' address and */
/* portnumber is returned. */
/* */
/* output: if accept is successful: connecting process' address and portno */
/* asa.sin-port = Remote_Port_Number */
/* asa.sin_addr = Remote_Host_addr */
/* */
/* 0 is returned when the connection is established. */
/* -1 error. (error number is placed in tcp_errno)? */
/* */
/* Driver: xsoioctl in MEXSOCKET */
/*---------------------------------------------------------------------------*/
/* Corresponding ADA procedure: Procedure Connect(....) -- passive connect */
/*===========================================================================*/
/*\f
*/
naccept(dev_id,sock_id,asa)
int dev_id; /* returned from previuos mopen */
short sock_id;
struct sockaddr *asa;
{
struct ioc_para iocpara ; /* used to pass param to driver */
#ifdef TRACE
printf("TCPLIB: naccept()\n");
#endif
iocpara.cmd = SOACCEPT ;
iocpara.timeout = 0000 ; /* no timeout */
iocpara.type = SOCK_STREAM; /* do I need this ??? */
iocpara.isaddr = 1 ; /* do I need this ??? */
iocpara.sock_id = sock_id ;
mso_ioctl(dev_id,&iocpara) ;
tcp_errno = iocpara.reply;
if (tcp_errno != 0 ) goto error;
asa->sin_port = iocpara.asa.sin_port ; /* driver placed Remote port here */
asa->sin_addr = iocpara.asa.sin_addr ; /* driver placed Remote addr here */
#ifdef TRACE
printf("TCPLIB: naccept() done. addr =x%x. Port = x%x \n",
asa->sin_addr,asa->sin_port);
#endif
return 0;
error:
#ifdef ERR_REPORT
print_error(tcp_errno,"naccept().");
#else
#ifdef ERR_PRINT
printf("TCPLIB: *** ERROR in routine naccept(). ErrCode = x%x\n",tcp_errno);
#endif
#endif
return -1;
}
/*--------------------------------------------------------------------------*/
/*\f
*/
/*===========================================================================*/
/* NIOCTL. */
/* */
/* Call:status = nioctl(dev_id,sock_id,func,para) */
/* */
/* input: dev_id: device id, returned from previus mopen() */
/* sock_id: socket_id returned by previus socket() call. */
/* ioctlcmd: Code for function to perform: */
/* para: pointer to in/out parameter. */
/* */
/* output: Depends on ioctlcmd: see below */
/* ------------------------------------------------------------------------ */
/* FIONREAD: Returns a byte count (in parameter 'para') of data in the */
/* socket's receive buffer. */
/* The user can use this before a nread() to avoid waiting for data.*/
/* ------------------------------------------------------------------------ */
/* FIONBIO: Enable/disable nonblocking IO */
/* input: *para = 1 - enable nonblocking IO */
/* input *para = 0 - disable nonblocking IO */
/* no output in *para. */
/* ------------------------------------------------------------------------ */
/* other functions may work, (if they are made 'not comments'). */
/* belived to be supported in driver ?? but are not tested (yet). */
/* ------------------------------------------------------------------------ */
/* */
/* output = -1 = error. (error number is placed in tcp_errno) */
/* */
/* Driver: xsoioctl - xsocontrol in MEXSOCKET */
/*---------------------------------------------------------------------------*/
/* Corresponding ADA procedure: ????? */
/*===========================================================================*/
/*\f
*/
nioctl(dev_id,sock_id,func,para)
int dev_id; /* returned from previuos mopen */
short sock_id;
short func; /* function code */
int *para;
{
struct ioc_para iocpara ; /* used to pass param to driver */
#ifdef TRACE
printf("TCPLIB: nioctl()\n");
#endif
iocpara.cmd = func ; /* = FIONREAD or FIONBIO ... ? */
iocpara.timeout = 2000 ; /* timeout in ticks for board response */
iocpara.sock_id = sock_id ;
/* check if a valid (implemented) function request */
switch(func)
{
case FIONREAD : /* ret no of bytes in rec buffer */
/* case SIOCGKEEP: */
/* case SIOCGLINGER: */
/* case SIOCRCVOOB: */
/* case SIOCATMARK: */
/* case SIOCGPGRP: */
break; /* no input parameter tu functions above */
/* case SIOCSENDOOB: */
case FIONBIO: /* enable disable nonblocking IO*/
/* case SIOCDONE: */
/* case SIOCSKEEP: */
/* case SIOCSLINGER: */
/* case SIOCSPGRP: */
iocpara.options = *para ; break;
default: tcp_errno = 0x5500 ; goto error; /* err code to be def later???*/
}
mso_ioctl(dev_id,&iocpara) ;
tcp_errno = iocpara.reply ;
#ifdef TRACE
printf("TCPLIB: nioctl() done. reply = x%x *para = %x\n",
iocpara.reply,iocpara.options );
#endif
if (tcp_errno != 0 ) goto error;
/* ---- put result (if any) in *para ---- */
switch(func)
{
case FIONREAD : /* ret no of bytes (int) in rec buf*/
/* case SIOCGKEEP: */ /* these returns a short */
/* case SIOCGLINGER: */
/* case SIOCATMARK: */
/* case SIOCGPGRP: */
/* case SIOCRCVOOB: */ /* this returns a char */
*para = iocpara.options ;
break;
}
return 0;
error:
#ifdef ERR_REPORT
print_error(tcp_errno,"nioctl().");
#else
#ifdef ERR_PRINT
printf("TCPLIB: *** ERROR in routine nioctl(). ErrCode = x%x\n",tcp_errno);
#endif
#endif
return -1;
}
/*-------------------------------------------------------------------------*/
/*\f
*/
/*===========================================================================*/
/* interface for driver call from nsocket,nsockaddr, naccept, nconnect,nioctl*/
/* return 0 if OK, -1 if error. return data in struct ioc_para. */
/*===========================================================================*/
#asm
mso_ioctl:
MOVEM.L D1/A0,-(A7)
MOVE.L D1,A0 /* A0 = pntr to ioc_para structure */
MOVE.W #FUNC_SOIOCTL,D1 /* D1 = funtion code passed to driver */
/* D0 = parameter path to OS-9 call */
OS9 I$GetStt
BCS.S err_mso /* error if carry set */
MOVEM.L (A7)+,D1/A0
RTS
*
err_mso MOVE.W #ERR_DRV,(A0) /* return error code in parptr-reply */
MOVEM.L (A7)+,D1/A0
RTS
#endasm
/*---------------------------------------------------------------------------*/
/*\f
*/
/*==========================================================================*/
/* NREAD */
/* */
/* Call: no_of_bytes = nread(id,s_id,bufptr,buflen) */
/* no_of_bytes = nreread(id,s_id,bufptr,buflen) << no timeout >> */
/* */
/* If the connection is still open but no message is in the queue, nread */
/* wait for the message. */
/* If the remote host is disconnected, nread will return zero. */
/* wait for the message. */
/* If bufflen < the maximum packet size (1024) and the message is > than */
/* buflen, buflen bytes will be read and the rest of the packet will be lost.*/
/* Therefore allways use a readbuffer with size >= 1024. */
/* */
/* Input: dev_id = device id. (returned from previus nopen) */
/* sock_id = socket id. (returned from previus nsocket) */
/* r_length = max no of bytes. */
/* r_buff = pointer to read buffer. */
/* */
/* output: no_of_bytes = -1 -- error. (errornumber is placed in tcp_errno)*/
/* no_of_bytes number of bytes read. */
/* */
/* Driver: xsoread in MEXSOCKET */
/*--------------------------------------------------------------------------*/
/* Corresponding ADA procedure: */
/* */
/* Procedure Receive */
/* ( */
/* Connection : Transport.connection_Id; */
/* Status : out Transport_Defs.Status_Code; */
/* Data : out Byte_Defs.Byte_String; */
/* Count : out Natural; */
/* Max_Wait : Duration := Duration'last; */
/* ); */
/*===========================================================================*/
/*\f
*/
int nread(dev_id,sock_id,r_buff,r_length)
int dev_id;
int sock_id;
int r_length;
char *r_buff;
{
struct ioc_para iocpara;
int count;
#ifdef TRACE
printf("TCPLIB: nread()\n");
#endif
iocpara.timeout = 0000 ; /* no timeout for board response */
iocpara.sock_id = sock_id ;
iocpara.bufptr = r_buff ;
iocpara.length = r_length ;
read_call(dev_id,&iocpara) ;
tcp_errno = iocpara.reply;
if (tcp_errno != 0 ) goto error;
#ifdef TRACE
printf("TCPLIB: nread() done. reply = x%x count = %x\n",
iocpara.reply,iocpara.length );
#endif
return (iocpara.length) ;
error:
#ifdef ERR_REPORT
print_error(tcp_errno,"nread().");
#else
#ifdef ERR_PRINT
printf("TCPLIB: *** ERROR in routine nread(). ErrCode = x%x\n",tcp_errno);
#endif
#endif
return -1;
}
/*==========================================================================*/
/* <<<<< not tested >>>>>> */
/*--------------------------------------------------------------------------*/
int nreread(dev_id,sock_id,r_buff,r_length)
int dev_id,sock_id,r_length;
char *r_buff;
{
struct ioc_para iocpara;
int count;
#ifdef TRACE
printf("TCPLIB: nreread()\n");
#endif
iocpara.timeout = 0000 ; /* no timeout for board response */
iocpara.sock_id = sock_id ;
iocpara.bufptr = r_buff ;
iocpara.length = r_length ;
read_call(dev_id,&iocpara) ;
tcp_errno = iocpara.reply;
if (tcp_errno != 0 ) goto error;
#ifdef TRACE
printf("TCPLIB: nreread() done. reply = x%x count = %x\n",
iocpara.reply,iocpara.length );
#endif
return (iocpara.length) ;
error:
#ifdef ERR_REPORT
print_error(tcp_errno,"nreread().");
#else
#ifdef ERR_PRINT
printf("TCPLIB: *** ERROR in routine nreread(). ErrCode = x%x\n",tcp_errno);
#endif
#endif
return -1;
}
/*--------------------------------------------------------------------------*/
/* interface for driver call from nread, nreread */
/* return 0 if OK, -1 if error. return data in struct ioc_para. */
/*--------------------------------------------------------------------------*/
#asm
read_call:
MOVEM.L D1/A0,-(A7)
MOVE.L D1,A0 /* A0 = pntr ioc_para structure */
MOVE.W #FUNC_READ,D1 /* D1 = funtion code passed to driver */
/* D0 = parameter path to OS-9 call */
OS9 I$GetStt
BCS.S err_rea /* error if carry set */
MOVEM.L (A7)+,D1/A0
RTS
err_rea MOVE.W #ERR_DRV,(A0) /* return error code in parptr-reply */
MOVEM.L (A7)+,D1/A0
RTS
#endasm
/*---------------------------------------------------------------------------*/
/*\f
*/
/*==========================================================================*/
/* NWRITE */
/* */
/* input: id: returned from previus mopen() */
/* s_id: socket_id returned by previus socket() call. */
/* s_buff: pointer to the message. */
/* s_length: length of the message. */
/* */
/* output: 0 number of written bytes. */
/* -1 -- error. (errornumber is placed in tcp_errno) */
/* */
/* Driver: xsowrite in MEX_SOCKET */
/*--------------------------------------------------------------------------*/
/* Corresponding ADA procedure: */
/* */
/* Procedure Transmit */
/* ( */
/* Connection : Transport.connection_Id; */
/* Status : out Transport_Defs.Status_Type; */
/* Data : out Byte_Defs.Byte_String; */
/* Count : out Natural; */
/* Max_Wait : Duration := Duration'last; */
/* More : Boolean := False */
/* ); */
/*===========================================================================*/
/*\f
*/
int nwrite(dev_id,sock_id,s_buff,s_length)
int dev_id,sock_id,s_length;
char *s_buff;
{
struct ioc_para iocpara;
#ifdef TRACE
printf("TCPLIB: nwrite()\n");
#endif
iocpara.timeout = 8000 ; /* timeout in ticks for board response */
iocpara.sock_id = sock_id ;
iocpara.bufptr = s_buff ;
iocpara.length = s_length ;
write_call(dev_id,&iocpara) ;
tcp_errno = iocpara.reply;
if (tcp_errno != 0 ) goto error;
#ifdef TRACE
printf("TCPLIB: nwrite() done. reply = x%x count = %x\n",
iocpara.reply,iocpara.length );
#endif
return (iocpara.length) ;
error:
#ifdef ERR_REPORT
print_error(tcp_errno,"nwrite().");
#else
#ifdef ERR_PRINT
printf("TCPLIB: *** ERROR in routine nwrite(). ErrCode = x%x\n",tcp_errno);
#endif
#endif
return -1;
}
/*--------------------------------------------------------------------------*/
/* interface for driver call from write */
/* return 0 if OK, -1 if error. return data in struct ioc_para. */
/*--------------------------------------------------------------------------*/
#asm
write_call:
MOVEM.L D1/A0,-(A7)
MOVE.L D1,A0 /* A0 = pntr ioc_para structure */
MOVE.W #FUNC_WRITE,D1 /* D1 = funtion code passed to driver */
/* D0 = parameter path to OS-9 call */
OS9 I$GetStt
BCS.S err_wri /* error if carry set */
MOVEM.L (A7)+,D1/A0
RTS
err_wri MOVE.W #ERR_DRV,(A0) /* return error code in parptr-reply */
MOVEM.L (A7)+,D1/A0
RTS
#endasm
/*---------------------------------------------------------------------------*/
/*\f
*/
/*==========================================================================*/
/* MSOCLOSE */
/* dont close driver only socket. */
/* input: dev_id: returned from previus mopen() */
/* sock_id: socket_id returned by previus nsocket() call. */
/* */
/* output: 0 OK */
/* -1 -- error. (errornumber is placed in tcp_errno) */
/* */
/* Driver: xsoclose in MEXSOCKET */
/*--------------------------------------------------------------------------*/
/* Corresponding ADA procedure: */
/* Procedure Disconnect ( Connection: Connection: Transport.Connection_Id );*/
/*===========================================================================*/
/*\f
*/
int nsoclose(dev_id,sock_id)
int dev_id,sock_id;
{
struct ioc_para iocpara;
#ifdef TRACE
printf("TCPLIB: nsoclose()\n");
#endif
iocpara.timeout = 2000 ; /* timeout in ticks for board response */
iocpara.sock_id = sock_id ;
soclose_call(dev_id,&iocpara) ;
tcp_errno = iocpara.reply;
if (tcp_errno != 0 ) goto error;
#ifdef TRACE
printf("TCPLIB: nsoclose() done. status = x%x\n",iocpara.reply);
#endif
return 0 ;
error:
#ifdef ERR_REPORT
print_error(tcp_errno,"nsoclose().");
#else
#ifdef ERR_PRINT
printf("TCPLIB: *** ERROR in routine nsoclose(). ErrCode = x%x\n",tcp_errno);
#endif
#endif
return(-1);
}
/*---------------------------------------------------------------------------*/
/* interface for driver call from soclose */
/* return 0 if OK, -1 if error. return data in struct ioc_para. */
/*---------------------------------------------------------------------------*/
#asm
soclose_call:
MOVEM.L D1/A0,-(A7)
MOVE.L D1,A0 /* A0 = pntr ioc_para structure */
MOVE.W #FUNC_SOCLOSE,D1 /* D1 = funtion code passed to driver */
/* D0 = parameter path to OS-9 call */
OS9 I$GetStt
BCS.S err_scl /* error if carry set */
MOVEM.L (A7)+,D1/A0
RTS
err_scl MOVE.W #ERR_DRV,(A0) /* return error code in parptr-reply */
MOVEM.L (A7)+,D1/A0
RTS
#endasm
/*---------------------------------------------------------------------------*/
/*\f
*/
/*==========================================================================*/
/* */
/* rval = nclose(id,s_id) perform an OS-9 close. */
/* if s_id >0 then also the socket is closed. */
/* (see nsoclose) */
/* Call: rval = nclose(dev_id,sock_id) */
/* */
/* input: dev_id: returned from previus mopen() */
/* sock_id: socket_id returned by previus socket() call. */
/* if =0 nsoclose is not called. */
/* if >0 a nsoclose is first performed. */
/* output: >=0 OK . */
/* -1 if error */
/* */
/* Driver: */
/*--------------------------------------------------------------------------*/
/* Corresponding ADA procedure: */
/* Procedure Close ( Connection: Transport.Connection_Id ); */
/*===========================================================================*/
int nclose(dev_id,sock_id)
int dev_id;
short sock_id;
{
int status ;
#ifdef TRACE
printf("TCPLIB: nclose()\n");
#endif
if (sock_id >0 ) nsoclose(dev_id,sock_id); /* no error handling ???? */
status = close(dev_id);
#ifdef TRACE
printf("TCPLIB: nclose() done. status = x%x\n",status);
#endif
return (status);
}
/*==========================================================================*/
/*\f
*/
/*===========================================================================*/
/* Whenever the process receives a signal this routine is executed. */
/* (an exception is the S$Wake signal sent by the interrrupt routine). */
/* control C -> signal code = 3 */
/* control E -> signal code = 2 */
/*===========================================================================*/
/* assembler routine t set up the intercept routine */
#asm
init_intercept:
MOVEM.L A0,-(sp)
LEA call_intercept(pc),A0
OS9 F$Icpt
MOVEM.L (sp)+,A0
RTS
call_intercept:
BSR tcp_intercept /* entry intercept routine sigcode in D1.W */
OS9 F$RTE
#endasm
/*===========================================================================*/
tcp_intercept(dummy,signalcode)
int dummy,signalcode;
{
switch(signalcode & 0xffff)
{
case 2: /* control E was pressed. Abort process. (after cleaning)*/
/* first perform some cleaning up, then exit process. */
#ifdef ERR_PRINT
printf
(">>>>>>>> Control E was pressed. Abort process. (after cleaning up.)\n");
#endif
tcp_cleanup( getpid() );
exit();
case 3: /* control C was pressed. */
/* just return. If the driver was waiting for a board */
/* interrupt. Error code ERR_ABORT will be returned to */
/* the caller which must do his own error handling. */
#ifdef ERR_PRINT
printf(">>>>>>>> Control C was pressed. Process interrupted.\n");
#endif
break;
default:
#ifdef ERR_PRINT
printf("TCPLIB: tcp_intercept() signalcode = %x.\n",signalcode);
#endif
exit();
}
}
/*===========================================================================*/
/* This function will free resoures on the EXOS bord owned by the process */
/* specified by the input parameter pid. */
/*===========================================================================*/
tcp_cleanup(pid)
int pid ;
{
struct ioc_para iocpara;
iocpara.type = pid;
#ifdef ERR_PRINT
printf("TCPLIB: tcp_cleanup() calling driver. Process id = x%x\n",pid);
#endif
cleanup_call(device_id,&iocpara) ;
}
/*===========================================================================*/
/* interface for driver call from tcp_cleanup to xsocleanup in MEXSOCKET.C */
/* return 0 if OK, -1 if error. return data in struct ioc_para. */
/*===========================================================================*/
#asm
cleanup_call:
MOVEM.L D1/A0,-(A7)
MOVE.L D1,A0 /* A0 = pntr to ioc_para structure */
MOVE.W #FUNC_CLEANUP,D1 /* D1 = funtion code passed to driver */
/* D0 = parameter path to OS-9 call */
OS9 I$GetStt
BCS.S err_cln /* error if carry set */
MOVEM.L (A7)+,D1/A0
RTS
*
err_cln MOVE.W #ERR_DRV,(A0) /* return error code in parptr-reply */
MOVEM.L (A7)+,D1/A0
RTS
#endasm
/*===========================================================================*/