⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nmeap01.c

📁 GARMIN的GPS信息解释器
💻 C
📖 第 1 页 / 共 2 页
字号:
    return id;
}

/**
                 +-5-+              +---+
                 v   |              v   |
 +------+       +------+           +------+         +------+         +------+
 |   0  |--$--> |1-hdr |--alnum--> |2-data|----\r-->| 6-LF |---\n--->| done |--> 0
 +------+       +------+           +------+         +------+         +------+
                                    |                 ^
                                    *                 +--------\r-------+
                                    V                                   |
                                 +------+           +------+         +------+
                                 |3-cks |--xdigit-->|4-cks |-xdigit->| 5-CR |
                                 +------+           +------+         +------+
                                 
return to start conditions:
1. buffer overflow
2. invalid character for state

checksum calculation
two hex digits represent the XOR of all characters between, but not
including, the "$" and "*".  A checksum is required on some
sentences.

*/
int nmeap_parse(nmeap_context_t *context,char ch)
{
    int status = 0;
    
    /* check for input buffer overrun first to avoid duplicating code in the
    individual states
    */
    if (context->input_count >= (sizeof(context->input)-1)) {
        /* input buffer overrun, restart state machine */
        context->input_state = 0;
        /* reset input count */
        context->input_count = 0;
    }
    
    /* store the byte */
    context->input[context->input_count] = ch;
    
    /* next buffer position */
    context->input_count++;
    
    /* run it through the lexical scanner */
    switch(context->input_state) {
    /* LOOKING FOR $ */
    case 0:
        if (ch == '$') {
            /*look for id */
            context->input_state = 1;
            context->ccks        = 0;
			context->icks        = 0;
        }
        else {
            /* header error, start over */
            context->err_hdr++;
            context->input_state = 0;
            context->input_count = 0;
        }
        break;
    /* LOOKING FOR 5 CHARACTER SENTENCE ID */
    case 1:
        /* allow numbers even though it isn't usually done */
        /* a proprietary id might have a numeral */
        if (isalnum(ch)) {
            /* store name separately */
            context->input_name[context->input_count - 2] = ch;
            /* checksum */
            context->ccks ^= ch;
            /* end of header? */
            if (context->input_count >= 6) {
                /* yes, get body */
                context->input_state = 2;
            }
        }
        else {
            /* bad character, start over */
            context->err_id++;
            context->input_state = 0;
            context->input_count = 0;
        }
        break;
    /* LOOKING FOR CR OR CHECKSUM INDICATOR */
    case 2:
        if (ch == '*') {
            /* this sentence has a checksum */
            context->input_state = 3;
        }
        else if (ch == '\r') {
            /* carriage return, no checksum, force a match */
			context->icks = 0;
			context->ccks = 0;
            context->input_state = 6;
        }
        else {
            /* continue accumulating data */
            /* checksum */
            context->ccks ^= ch;
        }
        break;
    /* LOOKING FOR FIRST CHECKSUM CHARACTER */
    case 3:
        /* must be upper case hex digit */
        if (isxdigit(ch) && (ch <= 'F')) {
            /* got first checksum byte */
            context->input_state = 4;
            context->icks = HEXTOBIN(ch) << 4;
        }
        else {
            /* input error, restart */
            context->err_cks++;
            context->input_state = 0;
            context->input_count = 0;
        }
        break;
        /* LOOKING FOR SECOND CHECKSUM CHARACTER */
    case 4:
        /* must be upper case hex digit */
        if (isxdigit(ch) && (ch <= 'F')) {
            /* got second checksum byte */
            context->input_state = 5;
            context->icks += HEXTOBIN(ch);
        }
        else {
            /* input error, restart */
            context->err_cks++;
            context->input_state = 0;
            context->input_count = 0;
        }
        break;
    /* LOOKING FOR CR */
    case 5:
        if (ch == '\r') {
            /* carriage return */
            context->input_state = 6;
        }
        else {
            /* input error, restart */
            context->err_crl++;
            context->input_state = 0;
            context->input_count = 0;
        }
        break;
    /* LOOKING FOR LINE FEED */
    case 6:
        if (ch == '\n') {
            /* linefeed, line complete */
            
            /* delimit buffer */
            context->input[context->input_count] = 0;
            
            /* if the checksums match, process the sentence */
			if (context->ccks == context->icks) {
				/* process */
				status = nmeap_process(context);
				
				/* count good messages */
				context->msgs++;
			}
			else {
				/* count checksum errors */
				context->err_cks++;
			}
            
            /* restart next time */
            context->input_state = 0;
            context->input_count = 0;
        }
        else {
            /* input error, restart */
            context->err_crl++;
            context->input_state = 0;
            context->input_count = 0;
        }
        break;
    default:
        context->err_unk++;
        context->input_state = 0;
        break;
    }
            
	return status;
}

