/*! \brief License permissions checking function.
 *
 * The function will check the license given as first paramenter is compatible
 * with the permissions accepted by user in <tt>Permission Mask</tt> given as
 * second parameter. Exiting, the function will return in <tt>mask</tt>
 * parameter the mask of permissions that conflict with license.
 *
 * \param license cc_license struct of license.
 *
 * \param mask pointer to permission mask used as input paramter for
 * accepted permissions by user and as return value for conflicting
 * permissions.
 */
int cc_perm_chk(cc_license * license, cc_perm_mask * mask)
{
        cc_perm_mask parsedmsk;
        return 0; //TODO: Disabled license check, should be made in a better way

        if (!license) {
                nms_printf(NMSML_DBG1, "no CC license defined\n");
                return 0;
        }
        // uriLicense parse
        if (!license->uriLicense)
                return nms_printf(NMSML_ERR,
                                  "no uriLicense present: could not parse license uri\n");
        if ((cc_parse_urilicense(license->uriLicense, &parsedmsk)))
                return nms_printf(NMSML_ERR,
                                  "cannot parse uriLicense (cc_prms_mask)\n");

        *((CC_BITMASK_T *) mask) =
                ~(*((CC_BITMASK_T *) mask)) & *((CC_BITMASK_T *) & parsedmsk);

        if (*((CC_BITMASK_T *) mask))
                return 1;

        return 0;
}
int set_rtsp_sessions(rtsp_thread * rtsp_th, int content_length,
                      char *content_base, char *body)
{
        sdp_attr *sdp_a;
        char *tkn;

        switch (rtsp_th->descr_fmt) {
        case DESCRIPTION_SDP_FORMAT:
                if (!
                                (rtsp_th->rtsp_queue =
                                         rtsp_sess_create(rtsp_th->urlname, content_base)))
                        return 1;

                if (!
                                (rtsp_th->rtsp_queue->body =
                                         (char *) malloc(content_length + 1)))
                        return nms_printf(NMSML_FATAL,
                                          "Cannot allocate memory.\n");
                memcpy(rtsp_th->rtsp_queue->body, body, content_length);
                rtsp_th->rtsp_queue->body[content_length] = '\0';

                rtsp_th->type = M_ON_DEMAND;

                if (!
                                (rtsp_th->rtsp_queue->info =
                                         sdp_session_setup(rtsp_th->rtsp_queue->body,
                                                           content_length)))
                        return nms_printf(NMSML_ERR, "SDP parse error\n");

                // we look for particular attributes of session
                for (sdp_a = rtsp_th->rtsp_queue->info->attr_list; sdp_a;
                                sdp_a = sdp_a->next) {
                        if (!strncasecmp(sdp_a->name, "control", 7)) {
                                tkn = sdp_a->value;    // 7 == strlen("control")
                                while ((*tkn == ' ') || (*tkn == ':'))    // skip spaces and colon
                                        tkn++;
                                rtsp_th->rtsp_queue->pathname = tkn;
                                rtsp_th->type = CONTAINER;
                        }
                }

                // media setup
                if (set_rtsp_media(rtsp_th))
                        return 1;

                break;
        case DESCRIPTION_MH_FORMAT:
                /* not yet implemented */
                // break;
        default:
                nms_printf(NMSML_ERR, "Unknown decription format.\n");
                return 1;
                break;
        }

        return 0;
}
Example #3
0
/*! \brief Parses Licenes URI and fills cc_perms data structure.
 *
 * To know what are the conditions of the license we parse the uri and look for
 * short names.
 *
 * \param uri license uri to parse.
 * \param conds cc_perms structure to be filled.
 */
int cc_parse_urilicense(char *uri, cc_perm_mask * mask)
{
    char *tkn, *permstr, *step;
    unsigned int i;

    memset(mask, 0, sizeof(*mask));

    // look if there is an "http:// prefix"
    if (strncasecmp(uri, "http://", 7))
        tkn = uri;
    else
        tkn = uri + 7;

    if (strncasecmp(tkn, BASE_URI_LICENSE, strlen(BASE_URI_LICENSE)))    // TODO: must continue or give an error, or ask what to to?
        return nms_printf(NMSML_ERR,
                  "the base URI of license is not \"%s\", so it can't be considered valid\n");

    tkn = tkn + strlen(BASE_URI_LICENSE);
    while (*tkn == '/')
        tkn++;
    if (!(permstr = strdup(tkn)))
        return nms_printf(NMSML_FATAL,
                  "memory error in cc_parse_urilicense\n");
    if ((tkn = strchr(permstr, '/')))
        *tkn = '\0';

    // Check for special licenses :TODO
    // for (i=0; i<sizeof(cc_spec_licenses)/sizeof(*cc_spec_licenses); i++) {
    for (i = 0; cc_spec_licenses[i].int_code; i++) {
        if (!strcasecmp(permstr, cc_spec_licenses[i].urlstr)) {
            mask->spec_license = cc_spec_licenses[i].int_code;
            break;
        }
    }

    if (!mask->spec_license)
        // Search for CC atributes
        for (tkn = strtok_r(permstr, "-", &step);
             tkn;
             tkn = strtok_r(NULL, "-", &step)) {
            // while(tkn) {
            if (!strcasecmp(tkn, cc_by.urltkn))
                mask->by = 1;
            else if (!strcasecmp(tkn, cc_nc.urltkn))
                mask->nc = 1;
            else if (!strcasecmp(tkn, cc_nd.urltkn))
                mask->nd = 1;
            else if (!strcasecmp(tkn, cc_sa.urltkn))
                mask->sa = 1;
        }

    free(permstr);

    return 0;
}
Example #4
0
int check_response(rtsp_thread * rtsp_th)
{
    int wait_res = rtsp_th->wait_for.res;
    int wait_cseq = rtsp_th->wait_for.cseq;
    char *wait_s_id = rtsp_th->wait_for.session_id;
    char Session_ID[RTSP_SESSION_ID_LEN];
    char *str_pos, *content;
    int CSeq;
    int opcode = 0;

    if ((content = strchr(rtsp_th->in_buffer.data, '\n')) == NULL) {
        nms_printf(NMSML_ERR,
               "ERROR: CANNOT find end of line in server response.\n");
        return -1;
    }

    if ((str_pos = strcasestr(content, "CSeq")) == NULL) {
        nms_printf(NMSML_ERR,
               "ERROR: CANNOT find CSeq number in server response.\n");
        return -1;
    }
    str_pos += 5;
    while ((*(str_pos) == ' ') || (*(str_pos) == ':'))
        str_pos++;
    sscanf(str_pos, "%d", &CSeq);
    switch (wait_res) {
    case RTSP_GET_RESPONSE:
        if (CSeq == 1)
            opcode = RTSP_GET_RESPONSE;
        break;
    case RTSP_SETUP_RESPONSE:
        if (CSeq == wait_cseq)
            opcode = RTSP_SETUP_RESPONSE;
        break;
    default:
        if ((str_pos = strcasestr(content, "Session")) != NULL) {
            str_pos += 7;
            if (get_session_str(Session_ID, str_pos)) {
                nms_printf(NMSML_ERR, "ERROR: CANNOT get SessionID\n");
                break;
            }
            if (strcmp(Session_ID, wait_s_id)) {
                nms_printf(NMSML_ERR, "Unexpected SessionID\n");
                break;
            }
        }
        if (CSeq == wait_cseq)
            opcode = wait_res;
        break;
    }
    nms_printf(NMSML_DBG2, "Opcode Set to %d\n", opcode);
    return opcode;
}
Example #5
0
// private functions
static int mpa_sync(uint8_t ** data, size_t * data_len /*, mpa_frm *mpa */ )
{
#if 0                // ID3 tag check not useful
    int ret;

    if (!mpa->probed) {
        /*look if ID3 tag is present */
        if (!memcmp(*data, "ID3", 3)) {    // ID3 tag present
            id3v2_hdr id3hdr;

            // fnc_log(FNC_LOG_DEBUG, "ID3v2 tag present in %s\n", i_stream->name);

            memcpy(&id3hdr, *data, 4);
            // if ( (ret = istream_read(ID3v2_HDRLEN - 4, &id3hdr.rev, i_stream)) != ID3v2_HDRLEN - 4 )
            if ((ret =
                 mpa_read(ID3v2_HDRLEN - 4, &id3hdr.rev,
                      in)) != ID3v2_HDRLEN - 4)
                return (ret < 0) ? ERR_PARSE : ERR_EOF;
            // if ( (ret=mpa_read_id3v2(&id3hdr, i_stream, mpa)) )
            if ((ret = mpa_read_id3v2(&id3hdr, in, mpa)))
                return ret;
            // if ( (ret=istream_read(4, *data, i_stream)) != 4 )
            if ((ret = mpa_read(4, *data, in)) != 4)
                return (ret < 0) ? ERR_PARSE : ERR_EOF;
        }
    }
#endif

    for (; !MPA_IS_SYNC(*data) && (*data_len >= 4);
         (*data)++, (*data_len)--)
        nms_printf(NMSML_DBG3, "[MPA] sync: %X%X%X%X\n", data[0],
               data[1], data[2], data[3]);

    return (*data_len >= 4) ? 0 /*sync found */ : 1 /*sync not found */ ;
}
rtsp_session *rtsp_sess_create(char *urlname, char *content_base)
{
        rtsp_session *rtsp_s;

        if ((rtsp_s = (rtsp_session *) malloc(sizeof(rtsp_session))) == NULL) {
                nms_printf(NMSML_FATAL,
                           "rtsp_sess_create: Cannot allocate memory.\n");
                return NULL;
        }
        if (content_base == NULL) {
                rtsp_s->content_base = NULL;
                rtsp_s->pathname = urlname;
        } else {
                /* shawill: using strdup insted
                   if ((rtsp_s->pathname=rtsp_s->content_base=(char *)malloc(strlen(content_base)+1))==NULL) {
                   nms_printf(NMSML_FATAL, "Cannot allocate memory!\n");
                   return NULL;
                   }
                   strcpy(rtsp_s->content_base,content_base);
                 */
                if (!
                                (rtsp_s->pathname = rtsp_s->content_base =
                                                            strdup(content_base)))
                        return NULL;
                rtsp_s->pathname += strlen(content_base);
        }
        rtsp_s->Session_ID[0] = '\0';
        rtsp_s->CSeq = 1;
        rtsp_s->media_queue = NULL;
        rtsp_s->next = NULL;

        rtsp_s->info = NULL;

        return rtsp_s;
}
Example #7
0
static int single_parse(rtp_vorbis * vorb, rtp_pkt * pkt, rtp_frame * fr,
            rtp_buff * config, rtp_ssrc * ssrc)
{
    uint8_t * this_pkt = RTP_PKT_DATA(pkt) + vorb->offset;
    unsigned len = nms_consume_BE2(&this_pkt);

    if (vorb->id != RTP_XIPH_ID(pkt) &&    //not the current id
        //  !cfg_cache_find(vorb,RTP_XIPH_ID(pkt)) || //XXX
        (RTP_XIPH_T(pkt) != 1)    //not a config packet
       ) {
        nms_printf(NMSML_ERR, "Id %0x unknown, expected %0x\n",
                   (unsigned)RTP_XIPH_ID(pkt), (unsigned)vorb->id);
        return RTP_PARSE_ERROR;
    }

    fr->data = vorb->buf = realloc(vorb->buf, len);
    fr->len = vorb->len = len;

    memcpy(fr->data, this_pkt, fr->len);
    vorb->pkts--;
    if (vorb->pkts == 0) {
        rtp_rm_pkt(ssrc);
    }

    if (RTP_XIPH_T(pkt) == 1)
        return -1; //cfg_fixup(vorb, fr, config, RTP_XIPH_ID(pkt));
    else {
        config->data = vorb->conf[0].conf;
        config->len  = vorb->conf[0].len;
    }

    return 0;
}
/**
 * Sends the Bye packet. Actually it does nothing
 * @param rtp_sess The session for which to send the bye packet
 * @return 0
 */
