Translating c code help required

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • lombardm

    #1

    Translating c code help required

    I am trying to decipher/translate some code that I have no experience
    with.

    I am trying to find out how the checksum is computed for a Megellan
    Explorist GPS Waypoint (POI) file. Below is the first 3 lines of a
    typical
    file. I understand everything except how the "a*23" at the end of the
    line
    is arrived at.

    $PMGNFMT,%WPL,L AT,HEMI,LON,HEM I,ALT,UNIT,NAME ,MSG,ICON,CHKSU M,
    %META,ASCII
    $PMGNWPL,3137.5 4374,S,01914.37 622,E,0,M,WPT00 1,,a*23
    $PMGNWPL,3122.1 8567,S,01906.50 683,E,0,M,WPT00 2,,a*21

    Below is an extract of the code for a program that generates lines
    like the above and calculates the checksum
    (It looks like the relevant section). The full code can be found here:
    Download GPSBabel for free. GPSBabel converts and transfers data like waypoints, tracks & routes. ** This site is of historical interest only. The project is active on www.gpsbabel.org and github.


    The code is in C of which I understand nothing. My only experience at
    this
    stage is Excel VBA. Can someone please explain in plain text (or VBA)
    how
    the checksum is calculated.

    Many thanks
    Laurence


    /*
    * Given a protocol message, compute the checksum as needed by
    * the Magellan protocol.
    */
    unsigned int
    mag_checksum(co nst char * const buf)
    {
    int csum = 0;
    const char *p;

    for(p = buf; *p; p++) {
    csum ^= *p;
    }

    return csum;
    }
    static unsigned int
    mag_pchecksum(c onst char * const buf, int len)
    {
    int csum = 0;
    const char *p = buf;
    for (; len ; len--) {
    csum ^= *p++;
    }
    return csum;
    }

    static void
    mag_writemsg(co nst char * const buf)
    {
    unsigned int osum = mag_checksum(bu f);
    int retry_cnt = 5;
    int i;
    char obuf[1000];

    if (debug_serial) {
    warning("WRITE: $%s*%02X\r\n",b uf, osum);
    }

    retry:

    i = sprintf(obuf, "$%s*%02X\r\n", buf, osum);
    termwrite(obuf, i);
    if (magrxstate == mrs_handon || magrxstate == mrs_awaiting_ac k) {
    magrxstate = mrs_awaiting_ac k;
    mag_readmsg(trk data);
    if (last_rx_csum != osum) {
    if (debug_serial) {
    warning("COMM ERROR: Expected %02x, got %02x",
    osum, last_rx_csum);
    }
    if (retry_cnt--)
    goto retry;
    else {
    mag_handoff();
    fatal(MYNAME
    ": Too many communication errors.\n");
    }
    }
    }
    }

  • Walter Roberson

    #2
    Re: Translating c code help required

    In article <1190786469.669 276.131850@57g2 000hsv.googlegr oups.com>,
    lombardm <lombardm@mweb. co.zawrote:
    >I understand everything except how the "a*23" at the end of the
    >line
    >is arrived at.
    >$PMGNWPL,3137. 54374,S,01914.3 7622,E,0,M,WPT0 01,,a*23
    >Can someone please explain in plain text (or VBA) how
    >the checksum is calculated.
    int csum = 0;
    Start the checksum at 0.
    const char *p;
    for(p = buf; *p; p++) {
    Loop over every character in the buffer until you get to the end
    of the string (which is marked by a character which is binary 0)
    csum ^= *p;
    xor each character into the checksum.

    Because xor never creates new "on" bits where everything used
    to be "off", this the result will never be more than one character
    wide. That one character is later printed in hexadecimal.
    --
    Okay, buzzwords only. Two syllables, tops. -- Laurie Anderson

    Comment

    • Army1987

      #3
      Re: Translating c code help required

      On Tue, 25 Sep 2007 23:01:09 -0700, lombardm wrote:
      I am trying to decipher/translate some code that I have no experience
      with.
      >
      I am trying to find out how the checksum is computed for a Megellan
      Explorist GPS Waypoint (POI) file. Below is the first 3 lines of a
      typical
      file. I understand everything except how the "a*23" at the end of the
      line
      is arrived at.
      >
      $PMGNFMT,%WPL,L AT,HEMI,LON,HEM I,ALT,UNIT,NAME ,MSG,ICON,CHKSU M,
      %META,ASCII
      $PMGNWPL,3137.5 4374,S,01914.37 622,E,0,M,WPT00 1,,a*23
      $PMGNWPL,3122.1 8567,S,01906.50 683,E,0,M,WPT00 2,,a*21
      >
      Below is an extract of the code for a program that generates lines
      like the above and calculates the checksum
      (It looks like the relevant section). The full code can be found here:
      Download GPSBabel for free. GPSBabel converts and transfers data like waypoints, tracks & routes. ** This site is of historical interest only. The project is active on www.gpsbabel.org and github.

      >
      The code is in C of which I understand nothing. My only experience at
      this
      stage is Excel VBA. Can someone please explain in plain text (or VBA)
      how
      the checksum is calculated.
      >
      Many thanks
      Laurence
      >
      >
      /*
      * Given a protocol message, compute the checksum as needed by
      * the Magellan protocol.
      */
      unsigned int
      mag_checksum(co nst char * const buf)
      {
      int csum = 0;
      const char *p;
      >
      for(p = buf; *p; p++) {
      csum ^= *p;
      }
      >
      return csum;
      }
      This is the bitwise exclusive-or of the values of characters in
      buf.
      static unsigned int
      mag_pchecksum(c onst char * const buf, int len)
      {
      int csum = 0;
      const char *p = buf;
      for (; len ; len--) {
      (I don't get why on earth len is signed; what happens if is
      negative? What's wrong with while (len--) where len is a size_t?
      csum ^= *p++;
      }
      return csum;
      Ditto as above, but it stops after len characters instead of at
      the first null.
      }
      >
      static void
      mag_writemsg(co nst char * const buf)
      {
      unsigned int osum = mag_checksum(bu f);
      int retry_cnt = 5;
      int i;
      char obuf[1000];
      >
      if (debug_serial) {
      warning("WRITE: $%s*%02X\r\n",b uf, osum);
      }
      >
      retry:
      >
      i = sprintf(obuf, "$%s*%02X\r\n", buf, osum);
      It writes "$", the contents of buf, osum as two hex digits, a
      carriage return and a line feed to obuf.
      termwrite(obuf, i);
      I guess it writes obuf somewhere.
      if (magrxstate == mrs_handon || magrxstate == mrs_awaiting_ac k) {
      Without knowing what these are I can't help...
      magrxstate = mrs_awaiting_ac k;
      mag_readmsg(trk data);
      if (last_rx_csum != osum) {
      if (debug_serial) {
      warning("COMM ERROR: Expected %02x, got %02x",
      osum, last_rx_csum);
      }
      if (retry_cnt--)
      goto retry;
      (*cough cough* Hasn't anybody told them 'bout do {} while()? )
      else {
      mag_handoff();
      fatal(MYNAME
      ": Too many communication errors.\n");
      }
      }
      }
      }
      --
      Army1987 (Replace "NOSPAM" with "email")
      A hamburger is better than nothing.
      Nothing is better than eternal happiness.
      Therefore, a hamburger is better than eternal happiness.

      Comment

      • lombardm

        #4
        Re: Translating c code help required

        Sorry folks - I know NOTHING about C and all your replies are Greek to
        me.

        I hoping for a bit of pseudo VBA code like the following (in my
        example code the Ascii cvalues of the individual characters of
        InputLine are added together and converted to hexadecimal)

        Checksum = 0
        For i = 1 to length(Inputlin e)
        Checksum = checksum + Chr(Mid(InputLi ne(i,1))
        Next i
        HChecksum = Hex(Checksum)

        Thanks
        Laurence


        Army1987 wrote:
        On Tue, 25 Sep 2007 23:01:09 -0700, lombardm wrote:
        >
        I am trying to decipher/translate some code that I have no experience
        with.

        I am trying to find out how the checksum is computed for a Megellan
        Explorist GPS Waypoint (POI) file. Below is the first 3 lines of a
        typical
        file. I understand everything except how the "a*23" at the end of the
        line
        is arrived at.

        $PMGNFMT,%WPL,L AT,HEMI,LON,HEM I,ALT,UNIT,NAME ,MSG,ICON,CHKSU M,
        %META,ASCII
        $PMGNWPL,3137.5 4374,S,01914.37 622,E,0,M,WPT00 1,,a*23
        $PMGNWPL,3122.1 8567,S,01906.50 683,E,0,M,WPT00 2,,a*21

        Below is an extract of the code for a program that generates lines
        like the above and calculates the checksum
        (It looks like the relevant section). The full code can be found here:
        Download GPSBabel for free. GPSBabel converts and transfers data like waypoints, tracks & routes. ** This site is of historical interest only. The project is active on www.gpsbabel.org and github.


        The code is in C of which I understand nothing. My only experience at
        this
        stage is Excel VBA. Can someone please explain in plain text (or VBA)
        how
        the checksum is calculated.

        Many thanks
        Laurence


        /*
        * Given a protocol message, compute the checksum as needed by
        * the Magellan protocol.
        */
        unsigned int
        mag_checksum(co nst char * const buf)
        {
        int csum = 0;
        const char *p;

        for(p = buf; *p; p++) {
        csum ^= *p;
        }

        return csum;
        }
        This is the bitwise exclusive-or of the values of characters in
        buf.
        >
        static unsigned int
        mag_pchecksum(c onst char * const buf, int len)
        {
        int csum = 0;
        const char *p = buf;
        for (; len ; len--) {
        (I don't get why on earth len is signed; what happens if is
        negative? What's wrong with while (len--) where len is a size_t?
        csum ^= *p++;
        }
        return csum;
        Ditto as above, but it stops after len characters instead of at
        the first null.
        }

        static void
        mag_writemsg(co nst char * const buf)
        {
        unsigned int osum = mag_checksum(bu f);
        int retry_cnt = 5;
        int i;
        char obuf[1000];

        if (debug_serial) {
        warning("WRITE: $%s*%02X\r\n",b uf, osum);
        }

        retry:

        i = sprintf(obuf, "$%s*%02X\r\n", buf, osum);
        It writes "$", the contents of buf, osum as two hex digits, a
        carriage return and a line feed to obuf.
        termwrite(obuf, i);
        I guess it writes obuf somewhere.
        if (magrxstate == mrs_handon || magrxstate == mrs_awaiting_ac k) {
        Without knowing what these are I can't help...
        magrxstate = mrs_awaiting_ac k;
        mag_readmsg(trk data);
        if (last_rx_csum != osum) {
        if (debug_serial) {
        warning("COMM ERROR: Expected %02x, got %02x",
        osum, last_rx_csum);
        }
        if (retry_cnt--)
        goto retry;
        (*cough cough* Hasn't anybody told them 'bout do {} while()? )
        else {
        mag_handoff();
        fatal(MYNAME
        ": Too many communication errors.\n");
        }
        }
        }
        }
        >
        --
        Army1987 (Replace "NOSPAM" with "email")
        A hamburger is better than nothing.
        Nothing is better than eternal happiness.
        Therefore, a hamburger is better than eternal happiness.

        Comment

        • Ben Bacarisse

          #5
          Re: Translating c code help required

          lombardm <lombardm@mweb. co.zawrites:
          Army1987 wrote:
          >On Tue, 25 Sep 2007 23:01:09 -0700, lombardm wrote:
          >>
          I am trying to decipher/translate some code that I have no experience
          with.
          >
          I am trying to find out how the checksum is computed for a Megellan
          Explorist GPS Waypoint (POI) file. Below is the first 3 lines of a
          typical
          file. I understand everything except how the "a*23" at the end of the
          line
          is arrived at.
          >
          $PMGNFMT,%WPL,L AT,HEMI,LON,HEM I,ALT,UNIT,NAME ,MSG,ICON,CHKSU M,
          %META,ASCII
          $PMGNWPL,3137.5 4374,S,01914.37 622,E,0,M,WPT00 1,,a*23
          $PMGNWPL,3122.1 8567,S,01906.50 683,E,0,M,WPT00 2,,a*21
          >
          Below is an extract of the code for a program that generates lines
          like the above and calculates the checksum
          <snip>
          unsigned int
          mag_checksum(co nst char * const buf)
          {
          int csum = 0;
          const char *p;
          >
          for(p = buf; *p; p++) {
          csum ^= *p;
          }
          >
          return csum;
          }
          >This is the bitwise exclusive-or of the values of characters in
          >buf.
          <snip>
          >
          Sorry folks - I know NOTHING about C and all your replies are Greek to
          me.
          Please don't top post. You should interleave you reply and trim any
          material not required.
          I hoping for a bit of pseudo VBA code like the following (in my
          example code the Ascii cvalues of the individual characters of
          InputLine are added together and converted to hexadecimal)
          The reply you got said it in English. Surely you can turn that into
          VBA? If not, then this is not the right place to ask. Take the
          snipped of C and the line that says what it does ("exclusive or" is the
          key bit) and post that to a VBA group. They can then do the translation.

          .... although it is possible that:
          Checksum = 0
          For i = 1 to length(Inputlin e)
          Checksum = checksum + Chr(Mid(InputLi ne(i,1))
          replace with:
          Checksum = checksum Xor Chr(Mid(InputLi ne(i,1))
          Next i
          HChecksum = Hex(Checksum)
          does it.

          --
          Ben.

          Comment

          • lombardm

            #6
            Re: Translating c code help required

            Please don't top post. You should interleave you reply and trim any
            material not required.
            Thanks for your reply. My apologies for not adhering to protocol.
            Laurence

            Comment

            • CBFalconer

              #7
              Re: Translating c code help required

              Walter Roberson wrote:
              lombardm <lombardm@mweb. co.zawrote:
              >
              .... snip ...
              >
              >Can someone please explain in plain text (or VBA) how
              >the checksum is calculated.
              >
              Start the checksum at 0.
              >
              >const char *p;
              >
              >for(p = buf; *p; p++) {
              >
              Loop over every character in the buffer until you get to the end
              of the string (which is marked by a character which is binary 0)
              >
              > csum ^= *p;
              >
              xor each character into the checksum.
              >
              Because xor never creates new "on" bits where everything used
              to be "off", this the result will never be more than one character
              wide. That one character is later printed in hexadecimal.
              Or other mechanisms.

              --
              Chuck F (cbfalconer at maineline dot net)
              Available for consulting/temporary embedded and systems.
              <http://cbfalconer.home .att.net>



              --
              Posted via a free Usenet account from http://www.teranews.com

              Comment

              • CBFalconer

                #8
                Re: Translating c code help required

                lombardm wrote:
                >
                Sorry folks - I know NOTHING about C and all your replies are
                Greek to me.
                >
                I hoping for a bit of pseudo VBA code like the following (in my
                example code the Ascii cvalues of the individual characters of
                InputLine are added together and converted to hexadecimal)
                Don't top-post. That has lost all the history. So I (and others)
                have no idea what the thread is really about.

                --
                Chuck F (cbfalconer at maineline dot net)
                Available for consulting/temporary embedded and systems.
                <http://cbfalconer.home .att.net>



                --
                Posted via a free Usenet account from http://www.teranews.com

                Comment

                • Kevin Bagust

                  #9
                  Re: Translating c code help required

                  lombardm wrote:
                  I am trying to decipher/translate some code that I have no experience
                  with.
                  >
                  I am trying to find out how the checksum is computed for a Megellan
                  Explorist GPS Waypoint (POI) file. Below is the first 3 lines of a
                  typical
                  file. I understand everything except how the "a*23" at the end of the
                  line
                  is arrived at.
                  >
                  $PMGNFMT,%WPL,L AT,HEMI,LON,HEM I,ALT,UNIT,NAME ,MSG,ICON,CHKSU M,
                  %META,ASCII
                  $PMGNWPL,3137.5 4374,S,01914.37 622,E,0,M,WPT00 1,,a*23
                  $PMGNWPL,3122.1 8567,S,01906.50 683,E,0,M,WPT00 2,,a*21
                  These are NMEA 0183 messages. If you do a web search for NMEA checksum
                  VB you should find examples how to calculate them using VB.

                  Kevin.

                  Comment

                  • lombardm

                    #10
                    Re: Translating c code help required


                    Kevin Bagust wrote:
                    lombardm wrote:
                    I am trying to decipher/translate some code that I have no experience
                    with.

                    I am trying to find out how the checksum is computed for a Megellan
                    Explorist GPS Waypoint (POI) file. Below is the first 3 lines of a
                    typical
                    file. I understand everything except how the "a*23" at the end of the
                    line
                    is arrived at.
                    >
                    $PMGNFMT,%WPL,L AT,HEMI,LON,HEM I,ALT,UNIT,NAME ,MSG,ICON,CHKSU M,
                    %META,ASCII
                    $PMGNWPL,3137.5 4374,S,01914.37 622,E,0,M,WPT00 1,,a*23
                    $PMGNWPL,3122.1 8567,S,01906.50 683,E,0,M,WPT00 2,,a*21
                    >
                    These are NMEA 0183 messages. If you do a web search for NMEA checksum
                    VB you should find examples how to calculate them using VB.
                    Thank you very much - this is exactly what I am looking for - found
                    the solution right away and it works. Thought the information was out
                    there - just need to find it!
                    Thanks once again
                    >
                    Kevin.

                    Comment

                    Working...