diff options
author | Mamadou DIOP <bossiel@yahoo.fr> | 2015-08-17 01:56:35 +0200 |
---|---|---|
committer | Mamadou DIOP <bossiel@yahoo.fr> | 2015-08-17 01:56:35 +0200 |
commit | 631fffee8a28b1bec5ed1f1d26a20e0135967f99 (patch) | |
tree | 74afe3bf3efe15aa82bcd0272b2b0f4d48c2d837 /tinySDP | |
parent | 7908865936604036e6f200f1b5e069f8752f3a3a (diff) | |
download | doubango-631fffee8a28b1bec5ed1f1d26a20e0135967f99.zip doubango-631fffee8a28b1bec5ed1f1d26a20e0135967f99.tar.gz |
-
Diffstat (limited to 'tinySDP')
82 files changed, 15830 insertions, 0 deletions
diff --git a/tinySDP/Makefile.am b/tinySDP/Makefile.am new file mode 100644 index 0000000..30ee5be --- /dev/null +++ b/tinySDP/Makefile.am @@ -0,0 +1,46 @@ +lib_LTLIBRARIES = libtinySDP.la +libtinySDP_la_LIBADD = ../tinySAK/libtinySAK.la +libtinySDP_la_CPPFLAGS = -I../tinySAK/src -Iinclude + +libtinySDP_la_SOURCES = \ + src/tsdp.c\ + src/tsdp_message.c + +libtinySDP_la_SOURCES += src/headers/tsdp_header.c\ + src/headers/tsdp_header_A.c\ + src/headers/tsdp_header_B.c\ + src/headers/tsdp_header_C.c\ + src/headers/tsdp_header_Dummy.c\ + src/headers/tsdp_header_E.c\ + src/headers/tsdp_header_I.c\ + src/headers/tsdp_header_K.c\ + src/headers/tsdp_header_M.c\ + src/headers/tsdp_header_O.c\ + src/headers/tsdp_header_P.c\ + src/headers/tsdp_header_R.c\ + src/headers/tsdp_header_S.c\ + src/headers/tsdp_header_T.c\ + src/headers/tsdp_header_U.c\ + src/headers/tsdp_header_V.c\ + src/headers/tsdp_header_Z.c + +libtinySDP_la_SOURCES += src/parsers/tsdp_parser_message.c + + +libtinySDP_la_LDFLAGS = $LDFLAGS -no-undefined +if TARGET_OS_IS_ANDROID +libtinySDP_la_LDFLAGS += -static +endif + + +_includedir = $(includedir)/tinysdp +_include_HEADERS = include/*.h +__includedir = $(includedir)/tinysdp/tinysdp +__include_HEADERS = include/tinysdp/*.h +headers_includedir = $(includedir)/tinysdp/tinysdp/headers +headers_include_HEADERS = include/tinysdp/headers/*.h +parsers_includedir = $(includedir)/tinysdp/tinysdp/parsers +parsers_include_HEADERS = include/tinysdp/parsers/*.h + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = tinySDP.pc
\ No newline at end of file diff --git a/tinySDP/abnf/sdp.abnf b/tinySDP/abnf/sdp.abnf new file mode 100644 index 0000000..b92992b --- /dev/null +++ b/tinySDP/abnf/sdp.abnf @@ -0,0 +1,42 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; RFC 5234 - ABNF CORE RULES +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +OCTET= %x00-FF ; 8 bits of data +CHAR= %x01-7F ; any 7-bit US-ASCII character, excluding NUL +VCHAR= %x21-7E ; visible (printing) characters +ALPHA= %x41-5A / %x61-7A ; A-Z / a-z +DIGIT= %x30-39 ; 0-9 + +CTL= %x00-1F / %x7F ; any US-ASCII control character: ; (octets 0 - 31) and DEL (127) + +HTAB= %x09 ; horizontal tab +LF= %x0A ; linefeed +CR= %x0D ; carriage return +SP= %x20 ; space +DQUOTE= %x22 ; " (Double Quote) +BIT= "0" / "1" + +HEXDIG= DIGIT / "A" / "B" / "C" / "D" / "E" / "F" + +CRLF= CR LF ; Internet standard newline +WSP= SP / HTAB ; white space +LWSP= *(WSP / CRLF WSP) ; linear white space (past newline) +;--------------------------------------------------------------------------------------------------------- + + + + + + + + + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; RFC 4566 - SDP ABNF +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/tinySDP/docs_soa/soa.VSD b/tinySDP/docs_soa/soa.VSD Binary files differnew file mode 100644 index 0000000..bd36e6d --- /dev/null +++ b/tinySDP/docs_soa/soa.VSD diff --git a/tinySDP/docs_soa/soa.doc b/tinySDP/docs_soa/soa.doc Binary files differnew file mode 100644 index 0000000..eeea1eb --- /dev/null +++ b/tinySDP/docs_soa/soa.doc diff --git a/tinySDP/droid-makefile b/tinySDP/droid-makefile new file mode 100644 index 0000000..f969ebe --- /dev/null +++ b/tinySDP/droid-makefile @@ -0,0 +1,49 @@ +APP := lib$(PROJECT)_$(MARCH).$(EXT) + +CFLAGS := $(CFLAGS_LIB) -I../tinySAK/src -I./include +LDFLAGS := $(LDFLAGS_LIB) -ltinySAK_$(MARCH) + +all: $(APP) + +OBJS = \ + src/tsdp.o\ + src/tsdp_message.o + ### heasers +OBJS += src/headers/tsdp_header.o\ + src/headers/tsdp_header_A.o\ + src/headers/tsdp_header_B.o\ + src/headers/tsdp_header_C.o\ + src/headers/tsdp_header_Dummy.o\ + src/headers/tsdp_header_E.o\ + src/headers/tsdp_header_I.o\ + src/headers/tsdp_header_K.o\ + src/headers/tsdp_header_M.o\ + src/headers/tsdp_header_O.o\ + src/headers/tsdp_header_P.o\ + src/headers/tsdp_header_R.o\ + src/headers/tsdp_header_S.o\ + src/headers/tsdp_header_T.o\ + src/headers/tsdp_header_U.o\ + src/headers/tsdp_header_V.o\ + src/headers/tsdp_header_Z.o + ### parsers +OBJS += src/parsers/tsdp_parser_message.o + + +$(APP): $(OBJS) +ifeq ($(EXT), a) + $(AR) rcs $@ $^ +else + $(CC) $(LDFLAGS) -o $@ $^ +endif + +%.o: %.c + $(CC) -c $(INCLUDE) $(CFLAGS) $< -o $@ + +install: $(APP) + $(ANDROID_SDK_ROOT)/tools/adb remount + $(ANDROID_SDK_ROOT)/tools/adb push $(APP) $(LIB_DIR)/$(APP) + $(ANDROID_SDK_ROOT)/tools/adb shell chmod 777 $(LIB_DIR)/$(APP) + +clean: + @rm -f $(OBJS) $(APP)
\ No newline at end of file diff --git a/tinySDP/include/tinysdp.h b/tinySDP/include/tinysdp.h new file mode 100644 index 0000000..96883de --- /dev/null +++ b/tinySDP/include/tinysdp.h @@ -0,0 +1,53 @@ +/* +* Copyright (C) 2009 Mamadou Diop. +* +* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org> +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ +/**@file tinysdp.h + * @brief SDP API functions. + * + * @author Mamadou Diop <diopmamadou(at)doubango[dot]org> + * + + */ +#ifndef TINYSDP_TINYSDP_H +#define TINYSDP_TINYSDP_H + +#include "tinysdp/tsdp_message.h" +#include "tinysdp/parsers/tsdp_parser_message.h" + +#include "tinysdp/headers/tsdp_header_A.h" +#include "tinysdp/headers/tsdp_header_B.h" +#include "tinysdp/headers/tsdp_header_C.h" +#include "tinysdp/headers/tsdp_header_Dummy.h" +#include "tinysdp/headers/tsdp_header_E.h" +#include "tinysdp/headers/tsdp_header_I.h" +#include "tinysdp/headers/tsdp_header_K.h" +#include "tinysdp/headers/tsdp_header_M.h" +#include "tinysdp/headers/tsdp_header_O.h" +#include "tinysdp/headers/tsdp_header_P.h" +#include "tinysdp/headers/tsdp_header_R.h" +#include "tinysdp/headers/tsdp_header_S.h" +#include "tinysdp/headers/tsdp_header_T.h" +#include "tinysdp/headers/tsdp_header_U.h" +#include "tinysdp/headers/tsdp_header_V.h" +#include "tinysdp/headers/tsdp_header_Z.h" + +#endif /* TINYSDP_TINYSDP_H */ + diff --git a/tinySDP/include/tinysdp/headers/tsdp_header.h b/tinySDP/include/tinysdp/headers/tsdp_header.h new file mode 100644 index 0000000..ce669b5 --- /dev/null +++ b/tinySDP/include/tinysdp/headers/tsdp_header.h @@ -0,0 +1,124 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org> +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_header.h + * @brief Defines a SDP header/line (<type>=<value>). + * + * @author Mamadou Diop <diopmamadou(at)doubango[dot]org> + * + + */ +#ifndef TINYSDP_HEADER_H +#define TINYSDP_HEADER_H + +#include "tinysdp_config.h" + +#include "tsk_ragel_state.h" +#include "tsk_list.h" + +TSDP_BEGIN_DECLS + +struct tsdp_header_s; + +#define TSDP_HEADER(self) ((tsdp_header_t*)(self)) +#define TSDP_HEADER_CONST(self) ((const tsdp_header_t*)(self)) +#define TSDP_HEADER_VALUE_TOSTRING_F(self) ((tsdp_header_value_tostring_f)(self)) + +typedef int (*tsdp_header_value_tostring_f)(const struct tsdp_header_s* header, tsk_buffer_t* output); +typedef struct tsdp_header_s* (*tsdp_header_clone_f)(const struct tsdp_header_s* header); + +#define TSDP_HTYPE_V_RANK 0 +#define TSDP_HTYPE_O_RANK 1 +#define TSDP_HTYPE_S_RANK 2 +#define TSDP_HTYPE_I_RANK 3 +#define TSDP_HTYPE_U_RANK 4 +#define TSDP_HTYPE_E_RANK 5 +#define TSDP_HTYPE_P_RANK 6 +#define TSDP_HTYPE_C_RANK 7 +#define TSDP_HTYPE_B_RANK 8 +#define TSDP_HTYPE_Z_RANK 11 +#define TSDP_HTYPE_K_RANK 12 +#define TSDP_HTYPE_A_RANK 13 +#define TSDP_HTYPE_T_RANK 9 +#define TSDP_HTYPE_R_RANK 10 +#define TSDP_HTYPE_M_RANK 14 +//#define TSDP_HTYPE_I_RANK 15 +//#define TSDP_HTYPE_C_RANK 16 +//#define TSDP_HTYPE_B_RANK 17 + +#define TSDP_HTYPE_DUMMY_RANK 255 + +/** + * @enum tsdp_header_type_e + * + * @brief List of all supported headers. +**/ +typedef enum tsdp_header_type_e +{ + tsdp_htype_A, + tsdp_htype_B, + tsdp_htype_C, + tsdp_htype_Dummy, + tsdp_htype_E, + tsdp_htype_I, + tsdp_htype_K, + tsdp_htype_M, + tsdp_htype_O, + tsdp_htype_P, + tsdp_htype_R, + tsdp_htype_S, + tsdp_htype_T, + tsdp_htype_U, + tsdp_htype_V, + tsdp_htype_Z +} +tsdp_header_type_t; + +/*================================ +*/ +typedef struct tsdp_header_s +{ + TSK_DECLARE_OBJECT; + tsdp_header_type_t type; + //! Because all SDP headers shall appear in a fixed order, the rank is used to place each header. + // Info: RFC 4566 - 5. SDP Specification. + uint8_t rank; + tsdp_header_value_tostring_f tostring; + tsdp_header_clone_f clone; +} +tsdp_header_t; + +#define TSDP_DECLARE_HEADER tsdp_header_t __header__ +typedef tsk_list_t tsdp_headers_L_t; /**< List of @ref tsdp_header_t elements. */ +/* +================================*/ + +int tsdp_header_rank_cmp(const tsdp_header_t*, const tsdp_header_t*); +TINYSDP_API tsdp_header_t* tsdp_header_clone(const tsdp_header_t*); +TINYSDP_API char tsdp_header_get_name(tsdp_header_type_t type); +TINYSDP_API char tsdp_header_get_nameex(const tsdp_header_t *self); +TINYSDP_API int tsdp_header_serialize(const tsdp_header_t *self, tsk_buffer_t *output); +TINYSDP_API char* tsdp_header_tostring(const tsdp_header_t *self); + +TSDP_END_DECLS + +#endif /* TINYSDP_HEADER_H */ diff --git a/tinySDP/include/tinysdp/headers/tsdp_header_A.h b/tinySDP/include/tinysdp/headers/tsdp_header_A.h new file mode 100644 index 0000000..04aff7f --- /dev/null +++ b/tinySDP/include/tinysdp/headers/tsdp_header_A.h @@ -0,0 +1,76 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org> +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_header_A.h + * @brief SDP "a=" header (Attributes). + * + * @author Mamadou Diop <diopmamadou(at)doubango[dot]org> + * + * + */ +#ifndef _TSDP_HEADER_A_H_ +#define _TSDP_HEADER_A_H_ + +#include "tinysdp_config.h" +#include "tinysdp/headers/tsdp_header.h" + +TSDP_BEGIN_DECLS + +#define TSDP_HEADER_A_VA_ARGS(field, value) tsdp_header_A_def_t, (const char*)(field), (const char*)(value) + +#define TSDP_HEADER_A(self) ((tsdp_header_A_t*)(self)) + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/// @struct +/// +/// @brief SDP "a=" header (Attributes). +/// +/// @par ABNF : a=attribute +/// attribute = (att-field ":" att-value) / att-field +/// att-field = token +/// att-value = byte-string +/// +//////////////////////////////////////////////////////////////////////////////////////////////////// +typedef struct tsdp_header_A_s +{ + TSDP_DECLARE_HEADER; + + char* field; + char* value; +} +tsdp_header_A_t; + +typedef tsk_list_t tsdp_headers_A_L_t; + +TINYSDP_API tsdp_header_A_t* tsdp_header_A_create(const char* field, const char* value); +TINYSDP_API tsdp_header_A_t* tsdp_header_A_create_null(); + +TINYSDP_API tsdp_header_A_t *tsdp_header_A_parse(const char *data, tsk_size_t size); +TINYSDP_API int tsdp_header_A_removeAll_by_field(tsdp_headers_A_L_t *attributes, const char* field); +TINYSDP_API int tsdp_header_A_removeAll_by_fields(tsdp_headers_A_L_t *attributes, const char** fields, tsk_size_t fields_count); + +TINYSDP_GEXTERN const tsk_object_def_t *tsdp_header_A_def_t; + +TSDP_END_DECLS + +#endif /* _TSDP_HEADER_A_H_ */ + diff --git a/tinySDP/include/tinysdp/headers/tsdp_header_B.h b/tinySDP/include/tinysdp/headers/tsdp_header_B.h new file mode 100644 index 0000000..360d3d7 --- /dev/null +++ b/tinySDP/include/tinysdp/headers/tsdp_header_B.h @@ -0,0 +1,72 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org> +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_header_B.h + * @brief SDP "b=" header (Bandwidth). + * + * @author Mamadou Diop <diopmamadou(at)doubango[dot]org> + * + * + */ +#ifndef _TSDP_HEADER_B_H_ +#define _TSDP_HEADER_B_H_ + +#include "tinysdp_config.h" +#include "tinysdp/headers/tsdp_header.h" + +TSDP_BEGIN_DECLS + + +#define TSDP_HEADER_B_VA_ARGS(bwtype, bandwidth) tsdp_header_B_def_t, (const char*)bwtype, (uint32_t)bandwidth + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/// @struct +/// +/// @brief SDP "b=" header (Bandwidth). +/// +/// @par ABNF : b=<bwtype> HCOLON <bandwidth> +/// bwtype = token +/// bandwidth = 1*DIGIT +/// +//////////////////////////////////////////////////////////////////////////////////////////////////// +typedef struct tsdp_header_B_s +{ + TSDP_DECLARE_HEADER; + + char* bwtype; + uint32_t bandwidth; +} +tsdp_header_B_t; + +typedef tsk_list_t tsdp_headers_B_L_t; + +TINYSDP_API tsdp_header_B_t* tsdp_header_B_create(const char* bwtype, uint32_t bandwidth); +TINYSDP_API tsdp_header_B_t* tsdp_header_b_create_null(); + +TINYSDP_API tsdp_header_B_t *tsdp_header_B_parse(const char *data, tsk_size_t size); + +TINYSDP_GEXTERN const tsk_object_def_t *tsdp_header_B_def_t; + +TSDP_END_DECLS + +#endif /* _TSDP_HEADER_B_H_ */ + diff --git a/tinySDP/include/tinysdp/headers/tsdp_header_C.h b/tinySDP/include/tinysdp/headers/tsdp_header_C.h new file mode 100644 index 0000000..e5c5399 --- /dev/null +++ b/tinySDP/include/tinysdp/headers/tsdp_header_C.h @@ -0,0 +1,76 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org> +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_header_C.h + * @brief SDP "c=" header (Connection Data). + * + * @author Mamadou Diop <diopmamadou(at)doubango[dot]org> + * + * + */ +#ifndef _TSDP_HEADER_C_H_ +#define _TSDP_HEADER_C_H_ + +#include "tinysdp_config.h" +#include "tinysdp/headers/tsdp_header.h" + +TSDP_BEGIN_DECLS + +#define TSDP_HEADER_C_VA_ARGS(nettype, addrtype, addr) tsdp_header_C_def_t, (const char*)(nettype), (const char*)(addrtype), (const char*)(addr) + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/// @struct +/// +/// @brief SDP "c=" header (Connection Data). +/// A session description MUST contain either at least one "c=" field in +/// each media description or a single "c=" field at the session level. +/// It MAY contain a single session-level "c=" field and additional "c=" +/// field(s) per media description, in which case the per-media values +/// override the session-level settings for the respective media. +/// +/// +/// +/// @par ABNF : c= nettype SP addrtype SP connection-address +/// +//////////////////////////////////////////////////////////////////////////////////////////////////// +typedef struct tsdp_header_C_s +{ + TSDP_DECLARE_HEADER; + char* nettype; + char* addrtype; + char* addr; +} +tsdp_header_C_t; + +typedef tsk_list_t tsdp_headers_C_L_t; + +TINYSDP_API tsdp_header_C_t* tsdp_header_c_create(const char* nettype, const char* addrtype, const char* addr); +TINYSDP_API tsdp_header_C_t* tsdp_header_c_create_null(); + +TINYSDP_API tsdp_header_C_t *tsdp_header_C_parse(const char *data, tsk_size_t size); + +TINYSDP_GEXTERN const tsk_object_def_t *tsdp_header_C_def_t; + +TSDP_END_DECLS + +#endif /* _TSDP_HEADER_C_H_ */ + diff --git a/tinySDP/include/tinysdp/headers/tsdp_header_Dummy.h b/tinySDP/include/tinysdp/headers/tsdp_header_Dummy.h new file mode 100644 index 0000000..e9ec9b5 --- /dev/null +++ b/tinySDP/include/tinysdp/headers/tsdp_header_Dummy.h @@ -0,0 +1,68 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org> +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_header_Dummy.h + * @brief SDP dummy header. + * + * @author Mamadou Diop <diopmamadou(at)doubango[dot]org> + * + + */ +#ifndef _TSDP_HEADER_DUMMY_H_ +#define _TSDP_HEADER_DUMMY_H_ + +#include "tinysdp_config.h" +#include "tinysdp/headers/tsdp_header.h" + +TSDP_BEGIN_DECLS + +#define TSDP_HEADER_DUMMY_VA_ARGS(name, value) tsdp_header_Dummy_def_t, (char)name, (const char*)value + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/// @struct +/// +/// @brief SDP Dummy header. +/// +/// @par ABNF : alpha SP* "=" SP*<: any* +/// +//////////////////////////////////////////////////////////////////////////////////////////////////// +typedef struct tsdp_header_Dummy_s +{ + TSDP_DECLARE_HEADER; + char name; + char *value; +} +tsdp_header_Dummy_t; + +typedef tsk_list_t tsdp_headers_Dummy_L_t; + +TINYSDP_API tsdp_header_Dummy_t* tsdp_header_dummy_create(char name, const char* value); +TINYSDP_API tsdp_header_Dummy_t* tsdp_header_dummy_create_null(); + +TINYSDP_API tsdp_header_Dummy_t *tsdp_header_Dummy_parse(const char *data, tsk_size_t size); + +TINYSDP_GEXTERN const tsk_object_def_t *tsdp_header_Dummy_def_t; + +TSDP_END_DECLS + +#endif /* _TSDP_HEADER_DUMMY_H_ */ + diff --git a/tinySDP/include/tinysdp/headers/tsdp_header_E.h b/tinySDP/include/tinysdp/headers/tsdp_header_E.h new file mode 100644 index 0000000..a024b6a --- /dev/null +++ b/tinySDP/include/tinysdp/headers/tsdp_header_E.h @@ -0,0 +1,71 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org> +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_header_E.h + * @brief SDP "e=" header (Email Address). + * + * @author Mamadou Diop <diopmamadou(at)doubango[dot]org> + * + * + */ +#ifndef _TSDP_HEADER_E_H_ +#define _TSDP_HEADER_E_H_ + +#include "tinysdp_config.h" +#include "tinysdp/headers/tsdp_header.h" + +TSDP_BEGIN_DECLS + +#define TSDP_HEADER_E_VA_ARGS(value) tsdp_header_E_def_t, (const char*)value + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/// @struct +/// +/// @brief SDP "e=" header (Email Address). +/// +/// The "e=" line specifies contact information for the person +/// responsible for the conference. This is not necessarily the same +/// person that created the conference announcement. +/// +/// @par ABNF : e= email-address +/// +//////////////////////////////////////////////////////////////////////////////////////////////////// +typedef struct tsdp_header_E_s +{ + TSDP_DECLARE_HEADER; + char* value; +} +tsdp_header_E_t; + +typedef tsk_list_t tsdp_headers_E_L_t; + +TINYSDP_API tsdp_header_E_t* tsdp_header_E_create(const char* value); +TINYSDP_API tsdp_header_E_t* tsdp_header_E_create_null(); + +TINYSDP_API tsdp_header_E_t *tsdp_header_E_parse(const char *data, tsk_size_t size); + +TINYSDP_GEXTERN const tsk_object_def_t *tsdp_header_E_def_t; + +TSDP_END_DECLS + +#endif /* _TSDP_HEADER_E_H_ */ + diff --git a/tinySDP/include/tinysdp/headers/tsdp_header_I.h b/tinySDP/include/tinysdp/headers/tsdp_header_I.h new file mode 100644 index 0000000..5f5d4fd --- /dev/null +++ b/tinySDP/include/tinysdp/headers/tsdp_header_I.h @@ -0,0 +1,67 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org> +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_header_I.h + * @brief SDP "i=" header (Session Information). + * + * @author Mamadou Diop <diopmamadou(at)doubango[dot]org> + * + * + */ +#ifndef _TSDP_HEADER_I_H_ +#define _TSDP_HEADER_I_H_ + +#include "tinysdp_config.h" +#include "tinysdp/headers/tsdp_header.h" + +TSDP_BEGIN_DECLS + +#define TSDP_HEADER_I_VA_ARGS(value) tsdp_header_I_def_t, (const char*)value + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/// @struct +/// +/// @brief SDP "i=" header (Session Information). +/// +/// @par ABNF : i=text +/// +//////////////////////////////////////////////////////////////////////////////////////////////////// +typedef struct tsdp_header_I_s +{ + TSDP_DECLARE_HEADER; + char* value; +} +tsdp_header_I_t; + +typedef tsk_list_t tsdp_headers_I_L_t; + +TINYSDP_API tsdp_header_I_t* tsdp_header_I_create(const char* value); +TINYSDP_API tsdp_header_I_t* tsdp_header_I_create_null(); + +TINYSDP_API tsdp_header_I_t *tsdp_header_I_parse(const char *data, tsk_size_t size); + +TINYSDP_GEXTERN const tsk_object_def_t *tsdp_header_I_def_t; + +TSDP_END_DECLS + +#endif /* _TSDP_HEADER_I_H_ */ + diff --git a/tinySDP/include/tinysdp/headers/tsdp_header_K.h b/tinySDP/include/tinysdp/headers/tsdp_header_K.h new file mode 100644 index 0000000..5ca090f --- /dev/null +++ b/tinySDP/include/tinysdp/headers/tsdp_header_K.h @@ -0,0 +1,73 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org> +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_header_K.h + * @brief SDP "k=" header (Encryption Key). + * + * @author Mamadou Diop <diopmamadou(at)doubango[dot]org> + * + * + */ +#ifndef _TSDP_HEADER_K_H_ +#define _TSDP_HEADER_K_H_ + +#include "tinysdp_config.h" +#include "tinysdp/headers/tsdp_header.h" + +TSDP_BEGIN_DECLS + +#define TSDP_HEADER_K_VA_ARGS(value) tsdp_header_K_def_t, (const char*)value + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/// @struct +/// +/// @brief SDP "k=" header (Encryption Key). +/// +/// +/// @par ABNF : k= key-type +/// key-type = "prompt" / "clear:" text / "base64:" base64 / "uri:" uri +/// base64 = *base64-unit [base64-pad] +/// base64-unit = 4base64-char +/// base64-pad = 2base64-char "==" / 3base64-pad "=" +/// base64-char = ALPHA / DIGIT / "+" / "/" +/// +//////////////////////////////////////////////////////////////////////////////////////////////////// +typedef struct tsdp_header_K_s +{ + TSDP_DECLARE_HEADER; + char* value; +} +tsdp_header_K_t; + +typedef tsk_list_t tsdp_headers_K_L_t; + +TINYSDP_API tsdp_header_K_t* tsdp_header_K_create(const char* value); +TINYSDP_API tsdp_header_K_t* tsdp_header_K_create_null(); + +tsdp_header_K_t *tsdp_header_K_parse(const char *data, tsk_size_t size); + +TINYSDP_GEXTERN const tsk_object_def_t *tsdp_header_K_def_t; + +TSDP_END_DECLS + +#endif /* _TSDP_HEADER_P_H_ */ + diff --git a/tinySDP/include/tinysdp/headers/tsdp_header_M.h b/tinySDP/include/tinysdp/headers/tsdp_header_M.h new file mode 100644 index 0000000..fad13b0 --- /dev/null +++ b/tinySDP/include/tinysdp/headers/tsdp_header_M.h @@ -0,0 +1,149 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org> +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_header_M.h + * @brief SDP "m=" header (Media Descriptions). + * + * @author Mamadou Diop <diopmamadou(at)doubango[dot]org> + * + * + */ +#ifndef _TSDP_HEADER_M_H_ +#define _TSDP_HEADER_M_H_ + +#include "tinysdp_config.h" +#include "tinysdp/headers/tsdp_header.h" + +#include "tinysdp/headers/tsdp_header_A.h" +#include "tinysdp/headers/tsdp_header_B.h" +#include "tinysdp/headers/tsdp_header_C.h" +#include "tinysdp/headers/tsdp_header_I.h" +#include "tinysdp/headers/tsdp_header_K.h" + +#include "tsk_string.h" + +TSDP_BEGIN_DECLS + +#define TSDP_HEADER_M_VA_ARGS(media, port, proto) tsdp_header_M_def_t, (const char*)media, (uint32_t)port, (const char*)proto + +#define TSDP_HEADER_M(self) ((tsdp_header_M_t*)(self)) + +#define TSDP_FMT_VA_ARGS(fmt) tsdp_fmt_def_t, (const char*)fmt + +typedef tsk_string_t tsdp_fmt_t; +typedef tsk_strings_L_t tsk_fmts_L_t; +#define tsdp_fmt_def_t tsk_string_def_t +#define TSDP_FMT_STR(self) TSK_STRING_STR(self) + +TINYSDP_API tsdp_fmt_t* tsdp_fmt_create(const char* fmt); + +//#define TSDP_HEADER_M_SET_FMT(fmt) (int)0x01, (const char*)fmt +//#define TSDP_HEADER_M_SET_A(field, value) (int)0x02, (const char*)field, (const char*)value +//#define TSDP_HEADER_M_SET_NULL() (int)0x00 + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/// @struct +/// +/// @brief SDP "m=" header (Media Descriptions). +/// +/// @par ABNF : m=*(media-field +/// information-field +/// *connection-field +/// bandwidth-fields +/// key-field +/// attribute-fields) +/// +/// media-field = %x6d "=" media SP port ["/" integer] SP proto 1*(SP fmt) CRLF +/// media = token +/// port = 1*DIGIT +/// proto = token *("/" token) +/// fmt = token +/// +//////////////////////////////////////////////////////////////////////////////////////////////////// +typedef struct tsdp_header_M_s +{ + TSDP_DECLARE_HEADER; + + char* media; + uint32_t port; + uint32_t nports; /**< <number of ports> */ + char* proto; + tsk_fmts_L_t* FMTs; + + // Fields below will be set by the message parser. + tsdp_header_I_t* I; + tsdp_header_C_t* C; + tsdp_headers_B_L_t* Bandwidths; // (zero or more bandwidth information lines) + tsdp_header_K_t* K; // (encryption key) + tsdp_headers_A_L_t* Attributes; // (zero or more media attribute lines) +} +tsdp_header_M_t; + +typedef enum tsdp_header_M_diff_e { + tsdp_header_M_diff_none = 0x0000000, + tsdp_header_M_diff_hold_resume = (0x0000001 << 0), + tsdp_header_M_diff_index = (0x0000001 << 1), + tsdp_header_M_diff_codecs = (0x0000001 << 2), + tsdp_header_M_diff_network_info = (0x0000001 << 3), + tsdp_header_M_diff_ice_enabled = (0x0000001 << 4), + tsdp_header_M_diff_ice_restart = (0x0000001 << 5), + tsdp_header_M_diff_dtls_fingerprint = (0x0000001 << 6), + tsdp_header_M_diff_sdes_crypto = (0x0000001 << 7), + tsdp_header_M_diff_media_type = (0x0000001 << 8), + tsdp_header_M_diff_all = 0xFFFFFFFF +} +tsdp_header_M_diff_t; + +typedef tsk_list_t tsdp_headers_M_L_t; + +TINYSDP_API tsdp_header_M_t* tsdp_header_M_create(const char* media, uint32_t port, const char* proto); +TINYSDP_API tsdp_header_M_t* tsdp_header_M_create_null(); + +TINYSDP_API tsdp_header_M_t *tsdp_header_M_parse(const char *data, tsk_size_t size); +TINYSDP_API int tsdp_header_M_remove(tsdp_header_M_t* self, tsdp_header_type_t type); +TINYSDP_API int tsdp_header_M_add(tsdp_header_M_t* self, const tsdp_header_t* header); +TINYSDP_API int tsdp_header_M_add_headers(tsdp_header_M_t* self, ...); +TINYSDP_API int tsdp_header_M_add_headers_2(tsdp_header_M_t* self, const tsdp_headers_L_t* headers); +TINYSDP_API int tsdp_header_M_add_fmt(tsdp_header_M_t* self, const char* fmt); +TINYSDP_API int tsdp_header_M_remove_fmt(tsdp_header_M_t* self, const char* fmt); +TINYSDP_API tsk_bool_t tsdp_header_M_have_fmt(const tsdp_header_M_t* self, const char* fmt); +TINYSDP_API const tsdp_header_A_t* tsdp_header_M_findA_at(const tsdp_header_M_t* self, const char* field, tsk_size_t index); +TINYSDP_API const tsdp_header_A_t* tsdp_header_M_findA(const tsdp_header_M_t* self, const char* field); +TINYSDP_API char* tsdp_header_M_getAValue(const tsdp_header_M_t* self, const char* field, const char* fmt); +#define tsdp_header_M_get_rtpmap(self, fmt) tsdp_header_M_getAValue((self), "rtpmap", (fmt)) +#define tsdp_header_M_get_fmtp(self, fmt) tsdp_header_M_getAValue((self), "fmtp", (fmt)) +#define tsdp_header_M_get_imageattr(self, fmt) tsdp_header_M_getAValue((self), "imageattr", (fmt)) +TINYSDP_API int tsdp_header_M_hold(tsdp_header_M_t* self, tsk_bool_t local); +TINYSDP_API tsk_bool_t tsdp_header_M_is_held(const tsdp_header_M_t* self, tsk_bool_t local); +TINYSDP_API int tsdp_header_M_set_holdresume_att(tsdp_header_M_t* self, tsk_bool_t lo_held, tsk_bool_t ro_held); +TINYSDP_API const char* tsdp_header_M_get_holdresume_att(const tsdp_header_M_t* self); +TINYSDP_API int tsdp_header_M_resume(tsdp_header_M_t* self, tsk_bool_t local); +TINYSDP_API tsk_bool_t tsdp_header_M_is_ice_enabled(const tsdp_header_M_t* self); +TINYSDP_API tsk_bool_t tsdp_header_M_is_ice_restart(const tsdp_header_M_t* self); +TINYSDP_API int tsdp_header_M_diff(const tsdp_header_M_t* M_old, const tsdp_header_M_t* M_new, tsdp_header_M_diff_t* diff); + +TINYSDP_GEXTERN const tsk_object_def_t *tsdp_header_M_def_t; + +TSDP_END_DECLS + +#endif /* _TSDP_HEADER_M_H_ */ + diff --git a/tinySDP/include/tinysdp/headers/tsdp_header_O.h b/tinySDP/include/tinysdp/headers/tsdp_header_O.h new file mode 100644 index 0000000..20a1994 --- /dev/null +++ b/tinySDP/include/tinysdp/headers/tsdp_header_O.h @@ -0,0 +1,119 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org> +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_header_O.h + * @brief SDP "o=" header (Origin). + * + * @author Mamadou Diop <diopmamadou(at)doubango[dot]org> + * + * @date Created: Oat Nov 8 16:54:58 2009 mdiop + */ +#ifndef _TSDP_HEADER_O_H_ +#define _TSDP_HEADER_O_H_ + +#include "tinysdp_config.h" +#include "tinysdp/headers/tsdp_header.h" + +TSDP_BEGIN_DECLS + + +#define TSDP_HEADER_O_VA_ARGS(username, sess_id, sess_version, nettype, addrtype, addr) tsdp_header_O_def_t, (const char*)username, (uint32_t)sess_id, (uint32_t)sess_version, (const char*)nettype, (const char*)addrtype, (const char*)addr +#define TSDP_HEADER_O_VA_ARGS_DEFAULT(username, nettype, addrtype, addr) TSDP_HEADER_O_VA_ARGS(username, TSDP_HEADER_O_SESS_ID_DEFAULT, TSDP_HEADER_O_SESS_VERSION_DEFAULT, nettype, addrtype, addr) + +#define TSDP_HEADER_O_SESS_ID_DEFAULT 123456 +#define TSDP_HEADER_O_SESS_VERSION_DEFAULT 678901 + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/// @struct +/// +/// @brief SDP "o=" header (Origin). +/// The "o=" field gives the originator of the session (her username and +/// the address of the user's host) plus a session identifier and version number. +/// +/// @par ABNF : u=username SP +/// sess-id SP sess-version SP nettype SP addrtype SP unicast-address +/// +/// username = non-ws-string +/// sess-id = 1*DIGIT +/// sess-version = 1*DIGIT +/// nettype = token +/// addrtype = token +/// unicast-address = FQDN +/// +//////////////////////////////////////////////////////////////////////////////////////////////////// +typedef struct tsdp_header_O_s +{ + TSDP_DECLARE_HEADER; + + /** <username> is the user's login on the originating host, or it is "-" + if the originating host does not support the concept of user IDs. + The <username> MUST NOT contain spaces.*/ + char* username; + /** <sess-id>, <nettype>, <addrtype>, and <unicast-address> forms a + globally unique identifier for the session. The method of + <sess-id> allocation is up to the creating tool, but it has been + suggested that a Network Time Protocol (NTP) format timestamp be + used to ensure uniqueness*/ + uint32_t sess_id; + /** <sess-version> is a version number for this session description. Its + usage is up to the creating tool, so long as <sess-version> is + increased when a modification is made to the session data. Again, + it is RECOMMENDED that an NTP format timestamp is used.*/ + uint32_t sess_version; + /** <nettype> is a text string giving the type of network. Initially + "IN" is defined to have the meaning "Internet", but other values + MAY be registered in the future (see Section 8 of RFC 4566)*/ + char* nettype; + /**<addrtype> is a text string giving the type of the address that + follows. Initially "IP4" and "IP6" are defined, but other values + MAY be registered in the future (see Section 8 of RFC 4566)*/ + char* addrtype; + /** <unicast-address> is the address of the machine from which the + session was created. For an address type of IP4, this is either + the fully qualified domain name of the machine or the dotted- + decimal representation of the IP version 4 address of the machine. + For an address type of IP6, this is either the fully qualified + domain name of the machine or the compressed textual + representation of the IP version 6 address of the machine. For + both IP4 and IP6, the fully qualified domain name is the form that + SHOULD be given unless this is unavailable, in which case the + globally unique address MAY be substituted. A local IP address + MUST NOT be used in any context where the SDP description might + leave the scope in which the address is meaningful (for example, a + local address MUST NOT be included in an application-level + referral that might leave the scope)*/ + char* addr; +} +tsdp_header_O_t; + +TINYSDP_API tsdp_header_O_t* tsdp_header_O_create(const char* username, uint32_t sess_id, uint32_t sess_version, const char* nettype, const char* addrtype, const char* addr); +TINYSDP_API tsdp_header_O_t* tsdp_header_O_create_null(); +TINYSDP_API tsdp_header_O_t* tsdp_header_O_create_default(const char* username, const char* nettype, const char* addrtype, const char* addr); + +TINYSDP_API tsdp_header_O_t *tsdp_header_O_parse(const char *data, tsk_size_t size); + +TINYSDP_GEXTERN const tsk_object_def_t *tsdp_header_O_def_t; + +TSDP_END_DECLS + +#endif /* _TSDP_HEADER_O_H_ */ + diff --git a/tinySDP/include/tinysdp/headers/tsdp_header_P.h b/tinySDP/include/tinysdp/headers/tsdp_header_P.h new file mode 100644 index 0000000..ca73886 --- /dev/null +++ b/tinySDP/include/tinysdp/headers/tsdp_header_P.h @@ -0,0 +1,71 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org> +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_header_P.h + * @brief SDP "p=" header (Phone Number). + * + * @author Mamadou Diop <diopmamadou(at)doubango[dot]org> + * + * + */ +#ifndef _TSDP_HEADER_P_H_ +#define _TSDP_HEADER_P_H_ + +#include "tinysdp_config.h" +#include "tinysdp/headers/tsdp_header.h" + +TSDP_BEGIN_DECLS + +#define TSDP_HEADER_P_VA_ARGS(value) tsdp_header_P_def_t, (const char*)value + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/// @struct +/// +/// @brief SDP "p=" header (Phone Number). +/// The "p=" line specifies contact information for the person +/// responsible for the conference. This is not necessarily the same +/// person that created the conference announcement. +/// +/// +/// @par ABNF : p= phone-number +/// +//////////////////////////////////////////////////////////////////////////////////////////////////// +typedef struct tsdp_header_P_s +{ + TSDP_DECLARE_HEADER; + char* value; +} +tsdp_header_P_t; + +typedef tsk_list_t tsdp_headers_P_L_t; + +TINYSDP_API tsdp_header_P_t* tsdp_header_P_create(const char* value); +TINYSDP_API tsdp_header_P_t* tsdp_header_P_create_null(); + +TINYSDP_API tsdp_header_P_t *tsdp_header_P_parse(const char *data, tsk_size_t size); + +TINYSDP_GEXTERN const tsk_object_def_t *tsdp_header_P_def_t; + +TSDP_END_DECLS + +#endif /* _TSDP_HEADER_P_H_ */ + diff --git a/tinySDP/include/tinysdp/headers/tsdp_header_R.h b/tinySDP/include/tinysdp/headers/tsdp_header_R.h new file mode 100644 index 0000000..a5277cc --- /dev/null +++ b/tinySDP/include/tinysdp/headers/tsdp_header_R.h @@ -0,0 +1,77 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org> +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_header_R.h + * @brief SDP "r=" header (Repeat Times). + * + * @author Mamadou Diop <diopmamadou(at)doubango[dot]org> + * + * + */ +#ifndef _TSDP_HEADER_R_H_ +#define _TSDP_HEADER_R_H_ + +#include "tinysdp_config.h" +#include "tinysdp/headers/tsdp_header.h" + +#include "tsk_string.h" + +TSDP_BEGIN_DECLS + +#define TSDP_HEADER_R_VA_ARGS() tsdp_header_R_def_t + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/// @struct +/// +/// @brief SDP "r=" header (Repeat Times). +/// +/// The "e=" line "r=" fields specify repeat times for a session. +/// +/// @par ABNF : r= repeat-interval SP typed-time 1*(SP typed-time) +/// repeat-interval = POS-DIGIT *DIGIT [fixed-len-time-unit] +/// typed-time = 1*DIGIT [fixed-len-time-unit] +/// 1*DIGIT [fixed-len-time-unit] +/// fixed-len-time-unit = "d" / "h" / "m" / "s" +/// +//////////////////////////////////////////////////////////////////////////////////////////////////// +typedef struct tsdp_header_R_s +{ + TSDP_DECLARE_HEADER; + char* repeat_interval; + char* typed_time; + tsk_strings_L_t* typed_times; +} +tsdp_header_R_t; + +typedef tsk_list_t tsdp_headers_R_L_t; + +TINYSDP_API tsdp_header_R_t* tsdp_header_R_create(); +TINYSDP_API tsdp_header_R_t* tsdp_header_R_create_null(); + +TINYSDP_API tsdp_header_R_t *tsdp_header_R_parse(const char *data, tsk_size_t size); + +TINYSDP_GEXTERN const tsk_object_def_t *tsdp_header_R_def_t; + +TSDP_END_DECLS + +#endif /* _TSDP_HEADER_R_H_ */ + diff --git a/tinySDP/include/tinysdp/headers/tsdp_header_S.h b/tinySDP/include/tinysdp/headers/tsdp_header_S.h new file mode 100644 index 0000000..4f2316a --- /dev/null +++ b/tinySDP/include/tinysdp/headers/tsdp_header_S.h @@ -0,0 +1,65 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org> +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_header_S.h + * @brief SDP "s=" header (Session Name). + * + * @author Mamadou Diop <diopmamadou(at)doubango[dot]org> + * + + */ +#ifndef _TSDP_HEADER_S_H_ +#define _TSDP_HEADER_S_H_ + +#include "tinysdp_config.h" +#include "tinysdp/headers/tsdp_header.h" + +TSDP_BEGIN_DECLS + +#define TSDP_HEADER_S_VA_ARGS(value) tsdp_header_S_def_t, (const char*)value + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/// @struct +/// +/// @brief SDP "s=" header (Session Name). +/// +/// @par ABNF : s=text +/// +//////////////////////////////////////////////////////////////////////////////////////////////////// +typedef struct tsdp_header_S_s +{ + TSDP_DECLARE_HEADER; + char* value; +} +tsdp_header_S_t; + +TINYSDP_API tsdp_header_S_t* tsdp_header_S_create(const char* value); +TINYSDP_API tsdp_header_S_t* tsdp_header_S_create_null(); + +TINYSDP_API tsdp_header_S_t *tsdp_header_S_parse(const char *data, tsk_size_t size); + +TINYSDP_GEXTERN const tsk_object_def_t *tsdp_header_S_def_t; + +TSDP_END_DECLS + +#endif /* _TSDP_HEADER_S_H_ */ + diff --git a/tinySDP/include/tinysdp/headers/tsdp_header_T.h b/tinySDP/include/tinysdp/headers/tsdp_header_T.h new file mode 100644 index 0000000..596094d --- /dev/null +++ b/tinySDP/include/tinysdp/headers/tsdp_header_T.h @@ -0,0 +1,81 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org> +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_header_T.h + * @brief SDP "t=" header (Timing). + * + * @author Mamadou Diop <diopmamadou(at)doubango[dot]org> + * + * + */ +#ifndef _TSDP_HEADER_T_H_ +#define _TSDP_HEADER_T_H_ + +#include "tinysdp_config.h" +#include "tinysdp/headers/tsdp_header.h" + +#include "tinysdp/headers/tsdp_header_R.h" + +TSDP_BEGIN_DECLS + +#define TSDP_HEADER_T_VA_ARGS(start, stop) tsdp_header_T_def_t, (uint64_t)start, (uint64_t)stop + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/// @struct +/// +/// @brief SDP "t=" header (Timing). +/// The "t=" lines specify the start and stop times for a session. +/// Multiple "t=" lines MAY be used if a session is active at multiple +/// irregularly spaced times; each additional "t=" line specifies an +/// additional period of time for which the session will be active. If +/// the session is active at regular times, an "r=" line (see below) +/// should be used in addition to, and following, a "t=" line -- in which +/// case the "t=" line specifies the start and stop times of the repeat +/// sequence. +/// +/// +/// @par ABNF : t= start-time SP stop-time *( CRLF repeat-fields ) +/// +//////////////////////////////////////////////////////////////////////////////////////////////////// +typedef struct tsdp_header_T_s +{ + TSDP_DECLARE_HEADER; + uint64_t start; + uint64_t stop; + + tsdp_headers_R_L_t* repeat_fields; +} +tsdp_header_T_t; + +typedef tsk_list_t tsdp_headers_T_L_t; + +TINYSDP_API tsdp_header_T_t* tsdp_header_T_create(uint64_t start, uint64_t stop); +TINYSDP_API tsdp_header_T_t* tsdp_header_T_create_null(); + +TINYSDP_API tsdp_header_T_t *tsdp_header_T_parse(const char *data, tsk_size_t size); + +TINYSDP_GEXTERN const tsk_object_def_t *tsdp_header_T_def_t; + +TSDP_END_DECLS + +#endif /* _TSDP_HEADER_P_H_ */ + diff --git a/tinySDP/include/tinysdp/headers/tsdp_header_U.h b/tinySDP/include/tinysdp/headers/tsdp_header_U.h new file mode 100644 index 0000000..d42a503 --- /dev/null +++ b/tinySDP/include/tinysdp/headers/tsdp_header_U.h @@ -0,0 +1,67 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org> +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_header_U.h + * @brief SDP "u=" header (URI). + * + * @author Mamadou Diop <diopmamadou(at)doubango[dot]org> + * + * @date Created: Uat Nov 8 16:54:58 2009 mdiop + */ +#ifndef _TSDP_HEADER_U_H_ +#define _TSDP_HEADER_U_H_ + +#include "tinysdp_config.h" +#include "tinysdp/headers/tsdp_header.h" + +TSDP_BEGIN_DECLS + +#define TSDP_HEADER_U_VA_ARGS(value) tsdp_header_U_def_t, (const char*)value + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/// @struct +/// +/// @brief SDP "u=" header (URI). +/// +/// @par ABNF : u=uri +/// +//////////////////////////////////////////////////////////////////////////////////////////////////// +typedef struct tsdp_header_U_s +{ + TSDP_DECLARE_HEADER; + char* value; +} +tsdp_header_U_t; + +typedef tsk_list_t tsdp_headers_U_L_t; + +TINYSDP_API tsdp_header_U_t* tsdp_header_U_create(const char* value); +TINYSDP_API tsdp_header_U_t* tsdp_header_U_create_null(); + +TINYSDP_API tsdp_header_U_t *tsdp_header_U_parse(const char *data, tsk_size_t size); + +TINYSDP_GEXTERN const tsk_object_def_t *tsdp_header_U_def_t; + +TSDP_END_DECLS + +#endif /* _TSDP_HEADER_U_H_ */ + diff --git a/tinySDP/include/tinysdp/headers/tsdp_header_V.h b/tinySDP/include/tinysdp/headers/tsdp_header_V.h new file mode 100644 index 0000000..bf3578a --- /dev/null +++ b/tinySDP/include/tinysdp/headers/tsdp_header_V.h @@ -0,0 +1,71 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org> +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_header_V.h + * @brief SDP "v=" header (Protocol Version). + * + * @author Mamadou Diop <diopmamadou(at)doubango[dot]org> + * + + */ +#ifndef _TSDP_HEADER_V_H_ +#define _TSDP_HEADER_V_H_ + +#include "tinysdp_config.h" +#include "tinysdp/headers/tsdp_header.h" + +TSDP_BEGIN_DECLS + +#define TSDP_HEADER_V_VA_ARGS(version) tsdp_header_V_def_t, (int32_t)version + +#define TSDP_HEADER_V_DEFAULT 0 + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/// @struct +/// +/// @brief SDP "v=" header (Protocol Version). +/// The "v=" field gives the version of the Session Description Protocol. +/// This memo (RFC 4566) defines version 0. There is no minor version number. +/// +/// @par ABNF : v=1*DIGIT +/// +//////////////////////////////////////////////////////////////////////////////////////////////////// +typedef struct tsdp_header_V_s +{ + TSDP_DECLARE_HEADER; + int32_t version; +} +tsdp_header_V_t; + +typedef tsk_list_t tsdp_headers_V_L_t; + +TINYSDP_API tsdp_header_V_t* tsdp_header_V_create(int32_t version); +TINYSDP_API tsdp_header_V_t* tsdp_header_V_create_null(); + +TINYSDP_API tsdp_header_V_t *tsdp_header_V_parse(const char *data, tsk_size_t size); + +TINYSDP_GEXTERN const tsk_object_def_t *tsdp_header_V_def_t; + +TSDP_END_DECLS + +#endif /* _TSDP_HEADER_V_H_ */ + diff --git a/tinySDP/include/tinysdp/headers/tsdp_header_Z.h b/tinySDP/include/tinysdp/headers/tsdp_header_Z.h new file mode 100644 index 0000000..e962cc8 --- /dev/null +++ b/tinySDP/include/tinysdp/headers/tsdp_header_Z.h @@ -0,0 +1,87 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org> +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_header_Z.h + * @brief SDP "z=" header (Time Zones). + * + * @author Mamadou Diop <diopmamadou(at)doubango[dot]org> + * + * + */ +#ifndef _TSDP_HEADER_Z_H_ +#define _TSDP_HEADER_Z_H_ + +#include "tinysdp_config.h" +#include "tinysdp/headers/tsdp_header.h" + +TSDP_BEGIN_DECLS + +#define TSDP_HEADER_Z_VA_ARGS(time, shifted_back, typed_time) tsdp_header_Z_def_t, (uint64_t)time, (tsk_bool_t)shifted_back, (const char*)typed_time + +typedef struct tsdp_zone_s +{ + TSK_DECLARE_OBJECT; + + uint64_t time; + tsk_bool_t shifted_back; + char* typed_time; +} +tsdp_zone_t; +typedef tsk_list_t tsdp_zones_L_t; + +TINYSDP_API tsdp_zone_t* tsdp_zone_create(uint64_t time, tsk_bool_t shifted_back, const char* typed_time) ; +TINYSDP_API tsdp_zone_t* tsdp_zone_create_null(); + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/// @struct +/// +/// @brief SDP "z=" header (Time Zones). +/// +/// @par ABNF : z=time SP ["-"] typed-time +/// *(SP time SP ["-"] typed-time) +/// time = POS-DIGIT 9*DIGIT +/// typed-time = 1*DIGIT [fixed-len-time-unit] +/// fixed-len-time-unit = "d" / "h" / "m" / "s" +/// +//////////////////////////////////////////////////////////////////////////////////////////////////// +typedef struct tsdp_header_Z_s +{ + TSDP_DECLARE_HEADER; + + tsdp_zones_L_t* zones; +} +tsdp_header_Z_t; + +typedef tsk_list_t tsdp_headers_Z_L_t; + +TINYSDP_API tsdp_header_Z_t* tsdp_header_Z_create(uint64_t time, tsk_bool_t shifted_back, const char* typed_time); +TINYSDP_API tsdp_header_Z_t* tsdp_header_Z_create_null(); + +TINYSDP_API tsdp_header_Z_t *tsdp_header_Z_parse(const char *data, tsk_size_t size); + +TINYSDP_GEXTERN const tsk_object_def_t *tsdp_header_Z_def_t; +TINYSDP_GEXTERN const tsk_object_def_t *tsdp_zone_def_t; + +TSDP_END_DECLS + +#endif /* _TSDP_HEADER_Z_H_ */ + diff --git a/tinySDP/include/tinysdp/parsers/tsdp_parser_header.h b/tinySDP/include/tinysdp/parsers/tsdp_parser_header.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tinySDP/include/tinysdp/parsers/tsdp_parser_header.h diff --git a/tinySDP/include/tinysdp/parsers/tsdp_parser_message.h b/tinySDP/include/tinysdp/parsers/tsdp_parser_message.h new file mode 100644 index 0000000..811cb86 --- /dev/null +++ b/tinySDP/include/tinysdp/parsers/tsdp_parser_message.h @@ -0,0 +1,44 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org> +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_parser_message.h + * @brief SDP message parser. + * + * @author Mamadou Diop <diopmamadou(at)doubango[dot]org> + * + + */ +#ifndef TINYSDP_PARSER_MESSAGE_H +#define TINYSDP_PARSER_MESSAGE_H + +#include "tinysdp_config.h" +#include "tinysdp/tsdp_message.h" +#include "tsk_ragel_state.h" + +TSDP_BEGIN_DECLS + +TINYSDP_API tsdp_message_t* tsdp_message_parse(const void *input, tsk_size_t size); + +TSDP_END_DECLS + +#endif /* TINYSDP_PARSER_MESSAGE_H */ + diff --git a/tinySDP/include/tinysdp/tsdp_message.h b/tinySDP/include/tinysdp/tsdp_message.h new file mode 100644 index 0000000..4d7c226 --- /dev/null +++ b/tinySDP/include/tinysdp/tsdp_message.h @@ -0,0 +1,107 @@ +/* +* Copyright (C) 2010-2015 Mamadou DIOP. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_message.h + * @brief SDP message. + * + */ +#ifndef TINYSDP_MESSAGE_H +#define TINYSDP_MESSAGE_H + +#include "tinysdp_config.h" + +#include "tinysdp/headers/tsdp_header.h" + +#include "tinysdp/headers/tsdp_header_M.h" + +TSDP_BEGIN_DECLS + +typedef struct tsdp_message_s +{ + TSK_DECLARE_OBJECT; + + //! List of @ref tsdp_header_t elements. + tsdp_headers_L_t* headers; +} +tsdp_message_t; + +typedef tsdp_message_t tsdp_offer_t; +typedef tsdp_message_t tsdp_answer_t; +typedef tsdp_message_t tsdp_caps_t; + +TINYSDP_API int tsdp_message_add_header(tsdp_message_t *self, const tsdp_header_t *hdr); +TINYSDP_API int tsdp_message_add_headers(tsdp_message_t *self, ...); + +#if defined(__SYMBIAN32__) && 0 +static void TSDP_MESSAGE_ADD_HEADER(tsdp_message_t *self, ...) + { + va_list ap; + tsdp_header_t *header; + const tsk_object_def_t *objdef; + + va_start(ap, self); + objdef = va_arg(ap, const tsk_object_def_t*); + header = (tsdp_header_t *)tsk_object_new_2(objdef, &ap); + va_end(ap); + + tsdp_message_add_header(self, header); + tsk_object_unref(header); + } +#else +#define TSDP_MESSAGE_ADD_HEADER(self, objdef, ...) \ + { \ + tsdp_header_t *header = (tsdp_header_t *)tsk_object_new(objdef, ##__VA_ARGS__); \ + tsdp_message_add_header(self, header); \ + tsk_object_unref(header); \ + } +#endif + +TINYSDP_API const tsdp_header_t *tsdp_message_get_headerAt(const tsdp_message_t *self, tsdp_header_type_t type, tsk_size_t index); +TINYSDP_API const tsdp_header_t *tsdp_message_get_header(const tsdp_message_t *self, tsdp_header_type_t type); +TINYSDP_API const tsdp_header_A_t* tsdp_message_get_headerA_at(const tsdp_message_t* self, const char* field, tsk_size_t index); +TINYSDP_API const tsdp_header_A_t* tsdp_message_get_headerA(const tsdp_message_t* self, const char* field); +TINYSDP_API const tsdp_header_t *tsdp_message_get_headerByName(const tsdp_message_t *self, char name); +TINYSDP_API int tsdp_message_get_sess_version(const tsdp_message_t *self, uint32_t *version); + +TINYSDP_API int tsdp_message_serialize(const tsdp_message_t *self, tsk_buffer_t *output); +TINYSDP_API char* tsdp_message_tostring(const tsdp_message_t *self); + +TINYSDP_API tsdp_message_t* tsdp_message_create_empty(const char* addr, tsk_bool_t ipv6, uint32_t version); +TINYSDP_API tsdp_message_t* tsdp_message_clone(const tsdp_message_t *self); +TINYSDP_API int tsdp_message_add_media(tsdp_message_t *self, const char* media, uint32_t port, const char* proto, ...); +TINYSDP_API int tsdp_message_add_media_2(tsdp_message_t *self, const char* media, uint32_t port, const char* proto, va_list *ap); +TINYSDP_API int tsdp_message_remove_media(tsdp_message_t *self, const char* media); +TINYSDP_API const tsdp_header_M_t* tsdp_message_find_media(const tsdp_message_t *self, const char* media); + + +// 3GPP TS 24.610 Communication HOLD +TINYSDP_API int tsdp_message_hold(tsdp_message_t* self, const char* media); +TINYSDP_API int tsdp_message_resume(tsdp_message_t* self, const char* media); + +TINYSDP_API tsk_bool_t tsdp_message_is_ice_enabled(const tsdp_message_t *self, tsk_size_t media_index); +TINYSDP_API tsk_bool_t tsdp_message_is_ice_restart(const tsdp_message_t *self, tsk_size_t media_index); + +TINYSDP_API tsdp_message_t* tsdp_message_create(); + +TINYSDP_GEXTERN const tsk_object_def_t *tsdp_message_def_t; + +TSDP_END_DECLS + +#endif /* TINYSDP_MESSAGE_H */ diff --git a/tinySDP/include/tinysdp_config.h b/tinySDP/include/tinysdp_config.h new file mode 100644 index 0000000..23ee4c8 --- /dev/null +++ b/tinySDP/include/tinysdp_config.h @@ -0,0 +1,99 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org> +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +#ifndef TINYSDP_CONFIG_H +#define TINYSDP_CONFIG_H + +#ifdef __SYMBIAN32__ +#undef _WIN32 /* Because of WINSCW */ +#endif + +// Windows (XP/Vista/7/CE and Windows Mobile) macro definition. +#if defined(WIN32)|| defined(_WIN32) || defined(_WIN32_WCE) +# define TSDP_UNDER_WINDOWS 1 +# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP || WINAPI_FAMILY == WINAPI_FAMILY_APP) +# define TSDP_UNDER_WINDOWS_RT 1 +# endif +#endif + +// OS X or iOS +#if defined(__APPLE__) +# define TSDP_UNDER_APPLE 1 +# include <TargetConditionals.h> +# include <Availability.h> +#endif +#if TARGET_OS_MAC +# define TSDP_UNDER_MAC 1 +#endif +#if TARGET_OS_IPHONE +# define TSDP_UNDER_IPHONE 1 +#endif +#if TARGET_IPHONE_SIMULATOR +# define TSDP_UNDER_IPHONE_SIMULATOR 1 +#endif + + +#if (TSDP_UNDER_WINDOWS || defined(__SYMBIAN32__)) && defined(TINYSDP_EXPORTS) +# define TINYSDP_API __declspec(dllexport) +# define TINYSDP_GEXTERN extern __declspec(dllexport) +#elif (TSDP_UNDER_WINDOWS || defined(__SYMBIAN32__)) && !defined(TINYSDP_IMPORTS_IGNORE) +# define TINYSDP_API __declspec(dllimport) +# define TINYSDP_GEXTERN __declspec(dllimport) +#else +# define TINYSDP_API +# define TINYSDP_GEXTERN extern +#endif + +/* Guards against C++ name mangling +*/ +#ifdef __cplusplus +# define TSDP_BEGIN_DECLS extern "C" { +# define TSDP_END_DECLS } +#else +# define TSDP_BEGIN_DECLS +# define TSDP_END_DECLS +#endif + +/* Disable some well-known warnings +*/ +#ifdef _MSC_VER +# if !defined(_CRT_SECURE_NO_WARNINGS) +# define _CRT_SECURE_NO_WARNINGS +# endif /* _CRT_SECURE_NO_WARNINGS */ +#endif + +/* Detecting C99 compilers + */ +#if (__STDC_VERSION__ == 199901L) && !defined(__C99__) +# define __C99__ +#endif + +#include <stdint.h> +#ifdef __SYMBIAN32__ +#include <stdlib.h> +#endif + +#if HAVE_CONFIG_H + #include <config.h> +#endif + +#endif // TINYSDP_CONFIG_H diff --git a/tinySDP/include/tsdp.h b/tinySDP/include/tsdp.h new file mode 100644 index 0000000..f09e9f4 --- /dev/null +++ b/tinySDP/include/tsdp.h @@ -0,0 +1,63 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org> +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ +/**@file tsdp.h + * @brief SDP (RFC 4566) implementations with both MMTel and PoC extensions. + * + * @author Mamadou Diop <diopmamadou(at)doubango[dot]org> + * + + */ +#ifndef TINYSDP_TSDP_H +#define TINYSDP_TSDP_H + +#include "tinysdp_config.h" + +#include "tinysdp/tsdp_message.h" + +TSDP_BEGIN_DECLS + +#define TSDP_CTX_CREATE() tsk_object_new(tsdp_ctx_def_t) + +typedef void tsdp_ctx_handle_t; + +TINYSDP_API const tsdp_message_t* tsdp_ctx_local_get_sdp(const tsdp_ctx_handle_t* self); +TINYSDP_API int tsdp_ctx_local_create_sdp(tsdp_ctx_handle_t* self, const tsdp_message_t* local); +TINYSDP_API int tsdp_ctx_local_create_sdp_2(tsdp_ctx_handle_t* self, const char* sdp, tsk_size_t size); +TINYSDP_API int tsdp_ctx_local_add_headers(tsdp_ctx_handle_t* self, ...); +TINYSDP_API int tsdp_ctx_local_add_media(tsdp_ctx_handle_t* self, const tsdp_header_M_t* media); +TINYSDP_API int tsdp_ctx_local_add_media_2(tsdp_ctx_handle_t* self, const char* media, uint32_t port, const char* proto, ...); + +TINYSDP_API const tsdp_message_t* tsdp_ctx_remote_get_sdp(const tsdp_ctx_handle_t* self); + +TINYSDP_API const tsdp_message_t* tsdp_ctx_negotiated_get_sdp(const tsdp_ctx_handle_t* self); + + +// 3GPP TS 24.610 Communication HOLD +TINYSDP_API int tsdp_ctx_hold(tsdp_ctx_handle_t* self, const char* media); +TINYSDP_API int tsdp_ctx_resume(tsdp_ctx_handle_t* self, const char* media); + +TINYSDP_GEXTERN const tsk_object_def_t *tsdp_ctx_def_t; + +TSDP_END_DECLS + + +#endif /* TINYSDP_TSDP_H */ diff --git a/tinySDP/ragel.sh b/tinySDP/ragel.sh new file mode 100644 index 0000000..702086a --- /dev/null +++ b/tinySDP/ragel.sh @@ -0,0 +1,59 @@ +# Ragel generator +# For more information about Ragel: http://www.complang.org/ragel/ + +export OPTIONS="-C -L -T0" +#export OPTIONS="-C -L -G2" + +# SDP Message parser +ragel.exe $OPTIONS -o ./src/parsers/tsdp_parser_message.c ./ragel/tsdp_parser_message.rl + + + +# ==A +ragel.exe $OPTIONS -o ./src/headers/tsdp_header_A.c ./ragel/tsdp_parser_header_A.rl + +# ==B +ragel.exe $OPTIONS -o ./src/headers/tsdp_header_B.c ./ragel/tsdp_parser_header_B.rl + +# ==C +ragel.exe $OPTIONS -o ./src/headers/tsdp_header_C.c ./ragel/tsdp_parser_header_C.rl + +# ==Dummy +ragel.exe $OPTIONS -o ./src/headers/tsdp_header_Dummy.c ./ragel/tsdp_parser_header_Dummy.rl + +# ==E +ragel.exe $OPTIONS -o ./src/headers/tsdp_header_E.c ./ragel/tsdp_parser_header_E.rl + +# ==I +ragel.exe $OPTIONS -o ./src/headers/tsdp_header_I.c ./ragel/tsdp_parser_header_I.rl + +# ==K +ragel.exe $OPTIONS -o ./src/headers/tsdp_header_K.c ./ragel/tsdp_parser_header_K.rl + +# ==M +ragel.exe $OPTIONS -o ./src/headers/tsdp_header_M.c ./ragel/tsdp_parser_header_M.rl + +# ==O +ragel.exe $OPTIONS -o ./src/headers/tsdp_header_O.c ./ragel/tsdp_parser_header_O.rl + +# ==P +ragel.exe $OPTIONS -o ./src/headers/tsdp_header_P.c ./ragel/tsdp_parser_header_P.rl + +# ==R +ragel.exe $OPTIONS -o ./src/headers/tsdp_header_R.c ./ragel/tsdp_parser_header_R.rl + +# ==S +ragel.exe $OPTIONS -o ./src/headers/tsdp_header_S.c ./ragel/tsdp_parser_header_S.rl + +# ==T +ragel.exe $OPTIONS -o ./src/headers/tsdp_header_T.c ./ragel/tsdp_parser_header_T.rl + +# ==U +ragel.exe $OPTIONS -o ./src/headers/tsdp_header_U.c ./ragel/tsdp_parser_header_U.rl + +# ==V +ragel.exe $OPTIONS -o ./src/headers/tsdp_header_V.c ./ragel/tsdp_parser_header_V.rl + +# ==Z +ragel.exe $OPTIONS -o ./src/headers/tsdp_header_Z.c ./ragel/tsdp_parser_header_Z.rl + diff --git a/tinySDP/ragel/tsdp_machine_utils.rl b/tinySDP/ragel/tsdp_machine_utils.rl new file mode 100644 index 0000000..ed2b2b9 --- /dev/null +++ b/tinySDP/ragel/tsdp_machine_utils.rl @@ -0,0 +1,72 @@ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ +/**@file tsdp_machine_utils.rl + * @brief Ragel file. + */ +%%{ + + machine tsdp_machine_utils; + + OCTET = "0x"[0-9A-Fa-f]+; + CHAR = 0x01..0x7f; + VCHAR = 0x21..0x7e; + ALPHA = 0x41..0x5a | 0x61..0x7a; + DIGIT = 0x30..0x39; + CTL = 0x00..0x1f | 0x7f; + HTAB = "\t"; + LF = "\n"; + CR = "\r"; + SP = " "; + DQUOTE = "\""; + BIT = "0" | "1"; + HEXDIG = DIGIT | "A"i | "B"i | "C"i | "D"i | "E"i | "F"i; + CRLF = CR LF; + WSP = SP | HTAB; + LWSP = ( WSP | ( CRLF WSP ) )*; + LWS = ( WSP* CRLF )? WSP+; + SWS = LWS?; + EQUAL = SWS "=" SWS; + LHEX = DIGIT | 0x61..0x66; + HCOLON = ( SP | HTAB )* ":" SWS; + separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\\" | DQUOTE | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HTAB; + STAR = SWS "*" SWS; + SLASH = SWS "/" SWS; + LPAREN = SWS "(" SWS; + RPAREN = SWS ")" SWS; + COMMA = SWS "," SWS; + SEMI = SWS ";" SWS; + COLON = SWS ":" SWS; + LAQUOT = SWS "<"; + LDQUOT = SWS DQUOTE; + RAQUOT = ">" SWS; + RDQUOT = DQUOTE SWS; + UTF8_CONT = 0x80..0xbf; + ##### FIXME: UTF8_NONASCII up to 2bytes will fail on Android + UTF8_NONASCII = ( 0x80..0xff ); + #UTF8_NONASCII = ( 0xc0..0xdf UTF8_CONT ) | ( 0xe0..0xef UTF8_CONT{2} ) | ( 0xf0..0xf7 UTF8_CONT{3} ) | ( 0xf8..0xfb UTF8_CONT{4} ) | ( 0xfc..0xfd UTF8_CONT{5} ); ctext = 0x21..0x27 | 0x2a..0x5b | 0x5d..0x7e | UTF8_NONASCII | LWS; + qvalue = ( "0" ( "." DIGIT{,3} )? ) | ( "1" ( "." "0"{,3} )? ); + alphanum = ALPHA | DIGIT; + token = ( alphanum | "-" | "." | "!" | "%" | "*" | "_" | "+" | "`" | "'" | "~" )+; + ietf_token = token; + x_token = "x-"i token; + iana_token = token; + token_nodot = ( alphanum | "-" | "!" | "%" | "*" | "_" | "+" | "`" | "'" | "~" )+; + word = ( alphanum | "-" | "." | "!" | "%" | "*" | "_" | "+" | "`" | "'" | "~" | "(" | ")" | "<" | ">" | ":" | "\\" | DQUOTE | "/" | "[" | "]" | "?" | "{" | "}" )+; +}%% diff --git a/tinySDP/ragel/tsdp_parser_header_A.rl b/tinySDP/ragel/tsdp_parser_header_A.rl new file mode 100644 index 0000000..29f7a20 --- /dev/null +++ b/tinySDP/ragel/tsdp_parser_header_A.rl @@ -0,0 +1,229 @@ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_header_A.c + * @brief SDP "a=" header (Attributes). + * + */ +#include "tinysdp/headers/tsdp_header_A.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_string.h" + +#include <string.h> + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsdp_machine_parser_header_A; + + # Includes + include tsdp_machine_utils "./ragel/tsdp_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_field{ + TSK_PARSER_SET_STRING(hdr_A->field); + } + + action parse_value{ + TSK_PARSER_SET_STRING(hdr_A->value); + } + + field = token>tag %parse_field; + value = any*>tag %parse_value; + + A = 'a' SP* "=" SP*<: ((field ":" value) | (field)); + + # Entry point + main := A :>CRLF?; + +}%% + + + +tsdp_header_A_t* tsdp_header_A_create(const char* field, const char* value) +{ + return tsk_object_new(TSDP_HEADER_A_VA_ARGS(field, value)); +} + +tsdp_header_A_t* tsdp_header_A_create_null() +{ + return tsdp_header_A_create(tsk_null, tsk_null); +} + + +int tsdp_header_A_tostring(const tsdp_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsdp_header_A_t *A = (const tsdp_header_A_t *)header; + + return tsk_buffer_append_2(output, "%s%s%s", + A->field, + + A->value ? ":" : "", + A->value ? A->value : "" + ); + } + + return -1; +} + +tsdp_header_t* tsdp_header_A_clone(const tsdp_header_t* header) +{ + if(header){ + const tsdp_header_A_t *A = (const tsdp_header_A_t *)header; + return (tsdp_header_t*)tsdp_header_A_create(A->field, A->value); + } + return tsk_null; +} + +tsdp_header_A_t *tsdp_header_A_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsdp_header_A_t *hdr_A = tsdp_header_A_create_null(); + + const char *tag_start = tsk_null; + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + %%write data; + %%write init; + (void)(tsdp_machine_parser_header_A_first_final); + (void)(tsdp_machine_parser_header_A_error); + (void)(tsdp_machine_parser_header_A_en_main); + %%write exec; + TSK_RAGEL_DISABLE_WARNINGS_END() + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse \"a=\" header."); + TSK_OBJECT_SAFE_FREE(hdr_A); + } + + return hdr_A; +} + + +int tsdp_header_A_removeAll_by_field(tsdp_headers_A_L_t *attributes, const char* field) +{ + tsk_list_item_t* item; + const tsdp_header_A_t* A; + + if(!attributes || !field){ + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + +again: + tsk_list_foreach(item, attributes){ + if(!(A = item->data) || TSDP_HEADER(A)->type != tsdp_htype_A){ + continue; + } + if(tsk_striequals(field, A->field)){ + tsk_list_remove_item(attributes, item); + goto again; + } + } + + return 0; +} + +int tsdp_header_A_removeAll_by_fields(tsdp_headers_A_L_t *attributes, const char** fields, tsk_size_t fields_count) +{ + tsk_size_t i; + + if(!attributes || !fields){ + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + for(i = 0; i < fields_count; ++i){ + if(!fields[i]){ + continue; + } + tsdp_header_A_removeAll_by_field(attributes, fields[i]); + } + return 0; +} + + + + +//======================================================== +// A header object definition +// + +static tsk_object_t* tsdp_header_A_ctor(tsk_object_t *self, va_list * app) +{ + tsdp_header_A_t *A = self; + if(A) + { + TSDP_HEADER(A)->type = tsdp_htype_A; + TSDP_HEADER(A)->tostring = tsdp_header_A_tostring; + TSDP_HEADER(A)->clone = tsdp_header_A_clone; + TSDP_HEADER(A)->rank = TSDP_HTYPE_A_RANK; + + A->field = tsk_strdup(va_arg(*app, const char*)); + A->value = tsk_strdup(va_arg(*app, const char*)); + } + else{ + TSK_DEBUG_ERROR("Failed to create new A header."); + } + return self; +} + +static tsk_object_t* tsdp_header_A_dtor(tsk_object_t *self) +{ + tsdp_header_A_t *A = self; + if(A){ + TSK_FREE(A->field); + TSK_FREE(A->value); + } + else{ + TSK_DEBUG_ERROR("Null A header."); + } + + return self; +} +static int tsdp_header_A_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) +{ + if(obj1 && obj2){ + return tsdp_header_rank_cmp(obj1, obj2); + } + else{ + return -1; + } +} + +static const tsk_object_def_t tsdp_header_A_def_s = +{ + sizeof(tsdp_header_A_t), + tsdp_header_A_ctor, + tsdp_header_A_dtor, + tsdp_header_A_cmp +}; + +const tsk_object_def_t *tsdp_header_A_def_t = &tsdp_header_A_def_s; diff --git a/tinySDP/ragel/tsdp_parser_header_B.rl b/tinySDP/ragel/tsdp_parser_header_B.rl new file mode 100644 index 0000000..63500b7 --- /dev/null +++ b/tinySDP/ragel/tsdp_parser_header_B.rl @@ -0,0 +1,186 @@ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + + +/**@file tsdp_header_B.c + * @brief SDP "b=" header (Bandwidth). + * + */ +#include "tinysdp/headers/tsdp_header_B.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_string.h" + +#include <string.h> + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsdp_machine_parser_header_B; + + # Includes + include tsdp_machine_utils "./ragel/tsdp_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_bwtype{ + TSK_PARSER_SET_STRING(hdr_B->bwtype); + } + + action parse_bandwidth{ + TSK_PARSER_SET_UINT(hdr_B->bandwidth); + } + + bwtype = token>tag %parse_bwtype; + bandwidth = DIGIT+>tag %parse_bandwidth; + + B = 'b' SP* "=" SP*<: bwtype ":" bandwidth; + + # Entry point + main := B :>CRLF?; + +}%% + + + + +tsdp_header_B_t* tsdp_header_B_create(const char* bwtype, uint32_t bandwidth) +{ + return tsk_object_new(TSDP_HEADER_B_VA_ARGS(bwtype, bandwidth)); +} + +tsdp_header_B_t* tsdp_header_B_create_null() +{ + return tsdp_header_B_create(tsk_null, 0); +} + +int tsdp_header_B_tostring(const tsdp_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsdp_header_B_t *B = (const tsdp_header_B_t *)header; + + return tsk_buffer_append_2(output, "%s:%u", + B->bwtype, + B->bandwidth + ); + } + + return -1; +} + +tsdp_header_t* tsdp_header_B_clone(const tsdp_header_t* header) +{ + if(header){ + const tsdp_header_B_t *B = (const tsdp_header_B_t *)header; + return (tsdp_header_t*)tsdp_header_B_create(B->bwtype, B->bandwidth); + } + return tsk_null; +} + +tsdp_header_B_t *tsdp_header_B_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsdp_header_B_t *hdr_B = tsdp_header_B_create_null(); + + const char *tag_start = tsk_null; + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + %%write data; + (void)(tsdp_machine_parser_header_B_first_final); + (void)(tsdp_machine_parser_header_B_error); + (void)(tsdp_machine_parser_header_B_en_main); + %%write init; + %%write exec; + TSK_RAGEL_DISABLE_WARNINGS_END() + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse \"b=\" header."); + TSK_OBJECT_SAFE_FREE(hdr_B); + } + + return hdr_B; +} + + + + + + + +//======================================================== +// B header object definition +// + +static tsk_object_t* tsdp_header_B_ctor(tsk_object_t *self, va_list * app) +{ + tsdp_header_B_t *B = self; + if(B){ + TSDP_HEADER(B)->type = tsdp_htype_B; + TSDP_HEADER(B)->tostring = tsdp_header_B_tostring; + TSDP_HEADER(B)->clone = tsdp_header_B_clone; + TSDP_HEADER(B)->rank = TSDP_HTYPE_B_RANK; + + B->bwtype = tsk_strdup(va_arg(*app, const char*)); + B->bandwidth = va_arg(*app, uint32_t); + } + else{ + TSK_DEBUG_ERROR("Failed to create new B header."); + } + return self; +} + +static tsk_object_t* tsdp_header_B_dtor(tsk_object_t *self) +{ + tsdp_header_B_t *B = self; + if(B){ + TSK_FREE(B->bwtype); + } + else{ + TSK_DEBUG_ERROR("Null B header."); + } + + return self; +} +static int tsdp_header_B_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) +{ + if(obj1 && obj2){ + return tsdp_header_rank_cmp(obj1, obj2); + } + else{ + return -1; + } +} + +static const tsk_object_def_t tsdp_header_B_def_s = +{ + sizeof(tsdp_header_B_t), + tsdp_header_B_ctor, + tsdp_header_B_dtor, + tsdp_header_B_cmp +}; + +const tsk_object_def_t *tsdp_header_B_def_t = &tsdp_header_B_def_s; diff --git a/tinySDP/ragel/tsdp_parser_header_C.rl b/tinySDP/ragel/tsdp_parser_header_C.rl new file mode 100644 index 0000000..ff87043 --- /dev/null +++ b/tinySDP/ragel/tsdp_parser_header_C.rl @@ -0,0 +1,193 @@ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + + +/**@file tsdp_header_C.c + * @brief "c=" header (Connection Data). + */ +#include "tinysdp/headers/tsdp_header_C.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_string.h" + +#include <string.h> + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsdp_machine_parser_header_C; + + # Includes + include tsdp_machine_utils "./ragel/tsdp_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_nettype{ + TSK_PARSER_SET_STRING(hdr_C->nettype); + } + + action parse_addrtype{ + TSK_PARSER_SET_STRING(hdr_C->addrtype); + } + + action parse_addr{ + TSK_PARSER_SET_STRING(hdr_C->addr); + } + + nettype = any* >tag %parse_nettype; + addrtype = any* >tag %parse_addrtype; + addr = any* >tag %parse_addr; + C = 'c' SP* "=" SP*<: nettype :>SP addrtype :>SP addr; + + # Entry point + main := C :>CRLF?; + +}%% + + +tsdp_header_C_t* tsdp_header_c_create(const char* nettype, const char* addrtype, const char* addr) +{ + return tsk_object_new(TSDP_HEADER_C_VA_ARGS(nettype, addrtype, addr)); +} + +tsdp_header_C_t* tsdp_header_c_create_null() +{ + return tsdp_header_c_create(tsk_null, tsk_null, tsk_null); +} + +int tsdp_header_C_tostring(const tsdp_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsdp_header_C_t *C = (const tsdp_header_C_t *)header; + + return tsk_buffer_append_2(output, "%s %s %s", + C->nettype, + C->addrtype, + C->addr + ); + + return 0; + } + + return -1; +} + +tsdp_header_t* tsdp_header_C_clone(const tsdp_header_t* header) +{ + if(header){ + const tsdp_header_C_t *C = (const tsdp_header_C_t *)header; + return (tsdp_header_t*)tsdp_header_c_create(C->nettype, C->addrtype, C->addr); + } + return tsk_null; +} + +tsdp_header_C_t *tsdp_header_C_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsdp_header_C_t *hdr_C = tsdp_header_c_create_null(); + + const char *tag_start = tsk_null; + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + %%write data; + (void)(tsdp_machine_parser_header_C_first_final); + (void)(tsdp_machine_parser_header_C_error); + (void)(tsdp_machine_parser_header_C_en_main); + %%write init; + %%write exec; + TSK_RAGEL_DISABLE_WARNINGS_END() + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse \"c=\" header."); + TSK_OBJECT_SAFE_FREE(hdr_C); + } + + return hdr_C; +} + + + + + + + +//======================================================== +// E header object definition +// + +static tsk_object_t* tsdp_header_C_ctor(tsk_object_t *self, va_list * app) +{ + tsdp_header_C_t *C = self; + if(C){ + TSDP_HEADER(C)->type = tsdp_htype_C; + TSDP_HEADER(C)->tostring = tsdp_header_C_tostring; + TSDP_HEADER(C)->clone = tsdp_header_C_clone; + TSDP_HEADER(C)->rank = TSDP_HTYPE_C_RANK; + + C->nettype = tsk_strdup(va_arg(*app, const char*)); + C->addrtype = tsk_strdup(va_arg(*app, const char*)); + C->addr = tsk_strdup(va_arg(*app, const char*)); + } + else{ + TSK_DEBUG_ERROR("Failed to create new C header."); + } + return self; +} + +static tsk_object_t* tsdp_header_C_dtor(tsk_object_t *self) +{ + tsdp_header_C_t *C = self; + if(C){ + TSK_FREE(C->nettype); + TSK_FREE(C->addrtype); + TSK_FREE(C->addr); + } + else{ + TSK_DEBUG_ERROR("Null PC header."); + } + + return self; +} +static int tsdp_header_C_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) +{ + if(obj1 && obj2){ + return tsdp_header_rank_cmp(obj1, obj2); + } + else{ + return -1; + } +} + +static const tsk_object_def_t tsdp_header_C_def_s = +{ + sizeof(tsdp_header_C_t), + tsdp_header_C_ctor, + tsdp_header_C_dtor, + tsdp_header_C_cmp +}; + +const tsk_object_def_t *tsdp_header_C_def_t = &tsdp_header_C_def_s; diff --git a/tinySDP/ragel/tsdp_parser_header_Dummy.rl b/tinySDP/ragel/tsdp_parser_header_Dummy.rl new file mode 100644 index 0000000..61c27f4 --- /dev/null +++ b/tinySDP/ragel/tsdp_parser_header_Dummy.rl @@ -0,0 +1,183 @@ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_header_Dummy.c + * @brief SDP Dummy header. + */ +#include "tinysdp/headers/tsdp_header_Dummy.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_string.h" + +#include <string.h> + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsdp_machine_parser_header_Dummy; + + # Includes + include tsdp_machine_utils "./ragel/tsdp_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_name{ + hdr_Dummy->name = *tag_start; + } + + action parse_value{ + TSK_PARSER_SET_STRING(hdr_Dummy->value); + } + + Dummy = alpha>tag %parse_name SP* "=" SP*<: any*>tag %parse_value; + + # Entry point + main := Dummy :>CRLF?; + +}%% + + + +tsdp_header_Dummy_t* tsdp_header_dummy_create(char name, const char* value) +{ + return tsk_object_new(TSDP_HEADER_DUMMY_VA_ARGS(name, value)); +} + +tsdp_header_Dummy_t* tsdp_header_dummy_create_null() +{ + return tsdp_header_dummy_create(0, tsk_null); +} + +int tsdp_header_Dummy_tostring(const tsdp_header_t* header, tsk_buffer_t* output) +{ + if(header) + { + const tsdp_header_Dummy_t *Dummy = (const tsdp_header_Dummy_t *)header; + if(Dummy->value){ + return tsk_buffer_append(output, Dummy->value, tsk_strlen(Dummy->value)); + } + return 0; + } + + return -1; +} + +tsdp_header_t* tsdp_header_Dummy_clone(const tsdp_header_t* header) +{ + if(header){ + const tsdp_header_Dummy_t *Dummy = (const tsdp_header_Dummy_t *)header; + return (tsdp_header_t*)tsdp_header_dummy_create(Dummy->name, Dummy->value); + } + return tsk_null; +} + +tsdp_header_Dummy_t *tsdp_header_Dummy_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsdp_header_Dummy_t *hdr_Dummy = tsdp_header_dummy_create_null(); + + const char *tag_start = tsk_null; + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + %%write data; + (void)(tsdp_machine_parser_header_Dummy_first_final); + (void)(tsdp_machine_parser_header_Dummy_error); + (void)(tsdp_machine_parser_header_Dummy_en_main); + %%write init; + %%write exec; + TSK_RAGEL_DISABLE_WARNINGS_END() + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse dummy header."); + TSK_OBJECT_SAFE_FREE(hdr_Dummy); + } + + return hdr_Dummy; +} + + + + + + + +//======================================================== +// Dummy header object definition +// + +static tsk_object_t* tsdp_header_Dummy_ctor(tsk_object_t *self, va_list * app) +{ + tsdp_header_Dummy_t *Dummy = self; + if(Dummy){ + TSDP_HEADER(Dummy)->type = tsdp_htype_Dummy; + TSDP_HEADER(Dummy)->tostring = tsdp_header_Dummy_tostring; + TSDP_HEADER(Dummy)->clone = tsdp_header_Dummy_clone; + TSDP_HEADER(Dummy)->rank = TSDP_HTYPE_DUMMY_RANK; +#if defined(__GNUC__) + Dummy->name = va_arg(*app, const int); +#else + Dummy->name = va_arg(*app, const char); +#endif + Dummy->value = tsk_strdup(va_arg(*app, const char*)); + } + else{ + TSK_DEBUG_ERROR("Failed to create new Dummy header."); + } + return self; +} + +static tsk_object_t* tsdp_header_Dummy_dtor(tsk_object_t *self) +{ + tsdp_header_Dummy_t *Dummy = self; + if(Dummy){ + TSK_FREE(Dummy->value); + } + else{ + TSK_DEBUG_ERROR("Null Dummy header."); + } + + return self; +} +static int tsdp_header_Dummy_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) +{ + if(obj1 && obj2){ + return tsdp_header_rank_cmp(obj1, obj2); + } + else{ + return -1; + } +} + +static const tsk_object_def_t tsdp_header_Dummy_def_s = +{ + sizeof(tsdp_header_Dummy_t), + tsdp_header_Dummy_ctor, + tsdp_header_Dummy_dtor, + tsdp_header_Dummy_cmp +}; + +const tsk_object_def_t *tsdp_header_Dummy_def_t = &tsdp_header_Dummy_def_s; diff --git a/tinySDP/ragel/tsdp_parser_header_E.rl b/tinySDP/ragel/tsdp_parser_header_E.rl new file mode 100644 index 0000000..60ca08d --- /dev/null +++ b/tinySDP/ragel/tsdp_parser_header_E.rl @@ -0,0 +1,175 @@ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + + +/**@file tsdp_header_E.c + * @brief SDP "e=" header (Session Information). + */ +#include "tinysdp/headers/tsdp_header_E.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_string.h" + +#include <string.h> + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsdp_machine_parser_header_E; + + # Includes + include tsdp_machine_utils "./ragel/tsdp_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_value{ + TSK_PARSER_SET_STRING(hdr_E->value); + } + + E = 'e' SP* "=" SP*<: any*>tag %parse_value; + + # Entry point + main := E :>CRLF?; + +}%% + + + +tsdp_header_E_t* tsdp_header_E_create(const char* value) +{ + return tsk_object_new(TSDP_HEADER_E_VA_ARGS(value)); +} + +tsdp_header_E_t* tsdp_header_E_create_null() +{ + return tsdp_header_E_create(tsk_null); +} + +int tsdp_header_E_tostring(const tsdp_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsdp_header_E_t *E = (const tsdp_header_E_t *)header; + if(E->value){ + tsk_buffer_append(output, E->value, tsk_strlen(E->value)); + } + return 0; + } + + return -1; +} + +tsdp_header_t* tsdp_header_E_clone(const tsdp_header_t* header) +{ + if(header){ + const tsdp_header_E_t *E = (const tsdp_header_E_t *)header; + return (tsdp_header_t*)tsdp_header_E_create(E->value); + } + return tsk_null; +} + +tsdp_header_E_t *tsdp_header_E_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsdp_header_E_t *hdr_E = tsdp_header_E_create_null(); + + const char *tag_start = tsk_null; + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + %%write data; + (void)(tsdp_machine_parser_header_E_first_final); + (void)(tsdp_machine_parser_header_E_error); + (void)(tsdp_machine_parser_header_E_en_main); + %%write init; + %%write exec; + TSK_RAGEL_DISABLE_WARNINGS_END() + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse \"e=\" header."); + TSK_OBJECT_SAFE_FREE(hdr_E); + } + + return hdr_E; +} + + + + + + + +//======================================================== +// E header object definition +// + +static tsk_object_t* tsdp_header_E_ctor(tsk_object_t *self, va_list * app) +{ + tsdp_header_E_t *E = self; + if(E){ + TSDP_HEADER(E)->type = tsdp_htype_E; + TSDP_HEADER(E)->tostring = tsdp_header_E_tostring; + TSDP_HEADER(E)->clone = tsdp_header_E_clone; + TSDP_HEADER(E)->rank = TSDP_HTYPE_E_RANK; + + E->value = tsk_strdup(va_arg(*app, const char*)); + } + else{ + TSK_DEBUG_ERROR("Failed to create new E header."); + } + return self; +} + +static tsk_object_t* tsdp_header_E_dtor(tsk_object_t *self) +{ + tsdp_header_E_t *E = self; + if(E){ + TSK_FREE(E->value); + } + else{ + TSK_DEBUG_ERROR("Null E header."); + } + + return self; +} +static int tsdp_header_E_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) +{ + if(obj1 && obj2){ + return tsdp_header_rank_cmp(obj1, obj2); + } + else{ + return -1; + } +} + +static const tsk_object_def_t tsdp_header_E_def_s = +{ + sizeof(tsdp_header_E_t), + tsdp_header_E_ctor, + tsdp_header_E_dtor, + tsdp_header_E_cmp +}; + +const tsk_object_def_t *tsdp_header_E_def_t = &tsdp_header_E_def_s; diff --git a/tinySDP/ragel/tsdp_parser_header_I.rl b/tinySDP/ragel/tsdp_parser_header_I.rl new file mode 100644 index 0000000..7804ba7 --- /dev/null +++ b/tinySDP/ragel/tsdp_parser_header_I.rl @@ -0,0 +1,176 @@ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + + +/**@file tsdp_header_I.c + * @brief SDP "i=" header (Session Information). + */ +#include "tinysdp/headers/tsdp_header_I.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_string.h" + +#include <string.h> + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsdp_machine_parser_header_I; + + # Includes + include tsdp_machine_utils "./ragel/tsdp_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_value{ + TSK_PARSER_SET_STRING(hdr_I->value); + } + + I = 'i' SP* "=" SP*<: any*>tag %parse_value; + + # Entry point + main := I :>CRLF?; + +}%% + + +tsdp_header_I_t* tsdp_header_I_create(const char* value) +{ + return tsk_object_new(TSDP_HEADER_I_VA_ARGS(value)); +} + +tsdp_header_I_t* tsdp_header_I_create_null() +{ + return tsdp_header_I_create(tsk_null); +} + +int tsdp_header_I_tostring(const tsdp_header_t* header, tsk_buffer_t* output) +{ + if(header) + { + const tsdp_header_I_t *I = (const tsdp_header_I_t *)header; + if(I->value){ + tsk_buffer_append(output, I->value, tsk_strlen(I->value)); + } + return 0; + } + + return -1; +} + +tsdp_header_t* tsdp_header_I_clone(const tsdp_header_t* header) +{ + if(header){ + const tsdp_header_I_t *I = (const tsdp_header_I_t *)header; + return (tsdp_header_t*)tsdp_header_I_create(I->value); + } + return tsk_null; +} + +tsdp_header_I_t *tsdp_header_I_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsdp_header_I_t *hdr_I = tsdp_header_I_create_null(); + + const char *tag_start = tsk_null; + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + %%write data; + (void)(tsdp_machine_parser_header_I_first_final); + (void)(tsdp_machine_parser_header_I_error); + (void)(tsdp_machine_parser_header_I_en_main); + %%write init; + %%write exec; + TSK_RAGEL_DISABLE_WARNINGS_END() + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse \"i=\" header."); + TSK_OBJECT_SAFE_FREE(hdr_I); + } + + return hdr_I; +} + + + + + + + +//======================================================== +// I header object definition +// + +static tsk_object_t* tsdp_header_I_ctor(tsk_object_t *self, va_list * app) +{ + tsdp_header_I_t *I = self; + if(I) + { + TSDP_HEADER(I)->type = tsdp_htype_I; + TSDP_HEADER(I)->tostring = tsdp_header_I_tostring; + TSDP_HEADER(I)->clone = tsdp_header_I_clone; + TSDP_HEADER(I)->rank = TSDP_HTYPE_I_RANK; + + I->value = tsk_strdup(va_arg(*app, const char*)); + } + else{ + TSK_DEBUG_ERROR("Failed to create new I header."); + } + return self; +} + +static tsk_object_t* tsdp_header_I_dtor(tsk_object_t *self) +{ + tsdp_header_I_t *I = self; + if(I){ + TSK_FREE(I->value); + } + else{ + TSK_DEBUG_ERROR("Null I header."); + } + + return self; +} +static int tsdp_header_I_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) +{ + if(obj1 && obj2){ + return tsdp_header_rank_cmp(obj1, obj2); + } + else{ + return -1; + } +} + +static const tsk_object_def_t tsdp_header_I_def_s = +{ + sizeof(tsdp_header_I_t), + tsdp_header_I_ctor, + tsdp_header_I_dtor, + tsdp_header_I_cmp +}; + +const tsk_object_def_t *tsdp_header_I_def_t = &tsdp_header_I_def_s; diff --git a/tinySDP/ragel/tsdp_parser_header_K.rl b/tinySDP/ragel/tsdp_parser_header_K.rl new file mode 100644 index 0000000..5514d20 --- /dev/null +++ b/tinySDP/ragel/tsdp_parser_header_K.rl @@ -0,0 +1,175 @@ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + + +/**@file tsdp_header_K.c + * @brief SDP "k=" header (Encryption Key). + */ +#include "tinysdp/headers/tsdp_header_K.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_string.h" + +#include <string.h> + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsdp_machine_parser_header_K; + + # Includes + include tsdp_machine_utils "./ragel/tsdp_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_value{ + TSK_PARSER_SET_STRING(hdr_K->value); + } + + K = 'k' SP* "=" SP*<: any*>tag %parse_value; + + # Entry point + main := K :>CRLF?; + +}%% + + + +tsdp_header_K_t* tsdp_header_K_create(const char* value) +{ + return tsk_object_new(TSDP_HEADER_K_VA_ARGS(value)); +} + +tsdp_header_K_t* tsdp_header_K_create_null() +{ + return tsdp_header_K_create(tsk_null); +} + +int tsdp_header_K_tostring(const tsdp_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsdp_header_K_t *K = (const tsdp_header_K_t *)header; + if(K->value){ + tsk_buffer_append(output, K->value, tsk_strlen(K->value)); + } + return 0; + } + + return -1; +} + +tsdp_header_t* tsdp_header_K_clone(const tsdp_header_t* header) +{ + if(header){ + const tsdp_header_K_t *K = (const tsdp_header_K_t *)header; + return (tsdp_header_t*)tsdp_header_K_create(K->value); + } + return tsk_null; +} + +tsdp_header_K_t *tsdp_header_K_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsdp_header_K_t *hdr_K = tsdp_header_K_create_null(); + + const char *tag_start = tsk_null; + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + %%write data; + (void)(tsdp_machine_parser_header_K_first_final); + (void)(tsdp_machine_parser_header_K_error); + (void)(tsdp_machine_parser_header_K_en_main); + %%write init; + %%write exec; + TSK_RAGEL_DISABLE_WARNINGS_END() + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse \"k=\" header."); + TSK_OBJECT_SAFE_FREE(hdr_K); + } + + return hdr_K; +} + + + + + + + +//======================================================== +// K header object definition +// + +static tsk_object_t* tsdp_header_K_ctor(tsk_object_t *self, va_list * app) +{ + tsdp_header_K_t *K = self; + if(K){ + TSDP_HEADER(K)->type = tsdp_htype_K; + TSDP_HEADER(K)->tostring = tsdp_header_K_tostring; + TSDP_HEADER(K)->clone = tsdp_header_K_clone; + TSDP_HEADER(K)->rank = TSDP_HTYPE_P_RANK; + + K->value = tsk_strdup(va_arg(*app, const char*)); + } + else{ + TSK_DEBUG_ERROR("Failed to create new K header."); + } + return self; +} + +static tsk_object_t* tsdp_header_K_dtor(tsk_object_t *self) +{ + tsdp_header_K_t *K = self; + if(K){ + TSK_FREE(K->value); + } + else{ + TSK_DEBUG_ERROR("Null K header."); + } + + return self; +} +static int tsdp_header_K_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) +{ + if(obj1 && obj2){ + return tsdp_header_rank_cmp(obj1, obj2); + } + else{ + return -1; + } +} + +static const tsk_object_def_t tsdp_header_K_def_s = +{ + sizeof(tsdp_header_K_t), + tsdp_header_K_ctor, + tsdp_header_K_dtor, + tsdp_header_K_cmp +}; + +const tsk_object_def_t *tsdp_header_K_def_t = &tsdp_header_K_def_s; diff --git a/tinySDP/ragel/tsdp_parser_header_M.rl b/tinySDP/ragel/tsdp_parser_header_M.rl new file mode 100644 index 0000000..02b2fe4 --- /dev/null +++ b/tinySDP/ragel/tsdp_parser_header_M.rl @@ -0,0 +1,723 @@ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + + +/**@file tsdp_header_M.c + * @brief SDP "m=" header (Media Descriptions). + * + */ +#include "tinysdp/headers/tsdp_header_M.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_string.h" + +#include <string.h> + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsdp_machine_parser_header_M; + + # Includes + include tsdp_machine_utils "./ragel/tsdp_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_media{ + TSK_PARSER_SET_STRING(hdr_M->media); + } + + action parse_port{ + TSK_PARSER_SET_UINT(hdr_M->port); + } + + action parse_nports{ + TSK_PARSER_SET_UINT(hdr_M->nports); + } + + action parse_proto{ + TSK_PARSER_SET_STRING(hdr_M->proto); + } + + action parse_fmt{ + TSK_PARSER_ADD_STRING(hdr_M->FMTs); + } + + media = token>tag %parse_media; + port = DIGIT+>tag %parse_port; + nports = DIGIT+>tag %parse_port; + proto = (token ("/" token)*)>tag %parse_proto; + fmt = token>tag %parse_fmt; + + #// media SP port ["/" integer] SP proto 1*(SP fmt) + M = 'm' SP* "=" SP*<: media SP port ("/" nports)? SP proto (SP fmt)* (SP{1})?; # The last SP is for buggy browsers (e.g. Nightly 20.0a1 => "m=application 51713 SCTP/DTLS 5000 \r\n") + + # Entry point + main := M :>CRLF?; +}%% + + + +tsdp_header_M_t* tsdp_header_M_create(const char* media, uint32_t port, const char* proto) +{ + return tsk_object_new(TSDP_HEADER_M_VA_ARGS(media, port, proto)); +} + +tsdp_header_M_t* tsdp_header_M_create_null() +{ + return tsdp_header_M_create(tsk_null, 0, tsk_null); +} + +tsdp_fmt_t* tsdp_fmt_create(const char* fmt) +{ + return tsk_object_new(TSDP_FMT_VA_ARGS(fmt)); +} + + +int tsdp_header_M_tostring(const tsdp_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsdp_header_M_t *M = (const tsdp_header_M_t *)header; + const tsk_list_item_t* item; + tsk_istr_t nports; + + tsk_itoa(M->nports, &nports); + + /* IMPORTANT: Keep the order. + + m= (media name and transport address) + i=* (media title) + c=* (connection information -- optional if included at + session level) + b=* (zero or more bandwidth information lines) + k=* (encryption key) + a=* (zero or more media attribute lines) + */ + tsk_buffer_append_2(output, "%s %u%s%s %s", + M->media, + M->port, + + M->nports ? "/" : "", + M->nports ? nports : "", + + M->proto + ); + // FMTs + tsk_list_foreach(item, M->FMTs){ + tsk_buffer_append_2(output, " %s", TSDP_FMT_STR(item->data)); + } + tsk_buffer_append(output, "\r\n", 2); // close the "m=" line. + // i=* (media title) + if(M->I){ + tsdp_header_serialize(TSDP_HEADER(M->I), output); + } + // c=* (connection information -- optional if included at session level) + if(M->C){ + tsdp_header_serialize(TSDP_HEADER(M->C), output); + } + // b=* (zero or more bandwidth information lines) + if(M->Bandwidths){ + tsk_list_foreach(item, M->Bandwidths){ + tsdp_header_serialize(TSDP_HEADER(item->data), output); + } + } + // k=* (encryption key) + if(M->K){ + tsdp_header_serialize(TSDP_HEADER(M->K), output); + } + // a=* (zero or more media attribute lines) + if(M->Attributes){ + tsk_list_foreach(item, M->Attributes){ + tsdp_header_serialize(TSDP_HEADER(item->data), output); + } + } + return 0; + } + + return -1; +} + +tsdp_header_t* tsdp_header_M_clone(const tsdp_header_t* header) +{ + if(header){ + const tsdp_header_M_t *M = (const tsdp_header_M_t *)header; + tsdp_header_M_t* clone; + const tsk_list_item_t* item; + + if((clone = tsdp_header_M_create(M->media, M->port, M->proto))){ + clone->nports = M->nports; + + // Formats + tsk_list_foreach(item, M->FMTs){ + tsk_string_t* string = tsk_string_create(TSK_STRING_STR(item->data)); + tsk_list_push_back_data(clone->FMTs, (void**)&string); + } + + // I + clone->I = (tsdp_header_I_t*) (M->I ? TSDP_HEADER(M->I)->clone(TSDP_HEADER(M->I)) : tsk_null); + // C + clone->C = (tsdp_header_C_t*) (M->C ? TSDP_HEADER(M->C)->clone(TSDP_HEADER(M->C)) : tsk_null); + // Bandwidths + tsk_list_foreach(item, M->Bandwidths){ + tsdp_header_t* B; + if(!clone->Bandwidths){ + clone->Bandwidths = tsk_list_create(); + } + B = ((tsdp_header_t*)item->data)->clone((tsdp_header_t*)item->data); + tsk_list_push_back_data(clone->Bandwidths, (void**)&B); + } + // K + clone->K = (tsdp_header_K_t*) (M->K ? TSDP_HEADER(M->K)->clone(TSDP_HEADER(M->K)) : tsk_null); + // Attributes + tsk_list_foreach(item, M->Attributes){ + tsdp_header_t* A; + if(!clone->Attributes){ + clone->Attributes = tsk_list_create(); + } + A = ((tsdp_header_t*)item->data)->clone((tsdp_header_t*)item->data); + tsk_list_push_back_data(clone->Attributes, (void**)&A); + } + } + + return TSDP_HEADER(clone); + } + return tsk_null; +} + +tsdp_header_M_t *tsdp_header_M_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsdp_header_M_t *hdr_M = tsdp_header_M_create_null(); + + const char *tag_start = tsk_null; + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + %%write data; + (void)(tsdp_machine_parser_header_M_first_final); + (void)(tsdp_machine_parser_header_M_error); + (void)(tsdp_machine_parser_header_M_en_main); + %%write init; + %%write exec; + TSK_RAGEL_DISABLE_WARNINGS_END() + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse \"m=\" header."); + TSK_OBJECT_SAFE_FREE(hdr_M); + } + + return hdr_M; +} + + +// for A headers, use "tsdp_header_A_removeAll_by_field()" +int tsdp_header_M_remove(tsdp_header_M_t* self, tsdp_header_type_t type) +{ + switch(type){ + case tsdp_htype_I: + { + TSK_OBJECT_SAFE_FREE(self->I); + break; + } + case tsdp_htype_C: + { + TSK_OBJECT_SAFE_FREE(self->C); + break; + } + case tsdp_htype_B: + { + if(self->Bandwidths){ + tsk_list_clear_items(self->Bandwidths); + } + break; + } + case tsdp_htype_K: + { + TSK_OBJECT_SAFE_FREE(self->K); + break; + } + } + return 0; +} + +int tsdp_header_M_add(tsdp_header_M_t* self, const tsdp_header_t* header) +{ + if(!self || !header){ + return -1; + } + + switch(header->type){ + case tsdp_htype_I: + { + TSK_OBJECT_SAFE_FREE(self->I); + self->I = tsk_object_ref((void*)header); + break; + } + case tsdp_htype_C: + { + TSK_OBJECT_SAFE_FREE(self->C); + self->C = tsk_object_ref((void*)header); + break; + } + case tsdp_htype_B: + { + tsdp_header_t* B = tsk_object_ref((void*)header); + if(!self->Bandwidths){ + self->Bandwidths = tsk_list_create(); + } + tsk_list_push_back_data(self->Bandwidths, (void**)&B); + break; + } + case tsdp_htype_K: + { + TSK_OBJECT_SAFE_FREE(self->K); + self->K = tsk_object_ref((void*)header); + break; + } + case tsdp_htype_A: + { + tsdp_header_t* A = tsk_object_ref((void*)header); + if(!self->Attributes){ + self->Attributes = tsk_list_create(); + } + tsk_list_push_back_data(self->Attributes, (void**)&A); + break; + } + } + + return 0; +} + +int tsdp_header_M_add_headers(tsdp_header_M_t* self, ...) +{ + const tsk_object_def_t* objdef; + tsdp_header_t *header; + tsdp_fmt_t* fmt; + va_list ap; + + if(!self){ + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + va_start(ap, self); + while((objdef = va_arg(ap, const tsk_object_def_t*))){ + if(objdef == tsdp_fmt_def_t){ + if((fmt = tsk_object_new_2(objdef, &ap))){ + tsk_list_push_back_data(self->FMTs, (void**)&fmt); + } + } + else{ + if((header = tsk_object_new_2(objdef, &ap))){ + tsdp_header_M_add(self, header); + TSK_OBJECT_SAFE_FREE(header); + } + } + } + va_end(ap); + + return 0; +} + +int tsdp_header_M_add_headers_2(tsdp_header_M_t* self, const tsdp_headers_L_t* headers) +{ + const tsk_list_item_t* item; + + if(!self || !headers){ + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + tsk_list_foreach(item, headers){ + tsdp_header_M_add(self, item->data); + } + + return 0; +} + +int tsdp_header_M_add_fmt(tsdp_header_M_t* self, const char* fmt) +{ + tsdp_fmt_t* _fmt; + if(!self || tsk_strnullORempty(fmt)){ + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + if((_fmt = tsdp_fmt_create(fmt))){ + tsk_list_push_back_data(self->FMTs, (void**)&_fmt); + return 0; + } + else{ + TSK_DEBUG_ERROR("Failed to create fmt object"); + return -2; + } +} + +int tsdp_header_M_remove_fmt(tsdp_header_M_t* self, const char* fmt) +{ + const tsk_list_item_t* itemM; + const tsdp_fmt_t* _fmt; + char* fmt_plus_space = tsk_null; + tsk_size_t fmt_plus_space_len; + if(!self || tsk_strnullORempty(fmt)){ + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + tsk_sprintf(&fmt_plus_space, "%s ", fmt); + if((fmt_plus_space_len = tsk_strlen(fmt_plus_space))){ + tsk_list_foreach(itemM, self->FMTs){ + if(!(_fmt = (const tsdp_fmt_t*)itemM->data)){ + continue; + } + if(tsk_striequals(_fmt->value, fmt)){ + // remove all A headers using this attribute + const tsdp_header_A_t* A; + const tsk_list_item_t* itemA; +removeAttributes: + tsk_list_foreach(itemA, self->Attributes){ + if(!(A = (const tsdp_header_A_t*)itemA->data)){ + continue; + } + if(tsk_strindexOf(A->value, fmt_plus_space_len, fmt_plus_space) == 0){ + // Guard to be sure we know what to remove. For example: + // tsdp_header_M_remove_fmt(self, 0) would remove both + // a=rtpmap:0 PCMU/8000/1 + // a=crypto:0 AES_CM_128_HMAC_SHA1_32 inline:Gi8s25tDKDnd/xORJ/ZtRWWC1drVbax5Ve4ftCWd + // and cause issue 115: https://code.google.com/p/webrtc2sip/issues/detail?id=115 + if(!tsk_striequals(A->field, "crypto")){ + tsk_list_remove_item(self->Attributes, (tsk_list_item_t*)itemA); + goto removeAttributes; + } + } + } + tsk_list_remove_item(self->FMTs, (tsk_list_item_t*)itemM); + break; + } + } + } + TSK_FREE(fmt_plus_space); + return 0; +} + +tsk_bool_t tsdp_header_M_have_fmt(tsdp_header_M_t* self, const char* fmt) +{ + if(self &&! tsk_strnullORempty(fmt)){ + const tsk_list_item_t* item; + const tsdp_fmt_t* _fmt; + tsk_list_foreach(item, self->FMTs){ + if(!(_fmt = (const tsdp_fmt_t*)item->data)){ + continue; + } + if(tsk_striequals(_fmt->value, fmt)){ + return tsk_true; + } + } + } + + return tsk_false; +} + +const tsdp_header_A_t* tsdp_header_M_findA_at(const tsdp_header_M_t* self, const char* field, tsk_size_t index) +{ + const tsk_list_item_t *item; + tsk_size_t pos = 0; + const tsdp_header_A_t* A; + + if(!self){ + TSK_DEBUG_ERROR("Invalid parameter"); + return tsk_null; + } + + tsk_list_foreach(item, self->Attributes){ + if(!(A = item->data)){ + continue; + } + + if(tsk_strequals(A->field, field)){ + if(pos++ >= index){ + return A; + } + } + } + + return tsk_null; +} + +const tsdp_header_A_t* tsdp_header_M_findA(const tsdp_header_M_t* self, const char* field) +{ + return tsdp_header_M_findA_at(self, field, 0); +} + +char* tsdp_header_M_getAValue(const tsdp_header_M_t* self, const char* field, const char* fmt) +{ + char *value = tsk_null; /* e.g. AMR-WB/16000 */ + tsk_size_t i = 0, fmt_len, A_len; + int indexof; + const tsdp_header_A_t* A; + + fmt_len = tsk_strlen(fmt); + if(!self || !fmt_len || fmt_len > 3/*'0-255' or '*'*/){ + TSK_DEBUG_ERROR("Invalid parameter"); + return tsk_null; + } + + /* find "a=rtpmap" */ + while((A = tsdp_header_M_findA_at(self, field, i++))){ + /* A->value would be: "98 AMR-WB/16000" */ + if((A_len = tsk_strlen(A->value)) < (fmt_len + 1/*space*/)){ + continue; + } + if((indexof = tsk_strindexOf(A->value, A_len, fmt)) == 0 && (A->value[fmt_len] == ' ')){ + value = tsk_strndup(&A->value[fmt_len+1], (A_len-(fmt_len+1))); + break; + } + } + return value; +} + +/* as per 3GPP TS 34.610 */ +int tsdp_header_M_hold(tsdp_header_M_t* self, tsk_bool_t local) +{ + const tsdp_header_A_t* a; + if(!self){ + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + if((a = tsdp_header_M_findA(self, local ? "recvonly" : "sendonly"))){ + // an "inactive" SDP attribute if the stream was previously set to "recvonly" media stream + tsk_strupdate(&(TSDP_HEADER_A(a)->field), local ? "inactive" : "recvonly"); + } + else if((a = tsdp_header_M_findA(self, "sendrecv"))){ + // a "sendonly" SDP attribute if the stream was previously set to "sendrecv" media stream + tsk_strupdate(&(TSDP_HEADER_A(a)->field), local ? "sendonly" : "recvonly"); + } + else{ + // default value is sendrecv. hold on default --> sendonly + if(!(a = tsdp_header_M_findA(self, local ? "sendonly" : "recvonly")) && !(a = tsdp_header_M_findA(self, "inactive"))){ + tsdp_header_A_t* newA; + if((newA = tsdp_header_A_create(local ? "sendonly" : "recvonly", tsk_null))){ + tsdp_header_M_add(self, TSDP_HEADER_CONST(newA)); + TSK_OBJECT_SAFE_FREE(newA); + } + } + } + return 0; +} + +/* as per 3GPP TS 34.610 */ +int tsdp_header_M_set_holdresume_att(tsdp_header_M_t* self, tsk_bool_t lo_held, tsk_bool_t ro_held) +{ + const tsdp_header_A_t* A; + static const char* hold_resume_atts[2][2] = + { + {"sendrecv", "recvonly"}, + {"sendonly", "inactive"}, + }; + if(!self){ + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + if((A = tsdp_header_M_findA(self, "sendrecv")) || (A = tsdp_header_M_findA(self, "sendonly")) || (A = tsdp_header_M_findA(self, "recvonly")) || (A = tsdp_header_M_findA(self, "inactive"))){ + tsk_strupdate(&(TSDP_HEADER_A(A)->field), hold_resume_atts[lo_held & 1][ro_held & 1]); + } + else{ + tsdp_header_A_t* newA; + if((newA = tsdp_header_A_create(hold_resume_atts[lo_held & 1][ro_held & 1], tsk_null))){ + tsdp_header_M_add(self, TSDP_HEADER_CONST(newA)); + TSK_OBJECT_SAFE_FREE(newA); + } + } + + return 0; +} + +const char* tsdp_header_M_get_holdresume_att(const tsdp_header_M_t* self) +{ + static const char* hold_resume_atts[4] = {"sendrecv"/*first because most likely to be present*/, "recvonly", "sendonly", "inactive"}; + static tsk_size_t hold_resume_atts_count = sizeof(hold_resume_atts)/sizeof(hold_resume_atts[0]); + tsk_size_t i; + if(!self){ + TSK_DEBUG_ERROR("Invalid parameter"); + return hold_resume_atts[0]; + } + for(i = 0; i < hold_resume_atts_count; ++i){ + if(tsdp_header_M_findA(self, hold_resume_atts[i])){ + return hold_resume_atts[i]; + } + } + return hold_resume_atts[0]; +} + +tsk_bool_t tsdp_header_M_is_held(const tsdp_header_M_t* self, tsk_bool_t local) +{ + if(!self){ + TSK_DEBUG_ERROR("Invalid parameter"); + return tsk_false; + } + + /* both cases */ + if(tsdp_header_M_findA(self, "inactive")){ + return tsk_true; + } + + if(local){ + return tsdp_header_M_findA(self, "recvonly") ? tsk_true : tsk_false; + } + else{ + return tsdp_header_M_findA(self, "sendonly") ? tsk_true : tsk_false; + } +} + +/* as per 3GPP TS 34.610 */ +int tsdp_header_M_resume(tsdp_header_M_t* self, tsk_bool_t local) +{ + const tsdp_header_A_t* a; + if(!self){ + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + if((a = tsdp_header_M_findA(self, "inactive"))){ + // a "recvonly" SDP attribute if the stream was previously an inactive media stream + tsk_strupdate(&(TSDP_HEADER_A(a)->field), local ? "recvonly" : "sendonly"); + } + else if((a = tsdp_header_M_findA(self, local ? "sendonly" : "recvonly"))){ + // a "sendrecv" SDP attribute if the stream was previously a sendonly media stream, or the attribute may be omitted, since sendrecv is the default + tsk_strupdate(&(TSDP_HEADER_A(a)->field), "sendrecv"); + } + return 0; +} + +// +//int tsdp_header_M_set(tsdp_header_M_t* self, ...) +//{ +// int ret = -1; +// va_list params; +// int type; +// +// va_start(params, self); +// +// if(!m){ +// goto bail; +// } +// +// while((type=va_arg(params, int))){ +// switch(type){ +// case 0x01: /* FMT */ +// { +// tsk_string_t* fmt = tsk_string_create(va_arg(values, const char *)); +// if(fmt){ +// tsk_list_push_back_data(sefl->FMTs, (void**)&fmt); +// } +// break; +// } +// case 0x02: /* A */ +// { +// tsdp_header_A_t* A = tsdp_header_A_create(va_arg(values, const char *), va_arg(values, const char *)); +// if(A){ +// if(!M->Attributes){ +// M->Attributes = tsk_list_create(); +// } +// tsk_list_push_back_data(M->Attributes, (void**)&A); +// } +// break; +// } +// } +// } +// +//bail: +// va_end(params); +// return ret; +//} + + + +//======================================================== +// M header object definition +// + +static tsk_object_t* tsdp_header_M_ctor(tsk_object_t *self, va_list * app) +{ + tsdp_header_M_t *M = self; + if(M){ + TSDP_HEADER(M)->type = tsdp_htype_M; + TSDP_HEADER(M)->tostring = tsdp_header_M_tostring; + TSDP_HEADER(M)->clone = tsdp_header_M_clone; + TSDP_HEADER(M)->rank = TSDP_HTYPE_M_RANK; + + M->FMTs = tsk_list_create(); // Because there is at least one fmt. + + M->media = tsk_strdup(va_arg(*app, const char*)); + M->port = va_arg(*app, uint32_t); + M->proto = tsk_strdup(va_arg(*app, const char*)); + } + else{ + TSK_DEBUG_ERROR("Failed to create new M header."); + } + return self; +} + +static tsk_object_t* tsdp_header_M_dtor(tsk_object_t *self) +{ + tsdp_header_M_t *M = self; + if(M){ + TSK_FREE(M->media); + TSK_FREE(M->proto); + TSK_OBJECT_SAFE_FREE(M->FMTs); + + TSK_OBJECT_SAFE_FREE(M->I); + TSK_OBJECT_SAFE_FREE(M->C); + TSK_OBJECT_SAFE_FREE(M->Bandwidths); + TSK_OBJECT_SAFE_FREE(M->K); + TSK_OBJECT_SAFE_FREE(M->Attributes); + } + else{ + TSK_DEBUG_ERROR("Null M header."); + } + + return self; +} +static int tsdp_header_M_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) +{ + if(obj1 && obj2){ + return tsdp_header_rank_cmp(obj1, obj2); + } + else{ + return -1; + } +} + +static const tsk_object_def_t tsdp_header_M_def_s = +{ + sizeof(tsdp_header_M_t), + tsdp_header_M_ctor, + tsdp_header_M_dtor, + tsdp_header_M_cmp +}; + +const tsk_object_def_t *tsdp_header_M_def_t = &tsdp_header_M_def_s; diff --git a/tinySDP/ragel/tsdp_parser_header_O.rl b/tinySDP/ragel/tsdp_parser_header_O.rl new file mode 100644 index 0000000..405676e --- /dev/null +++ b/tinySDP/ragel/tsdp_parser_header_O.rl @@ -0,0 +1,223 @@ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_header_O.c + * @brief SDP "o=" header (Origin). + */ +#include "tinysdp/headers/tsdp_header_O.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_string.h" + +#include <string.h> + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsdp_machine_parser_header_O; + + # Includes + include tsdp_machine_utils "./ragel/tsdp_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_username{ + TSK_PARSER_SET_STRING(hdr_O->username); + } + + action parse_sess_id{ + TSK_PARSER_SET_UINT(hdr_O->sess_id); + } + + action parse_sess_version{ + TSK_PARSER_SET_UINT(hdr_O->sess_version); + } + + action parse_nettype{ + TSK_PARSER_SET_STRING(hdr_O->nettype); + } + + action parse_addrtype{ + TSK_PARSER_SET_STRING(hdr_O->addrtype); + } + + action parse_addr{ + TSK_PARSER_SET_STRING(hdr_O->addr); + } + + username = any*>tag %parse_username; + sess_id = DIGIT+>tag %parse_sess_id; + sess_version = DIGIT+>tag %parse_sess_version; + nettype = any*>tag %parse_nettype; + addrtype = any*>tag %parse_addrtype; + addr = any*>tag %parse_addr; + O = 'o' SP* "=" SP*<: username :>SP sess_id :>SP sess_version :>SP nettype :>SP addrtype :>SP addr; + + # Entry point + main := O :>CRLF?; + +}%% + + + + +tsdp_header_O_t* tsdp_header_O_create(const char* username, uint32_t sess_id, uint32_t sess_version, const char* nettype, const char* addrtype, const char* addr) +{ + return tsk_object_new(TSDP_HEADER_O_VA_ARGS(username, sess_id, sess_version, nettype, addrtype, addr)); +} + +tsdp_header_O_t* tsdp_header_O_create_null() +{ + return tsdp_header_O_create(tsk_null, 0, 0, tsk_null, tsk_null, tsk_null); +} + +tsdp_header_O_t* tsdp_header_O_create_default(const char* username, const char* nettype, const char* addrtype, const char* addr) +{ + return tsdp_header_O_create(username, TSDP_HEADER_O_SESS_ID_DEFAULT, TSDP_HEADER_O_SESS_VERSION_DEFAULT, nettype, addrtype, addr); +} + + +int tsdp_header_O_tostring(const tsdp_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsdp_header_O_t *O = (const tsdp_header_O_t *)header; + + // o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com + return tsk_buffer_append_2(output, "%s %u %u %s %s %s", + O->username, + O->sess_id, + O->sess_version, + O->nettype, + O->addrtype, + O->addr + ); + + return 0; + } + + return -1; +} + +tsdp_header_t* tsdp_header_O_clone(const tsdp_header_t* header) +{ + if(header){ + const tsdp_header_O_t *O = (const tsdp_header_O_t *)header; + return (tsdp_header_t*)tsdp_header_O_create(O->username, O->sess_id, O->sess_version, O->nettype, O->addrtype, O->addr); + } + return tsk_null; +} + +tsdp_header_O_t *tsdp_header_O_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsdp_header_O_t *hdr_O = tsdp_header_O_create_null(); + + const char *tag_start = tsk_null; + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + %%write data; + (void)(tsdp_machine_parser_header_O_first_final); + (void)(tsdp_machine_parser_header_O_error); + (void)(tsdp_machine_parser_header_O_en_main); + %%write init; + %%write exec; + TSK_RAGEL_DISABLE_WARNINGS_END() + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse \"o=\" header."); + TSK_OBJECT_SAFE_FREE(hdr_O); + } + + return hdr_O; +} + + + + + + + +//======================================================== +// O header object definition +// + +static tsk_object_t* tsdp_header_O_ctor(tsk_object_t *self, va_list * app) +{ + tsdp_header_O_t *O = self; + if(O){ + TSDP_HEADER(O)->type = tsdp_htype_O; + TSDP_HEADER(O)->tostring = tsdp_header_O_tostring; + TSDP_HEADER(O)->clone = tsdp_header_O_clone; + TSDP_HEADER(O)->rank = TSDP_HTYPE_O_RANK; + + O->username = tsk_strdup(va_arg(*app, const char*)); + O->sess_id = va_arg(*app, uint32_t); + O->sess_version = va_arg(*app, uint32_t); + O->nettype = tsk_strdup(va_arg(*app, const char*)); + O->addrtype = tsk_strdup(va_arg(*app, const char*)); + O->addr = tsk_strdup(va_arg(*app, const char*)); + } + else{ + TSK_DEBUG_ERROR("Failed to create new O header."); + } + return self; +} + +static tsk_object_t* tsdp_header_O_dtor(tsk_object_t *self) +{ + tsdp_header_O_t *O = self; + if(O){ + TSK_FREE(O->username); + TSK_FREE(O->nettype); + TSK_FREE(O->addrtype); + TSK_FREE(O->addr); + } + else{ + TSK_DEBUG_ERROR("Null O header."); + } + + return self; +} +static int tsdp_header_O_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) +{ + if(obj1 && obj2){ + return tsdp_header_rank_cmp(obj1, obj2); + } + else{ + return -1; + } +} + +static const tsk_object_def_t tsdp_header_O_def_s = +{ + sizeof(tsdp_header_O_t), + tsdp_header_O_ctor, + tsdp_header_O_dtor, + tsdp_header_O_cmp +}; + +const tsk_object_def_t *tsdp_header_O_def_t = &tsdp_header_O_def_s; diff --git a/tinySDP/ragel/tsdp_parser_header_P.rl b/tinySDP/ragel/tsdp_parser_header_P.rl new file mode 100644 index 0000000..949c892 --- /dev/null +++ b/tinySDP/ragel/tsdp_parser_header_P.rl @@ -0,0 +1,174 @@ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + + +/**@file tsdp_header_P.c + * @brief SDP "p=" header (Phone Number). + */ +#include "tinysdp/headers/tsdp_header_P.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_string.h" + +#include <string.h> + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsdp_machine_parser_header_P; + + # Includes + include tsdp_machine_utils "./ragel/tsdp_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_value{ + TSK_PARSER_SET_STRING(hdr_P->value); + } + + P = 'p' SP* "=" SP*<: any*>tag %parse_value; + + # Entry point + main := P :>CRLF?; + +}%% + + +tsdp_header_P_t* tsdp_header_P_create(const char* value) +{ + return tsk_object_new(TSDP_HEADER_P_VA_ARGS(value)); +} + +tsdp_header_P_t* tsdp_header_P_create_null() +{ + return tsdp_header_P_create(tsk_null); +} + +int tsdp_header_P_tostring(const tsdp_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsdp_header_P_t *P = (const tsdp_header_P_t *)header; + if(P->value){ + tsk_buffer_append(output, P->value, tsk_strlen(P->value)); + } + return 0; + } + + return -1; +} + +tsdp_header_t* tsdp_header_P_clone(const tsdp_header_t* header) +{ + if(header){ + const tsdp_header_P_t *P = (const tsdp_header_P_t *)header; + return (tsdp_header_t*)tsdp_header_P_create(P->value); + } + return tsk_null; +} + +tsdp_header_P_t *tsdp_header_P_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsdp_header_P_t *hdr_P = tsdp_header_P_create_null(); + + const char *tag_start = tsk_null; + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + %%write data; + (void)(tsdp_machine_parser_header_P_first_final); + (void)(tsdp_machine_parser_header_P_error); + (void)(tsdp_machine_parser_header_P_en_main); + %%write init; + %%write exec; + TSK_RAGEL_DISABLE_WARNINGS_END() + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse \"p=\" header."); + TSK_OBJECT_SAFE_FREE(hdr_P); + } + + return hdr_P; +} + + + + + + + +//======================================================== +// P header object definition +// + +static tsk_object_t* tsdp_header_P_ctor(tsk_object_t *self, va_list * app) +{ + tsdp_header_P_t *P = self; + if(P){ + TSDP_HEADER(P)->type = tsdp_htype_P; + TSDP_HEADER(P)->tostring = tsdp_header_P_tostring; + TSDP_HEADER(P)->clone = tsdp_header_P_clone; + TSDP_HEADER(P)->rank = TSDP_HTYPE_P_RANK; + + P->value = tsk_strdup(va_arg(*app, const char*)); + } + else{ + TSK_DEBUG_ERROR("Failed to create new P header."); + } + return self; +} + +static tsk_object_t* tsdp_header_P_dtor(tsk_object_t *self) +{ + tsdp_header_P_t *P = self; + if(P){ + TSK_FREE(P->value); + } + else{ + TSK_DEBUG_ERROR("Null P header."); + } + + return self; +} +static int tsdp_header_P_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) +{ + if(obj1 && obj2){ + return tsdp_header_rank_cmp(obj1, obj2); + } + else{ + return -1; + } +} + +static const tsk_object_def_t tsdp_header_P_def_s = +{ + sizeof(tsdp_header_P_t), + tsdp_header_P_ctor, + tsdp_header_P_dtor, + tsdp_header_P_cmp +}; + +const tsk_object_def_t *tsdp_header_P_def_t = &tsdp_header_P_def_s; diff --git a/tinySDP/ragel/tsdp_parser_header_R.rl b/tinySDP/ragel/tsdp_parser_header_R.rl new file mode 100644 index 0000000..22507b3 --- /dev/null +++ b/tinySDP/ragel/tsdp_parser_header_R.rl @@ -0,0 +1,215 @@ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + + +/**@file tsdp_header_R.c + * @brief SDP "r=" header (Repeat Times). + * + */ +#include "tinysdp/headers/tsdp_header_R.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_string.h" + +#include <string.h> + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsdp_machine_parser_header_R; + + # Includes + include tsdp_machine_utils "./ragel/tsdp_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_repeat_interval{ + TSK_PARSER_SET_STRING(hdr_R->repeat_interval); + } + + action parse_typed_time{ + if(!hdr_R->typed_time){ + TSK_PARSER_SET_STRING(hdr_R->typed_time); + } + else{ + TSK_PARSER_ADD_STRING(hdr_R->typed_times); + } + } + + fixed_len_time_unit = "d" | "h" | "m" | "s"; + + repeat_interval = (DIGIT+ fixed_len_time_unit?) >tag %parse_repeat_interval; + typed_time = (DIGIT+ fixed_len_time_unit?) >tag %parse_typed_time; + + R = 'r' SP* "=" SP*<: repeat_interval :>SP typed_time (SP<: typed_time)+; + + # Entry point + main := R :>CRLF?; + +}%% + + + +tsdp_header_R_t* tsdp_header_R_create() +{ + return tsk_object_new(TSDP_HEADER_R_VA_ARGS()); +} + +tsdp_header_R_t* tsdp_header_R_create_null() +{ + return tsdp_header_R_create(); +} + +int tsdp_header_R_tostring(const tsdp_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsdp_header_R_t *R = (const tsdp_header_R_t *)header; + const tsk_list_item_t* item; + + // r=7d 1h 0 25h + tsk_buffer_append_2(output, "%s %s", + R->repeat_interval, + R->typed_time + ); + tsk_list_foreach(item, R->typed_times){ + tsk_string_t* string = item->data; + tsk_buffer_append_2(output, " %s", TSK_STRING_STR(string)); + } + + return 0; + } + + return -1; +} + +tsdp_header_t* tsdp_header_R_clone(const tsdp_header_t* header) +{ + if(header){ + const tsdp_header_R_t *R = (const tsdp_header_R_t *)header; + tsdp_header_R_t* clone; + const tsk_list_item_t* item; + + if((clone = tsdp_header_R_create_null())){ + clone->repeat_interval = tsk_strdup(R->repeat_interval); + clone->typed_time = tsk_strdup(R->typed_time); + + if(R->typed_times){ + clone->typed_times = tsk_list_create(); + } + + tsk_list_foreach(item, R->typed_times){ + tsk_string_t* string = tsk_string_create(TSK_STRING_STR(item->data)); + tsk_list_push_back_data(clone->typed_times, (void**)&string); + } + } + return TSDP_HEADER(clone); + } + return tsk_null; +} + +tsdp_header_R_t *tsdp_header_R_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsdp_header_R_t *hdr_R = tsdp_header_R_create_null(); + + const char *tag_start = tsk_null; + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + %%write data; + (void)(tsdp_machine_parser_header_R_first_final); + (void)(tsdp_machine_parser_header_R_error); + (void)(tsdp_machine_parser_header_R_en_main); + %%write init; + %%write exec; + TSK_RAGEL_DISABLE_WARNINGS_END() + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse \"r=\" header."); + TSK_OBJECT_SAFE_FREE(hdr_R); + } + + return hdr_R; +} + + + + + + + +//======================================================== +// E header object definition +// + +static tsk_object_t* tsdp_header_R_ctor(tsk_object_t *self, va_list * app) +{ + tsdp_header_R_t *R = self; + if(R){ + TSDP_HEADER(R)->type = tsdp_htype_R; + TSDP_HEADER(R)->tostring = tsdp_header_R_tostring; + TSDP_HEADER(R)->clone = tsdp_header_R_clone; + TSDP_HEADER(R)->rank = TSDP_HTYPE_R_RANK; + } + else{ + TSK_DEBUG_ERROR("Failed to create new E header."); + } + return self; +} + +static tsk_object_t* tsdp_header_R_dtor(tsk_object_t *self) +{ + tsdp_header_R_t *R = self; + if(R){ + TSK_FREE(R->repeat_interval); + TSK_FREE(R->typed_time); + TSK_OBJECT_SAFE_FREE(R->typed_times); + } + else{ + TSK_DEBUG_ERROR("Null R header."); + } + + return self; +} +static int tsdp_header_R_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) +{ + if(obj1 && obj2){ + return tsdp_header_rank_cmp(obj1, obj2); + } + else{ + return -1; + } +} + +static const tsk_object_def_t tsdp_header_R_def_s = +{ + sizeof(tsdp_header_R_t), + tsdp_header_R_ctor, + tsdp_header_R_dtor, + tsdp_header_R_cmp +}; + +const tsk_object_def_t *tsdp_header_R_def_t = &tsdp_header_R_def_s; diff --git a/tinySDP/ragel/tsdp_parser_header_S.rl b/tinySDP/ragel/tsdp_parser_header_S.rl new file mode 100644 index 0000000..1b7e562 --- /dev/null +++ b/tinySDP/ragel/tsdp_parser_header_S.rl @@ -0,0 +1,172 @@ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_header_S.c + * @brief SDP "s=" header (Session Name). + */ +#include "tinysdp/headers/tsdp_header_S.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_string.h" + +#include <string.h> + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsdp_machine_parser_header_S; + + # Includes + include tsdp_machine_utils "./ragel/tsdp_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_value{ + TSK_PARSER_SET_STRING(hdr_S->value); + } + + S = 's' SP* "=" SP*<: any*>tag %parse_value; + + # Entry point + main := S :>CRLF?; + +}%% + + +tsdp_header_S_t* tsdp_header_S_create(const char* value) +{ + return tsk_object_new(TSDP_HEADER_S_VA_ARGS(value)); +} +tsdp_header_S_t* tsdp_header_S_create_null() +{ + return tsdp_header_S_create(tsk_null); +} + +int tsdp_header_S_tostring(const tsdp_header_t* header, tsk_buffer_t* output) +{ + if(header) + { + const tsdp_header_S_t *S = (const tsdp_header_S_t *)header; + if(S->value){ + tsk_buffer_append(output, S->value, tsk_strlen(S->value)); + } + return 0; + } + + return -1; +} + +tsdp_header_t* tsdp_header_S_clone(const tsdp_header_t* header) +{ + if(header){ + const tsdp_header_S_t *S = (const tsdp_header_S_t *)header; + return (tsdp_header_t*)tsdp_header_S_create(S->value); + } + return tsk_null; +} + +tsdp_header_S_t *tsdp_header_S_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsdp_header_S_t *hdr_S = tsdp_header_S_create_null(); + + const char *tag_start = tsk_null; + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + %%write data; + (void)(tsdp_machine_parser_header_S_first_final); + (void)(tsdp_machine_parser_header_S_error); + (void)(tsdp_machine_parser_header_S_en_main); + %%write init; + %%write exec; + TSK_RAGEL_DISABLE_WARNINGS_END() + + if( cs < %%{ write first_final; }%% ){ + TSK_OBJECT_SAFE_FREE(hdr_S); + } + + return hdr_S; +} + + + + + + + +//======================================================== +// S header object definition +// + +static tsk_object_t* tsdp_header_S_ctor(tsk_object_t *self, va_list * app) +{ + tsdp_header_S_t *S = self; + if(S){ + TSDP_HEADER(S)->type = tsdp_htype_S; + TSDP_HEADER(S)->tostring = tsdp_header_S_tostring; + TSDP_HEADER(S)->clone = tsdp_header_S_clone; + TSDP_HEADER(S)->rank = TSDP_HTYPE_S_RANK; + + S->value = tsk_strdup(va_arg(*app, const char*)); + } + else{ + TSK_DEBUG_ERROR("Failed to create new S header."); + } + return self; +} + +static tsk_object_t* tsdp_header_S_dtor(tsk_object_t *self) +{ + tsdp_header_S_t *S = self; + if(S){ + TSK_FREE(S->value); + } + else{ + TSK_DEBUG_ERROR("Null S header."); + } + + return self; +} +static int tsdp_header_S_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) +{ + if(obj1 && obj2){ + return tsdp_header_rank_cmp(obj1, obj2); + } + else{ + return -1; + } +} + +static const tsk_object_def_t tsdp_header_S_def_s = +{ + sizeof(tsdp_header_S_t), + tsdp_header_S_ctor, + tsdp_header_S_dtor, + tsdp_header_S_cmp +}; + +const tsk_object_def_t *tsdp_header_S_def_t = &tsdp_header_S_def_s; diff --git a/tinySDP/ragel/tsdp_parser_header_T.rl b/tinySDP/ragel/tsdp_parser_header_T.rl new file mode 100644 index 0000000..044178d --- /dev/null +++ b/tinySDP/ragel/tsdp_parser_header_T.rl @@ -0,0 +1,226 @@ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_header_T.c + * @brief SDP "t=" header (Timing). + */ +#include "tinysdp/headers/tsdp_header_T.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_string.h" + +#include <string.h> + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsdp_machine_parser_header_T; + + # Includes + include tsdp_machine_utils "./ragel/tsdp_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_start_time{ + TSK_PARSER_SET_INTEGER_EX(hdr_T->start, uint64_t, atoi64); + } + + action parse_stop_time{ + TSK_PARSER_SET_INTEGER_EX(hdr_T->stop, uint64_t, atoi64); + } + + action parse_repeat_fields{ + tsdp_header_R_t* header_R; + if((header_R = tsdp_header_R_parse(tag_start, (p - tag_start)))){ + if(!hdr_T->repeat_fields){ + hdr_T->repeat_fields = tsk_list_create(); + } + tsk_list_push_back_data(hdr_T->repeat_fields, (void**)&header_R); + } + } + + start_time = DIGIT+ >tag %parse_start_time; + stop_time = DIGIT+ >tag %parse_stop_time; + repeat_fields = any+ >tag %parse_repeat_fields; + + T = 't' SP* "=" SP*<: start_time :>SP stop_time (CRLF <:repeat_fields)?; + + # Entry point + main := T :>CRLF?; + +}%% + + +tsdp_header_T_t* tsdp_header_T_create(uint64_t start, uint64_t stop) +{ + return tsk_object_new(TSDP_HEADER_T_VA_ARGS(start, stop)); +} + +tsdp_header_T_t* tsdp_header_T_create_null() +{ + return tsdp_header_T_create(0, 0); +} + +int tsdp_header_T_tostring(const tsdp_header_t* header, tsk_buffer_t* output) +{ + if(header) + { + const tsdp_header_T_t *T = (const tsdp_header_T_t *)header; + const tsk_list_item_t *item; + + //"t=3034423619 3042462419\r\n" + //"r=7d 1h 0 25h\r\n" + // IMPORTANT: Do not append the last CRLF (because we only print the header value). + tsk_buffer_append_2(output, "%llu %llu", + T->start, + T->stop + ); + + tsk_list_foreach(item, T->repeat_fields) + { + if(TSK_LIST_IS_FIRST(T->repeat_fields, item)){ + tsk_buffer_append(output, "\r\n", 2); + } + tsk_buffer_append_2(output, "%c=", tsdp_header_get_nameex(TSDP_HEADER(item->data))); + TSDP_HEADER(item->data)->tostring(TSDP_HEADER(item->data), output); + //tsdp_header_tostring(TSDP_HEADER(item->data), output); + + if(!TSK_LIST_IS_LAST(T->repeat_fields, item)){ + tsk_buffer_append(output, "\r\n", 2); + } + } + + return 0; + } + + return -1; +} + +tsdp_header_t* tsdp_header_T_clone(const tsdp_header_t* header) +{ + if(header){ + const tsdp_header_T_t *T = (const tsdp_header_T_t *)header; + tsdp_header_T_t* clone; + const tsk_list_item_t *item; + + if((clone = tsdp_header_T_create(T->start, T->stop))){ + + if(T->repeat_fields){ + clone->repeat_fields = tsk_list_create(); + } + + tsk_list_foreach(item, T->repeat_fields){ + const tsdp_header_t* curr = item->data; + tsdp_header_t* hdr_clone = curr->clone(curr); + tsk_list_push_back_data(clone->repeat_fields, (void**)&hdr_clone); + } + } + return TSDP_HEADER(clone); + } + return tsk_null; +} + +tsdp_header_T_t *tsdp_header_T_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsdp_header_T_t *hdr_T = tsdp_header_T_create_null(); + + const char *tag_start = tsk_null; + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + %%write data; + (void)(tsdp_machine_parser_header_T_first_final); + (void)(tsdp_machine_parser_header_T_error); + (void)(tsdp_machine_parser_header_T_en_main); + %%write init; + %%write exec; + TSK_RAGEL_DISABLE_WARNINGS_END() + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse \"t=\" header."); + TSK_OBJECT_SAFE_FREE(hdr_T); + } + + return hdr_T; +} + + + + + + + +//======================================================== +// T header object definition +// + +static tsk_object_t* tsdp_header_T_ctor(tsk_object_t *self, va_list * app) +{ + tsdp_header_T_t *T = self; + if(T){ + TSDP_HEADER(T)->type = tsdp_htype_T; + TSDP_HEADER(T)->tostring = tsdp_header_T_tostring; + TSDP_HEADER(T)->clone = tsdp_header_T_clone; + TSDP_HEADER(T)->rank = TSDP_HTYPE_T_RANK; + } + else{ + TSK_DEBUG_ERROR("Failed to create new U header."); + } + return self; +} + +static tsk_object_t* tsdp_header_T_dtor(tsk_object_t *self) +{ + tsdp_header_T_t *T = self; + if(T){ + TSK_OBJECT_SAFE_FREE(T->repeat_fields); + } + else{ + TSK_DEBUG_ERROR("Null U header."); + } + + return self; +} +static int tsdp_header_T_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) +{ + if(obj1 && obj2){ + return tsdp_header_rank_cmp(obj1, obj2); + } + else{ + return -1; + } +} + +static const tsk_object_def_t tsdp_header_T_def_s = +{ + sizeof(tsdp_header_T_t), + tsdp_header_T_ctor, + tsdp_header_T_dtor, + tsdp_header_T_cmp +}; + +const tsk_object_def_t *tsdp_header_T_def_t = &tsdp_header_T_def_s; diff --git a/tinySDP/ragel/tsdp_parser_header_U.rl b/tinySDP/ragel/tsdp_parser_header_U.rl new file mode 100644 index 0000000..026754b --- /dev/null +++ b/tinySDP/ragel/tsdp_parser_header_U.rl @@ -0,0 +1,176 @@ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_header_U.c + * @brief SDP "u=" header (URI). + */ +#include "tinysdp/headers/tsdp_header_U.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_string.h" + +#include <string.h> + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsdp_machine_parser_header_U; + + # Includes + include tsdp_machine_utils "./ragel/tsdp_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_value{ + TSK_PARSER_SET_STRING(hdr_U->value); + } + + U = 'u' SP* "=" SP*<: any*>tag %parse_value; + + # Entry point + main := U :>CRLF?; + +}%% + + + +tsdp_header_U_t* tsdp_header_U_create(const char* value) +{ + return tsk_object_new(TSDP_HEADER_U_VA_ARGS(value)); +} + +tsdp_header_U_t* tsdp_header_U_create_null() +{ + return tsdp_header_U_create(tsk_null); +} + +int tsdp_header_U_tostring(const tsdp_header_t* header, tsk_buffer_t* output) +{ + if(header) + { + const tsdp_header_U_t *U = (const tsdp_header_U_t *)header; + if(U->value){ + tsk_buffer_append(output, U->value, tsk_strlen(U->value)); + } + return 0; + } + + return -1; +} + +tsdp_header_t* tsdp_header_U_clone(const tsdp_header_t* header) +{ + if(header){ + const tsdp_header_U_t *U = (const tsdp_header_U_t *)header; + return (tsdp_header_t*)tsdp_header_U_create(U->value); + } + return tsk_null; +} + +tsdp_header_U_t *tsdp_header_U_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsdp_header_U_t *hdr_U = tsdp_header_U_create_null(); + + const char *tag_start = tsk_null; + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + %%write data; + (void)(tsdp_machine_parser_header_U_first_final); + (void)(tsdp_machine_parser_header_U_error); + (void)(tsdp_machine_parser_header_U_en_main); + %%write init; + %%write exec; + TSK_RAGEL_DISABLE_WARNINGS_END() + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse \"u=\" header."); + TSK_OBJECT_SAFE_FREE(hdr_U); + } + + return hdr_U; +} + + + + + + + +//======================================================== +// U header object definition +// + +static tsk_object_t* tsdp_header_U_ctor(tsk_object_t *self, va_list * app) +{ + tsdp_header_U_t *U = self; + if(U) + { + TSDP_HEADER(U)->type = tsdp_htype_U; + TSDP_HEADER(U)->tostring = tsdp_header_U_tostring; + TSDP_HEADER(U)->clone = tsdp_header_U_clone; + TSDP_HEADER(U)->rank = TSDP_HTYPE_U_RANK; + + U->value = tsk_strdup(va_arg(*app, const char*)); + } + else{ + TSK_DEBUG_ERROR("Failed to create new U header."); + } + return self; +} + +static tsk_object_t* tsdp_header_U_dtor(tsk_object_t *self) +{ + tsdp_header_U_t *U = self; + if(U){ + TSK_FREE(U->value); + } + else{ + TSK_DEBUG_ERROR("Null U header."); + } + + return self; +} +static int tsdp_header_U_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) +{ + if(obj1 && obj2){ + return tsdp_header_rank_cmp(obj1, obj2); + } + else{ + return -1; + } +} + +static const tsk_object_def_t tsdp_header_U_def_s = +{ + sizeof(tsdp_header_U_t), + tsdp_header_U_ctor, + tsdp_header_U_dtor, + tsdp_header_U_cmp +}; + +const tsk_object_def_t *tsdp_header_U_def_t = &tsdp_header_U_def_s; diff --git a/tinySDP/ragel/tsdp_parser_header_V.rl b/tinySDP/ragel/tsdp_parser_header_V.rl new file mode 100644 index 0000000..6b66963 --- /dev/null +++ b/tinySDP/ragel/tsdp_parser_header_V.rl @@ -0,0 +1,173 @@ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_header_V.c + * @brief SDP "v=" header (Protocol Version). + */ +#include "tinysdp/headers/tsdp_header_V.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_string.h" + +#include <string.h> + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsdp_machine_parser_header_V; + + # Includes + include tsdp_machine_utils "./ragel/tsdp_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_version{ + TSK_PARSER_SET_INT(hdr_V->version); + } + + V = 'v' SP* "=" SP*<: DIGIT+>tag %parse_version; + + # Entry point + main := V :>CRLF?; + +}%% + + +tsdp_header_V_t* tsdp_header_V_create(int32_t version) +{ + return tsk_object_new(TSDP_HEADER_V_VA_ARGS(version)); +} + +tsdp_header_V_t* tsdp_header_V_create_null() +{ + return tsdp_header_V_create(TSDP_HEADER_V_DEFAULT); +} + +int tsdp_header_V_tostring(const tsdp_header_t* header, tsk_buffer_t* output) +{ + if(header) + { + const tsdp_header_V_t *V = (const tsdp_header_V_t *)header; + if(V->version >=0){ + tsk_buffer_append_2(output, "%d", V->version); + } + return 0; + } + + return -1; +} + +tsdp_header_t* tsdp_header_V_clone(const tsdp_header_t* header) +{ + if(header){ + const tsdp_header_V_t *V = (const tsdp_header_V_t *)header; + return (tsdp_header_t*)tsdp_header_V_create(V->version); + } + return tsk_null; +} + +tsdp_header_V_t *tsdp_header_V_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsdp_header_V_t *hdr_V = tsdp_header_V_create_null(); + + const char *tag_start = tsk_null; + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + %%write data; + (void)(tsdp_machine_parser_header_V_first_final); + (void)(tsdp_machine_parser_header_V_error); + (void)(tsdp_machine_parser_header_V_en_main); + %%write init; + %%write exec; + TSK_RAGEL_DISABLE_WARNINGS_END() + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse \"v=\" header."); + TSK_OBJECT_SAFE_FREE(hdr_V); + } + + return hdr_V; +} + + + + + + + +//======================================================== +// V header object definition +// + +static tsk_object_t* tsdp_header_V_ctor(tsk_object_t *self, va_list * app) +{ + tsdp_header_V_t *V = self; + if(V){ + TSDP_HEADER(V)->type = tsdp_htype_V; + TSDP_HEADER(V)->tostring = tsdp_header_V_tostring; + TSDP_HEADER(V)->clone = tsdp_header_V_clone; + TSDP_HEADER(V)->rank = TSDP_HTYPE_V_RANK; + + V->version = va_arg(*app, int32_t); + } + else{ + TSK_DEBUG_ERROR("Failed to create new V header."); + } + return self; +} + +static tsk_object_t* tsdp_header_V_dtor(tsk_object_t *self) +{ + tsdp_header_V_t *V = self; + if(V){ + } + else{ + TSK_DEBUG_ERROR("Null V header."); + } + + return self; +} +static int tsdp_header_V_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) +{ + if(obj1 && obj2){ + return tsdp_header_rank_cmp(obj1, obj2); + } + else{ + return -1; + } +} + +static const tsk_object_def_t tsdp_header_V_def_s = +{ + sizeof(tsdp_header_V_t), + tsdp_header_V_ctor, + tsdp_header_V_dtor, + tsdp_header_V_cmp +}; + +const tsk_object_def_t *tsdp_header_V_def_t = &tsdp_header_V_def_s; diff --git a/tinySDP/ragel/tsdp_parser_header_Z.rl b/tinySDP/ragel/tsdp_parser_header_Z.rl new file mode 100644 index 0000000..85c90b9 --- /dev/null +++ b/tinySDP/ragel/tsdp_parser_header_Z.rl @@ -0,0 +1,277 @@ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + + +/**@file tsdp_header_Z.c + * @brief SDP "z=" header (Time Zones). + * + */ +#include "tinysdp/headers/tsdp_header_Z.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_string.h" + +#include <string.h> + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsdp_machine_parser_header_Z; + + # Includes + include tsdp_machine_utils "./ragel/tsdp_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action create_zone{ + if(!zone){ + zone = tsdp_zone_create_null(); + } + } + + action add_zone{ + if(zone){ + tsk_list_push_back_data(hdr_Z->zones,(void**)&zone); + } + } + + action parse_time{ + if(zone){ + TSK_PARSER_SET_INTEGER_EX(zone->time, uint64_t, atoi64); + } + } + + action parse_typed_time{ + if(zone){ + TSK_PARSER_SET_STRING(zone->typed_time); + } + } + + action shifted{ + if(zone){ + zone->shifted_back = tsk_true; + } + } + + fixed_len_time_unit = "d" | "h" | "m" | "s"; + + time = DIGIT+ >tag %parse_time; + typed_time = (DIGIT+ fixed_len_time_unit?) >tag %parse_typed_time; + + Z = 'z' SP* "=" (time SP ("-"%shifted)? typed_time) >create_zone %add_zone + (SP time SP ("-"%shifted)? typed_time)* >create_zone %add_zone; + + # Entry point + main := Z :>CRLF?; + +}%% + + +tsdp_header_Z_t* tsdp_header_Z_create(uint64_t time, tsk_bool_t shifted_back, const char* typed_time) +{ + return tsk_object_new(TSDP_HEADER_Z_VA_ARGS(time, shifted_back, typed_time)); +} + +tsdp_header_Z_t* tsdp_header_Z_create_null() +{ + return tsdp_header_Z_create(0L, tsk_false, tsk_null); +} + + +tsdp_zone_t* tsdp_zone_create(uint64_t time, tsk_bool_t shifted_back, const char* typed_time) +{ + return tsk_object_new(tsdp_zone_def_t, time, shifted_back, typed_time); +} + +tsdp_zone_t* tsdp_zone_create_null() +{ + return tsdp_zone_create(0L, tsk_false, tsk_null); +} + +int tsdp_header_Z_tostring(const tsdp_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsdp_header_Z_t *Z = (const tsdp_header_Z_t *)header; + const tsk_list_item_t *item; + const tsdp_zone_t* zone; + + tsk_list_foreach(item, Z->zones){ + zone = (const tsdp_zone_t*)item->data; + // time SP ["-"] typed-time + tsk_buffer_append_2(output, "%s%llu %s%s", + TSK_LIST_IS_FIRST(Z->zones, item) ? "" : " ", + zone->time, + zone->shifted_back ? "-" : "", + zone->typed_time + ); + } + } + + return -1; +} + +tsdp_header_Z_t *tsdp_header_Z_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsdp_header_Z_t *hdr_Z = tsdp_header_Z_create_null(); + tsdp_zone_t* zone = tsk_null; + + const char *tag_start = tsk_null; + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + %%write data; + (void)(tsdp_machine_parser_header_Z_first_final); + (void)(tsdp_machine_parser_header_Z_error); + (void)(tsdp_machine_parser_header_Z_en_main); + %%write init; + %%write exec; + TSK_RAGEL_DISABLE_WARNINGS_END() + + if(zone){ + TSK_OBJECT_SAFE_FREE(zone); + } + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse \"z=\" header."); + TSK_OBJECT_SAFE_FREE(hdr_Z); + } + + return hdr_Z; +} + + + + + + + +//======================================================== +// Z header object definition +// + +static tsk_object_t* tsdp_header_Z_ctor(tsk_object_t *self, va_list * app) +{ + tsdp_header_Z_t *Z = self; + if(Z){ + TSDP_HEADER(Z)->type = tsdp_htype_Z; + TSDP_HEADER(Z)->tostring = tsdp_header_Z_tostring; + TSDP_HEADER(Z)->rank = TSDP_HTYPE_Z_RANK; + + if((Z->zones = tsk_list_create())){ + uint64_t time = va_arg(*app, uint64_t); + unsigned shifted_back = va_arg(*app, unsigned); + const char* typed_time = va_arg(*app, const char*); + + if(typed_time){ + tsdp_zone_t *zone; + if((zone = tsdp_zone_create(time, shifted_back, typed_time))){ + tsk_list_push_back_data(Z->zones,(void**)&zone); + } + } + } + } + else{ + TSK_DEBUG_ERROR("Failed to create new Z header."); + } + return self; +} + +static tsk_object_t* tsdp_header_Z_dtor(tsk_object_t *self) +{ + tsdp_header_Z_t *Z = self; + if(Z){ + TSK_OBJECT_SAFE_FREE(Z->zones); + } + else{ + TSK_DEBUG_ERROR("Null Z header."); + } + + return self; +} +static int tsdp_header_Z_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) +{ + if(obj1 && obj2){ + return tsdp_header_rank_cmp(obj1, obj2); + } + else{ + return -1; + } +} + +static const tsk_object_def_t tsdp_header_Z_def_s = +{ + sizeof(tsdp_header_Z_t), + tsdp_header_Z_ctor, + tsdp_header_Z_dtor, + tsdp_header_Z_cmp +}; + +const tsk_object_def_t *tsdp_header_Z_def_t = &tsdp_header_Z_def_s; + + + + +//======================================================== +// Zone object definition +// + +static tsk_object_t* tsdp_zone_ctor(tsk_object_t *self, va_list * app) +{ + tsdp_zone_t *zone = self; + if(zone){ + zone->time = va_arg(*app, uint64_t); + zone->shifted_back = va_arg(*app, tsk_bool_t); + zone->typed_time = tsk_strdup( va_arg(*app, const char*) ); + } + else{ + TSK_DEBUG_ERROR("Failed to create new zone object."); + } + return self; +} + +static tsk_object_t* tsdp_zone_dtor(tsk_object_t *self) +{ + tsdp_zone_t *zone = self; + if(zone){ + TSK_FREE(zone->typed_time); + } + else{ + TSK_DEBUG_ERROR("Null zone object."); + } + + return self; +} + +static const tsk_object_def_t tsdp_zone_def_s = +{ + sizeof(tsdp_zone_t), + tsdp_zone_ctor, + tsdp_zone_dtor, + tsk_null +}; + +const tsk_object_def_t *tsdp_zone_def_t = &tsdp_zone_def_s; diff --git a/tinySDP/ragel/tsdp_parser_message.rl b/tinySDP/ragel/tsdp_parser_message.rl new file mode 100644 index 0000000..b09a743 --- /dev/null +++ b/tinySDP/ragel/tsdp_parser_message.rl @@ -0,0 +1,288 @@ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ +/**@file tsdp_machine_message.rl + * @brief Ragel file. + */ +#include "tinysdp/parsers/tsdp_parser_message.h" + +#include "tinysdp/headers/tsdp_header_A.h" +#include "tinysdp/headers/tsdp_header_B.h" +#include "tinysdp/headers/tsdp_header_C.h" +#include "tinysdp/headers/tsdp_header_Dummy.h" +#include "tinysdp/headers/tsdp_header_E.h" +#include "tinysdp/headers/tsdp_header_I.h" +#include "tinysdp/headers/tsdp_header_K.h" +#include "tinysdp/headers/tsdp_header_M.h" +#include "tinysdp/headers/tsdp_header_O.h" +#include "tinysdp/headers/tsdp_header_P.h" +#include "tinysdp/headers/tsdp_header_R.h" +#include "tinysdp/headers/tsdp_header_S.h" +#include "tinysdp/headers/tsdp_header_T.h" +#include "tinysdp/headers/tsdp_header_U.h" +#include "tinysdp/headers/tsdp_header_V.h" +#include "tinysdp/headers/tsdp_header_Z.h" + +#include "tsk_debug.h" + +%%{ + machine tsdp_machine_message; + + ########################################### + # Includes + ########################################### + include tsdp_machine_utils "./ragel/tsdp_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + ########################################### + # Actions + ########################################### + action parse_header_A{ + if(hdr_M){ + if(!hdr_M->Attributes){ + hdr_M->Attributes = tsk_list_create(); + } + if((header = (tsdp_header_t*)tsdp_header_A_parse(tag_start, (p - tag_start)))){ + tsk_list_push_back_data(hdr_M->Attributes, (void**)&header); + } + } + else if((header = (tsdp_header_t*)tsdp_header_A_parse(tag_start, (p - tag_start)))){ + tsdp_message_add_header(sdp_msg, header); + tsk_object_unref(header); + } + } + + action parse_header_B{ + if(hdr_M){ + if(!hdr_M->Bandwidths){ + hdr_M->Bandwidths = tsk_list_create(); + } + if((header = (tsdp_header_t*)tsdp_header_B_parse(tag_start, (p - tag_start)))){ + tsk_list_push_back_data(hdr_M->Bandwidths, (void**)&header); + } + } + else if((header = (tsdp_header_t*)tsdp_header_B_parse(tag_start, (p - tag_start)))){ + tsdp_message_add_header(sdp_msg, header); + tsk_object_unref(header); + } + } + + action parse_header_C{ + if(hdr_M && !hdr_M->C){ + hdr_M->C = tsdp_header_C_parse(tag_start, (p - tag_start)); + } + else if((header = (tsdp_header_t*)tsdp_header_C_parse(tag_start, (p - tag_start)))){ + tsdp_message_add_header(sdp_msg, header); + tsk_object_unref(header); + } + } + + action parse_header_Dummy{ + if((header = (tsdp_header_t*)tsdp_header_Dummy_parse(tag_start, (p - tag_start)))){ + tsdp_message_add_header(sdp_msg, header); + tsk_object_unref(header); + } + } + + action parse_header_E{ + if((header = (tsdp_header_t*)tsdp_header_E_parse(tag_start, (p - tag_start)))){ + tsdp_message_add_header(sdp_msg, header); + tsk_object_unref(header); + } + } + + action parse_header_I{ + if(hdr_M && !hdr_M->I){ + hdr_M->I = tsdp_header_I_parse(tag_start, (p - tag_start)); + } + else if((header = (tsdp_header_t*)tsdp_header_I_parse(tag_start, (p - tag_start)))){ + tsdp_message_add_header(sdp_msg, header); + tsk_object_unref(header); + } + } + + action parse_header_K{ + if(hdr_M && !hdr_M->K){ + hdr_M->K = tsdp_header_K_parse(tag_start, (p - tag_start)); + } + else if((header = (tsdp_header_t*)tsdp_header_K_parse(tag_start, (p - tag_start)))){ + tsdp_message_add_header(sdp_msg, header); + tsk_object_unref(header); + } + } + + action parse_header_M{ + if((hdr_M = tsdp_header_M_parse(tag_start, (p - tag_start)))){ + tsdp_message_add_header(sdp_msg, TSDP_HEADER(hdr_M)); + hdr_M = tsk_object_unref(hdr_M); + } + } + + action parse_header_O{ + if((header = (tsdp_header_t*)tsdp_header_O_parse(tag_start, (p - tag_start)))){ + tsdp_message_add_header(sdp_msg, header); + tsk_object_unref(header); + } + } + + action parse_header_P{ + if((header = (tsdp_header_t*)tsdp_header_P_parse(tag_start, (p - tag_start)))){ + tsdp_message_add_header(sdp_msg, header); + tsk_object_unref(header); + } + } + + action parse_header_R{ + if((header = (tsdp_header_t*)tsdp_header_R_parse(tag_start, (p - tag_start)))){ + if(hdr_T){ + if(!hdr_T->repeat_fields){ + hdr_T->repeat_fields = tsk_list_create(); + } + tsk_list_push_back_data(hdr_T->repeat_fields, (void**)&header); + } + else{ + tsdp_message_add_header(sdp_msg, header); + tsk_object_unref(header); + } + } + } + + action parse_header_S{ + if((header = (tsdp_header_t*)tsdp_header_S_parse(tag_start, (p - tag_start)))){ + tsdp_message_add_header(sdp_msg, header); + tsk_object_unref(header); + } + } + + action parse_header_T{ + if((hdr_T = tsdp_header_T_parse(tag_start, (p - tag_start)))){ + tsdp_message_add_header(sdp_msg, TSDP_HEADER(hdr_T)); + hdr_T = tsk_object_unref(hdr_T); + } + } + + action parse_header_U{ + if((header = (tsdp_header_t*)tsdp_header_U_parse(tag_start, (p - tag_start)))){ + tsdp_message_add_header(sdp_msg, header); + tsk_object_unref(header); + } + } + + action parse_header_V{ + if((header = (tsdp_header_t*)tsdp_header_V_parse(tag_start, (p - tag_start)))){ + tsdp_message_add_header(sdp_msg, header); + tsk_object_unref(header); + } + } + + action parse_header_Z{ + if((header = (tsdp_header_t*)tsdp_header_Z_parse(tag_start, (p - tag_start)))){ + tsdp_message_add_header(sdp_msg, header); + tsk_object_unref(header); + } + } + + ########################################### + # Headers + ########################################### + + A = "a"i SP* "=" SP*<: any* %parse_header_A :>CRLF; + B = "b"i SP* "=" SP*<: any* %parse_header_B :>CRLF; + C = "c"i SP* "=" SP*<: any* %parse_header_C :>CRLF; + E = "e"i SP* "=" SP*<: any* %parse_header_E :>CRLF; + I = "i"i SP* "=" SP*<: any* %parse_header_I :>CRLF; + K = "k"i SP* "=" SP*<: any* %parse_header_K :>CRLF; + M = "m"i SP* "=" SP*<: any* %parse_header_M :>CRLF; + O = "o"i SP* "=" SP*<: any* %parse_header_O :>CRLF; + P = "p"i SP* "=" SP*<: any* %parse_header_P :>CRLF; + R = "r"i SP* "=" SP*<: any* %parse_header_R :>CRLF; + S = "s"i SP* "=" SP*<: any* %parse_header_S :>CRLF; + T = "t"i SP* "=" SP*<: any* %parse_header_T :>CRLF; + U = "u"i SP* "=" SP*<: any* %parse_header_U :>CRLF; + V = "v"i SP* "=" SP*<: any* %parse_header_V :>CRLF; + Z = "z"i SP* "=" SP*<: any* %parse_header_Z :>CRLF; + + Dummy = alpha SP* "=" SP*<: any* %parse_header_Dummy :>CRLF; + + Header = (A | B | C | E | I | K | M | O | P | R | S | T | U | V | Z)>tag >1 | (Dummy>tag) >0; + + + ########################################### + # Message + ########################################### + SDP_message = Header*; + + ########################################### + # Entry Point + ########################################### + main := SDP_message; +}%% + +TSK_RAGEL_DISABLE_WARNINGS_BEGIN() +/* Ragel data */ +%% write data; +TSK_RAGEL_DISABLE_WARNINGS_END() + +tsdp_message_t* tsdp_message_parse(const void *input, tsk_size_t size) +{ + tsdp_message_t* sdp_msg = tsk_null; + const char* tag_start = tsk_null; + tsdp_header_t *header = tsk_null; + tsdp_header_T_t *hdr_T = tsk_null; + tsdp_header_M_t *hdr_M = tsk_null; + + /* Ragel variables */ + int cs = 0; + const char* p = input; + const char* pe = p + size; + const char* eof = tsk_null; + + (void)(eof); + + if(!input || !size){ + TSK_DEBUG_ERROR("Null or empty buffer."); + goto bail; + } + + if(!(sdp_msg = tsdp_message_create())){ + goto bail; + } + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + /* Ragel init */ + %% write init; + + /* Ragel execute */ + %% write exec; + TSK_RAGEL_DISABLE_WARNINGS_END() + + /* Check result */ + if( cs < %%{ write first_final; }%% ) + { + TSK_DEBUG_ERROR("Failed to parse SDP message."); + TSK_OBJECT_SAFE_FREE(sdp_msg); + goto bail; + } + +bail: + return sdp_msg; +} diff --git a/tinySDP/src/headers/tsdp_header.c b/tinySDP/src/headers/tsdp_header.c new file mode 100644 index 0000000..f288f85 --- /dev/null +++ b/tinySDP/src/headers/tsdp_header.c @@ -0,0 +1,139 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org> +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_header.c + * @brief Defines a SDP header/line (<type>=<value>). + * + * @author Mamadou Diop <diopmamadou(at)doubango[dot]org> + * + + */ +#include "tinysdp/headers/tsdp_header.h" + +#include "tinysdp/headers/tsdp_header_Dummy.h" + +#include "tsk_string.h" + +int tsdp_header_rank_cmp(const tsdp_header_t* hdr1, const tsdp_header_t* hdr2) +{ + if(hdr1 && hdr2){ + return (hdr1->rank - hdr2->rank); + } + else{ + return -1; + } +} + +tsdp_header_t* tsdp_header_clone(const tsdp_header_t* self) +{ + if(self){ + return self->clone(self); + } + return tsk_null; +} + +/** Gets the name of the SDP header with a type equal to @a type. + * @param type The @a type of the header for which to retrieve the name. + * + * @return The name of the header. +**/ +char tsdp_header_get_name(tsdp_header_type_t type) +{ + switch(type) + { + case tsdp_htype_A: return 'a'; + case tsdp_htype_B: return 'b'; + case tsdp_htype_C: return 'c'; + case tsdp_htype_E: return 'e'; + case tsdp_htype_I: return 'i'; + case tsdp_htype_K: return 'k'; + case tsdp_htype_M: return 'm'; + case tsdp_htype_O: return 'o'; + case tsdp_htype_P: return 'p'; + case tsdp_htype_R: return 'r'; + case tsdp_htype_S: return 's'; + case tsdp_htype_T: return 't'; + case tsdp_htype_U: return 'u'; + case tsdp_htype_V: return 'v'; + case tsdp_htype_Z: return 'z'; + + default: return '*'; + } +} + +char tsdp_header_get_nameex(const tsdp_header_t *self) +{ + if(self){ + if(self->type == tsdp_htype_Dummy){ + return ((tsdp_header_Dummy_t*)(self))->name; + } + else{ + return tsdp_header_get_name(self->type); + } + } + return '*'; +} + + +int tsdp_header_serialize(const tsdp_header_t *self, tsk_buffer_t *output) +{ + static char name; + int ret = -1; + if(!self || !output){ + return -1; + } + + /* Name */ + name = tsdp_header_get_nameex(self); + tsk_buffer_append_2(output, "%c=", name); + + /* Value */ + if((ret = self->tostring(self, output))){ + // Abort? + } + + /* CRLF*/ + if(output->size>2){ + if(*(TSK_BUFFER_TO_U8(output)+TSK_BUFFER_SIZE(output)-2) != '\r' + && *(TSK_BUFFER_TO_U8(output)+TSK_BUFFER_SIZE(output)-1) != '\n'){ + ret = tsk_buffer_append(output, "\r\n", 2); + } + } + else{ + ret = tsk_buffer_append(output, "\r\n", 2); + } + + return ret; +} + +char* tsdp_header_tostring(const tsdp_header_t *self) +{ + tsk_buffer_t* output = tsk_buffer_create_null(); + char* str = tsk_null; + + if(!(tsdp_header_serialize(self, output))){ + str = tsk_strndup(TSK_BUFFER_DATA(output), TSK_BUFFER_SIZE(output)); + } + + TSK_OBJECT_SAFE_FREE(output); + return str; +} diff --git a/tinySDP/src/headers/tsdp_header_A.c b/tinySDP/src/headers/tsdp_header_A.c new file mode 100644 index 0000000..adf9e7c --- /dev/null +++ b/tinySDP/src/headers/tsdp_header_A.c @@ -0,0 +1,417 @@ + +/* #line 1 "./ragel/tsdp_parser_header_A.rl" */ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_header_A.c + * @brief SDP "a=" header (Attributes). + * + */ +#include "tinysdp/headers/tsdp_header_A.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_string.h" + +#include <string.h> + +/*********************************** +* Ragel state machine. +*/ + +/* #line 62 "./ragel/tsdp_parser_header_A.rl" */ + + + + +tsdp_header_A_t* tsdp_header_A_create(const char* field, const char* value) +{ + return tsk_object_new(TSDP_HEADER_A_VA_ARGS(field, value)); +} + +tsdp_header_A_t* tsdp_header_A_create_null() +{ + return tsdp_header_A_create(tsk_null, tsk_null); +} + + +int tsdp_header_A_tostring(const tsdp_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsdp_header_A_t *A = (const tsdp_header_A_t *)header; + + return tsk_buffer_append_2(output, "%s%s%s", + A->field, + + A->value ? ":" : "", + A->value ? A->value : "" + ); + } + + return -1; +} + +tsdp_header_t* tsdp_header_A_clone(const tsdp_header_t* header) +{ + if(header){ + const tsdp_header_A_t *A = (const tsdp_header_A_t *)header; + return (tsdp_header_t*)tsdp_header_A_create(A->field, A->value); + } + return tsk_null; +} + +tsdp_header_A_t *tsdp_header_A_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsdp_header_A_t *hdr_A = tsdp_header_A_create_null(); + + const char *tag_start = tsk_null; + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + +/* #line 93 "./src/headers/tsdp_header_A.c" */ +static const char _tsdp_machine_parser_header_A_actions[] = { + 0, 1, 0, 1, 1, 1, 2, 2, + 0, 2 +}; + +static const char _tsdp_machine_parser_header_A_key_offsets[] = { + 0, 0, 1, 3, 18, 19, 35, 35, + 36 +}; + +static const char _tsdp_machine_parser_header_A_trans_keys[] = { + 97, 32, 61, 32, 33, 37, 39, 126, + 42, 43, 45, 46, 48, 57, 65, 90, + 95, 122, 10, 13, 33, 37, 39, 58, + 126, 42, 43, 45, 46, 48, 57, 65, + 90, 95, 122, 13, 13, 0 +}; + +static const char _tsdp_machine_parser_header_A_single_lengths[] = { + 0, 1, 2, 5, 1, 6, 0, 1, + 1 +}; + +static const char _tsdp_machine_parser_header_A_range_lengths[] = { + 0, 0, 0, 5, 0, 5, 0, 0, + 0 +}; + +static const char _tsdp_machine_parser_header_A_index_offsets[] = { + 0, 0, 2, 5, 16, 18, 30, 31, + 33 +}; + +static const char _tsdp_machine_parser_header_A_indicies[] = { + 0, 1, 0, 2, 1, 2, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 1, + 4, 1, 5, 6, 6, 6, 7, 6, + 6, 6, 6, 6, 6, 1, 1, 9, + 8, 11, 10, 0 +}; + +static const char _tsdp_machine_parser_header_A_trans_targs[] = { + 2, 0, 3, 5, 6, 4, 5, 7, + 8, 4, 8, 4 +}; + +static const char _tsdp_machine_parser_header_A_trans_actions[] = { + 0, 0, 0, 1, 0, 3, 0, 3, + 1, 7, 0, 5 +}; + +static const char _tsdp_machine_parser_header_A_eof_actions[] = { + 0, 0, 0, 0, 0, 3, 0, 7, + 5 +}; + +static const int tsdp_machine_parser_header_A_start = 1; +static const int tsdp_machine_parser_header_A_first_final = 5; +static const int tsdp_machine_parser_header_A_error = 0; + +static const int tsdp_machine_parser_header_A_en_main = 1; + + +/* #line 114 "./ragel/tsdp_parser_header_A.rl" */ + +/* #line 159 "./src/headers/tsdp_header_A.c" */ + { + cs = tsdp_machine_parser_header_A_start; + } + +/* #line 115 "./ragel/tsdp_parser_header_A.rl" */ + (void)(tsdp_machine_parser_header_A_first_final); + (void)(tsdp_machine_parser_header_A_error); + (void)(tsdp_machine_parser_header_A_en_main); + +/* #line 169 "./src/headers/tsdp_header_A.c" */ + { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + + if ( p == pe ) + goto _test_eof; + if ( cs == 0 ) + goto _out; +_resume: + _keys = _tsdp_machine_parser_header_A_trans_keys + _tsdp_machine_parser_header_A_key_offsets[cs]; + _trans = _tsdp_machine_parser_header_A_index_offsets[cs]; + + _klen = _tsdp_machine_parser_header_A_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _tsdp_machine_parser_header_A_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += ((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + _trans = _tsdp_machine_parser_header_A_indicies[_trans]; + cs = _tsdp_machine_parser_header_A_trans_targs[_trans]; + + if ( _tsdp_machine_parser_header_A_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _tsdp_machine_parser_header_A_actions + _tsdp_machine_parser_header_A_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) + { + switch ( *_acts++ ) + { + case 0: +/* #line 42 "./ragel/tsdp_parser_header_A.rl" */ + { + tag_start = p; + } + break; + case 1: +/* #line 46 "./ragel/tsdp_parser_header_A.rl" */ + { + TSK_PARSER_SET_STRING(hdr_A->field); + } + break; + case 2: +/* #line 50 "./ragel/tsdp_parser_header_A.rl" */ + { + TSK_PARSER_SET_STRING(hdr_A->value); + } + break; +/* #line 261 "./src/headers/tsdp_header_A.c" */ + } + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; + _test_eof: {} + if ( p == eof ) + { + const char *__acts = _tsdp_machine_parser_header_A_actions + _tsdp_machine_parser_header_A_eof_actions[cs]; + unsigned int __nacts = (unsigned int) *__acts++; + while ( __nacts-- > 0 ) { + switch ( *__acts++ ) { + case 0: +/* #line 42 "./ragel/tsdp_parser_header_A.rl" */ + { + tag_start = p; + } + break; + case 1: +/* #line 46 "./ragel/tsdp_parser_header_A.rl" */ + { + TSK_PARSER_SET_STRING(hdr_A->field); + } + break; + case 2: +/* #line 50 "./ragel/tsdp_parser_header_A.rl" */ + { + TSK_PARSER_SET_STRING(hdr_A->value); + } + break; +/* #line 295 "./src/headers/tsdp_header_A.c" */ + } + } + } + + _out: {} + } + +/* #line 119 "./ragel/tsdp_parser_header_A.rl" */ + TSK_RAGEL_DISABLE_WARNINGS_END() + + if( cs < +/* #line 307 "./src/headers/tsdp_header_A.c" */ +5 +/* #line 121 "./ragel/tsdp_parser_header_A.rl" */ + ){ + TSK_DEBUG_ERROR("Failed to parse \"a=\" header."); + TSK_OBJECT_SAFE_FREE(hdr_A); + } + + return hdr_A; +} + + +int tsdp_header_A_removeAll_by_field(tsdp_headers_A_L_t *attributes, const char* field) +{ + tsk_list_item_t* item; + const tsdp_header_A_t* A; + + if(!attributes || !field){ + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + +again: + tsk_list_foreach(item, attributes){ + if(!(A = item->data) || TSDP_HEADER(A)->type != tsdp_htype_A){ + continue; + } + if(tsk_striequals(field, A->field)){ + tsk_list_remove_item(attributes, item); + goto again; + } + } + + return 0; +} + +int tsdp_header_A_removeAll_by_fields(tsdp_headers_A_L_t *attributes, const char** fields, tsk_size_t fields_count) +{ + tsk_size_t i; + + if(!attributes || !fields){ + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + for(i = 0; i < fields_count; ++i){ + if(!fields[i]){ + continue; + } + tsdp_header_A_removeAll_by_field(attributes, fields[i]); + } + return 0; +} + + + + +//======================================================== +// A header object definition +// + +static tsk_object_t* tsdp_header_A_ctor(tsk_object_t *self, va_list * app) +{ + tsdp_header_A_t *A = self; + if(A) + { + TSDP_HEADER(A)->type = tsdp_htype_A; + TSDP_HEADER(A)->tostring = tsdp_header_A_tostring; + TSDP_HEADER(A)->clone = tsdp_header_A_clone; + TSDP_HEADER(A)->rank = TSDP_HTYPE_A_RANK; + + A->field = tsk_strdup(va_arg(*app, const char*)); + A->value = tsk_strdup(va_arg(*app, const char*)); + } + else{ + TSK_DEBUG_ERROR("Failed to create new A header."); + } + return self; +} + +static tsk_object_t* tsdp_header_A_dtor(tsk_object_t *self) +{ + tsdp_header_A_t *A = self; + if(A){ + TSK_FREE(A->field); + TSK_FREE(A->value); + } + else{ + TSK_DEBUG_ERROR("Null A header."); + } + + return self; +} +static int tsdp_header_A_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) +{ + if(obj1 && obj2){ + return tsdp_header_rank_cmp(obj1, obj2); + } + else{ + return -1; + } +} + +static const tsk_object_def_t tsdp_header_A_def_s = +{ + sizeof(tsdp_header_A_t), + tsdp_header_A_ctor, + tsdp_header_A_dtor, + tsdp_header_A_cmp +}; + +const tsk_object_def_t *tsdp_header_A_def_t = &tsdp_header_A_def_s; diff --git a/tinySDP/src/headers/tsdp_header_B.c b/tinySDP/src/headers/tsdp_header_B.c new file mode 100644 index 0000000..28835c1 --- /dev/null +++ b/tinySDP/src/headers/tsdp_header_B.c @@ -0,0 +1,361 @@ + +/* #line 1 "./ragel/tsdp_parser_header_B.rl" */ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + + +/**@file tsdp_header_B.c + * @brief SDP "b=" header (Bandwidth). + * + */ +#include "tinysdp/headers/tsdp_header_B.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_string.h" + +#include <string.h> + +/*********************************** +* Ragel state machine. +*/ + +/* #line 63 "./ragel/tsdp_parser_header_B.rl" */ + + + + + +tsdp_header_B_t* tsdp_header_B_create(const char* bwtype, uint32_t bandwidth) +{ + return tsk_object_new(TSDP_HEADER_B_VA_ARGS(bwtype, bandwidth)); +} + +tsdp_header_B_t* tsdp_header_B_create_null() +{ + return tsdp_header_B_create(tsk_null, 0); +} + +int tsdp_header_B_tostring(const tsdp_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsdp_header_B_t *B = (const tsdp_header_B_t *)header; + + return tsk_buffer_append_2(output, "%s:%u", + B->bwtype, + B->bandwidth + ); + } + + return -1; +} + +tsdp_header_t* tsdp_header_B_clone(const tsdp_header_t* header) +{ + if(header){ + const tsdp_header_B_t *B = (const tsdp_header_B_t *)header; + return (tsdp_header_t*)tsdp_header_B_create(B->bwtype, B->bandwidth); + } + return tsk_null; +} + +tsdp_header_B_t *tsdp_header_B_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsdp_header_B_t *hdr_B = tsdp_header_B_create_null(); + + const char *tag_start = tsk_null; + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + +/* #line 92 "./src/headers/tsdp_header_B.c" */ +static const char _tsdp_machine_parser_header_B_actions[] = { + 0, 1, 0, 1, 1, 1, 2 +}; + +static const char _tsdp_machine_parser_header_B_key_offsets[] = { + 0, 0, 1, 3, 18, 33, 35, 36, + 39 +}; + +static const char _tsdp_machine_parser_header_B_trans_keys[] = { + 98, 32, 61, 32, 33, 37, 39, 126, + 42, 43, 45, 46, 48, 57, 65, 90, + 95, 122, 33, 37, 39, 58, 126, 42, + 43, 45, 46, 48, 57, 65, 90, 95, + 122, 48, 57, 10, 13, 48, 57, 0 +}; + +static const char _tsdp_machine_parser_header_B_single_lengths[] = { + 0, 1, 2, 5, 5, 0, 1, 1, + 0 +}; + +static const char _tsdp_machine_parser_header_B_range_lengths[] = { + 0, 0, 0, 5, 5, 1, 0, 1, + 0 +}; + +static const char _tsdp_machine_parser_header_B_index_offsets[] = { + 0, 0, 2, 5, 16, 27, 29, 31, + 34 +}; + +static const char _tsdp_machine_parser_header_B_indicies[] = { + 0, 1, 0, 2, 1, 2, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 1, + 4, 4, 4, 5, 4, 4, 4, 4, + 4, 4, 1, 6, 1, 7, 1, 8, + 9, 1, 1, 0 +}; + +static const char _tsdp_machine_parser_header_B_trans_targs[] = { + 2, 0, 3, 4, 4, 5, 7, 8, + 6, 7 +}; + +static const char _tsdp_machine_parser_header_B_trans_actions[] = { + 0, 0, 0, 1, 0, 3, 1, 0, + 5, 0 +}; + +static const char _tsdp_machine_parser_header_B_eof_actions[] = { + 0, 0, 0, 0, 0, 0, 0, 5, + 0 +}; + +static const int tsdp_machine_parser_header_B_start = 1; +static const int tsdp_machine_parser_header_B_first_final = 7; +static const int tsdp_machine_parser_header_B_error = 0; + +static const int tsdp_machine_parser_header_B_en_main = 1; + + +/* #line 113 "./ragel/tsdp_parser_header_B.rl" */ + (void)(tsdp_machine_parser_header_B_first_final); + (void)(tsdp_machine_parser_header_B_error); + (void)(tsdp_machine_parser_header_B_en_main); + +/* #line 160 "./src/headers/tsdp_header_B.c" */ + { + cs = tsdp_machine_parser_header_B_start; + } + +/* #line 117 "./ragel/tsdp_parser_header_B.rl" */ + +/* #line 167 "./src/headers/tsdp_header_B.c" */ + { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + + if ( p == pe ) + goto _test_eof; + if ( cs == 0 ) + goto _out; +_resume: + _keys = _tsdp_machine_parser_header_B_trans_keys + _tsdp_machine_parser_header_B_key_offsets[cs]; + _trans = _tsdp_machine_parser_header_B_index_offsets[cs]; + + _klen = _tsdp_machine_parser_header_B_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _tsdp_machine_parser_header_B_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += ((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + _trans = _tsdp_machine_parser_header_B_indicies[_trans]; + cs = _tsdp_machine_parser_header_B_trans_targs[_trans]; + + if ( _tsdp_machine_parser_header_B_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _tsdp_machine_parser_header_B_actions + _tsdp_machine_parser_header_B_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) + { + switch ( *_acts++ ) + { + case 0: +/* #line 43 "./ragel/tsdp_parser_header_B.rl" */ + { + tag_start = p; + } + break; + case 1: +/* #line 47 "./ragel/tsdp_parser_header_B.rl" */ + { + TSK_PARSER_SET_STRING(hdr_B->bwtype); + } + break; + case 2: +/* #line 51 "./ragel/tsdp_parser_header_B.rl" */ + { + TSK_PARSER_SET_UINT(hdr_B->bandwidth); + } + break; +/* #line 259 "./src/headers/tsdp_header_B.c" */ + } + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; + _test_eof: {} + if ( p == eof ) + { + const char *__acts = _tsdp_machine_parser_header_B_actions + _tsdp_machine_parser_header_B_eof_actions[cs]; + unsigned int __nacts = (unsigned int) *__acts++; + while ( __nacts-- > 0 ) { + switch ( *__acts++ ) { + case 2: +/* #line 51 "./ragel/tsdp_parser_header_B.rl" */ + { + TSK_PARSER_SET_UINT(hdr_B->bandwidth); + } + break; +/* #line 281 "./src/headers/tsdp_header_B.c" */ + } + } + } + + _out: {} + } + +/* #line 118 "./ragel/tsdp_parser_header_B.rl" */ + TSK_RAGEL_DISABLE_WARNINGS_END() + + if( cs < +/* #line 293 "./src/headers/tsdp_header_B.c" */ +7 +/* #line 120 "./ragel/tsdp_parser_header_B.rl" */ + ){ + TSK_DEBUG_ERROR("Failed to parse \"b=\" header."); + TSK_OBJECT_SAFE_FREE(hdr_B); + } + + return hdr_B; +} + + + + + + + +//======================================================== +// B header object definition +// + +static tsk_object_t* tsdp_header_B_ctor(tsk_object_t *self, va_list * app) +{ + tsdp_header_B_t *B = self; + if(B){ + TSDP_HEADER(B)->type = tsdp_htype_B; + TSDP_HEADER(B)->tostring = tsdp_header_B_tostring; + TSDP_HEADER(B)->clone = tsdp_header_B_clone; + TSDP_HEADER(B)->rank = TSDP_HTYPE_B_RANK; + + B->bwtype = tsk_strdup(va_arg(*app, const char*)); + B->bandwidth = va_arg(*app, uint32_t); + } + else{ + TSK_DEBUG_ERROR("Failed to create new B header."); + } + return self; +} + +static tsk_object_t* tsdp_header_B_dtor(tsk_object_t *self) +{ + tsdp_header_B_t *B = self; + if(B){ + TSK_FREE(B->bwtype); + } + else{ + TSK_DEBUG_ERROR("Null B header."); + } + + return self; +} +static int tsdp_header_B_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) +{ + if(obj1 && obj2){ + return tsdp_header_rank_cmp(obj1, obj2); + } + else{ + return -1; + } +} + +static const tsk_object_def_t tsdp_header_B_def_s = +{ + sizeof(tsdp_header_B_t), + tsdp_header_B_ctor, + tsdp_header_B_dtor, + tsdp_header_B_cmp +}; + +const tsk_object_def_t *tsdp_header_B_def_t = &tsdp_header_B_def_s; diff --git a/tinySDP/src/headers/tsdp_header_C.c b/tinySDP/src/headers/tsdp_header_C.c new file mode 100644 index 0000000..ddf3f4e --- /dev/null +++ b/tinySDP/src/headers/tsdp_header_C.c @@ -0,0 +1,367 @@ + +/* #line 1 "./ragel/tsdp_parser_header_C.rl" */ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + + +/**@file tsdp_header_C.c + * @brief "c=" header (Connection Data). + */ +#include "tinysdp/headers/tsdp_header_C.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_string.h" + +#include <string.h> + +/*********************************** +* Ragel state machine. +*/ + +/* #line 66 "./ragel/tsdp_parser_header_C.rl" */ + + + +tsdp_header_C_t* tsdp_header_c_create(const char* nettype, const char* addrtype, const char* addr) +{ + return tsk_object_new(TSDP_HEADER_C_VA_ARGS(nettype, addrtype, addr)); +} + +tsdp_header_C_t* tsdp_header_c_create_null() +{ + return tsdp_header_c_create(tsk_null, tsk_null, tsk_null); +} + +int tsdp_header_C_tostring(const tsdp_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsdp_header_C_t *C = (const tsdp_header_C_t *)header; + + return tsk_buffer_append_2(output, "%s %s %s", + C->nettype, + C->addrtype, + C->addr + ); + + return 0; + } + + return -1; +} + +tsdp_header_t* tsdp_header_C_clone(const tsdp_header_t* header) +{ + if(header){ + const tsdp_header_C_t *C = (const tsdp_header_C_t *)header; + return (tsdp_header_t*)tsdp_header_c_create(C->nettype, C->addrtype, C->addr); + } + return tsk_null; +} + +tsdp_header_C_t *tsdp_header_C_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsdp_header_C_t *hdr_C = tsdp_header_c_create_null(); + + const char *tag_start = tsk_null; + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + +/* #line 92 "./src/headers/tsdp_header_C.c" */ +static const char _tsdp_machine_parser_header_C_actions[] = { + 0, 1, 0, 1, 1, 1, 2, 1, + 3, 2, 0, 2, 2, 0, 3 +}; + +static const char _tsdp_machine_parser_header_C_key_offsets[] = { + 0, 0, 1, 3, 4, 5, 6, 7, + 8, 9, 10 +}; + +static const char _tsdp_machine_parser_header_C_trans_keys[] = { + 99, 32, 61, 32, 32, 32, 32, 10, + 13, 13, 0 +}; + +static const char _tsdp_machine_parser_header_C_single_lengths[] = { + 0, 1, 2, 1, 1, 1, 1, 1, + 1, 1, 0 +}; + +static const char _tsdp_machine_parser_header_C_range_lengths[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0 +}; + +static const char _tsdp_machine_parser_header_C_index_offsets[] = { + 0, 0, 2, 5, 7, 9, 11, 13, + 15, 17, 19 +}; + +static const char _tsdp_machine_parser_header_C_trans_targs[] = { + 2, 0, 2, 3, 0, 3, 4, 5, + 4, 8, 6, 8, 6, 10, 0, 7, + 9, 7, 9, 0, 0 +}; + +static const char _tsdp_machine_parser_header_C_trans_actions[] = { + 0, 0, 0, 0, 0, 0, 1, 3, + 0, 9, 1, 5, 0, 0, 0, 12, + 1, 7, 0, 0, 0 +}; + +static const char _tsdp_machine_parser_header_C_eof_actions[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 7, 0 +}; + +static const int tsdp_machine_parser_header_C_start = 1; +static const int tsdp_machine_parser_header_C_first_final = 8; +static const int tsdp_machine_parser_header_C_error = 0; + +static const int tsdp_machine_parser_header_C_en_main = 1; + + +/* #line 117 "./ragel/tsdp_parser_header_C.rl" */ + (void)(tsdp_machine_parser_header_C_first_final); + (void)(tsdp_machine_parser_header_C_error); + (void)(tsdp_machine_parser_header_C_en_main); + +/* #line 152 "./src/headers/tsdp_header_C.c" */ + { + cs = tsdp_machine_parser_header_C_start; + } + +/* #line 121 "./ragel/tsdp_parser_header_C.rl" */ + +/* #line 159 "./src/headers/tsdp_header_C.c" */ + { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + + if ( p == pe ) + goto _test_eof; + if ( cs == 0 ) + goto _out; +_resume: + _keys = _tsdp_machine_parser_header_C_trans_keys + _tsdp_machine_parser_header_C_key_offsets[cs]; + _trans = _tsdp_machine_parser_header_C_index_offsets[cs]; + + _klen = _tsdp_machine_parser_header_C_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _tsdp_machine_parser_header_C_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += ((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + cs = _tsdp_machine_parser_header_C_trans_targs[_trans]; + + if ( _tsdp_machine_parser_header_C_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _tsdp_machine_parser_header_C_actions + _tsdp_machine_parser_header_C_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) + { + switch ( *_acts++ ) + { + case 0: +/* #line 42 "./ragel/tsdp_parser_header_C.rl" */ + { + tag_start = p; + } + break; + case 1: +/* #line 46 "./ragel/tsdp_parser_header_C.rl" */ + { + TSK_PARSER_SET_STRING(hdr_C->nettype); + } + break; + case 2: +/* #line 50 "./ragel/tsdp_parser_header_C.rl" */ + { + TSK_PARSER_SET_STRING(hdr_C->addrtype); + } + break; + case 3: +/* #line 54 "./ragel/tsdp_parser_header_C.rl" */ + { + TSK_PARSER_SET_STRING(hdr_C->addr); + } + break; +/* #line 256 "./src/headers/tsdp_header_C.c" */ + } + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; + _test_eof: {} + if ( p == eof ) + { + const char *__acts = _tsdp_machine_parser_header_C_actions + _tsdp_machine_parser_header_C_eof_actions[cs]; + unsigned int __nacts = (unsigned int) *__acts++; + while ( __nacts-- > 0 ) { + switch ( *__acts++ ) { + case 0: +/* #line 42 "./ragel/tsdp_parser_header_C.rl" */ + { + tag_start = p; + } + break; + case 3: +/* #line 54 "./ragel/tsdp_parser_header_C.rl" */ + { + TSK_PARSER_SET_STRING(hdr_C->addr); + } + break; +/* #line 284 "./src/headers/tsdp_header_C.c" */ + } + } + } + + _out: {} + } + +/* #line 122 "./ragel/tsdp_parser_header_C.rl" */ + TSK_RAGEL_DISABLE_WARNINGS_END() + + if( cs < +/* #line 296 "./src/headers/tsdp_header_C.c" */ +8 +/* #line 124 "./ragel/tsdp_parser_header_C.rl" */ + ){ + TSK_DEBUG_ERROR("Failed to parse \"c=\" header."); + TSK_OBJECT_SAFE_FREE(hdr_C); + } + + return hdr_C; +} + + + + + + + +//======================================================== +// E header object definition +// + +static tsk_object_t* tsdp_header_C_ctor(tsk_object_t *self, va_list * app) +{ + tsdp_header_C_t *C = self; + if(C){ + TSDP_HEADER(C)->type = tsdp_htype_C; + TSDP_HEADER(C)->tostring = tsdp_header_C_tostring; + TSDP_HEADER(C)->clone = tsdp_header_C_clone; + TSDP_HEADER(C)->rank = TSDP_HTYPE_C_RANK; + + C->nettype = tsk_strdup(va_arg(*app, const char*)); + C->addrtype = tsk_strdup(va_arg(*app, const char*)); + C->addr = tsk_strdup(va_arg(*app, const char*)); + } + else{ + TSK_DEBUG_ERROR("Failed to create new C header."); + } + return self; +} + +static tsk_object_t* tsdp_header_C_dtor(tsk_object_t *self) +{ + tsdp_header_C_t *C = self; + if(C){ + TSK_FREE(C->nettype); + TSK_FREE(C->addrtype); + TSK_FREE(C->addr); + } + else{ + TSK_DEBUG_ERROR("Null PC header."); + } + + return self; +} +static int tsdp_header_C_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) +{ + if(obj1 && obj2){ + return tsdp_header_rank_cmp(obj1, obj2); + } + else{ + return -1; + } +} + +static const tsk_object_def_t tsdp_header_C_def_s = +{ + sizeof(tsdp_header_C_t), + tsdp_header_C_ctor, + tsdp_header_C_dtor, + tsdp_header_C_cmp +}; + +const tsk_object_def_t *tsdp_header_C_def_t = &tsdp_header_C_def_s; diff --git a/tinySDP/src/headers/tsdp_header_Dummy.c b/tinySDP/src/headers/tsdp_header_Dummy.c new file mode 100644 index 0000000..3aa3461 --- /dev/null +++ b/tinySDP/src/headers/tsdp_header_Dummy.c @@ -0,0 +1,353 @@ + +/* #line 1 "./ragel/tsdp_parser_header_Dummy.rl" */ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_header_Dummy.c + * @brief SDP Dummy header. + */ +#include "tinysdp/headers/tsdp_header_Dummy.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_string.h" + +#include <string.h> + +/*********************************** +* Ragel state machine. +*/ + +/* #line 58 "./ragel/tsdp_parser_header_Dummy.rl" */ + + + + +tsdp_header_Dummy_t* tsdp_header_dummy_create(char name, const char* value) +{ + return tsk_object_new(TSDP_HEADER_DUMMY_VA_ARGS(name, value)); +} + +tsdp_header_Dummy_t* tsdp_header_dummy_create_null() +{ + return tsdp_header_dummy_create(0, tsk_null); +} + +int tsdp_header_Dummy_tostring(const tsdp_header_t* header, tsk_buffer_t* output) +{ + if(header) + { + const tsdp_header_Dummy_t *Dummy = (const tsdp_header_Dummy_t *)header; + if(Dummy->value){ + return tsk_buffer_append(output, Dummy->value, tsk_strlen(Dummy->value)); + } + return 0; + } + + return -1; +} + +tsdp_header_t* tsdp_header_Dummy_clone(const tsdp_header_t* header) +{ + if(header){ + const tsdp_header_Dummy_t *Dummy = (const tsdp_header_Dummy_t *)header; + return (tsdp_header_t*)tsdp_header_dummy_create(Dummy->name, Dummy->value); + } + return tsk_null; +} + +tsdp_header_Dummy_t *tsdp_header_Dummy_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsdp_header_Dummy_t *hdr_Dummy = tsdp_header_dummy_create_null(); + + const char *tag_start = tsk_null; + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + +/* #line 89 "./src/headers/tsdp_header_Dummy.c" */ +static const char _tsdp_machine_parser_header_Dummy_actions[] = { + 0, 1, 0, 1, 1, 1, 2, 2, + 0, 2 +}; + +static const char _tsdp_machine_parser_header_Dummy_key_offsets[] = { + 0, 0, 4, 6, 8, 9, 11, 12 +}; + +static const char _tsdp_machine_parser_header_Dummy_trans_keys[] = { + 65, 90, 97, 122, 32, 61, 32, 61, + 10, 13, 32, 13, 0 +}; + +static const char _tsdp_machine_parser_header_Dummy_single_lengths[] = { + 0, 0, 2, 2, 1, 2, 1, 0 +}; + +static const char _tsdp_machine_parser_header_Dummy_range_lengths[] = { + 0, 2, 0, 0, 0, 0, 0, 0 +}; + +static const char _tsdp_machine_parser_header_Dummy_index_offsets[] = { + 0, 0, 3, 6, 9, 11, 14, 16 +}; + +static const char _tsdp_machine_parser_header_Dummy_trans_targs[] = { + 2, 2, 0, 3, 5, 0, 3, 5, + 0, 7, 0, 4, 5, 6, 4, 6, + 0, 0 +}; + +static const char _tsdp_machine_parser_header_Dummy_trans_actions[] = { + 1, 1, 0, 3, 3, 0, 0, 0, + 0, 0, 0, 7, 0, 1, 5, 0, + 0, 0 +}; + +static const char _tsdp_machine_parser_header_Dummy_eof_actions[] = { + 0, 0, 0, 0, 0, 7, 5, 0 +}; + +static const int tsdp_machine_parser_header_Dummy_start = 1; +static const int tsdp_machine_parser_header_Dummy_first_final = 5; +static const int tsdp_machine_parser_header_Dummy_error = 0; + +static const int tsdp_machine_parser_header_Dummy_en_main = 1; + + +/* #line 107 "./ragel/tsdp_parser_header_Dummy.rl" */ + (void)(tsdp_machine_parser_header_Dummy_first_final); + (void)(tsdp_machine_parser_header_Dummy_error); + (void)(tsdp_machine_parser_header_Dummy_en_main); + +/* #line 144 "./src/headers/tsdp_header_Dummy.c" */ + { + cs = tsdp_machine_parser_header_Dummy_start; + } + +/* #line 111 "./ragel/tsdp_parser_header_Dummy.rl" */ + +/* #line 151 "./src/headers/tsdp_header_Dummy.c" */ + { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + + if ( p == pe ) + goto _test_eof; + if ( cs == 0 ) + goto _out; +_resume: + _keys = _tsdp_machine_parser_header_Dummy_trans_keys + _tsdp_machine_parser_header_Dummy_key_offsets[cs]; + _trans = _tsdp_machine_parser_header_Dummy_index_offsets[cs]; + + _klen = _tsdp_machine_parser_header_Dummy_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _tsdp_machine_parser_header_Dummy_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += ((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + cs = _tsdp_machine_parser_header_Dummy_trans_targs[_trans]; + + if ( _tsdp_machine_parser_header_Dummy_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _tsdp_machine_parser_header_Dummy_actions + _tsdp_machine_parser_header_Dummy_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) + { + switch ( *_acts++ ) + { + case 0: +/* #line 41 "./ragel/tsdp_parser_header_Dummy.rl" */ + { + tag_start = p; + } + break; + case 1: +/* #line 45 "./ragel/tsdp_parser_header_Dummy.rl" */ + { + hdr_Dummy->name = *tag_start; + } + break; + case 2: +/* #line 49 "./ragel/tsdp_parser_header_Dummy.rl" */ + { + TSK_PARSER_SET_STRING(hdr_Dummy->value); + } + break; +/* #line 242 "./src/headers/tsdp_header_Dummy.c" */ + } + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; + _test_eof: {} + if ( p == eof ) + { + const char *__acts = _tsdp_machine_parser_header_Dummy_actions + _tsdp_machine_parser_header_Dummy_eof_actions[cs]; + unsigned int __nacts = (unsigned int) *__acts++; + while ( __nacts-- > 0 ) { + switch ( *__acts++ ) { + case 0: +/* #line 41 "./ragel/tsdp_parser_header_Dummy.rl" */ + { + tag_start = p; + } + break; + case 2: +/* #line 49 "./ragel/tsdp_parser_header_Dummy.rl" */ + { + TSK_PARSER_SET_STRING(hdr_Dummy->value); + } + break; +/* #line 270 "./src/headers/tsdp_header_Dummy.c" */ + } + } + } + + _out: {} + } + +/* #line 112 "./ragel/tsdp_parser_header_Dummy.rl" */ + TSK_RAGEL_DISABLE_WARNINGS_END() + + if( cs < +/* #line 282 "./src/headers/tsdp_header_Dummy.c" */ +5 +/* #line 114 "./ragel/tsdp_parser_header_Dummy.rl" */ + ){ + TSK_DEBUG_ERROR("Failed to parse dummy header."); + TSK_OBJECT_SAFE_FREE(hdr_Dummy); + } + + return hdr_Dummy; +} + + + + + + + +//======================================================== +// Dummy header object definition +// + +static tsk_object_t* tsdp_header_Dummy_ctor(tsk_object_t *self, va_list * app) +{ + tsdp_header_Dummy_t *Dummy = self; + if(Dummy){ + TSDP_HEADER(Dummy)->type = tsdp_htype_Dummy; + TSDP_HEADER(Dummy)->tostring = tsdp_header_Dummy_tostring; + TSDP_HEADER(Dummy)->clone = tsdp_header_Dummy_clone; + TSDP_HEADER(Dummy)->rank = TSDP_HTYPE_DUMMY_RANK; +#if defined(__GNUC__) + Dummy->name = va_arg(*app, const int); +#else + Dummy->name = va_arg(*app, const char); +#endif + Dummy->value = tsk_strdup(va_arg(*app, const char*)); + } + else{ + TSK_DEBUG_ERROR("Failed to create new Dummy header."); + } + return self; +} + +static tsk_object_t* tsdp_header_Dummy_dtor(tsk_object_t *self) +{ + tsdp_header_Dummy_t *Dummy = self; + if(Dummy){ + TSK_FREE(Dummy->value); + } + else{ + TSK_DEBUG_ERROR("Null Dummy header."); + } + + return self; +} +static int tsdp_header_Dummy_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) +{ + if(obj1 && obj2){ + return tsdp_header_rank_cmp(obj1, obj2); + } + else{ + return -1; + } +} + +static const tsk_object_def_t tsdp_header_Dummy_def_s = +{ + sizeof(tsdp_header_Dummy_t), + tsdp_header_Dummy_ctor, + tsdp_header_Dummy_dtor, + tsdp_header_Dummy_cmp +}; + +const tsk_object_def_t *tsdp_header_Dummy_def_t = &tsdp_header_Dummy_def_s; diff --git a/tinySDP/src/headers/tsdp_header_E.c b/tinySDP/src/headers/tsdp_header_E.c new file mode 100644 index 0000000..f958ca1 --- /dev/null +++ b/tinySDP/src/headers/tsdp_header_E.c @@ -0,0 +1,340 @@ + +/* #line 1 "./ragel/tsdp_parser_header_E.rl" */ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + + +/**@file tsdp_header_E.c + * @brief SDP "e=" header (Session Information). + */ +#include "tinysdp/headers/tsdp_header_E.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_string.h" + +#include <string.h> + +/*********************************** +* Ragel state machine. +*/ + +/* #line 55 "./ragel/tsdp_parser_header_E.rl" */ + + + + +tsdp_header_E_t* tsdp_header_E_create(const char* value) +{ + return tsk_object_new(TSDP_HEADER_E_VA_ARGS(value)); +} + +tsdp_header_E_t* tsdp_header_E_create_null() +{ + return tsdp_header_E_create(tsk_null); +} + +int tsdp_header_E_tostring(const tsdp_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsdp_header_E_t *E = (const tsdp_header_E_t *)header; + if(E->value){ + tsk_buffer_append(output, E->value, tsk_strlen(E->value)); + } + return 0; + } + + return -1; +} + +tsdp_header_t* tsdp_header_E_clone(const tsdp_header_t* header) +{ + if(header){ + const tsdp_header_E_t *E = (const tsdp_header_E_t *)header; + return (tsdp_header_t*)tsdp_header_E_create(E->value); + } + return tsk_null; +} + +tsdp_header_E_t *tsdp_header_E_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsdp_header_E_t *hdr_E = tsdp_header_E_create_null(); + + const char *tag_start = tsk_null; + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + +/* #line 89 "./src/headers/tsdp_header_E.c" */ +static const char _tsdp_machine_parser_header_E_actions[] = { + 0, 1, 0, 1, 1, 2, 0, 1 + +}; + +static const char _tsdp_machine_parser_header_E_key_offsets[] = { + 0, 0, 1, 3, 4, 6, 7 +}; + +static const char _tsdp_machine_parser_header_E_trans_keys[] = { + 101, 32, 61, 10, 13, 32, 13, 0 +}; + +static const char _tsdp_machine_parser_header_E_single_lengths[] = { + 0, 1, 2, 1, 2, 1, 0 +}; + +static const char _tsdp_machine_parser_header_E_range_lengths[] = { + 0, 0, 0, 0, 0, 0, 0 +}; + +static const char _tsdp_machine_parser_header_E_index_offsets[] = { + 0, 0, 2, 5, 7, 10, 12 +}; + +static const char _tsdp_machine_parser_header_E_trans_targs[] = { + 2, 0, 2, 4, 0, 6, 0, 3, + 4, 5, 3, 5, 0, 0 +}; + +static const char _tsdp_machine_parser_header_E_trans_actions[] = { + 0, 0, 0, 0, 0, 0, 0, 5, + 0, 1, 3, 0, 0, 0 +}; + +static const char _tsdp_machine_parser_header_E_eof_actions[] = { + 0, 0, 0, 0, 5, 3, 0 +}; + +static const int tsdp_machine_parser_header_E_start = 1; +static const int tsdp_machine_parser_header_E_first_final = 4; +static const int tsdp_machine_parser_header_E_error = 0; + +static const int tsdp_machine_parser_header_E_en_main = 1; + + +/* #line 103 "./ragel/tsdp_parser_header_E.rl" */ + (void)(tsdp_machine_parser_header_E_first_final); + (void)(tsdp_machine_parser_header_E_error); + (void)(tsdp_machine_parser_header_E_en_main); + +/* #line 141 "./src/headers/tsdp_header_E.c" */ + { + cs = tsdp_machine_parser_header_E_start; + } + +/* #line 107 "./ragel/tsdp_parser_header_E.rl" */ + +/* #line 148 "./src/headers/tsdp_header_E.c" */ + { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + + if ( p == pe ) + goto _test_eof; + if ( cs == 0 ) + goto _out; +_resume: + _keys = _tsdp_machine_parser_header_E_trans_keys + _tsdp_machine_parser_header_E_key_offsets[cs]; + _trans = _tsdp_machine_parser_header_E_index_offsets[cs]; + + _klen = _tsdp_machine_parser_header_E_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _tsdp_machine_parser_header_E_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += ((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + cs = _tsdp_machine_parser_header_E_trans_targs[_trans]; + + if ( _tsdp_machine_parser_header_E_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _tsdp_machine_parser_header_E_actions + _tsdp_machine_parser_header_E_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) + { + switch ( *_acts++ ) + { + case 0: +/* #line 42 "./ragel/tsdp_parser_header_E.rl" */ + { + tag_start = p; + } + break; + case 1: +/* #line 46 "./ragel/tsdp_parser_header_E.rl" */ + { + TSK_PARSER_SET_STRING(hdr_E->value); + } + break; +/* #line 233 "./src/headers/tsdp_header_E.c" */ + } + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; + _test_eof: {} + if ( p == eof ) + { + const char *__acts = _tsdp_machine_parser_header_E_actions + _tsdp_machine_parser_header_E_eof_actions[cs]; + unsigned int __nacts = (unsigned int) *__acts++; + while ( __nacts-- > 0 ) { + switch ( *__acts++ ) { + case 0: +/* #line 42 "./ragel/tsdp_parser_header_E.rl" */ + { + tag_start = p; + } + break; + case 1: +/* #line 46 "./ragel/tsdp_parser_header_E.rl" */ + { + TSK_PARSER_SET_STRING(hdr_E->value); + } + break; +/* #line 261 "./src/headers/tsdp_header_E.c" */ + } + } + } + + _out: {} + } + +/* #line 108 "./ragel/tsdp_parser_header_E.rl" */ + TSK_RAGEL_DISABLE_WARNINGS_END() + + if( cs < +/* #line 273 "./src/headers/tsdp_header_E.c" */ +4 +/* #line 110 "./ragel/tsdp_parser_header_E.rl" */ + ){ + TSK_DEBUG_ERROR("Failed to parse \"e=\" header."); + TSK_OBJECT_SAFE_FREE(hdr_E); + } + + return hdr_E; +} + + + + + + + +//======================================================== +// E header object definition +// + +static tsk_object_t* tsdp_header_E_ctor(tsk_object_t *self, va_list * app) +{ + tsdp_header_E_t *E = self; + if(E){ + TSDP_HEADER(E)->type = tsdp_htype_E; + TSDP_HEADER(E)->tostring = tsdp_header_E_tostring; + TSDP_HEADER(E)->clone = tsdp_header_E_clone; + TSDP_HEADER(E)->rank = TSDP_HTYPE_E_RANK; + + E->value = tsk_strdup(va_arg(*app, const char*)); + } + else{ + TSK_DEBUG_ERROR("Failed to create new E header."); + } + return self; +} + +static tsk_object_t* tsdp_header_E_dtor(tsk_object_t *self) +{ + tsdp_header_E_t *E = self; + if(E){ + TSK_FREE(E->value); + } + else{ + TSK_DEBUG_ERROR("Null E header."); + } + + return self; +} +static int tsdp_header_E_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) +{ + if(obj1 && obj2){ + return tsdp_header_rank_cmp(obj1, obj2); + } + else{ + return -1; + } +} + +static const tsk_object_def_t tsdp_header_E_def_s = +{ + sizeof(tsdp_header_E_t), + tsdp_header_E_ctor, + tsdp_header_E_dtor, + tsdp_header_E_cmp +}; + +const tsk_object_def_t *tsdp_header_E_def_t = &tsdp_header_E_def_s; diff --git a/tinySDP/src/headers/tsdp_header_I.c b/tinySDP/src/headers/tsdp_header_I.c new file mode 100644 index 0000000..15b204c --- /dev/null +++ b/tinySDP/src/headers/tsdp_header_I.c @@ -0,0 +1,341 @@ + +/* #line 1 "./ragel/tsdp_parser_header_I.rl" */ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + + +/**@file tsdp_header_I.c + * @brief SDP "i=" header (Session Information). + */ +#include "tinysdp/headers/tsdp_header_I.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_string.h" + +#include <string.h> + +/*********************************** +* Ragel state machine. +*/ + +/* #line 55 "./ragel/tsdp_parser_header_I.rl" */ + + + +tsdp_header_I_t* tsdp_header_I_create(const char* value) +{ + return tsk_object_new(TSDP_HEADER_I_VA_ARGS(value)); +} + +tsdp_header_I_t* tsdp_header_I_create_null() +{ + return tsdp_header_I_create(tsk_null); +} + +int tsdp_header_I_tostring(const tsdp_header_t* header, tsk_buffer_t* output) +{ + if(header) + { + const tsdp_header_I_t *I = (const tsdp_header_I_t *)header; + if(I->value){ + tsk_buffer_append(output, I->value, tsk_strlen(I->value)); + } + return 0; + } + + return -1; +} + +tsdp_header_t* tsdp_header_I_clone(const tsdp_header_t* header) +{ + if(header){ + const tsdp_header_I_t *I = (const tsdp_header_I_t *)header; + return (tsdp_header_t*)tsdp_header_I_create(I->value); + } + return tsk_null; +} + +tsdp_header_I_t *tsdp_header_I_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsdp_header_I_t *hdr_I = tsdp_header_I_create_null(); + + const char *tag_start = tsk_null; + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + +/* #line 89 "./src/headers/tsdp_header_I.c" */ +static const char _tsdp_machine_parser_header_I_actions[] = { + 0, 1, 0, 1, 1, 2, 0, 1 + +}; + +static const char _tsdp_machine_parser_header_I_key_offsets[] = { + 0, 0, 1, 3, 4, 6, 7 +}; + +static const char _tsdp_machine_parser_header_I_trans_keys[] = { + 105, 32, 61, 10, 13, 32, 13, 0 +}; + +static const char _tsdp_machine_parser_header_I_single_lengths[] = { + 0, 1, 2, 1, 2, 1, 0 +}; + +static const char _tsdp_machine_parser_header_I_range_lengths[] = { + 0, 0, 0, 0, 0, 0, 0 +}; + +static const char _tsdp_machine_parser_header_I_index_offsets[] = { + 0, 0, 2, 5, 7, 10, 12 +}; + +static const char _tsdp_machine_parser_header_I_trans_targs[] = { + 2, 0, 2, 4, 0, 6, 0, 3, + 4, 5, 3, 5, 0, 0 +}; + +static const char _tsdp_machine_parser_header_I_trans_actions[] = { + 0, 0, 0, 0, 0, 0, 0, 5, + 0, 1, 3, 0, 0, 0 +}; + +static const char _tsdp_machine_parser_header_I_eof_actions[] = { + 0, 0, 0, 0, 5, 3, 0 +}; + +static const int tsdp_machine_parser_header_I_start = 1; +static const int tsdp_machine_parser_header_I_first_final = 4; +static const int tsdp_machine_parser_header_I_error = 0; + +static const int tsdp_machine_parser_header_I_en_main = 1; + + +/* #line 103 "./ragel/tsdp_parser_header_I.rl" */ + (void)(tsdp_machine_parser_header_I_first_final); + (void)(tsdp_machine_parser_header_I_error); + (void)(tsdp_machine_parser_header_I_en_main); + +/* #line 141 "./src/headers/tsdp_header_I.c" */ + { + cs = tsdp_machine_parser_header_I_start; + } + +/* #line 107 "./ragel/tsdp_parser_header_I.rl" */ + +/* #line 148 "./src/headers/tsdp_header_I.c" */ + { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + + if ( p == pe ) + goto _test_eof; + if ( cs == 0 ) + goto _out; +_resume: + _keys = _tsdp_machine_parser_header_I_trans_keys + _tsdp_machine_parser_header_I_key_offsets[cs]; + _trans = _tsdp_machine_parser_header_I_index_offsets[cs]; + + _klen = _tsdp_machine_parser_header_I_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _tsdp_machine_parser_header_I_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += ((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + cs = _tsdp_machine_parser_header_I_trans_targs[_trans]; + + if ( _tsdp_machine_parser_header_I_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _tsdp_machine_parser_header_I_actions + _tsdp_machine_parser_header_I_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) + { + switch ( *_acts++ ) + { + case 0: +/* #line 42 "./ragel/tsdp_parser_header_I.rl" */ + { + tag_start = p; + } + break; + case 1: +/* #line 46 "./ragel/tsdp_parser_header_I.rl" */ + { + TSK_PARSER_SET_STRING(hdr_I->value); + } + break; +/* #line 233 "./src/headers/tsdp_header_I.c" */ + } + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; + _test_eof: {} + if ( p == eof ) + { + const char *__acts = _tsdp_machine_parser_header_I_actions + _tsdp_machine_parser_header_I_eof_actions[cs]; + unsigned int __nacts = (unsigned int) *__acts++; + while ( __nacts-- > 0 ) { + switch ( *__acts++ ) { + case 0: +/* #line 42 "./ragel/tsdp_parser_header_I.rl" */ + { + tag_start = p; + } + break; + case 1: +/* #line 46 "./ragel/tsdp_parser_header_I.rl" */ + { + TSK_PARSER_SET_STRING(hdr_I->value); + } + break; +/* #line 261 "./src/headers/tsdp_header_I.c" */ + } + } + } + + _out: {} + } + +/* #line 108 "./ragel/tsdp_parser_header_I.rl" */ + TSK_RAGEL_DISABLE_WARNINGS_END() + + if( cs < +/* #line 273 "./src/headers/tsdp_header_I.c" */ +4 +/* #line 110 "./ragel/tsdp_parser_header_I.rl" */ + ){ + TSK_DEBUG_ERROR("Failed to parse \"i=\" header."); + TSK_OBJECT_SAFE_FREE(hdr_I); + } + + return hdr_I; +} + + + + + + + +//======================================================== +// I header object definition +// + +static tsk_object_t* tsdp_header_I_ctor(tsk_object_t *self, va_list * app) +{ + tsdp_header_I_t *I = self; + if(I) + { + TSDP_HEADER(I)->type = tsdp_htype_I; + TSDP_HEADER(I)->tostring = tsdp_header_I_tostring; + TSDP_HEADER(I)->clone = tsdp_header_I_clone; + TSDP_HEADER(I)->rank = TSDP_HTYPE_I_RANK; + + I->value = tsk_strdup(va_arg(*app, const char*)); + } + else{ + TSK_DEBUG_ERROR("Failed to create new I header."); + } + return self; +} + +static tsk_object_t* tsdp_header_I_dtor(tsk_object_t *self) +{ + tsdp_header_I_t *I = self; + if(I){ + TSK_FREE(I->value); + } + else{ + TSK_DEBUG_ERROR("Null I header."); + } + + return self; +} +static int tsdp_header_I_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) +{ + if(obj1 && obj2){ + return tsdp_header_rank_cmp(obj1, obj2); + } + else{ + return -1; + } +} + +static const tsk_object_def_t tsdp_header_I_def_s = +{ + sizeof(tsdp_header_I_t), + tsdp_header_I_ctor, + tsdp_header_I_dtor, + tsdp_header_I_cmp +}; + +const tsk_object_def_t *tsdp_header_I_def_t = &tsdp_header_I_def_s; diff --git a/tinySDP/src/headers/tsdp_header_K.c b/tinySDP/src/headers/tsdp_header_K.c new file mode 100644 index 0000000..05d96a5 --- /dev/null +++ b/tinySDP/src/headers/tsdp_header_K.c @@ -0,0 +1,340 @@ + +/* #line 1 "./ragel/tsdp_parser_header_K.rl" */ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + + +/**@file tsdp_header_K.c + * @brief SDP "k=" header (Encryption Key). + */ +#include "tinysdp/headers/tsdp_header_K.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_string.h" + +#include <string.h> + +/*********************************** +* Ragel state machine. +*/ + +/* #line 55 "./ragel/tsdp_parser_header_K.rl" */ + + + + +tsdp_header_K_t* tsdp_header_K_create(const char* value) +{ + return tsk_object_new(TSDP_HEADER_K_VA_ARGS(value)); +} + +tsdp_header_K_t* tsdp_header_K_create_null() +{ + return tsdp_header_K_create(tsk_null); +} + +int tsdp_header_K_tostring(const tsdp_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsdp_header_K_t *K = (const tsdp_header_K_t *)header; + if(K->value){ + tsk_buffer_append(output, K->value, tsk_strlen(K->value)); + } + return 0; + } + + return -1; +} + +tsdp_header_t* tsdp_header_K_clone(const tsdp_header_t* header) +{ + if(header){ + const tsdp_header_K_t *K = (const tsdp_header_K_t *)header; + return (tsdp_header_t*)tsdp_header_K_create(K->value); + } + return tsk_null; +} + +tsdp_header_K_t *tsdp_header_K_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsdp_header_K_t *hdr_K = tsdp_header_K_create_null(); + + const char *tag_start = tsk_null; + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + +/* #line 89 "./src/headers/tsdp_header_K.c" */ +static const char _tsdp_machine_parser_header_K_actions[] = { + 0, 1, 0, 1, 1, 2, 0, 1 + +}; + +static const char _tsdp_machine_parser_header_K_key_offsets[] = { + 0, 0, 1, 3, 4, 6, 7 +}; + +static const char _tsdp_machine_parser_header_K_trans_keys[] = { + 107, 32, 61, 10, 13, 32, 13, 0 +}; + +static const char _tsdp_machine_parser_header_K_single_lengths[] = { + 0, 1, 2, 1, 2, 1, 0 +}; + +static const char _tsdp_machine_parser_header_K_range_lengths[] = { + 0, 0, 0, 0, 0, 0, 0 +}; + +static const char _tsdp_machine_parser_header_K_index_offsets[] = { + 0, 0, 2, 5, 7, 10, 12 +}; + +static const char _tsdp_machine_parser_header_K_trans_targs[] = { + 2, 0, 2, 4, 0, 6, 0, 3, + 4, 5, 3, 5, 0, 0 +}; + +static const char _tsdp_machine_parser_header_K_trans_actions[] = { + 0, 0, 0, 0, 0, 0, 0, 5, + 0, 1, 3, 0, 0, 0 +}; + +static const char _tsdp_machine_parser_header_K_eof_actions[] = { + 0, 0, 0, 0, 5, 3, 0 +}; + +static const int tsdp_machine_parser_header_K_start = 1; +static const int tsdp_machine_parser_header_K_first_final = 4; +static const int tsdp_machine_parser_header_K_error = 0; + +static const int tsdp_machine_parser_header_K_en_main = 1; + + +/* #line 103 "./ragel/tsdp_parser_header_K.rl" */ + (void)(tsdp_machine_parser_header_K_first_final); + (void)(tsdp_machine_parser_header_K_error); + (void)(tsdp_machine_parser_header_K_en_main); + +/* #line 141 "./src/headers/tsdp_header_K.c" */ + { + cs = tsdp_machine_parser_header_K_start; + } + +/* #line 107 "./ragel/tsdp_parser_header_K.rl" */ + +/* #line 148 "./src/headers/tsdp_header_K.c" */ + { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + + if ( p == pe ) + goto _test_eof; + if ( cs == 0 ) + goto _out; +_resume: + _keys = _tsdp_machine_parser_header_K_trans_keys + _tsdp_machine_parser_header_K_key_offsets[cs]; + _trans = _tsdp_machine_parser_header_K_index_offsets[cs]; + + _klen = _tsdp_machine_parser_header_K_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _tsdp_machine_parser_header_K_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += ((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + cs = _tsdp_machine_parser_header_K_trans_targs[_trans]; + + if ( _tsdp_machine_parser_header_K_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _tsdp_machine_parser_header_K_actions + _tsdp_machine_parser_header_K_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) + { + switch ( *_acts++ ) + { + case 0: +/* #line 42 "./ragel/tsdp_parser_header_K.rl" */ + { + tag_start = p; + } + break; + case 1: +/* #line 46 "./ragel/tsdp_parser_header_K.rl" */ + { + TSK_PARSER_SET_STRING(hdr_K->value); + } + break; +/* #line 233 "./src/headers/tsdp_header_K.c" */ + } + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; + _test_eof: {} + if ( p == eof ) + { + const char *__acts = _tsdp_machine_parser_header_K_actions + _tsdp_machine_parser_header_K_eof_actions[cs]; + unsigned int __nacts = (unsigned int) *__acts++; + while ( __nacts-- > 0 ) { + switch ( *__acts++ ) { + case 0: +/* #line 42 "./ragel/tsdp_parser_header_K.rl" */ + { + tag_start = p; + } + break; + case 1: +/* #line 46 "./ragel/tsdp_parser_header_K.rl" */ + { + TSK_PARSER_SET_STRING(hdr_K->value); + } + break; +/* #line 261 "./src/headers/tsdp_header_K.c" */ + } + } + } + + _out: {} + } + +/* #line 108 "./ragel/tsdp_parser_header_K.rl" */ + TSK_RAGEL_DISABLE_WARNINGS_END() + + if( cs < +/* #line 273 "./src/headers/tsdp_header_K.c" */ +4 +/* #line 110 "./ragel/tsdp_parser_header_K.rl" */ + ){ + TSK_DEBUG_ERROR("Failed to parse \"k=\" header."); + TSK_OBJECT_SAFE_FREE(hdr_K); + } + + return hdr_K; +} + + + + + + + +//======================================================== +// K header object definition +// + +static tsk_object_t* tsdp_header_K_ctor(tsk_object_t *self, va_list * app) +{ + tsdp_header_K_t *K = self; + if(K){ + TSDP_HEADER(K)->type = tsdp_htype_K; + TSDP_HEADER(K)->tostring = tsdp_header_K_tostring; + TSDP_HEADER(K)->clone = tsdp_header_K_clone; + TSDP_HEADER(K)->rank = TSDP_HTYPE_P_RANK; + + K->value = tsk_strdup(va_arg(*app, const char*)); + } + else{ + TSK_DEBUG_ERROR("Failed to create new K header."); + } + return self; +} + +static tsk_object_t* tsdp_header_K_dtor(tsk_object_t *self) +{ + tsdp_header_K_t *K = self; + if(K){ + TSK_FREE(K->value); + } + else{ + TSK_DEBUG_ERROR("Null K header."); + } + + return self; +} +static int tsdp_header_K_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) +{ + if(obj1 && obj2){ + return tsdp_header_rank_cmp(obj1, obj2); + } + else{ + return -1; + } +} + +static const tsk_object_def_t tsdp_header_K_def_s = +{ + sizeof(tsdp_header_K_t), + tsdp_header_K_ctor, + tsdp_header_K_dtor, + tsdp_header_K_cmp +}; + +const tsk_object_def_t *tsdp_header_K_def_t = &tsdp_header_K_def_s; diff --git a/tinySDP/src/headers/tsdp_header_M.c b/tinySDP/src/headers/tsdp_header_M.c new file mode 100644 index 0000000..597839b --- /dev/null +++ b/tinySDP/src/headers/tsdp_header_M.c @@ -0,0 +1,1086 @@ + +/* #line 1 "./ragel/tsdp_parser_header_M.rl" */ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + + +/**@file tsdp_header_M.c + * @brief SDP "m=" header (Media Descriptions). + * + */ +#include "tinysdp/headers/tsdp_header_M.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_string.h" + +#include <string.h> + +/*********************************** +* Ragel state machine. +*/ + +/* #line 78 "./ragel/tsdp_parser_header_M.rl" */ + + + + +tsdp_header_M_t* tsdp_header_M_create(const char* media, uint32_t port, const char* proto) +{ + return tsk_object_new(TSDP_HEADER_M_VA_ARGS(media, port, proto)); +} + +tsdp_header_M_t* tsdp_header_M_create_null() +{ + return tsdp_header_M_create(tsk_null, 0, tsk_null); +} + +tsdp_fmt_t* tsdp_fmt_create(const char* fmt) +{ + return tsk_object_new(TSDP_FMT_VA_ARGS(fmt)); +} + + +int tsdp_header_M_tostring(const tsdp_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsdp_header_M_t *M = (const tsdp_header_M_t *)header; + const tsk_list_item_t* item; + tsk_istr_t nports; + + tsk_itoa(M->nports, &nports); + + /* IMPORTANT: Keep the order. + + m= (media name and transport address) + i=* (media title) + c=* (connection information -- optional if included at + session level) + b=* (zero or more bandwidth information lines) + k=* (encryption key) + a=* (zero or more media attribute lines) + */ + tsk_buffer_append_2(output, "%s %u%s%s %s", + M->media, + M->port, + + M->nports ? "/" : "", + M->nports ? nports : "", + + M->proto + ); + // FMTs + tsk_list_foreach(item, M->FMTs){ + tsk_buffer_append_2(output, " %s", TSDP_FMT_STR(item->data)); + } + tsk_buffer_append(output, "\r\n", 2); // close the "m=" line. + // i=* (media title) + if(M->I){ + tsdp_header_serialize(TSDP_HEADER(M->I), output); + } + // c=* (connection information -- optional if included at session level) + if(M->C){ + tsdp_header_serialize(TSDP_HEADER(M->C), output); + } + // b=* (zero or more bandwidth information lines) + if(M->Bandwidths){ + tsk_list_foreach(item, M->Bandwidths){ + tsdp_header_serialize(TSDP_HEADER(item->data), output); + } + } + // k=* (encryption key) + if(M->K){ + tsdp_header_serialize(TSDP_HEADER(M->K), output); + } + // a=* (zero or more media attribute lines) + if(M->Attributes){ + tsk_list_foreach(item, M->Attributes){ + tsdp_header_serialize(TSDP_HEADER(item->data), output); + } + } + return 0; + } + + return -1; +} + +tsdp_header_t* tsdp_header_M_clone(const tsdp_header_t* header) +{ + if(header){ + const tsdp_header_M_t *M = (const tsdp_header_M_t *)header; + tsdp_header_M_t* clone; + const tsk_list_item_t* item; + + if((clone = tsdp_header_M_create(M->media, M->port, M->proto))){ + clone->nports = M->nports; + + // Formats + tsk_list_foreach(item, M->FMTs){ + tsk_string_t* string = tsk_string_create(TSK_STRING_STR(item->data)); + tsk_list_push_back_data(clone->FMTs, (void**)&string); + } + + // I + clone->I = (tsdp_header_I_t*) (M->I ? TSDP_HEADER(M->I)->clone(TSDP_HEADER(M->I)) : tsk_null); + // C + clone->C = (tsdp_header_C_t*) (M->C ? TSDP_HEADER(M->C)->clone(TSDP_HEADER(M->C)) : tsk_null); + // Bandwidths + tsk_list_foreach(item, M->Bandwidths){ + tsdp_header_t* B; + if(!clone->Bandwidths){ + clone->Bandwidths = tsk_list_create(); + } + B = ((tsdp_header_t*)item->data)->clone((tsdp_header_t*)item->data); + tsk_list_push_back_data(clone->Bandwidths, (void**)&B); + } + // K + clone->K = (tsdp_header_K_t*) (M->K ? TSDP_HEADER(M->K)->clone(TSDP_HEADER(M->K)) : tsk_null); + // Attributes + tsk_list_foreach(item, M->Attributes){ + tsdp_header_t* A; + if(!clone->Attributes){ + clone->Attributes = tsk_list_create(); + } + A = ((tsdp_header_t*)item->data)->clone((tsdp_header_t*)item->data); + tsk_list_push_back_data(clone->Attributes, (void**)&A); + } + } + + return TSDP_HEADER(clone); + } + return tsk_null; +} + +tsdp_header_M_t *tsdp_header_M_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsdp_header_M_t *hdr_M = tsdp_header_M_create_null(); + + const char *tag_start = tsk_null; + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + +/* #line 184 "./src/headers/tsdp_header_M.c" */ +static const char _tsdp_machine_parser_header_M_actions[] = { + 0, 1, 0, 1, 1, 1, 2, 1, + 3, 1, 4 +}; + +static const char _tsdp_machine_parser_header_M_key_offsets[] = { + 0, 0, 1, 3, 18, 33, 35, 39, + 53, 54, 68, 70, 73, 88, 88, 103 +}; + +static const char _tsdp_machine_parser_header_M_trans_keys[] = { + 109, 32, 61, 32, 33, 37, 39, 126, + 42, 43, 45, 46, 48, 57, 65, 90, + 95, 122, 32, 33, 37, 39, 126, 42, + 43, 45, 46, 48, 57, 65, 90, 95, + 122, 48, 57, 32, 47, 48, 57, 33, + 37, 39, 126, 42, 43, 45, 46, 48, + 57, 65, 90, 95, 122, 10, 33, 37, + 39, 126, 42, 43, 45, 46, 48, 57, + 65, 90, 95, 122, 48, 57, 32, 48, + 57, 13, 32, 33, 37, 39, 47, 126, + 42, 43, 45, 57, 65, 90, 95, 122, + 13, 33, 37, 39, 126, 42, 43, 45, + 46, 48, 57, 65, 90, 95, 122, 13, + 32, 33, 37, 39, 126, 42, 43, 45, + 46, 48, 57, 65, 90, 95, 122, 0 +}; + +static const char _tsdp_machine_parser_header_M_single_lengths[] = { + 0, 1, 2, 5, 5, 0, 2, 4, + 1, 4, 0, 1, 7, 0, 5, 6 +}; + +static const char _tsdp_machine_parser_header_M_range_lengths[] = { + 0, 0, 0, 5, 5, 1, 1, 5, + 0, 5, 1, 1, 4, 0, 5, 5 +}; + +static const char _tsdp_machine_parser_header_M_index_offsets[] = { + 0, 0, 2, 5, 16, 27, 29, 33, + 43, 45, 55, 57, 60, 72, 73, 84 +}; + +static const char _tsdp_machine_parser_header_M_indicies[] = { + 0, 1, 0, 2, 1, 2, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 1, + 4, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 1, 6, 1, 7, 8, 9, + 1, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 1, 11, 1, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 1, 13, + 1, 7, 14, 1, 15, 16, 12, 12, + 12, 17, 12, 12, 12, 12, 12, 1, + 1, 18, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 1, 20, 21, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 1, + 0 +}; + +static const char _tsdp_machine_parser_header_M_trans_targs[] = { + 2, 0, 3, 4, 5, 4, 6, 7, + 10, 6, 12, 13, 12, 11, 11, 8, + 14, 9, 8, 15, 8, 14, 15 +}; + +static const char _tsdp_machine_parser_header_M_trans_actions[] = { + 0, 0, 0, 1, 3, 0, 1, 5, + 5, 0, 1, 0, 0, 1, 0, 7, + 7, 0, 0, 1, 9, 9, 0 +}; + +static const char _tsdp_machine_parser_header_M_eof_actions[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 0, 0, 9 +}; + +static const int tsdp_machine_parser_header_M_start = 1; +static const int tsdp_machine_parser_header_M_first_final = 12; +static const int tsdp_machine_parser_header_M_error = 0; + +static const int tsdp_machine_parser_header_M_en_main = 1; + + +/* #line 220 "./ragel/tsdp_parser_header_M.rl" */ + (void)(tsdp_machine_parser_header_M_first_final); + (void)(tsdp_machine_parser_header_M_error); + (void)(tsdp_machine_parser_header_M_en_main); + +/* #line 273 "./src/headers/tsdp_header_M.c" */ + { + cs = tsdp_machine_parser_header_M_start; + } + +/* #line 224 "./ragel/tsdp_parser_header_M.rl" */ + +/* #line 280 "./src/headers/tsdp_header_M.c" */ + { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + + if ( p == pe ) + goto _test_eof; + if ( cs == 0 ) + goto _out; +_resume: + _keys = _tsdp_machine_parser_header_M_trans_keys + _tsdp_machine_parser_header_M_key_offsets[cs]; + _trans = _tsdp_machine_parser_header_M_index_offsets[cs]; + + _klen = _tsdp_machine_parser_header_M_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _tsdp_machine_parser_header_M_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += ((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + _trans = _tsdp_machine_parser_header_M_indicies[_trans]; + cs = _tsdp_machine_parser_header_M_trans_targs[_trans]; + + if ( _tsdp_machine_parser_header_M_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _tsdp_machine_parser_header_M_actions + _tsdp_machine_parser_header_M_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) + { + switch ( *_acts++ ) + { + case 0: +/* #line 43 "./ragel/tsdp_parser_header_M.rl" */ + { + tag_start = p; + } + break; + case 1: +/* #line 47 "./ragel/tsdp_parser_header_M.rl" */ + { + TSK_PARSER_SET_STRING(hdr_M->media); + } + break; + case 2: +/* #line 51 "./ragel/tsdp_parser_header_M.rl" */ + { + TSK_PARSER_SET_UINT(hdr_M->port); + } + break; + case 3: +/* #line 59 "./ragel/tsdp_parser_header_M.rl" */ + { + TSK_PARSER_SET_STRING(hdr_M->proto); + } + break; + case 4: +/* #line 63 "./ragel/tsdp_parser_header_M.rl" */ + { + TSK_PARSER_ADD_STRING(hdr_M->FMTs); + } + break; +/* #line 384 "./src/headers/tsdp_header_M.c" */ + } + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; + _test_eof: {} + if ( p == eof ) + { + const char *__acts = _tsdp_machine_parser_header_M_actions + _tsdp_machine_parser_header_M_eof_actions[cs]; + unsigned int __nacts = (unsigned int) *__acts++; + while ( __nacts-- > 0 ) { + switch ( *__acts++ ) { + case 3: +/* #line 59 "./ragel/tsdp_parser_header_M.rl" */ + { + TSK_PARSER_SET_STRING(hdr_M->proto); + } + break; + case 4: +/* #line 63 "./ragel/tsdp_parser_header_M.rl" */ + { + TSK_PARSER_ADD_STRING(hdr_M->FMTs); + } + break; +/* #line 412 "./src/headers/tsdp_header_M.c" */ + } + } + } + + _out: {} + } + +/* #line 225 "./ragel/tsdp_parser_header_M.rl" */ + TSK_RAGEL_DISABLE_WARNINGS_END() + + if( cs < +/* #line 424 "./src/headers/tsdp_header_M.c" */ +12 +/* #line 227 "./ragel/tsdp_parser_header_M.rl" */ + ){ + TSK_DEBUG_ERROR("Failed to parse \"m=\" header."); + TSK_OBJECT_SAFE_FREE(hdr_M); + } + + return hdr_M; +} + + +// for A headers, use "tsdp_header_A_removeAll_by_field()" +int tsdp_header_M_remove(tsdp_header_M_t* self, tsdp_header_type_t type) +{ + switch(type){ + case tsdp_htype_I: + { + TSK_OBJECT_SAFE_FREE(self->I); + break; + } + case tsdp_htype_C: + { + TSK_OBJECT_SAFE_FREE(self->C); + break; + } + case tsdp_htype_B: + { + if(self->Bandwidths){ + tsk_list_clear_items(self->Bandwidths); + } + break; + } + case tsdp_htype_K: + { + TSK_OBJECT_SAFE_FREE(self->K); + break; + } + } + return 0; +} + +int tsdp_header_M_add(tsdp_header_M_t* self, const tsdp_header_t* header) +{ + if(!self || !header){ + return -1; + } + + switch(header->type){ + case tsdp_htype_I: + { + TSK_OBJECT_SAFE_FREE(self->I); + self->I = tsk_object_ref((void*)header); + break; + } + case tsdp_htype_C: + { + TSK_OBJECT_SAFE_FREE(self->C); + self->C = tsk_object_ref((void*)header); + break; + } + case tsdp_htype_B: + { + tsdp_header_t* B = tsk_object_ref((void*)header); + if(!self->Bandwidths){ + self->Bandwidths = tsk_list_create(); + } + tsk_list_push_back_data(self->Bandwidths, (void**)&B); + break; + } + case tsdp_htype_K: + { + TSK_OBJECT_SAFE_FREE(self->K); + self->K = tsk_object_ref((void*)header); + break; + } + case tsdp_htype_A: + { + tsdp_header_t* A = tsk_object_ref((void*)header); + if(!self->Attributes){ + self->Attributes = tsk_list_create(); + } + tsk_list_push_back_data(self->Attributes, (void**)&A); + break; + } + } + + return 0; +} + +int tsdp_header_M_add_headers(tsdp_header_M_t* self, ...) +{ + const tsk_object_def_t* objdef; + tsdp_header_t *header; + tsdp_fmt_t* fmt; + va_list ap; + + if(!self){ + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + va_start(ap, self); + while((objdef = va_arg(ap, const tsk_object_def_t*))){ + if(objdef == tsdp_fmt_def_t){ + if((fmt = tsk_object_new_2(objdef, &ap))){ + tsk_list_push_back_data(self->FMTs, (void**)&fmt); + } + } + else{ + if((header = tsk_object_new_2(objdef, &ap))){ + tsdp_header_M_add(self, header); + TSK_OBJECT_SAFE_FREE(header); + } + } + } + va_end(ap); + + return 0; +} + +int tsdp_header_M_add_headers_2(tsdp_header_M_t* self, const tsdp_headers_L_t* headers) +{ + const tsk_list_item_t* item; + + if(!self || !headers){ + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + tsk_list_foreach(item, headers){ + tsdp_header_M_add(self, item->data); + } + + return 0; +} + +int tsdp_header_M_add_fmt(tsdp_header_M_t* self, const char* fmt) +{ + tsdp_fmt_t* _fmt; + if(!self || tsk_strnullORempty(fmt)){ + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + if((_fmt = tsdp_fmt_create(fmt))){ + tsk_list_push_back_data(self->FMTs, (void**)&_fmt); + return 0; + } + else{ + TSK_DEBUG_ERROR("Failed to create fmt object"); + return -2; + } +} + +int tsdp_header_M_remove_fmt(tsdp_header_M_t* self, const char* fmt) +{ + const tsk_list_item_t* itemM; + const tsdp_fmt_t* _fmt; + char* fmt_plus_space = tsk_null; + tsk_size_t fmt_plus_space_len; + if(!self || tsk_strnullORempty(fmt)){ + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + tsk_sprintf(&fmt_plus_space, "%s ", fmt); + if((fmt_plus_space_len = tsk_strlen(fmt_plus_space))){ + tsk_list_foreach(itemM, self->FMTs){ + if(!(_fmt = (const tsdp_fmt_t*)itemM->data)){ + continue; + } + if(tsk_striequals(_fmt->value, fmt)){ + // remove all A headers using this attribute + const tsdp_header_A_t* A; + const tsk_list_item_t* itemA; +removeAttributes: + tsk_list_foreach(itemA, self->Attributes){ + if(!(A = (const tsdp_header_A_t*)itemA->data)){ + continue; + } + if(tsk_strindexOf(A->value, fmt_plus_space_len, fmt_plus_space) == 0){ + // Guard to be sure we know what to remove. For example: + // tsdp_header_M_remove_fmt(self, 0) would remove both + // a=rtpmap:0 PCMU/8000/1 + // a=crypto:0 AES_CM_128_HMAC_SHA1_32 inline:Gi8s25tDKDnd/xORJ/ZtRWWC1drVbax5Ve4ftCWd + // and cause issue 115: https://code.google.com/p/webrtc2sip/issues/detail?id=115 + if(!tsk_striequals(A->field, "crypto")){ + tsk_list_remove_item(self->Attributes, (tsk_list_item_t*)itemA); + goto removeAttributes; + } + } + } + tsk_list_remove_item(self->FMTs, (tsk_list_item_t*)itemM); + break; + } + } + } + TSK_FREE(fmt_plus_space); + return 0; +} + +tsk_bool_t tsdp_header_M_have_fmt(const tsdp_header_M_t* self, const char* fmt) +{ + if(self && !tsk_strnullORempty(fmt)){ + const tsk_list_item_t* item; + const tsdp_fmt_t* _fmt; + tsk_list_foreach(item, self->FMTs){ + if(!(_fmt = (const tsdp_fmt_t*)item->data)){ + continue; + } + if(tsk_striequals(_fmt->value, fmt)){ + return tsk_true; + } + } + } + + return tsk_false; +} + +const tsdp_header_A_t* tsdp_header_M_findA_at(const tsdp_header_M_t* self, const char* field, tsk_size_t index) +{ + const tsk_list_item_t *item; + tsk_size_t pos = 0; + const tsdp_header_A_t* A; + + if(!self){ + TSK_DEBUG_ERROR("Invalid parameter"); + return tsk_null; + } + + tsk_list_foreach(item, self->Attributes){ + if(!(A = item->data)){ + continue; + } + + if(tsk_strequals(A->field, field)){ + if(pos++ >= index){ + return A; + } + } + } + + return tsk_null; +} + +const tsdp_header_A_t* tsdp_header_M_findA(const tsdp_header_M_t* self, const char* field) +{ + return tsdp_header_M_findA_at(self, field, 0); +} + +char* tsdp_header_M_getAValue(const tsdp_header_M_t* self, const char* field, const char* fmt) +{ + char *value = tsk_null; /* e.g. AMR-WB/16000 */ + tsk_size_t i = 0, fmt_len, A_len; + int indexof; + const tsdp_header_A_t* A; + + fmt_len = tsk_strlen(fmt); + if(!self || !fmt_len || fmt_len > 3/*'0-255' or '*'*/){ + TSK_DEBUG_ERROR("Invalid parameter"); + return tsk_null; + } + + /* find "a=rtpmap" */ + while((A = tsdp_header_M_findA_at(self, field, i++))){ + /* A->value would be: "98 AMR-WB/16000" */ + if((A_len = tsk_strlen(A->value)) < (fmt_len + 1/*space*/)){ + continue; + } + if((indexof = tsk_strindexOf(A->value, A_len, fmt)) == 0 && (A->value[fmt_len] == ' ')){ + value = tsk_strndup(&A->value[fmt_len+1], (A_len-(fmt_len+1))); + break; + } + } + return value; +} + +/* as per 3GPP TS 34.610 */ +int tsdp_header_M_hold(tsdp_header_M_t* self, tsk_bool_t local) +{ + const tsdp_header_A_t* a; + if(!self){ + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + if((a = tsdp_header_M_findA(self, local ? "recvonly" : "sendonly"))){ + // an "inactive" SDP attribute if the stream was previously set to "recvonly" media stream + tsk_strupdate(&(TSDP_HEADER_A(a)->field), local ? "inactive" : "recvonly"); + } + else if((a = tsdp_header_M_findA(self, "sendrecv"))){ + // a "sendonly" SDP attribute if the stream was previously set to "sendrecv" media stream + tsk_strupdate(&(TSDP_HEADER_A(a)->field), local ? "sendonly" : "recvonly"); + } + else{ + // default value is sendrecv. hold on default --> sendonly + if(!(a = tsdp_header_M_findA(self, local ? "sendonly" : "recvonly")) && !(a = tsdp_header_M_findA(self, "inactive"))){ + tsdp_header_A_t* newA; + if((newA = tsdp_header_A_create(local ? "sendonly" : "recvonly", tsk_null))){ + tsdp_header_M_add(self, TSDP_HEADER_CONST(newA)); + TSK_OBJECT_SAFE_FREE(newA); + } + } + } + return 0; +} + +/* as per 3GPP TS 34.610 */ +int tsdp_header_M_set_holdresume_att(tsdp_header_M_t* self, tsk_bool_t lo_held, tsk_bool_t ro_held) +{ + const tsdp_header_A_t* A; + static const char* hold_resume_atts[2][2] = + { + {"sendrecv", "recvonly"}, + {"sendonly", "inactive"}, + }; + if(!self){ + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + if((A = tsdp_header_M_findA(self, "sendrecv")) || (A = tsdp_header_M_findA(self, "sendonly")) || (A = tsdp_header_M_findA(self, "recvonly")) || (A = tsdp_header_M_findA(self, "inactive"))){ + tsk_strupdate(&(TSDP_HEADER_A(A)->field), hold_resume_atts[lo_held & 1][ro_held & 1]); + } + else{ + tsdp_header_A_t* newA; + if((newA = tsdp_header_A_create(hold_resume_atts[lo_held & 1][ro_held & 1], tsk_null))){ + tsdp_header_M_add(self, TSDP_HEADER_CONST(newA)); + TSK_OBJECT_SAFE_FREE(newA); + } + } + + return 0; +} + +const char* tsdp_header_M_get_holdresume_att(const tsdp_header_M_t* self) +{ + static const char* hold_resume_atts[4] = {"sendrecv"/*first because most likely to be present*/, "recvonly", "sendonly", "inactive"}; + static tsk_size_t hold_resume_atts_count = sizeof(hold_resume_atts)/sizeof(hold_resume_atts[0]); + tsk_size_t i; + if(!self){ + TSK_DEBUG_ERROR("Invalid parameter"); + return hold_resume_atts[0]; + } + for(i = 0; i < hold_resume_atts_count; ++i){ + if(tsdp_header_M_findA(self, hold_resume_atts[i])){ + return hold_resume_atts[i]; + } + } + return hold_resume_atts[0]; +} + +tsk_bool_t tsdp_header_M_is_held(const tsdp_header_M_t* self, tsk_bool_t local) +{ + if(!self){ + TSK_DEBUG_ERROR("Invalid parameter"); + return tsk_false; + } + + /* both cases */ + if(tsdp_header_M_findA(self, "inactive")){ + return tsk_true; + } + + if(local){ + return tsdp_header_M_findA(self, "recvonly") ? tsk_true : tsk_false; + } + else{ + return tsdp_header_M_findA(self, "sendonly") ? tsk_true : tsk_false; + } +} + +/* as per 3GPP TS 34.610 */ +int tsdp_header_M_resume(tsdp_header_M_t* self, tsk_bool_t local) +{ + const tsdp_header_A_t* a; + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + if((a = tsdp_header_M_findA(self, "inactive"))){ + // a "recvonly" SDP attribute if the stream was previously an inactive media stream + tsk_strupdate(&(TSDP_HEADER_A(a)->field), local ? "recvonly" : "sendonly"); + } + else if((a = tsdp_header_M_findA(self, local ? "sendonly" : "recvonly"))){ + // a "sendrecv" SDP attribute if the stream was previously a sendonly media stream, or the attribute may be omitted, since sendrecv is the default + tsk_strupdate(&(TSDP_HEADER_A(a)->field), "sendrecv"); + } + return 0; +} + +tsk_bool_t tsdp_header_M_is_ice_enabled(const tsdp_header_M_t* self) +{ + if (self) { + const tsdp_header_A_t *A; + tsk_bool_t have_ufrag = tsk_false, have_pwd = tsk_false, have_candidates = tsk_false; + + if ((A = tsdp_header_M_findA(self, "ice-ufrag"))) { + have_ufrag = tsk_true; + } + if ((A = tsdp_header_M_findA(self, "ice-pwd"))) { + have_pwd = tsk_true; + } + have_candidates = (tsdp_header_M_findA_at(self, "candidate", 0) != tsk_null); + return have_ufrag && have_pwd && have_candidates; + } + return tsk_false; +} + +tsk_bool_t tsdp_header_M_is_ice_restart(const tsdp_header_M_t* self) +{ + // https://tools.ietf.org/html/rfc5245#section-9.1.1.1 + if (self) { + return (self->C && self->C->addr && tsk_striequals("0.0.0.0", self->C->addr)); + } + return tsk_false; +} + +int tsdp_header_M_diff(const tsdp_header_M_t* M_old, const tsdp_header_M_t* M_new, tsdp_header_M_diff_t* _diff) +{ + tsdp_header_M_diff_t diff = tsdp_header_M_diff_none; + const tsdp_header_A_t *A0, *A1; + int ret = 0; + tsk_size_t index; + if (!M_old || !_diff) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + if (!M_new || !tsk_striequals(M_new->media, M_old->media)) { + // media lines must be at the same index + // (M1 == null) means media lines are not at the same index or new one have been added/removed + diff |= tsdp_header_M_diff_index; + } + + // hold/resume + if (M_new && !tsk_striequals(tsdp_header_M_get_holdresume_att(M_old), tsdp_header_M_get_holdresume_att(M_new))) { + diff |= tsdp_header_M_diff_hold_resume; + } + + // dtls fingerprint + A0 = tsdp_header_M_findA_at(M_old, "fingerprint", 0); + A1 = M_new ? tsdp_header_M_findA_at(M_new, "fingerprint", 0) : tsk_null; + if (A0 && A1 && !tsk_striequals(A0->value, A1->value)) { + diff |= tsdp_header_M_diff_dtls_fingerprint; + } + + // sdes cryptos + index = 0; + do { + A0 = tsdp_header_M_findA_at(M_old, "crypto", index); + A1 = M_new ? tsdp_header_M_findA_at(M_new, "crypto", index) : tsk_null; + if (A0 && A1) { + if (!tsk_striequals(A0->value, A1->value)) { + diff |= tsdp_header_M_diff_sdes_crypto; + } + } + else if (index == 0 && (A0 || A1)) { // (A1 && !AO) means "more" crypto lines, otherwise "less". In all cases if the first matched we're ok + diff |= tsdp_header_M_diff_sdes_crypto; + } + ++index; + } while ((A0 && A1) && ((diff & tsdp_header_M_diff_sdes_crypto) != tsdp_header_M_diff_sdes_crypto)); + + // media lines + if ((diff & tsdp_header_M_diff_index) != tsdp_header_M_diff_index) { + char* M0ProtoF = tsk_null; // old proto with "F" at the end, do nothing if we transit from AVP to AVPF because it means nego. succeeded + tsk_strcat_2(&M0ProtoF, "%sF", M_old->proto); + if ( + // (M1 == null) means media lines are not at the same index or new one have been added/removed + (!M_new) + // same media (e.g. audio) + || !tsk_striequals(M_new->media, M_old->media) + // same protos (e.g. SRTP) + || !(tsk_striequals(M_new->proto, M_old->proto) || tsk_striequals(M_new->proto, M0ProtoF))) + { + diff |= tsdp_header_M_diff_index; + } + TSK_FREE(M0ProtoF); + } + + // codecs + if (M_new && (diff & tsdp_header_M_diff_index) != tsdp_header_M_diff_index) { // make sure it's same media at same index + if (tsk_list_count_all(M_old->FMTs) == tsk_list_count_all(M_new->FMTs)) { + if ((diff & tsdp_header_M_diff_index) != tsdp_header_M_diff_index) { // make sure it's same media at same index + const tsk_list_item_t* codec_item0; + const tsdp_fmt_t* codec_fmt1; + tsk_size_t codec_index0 = 0; + tsk_list_foreach(codec_item0, M_old->FMTs) { + codec_fmt1 = (const tsdp_fmt_t*)tsk_list_find_object_by_pred_at_index(M_new->FMTs, tsk_null, tsk_null, codec_index0++); + if (!codec_fmt1 || !tsk_striequals(codec_fmt1->value, ((const tsdp_fmt_t*)codec_item0->data)->value)) { + diff |= tsdp_header_M_diff_codecs; + break; + } + } + } + } + else { + diff |= tsdp_header_M_diff_codecs; + } + } + + // network ports + if ((M_new ? M_new->port : 0) != (M_old->port)) { + diff |= tsdp_header_M_diff_network_info; + } + + if (M_new) { + if ((diff & tsdp_header_M_diff_network_info) != tsdp_header_M_diff_network_info) { + // Connection informations must be both "null" or "not-null" + if (!((M_old->C && M_new->C) || (!M_old->C && !M_new->C))) { + diff |= tsdp_header_M_diff_network_info; + } + else if (M_old->C) { + if (!tsk_strequals(M_new->C->addr, M_old->C->addr) || !tsk_strequals(M_new->C->nettype, M_old->C->nettype) || !tsk_strequals(M_new->C->addrtype, M_old->C->addrtype)) { + diff |= tsdp_header_M_diff_network_info; + } + } + } + } + + // media type + if (M_new) { + if (!tsk_striequals(M_new->media, M_old->media)) { + diff |= tsdp_header_M_diff_media_type; + } + else { + if (tsk_striequals(M_new->media, "audio") || tsk_striequals(M_new->media, "video")) { + const char *content0, *content1; + // check if it's BFCP audio/video session + // content attribute described in http://tools.ietf.org/html/rfc4796 + A0 = tsdp_header_M_findA(M_old, "content"); + A1 = tsdp_header_M_findA(M_new, "content"); + content0 = A0 ? A0->value : "main"; + content1 = A1 ? A1->value : "main"; + if (!tsk_striequals(content0, content1)) { + diff |= tsdp_header_M_diff_media_type; + } + } + } + } + + // ice + if (M_new) { + if (tsdp_header_M_is_ice_enabled(M_new)) { + diff |= tsdp_header_M_diff_ice_enabled; + } + if (tsdp_header_M_is_ice_restart(M_new)) { + diff |= tsdp_header_M_diff_ice_restart; + } + } + + *_diff = diff; + return ret; +} + +// +//int tsdp_header_M_set(tsdp_header_M_t* self, ...) +//{ +// int ret = -1; +// va_list params; +// int type; +// +// va_start(params, self); +// +// if(!m){ +// goto bail; +// } +// +// while((type=va_arg(params, int))){ +// switch(type){ +// case 0x01: /* FMT */ +// { +// tsk_string_t* fmt = tsk_string_create(va_arg(values, const char *)); +// if(fmt){ +// tsk_list_push_back_data(sefl->FMTs, (void**)&fmt); +// } +// break; +// } +// case 0x02: /* A */ +// { +// tsdp_header_A_t* A = tsdp_header_A_create(va_arg(values, const char *), va_arg(values, const char *)); +// if(A){ +// if(!M->Attributes){ +// M->Attributes = tsk_list_create(); +// } +// tsk_list_push_back_data(M->Attributes, (void**)&A); +// } +// break; +// } +// } +// } +// +//bail: +// va_end(params); +// return ret; +//} + + + +//======================================================== +// M header object definition +// + +static tsk_object_t* tsdp_header_M_ctor(tsk_object_t *self, va_list * app) +{ + tsdp_header_M_t *M = self; + if(M){ + TSDP_HEADER(M)->type = tsdp_htype_M; + TSDP_HEADER(M)->tostring = tsdp_header_M_tostring; + TSDP_HEADER(M)->clone = tsdp_header_M_clone; + TSDP_HEADER(M)->rank = TSDP_HTYPE_M_RANK; + + M->FMTs = tsk_list_create(); // Because there is at least one fmt. + + M->media = tsk_strdup(va_arg(*app, const char*)); + M->port = va_arg(*app, uint32_t); + M->proto = tsk_strdup(va_arg(*app, const char*)); + } + else{ + TSK_DEBUG_ERROR("Failed to create new M header."); + } + return self; +} + +static tsk_object_t* tsdp_header_M_dtor(tsk_object_t *self) +{ + tsdp_header_M_t *M = self; + if(M){ + TSK_FREE(M->media); + TSK_FREE(M->proto); + TSK_OBJECT_SAFE_FREE(M->FMTs); + + TSK_OBJECT_SAFE_FREE(M->I); + TSK_OBJECT_SAFE_FREE(M->C); + TSK_OBJECT_SAFE_FREE(M->Bandwidths); + TSK_OBJECT_SAFE_FREE(M->K); + TSK_OBJECT_SAFE_FREE(M->Attributes); + } + else{ + TSK_DEBUG_ERROR("Null M header."); + } + + return self; +} +static int tsdp_header_M_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) +{ + if(obj1 && obj2){ + return tsdp_header_rank_cmp(obj1, obj2); + } + else{ + return -1; + } +} + +static const tsk_object_def_t tsdp_header_M_def_s = +{ + sizeof(tsdp_header_M_t), + tsdp_header_M_ctor, + tsdp_header_M_dtor, + tsdp_header_M_cmp +}; + +const tsk_object_def_t *tsdp_header_M_def_t = &tsdp_header_M_def_s; diff --git a/tinySDP/src/headers/tsdp_header_O.c b/tinySDP/src/headers/tsdp_header_O.c new file mode 100644 index 0000000..b9c4fcc --- /dev/null +++ b/tinySDP/src/headers/tsdp_header_O.c @@ -0,0 +1,412 @@ + +/* #line 1 "./ragel/tsdp_parser_header_O.rl" */ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_header_O.c + * @brief SDP "o=" header (Origin). + */ +#include "tinysdp/headers/tsdp_header_O.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_string.h" + +#include <string.h> + +/*********************************** +* Ragel state machine. +*/ + +/* #line 80 "./ragel/tsdp_parser_header_O.rl" */ + + + + + +tsdp_header_O_t* tsdp_header_O_create(const char* username, uint32_t sess_id, uint32_t sess_version, const char* nettype, const char* addrtype, const char* addr) +{ + return tsk_object_new(TSDP_HEADER_O_VA_ARGS(username, sess_id, sess_version, nettype, addrtype, addr)); +} + +tsdp_header_O_t* tsdp_header_O_create_null() +{ + return tsdp_header_O_create(tsk_null, 0, 0, tsk_null, tsk_null, tsk_null); +} + +tsdp_header_O_t* tsdp_header_O_create_default(const char* username, const char* nettype, const char* addrtype, const char* addr) +{ + return tsdp_header_O_create(username, TSDP_HEADER_O_SESS_ID_DEFAULT, TSDP_HEADER_O_SESS_VERSION_DEFAULT, nettype, addrtype, addr); +} + + +int tsdp_header_O_tostring(const tsdp_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsdp_header_O_t *O = (const tsdp_header_O_t *)header; + + // o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com + return tsk_buffer_append_2(output, "%s %u %u %s %s %s", + O->username, + O->sess_id, + O->sess_version, + O->nettype, + O->addrtype, + O->addr + ); + + return 0; + } + + return -1; +} + +tsdp_header_t* tsdp_header_O_clone(const tsdp_header_t* header) +{ + if(header){ + const tsdp_header_O_t *O = (const tsdp_header_O_t *)header; + return (tsdp_header_t*)tsdp_header_O_create(O->username, O->sess_id, O->sess_version, O->nettype, O->addrtype, O->addr); + } + return tsk_null; +} + +tsdp_header_O_t *tsdp_header_O_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsdp_header_O_t *hdr_O = tsdp_header_O_create_null(); + + const char *tag_start = tsk_null; + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + +/* #line 103 "./src/headers/tsdp_header_O.c" */ +static const char _tsdp_machine_parser_header_O_actions[] = { + 0, 1, 0, 1, 1, 1, 2, 1, + 3, 1, 4, 1, 5, 1, 6, 2, + 0, 4, 2, 0, 5, 2, 0, 6 + +}; + +static const char _tsdp_machine_parser_header_O_key_offsets[] = { + 0, 0, 1, 3, 4, 5, 7, 10, + 12, 15, 16, 17, 18, 19, 20, 21, + 22 +}; + +static const char _tsdp_machine_parser_header_O_trans_keys[] = { + 111, 32, 61, 32, 32, 48, 57, 32, + 48, 57, 48, 57, 32, 48, 57, 32, + 32, 32, 32, 10, 13, 13, 0 +}; + +static const char _tsdp_machine_parser_header_O_single_lengths[] = { + 0, 1, 2, 1, 1, 0, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 0 +}; + +static const char _tsdp_machine_parser_header_O_range_lengths[] = { + 0, 0, 0, 0, 0, 1, 1, 1, + 1, 0, 0, 0, 0, 0, 0, 0, + 0 +}; + +static const char _tsdp_machine_parser_header_O_index_offsets[] = { + 0, 0, 2, 5, 7, 9, 11, 14, + 16, 19, 21, 23, 25, 27, 29, 31, + 33 +}; + +static const char _tsdp_machine_parser_header_O_trans_targs[] = { + 2, 0, 2, 3, 0, 3, 4, 5, + 4, 6, 0, 7, 6, 0, 8, 0, + 9, 8, 0, 11, 10, 11, 10, 14, + 12, 14, 12, 16, 0, 13, 15, 13, + 15, 0, 0 +}; + +static const char _tsdp_machine_parser_header_O_trans_actions[] = { + 0, 0, 0, 0, 0, 0, 1, 3, + 0, 1, 0, 5, 0, 0, 1, 0, + 7, 0, 0, 15, 1, 9, 0, 18, + 1, 11, 0, 0, 0, 21, 1, 13, + 0, 0, 0 +}; + +static const char _tsdp_machine_parser_header_O_eof_actions[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 21, 13, + 0 +}; + +static const int tsdp_machine_parser_header_O_start = 1; +static const int tsdp_machine_parser_header_O_first_final = 14; +static const int tsdp_machine_parser_header_O_error = 0; + +static const int tsdp_machine_parser_header_O_en_main = 1; + + +/* #line 143 "./ragel/tsdp_parser_header_O.rl" */ + (void)(tsdp_machine_parser_header_O_first_final); + (void)(tsdp_machine_parser_header_O_error); + (void)(tsdp_machine_parser_header_O_en_main); + +/* #line 175 "./src/headers/tsdp_header_O.c" */ + { + cs = tsdp_machine_parser_header_O_start; + } + +/* #line 147 "./ragel/tsdp_parser_header_O.rl" */ + +/* #line 182 "./src/headers/tsdp_header_O.c" */ + { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + + if ( p == pe ) + goto _test_eof; + if ( cs == 0 ) + goto _out; +_resume: + _keys = _tsdp_machine_parser_header_O_trans_keys + _tsdp_machine_parser_header_O_key_offsets[cs]; + _trans = _tsdp_machine_parser_header_O_index_offsets[cs]; + + _klen = _tsdp_machine_parser_header_O_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _tsdp_machine_parser_header_O_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += ((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + cs = _tsdp_machine_parser_header_O_trans_targs[_trans]; + + if ( _tsdp_machine_parser_header_O_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _tsdp_machine_parser_header_O_actions + _tsdp_machine_parser_header_O_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) + { + switch ( *_acts++ ) + { + case 0: +/* #line 41 "./ragel/tsdp_parser_header_O.rl" */ + { + tag_start = p; + } + break; + case 1: +/* #line 45 "./ragel/tsdp_parser_header_O.rl" */ + { + TSK_PARSER_SET_STRING(hdr_O->username); + } + break; + case 2: +/* #line 49 "./ragel/tsdp_parser_header_O.rl" */ + { + TSK_PARSER_SET_UINT(hdr_O->sess_id); + } + break; + case 3: +/* #line 53 "./ragel/tsdp_parser_header_O.rl" */ + { + TSK_PARSER_SET_UINT(hdr_O->sess_version); + } + break; + case 4: +/* #line 57 "./ragel/tsdp_parser_header_O.rl" */ + { + TSK_PARSER_SET_STRING(hdr_O->nettype); + } + break; + case 5: +/* #line 61 "./ragel/tsdp_parser_header_O.rl" */ + { + TSK_PARSER_SET_STRING(hdr_O->addrtype); + } + break; + case 6: +/* #line 65 "./ragel/tsdp_parser_header_O.rl" */ + { + TSK_PARSER_SET_STRING(hdr_O->addr); + } + break; +/* #line 297 "./src/headers/tsdp_header_O.c" */ + } + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; + _test_eof: {} + if ( p == eof ) + { + const char *__acts = _tsdp_machine_parser_header_O_actions + _tsdp_machine_parser_header_O_eof_actions[cs]; + unsigned int __nacts = (unsigned int) *__acts++; + while ( __nacts-- > 0 ) { + switch ( *__acts++ ) { + case 0: +/* #line 41 "./ragel/tsdp_parser_header_O.rl" */ + { + tag_start = p; + } + break; + case 6: +/* #line 65 "./ragel/tsdp_parser_header_O.rl" */ + { + TSK_PARSER_SET_STRING(hdr_O->addr); + } + break; +/* #line 325 "./src/headers/tsdp_header_O.c" */ + } + } + } + + _out: {} + } + +/* #line 148 "./ragel/tsdp_parser_header_O.rl" */ + TSK_RAGEL_DISABLE_WARNINGS_END() + + if( cs < +/* #line 337 "./src/headers/tsdp_header_O.c" */ +14 +/* #line 150 "./ragel/tsdp_parser_header_O.rl" */ + ){ + TSK_DEBUG_ERROR("Failed to parse \"o=\" header."); + TSK_OBJECT_SAFE_FREE(hdr_O); + } + + return hdr_O; +} + + + + + + + +//======================================================== +// O header object definition +// + +static tsk_object_t* tsdp_header_O_ctor(tsk_object_t *self, va_list * app) +{ + tsdp_header_O_t *O = self; + if(O){ + TSDP_HEADER(O)->type = tsdp_htype_O; + TSDP_HEADER(O)->tostring = tsdp_header_O_tostring; + TSDP_HEADER(O)->clone = tsdp_header_O_clone; + TSDP_HEADER(O)->rank = TSDP_HTYPE_O_RANK; + + O->username = tsk_strdup(va_arg(*app, const char*)); + O->sess_id = va_arg(*app, uint32_t); + O->sess_version = va_arg(*app, uint32_t); + O->nettype = tsk_strdup(va_arg(*app, const char*)); + O->addrtype = tsk_strdup(va_arg(*app, const char*)); + O->addr = tsk_strdup(va_arg(*app, const char*)); + } + else{ + TSK_DEBUG_ERROR("Failed to create new O header."); + } + return self; +} + +static tsk_object_t* tsdp_header_O_dtor(tsk_object_t *self) +{ + tsdp_header_O_t *O = self; + if(O){ + TSK_FREE(O->username); + TSK_FREE(O->nettype); + TSK_FREE(O->addrtype); + TSK_FREE(O->addr); + } + else{ + TSK_DEBUG_ERROR("Null O header."); + } + + return self; +} +static int tsdp_header_O_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) +{ + if(obj1 && obj2){ + return tsdp_header_rank_cmp(obj1, obj2); + } + else{ + return -1; + } +} + +static const tsk_object_def_t tsdp_header_O_def_s = +{ + sizeof(tsdp_header_O_t), + tsdp_header_O_ctor, + tsdp_header_O_dtor, + tsdp_header_O_cmp +}; + +const tsk_object_def_t *tsdp_header_O_def_t = &tsdp_header_O_def_s; diff --git a/tinySDP/src/headers/tsdp_header_P.c b/tinySDP/src/headers/tsdp_header_P.c new file mode 100644 index 0000000..aa3f6ba --- /dev/null +++ b/tinySDP/src/headers/tsdp_header_P.c @@ -0,0 +1,339 @@ + +/* #line 1 "./ragel/tsdp_parser_header_P.rl" */ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + + +/**@file tsdp_header_P.c + * @brief SDP "p=" header (Phone Number). + */ +#include "tinysdp/headers/tsdp_header_P.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_string.h" + +#include <string.h> + +/*********************************** +* Ragel state machine. +*/ + +/* #line 55 "./ragel/tsdp_parser_header_P.rl" */ + + + +tsdp_header_P_t* tsdp_header_P_create(const char* value) +{ + return tsk_object_new(TSDP_HEADER_P_VA_ARGS(value)); +} + +tsdp_header_P_t* tsdp_header_P_create_null() +{ + return tsdp_header_P_create(tsk_null); +} + +int tsdp_header_P_tostring(const tsdp_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsdp_header_P_t *P = (const tsdp_header_P_t *)header; + if(P->value){ + tsk_buffer_append(output, P->value, tsk_strlen(P->value)); + } + return 0; + } + + return -1; +} + +tsdp_header_t* tsdp_header_P_clone(const tsdp_header_t* header) +{ + if(header){ + const tsdp_header_P_t *P = (const tsdp_header_P_t *)header; + return (tsdp_header_t*)tsdp_header_P_create(P->value); + } + return tsk_null; +} + +tsdp_header_P_t *tsdp_header_P_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsdp_header_P_t *hdr_P = tsdp_header_P_create_null(); + + const char *tag_start = tsk_null; + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + +/* #line 88 "./src/headers/tsdp_header_P.c" */ +static const char _tsdp_machine_parser_header_P_actions[] = { + 0, 1, 0, 1, 1, 2, 0, 1 + +}; + +static const char _tsdp_machine_parser_header_P_key_offsets[] = { + 0, 0, 1, 3, 4, 6, 7 +}; + +static const char _tsdp_machine_parser_header_P_trans_keys[] = { + 112, 32, 61, 10, 13, 32, 13, 0 +}; + +static const char _tsdp_machine_parser_header_P_single_lengths[] = { + 0, 1, 2, 1, 2, 1, 0 +}; + +static const char _tsdp_machine_parser_header_P_range_lengths[] = { + 0, 0, 0, 0, 0, 0, 0 +}; + +static const char _tsdp_machine_parser_header_P_index_offsets[] = { + 0, 0, 2, 5, 7, 10, 12 +}; + +static const char _tsdp_machine_parser_header_P_trans_targs[] = { + 2, 0, 2, 4, 0, 6, 0, 3, + 4, 5, 3, 5, 0, 0 +}; + +static const char _tsdp_machine_parser_header_P_trans_actions[] = { + 0, 0, 0, 0, 0, 0, 0, 5, + 0, 1, 3, 0, 0, 0 +}; + +static const char _tsdp_machine_parser_header_P_eof_actions[] = { + 0, 0, 0, 0, 5, 3, 0 +}; + +static const int tsdp_machine_parser_header_P_start = 1; +static const int tsdp_machine_parser_header_P_first_final = 4; +static const int tsdp_machine_parser_header_P_error = 0; + +static const int tsdp_machine_parser_header_P_en_main = 1; + + +/* #line 102 "./ragel/tsdp_parser_header_P.rl" */ + (void)(tsdp_machine_parser_header_P_first_final); + (void)(tsdp_machine_parser_header_P_error); + (void)(tsdp_machine_parser_header_P_en_main); + +/* #line 140 "./src/headers/tsdp_header_P.c" */ + { + cs = tsdp_machine_parser_header_P_start; + } + +/* #line 106 "./ragel/tsdp_parser_header_P.rl" */ + +/* #line 147 "./src/headers/tsdp_header_P.c" */ + { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + + if ( p == pe ) + goto _test_eof; + if ( cs == 0 ) + goto _out; +_resume: + _keys = _tsdp_machine_parser_header_P_trans_keys + _tsdp_machine_parser_header_P_key_offsets[cs]; + _trans = _tsdp_machine_parser_header_P_index_offsets[cs]; + + _klen = _tsdp_machine_parser_header_P_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _tsdp_machine_parser_header_P_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += ((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + cs = _tsdp_machine_parser_header_P_trans_targs[_trans]; + + if ( _tsdp_machine_parser_header_P_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _tsdp_machine_parser_header_P_actions + _tsdp_machine_parser_header_P_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) + { + switch ( *_acts++ ) + { + case 0: +/* #line 42 "./ragel/tsdp_parser_header_P.rl" */ + { + tag_start = p; + } + break; + case 1: +/* #line 46 "./ragel/tsdp_parser_header_P.rl" */ + { + TSK_PARSER_SET_STRING(hdr_P->value); + } + break; +/* #line 232 "./src/headers/tsdp_header_P.c" */ + } + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; + _test_eof: {} + if ( p == eof ) + { + const char *__acts = _tsdp_machine_parser_header_P_actions + _tsdp_machine_parser_header_P_eof_actions[cs]; + unsigned int __nacts = (unsigned int) *__acts++; + while ( __nacts-- > 0 ) { + switch ( *__acts++ ) { + case 0: +/* #line 42 "./ragel/tsdp_parser_header_P.rl" */ + { + tag_start = p; + } + break; + case 1: +/* #line 46 "./ragel/tsdp_parser_header_P.rl" */ + { + TSK_PARSER_SET_STRING(hdr_P->value); + } + break; +/* #line 260 "./src/headers/tsdp_header_P.c" */ + } + } + } + + _out: {} + } + +/* #line 107 "./ragel/tsdp_parser_header_P.rl" */ + TSK_RAGEL_DISABLE_WARNINGS_END() + + if( cs < +/* #line 272 "./src/headers/tsdp_header_P.c" */ +4 +/* #line 109 "./ragel/tsdp_parser_header_P.rl" */ + ){ + TSK_DEBUG_ERROR("Failed to parse \"p=\" header."); + TSK_OBJECT_SAFE_FREE(hdr_P); + } + + return hdr_P; +} + + + + + + + +//======================================================== +// P header object definition +// + +static tsk_object_t* tsdp_header_P_ctor(tsk_object_t *self, va_list * app) +{ + tsdp_header_P_t *P = self; + if(P){ + TSDP_HEADER(P)->type = tsdp_htype_P; + TSDP_HEADER(P)->tostring = tsdp_header_P_tostring; + TSDP_HEADER(P)->clone = tsdp_header_P_clone; + TSDP_HEADER(P)->rank = TSDP_HTYPE_P_RANK; + + P->value = tsk_strdup(va_arg(*app, const char*)); + } + else{ + TSK_DEBUG_ERROR("Failed to create new P header."); + } + return self; +} + +static tsk_object_t* tsdp_header_P_dtor(tsk_object_t *self) +{ + tsdp_header_P_t *P = self; + if(P){ + TSK_FREE(P->value); + } + else{ + TSK_DEBUG_ERROR("Null P header."); + } + + return self; +} +static int tsdp_header_P_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) +{ + if(obj1 && obj2){ + return tsdp_header_rank_cmp(obj1, obj2); + } + else{ + return -1; + } +} + +static const tsk_object_def_t tsdp_header_P_def_s = +{ + sizeof(tsdp_header_P_t), + tsdp_header_P_ctor, + tsdp_header_P_dtor, + tsdp_header_P_cmp +}; + +const tsk_object_def_t *tsdp_header_P_def_t = &tsdp_header_P_def_s; diff --git a/tinySDP/src/headers/tsdp_header_R.c b/tinySDP/src/headers/tsdp_header_R.c new file mode 100644 index 0000000..848a35a --- /dev/null +++ b/tinySDP/src/headers/tsdp_header_R.c @@ -0,0 +1,394 @@ + +/* #line 1 "./ragel/tsdp_parser_header_R.rl" */ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + + +/**@file tsdp_header_R.c + * @brief SDP "r=" header (Repeat Times). + * + */ +#include "tinysdp/headers/tsdp_header_R.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_string.h" + +#include <string.h> + +/*********************************** +* Ragel state machine. +*/ + +/* #line 70 "./ragel/tsdp_parser_header_R.rl" */ + + + + +tsdp_header_R_t* tsdp_header_R_create() +{ + return tsk_object_new(TSDP_HEADER_R_VA_ARGS()); +} + +tsdp_header_R_t* tsdp_header_R_create_null() +{ + return tsdp_header_R_create(); +} + +int tsdp_header_R_tostring(const tsdp_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsdp_header_R_t *R = (const tsdp_header_R_t *)header; + const tsk_list_item_t* item; + + // r=7d 1h 0 25h + tsk_buffer_append_2(output, "%s %s", + R->repeat_interval, + R->typed_time + ); + tsk_list_foreach(item, R->typed_times){ + tsk_string_t* string = item->data; + tsk_buffer_append_2(output, " %s", TSK_STRING_STR(string)); + } + + return 0; + } + + return -1; +} + +tsdp_header_t* tsdp_header_R_clone(const tsdp_header_t* header) +{ + if(header){ + const tsdp_header_R_t *R = (const tsdp_header_R_t *)header; + tsdp_header_R_t* clone; + const tsk_list_item_t* item; + + if((clone = tsdp_header_R_create_null())){ + clone->repeat_interval = tsk_strdup(R->repeat_interval); + clone->typed_time = tsk_strdup(R->typed_time); + + if(R->typed_times){ + clone->typed_times = tsk_list_create(); + } + + tsk_list_foreach(item, R->typed_times){ + tsk_string_t* string = tsk_string_create(TSK_STRING_STR(item->data)); + tsk_list_push_back_data(clone->typed_times, (void**)&string); + } + } + return TSDP_HEADER(clone); + } + return tsk_null; +} + +tsdp_header_R_t *tsdp_header_R_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsdp_header_R_t *hdr_R = tsdp_header_R_create_null(); + + const char *tag_start = tsk_null; + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + +/* #line 115 "./src/headers/tsdp_header_R.c" */ +static const char _tsdp_machine_parser_header_R_actions[] = { + 0, 1, 0, 1, 1, 1, 2 +}; + +static const char _tsdp_machine_parser_header_R_key_offsets[] = { + 0, 0, 1, 3, 6, 13, 15, 22, + 24, 25, 26, 27, 35, 35 +}; + +static const char _tsdp_machine_parser_header_R_trans_keys[] = { + 114, 32, 61, 32, 48, 57, 32, 100, + 104, 109, 115, 48, 57, 48, 57, 32, + 100, 104, 109, 115, 48, 57, 48, 57, + 10, 32, 32, 13, 32, 100, 104, 109, + 115, 48, 57, 13, 32, 0 +}; + +static const char _tsdp_machine_parser_header_R_single_lengths[] = { + 0, 1, 2, 1, 5, 0, 5, 0, + 1, 1, 1, 6, 0, 2 +}; + +static const char _tsdp_machine_parser_header_R_range_lengths[] = { + 0, 0, 0, 1, 1, 1, 1, 1, + 0, 0, 0, 1, 0, 0 +}; + +static const char _tsdp_machine_parser_header_R_index_offsets[] = { + 0, 0, 2, 5, 8, 15, 17, 24, + 26, 28, 30, 32, 40, 41 +}; + +static const char _tsdp_machine_parser_header_R_indicies[] = { + 0, 1, 0, 2, 1, 2, 3, 1, + 4, 6, 6, 6, 6, 5, 1, 7, + 1, 8, 10, 10, 10, 10, 9, 1, + 11, 1, 12, 1, 8, 1, 4, 1, + 13, 8, 15, 15, 15, 15, 14, 1, + 1, 13, 8, 1, 0 +}; + +static const char _tsdp_machine_parser_header_R_trans_targs[] = { + 2, 0, 3, 4, 5, 4, 10, 6, + 7, 6, 9, 11, 12, 8, 11, 13 +}; + +static const char _tsdp_machine_parser_header_R_trans_actions[] = { + 0, 0, 0, 1, 3, 0, 0, 1, + 5, 0, 0, 1, 0, 5, 0, 0 +}; + +static const char _tsdp_machine_parser_header_R_eof_actions[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 5, 0, 5 +}; + +static const int tsdp_machine_parser_header_R_start = 1; +static const int tsdp_machine_parser_header_R_first_final = 11; +static const int tsdp_machine_parser_header_R_error = 0; + +static const int tsdp_machine_parser_header_R_en_main = 1; + + +/* #line 143 "./ragel/tsdp_parser_header_R.rl" */ + (void)(tsdp_machine_parser_header_R_first_final); + (void)(tsdp_machine_parser_header_R_error); + (void)(tsdp_machine_parser_header_R_en_main); + +/* #line 184 "./src/headers/tsdp_header_R.c" */ + { + cs = tsdp_machine_parser_header_R_start; + } + +/* #line 147 "./ragel/tsdp_parser_header_R.rl" */ + +/* #line 191 "./src/headers/tsdp_header_R.c" */ + { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + + if ( p == pe ) + goto _test_eof; + if ( cs == 0 ) + goto _out; +_resume: + _keys = _tsdp_machine_parser_header_R_trans_keys + _tsdp_machine_parser_header_R_key_offsets[cs]; + _trans = _tsdp_machine_parser_header_R_index_offsets[cs]; + + _klen = _tsdp_machine_parser_header_R_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _tsdp_machine_parser_header_R_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += ((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + _trans = _tsdp_machine_parser_header_R_indicies[_trans]; + cs = _tsdp_machine_parser_header_R_trans_targs[_trans]; + + if ( _tsdp_machine_parser_header_R_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _tsdp_machine_parser_header_R_actions + _tsdp_machine_parser_header_R_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) + { + switch ( *_acts++ ) + { + case 0: +/* #line 43 "./ragel/tsdp_parser_header_R.rl" */ + { + tag_start = p; + } + break; + case 1: +/* #line 47 "./ragel/tsdp_parser_header_R.rl" */ + { + TSK_PARSER_SET_STRING(hdr_R->repeat_interval); + } + break; + case 2: +/* #line 51 "./ragel/tsdp_parser_header_R.rl" */ + { + if(!hdr_R->typed_time){ + TSK_PARSER_SET_STRING(hdr_R->typed_time); + } + else{ + TSK_PARSER_ADD_STRING(hdr_R->typed_times); + } + } + break; +/* #line 288 "./src/headers/tsdp_header_R.c" */ + } + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; + _test_eof: {} + if ( p == eof ) + { + const char *__acts = _tsdp_machine_parser_header_R_actions + _tsdp_machine_parser_header_R_eof_actions[cs]; + unsigned int __nacts = (unsigned int) *__acts++; + while ( __nacts-- > 0 ) { + switch ( *__acts++ ) { + case 2: +/* #line 51 "./ragel/tsdp_parser_header_R.rl" */ + { + if(!hdr_R->typed_time){ + TSK_PARSER_SET_STRING(hdr_R->typed_time); + } + else{ + TSK_PARSER_ADD_STRING(hdr_R->typed_times); + } + } + break; +/* #line 315 "./src/headers/tsdp_header_R.c" */ + } + } + } + + _out: {} + } + +/* #line 148 "./ragel/tsdp_parser_header_R.rl" */ + TSK_RAGEL_DISABLE_WARNINGS_END() + + if( cs < +/* #line 327 "./src/headers/tsdp_header_R.c" */ +11 +/* #line 150 "./ragel/tsdp_parser_header_R.rl" */ + ){ + TSK_DEBUG_ERROR("Failed to parse \"r=\" header."); + TSK_OBJECT_SAFE_FREE(hdr_R); + } + + return hdr_R; +} + + + + + + + +//======================================================== +// E header object definition +// + +static tsk_object_t* tsdp_header_R_ctor(tsk_object_t *self, va_list * app) +{ + tsdp_header_R_t *R = self; + if(R){ + TSDP_HEADER(R)->type = tsdp_htype_R; + TSDP_HEADER(R)->tostring = tsdp_header_R_tostring; + TSDP_HEADER(R)->clone = tsdp_header_R_clone; + TSDP_HEADER(R)->rank = TSDP_HTYPE_R_RANK; + } + else{ + TSK_DEBUG_ERROR("Failed to create new E header."); + } + return self; +} + +static tsk_object_t* tsdp_header_R_dtor(tsk_object_t *self) +{ + tsdp_header_R_t *R = self; + if(R){ + TSK_FREE(R->repeat_interval); + TSK_FREE(R->typed_time); + TSK_OBJECT_SAFE_FREE(R->typed_times); + } + else{ + TSK_DEBUG_ERROR("Null R header."); + } + + return self; +} +static int tsdp_header_R_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) +{ + if(obj1 && obj2){ + return tsdp_header_rank_cmp(obj1, obj2); + } + else{ + return -1; + } +} + +static const tsk_object_def_t tsdp_header_R_def_s = +{ + sizeof(tsdp_header_R_t), + tsdp_header_R_ctor, + tsdp_header_R_dtor, + tsdp_header_R_cmp +}; + +const tsk_object_def_t *tsdp_header_R_def_t = &tsdp_header_R_def_s; diff --git a/tinySDP/src/headers/tsdp_header_S.c b/tinySDP/src/headers/tsdp_header_S.c new file mode 100644 index 0000000..a9e28eb --- /dev/null +++ b/tinySDP/src/headers/tsdp_header_S.c @@ -0,0 +1,337 @@ + +/* #line 1 "./ragel/tsdp_parser_header_S.rl" */ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_header_S.c + * @brief SDP "s=" header (Session Name). + */ +#include "tinysdp/headers/tsdp_header_S.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_string.h" + +#include <string.h> + +/*********************************** +* Ragel state machine. +*/ + +/* #line 54 "./ragel/tsdp_parser_header_S.rl" */ + + + +tsdp_header_S_t* tsdp_header_S_create(const char* value) +{ + return tsk_object_new(TSDP_HEADER_S_VA_ARGS(value)); +} +tsdp_header_S_t* tsdp_header_S_create_null() +{ + return tsdp_header_S_create(tsk_null); +} + +int tsdp_header_S_tostring(const tsdp_header_t* header, tsk_buffer_t* output) +{ + if(header) + { + const tsdp_header_S_t *S = (const tsdp_header_S_t *)header; + if(S->value){ + tsk_buffer_append(output, S->value, tsk_strlen(S->value)); + } + return 0; + } + + return -1; +} + +tsdp_header_t* tsdp_header_S_clone(const tsdp_header_t* header) +{ + if(header){ + const tsdp_header_S_t *S = (const tsdp_header_S_t *)header; + return (tsdp_header_t*)tsdp_header_S_create(S->value); + } + return tsk_null; +} + +tsdp_header_S_t *tsdp_header_S_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsdp_header_S_t *hdr_S = tsdp_header_S_create_null(); + + const char *tag_start = tsk_null; + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + +/* #line 87 "./src/headers/tsdp_header_S.c" */ +static const char _tsdp_machine_parser_header_S_actions[] = { + 0, 1, 0, 1, 1, 2, 0, 1 + +}; + +static const char _tsdp_machine_parser_header_S_key_offsets[] = { + 0, 0, 1, 3, 4, 6, 7 +}; + +static const char _tsdp_machine_parser_header_S_trans_keys[] = { + 115, 32, 61, 10, 13, 32, 13, 0 +}; + +static const char _tsdp_machine_parser_header_S_single_lengths[] = { + 0, 1, 2, 1, 2, 1, 0 +}; + +static const char _tsdp_machine_parser_header_S_range_lengths[] = { + 0, 0, 0, 0, 0, 0, 0 +}; + +static const char _tsdp_machine_parser_header_S_index_offsets[] = { + 0, 0, 2, 5, 7, 10, 12 +}; + +static const char _tsdp_machine_parser_header_S_trans_targs[] = { + 2, 0, 2, 4, 0, 6, 0, 3, + 4, 5, 3, 5, 0, 0 +}; + +static const char _tsdp_machine_parser_header_S_trans_actions[] = { + 0, 0, 0, 0, 0, 0, 0, 5, + 0, 1, 3, 0, 0, 0 +}; + +static const char _tsdp_machine_parser_header_S_eof_actions[] = { + 0, 0, 0, 0, 5, 3, 0 +}; + +static const int tsdp_machine_parser_header_S_start = 1; +static const int tsdp_machine_parser_header_S_first_final = 4; +static const int tsdp_machine_parser_header_S_error = 0; + +static const int tsdp_machine_parser_header_S_en_main = 1; + + +/* #line 101 "./ragel/tsdp_parser_header_S.rl" */ + (void)(tsdp_machine_parser_header_S_first_final); + (void)(tsdp_machine_parser_header_S_error); + (void)(tsdp_machine_parser_header_S_en_main); + +/* #line 139 "./src/headers/tsdp_header_S.c" */ + { + cs = tsdp_machine_parser_header_S_start; + } + +/* #line 105 "./ragel/tsdp_parser_header_S.rl" */ + +/* #line 146 "./src/headers/tsdp_header_S.c" */ + { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + + if ( p == pe ) + goto _test_eof; + if ( cs == 0 ) + goto _out; +_resume: + _keys = _tsdp_machine_parser_header_S_trans_keys + _tsdp_machine_parser_header_S_key_offsets[cs]; + _trans = _tsdp_machine_parser_header_S_index_offsets[cs]; + + _klen = _tsdp_machine_parser_header_S_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _tsdp_machine_parser_header_S_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += ((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + cs = _tsdp_machine_parser_header_S_trans_targs[_trans]; + + if ( _tsdp_machine_parser_header_S_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _tsdp_machine_parser_header_S_actions + _tsdp_machine_parser_header_S_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) + { + switch ( *_acts++ ) + { + case 0: +/* #line 41 "./ragel/tsdp_parser_header_S.rl" */ + { + tag_start = p; + } + break; + case 1: +/* #line 45 "./ragel/tsdp_parser_header_S.rl" */ + { + TSK_PARSER_SET_STRING(hdr_S->value); + } + break; +/* #line 231 "./src/headers/tsdp_header_S.c" */ + } + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; + _test_eof: {} + if ( p == eof ) + { + const char *__acts = _tsdp_machine_parser_header_S_actions + _tsdp_machine_parser_header_S_eof_actions[cs]; + unsigned int __nacts = (unsigned int) *__acts++; + while ( __nacts-- > 0 ) { + switch ( *__acts++ ) { + case 0: +/* #line 41 "./ragel/tsdp_parser_header_S.rl" */ + { + tag_start = p; + } + break; + case 1: +/* #line 45 "./ragel/tsdp_parser_header_S.rl" */ + { + TSK_PARSER_SET_STRING(hdr_S->value); + } + break; +/* #line 259 "./src/headers/tsdp_header_S.c" */ + } + } + } + + _out: {} + } + +/* #line 106 "./ragel/tsdp_parser_header_S.rl" */ + TSK_RAGEL_DISABLE_WARNINGS_END() + + if( cs < +/* #line 271 "./src/headers/tsdp_header_S.c" */ +4 +/* #line 108 "./ragel/tsdp_parser_header_S.rl" */ + ){ + TSK_OBJECT_SAFE_FREE(hdr_S); + } + + return hdr_S; +} + + + + + + + +//======================================================== +// S header object definition +// + +static tsk_object_t* tsdp_header_S_ctor(tsk_object_t *self, va_list * app) +{ + tsdp_header_S_t *S = self; + if(S){ + TSDP_HEADER(S)->type = tsdp_htype_S; + TSDP_HEADER(S)->tostring = tsdp_header_S_tostring; + TSDP_HEADER(S)->clone = tsdp_header_S_clone; + TSDP_HEADER(S)->rank = TSDP_HTYPE_S_RANK; + + S->value = tsk_strdup(va_arg(*app, const char*)); + } + else{ + TSK_DEBUG_ERROR("Failed to create new S header."); + } + return self; +} + +static tsk_object_t* tsdp_header_S_dtor(tsk_object_t *self) +{ + tsdp_header_S_t *S = self; + if(S){ + TSK_FREE(S->value); + } + else{ + TSK_DEBUG_ERROR("Null S header."); + } + + return self; +} +static int tsdp_header_S_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) +{ + if(obj1 && obj2){ + return tsdp_header_rank_cmp(obj1, obj2); + } + else{ + return -1; + } +} + +static const tsk_object_def_t tsdp_header_S_def_s = +{ + sizeof(tsdp_header_S_t), + tsdp_header_S_ctor, + tsdp_header_S_dtor, + tsdp_header_S_cmp +}; + +const tsk_object_def_t *tsdp_header_S_def_t = &tsdp_header_S_def_s; diff --git a/tinySDP/src/headers/tsdp_header_T.c b/tinySDP/src/headers/tsdp_header_T.c new file mode 100644 index 0000000..edcb909 --- /dev/null +++ b/tinySDP/src/headers/tsdp_header_T.c @@ -0,0 +1,380 @@ + +/* #line 1 "./ragel/tsdp_parser_header_T.rl" */ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_header_T.c + * @brief SDP "t=" header (Timing). + */ +#include "tinysdp/headers/tsdp_header_T.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_string.h" + +#include <string.h> + +/*********************************** +* Ragel state machine. +*/ + +/* #line 72 "./ragel/tsdp_parser_header_T.rl" */ + + + +tsdp_header_T_t* tsdp_header_T_create(uint64_t start, uint64_t stop) +{ + return tsk_object_new(TSDP_HEADER_T_VA_ARGS(start, stop)); +} + +tsdp_header_T_t* tsdp_header_T_create_null() +{ + return tsdp_header_T_create(0, 0); +} + +int tsdp_header_T_tostring(const tsdp_header_t* header, tsk_buffer_t* output) +{ + if(header) + { + const tsdp_header_T_t *T = (const tsdp_header_T_t *)header; + const tsk_list_item_t *item; + + //"t=3034423619 3042462419\r\n" + //"r=7d 1h 0 25h\r\n" + // IMPORTANT: Do not append the last CRLF (because we only print the header value). + tsk_buffer_append_2(output, "%llu %llu", + T->start, + T->stop + ); + + tsk_list_foreach(item, T->repeat_fields) + { + if(TSK_LIST_IS_FIRST(T->repeat_fields, item)){ + tsk_buffer_append(output, "\r\n", 2); + } + tsk_buffer_append_2(output, "%c=", tsdp_header_get_nameex(TSDP_HEADER(item->data))); + TSDP_HEADER(item->data)->tostring(TSDP_HEADER(item->data), output); + //tsdp_header_tostring(TSDP_HEADER(item->data), output); + + if(!TSK_LIST_IS_LAST(T->repeat_fields, item)){ + tsk_buffer_append(output, "\r\n", 2); + } + } + + return 0; + } + + return -1; +} + +tsdp_header_t* tsdp_header_T_clone(const tsdp_header_t* header) +{ + if(header){ + const tsdp_header_T_t *T = (const tsdp_header_T_t *)header; + tsdp_header_T_t* clone; + const tsk_list_item_t *item; + + if((clone = tsdp_header_T_create(T->start, T->stop))){ + + if(T->repeat_fields){ + clone->repeat_fields = tsk_list_create(); + } + + tsk_list_foreach(item, T->repeat_fields){ + const tsdp_header_t* curr = item->data; + tsdp_header_t* hdr_clone = curr->clone(curr); + tsk_list_push_back_data(clone->repeat_fields, (void**)&hdr_clone); + } + } + return TSDP_HEADER(clone); + } + return tsk_null; +} + +tsdp_header_T_t *tsdp_header_T_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsdp_header_T_t *hdr_T = tsdp_header_T_create_null(); + + const char *tag_start = tsk_null; + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + +/* #line 124 "./src/headers/tsdp_header_T.c" */ +static const char _tsdp_machine_parser_header_T_actions[] = { + 0, 1, 0, 1, 1, 1, 2 +}; + +static const char _tsdp_machine_parser_header_T_key_offsets[] = { + 0, 0, 1, 3, 6, 9, 11, 12, + 15 +}; + +static const char _tsdp_machine_parser_header_T_trans_keys[] = { + 116, 32, 61, 32, 48, 57, 32, 48, + 57, 48, 57, 10, 13, 48, 57, 0 +}; + +static const char _tsdp_machine_parser_header_T_single_lengths[] = { + 0, 1, 2, 1, 1, 0, 1, 1, + 0 +}; + +static const char _tsdp_machine_parser_header_T_range_lengths[] = { + 0, 0, 0, 1, 1, 1, 0, 1, + 0 +}; + +static const char _tsdp_machine_parser_header_T_index_offsets[] = { + 0, 0, 2, 5, 8, 11, 13, 15, + 18 +}; + +static const char _tsdp_machine_parser_header_T_trans_targs[] = { + 2, 0, 2, 3, 0, 3, 4, 0, + 5, 4, 0, 7, 0, 8, 0, 6, + 7, 0, 0, 0 +}; + +static const char _tsdp_machine_parser_header_T_trans_actions[] = { + 0, 0, 0, 0, 0, 0, 1, 0, + 3, 0, 0, 1, 0, 0, 0, 5, + 0, 0, 0, 0 +}; + +static const char _tsdp_machine_parser_header_T_eof_actions[] = { + 0, 0, 0, 0, 0, 0, 0, 5, + 0 +}; + +static const int tsdp_machine_parser_header_T_start = 1; +static const int tsdp_machine_parser_header_T_first_final = 7; +static const int tsdp_machine_parser_header_T_error = 0; + +static const int tsdp_machine_parser_header_T_en_main = 1; + + +/* #line 156 "./ragel/tsdp_parser_header_T.rl" */ + (void)(tsdp_machine_parser_header_T_first_final); + (void)(tsdp_machine_parser_header_T_error); + (void)(tsdp_machine_parser_header_T_en_main); + +/* #line 183 "./src/headers/tsdp_header_T.c" */ + { + cs = tsdp_machine_parser_header_T_start; + } + +/* #line 160 "./ragel/tsdp_parser_header_T.rl" */ + +/* #line 190 "./src/headers/tsdp_header_T.c" */ + { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + + if ( p == pe ) + goto _test_eof; + if ( cs == 0 ) + goto _out; +_resume: + _keys = _tsdp_machine_parser_header_T_trans_keys + _tsdp_machine_parser_header_T_key_offsets[cs]; + _trans = _tsdp_machine_parser_header_T_index_offsets[cs]; + + _klen = _tsdp_machine_parser_header_T_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _tsdp_machine_parser_header_T_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += ((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + cs = _tsdp_machine_parser_header_T_trans_targs[_trans]; + + if ( _tsdp_machine_parser_header_T_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _tsdp_machine_parser_header_T_actions + _tsdp_machine_parser_header_T_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) + { + switch ( *_acts++ ) + { + case 0: +/* #line 41 "./ragel/tsdp_parser_header_T.rl" */ + { + tag_start = p; + } + break; + case 1: +/* #line 45 "./ragel/tsdp_parser_header_T.rl" */ + { + TSK_PARSER_SET_INTEGER_EX(hdr_T->start, uint64_t, atoi64); + } + break; + case 2: +/* #line 49 "./ragel/tsdp_parser_header_T.rl" */ + { + TSK_PARSER_SET_INTEGER_EX(hdr_T->stop, uint64_t, atoi64); + } + break; +/* #line 281 "./src/headers/tsdp_header_T.c" */ + } + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; + _test_eof: {} + if ( p == eof ) + { + const char *__acts = _tsdp_machine_parser_header_T_actions + _tsdp_machine_parser_header_T_eof_actions[cs]; + unsigned int __nacts = (unsigned int) *__acts++; + while ( __nacts-- > 0 ) { + switch ( *__acts++ ) { + case 2: +/* #line 49 "./ragel/tsdp_parser_header_T.rl" */ + { + TSK_PARSER_SET_INTEGER_EX(hdr_T->stop, uint64_t, atoi64); + } + break; +/* #line 303 "./src/headers/tsdp_header_T.c" */ + } + } + } + + _out: {} + } + +/* #line 161 "./ragel/tsdp_parser_header_T.rl" */ + TSK_RAGEL_DISABLE_WARNINGS_END() + + if( cs < +/* #line 315 "./src/headers/tsdp_header_T.c" */ +7 +/* #line 163 "./ragel/tsdp_parser_header_T.rl" */ + ){ + TSK_DEBUG_ERROR("Failed to parse \"t=\" header."); + TSK_OBJECT_SAFE_FREE(hdr_T); + } + + return hdr_T; +} + + + + + + + +//======================================================== +// T header object definition +// + +static tsk_object_t* tsdp_header_T_ctor(tsk_object_t *self, va_list * app) +{ + tsdp_header_T_t *T = self; + if(T){ + TSDP_HEADER(T)->type = tsdp_htype_T; + TSDP_HEADER(T)->tostring = tsdp_header_T_tostring; + TSDP_HEADER(T)->clone = tsdp_header_T_clone; + TSDP_HEADER(T)->rank = TSDP_HTYPE_T_RANK; + } + else{ + TSK_DEBUG_ERROR("Failed to create new U header."); + } + return self; +} + +static tsk_object_t* tsdp_header_T_dtor(tsk_object_t *self) +{ + tsdp_header_T_t *T = self; + if(T){ + TSK_OBJECT_SAFE_FREE(T->repeat_fields); + } + else{ + TSK_DEBUG_ERROR("Null U header."); + } + + return self; +} +static int tsdp_header_T_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) +{ + if(obj1 && obj2){ + return tsdp_header_rank_cmp(obj1, obj2); + } + else{ + return -1; + } +} + +static const tsk_object_def_t tsdp_header_T_def_s = +{ + sizeof(tsdp_header_T_t), + tsdp_header_T_ctor, + tsdp_header_T_dtor, + tsdp_header_T_cmp +}; + +const tsk_object_def_t *tsdp_header_T_def_t = &tsdp_header_T_def_s; diff --git a/tinySDP/src/headers/tsdp_header_U.c b/tinySDP/src/headers/tsdp_header_U.c new file mode 100644 index 0000000..81906db --- /dev/null +++ b/tinySDP/src/headers/tsdp_header_U.c @@ -0,0 +1,341 @@ + +/* #line 1 "./ragel/tsdp_parser_header_U.rl" */ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_header_U.c + * @brief SDP "u=" header (URI). + */ +#include "tinysdp/headers/tsdp_header_U.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_string.h" + +#include <string.h> + +/*********************************** +* Ragel state machine. +*/ + +/* #line 54 "./ragel/tsdp_parser_header_U.rl" */ + + + + +tsdp_header_U_t* tsdp_header_U_create(const char* value) +{ + return tsk_object_new(TSDP_HEADER_U_VA_ARGS(value)); +} + +tsdp_header_U_t* tsdp_header_U_create_null() +{ + return tsdp_header_U_create(tsk_null); +} + +int tsdp_header_U_tostring(const tsdp_header_t* header, tsk_buffer_t* output) +{ + if(header) + { + const tsdp_header_U_t *U = (const tsdp_header_U_t *)header; + if(U->value){ + tsk_buffer_append(output, U->value, tsk_strlen(U->value)); + } + return 0; + } + + return -1; +} + +tsdp_header_t* tsdp_header_U_clone(const tsdp_header_t* header) +{ + if(header){ + const tsdp_header_U_t *U = (const tsdp_header_U_t *)header; + return (tsdp_header_t*)tsdp_header_U_create(U->value); + } + return tsk_null; +} + +tsdp_header_U_t *tsdp_header_U_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsdp_header_U_t *hdr_U = tsdp_header_U_create_null(); + + const char *tag_start = tsk_null; + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + +/* #line 89 "./src/headers/tsdp_header_U.c" */ +static const char _tsdp_machine_parser_header_U_actions[] = { + 0, 1, 0, 1, 1, 2, 0, 1 + +}; + +static const char _tsdp_machine_parser_header_U_key_offsets[] = { + 0, 0, 1, 3, 4, 6, 7 +}; + +static const char _tsdp_machine_parser_header_U_trans_keys[] = { + 117, 32, 61, 10, 13, 32, 13, 0 +}; + +static const char _tsdp_machine_parser_header_U_single_lengths[] = { + 0, 1, 2, 1, 2, 1, 0 +}; + +static const char _tsdp_machine_parser_header_U_range_lengths[] = { + 0, 0, 0, 0, 0, 0, 0 +}; + +static const char _tsdp_machine_parser_header_U_index_offsets[] = { + 0, 0, 2, 5, 7, 10, 12 +}; + +static const char _tsdp_machine_parser_header_U_trans_targs[] = { + 2, 0, 2, 4, 0, 6, 0, 3, + 4, 5, 3, 5, 0, 0 +}; + +static const char _tsdp_machine_parser_header_U_trans_actions[] = { + 0, 0, 0, 0, 0, 0, 0, 5, + 0, 1, 3, 0, 0, 0 +}; + +static const char _tsdp_machine_parser_header_U_eof_actions[] = { + 0, 0, 0, 0, 5, 3, 0 +}; + +static const int tsdp_machine_parser_header_U_start = 1; +static const int tsdp_machine_parser_header_U_first_final = 4; +static const int tsdp_machine_parser_header_U_error = 0; + +static const int tsdp_machine_parser_header_U_en_main = 1; + + +/* #line 103 "./ragel/tsdp_parser_header_U.rl" */ + (void)(tsdp_machine_parser_header_U_first_final); + (void)(tsdp_machine_parser_header_U_error); + (void)(tsdp_machine_parser_header_U_en_main); + +/* #line 141 "./src/headers/tsdp_header_U.c" */ + { + cs = tsdp_machine_parser_header_U_start; + } + +/* #line 107 "./ragel/tsdp_parser_header_U.rl" */ + +/* #line 148 "./src/headers/tsdp_header_U.c" */ + { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + + if ( p == pe ) + goto _test_eof; + if ( cs == 0 ) + goto _out; +_resume: + _keys = _tsdp_machine_parser_header_U_trans_keys + _tsdp_machine_parser_header_U_key_offsets[cs]; + _trans = _tsdp_machine_parser_header_U_index_offsets[cs]; + + _klen = _tsdp_machine_parser_header_U_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _tsdp_machine_parser_header_U_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += ((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + cs = _tsdp_machine_parser_header_U_trans_targs[_trans]; + + if ( _tsdp_machine_parser_header_U_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _tsdp_machine_parser_header_U_actions + _tsdp_machine_parser_header_U_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) + { + switch ( *_acts++ ) + { + case 0: +/* #line 41 "./ragel/tsdp_parser_header_U.rl" */ + { + tag_start = p; + } + break; + case 1: +/* #line 45 "./ragel/tsdp_parser_header_U.rl" */ + { + TSK_PARSER_SET_STRING(hdr_U->value); + } + break; +/* #line 233 "./src/headers/tsdp_header_U.c" */ + } + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; + _test_eof: {} + if ( p == eof ) + { + const char *__acts = _tsdp_machine_parser_header_U_actions + _tsdp_machine_parser_header_U_eof_actions[cs]; + unsigned int __nacts = (unsigned int) *__acts++; + while ( __nacts-- > 0 ) { + switch ( *__acts++ ) { + case 0: +/* #line 41 "./ragel/tsdp_parser_header_U.rl" */ + { + tag_start = p; + } + break; + case 1: +/* #line 45 "./ragel/tsdp_parser_header_U.rl" */ + { + TSK_PARSER_SET_STRING(hdr_U->value); + } + break; +/* #line 261 "./src/headers/tsdp_header_U.c" */ + } + } + } + + _out: {} + } + +/* #line 108 "./ragel/tsdp_parser_header_U.rl" */ + TSK_RAGEL_DISABLE_WARNINGS_END() + + if( cs < +/* #line 273 "./src/headers/tsdp_header_U.c" */ +4 +/* #line 110 "./ragel/tsdp_parser_header_U.rl" */ + ){ + TSK_DEBUG_ERROR("Failed to parse \"u=\" header."); + TSK_OBJECT_SAFE_FREE(hdr_U); + } + + return hdr_U; +} + + + + + + + +//======================================================== +// U header object definition +// + +static tsk_object_t* tsdp_header_U_ctor(tsk_object_t *self, va_list * app) +{ + tsdp_header_U_t *U = self; + if(U) + { + TSDP_HEADER(U)->type = tsdp_htype_U; + TSDP_HEADER(U)->tostring = tsdp_header_U_tostring; + TSDP_HEADER(U)->clone = tsdp_header_U_clone; + TSDP_HEADER(U)->rank = TSDP_HTYPE_U_RANK; + + U->value = tsk_strdup(va_arg(*app, const char*)); + } + else{ + TSK_DEBUG_ERROR("Failed to create new U header."); + } + return self; +} + +static tsk_object_t* tsdp_header_U_dtor(tsk_object_t *self) +{ + tsdp_header_U_t *U = self; + if(U){ + TSK_FREE(U->value); + } + else{ + TSK_DEBUG_ERROR("Null U header."); + } + + return self; +} +static int tsdp_header_U_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) +{ + if(obj1 && obj2){ + return tsdp_header_rank_cmp(obj1, obj2); + } + else{ + return -1; + } +} + +static const tsk_object_def_t tsdp_header_U_def_s = +{ + sizeof(tsdp_header_U_t), + tsdp_header_U_ctor, + tsdp_header_U_dtor, + tsdp_header_U_cmp +}; + +const tsk_object_def_t *tsdp_header_U_def_t = &tsdp_header_U_def_s; diff --git a/tinySDP/src/headers/tsdp_header_V.c b/tinySDP/src/headers/tsdp_header_V.c new file mode 100644 index 0000000..e0a5181 --- /dev/null +++ b/tinySDP/src/headers/tsdp_header_V.c @@ -0,0 +1,332 @@ + +/* #line 1 "./ragel/tsdp_parser_header_V.rl" */ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_header_V.c + * @brief SDP "v=" header (Protocol Version). + */ +#include "tinysdp/headers/tsdp_header_V.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_string.h" + +#include <string.h> + +/*********************************** +* Ragel state machine. +*/ + +/* #line 54 "./ragel/tsdp_parser_header_V.rl" */ + + + +tsdp_header_V_t* tsdp_header_V_create(int32_t version) +{ + return tsk_object_new(TSDP_HEADER_V_VA_ARGS(version)); +} + +tsdp_header_V_t* tsdp_header_V_create_null() +{ + return tsdp_header_V_create(TSDP_HEADER_V_DEFAULT); +} + +int tsdp_header_V_tostring(const tsdp_header_t* header, tsk_buffer_t* output) +{ + if(header) + { + const tsdp_header_V_t *V = (const tsdp_header_V_t *)header; + if(V->version >=0){ + tsk_buffer_append_2(output, "%d", V->version); + } + return 0; + } + + return -1; +} + +tsdp_header_t* tsdp_header_V_clone(const tsdp_header_t* header) +{ + if(header){ + const tsdp_header_V_t *V = (const tsdp_header_V_t *)header; + return (tsdp_header_t*)tsdp_header_V_create(V->version); + } + return tsk_null; +} + +tsdp_header_V_t *tsdp_header_V_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsdp_header_V_t *hdr_V = tsdp_header_V_create_null(); + + const char *tag_start = tsk_null; + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + +/* #line 88 "./src/headers/tsdp_header_V.c" */ +static const char _tsdp_machine_parser_header_V_actions[] = { + 0, 1, 0, 1, 1 +}; + +static const char _tsdp_machine_parser_header_V_key_offsets[] = { + 0, 0, 1, 3, 6, 7, 10 +}; + +static const char _tsdp_machine_parser_header_V_trans_keys[] = { + 118, 32, 61, 32, 48, 57, 10, 13, + 48, 57, 0 +}; + +static const char _tsdp_machine_parser_header_V_single_lengths[] = { + 0, 1, 2, 1, 1, 1, 0 +}; + +static const char _tsdp_machine_parser_header_V_range_lengths[] = { + 0, 0, 0, 1, 0, 1, 0 +}; + +static const char _tsdp_machine_parser_header_V_index_offsets[] = { + 0, 0, 2, 5, 8, 10, 13 +}; + +static const char _tsdp_machine_parser_header_V_trans_targs[] = { + 2, 0, 2, 3, 0, 3, 5, 0, + 6, 0, 4, 5, 0, 0, 0 +}; + +static const char _tsdp_machine_parser_header_V_trans_actions[] = { + 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, 0 +}; + +static const char _tsdp_machine_parser_header_V_eof_actions[] = { + 0, 0, 0, 0, 0, 3, 0 +}; + +static const int tsdp_machine_parser_header_V_start = 1; +static const int tsdp_machine_parser_header_V_first_final = 5; +static const int tsdp_machine_parser_header_V_error = 0; + +static const int tsdp_machine_parser_header_V_en_main = 1; + + +/* #line 102 "./ragel/tsdp_parser_header_V.rl" */ + (void)(tsdp_machine_parser_header_V_first_final); + (void)(tsdp_machine_parser_header_V_error); + (void)(tsdp_machine_parser_header_V_en_main); + +/* #line 140 "./src/headers/tsdp_header_V.c" */ + { + cs = tsdp_machine_parser_header_V_start; + } + +/* #line 106 "./ragel/tsdp_parser_header_V.rl" */ + +/* #line 147 "./src/headers/tsdp_header_V.c" */ + { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + + if ( p == pe ) + goto _test_eof; + if ( cs == 0 ) + goto _out; +_resume: + _keys = _tsdp_machine_parser_header_V_trans_keys + _tsdp_machine_parser_header_V_key_offsets[cs]; + _trans = _tsdp_machine_parser_header_V_index_offsets[cs]; + + _klen = _tsdp_machine_parser_header_V_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _tsdp_machine_parser_header_V_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += ((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + cs = _tsdp_machine_parser_header_V_trans_targs[_trans]; + + if ( _tsdp_machine_parser_header_V_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _tsdp_machine_parser_header_V_actions + _tsdp_machine_parser_header_V_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) + { + switch ( *_acts++ ) + { + case 0: +/* #line 41 "./ragel/tsdp_parser_header_V.rl" */ + { + tag_start = p; + } + break; + case 1: +/* #line 45 "./ragel/tsdp_parser_header_V.rl" */ + { + TSK_PARSER_SET_INT(hdr_V->version); + } + break; +/* #line 232 "./src/headers/tsdp_header_V.c" */ + } + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; + _test_eof: {} + if ( p == eof ) + { + const char *__acts = _tsdp_machine_parser_header_V_actions + _tsdp_machine_parser_header_V_eof_actions[cs]; + unsigned int __nacts = (unsigned int) *__acts++; + while ( __nacts-- > 0 ) { + switch ( *__acts++ ) { + case 1: +/* #line 45 "./ragel/tsdp_parser_header_V.rl" */ + { + TSK_PARSER_SET_INT(hdr_V->version); + } + break; +/* #line 254 "./src/headers/tsdp_header_V.c" */ + } + } + } + + _out: {} + } + +/* #line 107 "./ragel/tsdp_parser_header_V.rl" */ + TSK_RAGEL_DISABLE_WARNINGS_END() + + if( cs < +/* #line 266 "./src/headers/tsdp_header_V.c" */ +5 +/* #line 109 "./ragel/tsdp_parser_header_V.rl" */ + ){ + TSK_DEBUG_ERROR("Failed to parse \"v=\" header."); + TSK_OBJECT_SAFE_FREE(hdr_V); + } + + return hdr_V; +} + + + + + + + +//======================================================== +// V header object definition +// + +static tsk_object_t* tsdp_header_V_ctor(tsk_object_t *self, va_list * app) +{ + tsdp_header_V_t *V = self; + if(V){ + TSDP_HEADER(V)->type = tsdp_htype_V; + TSDP_HEADER(V)->tostring = tsdp_header_V_tostring; + TSDP_HEADER(V)->clone = tsdp_header_V_clone; + TSDP_HEADER(V)->rank = TSDP_HTYPE_V_RANK; + + V->version = va_arg(*app, int32_t); + } + else{ + TSK_DEBUG_ERROR("Failed to create new V header."); + } + return self; +} + +static tsk_object_t* tsdp_header_V_dtor(tsk_object_t *self) +{ + tsdp_header_V_t *V = self; + if(V){ + } + else{ + TSK_DEBUG_ERROR("Null V header."); + } + + return self; +} +static int tsdp_header_V_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) +{ + if(obj1 && obj2){ + return tsdp_header_rank_cmp(obj1, obj2); + } + else{ + return -1; + } +} + +static const tsk_object_def_t tsdp_header_V_def_s = +{ + sizeof(tsdp_header_V_t), + tsdp_header_V_ctor, + tsdp_header_V_dtor, + tsdp_header_V_cmp +}; + +const tsk_object_def_t *tsdp_header_V_def_t = &tsdp_header_V_def_s; diff --git a/tinySDP/src/headers/tsdp_header_Z.c b/tinySDP/src/headers/tsdp_header_Z.c new file mode 100644 index 0000000..d00453e --- /dev/null +++ b/tinySDP/src/headers/tsdp_header_Z.c @@ -0,0 +1,485 @@ + +/* #line 1 "./ragel/tsdp_parser_header_Z.rl" */ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + + +/**@file tsdp_header_Z.c + * @brief SDP "z=" header (Time Zones). + * + */ +#include "tinysdp/headers/tsdp_header_Z.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_string.h" + +#include <string.h> + +/*********************************** +* Ragel state machine. +*/ + +/* #line 88 "./ragel/tsdp_parser_header_Z.rl" */ + + + +tsdp_header_Z_t* tsdp_header_Z_create(uint64_t time, tsk_bool_t shifted_back, const char* typed_time) +{ + return tsk_object_new(TSDP_HEADER_Z_VA_ARGS(time, shifted_back, typed_time)); +} + +tsdp_header_Z_t* tsdp_header_Z_create_null() +{ + return tsdp_header_Z_create(0L, tsk_false, tsk_null); +} + + +tsdp_zone_t* tsdp_zone_create(uint64_t time, tsk_bool_t shifted_back, const char* typed_time) +{ + return tsk_object_new(tsdp_zone_def_t, time, shifted_back, typed_time); +} + +tsdp_zone_t* tsdp_zone_create_null() +{ + return tsdp_zone_create(0L, tsk_false, tsk_null); +} + +int tsdp_header_Z_tostring(const tsdp_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsdp_header_Z_t *Z = (const tsdp_header_Z_t *)header; + const tsk_list_item_t *item; + const tsdp_zone_t* zone; + + tsk_list_foreach(item, Z->zones){ + zone = (const tsdp_zone_t*)item->data; + // time SP ["-"] typed-time + tsk_buffer_append_2(output, "%s%llu %s%s", + TSK_LIST_IS_FIRST(Z->zones, item) ? "" : " ", + zone->time, + zone->shifted_back ? "-" : "", + zone->typed_time + ); + } + } + + return -1; +} + +tsdp_header_Z_t *tsdp_header_Z_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsdp_header_Z_t *hdr_Z = tsdp_header_Z_create_null(); + tsdp_zone_t* zone = tsk_null; + + const char *tag_start = tsk_null; + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + +/* #line 101 "./src/headers/tsdp_header_Z.c" */ +static const char _tsdp_machine_parser_header_Z_actions[] = { + 0, 1, 0, 1, 3, 1, 4, 2, + 1, 0, 2, 4, 2, 2, 5, 0, + 3, 4, 2, 1 +}; + +static const char _tsdp_machine_parser_header_Z_key_offsets[] = { + 0, 0, 1, 3, 5, 8, 11, 13, + 14, 16, 19, 22, 24, 32, 32, 40, + 42 +}; + +static const char _tsdp_machine_parser_header_Z_trans_keys[] = { + 122, 32, 61, 48, 57, 32, 48, 57, + 45, 48, 57, 48, 57, 10, 48, 57, + 32, 48, 57, 45, 48, 57, 48, 57, + 13, 32, 100, 104, 109, 115, 48, 57, + 13, 32, 100, 104, 109, 115, 48, 57, + 13, 32, 13, 32, 0 +}; + +static const char _tsdp_machine_parser_header_Z_single_lengths[] = { + 0, 1, 2, 0, 1, 1, 0, 1, + 0, 1, 1, 0, 6, 0, 6, 2, + 2 +}; + +static const char _tsdp_machine_parser_header_Z_range_lengths[] = { + 0, 0, 0, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 0, 1, 0, + 0 +}; + +static const char _tsdp_machine_parser_header_Z_index_offsets[] = { + 0, 0, 2, 5, 7, 10, 13, 15, + 17, 19, 22, 25, 27, 35, 36, 44, + 47 +}; + +static const char _tsdp_machine_parser_header_Z_indicies[] = { + 0, 1, 0, 2, 1, 3, 1, 4, + 5, 1, 6, 7, 1, 8, 1, 9, + 1, 10, 1, 11, 12, 1, 13, 14, + 1, 15, 1, 16, 17, 19, 19, 19, + 19, 18, 1, 1, 20, 21, 23, 23, + 23, 23, 22, 1, 20, 21, 1, 16, + 17, 1, 0 +}; + +static const char _tsdp_machine_parser_header_Z_trans_targs[] = { + 2, 0, 3, 4, 5, 4, 6, 12, + 12, 13, 9, 10, 9, 11, 14, 14, + 7, 8, 12, 16, 7, 8, 14, 15 +}; + +static const char _tsdp_machine_parser_header_Z_trans_actions[] = { + 0, 0, 0, 7, 3, 0, 0, 1, + 13, 0, 1, 3, 0, 0, 1, 13, + 16, 16, 0, 0, 10, 5, 0, 0 +}; + +static const char _tsdp_machine_parser_header_Z_eof_actions[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 16, 0, 10, 10, + 16 +}; + +static const int tsdp_machine_parser_header_Z_start = 1; +static const int tsdp_machine_parser_header_Z_first_final = 12; +static const int tsdp_machine_parser_header_Z_error = 0; + +static const int tsdp_machine_parser_header_Z_en_main = 1; + + +/* #line 147 "./ragel/tsdp_parser_header_Z.rl" */ + (void)(tsdp_machine_parser_header_Z_first_final); + (void)(tsdp_machine_parser_header_Z_error); + (void)(tsdp_machine_parser_header_Z_en_main); + +/* #line 181 "./src/headers/tsdp_header_Z.c" */ + { + cs = tsdp_machine_parser_header_Z_start; + } + +/* #line 151 "./ragel/tsdp_parser_header_Z.rl" */ + +/* #line 188 "./src/headers/tsdp_header_Z.c" */ + { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + + if ( p == pe ) + goto _test_eof; + if ( cs == 0 ) + goto _out; +_resume: + _keys = _tsdp_machine_parser_header_Z_trans_keys + _tsdp_machine_parser_header_Z_key_offsets[cs]; + _trans = _tsdp_machine_parser_header_Z_index_offsets[cs]; + + _klen = _tsdp_machine_parser_header_Z_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _tsdp_machine_parser_header_Z_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += ((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + _trans = _tsdp_machine_parser_header_Z_indicies[_trans]; + cs = _tsdp_machine_parser_header_Z_trans_targs[_trans]; + + if ( _tsdp_machine_parser_header_Z_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _tsdp_machine_parser_header_Z_actions + _tsdp_machine_parser_header_Z_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) + { + switch ( *_acts++ ) + { + case 0: +/* #line 43 "./ragel/tsdp_parser_header_Z.rl" */ + { + tag_start = p; + } + break; + case 1: +/* #line 47 "./ragel/tsdp_parser_header_Z.rl" */ + { + if(!zone){ + zone = tsdp_zone_create_null(); + } + } + break; + case 2: +/* #line 53 "./ragel/tsdp_parser_header_Z.rl" */ + { + if(zone){ + tsk_list_push_back_data(hdr_Z->zones,(void**)&zone); + } + } + break; + case 3: +/* #line 59 "./ragel/tsdp_parser_header_Z.rl" */ + { + if(zone){ + TSK_PARSER_SET_INTEGER_EX(zone->time, uint64_t, atoi64); + } + } + break; + case 4: +/* #line 65 "./ragel/tsdp_parser_header_Z.rl" */ + { + if(zone){ + TSK_PARSER_SET_STRING(zone->typed_time); + } + } + break; + case 5: +/* #line 71 "./ragel/tsdp_parser_header_Z.rl" */ + { + if(zone){ + zone->shifted_back = tsk_true; + } + } + break; +/* #line 308 "./src/headers/tsdp_header_Z.c" */ + } + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; + _test_eof: {} + if ( p == eof ) + { + const char *__acts = _tsdp_machine_parser_header_Z_actions + _tsdp_machine_parser_header_Z_eof_actions[cs]; + unsigned int __nacts = (unsigned int) *__acts++; + while ( __nacts-- > 0 ) { + switch ( *__acts++ ) { + case 1: +/* #line 47 "./ragel/tsdp_parser_header_Z.rl" */ + { + if(!zone){ + zone = tsdp_zone_create_null(); + } + } + break; + case 2: +/* #line 53 "./ragel/tsdp_parser_header_Z.rl" */ + { + if(zone){ + tsk_list_push_back_data(hdr_Z->zones,(void**)&zone); + } + } + break; + case 4: +/* #line 65 "./ragel/tsdp_parser_header_Z.rl" */ + { + if(zone){ + TSK_PARSER_SET_STRING(zone->typed_time); + } + } + break; +/* #line 348 "./src/headers/tsdp_header_Z.c" */ + } + } + } + + _out: {} + } + +/* #line 152 "./ragel/tsdp_parser_header_Z.rl" */ + TSK_RAGEL_DISABLE_WARNINGS_END() + + if(zone){ + TSK_OBJECT_SAFE_FREE(zone); + } + + if( cs < +/* #line 364 "./src/headers/tsdp_header_Z.c" */ +12 +/* #line 158 "./ragel/tsdp_parser_header_Z.rl" */ + ){ + TSK_DEBUG_ERROR("Failed to parse \"z=\" header."); + TSK_OBJECT_SAFE_FREE(hdr_Z); + } + + return hdr_Z; +} + + + + + + + +//======================================================== +// Z header object definition +// + +static tsk_object_t* tsdp_header_Z_ctor(tsk_object_t *self, va_list * app) +{ + tsdp_header_Z_t *Z = self; + if(Z){ + TSDP_HEADER(Z)->type = tsdp_htype_Z; + TSDP_HEADER(Z)->tostring = tsdp_header_Z_tostring; + TSDP_HEADER(Z)->rank = TSDP_HTYPE_Z_RANK; + + if((Z->zones = tsk_list_create())){ + uint64_t time = va_arg(*app, uint64_t); + unsigned shifted_back = va_arg(*app, unsigned); + const char* typed_time = va_arg(*app, const char*); + + if(typed_time){ + tsdp_zone_t *zone; + if((zone = tsdp_zone_create(time, shifted_back, typed_time))){ + tsk_list_push_back_data(Z->zones,(void**)&zone); + } + } + } + } + else{ + TSK_DEBUG_ERROR("Failed to create new Z header."); + } + return self; +} + +static tsk_object_t* tsdp_header_Z_dtor(tsk_object_t *self) +{ + tsdp_header_Z_t *Z = self; + if(Z){ + TSK_OBJECT_SAFE_FREE(Z->zones); + } + else{ + TSK_DEBUG_ERROR("Null Z header."); + } + + return self; +} +static int tsdp_header_Z_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) +{ + if(obj1 && obj2){ + return tsdp_header_rank_cmp(obj1, obj2); + } + else{ + return -1; + } +} + +static const tsk_object_def_t tsdp_header_Z_def_s = +{ + sizeof(tsdp_header_Z_t), + tsdp_header_Z_ctor, + tsdp_header_Z_dtor, + tsdp_header_Z_cmp +}; + +const tsk_object_def_t *tsdp_header_Z_def_t = &tsdp_header_Z_def_s; + + + + +//======================================================== +// Zone object definition +// + +static tsk_object_t* tsdp_zone_ctor(tsk_object_t *self, va_list * app) +{ + tsdp_zone_t *zone = self; + if(zone){ + zone->time = va_arg(*app, uint64_t); + zone->shifted_back = va_arg(*app, tsk_bool_t); + zone->typed_time = tsk_strdup( va_arg(*app, const char*) ); + } + else{ + TSK_DEBUG_ERROR("Failed to create new zone object."); + } + return self; +} + +static tsk_object_t* tsdp_zone_dtor(tsk_object_t *self) +{ + tsdp_zone_t *zone = self; + if(zone){ + TSK_FREE(zone->typed_time); + } + else{ + TSK_DEBUG_ERROR("Null zone object."); + } + + return self; +} + +static const tsk_object_def_t tsdp_zone_def_s = +{ + sizeof(tsdp_zone_t), + tsdp_zone_ctor, + tsdp_zone_dtor, + tsk_null +}; + +const tsk_object_def_t *tsdp_zone_def_t = &tsdp_zone_def_s; diff --git a/tinySDP/src/parsers/tsdp_parser_message.c b/tinySDP/src/parsers/tsdp_parser_message.c new file mode 100644 index 0000000..b2f45fd --- /dev/null +++ b/tinySDP/src/parsers/tsdp_parser_message.c @@ -0,0 +1,477 @@ + +/* #line 1 "./ragel/tsdp_parser_message.rl" */ +/* +* Copyright (C) 2010-2015 Mamadou Diop. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ +/**@file tsdp_machine_message.rl + * @brief Ragel file. + */ +#include "tinysdp/parsers/tsdp_parser_message.h" + +#include "tinysdp/headers/tsdp_header_A.h" +#include "tinysdp/headers/tsdp_header_B.h" +#include "tinysdp/headers/tsdp_header_C.h" +#include "tinysdp/headers/tsdp_header_Dummy.h" +#include "tinysdp/headers/tsdp_header_E.h" +#include "tinysdp/headers/tsdp_header_I.h" +#include "tinysdp/headers/tsdp_header_K.h" +#include "tinysdp/headers/tsdp_header_M.h" +#include "tinysdp/headers/tsdp_header_O.h" +#include "tinysdp/headers/tsdp_header_P.h" +#include "tinysdp/headers/tsdp_header_R.h" +#include "tinysdp/headers/tsdp_header_S.h" +#include "tinysdp/headers/tsdp_header_T.h" +#include "tinysdp/headers/tsdp_header_U.h" +#include "tinysdp/headers/tsdp_header_V.h" +#include "tinysdp/headers/tsdp_header_Z.h" + +#include "tsk_debug.h" + + +/* #line 238 "./ragel/tsdp_parser_message.rl" */ + + +TSK_RAGEL_DISABLE_WARNINGS_BEGIN() +/* Ragel data */ + +/* #line 54 "./src/parsers/tsdp_parser_message.c" */ +static const char _tsdp_machine_message_actions[] = { + 0, 1, 0, 1, 1, 1, 2, 1, + 3, 1, 4, 1, 5, 1, 6, 1, + 7, 1, 8, 1, 9, 1, 10, 1, + 11, 1, 12, 1, 13, 1, 14, 1, + 15, 1, 16 +}; + +static const char _tsdp_machine_message_key_offsets[] = { + 0, 0, 2, 3, 4, 6, 7, 9, + 10, 12, 13, 15, 16, 18, 19, 21, + 22, 24, 25, 27, 28, 30, 31, 33, + 34, 36, 37, 39, 40, 42, 43, 45, + 46, 48, 49 +}; + +static const char _tsdp_machine_message_trans_keys[] = { + 32, 61, 13, 10, 32, 61, 13, 32, + 61, 13, 32, 61, 13, 32, 61, 13, + 32, 61, 13, 32, 61, 13, 32, 61, + 13, 32, 61, 13, 32, 61, 13, 32, + 61, 13, 32, 61, 13, 32, 61, 13, + 32, 61, 13, 32, 61, 13, 32, 61, + 13, 65, 66, 67, 69, 73, 75, 77, + 79, 80, 82, 83, 84, 85, 86, 90, + 97, 98, 99, 101, 105, 107, 109, 111, + 112, 114, 115, 116, 117, 118, 122, 68, + 89, 100, 121, 0 +}; + +static const char _tsdp_machine_message_single_lengths[] = { + 0, 2, 1, 1, 2, 1, 2, 1, + 2, 1, 2, 1, 2, 1, 2, 1, + 2, 1, 2, 1, 2, 1, 2, 1, + 2, 1, 2, 1, 2, 1, 2, 1, + 2, 1, 30 +}; + +static const char _tsdp_machine_message_range_lengths[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2 +}; + +static const char _tsdp_machine_message_index_offsets[] = { + 0, 0, 3, 5, 7, 10, 12, 15, + 17, 20, 22, 25, 27, 30, 32, 35, + 37, 40, 42, 45, 47, 50, 52, 55, + 57, 60, 62, 65, 67, 70, 72, 75, + 77, 80, 82 +}; + +static const char _tsdp_machine_message_trans_targs[] = { + 1, 2, 0, 3, 2, 34, 0, 4, + 5, 0, 3, 5, 6, 7, 0, 3, + 7, 8, 9, 0, 3, 9, 10, 11, + 0, 3, 11, 12, 13, 0, 3, 13, + 14, 15, 0, 3, 15, 16, 17, 0, + 3, 17, 18, 19, 0, 3, 19, 20, + 21, 0, 3, 21, 22, 23, 0, 3, + 23, 24, 25, 0, 3, 25, 26, 27, + 0, 3, 27, 28, 29, 0, 3, 29, + 30, 31, 0, 3, 31, 32, 33, 0, + 3, 33, 1, 4, 6, 10, 12, 14, + 16, 18, 20, 22, 24, 26, 28, 30, + 32, 1, 4, 6, 10, 12, 14, 16, + 18, 20, 22, 24, 26, 28, 30, 32, + 8, 8, 0, 0 +}; + +static const char _tsdp_machine_message_trans_actions[] = { + 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 5, 0, 0, 0, 0, 7, + 0, 0, 0, 0, 9, 0, 0, 0, + 0, 11, 0, 0, 0, 0, 13, 0, + 0, 0, 0, 15, 0, 0, 0, 0, + 17, 0, 0, 0, 0, 19, 0, 0, + 0, 0, 21, 0, 0, 0, 0, 23, + 0, 0, 0, 0, 25, 0, 0, 0, + 0, 27, 0, 0, 0, 0, 29, 0, + 0, 0, 0, 31, 0, 0, 0, 0, + 33, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 0 +}; + +static const int tsdp_machine_message_start = 34; +static const int tsdp_machine_message_first_final = 34; +static const int tsdp_machine_message_error = 0; + +static const int tsdp_machine_message_en_main = 34; + + +/* #line 243 "./ragel/tsdp_parser_message.rl" */ +TSK_RAGEL_DISABLE_WARNINGS_END() + +tsdp_message_t* tsdp_message_parse(const void *input, tsk_size_t size) +{ + tsdp_message_t* sdp_msg = tsk_null; + const char* tag_start = tsk_null; + tsdp_header_t *header = tsk_null; + tsdp_header_T_t *hdr_T = tsk_null; + tsdp_header_M_t *hdr_M = tsk_null; + + /* Ragel variables */ + int cs = 0; + const char* p = input; + const char* pe = p + size; + const char* eof = tsk_null; + + (void)(eof); + + if(!input || !size){ + TSK_DEBUG_ERROR("Null or empty buffer."); + goto bail; + } + + if(!(sdp_msg = tsdp_message_create())){ + goto bail; + } + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + /* Ragel init */ + +/* #line 183 "./src/parsers/tsdp_parser_message.c" */ + { + cs = tsdp_machine_message_start; + } + +/* #line 273 "./ragel/tsdp_parser_message.rl" */ + + /* Ragel execute */ + +/* #line 192 "./src/parsers/tsdp_parser_message.c" */ + { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + + if ( p == pe ) + goto _test_eof; + if ( cs == 0 ) + goto _out; +_resume: + _keys = _tsdp_machine_message_trans_keys + _tsdp_machine_message_key_offsets[cs]; + _trans = _tsdp_machine_message_index_offsets[cs]; + + _klen = _tsdp_machine_message_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _tsdp_machine_message_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += ((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + cs = _tsdp_machine_message_trans_targs[_trans]; + + if ( _tsdp_machine_message_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _tsdp_machine_message_actions + _tsdp_machine_message_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) + { + switch ( *_acts++ ) + { + case 0: +/* #line 52 "./ragel/tsdp_parser_message.rl" */ + { + tag_start = p; + } + break; + case 1: +/* #line 59 "./ragel/tsdp_parser_message.rl" */ + { + if(hdr_M){ + if(!hdr_M->Attributes){ + hdr_M->Attributes = tsk_list_create(); + } + if((header = (tsdp_header_t*)tsdp_header_A_parse(tag_start, (p - tag_start)))){ + tsk_list_push_back_data(hdr_M->Attributes, (void**)&header); + } + } + else if((header = (tsdp_header_t*)tsdp_header_A_parse(tag_start, (p - tag_start)))){ + tsdp_message_add_header(sdp_msg, header); + tsk_object_unref(header); + } + } + break; + case 2: +/* #line 74 "./ragel/tsdp_parser_message.rl" */ + { + if(hdr_M){ + if(!hdr_M->Bandwidths){ + hdr_M->Bandwidths = tsk_list_create(); + } + if((header = (tsdp_header_t*)tsdp_header_B_parse(tag_start, (p - tag_start)))){ + tsk_list_push_back_data(hdr_M->Bandwidths, (void**)&header); + } + } + else if((header = (tsdp_header_t*)tsdp_header_B_parse(tag_start, (p - tag_start)))){ + tsdp_message_add_header(sdp_msg, header); + tsk_object_unref(header); + } + } + break; + case 3: +/* #line 89 "./ragel/tsdp_parser_message.rl" */ + { + if(hdr_M && !hdr_M->C){ + hdr_M->C = tsdp_header_C_parse(tag_start, (p - tag_start)); + } + else if((header = (tsdp_header_t*)tsdp_header_C_parse(tag_start, (p - tag_start)))){ + tsdp_message_add_header(sdp_msg, header); + tsk_object_unref(header); + } + } + break; + case 4: +/* #line 99 "./ragel/tsdp_parser_message.rl" */ + { + if((header = (tsdp_header_t*)tsdp_header_Dummy_parse(tag_start, (p - tag_start)))){ + tsdp_message_add_header(sdp_msg, header); + tsk_object_unref(header); + } + } + break; + case 5: +/* #line 106 "./ragel/tsdp_parser_message.rl" */ + { + if((header = (tsdp_header_t*)tsdp_header_E_parse(tag_start, (p - tag_start)))){ + tsdp_message_add_header(sdp_msg, header); + tsk_object_unref(header); + } + } + break; + case 6: +/* #line 113 "./ragel/tsdp_parser_message.rl" */ + { + if(hdr_M && !hdr_M->I){ + hdr_M->I = tsdp_header_I_parse(tag_start, (p - tag_start)); + } + else if((header = (tsdp_header_t*)tsdp_header_I_parse(tag_start, (p - tag_start)))){ + tsdp_message_add_header(sdp_msg, header); + tsk_object_unref(header); + } + } + break; + case 7: +/* #line 123 "./ragel/tsdp_parser_message.rl" */ + { + if(hdr_M && !hdr_M->K){ + hdr_M->K = tsdp_header_K_parse(tag_start, (p - tag_start)); + } + else if((header = (tsdp_header_t*)tsdp_header_K_parse(tag_start, (p - tag_start)))){ + tsdp_message_add_header(sdp_msg, header); + tsk_object_unref(header); + } + } + break; + case 8: +/* #line 133 "./ragel/tsdp_parser_message.rl" */ + { + if((hdr_M = tsdp_header_M_parse(tag_start, (p - tag_start)))){ + tsdp_message_add_header(sdp_msg, TSDP_HEADER(hdr_M)); + hdr_M = tsk_object_unref(hdr_M); + } + } + break; + case 9: +/* #line 140 "./ragel/tsdp_parser_message.rl" */ + { + if((header = (tsdp_header_t*)tsdp_header_O_parse(tag_start, (p - tag_start)))){ + tsdp_message_add_header(sdp_msg, header); + tsk_object_unref(header); + } + } + break; + case 10: +/* #line 147 "./ragel/tsdp_parser_message.rl" */ + { + if((header = (tsdp_header_t*)tsdp_header_P_parse(tag_start, (p - tag_start)))){ + tsdp_message_add_header(sdp_msg, header); + tsk_object_unref(header); + } + } + break; + case 11: +/* #line 154 "./ragel/tsdp_parser_message.rl" */ + { + if((header = (tsdp_header_t*)tsdp_header_R_parse(tag_start, (p - tag_start)))){ + if(hdr_T){ + if(!hdr_T->repeat_fields){ + hdr_T->repeat_fields = tsk_list_create(); + } + tsk_list_push_back_data(hdr_T->repeat_fields, (void**)&header); + } + else{ + tsdp_message_add_header(sdp_msg, header); + tsk_object_unref(header); + } + } + } + break; + case 12: +/* #line 169 "./ragel/tsdp_parser_message.rl" */ + { + if((header = (tsdp_header_t*)tsdp_header_S_parse(tag_start, (p - tag_start)))){ + tsdp_message_add_header(sdp_msg, header); + tsk_object_unref(header); + } + } + break; + case 13: +/* #line 176 "./ragel/tsdp_parser_message.rl" */ + { + if((hdr_T = tsdp_header_T_parse(tag_start, (p - tag_start)))){ + tsdp_message_add_header(sdp_msg, TSDP_HEADER(hdr_T)); + hdr_T = tsk_object_unref(hdr_T); + } + } + break; + case 14: +/* #line 183 "./ragel/tsdp_parser_message.rl" */ + { + if((header = (tsdp_header_t*)tsdp_header_U_parse(tag_start, (p - tag_start)))){ + tsdp_message_add_header(sdp_msg, header); + tsk_object_unref(header); + } + } + break; + case 15: +/* #line 190 "./ragel/tsdp_parser_message.rl" */ + { + if((header = (tsdp_header_t*)tsdp_header_V_parse(tag_start, (p - tag_start)))){ + tsdp_message_add_header(sdp_msg, header); + tsk_object_unref(header); + } + } + break; + case 16: +/* #line 197 "./ragel/tsdp_parser_message.rl" */ + { + if((header = (tsdp_header_t*)tsdp_header_Z_parse(tag_start, (p - tag_start)))){ + tsdp_message_add_header(sdp_msg, header); + tsk_object_unref(header); + } + } + break; +/* #line 448 "./src/parsers/tsdp_parser_message.c" */ + } + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; + _test_eof: {} + _out: {} + } + +/* #line 276 "./ragel/tsdp_parser_message.rl" */ + TSK_RAGEL_DISABLE_WARNINGS_END() + + /* Check result */ + if( cs < +/* #line 466 "./src/parsers/tsdp_parser_message.c" */ +34 +/* #line 279 "./ragel/tsdp_parser_message.rl" */ + ) + { + TSK_DEBUG_ERROR("Failed to parse SDP message."); + TSK_OBJECT_SAFE_FREE(sdp_msg); + goto bail; + } + +bail: + return sdp_msg; +} diff --git a/tinySDP/src/tsdp.c b/tinySDP/src/tsdp.c new file mode 100644 index 0000000..48b05e6 --- /dev/null +++ b/tinySDP/src/tsdp.c @@ -0,0 +1,211 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org> +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ +/**@file tsdp.c + * @brief SDP (RFC 4566) implementations with both MMTel and PoC extensions. + * + * @author Mamadou Diop <diopmamadou(at)doubango[dot]org> + * + + */ +#include "tsdp.h" + +#include "tinysdp/parsers/tsdp_parser_message.h" + +// Defined in tsdp_message.c +extern int __pred_find_media_by_name(const tsk_list_item_t *item, const void *name); + + +typedef struct tsdp_ctx_s +{ + TSK_DECLARE_OBJECT; + + tsdp_message_t* local; + tsdp_message_t* remote; + tsdp_message_t* negotiated; +} +tsdp_ctx_t; + +const tsdp_message_t* tsdp_ctx_local_get_sdp(const tsdp_ctx_handle_t* self) +{ + const tsdp_ctx_t* ctx = self; + + if(ctx){ + return ctx->local; + } + else return tsk_null; +} + +int tsdp_ctx_local_create_sdp(tsdp_ctx_handle_t* self, const tsdp_message_t* local) +{ + tsdp_ctx_t* ctx = self; + tsdp_message_t* newsdp; + + if(!ctx || !local){ + return -1; + } + + // set new local sdp + if((newsdp = tsdp_message_clone(local))){ + TSK_OBJECT_SAFE_FREE(ctx->local); + ctx->local = newsdp; + return 0; + } + else return -2; +} + +int tsdp_ctx_local_create_sdp_2(tsdp_ctx_handle_t* self, const char* sdp, tsk_size_t size) +{ + tsdp_ctx_t* ctx = self; + tsdp_message_t* newsdp; + + if(!ctx || !sdp || !size){ + return -1; + } + + if((newsdp = tsdp_message_parse(sdp, size))){ + TSK_OBJECT_SAFE_FREE(ctx->local); + ctx->local = newsdp; + return 0; + } + else return -2; +} + +int tsdp_ctx_local_add_headers(tsdp_ctx_handle_t* self, ...) +{ + tsdp_ctx_t* ctx = self; + const tsk_object_def_t* objdef; + tsdp_header_t *header; + va_list ap; + + if(!ctx || !ctx->local){ + return -1; + } + + va_start(ap, self); + while((objdef = va_arg(ap, const tsk_object_def_t*))){ + if((header = tsk_object_new_2(objdef, &ap))){ + tsdp_message_add_header(ctx->local, header); + TSK_OBJECT_SAFE_FREE(header); + } + } + va_end(ap); + + return 0; +} + +int tsdp_ctx_local_add_media(tsdp_ctx_handle_t* self, const tsdp_header_M_t* media) +{ + tsdp_ctx_t* ctx = self; + + if(!ctx || !media){ + return -1; + } + + if(ctx->local){ + return tsdp_message_add_header(ctx->local, TSDP_HEADER(media)); + } + else return -2; +} + +int tsdp_ctx_local_add_media_2(tsdp_ctx_handle_t* self, const char* media, uint32_t port, const char* proto, ...) +{ + tsdp_ctx_t* ctx = self; + va_list ap; + + if(!ctx || !media || !proto){ + return -1; + } + + if(ctx->local){ + int ret; + va_start(ap, proto); + ret = tsdp_message_add_media_2(ctx->local, media, port, proto, &ap); + va_end(ap); + return ret; + } + else return -2; +} + +const tsdp_message_t* tsdp_ctx_remote_get_sdp(const tsdp_ctx_handle_t* self) +{ + const tsdp_ctx_t* ctx = self; + + if(ctx){ + return ctx->remote; + } + else return tsk_null; +} + +const tsdp_message_t* tsdp_ctx_negotiated_get_sdp(const tsdp_ctx_handle_t* self) +{ + const tsdp_ctx_t* ctx = self; + + if(ctx){ + return ctx->negotiated; + } + else return tsk_null; +} + + + + + + + + + + + + + + + +//================================================================================================= +// Sdp ctx object definition +// +static void* tsdp_ctx_create(void * self, va_list * app) +{ + tsdp_ctx_t *ctx = self; + if(ctx){ + } + return self; +} + +static void* tsdp_ctx_destroy(void * self) +{ + tsdp_ctx_t *ctx = self; + if(ctx){ + TSK_OBJECT_SAFE_FREE(ctx->local); + TSK_OBJECT_SAFE_FREE(ctx->remote); + TSK_OBJECT_SAFE_FREE(ctx->negotiated); + } + return self; +} + +static const tsk_object_def_t tsdp_ctx_def_s = +{ + sizeof(tsdp_ctx_t), + tsdp_ctx_create, + tsdp_ctx_destroy, + tsk_null, +}; +const tsk_object_def_t *tsdp_ctx_def_t = &tsdp_ctx_def_s; diff --git a/tinySDP/src/tsdp_message.c b/tinySDP/src/tsdp_message.c new file mode 100644 index 0000000..7be242f --- /dev/null +++ b/tinySDP/src/tsdp_message.c @@ -0,0 +1,503 @@ +/* +* Copyright (C) 2010-2015 Mamadou DIOP. +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +/**@file tsdp_message.c + * @brief SDP message. + */ + +#include "tinysdp/tsdp_message.h" + +#include "tinysdp/headers/tsdp_header_O.h" +#include "tinysdp/headers/tsdp_header_S.h" +#include "tinysdp/headers/tsdp_header_T.h" +#include "tinysdp/headers/tsdp_header_V.h" + +#include "tsk_debug.h" + +#define TSDP_LINE_S_VALUE_DEFAULT "-" /* as per RFC 3264 subclause 5 */ + +#define TSDP_LINE_O_USERNAME_DEFAULT "doubango" +#define TSDP_LINE_O_SESSION_VER_DEFAULT 2301 +#define TSDP_LINE_O_SESSION_ID_DEFAULT 1983 + +/*== Predicate function to find tsdp_header_t object by type. */ +static int __pred_find_header_by_type(const tsk_list_item_t *item, const void *tsdp_htype) +{ + if(item && item->data){ + tsdp_header_t *header = item->data; + tsdp_header_type_t htype = *((tsdp_header_type_t*)tsdp_htype); + return (header->type - htype); + } + return -1; +} + +/*== Predicate function to find tsdp_header_t object by name. */ +static int __pred_find_header_by_name(const tsk_list_item_t *item, const void *name) +{ + if(item && item->data && name){ + tsdp_header_t *header = item->data; + return tsdp_header_get_nameex(header) - *((const char*)name); + } + return -1; +} + +/*== Predicate function to find media object by name. */ +static int __pred_find_media_by_name(const tsk_list_item_t *item, const void *name) +{ + if(item && item->data && name){ + tsdp_header_t *header = item->data; + if(header->type == tsdp_htype_M){ + return tsk_stricmp(((tsdp_header_M_t*)header)->media, (const char*)name); + } + } + return -1; +} + +tsdp_message_t* tsdp_message_create() +{ + return tsk_object_new(tsdp_message_def_t); +} + +/*== Add headers/fmt to the media line */ +int __add_headers(tsdp_header_M_t* m, va_list *ap) +{ + const tsk_object_def_t* objdef; + tsdp_header_t *header; + tsdp_fmt_t* fmt; + + if(!m){ + return -1; + } + + while((objdef = va_arg(*ap, const tsk_object_def_t*))){ + if(objdef == tsdp_fmt_def_t){ + if((fmt = tsk_object_new_2(objdef, ap))){ + tsk_list_push_back_data(m->FMTs, (void**)&fmt); + } + } + else{ + if((header = tsk_object_new_2(objdef, ap))){ + tsdp_header_M_add(m, header); + TSK_OBJECT_SAFE_FREE(header); + } + } + } + return 0; +} + +int tsdp_message_add_header(tsdp_message_t *self, const tsdp_header_t *hdr) +{ + if(self && hdr){ + tsdp_header_t *header = tsk_object_ref((void*)hdr); + tsk_list_push_ascending_data(self->headers, (void**)&header); // Very important: Headers MUST appear in a fixed order (see ranks def). + + return 0; + } + return -1; +} + +int tsdp_message_add_headers(tsdp_message_t *self, ...) +{ + const tsk_object_def_t* objdef; + tsdp_header_t *header; + va_list ap; + + if(!self){ + return -1; + } + + va_start(ap, self); + while((objdef = va_arg(ap, const tsk_object_def_t*))){ + if((header = tsk_object_new_2(objdef, &ap))){ + tsdp_message_add_header(self, header); + TSK_OBJECT_SAFE_FREE(header); + } + } + va_end(ap); + + return 0; +} + +const tsdp_header_t *tsdp_message_get_headerAt(const tsdp_message_t *self, tsdp_header_type_t type, tsk_size_t index) +{ + tsk_size_t pos = 0; + const tsk_list_item_t *item; + const tsdp_header_t *hdr; + + if(!self || !self->headers){ + return tsk_null; + } + + tsk_list_foreach(item, self->headers){ + hdr = item->data; + if(hdr->type == type){ + if(pos++ >= index){ + return hdr; + } + } + } + + return tsk_null; +} + +const tsdp_header_t *tsdp_message_get_header(const tsdp_message_t *self, tsdp_header_type_t type) +{ + return tsdp_message_get_headerAt(self, type, 0); +} + +const tsdp_header_A_t* tsdp_message_get_headerA_at(const tsdp_message_t* self, const char* field, tsk_size_t index) +{ + + tsk_size_t pos = 0; + const tsk_list_item_t *item; + const tsdp_header_t *hdr; + const tsdp_header_A_t *hdrA; + + if(!self || !self->headers){ + return tsk_null; + } + + tsk_list_foreach(item, self->headers){ + hdr = item->data; + if((hdr->type == tsdp_htype_A) && (hdrA = (const tsdp_header_A_t *)hdr) && (tsk_striequals(hdrA->field, field))){ + if(pos++ >= index){ + return hdrA; + } + } + } + + return tsk_null; +} + +const tsdp_header_A_t* tsdp_message_get_headerA(const tsdp_message_t* self, const char* field) +{ + return tsdp_message_get_headerA_at(self, field, 0); +} + +const tsdp_header_t *tsdp_message_get_headerByName(const tsdp_message_t *self, char name) +{ + if(self){ + return tsk_list_find_object_by_pred(self->headers, __pred_find_header_by_name, &name); + } + else{ + TSK_DEBUG_ERROR("Invalid parameter"); + return tsk_null; + } +} + +int tsdp_message_get_sess_version(const tsdp_message_t *self, uint32_t *version) +{ + const tsdp_header_O_t* O; + if (!self || !version) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if ((O = (const tsdp_header_O_t*)tsdp_message_get_header(self, tsdp_htype_O))) { + *version = O->sess_version; + return 0; + } + return -2; +} + +int tsdp_message_serialize(const tsdp_message_t *self, tsk_buffer_t *output) +{ + const tsk_list_item_t* item; + + if(!self || !output){ + return -1; + } + + tsk_list_foreach(item, self->headers){ + if(tsdp_header_serialize(TSDP_HEADER(item->data), output)){ + // Abort? + } + } + + return 0; +} + +char* tsdp_message_tostring(const tsdp_message_t *self) +{ + tsk_buffer_t* output = tsk_buffer_create_null(); + char* ret = tsk_null; + + if(!tsdp_message_serialize(self, output)){ + ret = tsk_strndup(TSK_BUFFER_DATA(output), TSK_BUFFER_SIZE(output)); + } + + TSK_OBJECT_SAFE_FREE(output); + return ret; +} + +tsdp_message_t* tsdp_message_create_empty(const char* addr, tsk_bool_t ipv6, uint32_t version) +{ + tsdp_message_t* ret = 0; + + if(!(ret = tsdp_message_create())){ + return tsk_null; + } + + /* RFC 3264 - 5 Generating the Initial Offer + The numeric value of the session id and version in the o line MUST be + representable with a 64 bit signed integer. The initial value of the version MUST be less than + (2**62)-1, to avoid rollovers. + */ + TSDP_MESSAGE_ADD_HEADER(ret, TSDP_HEADER_V_VA_ARGS(0)); + TSDP_MESSAGE_ADD_HEADER(ret, TSDP_HEADER_O_VA_ARGS( + TSDP_LINE_O_USERNAME_DEFAULT, + TSDP_LINE_O_SESSION_ID_DEFAULT, + version, + "IN", + ipv6 ? "IP6" : "IP4", + addr)); + + /* RFC 3264 - 5 Generating the Initial Offer + The SDP "s=" line conveys the subject of the session, which is + reasonably defined for multicast, but ill defined for unicast. For + unicast sessions, it is RECOMMENDED that it consist of a single space + character (0x20) or a dash (-). + + Unfortunately, SDP does not allow the "s=" line to be empty. + */ + TSDP_MESSAGE_ADD_HEADER(ret, TSDP_HEADER_S_VA_ARGS(TSDP_LINE_S_VALUE_DEFAULT)); + + /* RFC 3264 - 5 Generating the Initial Offer + The SDP "t=" line conveys the time of the session. Generally, + streams for unicast sessions are created and destroyed through + external signaling means, such as SIP. In that case, the "t=" line + SHOULD have a value of "0 0". + */ + TSDP_MESSAGE_ADD_HEADER(ret, TSDP_HEADER_T_VA_ARGS(0, 0)); + + return ret; +} + +tsdp_message_t* tsdp_message_clone(const tsdp_message_t *self) +{ + tsdp_message_t* clone = tsk_null; + tsk_list_item_t* item; + tsdp_header_t* header; + + if(!self){ + goto bail; + } + + if((clone = tsdp_message_create())){ + tsk_list_foreach(item, self->headers){ + if((header = tsdp_header_clone(TSDP_HEADER(item->data)))){ + tsk_list_push_back_data(clone->headers, (void**)&header); + } + } + } + + +bail: + return clone; +} + +int tsdp_message_add_media(tsdp_message_t *self, const char* media, uint32_t port, const char* proto, ...) +{ + va_list ap; + int ret; + + va_start(ap, proto); + ret = tsdp_message_add_media_2(self, media, port, proto, &ap); + va_end(ap); + + return ret; +} + +int tsdp_message_add_media_2(tsdp_message_t *self, const char* media, uint32_t port, const char* proto, va_list *ap) +{ + int ret = -1; + tsdp_header_M_t* m; + + if(!self){ + return -1; + } + + if((m = tsdp_header_M_create(media, port, proto))){ + __add_headers(m, ap); + + ret = tsdp_message_add_header(self, TSDP_HEADER(m)); + TSK_OBJECT_SAFE_FREE(m); + } + + return ret; +} + +int tsdp_message_remove_media(tsdp_message_t *self, const char* media) +{ + if(!self || !media){ + return 0; + } + + tsk_list_remove_item_by_pred(self->headers, __pred_find_media_by_name, media); + return 0; +} + +const tsdp_header_M_t* tsdp_message_find_media(const tsdp_message_t *self, const char* media) +{ + if(self && media){ + const tsk_list_item_t* item; + if((item = tsk_list_find_item_by_pred(self->headers, __pred_find_media_by_name, media))){ + return TSDP_HEADER_M(item->data); + } + } + return tsk_null; +} + + + +/* ================= 3GPP TS 34.610 :: Communication HOLD (HOLD) using IP Multimedia (IM) Core ================*/ +int tsdp_message_hold(tsdp_message_t* self, const char* media) +{ + tsdp_header_M_t* M; + const tsk_list_item_t* item; + + if(!self){ + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + // 3GPP TS 34.610-900 - 4.5.2.1 Actions at the invoking UE + if((item = tsk_list_find_item_by_pred(self->headers, __pred_find_media_by_name, media))){ + M = TSDP_HEADER_M(item->data); + tsdp_header_M_hold(M, tsk_true); + } + + return 0; +} + +int tsdp_message_resume(tsdp_message_t* self, const char* media) +{ + tsdp_header_M_t* M; + const tsk_list_item_t* item; + + if(!self){ + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + // 3GPP TS 34.610-900 - 4.5.2.1 Actions at the invoking UE + if((item = tsk_list_find_item_by_pred(self->headers, __pred_find_media_by_name, media))){ + M = TSDP_HEADER_M(item->data); + tsdp_header_M_resume(M, tsk_true); + } + + return 0; +} + +tsk_bool_t tsdp_message_is_ice_enabled(const tsdp_message_t *self, tsk_size_t media_index) +{ + if (self) { + const tsdp_header_A_t *A; + const tsdp_header_M_t *M; + tsk_bool_t have_ufrag = tsk_false, have_pwd = tsk_false, have_candidates = tsk_false; + tsk_size_t index0 = 0; + + // session level attributes + if ((A = tsdp_message_get_headerA(self, "ice-ufrag"))) { + have_ufrag = tsk_true; + } + if ((A = tsdp_message_get_headerA(self, "ice-pwd"))) { + have_pwd = tsk_true; + } + while ((M = (const tsdp_header_M_t*)tsdp_message_get_headerAt(self, tsdp_htype_M, index0))) { + if (index0 == media_index) { + if ((A = tsdp_header_M_findA(M, "ice-ufrag"))) { + have_ufrag = tsk_true; + } + if ((A = tsdp_header_M_findA(M, "ice-pwd"))) { + have_pwd = tsk_true; + } + have_candidates = (tsdp_header_M_findA_at(M, "candidate", 0) != tsk_null); + return have_ufrag && have_pwd && have_candidates; + } + ++index0; + } + } + return tsk_false; +} + +tsk_bool_t tsdp_message_is_ice_restart(const tsdp_message_t *self, tsk_size_t media_index) +{ + // https://tools.ietf.org/html/rfc5245#section-9.1.1.1 + if (self) { + const tsdp_header_C_t *C; + const tsdp_header_M_t *M; + tsk_size_t index0 = 0; + + // Session level + if ((C = (const tsdp_header_C_t*)tsdp_message_get_header(self, tsdp_htype_C)) && C->addr){ + if (tsk_striequals("0.0.0.0", C->addr)) { + return tsk_true; + } + } + // Media level + while ((M = (const tsdp_header_M_t*)tsdp_message_get_headerAt(self, tsdp_htype_M, index0))) { + if (index0 == media_index) { + return (M->C && M->C->addr && tsk_striequals("0.0.0.0", M->C->addr)); + } + ++index0; + } + } + return tsk_false; +} + + + + + + + + + + + + + +//================================================================================================= +// SDP object definition +// +static void* tsdp_message_ctor(void * self, va_list * app) +{ + tsdp_message_t *message = self; + if(message){ + message->headers = tsk_list_create(); + } + return self; +} + +static void* tsdp_message_dtor(void * self) +{ + tsdp_message_t *message = self; + if(message){ + TSK_OBJECT_SAFE_FREE(message->headers); + } + return self; +} + +static const tsk_object_def_t tsdp_message_def_s = +{ + sizeof(tsdp_message_t), + tsdp_message_ctor, + tsdp_message_dtor, + tsk_null, +}; +const tsk_object_def_t *tsdp_message_def_t = &tsdp_message_def_s; diff --git a/tinySDP/test/droid-makefile b/tinySDP/test/droid-makefile new file mode 100644 index 0000000..0eeee58 --- /dev/null +++ b/tinySDP/test/droid-makefile @@ -0,0 +1,28 @@ +APP := test + +CFLAGS := $(CFLAGS_COMMON) -I../include -I../../tinySAK/src +LDFLAGS := $(LDFLAGS_COMMON) -Wl,-Bsymbolic,--whole-archive -l$(PROJECT) -ltinySAK -Wl,--entry=main + +all: $(APP) + +OBJS += $(APP).o + +$(APP): $(OBJS) + $(CC) $(LDFLAGS) -o $@ $^ + +%.o: %.c + $(CC) -c $(INCLUDE) $(CFLAGS) $< -o $@ + +install: $(APP) + $(ANDROID_SDK_ROOT)/tools/adb push $(APP) $(EXEC_DIR)/$(APP) + $(ANDROID_SDK_ROOT)/tools/adb shell chmod 777 $(EXEC_DIR)/$(APP) + +run: + $(ANDROID_SDK_ROOT)/tools/adb shell $(EXEC_DIR)/$(APP) + +#dbg: +# $(MAKE) $(MAKEFILE) DEBUG="-g -DDEBUG" +# $(MAKE) $(MAKEFILE) install + +clean: + @rm -f $(OBJS) $(APP)
\ No newline at end of file diff --git a/tinySDP/test/stdafx.c b/tinySDP/test/stdafx.c new file mode 100644 index 0000000..4cc45f4 --- /dev/null +++ b/tinySDP/test/stdafx.c @@ -0,0 +1,25 @@ +/* +* Copyright (C) 2009 Mamadou Diop. +* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org> +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/tinySDP/test/stdafx.h b/tinySDP/test/stdafx.h new file mode 100644 index 0000000..baaf88a --- /dev/null +++ b/tinySDP/test/stdafx.h @@ -0,0 +1,40 @@ +/* +* Copyright (C) 2009 Mamadou Diop. +* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org> +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +#ifndef TEST_TSDP_STDAFX_H +#define TEST_TSDP_STDAFX_H + +#ifdef WIN32 +#include "targetver.h" +#endif + +#include <stdio.h> + +#if (defined(_WIN32) || defined(WIN32) || defined(_WIN32_WCE)) && !defined(__SYMBIAN32__) +#include <tchar.h> +#endif + + + +// TODO: reference additional headers your program requires here +#include <string.h> + +#endif /* TEST_TSDP_STDAFX_H */ diff --git a/tinySDP/test/targetver.h b/tinySDP/test/targetver.h new file mode 100644 index 0000000..722ae77 --- /dev/null +++ b/tinySDP/test/targetver.h @@ -0,0 +1,35 @@ +/* +* Copyright (C) 2009 Mamadou Diop. +* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org> +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +#ifndef TSDP_TEST_TARGETVER_H +#define TSDP_TEST_TARGETVER_H +// The following macros define the minimum required platform. The minimum required platform +// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run +// your application. The macros work by enabling all features available on platform versions up to and +// including the version specified. + +// Modify the following defines if you have to target a platform prior to the ones specified below. +// Refer to MSDN for the latest info on corresponding values for different platforms. +#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista. +#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif + +#endif /* TSDP_TEST_TARGETVER_H */ diff --git a/tinySDP/test/test.c b/tinySDP/test/test.c new file mode 100644 index 0000000..75ea2e1 --- /dev/null +++ b/tinySDP/test/test.c @@ -0,0 +1,70 @@ +/* +* Copyright (C) 2009 Mamadou Diop. +* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org> +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ + +#include "stdafx.h" + +#include "tsk.h" + +#include "tsdp.h" +#include "tinysdp/parsers/tsdp_parser_message.h" + + + + +#define RUN_TEST_LOOP 1 + +#define RUN_TEST_ALL 0 +#define RUN_TEST_PARSER 1 +#define RUN_TEST_SOA 0 +#define RUN_TEST_RFC5939 0 + +#include "test_parser.h" +#include "test_soa.h" +#if RUN_TEST_RFC5939 || RUN_TEST_PARSER +//#include "test_rfc5939.h" +#endif + + +#ifdef _WIN32_WCE +int _tmain(int argc, _TCHAR* argv[]) +#else +int main() +#endif +{ + do + { + /* Print copyright information */ + printf("Doubango Project\nCopyright (C) 2009 - 2010 Mamadou Diop \n\n"); + +#if RUN_TEST_ALL || RUN_TEST_PARSER + test_parser(); +#endif + +#if RUN_TEST_ALL || RUN_TEST_SOA + test_soa(); +#endif + +#if RUN_TEST_ALL || RUN_TEST_RFC5939 + test_rfc5939(); +#endif + + } while(RUN_TEST_LOOP); +} diff --git a/tinySDP/test/test.vcproj b/tinySDP/test/test.vcproj new file mode 100644 index 0000000..aa712a1 --- /dev/null +++ b/tinySDP/test/test.vcproj @@ -0,0 +1,223 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="test" + ProjectGUID="{4555F4A7-6DC7-4844-9F3F-6AAB4443D4E9}" + RootNamespace="test" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..\thirdparties\win32\include;"$(SolutionDir)\include";..\..\tinySAK\src" + PreprocessorDefinitions="DEBUG_LEVEL=DEBUG_LEVEL_INFO;WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + WarnAsError="true" + DebugInformationFormat="4" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="$(OutDir)\tinySAK.lib $(OutDir)\tinySDP.lib" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="2" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + WarnAsError="true" + DebugInformationFormat="3" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="sources" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\stdafx.c" + > + </File> + <File + RelativePath=".\test.c" + > + </File> + </Filter> + <Filter + Name="include" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath=".\stdafx.h" + > + </File> + <File + RelativePath=".\targetver.h" + > + </File> + </Filter> + <Filter + Name="tests" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + <File + RelativePath=".\test_parser.h" + > + </File> + <File + RelativePath=".\test_rfc5939.h" + > + </File> + <File + RelativePath=".\test_soa.h" + > + </File> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/tinySDP/test/test_parser.h b/tinySDP/test/test_parser.h new file mode 100644 index 0000000..e53677a --- /dev/null +++ b/tinySDP/test/test_parser.h @@ -0,0 +1,286 @@ +/* +* Copyright (C) 2009 Mamadou Diop. +* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org> +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ +#ifndef _TEST_SDPPARSER_H +#define _TEST_SDPPARSER_H + +#include "tinysdp/headers/tsdp_header_Dummy.h" +#include "tinysdp/headers/tsdp_header_A.h" +#include "tinysdp/headers/tsdp_header_C.h" +#include "tinysdp/headers/tsdp_header_E.h" +#include "tinysdp/headers/tsdp_header_I.h" +#include "tinysdp/headers/tsdp_header_P.h" + +#define SDP_MSG1 \ + "v=0\r\n" \ + "o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com\r\n" \ + "s=\r\n" \ + "i=A Seminar on the session description protocol\r\n" \ + "u=http://www.example.com/seminars/sdp.pdf\r\n" \ + "e=j.doe@example.com (Jane Doe)\r\n" \ + "p=+1 617 555-6011\r\n" \ + "c=IN IP4 host.atlanta.example.com\r\n" \ + "b=X-YZ:128\r\n" \ + "z=2882844526 -1h 2898848070 0\r\n" \ + "k=base64:ZWFzdXJlLg==\r\n" \ + "t=3034423619 3042462419\r\n" \ + "r=7d 1h 0 25h\r\n" \ + "r=604800 3600 0 90000\r\n" \ + "w=my dummy header\r\n" \ + "m=audio 49170 RTP/AVP 0 8 97 98\r\n" \ + "i=Audio line\r\n" \ + "c=IN IP4 otherhost.biloxi.example.com\r\n" \ + "k=base64:ZWFzdXJlLgdddddddddddddddddddddd==\r\n" \ + "a=rtpmap:0 PCMU/8000\r\n" \ + "a=rtpmap:8 PCMA/8000\r\n" \ + "a=rtpmap:97 iLBC/8000\r\n" \ + "a=rtpmap:98 AMR-WB/16000\r\n" \ + "a=fmtp:98 octet-align=1\r\n" \ + "m=video 51372 RTP/AVP 31 32\r\n" \ + "i=Video line\r\n" \ + "b=A-YZ:92\r\n" \ + "b=B-YZ:256\r\n" \ + "a=rtpmap:31 H261/90000\r\n" \ + "a=rtpmap:32 MPV/90000\r\n" \ + "a=recvonly\r\n" + +#define SDP_MSG2 \ + "v=0\r\n" + +#define SDP_MSG3 \ + "v=0\r\n" \ + "o=lgevcs 1 1 IN IP4 192.168.1.115\r\n" \ + "s=-\r\n" \ + "c=IN IP4 192.168.1.115\r\n" \ + "b=AS:512\r\n" \ + "t=0 0\r\n" \ + "m=audio 2000 RTP/AVP 9 8 0 101\r\n" \ + "a=rtpmap:9 G722/8000\r\n" \ + "a=rtpmap:8 PCMA/8000\r\n" \ + "a=rtpmap:0 PCMU/8000\r\n" \ + "a=rtpmap:101 telephone-event/8000\r\n" \ + "a=fmtp:101 0-11,16\r\n" \ + "a=sendrecv\r\n" \ + "m=video 2002 RTP/AVP 34\r\n" \ + "b=TIAS:512000\r\n" \ + "a=content:main\r\n" \ + "a=rtpmap:34 H263/90000\r\n" \ + "a=fmtp:34 CIF=2\r\n" \ + "a=sendrecv\r\n" + +#define SDP_FF \ + "v=0\r\no=Mozilla-SIPUA-33.1.1 21626 0 IN IP4 0.0.0.0\r\ns=SIP Call\r\nt=0 0\r\na=ice-ufrag:d0a7e7c7\r\na=ice-pwd:f079952b194bac309ea77ff813540eb0\r\na=fingerprint:sha-256 10:B9:12:6F:F3:21:6B:F4:53:E2:70:BA:13:A3:3A:3C:DF:3F:28:FD:6D:E4:09:A4:6F:EC:57:95:7D:83:3E:46\r\nm=video 59587 UDP/TLS/RTP/SAVPF 120 126 97\r\nc=IN IP4 188.165.231.30\r\na=rtpmap:120 VP8/90000\r\na=rtpmap:126 H264/90000\r\na=fmtp:126 profile-level-id=42e01f;packetization-mode=1\r\na=rtpmap:97 H264/90000\r\na=fmtp:97 profile-level-id=42e01f\r\na=sendrecv\r\na=rtcp-fb:120 nack\r\na=rtcp-fb:120 nack pli\r\na=rtcp-fb:120 ccm fir\r\na=rtcp-fb:126 nack\r\na=rtcp-fb:126 nack pli\r\na=rtcp-fb:126 ccm fir\r\na=rtcp-fb:97 nack\r\na=rtcp-fb:97 nack pli\r\na=rtcp-fb:97 ccm fir\r\na=setup:actpass\r\na=candidate:0 1 UDP 2130379007 192.168.0.28 60862 typ host\r\na=candidate:1 1 UDP 1694236671 88.179.39.5 60862 typ srflx raddr 192.168.0.28 rport 60862\r\na=candidate:2 1 UDP 16515071 188.165.231.30 59587 typ relay raddr 188.165.231.30 rport 59587\r\na=candidate:0 2 UDP 2130379006 192.168.0.28 61634 typ host\r\na=candidate:1 2 UDP 1694236670 88.179.39.5 61634 typ srflx raddr 192.168.0.28 rport 61634\r\na=candidate:2 2 UDP 16515070 188.165.231.30 62984 typ relay raddr 188.165.231.30 rport 62984\r\na=rtcp-mux\r\n" + +#define SDP_MSG_TO_TEST SDP_FF + +void test_caps(); +void test_holdresume(); +void test_M(); + +void test_parser() +{ + tsdp_message_t *message = tsk_null; + char* str; + + //test_caps(); + //test_holdresume(); + //test_M(); + + // + // deserialize/serialize the message + // + if((message = tsdp_message_parse(SDP_MSG_TO_TEST, strlen(SDP_MSG_TO_TEST)))){ + + /* serialize the message */ + if((str = tsdp_message_tostring(message))){ + TSK_DEBUG_INFO("SDP Message=\n%s", str); + TSK_FREE(str); + } + + TSK_OBJECT_SAFE_FREE(message); + } + else{ + TSK_DEBUG_ERROR("Failed to parse SDP message."); + } + + // + // create empty message + // + if((message = tsdp_message_create_empty("127.0.0.1", tsk_false, 1))){ + + /* add media */ + tsdp_message_add_media(message, "audio", 8956, "RTP/AVP", + TSDP_HEADER_I_VA_ARGS("this is the information line"), + + // pcmu + TSDP_FMT_VA_ARGS("0"), + TSDP_HEADER_A_VA_ARGS("rtpmap", "0 pcmu/8000"), + TSDP_HEADER_A_VA_ARGS("3gpp_sync_info", "No Sync"), + + // pcma + TSDP_FMT_VA_ARGS("8"), + TSDP_HEADER_A_VA_ARGS("rtpmap", "8 pcma/8000"), + + // telephone event + TSDP_FMT_VA_ARGS("101"), + TSDP_HEADER_A_VA_ARGS("rtpmap", "101 telephone-event/8000"), + TSDP_HEADER_A_VA_ARGS("fmtp", "101 0-11"), + + + // common values + TSDP_HEADER_A_VA_ARGS("sendrecv", tsk_null), + TSDP_HEADER_A_VA_ARGS("ptime", "20"), + + tsk_null); + + //tsdp_message_remove_media(message, "video"); + //tsdp_message_remove_media(message, "audio"); + + /* serialize the message */ + if((str = tsdp_message_tostring(message))){ + TSK_DEBUG_INFO("\n\nEmpty SDP Message=\n%s", str); + TSK_FREE(str); + } + + TSK_OBJECT_SAFE_FREE(message); + } +} + +void test_caps() +{ + tsdp_message_t *message = tsk_null; + char* str; + + if((message = tsdp_message_create_empty("100.3.6.6", tsk_false, 1))){ + + tsdp_message_add_headers(message, + TSDP_HEADER_C_VA_ARGS("IN", "IP4", "192.0.2.4"), + TSDP_HEADER_E_VA_ARGS("j.doe@example.com (Jane Doe)"), + TSDP_HEADER_P_VA_ARGS("+44 (123)456789"), + + tsk_null); + + /* add (audio) media */ + tsdp_message_add_media(message, "audio", 0, "RTP/AVP", + TSDP_HEADER_I_VA_ARGS("this is the (audio)information line"), + + // PCMU + TSDP_FMT_VA_ARGS("0"), + TSDP_HEADER_A_VA_ARGS("rtpmap", "0 PCMU/8000"), + + // 1016 + TSDP_FMT_VA_ARGS("1"), + TSDP_HEADER_A_VA_ARGS("rtpmap", "1 1016/8000"), + + // GSM + TSDP_FMT_VA_ARGS("3"), + TSDP_HEADER_A_VA_ARGS("rtpmap", "3 GSM/8000"), + + tsk_null); + + /* add (video) media */ + tsdp_message_add_media(message, "video", 0, "RTP/AVP", + TSDP_HEADER_I_VA_ARGS("this is the (video)information line"), + + // H261 + TSDP_FMT_VA_ARGS("31"), + TSDP_HEADER_A_VA_ARGS("rtpmap", "31 H261/90000"), + + // H263 + TSDP_FMT_VA_ARGS("34"), + TSDP_HEADER_A_VA_ARGS("rtpmap", "34 H263/90000"), + + tsk_null); + + /* serialize the message */ + if((str = tsdp_message_tostring(message))){ + TSK_DEBUG_INFO("\n\nCapabilities SDP Message=\n%s", str); + TSK_FREE(str); + } + + TSK_OBJECT_SAFE_FREE(message); + } +} + + +void test_holdresume() +{ + tsdp_message_t *message = tsk_null; + char* str; + + if((message = tsdp_message_parse(SDP_MSG_TO_TEST, strlen(SDP_MSG_TO_TEST)))){ + + // hold audio + tsdp_message_hold(message, "audio"); + tsdp_message_hold(message, "audio"); + tsdp_message_hold(message, "video"); + tsdp_message_resume(message, "video"); + + /* serialize the message */ + if((str = tsdp_message_tostring(message))){ + TSK_DEBUG_INFO("SDP Message=\n%s", str); + TSK_FREE(str); + } + + TSK_OBJECT_SAFE_FREE(message); + } + else{ + TSK_DEBUG_ERROR("Failed to parse SDP message."); + } +} + +void test_M() +{ + char* rtpmap, *fmtp; + const tsk_list_item_t* item; + const tsdp_header_M_t* M; + + tsdp_message_t *message = tsk_null; + + if((message = tsdp_message_parse(SDP_MSG_TO_TEST, strlen(SDP_MSG_TO_TEST)))){ + + tsk_list_foreach(item, message->headers){ + if(!(item->data) || (TSDP_HEADER(item->data)->type != tsdp_htype_M)){ + continue; + } + M = (const tsdp_header_M_t*)(item->data); + + /* get rtpmap */ + if((rtpmap = tsdp_header_M_get_rtpmap(M, "98"))){ + TSK_DEBUG_INFO("RTPMAP=%s", rtpmap); + TSK_FREE(rtpmap); + } + + /* get fmtp */ + if((fmtp = tsdp_header_M_get_fmtp(M, "98"))){ + TSK_DEBUG_INFO("FMTP=%s", fmtp); + TSK_FREE(fmtp); + } + } + + TSK_OBJECT_SAFE_FREE(message); + } + else{ + TSK_DEBUG_ERROR("Failed to parse SDP message."); + } + +} + +#endif /* _TEST_SDPPARSER_H */ diff --git a/tinySDP/test/test_soa.h b/tinySDP/test/test_soa.h new file mode 100644 index 0000000..e0dc150 --- /dev/null +++ b/tinySDP/test/test_soa.h @@ -0,0 +1,109 @@ +/* +* Copyright (C) 2009 Mamadou Diop. +* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org> +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO 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. +* +* DOUBANGO 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 DOUBANGO. +* +*/ +#ifndef _TEST_SOA_H +#define _TEST_SOA_H + +#define SDP \ + "v=0\r\n" \ + "o=carol 28908764872 28908764872 IN IP4 100.3.6.6\r\n" \ + "s=-\r\n" \ + "t=0 0\r\n" \ + "c=IN IP4 192.0.2.4\r\n" \ + "m=video 0 RTP/AVP 31 34\r\n" \ + "a=rtpmap:31 H261/90000\r\n" \ + "a=rtpmap:34 H263/90000\r\n" + + +void test_create_sdp() +{ + tsdp_ctx_handle_t* ctx = TSDP_CTX_CREATE(); + const tsdp_message_t* sdp; + char* str; + + // Create local SDP from string + tsdp_ctx_local_create_sdp_2(ctx, SDP, strlen(SDP)); + if((sdp = tsdp_ctx_local_get_sdp(ctx))){ + if((str = tsdp_message_tostring(sdp))){ + TSK_DEBUG_INFO("Local SDP (2)=\n%s", str); + TSK_FREE(str); + } + } + + // Create local SDP from object + tsdp_ctx_local_create_sdp(ctx, sdp); + if((sdp = tsdp_ctx_local_get_sdp(ctx))){ + if((str = tsdp_message_tostring(sdp))){ + TSK_DEBUG_INFO("Local SDP (1)=\n%s", str); + TSK_FREE(str); + } + } + + // Add media to the local sdp + tsdp_ctx_local_add_media_2(ctx, "audio", 0, "RTP/AVP", + TSDP_HEADER_I_VA_ARGS("this is the (audio)information line"), + + // PCMU + TSDP_FMT_VA_ARGS("0"), + TSDP_HEADER_A_VA_ARGS("rtpmap", "0 PCMU/8000"), + + // 1016 + TSDP_FMT_VA_ARGS("1"), + TSDP_HEADER_A_VA_ARGS("rtpmap", "1 1016/8000"), + + // GSM + TSDP_FMT_VA_ARGS("3"), + TSDP_HEADER_A_VA_ARGS("rtpmap", "3 GSM/8000"), + + tsk_null); + if((str = tsdp_message_tostring(sdp))){ + TSK_DEBUG_INFO("Local SDP (audio)=\n%s", str); + TSK_FREE(str); + } + + // Add headers to the local sdp + tsdp_ctx_local_add_headers(ctx, + TSDP_HEADER_E_VA_ARGS("j.doe@example.com (Jane Doe)"), + TSDP_HEADER_P_VA_ARGS("+44 (123)456789"), + + tsk_null); + if((str = tsdp_message_tostring(sdp))){ + TSK_DEBUG_INFO("Local SDP (headers)=\n%s", str); + TSK_FREE(str); + } + + + TSK_OBJECT_SAFE_FREE(ctx); +} + +void test_soa() +{ + test_create_sdp(); +} + + + + + + + + + +#endif /* _TEST_SOA_H */ diff --git a/tinySDP/tinySDP.pc.in b/tinySDP/tinySDP.pc.in new file mode 100644 index 0000000..8731989 --- /dev/null +++ b/tinySDP/tinySDP.pc.in @@ -0,0 +1,14 @@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ +libdir = @libdir@ +includedir = @includedir@ + +Name : libtinySDP +Description : Doubango Telecom tinySDP (SDP protocol) library +Version : @PACKAGE_VERSION@ +Requires: +Requires.private: tinySAK = @PACKAGE_VERSION@ +Conflicts: +Cflags : -I${includedir}/tinysdp +Libs : -L${libdir} -ltinySDP +Libs.private: diff --git a/tinySDP/tinySDP.sln b/tinySDP/tinySDP.sln new file mode 100644 index 0000000..37b049e --- /dev/null +++ b/tinySDP/tinySDP.sln @@ -0,0 +1,51 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tinySDP", "tinySDP.vcproj", "{E45DB518-6562-4033-80E8-60030F0B169F}" + ProjectSection(ProjectDependencies) = postProject + {6BC9B796-10C6-4CF7-A6E4-E2DACCDA84DA} = {6BC9B796-10C6-4CF7-A6E4-E2DACCDA84DA} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tinySAK", "..\tinySAK\tinySAK.vcproj", "{6BC9B796-10C6-4CF7-A6E4-E2DACCDA84DA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test\test.vcproj", "{4555F4A7-6DC7-4844-9F3F-6AAB4443D4E9}" + ProjectSection(ProjectDependencies) = postProject + {E45DB518-6562-4033-80E8-60030F0B169F} = {E45DB518-6562-4033-80E8-60030F0B169F} + {6BC9B796-10C6-4CF7-A6E4-E2DACCDA84DA} = {6BC9B796-10C6-4CF7-A6E4-E2DACCDA84DA} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) = Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + Release|Win32 = Release|Win32 + Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) = Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E45DB518-6562-4033-80E8-60030F0B169F}.Debug|Win32.ActiveCfg = Debug|Win32 + {E45DB518-6562-4033-80E8-60030F0B169F}.Debug|Win32.Build.0 = Debug|Win32 + {E45DB518-6562-4033-80E8-60030F0B169F}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {E45DB518-6562-4033-80E8-60030F0B169F}.Release|Win32.ActiveCfg = Release|Win32 + {E45DB518-6562-4033-80E8-60030F0B169F}.Release|Win32.Build.0 = Release|Win32 + {E45DB518-6562-4033-80E8-60030F0B169F}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Win32 + {6BC9B796-10C6-4CF7-A6E4-E2DACCDA84DA}.Debug|Win32.ActiveCfg = Debug|Win32 + {6BC9B796-10C6-4CF7-A6E4-E2DACCDA84DA}.Debug|Win32.Build.0 = Debug|Win32 + {6BC9B796-10C6-4CF7-A6E4-E2DACCDA84DA}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {6BC9B796-10C6-4CF7-A6E4-E2DACCDA84DA}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {6BC9B796-10C6-4CF7-A6E4-E2DACCDA84DA}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Deploy.0 = Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {6BC9B796-10C6-4CF7-A6E4-E2DACCDA84DA}.Release|Win32.ActiveCfg = Release|Win32 + {6BC9B796-10C6-4CF7-A6E4-E2DACCDA84DA}.Release|Win32.Build.0 = Release|Win32 + {6BC9B796-10C6-4CF7-A6E4-E2DACCDA84DA}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {6BC9B796-10C6-4CF7-A6E4-E2DACCDA84DA}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {6BC9B796-10C6-4CF7-A6E4-E2DACCDA84DA}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Deploy.0 = Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {4555F4A7-6DC7-4844-9F3F-6AAB4443D4E9}.Debug|Win32.ActiveCfg = Debug|Win32 + {4555F4A7-6DC7-4844-9F3F-6AAB4443D4E9}.Debug|Win32.Build.0 = Debug|Win32 + {4555F4A7-6DC7-4844-9F3F-6AAB4443D4E9}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {4555F4A7-6DC7-4844-9F3F-6AAB4443D4E9}.Release|Win32.ActiveCfg = Release|Win32 + {4555F4A7-6DC7-4844-9F3F-6AAB4443D4E9}.Release|Win32.Build.0 = Release|Win32 + {4555F4A7-6DC7-4844-9F3F-6AAB4443D4E9}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/tinySDP/tinySDP.vcproj b/tinySDP/tinySDP.vcproj new file mode 100644 index 0000000..fa15c8d --- /dev/null +++ b/tinySDP/tinySDP.vcproj @@ -0,0 +1,472 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="tinySDP" + ProjectGUID="{E45DB518-6562-4033-80E8-60030F0B169F}" + RootNamespace="tinySDP" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="2" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories=""..\thirdparties\win32\include";"..\tinySAK\src";"..\tinySDP\include"" + PreprocessorDefinitions="DEBUG_LEVEL=DEBUG_LEVEL_INFO;WIN32;_DEBUG;_WINDOWS;_USRDLL;TINYSDP_EXPORTS" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + WarnAsError="true" + DebugInformationFormat="4" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="$(OutDir)\tinySAK.lib" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="2" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories=""..\thirdparties\win32\include";"..\tinySAK\src";"..\tinySDP\include"" + PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;TINYSDP_EXPORTS" + RuntimeLibrary="2" + EnableFunctionLevelLinking="false" + UsePrecompiledHeader="0" + WarningLevel="3" + WarnAsError="true" + DebugInformationFormat="3" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="$(OutDir)\tinySAK.lib" + LinkIncremental="1" + IgnoreDefaultLibraryNames="MSVCRTD" + GenerateDebugInformation="false" + SubSystem="2" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="source(*.c)" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\src\tsdp.c" + > + </File> + <File + RelativePath=".\src\tsdp_message.c" + > + </File> + <Filter + Name="headers" + > + <File + RelativePath=".\src\headers\tsdp_header.c" + > + </File> + <File + RelativePath=".\src\headers\tsdp_header_A.c" + > + </File> + <File + RelativePath=".\src\headers\tsdp_header_B.c" + > + </File> + <File + RelativePath=".\src\headers\tsdp_header_C.c" + > + </File> + <File + RelativePath=".\src\headers\tsdp_header_Dummy.c" + > + </File> + <File + RelativePath=".\src\headers\tsdp_header_E.c" + > + </File> + <File + RelativePath=".\src\headers\tsdp_header_I.c" + > + </File> + <File + RelativePath=".\src\headers\tsdp_header_K.c" + > + </File> + <File + RelativePath=".\src\headers\tsdp_header_M.c" + > + </File> + <File + RelativePath=".\src\headers\tsdp_header_O.c" + > + </File> + <File + RelativePath=".\src\headers\tsdp_header_P.c" + > + </File> + <File + RelativePath=".\src\headers\tsdp_header_R.c" + > + </File> + <File + RelativePath=".\src\headers\tsdp_header_S.c" + > + </File> + <File + RelativePath=".\src\headers\tsdp_header_T.c" + > + </File> + <File + RelativePath=".\src\headers\tsdp_header_U.c" + > + </File> + <File + RelativePath=".\src\headers\tsdp_header_V.c" + > + </File> + <File + RelativePath=".\src\headers\tsdp_header_Z.c" + > + </File> + </Filter> + <Filter + Name="parsers" + > + <File + RelativePath=".\src\parsers\tsdp_parser_message.c" + > + </File> + </Filter> + </Filter> + <Filter + Name="include(*.h)" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath=".\include\tinysdp.h" + > + </File> + <File + RelativePath=".\include\tinysdp_config.h" + > + </File> + <File + RelativePath=".\include\tsdp.h" + > + </File> + <File + RelativePath=".\include\tinySDP\tsdp_message.h" + > + </File> + <Filter + Name="headers" + > + <File + RelativePath=".\include\tinySDP\headers\tsdp_header.h" + > + </File> + <File + RelativePath=".\include\tinySDP\headers\tsdp_header_A.h" + > + </File> + <File + RelativePath=".\include\tinySDP\headers\tsdp_header_B.h" + > + </File> + <File + RelativePath=".\include\tinySDP\headers\tsdp_header_C.h" + > + </File> + <File + RelativePath=".\include\tinySDP\headers\tsdp_header_Dummy.h" + > + </File> + <File + RelativePath=".\include\tinySDP\headers\tsdp_header_E.h" + > + </File> + <File + RelativePath=".\include\tinySDP\headers\tsdp_header_I.h" + > + </File> + <File + RelativePath=".\include\tinySDP\headers\tsdp_header_K.h" + > + </File> + <File + RelativePath=".\include\tinySDP\headers\tsdp_header_M.h" + > + </File> + <File + RelativePath=".\include\tinySDP\headers\tsdp_header_O.h" + > + </File> + <File + RelativePath=".\include\tinySDP\headers\tsdp_header_P.h" + > + </File> + <File + RelativePath=".\include\tinySDP\headers\tsdp_header_R.h" + > + </File> + <File + RelativePath=".\include\tinySDP\headers\tsdp_header_S.h" + > + </File> + <File + RelativePath=".\include\tinySDP\headers\tsdp_header_T.h" + > + </File> + <File + RelativePath=".\include\tinySDP\headers\tsdp_header_U.h" + > + </File> + <File + RelativePath=".\include\tinySDP\headers\tsdp_header_V.h" + > + </File> + <File + RelativePath=".\include\tinySDP\headers\tsdp_header_Z.h" + > + </File> + </Filter> + <Filter + Name="parsers" + > + <File + RelativePath=".\include\tinySDP\parsers\tsdp_parser_header.h" + > + </File> + <File + RelativePath=".\include\tinySDP\parsers\tsdp_parser_message.h" + > + </File> + </Filter> + </Filter> + <Filter + Name="ragel(*.rl)" + > + <File + RelativePath=".\ragel\tsdp_machine_utils.rl" + > + </File> + <File + RelativePath=".\ragel\tsdp_parser_header_A.rl" + > + </File> + <File + RelativePath=".\ragel\tsdp_parser_header_B.rl" + > + </File> + <File + RelativePath=".\ragel\tsdp_parser_header_C.rl" + > + </File> + <File + RelativePath=".\ragel\tsdp_parser_header_Dummy.rl" + > + </File> + <File + RelativePath=".\ragel\tsdp_parser_header_E.rl" + > + </File> + <File + RelativePath=".\ragel\tsdp_parser_header_I.rl" + > + </File> + <File + RelativePath=".\ragel\tsdp_parser_header_K.rl" + > + </File> + <File + RelativePath=".\ragel\tsdp_parser_header_M.rl" + > + </File> + <File + RelativePath=".\ragel\tsdp_parser_header_O.rl" + > + </File> + <File + RelativePath=".\ragel\tsdp_parser_header_P.rl" + > + </File> + <File + RelativePath=".\ragel\tsdp_parser_header_R.rl" + > + </File> + <File + RelativePath=".\ragel\tsdp_parser_header_S.rl" + > + </File> + <File + RelativePath=".\ragel\tsdp_parser_header_T.rl" + > + </File> + <File + RelativePath=".\ragel\tsdp_parser_header_U.rl" + > + </File> + <File + RelativePath=".\ragel\tsdp_parser_header_V.rl" + > + </File> + <File + RelativePath=".\ragel\tsdp_parser_header_Z.rl" + > + </File> + <File + RelativePath=".\ragel\tsdp_parser_message.rl" + > + </File> + </Filter> + <Filter + Name="abnf(*.abnf)" + > + <File + RelativePath=".\abnf\sdp.abnf" + > + </File> + </Filter> + <Filter + Name="resources(*.rc)" + > + <File + RelativePath=".\version.rc" + > + </File> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/tinySDP/version.rc b/tinySDP/version.rc new file mode 100644 index 0000000..8b4671c --- /dev/null +++ b/tinySDP/version.rc @@ -0,0 +1,102 @@ +// Microsoft Visual C++ generated resource script. +// +// #include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 2.0.0.1156 + PRODUCTVERSION 2.0.0.1156 + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "Doubango telecom" + VALUE "FileDescription", "Doubango IMS Framework" + VALUE "FileVersion", "2.0.0.1156" + VALUE "InternalName", "tinysdp.dll" + VALUE "LegalCopyright", "(c) 2010-2013 Doubango Telecom. All rights reserved." + VALUE "OriginalFilename", "tinysdp.dll" + VALUE "ProductName", "Doubango IMS Framework" + VALUE "ProductVersion", "2.0.0.1156" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/tinySDP/winrt/tinySDP.sln b/tinySDP/winrt/tinySDP.sln new file mode 100644 index 0000000..6705947 --- /dev/null +++ b/tinySDP/winrt/tinySDP.sln @@ -0,0 +1,39 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Express 2012 for Windows Phone +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tinySDP", "tinySDP.vcxproj", "{982D737A-0649-4C32-A00E-08992A0B7673}" + ProjectSection(ProjectDependencies) = postProject + {19279F5B-CDAF-4187-9F09-2A896A828B05} = {19279F5B-CDAF-4187-9F09-2A896A828B05} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tinySAK", "..\..\tinySAK\winrt\tinySAK.vcxproj", "{19279F5B-CDAF-4187-9F09-2A896A828B05}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Debug|Win32 = Debug|Win32 + Release|ARM = Release|ARM + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {982D737A-0649-4C32-A00E-08992A0B7673}.Debug|ARM.ActiveCfg = Debug|ARM + {982D737A-0649-4C32-A00E-08992A0B7673}.Debug|ARM.Build.0 = Debug|ARM + {982D737A-0649-4C32-A00E-08992A0B7673}.Debug|Win32.ActiveCfg = Debug|Win32 + {982D737A-0649-4C32-A00E-08992A0B7673}.Debug|Win32.Build.0 = Debug|Win32 + {982D737A-0649-4C32-A00E-08992A0B7673}.Release|ARM.ActiveCfg = Release|ARM + {982D737A-0649-4C32-A00E-08992A0B7673}.Release|ARM.Build.0 = Release|ARM + {982D737A-0649-4C32-A00E-08992A0B7673}.Release|Win32.ActiveCfg = Release|Win32 + {982D737A-0649-4C32-A00E-08992A0B7673}.Release|Win32.Build.0 = Release|Win32 + {19279F5B-CDAF-4187-9F09-2A896A828B05}.Debug|ARM.ActiveCfg = Debug|ARM + {19279F5B-CDAF-4187-9F09-2A896A828B05}.Debug|ARM.Build.0 = Debug|ARM + {19279F5B-CDAF-4187-9F09-2A896A828B05}.Debug|Win32.ActiveCfg = Debug|Win32 + {19279F5B-CDAF-4187-9F09-2A896A828B05}.Debug|Win32.Build.0 = Debug|Win32 + {19279F5B-CDAF-4187-9F09-2A896A828B05}.Release|ARM.ActiveCfg = Release|ARM + {19279F5B-CDAF-4187-9F09-2A896A828B05}.Release|ARM.Build.0 = Release|ARM + {19279F5B-CDAF-4187-9F09-2A896A828B05}.Release|Win32.ActiveCfg = Release|Win32 + {19279F5B-CDAF-4187-9F09-2A896A828B05}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/tinySDP/winrt/tinySDP.vcxproj b/tinySDP/winrt/tinySDP.vcxproj new file mode 100644 index 0000000..59f4670 --- /dev/null +++ b/tinySDP/winrt/tinySDP.vcxproj @@ -0,0 +1,206 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{982d737a-0649-4c32-a00e-08992a0b7673}</ProjectGuid> + <RootNamespace>tinySDP</RootNamespace> + <DefaultLanguage>en-US</DefaultLanguage> + <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v110_wp80</PlatformToolset> + <IgnoreImportLibrary>false</IgnoreImportLibrary> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v110_wp80</PlatformToolset> + <IgnoreImportLibrary>false</IgnoreImportLibrary> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <PlatformToolset>v110_wp80</PlatformToolset> + <IgnoreImportLibrary>false</IgnoreImportLibrary> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <PlatformToolset>v110_wp80</PlatformToolset> + <IgnoreImportLibrary>false</IgnoreImportLibrary> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>$(SolutionDir)$(Configuration)\$(MSBuildProjectName)\</OutDir> + <IntDir>$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>$(SolutionDir)$(Configuration)\$(MSBuildProjectName)\</OutDir> + <IntDir>$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> + <OutDir>$(SolutionDir)$(Configuration)\$(MSBuildProjectName)\</OutDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> + <OutDir>$(SolutionDir)$(Configuration)\$(MSBuildProjectName)\</OutDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PreprocessorDefinitions>DEBUG_LEVEL=DEBUG_LEVEL_INFO;_USRDLL;TINYSDP_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <PrecompiledHeaderFile> + </PrecompiledHeaderFile> + <CompileAsWinRT>false</CompileAsWinRT> + <AdditionalUsingDirectories>$(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories)</AdditionalUsingDirectories> + <AdditionalIncludeDirectories>..\..\thirdparties\winrt\include;..\..\tinySAK\src;..\include</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>"$(SolutionDir)$(Configuration)\tinySAK\tinySAK.lib";%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <PreprocessorDefinitions>DEBUG_LEVEL=DEBUG_LEVEL_INFO;_USRDLL;TINYSDP_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> + <CompileAsWinRT>false</CompileAsWinRT> + <AdditionalUsingDirectories>$(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories)</AdditionalUsingDirectories> + <AdditionalIncludeDirectories>..\..\thirdparties\winrt\include;..\..\tinySAK\src;..\include</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>"$(SolutionDir)$(Configuration)\tinySAK\tinySAK.lib";%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> + <ClCompile> + <PreprocessorDefinitions>DEBUG_LEVEL=DEBUG_LEVEL_INFO;_USRDLL;TINYSDP_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <PrecompiledHeaderFile> + </PrecompiledHeaderFile> + <CompileAsWinRT>false</CompileAsWinRT> + <AdditionalUsingDirectories>$(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories)</AdditionalUsingDirectories> + <AdditionalIncludeDirectories>..\..\thirdparties\winrt\include;..\..\tinySAK\src;..\include</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>"$(SolutionDir)$(Configuration)\tinySAK\tinySAK.lib";%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> + <ClCompile> + <PreprocessorDefinitions>DEBUG_LEVEL=DEBUG_LEVEL_INFO;_USRDLL;TINYSDP_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> + <CompileAsWinRT>false</CompileAsWinRT> + <AdditionalUsingDirectories>$(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories)</AdditionalUsingDirectories> + <AdditionalIncludeDirectories>..\..\thirdparties\winrt\include;..\..\tinySAK\src;..\include</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>"$(SolutionDir)$(Configuration)\tinySAK\tinySAK.lib";%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <Reference Include="Windows"> + <IsWinMDFile>true</IsWinMDFile> + </Reference> + <Reference Include="platform.winmd"> + <IsWinMDFile>true</IsWinMDFile> + <Private>false</Private> + </Reference> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\src\headers\tsdp_header.c" /> + <ClCompile Include="..\src\headers\tsdp_header_A.c" /> + <ClCompile Include="..\src\headers\tsdp_header_B.c" /> + <ClCompile Include="..\src\headers\tsdp_header_C.c" /> + <ClCompile Include="..\src\headers\tsdp_header_Dummy.c" /> + <ClCompile Include="..\src\headers\tsdp_header_E.c" /> + <ClCompile Include="..\src\headers\tsdp_header_I.c" /> + <ClCompile Include="..\src\headers\tsdp_header_K.c" /> + <ClCompile Include="..\src\headers\tsdp_header_M.c" /> + <ClCompile Include="..\src\headers\tsdp_header_O.c" /> + <ClCompile Include="..\src\headers\tsdp_header_P.c" /> + <ClCompile Include="..\src\headers\tsdp_header_R.c" /> + <ClCompile Include="..\src\headers\tsdp_header_S.c" /> + <ClCompile Include="..\src\headers\tsdp_header_T.c" /> + <ClCompile Include="..\src\headers\tsdp_header_U.c" /> + <ClCompile Include="..\src\headers\tsdp_header_V.c" /> + <ClCompile Include="..\src\headers\tsdp_header_Z.c" /> + <ClCompile Include="..\src\parsers\tsdp_parser_message.c" /> + <ClCompile Include="..\src\tsdp.c" /> + <ClCompile Include="..\src\tsdp_message.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\include\tinysdp.h" /> + <ClInclude Include="..\include\tinysdp\headers\tsdp_header.h" /> + <ClInclude Include="..\include\tinysdp\headers\tsdp_header_A.h" /> + <ClInclude Include="..\include\tinysdp\headers\tsdp_header_B.h" /> + <ClInclude Include="..\include\tinysdp\headers\tsdp_header_C.h" /> + <ClInclude Include="..\include\tinysdp\headers\tsdp_header_Dummy.h" /> + <ClInclude Include="..\include\tinysdp\headers\tsdp_header_E.h" /> + <ClInclude Include="..\include\tinysdp\headers\tsdp_header_I.h" /> + <ClInclude Include="..\include\tinysdp\headers\tsdp_header_K.h" /> + <ClInclude Include="..\include\tinysdp\headers\tsdp_header_M.h" /> + <ClInclude Include="..\include\tinysdp\headers\tsdp_header_O.h" /> + <ClInclude Include="..\include\tinysdp\headers\tsdp_header_P.h" /> + <ClInclude Include="..\include\tinysdp\headers\tsdp_header_R.h" /> + <ClInclude Include="..\include\tinysdp\headers\tsdp_header_S.h" /> + <ClInclude Include="..\include\tinysdp\headers\tsdp_header_T.h" /> + <ClInclude Include="..\include\tinysdp\headers\tsdp_header_U.h" /> + <ClInclude Include="..\include\tinysdp\headers\tsdp_header_V.h" /> + <ClInclude Include="..\include\tinysdp\headers\tsdp_header_Z.h" /> + <ClInclude Include="..\include\tinysdp\parsers\tsdp_parser_header.h" /> + <ClInclude Include="..\include\tinysdp\parsers\tsdp_parser_message.h" /> + <ClInclude Include="..\include\tinysdp\tsdp_message.h" /> + <ClInclude Include="..\include\tinysdp_config.h" /> + <ClInclude Include="..\include\tsdp.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsPhone\v$(TargetPlatformVersion)\Microsoft.Cpp.WindowsPhone.$(TargetPlatformVersion).targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tinySDP/winrt/tinySDP.vcxproj.filters b/tinySDP/winrt/tinySDP.vcxproj.filters new file mode 100644 index 0000000..05ec6cd --- /dev/null +++ b/tinySDP/winrt/tinySDP.vcxproj.filters @@ -0,0 +1,163 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + <Filter Include="include"> + <UniqueIdentifier>{6c2faa44-5090-44b2-91e6-7ce9f6fd9a02}</UniqueIdentifier> + </Filter> + <Filter Include="source"> + <UniqueIdentifier>{5cd1b5d6-dc8a-4af0-812f-759f106f3866}</UniqueIdentifier> + </Filter> + <Filter Include="include\tinysdp"> + <UniqueIdentifier>{8e666991-781a-484c-b418-f459aebe9f07}</UniqueIdentifier> + </Filter> + <Filter Include="include\tinysdp\headers"> + <UniqueIdentifier>{bef68431-49a9-480b-9ffb-b874fdcc2bae}</UniqueIdentifier> + </Filter> + <Filter Include="include\tinysdp\parsers"> + <UniqueIdentifier>{342545e6-db3c-4de2-8893-975a82c6345c}</UniqueIdentifier> + </Filter> + <Filter Include="source\headers"> + <UniqueIdentifier>{41f36a8f-315b-4cf6-80b0-e4ef5f321d7f}</UniqueIdentifier> + </Filter> + <Filter Include="source\parsers"> + <UniqueIdentifier>{0bbe2e42-02e7-4259-8519-a75cb32c121d}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\src\tsdp.c"> + <Filter>source</Filter> + </ClCompile> + <ClCompile Include="..\src\tsdp_message.c"> + <Filter>source</Filter> + </ClCompile> + <ClCompile Include="..\src\headers\tsdp_header.c"> + <Filter>source\headers</Filter> + </ClCompile> + <ClCompile Include="..\src\headers\tsdp_header_A.c"> + <Filter>source\headers</Filter> + </ClCompile> + <ClCompile Include="..\src\headers\tsdp_header_B.c"> + <Filter>source\headers</Filter> + </ClCompile> + <ClCompile Include="..\src\headers\tsdp_header_C.c"> + <Filter>source\headers</Filter> + </ClCompile> + <ClCompile Include="..\src\headers\tsdp_header_Dummy.c"> + <Filter>source\headers</Filter> + </ClCompile> + <ClCompile Include="..\src\headers\tsdp_header_E.c"> + <Filter>source\headers</Filter> + </ClCompile> + <ClCompile Include="..\src\headers\tsdp_header_I.c"> + <Filter>source\headers</Filter> + </ClCompile> + <ClCompile Include="..\src\headers\tsdp_header_K.c"> + <Filter>source\headers</Filter> + </ClCompile> + <ClCompile Include="..\src\headers\tsdp_header_M.c"> + <Filter>source\headers</Filter> + </ClCompile> + <ClCompile Include="..\src\headers\tsdp_header_O.c"> + <Filter>source\headers</Filter> + </ClCompile> + <ClCompile Include="..\src\headers\tsdp_header_P.c"> + <Filter>source\headers</Filter> + </ClCompile> + <ClCompile Include="..\src\headers\tsdp_header_R.c"> + <Filter>source\headers</Filter> + </ClCompile> + <ClCompile Include="..\src\headers\tsdp_header_S.c"> + <Filter>source\headers</Filter> + </ClCompile> + <ClCompile Include="..\src\headers\tsdp_header_T.c"> + <Filter>source\headers</Filter> + </ClCompile> + <ClCompile Include="..\src\headers\tsdp_header_U.c"> + <Filter>source\headers</Filter> + </ClCompile> + <ClCompile Include="..\src\headers\tsdp_header_V.c"> + <Filter>source\headers</Filter> + </ClCompile> + <ClCompile Include="..\src\headers\tsdp_header_Z.c"> + <Filter>source\headers</Filter> + </ClCompile> + <ClCompile Include="..\src\parsers\tsdp_parser_message.c"> + <Filter>source\parsers</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\include\tinysdp.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="..\include\tinysdp_config.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="..\include\tsdp.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="..\include\tinysdp\tsdp_message.h"> + <Filter>include\tinysdp</Filter> + </ClInclude> + <ClInclude Include="..\include\tinysdp\headers\tsdp_header.h"> + <Filter>include\tinysdp\headers</Filter> + </ClInclude> + <ClInclude Include="..\include\tinysdp\headers\tsdp_header_A.h"> + <Filter>include\tinysdp\headers</Filter> + </ClInclude> + <ClInclude Include="..\include\tinysdp\headers\tsdp_header_B.h"> + <Filter>include\tinysdp\headers</Filter> + </ClInclude> + <ClInclude Include="..\include\tinysdp\headers\tsdp_header_C.h"> + <Filter>include\tinysdp\headers</Filter> + </ClInclude> + <ClInclude Include="..\include\tinysdp\headers\tsdp_header_Dummy.h"> + <Filter>include\tinysdp\headers</Filter> + </ClInclude> + <ClInclude Include="..\include\tinysdp\headers\tsdp_header_E.h"> + <Filter>include\tinysdp\headers</Filter> + </ClInclude> + <ClInclude Include="..\include\tinysdp\headers\tsdp_header_I.h"> + <Filter>include\tinysdp\headers</Filter> + </ClInclude> + <ClInclude Include="..\include\tinysdp\headers\tsdp_header_K.h"> + <Filter>include\tinysdp\headers</Filter> + </ClInclude> + <ClInclude Include="..\include\tinysdp\headers\tsdp_header_M.h"> + <Filter>include\tinysdp\headers</Filter> + </ClInclude> + <ClInclude Include="..\include\tinysdp\headers\tsdp_header_O.h"> + <Filter>include\tinysdp\headers</Filter> + </ClInclude> + <ClInclude Include="..\include\tinysdp\headers\tsdp_header_P.h"> + <Filter>include\tinysdp\headers</Filter> + </ClInclude> + <ClInclude Include="..\include\tinysdp\headers\tsdp_header_R.h"> + <Filter>include\tinysdp\headers</Filter> + </ClInclude> + <ClInclude Include="..\include\tinysdp\headers\tsdp_header_S.h"> + <Filter>include\tinysdp\headers</Filter> + </ClInclude> + <ClInclude Include="..\include\tinysdp\headers\tsdp_header_T.h"> + <Filter>include\tinysdp\headers</Filter> + </ClInclude> + <ClInclude Include="..\include\tinysdp\headers\tsdp_header_U.h"> + <Filter>include\tinysdp\headers</Filter> + </ClInclude> + <ClInclude Include="..\include\tinysdp\headers\tsdp_header_V.h"> + <Filter>include\tinysdp\headers</Filter> + </ClInclude> + <ClInclude Include="..\include\tinysdp\headers\tsdp_header_Z.h"> + <Filter>include\tinysdp\headers</Filter> + </ClInclude> + <ClInclude Include="..\include\tinysdp\parsers\tsdp_parser_header.h"> + <Filter>include\tinysdp\parsers</Filter> + </ClInclude> + <ClInclude Include="..\include\tinysdp\parsers\tsdp_parser_message.h"> + <Filter>include\tinysdp\parsers</Filter> + </ClInclude> + </ItemGroup> +</Project>
\ No newline at end of file |