0

I am building a POS application verifone (C-language) which should communicate with m2m switch from Morocco but I'm stuck when sending initialization message which should have a backslash like this (08\00) but when sending this I'm having 08\5c00. It converts backslash by its value in hex(5c). The tool I'm using is socket workbench to simulate the server. How can I send a backslash without being converted into \5c? It needs to be done in C Language.

EDIT

This is the data I want to send to the server with the header but when trying to print \00 I get \5C00

sprintf(data,"%s%s%s%s%s%s%s%s%s%s%s%s%s","\x30\x60\x60\x20\x15\x35\x35","\x08",‌"\\00","\x0x00","\x01\x30\x30\x30\x30\xC0\x30\x30\x30\x30","\x97","\\00","\x30\x30"‌,"\x00\x00\x01\x00","\x02",idTerminal,idCommercant,"\x20\x20\x20\xA4\xBC");
devasia2112
  • 5,844
  • 6
  • 36
  • 56
knk
  • 45
  • 2
  • 9
  • Show us the relevant piece of your code. – Klas Lindbäck Feb 10 '15 at 11:32
  • 1
    Maybe the server is receiving `\ ` but printing it as `\5c`? – Klas Lindbäck Feb 10 '15 at 11:43
  • this is the data i want to send to the server with its header but when i want to print \00 i have got \5C00: sprintf(data,"%s%s%s%s%s%s%s%s%s%s%s%s%s","\x30\x60\x60\x20\x15\x35\x35","\x08","\\00","\x0x00","\x01\x30\x30\x30\x30\xC0\x30\x30\x30\x30","\x97","\\00","\x30\x30","\x00\x00\x01\x00","\x02",idTerminal,idCommercant,"\x20\x20\x20\xA4\xBC"); – knk Feb 10 '15 at 13:18
  • That `sprintf` will put `\ ` in `data`, just as you want. The "problem" is with how the data is displayed in socket workbench. – Klas Lindbäck Feb 10 '15 at 13:28
  • you are right but for my verifone program to work it should be printed \00 instead of \5c00,i have one friend who has done it but doesn't want to share his code. – knk Feb 10 '15 at 13:45
  • If the server prints special characters using escape codes, then \00 would be the `\0` char. – Klas Lindbäck Feb 10 '15 at 13:48
  • let me try and tell you what it's going to print – knk Feb 10 '15 at 13:52
  • nothing is printed when sending \0 – knk Feb 10 '15 at 14:04
  • You may have to configure the server to accept binary data since \0 is also the string terminator character. (I haven't used socket workbench so I'm not familiar with its settings). – Klas Lindbäck Feb 10 '15 at 14:27
  • Just a thought, do you call any routine that encodes the data before it is sent? – Klas Lindbäck Feb 10 '15 at 14:36
  • no i do not encode anything before sending but when i do the same code in php i have no problem. You can try socket workbench and see what it is going to print and there you could have a better understanding.just a google search – knk Feb 10 '15 at 15:17

1 Answers1

0

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.

David
  • 4,665
  • 4
  • 34
  • 60
  • I realize this is a very old post (I'm not sure how I haven't seen it before today...) and that you have likely solved your problem already. If you *HAVE* solved it, would you share your solution? @knk – David Jul 24 '15 at 18:14