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

📄 mad_rlc.c

📁 这个程序实现了FLUTE协议
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Author: peltotas $ $Date: 2006/03/08 10:36:28 $ $Revision: 1.11 $ *//* *   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 *//* *   Portions of code derived from MCL library by Vincent Roca et al. *   (http://www.inrialpes.fr/planete/people/roca/mcl/) * *   Copyright (c) 1999-2004 INRIA - Universite Paris 6 - All rights reserved *   (main author: Julien Laboure - julien.laboure@inrialpes.fr *                 Vincent Roca - vincent.roca@inrialpes.fr) */#include "inc.h"static int mad_rlc_check_sequence(alc_session_t *s, int layer, int seqid);static int mad_rlc_process_rx_sp(alc_session_t *s);static int mad_rlc_add_late(alc_session_t *s, int layer, int nseq);static int mad_rlc_remove_late(alc_session_t *s, int layer, int nseq);static int mad_rlc_update_late_list(alc_session_t *s);static int mad_rlc_add_lost (alc_session_t *s);static int mad_rlc_update_loss_list(alc_session_t *s);static void mad_rlc_free_lists(alc_session_t *s);/* * This function initializes MAD RLC Congestion Control. * * Params:	alc_session_t *s: Pointer to session * * Return:	int: 0 in success, -1 otherwise * */int init_mad_rlc(alc_session_t *s) {	int i;	if(!(s->rlc = (mad_rlc_t*)calloc(1, sizeof(mad_rlc_t)))) {		printf("Could not alloc memory for mad rlc congestion control!\n");		return -1;	}	if(s->mode == SENDER) {		s->rlc->sp_cycle  =	RLC_SP_CYCLE;	}	else if(s->mode == RECEIVER) {		s->rlc->drop_highest_layer = false;		s->rlc->pkt_timeout = 	RLC_PKT_TIMEOUT;		s->rlc->deaf_period = 	RLC_DEAF_PERIOD;		s->rlc->loss_accepted =	RLC_LOSS_ACCEPTED;		s->rlc->late_accepted =	RLC_LATE_ACCEPTED;		s->rlc->loss_limit  = 	RLC_LOSS_LIMIT;		s->rlc->loss_timeout = 	RLC_LOSS_TIMEOUT;		s->rlc->rx_deaf_wait  = 0;		for(i = 0 ; i < MAX_CHANNELS_IN_SESSION; i++) {			s->rlc->rx_first_pkt[i] = 1;			s->rlc->rx_first_sp[i] = 0;		}	}		return 0;	}/* * This function closes MAD RLC Congestion Control. * * Params:	alc_session_t *s: Pointer to session * * Return:	void * */void close_mad_rlc(alc_session_t *s) {	if(s->mode == RECEIVER) {		mad_rlc_free_lists(s);	}	free(s->rlc);}/* * This function calculates next SP time. * * Params:	alc_session_t *s: Pointer to session, *			int layer: Layer number. * * Return:	double: Next SP time. * */double mad_rlc_next_sp(alc_session_t *s, int layer) {		double spacing;	double currenttime;	currenttime = sec();	spacing = (double)((double)s->rlc->sp_cycle / (double)1000) * (double)(min((1 << layer), 128 + layer));	return (currenttime + (double)spacing);}/* * This function resets SP. * * Params:	alc_session_t *s: Pointer to session * * Return:	void * */void mad_rlc_reset_tx_sp(alc_session_t *s) {		int i;	for(i = 0 ; i < MAX_CHANNELS_IN_SESSION; i++) {		s->rlc->tx_next_sp[i] = mad_rlc_next_sp(s, i);	}}/* * This function fills RLC header. * * Params:	alc_session_t *s: Pointer to session, *			rlc_hdr_t *rlc_hdr: Pointer to RLC header, *			int layer: Layer number. * * Return:	int: 0 in success, -1 otherwise. * */int mad_rlc_fill_header(alc_session_t *s, rlc_hdr_t *rlc_hdr, int layer) {		unsigned short hdr_seqid;	double currenttime;	currenttime = sec();	if(layer > MAX_CHANNELS_IN_SESSION || layer > s->nb_channel) {		printf("BAD layer!\n");		fflush(stdout);		return -1;	}		hdr_seqid = s->rlc->tx_layers_seq[layer];	s->rlc->tx_layers_seq[layer]++;			rlc_hdr->reserved = 0x55;	/* unused: rlc_reserved = 1010101 */	rlc_hdr->layer = layer;	rlc_hdr->seqid = htons(hdr_seqid);	if(s->rlc->tx_next_sp[layer] <= currenttime) {		if((layer + 1) == s->nb_channel) {			rlc_hdr->sp = 0;			}		else {			/* OK this is a new SP for this layer */			rlc_hdr->sp = 1;			/* calculate when next SP will occur */			s->rlc->tx_next_sp[layer] = mad_rlc_next_sp(s, layer);			if(layer + 1 < MAX_CHANNELS_IN_SESSION &&				s->ch_list[layer + 1]->start_sending == false) {				s->ch_list[layer + 1]->start_sending = true;				s->nb_sending_channel++;			}		}	}	else {	/* not a SP... */		rlc_hdr->sp = 0;	}	return 0;}/* * This function analyzes ALC packets CCI field. * * Params:	alc_session_t *s: Pointer to session, *			rlc_hdr_t *rlc_hdr: Pointer to RLC header.		 * * Return: * */int mad_rlc_analyze_cci(alc_session_t *s, rlc_hdr_t *rlc_hdr) {		unsigned char hdr_layer;		unsigned short hdr_seqid;	unsigned char hdr_sp;	double currenttime;	hdr_seqid = ntohs(rlc_hdr->seqid);	hdr_layer = rlc_hdr->layer;	hdr_sp = rlc_hdr->sp;	if(rlc_hdr->reserved != 0x55) {		return -1;	}	if(rlc_hdr->layer >= s->nb_channel) {		return -1;	}	mad_rlc_update_loss_list(s);	mad_rlc_update_late_list(s);	currenttime = sec();	if(s->rlc->rx_deaf_wait != 0) {				if(s->rlc->rx_deaf_wait > currenttime) {			s->rlc->rx_wait_for[rlc_hdr->layer] = hdr_seqid + 1;			return 0;		}	}	if(s->rlc->rx_first_pkt[hdr_layer]) {		/* First packet on this layer... */		s->rlc->rx_wait_for[hdr_layer] = hdr_seqid + 1;		s->rlc->rx_first_pkt[hdr_layer] = 0;		/* continue as this pkt may contain an SP */	} else {		/* check if some pkts have been lost or not */		mad_rlc_check_sequence(s, hdr_layer, hdr_seqid);	}	if(hdr_sp) {		if(hdr_layer == s->nb_channel - 1) {			/* This is a Synchronisation Point */			if(s->rlc->rx_first_sp[hdr_layer] == 1) {				/* skip 1st SP, especially after deaf-period */				s->rlc->rx_first_sp[hdr_layer] = 0;			} else {				mad_rlc_process_rx_sp(s);			}		}	}	return 0;}/* * This function checks packet's RLC sequence number. * * Params:	alc_session_t *s: Pointer to session, *			int layer: Layer number, *			int seqid: Packet's sequence number. * * Return:	int: 0 * */int mad_rlc_check_sequence(alc_session_t *s, int layer, int seqid) {	unsigned short Delta1;	unsigned short Delta2;	int i;	int late_limit;		if(s->rlc->rx_wait_for[layer] == seqid ) {		/* This is the packet we're waiting for, let's go on! */		s->rlc->rx_wait_for[layer]++;		return 0;	}	/* This is not the one we're waiting for... */	if(s->rlc->rx_wait_for[layer] < seqid) {		Delta1 = seqid - s->rlc->rx_wait_for[layer];		Delta2 = 65535 - Delta1;				if(Delta1 < Delta2) {						late_limit = RLC_MAX_LATES;						for(i = s->rlc->rx_wait_for[layer]; i < seqid; i++) {				mad_rlc_add_late(s, layer, i);				late_limit--;				if(late_limit <= 0 ) {					printf("RLC Warning*** Max number of LATE packets reached\n");					fflush(stdout);					break;				}			}			/* EOFIX */			s->rlc->rx_wait_for[layer] = seqid + 1;		}		else {			/* Late arrival packet (uint16 overflow) */			/* eg. we're waiting seq 4 and we get seq 65532 */			mad_rlc_remove_late(s, layer, seqid);		}	}	else { /* rx_wait_for > rlc_seqid */				Delta1 = s->rlc->rx_wait_for[layer] - seqid;		Delta2 = 65535 - Delta1;		if (Delta1 < Delta2) { /* Late arrival packet */		/* ie: we're waiting seq 501 and we get seq 498 */			mad_rlc_remove_late(s, layer, seqid);		}		else {		/* Some packet(s) are missing (uint16 overflow) */		/* ie: waiting seq 65531 and get seq 3 */			/* FIX 14/12/01 */			late_limit = RLC_MAX_LATES;			for(i = s->rlc->rx_wait_for[layer]; i != (seqid-1); i++) {				mad_rlc_add_late(s, layer, i);				late_limit--;				if(late_limit <= 0 ) {					printf("RLC Warning*** Max number of LATE packets reached\n");					fflush(stdout);					break;				}			}			/* EOFIX */			s->rlc->rx_wait_for[layer] = seqid + 1;		}	}	return 0;}/* * This function process RLC SP. * * Params:	alc_session_t *s: Pointer to session. * * Return:	int: 0 when no new layer, 1 when new layer, -1 otherwise. * */int mad_rlc_process_rx_sp(alc_session_t *s) {	unsigned long addr_nb;	int port_nb;	struct sockaddr_in ipv4;	static char addrs[MAX_CHANNELS_IN_SESSION][MAX_LENGTH];	/* multicast addresses */	static char ports[MAX_CHANNELS_IN_SESSION][MAX_LENGTH];	/* local port numbers  */	int retval = 0;	int ch_id;	unsigned short ipv6addr[8];	int nb_ipv6_part;	int dup_sep = 0;	char tmp[5];	int retcode;	int l, m, k;

⌨️ 快捷键说明

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