/* $Id: GSudpGetBuf.c,v 1.18 2010/07/16 17:36:49 tl Exp $ */ #include #include #include #include #include #include "efftape.h" #include "sender.h" #include "GSudpReceiver.h" #include "gsII.h" /*-------------------------------------------------------------------------*/ int GSudpGetBuf(EVENT_BUFFER * eb) { /* declarations */ unsigned int nBytes; int nf; char *ebc = (char *) eb; unsigned short test_eb_sum16(EVENT_BUFFER *), testsum; int eb_bytes_received = 0, goon = 1; char fragment[sizeof(EVENT_BUFFER) + sizeof(FRAGMENT_HEADER)]; #ifdef LINUX char mentfrag[sizeof(EVENT_BUFFER) + sizeof(FRAGMENT_HEADER)]; int i; #endif int num_frags; /* number of frags in event_buffer */ unsigned short next_frag; /* next expected fragement */ unsigned short last_frag; /* last expected fragement */ FRAGMENT_HEADER *frag; /* buffer for receiving 1 fragment of eb */ int frag_length; /* length of frag in bytes */ int frag_count; /* prototypes */ int UdpReceiveBuf(char *, size_t *, int); /* initialize, make frag_length the receiver of the udp */ /* fragments as big as it possible could be */ frag_length = sizeof(EVENT_BUFFER) + sizeof(FRAGMENT_HEADER); frag_count = 0; /*-----------------------------*/ /* search for a first fragment */ /*-----------------------------*/ for (;;) { /* sighup bailout */ if (goon == 0) return (0); /* receive a fragment */ #ifdef SOLARIS UdpReceiveBuf((char *) fragment, (size_t *) & nBytes, frag_length); #endif #ifdef LINUX UdpReceiveBuf((char *) mentfrag, (size_t *) & nBytes, frag_length); for (i = 0; i < nBytes; i += 2) { fragment[i] = mentfrag[i + 1]; fragment[i + 1] = mentfrag[i]; }; #endif /* point fragheader to beginning of buffer */ frag = (FRAGMENT_HEADER *) fragment; /* error return */ if ((int) nBytes <= 0) { return GET_1_OF_N_RECVFROM_ERROR; }; ++frag_count; eb_bytes_received = 0; /* check to see if this is the first fragment */ /* of a data block */ if ((frag->FragCounter & 0x00ff) == 1) { /* initialize last_frag_seq */ /* check that there is more than just a header */ if (frag->FragDataLength > sizeof(FRAGMENT_HEADER)) { eb_bytes_received += frag->FragDataLength; /* check for overflow */ if (eb_bytes_received > sizeof(EVENT_BUFFER)) { return EVENT_BUFFER_OVERFLOW_ERROR; } else { /* this looks promising... */ bcopy((char *) frag + sizeof(FRAGMENT_HEADER), ebc, (unsigned int) frag->FragDataLength); ebc += frag->FragDataLength; num_frags = frag->FragCounter >> 8; /* break out of the forever loop */ break; } } } /* fragment was start of data block */ }; /* forever loop */ /*-----------------------*/ /* Get rest of fragments */ /*-----------------------*/ next_frag = (num_frags << 8) | 2; last_frag = (num_frags << 8) + num_frags; for (nf = 2; nf <= num_frags; ++nf) { /* sighup bailout */ if (goon == 0) return (0); /* receive a fragment */ #ifdef SOLARIS UdpReceiveBuf((char *) frag, &nBytes, frag_length); #endif #ifdef LINUX UdpReceiveBuf((char *) mentfrag, (size_t *) & nBytes, frag_length); for (i = 0; i < nBytes; i += 2) { fragment[i] = mentfrag[i + 1]; fragment[i + 1] = mentfrag[i]; }; #endif /* error return */ if ((int) nBytes <= 0) { return GET_REST_OF_N_RECVFROM_ERROR; } ++frag_count; /* check if it's the next expected fragment */ if (frag->FragCounter == next_frag) { if (frag->FragDataLength > 0) { eb_bytes_received += frag->FragDataLength; /* now check the size */ if (eb_bytes_received > sizeof(EVENT_BUFFER)) { return EVENT_BUFFER_OVERFLOW_ERROR; } else { /* looks good ... copy it */ bcopy((char *) frag + sizeof(FRAGMENT_HEADER), ebc, (unsigned int) frag->FragDataLength); ebc += frag->FragDataLength; next_frag += 1; } } else { return EMPTY_FRAGMENT_ERROR; } } else { return UNEXPECTED_FRAGMENT_ERROR; } } /* got all, now do the checksum test */ testsum = test_eb_sum16(eb); if (testsum == 0) { return (EVENT_BUFFER_OK); } else { return CHECKSUM_FAILURE_ERROR; } } /*----------------------------------------------------------------------*/ unsigned short int test_eb_sum16(EVENT_BUFFER * ebp) { /* declarations */ unsigned short *us_ebp = (unsigned short *) ebp; unsigned short checksum = 0, expected_checksum; int j, max; /* save/knock out the checksum */ /* field that we received */ expected_checksum = us_ebp[10]; us_ebp[10] = 0; /* find checksum */ max = sizeof(EVENT_BUFFER) / sizeof(unsigned short); for (j = 0; j < max; ++j) { checksum += us_ebp[j]; }; checksum = ~checksum + 1; /* restore original checksum */ us_ebp[10] = expected_checksum; /* done */ if (checksum == expected_checksum) { #if(0) if (k > 0) { k--; printf("checksum ok..."); printf("sum range: 1..%i\n", max); printf("buffer val=0x%4.4x, ", expected_checksum); printf("calculated=0x%4.4x\n", checksum); }; #endif return 0; } else { #if(0) printf("checksum failure..."); printf("sum range: 1..%i\n", max); printf("buffer val=0x%4.4x, ", expected_checksum); printf("calculated=0x%4.4x\n", checksum); #endif return (-1); }; }