⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sip_msg.c

📁 一个开源SIP协议栈
💻 C
📖 第 1 页 / 共 4 页
字号:
}

///////////////////////////////////////////////////////////////////////////////
/*
 * Record-Route and Route header.
 */
static int pjsip_routing_hdr_print( pjsip_routing_hdr *r, char *buf, pj_size_t size );
static pjsip_routing_hdr* pjsip_routing_hdr_clone( pj_pool_t *pool, const pjsip_routing_hdr *r );
static pjsip_routing_hdr* pjsip_routing_hdr_shallow_clone( pj_pool_t *pool, const pjsip_routing_hdr *r );

static pjsip_hdr_vptr routing_hdr_vptr = 
{
    (pjsip_hdr_clone_fptr) &pjsip_routing_hdr_clone,
    (pjsip_hdr_clone_fptr) &pjsip_routing_hdr_shallow_clone,
    (pjsip_hdr_print_fptr) &pjsip_routing_hdr_print,
};

PJ_DEF(pjsip_rr_hdr*) pjsip_rr_hdr_init( pj_pool_t *pool,
					 void *mem )
{
    pjsip_rr_hdr *hdr = mem;

    PJ_UNUSED_ARG(pool);

    init_hdr(hdr, PJSIP_H_RECORD_ROUTE, &routing_hdr_vptr);
    pjsip_name_addr_init(&hdr->name_addr);
    pj_list_init(&hdr->other_param);
    return hdr;

}

PJ_DEF(pjsip_rr_hdr*) pjsip_rr_hdr_create( pj_pool_t *pool )
{
    void *mem = pj_pool_alloc(pool, sizeof(pjsip_rr_hdr));
    return pjsip_rr_hdr_init(pool, mem);
}

PJ_DEF(pjsip_route_hdr*) pjsip_route_hdr_init( pj_pool_t *pool,
					       void *mem )
{
    pjsip_route_hdr *hdr = mem;

    PJ_UNUSED_ARG(pool);

    init_hdr(hdr, PJSIP_H_ROUTE, &routing_hdr_vptr);
    pjsip_name_addr_init(&hdr->name_addr);
    pj_list_init(&hdr->other_param);
    return hdr;
}

PJ_DEF(pjsip_route_hdr*) pjsip_route_hdr_create( pj_pool_t *pool )
{
    void *mem = pj_pool_alloc(pool, sizeof(pjsip_route_hdr));
    return pjsip_route_hdr_init(pool, mem);
}

PJ_DEF(pjsip_rr_hdr*) pjsip_routing_hdr_set_rr( pjsip_routing_hdr *hdr )
{
    hdr->type = PJSIP_H_RECORD_ROUTE;
    hdr->name = hdr->sname = pjsip_hdr_names[PJSIP_H_RECORD_ROUTE];
    return hdr;
}

PJ_DEF(pjsip_route_hdr*) pjsip_routing_hdr_set_route( pjsip_routing_hdr *hdr )
{
    hdr->type = PJSIP_H_ROUTE;
    hdr->name = hdr->sname = pjsip_hdr_names[PJSIP_H_ROUTE];
    return hdr;
}

static int pjsip_routing_hdr_print( pjsip_routing_hdr *hdr,
				    char *buf, pj_size_t size )
{
    int printed;
    char *startbuf = buf;
    char *endbuf = buf + size;

    copy_advance(buf, hdr->name);
    *buf++ = ':';
    *buf++ = ' ';

    printed = pjsip_uri_print(PJSIP_URI_IN_ROUTING_HDR, &hdr->name_addr, buf, 
			      endbuf-buf);
    if (printed < 1)
	return -1;
    buf += printed;

    printed = pjsip_param_print_on(&hdr->other_param, buf, endbuf-buf, 
				   &pjsip_TOKEN_SPEC, 
				   &pjsip_TOKEN_SPEC, ';');
    if (printed < 0)
	return -1;
    buf += printed;

    return buf-startbuf;
}

static pjsip_routing_hdr* pjsip_routing_hdr_clone( pj_pool_t *pool,
						   const pjsip_routing_hdr *rhs )
{
    pjsip_routing_hdr *hdr = pj_pool_alloc(pool, sizeof(*hdr));

    init_hdr(hdr, rhs->type, rhs->vptr);
    pjsip_name_addr_init(&hdr->name_addr);
    pjsip_name_addr_assign(pool, &hdr->name_addr, &rhs->name_addr);
    pjsip_param_clone( pool, &hdr->other_param, &rhs->other_param);
    return hdr;
}

