Exemplo n.º 1
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.º 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
int call_answer(struct call *call, uint16_t scode)
{
	struct mbuf *desc;
	int err;

	if (!call || !call->sess)
		return EINVAL;

	if (STATE_INCOMING != call->state) {
		return 0;
	}

	info("answering call from %s with %u\n", call->peer_uri, scode);

	if (call->got_offer) {

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

	err = sdp_encode(&desc, call->sdp, !call->got_offer);
	if (err)
		return err;

	err = sipsess_answer(call->sess, scode, "Answering", desc,
			     "Allow: %s\r\n", uag_allowed_methods());

	mem_deref(desc);

	return err;
}
Exemplo n.º 4
0
int sdp_encode_list_to_file (session_desc_t *sptr,
			      const char *filename,
			      int append)
{
  FILE *ofile;
  sdp_encode_t sdp;
  int retval;
  
  CHECK_RETURN(prepare_sdp_encode(&sdp));
  ofile = fopen(filename, append ? "a" : "w");
  if (ofile == NULL) {
    free(sdp.buffer);
	return (-1);
  }
  while (sptr != NULL) {
    sdp.used = 0;
    retval = sdp_encode(sptr, &sdp);
    if (retval != 0) {
      break;
    }
    fputs(sdp.buffer, ofile);
    sptr = sptr->next;
  }
  fclose(ofile);
  free(sdp.buffer);
  return (0);
}
Exemplo n.º 5
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.º 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
int sdp_encode_one_to_memory (session_desc_t *sptr, char **mem)
{
  sdp_encode_t sdp;
  int retval;
  
  *mem = NULL;
  CHECK_RETURN(prepare_sdp_encode(&sdp));
  retval = sdp_encode(sptr, &sdp);
  if (retval != 0) {
    free(sdp.buffer);
    return (retval);
  }
  *mem = sdp.buffer;
  return (0);
}
Exemplo n.º 8
0
int sdp_encode_one_to_file (session_desc_t *sptr,
			    const char *filename,
			    int append)
{
  FILE *ofile;
  sdp_encode_t sdp;
  CHECK_RETURN(prepare_sdp_encode(&sdp));
  CHECK_RETURN(sdp_encode(sptr, &sdp));
  ofile = fopen(filename, append ? "a" : "w");
  if (ofile == NULL) {
    sdp_debug(LOG_CRIT, "Cannot open file %s", filename);
    free(sdp.buffer);
    return (-1);
  }
  fputs(sdp.buffer, ofile);
  fclose(ofile);
  free(sdp.buffer);
  return (0);
}
Exemplo n.º 9
0
int sdp_encode_list_to_memory (session_desc_t *sptr, char **mem, int *count)
{
  sdp_encode_t sdp;
  int retval;
  int cnt;
  
  *mem = NULL;
  CHECK_RETURN(prepare_sdp_encode(&sdp));
  cnt = 0;
  retval = 0;
  while (sptr != NULL && retval == 0) {
    retval = sdp_encode(sptr, &sdp);
    if (retval == 0)
      cnt++;
    sptr = sptr->next;
  }
  *mem = sdp.buffer;
  if (count != NULL)
    *count = cnt;
  return (retval);
}
Exemplo n.º 10
0
int call_sdp_get(const struct call *call, struct mbuf **descp, bool offer)
{
	return sdp_encode(descp, call->sdp, offer);
}
Exemplo n.º 11
0
int main(int argc, char *argv[])
{
	struct sa nsv[16];
	struct dnsc *dnsc = NULL;
	struct sa laddr;
	uint32_t nsc;
	int err; /* errno return values */

	/* enable coredumps to aid debugging */
	(void)sys_coredump_set(true);

	/* initialize libre state */
	err = libre_init();
	if (err) {
		re_fprintf(stderr, "re init failed: %s\n", strerror(err));
		goto out;
	}

	nsc = ARRAY_SIZE(nsv);

	/* fetch list of DNS server IP addresses */
	err = dns_srv_get(NULL, 0, nsv, &nsc);
	if (err) {
		re_fprintf(stderr, "unable to get dns servers: %s\n",
			   strerror(err));
		goto out;
	}

	/* create DNS client */
	err = dnsc_alloc(&dnsc, NULL, nsv, nsc);
	if (err) {
		re_fprintf(stderr, "unable to create dns client: %s\n",
			   strerror(err));
		goto out;
	}

	/* create SIP stack instance */
	err = sip_alloc(&sip, dnsc, 32, 32, 32,
			"ua demo v" VERSION " (" ARCH "/" OS ")",
			exit_handler, NULL);
	if (err) {
		re_fprintf(stderr, "sip error: %s\n", strerror(err));
		goto out;
	}

	/* fetch local IP address */
	err = net_default_source_addr_get(AF_INET, &laddr);
	if (err) {
		re_fprintf(stderr, "local address error: %s\n", strerror(err));
		goto out;
	}

	/* listen on random port */
	sa_set_port(&laddr, 0);

	/* add supported SIP transports */
	err |= sip_transp_add(sip, SIP_TRANSP_UDP, &laddr);
	err |= sip_transp_add(sip, SIP_TRANSP_TCP, &laddr);
	if (err) {
		re_fprintf(stderr, "transport error: %s\n", strerror(err));
		goto out;
	}

	/* create SIP session socket */
	err = sipsess_listen(&sess_sock, sip, 32, connect_handler, NULL);
	if (err) {
		re_fprintf(stderr, "session listen error: %s\n",
			   strerror(err));
		goto out;
	}

	/* create the RTP/RTCP socket */
	err = rtp_listen(&rtp, IPPROTO_UDP, &laddr, 10000, 30000, true,
			 rtp_handler, rtcp_handler, NULL);
	if (err) {
		re_fprintf(stderr, "rtp listen error: %m\n", err);
		goto out;
	}

	re_printf("local RTP port is %u\n", sa_port(rtp_local(rtp)));

	/* create SDP session */
	err = sdp_session_alloc(&sdp, &laddr);
	if (err) {
		re_fprintf(stderr, "sdp session error: %s\n", strerror(err));
		goto out;
	}

	/* add audio sdp media, using port from RTP socket */
	err = sdp_media_add(&sdp_media, sdp, "audio",
			    sa_port(rtp_local(rtp)), "RTP/AVP");
	if (err) {
		re_fprintf(stderr, "sdp media error: %s\n", strerror(err));
		goto out;
	}

	/* add G.711 sdp media format */
	err = sdp_format_add(NULL, sdp_media, false, "0", "PCMU", 8000, 1,
			     NULL, NULL, NULL, false, NULL);
	if (err) {
		re_fprintf(stderr, "sdp format error: %s\n", strerror(err));
		goto out;
	}

	/* invite provided URI */
	if (argc > 1) {

		struct mbuf *mb;

		/* create SDP offer */
		err = sdp_encode(&mb, sdp, true);
		if (err) {
			re_fprintf(stderr, "sdp encode error: %s\n",
				   strerror(err));
			goto out;
		}

		err = sipsess_connect(&sess, sess_sock, argv[1], name,
				      uri, name,
				      NULL, 0, "application/sdp", mb,
				      auth_handler, NULL, false,
				      offer_handler, answer_handler,
				      progress_handler, establish_handler,
				      NULL, NULL, close_handler, NULL, NULL);
		mem_deref(mb); /* free SDP buffer */
		if (err) {
			re_fprintf(stderr, "session connect error: %s\n",
				   strerror(err));
			goto out;
		}

		re_printf("inviting <%s>...\n", argv[1]);
	}
	else {

		err = sipreg_register(&reg, sip, registrar, uri, uri, 60, name,
				      NULL, 0, 0, auth_handler, NULL, false,
				      register_handler, NULL, NULL, NULL);
		if (err) {
			re_fprintf(stderr, "register error: %s\n",
				   strerror(err));
			goto out;
		}

		re_printf("registering <%s>...\n", uri);
	}

	/* main loop */
	err = re_main(signal_handler);

 out:
	/* clean up/free all state */
	mem_deref(sdp); /* will also free sdp_media */
	mem_deref(rtp);
	mem_deref(sess_sock);
	mem_deref(sip);
	mem_deref(dnsc);

	/* free librar state */
	libre_close();

	/* check for memory leaks */
	tmr_debug();
	mem_debug();

	return err;
}
Exemplo n.º 12
0
/** Test BFCP in SDP -- RFC 4583 */
int test_sdp_bfcp(void)
{
	static const char *msg_offer =
		"v=0\r\n"
		"o=alice 2890844526 2890844526 IN IP4 1.2.3.4\r\n"
		"s=-\r\n"
		"c=IN IP4 1.2.3.4\r\n"
		"t=0 0\r\n"
		"m=application 50000 TCP/BFCP *\r\n"
		"a=sendrecv\r\n"
		"a=setup:passive\r\n"
		"a=connection:new\r\n"
		"a=floorctrl:s-only\r\n"
		"a=confid:4321\r\n"
		"a=userid:1234\r\n"
		"a=floorid:1 m-stream:10\r\n"
		"a=floorid:2 m-stream:11\r\n"
		"m=audio 50002 RTP/AVP 0\r\n"
		"a=sendrecv\r\n"
		"a=label:10\r\n"
		"m=video 50004 RTP/AVP 31\r\n"
		"a=sendrecv\r\n"
		"a=label:11\r\n"
		;
	struct sdp_session *alice = NULL, *bob = NULL;
	struct sdp_media *bfcp, *audio, *video;
	struct mbuf *mbo = NULL, *mba = NULL;
	struct sa laddr;
	int err;

	/* create sessions */
	(void)sa_set_str(&laddr, "1.2.3.4", 0);
	err  = sdp_session_alloc(&alice, &laddr);
	if (err)
		goto out;

	err = sdp_media_add(&bfcp, alice, "application", 50000, "TCP/BFCP");
	if (err)
		goto out;

	err |= sdp_media_set_lattr(bfcp, true, "setup", "passive");
	err |= sdp_media_set_lattr(bfcp, true, "connection", "new");
	err |= sdp_media_set_lattr(bfcp, true, "floorctrl", "s-only");
	err |= sdp_media_set_lattr(bfcp, true, "confid", "4321");
	err |= sdp_media_set_lattr(bfcp, true, "userid", "1234");
	err |= sdp_media_set_lattr(bfcp, false, "floorid", "1 m-stream:10");
	sdp_media_del_lattr(bfcp, "floorid"); /* test attr delete */
	err |= sdp_media_set_lattr(bfcp, false, "floorid", "1 m-stream:10");
	err |= sdp_media_set_lattr(bfcp, false, "floorid", "2 m-stream:11");
	if (err)
		goto out;

	err = sdp_media_add(&audio, alice, "audio", 50002, "RTP/AVP");
	if (err)
		goto out;

	err = sdp_media_add(&video, alice, "video", 50004, "RTP/AVP");
	if (err)
		goto out;

	err |= sdp_media_set_lattr(audio, true, "label", "10");
	err |= sdp_media_set_lattr(video, true, "label", "11");
	if (err)
		goto out;

	err  = sdp_format_add(NULL, bfcp, false, "*", NULL, 0, 0,
			      NULL, NULL, NULL, false, NULL);
	err |= sdp_format_add(NULL, audio, false, "0", NULL, 0, 0,
			      NULL, NULL, NULL, false, NULL);
	err |= sdp_format_add(NULL, video, false, "31", NULL, 0, 0,
			      NULL, NULL, NULL, false, NULL);
	if (err)
		goto out;

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

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

 out:
	mem_deref(alice);
	mem_deref(bob);
	mem_deref(mbo);
	mem_deref(mba);

	return err;
}
Exemplo n.º 13
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;
}