Translating c code help required

Discussion in 'C Programming' started by lombardm, Sep 26, 2007.

  1. lombardm

    lombardm Guest

    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,LAT,HEMI,LON,HEMI,ALT,UNIT,NAME,MSG,ICON,CHKSUM,
    %META,ASCII
    $PMGNWPL,3137.54374,S,01914.37622,E,0,M,WPT001,,a*23
    $PMGNWPL,3122.18567,S,01906.50683,E,0,M,WPT002,,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:
    http://gpsbabel.cvs.sourceforge.net/*checkout*/gpsbabel/gpsbabel/magproto.c?revision=1.155

    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(const char * const buf)
    {
    int csum = 0;
    const char *p;

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

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

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

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

    retry:

    i = sprintf(obuf, "$%s*%02X\r\n",buf, osum);
    termwrite(obuf, i);
    if (magrxstate == mrs_handon || magrxstate == mrs_awaiting_ack) {
    magrxstate = mrs_awaiting_ack;
    mag_readmsg(trkdata);
    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");
    }
    }
    }
    }
    lombardm, Sep 26, 2007
    #1
    1. Advertising

  2. In article <>,
    lombardm <> wrote:
    >I understand everything except how the "a*23" at the end of the
    >line
    >is arrived at.


    >$PMGNWPL,3137.54374,S,01914.37622,E,0,M,WPT001,,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
    Walter Roberson, Sep 26, 2007
    #2
    1. Advertising

  3. lombardm

    Army1987 Guest

    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,LAT,HEMI,LON,HEMI,ALT,UNIT,NAME,MSG,ICON,CHKSUM,
    > %META,ASCII
    > $PMGNWPL,3137.54374,S,01914.37622,E,0,M,WPT001,,a*23
    > $PMGNWPL,3122.18567,S,01906.50683,E,0,M,WPT002,,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:
    > http://gpsbabel.cvs.sourceforge.net/*checkout*/gpsbabel/gpsbabel/magproto.c?revision=1.155
    >
    > 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(const 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(const 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(const char * const buf)
    > {
    > unsigned int osum = mag_checksum(buf);
    > int retry_cnt = 5;
    > int i;
    > char obuf[1000];
    >
    > if (debug_serial) {
    > warning("WRITE: $%s*%02X\r\n",buf, 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_ack) {

    Without knowing what these are I can't help...
    > magrxstate = mrs_awaiting_ack;
    > mag_readmsg(trkdata);
    > 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.
    Army1987, Sep 26, 2007
    #3
  4. lombardm

    lombardm Guest

    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(Inputline)
    Checksum = checksum + Chr(Mid(InputLine(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,LAT,HEMI,LON,HEMI,ALT,UNIT,NAME,MSG,ICON,CHKSUM,
    > > %META,ASCII
    > > $PMGNWPL,3137.54374,S,01914.37622,E,0,M,WPT001,,a*23
    > > $PMGNWPL,3122.18567,S,01906.50683,E,0,M,WPT002,,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:
    > > http://gpsbabel.cvs.sourceforge.net/*checkout*/gpsbabel/gpsbabel/magproto.c?revision=1.155
    > >
    > > 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(const 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(const 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(const char * const buf)
    > > {
    > > unsigned int osum = mag_checksum(buf);
    > > int retry_cnt = 5;
    > > int i;
    > > char obuf[1000];
    > >
    > > if (debug_serial) {
    > > warning("WRITE: $%s*%02X\r\n",buf, 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_ack) {

    > Without knowing what these are I can't help...
    > > magrxstate = mrs_awaiting_ack;
    > > mag_readmsg(trkdata);
    > > 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.
    lombardm, Sep 26, 2007
    #4
  5. lombardm <> writes:
    > 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,LAT,HEMI,LON,HEMI,ALT,UNIT,NAME,MSG,ICON,CHKSUM,
    >> > %META,ASCII
    >> > $PMGNWPL,3137.54374,S,01914.37622,E,0,M,WPT001,,a*23
    >> > $PMGNWPL,3122.18567,S,01906.50683,E,0,M,WPT002,,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(const 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(Inputline)
    > Checksum = checksum + Chr(Mid(InputLine(i,1))

    replace with:
    Checksum = checksum Xor Chr(Mid(InputLine(i,1))
    > Next i
    > HChecksum = Hex(Checksum)


    does it.

    --
    Ben.
    Ben Bacarisse, Sep 26, 2007
    #5
  6. lombardm

    lombardm Guest


    > 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
    lombardm, Sep 26, 2007
    #6
  7. lombardm

    CBFalconer Guest

    Walter Roberson wrote:
    > lombardm <> wrote:
    >

    .... 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
    CBFalconer, Sep 26, 2007
    #7
  8. lombardm

    CBFalconer Guest

    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
    CBFalconer, Sep 26, 2007
    #8
  9. lombardm

    Kevin Bagust Guest

    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,LAT,HEMI,LON,HEMI,ALT,UNIT,NAME,MSG,ICON,CHKSUM,
    > %META,ASCII
    > $PMGNWPL,3137.54374,S,01914.37622,E,0,M,WPT001,,a*23
    > $PMGNWPL,3122.18567,S,01906.50683,E,0,M,WPT002,,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.
    Kevin Bagust, Sep 26, 2007
    #9
  10. lombardm

    lombardm Guest

    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,LAT,HEMI,LON,HEMI,ALT,UNIT,NAME,MSG,ICON,CHKSUM,
    > > %META,ASCII
    > > $PMGNWPL,3137.54374,S,01914.37622,E,0,M,WPT001,,a*23
    > > $PMGNWPL,3122.18567,S,01906.50683,E,0,M,WPT002,,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.
    lombardm, Sep 27, 2007
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    5
    Views:
    411
  2. stax76
    Replies:
    3
    Views:
    495
    Jim Langston
    Aug 1, 2008
  3. Zach Dennis
    Replies:
    19
    Views:
    157
    Brian Candler
    Apr 14, 2005
  4. Kevin Tran

    Need help translating Ruby code

    Kevin Tran, Sep 9, 2008, in forum: Ruby
    Replies:
    1
    Views:
    101
    Glen Holcomb
    Sep 9, 2008
  5. Kamaljeet Saini
    Replies:
    2
    Views:
    145
    Kamaljeet Saini
    Jan 30, 2009
Loading...

Share This Page