Моя реализация функции приема xmodem не работает

Я хотел бы попросить совета о моем коде и показать вашу модель реализации.
Я реализую программу в коде ниже, и сделать этот код основа.

Теперь я реализовал функцию приемника для xmodem, но она не работает.

«xmodem_receive» вызывается в основной функции только после того, как напечатал «Отправка C ping ….» как printf и, готово.

Отправка xmodem работает так, как показано ниже.

введите описание изображения здесь

Прием Xmodem не работает. Он закончен до получения данных.
введите описание изображения здесь

Поэтому я хотел бы спросить

1) Почему моя функция получения xmodem не работает?

2) Почему STX присутствует как «K», и это может пройти через оператор IF

            if(recSTX == X_STX){
printf("STX is %c\n", &recSTX);
}else{
printf("Garabage payload %c\n", &recSTX);
}

Это моя функция реализации

static int xmodem_receive(int serial_fd, char* filename, int _crc){
int skip = 0;
uint8_t sdCRC = 'C';
uint8_t sdACK = X_ACK;
uint8_t eof = X_EOF;
uint8_t sdNAK = X_NAK;
uint8_t recSTX; // receive SOH from chunk
uint8_t recBlk; // receive blk from chunk
uint8_t recNegBlk; // receive blk negative from chunk
uint8_t recData[1024]; // receive data from chunk
uint16_t recChksum;
FILE *fp;
int ret, fd;
struct stat stat;
// If we want to receive, We have to send NAK to Sendor./* Writing as binary */
fp = fopen(filename, "wb");
//Send NAK still read SOH that header of one data chunks
while(1){
char status;
printf("Waiting for sender ping ...");
fflush(stdout);
//
do {
if(_crc){
printf("Send C ping....\n");
ret = write(serial_fd, &sdCRC, sizeof(sdCRC));
}else{
// send NAK before read SOH
printf("Send NAK ping....\n");
ret = write(serial_fd, &sdNAK, sizeof(sdNAK));
}    // after sending NAK,receiving SOH from chunk
fflush(stdout);
ret = read(serial_fd, &recSTX, sizeof(recSTX));if(recSTX == X_STX){
printf("STX is %c\n", &recSTX);
}else{
printf("Garabage payload %c\n", &recSTX);
}
fflush(stdout);
if (ret != sizeof(recSTX)) {
printf("Not working");
fflush(stdout);
perror("read");
return -errno;
}
} while (recSTX != X_STX);

//So next, receiving blk
ret = read(serial_fd, &recBlk, sizeof(recBlk));
printf("Block Num is %d\n", recBlk);
fflush(stdout);
if (ret != sizeof(recBlk)) {
perror("read");
return -errno;
}
ret = read(serial_fd, &recNegBlk, sizeof(recNegBlk));
printf("Negative Block Num is %d\n", recNegBlk);
fflush(stdout);
if (ret != sizeof(recNegBlk)) {
perror("read");
return -errno;
}
ret = read(serial_fd, (void *)&recData, sizeof(recData));
printf("Data buffer is %c\n", &recData);
fflush(stdout);
if (ret != sizeof(recData)) {
perror("read");
return -errno;
}
ret = read(serial_fd, &recChksum, sizeof(recChksum));
printf("Check sum is %c", &recChksum);
fflush(stdout);
if (ret != sizeof(recChksum)) {
perror("read");
return -errno;
}
// data block number check
if(recBlk == 0xff - recNegBlk){
perror("read");
return -errno;
}
// data integrity check
if(recChksum == swap16(crc16(recData, sizeof(recData)))){
perror("read");
return -errno;
}
// check of appended "0xff" from end of data to  end of chunk in chunk
unsigned char *ptr = recData;
ptr += sizeof(recData);
while(*ptr == 0xff){
ptr--;
}
fwrite(recData, (ptr - recData),1,fp); // write Datas bytes from our buffer
// set skip flag or end connect
ret = write(serial_fd, &eof, sizeof(uint8_t));
if (ret != sizeof(eof) || ret != sizeof(X_STX)){
return -errno;
}else{
if(ret == X_STX){
skip = 1;
}else if(ret == EOF){
printf("EOF ...");
ret = write(serial_fd, &sdACK, sizeof(sdACK));
break;
}else{
return -errno;
}
}

}
printf("done.\n");
fclose(fp);
return 0;

}

И это полный код.

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <string>

#define X_STX 0x02
#define X_ACK 0x06
#define X_NAK 0x15
#define X_EOF 0x04

#define min(a, b)       ((a) < (b) ? (a) : (b))

struct xmodem_chunk {
uint8_t start;
uint8_t block;
uint8_t block_neg;
uint8_t payload[1024];
uint16_t crc;
} __attribute__((packed));

#define CRC_POLY 0x1021
static uint16_t crc_update(uint16_t crc_in, int incr)
{
uint16_t xor1 = crc_in >> 15;
uint16_t out1 = crc_in << 1;

if(incr)
out1++;

if(xor1)
out1 ^= CRC_POLY; // xor 0b1000000100001

return out1;
}static uint16_t crc16(const uint8_t *data, uint16_t size)
{
uint16_t crc, i;

for (crc = 0; size > 0; size--, data++)
for (i = 0x80; i; i >>= 1)
crc = crc_update(crc, *data & i);

for (i = 0; i < 16; i++)
crc = crc_update(crc, 0);

return crc;
}

static uint16_t swap16(uint16_t in)
{
return (in >> 8) | ((in & 0xff) << 8);
}

enum {
PROTOCOL_XMODEM,
PROTOCOL_YMODEM,
};

static int xmodem_receive(int serial_fd, char* filename, int _crc){
int skip = 0;
uint8_t sdCRC = 'C';
uint8_t sdACK = X_ACK;
uint8_t eof = X_EOF;
uint8_t sdNAK = X_NAK;
uint8_t recSTX; // receive SOH from chunk
uint8_t recBlk; // receive blk from chunk
uint8_t recNegBlk; // receive blk negative from chunk
uint8_t recData[1024]; // receive data from chunk
uint16_t recChksum;
FILE *fp;
int ret, fd;
struct stat stat;
// If we want to receive, We have to send NAK to Sendor./* Writing as binary */
fp = fopen(filename, "wb");
//Send NAK still read SOH that header of one data chunks
while(1){
char status;
printf("Waiting for sender ping ...");
fflush(stdout);
//
do {
if(_crc){
printf("Send C ping....\n");
ret = write(serial_fd, &sdCRC, sizeof(sdCRC));
}else{
// send NAK before read SOH
printf("Send NAK ping....\n");
ret = write(serial_fd, &sdNAK, sizeof(sdNAK));
}    // after sending NAK,receiving SOH from chunk
fflush(stdout);
ret = read(serial_fd, &recSTX, sizeof(recSTX));if(recSTX == X_STX){
printf("STX is %c\n", &recSTX);
}else{
printf("Garabage payload %c\n", &recSTX);
}
fflush(stdout);
if (ret != sizeof(recSTX)) {
printf("Not working");
fflush(stdout);
perror("read");
return -errno;
}
} while (recSTX != X_STX);

//So next, receiving blk
ret = read(serial_fd, &recBlk, sizeof(recBlk));
printf("Block Num is %d\n", recBlk);
fflush(stdout);
if (ret != sizeof(recBlk)) {
perror("read");
return -errno;
}
ret = read(serial_fd, &recNegBlk, sizeof(recNegBlk));
printf("Negative Block Num is %d\n", recNegBlk);
fflush(stdout);
if (ret != sizeof(recNegBlk)) {
perror("read");
return -errno;
}
ret = read(serial_fd, (void *)&recData, sizeof(recData));
printf("Data buffer is %c\n", &recData);
fflush(stdout);
if (ret != sizeof(recData)) {
perror("read");
return -errno;
}
ret = read(serial_fd, &recChksum, sizeof(recChksum));
printf("Check sum is %c", &recChksum);
fflush(stdout);
if (ret != sizeof(recChksum)) {
perror("read");
return -errno;
}
// data block number check
if(recBlk == 0xff - recNegBlk){
perror("read");
return -errno;
}
// data integrity check
if(recChksum == swap16(crc16(recData, sizeof(recData)))){
perror("read");
return -errno;
}
// check of appended "0xff" from end of data to  end of chunk in chunk
unsigned char *ptr = recData;
ptr += sizeof(recData);
while(*ptr == 0xff){
ptr--;
}
fwrite(recData, (ptr - recData),1,fp); // write Datas bytes from our buffer
// set skip flag or end connect
ret = write(serial_fd, &eof, sizeof(uint8_t));
if (ret != sizeof(eof) || ret != sizeof(X_STX)){
return -errno;
}else{
if(ret == X_STX){
skip = 1;
}else if(ret == EOF){
printf("EOF ...");
ret = write(serial_fd, &sdACK, sizeof(sdACK));
break;
}else{
return -errno;
}
}

}
printf("done.\n");
fclose(fp);
return 0;

}

