Bläddra i källkod

Add support for $GPGSA sequences.

Denys Kuzmenko 11 år sedan
förälder
incheckning
e2838ed642
3 ändrade filer med 134 tillägg och 0 borttagningar
  1. 61 0
      minmea.c
  2. 33 0
      minmea.h
  3. 40 0
      tests.c

+ 61 - 0
minmea.c

@@ -271,6 +271,8 @@ enum minmea_type minmea_type(const char *sentence)
         return MINMEA_GPRMC;
     if (!strcmp(type, "GPGGA"))
         return MINMEA_GPGGA;
+    if (!strcmp(type, "GPGSA"))
+        return MINMEA_GPGSA;
 
     return MINMEA_UNKNOWN;
 }
@@ -333,6 +335,65 @@ bool minmea_parse_gpgga(struct minmea_gpgga *frame, const char *sentence)
     return true;
 }
 
+bool minmea_parse_gpgsa(struct minmea_gpgsa *frame, const char *sentence){
+	// $GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39
+	char type[6];
+
+	if (!minmea_scan(sentence, "tciiiiiiiiiiiiifff",
+			type,
+			&frame->mode,
+			&frame->fix_type,
+			&frame->sat1,
+			&frame->sat2,
+			&frame->sat3,
+			&frame->sat4,
+			&frame->sat5,
+			&frame->sat6,
+			&frame->sat7,
+			&frame->sat8,
+			&frame->sat9,
+			&frame->sat10,
+			&frame->sat11,
+			&frame->sat12,
+			&frame->pdop,
+			&frame->pdop_scale,
+			&frame->hdop,
+			&frame->hdop_scale,
+			&frame->vdop,
+			&frame->vdop_scale
+			)){
+		return false;
+	}
+	if (strcmp(type, "GPGSA")){
+		return false;
+	}
+
+	if(frame->mode == 'A'){
+		frame->mode = GPGSA_MODE_AUTO;
+	}
+	else if(frame->mode == 'M'){
+		frame->mode = GPGSA_MODE_FORCED;
+	}
+	else{
+		return false;
+	}
+
+	if(frame->fix_type == 1){
+		frame->fix_type = GPGSA_FIX_NONE;
+	}
+	else if(frame->fix_type == 2){
+		frame->fix_type = GPGSA_FIX_2D;
+	}
+	else if(frame->fix_type == 3){
+		frame->fix_type = GPGSA_FIX_3D;
+	}
+	else{
+		return false;
+	}
+
+	return true;
+}
+
 int minmea_gettimeofday(struct timeval *tv, const struct minmea_date *date, const struct minmea_time *time)
 {
     if (date->year == -1 || time->hours == -1)

+ 33 - 0
minmea.h

@@ -27,6 +27,7 @@ enum minmea_type {
     MINMEA_UNKNOWN = 0,
     MINMEA_GPRMC,
     MINMEA_GPGGA,
+    MINMEA_GPGSA,
 };
 
 struct minmea_date {
@@ -65,6 +66,37 @@ struct minmea_gpgga {
     int dgps_age;
 };
 
+enum minmea_gpgsa_mode {
+	GPGSA_MODE_AUTO,
+	GPGSA_MODE_FORCED
+};
+
+enum minmea_gpgsa_fix_type {
+	GPGSA_FIX_NONE,
+	GPGSA_FIX_2D,
+	GPGSA_FIX_3D
+};
+
+struct minmea_gpgsa {
+	int mode;
+	int fix_type;
+	int sat1;
+	int sat2;
+	int sat3;
+	int sat4;
+	int sat5;
+	int sat6;
+	int sat7;
+	int sat8;
+	int sat9;
+	int sat10;
+	int sat11;
+	int sat12;
+    int pdop, pdop_scale;
+    int hdop, hdop_scale;
+    int vdop, vdop_scale;
+};
+
 /**
  * Check sequence validity and checksum. Returns true for valid sequences.
  */
@@ -93,6 +125,7 @@ bool minmea_scan(const char *sentence, const char *format, ...);
  */
 bool minmea_parse_gprmc(struct minmea_gprmc *frame, const char *sentence);
 bool minmea_parse_gpgga(struct minmea_gpgga *frame, const char *sentence);
+bool minmea_parse_gpgsa(struct minmea_gpgsa *frame, const char *sentence);
 
 /**
  * Convert GPS UTC date/time representation to a UNIX timestamp.

+ 40 - 0
tests.c

@@ -328,11 +328,44 @@ START_TEST(test_minmea_parse_gpgga1)
 }
 END_TEST
 
+START_TEST(test_minmea_parse_gpgsa1)
+{
+    const char *sentence = "$GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39";
+    struct minmea_gpgsa frame = {};
+    struct minmea_gpgsa expected = {
+    	.mode = GPGSA_MODE_AUTO,
+    	.fix_type = GPGSA_FIX_3D,
+    	.sat1 = 4,
+    	.sat2 = 5,
+    	.sat3 = 0,
+    	.sat4 = 9,
+    	.sat5 = 12,
+    	.sat6 = 0,
+    	.sat7 = 0,
+    	.sat8 = 24,
+    	.sat9 = 0,
+    	.sat10 = 0,
+    	.sat11 = 0,
+    	.sat12 = 0,
+    	.pdop = 25,
+    	.pdop_scale = 10,
+    	.hdop = 13,
+    	.hdop_scale = 10,
+    	.vdop = 21,
+    	.vdop_scale = 10
+    };
+    ck_assert(minmea_check(sentence) == true);
+    ck_assert(minmea_parse_gpgsa(&frame, sentence) == true);
+    ck_assert(!memcmp(&frame, &expected, sizeof(frame)));
+}
+END_TEST
+
 START_TEST(test_minmea_usage1)
 {
     const char *sentences[] = {
         "$GPRMC,081836,A,3751.65,S,14507.36,E,000.0,360.0,130998,011.3,E*62",
         "$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47",
+        "$GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39",
         NULL,
     };
 
@@ -348,6 +381,12 @@ START_TEST(test_minmea_usage1)
                 ck_assert(minmea_parse_gpgga(&frame, *sentence) == true);
             } break;
             
+            case MINMEA_GPGSA: {
+                struct minmea_gpgsa frame;
+                ck_assert(minmea_parse_gpgsa(&frame, *sentence) == true);
+            } break;
+
+
             default: {
             } break;
         }
@@ -424,6 +463,7 @@ Suite *minmea_suite(void)
     tcase_add_test(tc_parse, test_minmea_parse_gprmc1);
     tcase_add_test(tc_parse, test_minmea_parse_gprmc2);
     tcase_add_test(tc_parse, test_minmea_parse_gpgga1);
+    tcase_add_test(tc_parse, test_minmea_parse_gpgsa1);
     suite_add_tcase(s, tc_parse);
 
     TCase *tc_usage = tcase_create("minmea_usage");