summaryrefslogtreecommitdiff
path: root/pjsip
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2006-07-18 14:39:40 +0000
committerBenny Prijono <bennylp@teluu.com>2006-07-18 14:39:40 +0000
commit490bd78f06ea0c101244760b2a5bbb1dae1b3041 (patch)
treee676089d77bd8ff0e0748e4666b3f6b21fb1e2b6 /pjsip
parent65035358b4b7f51b4183a0937e9e93ff130d7525 (diff)
Small improvements: (1) pjsua now responds to incoming OPTIONS request, which means that some modules (evsub, invite) need to register their capabilities to the endpoint, (2) added command in pjsua to send arbitrary request
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@612 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip')
-rw-r--r--pjsip/include/pjsip-simple/evsub.h12
-rw-r--r--pjsip/include/pjsip-ua/sip_inv.h15
-rw-r--r--pjsip/include/pjsua-lib/pjsua.h11
-rw-r--r--pjsip/src/pjsip-simple/evsub.c21
-rw-r--r--pjsip/src/pjsip-ua/sip_inv.c40
-rw-r--r--pjsip/src/pjsip/sip_dialog.c10
-rw-r--r--pjsip/src/pjsua-lib/pjsua_acc.c4
-rw-r--r--pjsip/src/pjsua-lib/pjsua_core.c120
8 files changed, 220 insertions, 13 deletions
diff --git a/pjsip/include/pjsip-simple/evsub.h b/pjsip/include/pjsip-simple/evsub.h
index 4eb2ae1c..e352e798 100644
--- a/pjsip/include/pjsip-simple/evsub.h
+++ b/pjsip/include/pjsip-simple/evsub.h
@@ -252,6 +252,18 @@ PJ_DECL(pj_status_t) pjsip_evsub_register_pkg( pjsip_module *pkg_mod,
unsigned accept_cnt,
const pj_str_t accept[]);
+/**
+ * Get the Allow-Events header. This header is built based on the packages
+ * that are registered to the evsub module.
+ *
+ * @param m Pointer to event subscription module instance, or
+ * NULL to use default instance (equal to
+ * #pjsip_evsub_instance()).
+ *
+ * @return The Allow-Events header.
+ */
+PJ_DECL(const pjsip_hdr*) pjsip_evsub_get_allow_events_hdr(pjsip_module *m);
+
/**
* Create client subscription session.
diff --git a/pjsip/include/pjsip-ua/sip_inv.h b/pjsip/include/pjsip-ua/sip_inv.h
index e07ba79a..cb6dc251 100644
--- a/pjsip/include/pjsip-ua/sip_inv.h
+++ b/pjsip/include/pjsip-ua/sip_inv.h
@@ -615,6 +615,21 @@ PJ_DECL(pjsip_inv_session*) pjsip_tsx_get_inv_session(pjsip_transaction *tsx);
PJ_DECL(const char *) pjsip_inv_state_name(pjsip_inv_state state);
+/**
+ * This is a utility function to create SIP body for SDP content.
+ *
+ * @param pool Pool to allocate memory.
+ * @param sdp SDP session to be put in the SIP message body.
+ * @param p_body Pointer to receive SIP message body containing
+ * the SDP session.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_create_sdp_body(pj_pool_t *pool,
+ pjmedia_sdp_session *sdp,
+ pjsip_msg_body **p_body);
+
+
PJ_END_DECL
/**
diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h
index 7ae37eed..5b8125a2 100644
--- a/pjsip/include/pjsua-lib/pjsua.h
+++ b/pjsip/include/pjsua-lib/pjsua.h
@@ -417,6 +417,11 @@ typedef struct pjsua_config
*/
pjsua_callback cb;
+ /**
+ * User agent string (default empty)
+ */
+ pj_str_t user_agent;
+
} pjsua_config;
@@ -468,6 +473,8 @@ PJ_INLINE(void) pjsua_config_dup(pj_pool_t *pool,
for (i=0; i<src->cred_count; ++i) {
pjsip_cred_dup(pool, &dst->cred_info[i], &src->cred_info[i]);
}
+
+ pj_strdup_with_null(pool, &dst->user_agent, &src->user_agent);
}
@@ -2080,7 +2087,7 @@ struct pjsua_media_config
* The media quality also sets speex codec quality/complexity to the
* number.
*
- * Default: 3.
+ * Default: 5.
*/
unsigned quality;
};
@@ -2099,7 +2106,7 @@ PJ_INLINE(void) pjsua_media_config_default(pjsua_media_config *cfg)
cfg->max_media_ports = 32;
cfg->has_ioqueue = PJ_TRUE;
cfg->thread_cnt = 1;
- cfg->quality = 3;
+ cfg->quality = 5;
}
diff --git a/pjsip/src/pjsip-simple/evsub.c b/pjsip/src/pjsip-simple/evsub.c
index 7b13d548..e5b4f526 100644
--- a/pjsip/src/pjsip-simple/evsub.c
+++ b/pjsip/src/pjsip-simple/evsub.c
@@ -420,6 +420,12 @@ PJ_DEF(pj_status_t) pjsip_evsub_register_pkg( pjsip_module *pkg_mod,
++mod_evsub.allow_events_hdr->count;
}
+ /* Add to endpoint's Accept header */
+ pjsip_endpt_add_capability(mod_evsub.endpt, &mod_evsub.mod,
+ PJSIP_H_ACCEPT, NULL,
+ pkg->pkg_accept->count,
+ pkg->pkg_accept->values);
+
/* Done */
@@ -431,6 +437,21 @@ PJ_DEF(pj_status_t) pjsip_evsub_register_pkg( pjsip_module *pkg_mod,
}
+/*
+ * Retrieve Allow-Events header
+ */
+PJ_DEF(const pjsip_hdr*) pjsip_evsub_get_allow_events_hdr(pjsip_module *m)
+{
+ struct mod_evsub *mod;
+
+ if (m == NULL)
+ m = pjsip_evsub_instance();
+
+ mod = (struct mod_evsub*)m;
+
+ return (pjsip_hdr*) mod->allow_events_hdr;
+}
+
/*
* Update expiration time.
diff --git a/pjsip/src/pjsip-ua/sip_inv.c b/pjsip/src/pjsip-ua/sip_inv.c
index d3176862..e35f0eea 100644
--- a/pjsip/src/pjsip-ua/sip_inv.c
+++ b/pjsip/src/pjsip-ua/sip_inv.c
@@ -112,11 +112,16 @@ struct tsx_inv_data
static pj_status_t mod_inv_load(pjsip_endpoint *endpt)
{
pj_str_t allowed[] = {{"INVITE", 6}, {"ACK",3}, {"BYE",3}, {"CANCEL",6}};
+ pj_str_t accepted = { "application/sdp", 15 };
/* Register supported methods: INVITE, ACK, BYE, CANCEL */
pjsip_endpt_add_capability(endpt, &mod_inv.mod, PJSIP_H_ALLOW, NULL,
PJ_ARRAY_SIZE(allowed), allowed);
+ /* Register "application/sdp" in Accept header */
+ pjsip_endpt_add_capability(endpt, &mod_inv.mod, PJSIP_H_ACCEPT, NULL,
+ 1, &accepted);
+
return PJ_SUCCESS;
}
@@ -959,22 +964,43 @@ static int print_sdp(pjsip_msg_body *body, char *buf, pj_size_t len)
return pjmedia_sdp_print(body->data, buf, len);
}
-static pjsip_msg_body *create_sdp_body(pj_pool_t *pool,
- const pjmedia_sdp_session *c_sdp)
+
+PJ_DEF(pj_status_t) pjsip_create_sdp_body( pj_pool_t *pool,
+ pjmedia_sdp_session *sdp,
+ pjsip_msg_body **p_body)
{
+ const pj_str_t STR_APPLICATION = { "application", 11};
+ const pj_str_t STR_SDP = { "sdp", 3 };
pjsip_msg_body *body;
-
body = pj_pool_zalloc(pool, sizeof(pjsip_msg_body));
- PJ_ASSERT_RETURN(body != NULL, NULL);
+ PJ_ASSERT_RETURN(body != NULL, PJ_ENOMEM);
- body->content_type.type = pj_str("application");
- body->content_type.subtype = pj_str("sdp");
- body->data = pjmedia_sdp_session_clone(pool, c_sdp);
+ body->content_type.type = STR_APPLICATION;
+ body->content_type.subtype = STR_SDP;
+ body->data = sdp;
body->len = 0;
body->clone_data = &clone_sdp;
body->print_body = &print_sdp;
+ *p_body = body;
+
+ return PJ_SUCCESS;
+}
+
+static pjsip_msg_body *create_sdp_body(pj_pool_t *pool,
+ const pjmedia_sdp_session *c_sdp)
+{
+ pjsip_msg_body *body;
+ pj_status_t status;
+
+ status = pjsip_create_sdp_body(pool,
+ pjmedia_sdp_session_clone(pool, c_sdp),
+ &body);
+
+ if (status != PJ_SUCCESS)
+ return NULL;
+
return body;
}
diff --git a/pjsip/src/pjsip/sip_dialog.c b/pjsip/src/pjsip/sip_dialog.c
index 9b59d258..c84cfd20 100644
--- a/pjsip/src/pjsip/sip_dialog.c
+++ b/pjsip/src/pjsip/sip_dialog.c
@@ -1344,8 +1344,9 @@ void pjsip_dlg_on_rx_request( pjsip_dialog *dlg, pjsip_rx_data *rdata )
pjsip_tx_data *tdata;
const pj_str_t reason = { "No session found", 16};
- PJ_LOG(4,(tsx->obj_name, "Incoming request was unhandled by "
- "dialog usages, sending 500 response"));
+ PJ_LOG(4,(tsx->obj_name, "%s was unhandled by "
+ "dialog usages, sending 500 response",
+ pjsip_rx_data_get_info(rdata)));
status = pjsip_dlg_create_response(dlg, rdata, 500, &reason, &tdata);
if (status == PJ_SUCCESS) {
@@ -1457,10 +1458,13 @@ void pjsip_dlg_on_rx_response( pjsip_dialog *dlg, pjsip_rx_data *rdata )
break;
}
+ /* Unhandled response does not necessarily mean error because
+ dialog usages may choose to process the transaction state instead.
if (i==dlg->usage_cnt) {
- PJ_LOG(4,(dlg->obj_name, "%s is unhandled by dialog usages",
+ PJ_LOG(4,(dlg->obj_name, "%s was not claimed by any dialog usages",
pjsip_rx_data_get_info(rdata)));
}
+ */
/* Unlock dialog and dec session, may destroy dialog. */
pjsip_dlg_dec_lock(dlg);
diff --git a/pjsip/src/pjsua-lib/pjsua_acc.c b/pjsip/src/pjsua-lib/pjsua_acc.c
index 61b4096a..1d5873be 100644
--- a/pjsip/src/pjsua-lib/pjsua_acc.c
+++ b/pjsip/src/pjsua-lib/pjsua_acc.c
@@ -538,8 +538,10 @@ PJ_DEF(pj_status_t) pjsua_acc_set_registration( pjsua_acc_id acc_id,
status = pjsip_regc_unregister(pjsua_var.acc[acc_id].regc, &tdata);
}
- if (status == PJ_SUCCESS)
+ if (status == PJ_SUCCESS) {
+ pjsua_process_msg_data(tdata, NULL);
status = pjsip_regc_send( pjsua_var.acc[acc_id].regc, tdata );
+ }
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to create/send REGISTER",
diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c
index 98480b9a..930543ea 100644
--- a/pjsip/src/pjsua-lib/pjsua_core.c
+++ b/pjsip/src/pjsua-lib/pjsua_core.c
@@ -129,6 +129,106 @@ static pjsip_module pjsua_msg_logger =
/*****************************************************************************
+ * Another simple module to handle incoming OPTIONS request
+ */
+
+/* Notification on incoming request */
+static pj_bool_t options_on_rx_request(pjsip_rx_data *rdata)
+{
+ pjsip_tx_data *tdata;
+ pjsip_response_addr res_addr;
+ pjmedia_sdp_session *sdp;
+ const pjsip_hdr *cap_hdr;
+ pj_status_t status;
+
+ /* Only want to handle OPTIONS requests */
+ if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method,
+ &pjsip_options_method) != 0)
+ {
+ return PJ_FALSE;
+ }
+
+ /* Create basic response. */
+ status = pjsip_endpt_create_response(pjsua_var.endpt, rdata, 200, NULL,
+ &tdata);
+ if (status != PJ_SUCCESS) {
+ pjsua_perror(THIS_FILE, "Unable to create OPTIONS response", status);
+ return PJ_TRUE;
+ }
+
+ /* Add Allow header */
+ cap_hdr = pjsip_endpt_get_capability(pjsua_var.endpt, PJSIP_H_ALLOW, NULL);
+ if (cap_hdr) {
+ pjsip_msg_add_hdr(tdata->msg, pjsip_hdr_clone(tdata->pool, cap_hdr));
+ }
+
+ /* Add Accept header */
+ cap_hdr = pjsip_endpt_get_capability(pjsua_var.endpt, PJSIP_H_ACCEPT, NULL);
+ if (cap_hdr) {
+ pjsip_msg_add_hdr(tdata->msg, pjsip_hdr_clone(tdata->pool, cap_hdr));
+ }
+
+ /* Add Supported header */
+ cap_hdr = pjsip_endpt_get_capability(pjsua_var.endpt, PJSIP_H_SUPPORTED, NULL);
+ if (cap_hdr) {
+ pjsip_msg_add_hdr(tdata->msg, pjsip_hdr_clone(tdata->pool, cap_hdr));
+ }
+
+ /* Add Allow-Events header from the evsub module */
+ cap_hdr = pjsip_evsub_get_allow_events_hdr(NULL);
+ if (cap_hdr) {
+ pjsip_msg_add_hdr(tdata->msg, pjsip_hdr_clone(tdata->pool, cap_hdr));
+ }
+
+ /* Add User-Agent header */
+ if (pjsua_var.ua_cfg.user_agent.slen) {
+ const pj_str_t USER_AGENT = { "User-Agent", 10};
+ pjsip_hdr *h;
+
+ h = (pjsip_hdr*) pjsip_generic_string_hdr_create(tdata->pool,
+ &USER_AGENT,
+ &pjsua_var.ua_cfg.user_agent);
+ pjsip_msg_add_hdr(tdata->msg, h);
+ }
+
+ /* Add SDP body, using call0's RTP address */
+ status = pjmedia_endpt_create_sdp(pjsua_var.med_endpt, tdata->pool, 1,
+ &pjsua_var.calls[0].skinfo, &sdp);
+ if (status == PJ_SUCCESS) {
+ pjsip_create_sdp_body(tdata->pool, sdp, &tdata->msg->body);
+ }
+
+ /* Send response statelessly */
+ pjsip_get_response_addr(tdata->pool, rdata, &res_addr);
+ status = pjsip_endpt_send_response(pjsua_var.endpt, &res_addr, tdata, NULL, NULL);
+ if (status != PJ_SUCCESS)
+ pjsip_tx_data_dec_ref(tdata);
+
+ return PJ_TRUE;
+}
+
+
+/* The module instance. */
+static pjsip_module pjsua_options_handler =
+{
+ NULL, NULL, /* prev, next. */
+ { "mod-pjsua-options", 17 }, /* Name. */
+ -1, /* Id */
+ PJSIP_MOD_PRIORITY_APPLICATION, /* Priority */
+ NULL, /* load() */
+ NULL, /* start() */
+ NULL, /* stop() */
+ NULL, /* unload() */
+ &options_on_rx_request, /* on_rx_request() */
+ NULL, /* on_rx_response() */
+ NULL, /* on_tx_request. */
+ NULL, /* on_tx_response() */
+ NULL, /* on_tsx_state() */
+
+};
+
+
+/*****************************************************************************
* These two functions are the main callbacks registered to PJSIP stack
* to receive SIP request and response messages that are outside any
* dialogs and any transactions.
@@ -234,6 +334,12 @@ PJ_DEF(pj_status_t) pjsua_reconfigure_logging(const pjsua_logging_config *cfg)
}
}
+ /* Unregister OPTIONS handler if it's previously registered */
+ if (pjsua_options_handler.id >= 0) {
+ pjsip_endpt_unregister_module(pjsua_var.endpt, &pjsua_options_handler);
+ pjsua_options_handler.id = -1;
+ }
+
/* Unregister msg logging if it's previously registered */
if (pjsua_msg_logger.id >= 0) {
pjsip_endpt_unregister_module(pjsua_var.endpt, &pjsua_msg_logger);
@@ -244,6 +350,8 @@ PJ_DEF(pj_status_t) pjsua_reconfigure_logging(const pjsua_logging_config *cfg)
if (pjsua_var.log_cfg.msg_logging)
pjsip_endpt_register_module(pjsua_var.endpt, &pjsua_msg_logger);
+ /* Register OPTIONS handler */
+ pjsip_endpt_register_module(pjsua_var.endpt, &pjsua_options_handler);
return PJ_SUCCESS;
}
@@ -1024,6 +1132,18 @@ void pjsua_process_msg_data(pjsip_tx_data *tdata,
pj_bool_t allow_body;
const pjsip_hdr *hdr;
+ /* Always add User-Agent */
+ if (pjsua_var.ua_cfg.user_agent.slen &&
+ tdata->msg->type == PJSIP_REQUEST_MSG)
+ {
+ const pj_str_t STR_USER_AGENT = { "User-Agent", 10 };
+ pjsip_hdr *h;
+ h = (pjsip_hdr*)pjsip_generic_string_hdr_create(tdata->pool,
+ &STR_USER_AGENT,
+ &pjsua_var.ua_cfg.user_agent);
+ pjsip_msg_add_hdr(tdata->msg, h);
+ }
+
if (!msg_data)
return;