static int xymodem_send(int serial_fd, const char *filename, int protocol, int wait)
{
size_t len;
int ret, fd;
uint8_t answer;
struct stat stat;
const uint8_t *buf;
uint8_t eof = X_EOF;
struct xmodem_chunk chunk;
int skip_payload = 0;

fd = open(filename, O_RDONLY);
if (fd < 0) {
perror("open");
return -errno;
}

fstat(fd, &stat);
len = stat.st_size;
buf = static_cast<uint8_t*>(mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0));
if (!buf) {
perror("mmap");
return -errno;
}

if (wait) {
printf("Waiting for receiver ping ...");
fflush(stdout);

do {
ret = read(serial_fd, &answer, sizeof(answer));
if (ret != sizeof(answer)) {
perror("read");
return -errno;
}
} while (answer != 'C');

printf("done.\n");
}

printf("Sending %s ", filename);

if (protocol == PROTOCOL_YMODEM) {
strncpy((char *) chunk.payload, filename, sizeof(chunk.payload));
chunk.block = 0;
skip_payload = 1;
} else {
chunk.block = 1;
}

chunk.start = X_STX;

while (len) {
size_t z = 0;
int next = 0;
char status;

if (!skip_payload) {
z = min(len, sizeof(chunk.payload));
memcpy(chunk.payload, buf, z);
memset(chunk.payload + z, 0xff, sizeof(chunk.payload) - z);
} else {
skip_payload = 0;
}

chunk.crc = swap16(crc16(chunk.payload, sizeof(chunk.payload)));
chunk.block_neg = 0xff - chunk.block;

ret = write(serial_fd, &chunk, sizeof(chunk));
if (ret != sizeof(chunk))
return -errno;

ret = read(serial_fd, &answer, sizeof(answer));
if (ret != sizeof(answer))
return -errno;
switch (answer) {
case X_NAK:
status = 'N';
break;
case X_ACK:
status = '.';
next = 1;
break;
default:
status = '?';
break;
}

printf("%c", status);
fflush(stdout);

if (next) {
chunk.block++;
len -= z;
buf += z;
}
}

ret = write(serial_fd, &eof, sizeof(eof));
if (ret != sizeof(eof))
return -errno;

/* send EOT again for YMODEM */
if (protocol == PROTOCOL_YMODEM) {
ret = write(serial_fd, &eof, sizeof(eof));
if (ret != sizeof(eof))
return -errno;
}

printf("done.\n");

return 0;
}

static int open_serial(const char *path, int baud)
{
int fd;
struct termios tty;

fd = open(path, O_RDWR | O_SYNC);
if (fd < 0) {
perror("open");
return -errno;
}

memset(&tty, 0, sizeof(tty));
if (tcgetattr(fd, &tty) != 0) {
perror("tcgetattr");
return -errno;
}

cfsetospeed(&tty, baud);
cfsetispeed(&tty, baud);

tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;     // 8-bit chars
tty.c_iflag &= ~IGNBRK;                         // disable break processing
tty.c_lflag = 0;                                // no signaling chars, no echo,
// no canonical processing
tty.c_oflag = 0;                                // no remapping, no delays
tty.c_cc[VMIN]  = 1;                            // read doesn't block
tty.c_cc[VTIME] = 5;                            // 0.5 seconds read timeout

tty.c_iflag &= ~(IXON | IXOFF | IXANY);         // shut off xon/xoff ctrl

tty.c_cflag |= (CLOCAL | CREAD);                // ignore modem controls,
// enable reading
tty.c_cflag &= ~(PARENB | PARODD);              // shut off parity
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CRTSCTS;

if (tcsetattr(fd, TCSANOW, &tty) != 0) {
perror("tcsetattr");
return -errno;
}

return fd;
}

static void dump_serial(int serial_fd)
{
char in;

for (;;) {
read(serial_fd, &in, sizeof(in));
printf("%c", in);
fflush(stdout);
}
}

#ifdef TEST_XMODEM_RECEIVE

#endif // TEST_XMODEM_RECEIVE

int main(int argc, char **argv)
{
int a, ret, serial_fd;

printf("STX: %c\n", X_STX);

printf("ACK: %c\n", X_ACK);

printf("NAK: %c\n", X_NAK);

printf("EOF: %c\n", X_EOF);

fflush(stdout);

serial_fd = open_serial("/dev/ttyUSB0", 115200);
if (serial_fd < 0)
return -errno;if(std::string(argv[2]) == "0" || std::string(argv[2]) == "0"){
ret = xymodem_send(serial_fd, argv[1], PROTOCOL_XMODEM, 1);
if (ret < 0)
return ret;
}

if(std::string(argv[2]) == "1"){
ret = xmodem_receive(serial_fd, argv[1], 1);
if (ret < 0)
return ret;
}return 0;
}

Спасибо за просмотр моих вопросов.

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]