Add server tcp api.
[bertos.git] / bertos / net / nmea.c
index fdf6b174bbdaf09bb45b550481a6a206ee66bb1b..f74879523e9bcf2f543c1520efc4e374e39e19af 100644 (file)
 #include <string.h>
 #include <stdlib.h>
 
-
+/*
+ * Make conversion from one string to int.
+ *
+ * You can specify the precision if the string is a float
+ * number. The result is an int multiplied to 10^precision.
+ */
 static uint32_t tokenToInt(const char *s, int precision)
 {
        uint32_t num = 0;
@@ -79,7 +84,7 @@ static uint32_t tokenToInt(const char *s, int precision)
 
        for(i = 0; i < NMEAP_MAX_SENTENCE_LENGTH; i++)
        {
-               char c = *s++;
+               unsigned char c = *s++;
 
                if (c == '.')
                {
@@ -103,6 +108,9 @@ static uint32_t tokenToInt(const char *s, int precision)
        return num;
 }
 
+/*
+ * Convert a string to micro degree.
+ */
 static udegree_t convertToDegree(const char *str)
 {
        uint32_t dec;
@@ -110,9 +118,7 @@ static udegree_t convertToDegree(const char *str)
        uint32_t min;
 
        if (*str == 0)
-       {
-        return 0;
-    }
+               return 0;
 
        dec = tokenToInt(str, 4);
        deg = dec / 1000000;
@@ -122,63 +128,70 @@ static udegree_t convertToDegree(const char *str)
        return dec;
 }
 
+/*
+ * Retun latitude in micro degree from a string.
+ */
 static udegree_t nmea_latitude(const char *plat, const char *phem)
 {
        int ns;
 
-    if (*phem == 0)
-        return 0;
+       if (*phem == 0)
+               return 0;
 
-    /* north lat is +, south lat is - */
-    if (*phem == 'N')
-        ns = 1;
-    else
-        ns = -1;
+       /* north lat is +, south lat is - */
+       ns = (*phem == 'N') ? 1 : -1;
 
 
        return ns * convertToDegree(plat);
 }
 
+/*
+ * Retun longitude in micro degree from a string.
+ */
 static udegree_t nmea_longitude(const char *plot, const char *phem)
 {
        int ew;
 
-    if (*phem == 0)
-        return 0;
+       if (*phem == 0)
+               return 0;
 
-    /* west long is negative, east long is positive */
-    if (*phem == 'E')
-        ew = 1;
-    else
-        ew = -1;
+       /* west long is negative, east long is positive */
+       ew = (*phem == 'E') ? 1 : -1;
 
        return ew * convertToDegree(plot);
 }
 
-static uint16_t nmea_altitude(const char *palt, const char *punits)
+/*
+ * Return altitude in meter from a string.
+ *
+ */
+static int32_t nmea_altitude(const char *palt, const char *punits)
 {
-       uint32_t alt;
+       int32_t alt;
 
        if (*palt == 0)
-        return 0;
+               return 0;
 
        alt = atoi(palt);
 
-    if (*punits == 'F')
+       if (*punits == 'F')
        {
-        /* convert to feet */
-        /* alt = alt * 3.2808399 */
+               /* convert to feet */
+               /* alt = alt * 3.2808399 */
                alt = alt * 3 +  /* 3.0 */
-                         (alt >> 2) + /* 0.25 */
-                         (alt >> 6) + /* 0.015625 */
-                         (alt >> 7) + /* 0.0078125 */
-                         (alt >> 8); /* 0,00390625 */
+                       (alt >> 2) + /* 0.25 */
+                       (alt >> 6) + /* 0.015625 */
+                       (alt >> 7) + /* 0.0078125 */
+                       (alt >> 8); /* 0,00390625 */
 
-    }
+       }
 
        return alt;
 }
 
+/*
+ * Convert time and date stamp string to unix time.
+ */
 static time_t timestampToSec(uint32_t time_stamp, uint32_t date_stamp)
 {
        struct tm t;
@@ -206,7 +219,7 @@ static time_t timestampToSec(uint32_t time_stamp, uint32_t date_stamp)
        t.tm_sec = tmr[0] + (ROUND_UP(msec, 1000) / 1000);
        t.tm_min = tmr[1];
        t.tm_hour = tmr[2];
-       //If we not have refence data, we set as default 1/1/1970.
+       //If we do not have refence data, we set 1/1/1970 as default
        t.tm_mday = 1;
        t.tm_mon = 0;
        t.tm_year = 70;
@@ -223,8 +236,8 @@ static time_t timestampToSec(uint32_t time_stamp, uint32_t date_stamp)
                }
                t.tm_mday = date[2];
                t.tm_mon = date[1] - 1; // time struct count month from 0 to 11;
-               // we should specific number of years from 1900, but the year field
-               // is only two cipher, so we sum 100 (2000 - 1900)..
+               // we should specify the number of years from 1900, but the year field
+               // is only two digits, so we add 100 (2000 - 1900)..
                t.tm_year = date[0] + 100;
        }
        LOG_INFO("times=%d,%d,%d,%d,%d,%d\n",t.tm_sec, t.tm_min, t.tm_hour, t.tm_year, t.tm_mon, t.tm_mday);
