remove unused code

This commit is contained in:
Marty Kraimer
1998-06-12 18:50:33 +00:00
parent ee6a29d3a3
commit aea3386205
8 changed files with 0 additions and 1951 deletions

View File

@@ -1,13 +0,0 @@
#
# $Id$
#
# Base Lowest Level Directroy Makefile
# by Janet Anderson
#
TOP=../..
include $(TOP)/config/CONFIG_BASE
include $(TOP)/config/RULES_ARCHS

View File

@@ -1,10 +0,0 @@
TOP = ../../..
include $(TOP)/config/CONFIG_BASE
INC := bdt.h
LIBSRCS := bdt.c
LIBRARY := Bdt
include $(TOP)/config/RULES.Host

View File

@@ -1,20 +0,0 @@
TOP = ../../..
include $(TOP)/config/CONFIG_BASE
SRCS.c += ../bdt.c
SRCS.c += ../bdtServ.c
SRCS.c += ../bdtServName.c
SRCS.c += ../bdtServPv.c
OBJS += bdt.o
OBJS += bdtServ.o
OBJS += bdtServName.o
OBJS += bdtServPv.o
PROD = bdt
include $(TOP)/config/RULES.Vx
$(PROD): $(OBJS)
$(RM) $@
$(LINK.c) $@ $(OBJS) $(LDLIBS)

View File

