If I'm understanding correctly, the first part of your example:
sprintf(data,"%s%s",
"\x30\x60\x60\x20\x15\x35\x35",
"\x08");
is doing exactly what you want. The problem is that on the next %s
, you are using "\\00"
and you want to server to receive ASCII \00
(which would be 0x5c, 0x30, 0x30), but instead the server reports that it is receiving ASCII \5c00
(which would be 0x5c, 0x,35, 0x43, 0x30, 0x30).
I agree with Klas Lindbäck in that it sounds like the VeriFone terminal is doing the correct thing, but the server is displaying it wrong. There are 2 things I would consider doing in order to troubleshoot this in order to prove that this is correct (and you can do just one or the other or you can do both together).
First: You can use LOG_PRINTF (or print to paper or the screen if you prefer) to print the values of each byte just before you send it off. Below is a quick-and-dirty function I wrote to do just that when I was troubleshooting a similar sort of problem once. Note that I only cared about the beginning of the string (as is the case with you, it seems) so I don't print the end if I run out of buffer space.
void LogDump(unsigned char* input, int expectedLength)
{
#ifdef LOGSYS_FLAG
char buffer[100];
int idx, bfdx;
memset(buffer, 0, sizeof(buffer));
bfdx = 0;
for (idx = 0; idx < expectedLength && bfdx < sizeof(buffer); idx++)
{
//if it is a printable character, print as is
if (input[idx] > 31 && input[idx] < 127)
{
buffer[bfdx++] = (char) input[idx];
continue;
}
//if we are almost out of buffer space, show that we are truncating
// the results with a ~ character and break. Note we are leaving 5 bytes
// because we expand non-printable characters like "<121>"
if (bfdx + 5 > sizeof(buffer))
{
buffer[bfdx++] = '~';
break;
}
//if we make it here, then we have a non-printable character, so we'll show
// the value inside of "<>" to visually denote it is a numeric representation
sprintf(&buffer[bfdx], "<%d>", (int) input[idx]);
//advance bfdx to the next 0 in buffer. It will be at least 3...
bfdx += 3;
//... but for 2 and 3 digit numbers, it will be more.
while (buffer[bfdx] > 0)
bfdx++;
}
//I like to surround my LOG_PRINTF statements with short waits because if there
// is a crash in the program directly after this call, the LOG_PRINTF will not
// finish writing to the serial port and that can make it look like this LOG_PRINTF
// never executed which can make it look like the problem is elsewhere
SVC_WAIT(5);
LOG_PRINTF(("%s", buffer));
SVC_WAIT(5);
#endif
}
Second: try assigning each position in your char array an explicit value. If you already used my LOG_PRINTF
suggestion above and found it was not sending what you thought it should be, this would be one way to fix it so that it DOES send EXACTLY what you want. This method is a bit more tedious, but since you are spelling it out each value, anyway, it shouldn't be too much more overhead:
data[0] = 0x30;
//actually, I'd probably use either the decimal value: data[0] = 48;
// or I'd use the ASCII value: data[0] = '0';
// depending on what this data actually represents, either of those is
// likely to be more clear to whomever has to read the code later.
// However, that's your call to make.
data[1] = 0x60;
data[2] = 0x60;
data[3] = 0x20;
data[4] = 0x15;
data[5] = 0x35;
data[6] = 0x35;
data[7] = 0x08;
data[8] = 0x5C; // This is the '\'
data[9] = 0x48; // The first '0'
data[10]= 0x48; // The second '0'
data[11]= 0;
//for starters, you may want to stop here and see what you get on the other side
After you have proven to yourself that it IS or IS NOT the VeriFone code causing the problem, you will know whether you need to focus on the terminal or on the server side.