<commit_before>/* *
 * This file is part of Feng
 *
 * Copyright (C) 2009 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 Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser 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
 *
 * */

/**
 * @file
 * @brief SDP session description
 *
 * This file contains the function used to generate the SDP session
 * description as needed by @ref RTSP_describe.
 */

#include <string.h>
#include <stdbool.h>

#include "fnc_log.h"
#include "sdp2.h"
#include "mediathread/description.h"
#include <netembryo/wsocket.h>
#include <netembryo/url.h>

#define SDP2_EL "\r\n"
#define DEFAULT_TTL 32

#define NTP_time(t) ((float)t + 2208988800U)

/**
 * @brief Simple pair for compound parameters in foreach functions
 *
 * This data structure is used to pass parameters along with foreach
 * functions, like @ref sdp_mdescr_private_append.
 */
typedef struct {
    /** The string to append the SDP2 description to */
    GString *descr;
    /** The currently-described media description object */
    MediaDescr *media;
} sdp_mdescr_append_pair;

/**
 * @brief Append media private field information to an SDP2 string
 *
 * @param element An sdp_field object in the list
 * @param user_data An sdp_mdescr_append_pair object
 *
 * @internal This function is only to be called by g_list_foreach().
 */
static void sdp_mdescr_private_append(gpointer element, gpointer user_data)
{
    sdp_field *private = (sdp_field *)element;
    sdp_mdescr_append_pair *pair = (sdp_mdescr_append_pair *)user_data;

    switch (private->type) {
    case empty_field:
        g_string_append_printf(pair->descr, "%s"SDP2_EL,
                               private->field);
        break;
    case fmtp:
        g_string_append_printf(pair->descr, "a=fmtp:%u %s"SDP2_EL,
                               m_descr_rtp_pt(pair->media),
                               private->field);
        break;
    case rtpmap:
        g_string_append_printf(pair->descr, "a=rtpmap:%u %s"SDP2_EL,
                               m_descr_rtp_pt(pair->media),
                               private->field);
        break;
    default: /* Ignore other private fields */
        break;
    }
}

/**
 * @brief Append all the private fields for a media description to an
 *        SDP2 string.
 *
 * @param element The media description to append the fields of
 * @param user_data The GString object to append the description to
 *
 * @internal This function is only to be called by g_list_foreach().
 */
static void sdp_mdescr_private_list_append(gpointer element, gpointer user_data)
{
    sdp_mdescr_append_pair pair = {
        .descr = (GString *)user_data,
        .media = (MediaDescr *)element
    };

    g_list_foreach(m_descr_sdp_private(pair.media),
                   sdp_mdescr_private_append,
                   &pair);
}

/**
 * @brief Append the payload type for the media description to an SDP2
 *        string.
 *
 * @param element The media description to append the fields of
 * @param user_data The GString object to append the description to
 *
 * @internal This function is only to be called by g_list_foreach().
 */
static void sdp_mdescr_pt_append(gpointer element, gpointer user_data)
{
    MediaDescr *mdescr = (MediaDescr *)element;
    GString *descr = (GString *)user_data;

    g_string_append_printf(descr, " %u",
                           m_descr_rtp_pt(mdescr));
}

/**
 * @brief Append the description for a given media to an SDP
 *        description.
 *
 * @param element List of MediaDescr instances to fetch the data
 *                     from.
 * @param user_data GString instance to append the description to
 *
 * @internal This function is only to be called by g_ptr_array_foreach().
 */