@@ -1,703 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <sys/wait.h>
#ifdef linux
#include <sys/resource.h>
#endif
#include <sys/types.h>
#include <sys/socket.h>
#ifdef vxWorks
#include <vxWorks.h>
#include <in.h>
#include <inetLib.h>
#include <taskLib.h>
#include <ioLib.h>
#include <selectLib.h>
#else
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <fcntl.h>
#endif
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include "bdt.h"
/* ---------------------------------------------------------------------- */
/* server mode functions */
#ifndef vxWorks /* server mode functions */
static char* filename=(char*)NULL;
/* ----------------------------- */
/* signal catcher for the server */
/* ----------------------------- */
static void catch_sig(int sig)
{
fprintf(stderr,"\nbdt server exiting\n");
unlink(filename);
exit(0);
}
/* -------------------------------- */
/* child reaper for the server mode */
/* -------------------------------- */
static void get_child(int sig)
{
while(wait3((int *)NULL,WNOHANG,(struct rusage *)NULL)>0);
#ifdef linux
signal(SIGCHLD,get_child); /* for reaping children */
#endif
}
/* ------------------------------- */
/* Clear the signals for a process */
/* ------------------------------- */
int BdtServerClearSignals()
{
signal(SIGCHLD,SIG_DFL);
signal(SIGHUP,SIG_DFL);
signal(SIGINT,SIG_DFL);
signal(SIGTERM,SIG_DFL);
signal(SIGQUIT,SIG_DFL);
return 0;
}
/* ----------------------------------------------------- */
/* Make a unix process into a generic background process */
/* ----------------------------------------------------- */
int BdtMakeServer(char** argv)
{
FILE* fd;
if(filename) return -1;
/* set up signal handling for the server */
signal(SIGCHLD,get_child); /* for reaping children */
signal(SIGHUP,catch_sig);
signal(SIGINT,catch_sig);
signal(SIGTERM,catch_sig);
signal(SIGQUIT,catch_sig);
/* disconnect from parent */
switch(fork())
{
case -1: /* error */
perror("Cannot fork");
return -1;
case 0: /* child */
#ifdef linux
setpgrp();
#else
setpgrp(0,0);
#endif
setsid();
break;
default: /* parent goes away */
exit(0);
}
/* save process ID */
filename=(char*)malloc(strlen(argv[0])+10);
sprintf(filename,"%s.%d",argv[0],getpid());
fd=fopen(filename,"w");
fprintf(fd,"%d",getpid());
fprintf(stderr,"\npv server pid: %d\n",getpid());
fclose(fd);
return 0;
}
#endif /* server mode functions */
/* ------------------------------------------ */
/* unimplemented channel access open function */
/* ------------------------------------------ */
BDT* BdtPvOpen(char *IocName, char* PvName)
{
BDT *bdt;
if((bdt = BdtIpOpen(IocName, BDT_TCP_PORT)) == NULL)
{
fprintf(stderr,"open of address %s failed\n", IocName);
return(NULL);
}
if(BdtServiceConnect(bdt, BDT_SERVICE_PV, PvName) < 0)
{
fprintf(stderr,"connect to PV %s failed\n", PvName);
BdtClose(bdt);
return(NULL);
}
return(bdt);
}
/* --------------------------------------------------------------- */
/* open a bulk data socket to a server given the server IP address */
/* --------------------------------------------------------------- */
BDT* BdtIpOpen(char* address, int Port)
{
struct hostent *pHostent;
struct sockaddr_in tsin;
unsigned long addr;
int osoc;
BDT *bdt;
#ifndef vxWorks
/* Deal with the name -vs- IP number issue. */
if (isdigit(address[0]))
#endif
addr=inet_addr(address);
#ifndef vxWorks
else
{
if ((pHostent = gethostbyname (address)) == NULL)
return(NULL);
memcpy (&addr,pHostent->h_addr,sizeof(addr));
printf("Converting name >%s< to IP number %08.8X\n", address, addr);
}
#endif
tsin.sin_port=0;
tsin.sin_family=AF_INET;
tsin.sin_addr.s_addr=htonl(INADDR_ANY);
if((osoc=socket(AF_INET,SOCK_STREAM,BDT_TCP))<0)
{
perror("BdtIpOpen: create socket failed");
return (BDT*)NULL;
}
if((bind(osoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
{
perror("BdtIpOpen: local address bind failed");
return (BDT*)NULL;
}
tsin.sin_port=htons(Port);
memcpy((char*)&tsin.sin_addr,(char*)&addr,sizeof(addr));
if(connect(osoc,(struct sockaddr*)&tsin,sizeof(tsin))<0)
{
perror("BdtIpOpen: connect failed");
close(osoc);
return (BDT*)NULL;
}
bdt=(BDT*)malloc(sizeof(BDT));
bdt->soc=osoc;
bdt->remaining_send=0;
bdt->remaining_recv=0;
bdt->state=BdtUnbound;
#ifndef vxWorks
{
int j;
j = fcntl(bdt->soc, F_GETFL, 0);
fcntl(bdt->soc, F_SETFL, j|O_NDELAY);
}
#endif
/* now connected to the bulk data socket on the IOC */
return bdt;
}
/* -------------------------------------- */
/* write size bytes from buffer to socket */
/* -------------------------------------- */
int BdtWrite(int soc,void* buffer,int size)
{
int rc;
int total;
unsigned char* data;
fd_set fds;
struct timeval to;
data=(unsigned char*)buffer;
total=size;
to.tv_sec = 5;
to.tv_usec = 0;
do
{
FD_ZERO(&fds);
FD_SET(soc, &fds);
if (select(soc+1, NULL, &fds, NULL, &to) != 1)
{
printf("BdtWrite: timeout waiting to write data\n");
return(-1);
}
/* send block of data */
if((rc=send(soc,&data[size-total],total,0))<0)
{
if(errno == EINTR)
rc = 0;
else
perror("BdtWrite: Send to remote failed");
}
else
total-=rc;
}
while(rc>0 && total>0);
return (rc<=0)?-1:0;
}
/* --------------------------------------- */
/* send a message header down a BDT socket */
/* --------------------------------------- */
int BdtSendHeader(BDT* bdt,unsigned short verb,int size)
{
BdtMsgHead buf;
if(bdt->state!=BdtIdle)
{
fprintf(stderr,"BdtSendHeader: Interface not idle\n");
bdt->state=BdtBad;
return -1;
}
buf.verb=htons(verb);
buf.size=htonl((unsigned long)size);
if(BdtWrite(bdt->soc,&buf.verb, sizeof(buf.verb))<0)
{
fprintf(stderr,"BdtSendHeader: write to remote failed");
return -1;
}
if(BdtWrite(bdt->soc,&buf.size, sizeof(buf.size))<0)
{
fprintf(stderr,"BdtSendHeader: write to remote failed");
return -1;
}
/* don't wait for response if data must go out */
if(size)
{
bdt->remaining_send=size;
bdt->state=BdtSData;
}
return 0;
}
/* ------------------------------------------- */
/* send a message data chunk down a BDT socket */
/* ------------------------------------------- */
int BdtSendData(BDT* bdt,void* buffer,int size)
{
int len;
int remaining;
int rc;
if(bdt->state!=BdtSData)
{
fprintf(stderr,"BdtSendData: Interface not in send data mode\n");
bdt->state=BdtBad;
return -1;
}
remaining=bdt->remaining_send-size;
if(remaining<0)
{
fprintf(stderr,"WARNING -- BdtSendData: To much data to send\n");
len=bdt->remaining_send;
}
else
len=size;
if (BdtWrite(bdt->soc, buffer, len) < 0)
return -1;
bdt->remaining_send-=len;
if(bdt->remaining_send<0)
{
fprintf(stderr,"BdtSendData: To much data Sent\n");
bdt->remaining_send=0;
}
if(bdt->remaining_send==0)
bdt->state=BdtIdle;
return len;
}
int BdtFlushOutput(BDT* bdt)
{
#ifdef vxWorks
ioctl(bdt->soc, FIOWFLUSH, 0);
#endif
}
/* ------------------------------------- */
/* Read exactly size bytes from remote */
/* ------------------------------------- */
int BdtRead(int soc,void* buffer,int size)
{
int rc,total;
unsigned char* data;
fd_set fds;
struct timeval to;
to.tv_sec = 5;
to.tv_usec = 0;
data=(unsigned char*)buffer;
total=size;
do
{
#if 1
/* wait for data chunk */
FD_ZERO(&fds);
FD_SET(soc, &fds);
if (select(soc+1, &fds, NULL, NULL, &to) != 1)
{
printf("BdtRead: timeout waiting for data\n");
return(-1);
}
#endif
if((rc=recv(soc,&data[size-total],total,0))<0)
{
if(errno==EINTR)
{
printf("BdtRead: EINTR");
rc=0;
}
else
{
perror("BdtRead: Receive data chunk failed");
}
}
else
total-=rc;
}
while(rc>0 && total>0);
return (rc<=0)?-1:0;
}
/* ------------------------------------- */
/* wait for a message header from remote */
/* ------------------------------------- */
int BdtReceiveHeader(BDT* bdt,int* verb,int* size)
{
BdtMsgHead buf;
/* can only receive header when in the idle state */
if (bdt->state == BdtEof)
return -1;
if(bdt->state != BdtIdle)
{
fprintf(stderr,"BdtReceiveHeader: Interface not idle\n");
bdt->state=BdtBad;
return -1;
}
if(BdtRead(bdt->soc,&buf.verb,sizeof(buf.verb))<0)
{
fprintf(stderr,"BdtReceiveHeader: Read failed\n");
return -1;
}
if(BdtRead(bdt->soc,&buf.size,sizeof(buf.size))<0)
{
fprintf(stderr,"BdtReceiveHeader: Read failed\n");
return -1;
}
/* copy message data to user */
*verb=ntohs(buf.verb);
*size=ntohl(buf.size);
if(*size)
bdt->state=BdtRData;
bdt->remaining_recv=*size;
return 0;
}
/* ------------------------------------------------------------------------
Wait for a chunk of data from remote.
User can continually call this with a maximum size until it return 0.
------------------------------------------------------------------------ */
int BdtReceiveData(BDT* bdt,void* buffer,int size)
{
int rc;
/* can only receive data when in the receive data state */
switch(bdt->state)
{
case BdtRData: break;
case BdtIdle: return 0;
default:
fprintf(stderr,"BdtReceiveData: bad receive state\n");
bdt->state=BdtBad;
break;
}
if (bdt->remaining_recv < size)
size = bdt->remaining_recv;
if(BdtRead(bdt->soc,buffer,size)<0)
{
fprintf(stderr,"BdtReceiveData: Read failed\n");
bdt->state = BdtEof;
return -1;
}
bdt->remaining_recv-=size;
if(bdt->remaining_recv<0)
{
fprintf(stderr,"BdtReceiveData: To much data received\n");
bdt->remaining_recv=0;
}
if(bdt->remaining_recv==0)
bdt->state=BdtIdle;
return size;
}
/* ------------------------------------------------------ */
/* connect to a process variable, useful if raw open used */
/* ------------------------------------------------------ */
int BdtServiceConnect(BDT* bdt, char* Name, char *Args)
{
int len;
int rc;
int size;
int verb;
unsigned char NameLen;
unsigned char ArgLen;
if(bdt->state!=BdtUnbound)
{
fprintf(stderr,"BdtServiceConnect: can only bind to one service\n");
return -1;
}
bdt->state=BdtIdle;
NameLen = strlen(Name)+1;
if (Args != NULL)
ArgLen = strlen(Args)+1;
else
ArgLen = 0;
/* send out connect message */
if(BdtSendHeader(bdt, BDT_Connect, NameLen+ArgLen) < 0)
{
fprintf(stderr,"BdtServiceConnect: send of connect header failed\n");
bdt->state=BdtUnbound;
return -1;
}
NameLen--;
ArgLen--;
/* send out the process variable to connect to */
if((BdtSendData(bdt, &NameLen, 1) < 0) || (BdtSendData(bdt, Name, NameLen) < 0))
{
fprintf(stderr,"BdtServiceConnect: send of connect body failed\n");
bdt->state=BdtUnbound;
return -1;
}
if (ArgLen > 0)
{
if ((BdtSendData(bdt, &ArgLen, 1) < 0) || (BdtSendData(bdt, Args, ArgLen) < 0))
{
fprintf(stderr,"BdtServiceConnect: send of connect body failed\n");
bdt->state=BdtUnbound;
return -1;
}
}
rc=0;
/* wait for response from connect to process variable */
if(BdtReceiveHeader(bdt,&verb,&size)<0)
{
fprintf(stderr,"BdtServiceConnect: receive reponse failed\n");
bdt->state=BdtUnbound;
return -1;
}
/* check response */
switch(verb)
{
case BDT_Ok:
rc=0;
break;
case BDT_Error:
fprintf(stderr,"BdtServiceConnect: connection rejected\n");
bdt->state=BdtUnbound;
rc=-1;
break;
default:
fprintf(stderr,"BdtServiceConnect: unknown response from remote\n");
bdt->state=BdtUnbound;
rc=-1;
break;
}
return rc;
}
/* -------------------- */
/* close the connection */
/* -------------------- */
int BdtClose(BDT* bdt)
{
int verb,size,done;
/* send a close message out */
if(BdtSendHeader(bdt,BDT_Close,0)<0)
{
fprintf(stderr,"BdtClose: Cannot send close message\n");
return -1;
}
done=0;
do
{
/* check response */
if(BdtReceiveHeader(bdt,&verb,&size)<0)
{
fprintf(stderr,"BdtClose: Close message response error\n");
return -1;
}
switch(verb)
{
case BDT_Ok:
done=1;
break;
case BDT_Error:
fprintf(stderr,"BdtClose: Close rejected\n");
return -1;
break;
default: break;
}
}
while(done==0);
bdt->state=BdtUnbound;
free(bdt);
return 0;
}
/* --------------------------------------- */
/* make a listener socket for UDP - simple */
/* --------------------------------------- */
int BdtOpenListenerUDP(int Port)
{
int nsoc;
struct sockaddr_in tsin;
tsin.sin_port=htons(Port);
tsin.sin_family=AF_INET;
tsin.sin_addr.s_addr=htonl(INADDR_ANY);
if((nsoc=socket(AF_INET,SOCK_DGRAM,BDT_UDP))<0)
{
perror("BdtOpenListenerUDP: open socket failed");
return -1;
}
if((bind(nsoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
{
perror("BdtOpenListenerUDP: local bind failed");
close(nsoc);
return -1;
}
return nsoc;
}
/* --------------------------------------- */
/* make a listener socket for TCP - simple */
/* --------------------------------------- */
int BdtOpenListenerTCP(int Port)
{
int nsoc;
struct sockaddr_in tsin;
memset (&tsin, 0, sizeof(struct sockaddr_in));
tsin.sin_port=htons(Port);
tsin.sin_family=htons(AF_INET);
tsin.sin_addr.s_addr=htonl(INADDR_ANY);
if((nsoc=socket(AF_INET,SOCK_STREAM,BDT_TCP))<0)
{
perror("BdtOpenListenerTCP: open socket failed");
return -1;
}
if((bind(nsoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
{
perror("BdtOpenListenerTCP: local bind failed");
close(nsoc);
return -1;
}
listen(nsoc,5);
return nsoc;
}
/* ------------------------------- */
/* make BDT from a socket - simple */
/* ------------------------------- */
BDT* BdtMakeBDT(int soc)
{
BDT* bdt;
bdt=(BDT*)malloc(sizeof(BDT));
bdt->soc=soc;
bdt->remaining_send=0;
bdt->remaining_recv=0;
bdt->state=BdtIdle;
return bdt;
}
/* --------------------------- */
/* free a BDT and close socket */
/* --------------------------- */
int BdtFreeBDT(BDT* bdt)
{
close(bdt->soc);
free(bdt);
return 0;
}
int BdtPvPutArray(BDT *bdt, short DbrType, void *Buf, unsigned long NumElements,
unsigned long ElementSize)
{
int Verb;
int Size;
unsigned long BufSize;
BufSize = NumElements * ElementSize;
if (BdtSendHeader(bdt, BDT_Put, 6 + BufSize) != 0)
return(-1);
if (BdtSendData(bdt, &DbrType, 2) < 0)
return(-1);
if (BdtSendData(bdt, &NumElements, 4) < 0)
return(-1);
if (BdtSendData(bdt, Buf, BufSize) < 0)
return(-1);
if (BdtReceiveHeader(bdt, &Verb, &Size) != 0)
return(-1);
if (Verb != BDT_Ok)
return(-1);
return(0);
}

View File

@@ -1,304 +0,0 @@
#ifndef __BDT_H
#define __BDT_H
/*
* $Log$
* Revision 1.4 1995/07/27 14:21:58 winans
* General mods for first release.
*
* Revision 1.3 1995/05/30 14:47:17 winans
* Added BDT_Ping and a port parm to BdtIpOpen.
*
* Revision 1.2 1995/05/16 15:38:00 winans
* Added BdtEof to BdtState enum list.
* Added WriteLock and DeltaFlagLock to vxWorks-side BDTs.
* Added port number args to BdtOpenListenerTCP() and BdtOpenListenerUDP().
*
* Revision 1.1 1995/05/11 02:08:44 jbk
* new file for the bulk data transfer stuff
*
*/
/*
Author: Jim Kowalkowski
Date: 5/1/95
*/
/* got from protocols(5) (cheated) or /etc/protocols */
#define BDT_UDP 17
#define BDT_TCP 6
/* server ports - in the user reserved area */
#define BDT_UDP_PORT 50296
#define BDT_TCP_PORT 50297
/* Well known service names */
#define BDT_SERVICE_PV "pv"
#define BDT_SERVICE_NAME "name"
#define BDT_SERVICE_DRV "drv"
#define PV_TRANSFER_SIZE 512
/* How often some type of message is expected to arrive at each end-point */
#define BDT_PING_INTERVAL 10 /* Specified in seconds */
#define BDT_CONENCTION_TIMEOUT 25 /* Specified in seconds */
/* message types */
#define BDT_Ok 0
#define BDT_Connect 1
#define BDT_Error 2
#define BDT_Get 3
#define BDT_Put 4
#define BDT_Close 5
#define BDT_Monitor 6
#define BDT_Value 7
#define BDT_Delta 8
#define BDT_Add 9
#define BDT_Delete 10
#define BDT_Ping 11
#define BDT_LAST_VERB 11
/* protocol states */
typedef enum
{ BdtIdle,BdtUnbound,BdtSData,BdtRData,BdtBad,BdtEof } BdtState;
/******************************************************************************
*
* The format of a BDT_Connect message is:
*
* BdtMsgHead.verb (unsigned 16 binary = BDT_Connect)
* BdtMsgHead.size (unsigned 32 bit binary)
* service name length (unsigned 8 bit binary)
* service name string (service name length characters)
* arg1 string length (unsigned 8 bit binary)
* arg1 string (arg1 string length characters)
* ...
*
******************************************************************************/
/******************************************************************************
*
* NOTICE!!!!!!!! MONITORS ARE NOT CURRENTLY SUPPORTED!!!!!!!
*
* The BdtMonitor structure is created on the server-side when ever a client
* registers a monitor. It contains a tag string that is given by the client
* when the monitor is established. This tag string is an arbitrary binary
* string of bytes... presumably used by the client as a pointer or index
* to a status structure that represents the resource being monitored.
*
* The Message portion of the BdtMonitor represents the body of the message
* that is to be sent to the client to indicate the status of the event that
* happened. (It may not be present in the message.)
*
* The BdtMonitor structures are only hooked into the bdt.pMonitor list if they
* are waiting to be sent to the client.
*
* The format of a BDT_Monitor message is:
*
* BdtMsgHead.verb (unsigned 16 binary = BDT_Monitor)
* BdtMsgHead.size (unsigned 32 bit binary)
* TagLength (unsigned 32 bit binary)
* Tag (TagLength characters)
* service name string (BdtMsgHead.size-TagLength-4 characters)
*
* The <service name string> for a monitor message should include the object
* name(s) that are to be monitored.
*
*
* The format of a BDT_Delta message is:
*
* BdtMsgHead.verb (unsigned 16 binary = BDT_Delta)
* BdtMsgHead.size (unsigned 32 bit binary)
* BdtMonitor.TagLength (unsigned 32 bit binary)
* BdtMonitor.Tag (BdtMonitor.TagLength characters)
* BdtMonitor.MessageLength (unsigned 32 bit binary)
* BdtMonitor.Message (BdtMonitor.MessageLength characters)
*
******************************************************************************/
struct bdt;
typedef struct BdtMonitor
{
struct bdt *pBdt; /* Connection to send notices back to */
char *Tag; /* Client-generated tag */
int TagLength; /* Length of tag */
char *Message; /* Server-gen'd status change message */
int MessageLength; /* Length of Message */
struct BdtMonitor *pNext; /* Allow queue of N outbound on BDT */
} BdtMonitor;
typedef int (*BdthandlerFunc)(struct bdt *Bdt);
typedef struct BdtHandlers
{
BdthandlerFunc Ok;
BdthandlerFunc Connect;
BdthandlerFunc Error;
BdthandlerFunc Get;
BdthandlerFunc Put;
BdthandlerFunc Close;
BdthandlerFunc Monitor;
BdthandlerFunc Value;
BdthandlerFunc Delta;
BdthandlerFunc Add;
BdthandlerFunc Delete;
BdthandlerFunc Ping;
} BdtHandlers;
struct bdt
{
int soc;
int remaining_send;
int remaining_recv;
BdtState state;
#ifdef vxWorks
char *Name; /* Service name (used for messages) */
SEM_ID WriteLock;
SEM_ID MonitorLock;
BdtMonitor *pMonitor; /* List of pending monitor events */
BdthandlerFunc *pHandlers; /* Support routines for messages */
void *pService; /* Provate pointer for service */
#endif
};
typedef struct bdt BDT;
struct BdtMsgHead
{
unsigned short verb;
unsigned long size;
};
typedef struct BdtMsgHead BdtMsgHead;
#define BdtGetSocket(BDT) (BDT->soc)
#define BdtGetResidualWrite(BDT) (BDT->remaining_send)
#define BdtGetResidualRead(BDT) (BDT->remaining_recv)
#define BdtGetProtoState(BDT) (BDT->state)
#ifdef vxWorks
#define BdtGetServiceName(BDT) (BDT->Name)
#endif
/* ------------------------------------------------------------------------
Server functions:
BdtOpenListenerTCP:
Open a socket locally bound to the bulk data transfer TCP server port.
Set the socket up as a listener. Return the open socket.
BdtOpenListenerUDP:
Open a socket locally bound to the bulk data transfer UDP server port.
Return the open socket.
------------------------------------------------------------------------ */
int BdtOpenListenerTCP(int Port);
int BdtOpenListenerUDP(int Port);
/* ------------------------------------------------------------------------
Utilities functions:
BdtMakeServer:
Available under unix only. Put process in the background, disassociate
process from controlling terminal and parent process, and prepare
signals for reaping children spawned by the process.
BdtServerClearSignals:
Clear the signal handlers for a process, set them to default.
BdtMakeBDT:
Allocate and initialize a BDT from a socket.
BdtFreeBDT:
Close the open socket and free the memory for the BDT.
------------------------------------------------------------------------ */
#ifndef vxWorks
int BdtMakeServer(char** argv);
int BdtServerClearSignals();
#endif
BDT* BdtMakeBDT(int socket); /* make a BDT from a socket */
int BdtFreeBDT(BDT* bdt); /* free a BDT */
/* ------------------------------------------------------------------------
Client functions:
BdtIpOpen:
Open a connection to an bulk data transfer given the IP address of the
machine where the server exists. The returned BDT is returned unbound,
a connect must be issued before data transactions can take place.
BdtPvOpen:
Open and connect (bind) to a process variable. Data transfers can
take place after this call.
BdtServiceConnect:
Used in conjunction with BdtIpOpen(). Bind an unbound BDT to a
generic service provided by the server at the other end of the open
connection.
BdtPvConnect:
Used in conjunction with BdtIpOpen(). Bind an unbound BDT to a
process variable on the server at the other end of the open
connection.
BdtClose:
Completely close a connection to a server and free the BDT.
BdtDeltaPending:
Check if a delta message arrived at an unexpected time. This function
clears the pending condition.
------------------------------------------------------------------------ */
BDT* BdtIpOpen(char* address, int port);
BDT* BdtPvOpen(char *IocName, char* PvName);
int BdtServiceConnect(BDT* bdt, char* service_name, char *args);
int BdtPvConnect(BDT* bdt, char* pv_name);
int BdtClose(BDT* bdt);
int BdtPvDeltaPending(BDT* bdt);
/* ------------------------------------------------------------------------
Client and Server shared functions:
BdtSendHeader:
Send a message header out to a connect BDT with command and message body
size information.
BdtSendData:
Send a portion or all the message body out a connected BDT. A header
must have previously been sent with length information. The interface
will only allow the amount of data specified in the header to be sent.
BdtWrite:
This call will block until all the data specified in the size parameter
are sent down the socket.
BdtRead:
This call will block until all the data specified in the size parameter
is read from the socket.
BdtReceiveHeader:
Wait until a message header appears at the BDT, return the action and
remaining message body size.
BdtReceiveData:
Wait for a chunk or the entire body of a message to appear at the BDT.
Put the data into the buffer for a maximum size. Return the amount of
data actually received, or zero if there is no data remaining for the
current message.
------------------------------------------------------------------------ */
int BdtSendHeader(BDT* bdt, unsigned short verb, int size);
int BdtSendData(BDT* bdt, void* buffer, int size);
int BdtReceiveHeader(BDT* bdt, int* verb, int* size);
int BdtReceiveData(BDT* bdt, void* buffer, int size);
int BdtRead(int socket, void* buffer, int size);
int BdtWrite(int socket, void* buffer, int size);
int BdtFlushOutput(BDT* bdt);
int BdtPvPutArray(BDT *bdt, short DbrType, void *Buf, unsigned long NumElements, unsigned long ElementSize);
#endif

View File

@@ -1,395 +0,0 @@
/*
*
* Author: John Winans
* Date: 95-05-22
*
* $Log$
* Revision 1.1 1995/07/27 14:22:56 winans
* first release
*
*/
/*****************************************************************************
*
* IOC listener task blocks on accept calls waiting for binders.
* If a bind arrives, a receiver task is spawned.
*
* IOC receiver task blocks on read calls waiting for transactions.
* When a transaction arrives it is serviced.
* At the end of a transaction service, a response is sent back.
* After the response is sent, a chack is made to see if a delta transmission
* was blocked by the transaction's use of the socket... if so, it is sent.
*
******************************************************************************/
#include <selectLib.h>
#include <stdio.h>
#include <signal.h>
#include <vxWorks.h>
#include <sys/socket.h>
#include <in.h>
#include <inetLib.h>
#include <taskLib.h>
#include <sysSymTbl.h>
#include <string.h>
#include "bdt.h"
#define BDT_TASK_PRIO 200
#define BDT_TASK_OPTIONS VX_FP_TASK
#define BDT_TASK_STACK 5000
#define STATIC static
/* used for debugging */
STATIC char *BdtNames[] = {
"BDT_Ok",
"BDT_Connect",
"BDT_Error",
"BDT_Get",
"BDT_Put",
"BDT_Close",
"BDT_Monitor",
"BDT_Value",
"BDT_Delta",
"BDT_Add",
"BDT_Delete",
"BDT_Ping"
};
STATIC int HexDump(char *ReadBuffer, int rbytes);
/*****************************************************************************
*
* A debugging routine that hex-dumps a message to the console.
*
*****************************************************************************/
void BDT_DumpMessage(BDT *Bdt)
{
char Buf[16*4];
int RecvLen;
while(Bdt->remaining_recv)
{
RecvLen = (Bdt->remaining_recv > sizeof(Buf)) ? sizeof(Buf): Bdt->remaining_recv;
if (BdtReceiveData(Bdt, Buf, RecvLen) != RecvLen)
return; /* Got EOF, (EOM handled by the while() */
HexDump(Buf, RecvLen);
}
}
/*****************************************************************************
*
* Throw away a message.
*
****************************************************************************/
void BDT_DiscardMessage(BDT *Bdt)
{
char Buf[16*4];
int RecvLen;
while(Bdt->remaining_recv)
{
RecvLen = (Bdt->remaining_recv > sizeof(Buf)) ? sizeof(Buf): Bdt->remaining_recv;
if (BdtReceiveData(Bdt, Buf, RecvLen) != RecvLen)
return; /* Got EOF, (EOM handled by the while() */
}
}
/*****************************************************************************
*
* Process a single Connect message. And return a response.
*
******************************************************************************/
STATIC int BDT_ProcessConnect(BDT *Bdt)
{
SYM_TYPE Type;
unsigned char length;
char Buf[50];
char HandlerName[70];
if (Bdt->remaining_recv > sizeof(Buf))
{
printf("BDT_ProcessConnect Connect Message too long %d\n", Bdt->remaining_recv);
BDT_DiscardMessage(Bdt);
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
if (Bdt->remaining_recv < 2)
{
printf("BDT_ProcessConnect Connect Message w/missing service name\n");
BDT_DiscardMessage(Bdt);
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
BdtReceiveData(Bdt, &length, 1);
if (length > sizeof(Buf))
{
printf("BDT_ProcessConnect Connect Message service name too long %d\n", length);
BDT_DiscardMessage(Bdt);
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
BdtReceiveData(Bdt, Buf, length);
Buf[length] = '\0';
sprintf(HandlerName, "_BDT_ServiceHandler_%s", Buf);
printf("BDT_ProcessConnect NAME service (%s)\n", HandlerName);
/*Bdt->pHandlers = (BdthandlerFunc *)(&BDT_NameServicehandlers);*/
if (symFindByNameEPICS(sysSymTbl, HandlerName, (char **)&(Bdt->pHandlers), &Type) != OK)
{
printf("BDT_ProcessConnect Connect to unknown service (%s)\n", Buf);
BdtSendHeader(Bdt, BDT_Error, 0);
}
else
{
Bdt->Name = (char *)malloc(strlen(Buf)+1);
strcpy(Bdt->Name, Buf);
if (Bdt->pHandlers[BDT_Connect] != NULL)
return((*(Bdt->pHandlers[BDT_Connect]))(Bdt));
else
{
BDT_DiscardMessage(Bdt);
BdtSendHeader(Bdt, BDT_Ok, 0);
}
}
return(0);
}
/*****************************************************************************
*
* Process a single message. And return a response.
*
******************************************************************************/
STATIC int BDT_ProcMessage(BDT *Bdt, unsigned short Command)
{
int RecvLen;
if (Command > BDT_LAST_VERB)
{
printf("BDT: %s Invalid command %d, length = %d\n", Bdt->Name, Command, Bdt->remaining_recv);
BDT_DumpMessage(Bdt);
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
if (Bdt->pHandlers == NULL)
{
if (Command == BDT_Connect)
BDT_ProcessConnect(Bdt);
else
{
printf("BDT_ProcMessage: %s got %s before connect\n", Bdt->Name, BdtNames[Command]);
BDT_DiscardMessage(Bdt);
BdtSendHeader(Bdt, BDT_Error, 0);
}
return(0);
}
if (Bdt->pHandlers[Command] == NULL)
{
printf("BDT_ProcMessage: service %s got %s... invalid\n", Bdt->Name, BdtNames[Command]);
}
return((*(Bdt->pHandlers[Command]))(Bdt));
}
/*****************************************************************************
*
* Wait on a socket read for a message. When one arrives, read the header,
* decode it, and call the message handler routine to process and respond to it.
*
******************************************************************************/
STATIC void BDT_ReceiverTask(int Sock)
{
int Verb;
int Size;
BDT Bdt;
int MonitorLockTimeout = (BDT_PING_INTERVAL*sysClkRateGet())/2;
static char *NoBdtName = "(No Name)";
fd_set FdSet;
struct timeval TimeVal;
int PollStatus;
int SocketState;
Bdt.soc = Sock;
Bdt.pMonitor = NULL;
Bdt.WriteLock = semBCreate(SEM_Q_PRIORITY, SEM_FULL);
Bdt.MonitorLock = semBCreate(SEM_Q_PRIORITY, SEM_FULL);
Bdt.state = BdtIdle;
Bdt.pHandlers = NULL;
Bdt.Name = NoBdtName;
printf("BDT_ReceiverTask(%d) started\n", Sock);
TimeVal.tv_sec = BDT_CONENCTION_TIMEOUT;
TimeVal.tv_usec = 0;
FD_ZERO(&FdSet);
FD_SET(Bdt.soc, &FdSet);
SocketState = 0;
while (((PollStatus = select(FD_SETSIZE, &FdSet, NULL, NULL, &TimeVal)) > 0) && (BdtReceiveHeader(&Bdt, &Verb, &Size) == 0))
{
semTake(Bdt.WriteLock, WAIT_FOREVER);
SocketState = BDT_ProcMessage(&Bdt, Verb);
if (SocketState != 0)
break;
#if 0
if (semTake(Bdt.MonitorLock, MonitorLockTimeout) == OK)
{
/* Check for delta flag and send if so */
/* Change this to run thru a delta-message linked list */
if (Bdt.pMonitor != NULL)
{
/* Send delta notifier */
}
semGive(Bdt.WriteLock); /* Order important for BDT_SendDelta */
semGive(Bdt.MonitorLock);
}
else
{
printf("BDT_ReceiverTask timeout on monitor semaphore. Monitors are stuck!\n");
semGive(Bdt.WriteLock);
}
#else
semGive(Bdt.WriteLock);
#endif
BdtFlushOutput(&Bdt);
FD_ZERO(&FdSet);
FD_SET(Bdt.soc, &FdSet);
}
if (SocketState == 0)
{
if (PollStatus == 0)
printf("BDT_ReceiverTask(%d) exiting on client timeout\n", Sock);
else
printf("BDT_ReceiverTask(%d) exiting on I/O error talking to Client\n", Sock);
}
else
printf("BDT_ReceiverTask(%d) received close from client\n", Sock);
/* Free up resources */
if (Bdt.Name != NoBdtName)
free(Bdt.Name);
close(Sock);
semDelete(Bdt.WriteLock);
semDelete(Bdt.MonitorLock);
return;
}
/*****************************************************************************
*
******************************************************************************/
#if 0
int BDT_SendDelta(int Socket, char *Message)
{
semTake (DeltaFlagLock, WAIT_FOREVER);
if (if (semTake(SocketWriteLock, no wait) == failed)
{
/* Reader task is busy... Post message for future transmission */
Bdt.pending_delta = 1;
}
else
{
write(Message); /* This COULD block */
semGive(SocketWriteLock);
}
semGive(DeltaFlagLock);
return (0);
}
#endif
/*****************************************************************************
*
* This task listens on a port for new connections. When one is made, it
* spawns a task to manage it.
*
******************************************************************************/
void BDT_ListenerTask(int Port)
{
/* Open a socket to listen on */
struct sockaddr_in ListenerAddr;
struct sockaddr_in ClientAddr;
int ListenerSock;
int ClientSock;
int ClientAddrLen;
int SockAddrSize = sizeof(struct sockaddr_in);
if (Port == 0)
Port = BDT_TCP_PORT;
printf("BDT_Listener(%d) started\n", Port);
if ((ListenerSock = BdtOpenListenerTCP(Port)) < 0)
{
printf("BDT_ListenerTask(%d) can't start listener\n", Port);
return;
}
while (1)
{
ClientAddrLen = sizeof(ClientAddr);
if((ClientSock = accept(ListenerSock, (struct sockaddr*)&ClientAddr, &ClientAddrLen)) < 0)
{
if(errno!=EINTR)
{
printf("BDT_ListenerTask(%d) accept() failed\n", Port);
}
}
else
{
/* Spawn a task to handle the new connection */
printf("Accepted a connection\n");
taskSpawn("BDT", BDT_TASK_PRIO, BDT_TASK_OPTIONS, BDT_TASK_STACK, (FUNCPTR)BDT_ReceiverTask, ClientSock, 2,3,4,5,6,7,8,9,0);
}
}
/* Never reached */
}
/*****************************************************************************
*
* A handy routine to assist in debugging.
*
******************************************************************************/
STATIC int HexDump(char *ReadBuffer, int rbytes)
{
int c = 0;
int i = 0;
int firsttime;
char ascii[20]; /* To hold printable portion of string */
if (!rbytes)
return(0);
firsttime = 1;
while(c < rbytes)
{
if ((c % 16) == 0)
{
if (!firsttime)
{
ascii[i] = '\0';
printf(" *%s*\n", ascii);
}
firsttime=0;
i = 0;
}
printf(" %02.2X", ReadBuffer[c] & 0xff);
ascii[i] = ReadBuffer[c];
if (!isprint(ascii[i]))
ascii[i] = '.';
++i;
++c;
}
while (c%16)
{
fputs(" ", stdout);
++c;
}
ascii[i] = '\0';
printf(" *%s*\n", ascii);
return(0);
}

View File

@@ -1,129 +0,0 @@
/*****************************************************************************
*
* Author: John Winans
* Date: 95-06-05
*
* $Id$
*
* $Log$
*
*****************************************************************************/
#include <selectLib.h>
#include <stdio.h>
#include <signal.h>
/*****************************************************************************
*
* IOC listener task blocks on accept calls waiting for binders.
* If a bind arrives, a receiver task is spawned.
*
* IOC receiver task blocks on read calls waiting for transactions.
* When a transaction arrives it is serviced.
* At the end of a transaction service, a response is sent back.
* After the response is sent, a chack is made to see if a delta transmission
* was blocked by the transaction's use of the socket... if so, it is sent.
*
******************************************************************************/
#include <vxWorks.h>
#include <sys/socket.h>
#include <in.h>
#include <inetLib.h>
#include <taskLib.h>
#include "bdt.h"
#define STATIC static
/*****************************************************************************
*
*****************************************************************************/
STATIC int BDT_NameServiceOk(BDT *Bdt)
{
printf("BDT_NameServiceOk \n");
return(0);
}
/*****************************************************************************
*
*****************************************************************************/
STATIC int BDT_NameServiceConnect(BDT *Bdt)
{
printf("BDT_NameServiceConnect \n");
BdtSendHeader(Bdt, BDT_Ok, 0);
return(0);
}
STATIC int BDT_NameServiceError(BDT *Bdt)
{
printf("BDT_NameServiceError \n");
return(0);
}
STATIC int BDT_NameServiceGet(BDT *Bdt)
{
printf("BDT_NameServiceGet \n");
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
STATIC int BDT_NameServicePut(BDT *Bdt)
{
printf("BDT_NameServicePut \n");
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
STATIC int BDT_NameServiceClose(BDT *Bdt)
{
printf("BDT_NameServiceClose \n");
BdtSendHeader(Bdt, BDT_Ok, 0);
return(0);
}
STATIC int BDT_NameServiceMonitor(BDT *Bdt)
{
printf("BDT_NameServiceMonitor \n");
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
STATIC int BDT_NameServiceValue(BDT *Bdt)
{
printf("BDT_NameServiceValue \n");
return(0);
}
STATIC int BDT_NameServiceDelta(BDT *Bdt)
{
printf("BDT_NameServiceDelta \n");
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
STATIC int BDT_NameServiceAdd(BDT *Bdt)
{
printf("BDT_NameServiceAdd \n");
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
STATIC int BDT_NameServiceDelete(BDT *Bdt)
{
printf("BDT_NameServiceDelete \n");
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
STATIC int BDT_NameServicePing(BDT *Bdt)
{
printf("BDT_NameServicePing \n");
BdtSendHeader(Bdt, BDT_Ok, 0);
return(0);
}
BdtHandlers BDT_ServiceHandler_name =
{
BDT_NameServiceOk,
BDT_NameServiceConnect,
BDT_NameServiceError,
BDT_NameServiceGet,
BDT_NameServicePut,
BDT_NameServiceClose,
BDT_NameServiceMonitor,
BDT_NameServiceValue,
BDT_NameServiceDelta,
BDT_NameServiceAdd,
BDT_NameServiceDelete,
BDT_NameServicePing
};

View File

@@ -1,377 +0,0 @@
/*****************************************************************************
*
* Author: John Winans
* Date: 95-06-05
*
* $Id$
*
* $Log$
*
******************************************************************************/
#include <vxWorks.h>
#include <semLib.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <dbCommon.h>
#include <dbAccess.h>
#include "bdt.h"
#define STATIC static
#define MESSAGE_PREFIX "BDT PV server:"
/*****************************************************************************
*
* These conversion finctions take care of one of the most insane parts
* of dealing with database access... having two different interfaces that
* have the same named enumerators in two seperate header files... that
* therefore can not be both included in the same file.
*
* This is so bad, I wanted to vomit when typing it in.
*
******************************************************************************/
STATIC int DbrOld2New(int Old)
{
switch (Old)
{
case 0: return(DBR_STRING);
case 1: return(DBR_SHORT);
case 2: return(DBR_FLOAT);
case 3: return(DBR_ENUM);
case 4: return(DBR_CHAR);
case 5: return(DBR_LONG);
case 6: return(DBR_DOUBLE);
default:
return(-1);
}
}
STATIC int DbrNew2Old(int New)
{
switch (New)
{
case DBR_STRING: return(0);
case DBR_CHAR: return(4);
case DBR_UCHAR: return(4);
case DBR_SHORT: return(1);
case DBR_USHORT: return(1);
case DBR_LONG: return(5);
case DBR_ULONG: return(5);
case DBR_FLOAT: return(2);
case DBR_DOUBLE: return(6);
case DBR_ENUM: return(3);
default:
return(-1);
}
}
/*****************************************************************************
*
* Handle the receipt of an OK message.
*
* The OK message is received as a confirmation of the last operation. It is
* not normally responded to.
*
*****************************************************************************/
STATIC int BDT_ServiceOk(BDT *Bdt)
{
printf("%s got a Ok message\n", MESSAGE_PREFIX);
return(0);
}
/*****************************************************************************
*
* Handle the receipt of a Connect message.
*
* The Connect is received when a new connection is first made.
* Any arguments left in the message body have not yet been read.
*
*****************************************************************************/
STATIC int BDT_ServiceConnect(BDT *Bdt)
{
unsigned char Length;
char Buf[100];
struct dbAddr *pDbAddr;
Buf[0] = '\0';
if (Bdt->remaining_recv > 0)
{
BdtReceiveData(Bdt, &Length, 1);
if (Length <= sizeof(Buf))
{
BdtReceiveData(Bdt, Buf, Length);
Buf[Length] = '\0';
}
else
{
printf("%s Connect message argument list too long\n", MESSAGE_PREFIX);
BDT_DiscardMessage(Bdt);
return(-1);
}
}
#ifdef DEBUG_VERBOSE
printf("%s got Connect >%s<\n", MESSAGE_PREFIX, Buf);
#endif
/* Find the PV in the database */
Bdt->pService = malloc(sizeof(struct dbAddr));
pDbAddr = (struct dbAddr *)(Bdt->pService);
if (dbNameToAddr(Buf, pDbAddr))
{
BdtSendHeader(Bdt, BDT_Error, 0);
free(Bdt->pService);
}
else
{
if (pDbAddr->dbr_field_type != pDbAddr->field_type)
{
BdtSendHeader(Bdt, BDT_Error, 0);
free(Bdt->pService);
}
else
BdtSendHeader(Bdt, BDT_Ok, 0);
}
return(0);
}
/*****************************************************************************
*
* Handle the receipt of an Error message.
*
*****************************************************************************/
STATIC int BDT_ServiceError(BDT *Bdt)
{
printf("%s got a Error message\n", MESSAGE_PREFIX);
return(0);
}
/*****************************************************************************
*
* Handle the receipt of a Get message.
*
* The response to a Get message is either an Error or a Value:
*
* Value message body format:
* SHORT EPICS data type enumerator (in old format)
* LONG Number of elements
* CHAR[] Value image
*
*
*****************************************************************************/
STATIC int BDT_ServiceGet(BDT *Bdt)
{
void *Buf;
struct dbAddr *pDbAddr = (struct dbAddr *)(Bdt->pService);
long NumElements;
long Size;
long l;
short OldType;
int stat;
#ifdef DEBUG_VERBOSE
printf("%s got a Get message\n", MESSAGE_PREFIX);
printf("field type=%d, field size=%d, elements=%d\n", pDbAddr->field_type, pDbAddr->field_size, pDbAddr->no_elements);
#endif
OldType = DbrNew2Old(pDbAddr->field_type);
if (OldType < 0)
{
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
/* Allocate a buffer to hold the response message data */
Buf = malloc(pDbAddr->field_size * pDbAddr->no_elements);
if (Buf == NULL)
{
printf("Can't allocate %d-byte buffer for get request to %s\n",
pDbAddr->field_size * pDbAddr->no_elements,
pDbAddr->precord->name);
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
/* Get the response message data */
NumElements = pDbAddr->no_elements;
if (stat=dbGetField(pDbAddr, pDbAddr->field_type, Buf, 0, &NumElements, NULL))
{
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
#if 0
/* Test hack to transfer HUGE buffers */
NumElements = pDbAddr->no_elements;
#endif
/* Send the response message */
Size = NumElements * pDbAddr->field_size;
BdtSendHeader(Bdt, BDT_Value, Size + sizeof(long) + sizeof(short));
BdtSendData(Bdt, &OldType, sizeof(short));
BdtSendData(Bdt, &NumElements, sizeof(long));
if (Size)
BdtSendData(Bdt, Buf, Size);
free(Buf);
return(0);
}
/*****************************************************************************
*
* Handle the receipt of a Put message.
*
* Put message body format:
* SHORT EPICS data type enumerator
* LONG Number of elements
* CHAR[] Value image
*
*****************************************************************************/
STATIC int BDT_ServicePut(BDT *Bdt)
{
long Size;
void *Buf;
short DbrType;
long NumElements;
struct dbAddr *pDbAddr = (struct dbAddr *)(Bdt->pService);
#ifdef DEBUG_VERBOSE
printf("%s got a Put message\n", MESSAGE_PREFIX);
#endif
if (BdtGetResidualRead(Bdt) < 6)
{
BDT_DiscardMessage(Bdt);
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
if (BdtGetResidualRead(Bdt) == 6)
{ /* Do data contents, just toss it */
BDT_DiscardMessage(Bdt);
BdtSendHeader(Bdt, BDT_Ok, 0);
return(0);
}
Buf = malloc(BdtGetResidualRead(Bdt) - 6);
if (Buf == NULL)
{
printf("Can't allocate %d-byte buffer for put request to %s\n",
BdtGetResidualRead(Bdt), pDbAddr->precord->name);
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
BdtReceiveData(Bdt, &DbrType, 2);
BdtReceiveData(Bdt, &NumElements, 4);
#ifdef DEBUG_VERBOSE
printf("record field type=%d, field size=%d, elements=%d\n", pDbAddr->field_type, pDbAddr->field_size, pDbAddr->no_elements);
printf("message field type=%d, field size=%d, elements=%d total %d\n", DbrType, pDbAddr->field_type ,NumElements, BdtGetResidualRead(Bdt));
#endif
BdtReceiveData(Bdt, Buf, BdtGetResidualRead(Bdt));
DbrType = DbrOld2New(DbrType);
if (DbrType < 0)
BdtSendHeader(Bdt, BDT_Error, 0);
else if (dbPutField(pDbAddr, DbrType, Buf, NumElements))
BdtSendHeader(Bdt, BDT_Error, 0);
else
BdtSendHeader(Bdt, BDT_Ok, 0);
free(Buf);
return(0);
}
/*****************************************************************************
*
* Handle the receipt of a Close message.
*
*****************************************************************************/
STATIC int BDT_ServiceClose(BDT *Bdt)
{
printf("%s got a Close message\n", MESSAGE_PREFIX);
free(Bdt->pService);
BdtSendHeader(Bdt, BDT_Ok, 0);
return(1);
}
/*****************************************************************************
*
* Handle the receipt of a Monitor message.
*
* Not Supported.
*
*****************************************************************************/
STATIC int BDT_ServiceMonitor(BDT *Bdt)
{
printf("%s got a Monitor message\n", MESSAGE_PREFIX);
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
/*****************************************************************************
*
* Handle the receipt of a Value message.
*
* Not Supported.
*
*****************************************************************************/
STATIC int BDT_ServiceValue(BDT *Bdt)
{
printf("%s got a Value message\n", MESSAGE_PREFIX);
return(0);
}
/*****************************************************************************
*
* Handle the receipt of a Delta message.
*
* Not Supported.
*
*****************************************************************************/
STATIC int BDT_ServiceDelta(BDT *Bdt)
{
printf("%s got a Delta message\n", MESSAGE_PREFIX);
BdtSendHeader(Bdt, BDT_Ok, 0);
return(0);
}
/*****************************************************************************
*
* Handle the receipt of an Add message.
*
* Not Supported.
*
*****************************************************************************/
STATIC int BDT_ServiceAdd(BDT *Bdt)
{
printf("%s got a Add message\n", MESSAGE_PREFIX);
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
/*****************************************************************************
*
* Handle the receipt of a Delete message.
*
* Not Supported.
*
*****************************************************************************/
STATIC int BDT_ServiceDelete(BDT *Bdt)
{
printf("%s got a Delete message\n", MESSAGE_PREFIX);
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
/*****************************************************************************
*
* Handle the receipt of a Ping message.
*
*****************************************************************************/
STATIC int BDT_ServicePing(BDT *Bdt)
{
printf("%s got a Ping message\n", MESSAGE_PREFIX);
BdtSendHeader(Bdt, BDT_Ok, 0);
return(0);
}
BdtHandlers BDT_ServiceHandler_pv =
{
BDT_ServiceOk,
BDT_ServiceConnect,
BDT_ServiceError,
BDT_ServiceGet,
BDT_ServicePut,
BDT_ServiceClose,
BDT_ServiceMonitor,
BDT_ServiceValue,
BDT_ServiceDelta,
BDT_ServiceAdd,
BDT_ServiceDelete,
BDT_ServicePing
};