Translating c code help required

L

lombardm

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");
}
}
}
}
 
W

Walter Roberson

I understand everything except how the "a*23" at the end of the
line
is arrived at.

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.
 
A

Army1987

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()? )
 
L

lombardm

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

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.
 
B

Ben Bacarisse

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.
 
L

lombardm

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
 
C

CBFalconer

Walter said:
.... snip ...


Start the checksum at 0.



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)


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.
 
C

CBFalconer

lombardm said:
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.
 
K

Kevin Bagust

lombardm said:
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.
 
L

lombardm

Kevin said:
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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top