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; }
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; }