blob: e30bc0d5e86988978742b5b5ea30b667db7d6f69 [file] [log] [blame]
/**
* @file info.c SIP Session Info
*
* Copyright (C) 2010 Creytiv.com
*/
#include <re_types.h>
#include <re_mem.h>
#include <re_mbuf.h>
#include <re_sa.h>
#include <re_list.h>
#include <re_hash.h>
#include <re_fmt.h>
#include <re_uri.h>
#include <re_tmr.h>
#include <re_msg.h>
#include <re_sip.h>
#include <re_sipsess.h>
#include "sipsess.h"
static int info_request(struct sipsess_request *req);
static void info_resp_handler(int err, const struct sip_msg *msg, void *arg)
{
struct sipsess_request *req = arg;
if (err || sip_request_loops(&req->ls, msg->scode))
goto out;
if (msg->scode < 200) {
return;
}
else if (msg->scode < 300) {
;
}
else {
if (req->sess->terminated)
goto out;
switch (msg->scode) {
case 401:
case 407:
err = sip_auth_authenticate(req->sess->auth, msg);
if (err) {
err = (err == EAUTH) ? 0 : err;
break;
}
err = info_request(req);
if (err)
break;
return;
case 408:
case 481:
sipsess_terminate(req->sess, 0, msg);
break;
}
}
out:
if (!req->sess->terminated) {
if (err == ETIMEDOUT)
sipsess_terminate(req->sess, err, NULL);
else
req->resph(err, msg, req->arg);
}
mem_deref(req);
}
static int info_request(struct sipsess_request *req)
{
return sip_drequestf(&req->req, req->sess->sip, true, "INFO",
req->sess->dlg, 0, req->sess->auth,
NULL, info_resp_handler, req,
"Content-Type: %s\r\n"
"Content-Length: %zu\r\n"
"\r\n"
"%b",
req->ctype,
mbuf_get_left(req->body),
mbuf_buf(req->body), mbuf_get_left(req->body));
}
/**
* Send a SIP INFO request in the SIP Session
*
* @param sess SIP Session
* @param ctype Content-type
* @param body Content description (e.g. SDP)
* @param resph Response handler
* @param arg Handler argument
*
* @return 0 if success, otherwise errorcode
*/
int sipsess_info(struct sipsess *sess, const char *ctype, struct mbuf *body,
sip_resp_h *resph, void *arg)
{
struct sipsess_request *req;
int err;
if (!sess || sess->terminated || !ctype || !body)
return EINVAL;
if (!sip_dialog_established(sess->dlg))
return ENOTCONN;
err = sipsess_request_alloc(&req, sess, ctype, body, resph, arg);
if (err)
return err;
err = info_request(req);
if (err)
mem_deref(req);
return err;
}