ファイルの転送プロトコルのxmodemをLinux上で実装しているのですが、
ファイルを小分けにしたデータとそのチェックサムを送信して、
別の端末で受け取っています。しかし、このデータをその受け取った端末で
チェックサムを計算して、送られたチェックサムと照合すると一致しません。
写真では9404がデータと一緒に送られるのですが、データから再計算して出したチェックサムには7541とでます。
全く良くわからないのですが,これはファイルの受信のポインタ処理に問題があるのでしょうか、
ファイルを受け取る際にread関数で、配列をwhileで回すことによって、1024バイトのデータを取得しています。
そこでのポインタ処理に問題があるのでしょうか。バイナリとポインタは慣れていないので感覚がつかめません。
それとも、別の問題があるのでしょうか。
送信側の処理(xymodem_send)
c++
1chunk.crc = swap16(crc16(chunk.payload, sizeof(chunk.payload)));
受け取り側の処理 (xmodem_receive)
c++
1 2 uint8_t recData[1024]; // receive data from chunk 3 uint16_t recChksum; 4 uint16_t recCRC; 5 6 // recData is data payload 7 ret = read(serial_fd, recData, sizeof(recData)); 8 9 printf("Data buffer is %c\n", &recData); 10 fflush(stdout); 11 12 // processing up to 1024bytes 13 if (ret != sizeof(recData)) { 14 rec_chunk_data += ret; 15 while(rec_chunk_data < sizeof(recData)){ 16 ret = read(serial_fd, recData + (sizeof(uint8_t) * rec_chunk_data), (sizeof(recData) - rec_chunk_data)); 17 rec_chunk_data += ret; 18 printf("ret is proceeding: %d\n", ret); 19 fflush(stdout); 20 } 21 } 22 23 ret = read(serial_fd, &recChksum, sizeof(recChksum)); 24 25 printf("Check sum is %d\n", recChksum); 26 fflush(stdout); 27 // Calculating checksum from data payload 28 recCRC = swap16(crc16(recData, sizeof(recData))); 29 // data integrity check 30 if(recChksum != recCRC){ 31 printf("Check sum is %d and %d\n", recChksum, swap16(crc16(recData, sizeof(recData)))); 32 perror("swap16"); 33 return -errno; 34 }
関係のある処理(コード)
c++
1#include <stdio.h> 2#include <stdlib.h> 3#include <stdint.h> 4#include <string.h> 5#include <errno.h> 6#include <unistd.h> 7#include <fcntl.h> 8#include <termios.h> 9#include <sys/types.h> 10#include <sys/stat.h> 11#include <sys/mman.h> 12#include <string> 13 14#define X_STX 0x02 15#define X_ACK 0x06 16#define X_NAK 0x15 17#define X_EOF 0x04 18 19 #define MAX_RETRY (9) 20 21#define min(a, b) ((a) < (b) ? (a) : (b)) 22 23struct xmodem_chunk { 24 uint8_t start; 25 uint8_t block; 26 uint8_t block_neg; 27 uint8_t payload[1024]; 28 uint16_t crc; 29} __attribute__((packed)); 30 31#define CRC_POLY 0x1021 32static uint16_t crc_update(uint16_t crc_in, int incr) 33{ 34 uint16_t xor1 = crc_in >> 15; 35 uint16_t out1 = crc_in << 1; 36 37 if(incr) 38 out1++; 39 40 if(xor1) 41 out1 ^= CRC_POLY; // xor 0b1000000100001 42 43 return out1; 44} 45 46 47static uint16_t crc16(const uint8_t *data, uint16_t size) 48{ 49 uint16_t crc, i; 50 51 for (crc = 0; size > 0; size--, data++) 52 for (i = 0x80; i; i >>= 1) 53 crc = crc_update(crc, *data & i); 54 55 for (i = 0; i < 16; i++) 56 crc = crc_update(crc, 0); 57 58 return crc; 59} 60 61static uint16_t swap16(uint16_t in) 62{ 63 return (in >> 8) | ((in & 0xff) << 8); 64} 65 66enum { 67 PROTOCOL_XMODEM, 68 PROTOCOL_YMODEM, 69}; 70
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/01/14 06:50
2017/01/14 06:54