@@ -239,17 +252,19 @@ void gpgga_callout(nmeap_context_t *context, void *data, void *user_data)
 {
        (void)context;
        (void)user_data;
-       NmeaGga *gga = (NmeaGga *)data;
-
-    LOG_INFO("Found GPGGA message %ld %ld %d %lu %d %d %d %d\n",
-            (long)gga->latitude,
-            (long)gga->longitude,
-            gga->altitude,
-            gga->time,
-            gga->satellites,
-            gga->quality,
-            gga->hdop,
-            gga->geoid);
+       (void)data;
+       LOG_INFOB(
+               NmeaGga *gga = (NmeaGga *)data;
+               LOG_INFO("Found GPGGA message %ld %ld %d %lu %d %d %d %d\n",
+                       (long)gga->latitude,
+                       (long)gga->longitude,
+                       gga->altitude,
+                       gga->time,
+                       gga->satellites,
+                       gga->quality,
+                       gga->hdop,
+                       gga->geoid);
+       );
 }
 
 /**
@@ -259,16 +274,19 @@ void gprmc_callout(nmeap_context_t *context, void *data, void *user_data)
 {
        (void)context;
        (void)user_data;
-    NmeaRmc *rmc = (NmeaRmc *)data;
-
-       LOG_INFO("Found GPRMC message %lu %c %ld %ld %d %d %d\n",
-            rmc->time,
-            rmc->warn,
-            (long)rmc->latitude,
-            (long)rmc->longitude,
-            rmc->speed,
-            rmc->course,
-            rmc->mag_var);
+       (void)data;
+       LOG_INFOB(
+               NmeaRmc *rmc = (NmeaRmc *)data;
+
+               LOG_INFO("Found GPRMC message %lu %c %ld %ld %d %d %d\n",
+                       rmc->time,
+                       rmc->warn,
+                       (long)rmc->latitude,
+                       (long)rmc->longitude,
+                       rmc->speed,
+                       rmc->course,
+                       rmc->mag_var);
+       );
 }
 
 /**
@@ -278,12 +296,15 @@ void gpgsv_callout(nmeap_context_t *context, void *data, void *user_data)
 {
        (void)context;
        (void)user_data;
-       NmeaGsv *gsv = (NmeaGsv *)data;
+       (void)data;
+       LOG_INFOB(
+               NmeaGsv *gsv = (NmeaGsv *)data;
 
-    LOG_INFO("Found GPGSV message %d %d %d\n", gsv->tot_message, gsv->message_num, gsv->tot_svv);
+               LOG_INFO("Found GPGSV message %d %d %d\n", gsv->tot_message, gsv->message_num, gsv->tot_svv);
 
-       for (int i = 0; i < 4; i++)
-           LOG_INFO("%d %d %d %d\n", gsv->info[i].sv_prn, gsv->info[i].elevation, gsv->info[i].azimut, gsv->info[i].snr);
+               for (int i = 0; i < 4; i++)
+                       LOG_INFO("%d %d %d %d\n", gsv->info[i].sv_prn, gsv->info[i].elevation, gsv->info[i].azimut, gsv->info[i].snr);
+       );
 }
 
 /**
@@ -293,9 +314,11 @@ void gpvtg_callout(nmeap_context_t *context, void *data, void *user_data)
 {
        (void)context;
        (void)user_data;
-       NmeaVtg *vtg = (NmeaVtg *)data;
-
-    LOG_INFO("Found GPVTG message %d %d %d\n", vtg->track_good,        vtg->knot_speed, vtg->km_speed);
+       (void)data;
+       LOG_INFOB(
+               NmeaVtg *vtg = (NmeaVtg *)data;
+               LOG_INFO("Found GPVTG message %d %d %d\n", vtg->track_good,     vtg->knot_speed, vtg->km_speed);
+       );
 }
 
 
@@ -338,10 +361,10 @@ int nmea_gpgga(nmeap_context_t *context, nmeap_sentence_t *sentence)
 int nmea_gprmc(nmeap_context_t *context, nmeap_sentence_t *sentence)
 {
 
-    /*
+       /*
         * get pointer to sentence data
         */
