/*
* 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
* 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 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <assert.h>
#include <errno.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <sip.h>
#include "sip_msg.h"
#include "sip_miscdefs.h"
#include "sip_parse_generic.h"
/*
* Response consists of SIP version, response code, response phrase and CRLF.
*/
void sip_free_content(_sip_msg_t *);
/*
* Allocate a new sip msg struct.
*/
{
}
}
/*
* Free all resources. The lock is taken by SIP_MSG_REFCNT_DECR. The
* thread that decrements the last refcount should take care that
* the message is not accessible to other threads before doing so.
* Else, if the message is still accessible to others, it is
* possible that the other thread could be waiting to take the
* lock when we proceed to destroy it.
*/
void
{
#ifdef __solaris__
#endif
(void) sip_delete_start_line_locked(_sip_msg);
}
}
}
}
/*
* Free a sip msg struct.
*/
void
{
return;
}
/*
* Hold a sip msg struct.
*/
void
{
return;
}
/*
* Clone a message
*/
{
int len;
return (NULL);
return (NULL);
/*
* Get start line
*/
return (NULL);
}
return (NULL);
}
while (sip_content != NULL) {
if (msg_content == NULL) {
return (NULL);
}
return (NULL);
}
len;
else
}
/*
* Since this is a new message, no threads should be referring
* to this, so it is not necessary to take the lock, however,
* since sip_msg_to_msgbuf() expects the lock to be held, we'll
* take it here.
*/
return (NULL);
}
}
/*
* Return the SIP message as a string. Caller frees the string
*/
char *
{
char *msgstr;
return (NULL);
}
return (msgstr);
}
/*
* Given a message generate a string that includes all the headers and the
* content.
*/
char *
{
int len = 0;
char *p;
char *e;
#ifdef _DEBUG
int tlen = 0;
int clen = 0;
#endif
*error = 0;
return (NULL);
}
#ifdef __solaris__
#endif
if (p == NULL) {
if (error != 0)
return (NULL);
}
e = p;
/*
* Get the start line
*/
e += len;
#ifdef _DEBUG
#endif
}
if (header->sip_header_state ==
} else {
}
#ifdef _DEBUG
#endif
}
e += len;
}
while (sip_content != NULL) {
#ifdef _DEBUG
#endif
e += len;
}
return (p);
}
/*
* This is called just before sending the message to the transport. It
* creates the sip_msg_buf from the SIP headers.
*/
int
{
int ret;
#ifdef _DEBUG
int tlen = 0;
int clen = 0;
#endif
return (EINVAL);
/*
* We could just be forwarding the message we
* received.
*/
return (0);
}
/*
* We are sending a new message or a message that we received
* but have modified it. We keep the old
* msgbuf till the message is freed as some
* headers still point to it.
*/
/*
* We add the content-length header here, if it has not
* already been added.
*/
/*
* Mark the previous header as deleted.
*/
}
if (ret != 0) {
return (ret);
}
return (ret);
}
/*
* Once the message has been sent it can not be modified
* any furthur as we keep a pointer to it for retransmission
*/
return (0);
}
/*
* Copy header values into ptr
*/
int
{
int tlen = 0;
int len = 0;
char *p = ptr;
char *s;
if (sip_parse_goto_values(header) != 0)
return (0);
p += len;
if (first) {
} else {
s = value->value_start;
while (*s != SIP_COMMA)
s--;
}
p += len;
while (s != value->value_start) {
break;
}
s--;
}
} else {
while (*s != '\r')
s--;
p += len;
}
}
}
return (tlen);
}
/*
* Add content (message body) to sip_msg
*/
int
{
return (EINVAL);
if (_sip_msg->sip_msg_cannot_be_modified) {
return (ENOTSUP);
}
if (msg_content == NULL) {
return (ENOMEM);
}
return (ENOMEM);
}
*loc = msg_content;
return (0);
}
/*
* Free the message content
*/
void
{
return;
}
}
/*
* Add a response line to sip_response
*/
int
{
int header_size;
int ret;
return (EINVAL);
return (ENOTSUP);
}
if (new_header == NULL) {
return (ENOMEM);
}
return (ret);
}
/*
* create a response based on the sip_request.
* Copies Call-ID, CSeq, From, To and Via headers from the request.
*/
{
return (NULL);
return (NULL);
/*
* Add response line.
*/
goto error;
/*
* Copy Via headers
*/
goto error;
/*
* Copy From header.
*/
goto error;
}
/*
* Copy To header. If To tag is present, copy it, if not then
* add one if the repsonse is not provisional.
*/
goto error;
}
} else {
char *xtra_param;
int taglen;
goto error;
}
if (xtra_param == NULL) {
if (tag_alloc)
goto error;
}
if (tag_alloc)
goto error;
}
}
/*
* Copy Call-ID header.
*/
B_FALSE)) {
goto error;
}
/*
* Copy CSEQ header
*/
B_FALSE)) {
goto error;
}
/*
* Copy RECORD-ROUTE header, if present.
*/
NULL) {
SIP_RECORD_ROUTE) != 0) {
goto error;
}
}
NULL) != 0) {
goto error;
}
}
return (NULL);
}
/*
* NON OK ACK : MUST contain values for the Call-ID, From, and Request-URI
* that are equal to the values of those header fields in the orig request
* passed to the transport. The To header field in the ACK MUST equal the To
* header field in the response being acknowledged. The ACK MUST contain the
* top Via header field of the original request. The CSeq header field in
* the ACK MUST contain the same value for the sequence number as was
* present in the original request, but the method parameter MUST be equal
* to "ACK".
*/
int
{
int seqno;
char *uri;
int ret;
return (EINVAL);
}
&_request->sip_msg_req_res)) != 0) {
return (ret);
}
}
sip_str_ptr == NULL) {
return (EINVAL);
}
return (EINVAL);
}
return (ret);
}
return (ret);
}
return (ret);
}
return (ret);
}
return (ret);
}
if (ret != 0)
return (ret);
return (ret);
return (ret);
return (0);
}
/*
* This is a 2XX ACK, for others ACK is constructed differently,
* esp. the branch id is retained.
*/
int
{
int seqno;
char *uri;
int ret;
return (EINVAL);
/*
* Get URI from the response, Contact field
*/
return (EINVAL);
}
0) {
return (ret);
}
return (EINVAL);
}
return (ENOMEM);
}
return (ret);
}
via_params)) != 0) {
return (ret);
}
return (ret);
}
return (ret);
}
return (ret);
}
/*
* Copy Max-Forward if present
*/
return (ret);
}
}
if (ret != 0)
return (ret);
return (ret);
return (0);
}
/*
* Request-Line = Method SP Request-URI SP SIP-Version CRLF
*/
int
char *request_uri)
{
int header_size;
return (EINVAL);
}
return (ENOTSUP);
}
if (new_header == NULL) {
return (ENOMEM);
}
return (0);
}