git: d9dbd960873e - main - net/belle-sip: Update version 5.2.94=>5.4.2
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 27 Mar 2025 09:18:02 UTC
The branch main has been updated by bofh:
URL: https://cgit.FreeBSD.org/ports/commit/?id=d9dbd960873e847818a0d965d4ce10631e38f793
commit d9dbd960873e847818a0d965d4ce10631e38f793
Author: Muhammad Moinur Rahman <bofh@FreeBSD.org>
AuthorDate: 2025-03-26 21:05:49 +0000
Commit: Muhammad Moinur Rahman <bofh@FreeBSD.org>
CommitDate: 2025-03-27 09:17:04 +0000
net/belle-sip: Update version 5.2.94=>5.4.2
Changelog: https://gitlab.linphone.org/BC/public/belle-sip/-/tags/5.4.2
Sponsored by: Cybermancer Infosec
---
net/belle-sip/Makefile | 17 +-
net/belle-sip/distinfo | 8 +-
net/belle-sip/files/belle_sip_headers_impl.cc | 2516 ++++++++++++++++++++
net/belle-sip/files/patch-CMakeLists.txt | 18 +
...pl.c => patch-src_belle__sip__headers__impl.cc} | 24 +-
.../files/patch-src_belle__sip__internal.h | 14 +-
net/belle-sip/files/patch-src_dns_dns.c | 29 -
net/belle-sip/pkg-plist | 8 +-
8 files changed, 2571 insertions(+), 63 deletions(-)
diff --git a/net/belle-sip/Makefile b/net/belle-sip/Makefile
index ea30799b20e7..0e6a2dfd65e9 100644
--- a/net/belle-sip/Makefile
+++ b/net/belle-sip/Makefile
@@ -1,5 +1,5 @@
PORTNAME= belle-sip
-DISTVERSION= 5.2.94
+DISTVERSION= 5.4.2
CATEGORIES= net java
MAINTAINER= bofh@FreeBSD.org
@@ -9,23 +9,24 @@ WWW= https://www.linphone.org/technical-corner/belle-sip.html
LICENSE= GPLv2+
LICENSE_FILE= ${WRKSRC}/LICENSE.txt
-LIB_DEPENDS= libantlr3c.so:devel/libantlr3c \
- libbctoolbox.so:net/bctoolbox \
- libbelr.so:textproc/belr
+BUILD_DEPENDS= ${LOCALBASE}/lib/libbctoolbox.a:net/bctoolbox \
+ ${LOCALBASE}/lib/libbcunit.a:devel/bcunit \
+ ${LOCALBASE}/lib/libbelr.a:textproc/belr
+LIB_DEPENDS= libantlr3c.so:devel/libantlr3c
USES= cmake cpe java:build tar:bz2
CPE_VENDOR= linphone
USE_GITLAB= yes
GL_SITE= https://gitlab.linphone.org/BC
GL_ACCOUNT= public
+GL_TUPLE= https://gitlab.linphone.org/BC/public:external:cpp-httplib:a2ed0d11c134b6c23da275103b5183b423cea8a8:httplib/tester/cpp-httplib
USE_LDCONFIG= yes
CMAKE_ARGS= -DCMAKE_PREFIX_PATH=${LOCALBASE} \
- -DENABLE_STATIC=NO \
-DENABLE_STRICT=NO \
- -DENABLE_TESTS=NO
+ -DENABLE_TESTS=NO \
+ -DENABLE_UNIT_TESTS=NO
-post-patch:
- @${REINPLACE_CMD} '/clock_gettime/d' ${WRKSRC}/CMakeLists.txt
+LDFLAGS+= -lpthread
.include <bsd.port.mk>
diff --git a/net/belle-sip/distinfo b/net/belle-sip/distinfo
index f204584637eb..22350636883a 100644
--- a/net/belle-sip/distinfo
+++ b/net/belle-sip/distinfo
@@ -1,3 +1,5 @@
-TIMESTAMP = 1690557657
-SHA256 (belle-sip-5.2.94.tar.bz2) = d94d4310a48162f480d60076867f325e99ac256d4a871d8e1062810c63e90f80
-SIZE (belle-sip-5.2.94.tar.bz2) = 3436258
+TIMESTAMP = 1743022710
+SHA256 (belle-sip-5.4.2.tar.bz2) = a8d74d193a3ac71c338c69b4047e91e59c1af9eb9640a2882aee4be8a6c5a889
+SIZE (belle-sip-5.4.2.tar.bz2) = 655526
+SHA256 (external-cpp-httplib-a2ed0d11c134b6c23da275103b5183b423cea8a8_GL0.tar.gz) = 9b4db463ede003979bd5ea9ec97c7b80e06b1d6da3f05ce39c43670c6807a0f0
+SIZE (external-cpp-httplib-a2ed0d11c134b6c23da275103b5183b423cea8a8_GL0.tar.gz) = 1153181
diff --git a/net/belle-sip/files/belle_sip_headers_impl.cc b/net/belle-sip/files/belle_sip_headers_impl.cc
new file mode 100644
index 000000000000..a660aa132a41
--- /dev/null
+++ b/net/belle-sip/files/belle_sip_headers_impl.cc
@@ -0,0 +1,2516 @@
+/*
+ * Copyright (c) 2012-2024 Belledonne Communications SARL.
+ *
+ * This file is part of belle-sip.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "belle-sip/headers.h"
+#include "belle-sip/parameters.h"
+#include "sip/sip_parser.hh"
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "belle_sip_internal.h"
+#include "listeningpoint_internal.h"
+
+/************************
+ * header
+ ***********************/
+
+GET_SET_STRING(belle_sip_header, name);
+#define PROTO_SIP 0x1
+#define PROTO_HTTP 0x1 << 1
+typedef belle_sip_header_t *(*header_parse_func)(const char *);
+
+struct header_name_func_pair {
+ int protocol;
+ const char *name;
+ header_parse_func func;
+};
+
+static struct header_name_func_pair header_table[] = {
+ {PROTO_SIP, "m", (header_parse_func)belle_sip_header_contact_parse},
+ {PROTO_SIP, BELLE_SIP_CONTACT, (header_parse_func)belle_sip_header_contact_parse},
+ {PROTO_SIP, "f", (header_parse_func)belle_sip_header_from_parse},
+ {PROTO_SIP, BELLE_SIP_FROM, (header_parse_func)belle_sip_header_from_parse},
+ {PROTO_SIP, "t", (header_parse_func)belle_sip_header_to_parse},
+ {PROTO_SIP, BELLE_SIP_TO, (header_parse_func)belle_sip_header_to_parse},
+ {PROTO_SIP, "d", (header_parse_func)belle_sip_header_diversion_parse},
+ {PROTO_SIP, BELLE_SIP_DIVERSION, (header_parse_func)belle_sip_header_diversion_parse},
+ {PROTO_SIP, "i", (header_parse_func)belle_sip_header_call_id_parse},
+ {PROTO_SIP, BELLE_SIP_CALL_ID, (header_parse_func)belle_sip_header_call_id_parse},
+ {PROTO_SIP, "r", (header_parse_func)belle_sip_header_retry_after_parse},
+ {PROTO_SIP, BELLE_SIP_RETRY_AFTER, (header_parse_func)belle_sip_header_retry_after_parse},
+ {PROTO_SIP, "l", (header_parse_func)belle_sip_header_content_length_parse},
+ {PROTO_SIP | PROTO_HTTP, BELLE_SIP_CONTENT_LENGTH, (header_parse_func)belle_sip_header_content_length_parse},
+ {PROTO_SIP, "c", (header_parse_func)belle_sip_header_content_type_parse},
+ {PROTO_SIP | PROTO_HTTP, BELLE_SIP_CONTENT_TYPE, (header_parse_func)belle_sip_header_content_type_parse},
+ {PROTO_SIP, BELLE_SIP_CSEQ, (header_parse_func)belle_sip_header_cseq_parse},
+ {PROTO_SIP, BELLE_SIP_ROUTE, (header_parse_func)belle_sip_header_route_parse},
+ {PROTO_SIP, BELLE_SIP_RECORD_ROUTE, (header_parse_func)belle_sip_header_record_route_parse},
+ {PROTO_SIP, "v", (header_parse_func)belle_sip_header_via_parse},
+ {PROTO_SIP, BELLE_SIP_VIA, (header_parse_func)belle_sip_header_via_parse},
+ {PROTO_SIP, "x", (header_parse_func)belle_sip_header_session_expires_parse},
+ {PROTO_SIP, BELLE_SIP_SESSION_EXPIRES, (header_parse_func)belle_sip_header_session_expires_parse},
+ {PROTO_SIP, BELLE_SIP_AUTHORIZATION, (header_parse_func)belle_sip_header_authorization_parse},
+ {PROTO_SIP, BELLE_SIP_PROXY_AUTHORIZATION, (header_parse_func)belle_sip_header_proxy_authorization_parse},
+ {PROTO_SIP | PROTO_HTTP, BELLE_SIP_WWW_AUTHENTICATE, (header_parse_func)belle_sip_header_www_authenticate_parse},
+ {PROTO_SIP | PROTO_HTTP, BELLE_SIP_PROXY_AUTHENTICATE,
+ (header_parse_func)belle_sip_header_proxy_authenticate_parse},
+ {PROTO_SIP, BELLE_SIP_MAX_FORWARDS, (header_parse_func)belle_sip_header_max_forwards_parse},
+ {PROTO_SIP | PROTO_HTTP, BELLE_SIP_USER_AGENT, (header_parse_func)belle_sip_header_user_agent_parse},
+ {PROTO_SIP, BELLE_SIP_EXPIRES, (header_parse_func)belle_sip_header_expires_parse},
+ {PROTO_SIP | PROTO_HTTP, BELLE_SIP_ALLOW, (header_parse_func)belle_sip_header_allow_parse},
+ {PROTO_SIP, BELLE_SIP_SUBSCRIPTION_STATE, (header_parse_func)belle_sip_header_subscription_state_parse},
+ {PROTO_SIP, BELLE_SIP_SERVICE_ROUTE, (header_parse_func)belle_sip_header_service_route_parse},
+ {PROTO_SIP, BELLE_SIP_REFER_TO, (header_parse_func)belle_sip_header_refer_to_parse},
+ {PROTO_SIP, BELLE_SIP_REFERRED_BY, (header_parse_func)belle_sip_header_referred_by_parse},
+ {PROTO_SIP, BELLE_SIP_REPLACES, (header_parse_func)belle_sip_header_replaces_parse},
+ {PROTO_SIP | PROTO_HTTP, BELLE_SIP_DATE, (header_parse_func)belle_sip_header_date_parse},
+ {PROTO_SIP, BELLE_SIP_P_PREFERRED_IDENTITY, (header_parse_func)belle_sip_header_p_preferred_identity_parse},
+ {PROTO_SIP, BELLE_SIP_PRIVACY, (header_parse_func)belle_sip_header_privacy_parse},
+ {PROTO_SIP, BELLE_SIP_EVENT, (header_parse_func)belle_sip_header_event_parse},
+ {PROTO_SIP, "o", (header_parse_func)belle_sip_header_event_parse},
+ {PROTO_SIP, BELLE_SIP_SUPPORTED, (header_parse_func)belle_sip_header_supported_parse},
+ {PROTO_SIP, "k", (header_parse_func)belle_sip_header_supported_parse},
+ {PROTO_SIP, BELLE_SIP_REQUIRE, (header_parse_func)belle_sip_header_require_parse},
+ {PROTO_SIP, BELLE_SIP_CONTENT_DISPOSITION, (header_parse_func)belle_sip_header_content_disposition_parse},
+ {PROTO_SIP | PROTO_HTTP, BELLE_SIP_ACCEPT, (header_parse_func)belle_sip_header_accept_parse},
+ {PROTO_SIP, BELLE_SIP_REASON, (header_parse_func)belle_sip_header_reason_parse},
+ {PROTO_SIP, BELLE_SIP_AUTHENTICATION_INFO, (header_parse_func)belle_sip_header_authentication_info_parse}};
+
+static belle_sip_header_t *belle_header_create(const char *name, const char *value, int protocol) {
+ size_t i;
+ belle_sip_header_t *ret;
+ size_t elements = sizeof(header_table) / sizeof(struct header_name_func_pair);
+
+ if (!name || name[0] == '\0') {
+ belle_sip_error("Cannot create header without name");
+ return NULL;
+ }
+
+ for (i = 0; i < elements; i++) {
+ if ((header_table[i].protocol & protocol) && strcasecmp(header_table[i].name, name) == 0) {
+ char *raw = belle_sip_strdup_printf("%s:%s", name, value);
+ ret = header_table[i].func(raw);
+ belle_sip_free(raw);
+ return ret;
+ }
+ }
+ /*not a known header*/
+ return BELLE_SIP_HEADER(belle_sip_header_extension_create(name, value));
+}
+
+belle_sip_header_t *belle_sip_header_create(const char *name, const char *value) {
+ return belle_header_create(name, value, PROTO_SIP);
+}
+
+belle_sip_header_t *belle_http_header_create(const char *name, const char *value) {
+ return belle_header_create(name, value, PROTO_HTTP);
+}
+
+void belle_sip_header_init(belle_sip_header_t *header) {
+}
+
+static void belle_sip_header_clone(belle_sip_header_t *header, const belle_sip_header_t *orig) {
+ CLONE_STRING(belle_sip_header, name, header, orig)
+ if (belle_sip_header_get_next(orig)) {
+ belle_sip_header_set_next(
+ header, BELLE_SIP_HEADER(belle_sip_object_clone(BELLE_SIP_OBJECT(belle_sip_header_get_next(orig)))));
+ }
+}
+
+static void belle_sip_header_destroy(belle_sip_header_t *header) {
+ if (header->name) belle_sip_free(header->name);
+ if (header->unparsed_value) belle_sip_free(header->unparsed_value);
+ if (header->next) belle_sip_object_unref(BELLE_SIP_OBJECT(header->next));
+}
+
+void belle_sip_header_set_next(belle_sip_header_t *header, belle_sip_header_t *next) {
+ if (next) belle_sip_object_ref(next);
+ if (header->next) belle_sip_object_unref(header->next);
+ header->next = next;
+}
+
+void belle_sip_header_append(belle_sip_header_t *header, belle_sip_header_t *next) {
+ auto current = header;
+ while (current->next)
+ current = current->next;
+ belle_sip_header_set_next(current, next);
+}
+
+belle_sip_header_t *belle_sip_header_get_next(const belle_sip_header_t *header) {
+ return header->next;
+}
+
+const char *belle_sip_header_get_unparsed_value(belle_sip_header_t *obj) {
+ if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(obj, belle_sip_header_extension_t)) {
+ return belle_sip_header_extension_get_value(BELLE_SIP_HEADER_EXTENSION(obj));
+ } else {
+ char *tmp = belle_sip_object_to_string(obj);
+ char *ret;
+ if (obj->unparsed_value) {
+ belle_sip_free(obj->unparsed_value);
+ obj->unparsed_value = NULL;
+ }
+ obj->unparsed_value = tmp;
+ ret = tmp;
+ ret += strlen(obj->name) + 1; /* name + semicolon*/
+ for (; *ret == ' '; ret++) {
+ }; /*skip spaces*/
+ return ret;
+ }
+}
+
+belle_sip_error_code
+belle_sip_header_marshal(belle_sip_header_t *header, char *buff, size_t buff_size, size_t *offset) {
+ if (header->name) {
+ return belle_sip_snprintf(buff, buff_size, offset, "%s: ", header->name);
+ } else {
+ belle_sip_warning("no header name found");
+ return BELLE_SIP_OK;
+ }
+}
+
+BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_header_t);
+
+BELLE_SIP_INSTANCIATE_VPTR(belle_sip_header_t,
+ belle_sip_object_t,
+ belle_sip_header_destroy,
+ belle_sip_header_clone,
+ belle_sip_header_marshal,
+ TRUE);
+
+BELLE_SIP_PARSE_WITH_CONTEXT_AND_RULE(header, message_header);
+
+belle_sip_header_t *belle_sip_header_new_dummy(void) {
+ return belle_sip_header_create("dummy", "dummy");
+}
+
+void belle_sip_header_set_unparsed_value(belle_sip_header_t *obj, const char *value) {
+ if (obj->unparsed_value) belle_sip_free(obj->unparsed_value);
+ if (value) {
+ obj->unparsed_value = belle_sip_strdup(value);
+ } else {
+ obj->unparsed_value = nullptr;
+ }
+}
+
+/************************
+ * header_address
+ ***********************/
+struct _belle_sip_header_address {
+ belle_sip_parameters_t base;
+ char *displayname;
+ belle_sip_uri_t *uri;
+ belle_generic_uri_t *absolute_uri;
+ unsigned char automatic;
+};
+
+static void belle_sip_header_address_init(belle_sip_header_address_t *object) {
+ belle_sip_parameters_init((belle_sip_parameters_t *)object); /*super*/
+}
+
+static void belle_sip_header_address_destroy(belle_sip_header_address_t *address) {
+ if (address->displayname) belle_sip_free(address->displayname);
+ if (address->uri) belle_sip_object_unref(address->uri);
+ if (address->absolute_uri) belle_sip_object_unref(address->absolute_uri);
+}
+
+static void _belle_sip_header_address_clone(belle_sip_header_address_t *addr, const belle_sip_header_address_t *orig) {
+ CLONE_STRING(belle_sip_header_address, displayname, addr, orig)
+ if (belle_sip_header_address_get_uri(orig)) {
+ belle_sip_header_address_set_uri(
+ addr, BELLE_SIP_URI(belle_sip_object_clone(BELLE_SIP_OBJECT(belle_sip_header_address_get_uri(orig)))));
+ }
+ if (belle_sip_header_address_get_absolute_uri(orig)) {
+ belle_sip_header_address_set_absolute_uri(addr, BELLE_GENERIC_URI(belle_sip_object_clone(BELLE_SIP_OBJECT(
+ belle_sip_header_address_get_absolute_uri(orig)))));
+ }
+ if (belle_sip_header_address_get_automatic(orig)) {
+ belle_sip_header_address_set_automatic(addr, belle_sip_header_address_get_automatic(orig));
+ }
+ belle_sip_parameters_copy_parameters_from(&addr->base, &orig->base);
+}
+belle_sip_header_address_t *belle_sip_header_address_clone(const belle_sip_header_address_t *orig) {
+ belle_sip_header_address_t *new_address = belle_sip_header_address_new();
+ _belle_sip_header_address_clone(new_address, orig);
+ return new_address;
+}
+
+static belle_sip_error_code _belle_sip_header_address_marshal(
+ belle_sip_header_address_t *header, char *buff, size_t buff_size, size_t *offset, int force_angle_quote) {
+ belle_sip_error_code error = BELLE_SIP_OK;
+ bool has_display_name = header->displayname != nullptr;
+
+ if (belle_sip_stack_name_addr_forced) force_angle_quote = TRUE;
+
+ /*1 display name*/
+ if (has_display_name) {
+ char *escaped_display_name = belle_sip_display_name_to_backslashed_escaped_string(header->displayname);
+ error = belle_sip_snprintf(buff, buff_size, offset, "\"%s\" ", escaped_display_name);
+ belle_sip_free(escaped_display_name);
+ if (error != BELLE_SIP_OK) return error;
+ }
+ if (header->uri || header->absolute_uri) {
+ bool has_parameters = belle_sip_parameters_get_parameter_names(&header->base);
+ bool is_sip_uri_with_headers_or_parameters =
+ (header->uri != nullptr) &&
+ (belle_sip_parameters_get_parameter_names((belle_sip_parameters_t *)header->uri) ||
+ belle_sip_uri_get_header_names(header->uri));
+ bool angle_quote_required =
+ force_angle_quote || has_display_name || is_sip_uri_with_headers_or_parameters || has_parameters;
+ /*cases where < is required*/
+ if (angle_quote_required) {
+ error = belle_sip_snprintf(buff, buff_size, offset, "%s", "<");
+ if (error != BELLE_SIP_OK) return error;
+ }
+ if (header->uri) {
+ error = belle_sip_uri_marshal(header->uri, buff, buff_size, offset);
+ } else {
+ error = belle_generic_uri_marshal(header->absolute_uri, buff, buff_size, offset);
+ }
+ if (error != BELLE_SIP_OK) return error;
+ if (angle_quote_required) {
+ error = belle_sip_snprintf(buff, buff_size, offset, "%s", ">");
+ if (error != BELLE_SIP_OK) return error;
+ }
+ }
+ error = belle_sip_parameters_marshal(&header->base, buff, buff_size, offset);
+ if (error != BELLE_SIP_OK) return error;
+ return error;
+}
+
+belle_sip_error_code
+belle_sip_header_address_marshal(belle_sip_header_address_t *header, char *buff, size_t buff_size, size_t *offset) {
+ return _belle_sip_header_address_marshal(header, buff, buff_size, offset, FALSE);
+}
+#define belle_sip_header_address_clone \
+ _belle_sip_header_address_clone /*because public clone function is not the one to be used internally*/
+BELLE_SIP_NEW_HEADER(header_address, parameters, "header_address");
+BELLE_SIP_ADDRESS_PARSE(header_address);
+GET_SET_STRING(belle_sip_header_address, displayname);
+SET_QUOTED_STRING(belle_sip_header_address, displayname);
+
+void belle_sip_header_address_set_quoted_displayname_with_slashes(belle_sip_header_address_t *address,
+ const char *value) {
+ char *unescaped_value = belle_sip_string_to_backslash_less_unescaped_string(value);
+ belle_sip_header_address_set_quoted_displayname(address, unescaped_value);
+ belle_sip_free(unescaped_value);
+}
+
+belle_sip_uri_t *belle_sip_header_address_get_uri(const belle_sip_header_address_t *address) {
+ return address->uri;
+}
+
+void belle_sip_header_address_set_uri(belle_sip_header_address_t *address, belle_sip_uri_t *uri) {
+ if (uri) belle_sip_object_ref(uri);
+ if (address->uri) {
+ belle_sip_object_unref(address->uri);
+ }
+ address->uri = uri;
+ if (address->absolute_uri && uri) {
+ belle_sip_warning("sip absolute uri [%p] already set for header_address [%p], cleaning it",
+ address->absolute_uri, address);
+ belle_sip_header_address_set_absolute_uri(address, NULL);
+ }
+}
+
+void belle_sip_header_address_set_automatic(belle_sip_header_address_t *address, int automatic) {
+ address->automatic = (unsigned char)automatic;
+}
+
+int belle_sip_header_address_get_automatic(const belle_sip_header_address_t *address) {
+ return address->automatic;
+}
+
+belle_generic_uri_t *belle_sip_header_address_get_absolute_uri(const belle_sip_header_address_t *address) {
+ return address->absolute_uri;
+}
+
+void belle_sip_header_address_set_absolute_uri(belle_sip_header_address_t *address, belle_generic_uri_t *absolute_uri) {
+ belle_sip_object_ref(absolute_uri);
+ if (address->absolute_uri) {
+ belle_sip_object_unref(address->absolute_uri);
+ }
+ address->absolute_uri = absolute_uri;
+ if (address->uri && absolute_uri) {
+ belle_sip_warning("sip uri [%p] already set for header_address [%p], cleaning it", address->uri, address);
+ belle_sip_header_address_set_uri(address, NULL);
+ }
+}
+
+void belle_sip_header_address_set_generic_uri(belle_sip_header_address_t *obj, belle_generic_uri_t *generic_uri) {
+ const char *scheme = belle_generic_uri_get_scheme(generic_uri);
+ if (scheme && (strcasecmp(scheme, "sip") != 0) && (strcasecmp(scheme, "sips") != 0)) {
+ belle_sip_header_address_set_absolute_uri(obj, generic_uri);
+ } else {
+ belle_sip_error("Cannot parse a sip/sips uri as a generic uri");
+ belle_sip_object_unref(generic_uri);
+ }
+}
+
+belle_sip_header_address_t *belle_sip_header_address_create(const char *display, belle_sip_uri_t *uri) {
+ belle_sip_header_address_t *address = belle_sip_header_address_new();
+ belle_sip_header_address_set_displayname(address, display);
+ belle_sip_header_address_set_uri(address, uri);
+ return address;
+}
+
+belle_sip_header_address_t *belle_sip_header_address_create2(const char *display, belle_generic_uri_t *uri) {
+ belle_sip_header_address_t *address = belle_sip_header_address_new();
+ belle_sip_header_address_set_displayname(address, display);
+ belle_sip_header_address_set_absolute_uri(address, uri);
+ return address;
+}
+
+int belle_sip_header_address_equals(const belle_sip_header_address_t *addr_a,
+ const belle_sip_header_address_t *addr_b) {
+ // Addresses are not identical if either is NULL
+ if (!addr_a | !addr_b) return -1;
+ belle_sip_uri_t *uri_a = belle_sip_header_address_get_uri(addr_a);
+ belle_sip_uri_t *uri_b = belle_sip_header_address_get_uri(addr_b);
+ // URIs are not identical if either is NULL
+ if (!uri_a | !uri_b) return -1;
+ const bool_t uri_equal = (belle_sip_uri_equals(uri_a, uri_b) != 0);
+
+ const char *displayname_a = belle_sip_header_address_get_displayname(addr_a);
+ const char *displayname_b = belle_sip_header_address_get_displayname(addr_b);
+ bool_t displayname_equal = FALSE;
+ if (displayname_a && displayname_b) {
+ displayname_equal = (strcmp(displayname_a, displayname_b) == 0);
+ } else if (!displayname_a & !displayname_b) {
+ displayname_equal = TRUE;
+ }
+ return ((uri_equal && displayname_equal) ? 0 : -1);
+}
+
+/*fast header address implementation*/
+
+belle_sip_header_address_t *belle_sip_header_address_fast_parse(const char *address) {
+ return belle_sip_header_address_parse(address);
+}
+
+/*
+ same as belle_sip_header_address_fast_parse but with no error log.
+ */
+belle_sip_header_address_t *belle_sip_header_address_try_fast_parse(const char *address) {
+ return belle_sip_try_header_address_parse(address);
+}
+
+belle_sip_header_address_t *belle_sip_header_address_try_parse(const char *address) {
+ return belle_sip_try_header_address_parse(address);
+}
+
+/******************************
+ * Allow header inherits from header
+ ******************************/
+struct _belle_sip_header_allow {
+ belle_sip_header_t header;
+ const char *method;
+};
+static void belle_sip_header_allow_clone(belle_sip_header_allow_t *allow, const belle_sip_header_allow_t *orig) {
+ CLONE_STRING(belle_sip_header_allow, method, allow, orig)
+}
+static void belle_sip_header_allow_destroy(belle_sip_header_allow_t *allow) {
+ if (allow->method) belle_sip_free((void *)allow->method);
+}
+
+belle_sip_error_code
+belle_sip_header_allow_marshal(belle_sip_header_allow_t *allow, char *buff, size_t buff_size, size_t *offset) {
+ belle_sip_error_code error = belle_sip_header_marshal(BELLE_SIP_HEADER(allow), buff, buff_size, offset);
+ if (error != BELLE_SIP_OK) return error;
+ error = belle_sip_snprintf(buff, buff_size, offset, "%s", allow->method);
+ if (error != BELLE_SIP_OK) return error;
+ return error;
+}
+
+BELLE_SIP_NEW_HEADER(header_allow, header, "Allow");
+BELLE_SIP_PARSE_FULL(header_allow);
+belle_sip_header_allow_t *belle_sip_header_allow_create(const char *methods) {
+ belle_sip_header_allow_t *allow = belle_sip_header_allow_new();
+ belle_sip_header_allow_set_method(allow, methods);
+ return allow;
+}
+GET_SET_STRING(belle_sip_header_allow, method);
+
+/************************
+ * Contact header object inherits from header_address
+ ***********************/
+struct _belle_sip_header_contact {
+ belle_sip_header_address_t address;
+ unsigned char wildcard;
+ unsigned char unknown;
+ unsigned char pad[2];
+};
+
+void belle_sip_header_contact_destroy(belle_sip_header_contact_t *contact) {
+}
+
+void belle_sip_header_contact_clone(belle_sip_header_contact_t *contact, const belle_sip_header_contact_t *orig) {
+ contact->wildcard = orig->wildcard;
+}
+
+belle_sip_error_code
+belle_sip_header_contact_marshal(belle_sip_header_contact_t *contact, char *buff, size_t buff_size, size_t *offset) {
+ belle_sip_error_code error = belle_sip_header_marshal(BELLE_SIP_HEADER(contact), buff, buff_size, offset);
+ if (error != BELLE_SIP_OK) return error;
+ if (contact->wildcard) {
+ error = belle_sip_snprintf(buff, buff_size, offset, "%s", "*");
+ } else {
+ error = belle_sip_header_address_marshal(&contact->address, buff, buff_size, offset);
+ }
+ return error;
+}
+
+BELLE_SIP_NEW_HEADER(header_contact, header_address, BELLE_SIP_CONTACT);
+BELLE_SIP_PARSE_WITH_CONTEXT(header_contact);
+belle_sip_header_contact_t *belle_sip_header_contact_create(const belle_sip_header_address_t *contact) {
+ belle_sip_header_contact_t *header = belle_sip_header_contact_new();
+ _belle_sip_object_copy(BELLE_SIP_OBJECT(header), BELLE_SIP_OBJECT(contact));
+ belle_sip_header_set_next(BELLE_SIP_HEADER(header), NULL); /*make sure only one header is kept*/
+ belle_sip_header_set_name(BELLE_SIP_HEADER(header), BELLE_SIP_CONTACT); /*restaure header name*/
+ return header;
+}
+GET_SET_INT_PARAM_PRIVATE(belle_sip_header_contact, expires, int, _);
+GET_SET_INT_PARAM_PRIVATE(belle_sip_header_contact, q, float, _);
+GET_SET_BOOL(belle_sip_header_contact, wildcard, is);
+
+void belle_sip_header_contact_set_string_wildcard(belle_sip_header_contact_t *contact, const char *wildcard) {
+ if (strcmp("*", wildcard) == 0) {
+ belle_sip_header_contact_set_wildcard(contact, 1);
+ }
+}
+
+int belle_sip_header_contact_set_expires(belle_sip_header_contact_t *contact, int expires) {
+ if (expires < 0) {
+ belle_sip_error("bad expires value [%i] for contact", expires);
+ return -1;
+ }
+ _belle_sip_header_contact_set_expires(contact, expires);
+ return 0;
+}
+int belle_sip_header_contact_set_qvalue(belle_sip_header_contact_t *contact, float qValue) {
+ if (qValue != -1 && qValue < 0 && qValue > 1) {
+ belle_sip_error("bad q value [%f] for contact", qValue);
+ return -1;
+ }
+ _belle_sip_header_contact_set_q(contact, qValue);
+ return 0;
+}
+float belle_sip_header_contact_get_qvalue(const belle_sip_header_contact_t *contact) {
+ return belle_sip_header_contact_get_q(contact);
+}
+
+unsigned int belle_sip_header_contact_equals(const belle_sip_header_contact_t *a, const belle_sip_header_contact_t *b) {
+ if (!a | !b) return 0;
+ return belle_sip_uri_equals(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(a)),
+ belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(b)));
+}
+unsigned int belle_sip_header_contact_not_equals(const belle_sip_header_contact_t *a,
+ const belle_sip_header_contact_t *b) {
+ return !belle_sip_header_contact_equals(a, b);
+}
+
+unsigned int belle_sip_header_contact_equals_with_uri_omitting(const belle_sip_header_contact_t *a,
+ const belle_sip_header_contact_t *b) {
+ if (!a | !b) return 0;
+ return belle_sip_uri_equals_with_uri_omitting(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(a)),
+ belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(b)));
+}
+unsigned int belle_sip_header_contact_not_equals_with_uri_omitting(const belle_sip_header_contact_t *a,
+ const belle_sip_header_contact_t *b) {
+ return !belle_sip_header_contact_equals_with_uri_omitting(a, b);
+}
+
+void belle_sip_header_contact_set_automatic(belle_sip_header_contact_t *a, int enabled) {
+ belle_sip_header_address_set_automatic((belle_sip_header_address_t *)a, enabled);
+}
+
+int belle_sip_header_contact_get_automatic(const belle_sip_header_contact_t *a) {
+ return belle_sip_header_address_get_automatic((belle_sip_header_address_t *)a);
+}
+
+void belle_sip_header_contact_set_unknown(belle_sip_header_contact_t *a, int value) {
+ a->unknown = value;
+}
+
+int belle_sip_header_contact_is_unknown(const belle_sip_header_contact_t *a) {
+ return a->unknown;
+}
+
+/**************************
+ * From header object inherits from header_address
+ ***************************/
+#define BELLE_SIP_FROM_LIKE_MARSHAL(header, force_angle_quote) \
+ belle_sip_error_code error = belle_sip_header_marshal(BELLE_SIP_HEADER(header), buff, buff_size, offset); \
+ if (error != BELLE_SIP_OK) return error; \
+ error = _belle_sip_header_address_marshal(&header->address, buff, buff_size, offset, force_angle_quote); \
+ if (error != BELLE_SIP_OK) return error; \
+ return error;
+
+struct _belle_sip_header_from {
+ belle_sip_header_address_t address;
+};
+
+static void belle_sip_header_from_destroy(belle_sip_header_from_t *from) {
+}
+
+static void belle_sip_header_from_clone(belle_sip_header_from_t *from, const belle_sip_header_from_t *cloned) {
+}
+
+belle_sip_error_code
+belle_sip_header_from_marshal(belle_sip_header_from_t *from, char *buff, size_t buff_size, size_t *offset) {
+ BELLE_SIP_FROM_LIKE_MARSHAL(from, FALSE);
+}
+
+belle_sip_header_from_t *belle_sip_header_from_create2(const char *uri, const char *tag) {
+ belle_sip_header_address_t *address = belle_sip_header_address_parse(uri);
+ if (address) {
+ belle_sip_header_from_t *from = belle_sip_header_from_create(address, tag);
+ belle_sip_object_unref(address);
+ return from;
+ } else return NULL;
+}
+belle_sip_header_from_t *belle_sip_header_from_create(const belle_sip_header_address_t *address, const char *tag) {
+ belle_sip_header_from_t *header = belle_sip_header_from_new();
+ belle_sip_uri_t *uri;
+ _belle_sip_object_copy((belle_sip_object_t *)header, (belle_sip_object_t *)address);
+ /*clear unwanted uri components*/
+ if ((uri = belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(header)))) {
+ belle_sip_parameters_t *params = BELLE_SIP_PARAMETERS(uri);
+ belle_sip_parameters_remove_parameter(params, "lr");
+ belle_sip_parameters_remove_parameter(params, "ttl");
+ belle_sip_parameters_remove_parameter(params, "method");
+ belle_sip_parameters_remove_parameter(params, "maddr");
+ belle_sip_parameters_remove_parameter(params, "transport");
+ belle_sip_uri_set_port(uri, 0);
+ belle_sip_uri_headers_clean(uri);
+ }
+ belle_sip_header_set_next(BELLE_SIP_HEADER(header), NULL); /*make sure only one header is kept*/
+ belle_sip_header_set_name(BELLE_SIP_HEADER(header), BELLE_SIP_FROM); /*restore header name*/
+ if (tag) belle_sip_header_from_set_tag(header, tag);
+ return header;
+}
+BELLE_SIP_NEW_HEADER(header_from, header_address, BELLE_SIP_FROM);
+BELLE_SIP_PARSE_HEADER_WITH_URI_CHECK(header_from);
+GET_SET_STRING_PARAM2(belle_sip_header_from, tag, raw_tag);
+
+void belle_sip_header_from_set_random_tag(belle_sip_header_from_t *obj) {
+ char tmp[BELLE_SIP_TAG_LENGTH];
+ belle_sip_header_from_set_raw_tag(obj, belle_sip_random_token(tmp, sizeof(tmp)));
+}
+
+void belle_sip_header_from_set_tag(belle_sip_header_from_t *obj, const char *tag) {
+ if (tag == BELLE_SIP_RANDOM_TAG) belle_sip_header_from_set_random_tag(obj);
+ else belle_sip_header_from_set_raw_tag(obj, tag);
+}
+
+const char *belle_sip_header_from_get_tag(const belle_sip_header_from_t *obj) {
+ return belle_sip_header_from_get_raw_tag(obj);
+}
+
+/**************************
+ * To header object inherits from header_address
+ ***************************/
+struct _belle_sip_header_to {
+ belle_sip_header_address_t address;
+};
+
+static void belle_sip_header_to_destroy(belle_sip_header_to_t *to) {
+}
+
+void belle_sip_header_to_clone(belle_sip_header_to_t *contact, const belle_sip_header_to_t *orig) {
+}
+
+belle_sip_error_code belle_sip_header_to_marshal(belle_sip_header_to_t *to,
+ char *buff,
+ size_t buff_size,
+ size_t *offset){BELLE_SIP_FROM_LIKE_MARSHAL(to, FALSE)}
+
+BELLE_SIP_NEW_HEADER(header_to, header_address, BELLE_SIP_TO);
+BELLE_SIP_PARSE_HEADER_WITH_URI_CHECK(header_to);
+GET_SET_STRING_PARAM2(belle_sip_header_to, tag, raw_tag);
+
+belle_sip_header_to_t *belle_sip_header_to_create2(const char *uri, const char *tag) {
+ belle_sip_header_address_t *address = belle_sip_header_address_parse(uri);
+ if (address) {
+ belle_sip_header_to_t *to = belle_sip_header_to_create(address, tag);
+ belle_sip_object_unref(address);
+ return to;
+ } else return NULL;
+}
+belle_sip_header_to_t *belle_sip_header_to_create(const belle_sip_header_address_t *address, const char *tag) {
+ belle_sip_header_to_t *header = belle_sip_header_to_new();
+ belle_sip_uri_t *uri;
+ _belle_sip_object_copy((belle_sip_object_t *)header, (belle_sip_object_t *)address);
+ /*clear unwanted uri components*/
+ if ((uri = belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(header)))) {
+ belle_sip_parameters_t *params = BELLE_SIP_PARAMETERS(uri);
+ belle_sip_parameters_remove_parameter(params, "lr");
+ belle_sip_parameters_remove_parameter(params, "ttl");
+ belle_sip_parameters_remove_parameter(params, "method");
+ belle_sip_parameters_remove_parameter(params, "maddr");
+ belle_sip_parameters_remove_parameter(params, "transport");
+ belle_sip_uri_set_port(uri, 0);
+ belle_sip_uri_headers_clean(uri);
+ }
+ belle_sip_header_set_next(BELLE_SIP_HEADER(header), NULL); /*make sure only one header is kept*/
+ belle_sip_header_set_name(BELLE_SIP_HEADER(header), BELLE_SIP_TO); /*restaure header name*/
+ if (tag) belle_sip_header_to_set_tag(header, tag);
+ return header;
+}
+void belle_sip_header_to_set_random_tag(belle_sip_header_to_t *obj) {
+ char tmp[8];
+ /*not less than 32bit */
+ belle_sip_header_to_set_tag(obj, belle_sip_random_token(tmp, sizeof(tmp)));
+}
+
+void belle_sip_header_to_set_tag(belle_sip_header_to_t *obj, const char *tag) {
+ if (tag == BELLE_SIP_RANDOM_TAG) belle_sip_header_to_set_random_tag(obj);
+ else belle_sip_header_to_set_raw_tag(obj, tag);
+}
+
+const char *belle_sip_header_to_get_tag(const belle_sip_header_to_t *obj) {
+ return belle_sip_header_to_get_raw_tag(obj);
+}
+
+/**************************
+ * Diversion header object inherits from header_address
+ ***************************/
+struct _belle_sip_header_diversion {
+ belle_sip_header_address_t address;
+};
+
+static void belle_sip_header_diversion_destroy(belle_sip_header_diversion_t *diversion) {
+}
+
+void belle_sip_header_diversion_clone(belle_sip_header_diversion_t *contact, const belle_sip_header_diversion_t *orig) {
+}
+
+belle_sip_error_code belle_sip_header_diversion_marshal(belle_sip_header_diversion_t *diversion,
+ char *buff,
+ size_t buff_size,
+ size_t *offset){BELLE_SIP_FROM_LIKE_MARSHAL(diversion, FALSE)}
+
+BELLE_SIP_NEW_HEADER(header_diversion, header_address, BELLE_SIP_DIVERSION) BELLE_SIP_PARSE_FULL(header_diversion);
+GET_SET_STRING_PARAM2(belle_sip_header_diversion, tag, raw_tag);
+
+belle_sip_header_diversion_t *belle_sip_header_diversion_create2(const char *uri, const char *tag) {
+ belle_sip_header_address_t *address = belle_sip_header_address_parse(uri);
+ if (address) {
+ belle_sip_header_diversion_t *diversion = belle_sip_header_diversion_create(address, tag);
+ belle_sip_object_unref(address);
+ return diversion;
+ } else return NULL;
+}
+belle_sip_header_diversion_t *belle_sip_header_diversion_create(const belle_sip_header_address_t *address,
+ const char *tag) {
+ belle_sip_header_diversion_t *header = belle_sip_header_diversion_new();
+ belle_sip_uri_t *uri;
+ _belle_sip_object_copy((belle_sip_object_t *)header, (belle_sip_object_t *)address);
+ /*clear unwanted uri components*/
+ if ((uri = belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(header)))) {
+ belle_sip_parameters_t *params = BELLE_SIP_PARAMETERS(uri);
+ belle_sip_parameters_remove_parameter(params, "lr");
+ belle_sip_parameters_remove_parameter(params, "ttl");
+ belle_sip_parameters_remove_parameter(params, "method");
+ belle_sip_parameters_remove_parameter(params, "maddr");
+ belle_sip_parameters_remove_parameter(params, "transport");
+ belle_sip_uri_set_port(uri, 0);
+ belle_sip_uri_headers_clean(uri);
+ }
+ belle_sip_header_set_name(BELLE_SIP_HEADER(header), BELLE_SIP_DIVERSION); /*restaure header name*/
+ if (tag) belle_sip_header_diversion_set_tag(header, tag);
+ return header;
+}
+void belle_sip_header_diversion_set_random_tag(belle_sip_header_diversion_t *obj) {
+ char tmp[8];
+ /*not less than 32bit */
+ belle_sip_header_diversion_set_tag(obj, belle_sip_random_token(tmp, sizeof(tmp)));
+}
+
+void belle_sip_header_diversion_set_tag(belle_sip_header_diversion_t *obj, const char *tag) {
+ if (tag == BELLE_SIP_RANDOM_TAG) belle_sip_header_diversion_set_random_tag(obj);
+ else belle_sip_header_diversion_set_raw_tag(obj, tag);
+}
+
+const char *belle_sip_header_diversion_get_tag(const belle_sip_header_diversion_t *obj) {
+ return belle_sip_header_diversion_get_raw_tag(obj);
+}
+
+/******************************
+ * Session-Expires inherits from parameters
+ ******************************/
+struct _belle_sip_header_session_expires {
+ belle_sip_parameters_t params_list;
+ int delta;
+};
+
+static void belle_sip_header_session_expires_destroy(belle_sip_header_session_expires_t *session_expires) {
+}
+
+static void belle_sip_header_session_expires_clone(belle_sip_header_session_expires_t *session_expires,
+ const belle_sip_header_session_expires_t *orig) {
+ session_expires->delta = orig->delta;
+ belle_sip_header_session_expires_set_refresher_value(session_expires,
+ belle_sip_header_session_expires_get_refresher_value(orig));
+}
+
+belle_sip_error_code belle_sip_header_session_expires_marshal(belle_sip_header_session_expires_t *session_expires,
+ char *buff,
+ size_t buff_size,
+ size_t *offset) {
+ belle_sip_error_code error = belle_sip_header_marshal(BELLE_SIP_HEADER(session_expires), buff, buff_size, offset);
+
+ if (session_expires->delta) {
+ error = belle_sip_snprintf(buff, buff_size, offset, "%i", session_expires->delta);
+ if (error != BELLE_SIP_OK) return error;
+ }
+
+ error = belle_sip_parameters_marshal(&session_expires->params_list, buff, buff_size, offset);
+ if (error != BELLE_SIP_OK) return error;
+
+ return error;
+}
+
+belle_sip_header_session_expires_t *
+belle_sip_header_session_expires_create(int delta, belle_sip_header_session_expires_refresher_t refresher) {
+ belle_sip_header_session_expires_t *session_expires = belle_sip_header_session_expires_new();
+
+ belle_sip_header_session_expires_set_delta(session_expires, delta);
+ if (refresher != BELLE_SIP_HEADER_SESSION_EXPIRES_UNSPECIFIED) {
+ belle_sip_header_session_expires_set_refresher_value(session_expires, refresher);
+ }
+
+ return session_expires;
+}
+
+BELLE_SIP_PARSE_FULL(header_session_expires);
+BELLE_SIP_NEW_HEADER(header_session_expires, parameters, BELLE_SIP_SESSION_EXPIRES);
+GET_SET_STRING_PARAM(belle_sip_header_session_expires, refresher);
+GET_SET_INT(belle_sip_header_session_expires, delta, int);
+
+belle_sip_header_session_expires_refresher_t
+belle_sip_header_session_expires_get_refresher_value(const belle_sip_header_session_expires_t *session_expires) {
+ const char *refresher_value = belle_sip_header_session_expires_get_refresher(session_expires);
+
+ if (refresher_value == NULL) {
+ return BELLE_SIP_HEADER_SESSION_EXPIRES_UNSPECIFIED;
+ } else if (strcmp("uac", refresher_value) == 0) {
+ return BELLE_SIP_HEADER_SESSION_EXPIRES_UAC;
+ } else if (strcmp("uas", refresher_value) == 0) {
+ return BELLE_SIP_HEADER_SESSION_EXPIRES_UAS;
+ }
+
+ return BELLE_SIP_HEADER_SESSION_EXPIRES_UNSPECIFIED;
+}
+
+void belle_sip_header_session_expires_set_refresher_value(
+ belle_sip_header_session_expires_t *session_expires, belle_sip_header_session_expires_refresher_t refresher_value) {
+ switch (refresher_value) {
+ case BELLE_SIP_HEADER_SESSION_EXPIRES_UNSPECIFIED:
+ belle_sip_parameters_remove_parameter(BELLE_SIP_PARAMETERS(session_expires), "refresher");
+ break;
+ case BELLE_SIP_HEADER_SESSION_EXPIRES_UAC:
+ belle_sip_header_session_expires_set_refresher(session_expires, "uac");
+ break;
+ case BELLE_SIP_HEADER_SESSION_EXPIRES_UAS:
+ belle_sip_header_session_expires_set_refresher(session_expires, "uas");
+ break;
+ }
+}
+
+/******************************
+ * User-Agent header inherits from header
+ ******************************/
+struct _belle_sip_header_user_agent {
+ belle_sip_header_t header;
+ belle_sip_list_t *products;
+};
+
+static void belle_sip_header_user_agent_destroy(belle_sip_header_user_agent_t *user_agent) {
+ belle_sip_header_user_agent_set_products(user_agent, NULL);
+}
+
+static void belle_sip_header_user_agent_clone(belle_sip_header_user_agent_t *user_agent,
+ const belle_sip_header_user_agent_t *orig) {
+ belle_sip_list_t *list = orig->products;
+ for (; list != NULL; list = list->next) {
+ belle_sip_header_user_agent_add_product(user_agent, (const char *)list->data);
+ }
+}
+
+belle_sip_error_code belle_sip_header_user_agent_marshal(belle_sip_header_user_agent_t *user_agent,
+ char *buff,
+ size_t buff_size,
+ size_t *offset) {
+ belle_sip_error_code error = BELLE_SIP_OK;
+ belle_sip_list_t *list = user_agent->products;
+ error = belle_sip_header_marshal(BELLE_SIP_HEADER(user_agent), buff, buff_size, offset);
+ if (error != BELLE_SIP_OK) return error;
+ for (; list != NULL; list = list->next) {
+ error = belle_sip_snprintf(buff, buff_size, offset, list == user_agent->products ? "%s" : " %s",
+ (const char *)list->data);
+ if (error != BELLE_SIP_OK) return error;
+ }
+ return error;
+}
+
+BELLE_SIP_NEW_HEADER(header_user_agent, header, "User-Agent");
+BELLE_SIP_PARSE_FULL(header_user_agent);
+
+belle_sip_list_t *belle_sip_header_user_agent_get_products(const belle_sip_header_user_agent_t *user_agent) {
+ return user_agent->products;
+}
+void belle_sip_header_user_agent_set_products(belle_sip_header_user_agent_t *user_agent, belle_sip_list_t *products) {
+ belle_sip_list_t *list;
+ if (user_agent->products) {
+ for (list = user_agent->products; list != NULL; list = list->next) {
+ belle_sip_free((void *)list->data);
+ }
+ belle_sip_list_free(user_agent->products);
+ }
+ user_agent->products = products;
+}
+void belle_sip_header_user_agent_add_product(belle_sip_header_user_agent_t *user_agent, const char *product) {
+ user_agent->products = belle_sip_list_append(user_agent->products, belle_sip_strdup(product));
+}
+
+int belle_sip_header_user_agent_get_products_as_string(const belle_sip_header_user_agent_t *user_agent,
+ char *value,
+ unsigned int value_size) {
+ size_t result = 0;
+ belle_sip_error_code error = BELLE_SIP_OK;
*** 1782 LINES SKIPPED ***