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

📄 alc_rx.c

📁 这个程序实现了FLUTE协议
💻 C
📖 第 1 页 / 共 3 页
字号:
/* $Author: peltotas $ $Date: 2006/03/14 12:01:00 $ $Revision: 1.86 $ *//* *   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 analyze_packet(char *data, int len, alc_channel_t *ch);int recv_packet(alc_session_t *s);/*   * This function receives packets from all channels in one session in thread. *  * Params:	void *s: Pointer to session	 * * Return:	void * */void* rx_thread(void *s) {		alc_session_t *session;	int retval = 0;	srand((unsigned)time(NULL));	session = (alc_session_t *)s;	while(session->state == SActive) {				if(session->nb_channel != 0) {			retval = recv_packet(session);		}/*#ifdef WIN32		Sleep(1);#else		usleep(1000);#endif*/	}#ifdef WIN32	_endthread();#else	pthread_exit(0);#endif	return NULL;}/*  * This function receives unit(s) from session's channels. *  * Params: alc_session_t *s: Pointer to session	 * * Return: int: Number of correct packets received from ALC session *  */int recv_packet(alc_session_t *s) {		char recvbuf[MAX_PACKET_LENGTH];	int recvlen;	int nb;	int i;	int retval;	int max_fd = 0;	int recv_pkts = 0;	fd_set rfds;	alc_channel_t *ch;	struct timeval tv;	struct sockaddr_storage from;	char hostname[100];	double loss_prob;#ifdef WIN32	int fromlen;#else	socklen_t fromlen;#endif	if(s->addr_family == PF_INET) {		fromlen = sizeof(struct sockaddr_in);	}	else if(s->addr_family == PF_INET6) {		fromlen = sizeof(struct sockaddr_in6);	}	memset(recvbuf, 0, MAX_PACKET_LENGTH);	FD_ZERO(&rfds);	tv.tv_sec = 1;	tv.tv_usec = 0;	for(i = 0; i < s->max_channel; i++) {		ch = s->ch_list[i];		if(ch != NULL) {			FD_SET(ch->rx_sock, &rfds);			max_fd = max((int)ch->rx_sock, max_fd);		}	}	nb = select((max_fd + 1), &rfds, NULL, NULL, &tv);	if(nb <= 0) {		return 0;	}	for(i = 0; i < s->max_channel; i++) {		ch = s->ch_list[i];		if(ch != NULL) {			memset((void *)&from, 0, sizeof(from));			if(FD_ISSET(ch->rx_sock, &rfds)) {				recvlen = recvfrom(ch->rx_sock, recvbuf, MAX_PACKET_LENGTH, 0,						   (struct sockaddr*)&from, &fromlen);				if(recvlen < 0) {					if(s->state == SExiting) {						/*printf("recv_packet() SExiting\n");						fflush(stdout);*/						return -2;					}					else if(s->state == SClosed) {						/*printf("recv_packet() SClosed\n");						fflush(stdout);*/						return 0;					}					else {	#ifdef WIN32						printf("recvfrom failed: %d\n", WSAGetLastError());						fflush(stdout);	#else						printf("recvfrom failed: %d\n", h_errno);	#endif						return -1;					}				}				loss_prob = 0;				if(ch->s->simul_losses) {					if(ch->previous_lost == true) {						loss_prob = ch->s->loss_ratio2;					}					else {						loss_prob = ch->s->loss_ratio1;					}				}				if(!randomloss(loss_prob)) {					getnameinfo((struct sockaddr*)&from, fromlen, hostname, sizeof(hostname), NULL, 0, NI_NUMERICHOST);					if(strcmp(s->src_addr, "") != 0) {						if(strcmp(hostname, s->src_addr) != 0) {						  printf("Packet to wrong session: wrong source: %s\n", hostname);						  fflush(stdout);						  continue;						}					}					retval = analyze_packet(recvbuf, recvlen, ch);					if(strcmp(s->src_addr, "") == 0) {					  if(s->verbosity > 0) {					    printf("Locked to source: %s\n", hostname);					    fflush(stdout);					  }					  memcpy(s->src_addr, hostname, strlen(hostname));					}					if(ch->s->cc_id == RLC) {						if(((ch->s->rlc->drop_highest_layer) && (ch->s->nb_channel != 1))) {							ch->s->rlc->drop_highest_layer = false;							close_alc_channel(ch->s->ch_list[ch->s->nb_channel - 1], ch->s);						}					}					if(retval == HDR_ERROR) {						continue;					}					else if(retval == DUP_PACKET) {						continue;					}					else if(retval == MEM_ERROR) {						return -1;					}										recv_pkts++;									ch->previous_lost = false;				}				else {					ch->previous_lost = true;				}			}		}	}	return recv_pkts;}/* * This function parses and analyzes alc packet. * * Params:	char *data: Pointer to packet's data, *			int len: Length of packet's data, *			alc_channel_t *ch: Pointer to channel * * Return:	int: Status of packet (OK, EMPTY_PACKET, HDR_ERROR, MEM_ERROR, DUP_PACKET) * */int analyze_packet(char *data, int len, alc_channel_t *ch) {  def_lct_hdr_t *def_lct_hdr = NULL;		    int hdrlen = 0;			/* length of whole header */  int retval = 0;  #ifdef WIN32  ULONGLONG tsi = 0;  ULONGLONG toi = 0;  ULONGLONG toi_len = 0;#else  unsigned long long tsi = 0;  unsigned long long toi = 0;  unsigned long long toi_len = 0;#endif    unsigned int sbn = 0;  unsigned int esi = 0;    unsigned short es_len = 0;  unsigned short sb_len = 0;    unsigned int max_sb_len = 0;  unsigned short max_nb_of_es = 0;    short fec_enc_id = 0;  int fec_inst_id = 0;    int fdt_instance_id = 0;  unsigned short flute_version = 0;  unsigned char content_enc_algo = 0;  unsigned short reserved = 0;    unsigned int word = 0;  #ifdef WIN32  ULONGLONG ull = 0;#else  unsigned long long ull = 0;#endif    trans_obj_t *trans_obj = NULL;  trans_block_t *trans_block = NULL;  trans_unit_t *trans_unit = NULL;  trans_unit_t *tu = NULL;  trans_unit_t *next_tu = NULL;  wanted_obj_t *wanted_obj = NULL;    int het = 0;  int hel = 0;  int exthdrlen = 0;    char *buf = NULL;  #ifdef WIN32  ULONGLONG block_len = 0;  ULONGLONG pos = 0;#else  unsigned long long block_len = 0;  unsigned long long pos = 0;#endif    char filename[MAX_PATH];  double rx_percent = 0;  unsigned int i = 0;    if(len < (int)(sizeof(def_lct_hdr_t))) {    printf("analyze_packet: packet too short %d\n", len);    fflush(stdout);    return HDR_ERROR;  }    def_lct_hdr = (def_lct_hdr_t*)data;    *(unsigned short*)def_lct_hdr = ntohs(*(unsigned short*)def_lct_hdr);    hdrlen += (int)(sizeof(def_lct_hdr_t));    if(def_lct_hdr->version != ALC_VERSION) {    printf("ALC version: %i not supported!\n", def_lct_hdr->version);    fflush(stdout);	    return HDR_ERROR;  }    if(def_lct_hdr->reserved != 0) {    printf("Reserved field not zero!\n");    fflush(stdout);    return HDR_ERROR;  }    if(def_lct_hdr->flag_t != 0) {    printf("Sender Current Time not supported!\n");    fflush(stdout);    return HDR_ERROR;  }    if(def_lct_hdr->flag_r != 0) {    printf("Expected Residual Time not supported!\n");    fflush(stdout);    return HDR_ERROR;  }    if(def_lct_hdr->flag_b == 1) {    /**** TODO ****/  }    if(def_lct_hdr->flag_c != 0) {    printf("Only 32 bits CCI-field supported!\n");    fflush(stdout);    return HDR_ERROR;  }  else {    if(def_lct_hdr->cci != 0) {            if(ch->s->cc_id == RLC) {		retval = mad_rlc_analyze_cci(ch->s, (rlc_hdr_t*)(data + 4));		if(retval < 0) {	  return HDR_ERROR;	}      }    }  }    if(def_lct_hdr->flag_h == 1) {        if(def_lct_hdr->flag_s == 0) { /* TSI 16 bits */      word = ntohl(*(unsigned int*)((char*)def_lct_hdr + hdrlen));      hdrlen += 4;            tsi = (word & 0xFFFF0000) >> 16;            if(tsi != ch->s->tsi) {#ifdef WIN32	printf("Packet to wrong session: wrong TSI: %I64u\n", tsi);#else	printf("Packet to wrong session: wrong TSI: %llu\n", tsi);#endif	fflush(stdout);	return HDR_ERROR;      }    }    else if(def_lct_hdr->flag_s == 1) { /* TSI 48 bits */            ull = ntohl(*(unsigned int*)((char*)def_lct_hdr + hdrlen));      tsi = ull << 16;      hdrlen += 4;            word = ntohl(*(unsigned int*)((char*)def_lct_hdr + hdrlen));      hdrlen += 4;            tsi += (word & 0xFFFF0000) >> 16;            if(tsi != ch->s->tsi) {#ifdef WIN32	printf("Packet to wrong session: wrong TSI: %I64u\n", tsi);#else	printf("Packet to wrong session: wrong TSI: %llu\n", tsi);#endif	fflush(stdout);	return HDR_ERROR;      }    }        if(def_lct_hdr->flag_a == 1) {      ch->s->state = STxStopped;    }        if(def_lct_hdr->flag_o == 0) { /* TOI 16 bits */      toi = (word & 0x0000FFFF);    }    else if(def_lct_hdr->flag_o == 1) { /* TOI 48 bits */            ull = (word & 0x0000FFFF);      toi = ull << 32;            toi += ntohl(*(unsigned int*)((char*)def_lct_hdr + hdrlen));      hdrlen += 4;    }    else {      printf("Only 16, 32, 48 or 64 bits TOI-field supported!\n");      fflush(stdout);      return HDR_ERROR;    }    /*else if(def_lct_hdr->flag_o == 2) {			      }      else if(def_lct_hdr->flag_o == 3) {      }*/  }  else {    if(def_lct_hdr->flag_s == 1) { /* TSI 32 bits */      tsi = ntohl(*(unsigned int*)((char*)def_lct_hdr + hdrlen));      hdrlen += 4;            if(tsi != ch->s->tsi) {#ifdef WIN32	printf("Packet to wrong session: wrong TSI: %I64u\n", tsi);#else	printf("Packet to wrong session: wrong TSI: %llu\n", tsi);#endif	fflush(stdout);	return HDR_ERROR;      }    }    else {      printf("Transport Session Identifier not present!\n");      fflush(stdout);      return HDR_ERROR;    }        if(def_lct_hdr->flag_a == 1) {      ch->s->state = STxStopped;    }        if(def_lct_hdr->flag_o == 0) { /* TOI 0 bits */            if(def_lct_hdr->flag_a != 1) {	printf("Transport Object Identifier not present!\n");	fflush(stdout);	return HDR_ERROR;      }      else {	return EMPTY_PACKET;      }    }    else if(def_lct_hdr->flag_o == 1) { /* TOI 32 bits */      toi = ntohl(*(unsigned int*)((char*)def_lct_hdr + hdrlen));      hdrlen += 4;    }    else if(def_lct_hdr->flag_o == 2) { /* TOI 64 bits */            ull = ntohl(*(unsigned int*)((char*)def_lct_hdr + hdrlen));      toi = ull << 32;      hdrlen += 4;            toi += ntohl(*(unsigned int*)((char*)def_lct_hdr + hdrlen));      hdrlen += 4;    }    else {      printf("Only 16, 32, 48 or 64 bits TOI-field supported!\n");      fflush(stdout);      return HDR_ERROR;    }    /*else if(def_lct_hdr->flag_o == 3) {      }*/  }    if(!toi == FDT_TOI) {        wanted_obj = get_wanted_object(ch->s, toi);        if(wanted_obj == NULL) {      /*printf("Packet to not wanted toi: %i\n", toi);	fflush(stdout);*/      return HDR_ERROR;    }        es_len = wanted_obj->es_len;    max_sb_len = wanted_obj->max_sb_len;    max_nb_of_es = wanted_obj->max_nb_of_es;    fec_enc_id = wanted_obj->fec_enc_id;    fec_inst_id = wanted_obj->fec_inst_id;    toi_len = wanted_obj->toi_len;        /* #ifdef USE_ZLIB */    content_enc_algo = wanted_obj->content_enc_algo;    /* #endif */      }    fec_enc_id = def_lct_hdr->codepoint;    if(fec_enc_id == COM_NO_C_FEC_ENC_ID) {  }  else if(fec_enc_id == SB_SYS_FEC_ENC_ID) {  }  else if(fec_enc_id == SIMPLE_XOR_FEC_ENC_ID) {  }  else {    printf("FEC Encoding ID: %i is not supported!\n", fec_enc_id);    fflush(stdout);    return HDR_ERROR;  }    if(def_lct_hdr->hdr_len > (hdrlen >> 2)) {        /* LCT header extensions(EXT_FDT, EXT_CENC, EXT_FTI, EXT_AUTH, EXT_NOP)       go through all possible EH */        exthdrlen = def_lct_hdr->hdr_len - (hdrlen >> 2);        while(exthdrlen > 0) {            word = ntohl(*(unsigned int*)((char*)def_lct_hdr + hdrlen));      hdrlen += 4;      exthdrlen--;            het = (word & 0xFF000000) >> 24;            if(het < 128) {	hel = (word & 0x00FF0000) >> 16;      }            switch(het) {	      case EXT_FDT:		flute_version = (word & 0x00F00000) >> 20;	fdt_instance_id = (word & 0x000FFFFF);		if(flute_version != FLUTE_VERSION) {	  printf("FLUTE version: %i is not supported\n", flute_version);	  return HDR_ERROR;	}		break;	      case EXT_CENC:		content_enc_algo = (word & 0x00FF0000) >> 16;	reserved = (word & 0x0000FFFF);		if(reserved != 0) {	  printf("Bad CENC header extension!\n");	  return HDR_ERROR;	}	#ifdef USE_ZLIB	if((content_enc_algo != 0) && (content_enc_algo != ZLIB)) {	  printf("Only NULL or ZLIB content encoding supported with FDT Instance!\n");	  return HDR_ERROR;	}#else	if(content_enc_algo != 0) {	  printf("Only NULL content encoding supported with FDT Instance!\n");	  return HDR_ERROR;	}#endif		break;	      case EXT_FTI:		if(hel != 4) {	  printf("Bad FTI header extension, length: %i\n", hel);	  return HDR_ERROR;	}		toi_len = ((word & 0x0000FFFF) << 16);		toi_len += ntohl(*(unsigned int*)((char*)def_lct_hdr + hdrlen));	hdrlen += 4;	exthdrlen--;		word = ntohl(*(unsigned int*)((char*)def_lct_hdr + hdrlen));	hdrlen += 4;	exthdrlen--;		fec_inst_id = ((word & 0xFFFF0000) >> 16);		if(fec_enc_id == SB_SYS_FEC_ENC_ID) {	  if(fec_inst_id != REED_SOL_FEC_INST_ID) {	    printf("FEC Encoding %i/%i is not supported!\n", fec_enc_id, fec_inst_id);

⌨️ 快捷键说明

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