static void fec_encode_all_stripes(sender_state_t sendst, struct slice *slice) { int stripe; struct net_config *config = sendst->config; struct fifo *fifo = sendst->fifo; int bytes = slice->bytes; int stripes = config->fec_stripes; int redundancy = config->fec_redundancy; int nrBlocks = (bytes + config->blockSize - 1) / config->blockSize; int leftOver = bytes % config->blockSize; unsigned char *fec_data = slice->fec_data; unsigned char *fec_blocks[redundancy]; unsigned char *data_blocks[128]; if(leftOver) { unsigned char *lastBlock = ADR(nrBlocks - 1, config->blockSize); memset(lastBlock+leftOver, 0, config->blockSize-leftOver); } for(stripe=0; stripe<stripes; stripe++) { int i,j; for(i=0; i<redundancy; i++) fec_blocks[i] = fec_data+config->blockSize*(stripe+i*stripes); for(i=stripe, j=0; i< nrBlocks; i+=stripes, j++) data_blocks[j] = ADR(i, config->blockSize); fec_encode(config->blockSize, data_blocks, j, fec_blocks, redundancy); } }
// Helper function to keep code base small void fec_test_codec(fec_scheme _fs, unsigned int _n, void * _opts) { #if !LIBFEC_ENABLED if ( _fs == LIQUID_FEC_CONV_V27 || _fs == LIQUID_FEC_CONV_V29 || _fs == LIQUID_FEC_CONV_V39 || _fs == LIQUID_FEC_CONV_V615 || _fs == LIQUID_FEC_CONV_V27P23 || _fs == LIQUID_FEC_CONV_V27P34 || _fs == LIQUID_FEC_CONV_V27P45 || _fs == LIQUID_FEC_CONV_V27P56 || _fs == LIQUID_FEC_CONV_V27P67 || _fs == LIQUID_FEC_CONV_V27P78 || _fs == LIQUID_FEC_CONV_V29P23 || _fs == LIQUID_FEC_CONV_V29P34 || _fs == LIQUID_FEC_CONV_V29P45 || _fs == LIQUID_FEC_CONV_V29P56 || _fs == LIQUID_FEC_CONV_V29P67 || _fs == LIQUID_FEC_CONV_V29P78 || _fs == LIQUID_FEC_RS_M8) { AUTOTEST_WARN("convolutional, Reed-Solomon codes unavailable (install libfec)\n"); return; } #endif // generate fec object fec q = fec_create(_fs,_opts); // create arrays unsigned int n_enc = fec_get_enc_msg_length(_fs,_n); unsigned char msg[_n]; // original message unsigned char msg_enc[n_enc]; // encoded message unsigned char msg_dec[_n]; // decoded message // initialze message unsigned int i; for (i=0; i<_n; i++) { msg[i] = rand() & 0xff; msg_dec[i] = 0; } // encode message fec_encode(q,_n,msg,msg_enc); // channel: add single error msg_enc[0] ^= 0x01; // decode message fec_decode(q,_n,msg_enc,msg_dec); // validate output CONTEND_SAME_DATA(msg,msg_dec,_n); // clean up objects fec_destroy(q); }
void pb_transmit_block(packet_buffer_t *pbl, pcap_t *ppcap, int *seq_nr, int port, int packet_length, uint8_t *packet_transmit_buffer, int packet_header_len, int data_packets_per_block, int fec_packets_per_block, int transmission_count) { int i; uint8_t *data_blocks[MAX_DATA_OR_FEC_PACKETS_PER_BLOCK]; uint8_t fec_pool[MAX_DATA_OR_FEC_PACKETS_PER_BLOCK][MAX_USER_PACKET_LENGTH]; uint8_t *fec_blocks[MAX_DATA_OR_FEC_PACKETS_PER_BLOCK]; for(i=0; i<data_packets_per_block; ++i) { data_blocks[i] = pbl[i].data; } if(fec_packets_per_block) { for(i=0; i<fec_packets_per_block; ++i) { fec_blocks[i] = fec_pool[i]; } fec_encode(packet_length, data_blocks, data_packets_per_block, (unsigned char **)fec_blocks, fec_packets_per_block); } uint8_t *pb = packet_transmit_buffer; set_port_no(pb, port); pb += packet_header_len; int x; for(x=0; x<transmission_count; ++x) { //send data and FEC packets interleaved int di = 0; int fi = 0; int seq_nr_tmp = *seq_nr; while(di < data_packets_per_block || fi < fec_packets_per_block) { if(di < data_packets_per_block) { pb_transmit_packet(ppcap, seq_nr_tmp, packet_transmit_buffer, packet_header_len, data_blocks[di], packet_length); seq_nr_tmp++; di++; } if(fi < fec_packets_per_block) { pb_transmit_packet(ppcap, seq_nr_tmp, packet_transmit_buffer, packet_header_len, fec_blocks[fi], packet_length); seq_nr_tmp++; fi++; } } } *seq_nr += data_packets_per_block + fec_packets_per_block; //reset the length back for(i=0; i< data_packets_per_block; ++i) { pbl[i].len = 0; } }
error_t hw_radio_send_packet(hw_radio_packet_t* packet, tx_packet_callback_t tx_cb, uint16_t eta, uint8_t dll_header_bg_frame[2]) { assert(eta == 0); // advertising not implemented on si4460 for now // TODO error handling EINVAL, ESIZE, EOFF if(current_state == HW_RADIO_STATE_TX) return EBUSY; uint8_t data_length = packet->length + 1; if (packet->tx_meta.tx_cfg.channel_id.channel_header.ch_coding == PHY_CODING_FEC_PN9) { DPRINT("Original packet: %d", data_length); DPRINT_DATA(packet->data, data_length); data_length = fec_encode(packet->data, data_length); DPRINT("Encoded packet: %d", data_length); DPRINT_DATA(packet->data, data_length); } else { if (has_hardware_crc) data_length -= 2; } tx_packet_callback = tx_cb; if(current_state == HW_RADIO_STATE_RX) { //pending_rx_cfg.channel_id = current_channel_id; //pending_rx_cfg.syncword_class = current_syncword_class; should_rx_after_tx_completed = true; } current_state = HW_RADIO_STATE_TX; current_packet = packet; DPRINT("Data to TX Fifo:"); DPRINT_DATA(packet->data, data_length); DPRINT("TX ch header=%x, ind=%i", packet->tx_meta.tx_cfg.channel_id.channel_header_raw, packet->tx_meta.tx_cfg.channel_id.center_freq_index); configure_channel((channel_id_t*)&(packet->tx_meta.tx_cfg.channel_id)); configure_eirp(packet->tx_meta.tx_cfg.eirp); configure_syncword_class(current_packet->tx_meta.tx_cfg.syncword_class, current_packet->tx_meta.tx_cfg.channel_id.channel_header.ch_coding); DEBUG_TX_START(); DEBUG_RX_END(); ezradioStartTx(packet, ez_channel_id, should_rx_after_tx_completed, data_length); return SUCCESS; }
// // AUTOTEST: repeat/3 codec // void autotest_rep5_codec() { unsigned int n=4; unsigned char msg[] = {0x25, 0x62, 0x3F, 0x52}; fec_scheme fs = LIQUID_FEC_REP5; // create arrays unsigned int n_enc = fec_get_enc_msg_length(fs,n); unsigned char msg_dec[n]; unsigned char msg_enc[n_enc]; // create object fec q = fec_create(fs,NULL); if (liquid_autotest_verbose) fec_print(q); // encode message fec_encode(q, n, msg, msg_enc); // corrupt encoded message, but no so much that it // can't be decoded msg_enc[ 0] = ~msg_enc[ 0]; msg_enc[ 4] = ~msg_enc[ 4]; // msg_enc[ 8] = ~msg_enc[ 8]; // msg_enc[12] = ~msg_enc[12]; // msg_enc[16] = ~msg_enc[16]; msg_enc[ 1] = ~msg_enc[ 1]; // msg_enc[ 5] = ~msg_enc[ 5]; msg_enc[ 9] = ~msg_enc[ 9]; // msg_enc[13] = ~msg_enc[13]; // msg_enc[17] = ~msg_enc[17]; // msg_enc[ 2] = ~msg_enc[ 2]; // msg_enc[ 6] = ~msg_enc[ 6]; msg_enc[10] = ~msg_enc[10]; msg_enc[14] = ~msg_enc[14]; // msg_enc[18] = ~msg_enc[18]; msg_enc[ 3] = ~msg_enc[ 3]; // msg_enc[ 7] = ~msg_enc[ 7]; // msg_enc[11] = ~msg_enc[11]; // msg_enc[15] = ~msg_enc[15]; msg_enc[19] = ~msg_enc[19]; // decode message fec_decode(q, n, msg_enc, msg_dec); // validate data are the same CONTEND_SAME_DATA(msg, msg_dec, n); // clean up objects fec_destroy(q); }
void rs_encode(void *code,char *data[],int size) { int k=get_k(code); int n=get_n(code); for(int i=k;i<n;i++) { fec_encode(code, (void **)data, data[i],i, size); } return ; }
error_t hw_radio_send_packet(hw_radio_packet_t* packet, tx_packet_callback_t tx_cb) { // TODO error handling EINVAL, ESIZE, EOFF if(current_state == HW_RADIO_STATE_TX) return EBUSY; uint8_t data_length = packet->length + 1; if (packet->tx_meta.tx_cfg.channel_id.channel_header.ch_coding == PHY_CODING_FEC_PN9) { DPRINT(LOG_STACK_PHY, "Original packet: %d", data_length); DPRINT_DATA(packet->data, data_length); data_length = fec_encode(packet->data, data_length); DPRINT(LOG_STACK_PHY, "Encoded packet: %d", data_length); DPRINT_DATA(packet->data, data_length); } else { if (has_hardware_crc) data_length -= 2; } tx_packet_callback = tx_cb; if(current_state == HW_RADIO_STATE_RX) { //pending_rx_cfg.channel_id = current_channel_id; //pending_rx_cfg.syncword_class = current_syncword_class; should_rx_after_tx_completed = true; } current_state = HW_RADIO_STATE_TX; current_packet = packet; DPRINT(LOG_STACK_PHY, "Data to TX Fifo:"); DPRINT_DATA(packet->data, data_length); configure_channel((channel_id_t*)&(packet->tx_meta.tx_cfg.channel_id)); configure_eirp(packet->tx_meta.tx_cfg.eirp); configure_syncword_class(current_packet->tx_meta.tx_cfg.syncword_class, current_packet->tx_meta.tx_cfg.channel_id.channel_header.ch_coding); DEBUG_TX_START(); DEBUG_RX_END(); ezradioStartTx(packet, ez_channel_id, should_rx_after_tx_completed, data_length); return SUCCESS; }
// // AUTOTEST: Hamming (7,4) codec // void autotest_hamming74_codec() { unsigned int n=4; unsigned char msg[] = {0x25, 0x62, 0x3F, 0x52}; fec_scheme fs = LIQUID_FEC_HAMMING74; // create arrays unsigned int n_enc = fec_get_enc_msg_length(fs,n); unsigned char msg_dec[n]; unsigned char msg_enc[n_enc]; // create object fec q = fec_create(fs,NULL); if (liquid_autotest_verbose) fec_print(q); // encode message fec_encode(q, n, msg, msg_enc); // corrupt encoded message msg_enc[0] ^= 0x04; // position 5 #if 0 msg_enc[1] ^= 0x04; // msg_enc[2] ^= 0x02; // msg_enc[3] ^= 0x01; // msg_enc[4] ^= 0x80; // msg_enc[5] ^= 0x40; // msg_enc[6] ^= 0x20; // #endif // decode message fec_decode(q, n, msg_enc, msg_dec); // validate data are the same CONTEND_SAME_DATA(msg, msg_dec, n); // clean up objects fec_destroy(q); }
unsigned int test_fec_decoding(void) { uint8_t input[15] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E}; uint8_t output[32]; TimerA_configureContinuousMode(__MSP430_BASEADDRESS_T0A5__, TIMERA_CLOCKSOURCE_SMCLK, TIMERA_CLOCKSOURCE_DIVIDER_1, TIMERA_TAIE_INTERRUPT_DISABLE, TIMERA_DO_CLEAR); fec_init_encode(input); fec_set_length(15); fec_encode(&output[0]); fec_encode(&output[4]); fec_encode(&output[8]); fec_encode(&output[12]); fec_encode(&output[16]); fec_encode(&output[20]); fec_encode(&output[24]); fec_encode(&output[28]); memset(input, 0, 15); fec_init_decode(input); fec_set_length(15); TimerA_clear(__MSP430_BASEADDRESS_T0A5__); fec_decode(&output[0]); fec_decode(&output[4]); fec_decode(&output[8]); fec_decode(&output[12]); fec_decode(&output[16]); fec_decode(&output[20]); fec_decode(&output[24]); fec_decode(&output[28]); TimerA_stop(__MSP430_BASEADDRESS_T0A5__); return TA0R - TIMER_OFFSET; }
void tx_data_isr() { //Calculate number of free bytes in TXFIFO uint8_t txBytes = 64 - ReadSingleReg(TXBYTES); #ifdef D7_PHY_USE_FEC if(fec) { uint8_t fecbuffer[4]; //If remaining bytes is equal or less than 255 - fifo size, set length to fixed if(remainingBytes < 192) set_length_infinite(false); while (txBytes >= 4) { //Get encoded data, stop when no more data available if(fec_encode(fecbuffer) == false) break; //Write data to tx fifo WriteBurstReg(TXFIFO, fecbuffer, 4); remainingBytes -= 4; txBytes -= 4; } } else { #endif //Limit number of bytes to remaining bytes if(txBytes > remainingBytes) txBytes = remainingBytes; //Write data to tx fifo WriteBurstReg(TXFIFO, bufferPosition, txBytes); remainingBytes -= txBytes; bufferPosition += txBytes; #ifdef D7_PHY_USE_FEC } #endif }
// Execute the packetizer on an input message // // _p : packetizer object // _msg : input message (uncoded bytes) // _pkt : encoded output message void packetizer_encode(packetizer _p, unsigned char * _msg, unsigned char * _pkt) { unsigned int i; // copy input message to internal buffer[0] memmove(_p->buffer_0, _msg, _p->msg_len); // compute crc, append to buffer unsigned int key = crc_generate_key(_p->check, _p->buffer_0, _p->msg_len); for (i=0; i<_p->crc_length; i++) { // append byte to buffer _p->buffer_0[_p->msg_len+_p->crc_length-i-1] = key & 0xff; // shift key by 8 bits key >>= 8; } // execute fec/interleaver plans for (i=0; i<_p->plan_len; i++) { // run the encoder: buffer[0] > buffer[1] fec_encode(_p->plan[i].f, _p->plan[i].dec_msg_len, _p->buffer_0, _p->buffer_1); // run the interleaver: buffer[1] > buffer[0] interleaver_encode(_p->plan[i].q, _p->buffer_1, _p->buffer_0); } // copy result to output memmove(_pkt, _p->buffer_0, _p->packet_len); }
char * encode(char *data, int k, int m, int chunksize) { fec_t *test; char *output; unsigned char *src[k]; unsigned char *fecs[m-k]; unsigned block[m-k]; int i; output = (char *)malloc((m * chunksize + 1) * sizeof(char)); for (i = 0; i < k; i++) { src[i] = output + i * chunksize; strncpy(src[i], data + (i * chunksize), chunksize); } for (i = 0; i < m - k; i++){ block[i] = k + i; fecs[i] = output + (k + i) * chunksize; } test = fec_new(k, m); fec_encode(test, src, fecs, block, (m - k), chunksize); output[m * chunksize] = '\0'; fec_free(test); return output; }
int main(void) { int i, j; unsigned char buf[NR_PKTS * PKT_SIZE]; unsigned char pktbuf[(NR_PKTS + DROPS) * PKT_SIZE]; struct fec_parms *fec; unsigned char *srcs[NR_PKTS]; unsigned char *pkt[NR_PKTS + DROPS]; int pktnr[NR_PKTS + DROPS]; struct timeval then, now; srand(3453); for (i=0; i < sizeof(buf); i++) if (i < ERASE_SIZE) buf[i] = rand(); else buf[i] = 0; for (i=0; i < NR_PKTS + DROPS; i++) srcs[i] = buf + (i * PKT_SIZE); for (i=0; i < NR_PKTS + DROPS; i++) { pkt[i] = malloc(PKT_SIZE); pktnr[i] = -1; } fec = fec_new(NR_PKTS, NR_PKTS + DROPS); if (!fec) { printf("fec_init() failed\n"); exit(1); } j = 0; for (i=0; i < NR_PKTS + DROPS; i++) { #if 1 if (i == 27 || i == 40 || i == 44 || i == 45 || i == 56 ) continue; #endif if (i == 69 || i == 93 || i == 103) continue; fec_encode(fec, srcs, pkt[j], i, PKT_SIZE); pktnr[j] = i; j++; } gettimeofday(&then, NULL); if (fec_decode(fec, pkt, pktnr, PKT_SIZE)) { printf("Decode failed\n"); exit(1); } for (i=0; i < NR_PKTS; i++) memcpy(pktbuf + (i*PKT_SIZE), pkt[i], PKT_SIZE); gettimeofday(&now, NULL); now.tv_sec -= then.tv_sec; now.tv_usec -= then.tv_usec; if (now.tv_usec < 0) { now.tv_usec += 1000000; now.tv_sec--; } if (memcmp(pktbuf, buf, ERASE_SIZE)) { int fd; printf("Compare failed\n"); fd = open("before", O_WRONLY|O_TRUNC|O_CREAT, 0644); if (fd >= 0) write(fd, buf, ERASE_SIZE); close(fd); fd = open("after", O_WRONLY|O_TRUNC|O_CREAT, 0644); if (fd >= 0) write(fd, pktbuf, ERASE_SIZE); exit(1); } printf("Decoded in %ld.%06lds\n", now.tv_sec, now.tv_usec); return 0; }
// Helper function to keep code base small void fec_encode_bench( struct rusage *_start, struct rusage *_finish, unsigned long int *_num_iterations, fec_scheme _fs, unsigned int _n, void * _opts) { #if !LIBFEC_ENABLED if ( _fs == LIQUID_FEC_CONV_V27 || _fs == LIQUID_FEC_CONV_V29 || _fs == LIQUID_FEC_CONV_V39 || _fs == LIQUID_FEC_CONV_V615 || _fs == LIQUID_FEC_CONV_V27P23 || _fs == LIQUID_FEC_CONV_V27P34 || _fs == LIQUID_FEC_CONV_V27P45 || _fs == LIQUID_FEC_CONV_V27P56 || _fs == LIQUID_FEC_CONV_V27P67 || _fs == LIQUID_FEC_CONV_V27P78 || _fs == LIQUID_FEC_CONV_V29P23 || _fs == LIQUID_FEC_CONV_V29P34 || _fs == LIQUID_FEC_CONV_V29P45 || _fs == LIQUID_FEC_CONV_V29P56 || _fs == LIQUID_FEC_CONV_V29P67 || _fs == LIQUID_FEC_CONV_V29P78 || _fs == LIQUID_FEC_RS_M8) { fprintf(stderr,"warning: convolutional, Reed-Solomon codes unavailable (install libfec)\n"); getrusage(RUSAGE_SELF, _start); memmove((void*)_finish,(void*)_start,sizeof(struct rusage)); return; } #endif // normalize number of iterations *_num_iterations /= _n; switch (_fs) { case LIQUID_FEC_NONE: *_num_iterations *= 500; break; case LIQUID_FEC_REP3: *_num_iterations *= 200; break; case LIQUID_FEC_REP5: *_num_iterations *= 100; break; case LIQUID_FEC_HAMMING74: *_num_iterations *= 30; break; case LIQUID_FEC_HAMMING84: *_num_iterations *= 100; break; case LIQUID_FEC_HAMMING128: *_num_iterations *= 100; break; case LIQUID_FEC_SECDED2216: *_num_iterations *= 10; break; case LIQUID_FEC_SECDED3932: *_num_iterations *= 10; break; case LIQUID_FEC_SECDED7264: *_num_iterations *= 10; break; case LIQUID_FEC_GOLAY2412: *_num_iterations *= 2; break; case LIQUID_FEC_CONV_V27: case LIQUID_FEC_CONV_V29: case LIQUID_FEC_CONV_V39: case LIQUID_FEC_CONV_V615: case LIQUID_FEC_CONV_V27P23: case LIQUID_FEC_CONV_V27P34: case LIQUID_FEC_CONV_V27P45: case LIQUID_FEC_CONV_V27P56: case LIQUID_FEC_CONV_V27P67: case LIQUID_FEC_CONV_V27P78: case LIQUID_FEC_CONV_V29P23: case LIQUID_FEC_CONV_V29P34: case LIQUID_FEC_CONV_V29P45: case LIQUID_FEC_CONV_V29P56: case LIQUID_FEC_CONV_V29P67: case LIQUID_FEC_CONV_V29P78: case LIQUID_FEC_RS_M8: *_num_iterations *= 1; break; default:; } if (*_num_iterations < 1) *_num_iterations = 1; // generate fec object fec q = fec_create(_fs,_opts); // create arrays unsigned int n_enc = fec_get_enc_msg_length(_fs,_n); unsigned char msg[_n]; // original message unsigned char msg_enc[n_enc]; // encoded message // initialze message unsigned long int i; for (i=0; i<_n; i++) { msg[i] = rand() & 0xff; } // start trials getrusage(RUSAGE_SELF, _start); for (i=0; i<(*_num_iterations); i++) { fec_encode(q,_n,msg,msg_enc); fec_encode(q,_n,msg,msg_enc); fec_encode(q,_n,msg,msg_enc); fec_encode(q,_n,msg,msg_enc); } getrusage(RUSAGE_SELF, _finish); *_num_iterations *= 4; // clean up objects fec_destroy(q); }
int test_decode(void *code, int k, int index[], int sz, char *s) { int errors; int reconstruct = 0 ; int item, i ; static int prev_k = 0, prev_sz = 0; static u_char **d_original = NULL, **d_src = NULL ; if (sz < 1 || sz > 8192) { fprintf(stderr, "test_decode: size %d invalid, must be 1..8K\n", sz); return 1 ; } if (k < 1 || k > GF_SIZE + 1) { fprintf(stderr, "test_decode: k %d invalid, must be 1..%d\n", k, GF_SIZE + 1 ); return 2 ; } if (prev_k != k || prev_sz != sz) { if (d_original != NULL) { for (i = 0 ; i < prev_k ; i++ ) { free(d_original[i]); free(d_src[i]); } free(d_original); free(d_src); d_original = NULL ; d_src = NULL ; } } prev_k = k ; prev_sz = sz ; if (d_original == NULL) { d_original = my_malloc(k * sizeof(void *), "d_original ptr"); d_src = my_malloc(k * sizeof(void *), "d_src ptr"); for (i = 0 ; i < k ; i++ ) { d_original[i] = my_malloc(sz, "d_original data"); d_src[i] = my_malloc(sz, "d_src data"); } /* * build sample data */ for (i = 0 ; i < k ; i++ ) { for (item=0; item < sz; item++) d_original[i][item] = ((item ^ i) + 3) & GF_SIZE; } } errors = 0 ; for( i = 0 ; i < k ; i++ ) if (index[i] >= k ) reconstruct ++ ; TICK(ticks[2]); for( i = 0 ; i < k ; i++ ) fec_encode(code, d_original, d_src[i], index[i], sz ); TOCK(ticks[2]); TICK(ticks[1]); if (fec_decode(code, d_src, index, sz)) { fprintf(stderr, "detected singular matrix for %s \n", s); return 1 ; } TOCK(ticks[1]); for (i=0; i<k; i++) if (bcmp(d_original[i], d_src[i], sz )) { errors++; fprintf(stderr, "error reconstructing block %d\n", i); } if (errors) fprintf(stderr, "Errors reconstructing %d blocks out of %d\n", errors, k); fprintf(stderr, " k %3d, l %3d c_enc %10.6f MB/s c_dec %10.6f MB/s \r", k, reconstruct, (double)(k * sz * reconstruct)/(double)ticks[2], (double)(k * sz * reconstruct)/(double)ticks[1]); return errors ; }
int main(int argc, char *argv[]) { char buf[256]; void *code ; int k = 4, n = 8; int i, item, sz = 1; int index[n], re_index[k] ; static u_char **d_original = NULL, **d_src = NULL, **data ; d_original = malloc(k * sizeof(void *)); data = malloc(k * sizeof(void *)); d_src = malloc(n * sizeof(void *)); for (i = 0 ; i < k ; i++ ) { d_original[i] = malloc(sz); data[i] = malloc(sz); } for (i = 0 ; i < n ; i++ ) { d_src[i] = malloc(sz); } code = fec_new(k, n); for (i = 0 ; i < k ; i++ ) { for (item=0; item < 1; item++) { d_original[i][item] = 3+i; printf("d_original[%d][%d] = %d, ",i, item, d_original[i][item]); printf("\n"); } } for( i = 0 ; i < n ; i++ ) { index[i] = n-i-1; printf("index[%d] = %d \n", i, index[i]); } for( i = 0 ; i < n ; i++ ) { printf("=======================================\n"); fec_encode(code, d_original, d_src[i], index[i], sz ); printf("i = %d, d_src = %x, index = %d \n", i, d_src[i][0], index[i]); printf("=======================================\n"); } data[0][0] = d_src[0][0]; data[1][0] = d_src[1][0]; data[2][0] = d_src[2][0]; data[3][0] = d_src[3][0]; re_index[0] = 7; re_index[1] = 6; re_index[2] = 5; re_index[3] = 4; for (i = 0 ; i < k ; i++ ) { for (item=0; item < 1; item++) { printf("before decode data: data[%d][%d] = %d, ",i, item, data[i][item]); printf("\n"); } } fec_decode(code, data, re_index, sz); for (i = 0 ; i < k ; i++ ) { for (item=0; item < 1; item++) { printf("decode data: data[%d][%d] = %d, ",i, item, data[i][item]); printf("\n"); } } fec_free(code); return 0; }