diff options
author | vi117747 <none@none> | 2006-10-07 14:26:26 -0700 |
---|---|---|
committer | vi117747 <none@none> | 2006-10-07 14:26:26 -0700 |
commit | 40cb5e5daa7b80bb70fcf8dadfb20f9281566331 (patch) | |
tree | dc95663e296c5dbf3cb8faa561e53416978eb4dc /usr/src/lib/libsip/common/sip_dialog_ui.c | |
parent | 56a424cca6b3f91f31bdab72a4626c48c779fe8b (diff) | |
download | illumos-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.c | 531 |
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); +} |