<commit_before>/* * 
 *  This file is part of Feng
 * 
 * Copyright (C) 2007 by LScube team <<EMAIL>> 
 * See AUTHORS for more details 
 *  
 * Feng 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.
 * 
 * Feng 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 Feng; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 *  
 * */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <fenice/rtcp.h>

#include <fenice/utils.h>
#include <fenice/fnc_log.h>
#include <netinet/in.h>

int RTCP_send_packet(RTP_session * session, rtcp_pkt_type type)
{
    unsigned char *pkt = NULL;
    RTCP_header hdr;
    uint32_t pkt_size = 0, hdr_s = 0;
    Track *t = r_selected_track(session->track_selector);

    hdr.version = 2;
    hdr.padding = 0;
    hdr.pt = type;
    hdr_s = sizeof(hdr);
    switch (type) {
    case SR:{
        struct timespec ntp_time;
        double now;
        RTCP_header_SR hdr_sr;
        int hdr_sr_s;
        hdr_sr_s = sizeof(hdr_sr);
        pkt_size = hdr_s + hdr_sr_s;
        hdr.length = htons((pkt_size >> 2) - 1);
        hdr.count = 0;
        hdr_sr.ssrc = htonl(session->ssrc);

        now = gettimeinseconds(&ntp_time);
        hdr_sr.ntp_timestampH =
            htonl((unsigned int) ntp_time.tv_sec + 2208988800u);
        hdr_sr.ntp_timestampL =
            htonl((((uint64_t) ntp_time.tv_nsec) << 32) / 1000000000u);
        hdr_sr.rtp_timestamp =
            htonl((unsigned int) ((now - session->start_time) *
                  t->properties->clock_rate) + session->start_rtptime);

        hdr_sr.pkt_count = htonl(session->rtcp_stats[i_server].pkt_count);
        hdr_sr.octet_count = htonl(session->rtcp_stats[i_server].octet_count);
        pkt = calloc(1, pkt_size);
        if (pkt == NULL)
            return ERR_ALLOC;
        memcpy(pkt, &hdr, hdr_s);
        memcpy(pkt + hdr_s, &hdr_sr, hdr_sr_s);
        break;
    }
    case RR:{
        RTCP_header_RR hdr_rr;
        int hdr_rr_s;
        hdr_rr_s = sizeof(hdr_rr);
        pkt_size = hdr_s + hdr_rr_s;
        hdr.length = htons((pkt_size >> 2) - 1);
        hdr.count = 0;
        hdr_rr.ssrc = htonl(session->ssrc);
        pkt = calloc(1, pkt_size);
        if (pkt == NULL)
            return ERR_ALLOC;
        memcpy(pkt, &hdr, hdr_s);
        memcpy(pkt + hdr_s, &hdr_rr, hdr_rr_s);
        break;
    }
    case SDES:{
        RTCP_header_SDES hdr_sdes;
        char *name;
        int hdr_sdes_s, name_s;

        name = prefs_get_hostname();
        name_s = strlen(name);
        hdr_sdes_s = sizeof(hdr_sdes);

        pkt_size = (((hdr_s + hdr_sdes_s + name_s) % 4) ? 1 : 0) +
                    hdr_s + hdr_sdes_s + name_s;
        hdr.length = htons((pkt_size >> 2) - 1);

        pkt = calloc(1, pkt_size);
        if (pkt == NULL)
            return ERR_ALLOC;
        hdr.count = 1;
        hdr_sdes.ssrc = htonl(session->ssrc);
        hdr_sdes.attr_name = CNAME;    // 1=CNAME
        hdr_sdes.len = name_s;
        memcpy(pkt, &hdr, hdr_s);
        memcpy(pkt + hdr_s, &hdr_sdes, hdr_sdes_s);
        memcpy(pkt + hdr_s + hdr_sdes_s, name, name_s);

        break;
    }
    case BYE:{
        RTCP_header_BYE hdr_bye;
        int hdr_bye_s;
        char reason[20] = "The medium is over.";
        hdr_bye_s = sizeof(hdr_bye);
        pkt_size = hdr_s + hdr_bye_s + sizeof(reason);
        hdr.length = htons((pkt_size >> 2) - 1);
        hdr.count = 1;
        hdr_bye.ssrc = htonl(session->ssrc);
        hdr_bye.length = htonl(strlen(reason));
        pkt = calloc(1, pkt_size);
        if (pkt == NULL)
            return ERR_ALLOC;
        memcpy(pkt, &hdr, hdr_s);
        memcpy(pkt + hdr_s, &hdr_bye, hdr_bye_s);
        memcpy(pkt + hdr_s + hdr_bye_s, reason, sizeof(reason));
        break;
    }
    default:
        return ERR_NOERROR;
    }

    if (session->rtcp_outsize + pkt_size <= sizeof(session->rtcp_outbuffer)) {
        memcpy(session->rtcp_outbuffer + session->rtcp_outsize, pkt, pkt_size);
        session->rtcp_outsize += pkt_size;
    } else {<commit_msg>Factorize the common header memcpy<commit_after>/* * 
 *  This file is part of Feng
 * 
 * Copyright (C) 2007 by LSc<NAME> <<EMAIL>> 
 * See AUTHORS for more details 
 *  
 * Feng 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.
 * 
 * Feng 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 Feng; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 *  
 * */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <fenice/rtcp.h>

#include <fenice/utils.h>
#include <fenice/fnc_log.h>
#include <netinet/in.h>

int RTCP_send_packet(RTP_session * session, rtcp_pkt_type type)
{
    unsigned char *pkt = NULL;
    RTCP_header hdr;
    uint32_t pkt_size = 0, hdr_s = 0;
    Track *t = r_selected_track(session->track_selector);

    hdr.version = 2;
    hdr.padding = 0;
    hdr.pt = type;
    hdr_s = sizeof(hdr);
    switch (type) {
    case SR:{
        struct timespec ntp_time;
        double now;
        RTCP_header_SR hdr_sr;
        int hdr_sr_s;
        hdr_sr_s = sizeof(hdr_sr);
        pkt_size = hdr_sr_s;
        hdr.length = htons((pkt_size >> 2) - 1);
        hdr.count = 0;
        hdr_sr.ssrc = htonl(session->ssrc);

        now = gettimeinseconds(&ntp_time);
        hdr_sr.ntp_timestampH =
            htonl((unsigned int) ntp_time.tv_sec + 2208988800u);
        hdr_sr.ntp_timestampL =
            htonl((((uint64_t) ntp_time.tv_nsec) << 32) / 1000000000u);
        hdr_sr.rtp_timestamp =
            htonl((unsigned int) ((now - session->start_time) *
                  t->properties->clock_rate) + session->start_rtptime);

        hdr_sr.pkt_count = htonl(session->rtcp_stats[i_server].pkt_count);
        hdr_sr.octet_count = htonl(session->rtcp_stats[i_server].octet_count);
        pkt = calloc(1, pkt_size);
        if (pkt == NULL)
            return ERR_ALLOC;
        memcpy(pkt, &hdr_sr, hdr_sr_s);
        break;
    }
    case RR:{
        RTCP_header_RR hdr_rr;
        int hdr_rr_s;
        hdr_rr_s = sizeof(hdr_rr);
        pkt_size = hdr_rr_s;
        hdr.length = htons((pkt_size >> 2) - 1);
        hdr.count = 0;
        hdr_rr.ssrc = htonl(session->ssrc);
        pkt = calloc(1, pkt_size);
        if (pkt == NULL)
            return ERR_ALLOC;
        memcpy(pkt, &hdr_rr, hdr_rr_s);
        break;
    }
    case SDES:{
        RTCP_header_SDES hdr_sdes;
        char *name;
        int hdr_sdes_s, name_s;

        name = prefs_get_hostname();
        name_s = strlen(name);
        hdr_sdes_s = sizeof(hdr_sdes);

        pkt_size = (((hdr_s + hdr_sdes_s + name_s) % 4) ? 1 : 0) +
                    hdr_sdes_s + name_s;
        hdr.length = htons((pkt_size >> 2) - 1);

        pkt = calloc(1, pkt_size);
        if (pkt == NULL)
            return ERR_ALLOC;
        hdr.count = 1;
        hdr_sdes.ssrc = htonl(session->ssrc);
        hdr_sdes.attr_name = CNAME;    // 1=CNAME
        hdr_sdes.len = name_s;
        memcpy(pkt, &hdr_sdes, hdr_sdes_s);
        memcpy(pkt + hdr_sdes_s, name, name_s);
        break;
    }
    case BYE:{
        RTCP_header_BYE hdr_bye;
        int hdr_bye_s;
        char reason[20] = "The medium is over.";
        hdr_bye_s = sizeof(hdr_bye);
        pkt_size = hdr_bye_s + sizeof(reason);
        hdr.length = htons((pkt_size >> 2) - 1);
        hdr.count = 1;
        hdr_bye.ssrc = htonl(session->ssrc);
        hdr_bye.length = htonl(strlen(reason));
        pkt = calloc(1, pkt_size);
        if (pkt == NULL)
            return ERR_ALLOC;
        memcpy(pkt, &hdr_bye, hdr_bye_s);
        memcpy(pkt + hdr_bye_s, reason, sizeof(reason));
        break;
    }
    default:
        return ERR_NOERROR;
    }

    if (session->rtcp_outsize + pkt_size + hdr_s <=
        sizeof(session->rtcp_outbuffer)) {
        memcpy(session->rtcp_outbuffer + session->rtcp_outsize, &hdr, hdr_s);
        memcpy(session->rtcp_outbuffer + session->rtcp_outsize + hdr_s,
               pkt, pkt_size);
        session->rtcp_outsize += pkt_size + hdr_s;
    } else {
{'fraction_non_alphanumeric': 0.11260113044441981, 'fraction_numerical': 0.015072592264213676, 'mean_word_length': 2.2802617230098146, 'pattern_counts': {'":': 0, '<': 28, '<?xml version=': 0, '>': 72, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5360336', 'n_tokens_mistral': 3391, 'n_tokens_neox': 3236, 'n_words': 772}