-static char rcsId[] = "$Header: /misc/hadesprojects/daq/cvsroot/eventbuilder/hadaq/nettrans.c,v 6.2 1999-10-06 17:05:08 muench Exp $";
+static char rcsId[] = "$Header: /misc/hadesprojects/daq/cvsroot/eventbuilder/hadaq/nettrans.c,v 6.3 1999-11-02 05:53:24 muench Exp $";
 
 #define _XOPEN_SOURCE_EXTENDED
 #include <unistd.h>
        return a < b ? a : b;
 }
 
-NetTrans *NetTrans_create(const char *name, size_t bandwidth, Worker *worker)
-{
-       NetTrans *my;
-       char *vpi;
-       char *vci;
-       LAtmAttr lAtmAttrS, *lAtmAttr = &lAtmAttrS;
-       char buf[80];
+static int openUdp(NetTrans *my, const char *name, int fl) {
+       return -1;
+}
 
-       my = allocMem(sizeof(NetTrans));
+static int openAtm(NetTrans *my, int vpi, int vci, size_t bw, int fl) {
+       int retVal;
+       LAtmAttr lAtmAttrS, *lAtmAttr = &lAtmAttrS;
 
-       strcpy(buf, name);
+       assert(my != NULL);
 
-       if (NULL == (vpi = strtok(buf, ":"))) {
-               return NULL;
-       }
-       if (NULL == (vci = strtok(NULL, ":"))) {
-               return NULL;
-       }
        lAtmAttr->aal = 5;
-       lAtmAttr->vpi = atoi(vpi);
-       lAtmAttr->vci = atoi(vci);
-       lAtmAttr->peakBandwidth = bandwidth;
+       lAtmAttr->vpi = vpi;
+       lAtmAttr->vci = vci;
+       lAtmAttr->peakBandwidth = bw;
 
        msglog(LOG_DEBUG, "aal: %d; vpi: %d; vci: %d; bandwidth: %d\n",
        lAtmAttr->aal, lAtmAttr->vpi, lAtmAttr->vci, lAtmAttr->peakBandwidth);
 
-       if (0 > (my->fd = lAtmOpen("/dev/fa0", O_RDONLY))) {
-               return NULL;
+       my->fd = lAtmOpen("/dev/fa0", fl);
+
+       if (0 > my->fd) {
+               retVal = -1;
+       } else {
+               switch (fl) {
+               case O_RDONLY:
+                       retVal = lAtmBind(my->fd, lAtmAttr);
+                       break;
+               case O_WRONLY:
+                       retVal = lAtmConnect(my->fd, lAtmAttr);
+                       break;
+               default:
+                       errno = EINVAL;
+                       retVal = -1;
+                       break;
+               }
+
+               if (0 > retVal) {
+                       lAtmClose(my->fd);
+               } else {
+                       my->mtuSize = 8192;
+               }
+       }
+
+       if (0 > retVal) {
+               msglog(LOG_DEBUG, "openAtm: %s\n", strerror(errno));
        }
-       if (0 > lAtmBind(my->fd, lAtmAttr)) {
-               lAtmClose(my->fd);
+       return retVal;
+}
+
+int openGeneric(NetTrans *my, const char *name, int flags, size_t bandwidth) {
+       int retVal;
+       char fam[32];
+       char pa[32];
+       char ep[32];
+
+       assert(my != NULL);
+       assert(name != NULL);
+
+       if (0 == (sscanf(name, "%[^:]:%[^:]:%s", fam, pa, ep))) {
+               errno = EINVAL;
+               retVal = -1;
+       } else {
+               if (strcmp(fam, "ATM") == 0) {
+                       int vpi;
+                       int vci;
+
+                       vpi = atoi(pa);
+                       vci = atoi(ep);
+                       my->type = NetTransType_atm;
+                       retVal = openAtm(my, vpi, vci, bandwidth, flags);
+               } else if (strcmp(fam, "UDP") == 0) {
+                       my->type = NetTransType_udp;
+                       retVal = openUdp(my, name, flags);
+               } else {
+                       my->type = NetTransType_invalid;
+                       errno = EINVAL;
+                       retVal = -1;
+               }
+       }
+
+       if (0 > retVal) {
+               msglog(LOG_DEBUG, "openGeneric: %s\n", strerror(errno));
+       }
+       return retVal;
+}
+
+int closeGeneric(NetTrans *my) {
+       int retVal;
+
+       assert(my != NULL);
+
+       switch (my->type) {
+       case NetTransType_atm:
+               retVal = lAtmClose(my->fd);
+               break;
+       }
+
+       if (0 > retVal) {
+               msglog(LOG_DEBUG, "closeGeneric: %s\n", strerror(errno));
+       }
+       return retVal;
+}
+
+int sendGeneric(NetTrans *my) {
+       int retVal;
+
+       assert(NetTrans_invariant(my));
+
+       switch (my->type) {
+       case NetTransType_atm:
+               retVal = lAtmSend(my->fd, my->pkt, Pkt_size(my->pkt));
+               break;
+       }
+
+       if (retVal != Pkt_size(my->pkt)) {
+               retVal = -1;
+       }
+
+       if (0 > retVal) {
+               msglog(LOG_DEBUG, "sendGeneric: %s\n", strerror(errno));
+       }
+       return retVal;
+}
+
+int recvGeneric(NetTrans *my) {
+       int retVal;
+
+       assert(NetTrans_invariant(my));
+
+       switch (my->type) {
+       case NetTransType_atm:
+               retVal = lAtmRecv(my->fd, my->pkt, my->mtuSize);
+               break;
+       }
+
+       if (retVal != Pkt_size(my->pkt)) {
+               retVal = -1;
+       }
+
+       if (0 > retVal) {
+               msglog(LOG_DEBUG, "recvGeneric: %s\n", strerror(errno));
+       }
+       return retVal;
+}
+
+int NetTrans_invariant(const NetTrans *my) {
+       return (
+               my != NULL
+               && (my->type == NetTransType_atm || my->type == NetTransType_udp)
+       );
+}
+
+NetTrans *NetTrans_create(const char *name, size_t bandwidth, Worker *worker)
+{
+       NetTrans *my;
+       char buf[80];
+
+       my = allocMem(sizeof(NetTrans));
+
+       if (0 > openGeneric(my, name, O_RDONLY, bandwidth)) {
                return NULL;
        }
-       my->mtuSize = 65535;
 
-       my->pkt = allocMem(my->mtuSize);
+       my->pkt = NULL;
        my->seqNr = 0;
        my->offset = 0;
 
 
        my = allocMem(sizeof(NetTrans));
 
-       strcpy(buf, name);
-
-       if (NULL == (vpi = strtok(buf, ":"))) {
+       if (0 > openGeneric(my, name, O_WRONLY, bandwidth)) {
                return NULL;
        }
-       if (NULL == (vci = strtok(NULL, ":"))) {
-               return NULL;
-       }
-       lAtmAttr->aal = 5;
-       lAtmAttr->vpi = atoi(vpi);
-       lAtmAttr->vci = atoi(vci);
-       lAtmAttr->peakBandwidth = bandwidth;
-
-       msglog(LOG_DEBUG, "aal: %d; vpi: %d; vci: %d; bandwidth: %d\n",
-       lAtmAttr->aal, lAtmAttr->vpi, lAtmAttr->vci, lAtmAttr->peakBandwidth);
-
-       if (0 > (my->fd = lAtmOpen("/dev/fa0", O_WRONLY))) {
-               return NULL;
-       }
-       if (0 > lAtmConnect(my->fd, lAtmAttr)) {
-               lAtmClose(my->fd);
-               return NULL;
-       }
-       my->mtuSize = 65535;
 
        my->pkt = allocMem(my->mtuSize);
        my->seqNr = 0;
 void NetTrans_close(NetTrans *my)
 {
        freeMem(my->pkt);
-       lAtmClose(my->fd);
+       closeGeneric(my);
        freeMem(my);
 }
 
                }
                Pkt_setSeqNr(my->pkt, my->seqNr++);
 
-               if (Pkt_size(my->pkt) != lAtmSend(my->fd, my->pkt, Pkt_size(my->pkt))) {
+               if (0 > sendGeneric(my)) {
                        return -1;
                }
                (*my->pktsSent)++;
        int retVal;
        int i;
        int pktIsOk;
-       int n;
-       void *pkt;
+       UInt4 savedHdr[4];
        UInt4 pktHdrSize;
        UInt4 pktSize;
        UInt4 pktId;
        /* the parent functions this should be handled, but this would need */
        /* better sunc. between nettrans & shmtrans */
        if (hadTu == NULL) {
-               if (0 > (n = lAtmRecv(my->fd, my->pkt, my->mtuSize))) {
+               if (0 > recvGeneric(my)) {
                        abort();
                }
                my->offset = 0;
      front of the beginning", save that data, and copy it back. CAUTION:
      Pkt_hdrSize() bytes in front of hadTu must be accessible! */
        pktHdrSize = Pkt_hdrSize();
-       pkt = (char *) hadTu + my->offset - pktHdrSize;
-       memcpy(my->pkt, pkt, pktHdrSize);
+       assert(sizeof(savedHdr) >= pktHdrSize);
 
-       if (0 > (n = lAtmRecv(my->fd, pkt, my->mtuSize))) {
-               memcpy(pkt, my->pkt, pktHdrSize);
-               abort();
-       }
-       if (n != Pkt_size(pkt)) {
-               memcpy(pkt, my->pkt, pktHdrSize);
+       my->pkt = (char *) hadTu + my->offset - pktHdrSize;
+       memcpy(savedHdr, my->pkt, pktHdrSize);
+
+       if (0 > recvGeneric(my)) {
                abort();
        }
        (*my->pktsReceived)++;
-       pktSize = n;
-       pktId = Pkt_id(pkt);
-       pktSeqNr = Pkt_seqNr(pkt);
-       memcpy(pkt, my->pkt, pktHdrSize);
+       pktSize = Pkt_size(my->pkt);
+       pktId = Pkt_id(my->pkt);
+       pktSeqNr = Pkt_seqNr(my->pkt);
+       memcpy(my->pkt, savedHdr, pktHdrSize);
+       my->pkt = NULL;
 
        if ((pktId & PktId_bom) != 0) { /* start of new msg */
                if (my->offset != 0) {