예제 #1
0
static int request(struct sip_req *sr)
{
    info("baresip.sipreq.request()\n");
    return sip_drequestf(&sr->req, uag_sip(), true, sr->method, sr->dlg,
                         0, sr->auth, NULL, resp_handler,
                         sr, sr->fmt ? "%s" : NULL, sr->fmt);
}
예제 #2
0
파일: ua.c 프로젝트: pasichnichenko/baresip
/* Handle incoming calls */
static void sipsess_conn_handler(const struct sip_msg *msg, void *arg)
{
	const struct sip_hdr *hdr;
	struct ua *ua;
	struct call *call = NULL;
	char to_uri[256];
	int err;

	(void)arg;

	ua = uag_find(&msg->uri.user);
	if (!ua) {
		warning("ua: %r: UA not found: %r\n",
			&msg->from.auri, &msg->uri.user);
		(void)sip_treply(NULL, uag_sip(), msg, 404, "Not Found");
		return;
	}

	/* handle multiple calls */
	if (list_count(&ua->calls) + 1 > MAX_CALLS) {
		info("ua: rejected call from %r (maximum %d calls)\n",
		     &msg->from.auri, MAX_CALLS);
		(void)sip_treply(NULL, uag.sip, msg, 486, "Busy Here");
		return;
	}

	/* Handle Require: header, check for any required extensions */
	hdr = sip_msg_hdr_apply(msg, true, SIP_HDR_REQUIRE,
				require_handler, ua);
	if (hdr) {
		info("ua: call from %r rejected with 420"
			     " -- option-tag '%r' not supported\n",
			     &msg->from.auri, &hdr->val);

		(void)sip_treplyf(NULL, NULL, uag.sip, msg, false,
				  420, "Bad Extension",
				  "Unsupported: %r\r\n"
				  "Content-Length: 0\r\n\r\n",
				  &hdr->val);
		return;
	}

	(void)pl_strcpy(&msg->to.auri, to_uri, sizeof(to_uri));

	err = ua_call_alloc(&call, ua, VIDMODE_ON, msg, NULL, to_uri);
	if (err) {
		warning("ua: call_alloc: %m\n", err);
		goto error;
	}

	err = call_accept(call, uag.sock, msg);
	if (err)
		goto error;

	return;

 error:
	mem_deref(call);
	(void)sip_treply(NULL, uag.sip, msg, 500, "Call Error");
}
예제 #3
0
파일: message.c 프로젝트: alfredh/baresip
static bool request_handler(const struct sip_msg *msg, void *arg)
{
	struct message *message = arg;
	struct ua *ua;
	struct le *le = message->lsnrl.head;
	bool hdld = false;

	if (pl_strcmp(&msg->met, "MESSAGE"))
		return false;

	ua = uag_find(&msg->uri.user);
	if (!ua) {
		(void)sip_treply(NULL, uag_sip(), msg, 404, "Not Found");
		return true;
	}

	while (le) {
		struct message_lsnr *lsnr = le->data;

		le = le->next;

		handle_message(lsnr, ua, msg);

		hdld = true;
	}

	return hdld;
}
예제 #4
0
파일: message.c 프로젝트: alfredh/baresip
/**
 * Listen to incoming SIP MESSAGE messages
 *
 * @param message Messaging subsystem
 * @param recvh   Message receive handler
 * @param arg     Handler argument
 *
 * @return 0 if success, otherwise errorcode
 */
int message_listen(struct message *message,
		   message_recv_h *recvh, void *arg)
{
	struct message_lsnr *lsnr;
	int err = 0;

	if (!message || !recvh)
		return EINVAL;

	/* create the SIP listener if it does not exist */
	if (!message->sip_lsnr) {

		err = sip_listen(&message->sip_lsnr, uag_sip(), true,
				 request_handler, message);
		if (err)
			goto out;
	}

	lsnr = mem_zalloc(sizeof(*lsnr), listener_destructor);
	if (!lsnr)
		return ENOMEM;

	lsnr->recvh = recvh;
	lsnr->arg = arg;

	list_append(&message->lsnrl, &lsnr->le, lsnr);

 out:
	return err;
}
예제 #5
0
파일: message.c 프로젝트: AmesianX/baresip
static void handle_message(struct ua *ua, const struct sip_msg *msg)
{
	static const char ctype_text[] = "text/plain";
	struct pl ctype_pl = {ctype_text, sizeof(ctype_text)-1};
	(void)ua;

	if (msg_ctype_cmp(&msg->ctyp, "text", "plain") && recvh) {
		recvh(&msg->from.auri, &ctype_pl, msg->mb, recvarg);
		(void)sip_reply(uag_sip(), msg, 200, "OK");
	}
	else {
		(void)sip_replyf(uag_sip(), msg, 415, "Unsupported Media Type",
				 "Accept: %s\r\n"
				 "Content-Length: 0\r\n"
				 "\r\n",
				 ctype_text);
	}
}
예제 #6
0
파일: notifier.c 프로젝트: FOSSRIT/baresip
static bool sub_handler(const struct sip_msg *msg, void *arg)
{
	struct ua *ua;

	(void)arg;

	ua = uag_find(&msg->uri.user);
	if (!ua) {
		warning("presence: no UA found for %r\n", &msg->uri.user);
		(void)sip_treply(NULL, uag_sip(), msg, 404, "Not Found");
		return true;
	}

	if (notifier_add(evsock, msg, ua))
		(void)sip_treply(NULL, uag_sip(), msg, 400, "Bad Presence");

	return true;
}
예제 #7
0
파일: notifier.c 프로젝트: FOSSRIT/baresip
int notifier_init(void)
{
	int err;

	err = sipevent_listen(&evsock, uag_sip(), 32, 32, sub_handler, NULL);
	if (err)
		return err;

	return cmd_register(cmdv, ARRAY_SIZE(cmdv));
}
예제 #8
0
파일: message.c 프로젝트: AmesianX/baresip
int message_init(message_recv_h *h, void *arg)
{
	int err;

	err = sip_listen(&lsnr, uag_sip(), true, request_handler, NULL);
	if (err)
		return err;

	recvh   = h;
	recvarg = arg;

	return 0;
}
예제 #9
0
파일: message.c 프로젝트: AmesianX/baresip
static bool request_handler(const struct sip_msg *msg, void *arg)
{
	struct ua *ua;

	(void)arg;

	if (pl_strcmp(&msg->met, "MESSAGE"))
		return false;

	ua = uag_find(&msg->uri.user);
	if (!ua) {
		(void)sip_treply(NULL, uag_sip(), msg, 404, "Not Found");
		return true;
	}

	handle_message(ua, msg);

	return true;
}
예제 #10
0
파일: call.c 프로젝트: sealaunch/baresip
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;
}
예제 #11
0
파일: call.c 프로젝트: aKlausKranz/baresip
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;
}