-    NmeaRmc *rmc = (NmeaRmc *)sentence->data;
+       NmeaRmc *rmc = (NmeaRmc *)sentence->data;
 
        ASSERT(rmc);
        ASSERT(context->tokens >= 10);
@@ -357,10 +380,10 @@ int nmea_gprmc(nmeap_context_t *context, nmeap_sentence_t *sentence)
        rmc->course     = atoi(context->token[8]);
        rmc->mag_var    = atoi(context->token[10]);
 
-    if (sentence->callout != 0)
-        (*sentence->callout)(context, rmc, context->user_data);
+       if (sentence->callout != 0)
+               (*sentence->callout)(context, rmc, context->user_data);
 
-    return NMEA_GPRMC;
+       return NMEA_GPRMC;
 }
 
 
@@ -370,10 +393,10 @@ int nmea_gprmc(nmeap_context_t *context, nmeap_sentence_t *sentence)
 int nmea_gpvtg(nmeap_context_t *context, nmeap_sentence_t *sentence)
 {
 
-    /*
+       /*
         * get pointer to sentence data
         */
-    NmeaVtg *vtg = (NmeaVtg *)sentence->data;
+       NmeaVtg *vtg = (NmeaVtg *)sentence->data;
 
        ASSERT(vtg);
        ASSERT(context->tokens >= 7);
@@ -385,13 +408,13 @@ int nmea_gpvtg(nmeap_context_t *context, nmeap_sentence_t *sentence)
        vtg->knot_speed  = atoi(context->token[5]);
        vtg->km_speed    = atoi(context->token[7]);
 
-    /*
+       /*
         * if the sentence has a callout, call it
         */
-    if (sentence->callout != 0)
-        (*sentence->callout)(context, vtg, context->user_data);
+       if (sentence->callout != 0)
+               (*sentence->callout)(context, vtg, context->user_data);
 
-    return NMEA_GPVTG;
+       return NMEA_GPVTG;
 }
 
 /**
@@ -399,11 +422,10 @@ int nmea_gpvtg(nmeap_context_t *context, nmeap_sentence_t *sentence)
  */
 int nmea_gpgsv(nmeap_context_t *context, nmeap_sentence_t *sentence)
 {
-
-    /*
+       /*
         * get pointer to sentence data
         */
-    NmeaGsv *gsv = (NmeaGsv *)sentence->data;
+       NmeaGsv *gsv = (NmeaGsv *)sentence->data;
 
 
        /*
@@ -424,21 +446,29 @@ int nmea_gpgsv(nmeap_context_t *context, nmeap_sentence_t *sentence)
                gsv->info[j].snr        = atoi(context->token[i + 3]);
        }
 
-    /*
+       /*
         * if the sentence has a callout, call it
         */
-    if (sentence->callout != 0)
-        (*sentence->callout)(context, gsv, context->user_data);
+       if (sentence->callout != 0)
+               (*sentence->callout)(context, gsv, context->user_data);
 
-    return NMEA_GPGSV;
+       return NMEA_GPGSV;
 }
 
+
+/**
+ * Parse NMEA sentence from a channel.
+ */
 void nmea_poll(nmeap_context_t *context, KFile *channel)
 {
-       int c;
+       int c, e;
        while ((c = kfile_getc(channel)) != EOF)
-       {
                nmeap_parse(context, c);
+
+       if ((e = kfile_error(channel)))
+       {
+               LOG_ERR("ch error [%0X]\n", e);
+               kfile_clearerr(channel);
        }
 }