static void sdp_media_descr(gpointer element, gpointer user_data)
{
    MediaDescrList m_descr_list = (MediaDescrList)element;
    GString *descr = (GString *)user_data;
    MediaDescr *m_descr = m_descr_list ? (MediaDescr *)m_descr_list->data : NULL;
    char *encoded_media_name;

    /* The following variables are used to read the data out of the
     * m_descr pointer, without calling the same inline function
     * twice.
     */
    MediaType type;
    float frame_rate;
    const char *commons_deed;
    const char *rdf_page;
    const char *title;
    const char *author;

    if (!m_descr)
        return;

    // m=
    /// @TODO Convert this to a string table
    switch ( (type = m_descr_type(m_descr)) ) {
    case MP_audio:
        g_string_append(descr, "m=audio ");
        break;
    case MP_video:
        g_string_append(descr, "m=video ");
        break;
    case MP_application:
        g_string_append(descr, "m=application ");
        break;
    case MP_data:
        g_string_append(descr, "m=data ");
        break;
    case MP_control:
        g_string_append(descr, "m=control ");
        break;
    }

    /// @TODO shawill: probably the transport should not be hard coded,
    /// but obtained in some way
    g_string_append_printf(descr, "%d RTP/AVP",
                           m_descr_rtp_port(m_descr));

    g_list_foreach(m_descr_list,
                   sdp_mdescr_pt_append,
                   descr);
<commit_msg>Use a string table to find the right m= value for the media.<commit_after>/* *
 * This file is part of Feng
 *
 * Copyright (C) 2009 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 Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser 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
 *
 * */

/**
 * @file
 * @brief SDP session description
 *
 * This file contains the function used to generate the SDP session
 * description as needed by @ref RTSP_describe.
 */

#include <string.h>
#include <stdbool.h>

#include "fnc_log.h"
#include "sdp2.h"
#include "mediathread/description.h"
#include <netembryo/wsocket.h>
#include <netembryo/url.h>

#define SDP2_EL "\r\n"
#define DEFAULT_TTL 32

#define NTP_time(t) ((float)t + 2208988800U)

/**
 * @brief Simple pair for compound parameters in foreach functions
 *
 * This data structure is used to pass parameters along with foreach
 * functions, like @ref sdp_mdescr_private_append.
 */
typedef struct {
    /** The string to append the SDP2 description to */
    GString *descr;
    /** The currently-described media description object */
    MediaDescr *media;
} sdp_mdescr_append_pair;

/**
 * @brief Append media private field information to an SDP2 string
 *
 * @param element An sdp_field object in the list
 * @param user_data An sdp_mdescr_append_pair object
 *
 * @internal This function is only to be called by g_list_foreach().
 */
static void sdp_mdescr_private_append(gpointer element, gpointer user_data)
{
    sdp_field *private = (sdp_field *)element;
    sdp_mdescr_append_pair *pair = (sdp_mdescr_append_pair *)user_data;

    switch (private->type) {
    case empty_field:
        g_string_append_printf(pair->descr, "%s"SDP2_EL,
                               private->field);
        break;
    case fmtp:
        g_string_append_printf(pair->descr, "a=fmtp:%u %s"SDP2_EL,
                               m_descr_rtp_pt(pair->media),
                               private->field);
        break;
    case rtpmap:
        g_string_append_printf(pair->descr, "a=rtpmap:%u %s"SDP2_EL,
                               m_descr_rtp_pt(pair->media),
                               private->field);
        break;
    default: /* Ignore other private fields */
        break;
    }
}

/**
 * @brief Append all the private fields for a media description to an
 *        SDP2 string.
 *
 * @param element The media description to append the fields of
 * @param user_data The GString object to append the description to
 *
 * @internal This function is only to be called by g_list_foreach().
 */
static void sdp_mdescr_private_list_append(gpointer element, gpointer user_data)
{
    sdp_mdescr_append_pair pair = {
        .descr = (GString *)user_data,
        .media = (MediaDescr *)element
    };

    g_list_foreach(m_descr_sdp_private(pair.media),
                   sdp_mdescr_private_append,
                   &pair);
}

/**
 * @brief Append the payload type for the media description to an SDP2
 *        string.
 *
 * @param element The media description to append the fields of
 * @param user_data The GString object to append the description to
 *
 * @internal This function is only to be called by g_list_foreach().
 */
static void sdp_mdescr_pt_append(gpointer element, gpointer user_data)
{
    MediaDescr *mdescr = (MediaDescr *)element;
    GString *descr = (GString *)user_data;

    g_string_append_printf(descr, " %u",
                           m_descr_rtp_pt(mdescr));
}

/**
 * @brief Append the description for a given media to an SDP
 *        description.
 *
 * @param element List of MediaDescr instances to fetch the data
 *                     from.
 * @param user_data GString instance to append the description to
 *
 * @internal This function is only to be called by g_ptr_array_foreach().
 */
static void sdp_media_descr(gpointer element, gpointer user_data)
{
    MediaDescrList m_descr_list = (MediaDescrList)element;
    GString *descr = (GString *)user_data;
    MediaDescr *m_descr = m_descr_list ? (MediaDescr *)m_descr_list->data : NULL;
    char *encoded_media_name;

    /* The following variables are used to read the data out of the
     * m_descr pointer, without calling the same inline function
     * twice.
     */
    MediaType type;
    float frame_rate;
    const char *commons_deed;
    const char *rdf_page;
    const char *title;
    const char *author;

    /* Associative-array of media types and their SDP strings.
     *
     * Note that the space at the end is used to avoid using
     * printf-like interfaces.
     */
    static const char *const sdp_media_types[] = {
        [MP_audio] = "m=audio ",
        [MP_video] = "m=video ",
        [MP_application] = "m=application ",
        [MP_data] = "m=data ",
        [MP_control] = "m=control "
    };

    if (!m_descr)
        return;

    type = m_descr_type(m_descr);

    /* MP_undef is the only case we don't handle. */
    g_assert(type != MP_undef);

    g_string_append(descr, sdp_media_types[type]);

    /// @TODO shawill: probably the transport should not be hard coded,
    /// but obtained in some way
    g_string_append_printf(descr, "%d RTP/AVP",
                           m_descr_rtp_port(m_descr));

    g_list_foreach(m_descr_list,
                   sdp_mdescr_pt_append,
                   descr);

{'fraction_non_alphanumeric': 0.08689714041826718, 'fraction_numerical': 0.0064874093043107125, 'mean_word_length': 2.7915857605177994, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, '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': '612952', 'n_tokens_mistral': 3670, 'n_tokens_neox': 3586, 'n_words': 1189}