int rtcp_send_bye(rtp_session * rtp_sess)
{
        // TODO: really send bye packet
        nms_printf(NMSML_DBG1,
                   "SRRC %d: sending RTCP Bye. Warning! Not yet implemented!",
                   rtp_sess->local_ssrc);
        return 0;
}
/**
 * Creates a copy of an nms_sockaddr structure
 */
int nms_sockaddr_dup(nms_sockaddr * dst, nms_sockaddr * src)
{

        if (!(dst->addr = malloc(src->addr_len)))
                return -nms_printf(NMSML_FATAL, "Cannot allocate memory\n");
        memcpy(dst->addr, src->addr, src->addr_len);
        dst->addr_len = src->addr_len;

        return 0;
}
/**
 * BYE packet handler, when rtcp layer gets a bye packet
 * it signals it to the rtp layer reporting the end
 * of stream.
 * @param ssrc The SSRC for which the packet was received
 * @param pkt The packet itself
 * @return 0
 */
int rtcp_parse_bye(rtp_ssrc * ssrc, rtcp_pkt * pkt)
{
        rtsp_thread * rtsp_t;
        int i;
        for (i = 0; i < pkt->common.count; i++)
                nms_printf(NMSML_DBG3, "Received BYE from SSRC: %u\n",
                           pkt->r.bye.src[i]);

        rtsp_t = ssrc->rtp_sess->owner;
        rtsp_t->rtp_th->run = 0;
        return 0;
}
Example #11
0
static int mpa_uninit_parser(rtp_ssrc * stm_src, unsigned pt)
{
    rtp_mpa *mpa_priv = stm_src->privs[pt];

    if (mpa_priv) {
        nms_printf(NMSML_DBG2,
               "[rtp_mpa] freeing private resources...\n");
        free(mpa_priv->data);
        free(mpa_priv);
    }

    return 0;
}
rtsp_session *rtsp_sess_dup(rtsp_session * curr_rtsp_s)
{
        rtsp_session *new_rtsp_s;

        if ((new_rtsp_s =
                                (rtsp_session *) malloc(sizeof(rtsp_session))) == NULL) {
                nms_printf(NMSML_FATAL, "Cannot allocate memory.\n");
                return NULL;
        }

        memcpy(new_rtsp_s, curr_rtsp_s, sizeof(rtsp_session));

        new_rtsp_s->Session_ID[0] = '\0';
        new_rtsp_s->next = NULL;

        return new_rtsp_s;
}
Example #13
0
// debug function to diplay MPA header information
static void mpa_info(mpa_frm * mpa)
{
    switch (mpa->id) {
    case MPA_MPEG_1:
        nms_printf(NMSML_DBG3, "[MPA] MPEG1\n");
        break;
    case MPA_MPEG_2:
        nms_printf(NMSML_DBG3, "[MPA] MPEG2\n");
        break;
    case MPA_MPEG_2_5:
        nms_printf(NMSML_DBG3, "[MPA] MPEG2.5\n");
        break;
    default:
        nms_printf(NMSML_DBG3, "[MPA] MPEG reserved (bad)\n");
        return;
        break;
    }
    switch (mpa->layer) {
    case MPA_LAYER_I:
        nms_printf(NMSML_DBG3, "[MPA] Layer I\n");
        break;
    case MPA_LAYER_II:
        nms_printf(NMSML_DBG3, "[MPA] Layer II\n");
        break;
    case MPA_LAYER_III:
        nms_printf(NMSML_DBG3, "[MPA] Layer III\n");
        break;
    default:
        nms_printf(NMSML_DBG3, "[MPA] Layer reserved (bad)\n");
        return;
        break;
    }
    nms_printf(NMSML_DBG3,
           "[MPA] bitrate: %d; sample rate: %3.0f; pkt_len: %d\n",
           mpa->bit_rate, mpa->sample_rate, mpa->frm_len);
}
Example #14
0
int issdplicense(char *sdp_a)
{
    unsigned int i;

    // shawill: sizeof(nms_cc_licenses)/sizeof(*nms_cc_licenses) == number of couples name-description present
    for (i = 0; i < sizeof(nms_cc_licenses) / sizeof(*nms_cc_licenses); i++) {
        if (!strncasecmp
            (sdp_a, nms_cc_licenses[i][CC_ATTR_NAME],
             strlen(nms_cc_licenses[i][CC_ATTR_NAME]))) {
            nms_printf(NMSML_DBG1,
                   "found valid cc field in SDP description (%s - %s)\n",
                   nms_cc_licenses[i][CC_ATTR_NAME],
                   nms_cc_licenses[i][CC_ATTR_DESCR]);
            return 1;
        }
    }

    return 0;
}
Example #15
0
int remove_pkt(rtsp_thread * rtsp_th)
{
    char *buff = NULL;
    size_t new_size = rtsp_th->in_buffer.size -
                      rtsp_th->in_buffer.first_pkt_size;

    if (new_size) {
        if ((buff = malloc(new_size)) == NULL)
            return nms_printf(NMSML_FATAL,
                              "remove_pkt: Cannot allocate memory!"
                              " (%d bytes)\n", new_size);

        memcpy(buff, rtsp_th->in_buffer.data +
                     rtsp_th->in_buffer.first_pkt_size,
                     rtsp_th->in_buffer.size -
                     rtsp_th->in_buffer.first_pkt_size);
    } else buff = NULL;

    free(rtsp_th->in_buffer.data);
    rtsp_th->in_buffer.data = buff;
    rtsp_th->in_buffer.size -= rtsp_th->in_buffer.first_pkt_size;
    rtsp_th->in_buffer.first_pkt_size = 0;
    return 0;
}
Example #16
0
int set_rtsp_media(rtsp_thread * rtsp_th)
{
    rtsp_session *curr_rtsp_s = rtsp_th->rtsp_queue;
    rtsp_medium *curr_rtsp_m = NULL;
    sdp_medium_info *sdp_m, *sdp_m_prev;
    sdp_attr *sdp_attr;
    char *tkn, *ch;
    uint8_t pt;
    int error=0;

    switch (rtsp_th->descr_fmt) {
    case DESCRIPTION_SDP_FORMAT:
        //erasing unknown media
        sdp_m = curr_rtsp_s->info->media_info_queue;
        sdp_m_prev = NULL;
        while (sdp_m) {
            error = 0;
            for (sdp_attr = sdp_m->attr_list; sdp_attr;
                    sdp_attr = sdp_attr->next) {
                if (!strncasecmp(sdp_attr->name, "rtpmap", 6)) {
                    tkn = sdp_attr->value;
                    while ((*tkn == ' ') || (*tkn == ':'))
                        tkn++;
                    strtoul(tkn, &tkn, 10);
                    while (*tkn == ' ')
                        tkn++;
                    if (!(ch = strchr(tkn, '/'))) {
                        nms_printf(NMSML_WARN, "Invalid field rtpmap.\n");
                        error++;
                    }
                    *ch = '\0';
                    if (rtp_parser_check(tkn)) {
                        nms_printf(NMSML_WARN, "Ignoring unsupported media"
                                   "type: %s.\n", tkn);
                        error++;
                    }
                    *ch = '/';
                }
            }
            if (error) {
                if (!sdp_m_prev) {
                    curr_rtsp_s->info->media_info_queue = sdp_m->next;
                    sdp_medium_destroy(sdp_m);
                    sdp_m = curr_rtsp_s->info->media_info_queue;
                } else {
                    sdp_m_prev->next = sdp_m->next;
                    sdp_medium_destroy(sdp_m);
                    sdp_m = sdp_m_prev->next;
                }
            } else {
                sdp_m_prev = sdp_m;
                sdp_m = sdp_m->next;
            }
        }
        if (!curr_rtsp_s->info->media_info_queue) {
            nms_printf(NMSML_ERR, "No known medium found.\n");
            return 1;
        }

        for (sdp_m = curr_rtsp_s->info->media_info_queue; sdp_m;
             sdp_m = sdp_m->next) {
            if (curr_rtsp_m == NULL) {
                /* first medium */
                if ((curr_rtsp_s->media_queue = curr_rtsp_m =
                     rtsp_med_create(rtsp_th)) == NULL)
                    return 1;
            } else if (rtsp_th->type == CONTAINER) {
                /* media in the same session */
                if ((curr_rtsp_m->next = rtsp_med_create(rtsp_th)) == NULL)
                    return 1;
                curr_rtsp_m->rtp_sess->next =
                    curr_rtsp_m->next->rtp_sess;
                curr_rtsp_m = curr_rtsp_m->next;
            } else if (rtsp_th->type == M_ON_DEMAND) {
                /* one medium for each session */
                if ((curr_rtsp_s->next = rtsp_sess_dup(curr_rtsp_s)) == NULL)
                    return 1;
                curr_rtsp_s = curr_rtsp_s->next;
                if ((curr_rtsp_s->media_queue = rtsp_med_create(rtsp_th)) ==
                    NULL)
                    return 1;
                curr_rtsp_m->rtp_sess->next =
                    curr_rtsp_s->media_queue->rtp_sess;
                curr_rtsp_m = curr_rtsp_s->media_queue;
            }
            curr_rtsp_m->medium_info = sdp_m;

            // setup rtp format list for current media
            for (tkn = sdp_m->fmts;
                 *tkn && !(!(pt = strtoul(tkn, &ch, 10)) && ch == tkn);
                 tkn = ch) {
                switch (sdp_m->media_type) {
                case 'A':
                    if (rtp_announce_pt(curr_rtsp_m->rtp_sess, pt, AU))
                        return 1;
                    break;
                case 'V':
                    if (rtp_announce_pt(curr_rtsp_m->rtp_sess, pt, VI))
                        return 1;
                    break;
                default:
                    // not recognized
                    if (rtp_announce_pt(curr_rtsp_m->rtp_sess, pt, NA))
                        return 1;
                    break;
                }
            }

            for (sdp_attr = sdp_m->attr_list; sdp_attr;
                 sdp_attr = sdp_attr->next) {
                if (!strncasecmp(sdp_attr->name, "control", 7)) {
                    tkn = sdp_attr->value;
                    while ((*tkn == ' ') || (*tkn == ':'))
                        tkn++;
                    curr_rtsp_m->filename = tkn;
                } else if (!strncasecmp(sdp_attr->name, "rtpmap", 6)) {
                    /* We assume the string in the format:
                     * rtpmap:PaloadType EncodingName/ClockRate[/Channels] */
                    tkn = sdp_attr->value;
                    // skip spaces and colon (we should not do this!)
                    while ((*tkn == ' ') || (*tkn == ':'))
                        tkn++;
                    if (((pt = strtoul(tkn, &tkn, 10)) >= 96)
                        && (pt <= 127)) {
                        while (*tkn == ' ')
                            tkn++;
                        if (!(ch = strchr(tkn, '/'))) {
                            nms_printf(NMSML_WARN, "Invalid field rtpmap.\n");
                            break;
                        }
                        *ch = '\0';
                        if (rtp_dynpt_reg (curr_rtsp_m->rtp_sess, pt, tkn))
                            return 1;
                        switch (sdp_m->media_type) {
                        case 'A':
                            sscanf(ch + 1, "%u/%c",
                                &curr_rtsp_m->rtp_sess->ptdefs[pt]->rate,
                                &RTP_AUDIO(curr_rtsp_m->rtp_sess->ptdefs[pt])->
                                   channels);
                            break;
                        case 'V':
                            sscanf(ch + 1, "%u",
                                   &curr_rtsp_m->rtp_sess->ptdefs[pt]->rate);
                            break;
                        default:
                            // not recognized
                            break;
                        }
                        *ch = '/';
                        tkn = ++ch;
                    } else {
                        // shawill: should be an error or a warning?
                        nms_printf(NMSML_WARN,
                            "Warning: rtpmap attribute is trying to set a"
                            "non-dynamic payload type: not permitted\n");
                    }
                } else
                    if (!strncasecmp(sdp_attr->name, "fmtp", 4)) {
                    /* We assume the string in the format:
                     * fmtp:PaloadType <format specific parameters> */
                    tkn = sdp_attr->value;    // 4 == strlen("fmtp")
                    // skip spaces and colon (we should not do this!)
                    while ((*tkn == ' ') || (*tkn == ':'))
                        tkn++;
                    if ((pt = strtoul(tkn, &tkn, 10)) <= 127) {
                        while (*tkn == ' ')
                            tkn++;
                        rtp_pt_attr_add(curr_rtsp_m->rtp_sess->ptdefs, pt, tkn);
                    } else {
                        // shawill: should be an error or a warning?
                        nms_printf(NMSML_WARN,
                            "Warning: fmtp attribute is trying to set an"
                            "out of bounds payload type: not permitted\n");
                    }
                /* dirty keyword from old fenice used for dinamic
                 * payload change - TO BE REMOVED
                 */
                } else if (!strncasecmp(sdp_attr->name, "med", 3)) {
                    sdp_medium_info m_info;
                    /* We assume the string in the format:
                     * med:sdp-like m= field */
                    tkn = sdp_attr->value;    // 3 == strlen("med")
                    // skip spaces and colon (we should not do this!)
                    while ((*tkn == ' ') || (*tkn == ':'))
                        tkn++;
                    if (sdp_parse_m_descr(&m_info, tkn)) {
                        nms_printf(NMSML_ERR,
                               "malformed a=med: from fenice\n");
                        return 1;
                    }
                    // check if everything is correct
                    if (!(pt = strtoul(m_info.fmts, &ch, 10))
                        && ch == m_info.fmts) {
                        nms_printf(NMSML_ERR,
                            "Could not determine pt value in a=med: string"
                            " from fenice\n");
                        return 1;
                    }
                    switch (sdp_m->media_type) {
                    case 'A':
                        if (strncasecmp
                            (tkn, "audio ", 6)) {
                            nms_printf(NMSML_ERR,
                                "a=med; attribute defined a different media"
                                " type than the original\n");
                            return 1;
                        }
                        if (rtp_announce_pt
                            (curr_rtsp_m->rtp_sess, pt,
                             AU))
                            return 1;
                        break;
                    case 'V':
                        if (strncasecmp
                            (tkn, "video ", 6)) {
                            nms_printf(NMSML_ERR,
                                "a=med; attribute defined a different media"
                                " type than the original\n");
                            return 1;
                        }
                        if (rtp_announce_pt
                            (curr_rtsp_m->rtp_sess, pt,
                             VI))
                            return 1;
                        break;
                    default:
                        // not recognized
                        if (rtp_announce_pt
                            (curr_rtsp_m->rtp_sess, pt,
                             NA))
                            return 1;
                        break;
                    }
                }
            }
        }
        break;
    case DESCRIPTION_MH_FORMAT:
        /* not yet implemented */
        // break;
    default:
        nms_printf(NMSML_ERR, "Unknown decription format.\n");
        return 1;
        break;
    }
    return 0;
}
int sdp_parse_m_descr(sdp_medium_info * m_info, char *m_descr)
{
    char *tkn, *endtkn;

    if (!(tkn = strchr(m_descr, ' ')))
        return nms_printf(NMSML_ERR,
                          "SDP Media description string not valid: (m=%s)\n",
                          m_descr);
    *tkn = '\0';

    // parse media type
    if (!strcmp(m_descr, "video"))
        m_info->media_type = 'V';
    else if (!strcmp(m_descr, "audio"))
        m_info->media_type = 'A';
    else if (!strcmp(m_descr, "application"))
        m_info->media_type = 'P';
    else if (!strcmp(m_descr, "data"))
        m_info->media_type = 'D';
    else if (!strcmp(m_descr, "control"))
        m_info->media_type = 'C';

    *tkn = ' ';

    // parse port and number of ports
    m_info->port = strtol(tkn, &endtkn, 10);
    if (tkn == endtkn)
        return nms_printf(NMSML_ERR,
                          "SDP Media description string not valid: (m=%s)\n"
                          "Could not find port field\n",
                          m_descr);
    tkn = endtkn;        // + 1;
    if (*endtkn == '/') {
        m_info->n_ports = strtol(tkn + 1, &endtkn, 10);
        tkn = endtkn;    // + 1;
    } else
        m_info->n_ports = 1;

    for (; *tkn == ' '; tkn++);    // skip spaces
    if (!(*tkn))
        return nms_printf(NMSML_ERR,
                          "SDP Media description string not valid: (m=%s)\n"
                          "Could not find transport field\n",
                          m_descr);

    // parse transport protocol
    if (!(endtkn = strchr(tkn, ' ')))
        return nms_printf(NMSML_ERR,
                          "SDP Media description string not valid: (m=%s)\n"
                          "Description terminates whithout <fmt list>\n",
                          m_descr);
    *endtkn = '\0';
    strncpy(m_info->transport, tkn, 7);
    m_info->transport[7] = '\0';
    *endtkn = ' ';
    tkn = endtkn + 1;

    // fmt list: here we expect to store payload types
    for (; *tkn == ' '; tkn++);    // skip spaces
    m_info->fmts = tkn;

    return 0;
}
Example #18
0
int rtsp_recv(rtsp_thread * rtsp_th)
{
    int n = -1, m = 0;
    char buffer[RTSP_BUFFERSIZE];
#ifdef ENABLE_SCTP
    nms_rtsp_interleaved *p;
    struct sctp_sndrcvinfo sinfo;
#endif

    memset(buffer, '\0', RTSP_BUFFERSIZE);

    switch(rtsp_th->transport.sock.socktype) {
    case TCP:
        n = nmst_read(&rtsp_th->transport, buffer, RTSP_BUFFERSIZE, NULL);
        break;
#ifdef ENABLE_SCTP
    case SCTP:
        memset(&sinfo, 0, sizeof(sinfo));
        n = nmst_read(&rtsp_th->transport, buffer, RTSP_BUFFERSIZE, &sinfo);
        m = sinfo.sinfo_stream;
        break;
#endif
    default:
        break;
    }
    if (n == 0) {
        return 0;
    }
    if (n < 0) {
        nms_printf(NMSML_ERR, "Could not read from RTSP socket\n");
        return n;
    }
    if (rtsp_th->transport.sock.socktype == TCP ||
        (rtsp_th->transport.sock.socktype == SCTP && m==0)) {
        if ((rtsp_th->in_buffer.size) == 0) {
            if ((rtsp_th->in_buffer.data =
                 (char *) calloc(1, n + 1)) == NULL)
                return nms_printf(NMSML_FATAL,
                  "Cannot alloc memory space for received RTSP data\n");

            memcpy(rtsp_th->in_buffer.data, buffer, n);
        } else {
            if ((rtsp_th->in_buffer.data =
                 (char *) realloc(rtsp_th->in_buffer.data,
                n + rtsp_th->in_buffer.size + 1)) ==
                NULL)
                return nms_printf(NMSML_FATAL,
                  "Cannot alloc memory space for received RTSP data\n");

            memcpy(rtsp_th->in_buffer.data + rtsp_th->in_buffer.size, buffer, n);
    }
    rtsp_th->in_buffer.size += n;
    rtsp_th->in_buffer.data[rtsp_th->in_buffer.size] = '\0';
    } else /* if (rtsp_th->transport.sock.socktype == SCTP && m!=0) */ {
#ifdef ENABLE_SCTP
        for (p = rtsp_th->interleaved; p && !((p->proto.sctp.rtp_st == m)
            || (p->proto.sctp.rtcp_st == m)); p = p->next);
        if (p) {
            if (p->proto.sctp.rtp_st == m) {
                nms_printf(NMSML_DBG2,
                       "Interleaved RTP data (%u bytes: channel %d -> sd %d)\n",
                       n, m, p->rtp_fd);
                send(p->rtp_fd, buffer, n, MSG_EOR);
            } else {
                nms_printf(NMSML_DBG2,
                       "Interleaved RTCP data (%u bytes: channel %d -> sd %d)\n",
                       n, m, p->rtcp_fd);
                send(p->rtcp_fd, buffer, n, MSG_EOR);
            }
        }
#endif
    }
    return n;
}
Example #19
0
/**
 * @brief scan status code of an RTSP reply
 *
 * @param status_line the status line in the reply
 * @return reply status code or -1 on error
 */