static pjsip_routing_hdr* pjsip_routing_hdr_shallow_clone( pj_pool_t *pool,
							   const pjsip_routing_hdr *rhs )
{
    pjsip_routing_hdr *hdr = pj_pool_alloc(pool, sizeof(*hdr));
    pj_memcpy(hdr, rhs, sizeof(*hdr));
    pjsip_param_shallow_clone( pool, &hdr->other_param, &rhs->other_param);
    return hdr;
}


///////////////////////////////////////////////////////////////////////////////
/*
 * Require header.
 */
PJ_DEF(pjsip_require_hdr*) pjsip_require_hdr_init( pj_pool_t *pool,
						   void *mem )
{
    pjsip_require_hdr *hdr = mem;

    PJ_UNUSED_ARG(pool);

    init_hdr(hdr, PJSIP_H_REQUIRE, &generic_array_hdr_vptr);
    hdr->count = 0;
    return hdr;
}

PJ_DEF(pjsip_require_hdr*) pjsip_require_hdr_create(pj_pool_t *pool)
{
    void *mem = pj_pool_alloc(pool, sizeof(pjsip_require_hdr));
    return pjsip_require_hdr_init(pool, mem);
}

///////////////////////////////////////////////////////////////////////////////
/*
 * Retry-After header.
 */
PJ_DEF(pjsip_retry_after_hdr*) pjsip_retry_after_hdr_init( pj_pool_t *pool,
							   void *mem,
							   int value )
{
    pjsip_retry_after_hdr *hdr = mem;

    PJ_UNUSED_ARG(pool);

    init_hdr(hdr, PJSIP_H_RETRY_AFTER, &generic_int_hdr_vptr);
    hdr->ivalue = value;
    return hdr;
}

PJ_DEF(pjsip_retry_after_hdr*) pjsip_retry_after_hdr_create(pj_pool_t *pool,
							    int value )
{
    void *mem = pj_pool_alloc(pool, sizeof(pjsip_retry_after_hdr));
    return pjsip_retry_after_hdr_init(pool, mem, value );
}


///////////////////////////////////////////////////////////////////////////////
/*
 * Supported header.
 */
PJ_DEF(pjsip_supported_hdr*) pjsip_supported_hdr_init( pj_pool_t *pool,
						       void *mem )
{
    pjsip_supported_hdr *hdr = mem;

    PJ_UNUSED_ARG(pool);
    init_hdr(hdr, PJSIP_H_SUPPORTED, &generic_array_hdr_vptr);
    hdr->count = 0;
    return hdr;
}

PJ_DEF(pjsip_supported_hdr*) pjsip_supported_hdr_create(pj_pool_t *pool)
{
    void *mem = pj_pool_alloc(pool, sizeof(pjsip_supported_hdr));
    return pjsip_supported_hdr_init(pool, mem);
}


///////////////////////////////////////////////////////////////////////////////
/*
 * Unsupported header.
 */
PJ_DEF(pjsip_unsupported_hdr*) pjsip_unsupported_hdr_init( pj_pool_t *pool,
							   void *mem )
{
    pjsip_unsupported_hdr *hdr = mem;
    
    PJ_UNUSED_ARG(pool);

    init_hdr(hdr, PJSIP_H_UNSUPPORTED, &generic_array_hdr_vptr);
    hdr->count = 0;
    return hdr;
}

PJ_DEF(pjsip_unsupported_hdr*) pjsip_unsupported_hdr_create(pj_pool_t *pool)
{
    void *mem = pj_pool_alloc(pool, sizeof(pjsip_unsupported_hdr));
    return pjsip_unsupported_hdr_init(pool, mem);
}

///////////////////////////////////////////////////////////////////////////////
/*
 * Via header.
 */
static int pjsip_via_hdr_print( pjsip_via_hdr *hdr, char *buf, pj_size_t size);
static pjsip_via_hdr* pjsip_via_hdr_clone( pj_pool_t *pool, const pjsip_via_hdr *hdr);
static pjsip_via_hdr* pjsip_via_hdr_shallow_clone( pj_pool_t *pool, const pjsip_via_hdr *hdr );

static pjsip_hdr_vptr via_hdr_vptr = 
{
    (pjsip_hdr_clone_fptr) &pjsip_via_hdr_clone,
    (pjsip_hdr_clone_fptr) &pjsip_via_hdr_shallow_clone,
    (pjsip_hdr_print_fptr) &pjsip_via_hdr_print,
};

