⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 alc_tx.c

📁 这个程序实现了FLUTE协议
💻 C
📖 第 1 页 / 共 3 页
字号:
/* $Author: peltotas $ $Date: 2006/03/16 13:02:07 $ $Revision: 1.79 $ *//* *   MAD-ALCLIB: Implementation of ALC/LCT protocols, Compact No-Code FEC, *   Simple XOR FEC, Reed-Solomon FEC, and RLC Congestion Control protocol. *   Copyright (c) 2003-2006 TUT - Tampere University of Technology *   main authors/contacts: jani.peltotalo@tut.fi and sami.peltotalo@tut.fi * *   This program is free software; you can redistribute it and/or modify *   it under the terms of the GNU General Public License as published by *   the Free Software Foundation; either version 2 of the License, or *   (at your option) any later version. * *   This program is distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY; without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *   GNU General Public License for more details. * *   You should have received a copy of the GNU General Public License *   along with this program; if not, write to the Free Software *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include "inc.h"/**** Private functions ****/int calculate_packet_length(alc_session_t *s);int send_unit(trans_unit_t *tr_unit, trans_block_t *tr_block, alc_session_t *s,			  alc_channel_t *ch,#ifdef WIN32			ULONGLONG toi,			ULONGLONG toilen,#else			unsigned long long toi,			unsigned long long toilen,#endif			unsigned int max_sblen,			unsigned short eslen,			unsigned char fec_enc_id,			unsigned short fec_inst_id);int add_pkt_to_tx_queue(alc_session_t *s, unsigned char *sendbuf,  unsigned int sendlen);/* * This function sends source block from object to channel or tx_queue. * * Params:	int *s_id: Pointer to Session identifier, *			int *ch_id: Pointer to Channel identifier (if NULL use queue mode), *			char *buf: Pointer to data to be sent, *			ULONGLONG/unsigned long long buf_len: Lenght of data to be sent, *			ULONGLONG/unsigned long long toi: Transport Object Identifier, *			ULONGLONG/unsigned long long toilen: Length of transport object, *			unsigned short eslen: Encoding Symbol Length, *			unsigned int max_sblen: Maximum-Size Source Block Length, *			unsigned int sbn: Souirce Block Number, *			unsigned char fec_enc_id: FEC Encoding ID, *			unsigned short fec_inst_id: FEC Instance ID, *			int is_last_block: is this last block for object (1 = yes, 0 = no). * * Return:	int: 0 after succesfull sending, -1 otherwise * */int alc_send(int *s_id, int *ch_id, char *buf, int buf_len,#ifdef WIN32			 ULONGLONG toi,			 ULONGLONG toi_len,#else			 unsigned long long toi,			 unsigned long long toi_len,#endif			 unsigned short es_len, unsigned int max_sb_len, unsigned int sbn,			 unsigned char fec_enc_id, unsigned short fec_inst_id) {	trans_block_t *tr_block = NULL;	trans_unit_t *tr_unit = NULL;	unsigned int i = 0;		alc_channel_t *ch = NULL;	alc_session_t *s = NULL;	int sent = 0;        int tb_data_left = 0;	int packet_length = 0;	double interval = 0;	double packetpersec = 0;	double currenttime = 0;	double lasttime = 0;	int addr_family = 0;	int use_fec_oti_ext_hdr = 0;	double loss_prob = 0;	int retval = 0;	double tx_percent = 0;	s = get_alc_session(*s_id);	if(ch_id != NULL) { /* Null-CC and one channel */		ch = s->ch_list[*ch_id];		addr_family = s->addr_family;		use_fec_oti_ext_hdr = s->use_fec_oti_ext_hdr;			if(toi == FDT_TOI) {			/* eslen + DEF_LCT_HDR + TSI + TOI + EXT_FDT + EXT_CENC + EXT_FTI + FEC_PL_ID + UDP + IP */ 			if(addr_family == PF_INET) {				if(((fec_enc_id == COM_NO_C_FEC_ENC_ID) || (fec_enc_id == COM_FEC_ENC_ID))) {					packet_length =  es_len + (sizeof(def_lct_hdr_t) + 4 + 4 + 4 + 4 + 16 + 4 + 8 + 20); 				}				else if(((fec_enc_id == SIMPLE_XOR_FEC_ENC_ID) || (fec_enc_id == SB_LB_E_FEC_ENC_ID) ||					(fec_enc_id == SB_SYS_FEC_ENC_ID))) {					packet_length =  es_len + (sizeof(def_lct_hdr_t) + 4 + 4 + 4 + 4 + 16 + 8 + 8 + 20); 				}			}			else if(addr_family == PF_INET6) {				if(((fec_enc_id == COM_NO_C_FEC_ENC_ID) || (fec_enc_id == COM_FEC_ENC_ID))) {					packet_length =  es_len + (sizeof(def_lct_hdr_t) + 4 + 4 + 4 + 4 + 16 + 4 + 8 + 40); 				}				else if(((fec_enc_id == SIMPLE_XOR_FEC_ENC_ID) || (fec_enc_id == SB_LB_E_FEC_ENC_ID) ||					(fec_enc_id == SB_SYS_FEC_ENC_ID))) {					packet_length =  es_len + (sizeof(def_lct_hdr_t) + 4 + 4 + 4 + 4 + 16 + 8 + 8 + 40); 				}			}		}		else {			if(addr_family == PF_INET) {				if(use_fec_oti_ext_hdr == 1) {					/* eslen + DEF_LCT_HDR + TSI + TOI + EXT_FTI + FEC_PL_ID + UDP + IP */ 										if(((fec_enc_id == COM_NO_C_FEC_ENC_ID) || (fec_enc_id == COM_FEC_ENC_ID))) {						packet_length =  es_len + (sizeof(def_lct_hdr_t) + 4 + 4 + 16 + 4 + 8 + 20); 					}					else if(((fec_enc_id == SIMPLE_XOR_FEC_ENC_ID) || (fec_enc_id == SB_LB_E_FEC_ENC_ID) ||						(fec_enc_id == SB_SYS_FEC_ENC_ID))) {						packet_length =  es_len + (sizeof(def_lct_hdr_t) + 4 + 4 + 16 + 8 + 8 + 20); 					}				}				else if(use_fec_oti_ext_hdr == 0) {					/* eslen + DEF_LCT_HDR + TSI + TOI + FEC_PL_ID + UDP + IP */ 										if(((fec_enc_id == COM_NO_C_FEC_ENC_ID) || (fec_enc_id == COM_FEC_ENC_ID))) {						packet_length =  es_len + (sizeof(def_lct_hdr_t) + 4 + 4 + 4 + 8 + 20); 					}					else if(((fec_enc_id == SIMPLE_XOR_FEC_ENC_ID) || (fec_enc_id == SB_LB_E_FEC_ENC_ID) ||						(fec_enc_id == SB_SYS_FEC_ENC_ID))) {						packet_length =  es_len + (sizeof(def_lct_hdr_t) + 4 + 4 + 8 + 8 + 20); 					}				}			}			else if(addr_family == PF_INET6) {				if(use_fec_oti_ext_hdr == 1) {					/* eslen + DEF_LCT_HDR + TSI + TOI + EXT_FTI + FEC_PL_ID + UDP + IP */ 										if(((fec_enc_id == COM_NO_C_FEC_ENC_ID) || (fec_enc_id == COM_FEC_ENC_ID))) {						packet_length =  es_len + (sizeof(def_lct_hdr_t) + 4 + 4 + 16 + 4 + 8 + 40); 					}					else if(((fec_enc_id == SIMPLE_XOR_FEC_ENC_ID) || (fec_enc_id == SB_LB_E_FEC_ENC_ID) ||						(fec_enc_id == SB_SYS_FEC_ENC_ID))) {						packet_length =  es_len + (sizeof(def_lct_hdr_t) + 4 + 4 + 16 + 8 + 8 + 40); 					}				}				else if(use_fec_oti_ext_hdr == 0) {					/* eslen + DEF_LCT_HDR + TSI + TOI + FEC_PL_ID + UDP + IP */ 										if(((fec_enc_id == COM_NO_C_FEC_ENC_ID) || (fec_enc_id == COM_FEC_ENC_ID))) {						packet_length =  es_len + (sizeof(def_lct_hdr_t) + 4 + 4 + 4 + 8 + 40); 					}					else if(((fec_enc_id == SIMPLE_XOR_FEC_ENC_ID) || (fec_enc_id == SB_LB_E_FEC_ENC_ID) ||						(fec_enc_id == SB_SYS_FEC_ENC_ID))) {						packet_length =  es_len + (sizeof(def_lct_hdr_t) + 4 + 4 + 8 + 8 + 40); 					}				}			}		}		 		packetpersec = ((double)(ch->tx_rate * 1000) / (double)(packet_length * 8));   		interval = ((double)1 / packetpersec);	}	if(fec_enc_id == COM_NO_C_FEC_ENC_ID) {		tr_block = null_fec_encode_src_block(buf, buf_len, sbn, es_len);	}	else if(fec_enc_id == SIMPLE_XOR_FEC_ENC_ID) {		tr_block = xor_fec_encode_src_block(buf, buf_len, sbn, es_len);	}	else if(((fec_enc_id == SB_SYS_FEC_ENC_ID) && (fec_inst_id == REED_SOL_FEC_INST_ID))) {		tr_block = rs_fec_encode_src_block(buf, buf_len, sbn, es_len, s->def_fec_ratio,						   max_sb_len);	}	else {		printf("FEC Encoding %i/%i is not supported!\n", fec_enc_id, fec_inst_id);		return -1; 	}	if(tr_block == NULL) {		return -1;	}	if(ch_id != NULL) {		lasttime = sec();		tb_data_left = es_len * tr_block->n;		tr_unit = tr_block->unit_list;					for(i = 0; i < tr_block->n; i++) {			while(1) {				if(s->state == SExiting) {					while(1) {						free(tr_unit->data);						if(tr_unit->esi == (tr_block->n - 1)) {							break;						}						tr_unit++;					}									free(tr_block->unit_list);					free(tr_block);					return -2;				}				currenttime = sec();		                				if (ch->s->calculate_session_size == false) {					while (currenttime < (lasttime + interval)) {						if(s->optimize_tx_rate) {#ifdef WIN32						Sleep(0);#else						usleep(0);#endif						}						else {#ifdef WIN32						  Sleep(1);#else					      usleep(1000);#endif					    }					    currenttime = sec();					}				}					loss_prob = 0;					if(s->simul_losses) {						if(ch->previous_lost == true) {							loss_prob = s->loss_ratio2;						}						else {							loss_prob = s->loss_ratio1;						}					}					if(!randomloss(loss_prob)) {						retval = send_unit(tr_unit, tr_block, s, ch, toi, toi_len, max_sb_len, es_len,											fec_enc_id, fec_inst_id);						if(retval < 0) {														while(1) {								free(tr_unit->data);								if(tr_unit->esi == (tr_block->n - 1)) {									break;								}								tr_unit++;							}													free(tr_block->unit_list);							free(tr_block);							return -1;						}						sent += tr_unit->len;                                                add_object_sent_bytes(*s_id, tb_data_left < tr_unit->len ?                                                                       (unsigned int)tb_data_left : tr_unit->len); 						tb_data_left -= tb_data_left < tr_unit->len ? tb_data_left : tr_unit->len;												if(((toi == FDT_TOI && s->verbosity == 4) || (toi != FDT_TOI && s->verbosity > 1))) {#ifdef WIN32						  tx_percent = (double)((double)(100 * ((double)(LONGLONG)get_object_sent_bytes(*s_id)/											(double)(LONGLONG)toi_len)));						  						  if(((tx_percent >= (get_object_last_print_tx_percent(*s_id) + 1))						      || (tx_percent == 100))) {						    set_object_last_print_tx_percent(*s_id, tx_percent);						    printf("%.2f%% of object sent (TOI=%I64u)\n", tx_percent, toi);						  }#else						  tx_percent = (double)((double)(100 *										 ((double)(long long)get_object_sent_bytes(*s_id)/										  (double)(long long)toi_len)));						  						  if(((tx_percent >= (get_object_last_print_tx_percent(*s_id) + 1))						      || (tx_percent == 100))) {						    set_object_last_print_tx_percent(*s_id, tx_percent);						    printf("%.2f%% of object sent (TOI=%llu)\n", tx_percent, toi);						  }						  #endif													  fflush(stdout);						}													ch->previous_lost = false;					}					else {						ch->previous_lost = true;					}									lasttime += interval;					break;				}			free(tr_unit->data);			tr_unit++;		}		free(tr_block->unit_list);		free(tr_block);	}	else {		tr_unit = tr_block->unit_list;				for(i = 0; i < tr_block->n; i++) {						retval = send_unit(tr_unit, tr_block, s, NULL, toi, toi_len,								max_sb_len, es_len, fec_enc_id, fec_inst_id);					if(retval == -1) {				i--;				continue;			}			else if(retval == -2) {				while(1) {					free(tr_unit->data);					if(tr_unit->esi == (tr_block->n - 1)) {						break;					}	 					tr_unit++;				}								free(tr_block->unit_list);				free(tr_block);				return retval;					}			free(tr_unit->data);			tr_unit++;		}		free(tr_block->unit_list);		free(tr_block);	}	return sent;}/* * This function sends one unit to tx_queue. * * Params:	trans_unit_t *tr_unit: Pointer to transport unit to be sent, *			trans_block_t *tr_block: Pointer to transport block that this units belongs, *			alc_session_t *s: Pointer to session, *			alc_channel_t *ch: Pointer to channel, *			unsigned int toi: Transport Object Identifier, *			ULONGLONG/unsigned long long toilen: Length of transport object, *			unsigned int max_sblen: Maximum-Size Source Block Length, *			unsigned short eslen: Encoding Symbol Length, *			unsigned char fec_enc_id: FEC Encoding ID, *			unsigned short fec_inst_id: FEC Instance ID. * * Return:	int: 0 in success, -1 or -2  in error/stopping cases. * */int send_unit(trans_unit_t *tr_unit, trans_block_t *tr_block, alc_session_t *s,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -