Added initial "norefersub" (RFC 4488) implementation in PJSUA-LIB, and also properly register all supported SIP method, accepted content type, and supported extensions to endpoint.

git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@688 74dad513-b988-da41-8d7b-12977e46ad98
This commit is contained in:
Benny Prijono 2006-08-20 09:12:19 +00:00
parent 3a5e1ab170
commit c8141a834a
4 changed files with 153 additions and 56 deletions

View File

@ -40,9 +40,17 @@
#define THIS_FILE "publishc.c"
/* Let's define this enum, so that it'll trigger compilation error
* when somebody define the same enum in sip_msg.h
*/
enum
{
PJSIP_PUBLISH_METHOD = PJSIP_OTHER_METHOD,
};
const pjsip_method pjsip_publish_method =
{
PJSIP_OTHER_METHOD,
PJSIP_PUBLISH_METHOD,
{ "PUBLISH", 7 }
};

View File

@ -94,6 +94,7 @@ pj_status_t pjsua_call_subsys_init(const pjsua_config *cfg)
{
pjsip_inv_callback inv_cb;
unsigned i;
const pj_str_t str_norefersub = { "norefersub", 10 };
pj_status_t status;
/* Init calls array. */
@ -116,6 +117,10 @@ pj_status_t pjsua_call_subsys_init(const pjsua_config *cfg)
status = pjsip_inv_usage_init(pjsua_var.endpt, &inv_cb);
PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
/* Add "norefersub" in Supported header */
pjsip_endpt_add_capability(pjsua_var.endpt, NULL, PJSIP_H_SUPPORTED,
NULL, 1, &str_norefersub);
return status;
}
@ -2124,10 +2129,12 @@ static void on_call_transfered( pjsip_inv_session *inv,
pjsua_call *existing_call;
int new_call;
const pj_str_t str_refer_to = { "Refer-To", 8};
const pj_str_t str_refer_sub = { "Refer-Sub", 9 };
pjsip_generic_string_hdr *refer_to;
pjsip_generic_string_hdr *refer_sub;
pj_bool_t no_refer_sub = PJ_FALSE;
char *uri;
pj_str_t tmp;
struct pjsip_evsub_user xfer_cb;
pjsip_status_code code;
pjsip_evsub *sub;
@ -2146,6 +2153,16 @@ static void on_call_transfered( pjsip_inv_session *inv,
return;
}
/* Find optional Refer-Sub header */
refer_sub = (pjsip_generic_string_hdr*)
pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_refer_sub, NULL);
if (refer_sub) {
if (!pj_strnicmp2(&refer_sub->hvalue, "true", 4)==0)
no_refer_sub = PJ_TRUE;
}
/* Notify callback */
code = PJSIP_SC_OK;
if (pjsua_var.ua_cfg.cb.on_call_transfered)
@ -2166,34 +2183,92 @@ static void on_call_transfered( pjsip_inv_session *inv,
(int)refer_to->hvalue.slen,
refer_to->hvalue.ptr));
/* Init callback */
pj_bzero(&xfer_cb, sizeof(xfer_cb));
xfer_cb.on_evsub_state = &xfer_on_evsub_state;
if (no_refer_sub) {
/*
* Always answer with 200.
*/
pjsip_tx_data *tdata;
const pj_str_t str_false = { "false", 5};
pjsip_hdr *hdr;
/* Create transferee event subscription */
status = pjsip_xfer_create_uas( inv->dlg, &xfer_cb, rdata, &sub);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to create xfer uas", status);
pjsip_dlg_respond( inv->dlg, rdata, 500, NULL, NULL, NULL);
return;
}
status = pjsip_dlg_create_response(inv->dlg, rdata, 200, NULL, &tdata);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to create 200 response to REFER",
status);
return;
}
/* Accept the REFER request, send 200 (OK). */
pjsip_xfer_accept(sub, rdata, code, NULL);
/* Add Refer-Sub header */
hdr = (pjsip_hdr*)
pjsip_generic_string_hdr_create(tdata->pool, &str_refer_sub,
&str_false);
pjsip_msg_add_hdr(tdata->msg, hdr);
/* Create initial NOTIFY request */
status = pjsip_xfer_notify( sub, PJSIP_EVSUB_STATE_ACTIVE,
100, NULL, &tdata);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to create NOTIFY to REFER", status);
return;
}
/* Send initial NOTIFY request */
status = pjsip_xfer_send_request( sub, tdata);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to send NOTIFY to REFER", status);
return;
/* Send answer */
status = pjsip_dlg_send_response(inv->dlg, pjsip_rdata_get_tsx(rdata),
tdata);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to create 200 response to REFER",
status);
return;
}
/* Don't have subscription */
sub = NULL;
} else {
struct pjsip_evsub_user xfer_cb;
pjsip_hdr hdr_list;
/* Init callback */
pj_bzero(&xfer_cb, sizeof(xfer_cb));
xfer_cb.on_evsub_state = &xfer_on_evsub_state;
/* Init additional header list to be sent with REFER response */
pj_list_init(&hdr_list);
/* Create transferee event subscription */
status = pjsip_xfer_create_uas( inv->dlg, &xfer_cb, rdata, &sub);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to create xfer uas", status);
pjsip_dlg_respond( inv->dlg, rdata, 500, NULL, NULL, NULL);
return;
}
/* If there's Refer-Sub header and the value is "true", send back
* Refer-Sub in the response with value "true" too.
*/
if (refer_sub) {
const pj_str_t str_true = { "true", 4 };
pjsip_hdr *hdr;
hdr = (pjsip_hdr*)
pjsip_generic_string_hdr_create(inv->dlg->pool,
&str_refer_sub,
&str_true);
pj_list_push_back(&hdr_list, hdr);
}
/* Accept the REFER request, send 200 (OK). */
pjsip_xfer_accept(sub, rdata, code, &hdr_list);
/* Create initial NOTIFY request */
status = pjsip_xfer_notify( sub, PJSIP_EVSUB_STATE_ACTIVE,
100, NULL, &tdata);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to create NOTIFY to REFER",
status);
return;
}
/* Send initial NOTIFY request */
status = pjsip_xfer_send_request( sub, tdata);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to send NOTIFY to REFER", status);
return;
}
}
/* We're cheating here.
@ -2211,32 +2286,36 @@ static void on_call_transfered( pjsip_inv_session *inv,
&new_call);
if (status != PJ_SUCCESS) {
/* Notify xferer about the error */
status = pjsip_xfer_notify(sub, PJSIP_EVSUB_STATE_TERMINATED,
500, NULL, &tdata);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to create NOTIFY to REFER",
status);
return;
}
status = pjsip_xfer_send_request(sub, tdata);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to send NOTIFY to REFER",
status);
return;
/* Notify xferer about the error (if we have subscription) */
if (sub) {
status = pjsip_xfer_notify(sub, PJSIP_EVSUB_STATE_TERMINATED,
500, NULL, &tdata);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to create NOTIFY to REFER",
status);
return;
}
status = pjsip_xfer_send_request(sub, tdata);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to send NOTIFY to REFER",
status);
return;
}
}
return;
}
/* Put the server subscription in inv_data.
* Subsequent state changed in pjsua_inv_on_state_changed() will be
* reported back to the server subscription.
*/
pjsua_var.calls[new_call].xfer_sub = sub;
if (sub) {
/* Put the server subscription in inv_data.
* Subsequent state changed in pjsua_inv_on_state_changed() will be
* reported back to the server subscription.
*/
pjsua_var.calls[new_call].xfer_sub = sub;
/* Put the invite_data in the subscription. */
pjsip_evsub_set_mod_data(sub, pjsua_var.mod.id,
&pjsua_var.calls[new_call]);
/* Put the invite_data in the subscription. */
pjsip_evsub_set_mod_data(sub, pjsua_var.mod.id,
&pjsua_var.calls[new_call]);
}
}

View File

@ -334,12 +334,6 @@ 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);
@ -350,9 +344,6 @@ 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;
}
@ -443,6 +434,7 @@ PJ_DEF(pj_status_t) pjsua_init( const pjsua_config *ua_cfg,
{
pjsua_config default_cfg;
pjsua_media_config default_media_cfg;
const pj_str_t STR_OPTIONS = { "OPTIONS", 7 };
pj_status_t status;
@ -541,6 +533,13 @@ PJ_DEF(pj_status_t) pjsua_init( const pjsua_config *ua_cfg,
if (status != PJ_SUCCESS)
goto on_error;
/* Register OPTIONS handler */
pjsip_endpt_register_module(pjsua_var.endpt, &pjsua_options_handler);
/* Add OPTIONS in Allow header */
pjsip_endpt_add_capability(pjsua_var.endpt, NULL, PJSIP_H_ALLOW,
NULL, 1, &STR_OPTIONS);
/* Start worker thread if needed. */
if (pjsua_var.ua_cfg.thread_cnt) {
unsigned i;

View File

@ -567,6 +567,9 @@ PJ_DEF(pj_status_t) pjsua_im_typing( pjsua_acc_id acc_id,
pj_status_t pjsua_im_init(void)
{
const pj_str_t msg_tag = { "MESSAGE", 7 };
const pj_str_t STR_MIME_TEXT_PLAIN = { "text/plain", 10 };
const pj_str_t STR_MIME_APP_ISCOMPOSING =
{ "application/im-iscomposing+xml", 30 };
pj_status_t status;
/* Register module */
@ -578,6 +581,14 @@ pj_status_t pjsua_im_init(void)
pjsip_endpt_add_capability( pjsua_var.endpt, &mod_pjsua_im, PJSIP_H_ALLOW,
NULL, 1, &msg_tag);
/* Register support for "application/im-iscomposing+xml" content */
pjsip_endpt_add_capability( pjsua_var.endpt, &mod_pjsua_im, PJSIP_H_ACCEPT,
NULL, 1, &STR_MIME_APP_ISCOMPOSING);
/* Register support for "text/plain" content */
pjsip_endpt_add_capability( pjsua_var.endpt, &mod_pjsua_im, PJSIP_H_ACCEPT,
NULL, 1, &STR_MIME_TEXT_PLAIN);
return PJ_SUCCESS;
}