PJ_DEF(pjsip_via_hdr*) pjsip_via_hdr_init( pj_pool_t *pool,
					   void *mem )
{
    pjsip_via_hdr *hdr = mem;

    PJ_UNUSED_ARG(pool);

    pj_bzero(mem, sizeof(pjsip_via_hdr));
    init_hdr(hdr, PJSIP_H_VIA, &via_hdr_vptr);
    hdr->ttl_param = -1;
    hdr->rport_param = -1;
    pj_list_init(&hdr->other_param);
    return hdr;

}

PJ_DEF(pjsip_via_hdr*) pjsip_via_hdr_create( pj_pool_t *pool )
{
    void *mem = pj_pool_alloc(pool, sizeof(pjsip_via_hdr));
    return pjsip_via_hdr_init(pool, mem);
}

static int pjsip_via_hdr_print( pjsip_via_hdr *hdr, 
				char *buf, pj_size_t size)
{
    int printed;
    char *startbuf = buf;
    char *endbuf = buf + size;
    pj_str_t sip_ver = { "SIP/2.0/", 8 };

    if ((pj_ssize_t)size < hdr->name.slen + sip_ver.slen + 
			   hdr->transport.slen + hdr->sent_by.host.slen + 12)
    {
	return -1;
    }

    /* pjsip_hdr_names */
    copy_advance(buf, hdr->name);
    *buf++ = ':';
    *buf++ = ' ';

    /* SIP/2.0/transport host:port */
    pj_memcpy(buf, sip_ver.ptr, sip_ver.slen);
    buf += sip_ver.slen;
    pj_memcpy(buf, hdr->transport.ptr, hdr->transport.slen);
    buf += hdr->transport.slen;
    *buf++ = ' ';
    pj_memcpy(buf, hdr->sent_by.host.ptr, hdr->sent_by.host.slen);
    buf += hdr->sent_by.host.slen;
    if (hdr->sent_by.port != 0) {
	*buf++ = ':';
	printed = pj_utoa(hdr->sent_by.port, buf);
	buf += printed;
    }

    if (hdr->ttl_param >= 0) {
	size = endbuf-buf;
	if (size < 14)
	    return -1;
	pj_memcpy(buf, ";ttl=", 5);
	printed = pj_utoa(hdr->ttl_param, buf+5);
	buf += printed + 5;
    }

    if (hdr->rport_param >= 0) {
	size = endbuf-buf;
	if (size < 14)
	    return -1;
	pj_memcpy(buf, ";rport", 6);
	buf += 6;
	if (hdr->rport_param > 0) {
	    *buf++ = '=';
	    buf += pj_utoa(hdr->rport_param, buf);
	}
    }


    copy_advance_pair(buf, ";maddr=", 7, hdr->maddr_param);
    copy_advance_pair(buf, ";received=", 10, hdr->recvd_param);
    copy_advance_pair(buf, ";branch=", 8, hdr->branch_param);
    
    printed = pjsip_param_print_on(&hdr->other_param, buf, endbuf-buf, 
				   &pjsip_TOKEN_SPEC,
				   &pjsip_TOKEN_SPEC, ';');
    if (printed < 0)
	return -1;
    buf += printed;
    
    return buf-startbuf;
}

static pjsip_via_hdr* pjsip_via_hdr_clone( pj_pool_t *pool, 
					   const pjsip_via_hdr *rhs)
{
    pjsip_via_hdr *hdr = pjsip_via_hdr_create(pool);
    pj_strdup(pool, &hdr->transport, &rhs->transport);
    pj_strdup(pool, &hdr->sent_by.host, &rhs->sent_by.host);
    hdr->sent_by.port = rhs->sent_by.port;
    hdr->ttl_param = rhs->ttl_param;
    hdr->rport_param = rhs->rport_param;
    pj_strdup(pool, &hdr->maddr_param, &rhs->maddr_param);
    pj_strdup(pool, &hdr->recvd_param, &rhs->recvd_param);
    pj_strdup(pool, &hdr->branch_param, &rhs->branch_param);
    pjsip_param_clone(pool, &hdr->other_param, &rhs->other_param);
    return hdr;
}

static pjsip_via_hdr* pjsip_via_hdr_shallow_clone( pj_pool_t *pool,
						   const pjsip_via_hdr *rhs )
{
    pjsip_via_hdr *hdr = pj_pool_alloc(pool, sizeof(*hdr));
    pj_memcpy(hdr, rhs, sizeof(*hdr));
    pjsip_param_shallow_clone(pool, &hdr->other_param, &rhs->other_param);
    return hdr;
}

///////////////////////////////////////////////////////////////////////////////
/*
 * Warning header.
 */
PJ_DEF(pjsip_warning_hdr*) pjsip_warning_hdr_create(  pj_pool_t *pool,
						      int code,
						      const pj_str_t *host,
						      const pj_str_t *text)
{
    const pj_str_t str_warning = { "Warning", 7 };
    pj_str_t hvalue;

    hvalue.ptr = pj_pool_alloc(pool, 10 +		/* code */
				     host->slen + 2 +	/* host */
				     text->slen + 2);	/* text */
    hvalue.slen = pj_ansi_sprintf(hvalue.ptr, "%u %.*s \"%.*s\"",
				  code, (int)host->slen, host->ptr,
				  (int)text->slen, text->ptr);

    return pjsip_generic_string_hdr_create(pool, &str_warning, &hvalue);
}

PJ_DEF(pjsip_warning_hdr*) 
pjsip_warning_hdr_create_from_status( pj_pool_t *pool,
				      const pj_str_t *host,
				      pj_status_t status)
{
    char errbuf[PJ_ERR_MSG_SIZE];
    pj_str_t text;
    
    text = pj_strerror(status, errbuf, sizeof(errbuf));
    return pjsip_warning_hdr_create(pool, 399, host, &text);
}

///////////////////////////////////////////////////////////////////////////////
/*
 * Message body manipulations.
 */
PJ_DEF(int) pjsip_print_text_body(pjsip_msg_body *msg_body, char *buf, pj_size_t size)
{
    if (size < msg_body->len)
	return -1;
    pj_memcpy(buf, msg_body->data, msg_body->len);
    return msg_body->len;
}

PJ_DEF(void*) pjsip_clone_text_data( pj_pool_t *pool, const void *data,
				     unsigned len)
{
    char *newdata = "";

    if (len) {
	newdata = pj_pool_alloc(pool, len);
	pj_memcpy(newdata, data, len);
    }
    return newdata;
}

PJ_DEF(pj_status_t) pjsip_msg_body_copy( pj_pool_t *pool,
					 pjsip_msg_body *dst_body,
					 const pjsip_msg_body *src_body )
{
    /* First check if clone_data field is initialized. */
    PJ_ASSERT_RETURN( src_body->clone_data!=NULL, PJ_EINVAL );

    /* Duplicate content-type */
    pj_strdup(pool, &dst_body->content_type.type, 
		    &src_body->content_type.type);
    pj_strdup(pool, &dst_body->content_type.subtype, 
		    &src_body->content_type.subtype);
    pj_strdup(pool, &dst_body->content_type.param,
		    &src_body->content_type.param);

    /* Duplicate data. */
    dst_body->data = (*src_body->clone_data)(pool, src_body->data, 
					     src_body->len );

    /* Length. */
    dst_body->len = src_body->len;

    /* Function pointers. */
    dst_body->print_body = src_body->print_body;
    dst_body->clone_data = src_body->clone_data;

    return PJ_SUCCESS;
}


PJ_DEF(pjsip_msg_body*) pjsip_msg_body_clone( pj_pool_t *pool,
					      const pjsip_msg_body *body )
{
    pjsip_msg_body *new_body;
    pj_status_t status;

    new_body = pj_pool_alloc(pool, sizeof(pjsip_msg_body));
    PJ_ASSERT_RETURN(new_body, NULL);

    status = pjsip_msg_body_copy(pool, new_body, body);

    return (status==PJ_SUCCESS) ? new_body : NULL;
}


PJ_DEF(pjsip_msg_body*) pjsip_msg_body_create( pj_pool_t *pool,
					       const pj_str_t *type,
					       const pj_str_t *subtype,
					       const pj_str_t *text )
{
    pjsip_msg_body *body;

    PJ_ASSERT_RETURN(pool && type && subtype && text, NULL);

    body = pj_pool_zalloc(pool, sizeof(pjsip_msg_body));
    PJ_ASSERT_RETURN(body != NULL, NULL);

    pj_strdup(pool, &body->content_type.type, type);
    pj_strdup(pool, &body->content_type.subtype, subtype);
    body->content_type.param.slen = 0;

    body->data = pj_pool_alloc(pool, text->slen);
    pj_memcpy(body->data, text->ptr, text->slen);
    body->len = text->slen;

    body->clone_data = &pjsip_clone_text_data;
    body->print_body = &pjsip_print_text_body;

    return body;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -