Asterisk - The Open Source Telephony Project GIT-master-a358458
res_format_attr_ilbc.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 2016, Alexander Traud
5 *
6 * Alexander Traud <pabstraud@compuserve.com>
7 *
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
13 *
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
17 */
18
19/*!
20 * \file
21 * \brief iLBC format attribute interface
22 *
23 * \author Alexander Traud <pabstraud@compuserve.com>
24 *
25 * \note http://tools.ietf.org/html/rfc3952
26 */
27
28/*** MODULEINFO
29 <support_level>core</support_level>
30 ***/
31
32#include "asterisk.h"
33
34#include <ctype.h> /* for tolower */
35
36#include "asterisk/module.h"
37#include "asterisk/format.h"
38#include "asterisk/strings.h" /* for ast_str_append */
39#include "asterisk/utils.h" /* for ast_free */
40
41#include "asterisk/ilbc.h"
42
44 .mode = 20,
45};
46
47static void ilbc_destroy(struct ast_format *format)
48{
49 struct ilbc_attr *attr = ast_format_get_attribute_data(format);
50
51 ast_free(attr);
52}
53
54static int ilbc_clone(const struct ast_format *src, struct ast_format *dst)
55{
56 struct ilbc_attr *original = ast_format_get_attribute_data(src);
57 struct ilbc_attr *attr = ast_malloc(sizeof(*attr));
58
59 if (!attr) {
60 return -1;
61 }
62
63 if (original) {
64 *attr = *original;
65 } else {
66 *attr = default_ilbc_attr;
67 }
68
70
71 return 0;
72}
73
74static struct ast_format *ilbc_parse_sdp_fmtp(const struct ast_format *format, const char *attributes)
75{
76 char *attribs = ast_strdupa(attributes), *attrib;
77 struct ast_format *cloned;
78 struct ilbc_attr *attr;
79 const char *kvp;
80 unsigned int val;
81
82 cloned = ast_format_clone(format);
83 if (!cloned) {
84 return NULL;
85 }
86 attr = ast_format_get_attribute_data(cloned);
87
88 /* lower-case everything, so we are case-insensitive */
89 for (attrib = attribs; *attrib; ++attrib) {
90 *attrib = tolower(*attrib);
91 } /* based on channels/chan_sip.c:process_a_sdp_image() */
92
93 if ((kvp = strstr(attribs, "mode")) && sscanf(kvp, "mode=%30u", &val) == 1) {
94 attr->mode = val;
95 } else {
96 attr->mode = 30; /* optional attribute; 30 is default value */
97 }
98
99 return cloned;
100}
101
102static void ilbc_generate_sdp_fmtp(const struct ast_format *format, unsigned int payload, struct ast_str **str)
103{
104 struct ilbc_attr *attr = ast_format_get_attribute_data(format);
105
106 if (!attr) {
107 attr = &default_ilbc_attr;
108 }
109
110 /* When the VoIP/SIP client Zoiper calls Asterisk and its
111 * iLBC 20 is disabled but iLBC 30 enabled, Zoiper still
112 * falls back to iLBC 20, when there is no mode=30 in the
113 * answer. Consequently, Zoiper defaults to iLBC 20. To
114 * make that client happy, Asterisk sends mode always.
115 * tested in June 2016, Zoiper Premium 1.13.2 for iPhone
116 */
117 /* if (attr->mode != 30) */ {
118 ast_str_append(str, 0, "a=fmtp:%u mode=%u\r\n", payload, attr->mode);
119 }
120}
121
122static struct ast_format *ilbc_getjoint(const struct ast_format *format1, const struct ast_format *format2)
123{
124 struct ast_format *jointformat;
125 struct ilbc_attr *attr1 = ast_format_get_attribute_data(format1);
126 struct ilbc_attr *attr2 = ast_format_get_attribute_data(format2);
127 struct ilbc_attr *attr_res;
128
129 if (!attr1) {
130 attr1 = &default_ilbc_attr;
131 }
132
133 if (!attr2) {
134 attr2 = &default_ilbc_attr;
135 }
136
137 jointformat = ast_format_clone(format1);
138 if (!jointformat) {
139 return NULL;
140 }
141 attr_res = ast_format_get_attribute_data(jointformat);
142
143 if (attr1->mode != attr2->mode) {
144 attr_res->mode = 30;
145 }
146
147 return jointformat;
148}
149
152 .format_clone = ilbc_clone,
153 .format_cmp = NULL,
154 .format_get_joint = ilbc_getjoint,
155 .format_attribute_set = NULL,
156 .format_parse_sdp_fmtp = ilbc_parse_sdp_fmtp,
157 .format_generate_sdp_fmtp = ilbc_generate_sdp_fmtp,
158};
159
160static int load_module(void)
161{
164 }
165
167}
168
169static int unload_module(void)
170{
171 return 0;
172}
173
174AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "iLBC Format Attribute Module",
175 .support_level = AST_MODULE_SUPPORT_CORE,
176 .load = load_module,
177 .unload = unload_module,
178 .load_pri = AST_MODPRI_CHANNEL_DEPEND,
const char * str
Definition: app_jack.c:147
Asterisk main include file. File version handling, generic pbx functions.
#define ast_free(a)
Definition: astmm.h:180
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
Media Format API.
void * ast_format_get_attribute_data(const struct ast_format *format)
Get the attribute data on a format.
Definition: format.c:125
void ast_format_set_attribute_data(struct ast_format *format, void *attribute_data)
Set the attribute data on a format.
Definition: format.c:130
struct ast_format * ast_format_clone(const struct ast_format *format)
Clone an existing media format so it can be modified.
Definition: format.c:180
#define ast_format_interface_register(codec, interface)
Register a format interface for use with the provided codec.
Definition: format.h:273
Asterisk module definitions.
@ AST_MODFLAG_LOAD_ORDER
Definition: module.h:317
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
Definition: module.h:543
@ AST_MODPRI_CHANNEL_DEPEND
Definition: module.h:326
@ AST_MODULE_SUPPORT_CORE
Definition: module.h:121
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static struct ast_format_interface ilbc_interface
static struct ast_format * ilbc_getjoint(const struct ast_format *format1, const struct ast_format *format2)
static struct ilbc_attr default_ilbc_attr
static void ilbc_destroy(struct ast_format *format)
static void ilbc_generate_sdp_fmtp(const struct ast_format *format, unsigned int payload, struct ast_str **str)
static int ilbc_clone(const struct ast_format *src, struct ast_format *dst)
static struct ast_format * ilbc_parse_sdp_fmtp(const struct ast_format *format, const char *attributes)
static int load_module(void)
static int unload_module(void)
#define NULL
Definition: resample.c:96
String manipulation functions.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1139
Optional format interface to extend format operations.
Definition: format.h:44
void(*const format_destroy)(struct ast_format *format)
Callback for when the format is destroyed, used to release attribute resources.
Definition: format.h:50
Definition of a media format.
Definition: format.c:43
Support for dynamic strings.
Definition: strings.h:623
Definition: ilbc.h:4
unsigned int mode
Definition: ilbc.h:5
Definition: ast_expr2.c:325
Utility functions.