Go to hell and back to get valid frames off the wire, and keep track of error counts
This commit is contained in:
		
							parent
							
								
									6a427c4097
								
							
						
					
					
						commit
						9af63066b6
					
				
					 2 changed files with 43 additions and 20 deletions
				
			
		| 
						 | 
				
			
			@ -31,6 +31,8 @@ patty_kiss_tnc *patty_kiss_tnc_open(const char *device, size_t bufsize);
 | 
			
		|||
 | 
			
		||||
void patty_kiss_tnc_close(patty_kiss_tnc *tnc);
 | 
			
		||||
 | 
			
		||||
int patty_kiss_tnc_errors(patty_kiss_tnc *tnc);
 | 
			
		||||
 | 
			
		||||
ssize_t patty_kiss_tnc_recv(patty_kiss_tnc *tnc,
 | 
			
		||||
    void **frame, int *port);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										61
									
								
								src/kiss.c
									
										
									
									
									
								
							
							
						
						
									
										61
									
								
								src/kiss.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -17,6 +17,7 @@ enum kiss_flags {
 | 
			
		|||
 | 
			
		||||
struct _patty_kiss_tnc {
 | 
			
		||||
    int    fd;
 | 
			
		||||
    int    errors;
 | 
			
		||||
    void * frame;
 | 
			
		||||
    void * buf;
 | 
			
		||||
    size_t bufsz;
 | 
			
		||||
| 
						 | 
				
			
			@ -42,6 +43,7 @@ patty_kiss_tnc *patty_kiss_tnc_open(const char *device, size_t bufsz) {
 | 
			
		|||
        goto error_open;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    tnc->errors = 0;
 | 
			
		||||
    tnc->bufsz  = bufsz;
 | 
			
		||||
    tnc->buflen = 0;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -113,7 +115,7 @@ static ssize_t tnc_decode(patty_kiss_tnc *tnc, void *frame, size_t *len, int *po
 | 
			
		|||
         * Not all KISS TNCs will emit a type byte at the start of a frame
 | 
			
		||||
         * to the host; if the low nybble has a value of zero, then presume
 | 
			
		||||
         * the high nybble to be the radio port number from which the
 | 
			
		||||
         * packet originated.
 | 
			
		||||
         * frame originated.
 | 
			
		||||
         */
 | 
			
		||||
        if (i == 1 && (c & 0x0f) == 0) {
 | 
			
		||||
            *port = (c & 0xf0) >> 4;
 | 
			
		||||
| 
						 | 
				
			
			@ -180,6 +182,18 @@ error_io:
 | 
			
		|||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void tnc_drop(patty_kiss_tnc *tnc) {
 | 
			
		||||
    memset(tnc->buf,   '\0', tnc->bufsz);
 | 
			
		||||
    memset(tnc->frame, '\0', tnc->bufsz);
 | 
			
		||||
 | 
			
		||||
    tnc->buflen = 0;
 | 
			
		||||
    tnc->errors++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int patty_kiss_tnc_errors(patty_kiss_tnc *tnc) {
 | 
			
		||||
    return tnc->errors;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void tnc_flush(patty_kiss_tnc *tnc, size_t len) {
 | 
			
		||||
    /*
 | 
			
		||||
     * Move everything from the buffer not processed up to this point, to the
 | 
			
		||||
| 
						 | 
				
			
			@ -195,35 +209,42 @@ static void tnc_flush(patty_kiss_tnc *tnc, size_t len) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
ssize_t patty_kiss_tnc_recv(patty_kiss_tnc *tnc, void **frame, int *port) {
 | 
			
		||||
    ssize_t decoded;
 | 
			
		||||
    ssize_t buffered, decoded;
 | 
			
		||||
     size_t framelen;
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Fill the buffer with something to parse!
 | 
			
		||||
     */
 | 
			
		||||
    if (tnc_buffer(tnc) < 0) {
 | 
			
		||||
        goto error_io;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Initialize the frame to be returned to the caller.
 | 
			
		||||
     */
 | 
			
		||||
    memset(tnc->frame, '\0', tnc->bufsz);
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Try to decode the TNC buffer into the packet.
 | 
			
		||||
     */
 | 
			
		||||
    if ((decoded = tnc_decode(tnc, tnc->frame, &framelen, port)) < 0) {
 | 
			
		||||
        goto error_io;
 | 
			
		||||
    }
 | 
			
		||||
    do {
 | 
			
		||||
        /*
 | 
			
		||||
         * Fill the buffer with something to parse.
 | 
			
		||||
         */
 | 
			
		||||
        if ((buffered = tnc_buffer(tnc)) < 0) {
 | 
			
		||||
            goto error_io;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * Try to decode the TNC buffer into the frame.
 | 
			
		||||
         */
 | 
			
		||||
        if ((decoded = tnc_decode(tnc, tnc->frame, &framelen, port)) < 0) {
 | 
			
		||||
            goto error_io;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * If we can no longer buffer nor decode any data, then drop the whole
 | 
			
		||||
         * frame.
 | 
			
		||||
         */
 | 
			
		||||
        if (decoded == 0 && buffered == 0) {
 | 
			
		||||
            tnc_drop(tnc);
 | 
			
		||||
        }
 | 
			
		||||
    } while (decoded == 0);
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * If we have decoded frame data, then flush the buffer up to the point of
 | 
			
		||||
     * the next frame start, if present.
 | 
			
		||||
     * Flush the buffer up to the point of the next frame start.
 | 
			
		||||
     */
 | 
			
		||||
    if (decoded) {
 | 
			
		||||
        tnc_flush(tnc, decoded);
 | 
			
		||||
    }
 | 
			
		||||
    tnc_flush(tnc, decoded);
 | 
			
		||||
 | 
			
		||||
    *frame = tnc->frame;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue