packet.c

来自「gpsd, a popular GPS daemon.」· C语言 代码 · 共 1,271 行 · 第 1/3 页

C
1,271
字号
	break;    case SIRF_TRAILER_1:	if (c == 0xb3)	    lexer->state = SIRF_RECOGNIZED;	else	    lexer->state = GROUND_STATE;	break;    case SIRF_RECOGNIZED:	if (c == 0xa0)	    lexer->state = SIRF_LEADER_1;	else	    lexer->state = GROUND_STATE;	break;#endif /* SIRF_ENABLE */#if defined(TSIP_ENABLE) || defined(EVERMORE_ENABLE) || defined(GARMIN_ENABLE)    case DLE_LEADER:#ifdef EVERMORE_ENABLE	if (c == STX) {	    lexer->state = EVERMORE_LEADER_2;	    break;	}#endif /* EVERMORE_ENABLE */#if defined(TSIP_ENABLE) || defined(GARMIN_ENABLE) || defined(NAVCOM_ENABLE)	/* garmin is special case of TSIP */	/* check last because there's no checksum */	if (c >= 0x13) {	    lexer->state = TSIP_PAYLOAD;	    break;	}	if (c == DLE) {	    lexer->state = GROUND_STATE;	    break;	}	// FALL-THRU!!!!! no break here#endif /* TSIP_ENABLE */#ifdef NAVCOM_ENABLE    case NAVCOM_LEADER_1:	if (c == 0x99)	    lexer->state = NAVCOM_LEADER_2;	else	    lexer->state = GROUND_STATE;	break;    case NAVCOM_LEADER_2:	if (c == 0x66)	    lexer->state = NAVCOM_LEADER_3;	else	    lexer->state = GROUND_STATE;	break;    case NAVCOM_LEADER_3:	lexer->state = NAVCOM_ID;	break;    case NAVCOM_ID:	lexer->length = (size_t)c - 4;	lexer->state = NAVCOM_LENGTH_1;	break;    case NAVCOM_LENGTH_1:	lexer->length += (c << 8);	lexer->state = NAVCOM_LENGTH_2;	break;    case NAVCOM_LENGTH_2:	if (--lexer->length == 0)	    lexer->state = NAVCOM_PAYLOAD;	break;    case NAVCOM_PAYLOAD:	{	    unsigned int n;	    unsigned char csum = lexer->inbuffer[3];	    for(n=4; (unsigned char *)(lexer->inbuffer + n) < lexer->inbufptr - 1; n++)	    csum ^= lexer->inbuffer[n];	    if(csum != c) {	    gpsd_report(LOG_INF, "Navcom packet type 0x%hx bad checksum 0x%hx, expecting 0x%hx\n",		    lexer->inbuffer[3], csum, c);	    gpsd_report(LOG_RAW, "Navcom packet dump: %s\n",			gpsd_hexdump(lexer->inbuffer, lexer->inbuflen));	    lexer->state = GROUND_STATE;	    break;	    }	}	lexer->state = NAVCOM_CSUM;	break;    case NAVCOM_CSUM:	if (c == 0x03)	    lexer->state = NAVCOM_RECOGNIZED;	else	    lexer->state = GROUND_STATE;	break;    case NAVCOM_RECOGNIZED:	if (c == 0x02)	    lexer->state = NAVCOM_LEADER_1;	else	    lexer->state = GROUND_STATE;	break;#endif /* NAVCOM_ENABLE */#endif /* TSIP_ENABLE || EVERMORE_ENABLE || GARMIN_ENABLE */#ifdef ZODIAC_ENABLE    case ZODIAC_EXPECTED:    case ZODIAC_RECOGNIZED:	if (c == 0xff)	    lexer->state = ZODIAC_LEADER_1;	else	    lexer->state = GROUND_STATE;	break;    case ZODIAC_LEADER_1:	if (c == 0x81)	    lexer->state = ZODIAC_LEADER_2;	else	    lexer->state = GROUND_STATE;	break;    case ZODIAC_LEADER_2:	lexer->state = ZODIAC_ID_1;	break;    case ZODIAC_ID_1:	lexer->state = ZODIAC_ID_2;	break;    case ZODIAC_ID_2:	lexer->length = (size_t)c;	lexer->state = ZODIAC_LENGTH_1;	break;    case ZODIAC_LENGTH_1:	lexer->length += (c << 8);	lexer->state = ZODIAC_LENGTH_2;	break;    case ZODIAC_LENGTH_2:	lexer->state = ZODIAC_FLAGS_1;	break;    case ZODIAC_FLAGS_1:	lexer->state = ZODIAC_FLAGS_2;	break;    case ZODIAC_FLAGS_2:	lexer->state = ZODIAC_HSUM_1;	break;    case ZODIAC_HSUM_1:	{ #define getword(i) (short)(lexer->inbuffer[2*(i)] | (lexer->inbuffer[2*(i)+1] << 8))	    short sum = getword(0) + getword(1) + getword(2) + getword(3);	    sum *= -1;	    if (sum != getword(4)) {		gpsd_report(LOG_IO,		    "Zodiac Header checksum 0x%hx expecting 0x%hx\n",		    sum, getword(4));		lexer->state = GROUND_STATE;		break;	    }	}	gpsd_report(LOG_RAW+1,"Zodiac header id=%hd len=%hd flags=%hx\n",	    getword(1), getword(2), getword(3)); #undef getword	if (lexer->length == 0) {	    lexer->state = ZODIAC_RECOGNIZED;	    break;	}	lexer->length *= 2;		/* word count to byte count */	lexer->length += 2;		/* checksum */	/* 10 bytes is the length of the Zodiac header */	if (lexer->length <= MAX_PACKET_LENGTH - 10)	    lexer->state = ZODIAC_PAYLOAD;	else	    lexer->state = GROUND_STATE;	break;    case ZODIAC_PAYLOAD:	if (--lexer->length == 0)	    lexer->state = ZODIAC_RECOGNIZED;	break;#endif /* ZODIAC_ENABLE */#ifdef UBX_ENABLE    case UBX_LEADER_1:	if (c == 0x62)	    lexer->state = UBX_LEADER_2;	else	    lexer->state = GROUND_STATE;	break;    case UBX_LEADER_2:	lexer->state = UBX_CLASS_ID;	break;    case UBX_CLASS_ID:	lexer->state = UBX_MESSAGE_ID;	break;    case UBX_MESSAGE_ID:	lexer->length = (size_t)c;	lexer->state = UBX_LENGTH_1;	break;    case UBX_LENGTH_1:	lexer->length += (c << 8);	if (lexer->length <= MAX_PACKET_LENGTH)	    lexer->state = UBX_LENGTH_2;	else	    lexer->state = GROUND_STATE;	break;    case UBX_LENGTH_2:	lexer->state = UBX_PAYLOAD;	break;    case UBX_PAYLOAD:	if (--lexer->length == 0)	    lexer->state = UBX_CHECKSUM_A;	/* else stay in payload state */	break;    case UBX_CHECKSUM_A:	lexer->state = UBX_RECOGNIZED;	break;    case UBX_RECOGNIZED:	if (c == 0xb5)	    lexer->state = UBX_LEADER_1;	else	    lexer->state = GROUND_STATE;	break;#endif /* UBX_ENABLE */#ifdef EVERMORE_ENABLE    case EVERMORE_LEADER_1:	if (c == STX)	    lexer->state = EVERMORE_LEADER_2;	else	    lexer->state = GROUND_STATE;	break;    case EVERMORE_LEADER_2:	lexer->length = (size_t)c;	if (c == DLE)	    lexer->state = EVERMORE_PAYLOAD_DLE;	else	    lexer->state = EVERMORE_PAYLOAD;	break;    case EVERMORE_PAYLOAD:	if (c == DLE)	    lexer->state = EVERMORE_PAYLOAD_DLE;	else if (--lexer->length == 0)	    lexer->state = GROUND_STATE;	break;    case EVERMORE_PAYLOAD_DLE:	switch (c) {	   case DLE: lexer->state = EVERMORE_PAYLOAD; break;	   case ETX: lexer->state = EVERMORE_RECOGNIZED; break;	   default: lexer->state = GROUND_STATE;	}    break;    case EVERMORE_RECOGNIZED:	if (c == DLE)	    lexer->state = EVERMORE_LEADER_1;	else	    lexer->state = GROUND_STATE;	break;#endif /* EVERMORE_ENABLE */#ifdef ITRAX_ENABLE    case ITALK_LEADER_1:	if (c == '!')	    lexer->state = ITALK_LEADER_2;	else	    lexer->state = GROUND_STATE;	break;    case ITALK_LEADER_2:	lexer->length = (size_t)(lexer->inbuffer[6] & 0xff);	lexer->state = ITALK_LENGTH;	break;    case ITALK_LENGTH:	lexer->length += 1;	/* fix number of words in payload */	lexer->length *= 2;	/* convert to number of bytes */	lexer->length += 3;	/* add trailer length */	lexer->state = ITALK_PAYLOAD;	break;    case ITALK_PAYLOAD:	/* lookahead for "<!" because sometimes packets are short but valid */	if ((c == '>') && (lexer->inbufptr[0] == '<') &&	    (lexer->inbufptr[1] == '!')){	    lexer->state = ITALK_RECOGNIZED;	    gpsd_report(LOG_PROG, "ITALK: trying to process runt packet\n");	    break;	} else if (--lexer->length == 0)	    lexer->state = ITALK_DELIVERED;	break;    case ITALK_DELIVERED:	if (c == '>')	    lexer->state = ITALK_RECOGNIZED;	else	    lexer->state = GROUND_STATE;	break;    case ITALK_RECOGNIZED:	if (c == '<')	    lexer->state = ITALK_LEADER_1;	else	    lexer->state = GROUND_STATE;	break;#endif /* ITRAX_ENABLE */#ifdef TSIP_ENABLE    case TSIP_LEADER:	/* unused case */	if (c >= 0x13)	    lexer->state = TSIP_PAYLOAD;	else	    lexer->state = GROUND_STATE;	break;    case TSIP_PAYLOAD:	if (c == DLE)	    lexer->state = TSIP_DLE;	break;    case TSIP_DLE:	switch (c)	{	case ETX:	    lexer->state = TSIP_RECOGNIZED;	    break;	case DLE:	    lexer->state = TSIP_PAYLOAD;	    break;	default:	    lexer->state = GROUND_STATE;	    break;	}	break;    case TSIP_RECOGNIZED:	if (c == DLE)	    /*	     * Don't go to TSIP_LEADER state -- TSIP packets aren't	     * checksummed, so false positives are easy.  We might be	     * looking at another DLE-stuffed protocol like EverMore	     * or Garmin streaming binary.	     */	    lexer->state = DLE_LEADER;	else	    lexer->state = GROUND_STATE;	break;#endif /* TSIP_ENABLE */#ifdef RTCM104_ENABLE    case RTCM_SYNC_STATE:    case RTCM_SKIP_STATE:	if ((isgpsstat = rtcm_decode(lexer, c)) == ISGPS_MESSAGE) {	    lexer->state = RTCM_RECOGNIZED;	    break;	} else if (isgpsstat == ISGPS_NO_SYNC)	    lexer->state = GROUND_STATE;	break;    case RTCM_RECOGNIZED:	if (rtcm_decode(lexer, c) == ISGPS_SYNC) {	    lexer->state = RTCM_SYNC_STATE;	    break;	} else	    lexer->state = GROUND_STATE;	break;#endif /* RTCM104_ENABLE */    }/*@ -charint +casebreak @*/}#define STATE_DEBUGstatic void packet_accept(struct gps_packet_t *lexer, int packet_type)/* packet grab succeeded, move to output buffer */{    size_t packetlen = lexer->inbufptr-lexer->inbuffer;    if (packetlen < sizeof(lexer->outbuffer)) {	memcpy(lexer->outbuffer, lexer->inbuffer, packetlen);	lexer->outbuflen = packetlen;	lexer->outbuffer[packetlen] = '\0';	lexer->type = packet_type;#ifdef STATE_DEBUG	gpsd_report(LOG_RAW+1, "Packet type %d accepted %d = %s\n",		packet_type, packetlen,		gpsd_hexdump(lexer->outbuffer, lexer->outbuflen));#endif /* STATE_DEBUG */    } else {	gpsd_report(LOG_ERROR, "Rejected too long packet type %d len %d\n",		packet_type,packetlen);    }}static void packet_discard(struct gps_packet_t *lexer)/* shift the input buffer to discard all data up to current input pointer */{    size_t discard = lexer->inbufptr - lexer->inbuffer;    size_t remaining = lexer->inbuflen - discard;    lexer->inbufptr = memmove(lexer->inbuffer,				lexer->inbufptr,				remaining);    lexer->inbuflen = remaining;#ifdef STATE_DEBUG    gpsd_report(LOG_RAW+1, "Packet discard of %d, chars remaining is %d = %s\n",		discard, remaining,		gpsd_hexdump(lexer->inbuffer, lexer->inbuflen));#endif /* STATE_DEBUG */}static void character_discard(struct gps_packet_t *lexer)/* shift the input buffer to discard one character and reread data */{    memmove(lexer->inbuffer, lexer->inbuffer+1, (size_t)--lexer->inbuflen);    lexer->inbufptr = lexer->inbuffer;#ifdef STATE_DEBUG    gpsd_report(LOG_RAW+1, "Character discarded, buffer %d chars = %s\n",		lexer->inbuflen,		gpsd_hexdump(lexer->inbuffer, lexer->inbuflen));#endif /* STATE_DEBUG */}/* get 0-origin big-endian words relative to start of packet buffer */#define getword(i) (short)(lexer->inbuffer[2*(i)] | (lexer->inbuffer[2*(i)+1] << 8))/* entry points begin here */ssize_t packet_parse(struct gps_packet_t *lexer, size_t fix)/* grab a packet; returns either BAD_PACKET or the length */{#ifdef STATE_DEBUG    gpsd_report(LOG_RAW+1, "Read %d chars to buffer offset %d (total %d): %s\n",		fix,		lexer->inbuflen,		lexer->inbuflen+fix,		gpsd_hexdump(lexer->inbufptr, fix));#endif /* STATE_DEBUG */    lexer->outbuflen = 0;    lexer->inbuflen += fix;    while (lexer->inbufptr < lexer->inbuffer + lexer->inbuflen) {	/*@ -modobserver @*/	unsigned char c = *lexer->inbufptr++;	/*@ +modobserver @*/	char *state_table[] = {#include "packet_names.h"	};	nextstate(lexer, c);	gpsd_report(LOG_RAW+2, "%08ld: character '%c' [%02x], new state: %s\n",		    lexer->char_counter,		    (isprint(c)?c:'.'),		    c,		    state_table[lexer->state]);	lexer->char_counter++;

⌨️ 快捷键说明

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