Exemplo n.º 1
0
int parse_sdp_file(arguments_t *a, char addrs[MAX_CHANNELS_IN_SESSION][INET6_ADDRSTRLEN],
		   char ports[MAX_CHANNELS_IN_SESSION][MAX_PORT_LENGTH], char *sdp_buf) {
  int i;
  int m_lines = 0;
  int j = 0;
  int number_of_port;
  int number_of_address;
  int nb_of_accepted_ch = 0;
  int nb_of_defined_ch = 0;
  
  struct sockaddr_in ipv4;
  struct sockaddr_in6 ipv6;
  
  int position = 0;
  
#ifdef _MSC_VER
  int addr_size;
#else
  char *ep;
#endif
  
  int m_line_att_pos;
  char *att_name;
  char *att_value;
  BOOL supported_fec = FALSE;
  BOOL fec_inst_exists = FALSE;

  char *addr_type = NULL;
  char *source_filter = NULL;
  char *tsi = NULL;
  char *flute_ch = NULL;
  int flute_ch_number;
  char *start_time = NULL;
  char *stop_time = NULL;
  fec_dec_t *fec_dec;
  fec_dec_t *current_fec_dec;
  
  sdp_message_init(&a->sdp);

  if(sdp_message_parse(a->sdp, sdp_buf) != 0) {
    printf("Error: sdp_parse()\n");
    fflush(stdout);
    return -1;
  }
  
  if((source_filter = sdp_attr_get(a->sdp, "source-filter")) == NULL) {
    printf("Error: Invalid SDP, source-filter not present.\n");
    fflush(stdout);
	return -1;
  }
  else {
	  a->src_filt = sf_char2struct(source_filter);
	  a->alc_a.src_addr = a->src_filt->src_addr;
  }

  if((tsi = sdp_attr_get(a->sdp, "flute-tsi")) == NULL) {
    printf("Error: Invalid SDP, TSI not present.\n");
    fflush(stdout);
	return -1;
  }
  else {
	a->alc_a.tsi = (unsigned int)atoi(tsi);
  }

  /* Default channel number is one and it is overwrited if there is
     'a:flute-ch' in the SDP file. */
  
  flute_ch_number = 1;
  flute_ch = sdp_attr_get(a->sdp, "flute-ch");
  
  if(flute_ch != NULL) {
    flute_ch_number = (unsigned int)atoi(flute_ch);
  }

  if((addr_type = sdp_message_c_addrtype_get(a->sdp, 0, 0)) == NULL) {
    printf("Error: Invalid SDP, no valid 'c' field.\n");
    fflush(stdout);
	return -1;
  }
  else {
	if(strcmp(addr_type, "IP4") == 0) {
		a->alc_a.addr_family = PF_INET;
	}
	else if(strcmp(addr_type, "IP6") == 0) {
		a->alc_a.addr_family = PF_INET6;
	}
	else {
		printf("Error: Invalid SDP, address type invalid.\n");
		fflush(stdout);
		return -1;
	}
  }
  
  /* fetch session starttime */
  
  start_time = sdp_message_t_start_time_get (a->sdp, 0);
  
  if(start_time != NULL) {
#ifdef _MSC_VER			  
    a->alc_a.start_time = _atoi64(start_time);
    
    if(a->alc_a.start_time > (unsigned long long)0xFFFFFFFFFFFFFFFF) {
      printf("Error: Invalid SDP, start time too big.\n");
      fflush(stdout);   
      return -1;
    }
#else				
    a->alc_a.start_time = strtoull(start_time, &ep, 10);
    
    if(errno == ERANGE && a->alc_a.start_time == 0xFFFFFFFFFFFFFFFFULL) {
      printf("Error: Invalid SDP, start time too big.\n");
      fflush(stdout); 
      return -1;
    }
#endif	
  }
  
  /* fetch session stoptime */
  
  stop_time = sdp_message_t_stop_time_get (a->sdp, 0);
  
  if(stop_time != NULL) {
#ifdef _MSC_VER			  
    a->alc_a.stop_time = _atoi64(stop_time);
    
    if(a->alc_a.stop_time > (unsigned long long)0xFFFFFFFFFFFFFFFF) {
      printf("Error: Invalid SDP, stop time too big.\n");
      fflush(stdout);   
      return -1;
    }
#else				
    a->alc_a.stop_time = strtoull(stop_time, &ep, 10);
    
    if(errno == ERANGE && a->alc_a.stop_time == 0xFFFFFFFFFFFFFFFFULL) {
      printf("Error: Invalid SDP, stop time too big.\n");
      fflush(stdout); 
      return -1;
    }
#endif
	if(a->alc_a.stop_time == 0) {
		a->cont = TRUE;
	}
  }
  
  /* Session level FEC declaration */
  fec_dec = sdp_fec_dec_get(a->sdp);
  
  /* Search how many m-lines is defined in SDP */

  while(1) {
	  if(sdp_message_endof_media(a->sdp, position) == 0) {
		  /* check that 'proto' field is FLUTE/UDP */
		  if(strcmp(sdp_message_m_proto_get(a->sdp, position), "FLUTE/UDP") == 0) {
			  /* check that payload number exists */
			  if(sdp_message_m_payload_get(a->sdp, position, 0) != NULL) {
				  m_lines++;
			  }
		  }
		  position++;
	  }
	  else {
		  break;
	  }
  }
  
  if(m_lines == 0) {
    printf("Error: Invalid SDP, no valid 'm' field.\n");
    fflush(stdout);
    fec_dec_free(fec_dec);
    return -1;
  }
  
  for(i = 0; i < m_lines; i++) {
    
    m_line_att_pos = 0;
    
    while((att_name = sdp_message_a_att_field_get(a->sdp, i, m_line_att_pos)) != NULL) {
      
      if(strcmp(att_name, "FEC") == 0) {
	fec_inst_exists = TRUE;
	att_value = sdp_message_a_att_value_get(a->sdp, i, m_line_att_pos);
	
	if(fec_dec == NULL) {
	  printf("Error: Invalid SDP, FEC-declaration does not exists.\n");
	  fflush(stdout);
	  return -1;
	}
	
	current_fec_dec = fec_dec;
	
	while(current_fec_dec != NULL) {
	  
	  if(current_fec_dec->index == (unsigned int)atoi(att_value)) {
	    
	    if(current_fec_dec->fec_enc_id == COM_NO_C_FEC_ENC_ID) {
	      a->alc_a.fec_enc_id = COM_NO_C_FEC_ENC_ID;
	      a->alc_a.fec_inst_id = 0;
	      supported_fec = TRUE;
	    }
	    else if(current_fec_dec->fec_enc_id == SIMPLE_XOR_FEC_ENC_ID) {
	      a->alc_a.fec_enc_id = SIMPLE_XOR_FEC_ENC_ID;
	      a->alc_a.fec_inst_id = 0;
	      supported_fec = TRUE;
	    }
	    else if(current_fec_dec->fec_enc_id  == RS_FEC_ENC_ID) {
              a->alc_a.fec_enc_id = RS_FEC_ENC_ID;
              a->alc_a.fec_inst_id = 0;
              supported_fec = TRUE;
        }
	    else if(current_fec_dec->fec_enc_id  == SB_SYS_FEC_ENC_ID &&
		    current_fec_dec->fec_inst_id == REED_SOL_FEC_INST_ID) {
	      a->alc_a.fec_enc_id = SB_SYS_FEC_ENC_ID;
	      a->alc_a.fec_inst_id = REED_SOL_FEC_INST_ID;
	      supported_fec = TRUE;
	    }
	  }
	  current_fec_dec = current_fec_dec->next;
	}
      }
      else if(strcmp(att_name, "FEC-declaration") == 0) {
	fec_inst_exists = TRUE;
	att_value = sdp_message_a_att_value_get(a->sdp, i, m_line_att_pos);
	
	current_fec_dec = fec_dec_char2struct(att_value);
	
	if(current_fec_dec->fec_enc_id == COM_NO_C_FEC_ENC_ID) {
	  a->alc_a.fec_enc_id = COM_NO_C_FEC_ENC_ID;
	  a->alc_a.fec_inst_id = 0;
	  supported_fec = TRUE;
	}
	else if(current_fec_dec->fec_enc_id == SIMPLE_XOR_FEC_ENC_ID) {
	  a->alc_a.fec_enc_id = SIMPLE_XOR_FEC_ENC_ID;
	  a->alc_a.fec_inst_id = 0;
	  supported_fec = TRUE;
	}
	else if(current_fec_dec->fec_enc_id  == RS_FEC_ENC_ID) {
	  a->alc_a.fec_enc_id = RS_FEC_ENC_ID;
	  a->alc_a.fec_inst_id = 0;
	  supported_fec = TRUE;
	}
	else if(current_fec_dec->fec_enc_id == SB_SYS_FEC_ENC_ID &&
		current_fec_dec->fec_inst_id == REED_SOL_FEC_INST_ID) {
	  a->alc_a.fec_enc_id = SB_SYS_FEC_ENC_ID;
	  a->alc_a.fec_inst_id = REED_SOL_FEC_INST_ID;
	  supported_fec = TRUE;
	}
	
	fec_dec_free(current_fec_dec);
      }
      m_line_att_pos++;
    }
  
    if(fec_inst_exists == FALSE) {
      supported_fec = TRUE;
      a->alc_a.fec_enc_id = COM_NO_C_FEC_ENC_ID;
      a->alc_a.fec_inst_id = 0;
    }
  
    /* how many ports in m-line */
    
    if(sdp_message_m_number_of_port_get(a->sdp, i) == NULL) {
      number_of_port = 1;
    }
    else {
      number_of_port = atoi(sdp_message_m_number_of_port_get(a->sdp, i));
    }
    
    /* how many addresses in c-line */
    
    if(sdp_message_c_addr_multicast_int_get(a->sdp, i, 0) == NULL) {
      number_of_address = 1;
    }
    else {
      number_of_address = atoi(sdp_message_c_addr_multicast_int_get(a->sdp, i, 0));
    }
    
    if(((number_of_port != 1) && (number_of_address != 1))) {
      printf("Error: Invalid SDP, confusing number of ports and addresses.\n");
      fflush(stdout);
      fec_dec_free(fec_dec);   
      return -1;
    }
    
    if(number_of_address == 1) {

      for(j = 0; j < number_of_port; j++) {	
	if(supported_fec == TRUE) {
	  memset(ports[nb_of_accepted_ch], 0, MAX_PORT_LENGTH);
	  memset(addrs[nb_of_accepted_ch], 0, INET6_ADDRSTRLEN); 
	  sprintf(ports[nb_of_accepted_ch], "%i", (atoi(sdp_message_m_port_get(a->sdp, i)) + j));
	  strcpy(addrs[nb_of_accepted_ch], sdp_message_c_addr_get(a->sdp, i, 0));

	  nb_of_accepted_ch++;
	}
	nb_of_defined_ch++;
      }
    }
    else if(number_of_port == 1) {

      for(j = 0; j < number_of_address; j++) {
	if(supported_fec == TRUE) {
	  if(a->alc_a.addr_family == PF_INET) {
	    memset(addrs[nb_of_accepted_ch], 0, INET6_ADDRSTRLEN);
	    ipv4.sin_addr.s_addr = htonl(ntohl(inet_addr(a->alc_a.addr)) + j);
	    sprintf(addrs[j], "%s", inet_ntoa(ipv4.sin_addr));
	    
	    memset(ports[nb_of_accepted_ch], 0, MAX_PORT_LENGTH);
	    sprintf(ports[nb_of_accepted_ch], "%i",  atoi(sdp_message_m_port_get(a->sdp, i)));
	  }
	  else if(a->alc_a.addr_family == PF_INET6) {
#ifdef _MSC_VER
	    addr_size = sizeof(struct sockaddr_in6);
	    WSAStringToAddress((char*)a->alc_a.addr, AF_INET6, NULL, (struct sockaddr*)&ipv6, &addr_size);
#else 
	    inet_pton(AF_INET6, a->alc_a.addr, &ipv6.sin6_addr);
#endif
	    
	    memset(addrs[nb_of_accepted_ch], 0, INET6_ADDRSTRLEN);

#ifdef _MSC_VER
	    addr_size = sizeof(addrs[nb_of_accepted_ch]);
		WSAAddressToString((struct sockaddr*)&ipv6, sizeof(struct sockaddr_in6),
			NULL, addrs[nb_of_accepted_ch], &addr_size);
#else
	    inet_ntop(AF_INET6, &ipv6.sin6_addr, addrs[nb_of_accepted_ch], sizeof(addrs[nb_of_accepted_ch]));
#endif
	    
	    memset(ports[nb_of_accepted_ch], 0, MAX_PORT_LENGTH);
	    sprintf(ports[nb_of_accepted_ch], "%i",  atoi(sdp_message_m_port_get(a->sdp, i)));
	    
	    if(j < (a->alc_a.nb_channel - 1)) {
	      if(increase_ipv6_address(&ipv6.sin6_addr) == -1) {
		printf("Increasing IPv6 address %s is not possible\n", addrs[j]);
		fec_dec_free(fec_dec);
		return -1;
	      }
	    }
	  }
	  nb_of_accepted_ch++;
	}
	nb_of_defined_ch++;
      }
    }
  }
    
  if(flute_ch_number != nb_of_defined_ch) {
    printf("Error: Invalid SDP, channel number not correct.\n");
    fflush(stdout);
    fec_dec_free(fec_dec);
    return -1;
  }
  
  a->alc_a.nb_channel = nb_of_accepted_ch;
  
  fec_dec_free(fec_dec);
  
  return 0;
}
Exemplo n.º 2
0
int mad_rlc_process_rx_sp(alc_session_t *s) {

  static char addrs[MAX_CHANNELS_IN_SESSION][INET6_ADDRSTRLEN];	/* multicast addresses */
  static char ports[MAX_CHANNELS_IN_SESSION][MAX_PORT_LENGTH];	/* local port numbers  */

  struct sockaddr_in ipv4;
  struct sockaddr_in6 ipv6;

#ifdef _MSC_VER
  int addr_size;
#endif

  int retcode;
  
  int retval = 0;
  
  if(s->rlc->rx_nblost_since_sp <= s->rlc->loss_accepted
     && s->rlc->rx_nblate_since_sp <= s->rlc->late_accepted) {
    
    if(s->addr_family == PF_INET) {
      if(s->addr_type == 1) {
	ipv4.sin_addr.s_addr = htonl(ntohl(inet_addr(s->ch_list[s->nb_channel - 1]->addr)));
      }
      else {
	ipv4.sin_addr.s_addr = htonl(ntohl(inet_addr(s->ch_list[s->nb_channel - 1]->addr)) + 1);
      }
      
      memset(addrs[s->nb_channel], 0, INET6_ADDRSTRLEN);
      sprintf(addrs[s->nb_channel], "%s", inet_ntoa(ipv4.sin_addr));
      
      memset(ports[s->nb_channel], 0, MAX_PORT_LENGTH);
      sprintf(ports[s->nb_channel], "%i", (atoi(s->ch_list[s->nb_channel - 1]->port) + 1));
    }
    else if(s->addr_family == PF_INET6) {
      
#ifdef _MSC_VER
	addr_size = sizeof(struct sockaddr_in6);
	WSAStringToAddress((char*)s->ch_list[s->nb_channel - 1]->addr, AF_INET6, NULL, (struct sockaddr*)&ipv6, &addr_size);
#else 
	inet_pton(AF_INET6, s->ch_list[s->nb_channel - 1]->addr, &ipv6.sin6_addr);
#endif

      if(s->addr_type == 0) {
	if(increase_ipv6_address(&ipv6.sin6_addr) == -1) {
	  printf("Increasing IPv6 address %s is not possible\n", s->ch_list[s->nb_channel - 1]->addr);
	  return -1;
	}
      }
      
      memset(addrs[s->nb_channel], 0, INET6_ADDRSTRLEN);

#ifdef _MSC_VER
	  addr_size = sizeof(addrs[s->nb_channel]);
      WSAAddressToString((struct sockaddr*)&ipv6, sizeof(struct sockaddr_in6),
			NULL, addrs[s->nb_channel], &addr_size);
#else
	  inet_ntop(AF_INET6, &ipv6.sin6_addr, addrs[s->nb_channel], sizeof(addrs[s->nb_channel]));
#endif
      
      memset(ports[s->nb_channel], 0, MAX_PORT_LENGTH);
      sprintf(ports[s->nb_channel], "%i", (atoi(s->ch_list[s->nb_channel - 1]->port) + 1));
    }
    
    retcode = add_alc_channel(s->s_id, ports[s->nb_channel], addrs[s->nb_channel],
			      s->ch_list[s->nb_channel - 1]->intface,
			      s->ch_list[s->nb_channel - 1]->intface_name);
    
    if(!(retcode < 0)) {
      s->rlc->rx_nblost_since_sp = 0;
      s->rlc->rx_nblate_since_sp = 0;
      retval = 1;
    }
  }
  
  return retval;
}