int check_status(char *status_line, rtsp_thread * rtsp_th)
{
    char ver[32];
    unsigned short res_state;
    char *reason_phrase;
    char *location = NULL;
    // string tokenizers
    char *tkn, *prev_tkn, *step = NULL;

    if (sscanf(status_line, "%31s %hu ", ver, &res_state) < 2) {
        nms_printf(NMSML_ERR,
               "invalid Status-Line in DESCRIBE Response\n");
        return -1;
    }
    reason_phrase = strchr(strchr(status_line, ' ') + 1, ' ') + 1;

    rtsp_th->response_id = res_state;

    if (RTSP_IS_SUCCESS(res_state))
        return res_state;
    else if (RTSP_IS_REDIRECT(res_state)) {
        nms_printf(NMSML_NORM,
               "WARNING: Redirection. reply was: %hu %s\n",
               res_state, reason_phrase);
        switch (res_state) {
        case RTSP_FOUND:
            if ((prev_tkn =
                 strtok_r(rtsp_th->in_buffer.data +
                          strlen(status_line) + 1, "\n", &step)) == NULL) {
                nms_printf(NMSML_ERR,
                       "Could not find \"Location\" so..."
                       " Where I'll redirect you?\n");
                return -1;
            }
            while (((tkn = strtok_r(NULL, "\n", &step)) != NULL)
                   && ((tkn - prev_tkn) > 1)) {
                if (((tkn - prev_tkn) == 2) && (*prev_tkn == '\r'))
                    break;
                if (!strncasecmp(prev_tkn, "Location", 8)) {
                    prev_tkn += 8;
                    while ((*(prev_tkn) == ' ') || (*(prev_tkn) == ':'))
                        prev_tkn++;
                    location = strdup(prev_tkn);
                    // sscanf(prev_tkn,"%d",&location);
                }
                prev_tkn = tkn;
            }
            if (location) {
                nms_printf(NMSML_NORM, "Redirecting to %s\n", location);
                rtsp_open((rtsp_ctrl*)rtsp_th, location);
            } else
                return -nms_printf(NMSML_ERR, "No location string\n");
        }
    } else if (RTSP_IS_CLIENT_ERROR(res_state))
        nms_printf(NMSML_ERR, "Client error. Reply was: %hu %s\n",
               res_state, reason_phrase);
    else if (RTSP_IS_SERVER_ERROR(res_state))
        nms_printf(NMSML_ERR, "Server error. Reply was: %hu %s\n",
               res_state, reason_phrase);
    return -1;
}
Example #20
0
static int mpa_parse(rtp_ssrc * stm_src, rtp_frame * fr, rtp_buff * config)
{
    rtp_mpa *mpa_priv;
    rtp_pkt *pkt;
    size_t pkt_len;        // size of RTP packet, rtp header included.
    mpa_frm mpa;
    uint8_t *mpa_data;

    if (!fr)
        return RTP_IN_PRM_ERR;

    mpa_priv = stm_src->privs[fr->pt];

    // XXX should we check if payload/mime-type are compatible with parser?

    if (!(pkt = rtp_get_pkt(stm_src, &pkt_len)))
        return RTP_BUFF_EMPTY;

    // discard pkt if it's fragmented and the first fragment was lost
    while (RTP_MPA_PKT(pkt)->frag_offset) {
        rtp_rm_pkt(stm_src);
        if (!(pkt = rtp_get_pkt(stm_src, &pkt_len)))
            return RTP_BUFF_EMPTY;
        else if (RTP_PKT_PT(pkt) != fr->pt)
            return RTP_PARSE_ERROR;
    }

    mpa_data = RTP_MPA_PKT(pkt)->data;

    nms_printf(NMSML_DBG3, "--- fr->len: %d-%d\n", pkt_len,
           RTP_PAYLOAD_SIZE(pkt, pkt_len));
    pkt_len = RTP_MPA_DATA_LEN(pkt, pkt_len);    // now pkt_len is only the payload len (excluded mpa subheader)
    nms_printf(NMSML_DBG3, "--- fr->len: %d\n", pkt_len);
    if (mpa_sync(&mpa_data, &pkt_len))
        return RTP_PARSE_ERROR;

    if (mpa_decode_header(mpa_data, &mpa))
        return RTP_PARSE_ERROR;

    /* XXX if the frame is not fragmented we could use directly the data contained in bufferpool
     * instead of memcpy the frame in a newly allocated space */
    // init private struct if this is the first time we're called
    if (!mpa_priv) {
        nms_printf(NMSML_DBG3,
               "[rtp_mpa] allocating new private struct...");
        if (!
            (stm_src->privs[fr->pt] = mpa_priv =
             malloc(sizeof(rtp_mpa))))
            return RTP_ERRALLOC;
        mpa_priv->data_size = max(DEFAULT_MPA_DATA_FRAME, mpa.frm_len);
        if (!(mpa_priv->data = malloc(mpa_priv->data_size)))
            return RTP_ERRALLOC;
        nms_printf(NMSML_DBG3, "done\n");
    } else if ((RTP_MPA_FRAG_OFFSET(pkt) + pkt_len) > mpa_priv->data_size) {
        nms_printf(NMSML_DBG3, "[rtp_mpa] reallocating data...");
        mpa_priv->data_size += max(DEFAULT_MPA_DATA_FRAME, pkt_len);
        if (!(mpa_priv->data = realloc(mpa_priv->data,  mpa_priv->data_size)))
            return RTP_ERRALLOC;
        nms_printf(NMSML_DBG3, "done\n");
    }
    fr->data = mpa_priv->data;

    for (fr->len = 0;
         pkt && (fr->len < mpa.frm_len) &&
         (fr->timestamp == RTP_PKT_TS(pkt));
         fr->len += pkt_len,
         rtp_rm_pkt(stm_src), (pkt =
                   rtp_get_pkt(stm_src, &pkt_len)), pkt_len =
         RTP_MPA_DATA_LEN(pkt, pkt_len)) {
        // pkt consistency checks
        if (RTP_MPA_FRAG_OFFSET(pkt) + pkt_len <= mpa_priv->data_size) {
            nms_printf(NMSML_DBG3,
                   "copying %d byte of data to offset: %d\n",
                   pkt_len, RTP_MPA_FRAG_OFFSET(pkt));
            memcpy(fr->data + RTP_MPA_FRAG_OFFSET(pkt), mpa_data,
                   pkt_len);
        }
    }
    nms_printf(NMSML_DBG3, "fr->len: %d\n", fr->len);

    return RTP_FILL_OK;
}