Beispiel #1
0
/**
 * There is data available on the feed. Read it into the buffer
 * then deal with what we got.
 *
 * @param ifd           [in] File-descriptor of the input data-feed
 * @retval 0            Success
 * @retval ENOMEM       Out of memory
 * @retval ENODATA      End of input data-feed
 */
int
feedTheXbuf(const int ifd)
{
	int status;
	size_t nn = 0;
	/* space available in buffer */
	ptrdiff_t remaining = (ptrdiff_t)theBuf->bufsiz - (theBuf->get - theBuf->base);

	if (remaining <= CHUNKSIZE) {
		if (theBuf->bufsiz >= maxProductSize) {
			log_warning_q(
			        "Data-product would exceed %lu bytes. Resetting input buffer.",
				maxProductSize);
			justify_xbuf(theBuf, 0);
		}

		log_info_q("Expanding input buffer size to %lu\n",
			(unsigned long)(2 * theBuf->bufsiz));

		theBuf = expand_xbuf(theBuf, theBuf->bufsiz);

		if (theBuf == NULL) {
			status = errno == 0 ? ENOMEM : errno;
			log_add_syserr("expand_xbuf");
                        log_flush_error();
			return status;
		}
	}

	status = (*read_feed)(ifd, (char *)theBuf->put, CHUNKSIZE, &nn);
	if(status != ENOERR)
	{
		log_add_errno(status, "read_feed");
                log_flush_error();
		return status;
	}
	/* else */
	if(nn == 0)
		return ENODATA; /* end of file */
	/* else */
	/* usual case */
	/* assert(nn > 0); */
	theBuf->cnt += nn;
	theBuf->put += nn;
	return ENOERR;
}
Beispiel #2
0
int
scan_faa604 (xbuf * buf)
{
    extern char *parity;
    int sent = 0;
    int ch;

    static enum state
    {
        SKIP,
        SEARCH,
        HEADER_SEEN
    }
    state = SEARCH;

    while ((ch = nextc (buf)) != EOB)
    {
        switch(ch) {
        case SOH:
            switch (state) {
            case SKIP:
                log_debug("Resync skipped %05ld bytes",
                          (long) (buf->get - buf->base) - 1);
                break;
            case HEADER_SEEN:
                sohetx_missed++;
                log_error("Lone SOH error           - %s",
                          faa604_err_ident(buf));
                break;
            }
            justify_xbuf (buf, 1);
            state = HEADER_SEEN;
            break;
        case ETX:
            switch (state) {
            case SKIP:
#if 0
            case SEARCH:
#endif
                sohetx_missed++;
                log_error("Lone ETX error           - %s",
                          faa604_err_ident(buf));
                break;
            case HEADER_SEEN:
            {
                const long plen = buf->get - buf->base;
                if(plen >= MIN_FAA604_MSG_LEN)
                {
                    faa604_send_buf (buf);
                    sent++;
                }
                else
                {
                    not_faa604++;
                    log_error("scan_faa604 - length %ld too short",
                              plen);
                }
                justify_xbuf (buf, 0);
                state = SEARCH;
            }
            break;
            }
            justify_xbuf (buf, 0);
            state = SEARCH;
            break;
#if defined(PARITY_ERR_CH)
        case 0:
            /*
             * Backward compatibility
             * except it can change file feeds
             */
            if(state == HEADER_SEEN
                    && (parity != NULL && *parity != 'n'))
            {
                *(buf->get -1) = PARITY_ERR_CH;
            }
            break;
#endif
        default:
            if(state == SEARCH && isgraph(ch))
                state = SKIP;
            break;
        }
    }			/* input character loop */

    return sent;
}
Beispiel #3
0
    scan_wmo_binary(xbuf *buf)
