Welcome, Guest. Please login or register.

Author Topic: C++ - sending hex bytes to a socket  (Read 5533 times)

Description:

0 Members and 1 Guest are viewing this topic.

Offline motorollinTopic starter

  • Hero Member
  • *****
  • Join Date: Nov 2005
  • Posts: 8669
C++ - sending hex bytes to a socket
« on: June 01, 2008, 07:30:13 PM »
I have decided to rewrite my RFXCOM (home automation) controller in C++, as the virtual serial ports redirected to TCP/IP turned out to be a bit unstable.

I have used a Berkeley Sockets example to get a test app connected to the RFXCOM, and it works. I now want to try sending a command to it to turn something on or off. The device takes its commands in hex bytes, but I have no idea how to create an array of hex digits to pass to send().

In Applescript I converted the hex digits to decimal, then created a string of ASCII characters from the binary numbers (e.g. 0x21 = decimal 33 = ASCII char "!"). I then sent this string of ASCII to the device. Can this be done in C++ if I can't send the hex digits directly?

--
moto
Code: [Select]
10  IT\'S THE FINAL COUNTDOWN
20  FOR C = 1 TO 2
30     DA-NA-NAAAA-NAAAA DA-NA-NA-NA-NAAAA
40     DA-NA-NAAAA-NAAAA DA-NA-NA-NA-NA-NA-NAAAAA
50  NEXT C
60  NA-NA-NAAAA
70  NA-NA NA-NA-NA-NA-NAAAA NAAA-NAAAAAAAAAAA
80  GOTO 10
 

Offline motorollinTopic starter

  • Hero Member
  • *****
  • Join Date: Nov 2005
  • Posts: 8669
Re: C++ - sending hex bytes to a socket
« Reply #1 on: June 02, 2008, 08:01:37 AM »
Sorted :-) I wanted to see what was actually being sent, so I found an example of an IP server which receives data from a client and prints it to cout. I connected my RFXCOM test app to it and noticed that the data being sent was correct, but there were a few extra bytes at the end. So I changed my send() routine to send a specific number of bytes rather than trying to calculate the size of the buffer. When I ran it, I got exactly the data I wanted coming in to the server. Here is the code which worked:

//Send data to RFXCOM
   buf[0] = 0x21;
   buf[1] = 0x00;
   buf[2] = 0xBB;
   buf[3] = 0x80;
   buf[4] = 0x9B;
   buf[5] = 0x00;
   
   if (send(socketDescriptor, buf, 6, 0) < 0) {
      printf("cannot send data ");
      close(socketDescriptor);
      exit(1);
   }



The data in the buffer in that example should turn my kitchen light on. When I sent it to the RFXCOM, it worked - once. It has never worked again. This is very annoying :roll:

--
moto
Code: [Select]
10  IT\'S THE FINAL COUNTDOWN
20  FOR C = 1 TO 2
30     DA-NA-NAAAA-NAAAA DA-NA-NA-NA-NAAAA
40     DA-NA-NAAAA-NAAAA DA-NA-NA-NA-NA-NA-NAAAAA
50  NEXT C
60  NA-NA-NAAAA
70  NA-NA NA-NA-NA-NA-NAAAA NAAA-NAAAAAAAAAAA
80  GOTO 10
 

Offline motorollinTopic starter

  • Hero Member
  • *****
  • Join Date: Nov 2005
  • Posts: 8669
Re: C++ - sending hex bytes to a socket
« Reply #2 on: June 02, 2008, 08:31:23 AM »
Ok, I think I might have found the problem with sending the data. If I send a string of hex with a 0x00 as one of the bytes, it stops receiving the rest. Well, when I say it stops receiving it, I can't see it. Here's an example. The client sends this buffer:

buf[0] = 0x21;
buf[1] = 0x00;
buf[2] = 0x21;
buf[3] = 0x21;
buf[4] = 0x21;
buf[5] = 0x21;

What I expect to see at the server end is "! !!!!" (that's one exclamation mark followed by a space followed by four exclamation marks). However, the server just prints one exclamation mark. I don't know whether that's because it stops reading after the 0x00, or just doesn't print anything after it. Here's the code which receives the data:

      memset(line, 0x00, LINE_ARRAY_SIZE);
      while (recv(connectSocket, line, MAX_MSG, 0) > 0) {
         cout << "  --  " << line << "\n";
         
         // Convert line to upper case.
         for (i = 0; line != '\0'; i++)
            line = toupper(line);
         
         // Send converted line back to client.
         if (send(connectSocket, line, strlen(line) + 1, 0) < 0)
            cerr << "Error: cannot send modified data";
         
         memset(line, 0x00, LINE_ARRAY_SIZE);  // set line to all zeroes
      }

I thought it might be something to do with the for loop, which seems to stop if the character it's checking is zero, but this occurs after the character is sent to cout.

Edit -

In fact I have now changed the receive routine to this:

      memset(line, 0x00, LINE_ARRAY_SIZE);
      while (recv(connectSocket, line, MAX_MSG, 0) > 0) {
         cout << "  --  " << line << "\n";      
         memset(line, 0x00, LINE_ARRAY_SIZE);  // set line to all zeroes
      }

I really can't see what is stopping the characters after 0x00 being printed, so I can only assume they're not being sent, or are being discarded by the server. Any help really, really appreciated guys! :-)

--
moto
Code: [Select]
10  IT\'S THE FINAL COUNTDOWN
20  FOR C = 1 TO 2
30     DA-NA-NAAAA-NAAAA DA-NA-NA-NA-NAAAA
40     DA-NA-NAAAA-NAAAA DA-NA-NA-NA-NA-NA-NAAAAA
50  NEXT C
60  NA-NA-NAAAA
70  NA-NA NA-NA-NA-NA-NAAAA NAAA-NAAAAAAAAAAA
80  GOTO 10
 

Offline motorollinTopic starter

  • Hero Member
  • *****
  • Join Date: Nov 2005
  • Posts: 8669
Re: C++ - sending hex bytes to a socket
« Reply #3 on: June 02, 2008, 11:10:29 AM »
Right, sorted :-) Someone over at CodeGuru told me that 0x00 is being interpreted as a null terminator, so it stopped printing. I confirmed this by converting each byte to a hex code and printing that, and I got 0x21, 0x00, 0x21 etc.

--
moto
Code: [Select]
10  IT\'S THE FINAL COUNTDOWN
20  FOR C = 1 TO 2
30     DA-NA-NAAAA-NAAAA DA-NA-NA-NA-NAAAA
40     DA-NA-NAAAA-NAAAA DA-NA-NA-NA-NA-NA-NAAAAA
50  NEXT C
60  NA-NA-NAAAA
70  NA-NA NA-NA-NA-NA-NAAAA NAAA-NAAAAAAAAAAA
80  GOTO 10