summaryrefslogtreecommitdiff
path: root/usr/src/lib/libsip/common/sip_dialog_ui.c
diff options
context:
space:
mode:
authorvi117747 <none@none>2006-10-07 14:26:26 -0700
committervi117747 <none@none>2006-10-07 14:26:26 -0700
commit40cb5e5daa7b80bb70fcf8dadfb20f9281566331 (patch)
treedc95663e296c5dbf3cb8faa561e53416978eb4dc /usr/src/lib/libsip/common/sip_dialog_ui.c
parent56a424cca6b3f91f31bdab72a4626c48c779fe8b (diff)
downloadillumos-gate-40cb5e5daa7b80bb70fcf8dadfb20f9281566331.tar.gz
PSARC 2006/402 SIP Library Integration
6461142 Integrate SIP in Solaris
Diffstat (limited to 'usr/src/lib/libsip/common/sip_dialog_ui.c')
-rw-r--r--usr/src/lib/libsip/common/sip_dialog_ui.c531
1 files changed, 531 insertions, 0 deletions
diff --git a/usr/src/lib/libsip/common/sip_dialog_ui.c b/usr/src/lib/libsip/common/sip_dialog_ui.c
new file mode 100644
index 0000000000..698a0c8761
--- /dev/null
+++ b/usr/src/lib/libsip/common/sip_dialog_ui.c
@@ -0,0 +1,531 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include "sip_parse_uri.h"
+#include "sip_msg.h"
+#include "sip_miscdefs.h"
+#include "sip_dialog.h"
+#include "sip_xaction.h"
+
+/*
+ * Create a request using the state maintained in the dialog.
+ */
+sip_msg_t
+sip_create_dialog_req(sip_method_t method, sip_dialog_t dialog,
+ char *transport, char *sent_by, int sent_by_port, char *via_param,
+ uint32_t maxforward, int cseq)
+{
+ _sip_dialog_t *_dialog;
+ sip_msg_t sip_msg;
+ char *uri;
+ int oldseq = 0;
+
+ if (!sip_manage_dialog || dialog == NULL || transport == NULL ||
+ sent_by == NULL) {
+ return (NULL);
+ }
+ if ((sip_msg = sip_new_msg()) == NULL)
+ return (NULL);
+ _dialog = (_sip_dialog_t *)dialog;
+ (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
+ /*
+ * Depending on the route set, if any, the request URI could either
+ * be the contact URI or the 1st URI from the route set.
+ */
+ uri = (char *)sip_dialog_req_uri(_dialog);
+ if (uri == NULL)
+ goto err_ret;
+ if (sip_add_request_line(sip_msg, method, uri) != 0) {
+ free(uri);
+ goto err_ret;
+ }
+ free(uri);
+ if (sip_copy_header(sip_msg, _dialog->sip_dlg_local_uri_tag, NULL) != 0)
+ goto err_ret;
+ if (sip_copy_header(sip_msg, _dialog->sip_dlg_remote_uri_tag, NULL) !=
+ 0) {
+ goto err_ret;
+ }
+ if (sip_copy_header(sip_msg, _dialog->sip_dlg_remote_target, NULL) != 0)
+ goto err_ret;
+ if (sip_add_via(sip_msg, transport, sent_by, sent_by_port, via_param) !=
+ 0) {
+ goto err_ret;
+ }
+ if (sip_add_maxforward(sip_msg, maxforward) != 0)
+ goto err_ret;
+ if (sip_copy_header(sip_msg, _dialog->sip_dlg_call_id, NULL) != 0)
+ goto err_ret;
+ if (cseq < 0) {
+ if (_dialog->sip_dlg_local_cseq == 0)
+ _dialog->sip_dlg_local_cseq = 1;
+ oldseq = _dialog->sip_dlg_local_cseq;
+ cseq = ++_dialog->sip_dlg_local_cseq;
+ }
+ if (sip_add_cseq(sip_msg, method, cseq) != 0) {
+ _dialog->sip_dlg_local_cseq = oldseq;
+ goto err_ret;
+ }
+ /*
+ * The route set, even if empty, overrides any pre-existing route set.
+ * If the route set is empty, the UAC MUST NOT add a Route header
+ * field to the request.
+ */
+ (void) sip_delete_header_by_name(sip_msg, SIP_ROUTE);
+
+ if (_dialog->sip_dlg_route_set != NULL) {
+ if (sip_copy_header(sip_msg, _dialog->sip_dlg_route_set,
+ NULL) != 0) {
+ _dialog->sip_dlg_local_cseq = oldseq;
+ goto err_ret;
+ }
+ }
+ (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
+ return (sip_msg);
+err_ret:
+ (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
+ sip_free_msg(sip_msg);
+ return (NULL);
+}
+
+/*
+ * Get the Dialog method
+ */
+int
+sip_get_dialog_method(sip_dialog_t dialog, int *error)
+{
+ _sip_dialog_t *_dialog;
+
+ if (error != NULL)
+ *error = 0;
+ if (!sip_manage_dialog) {
+ if (error != NULL)
+ *error = EINVAL;
+ return (0);
+ }
+ if (dialog == NULL) {
+ if (error != NULL)
+ *error = EINVAL;
+ return (0);
+ }
+ _dialog = (_sip_dialog_t *)dialog;
+ return (_dialog->sip_dlg_method);
+}
+
+/*
+ * Get the Dialog state
+ */
+int
+sip_get_dialog_state(sip_dialog_t dialog, int *error)
+{
+ _sip_dialog_t *_dialog;
+
+ if (error != NULL)
+ *error = 0;
+ if (!sip_manage_dialog) {
+ if (error != NULL)
+ *error = EINVAL;
+ return (0);
+ }
+ if (dialog == NULL) {
+ if (error != NULL)
+ *error = EINVAL;
+ return (0);
+ }
+ _dialog = (_sip_dialog_t *)dialog;
+ return (_dialog->sip_dlg_state);
+}
+
+/*
+ * Return the dialog callid
+ */
+const sip_str_t *
+sip_get_dialog_callid(sip_dialog_t dialog, int *error)
+{
+ _sip_dialog_t *_dialog;
+ const struct sip_value *val;
+ const sip_str_t *callid = NULL;
+
+ if (error != NULL)
+ *error = 0;
+ if (!sip_manage_dialog || dialog == NULL) {
+ if (error != NULL)
+ *error = EINVAL;
+ return (NULL);
+ }
+ _dialog = (_sip_dialog_t *)dialog;
+ (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
+ if (dialog->sip_dlg_call_id != NULL) {
+ val = sip_get_header_value(_dialog->sip_dlg_call_id, error);
+ if (val == NULL) {
+ (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
+ return (NULL);
+ }
+ callid = &((sip_hdr_value_t *)val)->str_val;
+ }
+ (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
+ return (callid);
+}
+
+/*
+ * Return the dialog localtag.
+ */
+const sip_str_t *
+sip_get_dialog_local_tag(sip_dialog_t dialog, int *error)
+{
+ _sip_dialog_t *_dialog;
+ const sip_str_t *ltag = NULL;
+ const struct sip_value *val;
+
+ if (error != NULL)
+ *error = 0;
+ if (!sip_manage_dialog || dialog == NULL) {
+ if (error != NULL)
+ *error = EINVAL;
+ return (NULL);
+ }
+ _dialog = (_sip_dialog_t *)dialog;
+ (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
+ if (dialog->sip_dlg_local_uri_tag != NULL) {
+ val = sip_get_header_value(_dialog->sip_dlg_local_uri_tag,
+ error);
+ if (val == NULL) {
+ (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
+ return (NULL);
+ }
+ ltag = sip_get_param_value((sip_header_value_t)val, "tag",
+ error);
+ }
+ (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
+ return (ltag);
+}
+
+/*
+ * Return the dialog remotetag
+ */
+const sip_str_t *
+sip_get_dialog_remote_tag(sip_dialog_t dialog, int *error)
+{
+ _sip_dialog_t *_dialog;
+ const sip_str_t *ttag = NULL;
+ const struct sip_value *val;
+
+ if (error != NULL)
+ *error = 0;
+ if (!sip_manage_dialog || dialog == NULL) {
+ if (error != NULL)
+ *error = EINVAL;
+ return (NULL);
+ }
+ _dialog = (_sip_dialog_t *)dialog;
+ (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
+ if (dialog->sip_dlg_remote_uri_tag != NULL) {
+ val = sip_get_header_value(_dialog->sip_dlg_remote_uri_tag,
+ error);
+ if (val == NULL) {
+ (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
+ return (NULL);
+ }
+ ttag = sip_get_param_value((sip_header_value_t)val, "tag",
+ error);
+ }
+ (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
+
+ return (ttag);
+}
+
+/*
+ * Return the dialog localuri.
+ */
+const struct sip_uri *
+sip_get_dialog_local_uri(sip_dialog_t dialog, int *error)
+{
+ _sip_dialog_t *_dialog;
+ const _sip_uri_t *luri = NULL;
+ const struct sip_value *val;
+
+ if (error != NULL)
+ *error = 0;
+ if (!sip_manage_dialog || dialog == NULL) {
+ if (error != NULL)
+ *error = EINVAL;
+ return (NULL);
+ }
+ _dialog = (_sip_dialog_t *)dialog;
+ (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
+ if (dialog->sip_dlg_local_uri_tag != NULL) {
+ val = sip_get_header_value(_dialog->sip_dlg_local_uri_tag,
+ error);
+ if (val == NULL) {
+ (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
+ return (NULL);
+ }
+ luri = val->sip_value_parse_uri;
+ }
+ (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
+
+ return ((sip_uri_t)luri);
+}
+
+/*
+ * Return the dialog remoteuri.
+ */
+const struct sip_uri *
+sip_get_dialog_remote_uri(sip_dialog_t dialog, int *error)
+{
+ _sip_dialog_t *_dialog;
+ const _sip_uri_t *ruri = NULL;
+ const struct sip_value *val;
+
+ if (error != NULL)
+ *error = 0;
+ if (!sip_manage_dialog || dialog == NULL) {
+ if (error != NULL)
+ *error = EINVAL;
+ return (NULL);
+ }
+ _dialog = (_sip_dialog_t *)dialog;
+ (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
+ if (dialog->sip_dlg_remote_uri_tag != NULL) {
+ val = sip_get_header_value(dialog->sip_dlg_remote_uri_tag,
+ error);
+ if (val == NULL) {
+ (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
+ return (NULL);
+ }
+ ruri = val->sip_value_parse_uri;
+ }
+ (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
+ return ((sip_uri_t)ruri);
+}
+
+/*
+ * Return the dialog remotetarg.
+ */
+const struct sip_uri *
+sip_get_dialog_remote_target_uri(sip_dialog_t dialog, int *error)
+{
+ _sip_dialog_t *_dialog;
+ const struct sip_uri *rtarg = NULL;
+ const struct sip_value *val;
+
+ if (error != NULL)
+ *error = 0;
+ if (!sip_manage_dialog || dialog == NULL) {
+ if (error != NULL)
+ *error = EINVAL;
+ return (NULL);
+ }
+ _dialog = (_sip_dialog_t *)dialog;
+ (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
+ if (dialog->sip_dlg_remote_target != NULL) {
+ val = sip_get_header_value(_dialog->sip_dlg_remote_target,
+ error);
+ if (val == NULL) {
+ (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
+ return (NULL);
+ }
+ rtarg = val->sip_value_parse_uri;
+ }
+ (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
+
+ return ((sip_uri_t)rtarg);
+}
+
+/*
+ * Return the dialog route set
+ */
+const sip_str_t *
+sip_get_dialog_route_set(sip_dialog_t dialog, int *error)
+{
+ _sip_dialog_t *_dialog;
+
+ if (error != NULL)
+ *error = 0;
+ if (!sip_manage_dialog || dialog == NULL) {
+ if (error != NULL)
+ *error = EINVAL;
+ return (NULL);
+ }
+ _dialog = (_sip_dialog_t *)dialog;
+ if (_dialog->sip_dlg_rset.sip_str_len > 0)
+ return (&_dialog->sip_dlg_rset);
+ return (NULL);
+}
+
+/*
+ * Return the dialog secure
+ */
+boolean_t
+sip_is_dialog_secure(sip_dialog_t dialog, int *error)
+{
+ _sip_dialog_t *_dialog;
+ boolean_t issecure;
+
+ if (error != NULL)
+ *error = 0;
+ if (!sip_manage_dialog || dialog == NULL) {
+ if (error != NULL)
+ *error = EINVAL;
+ return (B_FALSE);
+ }
+ _dialog = (_sip_dialog_t *)dialog;
+ (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
+ issecure = _dialog->sip_dlg_secure;
+ (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
+ return (issecure);
+}
+
+/*
+ * Return the dialog local cseq
+ */
+uint32_t
+sip_get_dialog_local_cseq(sip_dialog_t dialog, int *error)
+{
+ _sip_dialog_t *_dialog;
+ uint32_t cseq;
+
+ if (error != NULL)
+ *error = 0;
+ if (!sip_manage_dialog || dialog == NULL) {
+ if (error != NULL)
+ *error = EINVAL;
+ return (0);
+ }
+ _dialog = (_sip_dialog_t *)dialog;
+ (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
+ cseq = _dialog->sip_dlg_local_cseq;
+ (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
+ return (cseq);
+}
+
+/*
+ * Return the dialog remote cseq
+ */
+uint32_t
+sip_get_dialog_remote_cseq(sip_dialog_t dialog, int *error)
+{
+ _sip_dialog_t *_dialog;
+ uint32_t cseq;
+
+ if (error != NULL)
+ *error = 0;
+ if (!sip_manage_dialog || dialog == NULL) {
+ if (error != NULL)
+ *error = EINVAL;
+ return (0);
+ }
+ _dialog = (_sip_dialog_t *)dialog;
+ (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
+ cseq = _dialog->sip_dlg_remote_cseq;
+ (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
+ return (cseq);
+}
+
+/*
+ * Return the dialog type
+ */
+int
+sip_get_dialog_type(sip_dialog_t dialog, int *error)
+{
+ _sip_dialog_t *_dialog;
+ int type;
+
+ if (error != NULL)
+ *error = 0;
+ if (!sip_manage_dialog || dialog == NULL) {
+ if (error != NULL)
+ *error = EINVAL;
+ return (-1);
+ }
+ _dialog = (_sip_dialog_t *)dialog;
+ (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
+ type = _dialog->sip_dlg_type;
+ (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
+ return (type);
+}
+
+
+/*
+ * Partial dialog ?
+ */
+boolean_t
+sip_incomplete_dialog(sip_dialog_t dialog)
+{
+ _sip_dialog_t *_dialog;
+ boolean_t isnew;
+
+ if (!sip_manage_dialog || dialog == NULL)
+ return (B_FALSE);
+ _dialog = (_sip_dialog_t *)dialog;
+ (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
+ isnew = _dialog->sip_dlg_state == SIP_DLG_NEW;
+ (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
+ return (isnew);
+}
+
+/*
+ * Hold dialog
+ */
+void
+sip_hold_dialog(sip_dialog_t dialog)
+{
+ _sip_dialog_t *_dialog;
+
+ if (!sip_manage_dialog || dialog == NULL)
+ return;
+ _dialog = (_sip_dialog_t *)dialog;
+ (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
+ SIP_DLG_REFCNT_INCR(_dialog);
+ (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
+}
+
+/*
+ * Release dialog
+ */
+void
+sip_release_dialog(sip_dialog_t dialog)
+{
+ _sip_dialog_t *_dialog;
+
+ if (!sip_manage_dialog || dialog == NULL)
+ return;
+ _dialog = (_sip_dialog_t *)dialog;
+ SIP_DLG_REFCNT_DECR(_dialog);
+}
+
+/*
+ * Delete a dialog
+ */
+void
+sip_delete_dialog(sip_dialog_t dialog)
+{
+ if (!sip_manage_dialog || dialog == NULL)
+ return;
+ sip_dialog_terminate(dialog, NULL);
+}