Asterisk - The Open Source Telephony Project GIT-master-8924258
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
res_aeap.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 2021, Sangoma Technologies Corporation
5 *
6 * Ben Ford <bford@sangoma.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/*** MODULEINFO
20 <depend>res_http_websocket</depend>
21 <support_level>core</support_level>
22 ***/
23
24#include "asterisk.h"
25
26#include "asterisk/astobj2.h"
27#include "asterisk/module.h"
28#include "asterisk/sorcery.h"
29#include "asterisk/cli.h"
30#include "asterisk/format.h"
31#include "asterisk/format_cap.h"
32#include "asterisk/res_aeap.h"
33
34#include "res_aeap/general.h"
35
36/*** DOCUMENTATION
37 <configInfo name="res_aeap" language="en_US">
38 <synopsis>Asterisk External Application Protocol (AEAP) module for Asterisk</synopsis>
39 <configFile name="aeap.conf">
40 <configObject name="client">
41 <since>
42 <version>18.12.0</version>
43 <version>19.4.0</version>
44 </since>
45 <synopsis>AEAP client options</synopsis>
46 <configOption name="type">
47 <since>
48 <version>18.12.0</version>
49 <version>19.4.0</version>
50 </since>
51 <synopsis>Must be of type 'client'.</synopsis>
52 </configOption>
53 <configOption name="url">
54 <since>
55 <version>18.12.0</version>
56 <version>19.4.0</version>
57 </since>
58 <synopsis>The URL of the server to connect to.</synopsis>
59 </configOption>
60 <configOption name="protocol">
61 <since>
62 <version>18.12.0</version>
63 <version>19.4.0</version>
64 </since>
65 <synopsis>The application protocol.</synopsis>
66 </configOption>
67 <configOption name="codecs">
68 <since>
69 <version>18.12.0</version>
70 <version>19.4.0</version>
71 </since>
72 <synopsis>Optional media codec(s)</synopsis>
73 <description><para>
74 If this is specified, Asterisk will use this for codec related negotiations
75 with the external application. Otherwise, Asterisk will default to using the
76 codecs configured on the endpoint.
77 </para></description>
78 </configOption>
79 </configObject>
80 </configFile>
81 </configInfo>
82 ***/
83
84/* Asterisk External Application Protocol sorcery object */
86
88 return aeap_sorcery;
89}
90
92{
95 /*! The URL of the server to connect to */
97 /*! The application protocol */
99 );
100 /*! An optional list of codecs that will be used if provided */
102};
103
104static void client_config_destructor(void *obj)
105{
106 struct ast_aeap_client_config *cfg = obj;
107
109 ao2_cleanup(cfg->codecs);
110}
111
112static void *client_config_alloc(const char *name)
113{
114 struct ast_aeap_client_config *cfg;
115
117 if (!cfg) {
118 return NULL;
119 }
120
121 if (ast_string_field_init(cfg, 512)) {
122 ao2_ref(cfg, -1);
123 return NULL;
124 }
125
127 ao2_ref(cfg, -1);
128 return NULL;
129 }
130
131 return cfg;
132}
133
134static int client_config_apply(const struct ast_sorcery *sorcery, void *obj)
135{
136 struct ast_aeap_client_config *cfg = obj;
137
138 if (ast_strlen_zero(cfg->url)) {
139 ast_log(LOG_ERROR, "AEAP - URL must be present for '%s'\n", ast_sorcery_object_get_id(cfg));
140 return -1;
141 }
142
143 if (!ast_begins_with(cfg->url, "ws")) {
144 ast_log(LOG_ERROR, "AEAP - URL must be ws or wss for '%s'\n", ast_sorcery_object_get_id(cfg));
145 return -1;
146 }
147
148 return 0;
149}
150
152{
153 return cfg->codecs;
154}
155
157 const char *protocol)
158{
159 return !strcmp(protocol, cfg->protocol);
160}
161
162struct ao2_container *ast_aeap_client_configs_get(const char *protocol)
163{
164 struct ao2_container *container;
165 struct ast_variable *var;
166
167 var = protocol ? ast_variable_new("protocol ==", protocol, "") : NULL;
168
171
173
174 return container;
175}
176
177static struct ast_aeap_client_config *client_config_get(const char *id)
178{
180}
181
182static char *aeap_tab_complete_name(const char *word, struct ao2_container *container)
183{
184 void *obj;
185 struct ao2_iterator it;
186 int wordlen = strlen(word);
187 int ret;
188
190 while ((obj = ao2_iterator_next(&it))) {
191 if (!strncasecmp(word, ast_sorcery_object_get_id(obj), wordlen)) {
193 if (ret) {
194 ao2_ref(obj, -1);
195 break;
196 }
197 }
198 ao2_ref(obj, -1);
199 }
201
202 ao2_ref(container, -1);
203
204 return NULL;
205}
206
207static int aeap_cli_show(void *obj, void *arg, int flags)
208{
209 struct ast_cli_args *a = arg;
210 struct ast_variable *options;
211 struct ast_variable *i;
212
213 if (!obj) {
214 ast_cli(a->fd, "No AEAP configuration found\n");
215 return 0;
216 }
217
219 if (!options) {
220 return 0;
221 }
222
223 ast_cli(a->fd, "%s: %s\n", ast_sorcery_object_get_type(obj),
225
226 for (i = options; i; i = i->next) {
227 ast_cli(a->fd, "\t%s: %s\n", i->name, i->value);
228 }
229
230 ast_cli(a->fd, "\n");
231
233
234 return 0;
235}
236
237static char *client_config_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
238{
239 struct ast_aeap_client_config *cfg;
240
241 switch(cmd) {
242 case CLI_INIT:
243 e->command = "aeap show client";
244 e->usage =
245 "Usage: aeap show client <id>\n"
246 " Show the AEAP settings for a given client\n";
247 return NULL;
248 case CLI_GENERATE:
249 if (a->pos == 3) {
251 } else {
252 return NULL;
253 }
254 }
255
256 if (a->argc != 4) {
257 return CLI_SHOWUSAGE;
258 }
259
260 cfg = client_config_get(a->argv[3]);
261 aeap_cli_show(cfg, a, 0);
262 ao2_cleanup(cfg);
263
264 return CLI_SUCCESS;
265}
266
267static char *client_config_show_all(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
268{
269 struct ao2_container *container;
270
271 switch(cmd) {
272 case CLI_INIT:
273 e->command = "aeap show clients";
274 e->usage =
275 "Usage: aeap show clients\n"
276 " Show all configured AEAP clients\n";
277 return NULL;
278 case CLI_GENERATE:
279 return NULL;
280 }
281
282 if (a->argc != 3) {
283 return CLI_SHOWUSAGE;
284 }
285
288 ast_cli(a->fd, "No AEAP clients found\n");
290 return CLI_SUCCESS;
291 }
292
294 ao2_ref(container, -1);
295
296 return CLI_SUCCESS;
297}
298
299static struct ast_cli_entry aeap_cli[] = {
300 AST_CLI_DEFINE(client_config_show, "Show AEAP client configuration by id"),
301 AST_CLI_DEFINE(client_config_show_all, "Show all AEAP client configurations"),
302};
303
304static struct ast_aeap *aeap_create(const char *id, const struct ast_aeap_params *params,
305 int connect, int timeout)
306{
307 struct ast_aeap_client_config *cfg;
308 struct ast_aeap *aeap;
309 const char *url = NULL;
310 const char *protocol = NULL;
311
312 cfg = client_config_get(id);
313 if (cfg) {
314 url = cfg->url;
315 protocol = cfg->protocol;
316 }
317
318#ifdef TEST_FRAMEWORK
319 else if (ast_begins_with(id, "_aeap_test_")) {
320 url = "ws://127.0.0.1:8088/ws";
321 protocol = id;
322 }
323#endif
324
325 if (!url && !protocol) {
326 ast_log(LOG_ERROR, "AEAP: unable to get configuration for '%s'\n", id);
327 return NULL;
328 }
329
330 aeap = connect ? ast_aeap_create_and_connect(url, params, url, protocol, timeout) :
332
333 ao2_cleanup(cfg);
334 return aeap;
335}
336
337struct ast_aeap *ast_aeap_create_by_id(const char *id, const struct ast_aeap_params *params)
338{
339 return aeap_create(id, params, 0, 0);
340}
341
343 const struct ast_aeap_params *params, int timeout)
344{
345 return aeap_create(id, params, 1, timeout);
346}
347
349{
350 struct ast_aeap_client_config *cfg;
351 struct ast_variable *vars;
352
353 cfg = client_config_get(id);
354 if (!cfg) {
355 ast_log(LOG_WARNING, "AEAP: no client configuration '%s' to get fields\n", id);
356 return NULL;
357 }
358
360
361 ao2_ref(cfg, -1);
362 return vars;
363}
364
365static int reload_module(void)
366{
368
369 return 0;
370}
371
372static int unload_module(void)
373{
376
378
380
381 return 0;
382}
383
384static int load_module(void)
385{
388 }
389
391 {
392 ast_log(LOG_ERROR, "AEAP - failed to open sorcery\n");
394 }
395
396 ast_sorcery_apply_default(aeap_sorcery, AEAP_CONFIG_CLIENT, "config", "aeap.conf,criteria=type=client");
397
400 ast_log(LOG_ERROR, "AEAP - failed to register client sorcery object\n");
402 }
403
408
410
412
413 return 0;
414}
415
417 "Asterisk External Application Protocol Module for Asterisk",
418 .support_level = AST_MODULE_SUPPORT_CORE,
419 .load = load_module,
420 .unload = unload_module,
422 .load_pri = AST_MODPRI_CHANNEL_DEPEND,
423 .requires = "res_http_websocket",
enum queue_result id
Definition: app_queue.c:1808
#define var
Definition: ast_expr2f.c:605
Asterisk main include file. File version handling, generic pbx functions.
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
#define ast_log
Definition: astobj2.c:42
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition: astobj2.h:1693
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
@ OBJ_NODATA
Definition: astobj2.h:1044
Standard Command Line Interface.
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_SUCCESS
Definition: cli.h:44
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
#define AST_CLI_DEFINE(fn, txt,...)
Definition: cli.h:197
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
Definition: main/cli.c:2768
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
@ CLI_INIT
Definition: cli.h:152
@ CLI_GENERATE
Definition: cli.h:153
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
static struct ao2_container * codecs
Registered codecs.
Definition: codec.c:48
short word
#define STRFLDSET(type,...)
Convert a struct and a list of stringfield fields to an argument list of field offsets.
#define FLDSET(type,...)
Convert a struct and list of fields to an argument list of field offsets.
@ OPT_NOOP_T
Type for a default handler that should do nothing.
@ OPT_CODEC_T
Type for default option handler for format capabilities.
@ OPT_STRINGFIELD_T
Type for default option handler for stringfields.
Media Format API.
Format Capabilities API.
@ AST_FORMAT_CAP_FLAG_DEFAULT
Definition: format_cap.h:38
#define ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition: format_cap.h:49
static const char name[]
Definition: format_mp3.c:68
int aeap_general_initialize(void)
Initialize general/common AEAP facilities.
Definition: general.c:42
void aeap_general_finalize(void)
Finalize/cleanup general AEAP facilities.
Definition: general.c:34
struct ast_variable * ast_variable_list_sort(struct ast_variable *head)
Performs an in-place sort on the variable list by ascending name.
Definition: main/config.c:706
#define ast_variable_new(name, value, filename)
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1262
#define LOG_ERROR
#define LOG_WARNING
Asterisk module definitions.
@ AST_MODFLAG_LOAD_ORDER
Definition: module.h:331
@ AST_MODFLAG_GLOBAL_SYMBOLS
Definition: module.h:330
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
Definition: module.h:557
@ AST_MODPRI_CHANNEL_DEPEND
Definition: module.h:340
@ 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_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static char * aeap_tab_complete_name(const char *word, struct ao2_container *container)
Definition: res_aeap.c:182
struct ast_aeap * ast_aeap_create_and_connect_by_id(const char *id, const struct ast_aeap_params *params, int timeout)
Create and connect to an Asterisk external application by sorcery id.
Definition: res_aeap.c:342
static void * client_config_alloc(const char *name)
Definition: res_aeap.c:112
static char * client_config_show_all(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: res_aeap.c:267
int ast_aeap_client_config_has_protocol(const struct ast_aeap_client_config *cfg, const char *protocol)
Check a given protocol against that in an Asterisk external application configuration.
Definition: res_aeap.c:156
static struct ast_cli_entry aeap_cli[]
Definition: res_aeap.c:299
static int reload_module(void)
Definition: res_aeap.c:365
static void client_config_destructor(void *obj)
Definition: res_aeap.c:104
struct ast_variable * ast_aeap_custom_fields_get(const char *id)
Retrieve a list of custom configuration fields.
Definition: res_aeap.c:348
static char * client_config_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: res_aeap.c:237
struct ast_sorcery * ast_aeap_sorcery(void)
Retrieve the AEAP sorcery object.
Definition: res_aeap.c:87
struct ast_aeap * ast_aeap_create_by_id(const char *id, const struct ast_aeap_params *params)
Create an Asterisk external application object by sorcery id.
Definition: res_aeap.c:337
static int aeap_cli_show(void *obj, void *arg, int flags)
Definition: res_aeap.c:207
struct ao2_container * ast_aeap_client_configs_get(const char *protocol)
Retrieve a listing of all client configuration objects by protocol.
Definition: res_aeap.c:162
static struct ast_aeap * aeap_create(const char *id, const struct ast_aeap_params *params, int connect, int timeout)
Definition: res_aeap.c:304
static struct ast_sorcery * aeap_sorcery
Definition: res_aeap.c:85
static int load_module(void)
Definition: res_aeap.c:384
static struct ast_aeap_client_config * client_config_get(const char *id)
Definition: res_aeap.c:177
static int client_config_apply(const struct ast_sorcery *sorcery, void *obj)
Definition: res_aeap.c:134
static int unload_module(void)
Definition: res_aeap.c:372
const struct ast_format_cap * ast_aeap_client_config_codecs(const struct ast_aeap_client_config *cfg)
Retrieve codec capabilities from the configuration.
Definition: res_aeap.c:151
Asterisk External Application Protocol API.
struct ast_aeap * ast_aeap_create(const char *type, const struct ast_aeap_params *params)
Create an Asterisk external application object.
Definition: aeap.c:88
#define AEAP_CONFIG_CLIENT
Definition: res_aeap.h:35
struct ast_aeap * ast_aeap_create_and_connect(const char *type, const struct ast_aeap_params *params, const char *url, const char *protocol, int timeout)
Create and connect to an Asterisk external application.
Definition: aeap.c:363
static char url[512]
static int reload(void)
struct ao2_container * container
Definition: res_fax.c:531
static struct ast_sorcery * sorcery
#define NULL
Definition: resample.c:96
Sorcery Data Access Layer API.
#define ast_sorcery_unref(sorcery)
Decrease the reference count of a sorcery structure.
Definition: sorcery.h:1500
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2317
#define ast_sorcery_objectset_create(sorcery, object)
Create an object set (KVP list) for an object.
Definition: sorcery.h:1137
@ AST_RETRIEVE_FLAG_MULTIPLE
Return all matching objects.
Definition: sorcery.h:120
@ AST_RETRIEVE_FLAG_ALL
Perform no matching, return all objects.
Definition: sorcery.h:123
void ast_sorcery_load(const struct ast_sorcery *sorcery)
Inform any wizards to load persistent objects.
Definition: sorcery.c:1377
const char * ast_sorcery_object_get_type(const void *object)
Get the type of a sorcery object.
Definition: sorcery.c:2329
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
Definition: sorcery.c:1853
#define ast_sorcery_object_register(sorcery, type, alloc, transform, apply)
Register an object type.
Definition: sorcery.h:837
void ast_sorcery_reload(const struct ast_sorcery *sorcery)
Inform any wizards to reload persistent objects.
Definition: sorcery.c:1408
void * ast_sorcery_generic_alloc(size_t size, ao2_destructor_fn destructor)
Allocate a generic sorcery capable object.
Definition: sorcery.c:1728
#define ast_sorcery_object_field_register(sorcery, type, name, default_val, opt_type, flags,...)
Register a field within an object.
Definition: sorcery.h:955
#define ast_sorcery_apply_default(sorcery, type, name, data)
Definition: sorcery.h:476
#define ast_sorcery_open()
Open a new sorcery structure.
Definition: sorcery.h:406
void * ast_sorcery_retrieve_by_fields(const struct ast_sorcery *sorcery, const char *type, unsigned int flags, struct ast_variable *fields)
Retrieve an object or multiple objects using specific fields.
Definition: sorcery.c:1897
#define AST_DECLARE_STRING_FIELDS(field_list)
Declare the fields needed in a structure.
Definition: stringfields.h:341
#define AST_STRING_FIELD(name)
Declare a string field.
Definition: stringfields.h:303
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Checks whether a string begins with another.
Definition: strings.h:97
Generic container type.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
const ast_string_field url
Definition: res_aeap.c:99
struct ast_format_cap * codecs
Definition: res_aeap.c:101
const ast_string_field protocol
Definition: res_aeap.c:99
Callbacks and other parameters used by an Asterisk external application object.
Definition: res_aeap.h:144
Definition: aeap.c:47
const struct ast_aeap_params * params
Definition: aeap.c:49
descriptor for a cli entry.
Definition: cli.h:171
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
Full structure for sorcery.
Definition: sorcery.c:230
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
static struct test_options options
static struct test_val a
#define ARRAY_LEN(a)
Definition: utils.h:666