#endif
{
    int			sent = 0;
    int			ch;

    while ((ch = nextc(buf)) != EOB) {
#	if defined(SCAN_CHECK)
	    unsigned		prev_crc;
	    static unsigned	crc;
	    static unsigned	offset;
#	endif
	static enum state {
	    START,
	    SEARCH,
	    SOH_,
	    SOH_CR_,
	    SOH_CR_CR_,
	    HEADER_SEEN,
	    CR_,
	    CR_CR_,
	    CR_CR_NL_
#	    if defined(SCAN_CHECK)
		,
		TRAILER_SEEN,
		CHECKBYTE_SEEN
#	    endif
	}		state	= START;

	/*
	 * Incrementing the checksum at this point is not always necessary
	 * but is done to reduce the number of ADD_CRC() invocations and,
	 * consequently and hopefully, to reduce problems with maintenance
	 * and understanding.
	 */
#	if defined(SCAN_CHECK)
	    prev_crc	= crc;
	    ADD_CRC(crc, ch);
#	endif

	switch (state) {
	case START:
	    if (SOH == ch) {
#	if defined(SCAN_CHECK)
		RESET(offset, crc, ch);
#	endif
		state	= SOH_;
	    } else {
		if (CR != ch && NL != ch) {
		    udebug("garbage encountered while searching for header");
		}
		state	= SEARCH;
	    }
	    break;
	case SEARCH:
	    if (SOH == ch) {
#	if defined(SCAN_CHECK)
		RESET(offset, crc, ch);
#	endif
		state	= SOH_;
	    }
	    break;
	case SOH_:
#	    if defined(SCAN_CHECK)
		if (SOH == ch) {
		    RESET(offset, crc, ch);
		} else 
#	    endif
	    if (CR == ch) {
		state	= SOH_CR_;
	    } else {
		state	= SEARCH;
	    }
	    break;
	case SOH_CR_:
	    if (CR == ch) {
		state	= SOH_CR_CR_;
	    } else {
		state	= SEARCH;
	    }
	    break;
	case SOH_CR_CR_:
	    if (NL == ch) {
		justify_xbuf(buf, 4);
		state	= HEADER_SEEN;
	    } else if (CR != ch) {
		state	= SEARCH;
	    }
	    break;
	case HEADER_SEEN:
	    if (CR == ch)
		state	= CR_;
	    break;
	case CR_:
	    state	= CR == ch
			    ? CR_CR_
			    : HEADER_SEEN;
	    break;
	case CR_CR_:
	    if (NL == ch) {
		state = CR_CR_NL_;
	    } else if (CR != ch) {
		 state = HEADER_SEEN;
	    }
	    break;
	case CR_CR_NL_:
            if (ETX == ch)
	       { 
	       /* see if we can peek ahead, and if so,  does it look like
		  the start of a new product? */
               if(! peek_ahead(buf))
                  {
		  state = HEADER_SEEN;
		  break;
		  }
               }
	    if (ETX == ch) {
#		if defined(SCAN_CHECK)
		    state	= TRAILER_SEEN;
#		else
		    const long plen = buf->get - buf->base;
		    if(plen >= MIN_WMO_MSG_LEN)
		    {
			wmo_send_buf (buf, 0);
			sent++;
		    }
		    else
		    {
			not_wmo++;
			uerror("scan_wmo_binary: length %ld too short",
				plen);
		    }
		    justify_xbuf(buf, 0);
		    state	= START;
#		endif
	    } else if (CR == ch) {
		state	= CR_;
	    } else {
		    if (ESC == ch) {
			xbuf_rubout(buf);
#		if defined(SCAN_CHECK)
			crc	= prev_crc;
#		endif
		    }
		state	= HEADER_SEEN;
	    }
	    break;
#	if defined(SCAN_CHECK)
	    case TRAILER_SEEN:
		state	= CHECKBYTE_SEEN;
		break;
	    case CHECKBYTE_SEEN:
		if (0 != crc) {
			uerror("Checksum (0x%04x) error          %s",
				crc, wmo_err_ident(buf));
			bad_cksum++;
		}
		else {
		    const long plen = buf->get - buf->base;
		    if(plen >= MIN_WMO_MSG_LEN)
		    {
			wmo_send_buf (buf, 2);
			sent++;
		    }
		    else
		    {
			not_wmo++;
			uerror("scan_wmo_binary_crc: length %ld too short",
				plen);
		    }
		}
		justify_xbuf(buf, 0);
		state	= START;
		break;
#	endif
	}				/* state switch */

#	if defined(SCAN_CHECK)
	    offset++;
#	endif
    }					/* input character loop */
    return sent ;
}
Beispiel #4
0
int
scan_faa604_parity (xbuf * buf)
{
    extern char *parity;
    int sent = 0;
    int ch;

    static enum state
    {
        SKIP,
        SEARCH,
        HEADER_SEEN,
        PARITY_PIP
    }
    state = SEARCH;

    while ((ch = nextc (buf)) != EOB)
    {
        switch(ch) {
        case SOH:
            switch (state) {
            case SKIP:
                log_debug("Resync skipped %05ld bytes",
                          (long) (buf->get - buf->base) - 1);
                break;
            case HEADER_SEEN:
                sohetx_missed++;
                log_error("Lone SOH error           - %s",
                          faa604_err_ident(buf));
                break;
            case PARITY_PIP:
                parity_errs++;
                log_error("Parity error             - %s",
                          faa604_err_ident(buf));
                break;
            }
            justify_xbuf (buf, 1);
            state = HEADER_SEEN;
            break;
        case ETX:
            switch (state) {
            case SKIP:
#if 0
            case SEARCH:
#endif
                sohetx_missed++;
                log_error("Lone ETX error           - %s",
                          faa604_err_ident(buf));
                break;
            case HEADER_SEEN:
            {
                const long plen = buf->get - buf->base;
                if(plen >= MIN_FAA604_MSG_LEN)
                {
                    faa604_send_buf (buf);
                    sent++;
                }
                else
                {
                    not_faa604++;
                    log_error("scan_faa604 - length %ld too short",
                              plen);
                }
                justify_xbuf (buf, 0);
                state = SEARCH;
            }
            break;
            case PARITY_PIP:
                parity_errs++;
                log_error("Parity error             - %s",
                          faa604_err_ident(buf));
                break;
            }
            justify_xbuf (buf, 0);
            state = SEARCH;
            break;
        case 0:
            if(state == HEADER_SEEN
                    /* && (parity != NULL && *parity != 'n') */
              )
            {
                state = PARITY_PIP;
            }
            break;
        default:
            if(state == SEARCH && isgraph(ch))
                state = SKIP;
            break;
        }
    }			/* input character loop */

    return sent;
}
Beispiel #5
0
scan_wmo_parity (xbuf * buf)
#endif
{
	extern char *parity;
	int sent = 0;
	int ch;

	static enum state
	{
		SKIP,
		SEARCH,
		HEADER_SEEN,
		PARITY_PIP
	}
	state = SEARCH;

	while ((ch = nextc (buf)) != EOB)
	{
		switch(ch) {
		case SOH:	
			switch (state) {
			case SKIP:
				udebug ("Resync skipped %05ld bytes",
					(long) (buf->get - buf->base) - 1);
				break;
#if 0
			case SEARCH:
				udebug ("Search %05ld bytes",
					(long) (buf->get - buf->base) - 1);
				break;
#endif
			case HEADER_SEEN:
				sohetx_missed++;
				uerror("Lone SOH error                   %s",
					wmo_err_ident(buf));
				break;
			case PARITY_PIP:
				bad_cksum++;
				uerror("Parity error                     %s",
					wmo_err_ident(buf));
				break;
			}
			justify_xbuf (buf, 1);
			state = HEADER_SEEN;
			break;
		case ETX:	
			switch (state) {
			case SKIP:
#if 0
			case SEARCH:
#endif
				sohetx_missed++;
				uerror("Lone ETX error                   %s",
					wmo_err_ident(buf));
				break;
			case HEADER_SEEN:
			{
				const long plen = buf->get - buf->base;
				if(plen >= MIN_WMO_MSG_LEN)
				{
					wmo_send_buf (buf, 0);
					sent++;
				}
				else
				{
					not_wmo++;
					uerror("scan_wmo: length %ld too short",
						plen);
				}
				justify_xbuf (buf, 0);
				state = SEARCH;
			}
				break;
			case PARITY_PIP:
				bad_cksum++;
				uerror("Parity error                     %s",
					wmo_err_ident(buf));
				break;
			}
			justify_xbuf (buf, 0);
			state = SEARCH;
			break;
#if defined(SCAN_CHECK)
		case 0:	
		   	if(state == HEADER_SEEN
				/* && (parity != NULL && *parity != 'n') */
				)
		   	{
				state = PARITY_PIP;
		   	}
			break;
#elif defined(PARITY_ERR_CH)
		case 0:	
			/*
			 * Backward compatibility
			 * except it can change file feeds
			 */
		   	if(state == HEADER_SEEN
				 && (parity != NULL && *parity != 'n'))
			{
				*(buf->get -1) = PARITY_ERR_CH;
			}
			break;
#endif
		default:
			if(state == SEARCH && isgraph(ch))
				state = SKIP;
			break;
		}
	}			/* input character loop */

	return sent;
}