Exemplo n.º 1
0
static void sipsess_progr_handler(const struct sip_msg *msg, void *arg)
{
	struct call *call = arg;
	bool media;

	MAGIC_CHECK(call);

	info("call: SIP Progress: %u %r (%r/%r)\n",
	     msg->scode, &msg->reason, &msg->ctyp.type, &msg->ctyp.subtype);

	if (msg->scode <= 100)
		return;

	/* check for 18x and content-type
	 *
	 * 1. start media-stream if application/sdp
	 * 2. play local ringback tone if not
	 *
	 * we must also handle changes to/from 180 and 183,
	 * so we reset the media-stream/ringback each time.
	 */
	if (msg_ctype_cmp(&msg->ctyp, "application", "sdp")
	    && mbuf_get_left(msg->mb)
	    && !sdp_decode(call->sdp, msg->mb, false)) {
		media = true;
	}
	else if (msg_ctype_cmp(&msg->ctyp, "multipart", "mixed") &&
		 !sdp_decode_multipart(&msg->ctyp.params, msg->mb) &&
		 !sdp_decode(call->sdp, msg->mb, false)) {
		media = true;
	}
	else
		media = false;

	switch (msg->scode) {

	case 180:
		set_state(call, STATE_RINGING);
		break;

	case 183:
		set_state(call, STATE_EARLY);
		break;
	}

	if (media)
		call_event_handler(call, CALL_EVENT_PROGRESS, call->peer_uri);
	else
		call_event_handler(call, CALL_EVENT_RINGING, call->peer_uri);

	call_stream_stop(call);

	if (media)
		call_stream_start(call, false);
}
Exemplo n.º 2
0
static int sipsess_offer_handler(struct mbuf **descp,
				 const struct sip_msg *msg, void *arg)
{
	const bool got_offer = mbuf_get_left(msg->mb);
	struct call *call = arg;
	int err;

	MAGIC_CHECK(call);

	info("call: got re-INVITE%s\n", got_offer ? " (SDP Offer)" : "");

	if (got_offer) {

		/* Decode SDP Offer */
		err = sdp_decode(call->sdp, msg->mb, true);
		if (err)
			return err;

		err = update_media(call);
		if (err)
			return err;
	}

	/* Encode SDP Answer */
	return sdp_encode(descp, call->sdp, !got_offer);
}
Exemplo n.º 3
0
/*
 * called when an SDP offer is received (got offer: true) or
 * when an offer is to be sent (got_offer: false)
 */
static int offer_handler(struct mbuf **mbp, const struct sip_msg *msg,
			 void *arg)
{
	const bool got_offer = mbuf_get_left(msg->mb);
	int err;
	(void)arg;

	if (got_offer) {

		err = sdp_decode(sdp, msg->mb, true);
		if (err) {
			re_fprintf(stderr, "unable to decode SDP offer: %s\n",
				   strerror(err));
			return err;
		}

		re_printf("SDP offer received\n");
		update_media();
	}
	else {
		re_printf("sending SDP offer\n");
	}

	return sdp_encode(mbp, sdp, !got_offer);
}
Exemplo n.º 4
0
/* called upon incoming calls */
static void connect_handler(const struct sip_msg *msg, void *arg)
{
	struct mbuf *mb;
	bool got_offer;
	int err;
	(void)arg;

	if (sess) {
		/* Already in a call */
		(void)sip_treply(NULL, sip, msg, 486, "Busy Here");
		return;
	}

	got_offer = (mbuf_get_left(msg->mb) > 0);

	/* Decode SDP offer if incoming INVITE contains SDP */
	if (got_offer) {

		err = sdp_decode(sdp, msg->mb, true);
		if (err) {
			re_fprintf(stderr, "unable to decode SDP offer: %s\n",
				   strerror(err));
			goto out;
		}

		update_media();
	}

	/* Encode SDP */
	err = sdp_encode(&mb, sdp, !got_offer);
	if (err) {
		re_fprintf(stderr, "unable to encode SDP: %s\n",
			   strerror(err));
		goto out;
	}

	/* Answer incoming call */
	err = sipsess_accept(&sess, sess_sock, msg, 200, "OK",
			     name, "application/sdp", mb,
			     auth_handler, NULL, false,
			     offer_handler, answer_handler,
			     establish_handler, NULL, NULL,
			     close_handler, NULL, NULL);
	mem_deref(mb); /* free SDP buffer */
	if (err) {
		re_fprintf(stderr, "session accept error: %s\n",
			   strerror(err));
		goto out;
	}

 out:
	if (err) {
		(void)sip_treply(NULL, sip, msg, 500, strerror(err));
	}
	else {
		re_printf("accepting incoming call from <%r>\n",
			  &msg->from.auri);
	}
}
Exemplo n.º 5
0
/**
 * Test parsing of various SDP messages from various vendors
 */
int test_sdp_parse(void)
{
	struct sdp_session *sess = NULL;
	struct sdp_media *audio;
	struct mbuf *mb;
	struct sa laddr;
	uint32_t i;
	int err;

	mb = mbuf_alloc(2048);
	if (!mb)
		return ENOMEM;

	sa_init(&laddr, AF_INET);

	for (i=0; i<ARRAY_SIZE(msgs); i++) {

		sess = mem_deref(sess);

		err = sdp_session_alloc(&sess, &laddr);
		if (err)
			goto out;

		err = sdp_media_add(&audio, sess, sdp_media_audio, 5004,
				    sdp_proto_rtpavp);
		if (err)
			goto out;

		err = sdp_format_add(NULL, audio, false, ref_pt, ref_cname,
				     ref_srate, 1, NULL, NULL, NULL, false,
				     NULL);
		if (err)
			goto out;

		err = sdp_format_add(NULL, audio, false, "8", "PCMA", 8000, 1,
				     NULL, NULL, NULL, false, NULL);
		if (err)
			goto out;

		mbuf_rewind(mb);
		(void)mbuf_write_str(mb, msgs[i]);
		mb->pos = 0;

		err = sdp_decode(sess, mb, true);
		if (err)
			goto out;
	}

 out:
	mem_deref(sess);
	mem_deref(mb);

	return err;
}
Exemplo n.º 6
0
static int oa_offeranswer(struct oa *oa, const char *offer, const char *answer)
{
	struct mbuf *mbo = NULL, *mba = NULL;
	int err = 0;

	/* create and send offer, compare offer */
	err = sdp_encode(&mbo, oa->alice, true);
	if (err)
		goto out;

	if (!sdp_cmp(mbo, offer)) {
		DEBUG_WARNING("offer failed:\n%b", mbo->buf, mbo->end);
		err = EBADMSG;
		goto out;
	}

	/* bob decodes offer */
	err = sdp_decode(oa->bob, mbo, true);
	if (err)
		goto out;

	/* create and send answer, compare answer */
	err = sdp_encode(&mba, oa->bob, false);
	if (err)
		goto out;

	if (!sdp_cmp(mba, answer)) {
		DEBUG_WARNING("answer failed:\n%b", mba->buf, mba->end);
		err = EBADMSG;
		goto out;
	}

	err = sdp_decode(oa->alice, mba, false);

 out:
	oa_reset(oa);
	mem_deref(mbo);
	mem_deref(mba);

	return err;
}
Exemplo n.º 7
0
static session_desc_t *find_sdp_for_program (const char *cm,
        const char *loc,
        char *errmsg,
        uint32_t errlen,
        uint64_t prog)
{
    char buffer[1024];
    http_client_t *http_client;
    http_resp_t *http_resp;
    sdp_decode_info_t *sdp_info;
    session_desc_t *sdp, *ptr, *sdp_ret;
    int translated;
    int ret, ix;

    snprintf(buffer, sizeof(buffer), "http://%s/%s", cm, loc);
    http_resp = NULL;
    http_client = http_init_connection(buffer);

    if (http_client == NULL) {
        snprintf(errmsg, errlen, "Cannot create http client with %s\n",
                 cm);
        return NULL;
    }
    ret = http_get(http_client, NULL, &http_resp);

    sdp_ret = NULL;
    if (ret > 0) {
        sdp_info = set_sdp_decode_from_memory(http_resp->body);
        if ((sdp_decode(sdp_info, &sdp, &translated) == 0) &&
                (translated > 0)) {
            for (ix = 0; ix < translated && sdp_ret == NULL; ix++) {
                if (sdp->session_id == prog) {
                    sdp_ret = sdp;
                    sdp = sdp->next;
                    sdp_ret->next = NULL;
                } else {
                    ptr = sdp->next;
                    sdp->next = NULL;
                    sdp_free_session_desc(sdp);
                    sdp = ptr;
                }
            }
            sdp_decode_info_free(sdp_info);
            if (sdp != NULL) sdp_free_session_desc(sdp);

        }
    }
    http_resp_free(http_resp);
    http_free_connection(http_client);
    return sdp_ret;
}
Exemplo n.º 8
0
static int create_from_sdp (CPlayerSession *psptr,
                            const char *name,
                            char *errmsg,
                            uint32_t errlen,
                            sdp_decode_info_t *sdp_info,
                            int have_audio_driver,
                            control_callback_vft_t *cc_vft)
{
    session_desc_t *sdp;
    int translated;

    if (sdp_info == NULL) {
        strcpy(errmsg, "SDP error");
        return (-1);
    }

    if (sdp_decode(sdp_info, &sdp, &translated) != 0) {
        snprintf(errmsg, errlen, "Invalid SDP file");
        sdp_decode_info_free(sdp_info);
        return (-1);
    }

    if (translated != 1) {
        snprintf(errmsg, errlen, "More than 1 program described in SDP");
        sdp_decode_info_free(sdp_info);
        return (-1);
    }

    int err;
    if (sdp->control_string != NULL) {
        // An on demand file... Just use the URL...
        err = create_media_for_streaming_ondemand(psptr,
                sdp->control_string,
                errmsg,
                errlen,
                cc_vft);
        sdp_free_session_desc(sdp);
        sdp_decode_info_free(sdp_info);
        return (err);
    }
    sdp_decode_info_free(sdp_info);
    return (create_media_for_streaming_broadcast(psptr,
            sdp,
            errmsg,
            errlen,
            have_audio_driver,
            cc_vft));
}
Exemplo n.º 9
0
/* called when an SDP answer is received */
static int answer_handler(const struct sip_msg *msg, void *arg)
{
	int err;
	(void)arg;

	re_printf("SDP answer received\n");

	err = sdp_decode(sdp, msg->mb, false);
	if (err) {
		re_fprintf(stderr, "unable to decode SDP answer: %s\n",
			   strerror(err));
		return err;
	}

	update_media();

	return 0;
}
Exemplo n.º 10
0
int main (int argc, char **argv)
{
  sdp_decode_info_t *sdpd;
  session_desc_t *session;
  int err;
  int num_translated;
  char *formatted;
  
  argc--;
  argv++;

  if (argc == 0) {
    printf("No arguments specified\n");
    exit(1);
  }
  sdp_set_loglevel(LOG_DEBUG);
  sdp_set_error_func(library_message);
  sdpd = set_sdp_decode_from_filename(*argv);
  if (sdpd == NULL) {
    printf("Didn't find file %s\n", *argv);
    exit(1);
  }
  err = sdp_decode(sdpd, &session, &num_translated);
  if (err != 0) {
    printf("couldn't decode it - error code is %d - number %d\n", err,
	   num_translated + 1);
  }

  if (num_translated != 0) {
    session_dump_list(session);
    err = sdp_encode_list_to_memory(session, &formatted, NULL);
    if (err == 0) {
      printf("%s\n", formatted);
    } else {
      printf("Error formating session %d\n", err);
    }
    free(formatted);
    sdp_free_session_desc(session);
  }
  sdp_decode_info_free(sdpd);

  return (0);
}
Exemplo n.º 11
0
static int sipsess_answer_handler(const struct sip_msg *msg, void *arg)
{
	struct call *call = arg;
	int err;

	MAGIC_CHECK(call);

	if (msg_ctype_cmp(&msg->ctyp, "multipart", "mixed"))
		(void)sdp_decode_multipart(&msg->ctyp.params, msg->mb);

	err = sdp_decode(call->sdp, msg->mb, false);
	if (err) {
		warning("call: could not decode SDP answer: %m\n", err);
		return err;
	}

	err = update_media(call);
	if (err)
		return err;

	return 0;
}
Exemplo n.º 12
0
int check_name_for_network (const char *name,
                            int &isOnDemand,
                            int &isRtpOverRtsp)
{
    sdp_decode_info_t *sdp_info;
    session_desc_t *sdp;
    int translated;
    http_resp_t *http_resp;
    int do_sdp = 0;

    http_resp = NULL;
    isOnDemand = 0;
    isRtpOverRtsp = 0;
    sdp_info = NULL;
    if (strncmp(name, "mpeg2t://", strlen("mpeg2t://")) == 0) {
        return 1;
    }
    if (strncmp(name, "iptv://", strlen("iptv://")) == 0) {
        // more later to handle the on demand/streaming case
        return 1;
    }
    if (strncmp(name, "rtsp://", strlen("rtsp://")) == 0) {
        isOnDemand = 1;
        isRtpOverRtsp = config.get_config_value(CONFIG_USE_RTP_OVER_RTSP);
        return 1;
    }
    // handle http, .sdp case
    if (strncmp(name, "http://", strlen("http://")) == 0) {
        http_client_t *http_client;
        int ret;
        http_client = http_init_connection(name);

        if (http_client == NULL) {
            return -1;
        }
        ret = http_get(http_client, NULL, &http_resp);
        if (ret > 0) {
            sdp_decode_info_t *sdp_info;
            sdp_info = set_sdp_decode_from_memory(http_resp->body);
            do_sdp = 1;
            http_free_connection(http_client);
        } else return -1;
        do_sdp = 1;
    } else {
        const char *suffix = strrchr(name, '.');
        if (suffix == NULL) {
            return -1;
        }
        if (strcasecmp(suffix, ".sdp") == 0) {
            sdp_info = set_sdp_decode_from_filename(name);
            do_sdp = 1;
        } else
            return 0;
    }
    if (do_sdp != 0) {
        if ((sdp_decode(sdp_info, &sdp, &translated) != 0) ||
                translated != 1) {
            sdp_decode_info_free(sdp_info);
            return (-1);
        }
        if (sdp->control_string != NULL) {
            isOnDemand = 1;
            isRtpOverRtsp = config.get_config_value(CONFIG_USE_RTP_OVER_RTSP);
        }
        sdp_free_session_desc(sdp);
        if (http_resp != NULL)
            http_resp_free(http_resp);
        sdp_decode_info_free(sdp_info);
        return 1;
    }
    return 0;
}
Exemplo n.º 13
0
/*
 * create_streaming - create a session for streaming.  Create an
 * RTSP session with the server, get the SDP information from it.
 */
int CPlayerSession::create_streaming_ondemand (const char *url, 
					       char *errmsg,
					       uint32_t errlen, 
					       int use_tcp)
{
  rtsp_command_t cmd;
  rtsp_decode_t *decode;
  sdp_decode_info_t *sdpdecode;
  int dummy;
  int err;

  // streaming has seek capability (at least on demand)
  session_set_seekable(1);
  player_debug_message("Creating streaming %s", url);
  memset(&cmd, 0, sizeof(rtsp_command_t));

  /*
   * create RTSP session
   */
  if (use_tcp != 0) {
    m_rtsp_client = rtsp_create_client_for_rtp_tcp(url, &err);
  } else {
    m_rtsp_client = rtsp_create_client(url, &err);
  }
  if (m_rtsp_client == NULL) {
    snprintf(errmsg, errlen, "Failed to create RTSP client");
    player_error_message("Failed to create rtsp client - error %d", err);
    return (err);
  }
  m_rtp_over_rtsp = use_tcp;

  cmd.accept = "application/sdp";

  /*
   * Send the RTSP describe.  This should return SDP information about
   * the session.
   */
  int rtsp_resp;

  rtsp_resp = rtsp_send_describe(m_rtsp_client, &cmd, &decode);
  if (rtsp_resp != RTSP_RESPONSE_GOOD) {
    int retval;
    if (decode != NULL) {
      retval = (((decode->retcode[0] - '0') * 100) +
		((decode->retcode[1] - '0') * 10) +
		(decode->retcode[2] - '0'));
      snprintf(errmsg, errlen, "RTSP describe error %d %s", retval,
	       decode->retresp != NULL ? decode->retresp : "");
      free_decode_response(decode);
    } else {
      retval = -1;
      snprintf(errmsg, errlen, "RTSP return invalid %d", rtsp_resp);
    }
    player_error_message("Describe response not good\n");
    return (retval);
  }

  sdpdecode = set_sdp_decode_from_memory(decode->body);
  if (sdpdecode == NULL) {
    snprintf(errmsg, errlen, "Memory failure");
    player_error_message("Couldn't get sdp decode\n");
    free_decode_response(decode);
    return (-1);
  }

  /*
   * Decode the SDP information into structures we can use.
   */
  err = sdp_decode(sdpdecode, &m_sdp_info, &dummy);
  free(sdpdecode);
  if (err != 0) {
    snprintf(errmsg, errlen, "Couldn't decode session description %s",
	     decode->body);
    player_error_message("Couldn't decode sdp %s", decode->body);
    free_decode_response(decode);
    return (-1);
  }
  if (dummy != 1) {
    snprintf(errmsg, errlen, "Incorrect number of sessions in sdp decode %d",
	     dummy);
    player_error_message("%s", errmsg);
    free_decode_response(decode);
    return (-1);
  }

  /*
   * Make sure we can use the urls in the sdp info
   */
  if (decode->content_location != NULL) {
    // Note - we may have problems if the content location is not absolute.
    m_content_base = strdup(decode->content_location);
  } else if (decode->content_base != NULL) {
    m_content_base = strdup(decode->content_base);
  } else {
    int urllen = strlen(url);
    if (url[urllen] != '/') {
      char *temp;
      temp = (char *)malloc(urllen + 2);
      strcpy(temp, url);
      strcat(temp, "/");
      m_content_base = temp;
    } else {
      m_content_base = strdup(url);
    }
  }

  convert_relative_urls_to_absolute(m_sdp_info,
				    m_content_base);

  if (m_sdp_info->control_string != NULL) {
    player_debug_message("setting control url to %s", m_sdp_info->control_string);
    set_session_control_url(m_sdp_info->control_string);
  }
  free_decode_response(decode);
  m_streaming = 1;
  m_streaming_ondemand = (get_range_from_sdp(m_sdp_info) != NULL);
  return (0);
}
Exemplo n.º 14
0
int call_accept(struct call *call, struct sipsess_sock *sess_sock,
		const struct sip_msg *msg)
{
	bool got_offer;
	int err;

	if (!call || !msg)
		return EINVAL;

	call->outgoing = false;

	got_offer = (mbuf_get_left(msg->mb) > 0);

	err = pl_strdup(&call->peer_uri, &msg->from.auri);
	if (err)
		return err;

	if (pl_isset(&msg->from.dname)) {
		err = pl_strdup(&call->peer_name, &msg->from.dname);
		if (err)
			return err;
	}

	if (got_offer) {
		struct sdp_media *m;
		const struct sa *raddr;

		err = sdp_decode(call->sdp, msg->mb, true);
		if (err)
			return err;

		call->got_offer = true;

		/*
		 * Each media description in the SDP answer MUST
		 * use the same network type as the corresponding
		 * media description in the offer.
		 *
		 * See RFC 6157
		 */
		m = stream_sdpmedia(audio_strm(call->audio));
		raddr = sdp_media_raddr(m);

		if (sa_af(raddr) != call->af) {
			info("call: incompatible address-family"
			     " (local=%s, remote=%s)\n",
			     net_af2name(call->af),
			     net_af2name(sa_af(raddr)));

			sip_treply(NULL, uag_sip(), msg,
				   488, "Not Acceptable Here");

			call_event_handler(call, CALL_EVENT_CLOSED,
					   "Wrong address family");
			return 0;
		}

		/* Check if we have any common audio codecs, after
		 * the SDP offer has been parsed
		 */
		if (!have_common_audio_codecs(call)) {
			info("call: no common audio codecs - rejected\n");

			sip_treply(NULL, uag_sip(), msg,
				   488, "Not Acceptable Here");

			call_event_handler(call, CALL_EVENT_CLOSED,
					   "No audio codecs");

			return 0;
		}
	}

	err = sipsess_accept(&call->sess, sess_sock, msg, 180, "Ringing",
			     ua_cuser(call->ua), "application/sdp", NULL,
			     auth_handler, call->acc, true,
			     sipsess_offer_handler, sipsess_answer_handler,
			     sipsess_estab_handler, sipsess_info_handler,
			     sipsess_refer_handler, sipsess_close_handler,
			     call, "Allow: %s\r\n", uag_allowed_methods());
	if (err) {
		warning("call: sipsess_accept: %m\n", err);
		return err;
	}

	set_state(call, STATE_INCOMING);

	/* New call */
	tmr_start(&call->tmr_inv, LOCAL_TIMEOUT*1000, invite_timeout, call);

	if (!call->acc->mnat)
		call_event_handler(call, CALL_EVENT_INCOMING, call->peer_uri);

	return err;
}
Exemplo n.º 15
0
int main (int argc, char **argv)
{
  rtsp_client_t *rtsp_client;
  int ret;
  rtsp_command_t cmd;
  rtsp_decode_t *decode;
  session_desc_t *sdp;
  media_desc_t *media;
  sdp_decode_info_t *sdpdecode;
  rtsp_session_t *session;
  int dummy;

  rtsp_set_error_func(local_error_msg);
  rtsp_set_loglevel(LOG_DEBUG);
  memset(&cmd, 0, sizeof(rtsp_command_t));

  argv++;
  rtsp_client = rtsp_create_client(*argv, &ret, NULL, 0);

  if (rtsp_client == NULL) {
    printf("No client created - error %d\n", ret);
    return (1);
  }

  if (rtsp_send_describe(rtsp_client, &cmd, &decode) != RTSP_RESPONSE_GOOD) {
    printf("Describe response not good\n");
    free_decode_response(decode);
    free_rtsp_client(rtsp_client);
    return(1);
  }

  sdpdecode = set_sdp_decode_from_memory(decode->body);
  if (sdpdecode == NULL) {
    printf("Couldn't get sdp decode\n");
    free_decode_response(decode);
    free_rtsp_client(rtsp_client);
    return(1);
  }

  if (sdp_decode(sdpdecode, &sdp, &dummy) != 0) {
    printf("Couldn't decode sdp\n");
    free_decode_response(decode);
    free_rtsp_client(rtsp_client);
    return (1);
  }
  free(sdpdecode);

  if (decode->content_base == NULL) {
    convert_relative_urls_to_absolute (sdp, *argv);
  } else {
    convert_relative_urls_to_absolute(sdp, decode->content_base);
  }

  free_decode_response(decode);
  decode = NULL;
#if 1
  cmd.transport = "RTP/AVP;unicast;client_port=4588-4589";
#else
  cmd.transport = "RTP/AVP/TCP;interleaved=0-1";
#endif
  media = sdp->media;
  dummy = rtsp_send_setup(rtsp_client,
			  media->control_string,
			  &cmd,
			  &session,
			  &decode, 0);

  if (dummy != RTSP_RESPONSE_GOOD) {
    printf("Response to setup is %d\n", dummy);
    sdp_free_session_desc(sdp);
    free_decode_response(decode);
    free_rtsp_client(rtsp_client);
    return (1);
  }
  free_decode_response(decode);
  cmd.range = "npt=0.0-30.0";
  cmd.transport = NULL;
  if (sdp->control_string != NULL)
    dummy = rtsp_send_aggregate_play(rtsp_client, sdp->control_string, &cmd, &decode);
  else 
    dummy = rtsp_send_play(session, &cmd, &decode);
  if (dummy != RTSP_RESPONSE_GOOD) {
    printf("response to play is %d\n", dummy);
  } else {
    sleep(10);
  }
  free_decode_response(decode);
  cmd.transport = NULL;
  if (sdp->control_string != NULL)
    dummy = rtsp_send_aggregate_teardown(rtsp_client, sdp->control_string, &cmd, &decode);
  else 
    dummy = rtsp_send_teardown(session, NULL, &decode);
  printf("Teardown response %d\n", dummy);
  sdp_free_session_desc(sdp);
  free_decode_response(decode);
  free_rtsp_client(rtsp_client);
  return (0);
}  
Exemplo n.º 16
0
int call_accept(struct call *call, struct sipsess_sock *sess_sock,
		const struct sip_msg *msg)
{
	bool got_offer;
	int err;

	if (!call || !msg)
		return EINVAL;

	got_offer = (mbuf_get_left(msg->mb) > 0);

	err = pl_strdup(&call->peer_uri, &msg->from.auri);
	if (err)
		return err;

	if (pl_isset(&msg->from.dname)) {
		err = pl_strdup(&call->peer_name, &msg->from.dname);
		if (err)
			return err;
	}

	if (got_offer) {

		err = sdp_decode(call->sdp, msg->mb, true);
		if (err)
			return err;

		call->got_offer = true;

		/* Check if we have any common audio codecs, after
		 * the SDP offer has been parsed
		 */
		if (!have_common_audio_codecs(call)) {
			info("call: no common audio codecs - rejected\n");

			sip_treply(NULL, uag_sip(), msg,
				   488, "Not Acceptable Here");

			call_event_handler(call, CALL_EVENT_CLOSED,
					   "No audio codecs");

			return 0;
		}
	}

	err = sipsess_accept(&call->sess, sess_sock, msg, 180, "Ringing",
			     ua_cuser(call->ua), "application/sdp", NULL,
			     auth_handler, call->acc, true,
			     sipsess_offer_handler, sipsess_answer_handler,
			     sipsess_estab_handler, sipsess_info_handler,
			     sipsess_refer_handler, sipsess_close_handler,
			     call, "Allow: %s\r\n", uag_allowed_methods());
	if (err) {
		warning("call: sipsess_accept: %m\n", err);
		return err;
	}

	set_state(call, STATE_INCOMING);

	/* New call */
	tmr_start(&call->tmr_inv, LOCAL_TIMEOUT*1000, invite_timeout, call);

	if (!call->acc->mnat)
		call_event_handler(call, CALL_EVENT_INCOMING, call->peer_uri);

	return err;
}
Exemplo n.º 17
0
int test_sdp_all(void)
{
	struct sdp_session *sess = NULL;
	struct sdp_media *audio = NULL;
	struct mbuf *desc = NULL;
	struct sa ref;
	const struct sdp_format *rc = NULL, *sc;
	struct sa laddr;
	int err;

	(void)sa_set_str(&laddr, ref_host, 0);

	err = sdp_session_alloc(&sess, &laddr);
	if (err)
		goto out;

	err = sdp_media_add(&audio, sess, sdp_media_audio, 5004,
			    sdp_proto_rtpavp);
	if (err)
		goto out;

	err  = sdp_format_add(NULL, audio, false, ref_pt, ref_cname,
			      ref_srate, 1, NULL, NULL, NULL, false, NULL);
	err |= sdp_format_add(NULL, audio, false, "110", cname_speex,
			      16000, 2, NULL, NULL, NULL, false, NULL);
	if (err)
		goto out;

	/* find codec - expected */
	sc = sdp_media_format(audio, true, NULL, 0, "PCMU", 8000, 1);
	if (!sc) {
		DEBUG_WARNING("codec not found\n");
		err = ENOENT;
		goto out;
	}

	sc = sdp_media_format(audio, true, NULL, 110, "Speex", 16000, 2);
	if (!sc) {
		DEBUG_WARNING("codec not found: speex\n");
		err = ENOENT;
		goto out;
	}

	/* find codec - not expected */
	sc = sdp_media_format(audio, true, NULL, -1, "Speex", 8000, 1);
	if (sc) {
		DEBUG_WARNING("unexpected codec found\n");
		err = EINVAL;
		goto out;
	}

	err = sdp_encode(&desc, sess, true);
	if (err)
		goto out;

	if (!sdp_cmp(desc, ref_msg)) {
		DEBUG_WARNING("ref: %s\n", ref_msg);
		DEBUG_WARNING("sdp: %b\n", desc->buf, desc->end);
		err = EBADMSG;
		goto out;
	}

	err = sdp_decode(sess, desc, false);
	if (err)
		goto out;

	rc = sdp_media_rformat(audio, NULL);
	if (!rc) {
		err = ENOENT;
		goto out;
	}

	err = sa_set_str(&ref, ref_host, ref_port);
	if (err)
		goto out;

	err = EINVAL;

	if (!sa_cmp(sdp_media_raddr(audio), &ref, SA_ALL))
		goto out;

	if (!rc)
		goto out;

	if (0 != strcmp(rc->id, ref_pt))
		goto out;

	if (0 != strcmp(ref_cname, rc->name))
		goto out;

	if (rc->srate != ref_srate)
		goto out;

	err = 0;

 out:
	mem_deref(audio);
	mem_deref(sess);
	mem_deref(desc);

	return err;
}