/** 
 * parse a buffer of nmea data
 */
int nmeap_parseBuffer(nmeap_context_t *context,const char *buffer,int *length)
{
    int  i;
    int  status;
    int  rem;
    int  tlen;
    
    tlen   = *length;
    rem    = *length;
    status = 0;
    /* for each byte in the buffer */
    for(i=0;i<tlen;i++) {
        /* decrement remaining byte count */
        rem--;
        /* parse the byte */
        status = nmeap_parse(context,buffer[i]);
        if (status != 0) {
            /* message found or error */
            break;
        }
    }
	
    /* return remaining byte count */
    *length = rem;
	
    return status;
}

/** 
 * standard GPGGA sentence parser 
 */
int nmeap_gpgga(nmeap_context_t *context,nmeap_sentence_t *sentence)
{
#ifndef NDEBUG	
    int i;
#endif
    
    /* get pointer to sentence data */
    nmeap_gga_t *gga = (nmeap_gga_t *)sentence->data;
    
    /* if there is a data element, extract data from the tokens */
	if (gga != 0) {
		gga->latitude  = nmeap_latitude(context->token[2],context->token[3]);
		gga->longitude = nmeap_longitude(context->token[4],context->token[5]);
		gga->altitude  = nmeap_altitude(context->token[9],context->token[10]);
		gga->time       = atoi(context->token[1]);
		gga->satellites = atoi(context->token[7]);
		gga->quality    = atoi(context->token[6]);
		gga->hdop       = atof(context->token[8]);
		gga->geoid      = nmeap_altitude(context->token[11],context->token[12]);
	}

#ifndef NDEBUG    
    /* print raw input string */
    printf("%s",context->debug_input);
    
    /* print some validation data */
    printf("%s==%s %02x==%02x\n",context->input_name,sentence->name,context->icks,context->ccks);
    
    /* print the tokens */
    for(i=0;i<context->tokens;i++) {
        printf("%d:%s\n",i,context->token[i]);
    }
#endif   

    /* if the sentence has a callout, call it */
    if (sentence->callout != 0) {
        (*sentence->callout)(context,gga,context->user_data);
    }
    
    return NMEAP_GPGGA;
}

/** 
 * standard GPRMCntence parser 
 */
int nmeap_gprmc(nmeap_context_t *context,nmeap_sentence_t *sentence)
{
#ifndef NDEBUG	
    int i;
#endif

    /* get pointer to sentence data */
    nmeap_rmc_t *rmc = (nmeap_rmc_t *)sentence->data;
    
	/* if there is a data element, use it */
	if (rmc != 0) {
		/* extract data from the tokens */
		rmc->time       = atoi(context->token[1]);
		rmc->warn       = *context->token[2];
		rmc->latitude  = nmeap_latitude(context->token[3],context->token[4]);
		rmc->longitude = nmeap_longitude(context->token[5],context->token[6]);
		rmc->speed      = atof(context->token[7]);
		rmc->course     = atof(context->token[8]);
		rmc->date       = atoi(context->token[9]);
		rmc->magvar     = atof(context->token[10]);
	}

#ifndef NDEBUG    
    /* print raw input string */
    printf("%s",context->debug_input);
    
    /* print some validation data */
    printf("%s==%s %02x==%02x\n",context->input_name,sentence->name,context->icks,context->ccks);
    
    /* print the tokens */
    for(i=0;i<context->tokens;i++) {
        printf("%d:%s\n",i,context->token[i]);
    }
#endif   

    /* if the sentence has a callout, call it */
    if (sentence->callout != 0) {
        (*sentence->callout)(context,rmc,context->user_data);
    }
    
    return NMEAP_GPRMC;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -