Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C++ C Visual-Studio VC++
i have to send the following packet format to a machine:-
 
    byte     byte     bit         bit
                           2       2         1           1
                     +---------+-------+-------------+----------+
                     |  CM     |   00  |  check sum  |  CR      |
                     +---------+-------+-------------+----------+
 
I have the following instructions:-
 
All data isASCII character code without checksumand CR.
Calculate sum total from top till before checksum ( 1 bite unit ),then recognize this complement of 1 as checksum.
Finish of format is CR (Hexadecimal: OD)
 
So to implement this
i took
This is main .cpp
char data[6]="CM00";
typedef unsigned short int word16;
word16      check1;
int main()
{
int h=2;
check1 =calc_check(hh);
	data[4]= check1;
	data[5]=0x0D;
}
 
this is the file checksum .cpp
typedef unsigned char      byte;    // Byte is a char
typedef unsigned short int word16;  // 16-bit word is a short int
typedef unsigned int       word32;  // 32-bit word is an int

//----- Defines ---------------------------------------------------------------
#define BUFFER_LEN        6      // Length of buffer
extern char data[6];
 
word16      check;  
//----- Prototypes ------------------------------------------------------------
word16 checksum(char *addr, word32 count);
//int calc_check(int);
//===== Main program ==========================================================
int calc_check(int w)
{
	//byte        buff[BUFFER_LEN]; // Buffer of packet bytes

	// 16-bit checksum value
	word32      i;                // Loop counter

	// Load buffer with BUFFER_LEN random bytes
	for (i=0; i<BUFFER_LEN; i++)
	{
		//buff[i] = (byte) rand();
		data[i]=(byte) rand();
	}
 
	// Compute the 16-bit checksum
	//check = checksum(buff, BUFFER_LEN);
	check = checksum(data, BUFFER_LEN);
 
	// Output the checksum
	printf("checksum = %04X \n", check);
	return check;
 
}
 
//=============================================================================
//=  Compute Internet Checksum for count bytes beginning at location addr     =
//=============================================================================
word16 checksum(char *addr, word32 count)
{
	register word32 sum = 0;
	word16 * waddr = reinterpret_cast<word16*>(addr);//added
	// Main summing loop
	while(count > 1)
	{
		//sum = sum + *((word16 *) addr)++;//main
		sum = sum + *waddr++;
		//sum += *((word16 *) addr)++;
		count = count - 2;
	}
 
	// Add left-over byte, if any
	if (count > 0)
		sum = sum + *((byte *) addr);
 
	// Fold 32-bit sum to 16 bits
	while (sum>>16)
		sum = (sum & 0xFFFF) + (sum >> 16);
 
	return(~sum);
}
I think i am doing something wrong in checksum.cpp as i have given the statement
Calculate sum total from top till before checksum so acc to this statement i should do
for (i=0; i<2; i++)
    {
        //buff[i] = (byte) rand();
        data[i]=(byte) rand();
    }
Then am i doing this correct
 
data[4]= check1;
	data[5]=0x0D;
Posted 12-Sep-12 6:15am
Comments
armagedescu at 12-Sep-12 12:12pm
   
I am not sure that I understand your problem. Is it a problem of result calculated, or some other problem? As I understand, you are summing short int by short int. Is it correct? The result returned from checksum is short int and you assign that result to 1 byte integer. So, you lose 8 bits from checksum.
Tarun Batra at 13-Sep-12 2:09am
   
sir as u can see in the above packet format the check sum field is one bit,and i have done data[4]= check1; so is it correct?
armagedescu at 13-Sep-12 5:09am
   
No, you updated one byte, so it is eight bits, not one single.

1 solution

Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

No.
When you calculate your checksum, you overwrite everything in the buyffer, and then you are including all the characters in the message:
#define BUFFER_LEN        6      // Length of buffer
extern char data[6];
int calc_check(int w)
{
...
	// Load buffer with BUFFER_LEN random bytes
	for (i=0; i<BUFFER_LEN; i++)
	{
		data[i]=(byte) rand();
	}
 
	// Compute the 16-bit checksum
	check = checksum(data, BUFFER_LEN);
... 
}
Since the loop will overwrite the data you loaded before you called it.
Then you try to include the checksum byte in itself, and the CR terminator!
 
And that's ignoring that your code won't compile, because "h" and "hh" are not the same...
 

Why not hand the buffer and a length to the check routine, and have it return the check byte? If you did that, you could use the same function for incoming messages as well as outgoing...
  Permalink  
Comments
Tarun Batra at 13-Sep-12 2:05am
   
sir to avoid the loop to overwrite the data I loaded before I called it,i should do something like this:-for (i=0; i<4; i++)
{
//buff[i] = (byte) rand();
data[i]=(byte) rand();
} and then i should do data[4]= check1;
data[5]=0x0D; as i have the following statement "Calculate sum total from top till before check sum then recognize this
complement of 1 as check sum. Now am i correct?
OriginalGriff at 13-Sep-12 3:32am
   
No. Why the heck are you filling it with random data at all? All that does is overwrite whatever messgae you had to start with, and generates a check on the random rubbish!
Tarun Batra at 13-Sep-12 3:37am
   
yes air iyou are correct i should comment this part -for (i=0; i<4; i++)
{
//buff[i] = (byte) rand();
data[i]=(byte) rand();} and sir can u tell me one more thing?
OriginalGriff at 13-Sep-12 3:45am
   
It's not a case of commenting it - it probably shouldn't be there at all!
 
And what is the "other thing"?
Tarun Batra at 13-Sep-12 3:50am
   
Ya sir you are correct,just tell me please that in this statement "check = checksum(data, BUFFER_LEN);" in check variable i will be getting the checksum value and as u can see i have data part as "char data[6]="CM00";" so is it correct data[4]= check; and acc to statement Finish of format is CR (Hexadecimal: OD) i am doing "data[5]=0x0D;",,,are these both correct?
OriginalGriff at 13-Sep-12 4:06am
   
Almost - I wouldn't hand the BUFFER_LEN to the checksum function though. I would hand the length of the data in the buffer to be included in the checksum rather than the total size of the buffer.
 
In addition I would not play around with converting the char pointer to a word pointer - it may give unpredicable effects since char* data can be aligned on boundaries which may be illegal for word* data. Stick with char* instead.
Tarun Batra at 13-Sep-12 4:20am
   
sir i wanna show u my code,can i have your mail id or should i display here?And what about
"Finish of format is CR (Hexadecimal: OD)" would u say am i doing correct?
OriginalGriff at 13-Sep-12 4:33am
   
"can i have your mail id" - No :laugh:
I get enough Emails every day already!
 
"should i display here"
Relevant fragments, yes.
 
"would u say am i doing correct?" Yes - but I would use a #define instead of a "magic number".
#define FORMAT_TERMINATOR ((byte) 0x0D)
or similar. That way if you are wrong, or it changes later, it is easier to update the whole program.
Tarun Batra at 13-Sep-12 5:32am
   
char data[6]="CM00";check2=calc_check(hh);int calc_check(int w)
{word32 i; har buff[4];
for (i=0; i<4; i++)
{
buff[i]=data[i];
}
 
char check11=0;
check11 = checksum(buff, 4);return check11;
 
}word16 checksum(char *addr, word32 count)
{
register word32 sum = 0;
char sum1=0;
word16 * waddr = reinterpret_cast(addr);while(count > 1)
{sum1 = sum1 + *waddr++;count = count - 2;
}if (count > 0)
sum1= sum1 + *((byte *) addr);while (sum1>>24)
sum1 = (sum1 & 0xFFFF) + (sum1 >> 24);
printf("size of sum1 is %d\n",sizeof(sum1));
return(~sum1);}data[4]= check2;data[5]=FORMAT_TERMINATOR Please check now and tell me the changes
OriginalGriff at 13-Sep-12 5:47am
   
Do you have a major wish to complicate things? :laugh:
char checksum(char* addr, int count)
{
char sum = 0;
while (count-- > 0)
{
sum += *addr++;
}
// Not sure what this bit is all about.
}
 
Your checksum calculation code looks very odd - you accumulate a sum in a char (8 bits long) and then try to "fold" it as a 32 bit quantity (so using 24 bits which don't actually exist, and which will all be sign extended to 1 or 0).
 
Do you have a description of your checksum calculation, because your text in the question is a bit...well...rubbish?
Tarun Batra at 13-Sep-12 5:50am
   
I was trying to calculate the acc to this http://tools.ietf.org/rfc/rfc1071.txt,as if u have any code for standard check sum please give as i have to try many check sum algo.
OriginalGriff at 13-Sep-12 13:59pm
   
Are you sure that is the right checksum calculator?
It's kind of old, and it generates a 16 bit result which you need to fit into an 8 bit field...
Tarun Batra at 14-Sep-12 1:55am
   
Can u tell how to convert it into 8bit field?
OriginalGriff at 14-Sep-12 3:32am
   
You can't - the algorithm is for a 16 bit checksum, not a 8. If you "convert it to 8 bit" then it is not the correct checksum for teh algorithm.
 
I suspect that you want a different checksum method - and there are loads of them - probably either a simple sum, or an exclusive OR which are the simplest, and most common. Do you have a specification for the device you are trying to interface with? It should give you all the details, not rely on a 24 year old document that may or may not be relevant! :laugh:

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 DamithSL 320
1 OriginalGriff 275
2 Sergey Alexandrovich Kryukov 187
3 Afzaal Ahmad Zeeshan 154
4 Peter Leow 115
0 OriginalGriff 7,510
1 DamithSL 5,494
2 Sergey Alexandrovich Kryukov 4,954
3 Maciej Los 4,936
4 Kornfeld Eliyahu Peter 4,514


Advertise | Privacy | Mobile
Web01 | 2.8.141223.1 | Last Updated 12 Sep 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100