diff --git a/src/bdt/Makefile b/src/bdt/Makefile deleted file mode 100644 index 1e3cdc13e..000000000 --- a/src/bdt/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# -# $Id$ -# -# Base Lowest Level Directroy Makefile -# by Janet Anderson -# - -TOP=../.. - -include $(TOP)/config/CONFIG_BASE - -include $(TOP)/config/RULES_ARCHS - diff --git a/src/bdt/Makefile.Host b/src/bdt/Makefile.Host deleted file mode 100644 index d67f2969c..000000000 --- a/src/bdt/Makefile.Host +++ /dev/null @@ -1,10 +0,0 @@ -TOP = ../../.. -include $(TOP)/config/CONFIG_BASE - -INC := bdt.h - -LIBSRCS := bdt.c - -LIBRARY := Bdt - -include $(TOP)/config/RULES.Host diff --git a/src/bdt/Makefile.Vx b/src/bdt/Makefile.Vx deleted file mode 100644 index 377cfe49a..000000000 --- a/src/bdt/Makefile.Vx +++ /dev/null @@ -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) diff --git a/src/bdt/bdt.c b/src/bdt/bdt.c deleted file mode 100644 index 6591b8499..000000000 --- a/src/bdt/bdt.c +++ /dev/null @@ -1,703 +0,0 @@ -#include -#include -#include -#include -#include -#include -#ifdef linux -#include -#endif -#include -#include - -#ifdef vxWorks -#include -#include -#include -#include -#include -#include -#else -#include -#include -#include -#include -#include -#endif - -#include -#include -#include - -#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); -} diff --git a/src/bdt/bdt.h b/src/bdt/bdt.h deleted file mode 100644 index 30e06e561..000000000 --- a/src/bdt/bdt.h +++ /dev/null @@ -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 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 - diff --git a/src/bdt/bdtServ.c b/src/bdt/bdtServ.c deleted file mode 100644 index ed8bed86e..000000000 --- a/src/bdt/bdtServ.c +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#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); -} diff --git a/src/bdt/bdtServName.c b/src/bdt/bdtServName.c deleted file mode 100644 index 4b2d60f57..000000000 --- a/src/bdt/bdtServName.c +++ /dev/null @@ -1,129 +0,0 @@ -/***************************************************************************** -* -* Author: John Winans -* Date: 95-06-05 -* -* $Id$ -* -* $Log$ -* -*****************************************************************************/ - -#include -#include -#include - -/***************************************************************************** -* -* 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 -#include -#include -#include -#include - -#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 -}; diff --git a/src/bdt/bdtServPv.c b/src/bdt/bdtServPv.c deleted file mode 100644 index 47ce03b9a..000000000 --- a/src/bdt/bdtServPv.c +++ /dev/null @@ -1,377 +0,0 @@ -/***************************************************************************** -* -* Author: John Winans -* Date: 95-06-05 -* -* $Id$ -* -* $Log$ -* -******************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#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 -};