0

I have a device connected to serial port and waiting for a file to be transmited using xmodem protocol.

I have tried constructing a message using in xmodem format and sending it, however I'm not getting the expected ACK for the transfer.

Bellow are the relevant bits of code:

Format of XMODEM message:

struct xmodem_packet 
{
    uint8_t start;
    uint8_t block;
    uint8_t block_neg;
    uint8_t payload[128];
    uint16_t crc;
};

Opening and configuring port:

HANDLE portHandler = CreateFile(L"COM9", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    DCB config = { 0 };
    COMMTIMEOUTS timeout = { 0 };

    // Configure
    config.DCBlength = sizeof(config);
    GetCommState(portHandler, &config);
    config.BaudRate = CBR_115200;
    config.ByteSize = 8;
    config.StopBits = ONESTOPBIT;
    config.Parity = NOPARITY;
    SetCommState(portHandler, &config);
    timeout.ReadIntervalTimeout = 50;
    timeout.ReadTotalTimeoutConstant = 50;
    timeout.ReadTotalTimeoutMultiplier = 50;
    timeout.WriteTotalTimeoutConstant = 50;
    timeout.WriteTotalTimeoutMultiplier = 10;
    SetCommTimeouts(portHandler, &timeout);

Prepare module for XMODEM transfer:

    DWORD toRead = 1;
    DWORD wasWriten = 0;
    DWORD wasRead = 0;
    char responce = 0;
    WriteFile(portHandler, "set load xmodem\n", 3+4+6+3, &wasWriten, NULL);
    WriteFile(portHandler, "\n", 2, &wasWriten, NULL); // Doesn't work without this

Construct XMODEM frame

xmodem_frame frame;
frame.start = SOH;
frame.block = 0;
frame.block_neg = 0;
memcpy(frame.payload, "test_data", 128);
swap16(crc16(frame.payload, sizeof(frame.payload)));

Send frame and look for ACK:

    WriteFile(portHandler, &frame, sizeof(frame), &wasWriten, NULL);
    ReadFile(portHandler, &responce, toRead, &wasRead, NULL);

    if (responce == 6)
        std::cout << "ACK was recieved";
    else
        std::cout << "ACK wasn't recieved";

I was expecting to get an ACK, however "ACK wasn't recieved" is always printed.

triple fault
  • 13,410
  • 8
  • 32
  • 45
  • What is actually received? – DisappointedByUnaccountableMod Oct 09 '16 at 09:33
  • Have you tried connecting a serial port application to the port so you can see what your application is sending? Then, press control-F into that application to send ACK, see if your code sees it properly. Your magic numbers 3+4+6+3 and 2 are pretty nasty. What does the 2 mean in WriteFile(portHandler, "\n", 2, &wasWriten, NULL); // Doesn't work without this - is that supposed to be the length of "\n"? "\n" is one character long at runtime (normally!). – DisappointedByUnaccountableMod Oct 09 '16 at 09:38
  • Regarding the nasty constants: I'm currentry just trying to get it to work, thus constantly changing these constants. If it try to print the responce, I get: § – triple fault Oct 09 '16 at 10:45
  • OK, but it isn't too hard to put the string you are going to send into a variable, let's call this stringToSend, and then use len(stringToSend) in the call to WriteFile because then you can't possible mess up the length value - i.e. less likely to bite you when you change the string during debugging. In fact you should be able to put both these strings into one string and only use a single call to WriteFile. You didn't answer my question: is the 2 correct? – DisappointedByUnaccountableMod Oct 09 '16 at 10:48
  • And what is the funny symbol - can you print it's ascii value? Seems likely to be a symptom of your problem if you aren't receiving ACK but are in fact receiving (let's say) NAK. – DisappointedByUnaccountableMod Oct 09 '16 at 10:50
  • And, you don't show what the data is that you think you have sent. Have you checked that what is sent is actually worthy of an ACK? If it isn't then, inevitably, you'll never get an ACK. Is it me or is this debugging 101 - you _think_ on the basis of very flimsy evidence that the behaviour isn't right but maybe your data is wrong - don't assume it is right, print it out, or write it to a log file, then work through the logic. – DisappointedByUnaccountableMod Oct 09 '16 at 10:53
  • To be sure I build the simplest frame worthy of an ACK. I printed out that I get from the module and it seemsthat I get back echo, and after module started expecting xmodem, I get a NACK. – triple fault Oct 09 '16 at 12:45
  • "the simplest frame worthy of an ACK" Oh dear, you failed. Anyway, that's progress. Now you have to work out what is wrong with your sent packet. Have you manually checked the checksum? – DisappointedByUnaccountableMod Oct 09 '16 at 12:48
  • If you edit your question in some minor way I think I can remove the downvote. – DisappointedByUnaccountableMod Oct 09 '16 at 13:34

0 Answers0